diff --git a/_layouts/default.html b/_layouts/default.html
index 2ca41b4..dfcbb6c 100644
--- a/_layouts/default.html
+++ b/_layouts/default.html
@@ -36,11 +36,6 @@
media="screen"
charset="utf-8"
/>
-
diff --git a/bootstrap-toc.js b/bootstrap-toc.js
index 534f100..14b1109 100644
--- a/bootstrap-toc.js
+++ b/bootstrap-toc.js
@@ -2,24 +2,40 @@
* Bootstrap Table of Contents v<%= version %> (http://afeld.github.io/bootstrap-toc/)
* Copyright 2015 Aidan Feldman
* Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */
-(function($) {
+(function() {
"use strict";
window.Toc = {
helpers: {
// return all matching elements in the set, or their descendants
- findOrFilter: function($el, selector) {
- // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/
- // http://stackoverflow.com/a/12731439/358804
- var $descendants = $el.find(selector);
- return $el
- .filter(selector)
- .add($descendants)
- .filter(":not([data-toc-skip])");
+ findOrFilter: function(el, selector) {
+ var parent = el.parentElement || el;
+ var descendants = parent.querySelectorAll(selector);
+ var arr = [];
+
+ for (var i = 0; i < descendants.length; i++) {
+ var descendent = descendants[i];
+ if (
+ descendent === el ||
+ (descendent.parentElement !== el.parentElement &&
+ descendent.getAttribute("data-toc-skip") === null)
+ ) {
+ arr.push(descendent);
+ }
+ }
+
+ return arr.filter(function(item) {
+ if (item === el) return true;
+ while (item !== null) {
+ if (item.parentElement === el) return true;
+ item = item.parentElement;
+ }
+ return false;
+ });
},
generateUniqueIdBase: function(el) {
- var text = $(el).text();
+ var text = el.textContent;
// adapted from
// https://github.com/bryanbraun/anchorjs/blob/65fede08d0e4a705f72f1e7e6284f643d5ad3cf3/anchor.js#L237-L257
@@ -68,36 +84,39 @@
},
createNavList: function() {
- return $('
');
+ var ul = document.createElement("ul");
+ ul.classList.add("nav", "navbar-nav");
+ return ul;
},
- createChildNavList: function($parent) {
- var $childList = this.createNavList();
- $parent.append($childList);
- return $childList;
+ createChildNavList: function(parent) {
+ var childList = this.createNavList();
+ parent.appendChild(childList);
+ return childList;
},
generateNavEl: function(anchor, text) {
- var $a = $('');
- $a.attr("href", "#" + anchor);
- $a.text(text);
- var $li = $("");
- $li.append($a);
- return $li;
+ var a = document.createElement("a");
+ a.classList.add("nav-link");
+ a.setAttribute("href", "#" + anchor);
+ a.innerText = text;
+ var li = document.createElement("li");
+ li.appendChild(a);
+ return li;
},
generateNavItem: function(headingEl) {
var anchor = this.generateAnchor(headingEl);
- var $heading = $(headingEl);
- var text = $heading.data("toc-text") || $heading.text();
+ var text =
+ headingEl.getAttribute("data-toc-text") || headingEl.textContent;
return this.generateNavEl(anchor, text);
},
// Find the first heading level (``, then ``, etc.) that has more than one element. Defaults to 1 (for ``).
- getTopLevel: function($scope) {
+ getTopLevel: function(scope) {
for (var i = 1; i <= 6; i++) {
- var $headings = this.findOrFilter($scope, "h" + i);
- if ($headings.length > 1) {
+ var headings = this.findOrFilter(scope, "h" + i);
+ if (headings.length > 1) {
return i;
}
}
@@ -106,75 +125,83 @@
},
// returns the elements for the top level, and the next below it
- getHeadings: function($scope, topLevel) {
+ getHeadings: function(scope, topLevel) {
var topSelector = "h" + topLevel;
var secondaryLevel = topLevel + 1;
var secondarySelector = "h" + secondaryLevel;
- return this.findOrFilter($scope, topSelector + "," + secondarySelector);
+ return this.findOrFilter(scope, topSelector + "," + secondarySelector);
},
getNavLevel: function(el) {
return parseInt(el.tagName.charAt(1), 10);
},
- populateNav: function($topContext, topLevel, $headings) {
- var $context = $topContext;
- var $prevNav;
+ populateNav: function(topContext, topLevel, headings) {
+ var context = topContext;
+ var prevNav;
var helpers = this;
- $headings.each(function(i, el) {
- var $newNav = helpers.generateNavItem(el);
+ headings.forEach(function(el) {
+ var newNav = helpers.generateNavItem(el);
var navLevel = helpers.getNavLevel(el);
- // determine the proper $context
+ // determine the proper context
if (navLevel === topLevel) {
// use top level
- $context = $topContext;
- } else if ($prevNav && $context === $topContext) {
+ context = topContext;
+ } else if (prevNav && context === topContext) {
// create a new level of the tree and switch to it
- $context = helpers.createChildNavList($prevNav);
- } // else use the current $context
+ context = helpers.createChildNavList(prevNav);
+ } // else use the current context
- $context.append($newNav);
+ context.appendChild(newNav);
- $prevNav = $newNav;
+ prevNav = newNav;
});
},
parseOps: function(arg) {
var opts;
- if (arg.jquery) {
+ if (arg instanceof Element) {
opts = {
- $nav: arg
+ nav: arg
};
} else {
opts = arg;
}
- opts.$scope = opts.$scope || $(document.body);
+ opts.scope = opts.scope || document.body;
return opts;
}
},
- // accepts a jQuery object, or an options object
+ // accepts an Element object, or an options object
init: function(opts) {
opts = this.helpers.parseOps(opts);
// ensure that the data attribute is in place for styling
- opts.$nav.attr("data-toggle", "toc");
+ opts.nav.setAttribute("data-toggle", "toc");
- var $topContext = this.helpers.createChildNavList(opts.$nav);
- var topLevel = this.helpers.getTopLevel(opts.$scope);
- var $headings = this.helpers.getHeadings(opts.$scope, topLevel);
- this.helpers.populateNav($topContext, topLevel, $headings);
+ var topContext = this.helpers.createChildNavList(opts.nav);
+ var topLevel = this.helpers.getTopLevel(opts.scope);
+ var headings = this.helpers.getHeadings(opts.scope, topLevel);
+ this.helpers.populateNav(topContext, topLevel, headings);
}
};
- $(function() {
- $('nav[data-toggle="toc"]').each(function(i, el) {
- var $nav = $(el);
- Toc.init($nav);
- });
+ function ready(fn) {
+ if (document.readyState !== "loading") {
+ fn();
+ } else {
+ document.addEventListener("DOMContentLoaded", fn);
+ }
+ }
+
+ ready(function() {
+ var navs = document.querySelectorAll('nav[data-toggle="toc"]');
+ for (var i = 0; i < navs.length; i++) {
+ Toc.init(navs[i]);
+ }
});
-})(jQuery);
+})();
diff --git a/package-lock.json b/package-lock.json
index aa6f8fd..ea66b8a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1624,7 +1624,6 @@
"minipass": {
"version": "2.2.4",
"bundled": true,
- "optional": true,
"requires": {
"safe-buffer": "^5.1.1",
"yallist": "^3.0.0"
@@ -1800,8 +1799,7 @@
},
"safe-buffer": {
"version": "5.1.1",
- "bundled": true,
- "optional": true
+ "bundled": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -1879,8 +1877,7 @@
},
"yallist": {
"version": "3.0.2",
- "bundled": true,
- "optional": true
+ "bundled": true
}
}
},
@@ -2718,11 +2715,6 @@
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
- "jquery": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz",
- "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ=="
- },
"jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
diff --git a/package.json b/package.json
index 0ba8718..3953b4c 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,6 @@
"gulp-rename": "^1.4.0",
"gulp-template": "^5.0.0",
"gulp-uglify": "^3.0.1",
- "jquery": "^3.5.0",
"jshint": "^2.9.1-rc1",
"mocha": "^5.2.0"
}
diff --git a/test/index.html b/test/index.html
index 398a0f6..74eca62 100644
--- a/test/index.html
+++ b/test/index.html
@@ -8,7 +8,6 @@
foo
-
@@ -19,7 +18,6 @@