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.
Files changed (194) hide show
  1. package/.github/FUNDING.yml +0 -0
  2. package/.github/workflows/repo-lockdown.yml +0 -0
  3. package/.jsdoc.conf.json +0 -0
  4. package/LICENSE +0 -0
  5. package/README.md +2 -2
  6. package/docs/Dobo.html +0 -0
  7. package/docs/data/search.json +0 -0
  8. package/docs/fonts/Inconsolata-Regular.ttf +0 -0
  9. package/docs/fonts/OpenSans-Regular.ttf +0 -0
  10. package/docs/fonts/WorkSans-Bold.ttf +0 -0
  11. package/docs/global.html +0 -0
  12. package/docs/index.html +0 -0
  13. package/docs/index.js.html +0 -0
  14. package/docs/lib_collect-connections.js.html +0 -0
  15. package/docs/lib_collect-drivers.js.html +0 -0
  16. package/docs/lib_collect-features.js.html +0 -0
  17. package/docs/lib_collect-schemas.js.html +0 -0
  18. package/docs/lib_index.js.html +0 -0
  19. package/docs/method_model_create.js.html +0 -0
  20. package/docs/method_model_drop.js.html +0 -0
  21. package/docs/method_model_exists.js.html +0 -0
  22. package/docs/method_record_count.js.html +0 -0
  23. package/docs/method_record_create.js.html +0 -0
  24. package/docs/method_record_find-all.js.html +0 -0
  25. package/docs/method_record_find-one.js.html +0 -0
  26. package/docs/method_record_find.js.html +0 -0
  27. package/docs/method_record_get.js.html +0 -0
  28. package/docs/method_record_remove.js.html +0 -0
  29. package/docs/method_record_update.js.html +0 -0
  30. package/docs/method_record_upsert.js.html +0 -0
  31. package/docs/method_sanitize_body.js.html +0 -0
  32. package/docs/method_sanitize_date.js.html +0 -0
  33. package/docs/method_sanitize_id.js.html +0 -0
  34. package/docs/method_validate.js.html +0 -0
  35. package/docs/module-Lib.html +0 -0
  36. package/docs/scripts/core.js +476 -477
  37. package/docs/scripts/core.min.js +0 -0
  38. package/docs/scripts/resize.js +36 -36
  39. package/docs/scripts/search.js +105 -105
  40. package/docs/scripts/search.min.js +0 -0
  41. package/docs/scripts/third-party/Apache-License-2.0.txt +0 -0
  42. package/docs/scripts/third-party/fuse.js +1 -1
  43. package/docs/scripts/third-party/hljs-line-num-original.js +282 -285
  44. package/docs/scripts/third-party/hljs-line-num.js +1 -1
  45. package/docs/scripts/third-party/hljs-original.js +1195 -1202
  46. package/docs/scripts/third-party/hljs.js +1 -1
  47. package/docs/scripts/third-party/popper.js +1 -1
  48. package/docs/scripts/third-party/tippy.js +1 -1
  49. package/docs/scripts/third-party/tocbot.js +508 -509
  50. package/docs/scripts/third-party/tocbot.min.js +0 -0
  51. package/docs/static/bitcoin.jpeg +0 -0
  52. package/docs/static/home.md +0 -0
  53. package/docs/static/logo-ecosystem.png +0 -0
  54. package/docs/static/logo.png +0 -0
  55. package/docs/styles/clean-jsdoc-theme-base.css +0 -0
  56. package/docs/styles/clean-jsdoc-theme-dark.css +0 -0
  57. package/docs/styles/clean-jsdoc-theme-light.css +0 -0
  58. package/docs/styles/clean-jsdoc-theme-scrollbar.css +0 -0
  59. package/docs/styles/clean-jsdoc-theme-without-scrollbar.min.css +0 -0
  60. package/docs/styles/clean-jsdoc-theme.min.css +0 -0
  61. package/extend/bajo/intl/en-US.json +66 -28
  62. package/extend/bajo/intl/id.json +55 -27
  63. package/extend/bajoCli/applet/clear-record.js +22 -0
  64. package/extend/bajoCli/applet/connection.js +0 -0
  65. package/extend/bajoCli/applet/count-record.js +27 -0
  66. package/extend/bajoCli/applet/create-aggregate.js +33 -0
  67. package/extend/bajoCli/applet/create-histogram.js +33 -0
  68. package/extend/bajoCli/applet/create-record.js +39 -0
  69. package/extend/bajoCli/applet/find-record.js +27 -0
  70. package/extend/bajoCli/applet/get-record.js +27 -0
  71. package/extend/bajoCli/applet/lib/post-process.js +10 -17
  72. package/extend/bajoCli/applet/model.js +22 -0
  73. package/extend/bajoCli/applet/rebuild-model.js +91 -0
  74. package/extend/bajoCli/applet/remove-record.js +27 -0
  75. package/extend/bajoCli/applet/update-record.js +44 -0
  76. package/extend/bajoCli/applet.js +0 -0
  77. package/extend/dobo/driver/memory.js +170 -0
  78. package/extend/dobo/feature/created-at.js +9 -7
  79. package/extend/dobo/feature/dt.js +0 -0
  80. package/extend/dobo/feature/immutable.js +30 -0
  81. package/extend/dobo/feature/int-id.js +0 -0
  82. package/extend/dobo/feature/removed-at.js +32 -54
  83. package/extend/dobo/feature/updated-at.js +14 -12
  84. package/extend/waibuMpa/route/attachment/@model/@id/@field/@file.js +2 -6
  85. package/extend/waibuStatic/virtual.json +0 -0
  86. package/index.js +284 -371
  87. package/lib/collect-connections.js +49 -21
  88. package/lib/collect-drivers.js +19 -33
  89. package/lib/collect-features.js +24 -17
  90. package/lib/collect-models.js +321 -0
  91. package/lib/factory/action.js +161 -0
  92. package/lib/factory/connection.js +62 -0
  93. package/lib/factory/driver.js +372 -0
  94. package/lib/factory/feature.js +33 -0
  95. package/lib/factory/model/_util.js +402 -0
  96. package/lib/factory/model/build.js +15 -0
  97. package/lib/factory/model/clear-record.js +17 -0
  98. package/lib/factory/model/count-record.js +17 -0
  99. package/lib/factory/model/create-aggregate.js +17 -0
  100. package/lib/factory/model/create-attachment.js +29 -0
  101. package/lib/factory/model/create-histogram.js +17 -0
  102. package/lib/factory/model/create-record.js +35 -0
  103. package/lib/factory/model/drop.js +15 -0
  104. package/lib/factory/model/exists.js +21 -0
  105. package/lib/factory/model/find-all-record.js +71 -0
  106. package/lib/factory/model/find-attachment.js +29 -0
  107. package/lib/factory/model/find-one-record.js +19 -0
  108. package/{method/record/find.js → lib/factory/model/find-record.js} +103 -115
  109. package/lib/factory/model/get-attachment.js +15 -0
  110. package/lib/factory/model/get-record.js +79 -0
  111. package/lib/factory/model/list-attachment.js +37 -0
  112. package/lib/{add-fixtures.js → factory/model/load-fixtures.js} +69 -67
  113. package/lib/factory/model/remove-attachment.js +15 -0
  114. package/lib/factory/model/remove-record.js +59 -0
  115. package/lib/factory/model/sanitize-body.js +56 -0
  116. package/lib/factory/model/sanitize-id.js +7 -0
  117. package/lib/factory/model/sanitize-record.js +26 -0
  118. package/lib/factory/model/update-attachment.js +9 -0
  119. package/lib/factory/model/update-record.js +81 -0
  120. package/lib/factory/model/upsert-record.js +95 -0
  121. package/{method → lib/factory/model}/validate.js +38 -52
  122. package/lib/factory/model.js +150 -0
  123. package/lib/index.js +0 -0
  124. package/package.json +8 -4
  125. package/wiki/APPLETS.md +0 -0
  126. package/wiki/CHANGES.md +50 -0
  127. package/wiki/CONFIG.md +0 -0
  128. package/wiki/CONTRIBUTING.md +0 -0
  129. package/wiki/DEV-GUIDE.md +0 -0
  130. package/wiki/ECOSYSTEM.md +0 -0
  131. package/wiki/GETTING-STARTED.md +10 -10
  132. package/wiki/QUERY-LANGUAGE.md +0 -0
  133. package/wiki/USER-GUIDE.md +0 -0
  134. package/extend/bajoCli/applet/model-clear.js +0 -11
  135. package/extend/bajoCli/applet/model-rebuild.js +0 -101
  136. package/extend/bajoCli/applet/record-create.js +0 -43
  137. package/extend/bajoCli/applet/record-find.js +0 -28
  138. package/extend/bajoCli/applet/record-get.js +0 -24
  139. package/extend/bajoCli/applet/record-remove.js +0 -24
  140. package/extend/bajoCli/applet/record-update.js +0 -47
  141. package/extend/bajoCli/applet/schema.js +0 -22
  142. package/extend/bajoCli/applet/stat-count.js +0 -24
  143. package/lib/build-bulk-action.js +0 -12
  144. package/lib/check-unique.js +0 -39
  145. package/lib/collect-schemas.js +0 -91
  146. package/lib/exec-feature-hook.js +0 -13
  147. package/lib/exec-validation.js +0 -21
  148. package/lib/generic-prop-sanitizer.js +0 -32
  149. package/lib/handle-attachment-upload.js +0 -16
  150. package/lib/mem-db/conn-sanitizer.js +0 -8
  151. package/lib/mem-db/instantiate.js +0 -41
  152. package/lib/mem-db/method/model/clear.js +0 -6
  153. package/lib/mem-db/method/model/create.js +0 -5
  154. package/lib/mem-db/method/model/drop.js +0 -5
  155. package/lib/mem-db/method/model/exists.js +0 -5
  156. package/lib/mem-db/method/record/create.js +0 -12
  157. package/lib/mem-db/method/record/find.js +0 -20
  158. package/lib/mem-db/method/record/get.js +0 -9
  159. package/lib/mem-db/method/record/remove.js +0 -13
  160. package/lib/mem-db/method/record/update.js +0 -15
  161. package/lib/mem-db/method/stat/count.js +0 -11
  162. package/lib/mem-db/start.js +0 -25
  163. package/lib/merge-attachment-info.js +0 -16
  164. package/lib/multi-rel-rows.js +0 -42
  165. package/lib/resolve-method.js +0 -16
  166. package/lib/sanitize-schema.js +0 -198
  167. package/lib/single-rel-rows.js +0 -38
  168. package/method/attachment/copy-uploaded.js +0 -34
  169. package/method/attachment/create.js +0 -29
  170. package/method/attachment/find.js +0 -27
  171. package/method/attachment/get-path.js +0 -12
  172. package/method/attachment/get.js +0 -12
  173. package/method/attachment/pre-check.js +0 -9
  174. package/method/attachment/remove.js +0 -11
  175. package/method/attachment/update.js +0 -7
  176. package/method/bulk/create.js +0 -46
  177. package/method/model/clear.js +0 -22
  178. package/method/model/create.js +0 -32
  179. package/method/model/drop.js +0 -31
  180. package/method/model/exists.js +0 -37
  181. package/method/record/clear.js +0 -24
  182. package/method/record/count.js +0 -66
  183. package/method/record/create.js +0 -111
  184. package/method/record/find-all.js +0 -41
  185. package/method/record/find-one.js +0 -70
  186. package/method/record/get.js +0 -89
  187. package/method/record/remove.js +0 -72
  188. package/method/record/update.js +0 -104
  189. package/method/record/upsert.js +0 -51
  190. package/method/sanitize/body.js +0 -85
  191. package/method/sanitize/date.js +0 -27
  192. package/method/sanitize/id.js +0 -17
  193. package/method/stat/aggregate.js +0 -23
  194. package/method/stat/histogram.js +0 -26
