dobo 2.0.1 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +0 -0
- package/.github/workflows/repo-lockdown.yml +0 -0
- package/.jsdoc.conf.json +0 -0
- package/LICENSE +0 -0
- package/README.md +2 -2
- package/docs/Dobo.html +0 -0
- package/docs/data/search.json +0 -0
- package/docs/fonts/Inconsolata-Regular.ttf +0 -0
- package/docs/fonts/OpenSans-Regular.ttf +0 -0
- package/docs/fonts/WorkSans-Bold.ttf +0 -0
- package/docs/global.html +0 -0
- package/docs/index.html +0 -0
- package/docs/index.js.html +0 -0
- package/docs/lib_collect-connections.js.html +0 -0
- package/docs/lib_collect-drivers.js.html +0 -0
- package/docs/lib_collect-features.js.html +0 -0
- package/docs/lib_collect-schemas.js.html +0 -0
- package/docs/lib_index.js.html +0 -0
- package/docs/method_model_create.js.html +0 -0
- package/docs/method_model_drop.js.html +0 -0
- package/docs/method_model_exists.js.html +0 -0
- package/docs/method_record_count.js.html +0 -0
- package/docs/method_record_create.js.html +0 -0
- package/docs/method_record_find-all.js.html +0 -0
- package/docs/method_record_find-one.js.html +0 -0
- package/docs/method_record_find.js.html +0 -0
- package/docs/method_record_get.js.html +0 -0
- package/docs/method_record_remove.js.html +0 -0
- package/docs/method_record_update.js.html +0 -0
- package/docs/method_record_upsert.js.html +0 -0
- package/docs/method_sanitize_body.js.html +0 -0
- package/docs/method_sanitize_date.js.html +0 -0
- package/docs/method_sanitize_id.js.html +0 -0
- package/docs/method_validate.js.html +0 -0
- package/docs/module-Lib.html +0 -0
- package/docs/scripts/core.js +476 -477
- package/docs/scripts/core.min.js +0 -0
- package/docs/scripts/resize.js +36 -36
- package/docs/scripts/search.js +105 -105
- package/docs/scripts/search.min.js +0 -0
- package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
- package/docs/scripts/third-party/fuse.js +1 -1
- package/docs/scripts/third-party/hljs-line-num-original.js +282 -285
- package/docs/scripts/third-party/hljs-line-num.js +1 -1
- package/docs/scripts/third-party/hljs-original.js +1195 -1202
- package/docs/scripts/third-party/hljs.js +1 -1
- package/docs/scripts/third-party/popper.js +1 -1
- package/docs/scripts/third-party/tippy.js +1 -1
- package/docs/scripts/third-party/tocbot.js +508 -509
- package/docs/scripts/third-party/tocbot.min.js +0 -0
- package/docs/static/bitcoin.jpeg +0 -0
- package/docs/static/home.md +0 -0
- package/docs/static/logo-ecosystem.png +0 -0
- package/docs/static/logo.png +0 -0
- package/docs/styles/clean-jsdoc-theme-base.css +0 -0
- package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
- package/docs/styles/clean-jsdoc-theme-light.css +0 -0
- package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
- package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
- package/docs/styles/clean-jsdoc-theme.min.css +0 -0
- package/extend/bajo/intl/en-US.json +66 -28
- package/extend/bajo/intl/id.json +55 -27
- package/extend/bajoCli/applet/clear-record.js +22 -0
- package/extend/bajoCli/applet/connection.js +0 -0
- package/extend/bajoCli/applet/count-record.js +27 -0
- package/extend/bajoCli/applet/create-aggregate.js +33 -0
- package/extend/bajoCli/applet/create-histogram.js +33 -0
- package/extend/bajoCli/applet/create-record.js +39 -0
- package/extend/bajoCli/applet/find-record.js +27 -0
- package/extend/bajoCli/applet/get-record.js +27 -0
- package/extend/bajoCli/applet/lib/post-process.js +10 -17
- package/extend/bajoCli/applet/model.js +22 -0
- package/extend/bajoCli/applet/rebuild-model.js +91 -0
- package/extend/bajoCli/applet/remove-record.js +27 -0
- package/extend/bajoCli/applet/update-record.js +44 -0
- package/extend/bajoCli/applet.js +0 -0
- package/extend/dobo/driver/memory.js +170 -0
- package/extend/dobo/feature/created-at.js +9 -7
- package/extend/dobo/feature/dt.js +0 -0
- package/extend/dobo/feature/immutable.js +30 -0
- package/extend/dobo/feature/int-id.js +0 -0
- package/extend/dobo/feature/removed-at.js +32 -54
- package/extend/dobo/feature/updated-at.js +14 -12
- package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +2 -6
- package/extend/waibuStatic/virtual.json +0 -0
- package/index.js +284 -371
- package/lib/collect-connections.js +49 -21
- package/lib/collect-drivers.js +19 -33
- package/lib/collect-features.js +24 -17
- package/lib/collect-models.js +321 -0
- package/lib/factory/action.js +161 -0
- package/lib/factory/connection.js +62 -0
- package/lib/factory/driver.js +372 -0
- package/lib/factory/feature.js +33 -0
- package/lib/factory/model/_util.js +402 -0
- package/lib/factory/model/build.js +15 -0
- package/lib/factory/model/clear-record.js +17 -0
- package/lib/factory/model/count-record.js +17 -0
- package/lib/factory/model/create-aggregate.js +17 -0
- package/lib/factory/model/create-attachment.js +29 -0
- package/lib/factory/model/create-histogram.js +17 -0
- package/lib/factory/model/create-record.js +35 -0
- package/lib/factory/model/drop.js +15 -0
- package/lib/factory/model/exists.js +21 -0
- package/lib/factory/model/find-all-record.js +71 -0
- package/lib/factory/model/find-attachment.js +29 -0
- package/lib/factory/model/find-one-record.js +19 -0
- package/{method/record/find.js → lib/factory/model/find-record.js} +103 -115
- package/lib/factory/model/get-attachment.js +15 -0
- package/lib/factory/model/get-record.js +79 -0
- package/lib/factory/model/list-attachment.js +37 -0
- package/lib/{add-fixtures.js → factory/model/load-fixtures.js} +69 -67
- package/lib/factory/model/remove-attachment.js +15 -0
- package/lib/factory/model/remove-record.js +59 -0
- package/lib/factory/model/sanitize-body.js +56 -0
- package/lib/factory/model/sanitize-id.js +7 -0
- package/lib/factory/model/sanitize-record.js +26 -0
- package/lib/factory/model/update-attachment.js +9 -0
- package/lib/factory/model/update-record.js +81 -0
- package/lib/factory/model/upsert-record.js +95 -0
- package/{method → lib/factory/model}/validate.js +38 -52
- package/lib/factory/model.js +150 -0
- package/lib/index.js +0 -0
- package/package.json +8 -4
- package/wiki/APPLETS.md +0 -0
- package/wiki/CHANGES.md +50 -0
- package/wiki/CONFIG.md +0 -0
- package/wiki/CONTRIBUTING.md +0 -0
- package/wiki/DEV-GUIDE.md +0 -0
- package/wiki/ECOSYSTEM.md +0 -0
- package/wiki/GETTING-STARTED.md +10 -10
- package/wiki/QUERY-LANGUAGE.md +0 -0
- package/wiki/USER-GUIDE.md +0 -0
- package/extend/bajoCli/applet/model-clear.js +0 -11
- package/extend/bajoCli/applet/model-rebuild.js +0 -101
- package/extend/bajoCli/applet/record-create.js +0 -43
- package/extend/bajoCli/applet/record-find.js +0 -28
- package/extend/bajoCli/applet/record-get.js +0 -24
- package/extend/bajoCli/applet/record-remove.js +0 -24
- package/extend/bajoCli/applet/record-update.js +0 -47
- package/extend/bajoCli/applet/schema.js +0 -22
- package/extend/bajoCli/applet/stat-count.js +0 -24
- package/lib/build-bulk-action.js +0 -12
- package/lib/check-unique.js +0 -39
- package/lib/collect-schemas.js +0 -91
- package/lib/exec-feature-hook.js +0 -13
- package/lib/exec-validation.js +0 -21
- package/lib/generic-prop-sanitizer.js +0 -32
- package/lib/handle-attachment-upload.js +0 -16
- package/lib/mem-db/conn-sanitizer.js +0 -8
- package/lib/mem-db/instantiate.js +0 -41
- package/lib/mem-db/method/model/clear.js +0 -6
- package/lib/mem-db/method/model/create.js +0 -5
- package/lib/mem-db/method/model/drop.js +0 -5
- package/lib/mem-db/method/model/exists.js +0 -5
- package/lib/mem-db/method/record/create.js +0 -12
- package/lib/mem-db/method/record/find.js +0 -20
- package/lib/mem-db/method/record/get.js +0 -9
- package/lib/mem-db/method/record/remove.js +0 -13
- package/lib/mem-db/method/record/update.js +0 -15
- package/lib/mem-db/method/stat/count.js +0 -11
- package/lib/mem-db/start.js +0 -25
- package/lib/merge-attachment-info.js +0 -16
- package/lib/multi-rel-rows.js +0 -42
- package/lib/resolve-method.js +0 -16
- package/lib/sanitize-schema.js +0 -198
- package/lib/single-rel-rows.js +0 -38
- package/method/attachment/copy-uploaded.js +0 -34
- package/method/attachment/create.js +0 -29
- package/method/attachment/find.js +0 -27
- package/method/attachment/get-path.js +0 -12
- package/method/attachment/get.js +0 -12
- package/method/attachment/pre-check.js +0 -9
- package/method/attachment/remove.js +0 -11
- package/method/attachment/update.js +0 -7
- package/method/bulk/create.js +0 -46
- package/method/model/clear.js +0 -22
- package/method/model/create.js +0 -32
- package/method/model/drop.js +0 -31
- package/method/model/exists.js +0 -37
- package/method/record/clear.js +0 -24
- package/method/record/count.js +0 -66
- package/method/record/create.js +0 -111
- package/method/record/find-all.js +0 -41
- package/method/record/find-one.js +0 -70
- package/method/record/get.js +0 -89
- package/method/record/remove.js +0 -72
- package/method/record/update.js +0 -104
- package/method/record/upsert.js +0 -51
- package/method/sanitize/body.js +0 -85
- package/method/sanitize/date.js +0 -27
- package/method/sanitize/id.js +0 -17
- package/method/stat/aggregate.js +0 -23
- package/method/stat/histogram.js +0 -26
|
@@ -1,672 +1,671 @@
|
|
|
1
1
|
/* eslint no-var: off */
|
|
2
2
|
var defaultOptions = {
|
|
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
|
-
|
|
3
|
+
ignoreSelector: '.js-toc-ignore',
|
|
4
|
+
linkClass: 'toc-link',
|
|
5
|
+
extraLinkClasses: '',
|
|
6
|
+
activeLinkClass: 'is-active-link',
|
|
7
|
+
listClass: 'toc-list',
|
|
8
|
+
extraListClasses: '',
|
|
9
|
+
isCollapsedClass: 'is-collapsed',
|
|
10
|
+
collapsibleClass: 'is-collapsible',
|
|
11
|
+
listItemClass: 'toc-list-item',
|
|
12
|
+
activeListItemClass: 'is-active-li',
|
|
13
|
+
collapseDepth: 0,
|
|
14
|
+
scrollSmooth: true,
|
|
15
|
+
scrollSmoothDuration: 420,
|
|
16
|
+
scrollSmoothOffset: 0,
|
|
17
|
+
scrollEndCallback: function (e) { },
|
|
18
|
+
throttleTimeout: 50,
|
|
19
|
+
positionFixedSelector: null,
|
|
20
|
+
positionFixedClass: 'is-position-fixed',
|
|
21
|
+
fixedSidebarOffset: 'auto',
|
|
22
|
+
includeHtml: false,
|
|
23
|
+
includeTitleTags: false,
|
|
24
|
+
orderedList: true,
|
|
25
|
+
scrollContainer: null,
|
|
26
|
+
skipRendering: false,
|
|
27
|
+
headingLabelCallback: false,
|
|
28
|
+
ignoreHiddenElements: false,
|
|
29
|
+
headingObjectCallback: null,
|
|
30
|
+
basePath: '',
|
|
31
|
+
disableTocScrollSync: false
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function ParseContent(options) {
|
|
35
|
-
|
|
34
|
+
function ParseContent (options) {
|
|
35
|
+
var reduce = [].reduce
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
38
|
* Get the last item in an array and return a reference to it.
|
|
39
39
|
* @param {Array} array
|
|
40
40
|
* @return {Object}
|
|
41
41
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
function getLastItem (array) {
|
|
43
|
+
return array[array.length - 1]
|
|
44
|
+
}
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
/**
|
|
47
47
|
* Get heading level for a heading dom node.
|
|
48
48
|
* @param {HTMLElement} heading
|
|
49
49
|
* @return {Number}
|
|
50
50
|
*/
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
51
|
+
function getHeadingLevel (heading) {
|
|
52
|
+
return +heading.nodeName.toUpperCase().replace('H', '')
|
|
53
|
+
}
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
/**
|
|
56
56
|
* Get important properties from a heading element and store in a plain object.
|
|
57
57
|
* @param {HTMLElement} heading
|
|
58
58
|
* @return {Object}
|
|
59
59
|
*/
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
function getHeadingObject (heading) {
|
|
61
|
+
// each node is processed twice by this method because nestHeadingsArray() and addNode() calls it
|
|
62
|
+
// first time heading is real DOM node element, second time it is obj
|
|
63
|
+
// that is causing problem so I am processing only original DOM node
|
|
64
|
+
if (!(heading instanceof window.HTMLElement)) return heading
|
|
65
|
+
|
|
66
|
+
if (options.ignoreHiddenElements && (!heading.offsetHeight || !heading.offsetParent)) {
|
|
67
|
+
return null
|
|
68
|
+
}
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
const headingLabel = heading.getAttribute('data-heading-label') ||
|
|
71
71
|
(options.headingLabelCallback ? String(options.headingLabelCallback(heading.textContent)) : heading.textContent.trim())
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (options.includeHtml) {
|
|
81
|
-
obj.childNodes = heading.childNodes
|
|
82
|
-
}
|
|
72
|
+
var obj = {
|
|
73
|
+
id: heading.id,
|
|
74
|
+
children: [],
|
|
75
|
+
nodeName: heading.nodeName,
|
|
76
|
+
headingLevel: getHeadingLevel(heading),
|
|
77
|
+
textContent: headingLabel
|
|
78
|
+
}
|
|
83
79
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
if (options.includeHtml) {
|
|
81
|
+
obj.childNodes = heading.childNodes
|
|
82
|
+
}
|
|
87
83
|
|
|
88
|
-
|
|
84
|
+
if (options.headingObjectCallback) {
|
|
85
|
+
return options.headingObjectCallback(obj, heading)
|
|
89
86
|
}
|
|
90
87
|
|
|
91
|
-
|
|
88
|
+
return obj
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
92
|
* Add a node to the nested array.
|
|
93
93
|
* @param {Object} node
|
|
94
94
|
* @param {Array} nest
|
|
95
95
|
* @return {Array}
|
|
96
96
|
*/
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (level >= options.collapseDepth) {
|
|
119
|
-
obj.isCollapsed = true
|
|
120
|
-
}
|
|
97
|
+
function addNode (node, nest) {
|
|
98
|
+
var obj = getHeadingObject(node)
|
|
99
|
+
var level = obj.headingLevel
|
|
100
|
+
var array = nest
|
|
101
|
+
var lastItem = getLastItem(array)
|
|
102
|
+
var lastItemLevel = lastItem
|
|
103
|
+
? lastItem.headingLevel
|
|
104
|
+
: 0
|
|
105
|
+
var counter = level - lastItemLevel
|
|
106
|
+
|
|
107
|
+
while (counter > 0) {
|
|
108
|
+
lastItem = getLastItem(array)
|
|
109
|
+
// Handle case where there are multiple h5+ in a row.
|
|
110
|
+
if (lastItem && level === lastItem.headingLevel) {
|
|
111
|
+
break
|
|
112
|
+
} else if (lastItem && lastItem.children !== undefined) {
|
|
113
|
+
array = lastItem.children
|
|
114
|
+
}
|
|
115
|
+
counter--
|
|
116
|
+
}
|
|
121
117
|
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
if (level >= options.collapseDepth) {
|
|
119
|
+
obj.isCollapsed = true
|
|
124
120
|
}
|
|
125
121
|
|
|
126
|
-
|
|
122
|
+
array.push(obj)
|
|
123
|
+
return array
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
127
|
* Select headings in content area, exclude any selector in options.ignoreSelector
|
|
128
128
|
* @param {HTMLElement} contentElement
|
|
129
129
|
* @param {Array} headingSelector
|
|
130
130
|
* @return {Array}
|
|
131
131
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
132
|
+
function selectHeadings (contentElement, headingSelector) {
|
|
133
|
+
var selectors = headingSelector
|
|
134
|
+
if (options.ignoreSelector) {
|
|
135
|
+
selectors = headingSelector.split(',')
|
|
136
|
+
.map(function mapSelectors (selector) {
|
|
137
|
+
return selector.trim() + ':not(' + options.ignoreSelector + ')'
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
return contentElement.querySelectorAll(selectors)
|
|
142
|
+
} catch (e) {
|
|
143
143
|
console.warn('Headers not found with selector: ' + selectors); // eslint-disable-line
|
|
144
|
-
|
|
145
|
-
}
|
|
144
|
+
return null
|
|
146
145
|
}
|
|
146
|
+
}
|
|
147
147
|
|
|
148
|
-
|
|
148
|
+
/**
|
|
149
149
|
* Nest headings array into nested arrays with 'children' property.
|
|
150
150
|
* @param {Array} headingsArray
|
|
151
151
|
* @return {Object}
|
|
152
152
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
153
|
+
function nestHeadingsArray (headingsArray) {
|
|
154
|
+
return reduce.call(headingsArray, function reducer (prev, curr) {
|
|
155
|
+
var currentHeading = getHeadingObject(curr)
|
|
156
|
+
if (currentHeading) {
|
|
157
|
+
addNode(currentHeading, prev.nest)
|
|
158
|
+
}
|
|
159
|
+
return prev
|
|
160
|
+
}, {
|
|
161
|
+
nest: []
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return {
|
|
166
|
+
nestHeadingsArray,
|
|
167
|
+
selectHeadings
|
|
168
|
+
}
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
-
function BuildHtml(options) {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
171
|
+
function BuildHtml (options) {
|
|
172
|
+
var forEach = [].forEach
|
|
173
|
+
var some = [].some
|
|
174
|
+
var body = document.body
|
|
175
|
+
var tocElement
|
|
176
|
+
var mainContainer = document.querySelector(options.contentSelector)
|
|
177
|
+
var currentlyHighlighting = true
|
|
178
|
+
var SPACE_CHAR = ' '
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
181
|
* Create link and list elements.
|
|
182
182
|
* @param {Object} d
|
|
183
183
|
* @param {HTMLElement} container
|
|
184
184
|
* @return {HTMLElement}
|
|
185
185
|
*/
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
186
|
+
function createEl (d, container) {
|
|
187
|
+
var link = container.appendChild(createLink(d))
|
|
188
|
+
if (d.children.length) {
|
|
189
|
+
var list = createList(d.isCollapsed)
|
|
190
|
+
d.children.forEach(function (child) {
|
|
191
|
+
createEl(child, list)
|
|
192
|
+
})
|
|
193
|
+
link.appendChild(list)
|
|
195
194
|
}
|
|
195
|
+
}
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
/**
|
|
198
198
|
* Render nested heading array data into a given element.
|
|
199
199
|
* @param {HTMLElement} parent Optional. If provided updates the {@see tocElement} to match.
|
|
200
200
|
* @param {Array} data
|
|
201
201
|
* @return {HTMLElement}
|
|
202
202
|
*/
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
// Remove existing child if it exists.
|
|
218
|
-
if (tocElement.firstChild) {
|
|
219
|
-
tocElement.removeChild(tocElement.firstChild)
|
|
220
|
-
}
|
|
203
|
+
function render (parent, data) {
|
|
204
|
+
var collapsed = false
|
|
205
|
+
var container = createList(collapsed)
|
|
206
|
+
|
|
207
|
+
data.forEach(function (d) {
|
|
208
|
+
createEl(d, container)
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
// Return if no TOC element is provided or known.
|
|
212
|
+
tocElement = parent || tocElement
|
|
213
|
+
if (tocElement === null) {
|
|
214
|
+
return
|
|
215
|
+
}
|
|
221
216
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
217
|
+
// Remove existing child if it exists.
|
|
218
|
+
if (tocElement.firstChild) {
|
|
219
|
+
tocElement.removeChild(tocElement.firstChild)
|
|
220
|
+
}
|
|
226
221
|
|
|
227
|
-
|
|
228
|
-
|
|
222
|
+
// Just return the parent and don't append the list if no links are found.
|
|
223
|
+
if (data.length === 0) {
|
|
224
|
+
return tocElement
|
|
229
225
|
}
|
|
230
226
|
|
|
231
|
-
|
|
227
|
+
// Append the Elements that have been created
|
|
228
|
+
return tocElement.appendChild(container)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
232
|
* Create link element.
|
|
233
233
|
* @param {Object} data
|
|
234
234
|
* @return {HTMLElement}
|
|
235
235
|
*/
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
function createLink (data) {
|
|
237
|
+
var item = document.createElement('li')
|
|
238
|
+
var a = document.createElement('a')
|
|
239
|
+
if (options.listItemClass) {
|
|
240
|
+
item.setAttribute('class', options.listItemClass)
|
|
241
|
+
}
|
|
242
242
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
if (options.onClick) {
|
|
244
|
+
a.onclick = options.onClick
|
|
245
|
+
}
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
if (options.includeTitleTags) {
|
|
248
|
+
a.setAttribute('title', data.textContent)
|
|
249
|
+
}
|
|
250
250
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
251
|
+
if (options.includeHtml && data.childNodes.length) {
|
|
252
|
+
forEach.call(data.childNodes, function (node) {
|
|
253
|
+
a.appendChild(node.cloneNode(true))
|
|
254
|
+
})
|
|
255
|
+
} else {
|
|
256
|
+
// Default behavior.
|
|
257
|
+
a.textContent = data.textContent
|
|
258
|
+
}
|
|
259
|
+
a.setAttribute('href', options.basePath + '#' + data.id)
|
|
260
|
+
a.setAttribute('class', options.linkClass +
|
|
261
261
|
SPACE_CHAR + 'node-name--' + data.nodeName +
|
|
262
262
|
SPACE_CHAR + options.extraLinkClasses)
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
263
|
+
item.appendChild(a)
|
|
264
|
+
return item
|
|
265
|
+
}
|
|
266
266
|
|
|
267
|
-
|
|
267
|
+
/**
|
|
268
268
|
* Create list element.
|
|
269
269
|
* @param {Boolean} isCollapsed
|
|
270
270
|
* @return {HTMLElement}
|
|
271
271
|
*/
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
272
|
+
function createList (isCollapsed) {
|
|
273
|
+
var listElement = (options.orderedList) ? 'ol' : 'ul'
|
|
274
|
+
var list = document.createElement(listElement)
|
|
275
|
+
var classes = options.listClass +
|
|
276
276
|
SPACE_CHAR + options.extraListClasses
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
}
|
|
281
|
-
list.setAttribute('class', classes)
|
|
282
|
-
return list
|
|
277
|
+
if (isCollapsed) {
|
|
278
|
+
classes += SPACE_CHAR + options.collapsibleClass
|
|
279
|
+
classes += SPACE_CHAR + options.isCollapsedClass
|
|
283
280
|
}
|
|
281
|
+
list.setAttribute('class', classes)
|
|
282
|
+
return list
|
|
283
|
+
}
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
/**
|
|
286
286
|
* Update fixed sidebar class.
|
|
287
287
|
* @return {HTMLElement}
|
|
288
288
|
*/
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
289
|
+
function updateFixedSidebarClass () {
|
|
290
|
+
if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
|
|
291
|
+
var top
|
|
292
|
+
top = document.querySelector(options.scrollContainer).scrollTop
|
|
293
|
+
} else {
|
|
294
|
+
top = document.documentElement.scrollTop || body.scrollTop
|
|
295
|
+
}
|
|
296
|
+
var posFixedEl = document.querySelector(options.positionFixedSelector)
|
|
297
297
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
298
|
+
if (options.fixedSidebarOffset === 'auto') {
|
|
299
|
+
options.fixedSidebarOffset = tocElement.offsetTop
|
|
300
|
+
}
|
|
301
301
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
302
|
+
if (top > options.fixedSidebarOffset) {
|
|
303
|
+
if (posFixedEl.className.indexOf(options.positionFixedClass) === -1) {
|
|
304
|
+
posFixedEl.className += SPACE_CHAR + options.positionFixedClass
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
posFixedEl.className = posFixedEl.className.split(SPACE_CHAR + options.positionFixedClass).join('')
|
|
309
308
|
}
|
|
309
|
+
}
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
/**
|
|
312
312
|
* Get top position of heading
|
|
313
313
|
* @param {HTMLElement} obj
|
|
314
314
|
* @return {int} position
|
|
315
315
|
*/
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
return position
|
|
316
|
+
function getHeadingTopPos (obj) {
|
|
317
|
+
var position = 0
|
|
318
|
+
if (obj !== null) {
|
|
319
|
+
position = obj.offsetTop
|
|
320
|
+
if (options.hasInnerContainers) { position += getHeadingTopPos(obj.offsetParent) }
|
|
323
321
|
}
|
|
322
|
+
return position
|
|
323
|
+
}
|
|
324
324
|
|
|
325
|
+
function updateListActiveElement (topHeader) {
|
|
326
|
+
var forEach = [].forEach
|
|
325
327
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
// Add the active class to the active tocLink.
|
|
341
|
-
var activeTocLink = tocElement
|
|
342
|
-
.querySelector('.' + options.linkClass +
|
|
328
|
+
var tocLinks = tocElement
|
|
329
|
+
.querySelectorAll('.' + options.linkClass)
|
|
330
|
+
forEach.call(tocLinks, function (tocLink) {
|
|
331
|
+
tocLink.className = tocLink.className.split(SPACE_CHAR + options.activeLinkClass).join('')
|
|
332
|
+
})
|
|
333
|
+
var tocLis = tocElement
|
|
334
|
+
.querySelectorAll('.' + options.listItemClass)
|
|
335
|
+
forEach.call(tocLis, function (tocLi) {
|
|
336
|
+
tocLi.className = tocLi.className.split(SPACE_CHAR + options.activeListItemClass).join('')
|
|
337
|
+
})
|
|
338
|
+
|
|
339
|
+
// Add the active class to the active tocLink.
|
|
340
|
+
var activeTocLink = tocElement
|
|
341
|
+
.querySelector('.' + options.linkClass +
|
|
343
342
|
'.node-name--' + topHeader.nodeName +
|
|
344
343
|
'[href="' + options.basePath + '#' + topHeader.id.replace(/([ #;&,.+*~':"!^$[\]()=>|/@])/g, '\\$1') + '"]')
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
344
|
+
if (activeTocLink && activeTocLink.className.indexOf(options.activeLinkClass) === -1) {
|
|
345
|
+
activeTocLink.className += SPACE_CHAR + options.activeLinkClass
|
|
346
|
+
}
|
|
347
|
+
var li = activeTocLink && activeTocLink.parentNode
|
|
348
|
+
if (li && li.className.indexOf(options.activeListItemClass) === -1) {
|
|
349
|
+
li.className += SPACE_CHAR + options.activeListItemClass
|
|
350
|
+
}
|
|
352
351
|
|
|
353
|
-
|
|
354
|
-
|
|
352
|
+
var tocLists = tocElement
|
|
353
|
+
.querySelectorAll('.' + options.listClass + '.' + options.collapsibleClass)
|
|
355
354
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
355
|
+
// Collapse the other collapsible lists.
|
|
356
|
+
forEach.call(tocLists, function (list) {
|
|
357
|
+
if (list.className.indexOf(options.isCollapsedClass) === -1) {
|
|
358
|
+
list.className += SPACE_CHAR + options.isCollapsedClass
|
|
359
|
+
}
|
|
360
|
+
})
|
|
362
361
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
}
|
|
367
|
-
removeCollapsedFromParents(activeTocLink && activeTocLink.parentNode.parentNode)
|
|
362
|
+
// Expand the active link's collapsible list and its sibling if applicable.
|
|
363
|
+
if (activeTocLink && activeTocLink.nextSibling && activeTocLink.nextSibling.className.indexOf(options.isCollapsedClass) !== -1) {
|
|
364
|
+
activeTocLink.nextSibling.className = activeTocLink.nextSibling.className.split(SPACE_CHAR + options.isCollapsedClass).join('')
|
|
368
365
|
}
|
|
366
|
+
removeCollapsedFromParents(activeTocLink && activeTocLink.parentNode.parentNode)
|
|
367
|
+
}
|
|
369
368
|
|
|
370
|
-
|
|
369
|
+
/**
|
|
371
370
|
* Update TOC highlighting and collpased groupings.
|
|
372
371
|
*/
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
372
|
+
function updateToc (headingsArray) {
|
|
373
|
+
// If a fixed content container was set
|
|
374
|
+
if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
|
|
375
|
+
var top
|
|
376
|
+
top = document.querySelector(options.scrollContainer).scrollTop
|
|
377
|
+
} else {
|
|
378
|
+
top = document.documentElement.scrollTop || body.scrollTop
|
|
379
|
+
}
|
|
381
380
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
381
|
+
// Add fixed class at offset
|
|
382
|
+
if (options.positionFixedSelector) {
|
|
383
|
+
updateFixedSidebarClass()
|
|
384
|
+
}
|
|
386
385
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
386
|
+
// Get the top most heading currently visible on the page so we know what to highlight.
|
|
387
|
+
var headings = headingsArray
|
|
388
|
+
var topHeader
|
|
389
|
+
// Using some instead of each so that we can escape early.
|
|
390
|
+
if (currentlyHighlighting &&
|
|
392
391
|
tocElement !== null &&
|
|
393
392
|
headings.length > 0) {
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
}
|
|
393
|
+
some.call(headings, function (heading, i) {
|
|
394
|
+
var modifiedTopOffset = top + 10
|
|
395
|
+
if (mainContainer) {
|
|
396
|
+
modifiedTopOffset += mainContainer.clientHeight * (mainContainer.scrollTop) / (mainContainer.scrollHeight - mainContainer.clientHeight)
|
|
397
|
+
}
|
|
398
|
+
if (getHeadingTopPos(heading) > modifiedTopOffset) {
|
|
399
|
+
// Don't allow negative index value.
|
|
400
|
+
var index = (i === 0) ? i : i - 1
|
|
401
|
+
topHeader = headings[index]
|
|
402
|
+
return true
|
|
403
|
+
} else if (i === headings.length - 1) {
|
|
404
|
+
// This allows scrolling for the last heading on the page.
|
|
405
|
+
topHeader = headings[headings.length - 1]
|
|
406
|
+
return true
|
|
407
|
+
}
|
|
408
|
+
})
|
|
409
|
+
|
|
410
|
+
// Remove the active class from the other tocLinks.
|
|
411
|
+
updateListActiveElement(topHeader)
|
|
414
412
|
}
|
|
413
|
+
}
|
|
415
414
|
|
|
416
|
-
|
|
415
|
+
/**
|
|
417
416
|
* Remove collpased class from parent elements.
|
|
418
417
|
* @param {HTMLElement} element
|
|
419
418
|
* @return {HTMLElement}
|
|
420
419
|
*/
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
}
|
|
426
|
-
return element
|
|
420
|
+
function removeCollapsedFromParents (element) {
|
|
421
|
+
if (element && element.className.indexOf(options.collapsibleClass) !== -1 && element.className.indexOf(options.isCollapsedClass) !== -1) {
|
|
422
|
+
element.className = element.className.split(SPACE_CHAR + options.isCollapsedClass).join('')
|
|
423
|
+
return removeCollapsedFromParents(element.parentNode.parentNode)
|
|
427
424
|
}
|
|
425
|
+
return element
|
|
426
|
+
}
|
|
428
427
|
|
|
429
|
-
|
|
428
|
+
/**
|
|
430
429
|
* Disable TOC Animation when a link is clicked.
|
|
431
430
|
* @param {Event} event
|
|
432
431
|
*/
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
}
|
|
438
|
-
// Bind to tocLink clicks to temporarily disable highlighting
|
|
439
|
-
// while smoothScroll is animating.
|
|
440
|
-
currentlyHighlighting = false
|
|
432
|
+
function disableTocAnimation (event) {
|
|
433
|
+
var target = event.target || event.srcElement
|
|
434
|
+
if (typeof target.className !== 'string' || target.className.indexOf(options.linkClass) === -1) {
|
|
435
|
+
return
|
|
441
436
|
}
|
|
437
|
+
// Bind to tocLink clicks to temporarily disable highlighting
|
|
438
|
+
// while smoothScroll is animating.
|
|
439
|
+
currentlyHighlighting = false
|
|
440
|
+
}
|
|
442
441
|
|
|
443
|
-
|
|
442
|
+
/**
|
|
444
443
|
* Enable TOC Animation.
|
|
445
444
|
*/
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
445
|
+
function enableTocAnimation () {
|
|
446
|
+
currentlyHighlighting = true
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
return {
|
|
450
|
+
enableTocAnimation,
|
|
451
|
+
disableTocAnimation,
|
|
452
|
+
render,
|
|
453
|
+
updateToc,
|
|
454
|
+
updateListActiveElement
|
|
455
|
+
}
|
|
457
456
|
}
|
|
458
457
|
|
|
459
|
-
function updateTocScroll(options) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
458
|
+
function updateTocScroll (options) {
|
|
459
|
+
var toc = options.tocElement || document.querySelector(options.tocSelector)
|
|
460
|
+
if (toc && toc.scrollHeight > toc.clientHeight) {
|
|
461
|
+
var activeItem = toc.querySelector('.' + options.activeListItemClass)
|
|
462
|
+
if (activeItem) {
|
|
463
|
+
var topOffset = toc.getBoundingClientRect().top
|
|
464
|
+
toc.scrollTop = activeItem.offsetTop - topOffset
|
|
467
465
|
}
|
|
466
|
+
}
|
|
468
467
|
}
|
|
469
468
|
|
|
470
469
|
(function (root, factory) {
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
470
|
+
if (typeof define === 'function' && define.amd) {
|
|
471
|
+
define([], factory(root))
|
|
472
|
+
} else if (typeof exports === 'object') {
|
|
473
|
+
module.exports = factory(root)
|
|
474
|
+
} else {
|
|
475
|
+
root.tocbot = factory(root)
|
|
476
|
+
}
|
|
478
477
|
})(typeof global !== 'undefined' ? global : this.window || this.global, function (root) {
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
478
|
+
'use strict'
|
|
479
|
+
|
|
480
|
+
var options = {}
|
|
481
|
+
var tocbot = {}
|
|
482
|
+
var buildHtml
|
|
483
|
+
var parseContent
|
|
484
|
+
|
|
485
|
+
// Just return if its not a browser.
|
|
486
|
+
var supports = !!root && !!root.document && !!root.document.querySelector && !!root.addEventListener // Feature test
|
|
487
|
+
if (typeof window === 'undefined' && !supports) {
|
|
488
|
+
return
|
|
489
|
+
}
|
|
490
|
+
var headingsArray
|
|
491
|
+
|
|
492
|
+
// From: https://github.com/Raynos/xtend
|
|
493
|
+
var hasOwnProperty = Object.prototype.hasOwnProperty
|
|
494
|
+
function extend () {
|
|
495
|
+
var target = {}
|
|
496
|
+
for (var i = 0; i < arguments.length; i++) {
|
|
497
|
+
var source = arguments[i]
|
|
498
|
+
for (var key in source) {
|
|
499
|
+
if (hasOwnProperty.call(source, key)) {
|
|
500
|
+
target[key] = source[key]
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
return target
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// From: https://remysharp.com/2010/07/21/throttling-function-calls
|
|
508
|
+
function throttle (fn, threshhold, scope) {
|
|
509
|
+
threshhold || (threshhold = 250)
|
|
510
|
+
var last
|
|
511
|
+
var deferTimer
|
|
512
|
+
return function () {
|
|
513
|
+
var context = scope || this
|
|
514
|
+
var now = +new Date()
|
|
515
|
+
var args = arguments
|
|
516
|
+
if (last && now < last + threshhold) {
|
|
517
|
+
// hold on to it
|
|
518
|
+
clearTimeout(deferTimer)
|
|
519
|
+
deferTimer = setTimeout(function () {
|
|
520
|
+
last = now
|
|
521
|
+
fn.apply(context, args)
|
|
522
|
+
}, threshhold)
|
|
523
|
+
} else {
|
|
524
|
+
last = now
|
|
525
|
+
fn.apply(context, args)
|
|
526
|
+
}
|
|
529
527
|
}
|
|
528
|
+
}
|
|
530
529
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
530
|
+
function getContentElement (options) {
|
|
531
|
+
try {
|
|
532
|
+
return options.contentElement || document.querySelector(options.contentSelector)
|
|
533
|
+
} catch (e) {
|
|
535
534
|
console.warn('Contents element not found: ' + options.contentSelector) // eslint-disable-line
|
|
536
|
-
|
|
537
|
-
}
|
|
535
|
+
return null
|
|
538
536
|
}
|
|
537
|
+
}
|
|
539
538
|
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
539
|
+
function getTocElement (options) {
|
|
540
|
+
try {
|
|
541
|
+
return options.tocElement || document.querySelector(options.tocSelector)
|
|
542
|
+
} catch (e) {
|
|
544
543
|
console.warn('TOC element not found: ' + options.tocSelector) // eslint-disable-line
|
|
545
|
-
|
|
546
|
-
}
|
|
544
|
+
return null
|
|
547
545
|
}
|
|
546
|
+
}
|
|
548
547
|
|
|
549
|
-
|
|
548
|
+
/**
|
|
550
549
|
* Destroy tocbot.
|
|
551
550
|
*/
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
551
|
+
tocbot.destroy = function () {
|
|
552
|
+
var tocElement = getTocElement(options)
|
|
553
|
+
if (tocElement === null) {
|
|
554
|
+
return
|
|
555
|
+
}
|
|
557
556
|
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
557
|
+
if (!options.skipRendering) {
|
|
558
|
+
// Clear HTML.
|
|
559
|
+
if (tocElement) {
|
|
560
|
+
tocElement.innerHTML = ''
|
|
561
|
+
}
|
|
562
|
+
}
|
|
564
563
|
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
564
|
+
// Remove event listeners.
|
|
565
|
+
if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
|
|
566
|
+
document.querySelector(options.scrollContainer).removeEventListener('scroll', this._scrollListener, false)
|
|
567
|
+
document.querySelector(options.scrollContainer).removeEventListener('resize', this._scrollListener, false)
|
|
568
|
+
} else {
|
|
569
|
+
document.removeEventListener('scroll', this._scrollListener, false)
|
|
570
|
+
document.removeEventListener('resize', this._scrollListener, false)
|
|
573
571
|
}
|
|
572
|
+
}
|
|
574
573
|
|
|
575
|
-
|
|
574
|
+
/**
|
|
576
575
|
* Initialize tocbot.
|
|
577
576
|
* @param {object} customOptions
|
|
578
577
|
*/
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
// Merge defaults with user options.
|
|
586
|
-
// Set to options variable at the top.
|
|
587
|
-
options = extend(defaultOptions, customOptions || {})
|
|
588
|
-
this.options = options
|
|
589
|
-
this.state = {}
|
|
578
|
+
tocbot.init = function (customOptions) {
|
|
579
|
+
// feature test
|
|
580
|
+
if (!supports) {
|
|
581
|
+
return
|
|
582
|
+
}
|
|
590
583
|
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
584
|
+
// Merge defaults with user options.
|
|
585
|
+
// Set to options variable at the top.
|
|
586
|
+
options = extend(defaultOptions, customOptions || {})
|
|
587
|
+
this.options = options
|
|
588
|
+
this.state = {}
|
|
596
589
|
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
590
|
+
// Init smooth scroll if enabled (default).
|
|
591
|
+
if (options.scrollSmooth) {
|
|
592
|
+
options.duration = options.scrollSmoothDuration
|
|
593
|
+
options.offset = options.scrollSmoothOffset
|
|
594
|
+
}
|
|
600
595
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
this._headingsArray = headingsArray
|
|
605
|
-
this.updateTocListActiveElement = buildHtml.updateListActiveElement
|
|
596
|
+
// Pass options to these modules.
|
|
597
|
+
buildHtml = BuildHtml(options)
|
|
598
|
+
parseContent = ParseContent(options)
|
|
606
599
|
|
|
607
|
-
|
|
608
|
-
|
|
600
|
+
// For testing purposes.
|
|
601
|
+
this._buildHtml = buildHtml
|
|
602
|
+
this._parseContent = parseContent
|
|
603
|
+
this._headingsArray = headingsArray
|
|
604
|
+
this.updateTocListActiveElement = buildHtml.updateListActiveElement
|
|
609
605
|
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
return
|
|
613
|
-
}
|
|
606
|
+
// Destroy it if it exists first.
|
|
607
|
+
tocbot.destroy()
|
|
614
608
|
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
609
|
+
var contentElement = getContentElement(options)
|
|
610
|
+
if (contentElement === null) {
|
|
611
|
+
return
|
|
612
|
+
}
|
|
619
613
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
return
|
|
625
|
-
}
|
|
614
|
+
var tocElement = getTocElement(options)
|
|
615
|
+
if (tocElement === null) {
|
|
616
|
+
return
|
|
617
|
+
}
|
|
626
618
|
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
619
|
+
// Get headings array.
|
|
620
|
+
headingsArray = parseContent.selectHeadings(contentElement, options.headingSelector)
|
|
621
|
+
// Return if no headings are found.
|
|
622
|
+
if (headingsArray === null) {
|
|
623
|
+
return
|
|
624
|
+
}
|
|
630
625
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
}
|
|
626
|
+
// Build nested headings array.
|
|
627
|
+
var nestedHeadingsObj = parseContent.nestHeadingsArray(headingsArray)
|
|
628
|
+
var nestedHeadings = nestedHeadingsObj.nest
|
|
635
629
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
var isTop = e && e.target && e.target.scrollingElement && e.target.scrollingElement.scrollTop === 0
|
|
641
|
-
if ((e && (e.eventPhase === 0 || e.currentTarget === null)) || isTop) {
|
|
642
|
-
buildHtml.updateToc(headingsArray)
|
|
643
|
-
if (options.scrollEndCallback) {
|
|
644
|
-
options.scrollEndCallback(e)
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}, options.throttleTimeout)
|
|
648
|
-
this._scrollListener()
|
|
649
|
-
if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
|
|
650
|
-
document.querySelector(options.scrollContainer).addEventListener('scroll', this._scrollListener, false)
|
|
651
|
-
document.querySelector(options.scrollContainer).addEventListener('resize', this._scrollListener, false)
|
|
652
|
-
} else {
|
|
653
|
-
document.addEventListener('scroll', this._scrollListener, false)
|
|
654
|
-
document.addEventListener('resize', this._scrollListener, false)
|
|
655
|
-
}
|
|
630
|
+
// Render.
|
|
631
|
+
if (!options.skipRendering) {
|
|
632
|
+
buildHtml.render(tocElement, nestedHeadings)
|
|
633
|
+
}
|
|
656
634
|
|
|
657
|
-
|
|
635
|
+
// Update Sidebar and bind listeners.
|
|
636
|
+
this._scrollListener = throttle(function (e) {
|
|
637
|
+
buildHtml.updateToc(headingsArray)
|
|
638
|
+
!options.disableTocScrollSync && updateTocScroll(options)
|
|
639
|
+
var isTop = e && e.target && e.target.scrollingElement && e.target.scrollingElement.scrollTop === 0
|
|
640
|
+
if ((e && (e.eventPhase === 0 || e.currentTarget === null)) || isTop) {
|
|
641
|
+
buildHtml.updateToc(headingsArray)
|
|
642
|
+
if (options.scrollEndCallback) {
|
|
643
|
+
options.scrollEndCallback(e)
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}, options.throttleTimeout)
|
|
647
|
+
this._scrollListener()
|
|
648
|
+
if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
|
|
649
|
+
document.querySelector(options.scrollContainer).addEventListener('scroll', this._scrollListener, false)
|
|
650
|
+
document.querySelector(options.scrollContainer).addEventListener('resize', this._scrollListener, false)
|
|
651
|
+
} else {
|
|
652
|
+
document.addEventListener('scroll', this._scrollListener, false)
|
|
653
|
+
document.addEventListener('resize', this._scrollListener, false)
|
|
658
654
|
}
|
|
659
655
|
|
|
660
|
-
|
|
656
|
+
return this
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
661
660
|
* Refresh tocbot.
|
|
662
661
|
*/
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
662
|
+
tocbot.refresh = function (customOptions) {
|
|
663
|
+
tocbot.destroy()
|
|
664
|
+
tocbot.init(customOptions || this.options)
|
|
665
|
+
}
|
|
667
666
|
|
|
668
|
-
|
|
669
|
-
|
|
667
|
+
// Make tocbot available globally.
|
|
668
|
+
root.tocbot = tocbot
|
|
670
669
|
|
|
671
|
-
|
|
672
|
-
})
|
|
670
|
+
return tocbot
|
|
671
|
+
})
|