tocbot.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398
  1. /******/ (() => { // webpackBootstrap
  2. /******/ "use strict";
  3. /******/ var __webpack_modules__ = ({
  4. /***/ "./src/js/build-html.js":
  5. /*!******************************!*\
  6. !*** ./src/js/build-html.js ***!
  7. \******************************/
  8. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  9. __webpack_require__.r(__webpack_exports__);
  10. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  11. /* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)
  12. /* harmony export */ });
  13. /**
  14. * This file is responsible for building the DOM and updating DOM state.
  15. *
  16. * @author Tim Scanlin
  17. */
  18. /* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(options) {
  19. const forEach = [].forEach
  20. const some = [].some
  21. const body = typeof window !== "undefined" && document.body
  22. const SPACE_CHAR = " "
  23. let tocElement
  24. let currentlyHighlighting = true
  25. let eventCount = 0
  26. /**
  27. * Create link and list elements.
  28. * @param {Object} d
  29. * @param {HTMLElement} container
  30. * @return {HTMLElement}
  31. */
  32. function createEl(d, container) {
  33. const link = container.appendChild(createLink(d))
  34. if (d.children.length) {
  35. const list = createList(d.isCollapsed)
  36. d.children.forEach((child) => {
  37. createEl(child, list)
  38. })
  39. link.appendChild(list)
  40. }
  41. }
  42. /**
  43. * Render nested heading array data into a given element.
  44. * @param {HTMLElement} parent Optional. If provided updates the {@see tocElement} to match.
  45. * @param {Array} data
  46. * @return {HTMLElement}
  47. */
  48. function render(parent, data) {
  49. const collapsed = false
  50. const container = createList(collapsed)
  51. data.forEach((d) => {
  52. createEl(d, container)
  53. })
  54. // Return if no TOC element is provided or known.
  55. tocElement = parent || tocElement
  56. if (tocElement === null) {
  57. return
  58. }
  59. // Remove existing child if it exists.
  60. if (tocElement.firstChild) {
  61. tocElement.removeChild(tocElement.firstChild)
  62. }
  63. // Just return the parent and don't append the list if no links are found.
  64. if (data.length === 0) {
  65. return tocElement
  66. }
  67. // Append the Elements that have been created
  68. return tocElement.appendChild(container)
  69. }
  70. /**
  71. * Create link element.
  72. * @param {Object} data
  73. * @return {HTMLElement}
  74. */
  75. function createLink(data) {
  76. const item = document.createElement("li")
  77. const a = document.createElement("a")
  78. if (options.listItemClass) {
  79. item.setAttribute("class", options.listItemClass)
  80. }
  81. if (options.onClick) {
  82. a.onclick = options.onClick
  83. }
  84. if (options.includeTitleTags) {
  85. a.setAttribute("title", data.textContent)
  86. }
  87. if (options.includeHtml && data.childNodes.length) {
  88. forEach.call(data.childNodes, (node) => {
  89. a.appendChild(node.cloneNode(true))
  90. })
  91. } else {
  92. // Default behavior. Set to textContent to keep tests happy.
  93. a.textContent = data.textContent
  94. }
  95. a.setAttribute("href", `${options.basePath}#${data.id}`)
  96. a.setAttribute(
  97. "class",
  98. `${
  99. options.linkClass + SPACE_CHAR
  100. }node-name--${data.nodeName}${SPACE_CHAR}${options.extraLinkClasses}`,
  101. )
  102. item.appendChild(a)
  103. return item
  104. }
  105. /**
  106. * Create list element.
  107. * @param {Boolean} isCollapsed
  108. * @return {HTMLElement}
  109. */
  110. function createList(isCollapsed) {
  111. const listElement = options.orderedList ? "ol" : "ul"
  112. const list = document.createElement(listElement)
  113. let classes = options.listClass + SPACE_CHAR + options.extraListClasses
  114. if (isCollapsed) {
  115. // No plus/equals here fixes compilation issue.
  116. classes = classes + SPACE_CHAR + options.collapsibleClass
  117. classes = classes + SPACE_CHAR + options.isCollapsedClass
  118. }
  119. list.setAttribute("class", classes)
  120. return list
  121. }
  122. /**
  123. * Update fixed sidebar class.
  124. * @return {HTMLElement}
  125. */
  126. function updateFixedSidebarClass() {
  127. const scrollTop = getScrollTop()
  128. const posFixedEl = document.querySelector(options.positionFixedSelector)
  129. if (options.fixedSidebarOffset === "auto") {
  130. options.fixedSidebarOffset = tocElement.offsetTop
  131. }
  132. if (scrollTop > options.fixedSidebarOffset) {
  133. if (posFixedEl.className.indexOf(options.positionFixedClass) === -1) {
  134. posFixedEl.className += SPACE_CHAR + options.positionFixedClass
  135. }
  136. } else {
  137. posFixedEl.className = posFixedEl.className.replace(
  138. SPACE_CHAR + options.positionFixedClass,
  139. "",
  140. )
  141. }
  142. }
  143. /**
  144. * Get top position of heading
  145. * @param {HTMLElement} obj
  146. * @return {int} position
  147. */
  148. function getHeadingTopPos(obj) {
  149. let position = 0
  150. if (obj !== null) {
  151. position = obj.offsetTop
  152. if (options.hasInnerContainers) {
  153. position += getHeadingTopPos(obj.offsetParent)
  154. }
  155. }
  156. return position
  157. }
  158. /**
  159. * Update className only when changed.
  160. * @param {HTMLElement} obj
  161. * @param {string} className
  162. * @return {HTMLElement} obj
  163. */
  164. function updateClassname(obj, className) {
  165. if (obj && obj.className !== className) {
  166. obj.className = className
  167. }
  168. return obj
  169. }
  170. /**
  171. * Update TOC highlighting and collapsed groupings.
  172. */
  173. function updateToc(headingsArray, event) {
  174. // Add fixed class at offset
  175. if (options.positionFixedSelector) {
  176. updateFixedSidebarClass()
  177. }
  178. // Get the top most heading currently visible on the page so we know what to highlight.
  179. const headings = headingsArray
  180. // This is needed for scroll events since document doesn't have getAttribute
  181. const clickedHref = event?.target?.getAttribute
  182. ? event?.target?.getAttribute("href")
  183. : null
  184. const isBottomMode =
  185. clickedHref && clickedHref.charAt(0) === "#"
  186. ? getIsHeaderBottomMode(clickedHref.replace("#", ""))
  187. : false
  188. const shouldUpdate = currentlyHighlighting || isBottomMode
  189. if (event && eventCount < 5) {
  190. eventCount++
  191. }
  192. if (shouldUpdate && !!tocElement && headings.length > 0) {
  193. const topHeader = getTopHeader(headings)
  194. const oldActiveTocLink = tocElement.querySelector(
  195. `.${options.activeLinkClass}`,
  196. )
  197. const topHeaderId = topHeader.id.replace(
  198. /([ #;&,.+*~':"!^$[\]()=>|/\\@])/g,
  199. "\\$1",
  200. )
  201. const hashId = window.location.hash.replace("#", "")
  202. let activeId = topHeaderId
  203. // Handle case where they clicked a link that cannot be scrolled to.
  204. const isPageBottomMode = getIsPageBottomMode()
  205. if (clickedHref && isBottomMode) {
  206. activeId = clickedHref.replace("#", "")
  207. } else if (
  208. hashId &&
  209. hashId !== topHeaderId &&
  210. isPageBottomMode &&
  211. (getIsHeaderBottomMode(topHeaderId) || eventCount <= 2)
  212. ) {
  213. // This is meant to handle the case
  214. // of showing the items as highlighted when they
  215. // are in bottom mode and cannot be scrolled to.
  216. // Make sure that they stay highlighted on refresh
  217. // too, not just when clicked.
  218. activeId = hashId
  219. }
  220. const activeTocLink = tocElement.querySelector(
  221. `.${options.linkClass}[href="${options.basePath}#${activeId}"]`,
  222. )
  223. // Performance improvement to only change the classes
  224. // for the toc if a new link should be highlighted.
  225. if (oldActiveTocLink === activeTocLink) {
  226. return
  227. }
  228. // Remove the active class from the other tocLinks.
  229. const tocLinks = tocElement.querySelectorAll(`.${options.linkClass}`)
  230. forEach.call(tocLinks, (tocLink) => {
  231. updateClassname(
  232. tocLink,
  233. tocLink.className.replace(SPACE_CHAR + options.activeLinkClass, ""),
  234. )
  235. })
  236. const tocLis = tocElement.querySelectorAll(`.${options.listItemClass}`)
  237. forEach.call(tocLis, (tocLi) => {
  238. updateClassname(
  239. tocLi,
  240. tocLi.className.replace(SPACE_CHAR + options.activeListItemClass, ""),
  241. )
  242. })
  243. // Add the active class to the active tocLink.
  244. if (
  245. activeTocLink &&
  246. activeTocLink.className.indexOf(options.activeLinkClass) === -1
  247. ) {
  248. activeTocLink.className += SPACE_CHAR + options.activeLinkClass
  249. }
  250. const li = activeTocLink?.parentNode
  251. if (li && li.className.indexOf(options.activeListItemClass) === -1) {
  252. li.className += SPACE_CHAR + options.activeListItemClass
  253. }
  254. const tocLists = tocElement.querySelectorAll(
  255. `.${options.listClass}.${options.collapsibleClass}`,
  256. )
  257. // Collapse the other collapsible lists.
  258. forEach.call(tocLists, (list) => {
  259. if (list.className.indexOf(options.isCollapsedClass) === -1) {
  260. list.className += SPACE_CHAR + options.isCollapsedClass
  261. }
  262. })
  263. // Expand the active link's collapsible list and its sibling if applicable.
  264. if (
  265. activeTocLink?.nextSibling &&
  266. activeTocLink.nextSibling.className.indexOf(
  267. options.isCollapsedClass,
  268. ) !== -1
  269. ) {
  270. updateClassname(
  271. activeTocLink.nextSibling,
  272. activeTocLink.nextSibling.className.replace(
  273. SPACE_CHAR + options.isCollapsedClass,
  274. "",
  275. ),
  276. )
  277. }
  278. removeCollapsedFromParents(activeTocLink?.parentNode.parentNode)
  279. }
  280. }
  281. /**
  282. * Remove collapsed class from parent elements.
  283. * @param {HTMLElement} element
  284. * @return {HTMLElement}
  285. */
  286. function removeCollapsedFromParents(element) {
  287. if (
  288. element &&
  289. element.className.indexOf(options.collapsibleClass) !== -1 &&
  290. element.className.indexOf(options.isCollapsedClass) !== -1
  291. ) {
  292. updateClassname(
  293. element,
  294. element.className.replace(SPACE_CHAR + options.isCollapsedClass, ""),
  295. )
  296. return removeCollapsedFromParents(element.parentNode.parentNode)
  297. }
  298. return element
  299. }
  300. /**
  301. * Disable TOC Animation when a link is clicked.
  302. * @param {Event} event
  303. */
  304. function disableTocAnimation(event) {
  305. const target = event.target || event.srcElement
  306. if (
  307. typeof target.className !== "string" ||
  308. target.className.indexOf(options.linkClass) === -1
  309. ) {
  310. return
  311. }
  312. // Bind to tocLink clicks to temporarily disable highlighting
  313. // while smoothScroll is animating.
  314. currentlyHighlighting = false
  315. }
  316. /**
  317. * Enable TOC Animation.
  318. */
  319. function enableTocAnimation() {
  320. currentlyHighlighting = true
  321. }
  322. /**
  323. * Return currently highlighting status.
  324. */
  325. function getCurrentlyHighlighting() {
  326. return currentlyHighlighting
  327. }
  328. function getIsHeaderBottomMode(headerId) {
  329. const scrollEl = getScrollEl()
  330. const activeHeading = document?.getElementById(headerId)
  331. const isBottomMode =
  332. activeHeading.offsetTop >
  333. scrollEl.offsetHeight -
  334. scrollEl.clientHeight * 1.4 -
  335. options.bottomModeThreshold
  336. return isBottomMode
  337. }
  338. function getIsPageBottomMode() {
  339. const scrollEl = getScrollEl()
  340. const isScrollable = scrollEl.scrollHeight > scrollEl.clientHeight
  341. const isBottomMode =
  342. getScrollTop() + scrollEl.clientHeight >
  343. scrollEl.offsetHeight - options.bottomModeThreshold
  344. return isScrollable && isBottomMode
  345. }
  346. function getScrollEl() {
  347. let el
  348. if (
  349. options.scrollContainer &&
  350. document.querySelector(options.scrollContainer)
  351. ) {
  352. el = document.querySelector(options.scrollContainer)
  353. } else {
  354. el = document.documentElement || body
  355. }
  356. return el
  357. }
  358. function getScrollTop() {
  359. const el = getScrollEl()
  360. return el?.scrollTop || 0
  361. }
  362. function getTopHeader(headings, scrollTop = getScrollTop()) {
  363. let topHeader
  364. some.call(headings, (heading, i) => {
  365. if (getHeadingTopPos(heading) > scrollTop + options.headingsOffset + 10) {
  366. // Don't allow negative index value.
  367. const index = i === 0 ? i : i - 1
  368. topHeader = headings[index]
  369. return true
  370. }
  371. if (i === headings.length - 1) {
  372. // This allows scrolling for the last heading on the page.
  373. topHeader = headings[headings.length - 1]
  374. return true
  375. }
  376. })
  377. return topHeader
  378. }
  379. function updateUrlHashForHeader(headingsArray) {
  380. const scrollTop = getScrollTop()
  381. const topHeader = getTopHeader(headingsArray, scrollTop)
  382. const isPageBottomMode = getIsPageBottomMode()
  383. if ((!topHeader || scrollTop < 5) && !isPageBottomMode) {
  384. if (!(window.location.hash === "#" || window.location.hash === "")) {
  385. window.history.pushState(null, null, "#")
  386. }
  387. } else if (topHeader && !isPageBottomMode) {
  388. const newHash = `#${topHeader.id}`
  389. if (window.location.hash !== newHash) {
  390. window.history.pushState(null, null, newHash)
  391. }
  392. }
  393. }
  394. return {
  395. enableTocAnimation,
  396. disableTocAnimation,
  397. render,
  398. updateToc,
  399. getCurrentlyHighlighting,
  400. getTopHeader,
  401. getScrollTop,
  402. updateUrlHashForHeader,
  403. }
  404. }
  405. /***/ }),
  406. /***/ "./src/js/default-options.js":
  407. /*!***********************************!*\
  408. !*** ./src/js/default-options.js ***!
  409. \***********************************/
  410. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  411. __webpack_require__.r(__webpack_exports__);
  412. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  413. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  414. /* harmony export */ });
  415. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  416. // Where to render the table of contents.
  417. tocSelector: ".js-toc",
  418. // Or, you can pass in a DOM node instead
  419. tocElement: null,
  420. // Where to grab the headings to build the table of contents.
  421. contentSelector: ".js-toc-content",
  422. // Or, you can pass in a DOM node instead
  423. contentElement: null,
  424. // Which headings to grab inside of the contentSelector element.
  425. headingSelector: "h1, h2, h3",
  426. // Headings that match the ignoreSelector will be skipped.
  427. ignoreSelector: ".js-toc-ignore",
  428. // For headings inside relative or absolute positioned
  429. // containers within content.
  430. hasInnerContainers: false,
  431. // Main class to add to links.
  432. linkClass: "toc-link",
  433. // Extra classes to add to links.
  434. extraLinkClasses: "",
  435. // Class to add to active links,
  436. // the link corresponding to the top most heading on the page.
  437. activeLinkClass: "is-active-link",
  438. // Main class to add to lists.
  439. listClass: "toc-list",
  440. // Extra classes to add to lists.
  441. extraListClasses: "",
  442. // Class that gets added when a list should be collapsed.
  443. isCollapsedClass: "is-collapsed",
  444. // Class that gets added when a list should be able
  445. // to be collapsed but isn't necessarily collapsed.
  446. collapsibleClass: "is-collapsible",
  447. // Class to add to list items.
  448. listItemClass: "toc-list-item",
  449. // Class to add to active list items.
  450. activeListItemClass: "is-active-li",
  451. // How many heading levels should not be collapsed.
  452. // For example, number 6 will show everything since
  453. // there are only 6 heading levels and number 0 will collapse them all.
  454. // The sections that are hidden will open
  455. // and close as you scroll to headings within them.
  456. collapseDepth: 0,
  457. // Smooth scrolling enabled.
  458. scrollSmooth: true,
  459. // Smooth scroll duration.
  460. scrollSmoothDuration: 420,
  461. // Smooth scroll offset.
  462. scrollSmoothOffset: 0,
  463. // Callback for scroll end.
  464. scrollEndCallback: function (e) {},
  465. // Headings offset between the headings and the top of
  466. // the document (this is meant for minor adjustments).
  467. headingsOffset: 1,
  468. // Enable the URL hash to update with the proper heading ID as
  469. // a user scrolls the page.
  470. enableUrlHashUpdateOnScroll: false,
  471. // type of scroll handler to use. to make scroll event not too rapid.
  472. // Options are: "debounce" or "throttle"
  473. // when set auto , use debounce less than 333ms , other use throttle.
  474. // for ios browser can't use history.pushState() more than 100 times per 30 seconds reason
  475. scrollHandlerType: "auto",
  476. // scrollHandler delay in ms.
  477. scrollHandlerTimeout: 50,
  478. // Timeout between events firing to make sure it's
  479. // not too rapid (for performance reasons).
  480. throttleTimeout: 50,
  481. // Element to add the positionFixedClass to.
  482. positionFixedSelector: null,
  483. // Fixed position class to add to make sidebar fixed after scrolling
  484. // down past the fixedSidebarOffset.
  485. positionFixedClass: "is-position-fixed",
  486. // fixedSidebarOffset can be any number but by default is set
  487. // to auto which sets the fixedSidebarOffset to the sidebar
  488. // element's offsetTop from the top of the document on init.
  489. fixedSidebarOffset: "auto",
  490. // includeHtml can be set to true to include the HTML markup from the
  491. // heading node instead of just including the innerText.
  492. includeHtml: false,
  493. // includeTitleTags automatically sets the html title tag of the link
  494. // to match the title. This can be useful for SEO purposes or
  495. // when truncating titles.
  496. includeTitleTags: false,
  497. // onclick function to apply to all links in toc. will be called with
  498. // the event as the first parameter, and this can be used to stop,
  499. // propagation, prevent default or perform action
  500. onClick: function (e) {},
  501. // orderedList can be set to false to generate unordered lists (ul)
  502. // instead of ordered lists (ol)
  503. orderedList: true,
  504. // If there is a fixed article scroll container, set to calculate offset.
  505. scrollContainer: null,
  506. // prevent ToC DOM rendering if it's already rendered by an external system.
  507. skipRendering: false,
  508. // Optional callback to change heading labels.
  509. // For example it can be used to cut down and put ellipses on multiline headings you deem too long.
  510. // Called each time a heading is parsed. Expects a string and returns the modified label to display.
  511. // Additionally, the attribute `data-heading-label` may be used on a heading to specify
  512. // a shorter string to be used in the TOC.
  513. // function (string) => string
  514. headingLabelCallback: false,
  515. // ignore headings that are hidden in DOM
  516. ignoreHiddenElements: false,
  517. // Optional callback to modify properties of parsed headings.
  518. // The heading element is passed in node parameter and information
  519. // parsed by default parser is provided in obj parameter.
  520. // Function has to return the same or modified obj.
  521. // The heading will be excluded from TOC if nothing is returned.
  522. // function (object, HTMLElement) => object | void
  523. headingObjectCallback: null,
  524. // Set the base path, useful if you use a `base` tag in `head`.
  525. basePath: "",
  526. // Only takes affect when `tocSelector` is scrolling,
  527. // keep the toc scroll position in sync with the content.
  528. disableTocScrollSync: false,
  529. // If this is null then just use `tocElement` or `tocSelector` instead
  530. // assuming `disableTocScrollSync` is set to false. This allows for
  531. // scrolling an outer element (like a nav panel w/ search) containing the toc.
  532. // Please pass an element, not a selector here.
  533. tocScrollingWrapper: null,
  534. // Offset for the toc scroll (top) position when scrolling the page.
  535. // Only effective if `disableTocScrollSync` is false.
  536. tocScrollOffset: 30,
  537. // Threshold for when bottom mode should be enabled to handle
  538. // highlighting links that cannot be scrolled to.
  539. bottomModeThreshold: 30,
  540. });
  541. /***/ }),
  542. /***/ "./src/js/index-esm.js":
  543. /*!*****************************!*\
  544. !*** ./src/js/index-esm.js ***!
  545. \*****************************/
  546. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  547. __webpack_require__.r(__webpack_exports__);
  548. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  549. /* harmony export */ _buildHtml: () => (/* binding */ _buildHtml),
  550. /* harmony export */ _headingsArray: () => (/* binding */ _headingsArray),
  551. /* harmony export */ _options: () => (/* binding */ _options),
  552. /* harmony export */ _parseContent: () => (/* binding */ _parseContent),
  553. /* harmony export */ _scrollListener: () => (/* binding */ _scrollListener),
  554. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
  555. /* harmony export */ destroy: () => (/* binding */ destroy),
  556. /* harmony export */ init: () => (/* binding */ init),
  557. /* harmony export */ refresh: () => (/* binding */ refresh)
  558. /* harmony export */ });
  559. /* harmony import */ var _build_html_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./build-html.js */ "./src/js/build-html.js");
  560. /* harmony import */ var _default_options_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./default-options.js */ "./src/js/default-options.js");
  561. /* harmony import */ var _parse_content_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./parse-content.js */ "./src/js/parse-content.js");
  562. /* harmony import */ var _scroll_smooth_index_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./scroll-smooth/index.js */ "./src/js/scroll-smooth/index.js");
  563. /* harmony import */ var _update_toc_scroll_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./update-toc-scroll.js */ "./src/js/update-toc-scroll.js");
  564. /* eslint no-var: off */
  565. /**
  566. * Tocbot
  567. * Tocbot creates a table of contents based on HTML headings on a page,
  568. * this allows users to easily jump to different sections of the document.
  569. * Tocbot was inspired by tocify (http://gregfranko.com/jquery.tocify.js/).
  570. * The main differences are that it works natively without any need for jquery or jquery UI).
  571. *
  572. * @author Tim Scanlin
  573. */
  574. // For testing purposes.
  575. let _options = {} // Object to store current options.
  576. let _buildHtml
  577. let _parseContent
  578. let _headingsArray
  579. let _scrollListener
  580. let clickListener
  581. /**
  582. * Initialize tocbot.
  583. * @param {object} customOptions
  584. */
  585. function init(customOptions) {
  586. // Merge defaults with user options.
  587. // Set to options variable at the top.
  588. let hasInitialized = false
  589. _options = extend(_default_options_js__WEBPACK_IMPORTED_MODULE_1__["default"], customOptions || {})
  590. // Init smooth scroll if enabled (default).
  591. if (_options.scrollSmooth) {
  592. _options.duration = _options.scrollSmoothDuration
  593. _options.offset = _options.scrollSmoothOffset
  594. ;(0,_scroll_smooth_index_js__WEBPACK_IMPORTED_MODULE_3__["default"])(_options)
  595. }
  596. // Pass options to these modules.
  597. _buildHtml = (0,_build_html_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_options)
  598. _parseContent = (0,_parse_content_js__WEBPACK_IMPORTED_MODULE_2__["default"])(_options)
  599. // Destroy it if it exists first.
  600. destroy()
  601. const contentElement = getContentElement(_options)
  602. if (contentElement === null) {
  603. return
  604. }
  605. const tocElement = getTocElement(_options)
  606. if (tocElement === null) {
  607. return
  608. }
  609. // Get headings array.
  610. _headingsArray = _parseContent.selectHeadings(
  611. contentElement,
  612. _options.headingSelector,
  613. )
  614. // Return if no headings are found.
  615. if (_headingsArray === null) {
  616. return
  617. }
  618. // Build nested headings array.
  619. const nestedHeadingsObj = _parseContent.nestHeadingsArray(_headingsArray)
  620. const nestedHeadings = nestedHeadingsObj.nest
  621. // Render.
  622. if (!_options.skipRendering) {
  623. _buildHtml.render(tocElement, nestedHeadings)
  624. } else {
  625. // No need to attach listeners if skipRendering is true, this was causing errors.
  626. return this
  627. }
  628. // Update Sidebar and bind listeners.
  629. let isClick = false
  630. // choose timeout by _options
  631. const scrollHandlerTimeout =
  632. _options.scrollHandlerTimeout || _options.throttleTimeout // compatible with legacy configurations
  633. // choose debounce or throttle
  634. // default use debounce when delay is less than 333ms
  635. // the reason is ios browser has a limit : can't use history.pushState() more than 100 times per 30 seconds
  636. const scrollHandler = (fn, delay) =>
  637. getScrollHandler(fn, delay, _options.scrollHandlerType)
  638. _scrollListener = scrollHandler((e) => {
  639. _buildHtml.updateToc(_headingsArray, e)
  640. // Only do this update for normal scrolls and not during clicks.
  641. !_options.disableTocScrollSync && !isClick && (0,_update_toc_scroll_js__WEBPACK_IMPORTED_MODULE_4__["default"])(_options)
  642. if (_options.enableUrlHashUpdateOnScroll && hasInitialized) {
  643. const enableUpdatingHash = _buildHtml.getCurrentlyHighlighting()
  644. enableUpdatingHash && _buildHtml.updateUrlHashForHeader(_headingsArray)
  645. }
  646. const isTop = e?.target?.scrollingElement?.scrollTop === 0
  647. if ((e && (e.eventPhase === 0 || e.currentTarget === null)) || isTop) {
  648. _buildHtml.updateToc(_headingsArray)
  649. _options.scrollEndCallback?.(e)
  650. }
  651. }, scrollHandlerTimeout)
  652. // Fire it initially to setup the page.
  653. if (!hasInitialized) {
  654. _scrollListener()
  655. hasInitialized = true
  656. }
  657. // Fire scroll listener on hash change to trigger highlighting changes too.
  658. window.onhashchange = window.onscrollend = (e) => {
  659. _scrollListener(e)
  660. }
  661. if (
  662. _options.scrollContainer &&
  663. document.querySelector(_options.scrollContainer)
  664. ) {
  665. document
  666. .querySelector(_options.scrollContainer)
  667. .addEventListener("scroll", _scrollListener, false)
  668. document
  669. .querySelector(_options.scrollContainer)
  670. .addEventListener("resize", _scrollListener, false)
  671. } else {
  672. document.addEventListener("scroll", _scrollListener, false)
  673. document.addEventListener("resize", _scrollListener, false)
  674. }
  675. // Bind click listeners to disable animation.
  676. let timeout = null
  677. clickListener = throttle((event) => {
  678. isClick = true
  679. if (_options.scrollSmooth) {
  680. _buildHtml.disableTocAnimation(event)
  681. }
  682. _buildHtml.updateToc(_headingsArray, event)
  683. // Timeout to re-enable the animation.
  684. timeout && clearTimeout(timeout)
  685. timeout = setTimeout(() => {
  686. _buildHtml.enableTocAnimation()
  687. }, _options.scrollSmoothDuration)
  688. // Set is click w/ a bit of delay so that animations can finish
  689. // and we don't disturb the user while they click the toc.
  690. setTimeout(() => {
  691. isClick = false
  692. }, _options.scrollSmoothDuration + 100)
  693. }, _options.throttleTimeout)
  694. if (
  695. _options.scrollContainer &&
  696. document.querySelector(_options.scrollContainer)
  697. ) {
  698. document
  699. .querySelector(_options.scrollContainer)
  700. .addEventListener("click", clickListener, false)
  701. } else {
  702. document.addEventListener("click", clickListener, false)
  703. }
  704. }
  705. /**
  706. * Destroy tocbot.
  707. */
  708. function destroy() {
  709. const tocElement = getTocElement(_options)
  710. if (tocElement === null) {
  711. return
  712. }
  713. if (!_options.skipRendering) {
  714. // Clear HTML.
  715. if (tocElement) {
  716. tocElement.innerHTML = ""
  717. }
  718. }
  719. // Remove event listeners.
  720. if (
  721. _options.scrollContainer &&
  722. document.querySelector(_options.scrollContainer)
  723. ) {
  724. document
  725. .querySelector(_options.scrollContainer)
  726. .removeEventListener("scroll", _scrollListener, false)
  727. document
  728. .querySelector(_options.scrollContainer)
  729. .removeEventListener("resize", _scrollListener, false)
  730. if (_buildHtml) {
  731. document
  732. .querySelector(_options.scrollContainer)
  733. .removeEventListener("click", clickListener, false)
  734. }
  735. } else {
  736. document.removeEventListener("scroll", _scrollListener, false)
  737. document.removeEventListener("resize", _scrollListener, false)
  738. if (_buildHtml) {
  739. document.removeEventListener("click", clickListener, false)
  740. }
  741. }
  742. }
  743. /**
  744. * Refresh tocbot.
  745. */
  746. function refresh(customOptions) {
  747. destroy()
  748. init(customOptions || _options)
  749. }
  750. // From: https://github.com/Raynos/xtend
  751. const hasOwnProp = Object.prototype.hasOwnProperty
  752. function extend(...args) {
  753. const target = {}
  754. for (let i = 0; i < args.length; i++) {
  755. const source = args[i]
  756. for (const key in source) {
  757. if (hasOwnProp.call(source, key)) {
  758. target[key] = source[key]
  759. }
  760. }
  761. }
  762. return target
  763. }
  764. // From: https://remysharp.com/2010/07/21/throttling-function-calls
  765. function throttle(fn, threshold, scope) {
  766. threshold || (threshold = 250)
  767. let last
  768. let deferTimer
  769. return function (...args) {
  770. const context = scope || this
  771. const now = +new Date()
  772. if (last && now < last + threshold) {
  773. // hold on to it
  774. clearTimeout(deferTimer)
  775. deferTimer = setTimeout(() => {
  776. last = now
  777. fn.apply(context, args)
  778. }, threshold)
  779. } else {
  780. last = now
  781. fn.apply(context, args)
  782. }
  783. }
  784. }
  785. /**
  786. * Creates a debounced function that delays invoking `func` until after `wait` milliseconds
  787. * have elapsed since the last time the debounced function was invoked.
  788. *
  789. * @param {Function} func - The function to debounce.
  790. * @param {number} wait - The number of milliseconds to delay.
  791. * @returns {Function} - Returns the new debounced function.
  792. */
  793. function debounce(func, wait) {
  794. let timeout
  795. return (...args) => {
  796. clearTimeout(timeout)
  797. timeout = setTimeout(() => func.apply(this, args), wait)
  798. }
  799. }
  800. /**
  801. * Creates a scroll handler with specified timeout strategy
  802. * @param {number} timeout - Delay duration in milliseconds
  803. * @param {'debounce'|'throttle'|'auto'} type - Strategy type for scroll handling
  804. * @returns {Function} Configured scroll handler function
  805. */
  806. function getScrollHandler(func, timeout, type = "auto") {
  807. switch (type) {
  808. case "debounce":
  809. return debounce(func, timeout)
  810. case "throttle":
  811. return throttle(func, timeout)
  812. default:
  813. return timeout < 334 ? debounce(func, timeout) : throttle(func, timeout)
  814. }
  815. }
  816. function getContentElement(options) {
  817. try {
  818. return (
  819. options.contentElement || document.querySelector(options.contentSelector)
  820. )
  821. } catch (e) {
  822. console.warn(`Contents element not found: ${options.contentSelector}`) // eslint-disable-line
  823. return null
  824. }
  825. }
  826. function getTocElement(options) {
  827. try {
  828. return options.tocElement || document.querySelector(options.tocSelector)
  829. } catch (e) {
  830. console.warn(`TOC element not found: ${options.tocSelector}`) // eslint-disable-line
  831. return null
  832. }
  833. }
  834. // Add default export for easier use.
  835. const tocbot = {
  836. _options,
  837. _buildHtml,
  838. _parseContent,
  839. init,
  840. destroy,
  841. refresh,
  842. }
  843. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (tocbot);
  844. /***/ }),
  845. /***/ "./src/js/parse-content.js":
  846. /*!*********************************!*\
  847. !*** ./src/js/parse-content.js ***!
  848. \*********************************/
  849. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  850. __webpack_require__.r(__webpack_exports__);
  851. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  852. /* harmony export */ "default": () => (/* binding */ parseContent)
  853. /* harmony export */ });
  854. /**
  855. * This file is responsible for parsing the content from the DOM and making
  856. * sure data is nested properly.
  857. *
  858. * @author Tim Scanlin
  859. */
  860. function parseContent(options) {
  861. const reduce = [].reduce
  862. /**
  863. * Get the last item in an array and return a reference to it.
  864. * @param {Array} array
  865. * @return {Object}
  866. */
  867. function getLastItem(array) {
  868. return array[array.length - 1]
  869. }
  870. /**
  871. * Get heading level for a heading dom node.
  872. * @param {HTMLElement} heading
  873. * @return {Number}
  874. */
  875. function getHeadingLevel(heading) {
  876. return +heading.nodeName.toUpperCase().replace("H", "")
  877. }
  878. /**
  879. * Determine whether the object is an HTML Element.
  880. * Also works inside iframes. HTML Elements might be created by the parent document.
  881. * @param {Object} maybeElement
  882. * @return {Number}
  883. */
  884. function isHTMLElement(maybeElement) {
  885. try {
  886. return (
  887. maybeElement instanceof window.HTMLElement ||
  888. maybeElement instanceof window.parent.HTMLElement
  889. )
  890. } catch (e) {
  891. return maybeElement instanceof window.HTMLElement
  892. }
  893. }
  894. /**
  895. * Get important properties from a heading element and store in a plain object.
  896. * @param {HTMLElement} heading
  897. * @return {Object}
  898. */
  899. function getHeadingObject(heading) {
  900. // each node is processed twice by this method because nestHeadingsArray() and addNode() calls it
  901. // first time heading is real DOM node element, second time it is obj
  902. // that is causing problem so I am processing only original DOM node
  903. if (!isHTMLElement(heading)) return heading
  904. if (
  905. options.ignoreHiddenElements &&
  906. (!heading.offsetHeight || !heading.offsetParent)
  907. ) {
  908. return null
  909. }
  910. const headingLabel =
  911. heading.getAttribute("data-heading-label") ||
  912. (options.headingLabelCallback
  913. ? String(options.headingLabelCallback(heading.innerText))
  914. : (heading.innerText || heading.textContent).trim())
  915. const obj = {
  916. id: heading.id,
  917. children: [],
  918. nodeName: heading.nodeName,
  919. headingLevel: getHeadingLevel(heading),
  920. textContent: headingLabel,
  921. }
  922. if (options.includeHtml) {
  923. obj.childNodes = heading.childNodes
  924. }
  925. if (options.headingObjectCallback) {
  926. return options.headingObjectCallback(obj, heading)
  927. }
  928. return obj
  929. }
  930. /**
  931. * Add a node to the nested array.
  932. * @param {Object} node
  933. * @param {Array} nest
  934. * @return {Array}
  935. */
  936. function addNode(node, nest) {
  937. const obj = getHeadingObject(node)
  938. const level = obj.headingLevel
  939. let array = nest
  940. let lastItem = getLastItem(array)
  941. const lastItemLevel = lastItem ? lastItem.headingLevel : 0
  942. let counter = level - lastItemLevel
  943. while (counter > 0) {
  944. lastItem = getLastItem(array)
  945. // Handle case where there are multiple h5+ in a row.
  946. if (lastItem && level === lastItem.headingLevel) {
  947. break
  948. } else if (lastItem && lastItem.children !== undefined) {
  949. array = lastItem.children
  950. }
  951. counter--
  952. }
  953. if (level >= options.collapseDepth) {
  954. obj.isCollapsed = true
  955. }
  956. array.push(obj)
  957. return array
  958. }
  959. /**
  960. * Select headings in content area, exclude any selector in options.ignoreSelector
  961. * @param {HTMLElement} contentElement
  962. * @param {Array} headingSelector
  963. * @return {Array}
  964. */
  965. function selectHeadings(contentElement, headingSelector) {
  966. let selectors = headingSelector
  967. if (options.ignoreSelector) {
  968. selectors = headingSelector
  969. .split(",")
  970. .map(function mapSelectors(selector) {
  971. return `${selector.trim()}:not(${options.ignoreSelector})`
  972. })
  973. }
  974. try {
  975. return contentElement.querySelectorAll(selectors)
  976. } catch (e) {
  977. console.warn(`Headers not found with selector: ${selectors}`) // eslint-disable-line
  978. return null
  979. }
  980. }
  981. /**
  982. * Nest headings array into nested arrays with 'children' property.
  983. * @param {Array} headingsArray
  984. * @return {Object}
  985. */
  986. function nestHeadingsArray(headingsArray) {
  987. return reduce.call(
  988. headingsArray,
  989. function reducer(prev, curr) {
  990. const currentHeading = getHeadingObject(curr)
  991. if (currentHeading) {
  992. addNode(currentHeading, prev.nest)
  993. }
  994. return prev
  995. },
  996. {
  997. nest: [],
  998. },
  999. )
  1000. }
  1001. return {
  1002. nestHeadingsArray,
  1003. selectHeadings,
  1004. }
  1005. }
  1006. /***/ }),
  1007. /***/ "./src/js/scroll-smooth/index.js":
  1008. /*!***************************************!*\
  1009. !*** ./src/js/scroll-smooth/index.js ***!
  1010. \***************************************/
  1011. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  1012. __webpack_require__.r(__webpack_exports__);
  1013. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  1014. /* harmony export */ "default": () => (/* binding */ initSmoothScrolling)
  1015. /* harmony export */ });
  1016. /* eslint no-var: off */
  1017. /* globals location, requestAnimationFrame */
  1018. function initSmoothScrolling(options) {
  1019. // if (isCssSmoothSCrollSupported()) { return }
  1020. var duration = options.duration
  1021. var offset = options.offset
  1022. if (typeof window === "undefined" || typeof location === "undefined") return
  1023. var pageUrl = location.hash ? stripHash(location.href) : location.href
  1024. delegatedLinkHijacking()
  1025. function delegatedLinkHijacking() {
  1026. document.body.addEventListener("click", onClick, false)
  1027. function onClick(e) {
  1028. if (
  1029. !isInPageLink(e.target) ||
  1030. e.target.className.indexOf("no-smooth-scroll") > -1 ||
  1031. (e.target.href.charAt(e.target.href.length - 2) === "#" &&
  1032. e.target.href.charAt(e.target.href.length - 1) === "!") ||
  1033. e.target.className.indexOf(options.linkClass) === -1
  1034. ) {
  1035. return
  1036. }
  1037. // Don't prevent default or hash doesn't change.
  1038. // e.preventDefault()
  1039. jump(e.target.hash, {
  1040. duration,
  1041. offset,
  1042. callback: function () {
  1043. setFocus(e.target.hash)
  1044. },
  1045. })
  1046. }
  1047. }
  1048. function isInPageLink(n) {
  1049. return (
  1050. n.tagName.toLowerCase() === "a" &&
  1051. (n.hash.length > 0 || n.href.charAt(n.href.length - 1) === "#") &&
  1052. (stripHash(n.href) === pageUrl || stripHash(n.href) + "#" === pageUrl)
  1053. )
  1054. }
  1055. function stripHash(url) {
  1056. return url.slice(0, url.lastIndexOf("#"))
  1057. }
  1058. // function isCssSmoothSCrollSupported () {
  1059. // return 'scrollBehavior' in document.documentElement.style
  1060. // }
  1061. // Adapted from:
  1062. // https://www.nczonline.net/blog/2013/01/15/fixing-skip-to-content-links/
  1063. function setFocus(hash) {
  1064. var element = document.getElementById(hash.substring(1))
  1065. if (element) {
  1066. if (!/^(?:a|select|input|button|textarea)$/i.test(element.tagName)) {
  1067. element.tabIndex = -1
  1068. }
  1069. element.focus()
  1070. }
  1071. }
  1072. }
  1073. function jump(target, options) {
  1074. var start = window.pageYOffset
  1075. var opt = {
  1076. duration: options.duration,
  1077. offset: options.offset || 0,
  1078. callback: options.callback,
  1079. easing: options.easing || easeInOutQuad,
  1080. }
  1081. // This makes ids that start with a number work: ('[id="' + decodeURI(target).split('#').join('') + '"]')
  1082. // DecodeURI for nonASCII hashes, they was encoded, but id was not encoded, it lead to not finding the tgt element by id.
  1083. // And this is for IE: document.body.scrollTop
  1084. // Handle decoded and non-decoded URIs since sometimes URLs automatically transform them (support for internation chars).
  1085. var tgt =
  1086. document.querySelector(
  1087. '[id="' + decodeURI(target).split("#").join("") + '"]',
  1088. ) || document.querySelector('[id="' + target.split("#").join("") + '"]')
  1089. var distance =
  1090. typeof target === "string"
  1091. ? opt.offset +
  1092. (target
  1093. ? (tgt && tgt.getBoundingClientRect().top) || 0 // handle non-existent links better.
  1094. : -(document.documentElement.scrollTop || document.body.scrollTop))
  1095. : target
  1096. var duration =
  1097. typeof opt.duration === "function" ? opt.duration(distance) : opt.duration
  1098. var timeStart
  1099. var timeElapsed
  1100. requestAnimationFrame(function (time) {
  1101. timeStart = time
  1102. loop(time)
  1103. })
  1104. function loop(time) {
  1105. timeElapsed = time - timeStart
  1106. window.scrollTo(0, opt.easing(timeElapsed, start, distance, duration))
  1107. if (timeElapsed < duration) {
  1108. requestAnimationFrame(loop)
  1109. } else {
  1110. end()
  1111. }
  1112. }
  1113. function end() {
  1114. window.scrollTo(0, start + distance)
  1115. if (typeof opt.callback === "function") {
  1116. opt.callback()
  1117. }
  1118. }
  1119. // Robert Penner's easeInOutQuad - http://robertpenner.com/easing/
  1120. function easeInOutQuad(t, b, c, d) {
  1121. t /= d / 2
  1122. if (t < 1) return (c / 2) * t * t + b
  1123. t--
  1124. return (-c / 2) * (t * (t - 2) - 1) + b
  1125. }
  1126. }
  1127. /***/ }),
  1128. /***/ "./src/js/update-toc-scroll.js":
  1129. /*!*************************************!*\
  1130. !*** ./src/js/update-toc-scroll.js ***!
  1131. \*************************************/
  1132. /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
  1133. __webpack_require__.r(__webpack_exports__);
  1134. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  1135. /* harmony export */ "default": () => (/* binding */ updateTocScroll)
  1136. /* harmony export */ });
  1137. function updateTocScroll(options) {
  1138. const toc =
  1139. options.tocScrollingWrapper ||
  1140. options.tocElement ||
  1141. document.querySelector(options.tocSelector)
  1142. if (toc && toc.scrollHeight > toc.clientHeight) {
  1143. const activeItem = toc.querySelector(`.${options.activeListItemClass}`)
  1144. if (activeItem) {
  1145. // Determine element top and bottom
  1146. const eTop = activeItem.offsetTop
  1147. // Check if out of view
  1148. // Above scroll view
  1149. const scrollAmount = eTop - options.tocScrollOffset
  1150. toc.scrollTop = scrollAmount > 0 ? scrollAmount : 0
  1151. }
  1152. }
  1153. }
  1154. /***/ })
  1155. /******/ });
  1156. /************************************************************************/
  1157. /******/ // The module cache
  1158. /******/ var __webpack_module_cache__ = {};
  1159. /******/
  1160. /******/ // The require function
  1161. /******/ function __webpack_require__(moduleId) {
  1162. /******/ // Check if module is in cache
  1163. /******/ var cachedModule = __webpack_module_cache__[moduleId];
  1164. /******/ if (cachedModule !== undefined) {
  1165. /******/ return cachedModule.exports;
  1166. /******/ }
  1167. /******/ // Create a new module (and put it into the cache)
  1168. /******/ var module = __webpack_module_cache__[moduleId] = {
  1169. /******/ // no module.id needed
  1170. /******/ // no module.loaded needed
  1171. /******/ exports: {}
  1172. /******/ };
  1173. /******/
  1174. /******/ // Execute the module function
  1175. /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
  1176. /******/
  1177. /******/ // Return the exports of the module
  1178. /******/ return module.exports;
  1179. /******/ }
  1180. /******/
  1181. /************************************************************************/
  1182. /******/ /* webpack/runtime/define property getters */
  1183. /******/ (() => {
  1184. /******/ // define getter functions for harmony exports
  1185. /******/ __webpack_require__.d = (exports, definition) => {
  1186. /******/ for(var key in definition) {
  1187. /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  1188. /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  1189. /******/ }
  1190. /******/ }
  1191. /******/ };
  1192. /******/ })();
  1193. /******/
  1194. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  1195. /******/ (() => {
  1196. /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  1197. /******/ })();
  1198. /******/
  1199. /******/ /* webpack/runtime/make namespace object */
  1200. /******/ (() => {
  1201. /******/ // define __esModule on exports
  1202. /******/ __webpack_require__.r = (exports) => {
  1203. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  1204. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  1205. /******/ }
  1206. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  1207. /******/ };
  1208. /******/ })();
  1209. /******/
  1210. /************************************************************************/
  1211. var __webpack_exports__ = {};
  1212. // This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
  1213. (() => {
  1214. /*!******************************!*\
  1215. !*** ./src/js/index-dist.js ***!
  1216. \******************************/
  1217. __webpack_require__.r(__webpack_exports__);
  1218. /* harmony import */ var _index_esm_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./index-esm.js */ "./src/js/index-esm.js");
  1219. /* globals define */
  1220. ((root, factory) => {
  1221. if (typeof define === "function" && define.amd) {
  1222. define([], factory(root))
  1223. } else if (typeof exports === "object" && !(exports instanceof HTMLElement)) {
  1224. module.exports = factory(root)
  1225. } else {
  1226. root.tocbot = factory(root)
  1227. }
  1228. })(
  1229. typeof global !== "undefined" && !(global instanceof HTMLElement)
  1230. ? global
  1231. : window || global,
  1232. (root) => {
  1233. // Just return if its not a browser.
  1234. const supports =
  1235. !!root &&
  1236. !!root.document &&
  1237. !!root.document.querySelector &&
  1238. !!root.addEventListener // Feature test
  1239. if (typeof window === "undefined" && !supports) {
  1240. return
  1241. }
  1242. // Make tocbot available globally.
  1243. root.tocbot = _index_esm_js__WEBPACK_IMPORTED_MODULE_0__
  1244. return _index_esm_js__WEBPACK_IMPORTED_MODULE_0__
  1245. },
  1246. )
  1247. })();
  1248. /******/ })()
  1249. ;
  1250. //# sourceMappingURL=main.js.map