easy-toc
Version:
Lightweight Vanilla JS Table of Contents
2 lines (1 loc) • 3.6 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).easy_toc=t()}(this,(function(){"use strict";var e=document;return function(){function t(t,i){var n;this._defaults={include:["h1","h2","h3","h4","h5","h6"],exclude:["[data-no-toc]"],prefix:"easy_toc_",hierarchical:!0,anchor_tagname:"div",anchor_class:"anchor"},this.append_to_el=null!==t&&"string"==typeof t?(n=t,e.querySelector(n)):t,t||(this.append_to_el=e.body),this.settings=this._merge_settings(this._defaults,i||{}),this._includeStr=this.settings.include.join(","),this._excludeStr=this.settings.exclude.join(","),this._found_selectors={},this._toc_list_element=null,this._is_rendered=!1}return t.prototype._merge_settings=function(){for(var e=[],t=0;t<arguments.length;t++)e[t]=arguments[t];var i={};return Array.prototype.forEach.call(e,(function(e){for(var t in e){if(!Object.prototype.hasOwnProperty.call(e,t))return;i[t]=e[t]}})),i},t.prototype._get_nodes=function(){var t,i=this,n=(t=this._includeStr,e.querySelectorAll(t));return this.settings.exclude.length>0&&(n=Array.prototype.slice.call(n).filter((function(e){if(!0!==(e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector).call(e,i._excludeStr))return e}))),n},t.prototype._build_node_obj=function(){var e=this,t={},i={};return Array.prototype.forEach.call(this._get_nodes(),(function(n,r){var s;if(e.settings.hierarchical){var l=void 0;s=null!==(l=/h\d/i.exec(n.tagName))?parseInt(l[0].substr(1,1)):null}else s=null;var o=e._slugify(n.textContent,0,i);i[r]=o,t[r]={el:n,heading_level:s,className:e.settings.prefix+e.settings.anchor_class,id:e.settings.prefix+o}})),t},t.prototype._slugify=function(e,t,i){var n=e.trim().toLowerCase().split(" ").join("-").replace(/[!@#$%^&*():]/gi,"").replace(/\//gi,"-");return Object.values(i).indexOf(n)>-1&&(t++,n=this._slugify(e+" "+t,t,i)),n},t.prototype._wrap=function(e,t){e.parentNode.insertBefore(t,e),t.appendChild(e)},t.prototype._unwrap=function(e){var t=e.parentElement;t.insertAdjacentElement("afterend",e),t.parentNode.removeChild(t)},t.prototype._render=function(){var t=this,i=Object.values(this._found_selectors),n=this.settings.hierarchical?"ol":"ul",r=e.createElement(n);r.className=this.settings.prefix+"list",this._toc_list_element=r,this.append_to_el.appendChild(r);var s=null,l=r,o=1;Array.prototype.forEach.call(i,(function(i){var a=e.createElement(t.settings.anchor_tagname);a.classList.add(i.className),a.id=i.id,t._wrap(i.el,a);var c=e.createElement("li");if(c.className=t.settings.prefix+"list-item",t.settings.hierarchical&&null!==s&&s<i.heading_level){var h=e.createElement(n);h.setAttribute("data-level",o.toString()),l.appendChild(h),o++,(l=h).appendChild(c)}else t.settings.hierarchical&&null!==s&&s==i.heading_level?l.appendChild(c):(l=r,r.appendChild(c));var d=e.createElement("a");d.className=t.settings.prefix+"list-item_link",d.href="#"+i.id,d.setAttribute("data-heading_level",i.heading_level.toString()),d.innerText=i.el.textContent,c.appendChild(d),s=i.heading_level})),this._is_rendered=!0},t.prototype.init=function(){this.destroy(),this._found_selectors=this._build_node_obj(),this._render()},t.prototype.update=function(){this.init()},t.prototype.destroy=function(){var e=this;if(!1!==this._is_rendered){var t=Object.values(this._found_selectors);Array.prototype.forEach.call(t,(function(t){e._unwrap(t.el)})),this._toc_list_element.parentNode.removeChild(this._toc_list_element)}this._found_selectors={},this._is_rendered=!1},t}()}));