-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy path02-on-this-page.js
135 lines (120 loc) · 5.47 KB
/
02-on-this-page.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
;(function () {
'use strict'
var sidebar = document.querySelector('aside.toc.sidebar')
if (!sidebar) return
if (document.querySelector('body.-toc')) return sidebar.parentNode.removeChild(sidebar)
var levels = parseInt(sidebar.dataset.levels || 2)
if (levels < 0) return sidebar.parentNode.removeChild(sidebar) // remove the sidebar if :page-toclevels: -1
var article = document.querySelector('article.doc')
var selectors = document.querySelector('.nav-container .selectors')
var selectorsHeight = selectors ? selectors.getBoundingClientRect().height : 0
var headings
var headingSelector = []
for (var l = 0; l <= levels; l++) headingSelector.push(l ? '.sect' + l + '>h' + (l + 1) + '[id]' : 'h1[id].sect0')
if (!(headings = find(headingSelector.join(','), article)).length) return sidebar.parentNode.removeChild(sidebar) // remove sidebar if there are no headings
var lastActiveFragment
var links = {}
var list = headings.reduce(function (accum, heading) {
var link = document.createElement('a')
link.textContent = heading.textContent
links[(link.href = '#' + heading.id)] = link
var listItem = document.createElement('li')
listItem.dataset.level = parseInt(heading.nodeName.slice(1)) - 1
listItem.appendChild(link)
accum.appendChild(listItem)
return accum
}, document.createElement('ul'))
// var sel = document.createElement('select')
// var options = headings.reduce(function (accum, heading) {
// // var link = document.createElement('a')
// // link.textContent = heading.textContent
// // links[(link.href = '#' + heading.id)] = link
// var option = document.createElement('option')
// option.value = heading.id
// option.text = heading.textContent
// // listItem.dataset.level = parseInt(heading.nodeName.slice(1)) - 1
// // listItem.appendChild(link)
// accum.appendChild(option)
// return accum
// }, sel)
// options.classList.add('version-selector', 'dropdown-styles', 'page-wide-selector')
// console.log(options)
var menu = sidebar.querySelector('.toc-menu-placeholder')
if (!menu) (menu = document.createElement('div')).className = 'toc-menu-placeholder'
var title = document.createElement('h2')
title.textContent = sidebar.dataset.title || 'Contents'
menu.appendChild(title)
menu.appendChild(list)
// var tableSelector = document.querySelector('.page-wide-selector')
// if (tableSelector) {
// tableSelector.addEventListener('change', function (e) {
// const target = e.target
// const url = target.value
// window.location.hash = url
// location.reload()
// })
// }
var startOfContent = !document.getElementById('toc') && article.querySelector('h1.page ~ :not(.is-before-toc)')
if (startOfContent) {
var embeddedToc = document.createElement('aside')
embeddedToc.className = 'toc embedded'
embeddedToc.appendChild(menu.cloneNode(true))
startOfContent.parentNode.insertBefore(embeddedToc, startOfContent)
}
window.addEventListener('load', function () {
onScroll()
window.addEventListener('scroll', onScroll)
})
function onScroll () {
var scrolledBy = window.pageYOffset
var buffer = getNumericStyleVal(document.documentElement, 'fontSize') * 1.15
var ceil = selectors ? article.offsetTop + (selectorsHeight * 1.15) : article.offsetTop
if (scrolledBy && window.innerHeight + scrolledBy + 2 >= document.documentElement.scrollHeight) {
lastActiveFragment = Array.isArray(lastActiveFragment) ? lastActiveFragment : Array(lastActiveFragment || 0)
var activeFragments = []
var lastIdx = headings.length - 1
headings.forEach(function (heading, idx) {
var fragment = '#' + heading.id
if (idx === lastIdx || heading.getBoundingClientRect().top + getNumericStyleVal(heading, 'paddingTop') > ceil) {
activeFragments.push(fragment)
if (lastActiveFragment.indexOf(fragment) < 0) links[fragment].classList.add('is-active')
} else if (~lastActiveFragment.indexOf(fragment)) {
links[lastActiveFragment.shift()].classList.remove('is-active')
}
})
list.scrollTop = list.scrollHeight - list.offsetHeight
lastActiveFragment = activeFragments.length > 1 ? activeFragments : activeFragments[0]
return
}
if (Array.isArray(lastActiveFragment)) {
lastActiveFragment.forEach(function (fragment) {
links[fragment].classList.remove('is-active')
})
lastActiveFragment = undefined
}
var activeFragment
headings.some(function (heading) {
if (heading.getBoundingClientRect().top + getNumericStyleVal(heading, 'paddingTop') - buffer > ceil) return true
activeFragment = '#' + heading.id
})
if (activeFragment) {
if (activeFragment === lastActiveFragment) return
if (lastActiveFragment) links[lastActiveFragment].classList.remove('is-active')
var activeLink = links[activeFragment]
activeLink.classList.add('is-active')
if (list.scrollHeight > list.offsetHeight) {
list.scrollTop = Math.max(0, activeLink.offsetTop + activeLink.offsetHeight - list.offsetHeight)
}
lastActiveFragment = activeFragment
} else if (lastActiveFragment) {
links[lastActiveFragment].classList.remove('is-active')
lastActiveFragment = undefined
}
}
function find (selector, from) {
return [].slice.call((from || document).querySelectorAll(selector))
}
function getNumericStyleVal (el, prop) {
return parseFloat(window.getComputedStyle(el)[prop])
}
})()