@@ -1,672 +1,671 @@
1
1
  /* eslint no-var: off */
2
2
  var defaultOptions = {
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
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
- var reduce = [].reduce
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
- function getLastItem(array) {
43
- return array[array.length - 1]
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
- function getHeadingLevel(heading) {
52
- return +heading.nodeName.toUpperCase().replace('H', '')
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
- 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
- }
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
- const headingLabel = heading.getAttribute('data-heading-label') ||
70
+ const headingLabel = heading.getAttribute('data-heading-label') ||
71
71
  (options.headingLabelCallback ? String(options.headingLabelCallback(heading.textContent)) : heading.textContent.trim())
72
- var obj = {
73
- id: heading.id,
74
- children: [],
75
- nodeName: heading.nodeName,
76
- headingLevel: getHeadingLevel(heading),
77
- textContent: headingLabel
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
- if (options.headingObjectCallback) {
85
- return options.headingObjectCallback(obj, heading)
86
- }
80
+ if (options.includeHtml) {
81
+ obj.childNodes = heading.childNodes
82
+ }
87
83
 
88
- return obj
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
- 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
- }
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
- array.push(obj)
123
- return array
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
- 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) {
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
- return null
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
- 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: nestHeadingsArray,
167
- selectHeadings: selectHeadings
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
- 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
- /**
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
- 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)
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
- 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
- }
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
- // Just return the parent and don't append the list if no links are found.
223
- if (data.length === 0) {
224
- return tocElement
225
- }
217
+ // Remove existing child if it exists.
218
+ if (tocElement.firstChild) {
219
+ tocElement.removeChild(tocElement.firstChild)
220
+ }
226
221
 
227
- // Append the Elements that have been created
228
- return tocElement.appendChild(container)
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
- 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
- }
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
- if (options.onClick) {
244
- a.onclick = options.onClick
245
- }
243
+ if (options.onClick) {
244
+ a.onclick = options.onClick
245
+ }
246
246
 
247
- if (options.includeTitleTags) {
248
- a.setAttribute('title', data.textContent)
249
- }
247
+ if (options.includeTitleTags) {
248
+ a.setAttribute('title', data.textContent)
249
+ }
250
250
 
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 +
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
- item.appendChild(a)
264
- return item
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
- function createList(isCollapsed) {
273
- var listElement = (options.orderedList) ? 'ol' : 'ul'
274
- var list = document.createElement(listElement)
275
- var classes = options.listClass +
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
- if (isCollapsed) {
278
- classes += SPACE_CHAR + options.collapsibleClass
279
- classes += SPACE_CHAR + options.isCollapsedClass
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
- 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)
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
- if (options.fixedSidebarOffset === 'auto') {
299
- options.fixedSidebarOffset = tocElement.offsetTop
300
- }
298
+ if (options.fixedSidebarOffset === 'auto') {
299
+ options.fixedSidebarOffset = tocElement.offsetTop
300
+ }
301
301
 
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('')
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
- function getHeadingTopPos(obj) {
317
- var position = 0
318
- if (obj !== null) {
319
- position = obj.offsetTop
320
- if (options.hasInnerContainers) { position += getHeadingTopPos(obj.offsetParent) }
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
- function updateListActiveElement(topHeader) {
327
- var forEach = [].forEach
328
-
329
- var tocLinks = tocElement
330
- .querySelectorAll('.' + options.linkClass)
331
- forEach.call(tocLinks, function (tocLink) {
332
- tocLink.className = tocLink.className.split(SPACE_CHAR + options.activeLinkClass).join('')
333
- })
334
- var tocLis = tocElement
335
- .querySelectorAll('.' + options.listItemClass)
336
- forEach.call(tocLis, function (tocLi) {
337
- tocLi.className = tocLi.className.split(SPACE_CHAR + options.activeListItemClass).join('')
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
- if (activeTocLink && activeTocLink.className.indexOf(options.activeLinkClass) === -1) {
346
- activeTocLink.className += SPACE_CHAR + options.activeLinkClass
347
- }
348
- var li = activeTocLink && activeTocLink.parentNode
349
- if (li && li.className.indexOf(options.activeListItemClass) === -1) {
350
- li.className += SPACE_CHAR + options.activeListItemClass
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
- var tocLists = tocElement
354
- .querySelectorAll('.' + options.listClass + '.' + options.collapsibleClass)
352
+ var tocLists = tocElement
353
+ .querySelectorAll('.' + options.listClass + '.' + options.collapsibleClass)
355
354
 
356
- // Collapse the other collapsible lists.
357
- forEach.call(tocLists, function (list) {
358
- if (list.className.indexOf(options.isCollapsedClass) === -1) {
359
- list.className += SPACE_CHAR + options.isCollapsedClass
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
- // Expand the active link's collapsible list and its sibling if applicable.
364
- if (activeTocLink && activeTocLink.nextSibling && activeTocLink.nextSibling.className.indexOf(options.isCollapsedClass) !== -1) {
365
- activeTocLink.nextSibling.className = activeTocLink.nextSibling.className.split(SPACE_CHAR + options.isCollapsedClass).join('')
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
- function updateToc(headingsArray) {
374
- // If a fixed content container was set
375
- if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
376
- var top
377
- top = document.querySelector(options.scrollContainer).scrollTop
378
- } else {
379
- top = document.documentElement.scrollTop || body.scrollTop
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
- // Add fixed class at offset
383
- if (options.positionFixedSelector) {
384
- updateFixedSidebarClass()
385
- }
381
+ // Add fixed class at offset
382
+ if (options.positionFixedSelector) {
383
+ updateFixedSidebarClass()
384
+ }
386
385
 
387
- // Get the top most heading currently visible on the page so we know what to highlight.
388
- var headings = headingsArray
389
- var topHeader
390
- // Using some instead of each so that we can escape early.
391
- if (currentlyHighlighting &&
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
- some.call(headings, function (heading, i) {
395
- var modifiedTopOffset = top + 10
396
- if (mainContainer) {
397
- modifiedTopOffset += mainContainer.clientHeight * (mainContainer.scrollTop) / (mainContainer.scrollHeight - mainContainer.clientHeight)
398
- }
399
- if (getHeadingTopPos(heading) > modifiedTopOffset) {
400
- // Don't allow negative index value.
401
- var index = (i === 0) ? i : i - 1
402
- topHeader = headings[index]
403
- return true
404
- } else if (i === headings.length - 1) {
405
- // This allows scrolling for the last heading on the page.
406
- topHeader = headings[headings.length - 1]
407
- return true
408
- }
409
- })
410
-
411
- // Remove the active class from the other tocLinks.
412
- updateListActiveElement(topHeader)
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
- function removeCollapsedFromParents(element) {
422
- if (element && element.className.indexOf(options.collapsibleClass) !== -1 && element.className.indexOf(options.isCollapsedClass) !== -1) {
423
- element.className = element.className.split(SPACE_CHAR + options.isCollapsedClass).join('')
424
- return removeCollapsedFromParents(element.parentNode.parentNode)
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
- function disableTocAnimation(event) {
434
- var target = event.target || event.srcElement
435
- if (typeof target.className !== 'string' || target.className.indexOf(options.linkClass) === -1) {
436
- return
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
- function enableTocAnimation() {
447
- currentlyHighlighting = true
448
- }
449
-
450
- return {
451
- enableTocAnimation: enableTocAnimation,
452
- disableTocAnimation: disableTocAnimation,
453
- render: render,
454
- updateToc: updateToc,
455
- updateListActiveElement: updateListActiveElement
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
- var toc = options.tocElement || document.querySelector(options.tocSelector)
461
- if (toc && toc.scrollHeight > toc.clientHeight) {
462
- var activeItem = toc.querySelector('.' + options.activeListItemClass)
463
- if (activeItem) {
464
- var topOffset = toc.getBoundingClientRect().top
465
- toc.scrollTop = activeItem.offsetTop - topOffset
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
- if (typeof define === 'function' && define.amd) {
472
- define([], factory(root))
473
- } else if (typeof exports === 'object') {
474
- module.exports = factory(root)
475
- } else {
476
- root.tocbot = factory(root)
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
- 'use strict'
480
-
481
- var options = {}
482
- var tocbot = {}
483
- var buildHtml
484
- var parseContent
485
-
486
- // Just return if its not a browser.
487
- var supports = !!root && !!root.document && !!root.document.querySelector && !!root.addEventListener // Feature test
488
- if (typeof window === 'undefined' && !supports) {
489
- return
490
- }
491
- var headingsArray
492
-
493
- // From: https://github.com/Raynos/xtend
494
- var hasOwnProperty = Object.prototype.hasOwnProperty
495
- function extend() {
496
- var target = {}
497
- for (var i = 0; i < arguments.length; i++) {
498
- var source = arguments[i]
499
- for (var key in source) {
500
- if (hasOwnProperty.call(source, key)) {
501
- target[key] = source[key]
502
- }
503
- }
504
- }
505
- return target
506
- }
507
-
508
- // From: https://remysharp.com/2010/07/21/throttling-function-calls
509
- function throttle(fn, threshhold, scope) {
510
- threshhold || (threshhold = 250)
511
- var last
512
- var deferTimer
513
- return function () {
514
- var context = scope || this
515
- var now = +new Date()
516
- var args = arguments
517
- if (last && now < last + threshhold) {
518
- // hold on to it
519
- clearTimeout(deferTimer)
520
- deferTimer = setTimeout(function () {
521
- last = now
522
- fn.apply(context, args)
523
- }, threshhold)
524
- } else {
525
- last = now
526
- fn.apply(context, args)
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
- function getContentElement(options) {
532
- try {
533
- return options.contentElement || document.querySelector(options.contentSelector)
534
- } catch (e) {
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
- return null
537
- }
535
+ return null
538
536
  }
537
+ }
539
538
 
540
- function getTocElement(options) {
541
- try {
542
- return options.tocElement || document.querySelector(options.tocSelector)
543
- } catch (e) {
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
- return null
546
- }
544
+ return null
547
545
  }
546
+ }
548
547
 
549
- /**
548
+ /**
550
549
  * Destroy tocbot.
551
550
  */
552
- tocbot.destroy = function () {
553
- var tocElement = getTocElement(options)
554
- if (tocElement === null) {
555
- return
556
- }
551
+ tocbot.destroy = function () {
552
+ var tocElement = getTocElement(options)
553
+ if (tocElement === null) {
554
+ return
555
+ }
557
556
 
558
- if (!options.skipRendering) {
559
- // Clear HTML.
560
- if (tocElement) {
561
- tocElement.innerHTML = ''
562
- }
563
- }
557
+ if (!options.skipRendering) {
558
+ // Clear HTML.
559
+ if (tocElement) {
560
+ tocElement.innerHTML = ''
561
+ }
562
+ }
564
563
 
565
- // Remove event listeners.
566
- if (options.scrollContainer && document.querySelector(options.scrollContainer)) {
567
- document.querySelector(options.scrollContainer).removeEventListener('scroll', this._scrollListener, false)
568
- document.querySelector(options.scrollContainer).removeEventListener('resize', this._scrollListener, false)
569
- } else {
570
- document.removeEventListener('scroll', this._scrollListener, false)
571
- document.removeEventListener('resize', this._scrollListener, false)
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
- tocbot.init = function (customOptions) {
580
- // feature test
581
- if (!supports) {
582
- return
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
- // Init smooth scroll if enabled (default).
592
- if (options.scrollSmooth) {
593
- options.duration = options.scrollSmoothDuration
594
- options.offset = options.scrollSmoothOffset
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
- // Pass options to these modules.
598
- buildHtml = BuildHtml(options)
599
- parseContent = ParseContent(options)
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
- // For testing purposes.
602
- this._buildHtml = buildHtml
603
- this._parseContent = parseContent
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
- // Destroy it if it exists first.
608
- tocbot.destroy()
600
+ // For testing purposes.
601
+ this._buildHtml = buildHtml
602
+ this._parseContent = parseContent
603
+ this._headingsArray = headingsArray
604
+ this.updateTocListActiveElement = buildHtml.updateListActiveElement
609
605
 
610
- var contentElement = getContentElement(options)
611
- if (contentElement === null) {
612
- return
613
- }
606
+ // Destroy it if it exists first.
607
+ tocbot.destroy()
614
608
 
615
- var tocElement = getTocElement(options)
616
- if (tocElement === null) {
617
- return
618
- }
609
+ var contentElement = getContentElement(options)
610
+ if (contentElement === null) {
611
+ return
612
+ }
619
613
 
620
- // Get headings array.
621
- headingsArray = parseContent.selectHeadings(contentElement, options.headingSelector)
622
- // Return if no headings are found.
623
- if (headingsArray === null) {
624
- return
625
- }
614
+ var tocElement = getTocElement(options)
615
+ if (tocElement === null) {
616
+ return
617
+ }
626
618
 
627
- // Build nested headings array.
628
- var nestedHeadingsObj = parseContent.nestHeadingsArray(headingsArray)
629
- var nestedHeadings = nestedHeadingsObj.nest
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
- // Render.
632
- if (!options.skipRendering) {
633
- buildHtml.render(tocElement, nestedHeadings)
634
- }
626
+ // Build nested headings array.
627
+ var nestedHeadingsObj = parseContent.nestHeadingsArray(headingsArray)
628
+ var nestedHeadings = nestedHeadingsObj.nest
635
629
 
636
- // Update Sidebar and bind listeners.
637
- this._scrollListener = throttle(function (e) {
638
- buildHtml.updateToc(headingsArray)
639
- !options.disableTocScrollSync && updateTocScroll(options)
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
- return this
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
- tocbot.refresh = function (customOptions) {
664
- tocbot.destroy()
665
- tocbot.init(customOptions || this.options)
666
- }
662
+ tocbot.refresh = function (customOptions) {
663
+ tocbot.destroy()
664
+ tocbot.init(customOptions || this.options)
665
+ }
667
666
 
668
- // Make tocbot available globally.
669
- root.tocbot = tocbot
667
+ // Make tocbot available globally.
668
+ root.tocbot = tocbot
670
669
 
671
- return tocbot
672
- })
670
+ return tocbot
671
+ })