github outline - github.com

12/9/2019, 5:20:26 PM

当前为 2019-12-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name github outline - github.com
  3. // @namespace Violentmonkey Scripts
  4. // @match https://github.com/*
  5. // @grant none
  6. // @version 1.01
  7. // @author TianyiLi-e0991100238@gmail.com
  8. // @description 12/9/2019, 5:20:26 PM
  9. // ==/UserScript==
  10. if (document.querySelector('#readme article')) {
  11. const canvas = document.createElement('div')
  12. canvas.style = `
  13. position: fixed;
  14. top: 10vh;
  15. right: 8vw;
  16. width: 300px;
  17. border-radius: 5px;
  18. background: white;
  19. border: solid 1px #e0e0e0;
  20. overflow-y: auto;
  21. max-height: 60vh;
  22. `
  23. const markdownDOM = document.querySelector('#readme article')
  24. function recursiveNodeReader(node, nodeLevel = 1) {
  25. let n = node.querySelector('h1, h2, h3, h4, h5')
  26. let result = []
  27. do {
  28. if (['h1', 'h2', 'h3', 'h4', 'h5'].includes(n.tagName.toLowerCase())) {
  29. result.push({
  30. text: n.textContent,
  31. level:
  32. ['h1', 'h2', 'h3', 'h4', 'h5'].indexOf(n.tagName.toLowerCase()) + 1,
  33. link: n.querySelector('a').href,
  34. })
  35. }
  36. } while ((n = n.nextElementSibling))
  37. return result
  38. }
  39.  
  40. function renderDOM(domTree) {
  41. return domTree
  42. .map(
  43. node =>
  44. `<a style="display:block" href="${node.link}" level="${node.level}">${
  45. node.level > 1 ? '&nbsp;'.repeat(node.level - 2) + '└' : '─'
  46. }${node.text}</a>`
  47. )
  48. .join('')
  49. }
  50. const body = document.createElement('div')
  51. const header = document.createElement('div')
  52. header.textContent = 'Outline'
  53. header.style = `
  54. padding: .5rem .7rem;
  55. font-size: 2rem;
  56. position: sticky;
  57. top: 0px;
  58. background: white;
  59. `
  60.  
  61. body.style = `
  62. padding: .2rem .3rem;
  63. `
  64.  
  65. body.addEventListener('mousedown', e => e.stopPropagation(), {
  66. capture: true,
  67. })
  68. body.addEventListener('click', e => e.stopPropagation(), { capture: true })
  69. let isMove = false
  70. let position = {
  71. x: 0,
  72. y: 0,
  73. }
  74. let target = null
  75. function eleMove(e) {
  76. if (!isMove) return
  77. target.style.top = e.clientY - position.y + 'px'
  78. target.style.left = e.clientX - position.x + 'px'
  79. target.style.right = ''
  80. }
  81. canvas.addEventListener(
  82. 'mousedown',
  83. function(e) {
  84. isMove = true
  85. position.x = e.offsetX
  86. position.y = e.offsetY
  87. target = this
  88. window.addEventListener('mousemove', eleMove, true)
  89. }
  90. )
  91. canvas.addEventListener(
  92. 'mouseup',
  93. () => {
  94. isMove = false
  95. window.removeEventListener('mousemove', eleMove, true)
  96. }
  97. )
  98.  
  99. body.innerHTML = renderDOM(recursiveNodeReader(markdownDOM))
  100. canvas.appendChild(header)
  101. canvas.appendChild(body)
  102.  
  103. document.body.appendChild(canvas)
  104. }