您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Provide directory navigation of the markdown file content of the github/gitee website.
当前为
- // ==UserScript==
- // @name Git Markdown Content Navigation
- // @name:zh-CN Git Markdown 文件内容导航
- // @namespace https://github.com/wang1212/user-script/blob/main/git-markdown-content-navigation
- // @version 0.3.0
- // @description Provide directory navigation of the markdown file content of the github/gitee website.
- // @description:zh-cn 提供 github/gitee 网站 markdown 文件内容的目录导航。
- // @author wang1212
- // @match http*://github.com/*
- // @match http*://gitee.com/*
- // @grant GM_registerMenuCommand
- // @grant GM_openInTab
- // @grant GM_setValue
- // @grant GM_getValue
- // @supportURL https://github.com/wang1212/user-script/blob/main/git-markdown-content-navigation
- // @license MIT
- // ==/UserScript==
- ;(function () {
- 'use strict'
- const log = console.log
- /* ------------------------------- Register menu configuration item ----------------------------- */
- let menu_item_value_switch;
- let menu_item_id_switch;
- let menu_item_id_feedback;
- let menu_item_id_source;
- function registerMenuCommand() {
- //
- if (menu_item_id_switch) GM_unregisterMenuCommand(menu_item_id_switch);
- menu_item_value_switch = GM_getValue('menu_item_value_switch');
- menu_item_id_switch = GM_registerMenuCommand(
- !menu_item_value_switch ? '默认显示 [点击切换]' : '默认隐藏 [点击切换]',
- function() {
- GM_setValue('menu_item_value_switch', !menu_item_value_switch);
- location.reload();
- }
- );
- //
- if (menu_item_id_source) GM_unregisterMenuCommand(menu_item_id_source);
- menu_item_id_source = GM_registerMenuCommand(
- '源码 [GitHub]',
- function() {
- GM_openInTab('https://github.com/wang1212/user-script/tree/main/git-markdown-content-navigation', { active: true, insert: true, setParent: true });
- }
- );
- //
- if (menu_item_id_feedback) GM_unregisterMenuCommand(menu_item_id_feedback);
- menu_item_id_feedback = GM_registerMenuCommand(
- '反馈 & 更新',
- function() {
- GM_openInTab('https://greasyfork.org/scripts/421316-git-markdown-content-navigation', { active: true, insert: true, setParent: true });
- }
- );
- }
- registerMenuCommand();
- /* ------------------------------- Init ----------------------------- */
- const href = location.href
- const matchGithub = /github/
- const matchGithubRepository = /https?:\/\/github.com\/.+\/.+/
- const matchGitee = /gitee/
- const matchGiteeRepository = /https?:\/\/gitee.com\/.+\/.+/
- const isGithub = !!href.match(matchGithub)
- const isGitee = !!href.match(matchGitee)
- const isRepositoryPage = !!(href.match(matchGithubRepository) || href.match(matchGiteeRepository))
- /* ------------------------------- Parse MarkDown file content navigation ----------------------------- */
- function updateMarkdownFileContentNavigation() {
- let navBarElem = document.querySelector('.wang1212_md-content-nav')
- // Remove existing
- navBarElem && navBarElem.remove()
- if (!isRepositoryPage) return
- // titles
- const titles = getMarkDownContentTitles()
- if (!titles.length) return
- // navBar button
- navBarElem = document.createElement('div')
- navBarElem.classList.add('wang1212_md-content-nav')
- navBarElem.title = 'Markdown 文件内容导航'
- navBarElem.innerText = 'N'
- // Panel
- const navBarPanelElem = document.createElement('div')
- navBarPanelElem.classList.add('wang1212_md-content-nav_panel')
- navBarPanelElem.innerHTML = ''
- // draw titles
- titles.forEach((title) => {
- const level = +title.tagName.substr(-1)
- navBarPanelElem.innerHTML += `
- <p class="wang1212_md-content-nav_to-anchor" style="font-size: ${1 - ((level - 1) * 0).toFixed(2)}rem; margin: 0; padding-left: ${((level - 1) * 0.5).toFixed(
- 2
- )}rem" data-anchor="${title.anchorId}">
- ${title.text}
- </p>
- `
- })
- // --- CSS Style ---
- const styleElem = document.createElement('style')
- styleElem.type = 'text/css'
- styleElem.innerHTML = `
- .wang1212_md-content-nav {
- position: fixed;
- right: 1rem;
- bottom: 3.5rem;
- z-index: 1999;
- width: 2rem;
- height: 2rem;
- color: white;
- font-size: 1.5rem;
- line-height: 2rem;
- text-align: center;
- background-color: rgb(36, 41, 46);
- cursor: pointer;
- }
- .wang1212_md-content-nav_panel {
- position: absolute;
- right: 0;
- bottom: 2rem;
- display: block;
- width: 20rem;
- height: 75vh;
- padding: 0.5rem;
- overflow: auto;
- color: #999;
- text-align: left;
- background: white;
- box-shadow: rgba(0, 0, 0, 0.25) 0 0 0.5rem 0;
- }
- .wang1212_md-content-nav_to-anchor {
- line-height: 1.6 !important;
- transition: all 0.4s linear;
- }
- .wang1212_md-content-nav_to-anchor:hover {
- color: rgb(0, 0, 0);
- transform: translateX(4px);
- }
- `
- navBarElem.appendChild(navBarPanelElem)
- document.body.appendChild(navBarElem)
- document.head.appendChild(styleElem)
- // --- Event ---
- // Show/Hide
- navBarElem.addEventListener(
- 'click',
- (e) => {
- if (e.target !== navBarElem) return
- if (navBarPanelElem.style.display === 'none') {
- navBarPanelElem.style.display = 'block'
- } else {
- navBarPanelElem.style.display = 'none'
- }
- },
- false
- )
- if (menu_item_value_switch) {
- navBarPanelElem.style.display = 'none';
- }
- // fly to view
- navBarPanelElem.addEventListener(
- 'click',
- (e) => {
- if (!e.target.classList.contains('wang1212_md-content-nav_to-anchor')) return
- const anchorElem = document.getElementById(e.target.dataset.anchor)
- if (!anchorElem) return
- anchorElem.scrollIntoView({ behavior: 'smooth', block: 'start' })
- },
- false
- )
- }
- /* ------------------------------- To Top ----------------------------- */
- // to top button
- function updateGoToTopButton() {
- let toTopElem = document.querySelector('.wang1212_to-top')
- // Remove existing
- toTopElem && toTopElem.remove()
- // toTop button
- toTopElem = document.createElement('div')
- toTopElem.classList.add('wang1212_to-top')
- toTopElem.title = '回到顶部'
- toTopElem.innerText = '↑'
- // --- CSS Style ---
- const styleElem = document.createElement('style')
- styleElem.type = 'text/css'
- styleElem.innerHTML = `
- .wang1212_to-top {
- position: fixed;
- right: 1rem;
- bottom: 1rem;
- z-index: 1999;
- width: 2rem;
- height: 2rem;
- color: white;
- font-size: 1.5rem;
- line-height: 2rem;
- text-align: center;
- background-color: rgb(36, 41, 46);
- cursor: pointer;
- }
- `
- document.body.appendChild(toTopElem)
- document.head.appendChild(styleElem)
- // --- Event ---
- // fly to view
- toTopElem.addEventListener(
- 'click',
- () => {
- document.body.scrollIntoView({ behavior: 'smooth' })
- },
- false
- )
- }
- /* ------------------------------- Utils ----------------------------- */
- // parse titles
- function getMarkDownContentTitles() {
- let rootElem = document.querySelector('.markdown-body')
- if (!rootElem) return []
- const anchors = rootElem.querySelectorAll('a.anchor')
- if (!anchors.length) return []
- const titles = []
- anchors.forEach((elem) => {
- const parentElem = elem.parentElement
- titles.push({
- tagName: parentElem.tagName,
- text: parentElem.textContent,
- anchorId: elem.id,
- })
- })
- return titles
- }
- /* ------------------------------- Load ----------------------------- */
- function load() {
- updateMarkdownFileContentNavigation()
- updateGoToTopButton()
- }
- // Monitor page reload
- document.addEventListener('pjax:end', load, false)
- if (isGitee) {
- // Monitor page modify
- const observer = new MutationObserver(load)
- observer.observe(document.querySelector('.tree-holder'), { childList: true, subtree: false })
- }
- //
- load()
- })()