-
Notifications
You must be signed in to change notification settings - Fork 3
/
index.js
77 lines (68 loc) · 2.76 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(root => {
var document = root.document
getHeaderLevel.REGEXP = /h(\d)/i
function getHeaderLevel ($h) {
var level = Number(((($h || {}).tagName || '').match(getHeaderLevel.REGEXP) || [])[1])
return isNaN(level) ? undefined : level
}
var headerSels = []
for (var l = 1; l <= 6; l++) headerSels.push('h'+l)
var headerSel = headerSels.join(', ')
var anchorSel = 'a[id]'
var linkSel = 'a[href^="#"]:not(.anchor)'
root.chrome.storage.sync.get({
// default values
hideIfOutlineDetected: true,
float: false,
useInnerHTML: true
}, options => {
Array.from(document.querySelectorAll('.markdown-body')).forEach($md => {
var $headers = Array.from($md.querySelectorAll(headerSel))
if (options.hideIfOutlineDetected && $md.querySelectorAll(linkSel).length >= Math.max($headers.length - 10, 0)) return // there's already an outline in the document
var $container = document.createElement('div')
$container.classList.add('__github-markdown-outline-container')
if (options.float) $container.classList.add('__github-markdown-outline-container--float')
var $outline = document.createElement('ul')
$outline.classList.add('__github-markdown-outline')
$container.appendChild($outline)
// generate outline from headers
$headers.forEach($h => {
var level = getHeaderLevel($h)
if (!level) return
var $ul = $outline, $li, $child
for (var l = 1; l < level; l++) {
$li = $ul.lastChild || $ul.appendChild(document.createElement('li'))
$child = $li.lastChild || {}
$ul = $child.tagName === 'UL'
? $child
: $li.appendChild(document.createElement('ul'))
}
var $topic = $ul
.appendChild(document.createElement('li'))
.appendChild(document.createElement('a'))
if (options.useInnerHTML) {
$topic.innerHTML = $h.innerHTML
Array.from($topic.querySelectorAll(anchorSel)).forEach($child => {
$child.parentNode.removeChild($child)
})
} else {
$topic.innerText = $h.innerText
}
$topic.href = `#${$h.querySelector(anchorSel).id}`
})
// find all sublists with one item and replace with contents
Array.from($container.querySelectorAll('ul')).forEach($ul => {
var $parent = $ul.parentNode
var $li = $ul.firstChild
var $child = $li.firstChild
if ($li !== $ul.lastChild || $child.tagName !== 'UL') return
while ($child) {
$parent.insertBefore($child, $ul.nextSibling) // inserts to end of list if $ul.nextSibling is null
$child = $child.nextSibling
}
$parent.removeChild($ul)
})
$md.insertBefore($container, $md.firstChild)
})
})
})(this)