From db5a2d9be8e9e13652de2b175c5a26d4aa2a47b6 Mon Sep 17 00:00:00 2001 From: Yaohaixiao Date: Sat, 5 Aug 2023 16:31:40 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20afterScroll=20?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E5=8F=82=E6=95=B0=EF=BC=8C=E5=9C=A8=E6=BB=9A?= =?UTF-8?q?=E5=8A=A8=E7=BB=93=E6=9D=9F=E5=90=8E=E8=A7=A6=E5=8F=91=E7=9A=84?= =?UTF-8?q?=E5=9B=9E=E8=B0=83=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- anchors.min.js | 2 +- anchors.min.js.map | 2 +- api/pug/fixed.pug | 3 ++ api/pug/methods.pug | 2 ++ api/pug/options/afterScroll.pug | 52 +++++++++++++++++++++++++++++++++ api/pug/options/section.pug | 1 + chapters.min.js | 2 +- chapters.min.js.map | 2 +- docs/fixed.html | 30 ++++++++++++++++++- docs/flex.html | 27 ++++++++++++++++- docs/index.html | 29 ++++++++++++++++-- docs/js/outline.min.js | 2 +- docs/js/outline.min.js.map | 2 +- docs/sticky.html | 27 ++++++++++++++++- outline.min.js | 2 +- outline.min.js.map | 2 +- package.json | 2 +- src/anchors.js | 2 +- src/chapters.js | 2 +- src/outline.js | 22 ++++++++++++-- 20 files changed, 196 insertions(+), 19 deletions(-) create mode 100644 api/pug/options/afterScroll.pug diff --git a/anchors.min.js b/anchors.min.js index 0ecb635a..630cb823 100644 --- a/anchors.min.js +++ b/anchors.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Anchors=e()}(this,(function(){"use strict";const t=t=>"string"==typeof t,e=(t,e)=>{const r=Object.prototype.hasOwnProperty;return t&&r.call(t,e)},r=t=>Object.prototype.toString.apply(t),s=t=>"function"==typeof t||"[object Function]"===r(t),n=t=>("[object Object]"===r(t)||"object"==typeof t||s(t))&&null!==t;class i{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(r,s){const i=this.attrs;return t(r)?s&&e(i,r)?(i[r]=s,this):i[r]:n(r)?(o=i,l=r,Object.keys(l).forEach((t=>{e(l,t)&&(o[t]=l[t])})),this):0===arguments.length?i:this;var o,l}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const o=t=>!!(n(t)&&t.nodeName&&t.tagName&&1===t.nodeType),l=t=>t*t,c=(e=null)=>{let r,s;return e?t(e)?s=document.querySelector(e):o(e)&&(s=e):(r=document.querySelectorAll("html,body"),s=r[0].scrollTop-r[1].scrollTop>=0?r[0]:r[1]),s},a=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=a(t.offsetParent)),e},h=(t,e="")=>{const r=e.replace(/^>/i,"");return!!(e&&r&&t)&&(t.matches?t.matches(r):!!t.msMatchesSelector&&t.msMatchesSelector(r))},d=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,u=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],p=(t,e,r)=>{const s=u.indexOf(e)>-1;r._delegateListener&&delete(r=r._delegateListener)._delegateListener,function(t,e,r){const s=t._listeners;let n=-1;if(s.length<1)return!1;s.forEach(((t,s)=>{const i=t.fn;e===t.type&&(n=s,i===r&&(n=s))})),n>-1&&s.splice(n,1)}(t,e,r),t.removeEventListener(e,r,s)},m=function(e,r,s=!1){const n=t(e)?document.querySelector(e):e,i=n.childNodes,l=((e,r)=>{let s=e._listeners||[];return t(r)&&r&&(s=s.filter((t=>t.type===r))),s})(n,r);l.forEach((t=>{p(n,t.type,t.fn)})),(s||!0===r||1===arguments.length)&&n&&i&&i.forEach((t=>{o(t)&&m(t,r,s)}))},f=(t,e,r)=>{if(!s(r))return m(t,e);p(t,e,r)},y=(t,e,r,s,n,i,o=!1)=>{const l=u.indexOf(r)>-1,c=function(l){const a=function(t){const e=t.target;return(r=e)&&3===r.nodeType?r.parentNode:r;var r}(l),u=((t,e,r,s)=>{const n=r||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||s&&t===n)return t;if(t===n)break}while(t=d(t))})(a,e,t);let p=i||t;l.delegateTarget=u,!0===i&&(p=n),u&&(!0===o&&f(t,r,c),s.call(p,l,n))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:r,fn:c,data:n,context:i,capture:l}),s._delegateListener=c,t.addEventListener(r,c,l)},g={},b=t=>e(g,t)&&g[t].length>0,v=(t,e=!0)=>e?b(t):(t=>{let e=b(t),r=t.lastIndexOf(".");for(;!e&&-1!==r;)r=(t=t.substring(0,r)).lastIndexOf("."),e=b(t);return e})(t),A=(t,e,s=!0)=>{const n=t=>{if(!b(t))return!1;g[t].forEach((t=>{const s=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(r(e))>-1?e.toString():e;t.callback.call(t.context||t,s)}))},i=()=>{let e=t,r=t.lastIndexOf(".");for(;-1!==r;)e=e.substring(0,r),r=e.lastIndexOf("."),n(e);n(t),n("*")};if(!v(t))return!1;s?setTimeout(i,10):i()},E=t=>Array.isArray?Array.isArray(t):"[object Array]"===r(t),L=e=>!!t(e)&&e.replace(/^\s+|\s+$/g,""),$=t=>{return!(!n(t)||!(o(t)||(t=>!(!n(t)||"[object NodeList]"!==r(t)))(t)||(e=t,n(e)&&"[object DocumentFragment]"===r(e))||(t=>!(!n(t)||!("[object Text]"===r(t)||t.tagName&&3===t.nodeType)))(t)));var e},T=(t,e,r)=>{let s=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=r;break;case"value":"input"===s||"textarea"===s?t.value=r:t.setAttribute(e,r);break;case"className":t.className=r;break;default:t.setAttribute(e,r)}},M=(r,s,i)=>{const o="outline-heading",l=i.hasAnchor||!0,c=i.isAtStart||!0,a=i.showCode||!1,h=i.chapterCode||"",d=i.anchorURL||"",u=`heading-${s}`,p={id:u,className:c?`${o} ${o}_start`:o,"data-id":s},m=Object.keys(p),f=L(r.innerHTML);let y,g;if(m.forEach((t=>{T(r,t,p[t])})),a&&(r.innerHTML=h+" "+f),!l)return!1;g=((t,e=0,r="",s="outline")=>{const n=s?`xlink:href="#${s}-icon-${t}"`:`xlink:href="#icon-${t}"`,i=E(e)?e[0]:e,o=E(e)?e[1]:e,l=e?`width:${i}px;height:${o}px;`:"",c=``,a=document.createElement("i");return a.className="outline-icon",a.innerHTML=c,a})("hash"),y=((r,s,i)=>{const o=document.createDocumentFragment(),l=document.createElement(r),c=e=>$(e)||t(e),a=e=>{let r;if(!c(e))return!1;$(e)?r=e:t(e)&&(r=document.createTextNode(e)),o.appendChild(r)};return n(s)?Object.keys(s).forEach((t=>{e(s,t)&&T(l,t,s[t])})):E(s)&&s.every((t=>c(t)))&&s.forEach((t=>{a(t)})),E(i)?i.forEach((t=>{a(t)})):a(i),l.appendChild(o),l})("a",{id:`anchor-${s}`,className:`${o}__anchor anchor-${s}`,href:d||`#${u}`,target:d?"_blank":"self","data-id":s},[g]),r.appendChild(y)},x=(t,e)=>{let r,s=t.className;if(!s||!((t,e)=>{const r=new RegExp("(\\s|^)"+e+"(\\s|$)");let s,n;return!!o(t)&&(s=t.className,!!s&&(n=t.classList,n?.contains?t.classList.contains(e):!!s.match(r)))})(t,e))return!1;r=t.classList,r?.remove?r.remove(e):(s=L(s.replace(e,"")),t.className=s)},z=(e,r=!0,s=!0)=>{const n="outline-heading",i=e.innerHTML;let o;if(e.innerHTML=i.replace(/^\d+(?:(\.?\d*)*\s?)?/gi,""),e.removeAttribute("id"),e.removeAttribute("data-id"),x(e,n),!r)return!1;var l;o=e.querySelector(`.${n}__anchor`),s&&x(e,`${n}_start`),l=L(e.className),t(l)&&""===l&&e.removeAttribute("class"),e.removeChild(o)},j=(e,r=!0)=>{const s=[];let n=1,i=0;return e.forEach(((e,r)=>{const o=e.tagName.replace(/h/i,"");let l=parseInt(o,10),c=-1;var a;l>n?(i+=1,c=1===i?-1:r-1):l===n||li?1===l?(i=1,c=-1):c=s[r-1].pid:l<=i&&(1===l?i=1:(i-=n-l,i<=1&&(i=1)),c=1===i?-1:((t,e,r)=>{let s,n,i=t[r-1];for(n=0;n]+(>|$)/g,""):"")})})),r?(t=>{const e={};return t.forEach((t=>{const r=JSON.stringify((t=>[t.pid])(t));e[r]=e[r]||[],e[r].push(t),t.index=e[r].length,-1===t.pid&&(t.code=String(t.index))})),Object.keys(e).forEach((r=>{e[r].forEach(((e,r)=>{e.index=r+1,t.forEach((t=>{t.pid===e.id&&(t.code=e.code+"."+t.index)}))}))})),t})(s):s};class S extends i{constructor(t){super(),this.attrs=S.DEFAULTS,this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],t&&this.initialize(t)}initialize(e){let r,n,i,l,a;return this.attr(e),a=this.attr("articleElement"),n=this.attr("scrollElement"),i=this.attr("selector"),r=this.attr("created"),t(a)?l=document.querySelector(a):o(a)&&(l=a),l?(this.$articleElement=l,this.$scrollElement=c(n),this.$headings=[...l.querySelectorAll(i)],this.$headings.length<1||(this.chapters=j(this.$headings),s(r)&&r.call(this),this.render().addListeners()),this):this}getChapters(t=!1){const e=this.chapters;return t?((t,e,r)=>{const s={},n=[];return t.forEach(((t,r)=>{s[t[e]]=r,t.children=[]})),t.forEach((e=>{const i=t[s[e[r]]];-1!==e[r]?i.children.push(e):n.push(e)})),n})(e,"id","pid"):e}count(){return this.chapters.length}render(){const t=this.attr("mounted"),e=this.attr("hasAnchor"),r=this.attr("isAtStart"),n=this.attr("showCode"),i=this.attr("anchorURL"),o=this.$headings,l=this.getChapters();return((t=[])=>{const e=['','','','','','','',''],r=E(t)&&t.length>0?e.concat(t):e,s=document.body;let n=document.querySelector("#svg-sprites");n?n.innerHTML=r.join(""):(n=document.createElement("div"),n.innerHTML=``,s.insertBefore(n.firstChild,s.firstChild))})(),o.forEach(((t,s)=>{const o=l[s].code;M(t,s,{hasAnchor:e,isAtStart:r,showCode:n,chapterCode:o,anchorURL:i})})),s(t)&&t.call(this),this}scrollTo(t,e){return((t,e,r)=>{const n=c(t);let i=n.scrollTop,o=0;const a=e-i,h=n.scrollHeight,d=e-h<=0?e:h,u=t=>(s(r)&&r(t),!1),p=()=>{if(o+=1,a<0){if(i-=l(o),n.scrollTop=i,i<=e)return n.scrollTop=e,u(e)}else if(i+=l(o),n.scrollTop=i,i>=d)return n.scrollTop=d,u(d);requestAnimationFrame(p)};requestAnimationFrame(p)})(this.$scrollElement,t,e),this}destroy(){const t=this.attr("hasAnchor"),e=this.attr("isAtStart"),r=this.attr("beforeDestroy"),n=this.attr("afterDestroy"),i=this.$headings;return s(r)&&r.call(this),this.removeListeners(),i.forEach((r=>{z(r,t,e)})),this.attr(S.DEFAULTS),this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],s(n)&&n.call(this),this}onAnchorTrigger(t){const e=this.attr("anchorURL"),r=this.attr("afterScroll"),n=this.attr("stickyHeight"),i=t.delegateTarget.parentNode,o=a(i)-(n+10),l=this.$scrollElement,c=l.scrollHeight-l.clientHeight;return this.scrollTo(o,(()=>{s(r)&&r.call(this),((t,e=300)=>{!!s(t)&&setTimeout((()=>{t()}),e)})((()=>{A("toolbar:update",{top:o,min:0,max:c})}))})),e||function(t){t.stopPropagation(),t.preventDefault()}(t),this}addListeners(){const t=this.$articleElement;return y(t,".outline-heading__anchor","click",this.onAnchorTrigger,this,!0),this}removeListeners(){const t=this.$articleElement;return f(t,"click",this.onAnchorTrigger),this}}return S.DEFAULTS={scrollElement:"html,body",articleElement:"#article",selector:"h1,h2,h3,h4,h5,h6",stickyHeight:0,anchorURL:"",hasAnchor:!0,isAtStart:!0,showCode:!1,created:null,mounted:null,afterScroll:null,beforeDestroy:null,afterDestroy:null},S})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Anchors=e()}(this,(function(){"use strict";const t=t=>"string"==typeof t,e=(t,e)=>{const r=Object.prototype.hasOwnProperty;return t&&r.call(t,e)},r=t=>Object.prototype.toString.apply(t),s=t=>"function"==typeof t||"[object Function]"===r(t),n=t=>("[object Object]"===r(t)||"object"==typeof t||s(t))&&null!==t;class i{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(r,s){const i=this.attrs;return t(r)?s&&e(i,r)?(i[r]=s,this):i[r]:n(r)?(o=i,c=r,Object.keys(c).forEach((t=>{e(c,t)&&(o[t]=c[t])})),this):0===arguments.length?i:this;var o,c}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const o=t=>!!(n(t)&&t.nodeName&&t.tagName&&1===t.nodeType),c=t=>t*t,l=(e=null)=>{let r,s;return e?t(e)?s=document.querySelector(e):o(e)&&(s=e):(r=document.querySelectorAll("html,body"),s=r[0].scrollTop-r[1].scrollTop>=0?r[0]:r[1]),s},a=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=a(t.offsetParent)),e},h=(t,e="")=>{const r=e.replace(/^>/i,"");return!!(e&&r&&t)&&(t.matches?t.matches(r):!!t.msMatchesSelector&&t.msMatchesSelector(r))},d=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,u=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],p=(t,e,r)=>{const s=u.indexOf(e)>-1;r._delegateListener&&delete(r=r._delegateListener)._delegateListener,function(t,e,r){const s=t._listeners;let n=-1;if(s.length<1)return!1;s.forEach(((t,s)=>{const i=t.fn;e===t.type&&(n=s,i===r&&(n=s))})),n>-1&&s.splice(n,1)}(t,e,r),t.removeEventListener(e,r,s)},m=function(e,r,s=!1){const n=t(e)?document.querySelector(e):e,i=n.childNodes,c=((e,r)=>{let s=e._listeners||[];return t(r)&&r&&(s=s.filter((t=>t.type===r))),s})(n,r);c.forEach((t=>{p(n,t.type,t.fn)})),(s||!0===r||1===arguments.length)&&n&&i&&i.forEach((t=>{o(t)&&m(t,r,s)}))},f=(t,e,r)=>{if(!s(r))return m(t,e);p(t,e,r)},y=(t,e,r,s,n,i,o=!1)=>{const c=u.indexOf(r)>-1,l=function(c){const a=function(t){const e=t.target;return(r=e)&&3===r.nodeType?r.parentNode:r;var r}(c),u=((t,e,r,s)=>{const n=r||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===n&&h(t,e):h(t,e))||s&&t===n)return t;if(t===n)break}while(t=d(t))})(a,e,t);let p=i||t;c.delegateTarget=u,!0===i&&(p=n),u&&(!0===o&&f(t,r,l),s.call(p,c,n))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:r,fn:l,data:n,context:i,capture:c}),s._delegateListener=l,t.addEventListener(r,l,c)},g={},b=t=>e(g,t)&&g[t].length>0,v=(t,e=!0)=>e?b(t):(t=>{let e=b(t),r=t.lastIndexOf(".");for(;!e&&-1!==r;)r=(t=t.substring(0,r)).lastIndexOf("."),e=b(t);return e})(t),A=(t,e,s=!0)=>{const n=t=>{if(!b(t))return!1;g[t].forEach((t=>{const s=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(r(e))>-1?e.toString():e;t.callback.call(t.context||t,s)}))},i=()=>{let e=t,r=t.lastIndexOf(".");for(;-1!==r;)e=e.substring(0,r),r=e.lastIndexOf("."),n(e);n(t),n("*")};if(!v(t))return!1;s?setTimeout(i,10):i()},E=t=>Array.isArray?Array.isArray(t):"[object Array]"===r(t),L=e=>!!t(e)&&e.replace(/^\s+|\s+$/g,""),$=t=>{return!(!n(t)||!(o(t)||(t=>!(!n(t)||"[object NodeList]"!==r(t)))(t)||(e=t,n(e)&&"[object DocumentFragment]"===r(e))||(t=>!(!n(t)||!("[object Text]"===r(t)||t.tagName&&3===t.nodeType)))(t)));var e},T=(t,e,r)=>{let s=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=r;break;case"value":"input"===s||"textarea"===s?t.value=r:t.setAttribute(e,r);break;case"className":t.className=r;break;default:t.setAttribute(e,r)}},M=(r,s,i)=>{const o="outline-heading",c=i.hasAnchor||!0,l=i.isAtStart||!0,a=i.showCode||!1,h=i.chapterCode||"",d=i.anchorURL||"",u=`heading-${s}`,p={id:u,className:l?`${o} ${o}_start`:o,"data-id":s},m=Object.keys(p),f=L(r.innerHTML);let y,g;if(m.forEach((t=>{T(r,t,p[t])})),a&&(r.innerHTML=h+" "+f),!c)return!1;g=((t,e=0,r="",s="outline")=>{const n=s?`xlink:href="#${s}-icon-${t}"`:`xlink:href="#icon-${t}"`,i=E(e)?e[0]:e,o=E(e)?e[1]:e,c=e?`width:${i}px;height:${o}px;`:"",l=``,a=document.createElement("i");return a.className="outline-icon",a.innerHTML=l,a})("hash"),y=((r,s,i)=>{const o=document.createDocumentFragment(),c=document.createElement(r),l=e=>$(e)||t(e),a=e=>{let r;if(!l(e))return!1;$(e)?r=e:t(e)&&(r=document.createTextNode(e)),o.appendChild(r)};return n(s)?Object.keys(s).forEach((t=>{e(s,t)&&T(c,t,s[t])})):E(s)&&s.every((t=>l(t)))&&s.forEach((t=>{a(t)})),E(i)?i.forEach((t=>{a(t)})):a(i),c.appendChild(o),c})("a",{id:`anchor-${s}`,className:`${o}__anchor anchor-${s}`,href:d||`#${u}`,target:d?"_blank":"self","data-id":s},[g]),r.appendChild(y)},x=(t,e)=>{let r,s=t.className;if(!s||!((t,e)=>{const r=new RegExp("(\\s|^)"+e+"(\\s|$)");let s,n;return!!o(t)&&(s=t.className,!!s&&(n=t.classList,n?.contains?t.classList.contains(e):!!s.match(r)))})(t,e))return!1;r=t.classList,r?.remove?r.remove(e):(s=L(s.replace(e,"")),t.className=s)},z=(e,r=!0,s=!0)=>{const n="outline-heading",i=e.innerHTML;let o;if(e.innerHTML=i.replace(/^\d+(?:(\.?\d*)*\s?)?/gi,""),e.removeAttribute("id"),e.removeAttribute("data-id"),x(e,n),!r)return!1;var c;o=e.querySelector(`.${n}__anchor`),s&&x(e,`${n}_start`),c=L(e.className),t(c)&&""===c&&e.removeAttribute("class"),e.removeChild(o)},j=(e,r=!0)=>{const s=[];let n=1,i=0;return e.forEach(((e,r)=>{const o=e.tagName.replace(/h/i,"");let c=parseInt(o,10),l=-1;var a;c>n?(i+=1,l=1===i?-1:r-1):c===n||ci?1===c?(i=1,l=-1):l=s[r-1].pid:c<=i&&(1===c?i=1:(i-=n-c,i<=1&&(i=1)),l=1===i?-1:((t,e,r)=>{let s,n,i=t[r-1];for(n=0;n]+(>|$)/g,""):"")})})),r?(t=>{const e={};return t.forEach((t=>{const r=JSON.stringify((t=>[t.pid])(t));e[r]=e[r]||[],e[r].push(t),t.index=e[r].length,-1===t.pid&&(t.code=String(t.index))})),Object.keys(e).forEach((r=>{e[r].forEach(((e,r)=>{e.index=r+1,t.forEach((t=>{t.pid===e.id&&(t.code=e.code+"."+t.index)}))}))})),t})(s):s};class S extends i{constructor(t){super(),this.attrs=S.DEFAULTS,this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],t&&this.initialize(t)}initialize(e){let r,n,i,c,a;return this.attr(e),a=this.attr("articleElement"),n=this.attr("scrollElement"),i=this.attr("selector"),r=this.attr("created"),t(a)?c=document.querySelector(a):o(a)&&(c=a),c?(this.$articleElement=c,this.$scrollElement=l(n),this.$headings=[...c.querySelectorAll(i)],this.$headings.length<1||(this.chapters=j(this.$headings),s(r)&&r.call(this),this.render().addListeners()),this):this}getChapters(t=!1){const e=this.chapters;return t?((t,e,r)=>{const s={},n=[];return t.forEach(((t,r)=>{s[t[e]]=r,t.children=[]})),t.forEach((e=>{const i=t[s[e[r]]];-1!==e[r]?i.children.push(e):n.push(e)})),n})(e,"id","pid"):e}count(){return this.chapters.length}render(){const t=this.attr("mounted"),e=this.attr("hasAnchor"),r=this.attr("isAtStart"),n=this.attr("showCode"),i=this.attr("anchorURL"),o=this.$headings,c=this.getChapters();return((t=[])=>{const e=['','','','','','','',''],r=E(t)&&t.length>0?e.concat(t):e,s=document.body;let n=document.querySelector("#svg-sprites");n?n.innerHTML=r.join(""):(n=document.createElement("div"),n.innerHTML=``,s.insertBefore(n.firstChild,s.firstChild))})(),o.forEach(((t,s)=>{const o=c[s].code;M(t,s,{hasAnchor:e,isAtStart:r,showCode:n,chapterCode:o,anchorURL:i})})),s(t)&&t.call(this),this}scrollTo(t,e){return((t,e,r)=>{const n=l(t);let i=n.scrollTop,o=0;const a=e-i,h=n.scrollHeight,d=e-h<=0?e:h,u=t=>(s(r)&&r(t),!1),p=()=>{if(o+=1,a<0){if(i-=c(o),n.scrollTop=i,i<=e)return n.scrollTop=e,u(e)}else if(i+=c(o),n.scrollTop=i,i>=d)return n.scrollTop=d,u(d);requestAnimationFrame(p)};requestAnimationFrame(p)})(this.$scrollElement,t,e),this}destroy(){const t=this.attr("hasAnchor"),e=this.attr("isAtStart"),r=this.attr("beforeDestroy"),n=this.attr("afterDestroy"),i=this.$headings;return s(r)&&r.call(this),this.removeListeners(),i.forEach((r=>{z(r,t,e)})),this.attr(S.DEFAULTS),this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],s(n)&&n.call(this),this}onAnchorTrigger(t){const e=this.attr("anchorURL"),r=this.attr("afterScroll"),n=this.attr("stickyHeight"),i=t.delegateTarget.parentNode,o=a(i)-(n+10),c=this.$scrollElement,l=c.scrollHeight-c.clientHeight;return this.scrollTo(o,(()=>{s(r)&&r.call(this,"anchor"),((t,e=300)=>{!!s(t)&&setTimeout((()=>{t()}),e)})((()=>{A("toolbar:update",{top:o,min:0,max:l})}))})),e||function(t){t.stopPropagation(),t.preventDefault()}(t),this}addListeners(){const t=this.$articleElement;return y(t,".outline-heading__anchor","click",this.onAnchorTrigger,this,!0),this}removeListeners(){const t=this.$articleElement;return f(t,"click",this.onAnchorTrigger),this}}return S.DEFAULTS={scrollElement:"html,body",articleElement:"#article",selector:"h1,h2,h3,h4,h5,h6",stickyHeight:0,anchorURL:"",hasAnchor:!0,isAtStart:!0,showCode:!1,created:null,mounted:null,afterScroll:null,beforeDestroy:null,afterDestroy:null},S})); //# sourceMappingURL=anchors.min.js.map diff --git a/anchors.min.js.map b/anchors.min.js.map index 4d7909cd..f18b2e11 100644 --- a/anchors.min.js.map +++ b/anchors.min.js.map @@ -1 +1 @@ -{"version":3,"file":"anchors.min.js","sources":["src/utils/types/isString.js","src/utils/lang/hasOwn.js","src/utils/lang/toString.js","src/utils/types/isFunction.js","src/utils/types/isObject.js","src/base.js","src/utils/lang/extend.js","src/utils/types/isElement.js","src/utils/lang/easeInQuad.js","src/utils/dom/_getScrollElement.js","src/utils/dom/offsetTop.js","src/utils/dom/matches.js","src/utils/dom/getParentOrHost.js","src/utils/event/enum.js","src/utils/event/_off.js","src/utils/event/_delete.js","src/utils/event/purgeElement.js","src/utils/event/getListeners.js","src/utils/event/off.js","src/utils/event/on.js","src/utils/event/getTarget.js","src/utils/dom/resolveTextNode.js","src/utils/dom/closest.js","src/utils/observer/_subscribers.js","src/utils/observer/_hasDirectSubscribersFor.js","src/utils/observer/has.js","src/utils/observer/_hasSubscribers.js","src/utils/observer/emit.js","src/utils/types/isTypedArray.js","src/utils/types/isArray.js","src/utils/lang/trim.js","src/utils/types/isDOM.js","src/utils/types/isHTMLCollection.js","src/utils/types/isFragment.js","src/utils/types/isTextNode.js","src/utils/dom/setAttribute.js","src/_updateHeading.js","src/utils/icons.js","src/utils/dom/createElement.js","src/utils/dom/removeClass.js","src/utils/dom/hasClass.js","src/_resetHeading.js","src/utils/types/isEmpty.js","src/getChapters.js","src/utils/lang/stripTags.js","src/_getChapterParentIdByDiffer.js","src/_getChaptersWithCode.js","src/anchors.js","src/utils/lang/toTree.js","src/utils/dom/scrollTo.js","src/utils/lang/later.js","src/utils/event/stop.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n return purgeElement(el, type)\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector[0] === '>'\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","import trim from './utils/lang/trim'\r\nimport createElement from './utils/dom/createElement'\r\nimport setAttribute from './utils/dom/setAttribute'\r\n\r\nimport { createSvgIcon } from './utils/icons'\r\n\r\nconst _updateHeading = ($heading, i, options) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const hasAnchor = options.hasAnchor || true\r\n const isAtStart = options.isAtStart || true\r\n const showCode = options.showCode || false\r\n const chapterCode = options.chapterCode || ''\r\n const anchorURL = options.anchorURL || ''\r\n const headingId = `heading-${i}`\r\n const attrs = {\r\n id: headingId,\r\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\r\n 'data-id': i\r\n }\r\n const keys = Object.keys(attrs)\r\n const text = trim($heading.innerHTML)\r\n let $anchor\r\n let $icon\r\n\r\n keys.forEach((prop) => {\r\n setAttribute($heading, prop, attrs[prop])\r\n })\r\n\r\n if (showCode) {\r\n $heading.innerHTML = chapterCode + ' ' + text\r\n }\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $icon = createSvgIcon('hash')\r\n $anchor = createElement(\r\n 'a',\r\n {\r\n id: `anchor-${i}`,\r\n className: `${CLS_HEADING}__anchor anchor-${i}`,\r\n href: anchorURL ? anchorURL : `#${headingId}`,\r\n target: anchorURL ? '_blank' : 'self',\r\n 'data-id': i\r\n },\r\n [$icon]\r\n )\r\n $heading.appendChild($anchor)\r\n}\r\n\r\nexport default _updateHeading\r\n","import isArray from './types/isArray'\r\n\r\n/**\r\n * 绘制 SVG Sprites 图标集\r\n * ========================================================================\r\n * @method paintSvgSprites\r\n * @param {Array} [symbols] - (可选)symbols 图标数组\r\n * 传递 symbols - 绘制 symbols + SYMBOLS 的图标集\r\n * 不传递 symbols - 仅绘制默认 SYMBOLS 图标集\r\n */\r\nexport const paintSvgSprites = (symbols = []) => {\r\n const SYMBOLS = [\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n ''\r\n ]\r\n const sprites =\r\n isArray(symbols) && symbols.length > 0 ? SYMBOLS.concat(symbols) : SYMBOLS\r\n const $body = document.body\r\n let $icons = document.querySelector('#svg-sprites')\r\n\r\n if ($icons) {\r\n $icons.innerHTML = sprites.join('')\r\n } else {\r\n $icons = document.createElement('div')\r\n $icons.innerHTML =\r\n ``\r\n $body.insertBefore($icons.firstChild, $body.firstChild)\r\n }\r\n}\r\n\r\n/**\r\n * 创建 SVG 图标 DOM 元素\r\n * ========================================================================\r\n * @method createSvgIcon\r\n * @param {String} name\r\n * @param {Number|String|Array} [size]\r\n * @param {String} [color]\r\n * @param {String} [iconSet]\r\n * @returns {HTMLElement}\r\n */\r\nexport const createSvgIcon = (\r\n name,\r\n size = 0,\r\n color = '',\r\n iconSet = 'outline'\r\n) => {\r\n const binds = iconSet\r\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\r\n : `xlink:href=\"#icon-${name}\"`\r\n const width = isArray(size) ? size[0] : size\r\n const height = isArray(size) ? size[1] : size\r\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\r\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\r\n const svg =\r\n `` +\r\n `` +\r\n ``\r\n const $icon = document.createElement('i')\r\n\r\n $icon.className = 'outline-icon'\r\n $icon.innerHTML = svg\r\n\r\n return $icon\r\n}\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import removeClass from './utils/dom/removeClass'\r\nimport isEmpty from './utils/types/isEmpty'\r\nimport trim from './utils/lang/trim'\r\n\r\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const text = $heading.innerHTML\r\n let $anchor\r\n\r\n $heading.innerHTML = text.replace(/^\\d+(?:(\\.?\\d*)*\\s?)?/gi, '')\r\n $heading.removeAttribute('id')\r\n $heading.removeAttribute('data-id')\r\n\r\n removeClass($heading, CLS_HEADING)\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\r\n\r\n if (isAtStart) {\r\n removeClass($heading, `${CLS_HEADING}_start`)\r\n }\r\n\r\n if (isEmpty(trim($heading.className))) {\r\n $heading.removeAttribute('class')\r\n }\r\n\r\n $heading.removeChild($anchor)\r\n}\r\n\r\nexport default _resetHeading\r\n","import isString from './isString'\r\n/**\r\n * 检测数据是否为空字符串\r\n * ========================================================================\r\n * @method isEmpty\r\n * @param {String} str\r\n * @returns {boolean}\r\n */\r\nconst isEmpty = (str) => {\r\n return isString(str) && str === ''\r\n}\r\n\r\nexport default isEmpty\r\n","import trim from './utils/lang/trim'\r\nimport stripTags from './utils/lang/stripTags'\r\n\r\nimport _getChaptersWithCode from './_getChaptersWithCode'\r\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\r\n\r\nconst getChapters = (headings, showCode = true) => {\r\n const chapters = []\r\n let previous = 1\r\n let level = 0\r\n\r\n headings.forEach((heading, i) => {\r\n const headingLevel = heading.tagName.replace(/h/i, '')\r\n let current = parseInt(headingLevel, 10)\r\n let pid = -1\r\n\r\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\r\n // h2 (前一个标题)\r\n // h3 (当前标题)\r\n if (current > previous) {\r\n level += 1\r\n\r\n // 第一层级的 pid 是 -1\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n pid = i - 1\r\n }\r\n }\r\n // 当前标题的(标题标签)序号 = 前一个标题的序号\r\n // h2 (前一个标题)\r\n // h2 (当前标题)\r\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\r\n // h2\r\n // h4 (前一个标题)\r\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\r\n else if (current === previous || (current < previous && current > level)) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n pid = -1\r\n } else {\r\n pid = chapters[i - 1].pid\r\n }\r\n } else if (current <= level) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n } else {\r\n level = level - (previous - current)\r\n\r\n if (level <= 1) {\r\n level = 1\r\n }\r\n }\r\n\r\n // 第一级的标题\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\r\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\r\n }\r\n }\r\n\r\n previous = current\r\n\r\n chapters.push({\r\n id: i,\r\n pid: pid,\r\n level: level,\r\n rel: `heading-${i}`,\r\n text: stripTags(trim(heading.innerHTML))\r\n })\r\n })\r\n\r\n return showCode ? _getChaptersWithCode(chapters) : chapters\r\n}\r\n\r\nexport default getChapters\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 过滤所有 HTML 标签\r\n * ========================================================================\r\n * @method stripTags\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nconst stripTags = (str) => {\r\n if (!isString(str)) {\r\n return ''\r\n }\r\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\r\n}\r\n\r\nexport default stripTags\r\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\r\n let previous = chapters[index - 1]\r\n let pid\r\n let i\r\n\r\n for (i = 0; i < differ; i += 1) {\r\n pid = previous.pid\r\n previous = chapters[pid]\r\n }\r\n\r\n pid = previous.pid\r\n\r\n return pid\r\n}\r\n\r\nexport default _getChapterParentIdByDiffer\r\n","const _getChaptersWithCode = (chapters) => {\r\n const groups = {}\r\n const cb = (o) => {\r\n return [o.pid]\r\n }\r\n\r\n chapters.forEach((o) => {\r\n const group = JSON.stringify(cb(o))\r\n\r\n groups[group] = groups[group] || []\r\n groups[group].push(o)\r\n\r\n o.index = groups[group].length\r\n if (o.pid === -1) {\r\n o.code = String(o.index)\r\n }\r\n })\r\n\r\n Object.keys(groups).forEach((group) => {\r\n groups[group].forEach((c, i) => {\r\n c.index = i + 1\r\n chapters.forEach((o) => {\r\n if (o.pid === c.id) {\r\n o.code = c.code + '.' + o.index\r\n }\r\n })\r\n })\r\n })\r\n\r\n return chapters\r\n}\r\n\r\nexport default _getChaptersWithCode\r\n","import Base from './base'\r\n\r\n// 在文章的标题生成 anchor 链接\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport toTree from './utils/lang/toTree'\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _updateHeading from './_updateHeading'\r\nimport _resetHeading from './_resetHeading'\r\nimport getChapters from './getChapters'\r\n\r\nclass Anchors extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Anchors.DEFAULTS\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n\r\n this.chapters = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let scrollElement\r\n let selector\r\n let $articleElement\r\n let articleElement\r\n\r\n this.attr(options)\r\n articleElement = this.attr('articleElement')\r\n scrollElement = this.attr('scrollElement')\r\n selector = this.attr('selector')\r\n created = this.attr('created')\r\n\r\n if (isString(articleElement)) {\r\n $articleElement = document.querySelector(articleElement)\r\n } else if (isElement(articleElement)) {\r\n $articleElement = articleElement\r\n }\r\n\r\n if (!$articleElement) {\r\n return this\r\n }\r\n\r\n this.$articleElement = $articleElement\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n this.$headings = [...$articleElement.querySelectorAll(selector)]\r\n\r\n if (this.$headings.length < 1) {\r\n return this\r\n }\r\n\r\n this.chapters = getChapters(this.$headings)\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n const chapters = this.chapters\r\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const $headings = this.$headings\r\n const chapters = this.getChapters()\r\n\r\n paintSvgSprites()\r\n\r\n $headings.forEach(($heading, i) => {\r\n const chapterCode = chapters[i].code\r\n _updateHeading($heading, i, {\r\n hasAnchor,\r\n isAtStart,\r\n showCode,\r\n chapterCode,\r\n anchorURL\r\n })\r\n })\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n const $headings = this.$headings\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n $headings.forEach(($heading) => {\r\n _resetHeading($heading, hasAnchor, isAtStart)\r\n })\r\n\r\n this.attr(Anchors.DEFAULTS)\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n this.chapters = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onAnchorTrigger(evt) {\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const $heading = $anchor.parentNode\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const $scrollElement = this.$scrollElement\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this)\r\n }\r\n\r\n later(() => {\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.scrollTo(top, after)\r\n\r\n if (!anchorURL) {\r\n stop(evt)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n on(\r\n $articleElement,\r\n '.outline-heading__anchor',\r\n 'click',\r\n this.onAnchorTrigger,\r\n this,\r\n true\r\n )\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n off($articleElement, 'click', this.onAnchorTrigger)\r\n\r\n return this\r\n }\r\n}\r\n\r\nAnchors.DEFAULTS = {\r\n scrollElement: 'html,body',\r\n articleElement: '#article',\r\n selector: 'h1,h2,h3,h4,h5,h6',\r\n stickyHeight: 0,\r\n anchorURL: '',\r\n hasAnchor: true,\r\n isAtStart: true,\r\n showCode: false,\r\n created: null,\r\n mounted: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Anchors\r\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n requestAnimationFrame(play)\r\n }\r\n\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n *
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","offsetTop","el","top","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","fn","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","off","on","data","context","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","closest","overrideContext","push","addEventListener","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","setTimeout","isArray","Array","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","className","_updateHeading","$heading","CLS_HEADING","hasAnchor","isAtStart","showCode","chapterCode","anchorURL","headingId","id","text","innerHTML","$anchor","$icon","name","size","color","iconSet","binds","width","height","defaultRules","svg","createElement","createSvgIcon","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","href","removeClass","classList","allClass","pattern","RegExp","contains","match","hasClass","remove","_resetHeading","removeAttribute","removeChild","getChapters","headings","chapters","previous","level","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","rel","groups","group","JSON","stringify","cb","code","String","c","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","symbols","SYMBOLS","sprites","concat","$body","body","$icons","join","insertBefore","firstChild","paintSvgSprites","scrollTo","after","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","delay","later","publish","min","stopPropagation","preventDefault"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"anchors.min.js","sources":["src/utils/types/isString.js","src/utils/lang/hasOwn.js","src/utils/lang/toString.js","src/utils/types/isFunction.js","src/utils/types/isObject.js","src/base.js","src/utils/lang/extend.js","src/utils/types/isElement.js","src/utils/lang/easeInQuad.js","src/utils/dom/_getScrollElement.js","src/utils/dom/offsetTop.js","src/utils/dom/matches.js","src/utils/dom/getParentOrHost.js","src/utils/event/enum.js","src/utils/event/_off.js","src/utils/event/_delete.js","src/utils/event/purgeElement.js","src/utils/event/getListeners.js","src/utils/event/off.js","src/utils/event/on.js","src/utils/event/getTarget.js","src/utils/dom/resolveTextNode.js","src/utils/dom/closest.js","src/utils/observer/_subscribers.js","src/utils/observer/_hasDirectSubscribersFor.js","src/utils/observer/has.js","src/utils/observer/_hasSubscribers.js","src/utils/observer/emit.js","src/utils/types/isTypedArray.js","src/utils/types/isArray.js","src/utils/lang/trim.js","src/utils/types/isDOM.js","src/utils/types/isHTMLCollection.js","src/utils/types/isFragment.js","src/utils/types/isTextNode.js","src/utils/dom/setAttribute.js","src/_updateHeading.js","src/utils/icons.js","src/utils/dom/createElement.js","src/utils/dom/removeClass.js","src/utils/dom/hasClass.js","src/_resetHeading.js","src/utils/types/isEmpty.js","src/getChapters.js","src/utils/lang/stripTags.js","src/_getChapterParentIdByDiffer.js","src/_getChaptersWithCode.js","src/anchors.js","src/utils/lang/toTree.js","src/utils/dom/scrollTo.js","src/utils/lang/later.js","src/utils/event/stop.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n return purgeElement(el, type)\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector[0] === '>'\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","import trim from './utils/lang/trim'\r\nimport createElement from './utils/dom/createElement'\r\nimport setAttribute from './utils/dom/setAttribute'\r\n\r\nimport { createSvgIcon } from './utils/icons'\r\n\r\nconst _updateHeading = ($heading, i, options) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const hasAnchor = options.hasAnchor || true\r\n const isAtStart = options.isAtStart || true\r\n const showCode = options.showCode || false\r\n const chapterCode = options.chapterCode || ''\r\n const anchorURL = options.anchorURL || ''\r\n const headingId = `heading-${i}`\r\n const attrs = {\r\n id: headingId,\r\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\r\n 'data-id': i\r\n }\r\n const keys = Object.keys(attrs)\r\n const text = trim($heading.innerHTML)\r\n let $anchor\r\n let $icon\r\n\r\n keys.forEach((prop) => {\r\n setAttribute($heading, prop, attrs[prop])\r\n })\r\n\r\n if (showCode) {\r\n $heading.innerHTML = chapterCode + ' ' + text\r\n }\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $icon = createSvgIcon('hash')\r\n $anchor = createElement(\r\n 'a',\r\n {\r\n id: `anchor-${i}`,\r\n className: `${CLS_HEADING}__anchor anchor-${i}`,\r\n href: anchorURL ? anchorURL : `#${headingId}`,\r\n target: anchorURL ? '_blank' : 'self',\r\n 'data-id': i\r\n },\r\n [$icon]\r\n )\r\n $heading.appendChild($anchor)\r\n}\r\n\r\nexport default _updateHeading\r\n","import isArray from './types/isArray'\r\n\r\n/**\r\n * 绘制 SVG Sprites 图标集\r\n * ========================================================================\r\n * @method paintSvgSprites\r\n * @param {Array} [symbols] - (可选)symbols 图标数组\r\n * 传递 symbols - 绘制 symbols + SYMBOLS 的图标集\r\n * 不传递 symbols - 仅绘制默认 SYMBOLS 图标集\r\n */\r\nexport const paintSvgSprites = (symbols = []) => {\r\n const SYMBOLS = [\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n ''\r\n ]\r\n const sprites =\r\n isArray(symbols) && symbols.length > 0 ? SYMBOLS.concat(symbols) : SYMBOLS\r\n const $body = document.body\r\n let $icons = document.querySelector('#svg-sprites')\r\n\r\n if ($icons) {\r\n $icons.innerHTML = sprites.join('')\r\n } else {\r\n $icons = document.createElement('div')\r\n $icons.innerHTML =\r\n ``\r\n $body.insertBefore($icons.firstChild, $body.firstChild)\r\n }\r\n}\r\n\r\n/**\r\n * 创建 SVG 图标 DOM 元素\r\n * ========================================================================\r\n * @method createSvgIcon\r\n * @param {String} name\r\n * @param {Number|String|Array} [size]\r\n * @param {String} [color]\r\n * @param {String} [iconSet]\r\n * @returns {HTMLElement}\r\n */\r\nexport const createSvgIcon = (\r\n name,\r\n size = 0,\r\n color = '',\r\n iconSet = 'outline'\r\n) => {\r\n const binds = iconSet\r\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\r\n : `xlink:href=\"#icon-${name}\"`\r\n const width = isArray(size) ? size[0] : size\r\n const height = isArray(size) ? size[1] : size\r\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\r\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\r\n const svg =\r\n `` +\r\n `` +\r\n ``\r\n const $icon = document.createElement('i')\r\n\r\n $icon.className = 'outline-icon'\r\n $icon.innerHTML = svg\r\n\r\n return $icon\r\n}\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import removeClass from './utils/dom/removeClass'\r\nimport isEmpty from './utils/types/isEmpty'\r\nimport trim from './utils/lang/trim'\r\n\r\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const text = $heading.innerHTML\r\n let $anchor\r\n\r\n $heading.innerHTML = text.replace(/^\\d+(?:(\\.?\\d*)*\\s?)?/gi, '')\r\n $heading.removeAttribute('id')\r\n $heading.removeAttribute('data-id')\r\n\r\n removeClass($heading, CLS_HEADING)\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\r\n\r\n if (isAtStart) {\r\n removeClass($heading, `${CLS_HEADING}_start`)\r\n }\r\n\r\n if (isEmpty(trim($heading.className))) {\r\n $heading.removeAttribute('class')\r\n }\r\n\r\n $heading.removeChild($anchor)\r\n}\r\n\r\nexport default _resetHeading\r\n","import isString from './isString'\r\n/**\r\n * 检测数据是否为空字符串\r\n * ========================================================================\r\n * @method isEmpty\r\n * @param {String} str\r\n * @returns {boolean}\r\n */\r\nconst isEmpty = (str) => {\r\n return isString(str) && str === ''\r\n}\r\n\r\nexport default isEmpty\r\n","import trim from './utils/lang/trim'\r\nimport stripTags from './utils/lang/stripTags'\r\n\r\nimport _getChaptersWithCode from './_getChaptersWithCode'\r\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\r\n\r\nconst getChapters = (headings, showCode = true) => {\r\n const chapters = []\r\n let previous = 1\r\n let level = 0\r\n\r\n headings.forEach((heading, i) => {\r\n const headingLevel = heading.tagName.replace(/h/i, '')\r\n let current = parseInt(headingLevel, 10)\r\n let pid = -1\r\n\r\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\r\n // h2 (前一个标题)\r\n // h3 (当前标题)\r\n if (current > previous) {\r\n level += 1\r\n\r\n // 第一层级的 pid 是 -1\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n pid = i - 1\r\n }\r\n }\r\n // 当前标题的(标题标签)序号 = 前一个标题的序号\r\n // h2 (前一个标题)\r\n // h2 (当前标题)\r\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\r\n // h2\r\n // h4 (前一个标题)\r\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\r\n else if (current === previous || (current < previous && current > level)) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n pid = -1\r\n } else {\r\n pid = chapters[i - 1].pid\r\n }\r\n } else if (current <= level) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n } else {\r\n level = level - (previous - current)\r\n\r\n if (level <= 1) {\r\n level = 1\r\n }\r\n }\r\n\r\n // 第一级的标题\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\r\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\r\n }\r\n }\r\n\r\n previous = current\r\n\r\n chapters.push({\r\n id: i,\r\n pid: pid,\r\n level: level,\r\n rel: `heading-${i}`,\r\n text: stripTags(trim(heading.innerHTML))\r\n })\r\n })\r\n\r\n return showCode ? _getChaptersWithCode(chapters) : chapters\r\n}\r\n\r\nexport default getChapters\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 过滤所有 HTML 标签\r\n * ========================================================================\r\n * @method stripTags\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nconst stripTags = (str) => {\r\n if (!isString(str)) {\r\n return ''\r\n }\r\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\r\n}\r\n\r\nexport default stripTags\r\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\r\n let previous = chapters[index - 1]\r\n let pid\r\n let i\r\n\r\n for (i = 0; i < differ; i += 1) {\r\n pid = previous.pid\r\n previous = chapters[pid]\r\n }\r\n\r\n pid = previous.pid\r\n\r\n return pid\r\n}\r\n\r\nexport default _getChapterParentIdByDiffer\r\n","const _getChaptersWithCode = (chapters) => {\r\n const groups = {}\r\n const cb = (o) => {\r\n return [o.pid]\r\n }\r\n\r\n chapters.forEach((o) => {\r\n const group = JSON.stringify(cb(o))\r\n\r\n groups[group] = groups[group] || []\r\n groups[group].push(o)\r\n\r\n o.index = groups[group].length\r\n if (o.pid === -1) {\r\n o.code = String(o.index)\r\n }\r\n })\r\n\r\n Object.keys(groups).forEach((group) => {\r\n groups[group].forEach((c, i) => {\r\n c.index = i + 1\r\n chapters.forEach((o) => {\r\n if (o.pid === c.id) {\r\n o.code = c.code + '.' + o.index\r\n }\r\n })\r\n })\r\n })\r\n\r\n return chapters\r\n}\r\n\r\nexport default _getChaptersWithCode\r\n","import Base from './base'\r\n\r\n// 在文章的标题生成 anchor 链接\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport toTree from './utils/lang/toTree'\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _updateHeading from './_updateHeading'\r\nimport _resetHeading from './_resetHeading'\r\nimport getChapters from './getChapters'\r\n\r\nclass Anchors extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Anchors.DEFAULTS\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n\r\n this.chapters = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let scrollElement\r\n let selector\r\n let $articleElement\r\n let articleElement\r\n\r\n this.attr(options)\r\n articleElement = this.attr('articleElement')\r\n scrollElement = this.attr('scrollElement')\r\n selector = this.attr('selector')\r\n created = this.attr('created')\r\n\r\n if (isString(articleElement)) {\r\n $articleElement = document.querySelector(articleElement)\r\n } else if (isElement(articleElement)) {\r\n $articleElement = articleElement\r\n }\r\n\r\n if (!$articleElement) {\r\n return this\r\n }\r\n\r\n this.$articleElement = $articleElement\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n this.$headings = [...$articleElement.querySelectorAll(selector)]\r\n\r\n if (this.$headings.length < 1) {\r\n return this\r\n }\r\n\r\n this.chapters = getChapters(this.$headings)\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n const chapters = this.chapters\r\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const $headings = this.$headings\r\n const chapters = this.getChapters()\r\n\r\n paintSvgSprites()\r\n\r\n $headings.forEach(($heading, i) => {\r\n const chapterCode = chapters[i].code\r\n _updateHeading($heading, i, {\r\n hasAnchor,\r\n isAtStart,\r\n showCode,\r\n chapterCode,\r\n anchorURL\r\n })\r\n })\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n const $headings = this.$headings\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n $headings.forEach(($heading) => {\r\n _resetHeading($heading, hasAnchor, isAtStart)\r\n })\r\n\r\n this.attr(Anchors.DEFAULTS)\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n this.chapters = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onAnchorTrigger(evt) {\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const $heading = $anchor.parentNode\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const $scrollElement = this.$scrollElement\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'anchor')\r\n }\r\n\r\n later(() => {\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.scrollTo(top, after)\r\n\r\n if (!anchorURL) {\r\n stop(evt)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n on(\r\n $articleElement,\r\n '.outline-heading__anchor',\r\n 'click',\r\n this.onAnchorTrigger,\r\n this,\r\n true\r\n )\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n off($articleElement, 'click', this.onAnchorTrigger)\r\n\r\n return this\r\n }\r\n}\r\n\r\nAnchors.DEFAULTS = {\r\n scrollElement: 'html,body',\r\n articleElement: '#article',\r\n selector: 'h1,h2,h3,h4,h5,h6',\r\n stickyHeight: 0,\r\n anchorURL: '',\r\n hasAnchor: true,\r\n isAtStart: true,\r\n showCode: false,\r\n created: null,\r\n mounted: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Anchors\r\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n requestAnimationFrame(play)\r\n }\r\n\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n *
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","offsetTop","el","top","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","fn","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","off","on","data","context","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","closest","overrideContext","push","addEventListener","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","setTimeout","isArray","Array","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","className","_updateHeading","$heading","CLS_HEADING","hasAnchor","isAtStart","showCode","chapterCode","anchorURL","headingId","id","text","innerHTML","$anchor","$icon","name","size","color","iconSet","binds","width","height","defaultRules","svg","createElement","createSvgIcon","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","href","removeClass","classList","allClass","pattern","RegExp","contains","match","hasClass","remove","_resetHeading","removeAttribute","removeChild","getChapters","headings","chapters","previous","level","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","rel","groups","group","JSON","stringify","cb","code","String","c","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","symbols","SYMBOLS","sprites","concat","$body","body","$icons","join","insertBefore","firstChild","paintSvgSprites","scrollTo","after","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","delay","later","publish","min","stopPropagation","preventDefault"],"mappings":"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"} \ No newline at end of file diff --git a/api/pug/fixed.pug b/api/pug/fixed.pug index 79efaebe..db52b34a 100644 --- a/api/pug/fixed.pug +++ b/api/pug/fixed.pug @@ -58,4 +58,7 @@ html(lang='en') $header.classList.add(HEADER_STICKY) } } + defaults.afterScroll = function(top) { + console.log('top', top) + } outline = new Outline(Outline.DEFAULTS) diff --git a/api/pug/methods.pug b/api/pug/methods.pug index 84a25b95..902ccc18 100644 --- a/api/pug/methods.pug +++ b/api/pug/methods.pug @@ -24,6 +24,8 @@ ul.aside__list a.aside__anchor(href="#option-homepage") homepage li.aside__item a.aside__anchor(href="#option-customClass") customClass + li.aside__item + a.aside__anchor(href="#option-afterScroll") afterScroll li.aside__item a.aside__anchor(href="#option-afterSticky") afterSticky li.aside__item diff --git a/api/pug/options/afterScroll.pug b/api/pug/options/afterScroll.pug new file mode 100644 index 00000000..2ef5806d --- /dev/null +++ b/api/pug/options/afterScroll.pug @@ -0,0 +1,52 @@ +section.section + header.section__header + h3#option-afterScroll.section__h3 afterScroll + div.section__content + h4.section__h4 Description + dl.section__dl + dt.section__dt Type: + dd.section__dd Function + dl.section__dl + dt.section__dt Default: + dd.section__dd null + p 可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。 + h4.section__h4 Parameters + h5.section__h4 target + dl.section__dl + dt.section__dt Type: + dd.section__dd String + p afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称: + ul + li 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors; + li 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters; + li 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar; + li 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar; + p 注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。 + pre.section__pre + code.section__code. + const defaults = Outline.DEFAULTS + let outline + + defaults.position = 'fixed' + defaults.parentElement = '#aside' + defaults.stickyHeight = 86 + defaults.homepage = './index.html' + defaults.afterScroll = function(target) { + // 当然,如果你希望无论是点击什么都执行,就不需要判断了 + // 直接些通用的滚动结束的逻辑即可 + switch(target){ + case 'anchor': + // 针对点击 # 的处理逻辑 + break + case 'chapter': + // 针对点击导航菜单的处理逻辑 + break + case 'up': + // 针对点击向上滚动按钮的处理逻辑 + break + case 'down': + // 针对点击向下滚动按钮的处理逻辑 + break + } + } + outline = new Outline(Outline.DEFAULTS) diff --git a/api/pug/options/section.pug b/api/pug/options/section.pug index 7a398e76..3b3f3e51 100644 --- a/api/pug/options/section.pug +++ b/api/pug/options/section.pug @@ -14,5 +14,6 @@ section.section include anchorURL include homepage include customClass + include afterScroll include afterSticky include afterToggle diff --git a/chapters.min.js b/chapters.min.js index 6fb0ed59..68a102ad 100644 --- a/chapters.min.js +++ b/chapters.min.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chapters=e()}(this,(function(){"use strict";const t=t=>"string"==typeof t,e=(t,e)=>{const s=Object.prototype.hasOwnProperty;return t&&s.call(t,e)},s=t=>Object.prototype.toString.apply(t),i=t=>"function"==typeof t||"[object Function]"===s(t),r=t=>("[object Object]"===s(t)||"object"==typeof t||i(t))&&null!==t;class l{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(s,i){const l=this.attrs;return t(s)?i&&e(l,s)?(l[s]=i,this):l[s]:r(s)?(n=l,o=s,Object.keys(o).forEach((t=>{e(o,t)&&(n[t]=o[t])})),this):0===arguments.length?l:this;var n,o}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const n=t=>!!(r(t)&&t.nodeName&&t.tagName&&1===t.nodeType),o=(t,e=300)=>!!i(t)&&setTimeout((()=>{t()}),e),a=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],c=(t,e,s)=>{const i=a.indexOf(e)>-1;s._delegateListener&&delete(s=s._delegateListener)._delegateListener,function(t,e,s){const i=t._listeners;let r=-1;if(i.length<1)return!1;i.forEach(((t,i)=>{const l=t.fn;e===t.type&&(r=i,l===s&&(r=i))})),r>-1&&i.splice(r,1)}(t,e,s),t.removeEventListener(e,s,i)},h=function(e,s,i=!1){const r=t(e)?document.querySelector(e):e,l=r.childNodes,o=((e,s)=>{let i=e._listeners||[];return t(s)&&s&&(i=i.filter((t=>t.type===s))),i})(r,s);o.forEach((t=>{c(r,t.type,t.fn)})),(i||!0===s||1===arguments.length)&&r&&l&&l.forEach((t=>{n(t)&&h(t,s,i)}))},u=(t,e,s)=>{if(!i(s))return h(t,e);c(t,e,s)},d=(t,e,s,r,l,n=!1)=>{const o=a.indexOf(e)>-1,c=function(i){let o=l||t;!0===l&&(o=r),!0===n&&u(t,e,c),s.call(o,i,r)};if(!i(s))return!1;t._listeners||(t._listeners=[]),t._listeners.push({el:t,type:e,fn:c,data:r,context:l,capture:o}),s._delegateListener=c,t.addEventListener(e,c,o)},p=(t,e="")=>{const s=e.replace(/^>/i,"");return!!(e&&s&&t)&&(t.matches?t.matches(s):!!t.msMatchesSelector&&t.msMatchesSelector(s))},m=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,f=(t,e,s,i,r,l,n=!1)=>{const o=a.indexOf(s)>-1,c=function(o){const a=function(t){const e=t.target;return(s=e)&&3===s.nodeType?s.parentNode:s;var s}(o),h=((t,e,s,i)=>{const r=s||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===r&&p(t,e):p(t,e))||i&&t===r)return t;if(t===r)break}while(t=m(t))})(a,e,t);let d=l||t;o.delegateTarget=h,!0===l&&(d=r),h&&(!0===n&&u(t,s,c),i.call(d,o,r))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:s,fn:c,data:r,context:l,capture:o}),i._delegateListener=c,t.addEventListener(s,c,o)},y=t=>Array.isArray?Array.isArray(t):"[object Array]"===s(t),g=t=>{return!(!r(t)||!(n(t)||(t=>!(!r(t)||"[object NodeList]"!==s(t)))(t)||(e=t,r(e)&&"[object DocumentFragment]"===s(e))||(t=>!(!r(t)||!("[object Text]"===s(t)||t.tagName&&3===t.nodeType)))(t)));var e},$=(s,i,l)=>{const n=document.createDocumentFragment(),o=document.createElement(s),a=e=>g(e)||t(e),c=e=>{let s;if(!a(e))return!1;g(e)?s=e:t(e)&&(s=document.createTextNode(e)),n.appendChild(s)};return r(i)?Object.keys(i).forEach((t=>{e(i,t)&&((t,e,s)=>{let i=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=s;break;case"value":"input"===i||"textarea"===i?t.value=s:t.setAttribute(e,s);break;case"className":t.className=s;break;default:t.setAttribute(e,s)}})(o,t,i[t])})):y(i)&&i.every((t=>a(t)))&&i.forEach((t=>{c(t)})),y(l)?l.forEach((t=>{c(t)})):c(l),o.appendChild(n),o},T=t=>t*t,b=(e=null)=>{let s,i;return e?t(e)?i=document.querySelector(e):n(e)&&(i=e):(s=document.querySelectorAll("html,body"),i=s[0].scrollTop-s[1].scrollTop>=0?s[0]:s[1]),i},_=(t,e)=>{const s=new RegExp("(\\s|^)"+e+"(\\s|$)");let i,r;return!!n(t)&&(i=t.className,!!i&&(r=t.classList,r?.contains?t.classList.contains(e):!!i.match(s)))},E=(t,e)=>{let s,i;if(_(t,e))return!1;s=t.classList,s?.add?s.add(e):(i=t.className,i+=i.length>0?" "+e:e,t.className=i)},v=(e,s)=>{let i,r=e.className;if(!r||!_(e,s))return!1;var l;i=e.classList,i?.remove?i.remove(s):(l=r.replace(s,""),r=!!t(l)&&l.replace(/^\s+|\s+$/g,""),e.className=r)},x=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=x(t.offsetParent)),e},S=(t,e)=>{document.documentElement.style.setProperty(t,e)},N={},k=t=>e(N,t)&&N[t].length>0,A=(t,e=!0)=>e?k(t):(t=>{let e=k(t),s=t.lastIndexOf(".");for(;!e&&-1!==s;)s=(t=t.substring(0,s)).lastIndexOf("."),e=k(t);return e})(t),j=(t,e,i=!0)=>{const r=t=>{if(!k(t))return!1;N[t].forEach((t=>{const i=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(s(e))>-1?e.toString():e;t.callback.call(t.context||t,i)}))},l=()=>{let e=t,s=t.lastIndexOf(".");for(;-1!==s;)e=e.substring(0,s),s=e.lastIndexOf("."),r(e);r(t),r("*")};if(!A(t))return!1;i?setTimeout(l,10):l()};class L extends l{constructor(t){super(),this.attrs=L.DEFAULTS,this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.closed=!1,this.active=0,this.offsetTop=0,this.offsetWidth=0,this.$active=null,this.scrollTimer=null,this.resizeTimer=null,this.playing=!1,t&&this.initialize(t)}initialize(e){let s,r,l,o;return this.attr(e),s=this.attr("created"),r=this.attr("parentElement"),l=this.attr("scrollElement"),t(r)?o=document.querySelector(r):n(r)&&(o=r),this.$parentElement=o,this.$scrollElement=b(l),this.chapters=this.attr("chapters"),this.closed=this.attr("closed"),this.active=this.attr("active"),i(s)&&s.call(this),this.chapters.length<1||(this.render().addListeners(),this.$active=document.querySelector(`#chapter-${this.active}`)),this}isClosed(){return this.closed}isSticky(){return"sticky"===this.attr("position")}isFixed(){return"fixed"===this.attr("position")}isInside(){return this.isFixed()||this.isSticky()}isOutside(){return!this.isInside()}_paintEdge(){const t=this.attr("title"),e=this.attr("customClass"),s=this.$parentElement,i=[];let r,l,n,o,a=null;return s?(this.isInside()&&(a=$("h2",{className:"outline-chapters__title"},[t]),this.$title=a,i.push(a)),n=$("ul",{className:"outline-chapters__list outline-chapters_fixed outline-chapters_hidden"},[""]),this.$list=n,o=$("div",{className:"outline-chapters__placeholder"},[""]),this.$placeholder=o,l=$("div",{className:"outline-chapters__main"},[n,o]),this.$main=l,i.push(l),r=$("nav",{id:"outline-chapters",className:"outline-chapters"},i),this.$el=r,this.isSticky()&&(this.calculateStickyHeight(),E(r,"outline-chapters_sticky")),e&&E(r,e),s.appendChild(r),this):this}render(){const t=this.attr("showCode"),e=this.attr("mounted");let s,r;return this.$parentElement?(this._paintEdge(),r=this.$list,((t,e,s=!1)=>{const i=t=>document.getElementById(t);e.forEach((e=>{const r=e.pid,l=e.id,n=e.rel,o=$("span",{className:"outline-chapters__text"},[e.text]),a=$("a",{id:`chapter__anchor-${l}`,className:"outline-chapters__anchor",href:"#"+n,rel:n,"data-id":l},[o]);let c,h,u,d;s&&(c=$("span",{className:"outline-chapters__code","data-id":l},[e.code]),a.insertBefore(c,a.firstChild)),h=$("li",{id:`chapter-${l}`,className:"outline-chapters__item","data-id":l},[a]),-1===r?t.appendChild(h):(d=i(`chapter-${r}`),u=i(`subject-${r}`),u?u.appendChild(h):(u=$("ul",{id:"subject-"+r,className:"outline-chapters__subject"},[h]),d.appendChild(u)))}))})(r,this.chapters,t),v(r,"outline-chapters_fixed"),v(r,"outline-chapters_hidden"),s=this.$el,this.offsetTop=x(s),this.offsetWidth=s.offsetWidth,this.isFixed()&&(this.sticky(),S("--outline-chapters-width",`${this.offsetWidth}px`)),i(e)&&e.call(this),this.onObserver(),this):this}highlight(t){const e=this.$el.querySelector(`#chapter__anchor-${t}`),s="outline-chapters_active",i=this.$placeholder;let r;return this.$active&&v(this.$active,s),this.active=parseInt(e.getAttribute("data-id"),10),this.$active=e,E(this.$active,s),r=30*this.active,i.style.top=`calc(0.5em + ${r}px)`,this}sticky(){const t=this.attr("afterSticky"),e="outline-chapters_fixed",s=this.$el,r=this.offsetTop,l=this.$scrollElement.scrollTop;let n;return this.isFixed()?(n=!!(l>=r),n?E(s,e):v(s,e),i(t)&&t.call(this,this.isClosed(),n),this):this}calculateStickyHeight(){const t=document.documentElement,e=Math.max(t.clientHeight||0,window.innerHeight||0);return S("--outline-sticky-height",`${e}px`),this}scrollTo(t,e){return((t,e,s)=>{const r=b(t);let l=r.scrollTop,n=0;const o=e-l,a=r.scrollHeight,c=e-a<=0?e:a,h=t=>(i(s)&&s(t),!1),u=()=>{if(n+=1,o<0){if(l-=T(n),r.scrollTop=l,l<=e)return r.scrollTop=e,h(e)}else if(l+=T(n),r.scrollTop=l,l>=c)return r.scrollTop=c,h(c);requestAnimationFrame(u)};requestAnimationFrame(u)})(this.$scrollElement,t,e),this}show(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterOpened"),r=this.$el,l=this.$parentElement;return this.isInside()?(v(l,e),v(r,e),o((()=>{v(l,t),v(r,t)}),30)):v(r,e),this.closed=!1,i(s)&&s.call(this),this}hide(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterClosed"),r=this.$el,l=this.$parentElement;return this.isInside()?(E(l,t),E(r,t),o((()=>{E(l,e),E(r,e)}))):E(r,e),this.closed=!0,i(s)&&s.call(this),this}toggle(){const t=this.attr("afterToggle"),e=this.offsetTop,s=this.$scrollElement.scrollTop;let r;return this.isClosed()?this.show():this.hide(),i(t)&&o((()=>{r=!!(s>=e),t.call(this,this.isClosed(),r)})),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");return i(t)&&t.call(this),this.removeListeners(),this.$parentElement.removeChild(this.$el),this.attr(L.DEFAULTS),this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.active=0,this.offsetTop=0,this.$active=null,this.closed=!1,this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),i(e)&&e.call(this),this}onObserver(){let t=null;return((t,e={})=>{const s=e.root||null,r=e.selector||".outline-heading",l=e.context||null,o={rootMargin:e.rootMargin||"0px 0px -90% 0px"},a=new IntersectionObserver((e=>{e.forEach((e=>{e.intersectionRatio>0&&i(t)&&t.call(l||e.target,e.target)}))}),o),c=n(s)?s:document;s&&(o.root=s),c.querySelectorAll(r).forEach((t=>{a.observe(t)}))})((e=>{const s=e.getAttribute("data-id");if(this.playing)return!1;t&&clearTimeout(t),t=o((()=>{this.highlight(s)}),100)}),{context:this}),this}onSelect(t){const e=this.attr("stickyHeight"),s=t.delegateTarget,r=s.getAttribute("data-id"),l=s.href.split("#")[1],n=document.querySelector(`#${l}`),a=x(n)-(e+10),c=this.$scrollElement.scrollHeight,h=this.attr("afterScroll"),u=()=>{i(h)&&h.call(this),o((()=>{this.playing=!1,j("toolbar:update",{top:a,min:0,max:c})}))};return this.playing=!0,this.isFixed()?(this.sticky(),o((()=>{this.scrollTo(a,u),this.highlight(r)}),10)):(this.scrollTo(a,u),this.highlight(r)),function(t){t.stopPropagation(),t.preventDefault()}(t),this}onScroll(){const t=this.$scrollElement;return this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=o((()=>{const e=t.scrollTop,s=t.scrollHeight-t.clientHeight;this.isFixed()&&this.sticky(),j("toolbar:update",{top:e,min:0,max:s})}),50),this}onResize(){return this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=o((()=>{this.calculateStickyHeight()})),this}addListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),f(t,".outline-chapters__anchor","click",this.onSelect,this,!0),d(i,"scroll",this.onScroll,this,!0),this.isSticky()&&d(i,"resize",this.onResize,this,!0),this}removeListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),u(t,"click",this.onSelect),u(i,"scroll",this.onScroll),this.isSticky()&&d(i,"resize",this.onResize),this}}return L.DEFAULTS={parentElement:"",scrollElement:"",selector:"",active:0,closed:!1,showCode:!0,position:"relative",stickyHeight:0,chapters:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterSticky:null},L})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Chapters=e()}(this,(function(){"use strict";const t=t=>"string"==typeof t,e=(t,e)=>{const s=Object.prototype.hasOwnProperty;return t&&s.call(t,e)},s=t=>Object.prototype.toString.apply(t),i=t=>"function"==typeof t||"[object Function]"===s(t),r=t=>("[object Object]"===s(t)||"object"==typeof t||i(t))&&null!==t;class l{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(s,i){const l=this.attrs;return t(s)?i&&e(l,s)?(l[s]=i,this):l[s]:r(s)?(n=l,o=s,Object.keys(o).forEach((t=>{e(o,t)&&(n[t]=o[t])})),this):0===arguments.length?l:this;var n,o}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const n=t=>!!(r(t)&&t.nodeName&&t.tagName&&1===t.nodeType),o=(t,e=300)=>!!i(t)&&setTimeout((()=>{t()}),e),a=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],c=(t,e,s)=>{const i=a.indexOf(e)>-1;s._delegateListener&&delete(s=s._delegateListener)._delegateListener,function(t,e,s){const i=t._listeners;let r=-1;if(i.length<1)return!1;i.forEach(((t,i)=>{const l=t.fn;e===t.type&&(r=i,l===s&&(r=i))})),r>-1&&i.splice(r,1)}(t,e,s),t.removeEventListener(e,s,i)},h=function(e,s,i=!1){const r=t(e)?document.querySelector(e):e,l=r.childNodes,o=((e,s)=>{let i=e._listeners||[];return t(s)&&s&&(i=i.filter((t=>t.type===s))),i})(r,s);o.forEach((t=>{c(r,t.type,t.fn)})),(i||!0===s||1===arguments.length)&&r&&l&&l.forEach((t=>{n(t)&&h(t,s,i)}))},u=(t,e,s)=>{if(!i(s))return h(t,e);c(t,e,s)},d=(t,e,s,r,l,n=!1)=>{const o=a.indexOf(e)>-1,c=function(i){let o=l||t;!0===l&&(o=r),!0===n&&u(t,e,c),s.call(o,i,r)};if(!i(s))return!1;t._listeners||(t._listeners=[]),t._listeners.push({el:t,type:e,fn:c,data:r,context:l,capture:o}),s._delegateListener=c,t.addEventListener(e,c,o)},p=(t,e="")=>{const s=e.replace(/^>/i,"");return!!(e&&s&&t)&&(t.matches?t.matches(s):!!t.msMatchesSelector&&t.msMatchesSelector(s))},m=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,f=(t,e,s,i,r,l,n=!1)=>{const o=a.indexOf(s)>-1,c=function(o){const a=function(t){const e=t.target;return(s=e)&&3===s.nodeType?s.parentNode:s;var s}(o),h=((t,e,s,i)=>{const r=s||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===r&&p(t,e):p(t,e))||i&&t===r)return t;if(t===r)break}while(t=m(t))})(a,e,t);let d=l||t;o.delegateTarget=h,!0===l&&(d=r),h&&(!0===n&&u(t,s,c),i.call(d,o,r))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:s,fn:c,data:r,context:l,capture:o}),i._delegateListener=c,t.addEventListener(s,c,o)},y=t=>Array.isArray?Array.isArray(t):"[object Array]"===s(t),g=t=>{return!(!r(t)||!(n(t)||(t=>!(!r(t)||"[object NodeList]"!==s(t)))(t)||(e=t,r(e)&&"[object DocumentFragment]"===s(e))||(t=>!(!r(t)||!("[object Text]"===s(t)||t.tagName&&3===t.nodeType)))(t)));var e},$=(s,i,l)=>{const n=document.createDocumentFragment(),o=document.createElement(s),a=e=>g(e)||t(e),c=e=>{let s;if(!a(e))return!1;g(e)?s=e:t(e)&&(s=document.createTextNode(e)),n.appendChild(s)};return r(i)?Object.keys(i).forEach((t=>{e(i,t)&&((t,e,s)=>{let i=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=s;break;case"value":"input"===i||"textarea"===i?t.value=s:t.setAttribute(e,s);break;case"className":t.className=s;break;default:t.setAttribute(e,s)}})(o,t,i[t])})):y(i)&&i.every((t=>a(t)))&&i.forEach((t=>{c(t)})),y(l)?l.forEach((t=>{c(t)})):c(l),o.appendChild(n),o},T=t=>t*t,b=(e=null)=>{let s,i;return e?t(e)?i=document.querySelector(e):n(e)&&(i=e):(s=document.querySelectorAll("html,body"),i=s[0].scrollTop-s[1].scrollTop>=0?s[0]:s[1]),i},_=(t,e)=>{const s=new RegExp("(\\s|^)"+e+"(\\s|$)");let i,r;return!!n(t)&&(i=t.className,!!i&&(r=t.classList,r?.contains?t.classList.contains(e):!!i.match(s)))},E=(t,e)=>{let s,i;if(_(t,e))return!1;s=t.classList,s?.add?s.add(e):(i=t.className,i+=i.length>0?" "+e:e,t.className=i)},v=(e,s)=>{let i,r=e.className;if(!r||!_(e,s))return!1;var l;i=e.classList,i?.remove?i.remove(s):(l=r.replace(s,""),r=!!t(l)&&l.replace(/^\s+|\s+$/g,""),e.className=r)},x=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=x(t.offsetParent)),e},S=(t,e)=>{document.documentElement.style.setProperty(t,e)},N={},k=t=>e(N,t)&&N[t].length>0,A=(t,e=!0)=>e?k(t):(t=>{let e=k(t),s=t.lastIndexOf(".");for(;!e&&-1!==s;)s=(t=t.substring(0,s)).lastIndexOf("."),e=k(t);return e})(t),j=(t,e,i=!0)=>{const r=t=>{if(!k(t))return!1;N[t].forEach((t=>{const i=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(s(e))>-1?e.toString():e;t.callback.call(t.context||t,i)}))},l=()=>{let e=t,s=t.lastIndexOf(".");for(;-1!==s;)e=e.substring(0,s),s=e.lastIndexOf("."),r(e);r(t),r("*")};if(!A(t))return!1;i?setTimeout(l,10):l()};class L extends l{constructor(t){super(),this.attrs=L.DEFAULTS,this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.closed=!1,this.active=0,this.offsetTop=0,this.offsetWidth=0,this.$active=null,this.scrollTimer=null,this.resizeTimer=null,this.playing=!1,t&&this.initialize(t)}initialize(e){let s,r,l,o;return this.attr(e),s=this.attr("created"),r=this.attr("parentElement"),l=this.attr("scrollElement"),t(r)?o=document.querySelector(r):n(r)&&(o=r),this.$parentElement=o,this.$scrollElement=b(l),this.chapters=this.attr("chapters"),this.closed=this.attr("closed"),this.active=this.attr("active"),i(s)&&s.call(this),this.chapters.length<1||(this.render().addListeners(),this.$active=document.querySelector(`#chapter-${this.active}`)),this}isClosed(){return this.closed}isSticky(){return"sticky"===this.attr("position")}isFixed(){return"fixed"===this.attr("position")}isInside(){return this.isFixed()||this.isSticky()}isOutside(){return!this.isInside()}_paintEdge(){const t=this.attr("title"),e=this.attr("customClass"),s=this.$parentElement,i=[];let r,l,n,o,a=null;return s?(this.isInside()&&(a=$("h2",{className:"outline-chapters__title"},[t]),this.$title=a,i.push(a)),n=$("ul",{className:"outline-chapters__list outline-chapters_fixed outline-chapters_hidden"},[""]),this.$list=n,o=$("div",{className:"outline-chapters__placeholder"},[""]),this.$placeholder=o,l=$("div",{className:"outline-chapters__main"},[n,o]),this.$main=l,i.push(l),r=$("nav",{id:"outline-chapters",className:"outline-chapters"},i),this.$el=r,this.isSticky()&&(this.calculateStickyHeight(),E(r,"outline-chapters_sticky")),e&&E(r,e),s.appendChild(r),this):this}render(){const t=this.attr("showCode"),e=this.attr("mounted");let s,r;return this.$parentElement?(this._paintEdge(),r=this.$list,((t,e,s=!1)=>{const i=t=>document.getElementById(t);e.forEach((e=>{const r=e.pid,l=e.id,n=e.rel,o=$("span",{className:"outline-chapters__text"},[e.text]),a=$("a",{id:`chapter__anchor-${l}`,className:"outline-chapters__anchor",href:"#"+n,rel:n,"data-id":l},[o]);let c,h,u,d;s&&(c=$("span",{className:"outline-chapters__code","data-id":l},[e.code]),a.insertBefore(c,a.firstChild)),h=$("li",{id:`chapter-${l}`,className:"outline-chapters__item","data-id":l},[a]),-1===r?t.appendChild(h):(d=i(`chapter-${r}`),u=i(`subject-${r}`),u?u.appendChild(h):(u=$("ul",{id:"subject-"+r,className:"outline-chapters__subject"},[h]),d.appendChild(u)))}))})(r,this.chapters,t),v(r,"outline-chapters_fixed"),v(r,"outline-chapters_hidden"),s=this.$el,this.offsetTop=x(s),this.offsetWidth=s.offsetWidth,this.isFixed()&&(this.sticky(),S("--outline-chapters-width",`${this.offsetWidth}px`)),i(e)&&e.call(this),this.onObserver(),this):this}highlight(t){const e=this.$el.querySelector(`#chapter__anchor-${t}`),s="outline-chapters_active",i=this.$placeholder;let r;return this.$active&&v(this.$active,s),this.active=parseInt(e.getAttribute("data-id"),10),this.$active=e,E(this.$active,s),r=30*this.active,i.style.top=`calc(0.5em + ${r}px)`,this}sticky(){const t=this.attr("afterSticky"),e="outline-chapters_fixed",s=this.$el,r=this.offsetTop,l=this.$scrollElement.scrollTop;let n;return this.isFixed()?(n=!!(l>=r),n?E(s,e):v(s,e),i(t)&&t.call(this,this.isClosed(),n),this):this}calculateStickyHeight(){const t=document.documentElement,e=Math.max(t.clientHeight||0,window.innerHeight||0);return S("--outline-sticky-height",`${e}px`),this}scrollTo(t,e){return((t,e,s)=>{const r=b(t);let l=r.scrollTop,n=0;const o=e-l,a=r.scrollHeight,c=e-a<=0?e:a,h=t=>(i(s)&&s(t),!1),u=()=>{if(n+=1,o<0){if(l-=T(n),r.scrollTop=l,l<=e)return r.scrollTop=e,h(e)}else if(l+=T(n),r.scrollTop=l,l>=c)return r.scrollTop=c,h(c);requestAnimationFrame(u)};requestAnimationFrame(u)})(this.$scrollElement,t,e),this}show(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterOpened"),r=this.$el,l=this.$parentElement;return this.isInside()?(v(l,e),v(r,e),o((()=>{v(l,t),v(r,t)}),30)):v(r,e),this.closed=!1,i(s)&&s.call(this),this}hide(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterClosed"),r=this.$el,l=this.$parentElement;return this.isInside()?(E(l,t),E(r,t),o((()=>{E(l,e),E(r,e)}))):E(r,e),this.closed=!0,i(s)&&s.call(this),this}toggle(){const t=this.attr("afterToggle"),e=this.offsetTop,s=this.$scrollElement.scrollTop;let r;return this.isClosed()?this.show():this.hide(),i(t)&&o((()=>{r=!!(s>=e),t.call(this,this.isClosed(),r)})),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");return i(t)&&t.call(this),this.removeListeners(),this.$parentElement.removeChild(this.$el),this.attr(L.DEFAULTS),this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.active=0,this.offsetTop=0,this.$active=null,this.closed=!1,this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),i(e)&&e.call(this),this}onObserver(){let t=null;return((t,e={})=>{const s=e.root||null,r=e.selector||".outline-heading",l=e.context||null,o={rootMargin:e.rootMargin||"0px 0px -90% 0px"},a=new IntersectionObserver((e=>{e.forEach((e=>{e.intersectionRatio>0&&i(t)&&t.call(l||e.target,e.target)}))}),o),c=n(s)?s:document;s&&(o.root=s),c.querySelectorAll(r).forEach((t=>{a.observe(t)}))})((e=>{const s=e.getAttribute("data-id");if(this.playing)return!1;t&&clearTimeout(t),t=o((()=>{this.highlight(s)}),100)}),{context:this}),this}onSelect(t){const e=this.attr("stickyHeight"),s=t.delegateTarget,r=s.getAttribute("data-id"),l=s.href.split("#")[1],n=document.querySelector(`#${l}`),a=x(n)-(e+10),c=this.$scrollElement.scrollHeight,h=this.attr("afterScroll"),u=()=>{i(h)&&h.call(this,"chapter"),o((()=>{this.playing=!1,j("toolbar:update",{top:a,min:0,max:c})}))};return this.playing=!0,this.isFixed()?(this.sticky(),o((()=>{this.scrollTo(a,u),this.highlight(r)}),10)):(this.scrollTo(a,u),this.highlight(r)),function(t){t.stopPropagation(),t.preventDefault()}(t),this}onScroll(){const t=this.$scrollElement;return this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=o((()=>{const e=t.scrollTop,s=t.scrollHeight-t.clientHeight;this.isFixed()&&this.sticky(),j("toolbar:update",{top:e,min:0,max:s})}),50),this}onResize(){return this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=o((()=>{this.calculateStickyHeight()})),this}addListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),f(t,".outline-chapters__anchor","click",this.onSelect,this,!0),d(i,"scroll",this.onScroll,this,!0),this.isSticky()&&d(i,"resize",this.onResize,this,!0),this}removeListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),u(t,"click",this.onSelect),u(i,"scroll",this.onScroll),this.isSticky()&&d(i,"resize",this.onResize),this}}return L.DEFAULTS={parentElement:"",scrollElement:"",selector:"",active:0,closed:!1,showCode:!0,position:"relative",stickyHeight:0,chapters:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterSticky:null},L})); //# sourceMappingURL=chapters.min.js.map diff --git a/chapters.min.js.map b/chapters.min.js.map index 0d904f1e..08b5facf 100644 --- a/chapters.min.js.map +++ b/chapters.min.js.map @@ -1 +1 @@ -{"version":3,"file":"chapters.min.js","sources":["src/utils/types/isString.js","src/utils/lang/hasOwn.js","src/utils/lang/toString.js","src/utils/types/isFunction.js","src/utils/types/isObject.js","src/base.js","src/utils/lang/extend.js","src/utils/types/isElement.js","src/utils/lang/later.js","src/utils/event/enum.js","src/utils/event/_off.js","src/utils/event/_delete.js","src/utils/event/purgeElement.js","src/utils/event/getListeners.js","src/utils/event/off.js","src/utils/event/at.js","src/utils/dom/matches.js","src/utils/dom/getParentOrHost.js","src/utils/event/on.js","src/utils/event/getTarget.js","src/utils/dom/resolveTextNode.js","src/utils/dom/closest.js","src/utils/types/isArray.js","src/utils/types/isDOM.js","src/utils/types/isHTMLCollection.js","src/utils/types/isFragment.js","src/utils/types/isTextNode.js","src/utils/dom/createElement.js","src/utils/dom/setAttribute.js","src/utils/lang/easeInQuad.js","src/utils/dom/_getScrollElement.js","src/utils/dom/hasClass.js","src/utils/dom/addClass.js","src/utils/dom/removeClass.js","src/utils/lang/trim.js","src/utils/dom/offsetTop.js","src/utils/dom/setProperty.js","src/utils/observer/_subscribers.js","src/utils/observer/_hasDirectSubscribersFor.js","src/utils/observer/has.js","src/utils/observer/_hasSubscribers.js","src/utils/observer/emit.js","src/utils/types/isTypedArray.js","src/chapters.js","src/_paintChapters.js","src/utils/dom/scrollTo.js","src/utils/dom/intersection.js","src/utils/event/stop.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n return purgeElement(el, type)\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector[0] === '>'\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport publish from './utils/observer/emit'\r\n\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport _paintChapters from './_paintChapters'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Chapters.DEFAULTS\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.closed = false\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.offsetWidth = 0\r\n this.$active = null\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.playing = false\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n _paintEdge() {\r\n const STICKY = 'outline-chapters_sticky'\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n [title]\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement(\r\n 'ul',\r\n {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list ${FIXED} ${HIDDEN}`\r\n },\r\n ['']\r\n )\r\n this.$list = $list\r\n\r\n $placeholder = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__placeholder'\r\n },\r\n ['']\r\n )\r\n this.$placeholder = $placeholder\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n [$list, $placeholder]\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: 'outline-chapters'\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n\r\n $parentElement.appendChild($el)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n let $el\r\n let $list\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n this._paintEdge()\r\n\r\n $list = this.$list\r\n _paintChapters($list, this.chapters, showCode)\r\n removeClass($list, FIXED)\r\n removeClass($list, HIDDEN)\r\n\r\n $el = this.$el\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n this.onObserver()\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $anchor = this.$el.querySelector(`#chapter__anchor-${id}`)\r\n const HIGHLIGHT = 'outline-chapters_active'\r\n const $placeholder = this.$placeholder\r\n let top\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n this.$active = $anchor\r\n addClass(this.$active, HIGHLIGHT)\r\n\r\n top = 30 * this.active\r\n $placeholder.style.top = `calc(0.5em + ${top}px)`\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = !!(scrollTop >= top)\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n removeClass($parent, HIDDEN)\r\n removeClass($el, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n removeClass($el, FOLDED)\r\n }, 30)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n addClass($parent, FOLDED)\r\n addClass($el, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n addClass($el, HIDDEN)\r\n })\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = !!(scrollTop >= top)\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n this.$parentElement.removeChild(this.$el)\r\n\r\n this.attr(Chapters.DEFAULTS)\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.$active = null\r\n this.closed = false\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n let timer = null\r\n\r\n intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n timer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n { context: this }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this)\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 50)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize)\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const byId = (id) => document.getElementById(id)\r\n\r\n chapters.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n [chapter.text]\r\n )\r\n const $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n [$text]\r\n )\r\n let $code\r\n let $li\r\n let $ul\r\n let $parent\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n [chapter.code]\r\n )\r\n\r\n $link.insertBefore($code, $link.firstChild)\r\n }\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n [$link]\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $parent = byId(`chapter-${pid}`)\r\n $ul = byId(`subject-${pid}`)\r\n\r\n if (!$ul) {\r\n $ul = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n [$li]\r\n )\r\n\r\n $parent.appendChild($ul)\r\n } else {\r\n $ul.appendChild($li)\r\n }\r\n }\r\n })\r\n}\r\n\r\nexport default _paintChapters\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n requestAnimationFrame(play)\r\n }\r\n\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n}\r\n\r\nexport default intersection\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n *
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","later","fn","delay","setTimeout","CAPTURE_EVENTS","_off","el","type","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","document","querySelector","$children","childNodes","filter","getListeners","$child","off","at","data","context","once","evt","overrideContext","push","addEventListener","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","on","target","getTarget","delegateTarget","ctx","includeCTX","closest","isArray","Array","isDOM","isHTMLCollection","fragment","isTextNode","createElement","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","toLowerCase","style","cssText","setAttribute","className","every","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","querySelectorAll","scrollTop","hasClass","pattern","RegExp","allClass","classList","contains","match","addClass","add","removeClass","remove","offsetTop","top","offsetParent","setProperty","documentElement","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","Chapters","super","DEFAULTS","$title","$main","$list","$placeholder","$parentElement","chapters","closed","active","offsetWidth","$active","scrollTimer","resizeTimer","playing","created","parentElement","$parent","isClosed","isSticky","isFixed","isInside","isOutside","_paintEdge","title","customClass","contents","id","calculateStickyHeight","showCode","mounted","byId","getElementById","chapter","pid","rel","$text","text","$link","href","$code","$li","$ul","code","insertBefore","firstChild","_paintChapters","sticky","onObserver","highlight","$anchor","HIGHLIGHT","parseInt","getAttribute","afterSticky","FIXED","isStickying","height","Math","max","clientHeight","window","innerHeight","scrollTo","after","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","show","FOLDED","HIDDEN","opened","hide","toggle","afterToggle","beforeDestroy","afterDestroy","removeChild","clearTimeout","timer","props","root","rootMargin","Observer","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","$heading","onSelect","stickyHeight","headingId","split","afterScroll","publish","min","stopPropagation","preventDefault","onScroll","onResize","afterClosed","afterOpened"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"chapters.min.js","sources":["src/utils/types/isString.js","src/utils/lang/hasOwn.js","src/utils/lang/toString.js","src/utils/types/isFunction.js","src/utils/types/isObject.js","src/base.js","src/utils/lang/extend.js","src/utils/types/isElement.js","src/utils/lang/later.js","src/utils/event/enum.js","src/utils/event/_off.js","src/utils/event/_delete.js","src/utils/event/purgeElement.js","src/utils/event/getListeners.js","src/utils/event/off.js","src/utils/event/at.js","src/utils/dom/matches.js","src/utils/dom/getParentOrHost.js","src/utils/event/on.js","src/utils/event/getTarget.js","src/utils/dom/resolveTextNode.js","src/utils/dom/closest.js","src/utils/types/isArray.js","src/utils/types/isDOM.js","src/utils/types/isHTMLCollection.js","src/utils/types/isFragment.js","src/utils/types/isTextNode.js","src/utils/dom/createElement.js","src/utils/dom/setAttribute.js","src/utils/lang/easeInQuad.js","src/utils/dom/_getScrollElement.js","src/utils/dom/hasClass.js","src/utils/dom/addClass.js","src/utils/dom/removeClass.js","src/utils/lang/trim.js","src/utils/dom/offsetTop.js","src/utils/dom/setProperty.js","src/utils/observer/_subscribers.js","src/utils/observer/_hasDirectSubscribersFor.js","src/utils/observer/has.js","src/utils/observer/_hasSubscribers.js","src/utils/observer/emit.js","src/utils/types/isTypedArray.js","src/chapters.js","src/_paintChapters.js","src/utils/dom/scrollTo.js","src/utils/dom/intersection.js","src/utils/event/stop.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n return purgeElement(el, type)\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector[0] === '>'\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport publish from './utils/observer/emit'\r\n\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport _paintChapters from './_paintChapters'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Chapters.DEFAULTS\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.closed = false\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.offsetWidth = 0\r\n this.$active = null\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.playing = false\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n _paintEdge() {\r\n const STICKY = 'outline-chapters_sticky'\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n [title]\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement(\r\n 'ul',\r\n {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list ${FIXED} ${HIDDEN}`\r\n },\r\n ['']\r\n )\r\n this.$list = $list\r\n\r\n $placeholder = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__placeholder'\r\n },\r\n ['']\r\n )\r\n this.$placeholder = $placeholder\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n [$list, $placeholder]\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: 'outline-chapters'\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n\r\n $parentElement.appendChild($el)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n let $el\r\n let $list\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n this._paintEdge()\r\n\r\n $list = this.$list\r\n _paintChapters($list, this.chapters, showCode)\r\n removeClass($list, FIXED)\r\n removeClass($list, HIDDEN)\r\n\r\n $el = this.$el\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n this.onObserver()\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $anchor = this.$el.querySelector(`#chapter__anchor-${id}`)\r\n const HIGHLIGHT = 'outline-chapters_active'\r\n const $placeholder = this.$placeholder\r\n let top\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n this.$active = $anchor\r\n addClass(this.$active, HIGHLIGHT)\r\n\r\n top = 30 * this.active\r\n $placeholder.style.top = `calc(0.5em + ${top}px)`\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = !!(scrollTop >= top)\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n removeClass($parent, HIDDEN)\r\n removeClass($el, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n removeClass($el, FOLDED)\r\n }, 30)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n addClass($parent, FOLDED)\r\n addClass($el, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n addClass($el, HIDDEN)\r\n })\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = !!(scrollTop >= top)\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n this.$parentElement.removeChild(this.$el)\r\n\r\n this.attr(Chapters.DEFAULTS)\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.$active = null\r\n this.closed = false\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n let timer = null\r\n\r\n intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n timer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n { context: this }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'chapter')\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 50)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize)\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const byId = (id) => document.getElementById(id)\r\n\r\n chapters.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n [chapter.text]\r\n )\r\n const $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n [$text]\r\n )\r\n let $code\r\n let $li\r\n let $ul\r\n let $parent\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n [chapter.code]\r\n )\r\n\r\n $link.insertBefore($code, $link.firstChild)\r\n }\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n [$link]\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $parent = byId(`chapter-${pid}`)\r\n $ul = byId(`subject-${pid}`)\r\n\r\n if (!$ul) {\r\n $ul = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n [$li]\r\n )\r\n\r\n $parent.appendChild($ul)\r\n } else {\r\n $ul.appendChild($li)\r\n }\r\n }\r\n })\r\n}\r\n\r\nexport default _paintChapters\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n requestAnimationFrame(play)\r\n }\r\n\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n}\r\n\r\nexport default intersection\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n *
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","later","fn","delay","setTimeout","CAPTURE_EVENTS","_off","el","type","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","document","querySelector","$children","childNodes","filter","getListeners","$child","off","at","data","context","once","evt","overrideContext","push","addEventListener","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","on","target","getTarget","delegateTarget","ctx","includeCTX","closest","isArray","Array","isDOM","isHTMLCollection","fragment","isTextNode","createElement","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","toLowerCase","style","cssText","setAttribute","className","every","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","querySelectorAll","scrollTop","hasClass","pattern","RegExp","allClass","classList","contains","match","addClass","add","removeClass","remove","offsetTop","top","offsetParent","setProperty","documentElement","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","Chapters","super","DEFAULTS","$title","$main","$list","$placeholder","$parentElement","chapters","closed","active","offsetWidth","$active","scrollTimer","resizeTimer","playing","created","parentElement","$parent","isClosed","isSticky","isFixed","isInside","isOutside","_paintEdge","title","customClass","contents","id","calculateStickyHeight","showCode","mounted","byId","getElementById","chapter","pid","rel","$text","text","$link","href","$code","$li","$ul","code","insertBefore","firstChild","_paintChapters","sticky","onObserver","highlight","$anchor","HIGHLIGHT","parseInt","getAttribute","afterSticky","FIXED","isStickying","height","Math","max","clientHeight","window","innerHeight","scrollTo","after","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","show","FOLDED","HIDDEN","opened","hide","toggle","afterToggle","beforeDestroy","afterDestroy","removeChild","clearTimeout","timer","props","root","rootMargin","Observer","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","$heading","onSelect","stickyHeight","headingId","split","afterScroll","publish","min","stopPropagation","preventDefault","onScroll","onResize","afterClosed","afterOpened"],"mappings":"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"} \ No newline at end of file diff --git a/docs/fixed.html b/docs/fixed.html index 9305531e..c6cc194e 100644 --- a/docs/fixed.html +++ b/docs/fixed.html @@ -111,7 +111,32 @@ new Outline({ // 设置深色配置界面 customClass: 'theme-dark' -})

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
+})

afterScroll

Description

Type:
Function
Default:
null

可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。

Parameters

target
Type:
String

afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:

  • 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
  • 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
  • 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
  • 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;

注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。

const defaults = Outline.DEFAULTS
+let outline
+
+defaults.position = 'fixed'
+defaults.parentElement = '#aside'
+defaults.stickyHeight = 86
+defaults.homepage = './index.html'
+defaults.afterScroll = function(target) {
+  // 当然,如果你希望无论是点击什么都执行,就不需要判断了
+  // 直接些通用的滚动结束的逻辑即可
+  switch(target){
+    case 'anchor':
+      // 针对点击 # 的处理逻辑
+      break
+    case 'chapter':
+      // 针对点击导航菜单的处理逻辑
+      break
+    case 'up':
+      // 针对点击向上滚动按钮的处理逻辑
+      break
+    case 'down':
+      // 针对点击向下滚动按钮的处理逻辑
+      break
+  }
+}
+outline = new Outline(Outline.DEFAULTS)

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
 const HEADER_STICKY = 'header_sticky'
 const defaults = Outline.DEFAULTS
 let outline
@@ -825,4 +850,7 @@
     $header.classList.add(HEADER_STICKY)
   }
 }
+defaults.afterScroll = function(top) {
+  console.log('top', top)
+}
 outline = new Outline(Outline.DEFAULTS)
\ No newline at end of file
diff --git a/docs/flex.html b/docs/flex.html
index 581eebf4..c532377d 100644
--- a/docs/flex.html
+++ b/docs/flex.html
@@ -117,7 +117,32 @@
 new Outline({
   // 设置深色配置界面
   customClass: 'theme-dark'
-})

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
+})

afterScroll

Description

Type:
Function
Default:
null

可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。

Parameters

target
Type:
String

afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:

  • 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
  • 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
  • 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
  • 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;

注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。

const defaults = Outline.DEFAULTS
+let outline
+
+defaults.position = 'fixed'
+defaults.parentElement = '#aside'
+defaults.stickyHeight = 86
+defaults.homepage = './index.html'
+defaults.afterScroll = function(target) {
+  // 当然,如果你希望无论是点击什么都执行,就不需要判断了
+  // 直接些通用的滚动结束的逻辑即可
+  switch(target){
+    case 'anchor':
+      // 针对点击 # 的处理逻辑
+      break
+    case 'chapter':
+      // 针对点击导航菜单的处理逻辑
+      break
+    case 'up':
+      // 针对点击向上滚动按钮的处理逻辑
+      break
+    case 'down':
+      // 针对点击向下滚动按钮的处理逻辑
+      break
+  }
+}
+outline = new Outline(Outline.DEFAULTS)

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
 const HEADER_STICKY = 'header_sticky'
 const defaults = Outline.DEFAULTS
 let outline
diff --git a/docs/index.html b/docs/index.html
index f9fdd0b2..942c330d 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,4 +1,4 @@
-outline.js | 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/outline.js/outline.min.js"></script>

Options

outline.js 有者丰富的配置选项,以便适应不同的展示方式。

articleElement

Description

Type:
String|HTMLElement
Default:
'#article'
String:
选择器字符串,默认值:html,body(即 window 窗口);
HTMLElement:
'DOM 元素;

可选,用来指定页面中显示文章正文的 DOM 节点或者选择器字符串。

// Default Selector
+outline.js | 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/outline.js/outline.min.js"></script>

Options

outline.js 有者丰富的配置选项,以便适应不同的展示方式。

articleElement

Description

Type:
String|HTMLElement
Default:
'#article'
String:
选择器字符串,默认值:html,body(即 window 窗口);
HTMLElement:
'DOM 元素;

可选,用来指定页面中显示文章正文的 DOM 节点或者选择器字符串。

// Default Selector
 const outline = new Outline(Outline.DEFAULTS)
 
 // Customize Selector
@@ -54,7 +54,32 @@
 new Outline({
   // 设置深色配置界面
   customClass: 'theme-dark'
-})

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
+})

afterScroll

Description

Type:
Function
Default:
null

可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。

Parameters

target
Type:
String

afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:

  • 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
  • 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
  • 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
  • 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;

注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。

const defaults = Outline.DEFAULTS
+let outline
+
+defaults.position = 'fixed'
+defaults.parentElement = '#aside'
+defaults.stickyHeight = 86
+defaults.homepage = './index.html'
+defaults.afterScroll = function(target) {
+  // 当然,如果你希望无论是点击什么都执行,就不需要判断了
+  // 直接些通用的滚动结束的逻辑即可
+  switch(target){
+    case 'anchor':
+      // 针对点击 # 的处理逻辑
+      break
+    case 'chapter':
+      // 针对点击导航菜单的处理逻辑
+      break
+    case 'up':
+      // 针对点击向上滚动按钮的处理逻辑
+      break
+    case 'down':
+      // 针对点击向下滚动按钮的处理逻辑
+      break
+  }
+}
+outline = new Outline(Outline.DEFAULTS)

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
 const HEADER_STICKY = 'header_sticky'
 const defaults = Outline.DEFAULTS
 let outline
diff --git a/docs/js/outline.min.js b/docs/js/outline.min.js
index e7ab344a..02a5df24 100644
--- a/docs/js/outline.min.js
+++ b/docs/js/outline.min.js
@@ -1,2 +1,2 @@
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Outline=e()}(this,(function(){"use strict";const t=t=>"string"==typeof t,e=(t,e)=>{const s=Object.prototype.hasOwnProperty;return t&&s.call(t,e)},s=t=>Object.prototype.toString.apply(t),i=t=>"function"==typeof t||"[object Function]"===s(t),r=t=>("[object Object]"===s(t)||"object"==typeof t||i(t))&&null!==t;class l{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(s,i){const l=this.attrs;return t(s)?i&&e(l,s)?(l[s]=i,this):l[s]:r(s)?(n=l,o=s,Object.keys(o).forEach((t=>{e(o,t)&&(n[t]=o[t])})),this):0===arguments.length?l:this;var n,o}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const n=t=>!!(r(t)&&t.nodeName&&t.tagName&&1===t.nodeType),o=(t,e=300)=>!!i(t)&&setTimeout((()=>{t()}),e),h=t=>t*t,a=(e=null)=>{let s,i;return e?t(e)?i=document.querySelector(e):n(e)&&(i=e):(s=document.querySelectorAll("html,body"),i=s[0].scrollTop-s[1].scrollTop>=0?s[0]:s[1]),i},c=(t,e,s)=>{const r=a(t);let l=r.scrollTop,n=0;const o=e-l,c=r.scrollHeight,d=e-c<=0?e:c,u=t=>(i(s)&&s(t),!1),p=()=>{if(n+=1,o<0){if(l-=h(n),r.scrollTop=l,l<=e)return r.scrollTop=e,u(e)}else if(l+=h(n),r.scrollTop=l,l>=d)return r.scrollTop=d,u(d);requestAnimationFrame(p)};requestAnimationFrame(p)},d=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=d(t.offsetParent)),e},u=(t,e="")=>{const s=e.replace(/^>/i,"");return!!(e&&s&&t)&&(t.matches?t.matches(s):!!t.msMatchesSelector&&t.msMatchesSelector(s))},p=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,m=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],f=(t,e,s)=>{const i=m.indexOf(e)>-1;s._delegateListener&&delete(s=s._delegateListener)._delegateListener,function(t,e,s){const i=t._listeners;let r=-1;if(i.length<1)return!1;i.forEach(((t,i)=>{const l=t.fn;e===t.type&&(r=i,l===s&&(r=i))})),r>-1&&i.splice(r,1)}(t,e,s),t.removeEventListener(e,s,i)},g=function(e,s,i=!1){const r=t(e)?document.querySelector(e):e,l=r.childNodes,o=((e,s)=>{let i=e._listeners||[];return t(s)&&s&&(i=i.filter((t=>t.type===s))),i})(r,s);o.forEach((t=>{f(r,t.type,t.fn)})),(i||!0===s||1===arguments.length)&&r&&l&&l.forEach((t=>{n(t)&&g(t,s,i)}))},y=(t,e,s)=>{if(!i(s))return g(t,e);f(t,e,s)},b=(t,e,s,i,r,l,n=!1)=>{const o=m.indexOf(s)>-1,h=function(o){const a=function(t){const e=t.target;return(s=e)&&3===s.nodeType?s.parentNode:s;var s}(o),c=((t,e,s,i)=>{const r=s||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===r&&u(t,e):u(t,e))||i&&t===r)return t;if(t===r)break}while(t=p(t))})(a,e,t);let d=l||t;o.delegateTarget=c,!0===l&&(d=r),c&&(!0===n&&y(t,s,h),i.call(d,o,r))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:s,fn:h,data:r,context:l,capture:o}),i._delegateListener=h,t.addEventListener(s,h,o)},$=function(t){t.stopPropagation(),t.preventDefault()},v={},E=t=>e(v,t)&&v[t].length>0,_=(t,e=!0)=>e?E(t):(t=>{let e=E(t),s=t.lastIndexOf(".");for(;!e&&-1!==s;)s=(t=t.substring(0,s)).lastIndexOf("."),e=E(t);return e})(t),T=(t,e,i=!0)=>{const r=t=>{if(!E(t))return!1;v[t].forEach((t=>{const i=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(s(e))>-1?e.toString():e;t.callback.call(t.context||t,i)}))},l=()=>{let e=t,s=t.lastIndexOf(".");for(;-1!==s;)e=e.substring(0,s),s=e.lastIndexOf("."),r(e);r(t),r("*")};if(!_(t))return!1;i?setTimeout(l,10):l()},w=t=>Array.isArray?Array.isArray(t):"[object Array]"===s(t),L=(t=[])=>{const e=['','','','','','','',''],s=w(t)&&t.length>0?e.concat(t):e,i=document.body;let r=document.querySelector("#svg-sprites");r?r.innerHTML=s.join(""):(r=document.createElement("div"),r.innerHTML=``,i.insertBefore(r.firstChild,i.firstChild))},C=(t,e=0,s="",i="outline")=>{const r=i?`xlink:href="#${i}-icon-${t}"`:`xlink:href="#icon-${t}"`,l=w(e)?e[0]:e,n=w(e)?e[1]:e,o=e?`width:${l}px;height:${n}px;`:"",h=``,a=document.createElement("i");return a.className="outline-icon",a.innerHTML=h,a},x=e=>!!t(e)&&e.replace(/^\s+|\s+$/g,""),S=t=>{return!(!r(t)||!(n(t)||(t=>!(!r(t)||"[object NodeList]"!==s(t)))(t)||(e=t,r(e)&&"[object DocumentFragment]"===s(e))||(t=>!(!r(t)||!("[object Text]"===s(t)||t.tagName&&3===t.nodeType)))(t)));var e},z=(t,e,s)=>{let i=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=s;break;case"value":"input"===i||"textarea"===i?t.value=s:t.setAttribute(e,s);break;case"className":t.className=s;break;default:t.setAttribute(e,s)}},k=(s,i,l)=>{const n=document.createDocumentFragment(),o=document.createElement(s),h=e=>S(e)||t(e),a=e=>{let s;if(!h(e))return!1;S(e)?s=e:t(e)&&(s=document.createTextNode(e)),n.appendChild(s)};return r(i)?Object.keys(i).forEach((t=>{e(i,t)&&z(o,t,i[t])})):w(i)&&i.every((t=>h(t)))&&i.forEach((t=>{a(t)})),w(l)?l.forEach((t=>{a(t)})):a(l),o.appendChild(n),o},A=(t,e)=>{const s=new RegExp("(\\s|^)"+e+"(\\s|$)");let i,r;return!!n(t)&&(i=t.className,!!i&&(r=t.classList,r?.contains?t.classList.contains(e):!!i.match(s)))},N=(t,e)=>{let s,i=t.className;if(!i||!A(t,e))return!1;s=t.classList,s?.remove?s.remove(e):(i=x(i.replace(e,"")),t.className=i)},M=(e,s=!0,i=!0)=>{const r="outline-heading",l=e.innerHTML;let n;if(e.innerHTML=l.replace(/^\d+(?:(\.?\d*)*\s?)?/gi,""),e.removeAttribute("id"),e.removeAttribute("data-id"),N(e,r),!s)return!1;var o;n=e.querySelector(`.${r}__anchor`),i&&N(e,`${r}_start`),o=x(e.className),t(o)&&""===o&&e.removeAttribute("class"),e.removeChild(n)},D=(e,s=!0)=>{const i=[];let r=1,l=0;return e.forEach(((e,s)=>{const n=e.tagName.replace(/h/i,"");let o=parseInt(n,10),h=-1;var a;o>r?(l+=1,h=1===l?-1:s-1):o===r||ol?1===o?(l=1,h=-1):h=i[s-1].pid:o<=l&&(1===o?l=1:(l-=r-o,l<=1&&(l=1)),h=1===l?-1:((t,e,s)=>{let i,r,l=t[s-1];for(r=0;r]+(>|$)/g,""):"")})})),s?(t=>{const e={};return t.forEach((t=>{const s=JSON.stringify((t=>[t.pid])(t));e[s]=e[s]||[],e[s].push(t),t.index=e[s].length,-1===t.pid&&(t.code=String(t.index))})),Object.keys(e).forEach((s=>{e[s].forEach(((e,s)=>{e.index=s+1,t.forEach((t=>{t.pid===e.id&&(t.code=e.code+"."+t.index)}))}))})),t})(i):i};class H extends l{constructor(t){super(),this.attrs=H.DEFAULTS,this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],t&&this.initialize(t)}initialize(e){let s,r,l,o,h;return this.attr(e),h=this.attr("articleElement"),r=this.attr("scrollElement"),l=this.attr("selector"),s=this.attr("created"),t(h)?o=document.querySelector(h):n(h)&&(o=h),o?(this.$articleElement=o,this.$scrollElement=a(r),this.$headings=[...o.querySelectorAll(l)],this.$headings.length<1||(this.chapters=D(this.$headings),i(s)&&s.call(this),this.render().addListeners()),this):this}getChapters(t=!1){const e=this.chapters;return t?((t,e,s)=>{const i={},r=[];return t.forEach(((t,s)=>{i[t[e]]=s,t.children=[]})),t.forEach((e=>{const l=t[i[e[s]]];-1!==e[s]?l.children.push(e):r.push(e)})),r})(e,"id","pid"):e}count(){return this.chapters.length}render(){const t=this.attr("mounted"),e=this.attr("hasAnchor"),s=this.attr("isAtStart"),r=this.attr("showCode"),l=this.attr("anchorURL"),n=this.$headings,o=this.getChapters();return L(),n.forEach(((t,i)=>{const n=o[i].code;((t,e,s)=>{const i="outline-heading",r=s.hasAnchor||!0,l=s.isAtStart||!0,n=s.showCode||!1,o=s.chapterCode||"",h=s.anchorURL||"",a=`heading-${e}`,c={id:a,className:l?`${i} ${i}_start`:i,"data-id":e},d=Object.keys(c),u=x(t.innerHTML);let p,m;if(d.forEach((e=>{z(t,e,c[e])})),n&&(t.innerHTML=o+" "+u),!r)return!1;m=C("hash"),p=k("a",{id:`anchor-${e}`,className:`${i}__anchor anchor-${e}`,href:h||`#${a}`,target:h?"_blank":"self","data-id":e},[m]),t.appendChild(p)})(t,i,{hasAnchor:e,isAtStart:s,showCode:r,chapterCode:n,anchorURL:l})})),i(t)&&t.call(this),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}destroy(){const t=this.attr("hasAnchor"),e=this.attr("isAtStart"),s=this.attr("beforeDestroy"),r=this.attr("afterDestroy"),l=this.$headings;return i(s)&&s.call(this),this.removeListeners(),l.forEach((s=>{M(s,t,e)})),this.attr(H.DEFAULTS),this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],i(r)&&r.call(this),this}onAnchorTrigger(t){const e=this.attr("anchorURL"),s=this.attr("afterScroll"),r=this.attr("stickyHeight"),l=t.delegateTarget.parentNode,n=d(l)-(r+10),h=this.$scrollElement,a=h.scrollHeight-h.clientHeight;return this.scrollTo(n,(()=>{i(s)&&s.call(this),o((()=>{T("toolbar:update",{top:n,min:0,max:a})}))})),e||$(t),this}addListeners(){const t=this.$articleElement;return b(t,".outline-heading__anchor","click",this.onAnchorTrigger,this,!0),this}removeListeners(){const t=this.$articleElement;return y(t,"click",this.onAnchorTrigger),this}}H.DEFAULTS={scrollElement:"html,body",articleElement:"#article",selector:"h1,h2,h3,h4,h5,h6",stickyHeight:0,anchorURL:"",hasAnchor:!0,isAtStart:!0,showCode:!1,created:null,mounted:null,afterScroll:null,beforeDestroy:null,afterDestroy:null};const j=(t,e)=>{let s,i;if(A(t,e))return!1;s=t.classList,s?.add?s.add(e):(i=t.className,i+=i.length>0?" "+e:e,t.className=i)},O=(t,e)=>{document.documentElement.style.setProperty(t,e)};let F=2e3;const U=t=>(t?F=t:F+=1,O("--outline-zIndex",`${F}`),F);class I extends l{constructor(t){super(),this.attrs=I.DEFAULTS,this.title="",this.closed=!0,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,this.zIndex=0,t&&this.initialize(t)}initialize(t){let e;return this.attr(t),this.title=this.attr("title"),e=this.attr("created"),i(e)&&e.call(this),this.render().addListeners(),this}setTitle(t){return this.attr("title",t),this.title=t,this.$title.innerHTML=t,this}isClosed(){return this.closed}render(){const t=this.attr("mounted"),e=this.attr("size"),s=this.attr("placement"),r=this.attr("hasClose"),l=this.attr("hasOverlay"),n=this.attr("hasOffset"),o=this.attr("hasPadding"),h=this.attr("autoHeight"),a=this.attr("customClass"),c=document.createDocumentFragment();let d,u,p,m,f,g,y,b;return L(),this.zIndex=U(),m=k("h2",{className:"outline-drawer__title"},[this.title]),this.$title=m,r&&(f=k("div",{className:"outline-drawer__close"},[C("close",20)]),this.$close=f),p=k("header",{className:"outline-drawer__header"},[m,f]),this.$header=p,g=k("div",{className:"outline-drawer__main"},[""]),this.$main=g,o||j(g,"outline-drawer_full"),y=k("footer",{className:"outline-drawer__footer"},[""]),this.$footer=y,u=k("div",{className:`outline-drawer__modal outline-drawer_${s} outline-drawer_${e} outline-drawer_closed`},[p,g,y]),this.$modal=u,n&&j(u,"outline-drawer_offset"),h&&j(u,"outline-drawer_auto"),a&&j(u,a),l&&(b=k("div",{className:"outline-drawer__overlay"},[""]),this.$overlay=b),d=k("div",{className:"outline-drawer"},[u,b]),this.$el=d,c.appendChild(d),document.body.appendChild(c),i(t)&&t.call(this),this}open(){const t=this.attr("afterOpened"),e=this.$modal;return j(this.$el,"outline-drawer_opened"),N(e,"outline-drawer_closed"),j(e,"outline-drawer_opened"),o((()=>{this.closed=!1,i(t)&&t.call(this)})),this}close(){const t=this.attr("afterClosed"),e=this.$modal;return N(e,"outline-drawer_opened"),j(e,"outline-drawer_closed"),o((()=>{N(this.$el,"outline-drawer_opened"),this.closed=!0,i(t)&&t.call(this)})),this}toggle(){const t=this.attr("afterToggle"),e=this.isClosed();return e?this.open():this.close(),i(t)&&o((()=>{t.call(this,e)})),this}destroy(){const t=this.attr("afterDestroy"),e=this.attr("beforeDestroy");let s=this.zIndex;return i(e)&&e.call(this),this.removeListeners(),this.attrs=I.DEFAULTS,this.title="",this.closed=!1,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,s-=1,U(s),this.zIndex=0,i(t)&&t.call(this),this}addListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t&&b(s,".outline-drawer__close","click",this.onClose,this,!0),e&&b(s,".outline-drawer__overlay","click",this.onClose,this,!0),this}removeListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t||e?(y(s,"click",this.onClose),this):this}onClose(){return this.close(),this}}I.DEFAULTS={placement:"rtl",title:"标题",size:"regular",hasClose:!0,hasOverlay:!0,hasOffset:!1,hasPadding:!0,autoHeight:!0,created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterToggle:null};const q=(t,e,s,r,l,n=!1)=>{const o=m.indexOf(e)>-1,h=function(i){let o=l||t;!0===l&&(o=r),!0===n&&y(t,e,h),s.call(o,i,r)};if(!i(s))return!1;t._listeners||(t._listeners=[]),t._listeners.push({el:t,type:e,fn:h,data:r,context:l,capture:o}),s._delegateListener=h,t.addEventListener(e,h,o)};class B extends l{constructor(t){super(),this.attrs=B.DEFAULTS,this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.closed=!1,this.active=0,this.offsetTop=0,this.offsetWidth=0,this.$active=null,this.scrollTimer=null,this.resizeTimer=null,this.playing=!1,t&&this.initialize(t)}initialize(e){let s,r,l,o;return this.attr(e),s=this.attr("created"),r=this.attr("parentElement"),l=this.attr("scrollElement"),t(r)?o=document.querySelector(r):n(r)&&(o=r),this.$parentElement=o,this.$scrollElement=a(l),this.chapters=this.attr("chapters"),this.closed=this.attr("closed"),this.active=this.attr("active"),i(s)&&s.call(this),this.chapters.length<1||(this.render().addListeners(),this.$active=document.querySelector(`#chapter-${this.active}`)),this}isClosed(){return this.closed}isSticky(){return"sticky"===this.attr("position")}isFixed(){return"fixed"===this.attr("position")}isInside(){return this.isFixed()||this.isSticky()}isOutside(){return!this.isInside()}_paintEdge(){const t=this.attr("title"),e=this.attr("customClass"),s=this.$parentElement,i=[];let r,l,n,o,h=null;return s?(this.isInside()&&(h=k("h2",{className:"outline-chapters__title"},[t]),this.$title=h,i.push(h)),n=k("ul",{className:"outline-chapters__list outline-chapters_fixed outline-chapters_hidden"},[""]),this.$list=n,o=k("div",{className:"outline-chapters__placeholder"},[""]),this.$placeholder=o,l=k("div",{className:"outline-chapters__main"},[n,o]),this.$main=l,i.push(l),r=k("nav",{id:"outline-chapters",className:"outline-chapters"},i),this.$el=r,this.isSticky()&&(this.calculateStickyHeight(),j(r,"outline-chapters_sticky")),e&&j(r,e),s.appendChild(r),this):this}render(){const t=this.attr("showCode"),e=this.attr("mounted");let s,r;return this.$parentElement?(this._paintEdge(),r=this.$list,((t,e,s=!1)=>{const i=t=>document.getElementById(t);e.forEach((e=>{const r=e.pid,l=e.id,n=e.rel,o=k("span",{className:"outline-chapters__text"},[e.text]),h=k("a",{id:`chapter__anchor-${l}`,className:"outline-chapters__anchor",href:"#"+n,rel:n,"data-id":l},[o]);let a,c,d,u;s&&(a=k("span",{className:"outline-chapters__code","data-id":l},[e.code]),h.insertBefore(a,h.firstChild)),c=k("li",{id:`chapter-${l}`,className:"outline-chapters__item","data-id":l},[h]),-1===r?t.appendChild(c):(u=i(`chapter-${r}`),d=i(`subject-${r}`),d?d.appendChild(c):(d=k("ul",{id:"subject-"+r,className:"outline-chapters__subject"},[c]),u.appendChild(d)))}))})(r,this.chapters,t),N(r,"outline-chapters_fixed"),N(r,"outline-chapters_hidden"),s=this.$el,this.offsetTop=d(s),this.offsetWidth=s.offsetWidth,this.isFixed()&&(this.sticky(),O("--outline-chapters-width",`${this.offsetWidth}px`)),i(e)&&e.call(this),this.onObserver(),this):this}highlight(t){const e=this.$el.querySelector(`#chapter__anchor-${t}`),s="outline-chapters_active",i=this.$placeholder;let r;return this.$active&&N(this.$active,s),this.active=parseInt(e.getAttribute("data-id"),10),this.$active=e,j(this.$active,s),r=30*this.active,i.style.top=`calc(0.5em + ${r}px)`,this}sticky(){const t=this.attr("afterSticky"),e="outline-chapters_fixed",s=this.$el,r=this.offsetTop,l=this.$scrollElement.scrollTop;let n;return this.isFixed()?(n=!!(l>=r),n?j(s,e):N(s,e),i(t)&&t.call(this,this.isClosed(),n),this):this}calculateStickyHeight(){const t=document.documentElement,e=Math.max(t.clientHeight||0,window.innerHeight||0);return O("--outline-sticky-height",`${e}px`),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}show(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterOpened"),r=this.$el,l=this.$parentElement;return this.isInside()?(N(l,e),N(r,e),o((()=>{N(l,t),N(r,t)}),30)):N(r,e),this.closed=!1,i(s)&&s.call(this),this}hide(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterClosed"),r=this.$el,l=this.$parentElement;return this.isInside()?(j(l,t),j(r,t),o((()=>{j(l,e),j(r,e)}))):j(r,e),this.closed=!0,i(s)&&s.call(this),this}toggle(){const t=this.attr("afterToggle"),e=this.offsetTop,s=this.$scrollElement.scrollTop;let r;return this.isClosed()?this.show():this.hide(),i(t)&&o((()=>{r=!!(s>=e),t.call(this,this.isClosed(),r)})),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");return i(t)&&t.call(this),this.removeListeners(),this.$parentElement.removeChild(this.$el),this.attr(B.DEFAULTS),this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.active=0,this.offsetTop=0,this.$active=null,this.closed=!1,this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),i(e)&&e.call(this),this}onObserver(){let t=null;return((t,e={})=>{const s=e.root||null,r=e.selector||".outline-heading",l=e.context||null,o={rootMargin:e.rootMargin||"0px 0px -90% 0px"},h=new IntersectionObserver((e=>{e.forEach((e=>{e.intersectionRatio>0&&i(t)&&t.call(l||e.target,e.target)}))}),o),a=n(s)?s:document;s&&(o.root=s),a.querySelectorAll(r).forEach((t=>{h.observe(t)}))})((e=>{const s=e.getAttribute("data-id");if(this.playing)return!1;t&&clearTimeout(t),t=o((()=>{this.highlight(s)}),100)}),{context:this}),this}onSelect(t){const e=this.attr("stickyHeight"),s=t.delegateTarget,r=s.getAttribute("data-id"),l=s.href.split("#")[1],n=document.querySelector(`#${l}`),h=d(n)-(e+10),a=this.$scrollElement.scrollHeight,c=this.attr("afterScroll"),u=()=>{i(c)&&c.call(this),o((()=>{this.playing=!1,T("toolbar:update",{top:h,min:0,max:a})}))};return this.playing=!0,this.isFixed()?(this.sticky(),o((()=>{this.scrollTo(h,u),this.highlight(r)}),10)):(this.scrollTo(h,u),this.highlight(r)),$(t),this}onScroll(){const t=this.$scrollElement;return this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=o((()=>{const e=t.scrollTop,s=t.scrollHeight-t.clientHeight;this.isFixed()&&this.sticky(),T("toolbar:update",{top:e,min:0,max:s})}),50),this}onResize(){return this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=o((()=>{this.calculateStickyHeight()})),this}addListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),b(t,".outline-chapters__anchor","click",this.onSelect,this,!0),q(i,"scroll",this.onScroll,this,!0),this.isSticky()&&q(i,"resize",this.onResize,this,!0),this}removeListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),y(t,"click",this.onSelect),y(i,"scroll",this.onScroll),this.isSticky()&&q(i,"resize",this.onResize),this}}B.DEFAULTS={parentElement:"",scrollElement:"",selector:"",active:0,closed:!1,showCode:!0,position:"relative",stickyHeight:0,chapters:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterSticky:null};const R=(t,e=!0)=>{const s=C(t.icon,t.size),i=k("a",{className:"outline-toolbar__anchor",href:t.link},[s]),r=k("div",{className:`outline-toolbar__button ${t.name}`},[t.link?i:s]);return j(s,"outline-toolbar__icon"),e&&j(r,"outline-toolbar_rounded"),t.disabled&&j(r,"outline-toolbar_disabled"),r},P="outline-toolbar_disabled",Q="outline-toolbar_hidden";class V extends l{constructor(t){super(),this.attrs=V.DEFAULTS,this.$el=null,this.disabled=!1,this.closed=!1,this.buttons=[],t&&this.initialize(t)}initialize(t){let e;return this.attr(t),e=this.attr("created"),this.disabled=this.attr("disabled"),this.closed=this.attr("closed"),i(e)&&e.call(this),this.render().addListeners(),this}isDisabled(t){const e=this.attr("buttons");let s;return t?(s=e.find((e=>e.name===t)),!(!s||!s.disabled)):this.disabled}isClosed(){return this.closed}highlight(t){const e=this.buttons.find((e=>e.name===t)),s="outline-toolbar_active";let i;return i||(i=e.$el,A(i,s)?N(i,s):j(i,s)),this}render(){const t=this.attr("mounted"),e=this.attr("buttons")||[],s=this.attr("rounded"),r=this.attr("placement"),l=document.createDocumentFragment(),n=document.createDocumentFragment();return L(),e.forEach((t=>{const e=R(t,s);l.appendChild(e),this.buttons.push({name:t.name,$el:e})})),this.$el=k("div",{id:"outline-toolbar",className:`outline-toolbar outline-toolbar_${r}`},[l]),n.appendChild(this.$el),document.body.appendChild(n),this.closed&&this.hide(),this.disabled&&this.disable(),i(t)&&t.call(this),this}add(t){const e=this.$el,s=this.attr("buttons"),l=t.action,n=document.createDocumentFragment();let o;return r(t)?(s.push(t),n.appendChild(R(t))):w(t)&&t.forEach((t=>{n.appendChild(R(t))})),e.appendChild(n),l&&i(l.handler)&&(o=l.type||"click",b(e,`.${t.name}`,o,l.handler)),this}remove(t){const e=this.$el,s=this.attr("buttons"),i=s.find((e=>e.name===t));let r,l=-1;return i?(s.forEach(((e,s)=>{e.name===t&&(l=s)})),l>-1&&this.attr().buttons.splice(l,1),r=e.querySelector(`.${t}`),this.switch(t,!1),e.removeChild(r),this):this}switch(t,e){const s=this.$el,i=this.attr("buttons"),r=i.find((e=>e.name===t));let l,n,o,h;return r?(i.forEach((s=>{s.name===t&&(r.disabled=!e)})),l=r.action,h=s.querySelector(`.${t}`),l&&(n=l.type||"click",o=l.handler),e?(N(h,P),n&&o&&b(s,`.${t}`,n,o)):(j(h,P),n&&o&&y(s,n,o)),this):this}disable(t){const e=this.attr("afterDisabled");return t?this.switch(t,!1):(j(this.$el,P),this.removeListeners(),this.disabled=!0,i(e)&&e.call(this)),this}enable(t){const e=this.attr("afterEnabled");return t?this.switch(t,!0):(this.disabled=!1,N(this.$el,P),this.addListeners(),i(e)&&e.call(this)),this}show(t){const e=this.attr("afterOpened"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),N(l,Q)}else N(r,Q),this.closed=!1,i(e)&&o((()=>{e.call(this)}),310);return this}hide(t){const e=this.attr("afterClosed"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),j(l,Q)}else j(r,Q),this.closed=!0,i(e)&&o((()=>{e.call(this)}),310);return this}toggle(){return this.isClosed()?this.show():this.hide(),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");let s=this.$el;return i(t)&&t.call(this),this.removeListeners(),document.body.removeChild(s),s=null,this.attr(V.DEFAULTS),this.disabled=!1,this.closed=!1,this.buttons=[],i(e)&&e.call(this),this}refresh(){const t=this.$el,e=this.attr("buttons")||[];return this.removeListeners(),t.innerHTML="",e.forEach((t=>{this.$el.appendChild(R(t))})),this.addListeners(),this}addListeners(){const e=this.attr("buttons"),s=this.$el;return!e||e.length<1||e.forEach((e=>{const r=e.action;let l,n,o,h;if(this.disabled)return!1;r&&(n=r.handler,t(n)&&(h=n,r.handler=function(){T(h,e.name)},n=r.handler),l=r.type||"click",o=r.context),i(n)&&b(s,`.${e.name}`,l,n,o||this,!0)})),this}removeListeners(){const t=this.attr("buttons"),e=this.$el;return!t||t.length<1||t.forEach((t=>{const s=t.action;let r,l;if(this.disabled)return!1;s&&(l=s.handler,r=s.type||"click"),i(l)&&y(e,r,l)})),this}}V.DEFAULTS={placement:"ltr",closed:!1,disabled:!1,rounded:!0,buttons:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterDisabled:null,afterEnabled:null,beforeDestroy:null,afterDestroy:null};const W=(()=>{let t=0;return e=>(t+=1,e?e+"-"+t:"guid-"+t)})(),J=(t,e,s=null)=>{const r=W();let l="symbol"==typeof t?t.toString():t;return!!i(e)&&(v[l]||(v[l]=[]),v[l].push({topic:l,callback:e,context:s,token:r}),r)},G=t=>{if(!e(v,t))return!1;delete v[t]},K=(t,e)=>{if(!_(t))return!1;e?(t=>{const e=Object.keys(v);if(!t||e.length<1)return!1;e.forEach((e=>{const s=v[e];let i;s.forEach(((e,r)=>{e.callback!==t&&e.token!==t||(i=e.topic,s.splice(-1,r))})),s.length<1&&G(i)}))})(e):G(t)};class X extends l{constructor(t){super(),this.attrs=X.DEFAULTS,this.anchors=null,this.drawer=null,this.chapters=null,this.toolbar=null,t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}getChapters(t=!1){return this.anchors.getChapters(t)}count(){return this.anchors.count()}render(){return this._renderAnchors()._renderChapters()._renderToolbar(),this}_renderAnchors(){const t=this.attr("articleElement"),e=this.attr("selector"),s=this.attr("stickyHeight"),i=this.attr("scrollElement"),r=this.attr("showCode"),l=this.attr("anchorURL");return this.anchors=new H({articleElement:t,stickyHeight:s,scrollElement:i,selector:e,showCode:r,anchorURL:l}),this}_renderChapters(){const t=this.attr("title"),e=this.attr("stickyHeight"),s=this.attr("scrollElement"),i=this.attr("customClass"),r=this.attr("showCode"),l=this.attr("position"),n=this.attr("placement"),o=this.attr("afterSticky"),h=this.attr("afterToggle"),a=this.count();let c,d=this.attr("parentElement");return a<1||(c={scrollElement:s,showCode:r,position:l,title:t,stickyHeight:e,chapters:this.anchors.getChapters(),afterSticky:o,afterToggle:h},"relative"===l?(this.drawer=new I({placement:n,title:t,size:"tiny",hasOffset:!0,hasPadding:!1,customClass:i,afterClosed:()=>{this.toolbar.toggle()}}),d=this.drawer.$main):c.customClass=i,c.parentElement=d,this.chapters=new B(c)),this}_renderToolbar(){const t=this.attr("placement"),e=this.attr("homepage"),s=this.count(),i={name:"homepage",icon:"homepage",size:20,link:e},r={name:"menu",icon:"menu",size:18,action:{type:"click",handler:"toolbar:action:toggle"}},l=[];return l.push({name:"up",icon:"up",size:20,action:{type:"click",handler:"toolbar:action:up"}}),e&&l.push(i),s>0&&l.push(r),l.push({name:"down",icon:"down",size:20,action:{type:"click",handler:"toolbar:action:down"}}),this.toolbar=new V({placement:t,buttons:l}),this}toTop(){const t=this.toolbar,e=this.chapters,s=this.count();return e.playing=!0,this.scrollTo(0,(()=>{t.hide("up"),t.show("down"),s>0&&e.highlight(0),e.playing=!1})),this}toBottom(){const t=a(this.attr("scrollElement")),e=this.toolbar,s=this.chapters,i=this.count(),r=Math.floor(t.scrollHeight-t.clientHeight);return s.playing=!0,this.scrollTo(r,(()=>{e.hide("down"),e.show("up"),i>1&&s.highlight(i-1),s.playing=!1})),this}scrollTo(t,e){const s=this.attr("scrollElement");return c(s,t,e),this}toggle(){const t=this.attr("position"),e=this.toolbar,s=this.drawer,i=this.chapters,r=this.count();if("relative"!==t)i.toggle(),e.highlight("menu");else{if(e.toggle(),r<1)return this;o((()=>{i.isInside()?i.toggle():s.toggle()}))}return this}destroy(){const t=this.chapters,e=this.count();return this.removeListeners(),this.attr(X.DEFAULTS),this.anchors.destroy(),e<1&&(t.destroy(),t.isOutside()&&this.drawer.destroy()),this.toolbar.destroy(),this}onToggle(){return this.toggle(),this}onScrollTop(){return this.toTop(),this}onScrollBottom(){return this.toBottom(),this}onToolbarUpdate({top:t,min:e,max:s}){const i=this.toolbar,r=Math.ceil(t);return r<=e?(i.hide("up"),i.show("down")):r>=s?(i.hide("down"),i.show("up")):r>e&&r"string"==typeof t,e=(t,e)=>{const s=Object.prototype.hasOwnProperty;return t&&s.call(t,e)},s=t=>Object.prototype.toString.apply(t),i=t=>"function"==typeof t||"[object Function]"===s(t),r=t=>("[object Object]"===s(t)||"object"==typeof t||i(t))&&null!==t;class l{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(s,i){const l=this.attrs;return t(s)?i&&e(l,s)?(l[s]=i,this):l[s]:r(s)?(n=l,o=s,Object.keys(o).forEach((t=>{e(o,t)&&(n[t]=o[t])})),this):0===arguments.length?l:this;var n,o}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const n=t=>!!(r(t)&&t.nodeName&&t.tagName&&1===t.nodeType),o=(t,e=300)=>!!i(t)&&setTimeout((()=>{t()}),e),h=t=>t*t,a=(e=null)=>{let s,i;return e?t(e)?i=document.querySelector(e):n(e)&&(i=e):(s=document.querySelectorAll("html,body"),i=s[0].scrollTop-s[1].scrollTop>=0?s[0]:s[1]),i},c=(t,e,s)=>{const r=a(t);let l=r.scrollTop,n=0;const o=e-l,c=r.scrollHeight,d=e-c<=0?e:c,u=t=>(i(s)&&s(t),!1),p=()=>{if(n+=1,o<0){if(l-=h(n),r.scrollTop=l,l<=e)return r.scrollTop=e,u(e)}else if(l+=h(n),r.scrollTop=l,l>=d)return r.scrollTop=d,u(d);requestAnimationFrame(p)};requestAnimationFrame(p)},d=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=d(t.offsetParent)),e},u=(t,e="")=>{const s=e.replace(/^>/i,"");return!!(e&&s&&t)&&(t.matches?t.matches(s):!!t.msMatchesSelector&&t.msMatchesSelector(s))},p=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,m=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],f=(t,e,s)=>{const i=m.indexOf(e)>-1;s._delegateListener&&delete(s=s._delegateListener)._delegateListener,function(t,e,s){const i=t._listeners;let r=-1;if(i.length<1)return!1;i.forEach(((t,i)=>{const l=t.fn;e===t.type&&(r=i,l===s&&(r=i))})),r>-1&&i.splice(r,1)}(t,e,s),t.removeEventListener(e,s,i)},g=function(e,s,i=!1){const r=t(e)?document.querySelector(e):e,l=r.childNodes,o=((e,s)=>{let i=e._listeners||[];return t(s)&&s&&(i=i.filter((t=>t.type===s))),i})(r,s);o.forEach((t=>{f(r,t.type,t.fn)})),(i||!0===s||1===arguments.length)&&r&&l&&l.forEach((t=>{n(t)&&g(t,s,i)}))},y=(t,e,s)=>{if(!i(s))return g(t,e);f(t,e,s)},b=(t,e,s,i,r,l,n=!1)=>{const o=m.indexOf(s)>-1,h=function(o){const a=function(t){const e=t.target;return(s=e)&&3===s.nodeType?s.parentNode:s;var s}(o),c=((t,e,s,i)=>{const r=s||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===r&&u(t,e):u(t,e))||i&&t===r)return t;if(t===r)break}while(t=p(t))})(a,e,t);let d=l||t;o.delegateTarget=c,!0===l&&(d=r),c&&(!0===n&&y(t,s,h),i.call(d,o,r))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:s,fn:h,data:r,context:l,capture:o}),i._delegateListener=h,t.addEventListener(s,h,o)},$=function(t){t.stopPropagation(),t.preventDefault()},v={},E=t=>e(v,t)&&v[t].length>0,_=(t,e=!0)=>e?E(t):(t=>{let e=E(t),s=t.lastIndexOf(".");for(;!e&&-1!==s;)s=(t=t.substring(0,s)).lastIndexOf("."),e=E(t);return e})(t),T=(t,e,i=!0)=>{const r=t=>{if(!E(t))return!1;v[t].forEach((t=>{const i=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(s(e))>-1?e.toString():e;t.callback.call(t.context||t,i)}))},l=()=>{let e=t,s=t.lastIndexOf(".");for(;-1!==s;)e=e.substring(0,s),s=e.lastIndexOf("."),r(e);r(t),r("*")};if(!_(t))return!1;i?setTimeout(l,10):l()},w=t=>Array.isArray?Array.isArray(t):"[object Array]"===s(t),L=(t=[])=>{const e=['','','','','','','',''],s=w(t)&&t.length>0?e.concat(t):e,i=document.body;let r=document.querySelector("#svg-sprites");r?r.innerHTML=s.join(""):(r=document.createElement("div"),r.innerHTML=``,i.insertBefore(r.firstChild,i.firstChild))},S=(t,e=0,s="",i="outline")=>{const r=i?`xlink:href="#${i}-icon-${t}"`:`xlink:href="#icon-${t}"`,l=w(e)?e[0]:e,n=w(e)?e[1]:e,o=e?`width:${l}px;height:${n}px;`:"",h=``,a=document.createElement("i");return a.className="outline-icon",a.innerHTML=h,a},C=e=>!!t(e)&&e.replace(/^\s+|\s+$/g,""),x=t=>{return!(!r(t)||!(n(t)||(t=>!(!r(t)||"[object NodeList]"!==s(t)))(t)||(e=t,r(e)&&"[object DocumentFragment]"===s(e))||(t=>!(!r(t)||!("[object Text]"===s(t)||t.tagName&&3===t.nodeType)))(t)));var e},z=(t,e,s)=>{let i=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=s;break;case"value":"input"===i||"textarea"===i?t.value=s:t.setAttribute(e,s);break;case"className":t.className=s;break;default:t.setAttribute(e,s)}},k=(s,i,l)=>{const n=document.createDocumentFragment(),o=document.createElement(s),h=e=>x(e)||t(e),a=e=>{let s;if(!h(e))return!1;x(e)?s=e:t(e)&&(s=document.createTextNode(e)),n.appendChild(s)};return r(i)?Object.keys(i).forEach((t=>{e(i,t)&&z(o,t,i[t])})):w(i)&&i.every((t=>h(t)))&&i.forEach((t=>{a(t)})),w(l)?l.forEach((t=>{a(t)})):a(l),o.appendChild(n),o},A=(t,e)=>{const s=new RegExp("(\\s|^)"+e+"(\\s|$)");let i,r;return!!n(t)&&(i=t.className,!!i&&(r=t.classList,r?.contains?t.classList.contains(e):!!i.match(s)))},N=(t,e)=>{let s,i=t.className;if(!i||!A(t,e))return!1;s=t.classList,s?.remove?s.remove(e):(i=C(i.replace(e,"")),t.className=i)},M=(e,s=!0,i=!0)=>{const r="outline-heading",l=e.innerHTML;let n;if(e.innerHTML=l.replace(/^\d+(?:(\.?\d*)*\s?)?/gi,""),e.removeAttribute("id"),e.removeAttribute("data-id"),N(e,r),!s)return!1;var o;n=e.querySelector(`.${r}__anchor`),i&&N(e,`${r}_start`),o=C(e.className),t(o)&&""===o&&e.removeAttribute("class"),e.removeChild(n)},D=(e,s=!0)=>{const i=[];let r=1,l=0;return e.forEach(((e,s)=>{const n=e.tagName.replace(/h/i,"");let o=parseInt(n,10),h=-1;var a;o>r?(l+=1,h=1===l?-1:s-1):o===r||ol?1===o?(l=1,h=-1):h=i[s-1].pid:o<=l&&(1===o?l=1:(l-=r-o,l<=1&&(l=1)),h=1===l?-1:((t,e,s)=>{let i,r,l=t[s-1];for(r=0;r]+(>|$)/g,""):"")})})),s?(t=>{const e={};return t.forEach((t=>{const s=JSON.stringify((t=>[t.pid])(t));e[s]=e[s]||[],e[s].push(t),t.index=e[s].length,-1===t.pid&&(t.code=String(t.index))})),Object.keys(e).forEach((s=>{e[s].forEach(((e,s)=>{e.index=s+1,t.forEach((t=>{t.pid===e.id&&(t.code=e.code+"."+t.index)}))}))})),t})(i):i};class H extends l{constructor(t){super(),this.attrs=H.DEFAULTS,this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],t&&this.initialize(t)}initialize(e){let s,r,l,o,h;return this.attr(e),h=this.attr("articleElement"),r=this.attr("scrollElement"),l=this.attr("selector"),s=this.attr("created"),t(h)?o=document.querySelector(h):n(h)&&(o=h),o?(this.$articleElement=o,this.$scrollElement=a(r),this.$headings=[...o.querySelectorAll(l)],this.$headings.length<1||(this.chapters=D(this.$headings),i(s)&&s.call(this),this.render().addListeners()),this):this}getChapters(t=!1){const e=this.chapters;return t?((t,e,s)=>{const i={},r=[];return t.forEach(((t,s)=>{i[t[e]]=s,t.children=[]})),t.forEach((e=>{const l=t[i[e[s]]];-1!==e[s]?l.children.push(e):r.push(e)})),r})(e,"id","pid"):e}count(){return this.chapters.length}render(){const t=this.attr("mounted"),e=this.attr("hasAnchor"),s=this.attr("isAtStart"),r=this.attr("showCode"),l=this.attr("anchorURL"),n=this.$headings,o=this.getChapters();return L(),n.forEach(((t,i)=>{const n=o[i].code;((t,e,s)=>{const i="outline-heading",r=s.hasAnchor||!0,l=s.isAtStart||!0,n=s.showCode||!1,o=s.chapterCode||"",h=s.anchorURL||"",a=`heading-${e}`,c={id:a,className:l?`${i} ${i}_start`:i,"data-id":e},d=Object.keys(c),u=C(t.innerHTML);let p,m;if(d.forEach((e=>{z(t,e,c[e])})),n&&(t.innerHTML=o+" "+u),!r)return!1;m=S("hash"),p=k("a",{id:`anchor-${e}`,className:`${i}__anchor anchor-${e}`,href:h||`#${a}`,target:h?"_blank":"self","data-id":e},[m]),t.appendChild(p)})(t,i,{hasAnchor:e,isAtStart:s,showCode:r,chapterCode:n,anchorURL:l})})),i(t)&&t.call(this),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}destroy(){const t=this.attr("hasAnchor"),e=this.attr("isAtStart"),s=this.attr("beforeDestroy"),r=this.attr("afterDestroy"),l=this.$headings;return i(s)&&s.call(this),this.removeListeners(),l.forEach((s=>{M(s,t,e)})),this.attr(H.DEFAULTS),this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],i(r)&&r.call(this),this}onAnchorTrigger(t){const e=this.attr("anchorURL"),s=this.attr("afterScroll"),r=this.attr("stickyHeight"),l=t.delegateTarget.parentNode,n=d(l)-(r+10),h=this.$scrollElement,a=h.scrollHeight-h.clientHeight;return this.scrollTo(n,(()=>{i(s)&&s.call(this,"anchor"),o((()=>{T("toolbar:update",{top:n,min:0,max:a})}))})),e||$(t),this}addListeners(){const t=this.$articleElement;return b(t,".outline-heading__anchor","click",this.onAnchorTrigger,this,!0),this}removeListeners(){const t=this.$articleElement;return y(t,"click",this.onAnchorTrigger),this}}H.DEFAULTS={scrollElement:"html,body",articleElement:"#article",selector:"h1,h2,h3,h4,h5,h6",stickyHeight:0,anchorURL:"",hasAnchor:!0,isAtStart:!0,showCode:!1,created:null,mounted:null,afterScroll:null,beforeDestroy:null,afterDestroy:null};const j=(t,e)=>{let s,i;if(A(t,e))return!1;s=t.classList,s?.add?s.add(e):(i=t.className,i+=i.length>0?" "+e:e,t.className=i)},O=(t,e)=>{document.documentElement.style.setProperty(t,e)};let F=2e3;const U=t=>(t?F=t:F+=1,O("--outline-zIndex",`${F}`),F);class I extends l{constructor(t){super(),this.attrs=I.DEFAULTS,this.title="",this.closed=!0,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,this.zIndex=0,t&&this.initialize(t)}initialize(t){let e;return this.attr(t),this.title=this.attr("title"),e=this.attr("created"),i(e)&&e.call(this),this.render().addListeners(),this}setTitle(t){return this.attr("title",t),this.title=t,this.$title.innerHTML=t,this}isClosed(){return this.closed}render(){const t=this.attr("mounted"),e=this.attr("size"),s=this.attr("placement"),r=this.attr("hasClose"),l=this.attr("hasOverlay"),n=this.attr("hasOffset"),o=this.attr("hasPadding"),h=this.attr("autoHeight"),a=this.attr("customClass"),c=document.createDocumentFragment();let d,u,p,m,f,g,y,b;return L(),this.zIndex=U(),m=k("h2",{className:"outline-drawer__title"},[this.title]),this.$title=m,r&&(f=k("div",{className:"outline-drawer__close"},[S("close",20)]),this.$close=f),p=k("header",{className:"outline-drawer__header"},[m,f]),this.$header=p,g=k("div",{className:"outline-drawer__main"},[""]),this.$main=g,o||j(g,"outline-drawer_full"),y=k("footer",{className:"outline-drawer__footer"},[""]),this.$footer=y,u=k("div",{className:`outline-drawer__modal outline-drawer_${s} outline-drawer_${e} outline-drawer_closed`},[p,g,y]),this.$modal=u,n&&j(u,"outline-drawer_offset"),h&&j(u,"outline-drawer_auto"),a&&j(u,a),l&&(b=k("div",{className:"outline-drawer__overlay"},[""]),this.$overlay=b),d=k("div",{className:"outline-drawer"},[u,b]),this.$el=d,c.appendChild(d),document.body.appendChild(c),i(t)&&t.call(this),this}open(){const t=this.attr("afterOpened"),e=this.$modal;return j(this.$el,"outline-drawer_opened"),N(e,"outline-drawer_closed"),j(e,"outline-drawer_opened"),o((()=>{this.closed=!1,i(t)&&t.call(this)})),this}close(){const t=this.attr("afterClosed"),e=this.$modal;return N(e,"outline-drawer_opened"),j(e,"outline-drawer_closed"),o((()=>{N(this.$el,"outline-drawer_opened"),this.closed=!0,i(t)&&t.call(this)})),this}toggle(){const t=this.attr("afterToggle"),e=this.isClosed();return e?this.open():this.close(),i(t)&&o((()=>{t.call(this,e)})),this}destroy(){const t=this.attr("afterDestroy"),e=this.attr("beforeDestroy");let s=this.zIndex;return i(e)&&e.call(this),this.removeListeners(),this.attrs=I.DEFAULTS,this.title="",this.closed=!1,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,s-=1,U(s),this.zIndex=0,i(t)&&t.call(this),this}addListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t&&b(s,".outline-drawer__close","click",this.onClose,this,!0),e&&b(s,".outline-drawer__overlay","click",this.onClose,this,!0),this}removeListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t||e?(y(s,"click",this.onClose),this):this}onClose(){return this.close(),this}}I.DEFAULTS={placement:"rtl",title:"标题",size:"regular",hasClose:!0,hasOverlay:!0,hasOffset:!1,hasPadding:!0,autoHeight:!0,created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterToggle:null};const q=(t,e,s,r,l,n=!1)=>{const o=m.indexOf(e)>-1,h=function(i){let o=l||t;!0===l&&(o=r),!0===n&&y(t,e,h),s.call(o,i,r)};if(!i(s))return!1;t._listeners||(t._listeners=[]),t._listeners.push({el:t,type:e,fn:h,data:r,context:l,capture:o}),s._delegateListener=h,t.addEventListener(e,h,o)};class B extends l{constructor(t){super(),this.attrs=B.DEFAULTS,this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.closed=!1,this.active=0,this.offsetTop=0,this.offsetWidth=0,this.$active=null,this.scrollTimer=null,this.resizeTimer=null,this.playing=!1,t&&this.initialize(t)}initialize(e){let s,r,l,o;return this.attr(e),s=this.attr("created"),r=this.attr("parentElement"),l=this.attr("scrollElement"),t(r)?o=document.querySelector(r):n(r)&&(o=r),this.$parentElement=o,this.$scrollElement=a(l),this.chapters=this.attr("chapters"),this.closed=this.attr("closed"),this.active=this.attr("active"),i(s)&&s.call(this),this.chapters.length<1||(this.render().addListeners(),this.$active=document.querySelector(`#chapter-${this.active}`)),this}isClosed(){return this.closed}isSticky(){return"sticky"===this.attr("position")}isFixed(){return"fixed"===this.attr("position")}isInside(){return this.isFixed()||this.isSticky()}isOutside(){return!this.isInside()}_paintEdge(){const t=this.attr("title"),e=this.attr("customClass"),s=this.$parentElement,i=[];let r,l,n,o,h=null;return s?(this.isInside()&&(h=k("h2",{className:"outline-chapters__title"},[t]),this.$title=h,i.push(h)),n=k("ul",{className:"outline-chapters__list outline-chapters_fixed outline-chapters_hidden"},[""]),this.$list=n,o=k("div",{className:"outline-chapters__placeholder"},[""]),this.$placeholder=o,l=k("div",{className:"outline-chapters__main"},[n,o]),this.$main=l,i.push(l),r=k("nav",{id:"outline-chapters",className:"outline-chapters"},i),this.$el=r,this.isSticky()&&(this.calculateStickyHeight(),j(r,"outline-chapters_sticky")),e&&j(r,e),s.appendChild(r),this):this}render(){const t=this.attr("showCode"),e=this.attr("mounted");let s,r;return this.$parentElement?(this._paintEdge(),r=this.$list,((t,e,s=!1)=>{const i=t=>document.getElementById(t);e.forEach((e=>{const r=e.pid,l=e.id,n=e.rel,o=k("span",{className:"outline-chapters__text"},[e.text]),h=k("a",{id:`chapter__anchor-${l}`,className:"outline-chapters__anchor",href:"#"+n,rel:n,"data-id":l},[o]);let a,c,d,u;s&&(a=k("span",{className:"outline-chapters__code","data-id":l},[e.code]),h.insertBefore(a,h.firstChild)),c=k("li",{id:`chapter-${l}`,className:"outline-chapters__item","data-id":l},[h]),-1===r?t.appendChild(c):(u=i(`chapter-${r}`),d=i(`subject-${r}`),d?d.appendChild(c):(d=k("ul",{id:"subject-"+r,className:"outline-chapters__subject"},[c]),u.appendChild(d)))}))})(r,this.chapters,t),N(r,"outline-chapters_fixed"),N(r,"outline-chapters_hidden"),s=this.$el,this.offsetTop=d(s),this.offsetWidth=s.offsetWidth,this.isFixed()&&(this.sticky(),O("--outline-chapters-width",`${this.offsetWidth}px`)),i(e)&&e.call(this),this.onObserver(),this):this}highlight(t){const e=this.$el.querySelector(`#chapter__anchor-${t}`),s="outline-chapters_active",i=this.$placeholder;let r;return this.$active&&N(this.$active,s),this.active=parseInt(e.getAttribute("data-id"),10),this.$active=e,j(this.$active,s),r=30*this.active,i.style.top=`calc(0.5em + ${r}px)`,this}sticky(){const t=this.attr("afterSticky"),e="outline-chapters_fixed",s=this.$el,r=this.offsetTop,l=this.$scrollElement.scrollTop;let n;return this.isFixed()?(n=!!(l>=r),n?j(s,e):N(s,e),i(t)&&t.call(this,this.isClosed(),n),this):this}calculateStickyHeight(){const t=document.documentElement,e=Math.max(t.clientHeight||0,window.innerHeight||0);return O("--outline-sticky-height",`${e}px`),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}show(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterOpened"),r=this.$el,l=this.$parentElement;return this.isInside()?(N(l,e),N(r,e),o((()=>{N(l,t),N(r,t)}),30)):N(r,e),this.closed=!1,i(s)&&s.call(this),this}hide(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterClosed"),r=this.$el,l=this.$parentElement;return this.isInside()?(j(l,t),j(r,t),o((()=>{j(l,e),j(r,e)}))):j(r,e),this.closed=!0,i(s)&&s.call(this),this}toggle(){const t=this.attr("afterToggle"),e=this.offsetTop,s=this.$scrollElement.scrollTop;let r;return this.isClosed()?this.show():this.hide(),i(t)&&o((()=>{r=!!(s>=e),t.call(this,this.isClosed(),r)})),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");return i(t)&&t.call(this),this.removeListeners(),this.$parentElement.removeChild(this.$el),this.attr(B.DEFAULTS),this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.active=0,this.offsetTop=0,this.$active=null,this.closed=!1,this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),i(e)&&e.call(this),this}onObserver(){let t=null;return((t,e={})=>{const s=e.root||null,r=e.selector||".outline-heading",l=e.context||null,o={rootMargin:e.rootMargin||"0px 0px -90% 0px"},h=new IntersectionObserver((e=>{e.forEach((e=>{e.intersectionRatio>0&&i(t)&&t.call(l||e.target,e.target)}))}),o),a=n(s)?s:document;s&&(o.root=s),a.querySelectorAll(r).forEach((t=>{h.observe(t)}))})((e=>{const s=e.getAttribute("data-id");if(this.playing)return!1;t&&clearTimeout(t),t=o((()=>{this.highlight(s)}),100)}),{context:this}),this}onSelect(t){const e=this.attr("stickyHeight"),s=t.delegateTarget,r=s.getAttribute("data-id"),l=s.href.split("#")[1],n=document.querySelector(`#${l}`),h=d(n)-(e+10),a=this.$scrollElement.scrollHeight,c=this.attr("afterScroll"),u=()=>{i(c)&&c.call(this,"chapter"),o((()=>{this.playing=!1,T("toolbar:update",{top:h,min:0,max:a})}))};return this.playing=!0,this.isFixed()?(this.sticky(),o((()=>{this.scrollTo(h,u),this.highlight(r)}),10)):(this.scrollTo(h,u),this.highlight(r)),$(t),this}onScroll(){const t=this.$scrollElement;return this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=o((()=>{const e=t.scrollTop,s=t.scrollHeight-t.clientHeight;this.isFixed()&&this.sticky(),T("toolbar:update",{top:e,min:0,max:s})}),50),this}onResize(){return this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=o((()=>{this.calculateStickyHeight()})),this}addListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),b(t,".outline-chapters__anchor","click",this.onSelect,this,!0),q(i,"scroll",this.onScroll,this,!0),this.isSticky()&&q(i,"resize",this.onResize,this,!0),this}removeListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),y(t,"click",this.onSelect),y(i,"scroll",this.onScroll),this.isSticky()&&q(i,"resize",this.onResize),this}}B.DEFAULTS={parentElement:"",scrollElement:"",selector:"",active:0,closed:!1,showCode:!0,position:"relative",stickyHeight:0,chapters:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterSticky:null};const R=(t,e=!0)=>{const s=S(t.icon,t.size),i=k("a",{className:"outline-toolbar__anchor",href:t.link},[s]),r=k("div",{className:`outline-toolbar__button ${t.name}`},[t.link?i:s]);return j(s,"outline-toolbar__icon"),e&&j(r,"outline-toolbar_rounded"),t.disabled&&j(r,"outline-toolbar_disabled"),r},P="outline-toolbar_disabled",Q="outline-toolbar_hidden";class V extends l{constructor(t){super(),this.attrs=V.DEFAULTS,this.$el=null,this.disabled=!1,this.closed=!1,this.buttons=[],t&&this.initialize(t)}initialize(t){let e;return this.attr(t),e=this.attr("created"),this.disabled=this.attr("disabled"),this.closed=this.attr("closed"),i(e)&&e.call(this),this.render().addListeners(),this}isDisabled(t){const e=this.attr("buttons");let s;return t?(s=e.find((e=>e.name===t)),!(!s||!s.disabled)):this.disabled}isClosed(){return this.closed}highlight(t){const e=this.buttons.find((e=>e.name===t)),s="outline-toolbar_active";let i;return i||(i=e.$el,A(i,s)?N(i,s):j(i,s)),this}render(){const t=this.attr("mounted"),e=this.attr("buttons")||[],s=this.attr("rounded"),r=this.attr("placement"),l=document.createDocumentFragment(),n=document.createDocumentFragment();return L(),e.forEach((t=>{const e=R(t,s);l.appendChild(e),this.buttons.push({name:t.name,$el:e})})),this.$el=k("div",{id:"outline-toolbar",className:`outline-toolbar outline-toolbar_${r}`},[l]),n.appendChild(this.$el),document.body.appendChild(n),this.closed&&this.hide(),this.disabled&&this.disable(),i(t)&&t.call(this),this}add(t){const e=this.$el,s=this.attr("buttons"),l=t.action,n=document.createDocumentFragment();let o;return r(t)?(s.push(t),n.appendChild(R(t))):w(t)&&t.forEach((t=>{n.appendChild(R(t))})),e.appendChild(n),l&&i(l.handler)&&(o=l.type||"click",b(e,`.${t.name}`,o,l.handler)),this}remove(t){const e=this.$el,s=this.attr("buttons"),i=s.find((e=>e.name===t));let r,l=-1;return i?(s.forEach(((e,s)=>{e.name===t&&(l=s)})),l>-1&&this.attr().buttons.splice(l,1),r=e.querySelector(`.${t}`),this.switch(t,!1),e.removeChild(r),this):this}switch(t,e){const s=this.$el,i=this.attr("buttons"),r=i.find((e=>e.name===t));let l,n,o,h;return r?(i.forEach((s=>{s.name===t&&(r.disabled=!e)})),l=r.action,h=s.querySelector(`.${t}`),l&&(n=l.type||"click",o=l.handler),e?(N(h,P),n&&o&&b(s,`.${t}`,n,o)):(j(h,P),n&&o&&y(s,n,o)),this):this}disable(t){const e=this.attr("afterDisabled");return t?this.switch(t,!1):(j(this.$el,P),this.removeListeners(),this.disabled=!0,i(e)&&e.call(this)),this}enable(t){const e=this.attr("afterEnabled");return t?this.switch(t,!0):(this.disabled=!1,N(this.$el,P),this.addListeners(),i(e)&&e.call(this)),this}show(t){const e=this.attr("afterOpened"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),N(l,Q)}else N(r,Q),this.closed=!1,i(e)&&o((()=>{e.call(this)}),310);return this}hide(t){const e=this.attr("afterClosed"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),j(l,Q)}else j(r,Q),this.closed=!0,i(e)&&o((()=>{e.call(this)}),310);return this}toggle(){return this.isClosed()?this.show():this.hide(),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");let s=this.$el;return i(t)&&t.call(this),this.removeListeners(),document.body.removeChild(s),s=null,this.attr(V.DEFAULTS),this.disabled=!1,this.closed=!1,this.buttons=[],i(e)&&e.call(this),this}refresh(){const t=this.$el,e=this.attr("buttons")||[];return this.removeListeners(),t.innerHTML="",e.forEach((t=>{this.$el.appendChild(R(t))})),this.addListeners(),this}addListeners(){const e=this.attr("buttons"),s=this.$el;return!e||e.length<1||e.forEach((e=>{const r=e.action;let l,n,o,h;if(this.disabled)return!1;r&&(n=r.handler,t(n)&&(h=n,r.handler=function(){T(h,e.name)},n=r.handler),l=r.type||"click",o=r.context),i(n)&&b(s,`.${e.name}`,l,n,o||this,!0)})),this}removeListeners(){const t=this.attr("buttons"),e=this.$el;return!t||t.length<1||t.forEach((t=>{const s=t.action;let r,l;if(this.disabled)return!1;s&&(l=s.handler,r=s.type||"click"),i(l)&&y(e,r,l)})),this}}V.DEFAULTS={placement:"ltr",closed:!1,disabled:!1,rounded:!0,buttons:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterDisabled:null,afterEnabled:null,beforeDestroy:null,afterDestroy:null};const W=(()=>{let t=0;return e=>(t+=1,e?e+"-"+t:"guid-"+t)})(),J=(t,e,s=null)=>{const r=W();let l="symbol"==typeof t?t.toString():t;return!!i(e)&&(v[l]||(v[l]=[]),v[l].push({topic:l,callback:e,context:s,token:r}),r)},G=t=>{if(!e(v,t))return!1;delete v[t]},K=(t,e)=>{if(!_(t))return!1;e?(t=>{const e=Object.keys(v);if(!t||e.length<1)return!1;e.forEach((e=>{const s=v[e];let i;s.forEach(((e,r)=>{e.callback!==t&&e.token!==t||(i=e.topic,s.splice(-1,r))})),s.length<1&&G(i)}))})(e):G(t)};class X extends l{constructor(t){super(),this.attrs=X.DEFAULTS,this.anchors=null,this.drawer=null,this.chapters=null,this.toolbar=null,t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}getChapters(t=!1){return this.anchors.getChapters(t)}count(){return this.anchors.count()}render(){return this._renderAnchors()._renderChapters()._renderToolbar(),this}_renderAnchors(){const t=this.attr("articleElement"),e=this.attr("selector"),s=this.attr("stickyHeight"),i=this.attr("scrollElement"),r=this.attr("showCode"),l=this.attr("anchorURL"),n=this.attr("afterScroll");return this.anchors=new H({articleElement:t,stickyHeight:s,scrollElement:i,selector:e,showCode:r,anchorURL:l,afterScroll:n}),this}_renderChapters(){const t=this.attr("title"),e=this.attr("stickyHeight"),s=this.attr("scrollElement"),i=this.attr("customClass"),r=this.attr("showCode"),l=this.attr("position"),n=this.attr("placement"),o=this.attr("afterSticky"),h=this.attr("afterToggle"),a=this.attr("afterScroll"),c=this.count();let d,u=this.attr("parentElement");return c<1||(d={scrollElement:s,showCode:r,position:l,title:t,stickyHeight:e,chapters:this.anchors.getChapters(),afterSticky:o,afterToggle:h,afterScroll:a},"relative"===l?(this.drawer=new I({placement:n,title:t,size:"tiny",hasOffset:!0,hasPadding:!1,customClass:i,afterClosed:()=>{this.toolbar.toggle()}}),u=this.drawer.$main):d.customClass=i,d.parentElement=u,this.chapters=new B(d)),this}_renderToolbar(){const t=this.attr("placement"),e=this.attr("homepage"),s=this.count(),i={name:"homepage",icon:"homepage",size:20,link:e},r={name:"menu",icon:"menu",size:18,action:{type:"click",handler:"toolbar:action:toggle"}},l=[];return l.push({name:"up",icon:"up",size:20,action:{type:"click",handler:"toolbar:action:up"}}),e&&l.push(i),s>0&&l.push(r),l.push({name:"down",icon:"down",size:20,action:{type:"click",handler:"toolbar:action:down"}}),this.toolbar=new V({placement:t,buttons:l}),this}toTop(){const t=this.attr("afterScroll"),e=this.toolbar,s=this.chapters,r=this.count();return s.playing=!0,this.scrollTo(0,(()=>{e.hide("up"),e.show("down"),r>0&&s.highlight(0),s.playing=!1,i(t)&&t.call(e,"up")})),this}toBottom(){const t=this.attr("afterScroll"),e=a(this.attr("scrollElement")),s=this.toolbar,r=this.chapters,l=this.count(),n=Math.floor(e.scrollHeight-e.clientHeight);return r.playing=!0,this.scrollTo(n,(()=>{s.hide("down"),s.show("up"),l>1&&r.highlight(l-1),r.playing=!1,i(t)&&t.call(s,"bottom")})),this}scrollTo(t,e){const s=this.attr("scrollElement");return c(s,t,e),this}toggle(){const t=this.attr("position"),e=this.toolbar,s=this.drawer,i=this.chapters,r=this.count();if("relative"!==t)i.toggle(),e.highlight("menu");else{if(e.toggle(),r<1)return this;o((()=>{i.isInside()?i.toggle():s.toggle()}))}return this}destroy(){const t=this.chapters,e=this.count();return this.removeListeners(),this.attr(X.DEFAULTS),this.anchors.destroy(),e<1&&(t.destroy(),t.isOutside()&&this.drawer.destroy()),this.toolbar.destroy(),this}onToggle(){return this.toggle(),this}onScrollTop(){return this.toTop(),this}onScrollBottom(){return this.toBottom(),this}onToolbarUpdate({top:t,min:e,max:s}){const i=this.toolbar,r=Math.ceil(t);return r<=e?(i.hide("up"),i.show("down")):r>=s?(i.hide("down"),i.show("up")):r>e&&r {\r\n  return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n  const hasOwnProperty = Object.prototype.hasOwnProperty\r\n  return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n  return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n  return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n  return (\r\n    (toString(o) === '[object Object]' ||\r\n      typeof o === 'object' ||\r\n      isFunction(o)) &&\r\n    o !== null\r\n  )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n  constructor(options) {\r\n    this.attrs = {}\r\n\r\n    if (options) {\r\n      this.initialize(options)\r\n    }\r\n  }\r\n\r\n  initialize(options) {\r\n    this.attr(options).render().addListeners()\r\n    return this\r\n  }\r\n\r\n  attr(prop, value) {\r\n    const attrs = this.attrs\r\n\r\n    if (isString(prop)) {\r\n      // 只能扩展 attrs 中已有的属性\r\n      if (value && hasOwn(attrs, prop)) {\r\n        // 更新单个配置信息\r\n        attrs[prop] = value\r\n        return this\r\n      }\r\n\r\n      // 只传递 prop 参数,则返回对应的属性值\r\n      return attrs[prop]\r\n    } else if (isObject(prop)) {\r\n      // 批量更新配置信息\r\n      extend(attrs, prop)\r\n\r\n      return this\r\n    } else if (arguments.length === 0) {\r\n      // 不传递参数,直接返回整个\r\n      return attrs\r\n    }\r\n\r\n    return this\r\n  }\r\n\r\n  render() {\r\n    return this\r\n  }\r\n\r\n  destroy() {\r\n    this.removeListeners()\r\n    return this\r\n  }\r\n\r\n  reload(options) {\r\n    this.destroy().initialize(this.attr(options))\r\n    return this\r\n  }\r\n\r\n  addListeners() {\r\n    return this\r\n  }\r\n\r\n  removeListeners() {\r\n    return this\r\n  }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n  const keys = Object.keys(source)\r\n\r\n  keys.forEach((prop) => {\r\n    if (hasOwn(source, prop)) {\r\n      origin[prop] = source[prop]\r\n    }\r\n  })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n  return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n  if (!isFunction(fn)) {\r\n    return false\r\n  }\r\n\r\n  return setTimeout(() => {\r\n    fn()\r\n  }, delay)\r\n}\r\n\r\nexport default later\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n  return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n  let $rootElements\r\n  let $scrollElement\r\n\r\n  if (!scrollElement) {\r\n    $rootElements = document.querySelectorAll('html,body')\r\n    $scrollElement =\r\n      $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n        ? $rootElements[0]\r\n        : $rootElements[1]\r\n  } else {\r\n    if (isString(scrollElement)) {\r\n      $scrollElement = document.querySelector(scrollElement)\r\n    } else if (isElement(scrollElement)) {\r\n      $scrollElement = scrollElement\r\n    }\r\n  }\r\n\r\n  return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n  const $scrollElement = _getScrollElement(scrollElement)\r\n  let scrollTop = $scrollElement.scrollTop\r\n  let step = 0\r\n  const distance = top - scrollTop\r\n  const MAX_HEIGHT = $scrollElement.scrollHeight\r\n  const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n  const stop = (top) => {\r\n    if (isFunction(afterStop)) {\r\n      afterStop(top)\r\n    }\r\n\r\n    return false\r\n  }\r\n  const play = () => {\r\n    step += 1\r\n\r\n    // 向上滚动\r\n    if (distance < 0) {\r\n      scrollTop -= easeInQuad(step)\r\n      $scrollElement.scrollTop = scrollTop\r\n\r\n      if (scrollTop <= top) {\r\n        $scrollElement.scrollTop = top\r\n        return stop(top)\r\n      }\r\n    } else {\r\n      scrollTop += easeInQuad(step)\r\n      $scrollElement.scrollTop = scrollTop\r\n\r\n      if (scrollTop >= MAX_TOP) {\r\n        $scrollElement.scrollTop = MAX_TOP\r\n        return stop(MAX_TOP)\r\n      }\r\n    }\r\n\r\n    requestAnimationFrame(play)\r\n  }\r\n\r\n  requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n  let top = el.offsetTop\r\n\r\n  if (el.offsetParent !== null) {\r\n    top += offsetTop(el.offsetParent)\r\n  }\r\n\r\n  return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n  const sel = selector.replace(/^>/i, '')\r\n\r\n  if (!selector || !sel || !el) {\r\n    return false\r\n  }\r\n\r\n  /* istanbul ignore else */\r\n  if (el.matches) {\r\n    return el.matches(sel)\r\n  } else if (el.msMatchesSelector) {\r\n    return el.msMatchesSelector(sel)\r\n  } else {\r\n    return false\r\n  }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n  return el.host && el !== document && el.host.nodeType\r\n    ? el.host\r\n    : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","export const CAPTURE_EVENTS = [\r\n  'focusout',\r\n  'blur',\r\n  'focusin',\r\n  'focus',\r\n  'load',\r\n  'unload',\r\n  'mouseenter',\r\n  'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n  const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n  /* istanbul ignore else */\r\n  if (fn._delegateListener) {\r\n    fn = fn._delegateListener\r\n    delete fn._delegateListener\r\n  }\r\n\r\n  // 移除缓存的 _listeners 数据\r\n  _delete(el, type, fn)\r\n\r\n  el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n  const listeners = el._listeners\r\n  let index = -1\r\n\r\n  if (listeners.length < 1) {\r\n    return false\r\n  }\r\n\r\n  // 移除缓存的 _listeners 数据\r\n  listeners.forEach((listener, i) => {\r\n    const handler = listener.fn\r\n\r\n    if (type === listener.type) {\r\n      index = i\r\n\r\n      if (handler === fn) {\r\n        index = i\r\n      }\r\n    }\r\n  })\r\n\r\n  /* istanbul ignore else */\r\n  if (index > -1) {\r\n    listeners.splice(index, 1)\r\n  }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n  const $element = isString(el) ? document.querySelector(el) : el\r\n  const $children = $element.childNodes\r\n  const listeners = getListeners($element, type)\r\n\r\n  listeners.forEach((listener) => {\r\n    _off($element, listener.type, listener.fn)\r\n  })\r\n\r\n  if (\r\n    (recurse || type === true || arguments.length === 1) &&\r\n    $element &&\r\n    $children\r\n  ) {\r\n    $children.forEach(($child) => {\r\n      if (isElement($child)) {\r\n        purgeElement($child, type, recurse)\r\n      }\r\n    })\r\n  }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n  let listeners = el._listeners || []\r\n\r\n  if (isString(type) && type) {\r\n    listeners = listeners.filter((listener) => {\r\n      return listener.type === type\r\n    })\r\n  }\r\n\r\n  return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n  // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n  if (!isFunction(fn)) {\r\n    return purgeElement(el, type)\r\n  }\r\n\r\n  _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n  // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n  const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n  const listener = function (evt) {\r\n    const target = getTarget(evt)\r\n    // 通过 Element.matches 方法获得点击的目标元素\r\n    const delegateTarget = closest(target, selector, el)\r\n    let overrideContext = context || el\r\n\r\n    evt.delegateTarget = delegateTarget\r\n\r\n    // 当设置为 true 时,则事件处理器回调函数的\r\n    // this 上下文指向为 data 对象\r\n    if (context === true) {\r\n      overrideContext = data\r\n    }\r\n\r\n    /* istanbul ignore else */\r\n    if (delegateTarget) {\r\n      // 仅触发一次\r\n      /* istanbul ignore else */\r\n      if (once === true) {\r\n        off(el, type, listener)\r\n      }\r\n\r\n      fn.call(overrideContext, evt, data)\r\n    }\r\n  }\r\n\r\n  if (!el._listeners) {\r\n    el._listeners = []\r\n  }\r\n\r\n  // 缓存 options 元素绑定的事件处理器\r\n  el._listeners.push({\r\n    el,\r\n    selector,\r\n    type,\r\n    fn: listener,\r\n    data,\r\n    context,\r\n    capture\r\n  })\r\n\r\n  // 缓存包装后的事件处理器\r\n  fn._delegateListener = listener\r\n\r\n  el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n  const target = evt.target\r\n\r\n  return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n  if (el && el.nodeType === 3) {\r\n    return el.parentNode\r\n  }\r\n\r\n  return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n  const context = ctx || document\r\n\r\n  if (!el) {\r\n    return null\r\n  }\r\n\r\n  do {\r\n    /* istanbul ignore else */\r\n    if (\r\n      (selector != null &&\r\n        (selector[0] === '>'\r\n          ? el.parentNode === context && matches(el, selector)\r\n          : matches(el, selector))) ||\r\n      (includeCTX && el === context)\r\n    ) {\r\n      return el\r\n    }\r\n\r\n    /* istanbul ignore else */\r\n    if (el === context) {\r\n      break\r\n    }\r\n\r\n    /* jshint boss:true */\r\n  } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n * 
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isArray from './types/isArray'\r\n\r\n/**\r\n * 绘制 SVG Sprites 图标集\r\n * ========================================================================\r\n * @method paintSvgSprites\r\n * @param {Array} [symbols] - (可选)symbols 图标数组\r\n * 传递 symbols - 绘制 symbols + SYMBOLS 的图标集\r\n * 不传递 symbols - 仅绘制默认 SYMBOLS 图标集\r\n */\r\nexport const paintSvgSprites = (symbols = []) => {\r\n const SYMBOLS = [\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n ''\r\n ]\r\n const sprites =\r\n isArray(symbols) && symbols.length > 0 ? SYMBOLS.concat(symbols) : SYMBOLS\r\n const $body = document.body\r\n let $icons = document.querySelector('#svg-sprites')\r\n\r\n if ($icons) {\r\n $icons.innerHTML = sprites.join('')\r\n } else {\r\n $icons = document.createElement('div')\r\n $icons.innerHTML =\r\n ``\r\n $body.insertBefore($icons.firstChild, $body.firstChild)\r\n }\r\n}\r\n\r\n/**\r\n * 创建 SVG 图标 DOM 元素\r\n * ========================================================================\r\n * @method createSvgIcon\r\n * @param {String} name\r\n * @param {Number|String|Array} [size]\r\n * @param {String} [color]\r\n * @param {String} [iconSet]\r\n * @returns {HTMLElement}\r\n */\r\nexport const createSvgIcon = (\r\n name,\r\n size = 0,\r\n color = '',\r\n iconSet = 'outline'\r\n) => {\r\n const binds = iconSet\r\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\r\n : `xlink:href=\"#icon-${name}\"`\r\n const width = isArray(size) ? size[0] : size\r\n const height = isArray(size) ? size[1] : size\r\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\r\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\r\n const svg =\r\n `` +\r\n `` +\r\n ``\r\n const $icon = document.createElement('i')\r\n\r\n $icon.className = 'outline-icon'\r\n $icon.innerHTML = svg\r\n\r\n return $icon\r\n}\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import removeClass from './utils/dom/removeClass'\r\nimport isEmpty from './utils/types/isEmpty'\r\nimport trim from './utils/lang/trim'\r\n\r\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const text = $heading.innerHTML\r\n let $anchor\r\n\r\n $heading.innerHTML = text.replace(/^\\d+(?:(\\.?\\d*)*\\s?)?/gi, '')\r\n $heading.removeAttribute('id')\r\n $heading.removeAttribute('data-id')\r\n\r\n removeClass($heading, CLS_HEADING)\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\r\n\r\n if (isAtStart) {\r\n removeClass($heading, `${CLS_HEADING}_start`)\r\n }\r\n\r\n if (isEmpty(trim($heading.className))) {\r\n $heading.removeAttribute('class')\r\n }\r\n\r\n $heading.removeChild($anchor)\r\n}\r\n\r\nexport default _resetHeading\r\n","import isString from './isString'\r\n/**\r\n * 检测数据是否为空字符串\r\n * ========================================================================\r\n * @method isEmpty\r\n * @param {String} str\r\n * @returns {boolean}\r\n */\r\nconst isEmpty = (str) => {\r\n return isString(str) && str === ''\r\n}\r\n\r\nexport default isEmpty\r\n","import trim from './utils/lang/trim'\r\nimport stripTags from './utils/lang/stripTags'\r\n\r\nimport _getChaptersWithCode from './_getChaptersWithCode'\r\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\r\n\r\nconst getChapters = (headings, showCode = true) => {\r\n const chapters = []\r\n let previous = 1\r\n let level = 0\r\n\r\n headings.forEach((heading, i) => {\r\n const headingLevel = heading.tagName.replace(/h/i, '')\r\n let current = parseInt(headingLevel, 10)\r\n let pid = -1\r\n\r\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\r\n // h2 (前一个标题)\r\n // h3 (当前标题)\r\n if (current > previous) {\r\n level += 1\r\n\r\n // 第一层级的 pid 是 -1\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n pid = i - 1\r\n }\r\n }\r\n // 当前标题的(标题标签)序号 = 前一个标题的序号\r\n // h2 (前一个标题)\r\n // h2 (当前标题)\r\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\r\n // h2\r\n // h4 (前一个标题)\r\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\r\n else if (current === previous || (current < previous && current > level)) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n pid = -1\r\n } else {\r\n pid = chapters[i - 1].pid\r\n }\r\n } else if (current <= level) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n } else {\r\n level = level - (previous - current)\r\n\r\n if (level <= 1) {\r\n level = 1\r\n }\r\n }\r\n\r\n // 第一级的标题\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\r\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\r\n }\r\n }\r\n\r\n previous = current\r\n\r\n chapters.push({\r\n id: i,\r\n pid: pid,\r\n level: level,\r\n rel: `heading-${i}`,\r\n text: stripTags(trim(heading.innerHTML))\r\n })\r\n })\r\n\r\n return showCode ? _getChaptersWithCode(chapters) : chapters\r\n}\r\n\r\nexport default getChapters\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 过滤所有 HTML 标签\r\n * ========================================================================\r\n * @method stripTags\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nconst stripTags = (str) => {\r\n if (!isString(str)) {\r\n return ''\r\n }\r\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\r\n}\r\n\r\nexport default stripTags\r\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\r\n let previous = chapters[index - 1]\r\n let pid\r\n let i\r\n\r\n for (i = 0; i < differ; i += 1) {\r\n pid = previous.pid\r\n previous = chapters[pid]\r\n }\r\n\r\n pid = previous.pid\r\n\r\n return pid\r\n}\r\n\r\nexport default _getChapterParentIdByDiffer\r\n","const _getChaptersWithCode = (chapters) => {\r\n const groups = {}\r\n const cb = (o) => {\r\n return [o.pid]\r\n }\r\n\r\n chapters.forEach((o) => {\r\n const group = JSON.stringify(cb(o))\r\n\r\n groups[group] = groups[group] || []\r\n groups[group].push(o)\r\n\r\n o.index = groups[group].length\r\n if (o.pid === -1) {\r\n o.code = String(o.index)\r\n }\r\n })\r\n\r\n Object.keys(groups).forEach((group) => {\r\n groups[group].forEach((c, i) => {\r\n c.index = i + 1\r\n chapters.forEach((o) => {\r\n if (o.pid === c.id) {\r\n o.code = c.code + '.' + o.index\r\n }\r\n })\r\n })\r\n })\r\n\r\n return chapters\r\n}\r\n\r\nexport default _getChaptersWithCode\r\n","import Base from './base'\r\n\r\n// 在文章的标题生成 anchor 链接\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport toTree from './utils/lang/toTree'\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _updateHeading from './_updateHeading'\r\nimport _resetHeading from './_resetHeading'\r\nimport getChapters from './getChapters'\r\n\r\nclass Anchors extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Anchors.DEFAULTS\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n\r\n this.chapters = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let scrollElement\r\n let selector\r\n let $articleElement\r\n let articleElement\r\n\r\n this.attr(options)\r\n articleElement = this.attr('articleElement')\r\n scrollElement = this.attr('scrollElement')\r\n selector = this.attr('selector')\r\n created = this.attr('created')\r\n\r\n if (isString(articleElement)) {\r\n $articleElement = document.querySelector(articleElement)\r\n } else if (isElement(articleElement)) {\r\n $articleElement = articleElement\r\n }\r\n\r\n if (!$articleElement) {\r\n return this\r\n }\r\n\r\n this.$articleElement = $articleElement\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n this.$headings = [...$articleElement.querySelectorAll(selector)]\r\n\r\n if (this.$headings.length < 1) {\r\n return this\r\n }\r\n\r\n this.chapters = getChapters(this.$headings)\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n const chapters = this.chapters\r\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const $headings = this.$headings\r\n const chapters = this.getChapters()\r\n\r\n paintSvgSprites()\r\n\r\n $headings.forEach(($heading, i) => {\r\n const chapterCode = chapters[i].code\r\n _updateHeading($heading, i, {\r\n hasAnchor,\r\n isAtStart,\r\n showCode,\r\n chapterCode,\r\n anchorURL\r\n })\r\n })\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n const $headings = this.$headings\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n $headings.forEach(($heading) => {\r\n _resetHeading($heading, hasAnchor, isAtStart)\r\n })\r\n\r\n this.attr(Anchors.DEFAULTS)\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n this.chapters = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onAnchorTrigger(evt) {\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const $heading = $anchor.parentNode\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const $scrollElement = this.$scrollElement\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this)\r\n }\r\n\r\n later(() => {\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.scrollTo(top, after)\r\n\r\n if (!anchorURL) {\r\n stop(evt)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n on(\r\n $articleElement,\r\n '.outline-heading__anchor',\r\n 'click',\r\n this.onAnchorTrigger,\r\n this,\r\n true\r\n )\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n off($articleElement, 'click', this.onAnchorTrigger)\r\n\r\n return this\r\n }\r\n}\r\n\r\nAnchors.DEFAULTS = {\r\n scrollElement: 'html,body',\r\n articleElement: '#article',\r\n selector: 'h1,h2,h3,h4,h5,h6',\r\n stickyHeight: 0,\r\n anchorURL: '',\r\n hasAnchor: true,\r\n isAtStart: true,\r\n showCode: false,\r\n created: null,\r\n mounted: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Anchors\r\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import trim from './utils/lang/trim'\r\nimport createElement from './utils/dom/createElement'\r\nimport setAttribute from './utils/dom/setAttribute'\r\n\r\nimport { createSvgIcon } from './utils/icons'\r\n\r\nconst _updateHeading = ($heading, i, options) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const hasAnchor = options.hasAnchor || true\r\n const isAtStart = options.isAtStart || true\r\n const showCode = options.showCode || false\r\n const chapterCode = options.chapterCode || ''\r\n const anchorURL = options.anchorURL || ''\r\n const headingId = `heading-${i}`\r\n const attrs = {\r\n id: headingId,\r\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\r\n 'data-id': i\r\n }\r\n const keys = Object.keys(attrs)\r\n const text = trim($heading.innerHTML)\r\n let $anchor\r\n let $icon\r\n\r\n keys.forEach((prop) => {\r\n setAttribute($heading, prop, attrs[prop])\r\n })\r\n\r\n if (showCode) {\r\n $heading.innerHTML = chapterCode + ' ' + text\r\n }\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $icon = createSvgIcon('hash')\r\n $anchor = createElement(\r\n 'a',\r\n {\r\n id: `anchor-${i}`,\r\n className: `${CLS_HEADING}__anchor anchor-${i}`,\r\n href: anchorURL ? anchorURL : `#${headingId}`,\r\n target: anchorURL ? '_blank' : 'self',\r\n 'data-id': i\r\n },\r\n [$icon]\r\n )\r\n $heading.appendChild($anchor)\r\n}\r\n\r\nexport default _updateHeading\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","import setProperty from './utils/dom/setProperty'\r\n\r\nlet index = 2000\r\n\r\nconst zIndex = (idx) => {\r\n if (idx) {\r\n index = idx\r\n } else {\r\n index += 1\r\n }\r\n\r\n setProperty('--outline-zIndex', `${index}`)\r\n\r\n return index\r\n}\r\n\r\nexport default zIndex\r\n","import Base from './base'\r\n\r\nimport later from './utils/lang/later'\r\nimport isFunction from './utils/types/isFunction'\r\nimport addClass from './utils/dom/addClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport createElement from './utils/dom/createElement'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\n\r\nimport { paintSvgSprites, createSvgIcon } from './utils/icons'\r\nimport zIndex from './zIndex'\r\n\r\nclass Drawer extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = true\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n this.zIndex = 0\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n\r\n this.title = this.attr('title')\r\n created = this.attr('created')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n return this\r\n }\r\n\r\n setTitle(title) {\r\n this.attr('title', title)\r\n this.title = title\r\n this.$title.innerHTML = title\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const size = this.attr('size')\r\n const placement = this.attr('placement')\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const hasOffset = this.attr('hasOffset')\r\n const hasPadding = this.attr('hasPadding')\r\n const autoHeight = this.attr('autoHeight')\r\n const customClass = this.attr('customClass')\r\n const $fragment = document.createDocumentFragment()\r\n let $el\r\n let $modal\r\n let $header\r\n let $title\r\n let $close\r\n let $main\r\n let $footer\r\n let $overlay\r\n\r\n paintSvgSprites()\r\n this.zIndex = zIndex()\r\n\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-drawer__title'\r\n },\r\n [this.title]\r\n )\r\n this.$title = $title\r\n\r\n if (hasClose) {\r\n $close = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__close'\r\n },\r\n [createSvgIcon('close', 20)]\r\n )\r\n this.$close = $close\r\n }\r\n\r\n $header = createElement(\r\n 'header',\r\n {\r\n className: 'outline-drawer__header'\r\n },\r\n [$title, $close]\r\n )\r\n this.$header = $header\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__main'\r\n },\r\n ['']\r\n )\r\n this.$main = $main\r\n\r\n if (!hasPadding) {\r\n addClass($main, 'outline-drawer_full')\r\n }\r\n\r\n $footer = createElement(\r\n 'footer',\r\n {\r\n className: 'outline-drawer__footer'\r\n },\r\n ['']\r\n )\r\n this.$footer = $footer\r\n\r\n $modal = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer__modal outline-drawer_${placement} outline-drawer_${size} outline-drawer_closed`\r\n },\r\n [$header, $main, $footer]\r\n )\r\n this.$modal = $modal\r\n\r\n if (hasOffset) {\r\n addClass($modal, 'outline-drawer_offset')\r\n }\r\n\r\n if (autoHeight) {\r\n addClass($modal, 'outline-drawer_auto')\r\n }\r\n\r\n if (customClass) {\r\n addClass($modal, customClass)\r\n }\r\n\r\n if (hasOverlay) {\r\n $overlay = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__overlay'\r\n },\r\n ['']\r\n )\r\n this.$overlay = $overlay\r\n }\r\n\r\n $el = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer`\r\n },\r\n [$modal, $overlay]\r\n )\r\n this.$el = $el\r\n $fragment.appendChild($el)\r\n document.body.appendChild($fragment)\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n open() {\r\n const opened = this.attr('afterOpened')\r\n const $modal = this.$modal\r\n\r\n addClass(this.$el, 'outline-drawer_opened')\r\n removeClass($modal, 'outline-drawer_closed')\r\n addClass($modal, 'outline-drawer_opened')\r\n\r\n later(() => {\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n close() {\r\n const closed = this.attr('afterClosed')\r\n const $modal = this.$modal\r\n\r\n removeClass($modal, 'outline-drawer_opened')\r\n addClass($modal, 'outline-drawer_closed')\r\n\r\n later(() => {\r\n removeClass(this.$el, 'outline-drawer_opened')\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const closed = this.isClosed()\r\n\r\n if (closed) {\r\n this.open()\r\n } else {\r\n this.close()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n afterToggle.call(this, closed)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const afterDestroy = this.attr('afterDestroy')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n let index = this.zIndex\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = false\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n\r\n index -= 1\r\n zIndex(index)\r\n this.zIndex = 0\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (hasClose) {\r\n on($el, '.outline-drawer__close', 'click', this.onClose, this, true)\r\n }\r\n\r\n if (hasOverlay) {\r\n on($el, '.outline-drawer__overlay', 'click', this.onClose, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (!hasClose && !hasOverlay) {\r\n return this\r\n }\r\n\r\n off($el, 'click', this.onClose)\r\n\r\n return this\r\n }\r\n\r\n onClose() {\r\n this.close()\r\n return this\r\n }\r\n}\r\n\r\nDrawer.DEFAULTS = {\r\n placement: 'rtl',\r\n title: '标题',\r\n size: 'regular',\r\n hasClose: true,\r\n hasOverlay: true,\r\n hasOffset: false,\r\n hasPadding: true,\r\n autoHeight: true,\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterToggle: null\r\n}\r\n\r\nexport default Drawer\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport publish from './utils/observer/emit'\r\n\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport _paintChapters from './_paintChapters'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Chapters.DEFAULTS\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.closed = false\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.offsetWidth = 0\r\n this.$active = null\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.playing = false\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n _paintEdge() {\r\n const STICKY = 'outline-chapters_sticky'\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n [title]\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement(\r\n 'ul',\r\n {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list ${FIXED} ${HIDDEN}`\r\n },\r\n ['']\r\n )\r\n this.$list = $list\r\n\r\n $placeholder = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__placeholder'\r\n },\r\n ['']\r\n )\r\n this.$placeholder = $placeholder\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n [$list, $placeholder]\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: 'outline-chapters'\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n\r\n $parentElement.appendChild($el)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n let $el\r\n let $list\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n this._paintEdge()\r\n\r\n $list = this.$list\r\n _paintChapters($list, this.chapters, showCode)\r\n removeClass($list, FIXED)\r\n removeClass($list, HIDDEN)\r\n\r\n $el = this.$el\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n this.onObserver()\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $anchor = this.$el.querySelector(`#chapter__anchor-${id}`)\r\n const HIGHLIGHT = 'outline-chapters_active'\r\n const $placeholder = this.$placeholder\r\n let top\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n this.$active = $anchor\r\n addClass(this.$active, HIGHLIGHT)\r\n\r\n top = 30 * this.active\r\n $placeholder.style.top = `calc(0.5em + ${top}px)`\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = !!(scrollTop >= top)\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n removeClass($parent, HIDDEN)\r\n removeClass($el, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n removeClass($el, FOLDED)\r\n }, 30)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n addClass($parent, FOLDED)\r\n addClass($el, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n addClass($el, HIDDEN)\r\n })\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = !!(scrollTop >= top)\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n this.$parentElement.removeChild(this.$el)\r\n\r\n this.attr(Chapters.DEFAULTS)\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.$active = null\r\n this.closed = false\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n let timer = null\r\n\r\n intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n timer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n { context: this }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this)\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 50)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize)\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const byId = (id) => document.getElementById(id)\r\n\r\n chapters.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n [chapter.text]\r\n )\r\n const $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n [$text]\r\n )\r\n let $code\r\n let $li\r\n let $ul\r\n let $parent\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n [chapter.code]\r\n )\r\n\r\n $link.insertBefore($code, $link.firstChild)\r\n }\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n [$link]\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $parent = byId(`chapter-${pid}`)\r\n $ul = byId(`subject-${pid}`)\r\n\r\n if (!$ul) {\r\n $ul = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n [$li]\r\n )\r\n\r\n $parent.appendChild($ul)\r\n } else {\r\n $ul.appendChild($li)\r\n }\r\n }\r\n })\r\n}\r\n\r\nexport default _paintChapters\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n}\r\n\r\nexport default intersection\r\n","import { createSvgIcon } from './utils/icons'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\n\r\nconst _createButton = (button, rounded = true) => {\r\n const $icon = createSvgIcon(button.icon, button.size)\r\n const $anchor = createElement(\r\n 'a',\r\n {\r\n className: `outline-toolbar__anchor`,\r\n href: button.link\r\n },\r\n [$icon]\r\n )\r\n const $button = createElement(\r\n 'div',\r\n {\r\n className: `outline-toolbar__button ${button.name}`\r\n },\r\n [button.link ? $anchor : $icon]\r\n )\r\n\r\n addClass($icon, 'outline-toolbar__icon')\r\n\r\n if (rounded) {\r\n addClass($button, 'outline-toolbar_rounded')\r\n }\r\n\r\n if (button.disabled) {\r\n addClass($button, 'outline-toolbar_disabled')\r\n }\r\n\r\n return $button\r\n}\r\n\r\nexport default _createButton\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isObject from './utils/types/isObject'\r\nimport isArray from './utils/types/isArray'\r\nimport later from './utils/lang/later'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\nimport hasClass from './utils/dom/hasClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _createButton from './_createButton'\r\n\r\nconst DISABLED = 'outline-toolbar_disabled'\r\nconst HIDDEN = 'outline-toolbar_hidden'\r\n\r\nclass Toolbar extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Toolbar.DEFAULTS\r\n this.$el = null\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n this.disabled = this.attr('disabled')\r\n this.closed = this.attr('closed')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n isDisabled(name) {\r\n const buttons = this.attr('buttons')\r\n let button\r\n\r\n if (name) {\r\n button = buttons.find((option) => option.name === name)\r\n\r\n return !!(button && button.disabled)\r\n }\r\n\r\n return this.disabled\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n highlight(name) {\r\n const button = this.buttons.find((item) => item.name === name)\r\n const ACTIVE = 'outline-toolbar_active'\r\n let $button\r\n\r\n if ($button) {\r\n return this\r\n }\r\n\r\n $button = button.$el\r\n\r\n if (hasClass($button, ACTIVE)) {\r\n removeClass($button, ACTIVE)\r\n } else {\r\n addClass($button, ACTIVE)\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const buttons = this.attr('buttons') || []\r\n const rounded = this.attr('rounded')\r\n const placement = this.attr('placement')\r\n const $buttons = document.createDocumentFragment()\r\n const $fragment = document.createDocumentFragment()\r\n\r\n paintSvgSprites()\r\n\r\n buttons.forEach((button) => {\r\n const $button = _createButton(button, rounded)\r\n\r\n $buttons.appendChild($button)\r\n this.buttons.push({\r\n name: button.name,\r\n $el: $button\r\n })\r\n })\r\n\r\n this.$el = createElement(\r\n 'div',\r\n {\r\n id: 'outline-toolbar',\r\n className: `outline-toolbar outline-toolbar_${placement}`\r\n },\r\n [$buttons]\r\n )\r\n $fragment.appendChild(this.$el)\r\n document.body.appendChild($fragment)\r\n\r\n if (this.closed) {\r\n this.hide()\r\n }\r\n\r\n if (this.disabled) {\r\n this.disable()\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n add(button) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const action = button.action\r\n const $fragment = document.createDocumentFragment()\r\n let type\r\n\r\n if (isObject(button)) {\r\n buttons.push(button)\r\n $fragment.appendChild(_createButton(button))\r\n } else if (isArray(button)) {\r\n button.forEach((item) => {\r\n $fragment.appendChild(_createButton(item))\r\n })\r\n }\r\n $el.appendChild($fragment)\r\n\r\n if (action && isFunction(action.handler)) {\r\n type = action.type || 'click'\r\n on($el, `.${button.name}`, type, action.handler)\r\n }\r\n\r\n return this\r\n }\r\n\r\n remove(name) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let index = -1\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button, i) => {\r\n if (button.name === name) {\r\n index = i\r\n }\r\n })\r\n\r\n if (index > -1) {\r\n this.attr().buttons.splice(index, 1)\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n this.switch(name, false)\r\n $el.removeChild($button)\r\n\r\n return this\r\n }\r\n\r\n switch(name, enabled) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let action\r\n let type\r\n let listener\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((option) => {\r\n if (option.name === name) {\r\n button.disabled = !enabled\r\n }\r\n })\r\n\r\n action = button.action\r\n $button = $el.querySelector(`.${name}`)\r\n\r\n if (action) {\r\n type = action.type || 'click'\r\n listener = action.handler\r\n }\r\n\r\n if (enabled) {\r\n removeClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n on($el, `.${name}`, type, listener)\r\n }\r\n } else {\r\n addClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n off($el, type, listener)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n disable(name) {\r\n const disabled = this.attr('afterDisabled')\r\n\r\n if (name) {\r\n this.switch(name, false)\r\n } else {\r\n addClass(this.$el, DISABLED)\r\n this.removeListeners()\r\n this.disabled = true\r\n\r\n if (isFunction(disabled)) {\r\n disabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n enable(name) {\r\n const enabled = this.attr('afterEnabled')\r\n\r\n if (name) {\r\n this.switch(name, true)\r\n } else {\r\n this.disabled = false\r\n removeClass(this.$el, DISABLED)\r\n this.addListeners()\r\n\r\n if (isFunction(enabled)) {\r\n enabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n show(name) {\r\n const opened = this.attr('afterOpened')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n removeClass($button, HIDDEN)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n later(() => {\r\n opened.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide(name) {\r\n const closed = this.attr('afterClosed')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n $button = $el.querySelector(`.${name}`)\r\n addClass($button, HIDDEN)\r\n } else {\r\n addClass($el, HIDDEN)\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n later(() => {\r\n closed.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n let $el = this.$el\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n document.body.removeChild($el)\r\n $el = null\r\n\r\n this.attr(Toolbar.DEFAULTS)\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n refresh() {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons') || []\r\n\r\n this.removeListeners()\r\n $el.innerHTML = ''\r\n\r\n buttons.forEach((button) => {\r\n this.$el.appendChild(_createButton(button))\r\n })\r\n\r\n this.addListeners()\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n let context\r\n let command\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n if (isString(listener)) {\r\n command = listener\r\n action.handler = function () {\r\n publish(command, button.name)\r\n }\r\n listener = action.handler\r\n }\r\n\r\n type = action.type || 'click'\r\n context = action.context\r\n }\r\n\r\n if (isFunction(listener)) {\r\n on($el, `.${button.name}`, type, listener, context || this, true)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n type = action.type || 'click'\r\n }\r\n\r\n if (isFunction(listener)) {\r\n off($el, type, listener)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n}\r\n\r\nToolbar.DEFAULTS = {\r\n placement: 'ltr',\r\n closed: false,\r\n disabled: false,\r\n rounded: true,\r\n buttons: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterDisabled: null,\r\n afterEnabled: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Toolbar\r\n","/**\r\n * 生成唯一 id 字符串的函数\r\n * ========================================================================\r\n * @method guid\r\n * @param {String} [prefix] - 生成 id 的前缀字符串\r\n * @return {String} 返回一个表示唯一 id 的字符串\r\n */\r\nconst guid = (() => {\r\n let uuid = 0\r\n\r\n return (prefix) => {\r\n uuid += 1\r\n\r\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\r\n }\r\n})()\r\n\r\nexport default guid\r\n","import _subscribers from './_subscribers'\r\nimport isFunction from '../types/isFunction'\r\nimport guid from '../lang/guid'\r\n\r\n/**\r\n * 订阅主题,并给出处理器函数\r\n * ========================================================================\r\n * @method on\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Function} handler - (必须)主题的处理器函数\r\n * @param {Object} [context] - (可选)指定 this 执行上下文\r\n * @return {String|Boolean} - 唯一的 token 字符串,例如:'guid-1'。\r\n */\r\nconst on = (topic, handler, context = null) => {\r\n const token = guid()\r\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\r\n\r\n if (!isFunction(handler)) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (!_subscribers[subject]) {\r\n _subscribers[subject] = []\r\n }\r\n\r\n _subscribers[subject].push({\r\n topic: subject,\r\n callback: handler,\r\n context,\r\n token\r\n })\r\n\r\n return token\r\n}\r\n\r\nexport default on\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 删除与给定 topic 相同的订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriber\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _removeSubscriber = (topic) => {\r\n if (!hasOwn(_subscribers, topic)) {\r\n return false\r\n }\r\n\r\n delete _subscribers[topic]\r\n}\r\n\r\nexport default _removeSubscriber\r\n","import has from './has'\r\nimport _removeSubscriber from './_removeSubscriber'\r\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\r\n\r\n/**\r\n * 取消订阅主题\r\n * ========================================================================\r\n * @method off\r\n * @param {String} topic - (必须)订阅的主题\r\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\r\n */\r\nconst off = (topic, token) => {\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (token) {\r\n _removeSubscriberByToken(token)\r\n } else {\r\n _removeSubscriber(topic)\r\n }\r\n}\r\n\r\nexport default off\r\n","import _subscribers from './_subscribers'\r\nimport _removeSubscriber from './_removeSubscriber'\r\n\r\n/**\r\n * 通过订阅者 token 值删除订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriberByToken\r\n * @param {String} token - 订阅者 token 字符串\r\n * @returns {boolean}\r\n * @private\r\n */\r\nconst _removeSubscriberByToken = (token) => {\r\n const keys = Object.keys(_subscribers)\r\n let index = -1\r\n\r\n if (!token || keys.length < 1) {\r\n return false\r\n }\r\n\r\n keys.forEach((subject) => {\r\n const subscriber = _subscribers[subject]\r\n let topic\r\n\r\n subscriber.forEach((execution, j) => {\r\n if (execution.callback === token || execution.token === token) {\r\n topic = execution.topic\r\n subscriber.splice(index, j)\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (subscriber.length < 1) {\r\n _removeSubscriber(topic)\r\n }\r\n })\r\n}\r\n\r\nexport default _removeSubscriberByToken\r\n","import Base from './base'\r\nimport Anchors from './anchors'\r\nimport Drawer from './drawer'\r\nimport Chapters from './chapters'\r\nimport Toolbar from './toolbar'\r\n\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Outline extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Outline.DEFAULTS\r\n this.anchors = null\r\n this.drawer = null\r\n this.chapters = null\r\n this.toolbar = null\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n return this.anchors.getChapters(isTreeStructured)\r\n }\r\n\r\n count() {\r\n return this.anchors.count()\r\n }\r\n\r\n render() {\r\n this._renderAnchors()._renderChapters()._renderToolbar()\r\n\r\n return this\r\n }\r\n\r\n _renderAnchors() {\r\n const articleElement = this.attr('articleElement')\r\n const selector = this.attr('selector')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n\r\n this.anchors = new Anchors({\r\n articleElement,\r\n stickyHeight,\r\n scrollElement,\r\n selector,\r\n showCode,\r\n anchorURL\r\n })\r\n\r\n return this\r\n }\r\n\r\n _renderChapters() {\r\n const title = this.attr('title')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const customClass = this.attr('customClass')\r\n const showCode = this.attr('showCode')\r\n const position = this.attr('position')\r\n const placement = this.attr('placement')\r\n const afterSticky = this.attr('afterSticky')\r\n const afterToggle = this.attr('afterToggle')\r\n const count = this.count()\r\n let parentElement = this.attr('parentElement')\r\n let CHAPTERS_OPTIONS\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n CHAPTERS_OPTIONS = {\r\n scrollElement,\r\n showCode,\r\n position,\r\n title,\r\n stickyHeight,\r\n chapters: this.anchors.getChapters(),\r\n afterSticky,\r\n afterToggle\r\n }\r\n\r\n if (position === 'relative') {\r\n this.drawer = new Drawer({\r\n placement,\r\n title,\r\n size: 'tiny',\r\n hasOffset: true,\r\n hasPadding: false,\r\n customClass,\r\n afterClosed: () => {\r\n const toolbar = this.toolbar\r\n toolbar.toggle()\r\n }\r\n })\r\n parentElement = this.drawer.$main\r\n } else {\r\n CHAPTERS_OPTIONS.customClass = customClass\r\n }\r\n\r\n CHAPTERS_OPTIONS.parentElement = parentElement\r\n this.chapters = new Chapters(CHAPTERS_OPTIONS)\r\n\r\n return this\r\n }\r\n\r\n _renderToolbar() {\r\n const placement = this.attr('placement')\r\n const homepage = this.attr('homepage')\r\n const count = this.count()\r\n const UP = {\r\n name: 'up',\r\n icon: 'up',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:up'\r\n }\r\n }\r\n const HOME = {\r\n name: 'homepage',\r\n icon: 'homepage',\r\n size: 20,\r\n link: homepage\r\n }\r\n const MENU = {\r\n name: 'menu',\r\n icon: 'menu',\r\n size: 18,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:toggle'\r\n }\r\n }\r\n const DOWN = {\r\n name: 'down',\r\n icon: 'down',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:down'\r\n }\r\n }\r\n const buttons = []\r\n\r\n buttons.push(UP)\r\n if (homepage) {\r\n buttons.push(HOME)\r\n }\r\n if (count > 0) {\r\n buttons.push(MENU)\r\n }\r\n buttons.push(DOWN)\r\n\r\n this.toolbar = new Toolbar({\r\n placement,\r\n buttons: buttons\r\n })\r\n\r\n return this\r\n }\r\n\r\n toTop() {\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const afterTop = () => {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n\r\n if (count > 0) {\r\n chapters.highlight(0)\r\n }\r\n chapters.playing = false\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(0, afterTop)\r\n\r\n return this\r\n }\r\n\r\n toBottom() {\r\n const $scrollElement = _getScrollElement(this.attr('scrollElement'))\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const top = Math.floor(\r\n $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n )\r\n const afterDown = () => {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n\r\n if (count > 1) {\r\n chapters.highlight(count - 1)\r\n }\r\n chapters.playing = false\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(top, afterDown)\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, afterScroll) {\r\n const scrollElement = this.attr('scrollElement')\r\n scrollTo(scrollElement, top, afterScroll)\r\n return this\r\n }\r\n\r\n toggle() {\r\n const position = this.attr('position')\r\n const toolbar = this.toolbar\r\n const drawer = this.drawer\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n if (position !== 'relative') {\r\n chapters.toggle()\r\n toolbar.highlight('menu')\r\n } else {\r\n toolbar.toggle()\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n later(() => {\r\n if (chapters.isInside()) {\r\n chapters.toggle()\r\n } else {\r\n drawer.toggle()\r\n }\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n this.removeListeners()\r\n\r\n this.attr(Outline.DEFAULTS)\r\n this.anchors.destroy()\r\n if (count < 1) {\r\n chapters.destroy()\r\n if (chapters.isOutside()) {\r\n this.drawer.destroy()\r\n }\r\n }\r\n this.toolbar.destroy()\r\n\r\n return this\r\n }\r\n\r\n onToggle() {\r\n this.toggle()\r\n return this\r\n }\r\n\r\n onScrollTop() {\r\n this.toTop()\r\n return this\r\n }\r\n\r\n onScrollBottom() {\r\n this.toBottom()\r\n return this\r\n }\r\n\r\n onToolbarUpdate({ top, min, max }) {\r\n const toolbar = this.toolbar\r\n const current = Math.ceil(top)\r\n\r\n if (current <= min) {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n } else if (current >= max) {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n } else if (current > min && current < max) {\r\n toolbar.show('up')\r\n toolbar.show('down')\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n subscribe('toolbar:update', this.onToolbarUpdate, this)\r\n subscribe('toolbar:action:up', this.onScrollTop, this)\r\n subscribe('toolbar:action:toggle', this.onToggle, this)\r\n subscribe('toolbar:action:down', this.onScrollBottom, this)\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n unsubscribe('toolbar:update')\r\n unsubscribe('toolbar:action:up')\r\n unsubscribe('toolbar:action:toggle')\r\n unsubscribe('toolbar:action:down')\r\n return this\r\n }\r\n}\r\n\r\nOutline.DEFAULTS = {\r\n articleElement: '#article',\r\n selector: 'h2,h3,h4,h5,h6',\r\n title: '目录',\r\n scrollElement: 'html,body',\r\n position: 'relative',\r\n parentElement: '#aside',\r\n placement: 'rtl',\r\n showCode: true,\r\n anchorURL: '',\r\n stickyHeight: 0,\r\n customClass: '',\r\n afterSticky: null,\r\n afterToggle: null\r\n}\r\n\r\nif (window.jQuery) {\r\n // 将 Outline 扩展为一个 jquery 插件\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend(jQuery.fn, {\r\n outline: function (options) {\r\n // eslint-disable-next-line no-undef\r\n let $article = jQuery(this)\r\n\r\n return new Outline(\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend({}, options, {\r\n articleElement: $article\r\n })\r\n )\r\n }\r\n })\r\n}\r\n\r\nexport default Outline\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","later","fn","delay","setTimeout","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","scrollTo","top","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","offsetTop","el","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","off","on","data","context","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","closest","overrideContext","push","addEventListener","stopPropagation","preventDefault","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","isArray","Array","paintSvgSprites","symbols","SYMBOLS","sprites","concat","$body","body","$icons","innerHTML","join","createElement","insertBefore","firstChild","createSvgIcon","name","size","color","iconSet","binds","width","height","defaultRules","svg","$icon","className","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","hasClass","pattern","RegExp","allClass","classList","contains","match","removeClass","remove","_resetHeading","$heading","hasAnchor","isAtStart","CLS_HEADING","text","$anchor","removeAttribute","removeChild","getChapters","headings","showCode","chapters","previous","level","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","id","rel","groups","group","JSON","stringify","cb","code","String","c","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","anchorURL","chapterCode","headingId","href","_updateHeading","after","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","publish","min","addClass","add","setProperty","documentElement","zIndex","idx","Drawer","title","closed","$modal","$header","$title","$close","$main","$footer","$overlay","setTitle","isClosed","placement","hasClose","hasOverlay","hasOffset","hasPadding","autoHeight","customClass","open","opened","close","toggle","afterToggle","onClose","afterClosed","afterOpened","at","Chapters","$list","$placeholder","$parentElement","active","offsetWidth","$active","scrollTimer","resizeTimer","playing","parentElement","$parent","isSticky","isFixed","isInside","isOutside","_paintEdge","contents","calculateStickyHeight","byId","getElementById","chapter","$text","$link","$code","$li","$ul","_paintChapters","sticky","onObserver","highlight","HIGHLIGHT","getAttribute","afterSticky","FIXED","isStickying","Math","window","innerHeight","show","FOLDED","HIDDEN","hide","clearTimeout","timer","props","root","rootMargin","Observer","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","onSelect","split","onScroll","onResize","_createButton","button","rounded","icon","link","$button","disabled","DISABLED","Toolbar","buttons","isDisabled","find","option","ACTIVE","$buttons","disable","action","switch","enabled","enable","refresh","command","afterDisabled","afterEnabled","guid","uuid","prefix","token","subject","_removeSubscriber","execution","j","_removeSubscriberByToken","Outline","anchors","drawer","toolbar","_renderAnchors","_renderChapters","_renderToolbar","CHAPTERS_OPTIONS","homepage","HOME","MENU","toTop","toBottom","floor","onToggle","onScrollTop","onScrollBottom","onToolbarUpdate","ceil","subscribe","unsubscribe","jQuery","extend","outline","$article"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"outline.min.js","sources":["../../src/utils/types/isString.js","../../src/utils/lang/hasOwn.js","../../src/utils/lang/toString.js","../../src/utils/types/isFunction.js","../../src/utils/types/isObject.js","../../src/base.js","../../src/utils/lang/extend.js","../../src/utils/types/isElement.js","../../src/utils/lang/later.js","../../src/utils/lang/easeInQuad.js","../../src/utils/dom/_getScrollElement.js","../../src/utils/dom/scrollTo.js","../../src/utils/dom/offsetTop.js","../../src/utils/dom/matches.js","../../src/utils/dom/getParentOrHost.js","../../src/utils/event/enum.js","../../src/utils/event/_off.js","../../src/utils/event/_delete.js","../../src/utils/event/purgeElement.js","../../src/utils/event/getListeners.js","../../src/utils/event/off.js","../../src/utils/event/on.js","../../src/utils/event/getTarget.js","../../src/utils/dom/resolveTextNode.js","../../src/utils/dom/closest.js","../../src/utils/event/stop.js","../../src/utils/observer/_subscribers.js","../../src/utils/observer/_hasDirectSubscribersFor.js","../../src/utils/observer/has.js","../../src/utils/observer/_hasSubscribers.js","../../src/utils/observer/emit.js","../../src/utils/types/isTypedArray.js","../../src/utils/types/isArray.js","../../src/utils/icons.js","../../src/utils/lang/trim.js","../../src/utils/types/isDOM.js","../../src/utils/types/isHTMLCollection.js","../../src/utils/types/isFragment.js","../../src/utils/types/isTextNode.js","../../src/utils/dom/setAttribute.js","../../src/utils/dom/createElement.js","../../src/utils/dom/hasClass.js","../../src/utils/dom/removeClass.js","../../src/_resetHeading.js","../../src/utils/types/isEmpty.js","../../src/getChapters.js","../../src/utils/lang/stripTags.js","../../src/_getChapterParentIdByDiffer.js","../../src/_getChaptersWithCode.js","../../src/anchors.js","../../src/utils/lang/toTree.js","../../src/_updateHeading.js","../../src/utils/dom/addClass.js","../../src/utils/dom/setProperty.js","../../src/zIndex.js","../../src/drawer.js","../../src/utils/event/at.js","../../src/chapters.js","../../src/_paintChapters.js","../../src/utils/dom/intersection.js","../../src/_createButton.js","../../src/toolbar.js","../../src/utils/lang/guid.js","../../src/utils/observer/on.js","../../src/utils/observer/_removeSubscriber.js","../../src/utils/observer/off.js","../../src/utils/observer/_removeSubscriberByToken.js","../../src/outline.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n requestAnimationFrame(play)\r\n }\r\n\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n return purgeElement(el, type)\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector[0] === '>'\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n *
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isArray from './types/isArray'\r\n\r\n/**\r\n * 绘制 SVG Sprites 图标集\r\n * ========================================================================\r\n * @method paintSvgSprites\r\n * @param {Array} [symbols] - (可选)symbols 图标数组\r\n * 传递 symbols - 绘制 symbols + SYMBOLS 的图标集\r\n * 不传递 symbols - 仅绘制默认 SYMBOLS 图标集\r\n */\r\nexport const paintSvgSprites = (symbols = []) => {\r\n const SYMBOLS = [\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n ''\r\n ]\r\n const sprites =\r\n isArray(symbols) && symbols.length > 0 ? SYMBOLS.concat(symbols) : SYMBOLS\r\n const $body = document.body\r\n let $icons = document.querySelector('#svg-sprites')\r\n\r\n if ($icons) {\r\n $icons.innerHTML = sprites.join('')\r\n } else {\r\n $icons = document.createElement('div')\r\n $icons.innerHTML =\r\n ``\r\n $body.insertBefore($icons.firstChild, $body.firstChild)\r\n }\r\n}\r\n\r\n/**\r\n * 创建 SVG 图标 DOM 元素\r\n * ========================================================================\r\n * @method createSvgIcon\r\n * @param {String} name\r\n * @param {Number|String|Array} [size]\r\n * @param {String} [color]\r\n * @param {String} [iconSet]\r\n * @returns {HTMLElement}\r\n */\r\nexport const createSvgIcon = (\r\n name,\r\n size = 0,\r\n color = '',\r\n iconSet = 'outline'\r\n) => {\r\n const binds = iconSet\r\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\r\n : `xlink:href=\"#icon-${name}\"`\r\n const width = isArray(size) ? size[0] : size\r\n const height = isArray(size) ? size[1] : size\r\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\r\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\r\n const svg =\r\n `` +\r\n `` +\r\n ``\r\n const $icon = document.createElement('i')\r\n\r\n $icon.className = 'outline-icon'\r\n $icon.innerHTML = svg\r\n\r\n return $icon\r\n}\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import removeClass from './utils/dom/removeClass'\r\nimport isEmpty from './utils/types/isEmpty'\r\nimport trim from './utils/lang/trim'\r\n\r\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const text = $heading.innerHTML\r\n let $anchor\r\n\r\n $heading.innerHTML = text.replace(/^\\d+(?:(\\.?\\d*)*\\s?)?/gi, '')\r\n $heading.removeAttribute('id')\r\n $heading.removeAttribute('data-id')\r\n\r\n removeClass($heading, CLS_HEADING)\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\r\n\r\n if (isAtStart) {\r\n removeClass($heading, `${CLS_HEADING}_start`)\r\n }\r\n\r\n if (isEmpty(trim($heading.className))) {\r\n $heading.removeAttribute('class')\r\n }\r\n\r\n $heading.removeChild($anchor)\r\n}\r\n\r\nexport default _resetHeading\r\n","import isString from './isString'\r\n/**\r\n * 检测数据是否为空字符串\r\n * ========================================================================\r\n * @method isEmpty\r\n * @param {String} str\r\n * @returns {boolean}\r\n */\r\nconst isEmpty = (str) => {\r\n return isString(str) && str === ''\r\n}\r\n\r\nexport default isEmpty\r\n","import trim from './utils/lang/trim'\r\nimport stripTags from './utils/lang/stripTags'\r\n\r\nimport _getChaptersWithCode from './_getChaptersWithCode'\r\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\r\n\r\nconst getChapters = (headings, showCode = true) => {\r\n const chapters = []\r\n let previous = 1\r\n let level = 0\r\n\r\n headings.forEach((heading, i) => {\r\n const headingLevel = heading.tagName.replace(/h/i, '')\r\n let current = parseInt(headingLevel, 10)\r\n let pid = -1\r\n\r\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\r\n // h2 (前一个标题)\r\n // h3 (当前标题)\r\n if (current > previous) {\r\n level += 1\r\n\r\n // 第一层级的 pid 是 -1\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n pid = i - 1\r\n }\r\n }\r\n // 当前标题的(标题标签)序号 = 前一个标题的序号\r\n // h2 (前一个标题)\r\n // h2 (当前标题)\r\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\r\n // h2\r\n // h4 (前一个标题)\r\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\r\n else if (current === previous || (current < previous && current > level)) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n pid = -1\r\n } else {\r\n pid = chapters[i - 1].pid\r\n }\r\n } else if (current <= level) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n } else {\r\n level = level - (previous - current)\r\n\r\n if (level <= 1) {\r\n level = 1\r\n }\r\n }\r\n\r\n // 第一级的标题\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\r\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\r\n }\r\n }\r\n\r\n previous = current\r\n\r\n chapters.push({\r\n id: i,\r\n pid: pid,\r\n level: level,\r\n rel: `heading-${i}`,\r\n text: stripTags(trim(heading.innerHTML))\r\n })\r\n })\r\n\r\n return showCode ? _getChaptersWithCode(chapters) : chapters\r\n}\r\n\r\nexport default getChapters\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 过滤所有 HTML 标签\r\n * ========================================================================\r\n * @method stripTags\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nconst stripTags = (str) => {\r\n if (!isString(str)) {\r\n return ''\r\n }\r\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\r\n}\r\n\r\nexport default stripTags\r\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\r\n let previous = chapters[index - 1]\r\n let pid\r\n let i\r\n\r\n for (i = 0; i < differ; i += 1) {\r\n pid = previous.pid\r\n previous = chapters[pid]\r\n }\r\n\r\n pid = previous.pid\r\n\r\n return pid\r\n}\r\n\r\nexport default _getChapterParentIdByDiffer\r\n","const _getChaptersWithCode = (chapters) => {\r\n const groups = {}\r\n const cb = (o) => {\r\n return [o.pid]\r\n }\r\n\r\n chapters.forEach((o) => {\r\n const group = JSON.stringify(cb(o))\r\n\r\n groups[group] = groups[group] || []\r\n groups[group].push(o)\r\n\r\n o.index = groups[group].length\r\n if (o.pid === -1) {\r\n o.code = String(o.index)\r\n }\r\n })\r\n\r\n Object.keys(groups).forEach((group) => {\r\n groups[group].forEach((c, i) => {\r\n c.index = i + 1\r\n chapters.forEach((o) => {\r\n if (o.pid === c.id) {\r\n o.code = c.code + '.' + o.index\r\n }\r\n })\r\n })\r\n })\r\n\r\n return chapters\r\n}\r\n\r\nexport default _getChaptersWithCode\r\n","import Base from './base'\r\n\r\n// 在文章的标题生成 anchor 链接\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport toTree from './utils/lang/toTree'\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _updateHeading from './_updateHeading'\r\nimport _resetHeading from './_resetHeading'\r\nimport getChapters from './getChapters'\r\n\r\nclass Anchors extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Anchors.DEFAULTS\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n\r\n this.chapters = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let scrollElement\r\n let selector\r\n let $articleElement\r\n let articleElement\r\n\r\n this.attr(options)\r\n articleElement = this.attr('articleElement')\r\n scrollElement = this.attr('scrollElement')\r\n selector = this.attr('selector')\r\n created = this.attr('created')\r\n\r\n if (isString(articleElement)) {\r\n $articleElement = document.querySelector(articleElement)\r\n } else if (isElement(articleElement)) {\r\n $articleElement = articleElement\r\n }\r\n\r\n if (!$articleElement) {\r\n return this\r\n }\r\n\r\n this.$articleElement = $articleElement\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n this.$headings = [...$articleElement.querySelectorAll(selector)]\r\n\r\n if (this.$headings.length < 1) {\r\n return this\r\n }\r\n\r\n this.chapters = getChapters(this.$headings)\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n const chapters = this.chapters\r\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const $headings = this.$headings\r\n const chapters = this.getChapters()\r\n\r\n paintSvgSprites()\r\n\r\n $headings.forEach(($heading, i) => {\r\n const chapterCode = chapters[i].code\r\n _updateHeading($heading, i, {\r\n hasAnchor,\r\n isAtStart,\r\n showCode,\r\n chapterCode,\r\n anchorURL\r\n })\r\n })\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n const $headings = this.$headings\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n $headings.forEach(($heading) => {\r\n _resetHeading($heading, hasAnchor, isAtStart)\r\n })\r\n\r\n this.attr(Anchors.DEFAULTS)\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n this.chapters = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onAnchorTrigger(evt) {\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const $heading = $anchor.parentNode\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const $scrollElement = this.$scrollElement\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'anchor')\r\n }\r\n\r\n later(() => {\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.scrollTo(top, after)\r\n\r\n if (!anchorURL) {\r\n stop(evt)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n on(\r\n $articleElement,\r\n '.outline-heading__anchor',\r\n 'click',\r\n this.onAnchorTrigger,\r\n this,\r\n true\r\n )\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n off($articleElement, 'click', this.onAnchorTrigger)\r\n\r\n return this\r\n }\r\n}\r\n\r\nAnchors.DEFAULTS = {\r\n scrollElement: 'html,body',\r\n articleElement: '#article',\r\n selector: 'h1,h2,h3,h4,h5,h6',\r\n stickyHeight: 0,\r\n anchorURL: '',\r\n hasAnchor: true,\r\n isAtStart: true,\r\n showCode: false,\r\n created: null,\r\n mounted: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Anchors\r\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import trim from './utils/lang/trim'\r\nimport createElement from './utils/dom/createElement'\r\nimport setAttribute from './utils/dom/setAttribute'\r\n\r\nimport { createSvgIcon } from './utils/icons'\r\n\r\nconst _updateHeading = ($heading, i, options) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const hasAnchor = options.hasAnchor || true\r\n const isAtStart = options.isAtStart || true\r\n const showCode = options.showCode || false\r\n const chapterCode = options.chapterCode || ''\r\n const anchorURL = options.anchorURL || ''\r\n const headingId = `heading-${i}`\r\n const attrs = {\r\n id: headingId,\r\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\r\n 'data-id': i\r\n }\r\n const keys = Object.keys(attrs)\r\n const text = trim($heading.innerHTML)\r\n let $anchor\r\n let $icon\r\n\r\n keys.forEach((prop) => {\r\n setAttribute($heading, prop, attrs[prop])\r\n })\r\n\r\n if (showCode) {\r\n $heading.innerHTML = chapterCode + ' ' + text\r\n }\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $icon = createSvgIcon('hash')\r\n $anchor = createElement(\r\n 'a',\r\n {\r\n id: `anchor-${i}`,\r\n className: `${CLS_HEADING}__anchor anchor-${i}`,\r\n href: anchorURL ? anchorURL : `#${headingId}`,\r\n target: anchorURL ? '_blank' : 'self',\r\n 'data-id': i\r\n },\r\n [$icon]\r\n )\r\n $heading.appendChild($anchor)\r\n}\r\n\r\nexport default _updateHeading\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","import setProperty from './utils/dom/setProperty'\r\n\r\nlet index = 2000\r\n\r\nconst zIndex = (idx) => {\r\n if (idx) {\r\n index = idx\r\n } else {\r\n index += 1\r\n }\r\n\r\n setProperty('--outline-zIndex', `${index}`)\r\n\r\n return index\r\n}\r\n\r\nexport default zIndex\r\n","import Base from './base'\r\n\r\nimport later from './utils/lang/later'\r\nimport isFunction from './utils/types/isFunction'\r\nimport addClass from './utils/dom/addClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport createElement from './utils/dom/createElement'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\n\r\nimport { paintSvgSprites, createSvgIcon } from './utils/icons'\r\nimport zIndex from './zIndex'\r\n\r\nclass Drawer extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = true\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n this.zIndex = 0\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n\r\n this.title = this.attr('title')\r\n created = this.attr('created')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n return this\r\n }\r\n\r\n setTitle(title) {\r\n this.attr('title', title)\r\n this.title = title\r\n this.$title.innerHTML = title\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const size = this.attr('size')\r\n const placement = this.attr('placement')\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const hasOffset = this.attr('hasOffset')\r\n const hasPadding = this.attr('hasPadding')\r\n const autoHeight = this.attr('autoHeight')\r\n const customClass = this.attr('customClass')\r\n const $fragment = document.createDocumentFragment()\r\n let $el\r\n let $modal\r\n let $header\r\n let $title\r\n let $close\r\n let $main\r\n let $footer\r\n let $overlay\r\n\r\n paintSvgSprites()\r\n this.zIndex = zIndex()\r\n\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-drawer__title'\r\n },\r\n [this.title]\r\n )\r\n this.$title = $title\r\n\r\n if (hasClose) {\r\n $close = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__close'\r\n },\r\n [createSvgIcon('close', 20)]\r\n )\r\n this.$close = $close\r\n }\r\n\r\n $header = createElement(\r\n 'header',\r\n {\r\n className: 'outline-drawer__header'\r\n },\r\n [$title, $close]\r\n )\r\n this.$header = $header\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__main'\r\n },\r\n ['']\r\n )\r\n this.$main = $main\r\n\r\n if (!hasPadding) {\r\n addClass($main, 'outline-drawer_full')\r\n }\r\n\r\n $footer = createElement(\r\n 'footer',\r\n {\r\n className: 'outline-drawer__footer'\r\n },\r\n ['']\r\n )\r\n this.$footer = $footer\r\n\r\n $modal = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer__modal outline-drawer_${placement} outline-drawer_${size} outline-drawer_closed`\r\n },\r\n [$header, $main, $footer]\r\n )\r\n this.$modal = $modal\r\n\r\n if (hasOffset) {\r\n addClass($modal, 'outline-drawer_offset')\r\n }\r\n\r\n if (autoHeight) {\r\n addClass($modal, 'outline-drawer_auto')\r\n }\r\n\r\n if (customClass) {\r\n addClass($modal, customClass)\r\n }\r\n\r\n if (hasOverlay) {\r\n $overlay = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__overlay'\r\n },\r\n ['']\r\n )\r\n this.$overlay = $overlay\r\n }\r\n\r\n $el = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer`\r\n },\r\n [$modal, $overlay]\r\n )\r\n this.$el = $el\r\n $fragment.appendChild($el)\r\n document.body.appendChild($fragment)\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n open() {\r\n const opened = this.attr('afterOpened')\r\n const $modal = this.$modal\r\n\r\n addClass(this.$el, 'outline-drawer_opened')\r\n removeClass($modal, 'outline-drawer_closed')\r\n addClass($modal, 'outline-drawer_opened')\r\n\r\n later(() => {\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n close() {\r\n const closed = this.attr('afterClosed')\r\n const $modal = this.$modal\r\n\r\n removeClass($modal, 'outline-drawer_opened')\r\n addClass($modal, 'outline-drawer_closed')\r\n\r\n later(() => {\r\n removeClass(this.$el, 'outline-drawer_opened')\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const closed = this.isClosed()\r\n\r\n if (closed) {\r\n this.open()\r\n } else {\r\n this.close()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n afterToggle.call(this, closed)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const afterDestroy = this.attr('afterDestroy')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n let index = this.zIndex\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = false\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n\r\n index -= 1\r\n zIndex(index)\r\n this.zIndex = 0\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (hasClose) {\r\n on($el, '.outline-drawer__close', 'click', this.onClose, this, true)\r\n }\r\n\r\n if (hasOverlay) {\r\n on($el, '.outline-drawer__overlay', 'click', this.onClose, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (!hasClose && !hasOverlay) {\r\n return this\r\n }\r\n\r\n off($el, 'click', this.onClose)\r\n\r\n return this\r\n }\r\n\r\n onClose() {\r\n this.close()\r\n return this\r\n }\r\n}\r\n\r\nDrawer.DEFAULTS = {\r\n placement: 'rtl',\r\n title: '标题',\r\n size: 'regular',\r\n hasClose: true,\r\n hasOverlay: true,\r\n hasOffset: false,\r\n hasPadding: true,\r\n autoHeight: true,\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterToggle: null\r\n}\r\n\r\nexport default Drawer\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport publish from './utils/observer/emit'\r\n\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport _paintChapters from './_paintChapters'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Chapters.DEFAULTS\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.closed = false\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.offsetWidth = 0\r\n this.$active = null\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.playing = false\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n _paintEdge() {\r\n const STICKY = 'outline-chapters_sticky'\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n [title]\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement(\r\n 'ul',\r\n {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list ${FIXED} ${HIDDEN}`\r\n },\r\n ['']\r\n )\r\n this.$list = $list\r\n\r\n $placeholder = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__placeholder'\r\n },\r\n ['']\r\n )\r\n this.$placeholder = $placeholder\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n [$list, $placeholder]\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: 'outline-chapters'\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n\r\n $parentElement.appendChild($el)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n let $el\r\n let $list\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n this._paintEdge()\r\n\r\n $list = this.$list\r\n _paintChapters($list, this.chapters, showCode)\r\n removeClass($list, FIXED)\r\n removeClass($list, HIDDEN)\r\n\r\n $el = this.$el\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n this.onObserver()\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $anchor = this.$el.querySelector(`#chapter__anchor-${id}`)\r\n const HIGHLIGHT = 'outline-chapters_active'\r\n const $placeholder = this.$placeholder\r\n let top\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n this.$active = $anchor\r\n addClass(this.$active, HIGHLIGHT)\r\n\r\n top = 30 * this.active\r\n $placeholder.style.top = `calc(0.5em + ${top}px)`\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = !!(scrollTop >= top)\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n removeClass($parent, HIDDEN)\r\n removeClass($el, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n removeClass($el, FOLDED)\r\n }, 30)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n addClass($parent, FOLDED)\r\n addClass($el, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n addClass($el, HIDDEN)\r\n })\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = !!(scrollTop >= top)\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n this.$parentElement.removeChild(this.$el)\r\n\r\n this.attr(Chapters.DEFAULTS)\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.$active = null\r\n this.closed = false\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n let timer = null\r\n\r\n intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n timer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n { context: this }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'chapter')\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 50)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize)\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const byId = (id) => document.getElementById(id)\r\n\r\n chapters.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n [chapter.text]\r\n )\r\n const $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n [$text]\r\n )\r\n let $code\r\n let $li\r\n let $ul\r\n let $parent\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n [chapter.code]\r\n )\r\n\r\n $link.insertBefore($code, $link.firstChild)\r\n }\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n [$link]\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $parent = byId(`chapter-${pid}`)\r\n $ul = byId(`subject-${pid}`)\r\n\r\n if (!$ul) {\r\n $ul = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n [$li]\r\n )\r\n\r\n $parent.appendChild($ul)\r\n } else {\r\n $ul.appendChild($li)\r\n }\r\n }\r\n })\r\n}\r\n\r\nexport default _paintChapters\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n}\r\n\r\nexport default intersection\r\n","import { createSvgIcon } from './utils/icons'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\n\r\nconst _createButton = (button, rounded = true) => {\r\n const $icon = createSvgIcon(button.icon, button.size)\r\n const $anchor = createElement(\r\n 'a',\r\n {\r\n className: `outline-toolbar__anchor`,\r\n href: button.link\r\n },\r\n [$icon]\r\n )\r\n const $button = createElement(\r\n 'div',\r\n {\r\n className: `outline-toolbar__button ${button.name}`\r\n },\r\n [button.link ? $anchor : $icon]\r\n )\r\n\r\n addClass($icon, 'outline-toolbar__icon')\r\n\r\n if (rounded) {\r\n addClass($button, 'outline-toolbar_rounded')\r\n }\r\n\r\n if (button.disabled) {\r\n addClass($button, 'outline-toolbar_disabled')\r\n }\r\n\r\n return $button\r\n}\r\n\r\nexport default _createButton\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isObject from './utils/types/isObject'\r\nimport isArray from './utils/types/isArray'\r\nimport later from './utils/lang/later'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\nimport hasClass from './utils/dom/hasClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _createButton from './_createButton'\r\n\r\nconst DISABLED = 'outline-toolbar_disabled'\r\nconst HIDDEN = 'outline-toolbar_hidden'\r\n\r\nclass Toolbar extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Toolbar.DEFAULTS\r\n this.$el = null\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n this.disabled = this.attr('disabled')\r\n this.closed = this.attr('closed')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n isDisabled(name) {\r\n const buttons = this.attr('buttons')\r\n let button\r\n\r\n if (name) {\r\n button = buttons.find((option) => option.name === name)\r\n\r\n return !!(button && button.disabled)\r\n }\r\n\r\n return this.disabled\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n highlight(name) {\r\n const button = this.buttons.find((item) => item.name === name)\r\n const ACTIVE = 'outline-toolbar_active'\r\n let $button\r\n\r\n if ($button) {\r\n return this\r\n }\r\n\r\n $button = button.$el\r\n\r\n if (hasClass($button, ACTIVE)) {\r\n removeClass($button, ACTIVE)\r\n } else {\r\n addClass($button, ACTIVE)\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const buttons = this.attr('buttons') || []\r\n const rounded = this.attr('rounded')\r\n const placement = this.attr('placement')\r\n const $buttons = document.createDocumentFragment()\r\n const $fragment = document.createDocumentFragment()\r\n\r\n paintSvgSprites()\r\n\r\n buttons.forEach((button) => {\r\n const $button = _createButton(button, rounded)\r\n\r\n $buttons.appendChild($button)\r\n this.buttons.push({\r\n name: button.name,\r\n $el: $button\r\n })\r\n })\r\n\r\n this.$el = createElement(\r\n 'div',\r\n {\r\n id: 'outline-toolbar',\r\n className: `outline-toolbar outline-toolbar_${placement}`\r\n },\r\n [$buttons]\r\n )\r\n $fragment.appendChild(this.$el)\r\n document.body.appendChild($fragment)\r\n\r\n if (this.closed) {\r\n this.hide()\r\n }\r\n\r\n if (this.disabled) {\r\n this.disable()\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n add(button) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const action = button.action\r\n const $fragment = document.createDocumentFragment()\r\n let type\r\n\r\n if (isObject(button)) {\r\n buttons.push(button)\r\n $fragment.appendChild(_createButton(button))\r\n } else if (isArray(button)) {\r\n button.forEach((item) => {\r\n $fragment.appendChild(_createButton(item))\r\n })\r\n }\r\n $el.appendChild($fragment)\r\n\r\n if (action && isFunction(action.handler)) {\r\n type = action.type || 'click'\r\n on($el, `.${button.name}`, type, action.handler)\r\n }\r\n\r\n return this\r\n }\r\n\r\n remove(name) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let index = -1\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button, i) => {\r\n if (button.name === name) {\r\n index = i\r\n }\r\n })\r\n\r\n if (index > -1) {\r\n this.attr().buttons.splice(index, 1)\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n this.switch(name, false)\r\n $el.removeChild($button)\r\n\r\n return this\r\n }\r\n\r\n switch(name, enabled) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let action\r\n let type\r\n let listener\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((option) => {\r\n if (option.name === name) {\r\n button.disabled = !enabled\r\n }\r\n })\r\n\r\n action = button.action\r\n $button = $el.querySelector(`.${name}`)\r\n\r\n if (action) {\r\n type = action.type || 'click'\r\n listener = action.handler\r\n }\r\n\r\n if (enabled) {\r\n removeClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n on($el, `.${name}`, type, listener)\r\n }\r\n } else {\r\n addClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n off($el, type, listener)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n disable(name) {\r\n const disabled = this.attr('afterDisabled')\r\n\r\n if (name) {\r\n this.switch(name, false)\r\n } else {\r\n addClass(this.$el, DISABLED)\r\n this.removeListeners()\r\n this.disabled = true\r\n\r\n if (isFunction(disabled)) {\r\n disabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n enable(name) {\r\n const enabled = this.attr('afterEnabled')\r\n\r\n if (name) {\r\n this.switch(name, true)\r\n } else {\r\n this.disabled = false\r\n removeClass(this.$el, DISABLED)\r\n this.addListeners()\r\n\r\n if (isFunction(enabled)) {\r\n enabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n show(name) {\r\n const opened = this.attr('afterOpened')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n removeClass($button, HIDDEN)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n later(() => {\r\n opened.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide(name) {\r\n const closed = this.attr('afterClosed')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n $button = $el.querySelector(`.${name}`)\r\n addClass($button, HIDDEN)\r\n } else {\r\n addClass($el, HIDDEN)\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n later(() => {\r\n closed.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n let $el = this.$el\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n document.body.removeChild($el)\r\n $el = null\r\n\r\n this.attr(Toolbar.DEFAULTS)\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n refresh() {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons') || []\r\n\r\n this.removeListeners()\r\n $el.innerHTML = ''\r\n\r\n buttons.forEach((button) => {\r\n this.$el.appendChild(_createButton(button))\r\n })\r\n\r\n this.addListeners()\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n let context\r\n let command\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n if (isString(listener)) {\r\n command = listener\r\n action.handler = function () {\r\n publish(command, button.name)\r\n }\r\n listener = action.handler\r\n }\r\n\r\n type = action.type || 'click'\r\n context = action.context\r\n }\r\n\r\n if (isFunction(listener)) {\r\n on($el, `.${button.name}`, type, listener, context || this, true)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n type = action.type || 'click'\r\n }\r\n\r\n if (isFunction(listener)) {\r\n off($el, type, listener)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n}\r\n\r\nToolbar.DEFAULTS = {\r\n placement: 'ltr',\r\n closed: false,\r\n disabled: false,\r\n rounded: true,\r\n buttons: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterDisabled: null,\r\n afterEnabled: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Toolbar\r\n","/**\r\n * 生成唯一 id 字符串的函数\r\n * ========================================================================\r\n * @method guid\r\n * @param {String} [prefix] - 生成 id 的前缀字符串\r\n * @return {String} 返回一个表示唯一 id 的字符串\r\n */\r\nconst guid = (() => {\r\n let uuid = 0\r\n\r\n return (prefix) => {\r\n uuid += 1\r\n\r\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\r\n }\r\n})()\r\n\r\nexport default guid\r\n","import _subscribers from './_subscribers'\r\nimport isFunction from '../types/isFunction'\r\nimport guid from '../lang/guid'\r\n\r\n/**\r\n * 订阅主题,并给出处理器函数\r\n * ========================================================================\r\n * @method on\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Function} handler - (必须)主题的处理器函数\r\n * @param {Object} [context] - (可选)指定 this 执行上下文\r\n * @return {String|Boolean} - 唯一的 token 字符串,例如:'guid-1'。\r\n */\r\nconst on = (topic, handler, context = null) => {\r\n const token = guid()\r\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\r\n\r\n if (!isFunction(handler)) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (!_subscribers[subject]) {\r\n _subscribers[subject] = []\r\n }\r\n\r\n _subscribers[subject].push({\r\n topic: subject,\r\n callback: handler,\r\n context,\r\n token\r\n })\r\n\r\n return token\r\n}\r\n\r\nexport default on\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 删除与给定 topic 相同的订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriber\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _removeSubscriber = (topic) => {\r\n if (!hasOwn(_subscribers, topic)) {\r\n return false\r\n }\r\n\r\n delete _subscribers[topic]\r\n}\r\n\r\nexport default _removeSubscriber\r\n","import has from './has'\r\nimport _removeSubscriber from './_removeSubscriber'\r\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\r\n\r\n/**\r\n * 取消订阅主题\r\n * ========================================================================\r\n * @method off\r\n * @param {String} topic - (必须)订阅的主题\r\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\r\n */\r\nconst off = (topic, token) => {\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (token) {\r\n _removeSubscriberByToken(token)\r\n } else {\r\n _removeSubscriber(topic)\r\n }\r\n}\r\n\r\nexport default off\r\n","import _subscribers from './_subscribers'\r\nimport _removeSubscriber from './_removeSubscriber'\r\n\r\n/**\r\n * 通过订阅者 token 值删除订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriberByToken\r\n * @param {String} token - 订阅者 token 字符串\r\n * @returns {boolean}\r\n * @private\r\n */\r\nconst _removeSubscriberByToken = (token) => {\r\n const keys = Object.keys(_subscribers)\r\n let index = -1\r\n\r\n if (!token || keys.length < 1) {\r\n return false\r\n }\r\n\r\n keys.forEach((subject) => {\r\n const subscriber = _subscribers[subject]\r\n let topic\r\n\r\n subscriber.forEach((execution, j) => {\r\n if (execution.callback === token || execution.token === token) {\r\n topic = execution.topic\r\n subscriber.splice(index, j)\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (subscriber.length < 1) {\r\n _removeSubscriber(topic)\r\n }\r\n })\r\n}\r\n\r\nexport default _removeSubscriberByToken\r\n","import Base from './base'\r\nimport Anchors from './anchors'\r\nimport Drawer from './drawer'\r\nimport Chapters from './chapters'\r\nimport Toolbar from './toolbar'\r\n\r\nimport later from './utils/lang/later'\r\nimport isFunction from './utils/types/isFunction'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Outline extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Outline.DEFAULTS\r\n this.anchors = null\r\n this.drawer = null\r\n this.chapters = null\r\n this.toolbar = null\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n return this.anchors.getChapters(isTreeStructured)\r\n }\r\n\r\n count() {\r\n return this.anchors.count()\r\n }\r\n\r\n render() {\r\n this._renderAnchors()._renderChapters()._renderToolbar()\r\n\r\n return this\r\n }\r\n\r\n _renderAnchors() {\r\n const articleElement = this.attr('articleElement')\r\n const selector = this.attr('selector')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n\r\n this.anchors = new Anchors({\r\n articleElement,\r\n stickyHeight,\r\n scrollElement,\r\n selector,\r\n showCode,\r\n anchorURL,\r\n afterScroll\r\n })\r\n\r\n return this\r\n }\r\n\r\n _renderChapters() {\r\n const title = this.attr('title')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const customClass = this.attr('customClass')\r\n const showCode = this.attr('showCode')\r\n const position = this.attr('position')\r\n const placement = this.attr('placement')\r\n const afterSticky = this.attr('afterSticky')\r\n const afterToggle = this.attr('afterToggle')\r\n const afterScroll = this.attr('afterScroll')\r\n const count = this.count()\r\n let parentElement = this.attr('parentElement')\r\n let CHAPTERS_OPTIONS\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n CHAPTERS_OPTIONS = {\r\n scrollElement,\r\n showCode,\r\n position,\r\n title,\r\n stickyHeight,\r\n chapters: this.anchors.getChapters(),\r\n afterSticky,\r\n afterToggle,\r\n afterScroll\r\n }\r\n\r\n if (position === 'relative') {\r\n this.drawer = new Drawer({\r\n placement,\r\n title,\r\n size: 'tiny',\r\n hasOffset: true,\r\n hasPadding: false,\r\n customClass,\r\n afterClosed: () => {\r\n const toolbar = this.toolbar\r\n toolbar.toggle()\r\n }\r\n })\r\n parentElement = this.drawer.$main\r\n } else {\r\n CHAPTERS_OPTIONS.customClass = customClass\r\n }\r\n\r\n CHAPTERS_OPTIONS.parentElement = parentElement\r\n this.chapters = new Chapters(CHAPTERS_OPTIONS)\r\n\r\n return this\r\n }\r\n\r\n _renderToolbar() {\r\n const placement = this.attr('placement')\r\n const homepage = this.attr('homepage')\r\n const count = this.count()\r\n const UP = {\r\n name: 'up',\r\n icon: 'up',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:up'\r\n }\r\n }\r\n const HOME = {\r\n name: 'homepage',\r\n icon: 'homepage',\r\n size: 20,\r\n link: homepage\r\n }\r\n const MENU = {\r\n name: 'menu',\r\n icon: 'menu',\r\n size: 18,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:toggle'\r\n }\r\n }\r\n const DOWN = {\r\n name: 'down',\r\n icon: 'down',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:down'\r\n }\r\n }\r\n const buttons = []\r\n\r\n buttons.push(UP)\r\n if (homepage) {\r\n buttons.push(HOME)\r\n }\r\n if (count > 0) {\r\n buttons.push(MENU)\r\n }\r\n buttons.push(DOWN)\r\n\r\n this.toolbar = new Toolbar({\r\n placement,\r\n buttons: buttons\r\n })\r\n\r\n return this\r\n }\r\n\r\n toTop() {\r\n const afterScroll = this.attr('afterScroll')\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const afterTop = () => {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n\r\n if (count > 0) {\r\n chapters.highlight(0)\r\n }\r\n chapters.playing = false\r\n\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(toolbar, 'up')\r\n }\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(0, afterTop)\r\n\r\n return this\r\n }\r\n\r\n toBottom() {\r\n const afterScroll = this.attr('afterScroll')\r\n const $scrollElement = _getScrollElement(this.attr('scrollElement'))\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const top = Math.floor(\r\n $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n )\r\n const afterDown = () => {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n\r\n if (count > 1) {\r\n chapters.highlight(count - 1)\r\n }\r\n chapters.playing = false\r\n\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(toolbar, 'bottom')\r\n }\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(top, afterDown)\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, afterScroll) {\r\n const scrollElement = this.attr('scrollElement')\r\n scrollTo(scrollElement, top, afterScroll)\r\n return this\r\n }\r\n\r\n toggle() {\r\n const position = this.attr('position')\r\n const toolbar = this.toolbar\r\n const drawer = this.drawer\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n if (position !== 'relative') {\r\n chapters.toggle()\r\n toolbar.highlight('menu')\r\n } else {\r\n toolbar.toggle()\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n later(() => {\r\n if (chapters.isInside()) {\r\n chapters.toggle()\r\n } else {\r\n drawer.toggle()\r\n }\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n this.removeListeners()\r\n\r\n this.attr(Outline.DEFAULTS)\r\n this.anchors.destroy()\r\n if (count < 1) {\r\n chapters.destroy()\r\n if (chapters.isOutside()) {\r\n this.drawer.destroy()\r\n }\r\n }\r\n this.toolbar.destroy()\r\n\r\n return this\r\n }\r\n\r\n onToggle() {\r\n this.toggle()\r\n return this\r\n }\r\n\r\n onScrollTop() {\r\n this.toTop()\r\n return this\r\n }\r\n\r\n onScrollBottom() {\r\n this.toBottom()\r\n return this\r\n }\r\n\r\n onToolbarUpdate({ top, min, max }) {\r\n const toolbar = this.toolbar\r\n const current = Math.ceil(top)\r\n\r\n if (current <= min) {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n } else if (current >= max) {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n } else if (current > min && current < max) {\r\n toolbar.show('up')\r\n toolbar.show('down')\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n subscribe('toolbar:update', this.onToolbarUpdate, this)\r\n subscribe('toolbar:action:up', this.onScrollTop, this)\r\n subscribe('toolbar:action:toggle', this.onToggle, this)\r\n subscribe('toolbar:action:down', this.onScrollBottom, this)\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n unsubscribe('toolbar:update')\r\n unsubscribe('toolbar:action:up')\r\n unsubscribe('toolbar:action:toggle')\r\n unsubscribe('toolbar:action:down')\r\n return this\r\n }\r\n}\r\n\r\nOutline.DEFAULTS = {\r\n articleElement: '#article',\r\n selector: 'h2,h3,h4,h5,h6',\r\n title: '目录',\r\n scrollElement: 'html,body',\r\n position: 'relative',\r\n parentElement: '#aside',\r\n placement: 'rtl',\r\n showCode: true,\r\n anchorURL: '',\r\n stickyHeight: 0,\r\n customClass: '',\r\n afterSticky: null,\r\n afterToggle: null,\r\n afterScroll: null\r\n}\r\n\r\nif (window.jQuery) {\r\n // 将 Outline 扩展为一个 jquery 插件\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend(jQuery.fn, {\r\n outline: function (options) {\r\n // eslint-disable-next-line no-undef\r\n let $article = jQuery(this)\r\n\r\n return new Outline(\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend({}, options, {\r\n articleElement: $article\r\n })\r\n )\r\n }\r\n })\r\n}\r\n\r\nexport default Outline\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","later","fn","delay","setTimeout","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","scrollTo","top","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","offsetTop","el","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","off","on","data","context","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","closest","overrideContext","push","addEventListener","stopPropagation","preventDefault","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","isArray","Array","paintSvgSprites","symbols","SYMBOLS","sprites","concat","$body","body","$icons","innerHTML","join","createElement","insertBefore","firstChild","createSvgIcon","name","size","color","iconSet","binds","width","height","defaultRules","svg","$icon","className","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","hasClass","pattern","RegExp","allClass","classList","contains","match","removeClass","remove","_resetHeading","$heading","hasAnchor","isAtStart","CLS_HEADING","text","$anchor","removeAttribute","removeChild","getChapters","headings","showCode","chapters","previous","level","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","id","rel","groups","group","JSON","stringify","cb","code","String","c","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","anchorURL","chapterCode","headingId","href","_updateHeading","after","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","publish","min","addClass","add","setProperty","documentElement","zIndex","idx","Drawer","title","closed","$modal","$header","$title","$close","$main","$footer","$overlay","setTitle","isClosed","placement","hasClose","hasOverlay","hasOffset","hasPadding","autoHeight","customClass","open","opened","close","toggle","afterToggle","onClose","afterClosed","afterOpened","at","Chapters","$list","$placeholder","$parentElement","active","offsetWidth","$active","scrollTimer","resizeTimer","playing","parentElement","$parent","isSticky","isFixed","isInside","isOutside","_paintEdge","contents","calculateStickyHeight","byId","getElementById","chapter","$text","$link","$code","$li","$ul","_paintChapters","sticky","onObserver","highlight","HIGHLIGHT","getAttribute","afterSticky","FIXED","isStickying","Math","window","innerHeight","show","FOLDED","HIDDEN","hide","clearTimeout","timer","props","root","rootMargin","Observer","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","onSelect","split","onScroll","onResize","_createButton","button","rounded","icon","link","$button","disabled","DISABLED","Toolbar","buttons","isDisabled","find","option","ACTIVE","$buttons","disable","action","switch","enabled","enable","refresh","command","afterDisabled","afterEnabled","guid","uuid","prefix","token","subject","_removeSubscriber","execution","j","_removeSubscriberByToken","Outline","anchors","drawer","toolbar","_renderAnchors","_renderChapters","_renderToolbar","CHAPTERS_OPTIONS","homepage","HOME","MENU","toTop","toBottom","floor","onToggle","onScrollTop","onScrollBottom","onToolbarUpdate","ceil","subscribe","unsubscribe","jQuery","extend","outline","$article"],"mappings":"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"} \ No newline at end of file diff --git a/docs/sticky.html b/docs/sticky.html index c953b265..0afdbb8b 100644 --- a/docs/sticky.html +++ b/docs/sticky.html @@ -111,7 +111,32 @@ new Outline({ // 设置深色配置界面 customClass: 'theme-dark' -})

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
+})

afterScroll

Description

Type:
Function
Default:
null

可选,当点击导航菜单、文章中的 anchor 图标(#)或者上下滚动按钮会触发滚动,afterScroll() 回调函数会在滚动结束后触发执行。

Parameters

target
Type:
String

afterScroll() 回调函数有一个参数 target,返回的是当前点击的 DOM 元素的名称:

  • 'anchor':表示点击的是 anchor 图标,即文章中标题前的 “#” 图标,此时的 this 上下文指向 outline.anchors;
  • 'chapter':表示点击的是导航菜单的链接,此时的 this 上下文指向 outline.chapters;
  • 'up':表示点击的是工具栏的向上按钮,此时的 this 上下文指向 outline.toolbar;
  • 'down':表示点击的是工具栏的向下按钮,此时的 this 上下文指向 outline.toolbar;

注意:因为配置 afterScroll 回调函数会因为 4 个不同的 DOM 触发,所以需要根据 target 返回的值和此时的 this 指向判断处理。

const defaults = Outline.DEFAULTS
+let outline
+
+defaults.position = 'fixed'
+defaults.parentElement = '#aside'
+defaults.stickyHeight = 86
+defaults.homepage = './index.html'
+defaults.afterScroll = function(target) {
+  // 当然,如果你希望无论是点击什么都执行,就不需要判断了
+  // 直接些通用的滚动结束的逻辑即可
+  switch(target){
+    case 'anchor':
+      // 针对点击 # 的处理逻辑
+      break
+    case 'chapter':
+      // 针对点击导航菜单的处理逻辑
+      break
+    case 'up':
+      // 针对点击向上滚动按钮的处理逻辑
+      break
+    case 'down':
+      // 针对点击向下滚动按钮的处理逻辑
+      break
+  }
+}
+outline = new Outline(Outline.DEFAULTS)

afterSticky

Description

Type:
Function
Default:
null

可选,在设置 position: fixed 时,当导航菜单样式为 fixed 获取恢复为普通定位的时候,会触发执行 afterSticky 回调函数。

说明:afterSticky() 回调函数的 this 上下文执行 outline.chapters 对象。

Parameters

closed
Type:
Boolean

closed 参数值为 true 表示菜单处于隐藏状态,否则表示菜单处于显示状态

isSticky
Type:
Boolean

isSticky 参数值为 true 表示(position:fixed)菜单处于模拟 sticky 定位(position:fixed)状态,否则表示菜单处于普通状态。

const $header = document.querySelector('#header')
 const HEADER_STICKY = 'header_sticky'
 const defaults = Outline.DEFAULTS
 let outline
diff --git a/outline.min.js b/outline.min.js
index e7ab344a..02a5df24 100644
--- a/outline.min.js
+++ b/outline.min.js
@@ -1,2 +1,2 @@
-!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Outline=e()}(this,(function(){"use strict";const t=t=>"string"==typeof t,e=(t,e)=>{const s=Object.prototype.hasOwnProperty;return t&&s.call(t,e)},s=t=>Object.prototype.toString.apply(t),i=t=>"function"==typeof t||"[object Function]"===s(t),r=t=>("[object Object]"===s(t)||"object"==typeof t||i(t))&&null!==t;class l{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(s,i){const l=this.attrs;return t(s)?i&&e(l,s)?(l[s]=i,this):l[s]:r(s)?(n=l,o=s,Object.keys(o).forEach((t=>{e(o,t)&&(n[t]=o[t])})),this):0===arguments.length?l:this;var n,o}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const n=t=>!!(r(t)&&t.nodeName&&t.tagName&&1===t.nodeType),o=(t,e=300)=>!!i(t)&&setTimeout((()=>{t()}),e),h=t=>t*t,a=(e=null)=>{let s,i;return e?t(e)?i=document.querySelector(e):n(e)&&(i=e):(s=document.querySelectorAll("html,body"),i=s[0].scrollTop-s[1].scrollTop>=0?s[0]:s[1]),i},c=(t,e,s)=>{const r=a(t);let l=r.scrollTop,n=0;const o=e-l,c=r.scrollHeight,d=e-c<=0?e:c,u=t=>(i(s)&&s(t),!1),p=()=>{if(n+=1,o<0){if(l-=h(n),r.scrollTop=l,l<=e)return r.scrollTop=e,u(e)}else if(l+=h(n),r.scrollTop=l,l>=d)return r.scrollTop=d,u(d);requestAnimationFrame(p)};requestAnimationFrame(p)},d=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=d(t.offsetParent)),e},u=(t,e="")=>{const s=e.replace(/^>/i,"");return!!(e&&s&&t)&&(t.matches?t.matches(s):!!t.msMatchesSelector&&t.msMatchesSelector(s))},p=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,m=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],f=(t,e,s)=>{const i=m.indexOf(e)>-1;s._delegateListener&&delete(s=s._delegateListener)._delegateListener,function(t,e,s){const i=t._listeners;let r=-1;if(i.length<1)return!1;i.forEach(((t,i)=>{const l=t.fn;e===t.type&&(r=i,l===s&&(r=i))})),r>-1&&i.splice(r,1)}(t,e,s),t.removeEventListener(e,s,i)},g=function(e,s,i=!1){const r=t(e)?document.querySelector(e):e,l=r.childNodes,o=((e,s)=>{let i=e._listeners||[];return t(s)&&s&&(i=i.filter((t=>t.type===s))),i})(r,s);o.forEach((t=>{f(r,t.type,t.fn)})),(i||!0===s||1===arguments.length)&&r&&l&&l.forEach((t=>{n(t)&&g(t,s,i)}))},y=(t,e,s)=>{if(!i(s))return g(t,e);f(t,e,s)},b=(t,e,s,i,r,l,n=!1)=>{const o=m.indexOf(s)>-1,h=function(o){const a=function(t){const e=t.target;return(s=e)&&3===s.nodeType?s.parentNode:s;var s}(o),c=((t,e,s,i)=>{const r=s||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===r&&u(t,e):u(t,e))||i&&t===r)return t;if(t===r)break}while(t=p(t))})(a,e,t);let d=l||t;o.delegateTarget=c,!0===l&&(d=r),c&&(!0===n&&y(t,s,h),i.call(d,o,r))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:s,fn:h,data:r,context:l,capture:o}),i._delegateListener=h,t.addEventListener(s,h,o)},$=function(t){t.stopPropagation(),t.preventDefault()},v={},E=t=>e(v,t)&&v[t].length>0,_=(t,e=!0)=>e?E(t):(t=>{let e=E(t),s=t.lastIndexOf(".");for(;!e&&-1!==s;)s=(t=t.substring(0,s)).lastIndexOf("."),e=E(t);return e})(t),T=(t,e,i=!0)=>{const r=t=>{if(!E(t))return!1;v[t].forEach((t=>{const i=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(s(e))>-1?e.toString():e;t.callback.call(t.context||t,i)}))},l=()=>{let e=t,s=t.lastIndexOf(".");for(;-1!==s;)e=e.substring(0,s),s=e.lastIndexOf("."),r(e);r(t),r("*")};if(!_(t))return!1;i?setTimeout(l,10):l()},w=t=>Array.isArray?Array.isArray(t):"[object Array]"===s(t),L=(t=[])=>{const e=['','','','','','','',''],s=w(t)&&t.length>0?e.concat(t):e,i=document.body;let r=document.querySelector("#svg-sprites");r?r.innerHTML=s.join(""):(r=document.createElement("div"),r.innerHTML=``,i.insertBefore(r.firstChild,i.firstChild))},C=(t,e=0,s="",i="outline")=>{const r=i?`xlink:href="#${i}-icon-${t}"`:`xlink:href="#icon-${t}"`,l=w(e)?e[0]:e,n=w(e)?e[1]:e,o=e?`width:${l}px;height:${n}px;`:"",h=``,a=document.createElement("i");return a.className="outline-icon",a.innerHTML=h,a},x=e=>!!t(e)&&e.replace(/^\s+|\s+$/g,""),S=t=>{return!(!r(t)||!(n(t)||(t=>!(!r(t)||"[object NodeList]"!==s(t)))(t)||(e=t,r(e)&&"[object DocumentFragment]"===s(e))||(t=>!(!r(t)||!("[object Text]"===s(t)||t.tagName&&3===t.nodeType)))(t)));var e},z=(t,e,s)=>{let i=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=s;break;case"value":"input"===i||"textarea"===i?t.value=s:t.setAttribute(e,s);break;case"className":t.className=s;break;default:t.setAttribute(e,s)}},k=(s,i,l)=>{const n=document.createDocumentFragment(),o=document.createElement(s),h=e=>S(e)||t(e),a=e=>{let s;if(!h(e))return!1;S(e)?s=e:t(e)&&(s=document.createTextNode(e)),n.appendChild(s)};return r(i)?Object.keys(i).forEach((t=>{e(i,t)&&z(o,t,i[t])})):w(i)&&i.every((t=>h(t)))&&i.forEach((t=>{a(t)})),w(l)?l.forEach((t=>{a(t)})):a(l),o.appendChild(n),o},A=(t,e)=>{const s=new RegExp("(\\s|^)"+e+"(\\s|$)");let i,r;return!!n(t)&&(i=t.className,!!i&&(r=t.classList,r?.contains?t.classList.contains(e):!!i.match(s)))},N=(t,e)=>{let s,i=t.className;if(!i||!A(t,e))return!1;s=t.classList,s?.remove?s.remove(e):(i=x(i.replace(e,"")),t.className=i)},M=(e,s=!0,i=!0)=>{const r="outline-heading",l=e.innerHTML;let n;if(e.innerHTML=l.replace(/^\d+(?:(\.?\d*)*\s?)?/gi,""),e.removeAttribute("id"),e.removeAttribute("data-id"),N(e,r),!s)return!1;var o;n=e.querySelector(`.${r}__anchor`),i&&N(e,`${r}_start`),o=x(e.className),t(o)&&""===o&&e.removeAttribute("class"),e.removeChild(n)},D=(e,s=!0)=>{const i=[];let r=1,l=0;return e.forEach(((e,s)=>{const n=e.tagName.replace(/h/i,"");let o=parseInt(n,10),h=-1;var a;o>r?(l+=1,h=1===l?-1:s-1):o===r||ol?1===o?(l=1,h=-1):h=i[s-1].pid:o<=l&&(1===o?l=1:(l-=r-o,l<=1&&(l=1)),h=1===l?-1:((t,e,s)=>{let i,r,l=t[s-1];for(r=0;r]+(>|$)/g,""):"")})})),s?(t=>{const e={};return t.forEach((t=>{const s=JSON.stringify((t=>[t.pid])(t));e[s]=e[s]||[],e[s].push(t),t.index=e[s].length,-1===t.pid&&(t.code=String(t.index))})),Object.keys(e).forEach((s=>{e[s].forEach(((e,s)=>{e.index=s+1,t.forEach((t=>{t.pid===e.id&&(t.code=e.code+"."+t.index)}))}))})),t})(i):i};class H extends l{constructor(t){super(),this.attrs=H.DEFAULTS,this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],t&&this.initialize(t)}initialize(e){let s,r,l,o,h;return this.attr(e),h=this.attr("articleElement"),r=this.attr("scrollElement"),l=this.attr("selector"),s=this.attr("created"),t(h)?o=document.querySelector(h):n(h)&&(o=h),o?(this.$articleElement=o,this.$scrollElement=a(r),this.$headings=[...o.querySelectorAll(l)],this.$headings.length<1||(this.chapters=D(this.$headings),i(s)&&s.call(this),this.render().addListeners()),this):this}getChapters(t=!1){const e=this.chapters;return t?((t,e,s)=>{const i={},r=[];return t.forEach(((t,s)=>{i[t[e]]=s,t.children=[]})),t.forEach((e=>{const l=t[i[e[s]]];-1!==e[s]?l.children.push(e):r.push(e)})),r})(e,"id","pid"):e}count(){return this.chapters.length}render(){const t=this.attr("mounted"),e=this.attr("hasAnchor"),s=this.attr("isAtStart"),r=this.attr("showCode"),l=this.attr("anchorURL"),n=this.$headings,o=this.getChapters();return L(),n.forEach(((t,i)=>{const n=o[i].code;((t,e,s)=>{const i="outline-heading",r=s.hasAnchor||!0,l=s.isAtStart||!0,n=s.showCode||!1,o=s.chapterCode||"",h=s.anchorURL||"",a=`heading-${e}`,c={id:a,className:l?`${i} ${i}_start`:i,"data-id":e},d=Object.keys(c),u=x(t.innerHTML);let p,m;if(d.forEach((e=>{z(t,e,c[e])})),n&&(t.innerHTML=o+" "+u),!r)return!1;m=C("hash"),p=k("a",{id:`anchor-${e}`,className:`${i}__anchor anchor-${e}`,href:h||`#${a}`,target:h?"_blank":"self","data-id":e},[m]),t.appendChild(p)})(t,i,{hasAnchor:e,isAtStart:s,showCode:r,chapterCode:n,anchorURL:l})})),i(t)&&t.call(this),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}destroy(){const t=this.attr("hasAnchor"),e=this.attr("isAtStart"),s=this.attr("beforeDestroy"),r=this.attr("afterDestroy"),l=this.$headings;return i(s)&&s.call(this),this.removeListeners(),l.forEach((s=>{M(s,t,e)})),this.attr(H.DEFAULTS),this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],i(r)&&r.call(this),this}onAnchorTrigger(t){const e=this.attr("anchorURL"),s=this.attr("afterScroll"),r=this.attr("stickyHeight"),l=t.delegateTarget.parentNode,n=d(l)-(r+10),h=this.$scrollElement,a=h.scrollHeight-h.clientHeight;return this.scrollTo(n,(()=>{i(s)&&s.call(this),o((()=>{T("toolbar:update",{top:n,min:0,max:a})}))})),e||$(t),this}addListeners(){const t=this.$articleElement;return b(t,".outline-heading__anchor","click",this.onAnchorTrigger,this,!0),this}removeListeners(){const t=this.$articleElement;return y(t,"click",this.onAnchorTrigger),this}}H.DEFAULTS={scrollElement:"html,body",articleElement:"#article",selector:"h1,h2,h3,h4,h5,h6",stickyHeight:0,anchorURL:"",hasAnchor:!0,isAtStart:!0,showCode:!1,created:null,mounted:null,afterScroll:null,beforeDestroy:null,afterDestroy:null};const j=(t,e)=>{let s,i;if(A(t,e))return!1;s=t.classList,s?.add?s.add(e):(i=t.className,i+=i.length>0?" "+e:e,t.className=i)},O=(t,e)=>{document.documentElement.style.setProperty(t,e)};let F=2e3;const U=t=>(t?F=t:F+=1,O("--outline-zIndex",`${F}`),F);class I extends l{constructor(t){super(),this.attrs=I.DEFAULTS,this.title="",this.closed=!0,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,this.zIndex=0,t&&this.initialize(t)}initialize(t){let e;return this.attr(t),this.title=this.attr("title"),e=this.attr("created"),i(e)&&e.call(this),this.render().addListeners(),this}setTitle(t){return this.attr("title",t),this.title=t,this.$title.innerHTML=t,this}isClosed(){return this.closed}render(){const t=this.attr("mounted"),e=this.attr("size"),s=this.attr("placement"),r=this.attr("hasClose"),l=this.attr("hasOverlay"),n=this.attr("hasOffset"),o=this.attr("hasPadding"),h=this.attr("autoHeight"),a=this.attr("customClass"),c=document.createDocumentFragment();let d,u,p,m,f,g,y,b;return L(),this.zIndex=U(),m=k("h2",{className:"outline-drawer__title"},[this.title]),this.$title=m,r&&(f=k("div",{className:"outline-drawer__close"},[C("close",20)]),this.$close=f),p=k("header",{className:"outline-drawer__header"},[m,f]),this.$header=p,g=k("div",{className:"outline-drawer__main"},[""]),this.$main=g,o||j(g,"outline-drawer_full"),y=k("footer",{className:"outline-drawer__footer"},[""]),this.$footer=y,u=k("div",{className:`outline-drawer__modal outline-drawer_${s} outline-drawer_${e} outline-drawer_closed`},[p,g,y]),this.$modal=u,n&&j(u,"outline-drawer_offset"),h&&j(u,"outline-drawer_auto"),a&&j(u,a),l&&(b=k("div",{className:"outline-drawer__overlay"},[""]),this.$overlay=b),d=k("div",{className:"outline-drawer"},[u,b]),this.$el=d,c.appendChild(d),document.body.appendChild(c),i(t)&&t.call(this),this}open(){const t=this.attr("afterOpened"),e=this.$modal;return j(this.$el,"outline-drawer_opened"),N(e,"outline-drawer_closed"),j(e,"outline-drawer_opened"),o((()=>{this.closed=!1,i(t)&&t.call(this)})),this}close(){const t=this.attr("afterClosed"),e=this.$modal;return N(e,"outline-drawer_opened"),j(e,"outline-drawer_closed"),o((()=>{N(this.$el,"outline-drawer_opened"),this.closed=!0,i(t)&&t.call(this)})),this}toggle(){const t=this.attr("afterToggle"),e=this.isClosed();return e?this.open():this.close(),i(t)&&o((()=>{t.call(this,e)})),this}destroy(){const t=this.attr("afterDestroy"),e=this.attr("beforeDestroy");let s=this.zIndex;return i(e)&&e.call(this),this.removeListeners(),this.attrs=I.DEFAULTS,this.title="",this.closed=!1,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,s-=1,U(s),this.zIndex=0,i(t)&&t.call(this),this}addListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t&&b(s,".outline-drawer__close","click",this.onClose,this,!0),e&&b(s,".outline-drawer__overlay","click",this.onClose,this,!0),this}removeListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t||e?(y(s,"click",this.onClose),this):this}onClose(){return this.close(),this}}I.DEFAULTS={placement:"rtl",title:"标题",size:"regular",hasClose:!0,hasOverlay:!0,hasOffset:!1,hasPadding:!0,autoHeight:!0,created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterToggle:null};const q=(t,e,s,r,l,n=!1)=>{const o=m.indexOf(e)>-1,h=function(i){let o=l||t;!0===l&&(o=r),!0===n&&y(t,e,h),s.call(o,i,r)};if(!i(s))return!1;t._listeners||(t._listeners=[]),t._listeners.push({el:t,type:e,fn:h,data:r,context:l,capture:o}),s._delegateListener=h,t.addEventListener(e,h,o)};class B extends l{constructor(t){super(),this.attrs=B.DEFAULTS,this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.closed=!1,this.active=0,this.offsetTop=0,this.offsetWidth=0,this.$active=null,this.scrollTimer=null,this.resizeTimer=null,this.playing=!1,t&&this.initialize(t)}initialize(e){let s,r,l,o;return this.attr(e),s=this.attr("created"),r=this.attr("parentElement"),l=this.attr("scrollElement"),t(r)?o=document.querySelector(r):n(r)&&(o=r),this.$parentElement=o,this.$scrollElement=a(l),this.chapters=this.attr("chapters"),this.closed=this.attr("closed"),this.active=this.attr("active"),i(s)&&s.call(this),this.chapters.length<1||(this.render().addListeners(),this.$active=document.querySelector(`#chapter-${this.active}`)),this}isClosed(){return this.closed}isSticky(){return"sticky"===this.attr("position")}isFixed(){return"fixed"===this.attr("position")}isInside(){return this.isFixed()||this.isSticky()}isOutside(){return!this.isInside()}_paintEdge(){const t=this.attr("title"),e=this.attr("customClass"),s=this.$parentElement,i=[];let r,l,n,o,h=null;return s?(this.isInside()&&(h=k("h2",{className:"outline-chapters__title"},[t]),this.$title=h,i.push(h)),n=k("ul",{className:"outline-chapters__list outline-chapters_fixed outline-chapters_hidden"},[""]),this.$list=n,o=k("div",{className:"outline-chapters__placeholder"},[""]),this.$placeholder=o,l=k("div",{className:"outline-chapters__main"},[n,o]),this.$main=l,i.push(l),r=k("nav",{id:"outline-chapters",className:"outline-chapters"},i),this.$el=r,this.isSticky()&&(this.calculateStickyHeight(),j(r,"outline-chapters_sticky")),e&&j(r,e),s.appendChild(r),this):this}render(){const t=this.attr("showCode"),e=this.attr("mounted");let s,r;return this.$parentElement?(this._paintEdge(),r=this.$list,((t,e,s=!1)=>{const i=t=>document.getElementById(t);e.forEach((e=>{const r=e.pid,l=e.id,n=e.rel,o=k("span",{className:"outline-chapters__text"},[e.text]),h=k("a",{id:`chapter__anchor-${l}`,className:"outline-chapters__anchor",href:"#"+n,rel:n,"data-id":l},[o]);let a,c,d,u;s&&(a=k("span",{className:"outline-chapters__code","data-id":l},[e.code]),h.insertBefore(a,h.firstChild)),c=k("li",{id:`chapter-${l}`,className:"outline-chapters__item","data-id":l},[h]),-1===r?t.appendChild(c):(u=i(`chapter-${r}`),d=i(`subject-${r}`),d?d.appendChild(c):(d=k("ul",{id:"subject-"+r,className:"outline-chapters__subject"},[c]),u.appendChild(d)))}))})(r,this.chapters,t),N(r,"outline-chapters_fixed"),N(r,"outline-chapters_hidden"),s=this.$el,this.offsetTop=d(s),this.offsetWidth=s.offsetWidth,this.isFixed()&&(this.sticky(),O("--outline-chapters-width",`${this.offsetWidth}px`)),i(e)&&e.call(this),this.onObserver(),this):this}highlight(t){const e=this.$el.querySelector(`#chapter__anchor-${t}`),s="outline-chapters_active",i=this.$placeholder;let r;return this.$active&&N(this.$active,s),this.active=parseInt(e.getAttribute("data-id"),10),this.$active=e,j(this.$active,s),r=30*this.active,i.style.top=`calc(0.5em + ${r}px)`,this}sticky(){const t=this.attr("afterSticky"),e="outline-chapters_fixed",s=this.$el,r=this.offsetTop,l=this.$scrollElement.scrollTop;let n;return this.isFixed()?(n=!!(l>=r),n?j(s,e):N(s,e),i(t)&&t.call(this,this.isClosed(),n),this):this}calculateStickyHeight(){const t=document.documentElement,e=Math.max(t.clientHeight||0,window.innerHeight||0);return O("--outline-sticky-height",`${e}px`),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}show(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterOpened"),r=this.$el,l=this.$parentElement;return this.isInside()?(N(l,e),N(r,e),o((()=>{N(l,t),N(r,t)}),30)):N(r,e),this.closed=!1,i(s)&&s.call(this),this}hide(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterClosed"),r=this.$el,l=this.$parentElement;return this.isInside()?(j(l,t),j(r,t),o((()=>{j(l,e),j(r,e)}))):j(r,e),this.closed=!0,i(s)&&s.call(this),this}toggle(){const t=this.attr("afterToggle"),e=this.offsetTop,s=this.$scrollElement.scrollTop;let r;return this.isClosed()?this.show():this.hide(),i(t)&&o((()=>{r=!!(s>=e),t.call(this,this.isClosed(),r)})),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");return i(t)&&t.call(this),this.removeListeners(),this.$parentElement.removeChild(this.$el),this.attr(B.DEFAULTS),this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.active=0,this.offsetTop=0,this.$active=null,this.closed=!1,this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),i(e)&&e.call(this),this}onObserver(){let t=null;return((t,e={})=>{const s=e.root||null,r=e.selector||".outline-heading",l=e.context||null,o={rootMargin:e.rootMargin||"0px 0px -90% 0px"},h=new IntersectionObserver((e=>{e.forEach((e=>{e.intersectionRatio>0&&i(t)&&t.call(l||e.target,e.target)}))}),o),a=n(s)?s:document;s&&(o.root=s),a.querySelectorAll(r).forEach((t=>{h.observe(t)}))})((e=>{const s=e.getAttribute("data-id");if(this.playing)return!1;t&&clearTimeout(t),t=o((()=>{this.highlight(s)}),100)}),{context:this}),this}onSelect(t){const e=this.attr("stickyHeight"),s=t.delegateTarget,r=s.getAttribute("data-id"),l=s.href.split("#")[1],n=document.querySelector(`#${l}`),h=d(n)-(e+10),a=this.$scrollElement.scrollHeight,c=this.attr("afterScroll"),u=()=>{i(c)&&c.call(this),o((()=>{this.playing=!1,T("toolbar:update",{top:h,min:0,max:a})}))};return this.playing=!0,this.isFixed()?(this.sticky(),o((()=>{this.scrollTo(h,u),this.highlight(r)}),10)):(this.scrollTo(h,u),this.highlight(r)),$(t),this}onScroll(){const t=this.$scrollElement;return this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=o((()=>{const e=t.scrollTop,s=t.scrollHeight-t.clientHeight;this.isFixed()&&this.sticky(),T("toolbar:update",{top:e,min:0,max:s})}),50),this}onResize(){return this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=o((()=>{this.calculateStickyHeight()})),this}addListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),b(t,".outline-chapters__anchor","click",this.onSelect,this,!0),q(i,"scroll",this.onScroll,this,!0),this.isSticky()&&q(i,"resize",this.onResize,this,!0),this}removeListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),y(t,"click",this.onSelect),y(i,"scroll",this.onScroll),this.isSticky()&&q(i,"resize",this.onResize),this}}B.DEFAULTS={parentElement:"",scrollElement:"",selector:"",active:0,closed:!1,showCode:!0,position:"relative",stickyHeight:0,chapters:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterSticky:null};const R=(t,e=!0)=>{const s=C(t.icon,t.size),i=k("a",{className:"outline-toolbar__anchor",href:t.link},[s]),r=k("div",{className:`outline-toolbar__button ${t.name}`},[t.link?i:s]);return j(s,"outline-toolbar__icon"),e&&j(r,"outline-toolbar_rounded"),t.disabled&&j(r,"outline-toolbar_disabled"),r},P="outline-toolbar_disabled",Q="outline-toolbar_hidden";class V extends l{constructor(t){super(),this.attrs=V.DEFAULTS,this.$el=null,this.disabled=!1,this.closed=!1,this.buttons=[],t&&this.initialize(t)}initialize(t){let e;return this.attr(t),e=this.attr("created"),this.disabled=this.attr("disabled"),this.closed=this.attr("closed"),i(e)&&e.call(this),this.render().addListeners(),this}isDisabled(t){const e=this.attr("buttons");let s;return t?(s=e.find((e=>e.name===t)),!(!s||!s.disabled)):this.disabled}isClosed(){return this.closed}highlight(t){const e=this.buttons.find((e=>e.name===t)),s="outline-toolbar_active";let i;return i||(i=e.$el,A(i,s)?N(i,s):j(i,s)),this}render(){const t=this.attr("mounted"),e=this.attr("buttons")||[],s=this.attr("rounded"),r=this.attr("placement"),l=document.createDocumentFragment(),n=document.createDocumentFragment();return L(),e.forEach((t=>{const e=R(t,s);l.appendChild(e),this.buttons.push({name:t.name,$el:e})})),this.$el=k("div",{id:"outline-toolbar",className:`outline-toolbar outline-toolbar_${r}`},[l]),n.appendChild(this.$el),document.body.appendChild(n),this.closed&&this.hide(),this.disabled&&this.disable(),i(t)&&t.call(this),this}add(t){const e=this.$el,s=this.attr("buttons"),l=t.action,n=document.createDocumentFragment();let o;return r(t)?(s.push(t),n.appendChild(R(t))):w(t)&&t.forEach((t=>{n.appendChild(R(t))})),e.appendChild(n),l&&i(l.handler)&&(o=l.type||"click",b(e,`.${t.name}`,o,l.handler)),this}remove(t){const e=this.$el,s=this.attr("buttons"),i=s.find((e=>e.name===t));let r,l=-1;return i?(s.forEach(((e,s)=>{e.name===t&&(l=s)})),l>-1&&this.attr().buttons.splice(l,1),r=e.querySelector(`.${t}`),this.switch(t,!1),e.removeChild(r),this):this}switch(t,e){const s=this.$el,i=this.attr("buttons"),r=i.find((e=>e.name===t));let l,n,o,h;return r?(i.forEach((s=>{s.name===t&&(r.disabled=!e)})),l=r.action,h=s.querySelector(`.${t}`),l&&(n=l.type||"click",o=l.handler),e?(N(h,P),n&&o&&b(s,`.${t}`,n,o)):(j(h,P),n&&o&&y(s,n,o)),this):this}disable(t){const e=this.attr("afterDisabled");return t?this.switch(t,!1):(j(this.$el,P),this.removeListeners(),this.disabled=!0,i(e)&&e.call(this)),this}enable(t){const e=this.attr("afterEnabled");return t?this.switch(t,!0):(this.disabled=!1,N(this.$el,P),this.addListeners(),i(e)&&e.call(this)),this}show(t){const e=this.attr("afterOpened"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),N(l,Q)}else N(r,Q),this.closed=!1,i(e)&&o((()=>{e.call(this)}),310);return this}hide(t){const e=this.attr("afterClosed"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),j(l,Q)}else j(r,Q),this.closed=!0,i(e)&&o((()=>{e.call(this)}),310);return this}toggle(){return this.isClosed()?this.show():this.hide(),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");let s=this.$el;return i(t)&&t.call(this),this.removeListeners(),document.body.removeChild(s),s=null,this.attr(V.DEFAULTS),this.disabled=!1,this.closed=!1,this.buttons=[],i(e)&&e.call(this),this}refresh(){const t=this.$el,e=this.attr("buttons")||[];return this.removeListeners(),t.innerHTML="",e.forEach((t=>{this.$el.appendChild(R(t))})),this.addListeners(),this}addListeners(){const e=this.attr("buttons"),s=this.$el;return!e||e.length<1||e.forEach((e=>{const r=e.action;let l,n,o,h;if(this.disabled)return!1;r&&(n=r.handler,t(n)&&(h=n,r.handler=function(){T(h,e.name)},n=r.handler),l=r.type||"click",o=r.context),i(n)&&b(s,`.${e.name}`,l,n,o||this,!0)})),this}removeListeners(){const t=this.attr("buttons"),e=this.$el;return!t||t.length<1||t.forEach((t=>{const s=t.action;let r,l;if(this.disabled)return!1;s&&(l=s.handler,r=s.type||"click"),i(l)&&y(e,r,l)})),this}}V.DEFAULTS={placement:"ltr",closed:!1,disabled:!1,rounded:!0,buttons:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterDisabled:null,afterEnabled:null,beforeDestroy:null,afterDestroy:null};const W=(()=>{let t=0;return e=>(t+=1,e?e+"-"+t:"guid-"+t)})(),J=(t,e,s=null)=>{const r=W();let l="symbol"==typeof t?t.toString():t;return!!i(e)&&(v[l]||(v[l]=[]),v[l].push({topic:l,callback:e,context:s,token:r}),r)},G=t=>{if(!e(v,t))return!1;delete v[t]},K=(t,e)=>{if(!_(t))return!1;e?(t=>{const e=Object.keys(v);if(!t||e.length<1)return!1;e.forEach((e=>{const s=v[e];let i;s.forEach(((e,r)=>{e.callback!==t&&e.token!==t||(i=e.topic,s.splice(-1,r))})),s.length<1&&G(i)}))})(e):G(t)};class X extends l{constructor(t){super(),this.attrs=X.DEFAULTS,this.anchors=null,this.drawer=null,this.chapters=null,this.toolbar=null,t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}getChapters(t=!1){return this.anchors.getChapters(t)}count(){return this.anchors.count()}render(){return this._renderAnchors()._renderChapters()._renderToolbar(),this}_renderAnchors(){const t=this.attr("articleElement"),e=this.attr("selector"),s=this.attr("stickyHeight"),i=this.attr("scrollElement"),r=this.attr("showCode"),l=this.attr("anchorURL");return this.anchors=new H({articleElement:t,stickyHeight:s,scrollElement:i,selector:e,showCode:r,anchorURL:l}),this}_renderChapters(){const t=this.attr("title"),e=this.attr("stickyHeight"),s=this.attr("scrollElement"),i=this.attr("customClass"),r=this.attr("showCode"),l=this.attr("position"),n=this.attr("placement"),o=this.attr("afterSticky"),h=this.attr("afterToggle"),a=this.count();let c,d=this.attr("parentElement");return a<1||(c={scrollElement:s,showCode:r,position:l,title:t,stickyHeight:e,chapters:this.anchors.getChapters(),afterSticky:o,afterToggle:h},"relative"===l?(this.drawer=new I({placement:n,title:t,size:"tiny",hasOffset:!0,hasPadding:!1,customClass:i,afterClosed:()=>{this.toolbar.toggle()}}),d=this.drawer.$main):c.customClass=i,c.parentElement=d,this.chapters=new B(c)),this}_renderToolbar(){const t=this.attr("placement"),e=this.attr("homepage"),s=this.count(),i={name:"homepage",icon:"homepage",size:20,link:e},r={name:"menu",icon:"menu",size:18,action:{type:"click",handler:"toolbar:action:toggle"}},l=[];return l.push({name:"up",icon:"up",size:20,action:{type:"click",handler:"toolbar:action:up"}}),e&&l.push(i),s>0&&l.push(r),l.push({name:"down",icon:"down",size:20,action:{type:"click",handler:"toolbar:action:down"}}),this.toolbar=new V({placement:t,buttons:l}),this}toTop(){const t=this.toolbar,e=this.chapters,s=this.count();return e.playing=!0,this.scrollTo(0,(()=>{t.hide("up"),t.show("down"),s>0&&e.highlight(0),e.playing=!1})),this}toBottom(){const t=a(this.attr("scrollElement")),e=this.toolbar,s=this.chapters,i=this.count(),r=Math.floor(t.scrollHeight-t.clientHeight);return s.playing=!0,this.scrollTo(r,(()=>{e.hide("down"),e.show("up"),i>1&&s.highlight(i-1),s.playing=!1})),this}scrollTo(t,e){const s=this.attr("scrollElement");return c(s,t,e),this}toggle(){const t=this.attr("position"),e=this.toolbar,s=this.drawer,i=this.chapters,r=this.count();if("relative"!==t)i.toggle(),e.highlight("menu");else{if(e.toggle(),r<1)return this;o((()=>{i.isInside()?i.toggle():s.toggle()}))}return this}destroy(){const t=this.chapters,e=this.count();return this.removeListeners(),this.attr(X.DEFAULTS),this.anchors.destroy(),e<1&&(t.destroy(),t.isOutside()&&this.drawer.destroy()),this.toolbar.destroy(),this}onToggle(){return this.toggle(),this}onScrollTop(){return this.toTop(),this}onScrollBottom(){return this.toBottom(),this}onToolbarUpdate({top:t,min:e,max:s}){const i=this.toolbar,r=Math.ceil(t);return r<=e?(i.hide("up"),i.show("down")):r>=s?(i.hide("down"),i.show("up")):r>e&&r"string"==typeof t,e=(t,e)=>{const s=Object.prototype.hasOwnProperty;return t&&s.call(t,e)},s=t=>Object.prototype.toString.apply(t),i=t=>"function"==typeof t||"[object Function]"===s(t),r=t=>("[object Object]"===s(t)||"object"==typeof t||i(t))&&null!==t;class l{constructor(t){this.attrs={},t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}attr(s,i){const l=this.attrs;return t(s)?i&&e(l,s)?(l[s]=i,this):l[s]:r(s)?(n=l,o=s,Object.keys(o).forEach((t=>{e(o,t)&&(n[t]=o[t])})),this):0===arguments.length?l:this;var n,o}render(){return this}destroy(){return this.removeListeners(),this}reload(t){return this.destroy().initialize(this.attr(t)),this}addListeners(){return this}removeListeners(){return this}}const n=t=>!!(r(t)&&t.nodeName&&t.tagName&&1===t.nodeType),o=(t,e=300)=>!!i(t)&&setTimeout((()=>{t()}),e),h=t=>t*t,a=(e=null)=>{let s,i;return e?t(e)?i=document.querySelector(e):n(e)&&(i=e):(s=document.querySelectorAll("html,body"),i=s[0].scrollTop-s[1].scrollTop>=0?s[0]:s[1]),i},c=(t,e,s)=>{const r=a(t);let l=r.scrollTop,n=0;const o=e-l,c=r.scrollHeight,d=e-c<=0?e:c,u=t=>(i(s)&&s(t),!1),p=()=>{if(n+=1,o<0){if(l-=h(n),r.scrollTop=l,l<=e)return r.scrollTop=e,u(e)}else if(l+=h(n),r.scrollTop=l,l>=d)return r.scrollTop=d,u(d);requestAnimationFrame(p)};requestAnimationFrame(p)},d=t=>{let e=t.offsetTop;return null!==t.offsetParent&&(e+=d(t.offsetParent)),e},u=(t,e="")=>{const s=e.replace(/^>/i,"");return!!(e&&s&&t)&&(t.matches?t.matches(s):!!t.msMatchesSelector&&t.msMatchesSelector(s))},p=t=>t.host&&t!==document&&t.host.nodeType?t.host:t.parentNode,m=["focusout","blur","focusin","focus","load","unload","mouseenter","mouseleave"],f=(t,e,s)=>{const i=m.indexOf(e)>-1;s._delegateListener&&delete(s=s._delegateListener)._delegateListener,function(t,e,s){const i=t._listeners;let r=-1;if(i.length<1)return!1;i.forEach(((t,i)=>{const l=t.fn;e===t.type&&(r=i,l===s&&(r=i))})),r>-1&&i.splice(r,1)}(t,e,s),t.removeEventListener(e,s,i)},g=function(e,s,i=!1){const r=t(e)?document.querySelector(e):e,l=r.childNodes,o=((e,s)=>{let i=e._listeners||[];return t(s)&&s&&(i=i.filter((t=>t.type===s))),i})(r,s);o.forEach((t=>{f(r,t.type,t.fn)})),(i||!0===s||1===arguments.length)&&r&&l&&l.forEach((t=>{n(t)&&g(t,s,i)}))},y=(t,e,s)=>{if(!i(s))return g(t,e);f(t,e,s)},b=(t,e,s,i,r,l,n=!1)=>{const o=m.indexOf(s)>-1,h=function(o){const a=function(t){const e=t.target;return(s=e)&&3===s.nodeType?s.parentNode:s;var s}(o),c=((t,e,s,i)=>{const r=s||document;if(!t)return null;do{if(null!=e&&(">"===e[0]?t.parentNode===r&&u(t,e):u(t,e))||i&&t===r)return t;if(t===r)break}while(t=p(t))})(a,e,t);let d=l||t;o.delegateTarget=c,!0===l&&(d=r),c&&(!0===n&&y(t,s,h),i.call(d,o,r))};t._listeners||(t._listeners=[]),t._listeners.push({el:t,selector:e,type:s,fn:h,data:r,context:l,capture:o}),i._delegateListener=h,t.addEventListener(s,h,o)},$=function(t){t.stopPropagation(),t.preventDefault()},v={},E=t=>e(v,t)&&v[t].length>0,_=(t,e=!0)=>e?E(t):(t=>{let e=E(t),s=t.lastIndexOf(".");for(;!e&&-1!==s;)s=(t=t.substring(0,s)).lastIndexOf("."),e=E(t);return e})(t),T=(t,e,i=!0)=>{const r=t=>{if(!E(t))return!1;v[t].forEach((t=>{const i=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]","[object BigInt64Array]","[object BigUint64Array]"].indexOf(s(e))>-1?e.toString():e;t.callback.call(t.context||t,i)}))},l=()=>{let e=t,s=t.lastIndexOf(".");for(;-1!==s;)e=e.substring(0,s),s=e.lastIndexOf("."),r(e);r(t),r("*")};if(!_(t))return!1;i?setTimeout(l,10):l()},w=t=>Array.isArray?Array.isArray(t):"[object Array]"===s(t),L=(t=[])=>{const e=['','','','','','','',''],s=w(t)&&t.length>0?e.concat(t):e,i=document.body;let r=document.querySelector("#svg-sprites");r?r.innerHTML=s.join(""):(r=document.createElement("div"),r.innerHTML=``,i.insertBefore(r.firstChild,i.firstChild))},S=(t,e=0,s="",i="outline")=>{const r=i?`xlink:href="#${i}-icon-${t}"`:`xlink:href="#icon-${t}"`,l=w(e)?e[0]:e,n=w(e)?e[1]:e,o=e?`width:${l}px;height:${n}px;`:"",h=``,a=document.createElement("i");return a.className="outline-icon",a.innerHTML=h,a},C=e=>!!t(e)&&e.replace(/^\s+|\s+$/g,""),x=t=>{return!(!r(t)||!(n(t)||(t=>!(!r(t)||"[object NodeList]"!==s(t)))(t)||(e=t,r(e)&&"[object DocumentFragment]"===s(e))||(t=>!(!r(t)||!("[object Text]"===s(t)||t.tagName&&3===t.nodeType)))(t)));var e},z=(t,e,s)=>{let i=t.tagName.toLowerCase();switch(e){case"style":t.style.cssText=s;break;case"value":"input"===i||"textarea"===i?t.value=s:t.setAttribute(e,s);break;case"className":t.className=s;break;default:t.setAttribute(e,s)}},k=(s,i,l)=>{const n=document.createDocumentFragment(),o=document.createElement(s),h=e=>x(e)||t(e),a=e=>{let s;if(!h(e))return!1;x(e)?s=e:t(e)&&(s=document.createTextNode(e)),n.appendChild(s)};return r(i)?Object.keys(i).forEach((t=>{e(i,t)&&z(o,t,i[t])})):w(i)&&i.every((t=>h(t)))&&i.forEach((t=>{a(t)})),w(l)?l.forEach((t=>{a(t)})):a(l),o.appendChild(n),o},A=(t,e)=>{const s=new RegExp("(\\s|^)"+e+"(\\s|$)");let i,r;return!!n(t)&&(i=t.className,!!i&&(r=t.classList,r?.contains?t.classList.contains(e):!!i.match(s)))},N=(t,e)=>{let s,i=t.className;if(!i||!A(t,e))return!1;s=t.classList,s?.remove?s.remove(e):(i=C(i.replace(e,"")),t.className=i)},M=(e,s=!0,i=!0)=>{const r="outline-heading",l=e.innerHTML;let n;if(e.innerHTML=l.replace(/^\d+(?:(\.?\d*)*\s?)?/gi,""),e.removeAttribute("id"),e.removeAttribute("data-id"),N(e,r),!s)return!1;var o;n=e.querySelector(`.${r}__anchor`),i&&N(e,`${r}_start`),o=C(e.className),t(o)&&""===o&&e.removeAttribute("class"),e.removeChild(n)},D=(e,s=!0)=>{const i=[];let r=1,l=0;return e.forEach(((e,s)=>{const n=e.tagName.replace(/h/i,"");let o=parseInt(n,10),h=-1;var a;o>r?(l+=1,h=1===l?-1:s-1):o===r||ol?1===o?(l=1,h=-1):h=i[s-1].pid:o<=l&&(1===o?l=1:(l-=r-o,l<=1&&(l=1)),h=1===l?-1:((t,e,s)=>{let i,r,l=t[s-1];for(r=0;r]+(>|$)/g,""):"")})})),s?(t=>{const e={};return t.forEach((t=>{const s=JSON.stringify((t=>[t.pid])(t));e[s]=e[s]||[],e[s].push(t),t.index=e[s].length,-1===t.pid&&(t.code=String(t.index))})),Object.keys(e).forEach((s=>{e[s].forEach(((e,s)=>{e.index=s+1,t.forEach((t=>{t.pid===e.id&&(t.code=e.code+"."+t.index)}))}))})),t})(i):i};class H extends l{constructor(t){super(),this.attrs=H.DEFAULTS,this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],t&&this.initialize(t)}initialize(e){let s,r,l,o,h;return this.attr(e),h=this.attr("articleElement"),r=this.attr("scrollElement"),l=this.attr("selector"),s=this.attr("created"),t(h)?o=document.querySelector(h):n(h)&&(o=h),o?(this.$articleElement=o,this.$scrollElement=a(r),this.$headings=[...o.querySelectorAll(l)],this.$headings.length<1||(this.chapters=D(this.$headings),i(s)&&s.call(this),this.render().addListeners()),this):this}getChapters(t=!1){const e=this.chapters;return t?((t,e,s)=>{const i={},r=[];return t.forEach(((t,s)=>{i[t[e]]=s,t.children=[]})),t.forEach((e=>{const l=t[i[e[s]]];-1!==e[s]?l.children.push(e):r.push(e)})),r})(e,"id","pid"):e}count(){return this.chapters.length}render(){const t=this.attr("mounted"),e=this.attr("hasAnchor"),s=this.attr("isAtStart"),r=this.attr("showCode"),l=this.attr("anchorURL"),n=this.$headings,o=this.getChapters();return L(),n.forEach(((t,i)=>{const n=o[i].code;((t,e,s)=>{const i="outline-heading",r=s.hasAnchor||!0,l=s.isAtStart||!0,n=s.showCode||!1,o=s.chapterCode||"",h=s.anchorURL||"",a=`heading-${e}`,c={id:a,className:l?`${i} ${i}_start`:i,"data-id":e},d=Object.keys(c),u=C(t.innerHTML);let p,m;if(d.forEach((e=>{z(t,e,c[e])})),n&&(t.innerHTML=o+" "+u),!r)return!1;m=S("hash"),p=k("a",{id:`anchor-${e}`,className:`${i}__anchor anchor-${e}`,href:h||`#${a}`,target:h?"_blank":"self","data-id":e},[m]),t.appendChild(p)})(t,i,{hasAnchor:e,isAtStart:s,showCode:r,chapterCode:n,anchorURL:l})})),i(t)&&t.call(this),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}destroy(){const t=this.attr("hasAnchor"),e=this.attr("isAtStart"),s=this.attr("beforeDestroy"),r=this.attr("afterDestroy"),l=this.$headings;return i(s)&&s.call(this),this.removeListeners(),l.forEach((s=>{M(s,t,e)})),this.attr(H.DEFAULTS),this.$articleElement=null,this.$scrollElement=null,this.$headings=[],this.chapters=[],i(r)&&r.call(this),this}onAnchorTrigger(t){const e=this.attr("anchorURL"),s=this.attr("afterScroll"),r=this.attr("stickyHeight"),l=t.delegateTarget.parentNode,n=d(l)-(r+10),h=this.$scrollElement,a=h.scrollHeight-h.clientHeight;return this.scrollTo(n,(()=>{i(s)&&s.call(this,"anchor"),o((()=>{T("toolbar:update",{top:n,min:0,max:a})}))})),e||$(t),this}addListeners(){const t=this.$articleElement;return b(t,".outline-heading__anchor","click",this.onAnchorTrigger,this,!0),this}removeListeners(){const t=this.$articleElement;return y(t,"click",this.onAnchorTrigger),this}}H.DEFAULTS={scrollElement:"html,body",articleElement:"#article",selector:"h1,h2,h3,h4,h5,h6",stickyHeight:0,anchorURL:"",hasAnchor:!0,isAtStart:!0,showCode:!1,created:null,mounted:null,afterScroll:null,beforeDestroy:null,afterDestroy:null};const j=(t,e)=>{let s,i;if(A(t,e))return!1;s=t.classList,s?.add?s.add(e):(i=t.className,i+=i.length>0?" "+e:e,t.className=i)},O=(t,e)=>{document.documentElement.style.setProperty(t,e)};let F=2e3;const U=t=>(t?F=t:F+=1,O("--outline-zIndex",`${F}`),F);class I extends l{constructor(t){super(),this.attrs=I.DEFAULTS,this.title="",this.closed=!0,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,this.zIndex=0,t&&this.initialize(t)}initialize(t){let e;return this.attr(t),this.title=this.attr("title"),e=this.attr("created"),i(e)&&e.call(this),this.render().addListeners(),this}setTitle(t){return this.attr("title",t),this.title=t,this.$title.innerHTML=t,this}isClosed(){return this.closed}render(){const t=this.attr("mounted"),e=this.attr("size"),s=this.attr("placement"),r=this.attr("hasClose"),l=this.attr("hasOverlay"),n=this.attr("hasOffset"),o=this.attr("hasPadding"),h=this.attr("autoHeight"),a=this.attr("customClass"),c=document.createDocumentFragment();let d,u,p,m,f,g,y,b;return L(),this.zIndex=U(),m=k("h2",{className:"outline-drawer__title"},[this.title]),this.$title=m,r&&(f=k("div",{className:"outline-drawer__close"},[S("close",20)]),this.$close=f),p=k("header",{className:"outline-drawer__header"},[m,f]),this.$header=p,g=k("div",{className:"outline-drawer__main"},[""]),this.$main=g,o||j(g,"outline-drawer_full"),y=k("footer",{className:"outline-drawer__footer"},[""]),this.$footer=y,u=k("div",{className:`outline-drawer__modal outline-drawer_${s} outline-drawer_${e} outline-drawer_closed`},[p,g,y]),this.$modal=u,n&&j(u,"outline-drawer_offset"),h&&j(u,"outline-drawer_auto"),a&&j(u,a),l&&(b=k("div",{className:"outline-drawer__overlay"},[""]),this.$overlay=b),d=k("div",{className:"outline-drawer"},[u,b]),this.$el=d,c.appendChild(d),document.body.appendChild(c),i(t)&&t.call(this),this}open(){const t=this.attr("afterOpened"),e=this.$modal;return j(this.$el,"outline-drawer_opened"),N(e,"outline-drawer_closed"),j(e,"outline-drawer_opened"),o((()=>{this.closed=!1,i(t)&&t.call(this)})),this}close(){const t=this.attr("afterClosed"),e=this.$modal;return N(e,"outline-drawer_opened"),j(e,"outline-drawer_closed"),o((()=>{N(this.$el,"outline-drawer_opened"),this.closed=!0,i(t)&&t.call(this)})),this}toggle(){const t=this.attr("afterToggle"),e=this.isClosed();return e?this.open():this.close(),i(t)&&o((()=>{t.call(this,e)})),this}destroy(){const t=this.attr("afterDestroy"),e=this.attr("beforeDestroy");let s=this.zIndex;return i(e)&&e.call(this),this.removeListeners(),this.attrs=I.DEFAULTS,this.title="",this.closed=!1,this.$el=null,this.$modal=null,this.$header=null,this.$title=null,this.$close=null,this.$main=null,this.$footer=null,this.$overlay=null,s-=1,U(s),this.zIndex=0,i(t)&&t.call(this),this}addListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t&&b(s,".outline-drawer__close","click",this.onClose,this,!0),e&&b(s,".outline-drawer__overlay","click",this.onClose,this,!0),this}removeListeners(){const t=this.attr("hasClose"),e=this.attr("hasOverlay"),s=this.$el;return t||e?(y(s,"click",this.onClose),this):this}onClose(){return this.close(),this}}I.DEFAULTS={placement:"rtl",title:"标题",size:"regular",hasClose:!0,hasOverlay:!0,hasOffset:!1,hasPadding:!0,autoHeight:!0,created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterToggle:null};const q=(t,e,s,r,l,n=!1)=>{const o=m.indexOf(e)>-1,h=function(i){let o=l||t;!0===l&&(o=r),!0===n&&y(t,e,h),s.call(o,i,r)};if(!i(s))return!1;t._listeners||(t._listeners=[]),t._listeners.push({el:t,type:e,fn:h,data:r,context:l,capture:o}),s._delegateListener=h,t.addEventListener(e,h,o)};class B extends l{constructor(t){super(),this.attrs=B.DEFAULTS,this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.closed=!1,this.active=0,this.offsetTop=0,this.offsetWidth=0,this.$active=null,this.scrollTimer=null,this.resizeTimer=null,this.playing=!1,t&&this.initialize(t)}initialize(e){let s,r,l,o;return this.attr(e),s=this.attr("created"),r=this.attr("parentElement"),l=this.attr("scrollElement"),t(r)?o=document.querySelector(r):n(r)&&(o=r),this.$parentElement=o,this.$scrollElement=a(l),this.chapters=this.attr("chapters"),this.closed=this.attr("closed"),this.active=this.attr("active"),i(s)&&s.call(this),this.chapters.length<1||(this.render().addListeners(),this.$active=document.querySelector(`#chapter-${this.active}`)),this}isClosed(){return this.closed}isSticky(){return"sticky"===this.attr("position")}isFixed(){return"fixed"===this.attr("position")}isInside(){return this.isFixed()||this.isSticky()}isOutside(){return!this.isInside()}_paintEdge(){const t=this.attr("title"),e=this.attr("customClass"),s=this.$parentElement,i=[];let r,l,n,o,h=null;return s?(this.isInside()&&(h=k("h2",{className:"outline-chapters__title"},[t]),this.$title=h,i.push(h)),n=k("ul",{className:"outline-chapters__list outline-chapters_fixed outline-chapters_hidden"},[""]),this.$list=n,o=k("div",{className:"outline-chapters__placeholder"},[""]),this.$placeholder=o,l=k("div",{className:"outline-chapters__main"},[n,o]),this.$main=l,i.push(l),r=k("nav",{id:"outline-chapters",className:"outline-chapters"},i),this.$el=r,this.isSticky()&&(this.calculateStickyHeight(),j(r,"outline-chapters_sticky")),e&&j(r,e),s.appendChild(r),this):this}render(){const t=this.attr("showCode"),e=this.attr("mounted");let s,r;return this.$parentElement?(this._paintEdge(),r=this.$list,((t,e,s=!1)=>{const i=t=>document.getElementById(t);e.forEach((e=>{const r=e.pid,l=e.id,n=e.rel,o=k("span",{className:"outline-chapters__text"},[e.text]),h=k("a",{id:`chapter__anchor-${l}`,className:"outline-chapters__anchor",href:"#"+n,rel:n,"data-id":l},[o]);let a,c,d,u;s&&(a=k("span",{className:"outline-chapters__code","data-id":l},[e.code]),h.insertBefore(a,h.firstChild)),c=k("li",{id:`chapter-${l}`,className:"outline-chapters__item","data-id":l},[h]),-1===r?t.appendChild(c):(u=i(`chapter-${r}`),d=i(`subject-${r}`),d?d.appendChild(c):(d=k("ul",{id:"subject-"+r,className:"outline-chapters__subject"},[c]),u.appendChild(d)))}))})(r,this.chapters,t),N(r,"outline-chapters_fixed"),N(r,"outline-chapters_hidden"),s=this.$el,this.offsetTop=d(s),this.offsetWidth=s.offsetWidth,this.isFixed()&&(this.sticky(),O("--outline-chapters-width",`${this.offsetWidth}px`)),i(e)&&e.call(this),this.onObserver(),this):this}highlight(t){const e=this.$el.querySelector(`#chapter__anchor-${t}`),s="outline-chapters_active",i=this.$placeholder;let r;return this.$active&&N(this.$active,s),this.active=parseInt(e.getAttribute("data-id"),10),this.$active=e,j(this.$active,s),r=30*this.active,i.style.top=`calc(0.5em + ${r}px)`,this}sticky(){const t=this.attr("afterSticky"),e="outline-chapters_fixed",s=this.$el,r=this.offsetTop,l=this.$scrollElement.scrollTop;let n;return this.isFixed()?(n=!!(l>=r),n?j(s,e):N(s,e),i(t)&&t.call(this,this.isClosed(),n),this):this}calculateStickyHeight(){const t=document.documentElement,e=Math.max(t.clientHeight||0,window.innerHeight||0);return O("--outline-sticky-height",`${e}px`),this}scrollTo(t,e){const s=this.$scrollElement;return c(s,t,e),this}show(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterOpened"),r=this.$el,l=this.$parentElement;return this.isInside()?(N(l,e),N(r,e),o((()=>{N(l,t),N(r,t)}),30)):N(r,e),this.closed=!1,i(s)&&s.call(this),this}hide(){const t="outline-chapters_folded",e="outline-chapters_hidden",s=this.attr("afterClosed"),r=this.$el,l=this.$parentElement;return this.isInside()?(j(l,t),j(r,t),o((()=>{j(l,e),j(r,e)}))):j(r,e),this.closed=!0,i(s)&&s.call(this),this}toggle(){const t=this.attr("afterToggle"),e=this.offsetTop,s=this.$scrollElement.scrollTop;let r;return this.isClosed()?this.show():this.hide(),i(t)&&o((()=>{r=!!(s>=e),t.call(this,this.isClosed(),r)})),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");return i(t)&&t.call(this),this.removeListeners(),this.$parentElement.removeChild(this.$el),this.attr(B.DEFAULTS),this.$el=null,this.$title=null,this.$main=null,this.$list=null,this.$placeholder=null,this.$parentElement=null,this.$scrollElement=null,this.chapters=[],this.active=0,this.offsetTop=0,this.$active=null,this.closed=!1,this.scrollTimer&&(clearTimeout(this.scrollTimer),this.scrollTimer=null),this.resizeTimer&&(clearTimeout(this.resizeTimer),this.resizeTimer=null),i(e)&&e.call(this),this}onObserver(){let t=null;return((t,e={})=>{const s=e.root||null,r=e.selector||".outline-heading",l=e.context||null,o={rootMargin:e.rootMargin||"0px 0px -90% 0px"},h=new IntersectionObserver((e=>{e.forEach((e=>{e.intersectionRatio>0&&i(t)&&t.call(l||e.target,e.target)}))}),o),a=n(s)?s:document;s&&(o.root=s),a.querySelectorAll(r).forEach((t=>{h.observe(t)}))})((e=>{const s=e.getAttribute("data-id");if(this.playing)return!1;t&&clearTimeout(t),t=o((()=>{this.highlight(s)}),100)}),{context:this}),this}onSelect(t){const e=this.attr("stickyHeight"),s=t.delegateTarget,r=s.getAttribute("data-id"),l=s.href.split("#")[1],n=document.querySelector(`#${l}`),h=d(n)-(e+10),a=this.$scrollElement.scrollHeight,c=this.attr("afterScroll"),u=()=>{i(c)&&c.call(this,"chapter"),o((()=>{this.playing=!1,T("toolbar:update",{top:h,min:0,max:a})}))};return this.playing=!0,this.isFixed()?(this.sticky(),o((()=>{this.scrollTo(h,u),this.highlight(r)}),10)):(this.scrollTo(h,u),this.highlight(r)),$(t),this}onScroll(){const t=this.$scrollElement;return this.scrollTimer&&clearTimeout(this.scrollTimer),this.scrollTimer=o((()=>{const e=t.scrollTop,s=t.scrollHeight-t.clientHeight;this.isFixed()&&this.sticky(),T("toolbar:update",{top:e,min:0,max:s})}),50),this}onResize(){return this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=o((()=>{this.calculateStickyHeight()})),this}addListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),b(t,".outline-chapters__anchor","click",this.onSelect,this,!0),q(i,"scroll",this.onScroll,this,!0),this.isSticky()&&q(i,"resize",this.onResize,this,!0),this}removeListeners(){const t=this.$el,e=this.$scrollElement,s=e.tagName.toLowerCase();let i=e;return"html"!==s&&"body"!==s||(i=window),y(t,"click",this.onSelect),y(i,"scroll",this.onScroll),this.isSticky()&&q(i,"resize",this.onResize),this}}B.DEFAULTS={parentElement:"",scrollElement:"",selector:"",active:0,closed:!1,showCode:!0,position:"relative",stickyHeight:0,chapters:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterScroll:null,beforeDestroy:null,afterDestroy:null,afterSticky:null};const R=(t,e=!0)=>{const s=S(t.icon,t.size),i=k("a",{className:"outline-toolbar__anchor",href:t.link},[s]),r=k("div",{className:`outline-toolbar__button ${t.name}`},[t.link?i:s]);return j(s,"outline-toolbar__icon"),e&&j(r,"outline-toolbar_rounded"),t.disabled&&j(r,"outline-toolbar_disabled"),r},P="outline-toolbar_disabled",Q="outline-toolbar_hidden";class V extends l{constructor(t){super(),this.attrs=V.DEFAULTS,this.$el=null,this.disabled=!1,this.closed=!1,this.buttons=[],t&&this.initialize(t)}initialize(t){let e;return this.attr(t),e=this.attr("created"),this.disabled=this.attr("disabled"),this.closed=this.attr("closed"),i(e)&&e.call(this),this.render().addListeners(),this}isDisabled(t){const e=this.attr("buttons");let s;return t?(s=e.find((e=>e.name===t)),!(!s||!s.disabled)):this.disabled}isClosed(){return this.closed}highlight(t){const e=this.buttons.find((e=>e.name===t)),s="outline-toolbar_active";let i;return i||(i=e.$el,A(i,s)?N(i,s):j(i,s)),this}render(){const t=this.attr("mounted"),e=this.attr("buttons")||[],s=this.attr("rounded"),r=this.attr("placement"),l=document.createDocumentFragment(),n=document.createDocumentFragment();return L(),e.forEach((t=>{const e=R(t,s);l.appendChild(e),this.buttons.push({name:t.name,$el:e})})),this.$el=k("div",{id:"outline-toolbar",className:`outline-toolbar outline-toolbar_${r}`},[l]),n.appendChild(this.$el),document.body.appendChild(n),this.closed&&this.hide(),this.disabled&&this.disable(),i(t)&&t.call(this),this}add(t){const e=this.$el,s=this.attr("buttons"),l=t.action,n=document.createDocumentFragment();let o;return r(t)?(s.push(t),n.appendChild(R(t))):w(t)&&t.forEach((t=>{n.appendChild(R(t))})),e.appendChild(n),l&&i(l.handler)&&(o=l.type||"click",b(e,`.${t.name}`,o,l.handler)),this}remove(t){const e=this.$el,s=this.attr("buttons"),i=s.find((e=>e.name===t));let r,l=-1;return i?(s.forEach(((e,s)=>{e.name===t&&(l=s)})),l>-1&&this.attr().buttons.splice(l,1),r=e.querySelector(`.${t}`),this.switch(t,!1),e.removeChild(r),this):this}switch(t,e){const s=this.$el,i=this.attr("buttons"),r=i.find((e=>e.name===t));let l,n,o,h;return r?(i.forEach((s=>{s.name===t&&(r.disabled=!e)})),l=r.action,h=s.querySelector(`.${t}`),l&&(n=l.type||"click",o=l.handler),e?(N(h,P),n&&o&&b(s,`.${t}`,n,o)):(j(h,P),n&&o&&y(s,n,o)),this):this}disable(t){const e=this.attr("afterDisabled");return t?this.switch(t,!1):(j(this.$el,P),this.removeListeners(),this.disabled=!0,i(e)&&e.call(this)),this}enable(t){const e=this.attr("afterEnabled");return t?this.switch(t,!0):(this.disabled=!1,N(this.$el,P),this.addListeners(),i(e)&&e.call(this)),this}show(t){const e=this.attr("afterOpened"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),N(l,Q)}else N(r,Q),this.closed=!1,i(e)&&o((()=>{e.call(this)}),310);return this}hide(t){const e=this.attr("afterClosed"),s=this.attr("buttons").find((e=>e.name===t)),r=this.$el;let l;if(t){if(!s)return this;l=r.querySelector(`.${t}`),j(l,Q)}else j(r,Q),this.closed=!0,i(e)&&o((()=>{e.call(this)}),310);return this}toggle(){return this.isClosed()?this.show():this.hide(),this}destroy(){const t=this.attr("beforeDestroy"),e=this.attr("afterDestroy");let s=this.$el;return i(t)&&t.call(this),this.removeListeners(),document.body.removeChild(s),s=null,this.attr(V.DEFAULTS),this.disabled=!1,this.closed=!1,this.buttons=[],i(e)&&e.call(this),this}refresh(){const t=this.$el,e=this.attr("buttons")||[];return this.removeListeners(),t.innerHTML="",e.forEach((t=>{this.$el.appendChild(R(t))})),this.addListeners(),this}addListeners(){const e=this.attr("buttons"),s=this.$el;return!e||e.length<1||e.forEach((e=>{const r=e.action;let l,n,o,h;if(this.disabled)return!1;r&&(n=r.handler,t(n)&&(h=n,r.handler=function(){T(h,e.name)},n=r.handler),l=r.type||"click",o=r.context),i(n)&&b(s,`.${e.name}`,l,n,o||this,!0)})),this}removeListeners(){const t=this.attr("buttons"),e=this.$el;return!t||t.length<1||t.forEach((t=>{const s=t.action;let r,l;if(this.disabled)return!1;s&&(l=s.handler,r=s.type||"click"),i(l)&&y(e,r,l)})),this}}V.DEFAULTS={placement:"ltr",closed:!1,disabled:!1,rounded:!0,buttons:[],created:null,mounted:null,afterClosed:null,afterOpened:null,afterDisabled:null,afterEnabled:null,beforeDestroy:null,afterDestroy:null};const W=(()=>{let t=0;return e=>(t+=1,e?e+"-"+t:"guid-"+t)})(),J=(t,e,s=null)=>{const r=W();let l="symbol"==typeof t?t.toString():t;return!!i(e)&&(v[l]||(v[l]=[]),v[l].push({topic:l,callback:e,context:s,token:r}),r)},G=t=>{if(!e(v,t))return!1;delete v[t]},K=(t,e)=>{if(!_(t))return!1;e?(t=>{const e=Object.keys(v);if(!t||e.length<1)return!1;e.forEach((e=>{const s=v[e];let i;s.forEach(((e,r)=>{e.callback!==t&&e.token!==t||(i=e.topic,s.splice(-1,r))})),s.length<1&&G(i)}))})(e):G(t)};class X extends l{constructor(t){super(),this.attrs=X.DEFAULTS,this.anchors=null,this.drawer=null,this.chapters=null,this.toolbar=null,t&&this.initialize(t)}initialize(t){return this.attr(t).render().addListeners(),this}getChapters(t=!1){return this.anchors.getChapters(t)}count(){return this.anchors.count()}render(){return this._renderAnchors()._renderChapters()._renderToolbar(),this}_renderAnchors(){const t=this.attr("articleElement"),e=this.attr("selector"),s=this.attr("stickyHeight"),i=this.attr("scrollElement"),r=this.attr("showCode"),l=this.attr("anchorURL"),n=this.attr("afterScroll");return this.anchors=new H({articleElement:t,stickyHeight:s,scrollElement:i,selector:e,showCode:r,anchorURL:l,afterScroll:n}),this}_renderChapters(){const t=this.attr("title"),e=this.attr("stickyHeight"),s=this.attr("scrollElement"),i=this.attr("customClass"),r=this.attr("showCode"),l=this.attr("position"),n=this.attr("placement"),o=this.attr("afterSticky"),h=this.attr("afterToggle"),a=this.attr("afterScroll"),c=this.count();let d,u=this.attr("parentElement");return c<1||(d={scrollElement:s,showCode:r,position:l,title:t,stickyHeight:e,chapters:this.anchors.getChapters(),afterSticky:o,afterToggle:h,afterScroll:a},"relative"===l?(this.drawer=new I({placement:n,title:t,size:"tiny",hasOffset:!0,hasPadding:!1,customClass:i,afterClosed:()=>{this.toolbar.toggle()}}),u=this.drawer.$main):d.customClass=i,d.parentElement=u,this.chapters=new B(d)),this}_renderToolbar(){const t=this.attr("placement"),e=this.attr("homepage"),s=this.count(),i={name:"homepage",icon:"homepage",size:20,link:e},r={name:"menu",icon:"menu",size:18,action:{type:"click",handler:"toolbar:action:toggle"}},l=[];return l.push({name:"up",icon:"up",size:20,action:{type:"click",handler:"toolbar:action:up"}}),e&&l.push(i),s>0&&l.push(r),l.push({name:"down",icon:"down",size:20,action:{type:"click",handler:"toolbar:action:down"}}),this.toolbar=new V({placement:t,buttons:l}),this}toTop(){const t=this.attr("afterScroll"),e=this.toolbar,s=this.chapters,r=this.count();return s.playing=!0,this.scrollTo(0,(()=>{e.hide("up"),e.show("down"),r>0&&s.highlight(0),s.playing=!1,i(t)&&t.call(e,"up")})),this}toBottom(){const t=this.attr("afterScroll"),e=a(this.attr("scrollElement")),s=this.toolbar,r=this.chapters,l=this.count(),n=Math.floor(e.scrollHeight-e.clientHeight);return r.playing=!0,this.scrollTo(n,(()=>{s.hide("down"),s.show("up"),l>1&&r.highlight(l-1),r.playing=!1,i(t)&&t.call(s,"bottom")})),this}scrollTo(t,e){const s=this.attr("scrollElement");return c(s,t,e),this}toggle(){const t=this.attr("position"),e=this.toolbar,s=this.drawer,i=this.chapters,r=this.count();if("relative"!==t)i.toggle(),e.highlight("menu");else{if(e.toggle(),r<1)return this;o((()=>{i.isInside()?i.toggle():s.toggle()}))}return this}destroy(){const t=this.chapters,e=this.count();return this.removeListeners(),this.attr(X.DEFAULTS),this.anchors.destroy(),e<1&&(t.destroy(),t.isOutside()&&this.drawer.destroy()),this.toolbar.destroy(),this}onToggle(){return this.toggle(),this}onScrollTop(){return this.toTop(),this}onScrollBottom(){return this.toBottom(),this}onToolbarUpdate({top:t,min:e,max:s}){const i=this.toolbar,r=Math.ceil(t);return r<=e?(i.hide("up"),i.show("down")):r>=s?(i.hide("down"),i.show("up")):r>e&&r {\r\n  return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n  const hasOwnProperty = Object.prototype.hasOwnProperty\r\n  return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n  return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n  return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n  return (\r\n    (toString(o) === '[object Object]' ||\r\n      typeof o === 'object' ||\r\n      isFunction(o)) &&\r\n    o !== null\r\n  )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n  constructor(options) {\r\n    this.attrs = {}\r\n\r\n    if (options) {\r\n      this.initialize(options)\r\n    }\r\n  }\r\n\r\n  initialize(options) {\r\n    this.attr(options).render().addListeners()\r\n    return this\r\n  }\r\n\r\n  attr(prop, value) {\r\n    const attrs = this.attrs\r\n\r\n    if (isString(prop)) {\r\n      // 只能扩展 attrs 中已有的属性\r\n      if (value && hasOwn(attrs, prop)) {\r\n        // 更新单个配置信息\r\n        attrs[prop] = value\r\n        return this\r\n      }\r\n\r\n      // 只传递 prop 参数,则返回对应的属性值\r\n      return attrs[prop]\r\n    } else if (isObject(prop)) {\r\n      // 批量更新配置信息\r\n      extend(attrs, prop)\r\n\r\n      return this\r\n    } else if (arguments.length === 0) {\r\n      // 不传递参数,直接返回整个\r\n      return attrs\r\n    }\r\n\r\n    return this\r\n  }\r\n\r\n  render() {\r\n    return this\r\n  }\r\n\r\n  destroy() {\r\n    this.removeListeners()\r\n    return this\r\n  }\r\n\r\n  reload(options) {\r\n    this.destroy().initialize(this.attr(options))\r\n    return this\r\n  }\r\n\r\n  addListeners() {\r\n    return this\r\n  }\r\n\r\n  removeListeners() {\r\n    return this\r\n  }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n  const keys = Object.keys(source)\r\n\r\n  keys.forEach((prop) => {\r\n    if (hasOwn(source, prop)) {\r\n      origin[prop] = source[prop]\r\n    }\r\n  })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n  return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n  if (!isFunction(fn)) {\r\n    return false\r\n  }\r\n\r\n  return setTimeout(() => {\r\n    fn()\r\n  }, delay)\r\n}\r\n\r\nexport default later\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n  return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n  let $rootElements\r\n  let $scrollElement\r\n\r\n  if (!scrollElement) {\r\n    $rootElements = document.querySelectorAll('html,body')\r\n    $scrollElement =\r\n      $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n        ? $rootElements[0]\r\n        : $rootElements[1]\r\n  } else {\r\n    if (isString(scrollElement)) {\r\n      $scrollElement = document.querySelector(scrollElement)\r\n    } else if (isElement(scrollElement)) {\r\n      $scrollElement = scrollElement\r\n    }\r\n  }\r\n\r\n  return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n  const $scrollElement = _getScrollElement(scrollElement)\r\n  let scrollTop = $scrollElement.scrollTop\r\n  let step = 0\r\n  const distance = top - scrollTop\r\n  const MAX_HEIGHT = $scrollElement.scrollHeight\r\n  const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n  const stop = (top) => {\r\n    if (isFunction(afterStop)) {\r\n      afterStop(top)\r\n    }\r\n\r\n    return false\r\n  }\r\n  const play = () => {\r\n    step += 1\r\n\r\n    // 向上滚动\r\n    if (distance < 0) {\r\n      scrollTop -= easeInQuad(step)\r\n      $scrollElement.scrollTop = scrollTop\r\n\r\n      if (scrollTop <= top) {\r\n        $scrollElement.scrollTop = top\r\n        return stop(top)\r\n      }\r\n    } else {\r\n      scrollTop += easeInQuad(step)\r\n      $scrollElement.scrollTop = scrollTop\r\n\r\n      if (scrollTop >= MAX_TOP) {\r\n        $scrollElement.scrollTop = MAX_TOP\r\n        return stop(MAX_TOP)\r\n      }\r\n    }\r\n\r\n    requestAnimationFrame(play)\r\n  }\r\n\r\n  requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n  let top = el.offsetTop\r\n\r\n  if (el.offsetParent !== null) {\r\n    top += offsetTop(el.offsetParent)\r\n  }\r\n\r\n  return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n  const sel = selector.replace(/^>/i, '')\r\n\r\n  if (!selector || !sel || !el) {\r\n    return false\r\n  }\r\n\r\n  /* istanbul ignore else */\r\n  if (el.matches) {\r\n    return el.matches(sel)\r\n  } else if (el.msMatchesSelector) {\r\n    return el.msMatchesSelector(sel)\r\n  } else {\r\n    return false\r\n  }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n  return el.host && el !== document && el.host.nodeType\r\n    ? el.host\r\n    : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","export const CAPTURE_EVENTS = [\r\n  'focusout',\r\n  'blur',\r\n  'focusin',\r\n  'focus',\r\n  'load',\r\n  'unload',\r\n  'mouseenter',\r\n  'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n  const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n  /* istanbul ignore else */\r\n  if (fn._delegateListener) {\r\n    fn = fn._delegateListener\r\n    delete fn._delegateListener\r\n  }\r\n\r\n  // 移除缓存的 _listeners 数据\r\n  _delete(el, type, fn)\r\n\r\n  el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n  const listeners = el._listeners\r\n  let index = -1\r\n\r\n  if (listeners.length < 1) {\r\n    return false\r\n  }\r\n\r\n  // 移除缓存的 _listeners 数据\r\n  listeners.forEach((listener, i) => {\r\n    const handler = listener.fn\r\n\r\n    if (type === listener.type) {\r\n      index = i\r\n\r\n      if (handler === fn) {\r\n        index = i\r\n      }\r\n    }\r\n  })\r\n\r\n  /* istanbul ignore else */\r\n  if (index > -1) {\r\n    listeners.splice(index, 1)\r\n  }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n  const $element = isString(el) ? document.querySelector(el) : el\r\n  const $children = $element.childNodes\r\n  const listeners = getListeners($element, type)\r\n\r\n  listeners.forEach((listener) => {\r\n    _off($element, listener.type, listener.fn)\r\n  })\r\n\r\n  if (\r\n    (recurse || type === true || arguments.length === 1) &&\r\n    $element &&\r\n    $children\r\n  ) {\r\n    $children.forEach(($child) => {\r\n      if (isElement($child)) {\r\n        purgeElement($child, type, recurse)\r\n      }\r\n    })\r\n  }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n  let listeners = el._listeners || []\r\n\r\n  if (isString(type) && type) {\r\n    listeners = listeners.filter((listener) => {\r\n      return listener.type === type\r\n    })\r\n  }\r\n\r\n  return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n  // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n  if (!isFunction(fn)) {\r\n    return purgeElement(el, type)\r\n  }\r\n\r\n  _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n  // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n  const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n  const listener = function (evt) {\r\n    const target = getTarget(evt)\r\n    // 通过 Element.matches 方法获得点击的目标元素\r\n    const delegateTarget = closest(target, selector, el)\r\n    let overrideContext = context || el\r\n\r\n    evt.delegateTarget = delegateTarget\r\n\r\n    // 当设置为 true 时,则事件处理器回调函数的\r\n    // this 上下文指向为 data 对象\r\n    if (context === true) {\r\n      overrideContext = data\r\n    }\r\n\r\n    /* istanbul ignore else */\r\n    if (delegateTarget) {\r\n      // 仅触发一次\r\n      /* istanbul ignore else */\r\n      if (once === true) {\r\n        off(el, type, listener)\r\n      }\r\n\r\n      fn.call(overrideContext, evt, data)\r\n    }\r\n  }\r\n\r\n  if (!el._listeners) {\r\n    el._listeners = []\r\n  }\r\n\r\n  // 缓存 options 元素绑定的事件处理器\r\n  el._listeners.push({\r\n    el,\r\n    selector,\r\n    type,\r\n    fn: listener,\r\n    data,\r\n    context,\r\n    capture\r\n  })\r\n\r\n  // 缓存包装后的事件处理器\r\n  fn._delegateListener = listener\r\n\r\n  el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n  const target = evt.target\r\n\r\n  return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n  if (el && el.nodeType === 3) {\r\n    return el.parentNode\r\n  }\r\n\r\n  return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n  const context = ctx || document\r\n\r\n  if (!el) {\r\n    return null\r\n  }\r\n\r\n  do {\r\n    /* istanbul ignore else */\r\n    if (\r\n      (selector != null &&\r\n        (selector[0] === '>'\r\n          ? el.parentNode === context && matches(el, selector)\r\n          : matches(el, selector))) ||\r\n      (includeCTX && el === context)\r\n    ) {\r\n      return el\r\n    }\r\n\r\n    /* istanbul ignore else */\r\n    if (el === context) {\r\n      break\r\n    }\r\n\r\n    /* jshint boss:true */\r\n  } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n * 
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isArray from './types/isArray'\r\n\r\n/**\r\n * 绘制 SVG Sprites 图标集\r\n * ========================================================================\r\n * @method paintSvgSprites\r\n * @param {Array} [symbols] - (可选)symbols 图标数组\r\n * 传递 symbols - 绘制 symbols + SYMBOLS 的图标集\r\n * 不传递 symbols - 仅绘制默认 SYMBOLS 图标集\r\n */\r\nexport const paintSvgSprites = (symbols = []) => {\r\n const SYMBOLS = [\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n ''\r\n ]\r\n const sprites =\r\n isArray(symbols) && symbols.length > 0 ? SYMBOLS.concat(symbols) : SYMBOLS\r\n const $body = document.body\r\n let $icons = document.querySelector('#svg-sprites')\r\n\r\n if ($icons) {\r\n $icons.innerHTML = sprites.join('')\r\n } else {\r\n $icons = document.createElement('div')\r\n $icons.innerHTML =\r\n ``\r\n $body.insertBefore($icons.firstChild, $body.firstChild)\r\n }\r\n}\r\n\r\n/**\r\n * 创建 SVG 图标 DOM 元素\r\n * ========================================================================\r\n * @method createSvgIcon\r\n * @param {String} name\r\n * @param {Number|String|Array} [size]\r\n * @param {String} [color]\r\n * @param {String} [iconSet]\r\n * @returns {HTMLElement}\r\n */\r\nexport const createSvgIcon = (\r\n name,\r\n size = 0,\r\n color = '',\r\n iconSet = 'outline'\r\n) => {\r\n const binds = iconSet\r\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\r\n : `xlink:href=\"#icon-${name}\"`\r\n const width = isArray(size) ? size[0] : size\r\n const height = isArray(size) ? size[1] : size\r\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\r\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\r\n const svg =\r\n `` +\r\n `` +\r\n ``\r\n const $icon = document.createElement('i')\r\n\r\n $icon.className = 'outline-icon'\r\n $icon.innerHTML = svg\r\n\r\n return $icon\r\n}\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import removeClass from './utils/dom/removeClass'\r\nimport isEmpty from './utils/types/isEmpty'\r\nimport trim from './utils/lang/trim'\r\n\r\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const text = $heading.innerHTML\r\n let $anchor\r\n\r\n $heading.innerHTML = text.replace(/^\\d+(?:(\\.?\\d*)*\\s?)?/gi, '')\r\n $heading.removeAttribute('id')\r\n $heading.removeAttribute('data-id')\r\n\r\n removeClass($heading, CLS_HEADING)\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\r\n\r\n if (isAtStart) {\r\n removeClass($heading, `${CLS_HEADING}_start`)\r\n }\r\n\r\n if (isEmpty(trim($heading.className))) {\r\n $heading.removeAttribute('class')\r\n }\r\n\r\n $heading.removeChild($anchor)\r\n}\r\n\r\nexport default _resetHeading\r\n","import isString from './isString'\r\n/**\r\n * 检测数据是否为空字符串\r\n * ========================================================================\r\n * @method isEmpty\r\n * @param {String} str\r\n * @returns {boolean}\r\n */\r\nconst isEmpty = (str) => {\r\n return isString(str) && str === ''\r\n}\r\n\r\nexport default isEmpty\r\n","import trim from './utils/lang/trim'\r\nimport stripTags from './utils/lang/stripTags'\r\n\r\nimport _getChaptersWithCode from './_getChaptersWithCode'\r\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\r\n\r\nconst getChapters = (headings, showCode = true) => {\r\n const chapters = []\r\n let previous = 1\r\n let level = 0\r\n\r\n headings.forEach((heading, i) => {\r\n const headingLevel = heading.tagName.replace(/h/i, '')\r\n let current = parseInt(headingLevel, 10)\r\n let pid = -1\r\n\r\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\r\n // h2 (前一个标题)\r\n // h3 (当前标题)\r\n if (current > previous) {\r\n level += 1\r\n\r\n // 第一层级的 pid 是 -1\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n pid = i - 1\r\n }\r\n }\r\n // 当前标题的(标题标签)序号 = 前一个标题的序号\r\n // h2 (前一个标题)\r\n // h2 (当前标题)\r\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\r\n // h2\r\n // h4 (前一个标题)\r\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\r\n else if (current === previous || (current < previous && current > level)) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n pid = -1\r\n } else {\r\n pid = chapters[i - 1].pid\r\n }\r\n } else if (current <= level) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n } else {\r\n level = level - (previous - current)\r\n\r\n if (level <= 1) {\r\n level = 1\r\n }\r\n }\r\n\r\n // 第一级的标题\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\r\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\r\n }\r\n }\r\n\r\n previous = current\r\n\r\n chapters.push({\r\n id: i,\r\n pid: pid,\r\n level: level,\r\n rel: `heading-${i}`,\r\n text: stripTags(trim(heading.innerHTML))\r\n })\r\n })\r\n\r\n return showCode ? _getChaptersWithCode(chapters) : chapters\r\n}\r\n\r\nexport default getChapters\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 过滤所有 HTML 标签\r\n * ========================================================================\r\n * @method stripTags\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nconst stripTags = (str) => {\r\n if (!isString(str)) {\r\n return ''\r\n }\r\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\r\n}\r\n\r\nexport default stripTags\r\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\r\n let previous = chapters[index - 1]\r\n let pid\r\n let i\r\n\r\n for (i = 0; i < differ; i += 1) {\r\n pid = previous.pid\r\n previous = chapters[pid]\r\n }\r\n\r\n pid = previous.pid\r\n\r\n return pid\r\n}\r\n\r\nexport default _getChapterParentIdByDiffer\r\n","const _getChaptersWithCode = (chapters) => {\r\n const groups = {}\r\n const cb = (o) => {\r\n return [o.pid]\r\n }\r\n\r\n chapters.forEach((o) => {\r\n const group = JSON.stringify(cb(o))\r\n\r\n groups[group] = groups[group] || []\r\n groups[group].push(o)\r\n\r\n o.index = groups[group].length\r\n if (o.pid === -1) {\r\n o.code = String(o.index)\r\n }\r\n })\r\n\r\n Object.keys(groups).forEach((group) => {\r\n groups[group].forEach((c, i) => {\r\n c.index = i + 1\r\n chapters.forEach((o) => {\r\n if (o.pid === c.id) {\r\n o.code = c.code + '.' + o.index\r\n }\r\n })\r\n })\r\n })\r\n\r\n return chapters\r\n}\r\n\r\nexport default _getChaptersWithCode\r\n","import Base from './base'\r\n\r\n// 在文章的标题生成 anchor 链接\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport toTree from './utils/lang/toTree'\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _updateHeading from './_updateHeading'\r\nimport _resetHeading from './_resetHeading'\r\nimport getChapters from './getChapters'\r\n\r\nclass Anchors extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Anchors.DEFAULTS\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n\r\n this.chapters = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let scrollElement\r\n let selector\r\n let $articleElement\r\n let articleElement\r\n\r\n this.attr(options)\r\n articleElement = this.attr('articleElement')\r\n scrollElement = this.attr('scrollElement')\r\n selector = this.attr('selector')\r\n created = this.attr('created')\r\n\r\n if (isString(articleElement)) {\r\n $articleElement = document.querySelector(articleElement)\r\n } else if (isElement(articleElement)) {\r\n $articleElement = articleElement\r\n }\r\n\r\n if (!$articleElement) {\r\n return this\r\n }\r\n\r\n this.$articleElement = $articleElement\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n this.$headings = [...$articleElement.querySelectorAll(selector)]\r\n\r\n if (this.$headings.length < 1) {\r\n return this\r\n }\r\n\r\n this.chapters = getChapters(this.$headings)\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n const chapters = this.chapters\r\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const $headings = this.$headings\r\n const chapters = this.getChapters()\r\n\r\n paintSvgSprites()\r\n\r\n $headings.forEach(($heading, i) => {\r\n const chapterCode = chapters[i].code\r\n _updateHeading($heading, i, {\r\n hasAnchor,\r\n isAtStart,\r\n showCode,\r\n chapterCode,\r\n anchorURL\r\n })\r\n })\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n const $headings = this.$headings\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n $headings.forEach(($heading) => {\r\n _resetHeading($heading, hasAnchor, isAtStart)\r\n })\r\n\r\n this.attr(Anchors.DEFAULTS)\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n this.chapters = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onAnchorTrigger(evt) {\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const $heading = $anchor.parentNode\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const $scrollElement = this.$scrollElement\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this)\r\n }\r\n\r\n later(() => {\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.scrollTo(top, after)\r\n\r\n if (!anchorURL) {\r\n stop(evt)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n on(\r\n $articleElement,\r\n '.outline-heading__anchor',\r\n 'click',\r\n this.onAnchorTrigger,\r\n this,\r\n true\r\n )\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n off($articleElement, 'click', this.onAnchorTrigger)\r\n\r\n return this\r\n }\r\n}\r\n\r\nAnchors.DEFAULTS = {\r\n scrollElement: 'html,body',\r\n articleElement: '#article',\r\n selector: 'h1,h2,h3,h4,h5,h6',\r\n stickyHeight: 0,\r\n anchorURL: '',\r\n hasAnchor: true,\r\n isAtStart: true,\r\n showCode: false,\r\n created: null,\r\n mounted: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Anchors\r\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import trim from './utils/lang/trim'\r\nimport createElement from './utils/dom/createElement'\r\nimport setAttribute from './utils/dom/setAttribute'\r\n\r\nimport { createSvgIcon } from './utils/icons'\r\n\r\nconst _updateHeading = ($heading, i, options) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const hasAnchor = options.hasAnchor || true\r\n const isAtStart = options.isAtStart || true\r\n const showCode = options.showCode || false\r\n const chapterCode = options.chapterCode || ''\r\n const anchorURL = options.anchorURL || ''\r\n const headingId = `heading-${i}`\r\n const attrs = {\r\n id: headingId,\r\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\r\n 'data-id': i\r\n }\r\n const keys = Object.keys(attrs)\r\n const text = trim($heading.innerHTML)\r\n let $anchor\r\n let $icon\r\n\r\n keys.forEach((prop) => {\r\n setAttribute($heading, prop, attrs[prop])\r\n })\r\n\r\n if (showCode) {\r\n $heading.innerHTML = chapterCode + ' ' + text\r\n }\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $icon = createSvgIcon('hash')\r\n $anchor = createElement(\r\n 'a',\r\n {\r\n id: `anchor-${i}`,\r\n className: `${CLS_HEADING}__anchor anchor-${i}`,\r\n href: anchorURL ? anchorURL : `#${headingId}`,\r\n target: anchorURL ? '_blank' : 'self',\r\n 'data-id': i\r\n },\r\n [$icon]\r\n )\r\n $heading.appendChild($anchor)\r\n}\r\n\r\nexport default _updateHeading\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","import setProperty from './utils/dom/setProperty'\r\n\r\nlet index = 2000\r\n\r\nconst zIndex = (idx) => {\r\n if (idx) {\r\n index = idx\r\n } else {\r\n index += 1\r\n }\r\n\r\n setProperty('--outline-zIndex', `${index}`)\r\n\r\n return index\r\n}\r\n\r\nexport default zIndex\r\n","import Base from './base'\r\n\r\nimport later from './utils/lang/later'\r\nimport isFunction from './utils/types/isFunction'\r\nimport addClass from './utils/dom/addClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport createElement from './utils/dom/createElement'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\n\r\nimport { paintSvgSprites, createSvgIcon } from './utils/icons'\r\nimport zIndex from './zIndex'\r\n\r\nclass Drawer extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = true\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n this.zIndex = 0\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n\r\n this.title = this.attr('title')\r\n created = this.attr('created')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n return this\r\n }\r\n\r\n setTitle(title) {\r\n this.attr('title', title)\r\n this.title = title\r\n this.$title.innerHTML = title\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const size = this.attr('size')\r\n const placement = this.attr('placement')\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const hasOffset = this.attr('hasOffset')\r\n const hasPadding = this.attr('hasPadding')\r\n const autoHeight = this.attr('autoHeight')\r\n const customClass = this.attr('customClass')\r\n const $fragment = document.createDocumentFragment()\r\n let $el\r\n let $modal\r\n let $header\r\n let $title\r\n let $close\r\n let $main\r\n let $footer\r\n let $overlay\r\n\r\n paintSvgSprites()\r\n this.zIndex = zIndex()\r\n\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-drawer__title'\r\n },\r\n [this.title]\r\n )\r\n this.$title = $title\r\n\r\n if (hasClose) {\r\n $close = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__close'\r\n },\r\n [createSvgIcon('close', 20)]\r\n )\r\n this.$close = $close\r\n }\r\n\r\n $header = createElement(\r\n 'header',\r\n {\r\n className: 'outline-drawer__header'\r\n },\r\n [$title, $close]\r\n )\r\n this.$header = $header\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__main'\r\n },\r\n ['']\r\n )\r\n this.$main = $main\r\n\r\n if (!hasPadding) {\r\n addClass($main, 'outline-drawer_full')\r\n }\r\n\r\n $footer = createElement(\r\n 'footer',\r\n {\r\n className: 'outline-drawer__footer'\r\n },\r\n ['']\r\n )\r\n this.$footer = $footer\r\n\r\n $modal = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer__modal outline-drawer_${placement} outline-drawer_${size} outline-drawer_closed`\r\n },\r\n [$header, $main, $footer]\r\n )\r\n this.$modal = $modal\r\n\r\n if (hasOffset) {\r\n addClass($modal, 'outline-drawer_offset')\r\n }\r\n\r\n if (autoHeight) {\r\n addClass($modal, 'outline-drawer_auto')\r\n }\r\n\r\n if (customClass) {\r\n addClass($modal, customClass)\r\n }\r\n\r\n if (hasOverlay) {\r\n $overlay = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__overlay'\r\n },\r\n ['']\r\n )\r\n this.$overlay = $overlay\r\n }\r\n\r\n $el = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer`\r\n },\r\n [$modal, $overlay]\r\n )\r\n this.$el = $el\r\n $fragment.appendChild($el)\r\n document.body.appendChild($fragment)\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n open() {\r\n const opened = this.attr('afterOpened')\r\n const $modal = this.$modal\r\n\r\n addClass(this.$el, 'outline-drawer_opened')\r\n removeClass($modal, 'outline-drawer_closed')\r\n addClass($modal, 'outline-drawer_opened')\r\n\r\n later(() => {\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n close() {\r\n const closed = this.attr('afterClosed')\r\n const $modal = this.$modal\r\n\r\n removeClass($modal, 'outline-drawer_opened')\r\n addClass($modal, 'outline-drawer_closed')\r\n\r\n later(() => {\r\n removeClass(this.$el, 'outline-drawer_opened')\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const closed = this.isClosed()\r\n\r\n if (closed) {\r\n this.open()\r\n } else {\r\n this.close()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n afterToggle.call(this, closed)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const afterDestroy = this.attr('afterDestroy')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n let index = this.zIndex\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = false\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n\r\n index -= 1\r\n zIndex(index)\r\n this.zIndex = 0\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (hasClose) {\r\n on($el, '.outline-drawer__close', 'click', this.onClose, this, true)\r\n }\r\n\r\n if (hasOverlay) {\r\n on($el, '.outline-drawer__overlay', 'click', this.onClose, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (!hasClose && !hasOverlay) {\r\n return this\r\n }\r\n\r\n off($el, 'click', this.onClose)\r\n\r\n return this\r\n }\r\n\r\n onClose() {\r\n this.close()\r\n return this\r\n }\r\n}\r\n\r\nDrawer.DEFAULTS = {\r\n placement: 'rtl',\r\n title: '标题',\r\n size: 'regular',\r\n hasClose: true,\r\n hasOverlay: true,\r\n hasOffset: false,\r\n hasPadding: true,\r\n autoHeight: true,\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterToggle: null\r\n}\r\n\r\nexport default Drawer\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport publish from './utils/observer/emit'\r\n\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport _paintChapters from './_paintChapters'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Chapters.DEFAULTS\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.closed = false\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.offsetWidth = 0\r\n this.$active = null\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.playing = false\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n _paintEdge() {\r\n const STICKY = 'outline-chapters_sticky'\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n [title]\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement(\r\n 'ul',\r\n {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list ${FIXED} ${HIDDEN}`\r\n },\r\n ['']\r\n )\r\n this.$list = $list\r\n\r\n $placeholder = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__placeholder'\r\n },\r\n ['']\r\n )\r\n this.$placeholder = $placeholder\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n [$list, $placeholder]\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: 'outline-chapters'\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n\r\n $parentElement.appendChild($el)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n let $el\r\n let $list\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n this._paintEdge()\r\n\r\n $list = this.$list\r\n _paintChapters($list, this.chapters, showCode)\r\n removeClass($list, FIXED)\r\n removeClass($list, HIDDEN)\r\n\r\n $el = this.$el\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n this.onObserver()\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $anchor = this.$el.querySelector(`#chapter__anchor-${id}`)\r\n const HIGHLIGHT = 'outline-chapters_active'\r\n const $placeholder = this.$placeholder\r\n let top\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n this.$active = $anchor\r\n addClass(this.$active, HIGHLIGHT)\r\n\r\n top = 30 * this.active\r\n $placeholder.style.top = `calc(0.5em + ${top}px)`\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = !!(scrollTop >= top)\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n removeClass($parent, HIDDEN)\r\n removeClass($el, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n removeClass($el, FOLDED)\r\n }, 30)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n addClass($parent, FOLDED)\r\n addClass($el, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n addClass($el, HIDDEN)\r\n })\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = !!(scrollTop >= top)\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n this.$parentElement.removeChild(this.$el)\r\n\r\n this.attr(Chapters.DEFAULTS)\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.$active = null\r\n this.closed = false\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n let timer = null\r\n\r\n intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n timer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n { context: this }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this)\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 50)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize)\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const byId = (id) => document.getElementById(id)\r\n\r\n chapters.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n [chapter.text]\r\n )\r\n const $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n [$text]\r\n )\r\n let $code\r\n let $li\r\n let $ul\r\n let $parent\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n [chapter.code]\r\n )\r\n\r\n $link.insertBefore($code, $link.firstChild)\r\n }\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n [$link]\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $parent = byId(`chapter-${pid}`)\r\n $ul = byId(`subject-${pid}`)\r\n\r\n if (!$ul) {\r\n $ul = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n [$li]\r\n )\r\n\r\n $parent.appendChild($ul)\r\n } else {\r\n $ul.appendChild($li)\r\n }\r\n }\r\n })\r\n}\r\n\r\nexport default _paintChapters\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n}\r\n\r\nexport default intersection\r\n","import { createSvgIcon } from './utils/icons'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\n\r\nconst _createButton = (button, rounded = true) => {\r\n const $icon = createSvgIcon(button.icon, button.size)\r\n const $anchor = createElement(\r\n 'a',\r\n {\r\n className: `outline-toolbar__anchor`,\r\n href: button.link\r\n },\r\n [$icon]\r\n )\r\n const $button = createElement(\r\n 'div',\r\n {\r\n className: `outline-toolbar__button ${button.name}`\r\n },\r\n [button.link ? $anchor : $icon]\r\n )\r\n\r\n addClass($icon, 'outline-toolbar__icon')\r\n\r\n if (rounded) {\r\n addClass($button, 'outline-toolbar_rounded')\r\n }\r\n\r\n if (button.disabled) {\r\n addClass($button, 'outline-toolbar_disabled')\r\n }\r\n\r\n return $button\r\n}\r\n\r\nexport default _createButton\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isObject from './utils/types/isObject'\r\nimport isArray from './utils/types/isArray'\r\nimport later from './utils/lang/later'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\nimport hasClass from './utils/dom/hasClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _createButton from './_createButton'\r\n\r\nconst DISABLED = 'outline-toolbar_disabled'\r\nconst HIDDEN = 'outline-toolbar_hidden'\r\n\r\nclass Toolbar extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Toolbar.DEFAULTS\r\n this.$el = null\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n this.disabled = this.attr('disabled')\r\n this.closed = this.attr('closed')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n isDisabled(name) {\r\n const buttons = this.attr('buttons')\r\n let button\r\n\r\n if (name) {\r\n button = buttons.find((option) => option.name === name)\r\n\r\n return !!(button && button.disabled)\r\n }\r\n\r\n return this.disabled\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n highlight(name) {\r\n const button = this.buttons.find((item) => item.name === name)\r\n const ACTIVE = 'outline-toolbar_active'\r\n let $button\r\n\r\n if ($button) {\r\n return this\r\n }\r\n\r\n $button = button.$el\r\n\r\n if (hasClass($button, ACTIVE)) {\r\n removeClass($button, ACTIVE)\r\n } else {\r\n addClass($button, ACTIVE)\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const buttons = this.attr('buttons') || []\r\n const rounded = this.attr('rounded')\r\n const placement = this.attr('placement')\r\n const $buttons = document.createDocumentFragment()\r\n const $fragment = document.createDocumentFragment()\r\n\r\n paintSvgSprites()\r\n\r\n buttons.forEach((button) => {\r\n const $button = _createButton(button, rounded)\r\n\r\n $buttons.appendChild($button)\r\n this.buttons.push({\r\n name: button.name,\r\n $el: $button\r\n })\r\n })\r\n\r\n this.$el = createElement(\r\n 'div',\r\n {\r\n id: 'outline-toolbar',\r\n className: `outline-toolbar outline-toolbar_${placement}`\r\n },\r\n [$buttons]\r\n )\r\n $fragment.appendChild(this.$el)\r\n document.body.appendChild($fragment)\r\n\r\n if (this.closed) {\r\n this.hide()\r\n }\r\n\r\n if (this.disabled) {\r\n this.disable()\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n add(button) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const action = button.action\r\n const $fragment = document.createDocumentFragment()\r\n let type\r\n\r\n if (isObject(button)) {\r\n buttons.push(button)\r\n $fragment.appendChild(_createButton(button))\r\n } else if (isArray(button)) {\r\n button.forEach((item) => {\r\n $fragment.appendChild(_createButton(item))\r\n })\r\n }\r\n $el.appendChild($fragment)\r\n\r\n if (action && isFunction(action.handler)) {\r\n type = action.type || 'click'\r\n on($el, `.${button.name}`, type, action.handler)\r\n }\r\n\r\n return this\r\n }\r\n\r\n remove(name) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let index = -1\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button, i) => {\r\n if (button.name === name) {\r\n index = i\r\n }\r\n })\r\n\r\n if (index > -1) {\r\n this.attr().buttons.splice(index, 1)\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n this.switch(name, false)\r\n $el.removeChild($button)\r\n\r\n return this\r\n }\r\n\r\n switch(name, enabled) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let action\r\n let type\r\n let listener\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((option) => {\r\n if (option.name === name) {\r\n button.disabled = !enabled\r\n }\r\n })\r\n\r\n action = button.action\r\n $button = $el.querySelector(`.${name}`)\r\n\r\n if (action) {\r\n type = action.type || 'click'\r\n listener = action.handler\r\n }\r\n\r\n if (enabled) {\r\n removeClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n on($el, `.${name}`, type, listener)\r\n }\r\n } else {\r\n addClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n off($el, type, listener)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n disable(name) {\r\n const disabled = this.attr('afterDisabled')\r\n\r\n if (name) {\r\n this.switch(name, false)\r\n } else {\r\n addClass(this.$el, DISABLED)\r\n this.removeListeners()\r\n this.disabled = true\r\n\r\n if (isFunction(disabled)) {\r\n disabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n enable(name) {\r\n const enabled = this.attr('afterEnabled')\r\n\r\n if (name) {\r\n this.switch(name, true)\r\n } else {\r\n this.disabled = false\r\n removeClass(this.$el, DISABLED)\r\n this.addListeners()\r\n\r\n if (isFunction(enabled)) {\r\n enabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n show(name) {\r\n const opened = this.attr('afterOpened')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n removeClass($button, HIDDEN)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n later(() => {\r\n opened.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide(name) {\r\n const closed = this.attr('afterClosed')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n $button = $el.querySelector(`.${name}`)\r\n addClass($button, HIDDEN)\r\n } else {\r\n addClass($el, HIDDEN)\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n later(() => {\r\n closed.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n let $el = this.$el\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n document.body.removeChild($el)\r\n $el = null\r\n\r\n this.attr(Toolbar.DEFAULTS)\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n refresh() {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons') || []\r\n\r\n this.removeListeners()\r\n $el.innerHTML = ''\r\n\r\n buttons.forEach((button) => {\r\n this.$el.appendChild(_createButton(button))\r\n })\r\n\r\n this.addListeners()\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n let context\r\n let command\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n if (isString(listener)) {\r\n command = listener\r\n action.handler = function () {\r\n publish(command, button.name)\r\n }\r\n listener = action.handler\r\n }\r\n\r\n type = action.type || 'click'\r\n context = action.context\r\n }\r\n\r\n if (isFunction(listener)) {\r\n on($el, `.${button.name}`, type, listener, context || this, true)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n type = action.type || 'click'\r\n }\r\n\r\n if (isFunction(listener)) {\r\n off($el, type, listener)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n}\r\n\r\nToolbar.DEFAULTS = {\r\n placement: 'ltr',\r\n closed: false,\r\n disabled: false,\r\n rounded: true,\r\n buttons: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterDisabled: null,\r\n afterEnabled: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Toolbar\r\n","/**\r\n * 生成唯一 id 字符串的函数\r\n * ========================================================================\r\n * @method guid\r\n * @param {String} [prefix] - 生成 id 的前缀字符串\r\n * @return {String} 返回一个表示唯一 id 的字符串\r\n */\r\nconst guid = (() => {\r\n let uuid = 0\r\n\r\n return (prefix) => {\r\n uuid += 1\r\n\r\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\r\n }\r\n})()\r\n\r\nexport default guid\r\n","import _subscribers from './_subscribers'\r\nimport isFunction from '../types/isFunction'\r\nimport guid from '../lang/guid'\r\n\r\n/**\r\n * 订阅主题,并给出处理器函数\r\n * ========================================================================\r\n * @method on\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Function} handler - (必须)主题的处理器函数\r\n * @param {Object} [context] - (可选)指定 this 执行上下文\r\n * @return {String|Boolean} - 唯一的 token 字符串,例如:'guid-1'。\r\n */\r\nconst on = (topic, handler, context = null) => {\r\n const token = guid()\r\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\r\n\r\n if (!isFunction(handler)) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (!_subscribers[subject]) {\r\n _subscribers[subject] = []\r\n }\r\n\r\n _subscribers[subject].push({\r\n topic: subject,\r\n callback: handler,\r\n context,\r\n token\r\n })\r\n\r\n return token\r\n}\r\n\r\nexport default on\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 删除与给定 topic 相同的订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriber\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _removeSubscriber = (topic) => {\r\n if (!hasOwn(_subscribers, topic)) {\r\n return false\r\n }\r\n\r\n delete _subscribers[topic]\r\n}\r\n\r\nexport default _removeSubscriber\r\n","import has from './has'\r\nimport _removeSubscriber from './_removeSubscriber'\r\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\r\n\r\n/**\r\n * 取消订阅主题\r\n * ========================================================================\r\n * @method off\r\n * @param {String} topic - (必须)订阅的主题\r\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\r\n */\r\nconst off = (topic, token) => {\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (token) {\r\n _removeSubscriberByToken(token)\r\n } else {\r\n _removeSubscriber(topic)\r\n }\r\n}\r\n\r\nexport default off\r\n","import _subscribers from './_subscribers'\r\nimport _removeSubscriber from './_removeSubscriber'\r\n\r\n/**\r\n * 通过订阅者 token 值删除订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriberByToken\r\n * @param {String} token - 订阅者 token 字符串\r\n * @returns {boolean}\r\n * @private\r\n */\r\nconst _removeSubscriberByToken = (token) => {\r\n const keys = Object.keys(_subscribers)\r\n let index = -1\r\n\r\n if (!token || keys.length < 1) {\r\n return false\r\n }\r\n\r\n keys.forEach((subject) => {\r\n const subscriber = _subscribers[subject]\r\n let topic\r\n\r\n subscriber.forEach((execution, j) => {\r\n if (execution.callback === token || execution.token === token) {\r\n topic = execution.topic\r\n subscriber.splice(index, j)\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (subscriber.length < 1) {\r\n _removeSubscriber(topic)\r\n }\r\n })\r\n}\r\n\r\nexport default _removeSubscriberByToken\r\n","import Base from './base'\r\nimport Anchors from './anchors'\r\nimport Drawer from './drawer'\r\nimport Chapters from './chapters'\r\nimport Toolbar from './toolbar'\r\n\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Outline extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Outline.DEFAULTS\r\n this.anchors = null\r\n this.drawer = null\r\n this.chapters = null\r\n this.toolbar = null\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n return this.anchors.getChapters(isTreeStructured)\r\n }\r\n\r\n count() {\r\n return this.anchors.count()\r\n }\r\n\r\n render() {\r\n this._renderAnchors()._renderChapters()._renderToolbar()\r\n\r\n return this\r\n }\r\n\r\n _renderAnchors() {\r\n const articleElement = this.attr('articleElement')\r\n const selector = this.attr('selector')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n\r\n this.anchors = new Anchors({\r\n articleElement,\r\n stickyHeight,\r\n scrollElement,\r\n selector,\r\n showCode,\r\n anchorURL\r\n })\r\n\r\n return this\r\n }\r\n\r\n _renderChapters() {\r\n const title = this.attr('title')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const customClass = this.attr('customClass')\r\n const showCode = this.attr('showCode')\r\n const position = this.attr('position')\r\n const placement = this.attr('placement')\r\n const afterSticky = this.attr('afterSticky')\r\n const afterToggle = this.attr('afterToggle')\r\n const count = this.count()\r\n let parentElement = this.attr('parentElement')\r\n let CHAPTERS_OPTIONS\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n CHAPTERS_OPTIONS = {\r\n scrollElement,\r\n showCode,\r\n position,\r\n title,\r\n stickyHeight,\r\n chapters: this.anchors.getChapters(),\r\n afterSticky,\r\n afterToggle\r\n }\r\n\r\n if (position === 'relative') {\r\n this.drawer = new Drawer({\r\n placement,\r\n title,\r\n size: 'tiny',\r\n hasOffset: true,\r\n hasPadding: false,\r\n customClass,\r\n afterClosed: () => {\r\n const toolbar = this.toolbar\r\n toolbar.toggle()\r\n }\r\n })\r\n parentElement = this.drawer.$main\r\n } else {\r\n CHAPTERS_OPTIONS.customClass = customClass\r\n }\r\n\r\n CHAPTERS_OPTIONS.parentElement = parentElement\r\n this.chapters = new Chapters(CHAPTERS_OPTIONS)\r\n\r\n return this\r\n }\r\n\r\n _renderToolbar() {\r\n const placement = this.attr('placement')\r\n const homepage = this.attr('homepage')\r\n const count = this.count()\r\n const UP = {\r\n name: 'up',\r\n icon: 'up',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:up'\r\n }\r\n }\r\n const HOME = {\r\n name: 'homepage',\r\n icon: 'homepage',\r\n size: 20,\r\n link: homepage\r\n }\r\n const MENU = {\r\n name: 'menu',\r\n icon: 'menu',\r\n size: 18,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:toggle'\r\n }\r\n }\r\n const DOWN = {\r\n name: 'down',\r\n icon: 'down',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:down'\r\n }\r\n }\r\n const buttons = []\r\n\r\n buttons.push(UP)\r\n if (homepage) {\r\n buttons.push(HOME)\r\n }\r\n if (count > 0) {\r\n buttons.push(MENU)\r\n }\r\n buttons.push(DOWN)\r\n\r\n this.toolbar = new Toolbar({\r\n placement,\r\n buttons: buttons\r\n })\r\n\r\n return this\r\n }\r\n\r\n toTop() {\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const afterTop = () => {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n\r\n if (count > 0) {\r\n chapters.highlight(0)\r\n }\r\n chapters.playing = false\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(0, afterTop)\r\n\r\n return this\r\n }\r\n\r\n toBottom() {\r\n const $scrollElement = _getScrollElement(this.attr('scrollElement'))\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const top = Math.floor(\r\n $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n )\r\n const afterDown = () => {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n\r\n if (count > 1) {\r\n chapters.highlight(count - 1)\r\n }\r\n chapters.playing = false\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(top, afterDown)\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, afterScroll) {\r\n const scrollElement = this.attr('scrollElement')\r\n scrollTo(scrollElement, top, afterScroll)\r\n return this\r\n }\r\n\r\n toggle() {\r\n const position = this.attr('position')\r\n const toolbar = this.toolbar\r\n const drawer = this.drawer\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n if (position !== 'relative') {\r\n chapters.toggle()\r\n toolbar.highlight('menu')\r\n } else {\r\n toolbar.toggle()\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n later(() => {\r\n if (chapters.isInside()) {\r\n chapters.toggle()\r\n } else {\r\n drawer.toggle()\r\n }\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n this.removeListeners()\r\n\r\n this.attr(Outline.DEFAULTS)\r\n this.anchors.destroy()\r\n if (count < 1) {\r\n chapters.destroy()\r\n if (chapters.isOutside()) {\r\n this.drawer.destroy()\r\n }\r\n }\r\n this.toolbar.destroy()\r\n\r\n return this\r\n }\r\n\r\n onToggle() {\r\n this.toggle()\r\n return this\r\n }\r\n\r\n onScrollTop() {\r\n this.toTop()\r\n return this\r\n }\r\n\r\n onScrollBottom() {\r\n this.toBottom()\r\n return this\r\n }\r\n\r\n onToolbarUpdate({ top, min, max }) {\r\n const toolbar = this.toolbar\r\n const current = Math.ceil(top)\r\n\r\n if (current <= min) {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n } else if (current >= max) {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n } else if (current > min && current < max) {\r\n toolbar.show('up')\r\n toolbar.show('down')\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n subscribe('toolbar:update', this.onToolbarUpdate, this)\r\n subscribe('toolbar:action:up', this.onScrollTop, this)\r\n subscribe('toolbar:action:toggle', this.onToggle, this)\r\n subscribe('toolbar:action:down', this.onScrollBottom, this)\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n unsubscribe('toolbar:update')\r\n unsubscribe('toolbar:action:up')\r\n unsubscribe('toolbar:action:toggle')\r\n unsubscribe('toolbar:action:down')\r\n return this\r\n }\r\n}\r\n\r\nOutline.DEFAULTS = {\r\n articleElement: '#article',\r\n selector: 'h2,h3,h4,h5,h6',\r\n title: '目录',\r\n scrollElement: 'html,body',\r\n position: 'relative',\r\n parentElement: '#aside',\r\n placement: 'rtl',\r\n showCode: true,\r\n anchorURL: '',\r\n stickyHeight: 0,\r\n customClass: '',\r\n afterSticky: null,\r\n afterToggle: null\r\n}\r\n\r\nif (window.jQuery) {\r\n // 将 Outline 扩展为一个 jquery 插件\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend(jQuery.fn, {\r\n outline: function (options) {\r\n // eslint-disable-next-line no-undef\r\n let $article = jQuery(this)\r\n\r\n return new Outline(\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend({}, options, {\r\n articleElement: $article\r\n })\r\n )\r\n }\r\n })\r\n}\r\n\r\nexport default Outline\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","later","fn","delay","setTimeout","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","scrollTo","top","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","offsetTop","el","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","off","on","data","context","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","closest","overrideContext","push","addEventListener","stopPropagation","preventDefault","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","isArray","Array","paintSvgSprites","symbols","SYMBOLS","sprites","concat","$body","body","$icons","innerHTML","join","createElement","insertBefore","firstChild","createSvgIcon","name","size","color","iconSet","binds","width","height","defaultRules","svg","$icon","className","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","hasClass","pattern","RegExp","allClass","classList","contains","match","removeClass","remove","_resetHeading","$heading","hasAnchor","isAtStart","CLS_HEADING","text","$anchor","removeAttribute","removeChild","getChapters","headings","showCode","chapters","previous","level","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","id","rel","groups","group","JSON","stringify","cb","code","String","c","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","anchorURL","chapterCode","headingId","href","_updateHeading","after","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","publish","min","addClass","add","setProperty","documentElement","zIndex","idx","Drawer","title","closed","$modal","$header","$title","$close","$main","$footer","$overlay","setTitle","isClosed","placement","hasClose","hasOverlay","hasOffset","hasPadding","autoHeight","customClass","open","opened","close","toggle","afterToggle","onClose","afterClosed","afterOpened","at","Chapters","$list","$placeholder","$parentElement","active","offsetWidth","$active","scrollTimer","resizeTimer","playing","parentElement","$parent","isSticky","isFixed","isInside","isOutside","_paintEdge","contents","calculateStickyHeight","byId","getElementById","chapter","$text","$link","$code","$li","$ul","_paintChapters","sticky","onObserver","highlight","HIGHLIGHT","getAttribute","afterSticky","FIXED","isStickying","Math","window","innerHeight","show","FOLDED","HIDDEN","hide","clearTimeout","timer","props","root","rootMargin","Observer","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","onSelect","split","onScroll","onResize","_createButton","button","rounded","icon","link","$button","disabled","DISABLED","Toolbar","buttons","isDisabled","find","option","ACTIVE","$buttons","disable","action","switch","enabled","enable","refresh","command","afterDisabled","afterEnabled","guid","uuid","prefix","token","subject","_removeSubscriber","execution","j","_removeSubscriberByToken","Outline","anchors","drawer","toolbar","_renderAnchors","_renderChapters","_renderToolbar","CHAPTERS_OPTIONS","homepage","HOME","MENU","toTop","toBottom","floor","onToggle","onScrollTop","onScrollBottom","onToolbarUpdate","ceil","subscribe","unsubscribe","jQuery","extend","outline","$article"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"outline.min.js","sources":["src/utils/types/isString.js","src/utils/lang/hasOwn.js","src/utils/lang/toString.js","src/utils/types/isFunction.js","src/utils/types/isObject.js","src/base.js","src/utils/lang/extend.js","src/utils/types/isElement.js","src/utils/lang/later.js","src/utils/lang/easeInQuad.js","src/utils/dom/_getScrollElement.js","src/utils/dom/scrollTo.js","src/utils/dom/offsetTop.js","src/utils/dom/matches.js","src/utils/dom/getParentOrHost.js","src/utils/event/enum.js","src/utils/event/_off.js","src/utils/event/_delete.js","src/utils/event/purgeElement.js","src/utils/event/getListeners.js","src/utils/event/off.js","src/utils/event/on.js","src/utils/event/getTarget.js","src/utils/dom/resolveTextNode.js","src/utils/dom/closest.js","src/utils/event/stop.js","src/utils/observer/_subscribers.js","src/utils/observer/_hasDirectSubscribersFor.js","src/utils/observer/has.js","src/utils/observer/_hasSubscribers.js","src/utils/observer/emit.js","src/utils/types/isTypedArray.js","src/utils/types/isArray.js","src/utils/icons.js","src/utils/lang/trim.js","src/utils/types/isDOM.js","src/utils/types/isHTMLCollection.js","src/utils/types/isFragment.js","src/utils/types/isTextNode.js","src/utils/dom/setAttribute.js","src/utils/dom/createElement.js","src/utils/dom/hasClass.js","src/utils/dom/removeClass.js","src/_resetHeading.js","src/utils/types/isEmpty.js","src/getChapters.js","src/utils/lang/stripTags.js","src/_getChapterParentIdByDiffer.js","src/_getChaptersWithCode.js","src/anchors.js","src/utils/lang/toTree.js","src/_updateHeading.js","src/utils/dom/addClass.js","src/utils/dom/setProperty.js","src/zIndex.js","src/drawer.js","src/utils/event/at.js","src/chapters.js","src/_paintChapters.js","src/utils/dom/intersection.js","src/_createButton.js","src/toolbar.js","src/utils/lang/guid.js","src/utils/observer/on.js","src/utils/observer/_removeSubscriber.js","src/utils/observer/off.js","src/utils/observer/_removeSubscriberByToken.js","src/outline.js"],"sourcesContent":["/**\r\n * 检测数据是否为 String 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} str\r\n * @returns {boolean}\r\n */\r\nconst isString = (str) => {\r\n return typeof str === 'string'\r\n}\r\n\r\nexport default isString\r\n","/**\r\n * 检测对象自身属性中是否具有指定的属性。\r\n * ========================================================================\r\n * @method hasOwn\r\n * @param {Object} obj - (必须)检测的目标对象\r\n * @param {String} prop - (必须)属性名\r\n * @returns {Boolean}\r\n */\r\nconst hasOwn = (obj, prop) => {\r\n const hasOwnProperty = Object.prototype.hasOwnProperty\r\n return obj && hasOwnProperty.call(obj, prop)\r\n}\r\n\r\nexport default hasOwn\r\n","/**\r\n * Object 对象原型上的 toString 方法\r\n * ========================================================================\r\n * @method toString\r\n * @param {*} val\r\n * @returns {string}\r\n */\r\nconst toString = (val) => {\r\n return Object.prototype.toString.apply(val)\r\n}\r\n\r\nexport default toString\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测测试数据是否为 Function 类型\r\n * ========================================================================\r\n * @method isFunction\r\n * @param {*} val - (必须)待检测的数据\r\n * @returns {boolean} 'val' 是 Function 类型返回 true,否则返回 false\r\n */\r\nconst isFunction = (val) => {\r\n return typeof val === 'function' || toString(val) === '[object Function]'\r\n}\r\n\r\nexport default isFunction\r\n","import toString from '../lang/toString'\r\nimport isFunction from '../types/isFunction'\r\n\r\n/**\r\n * 检测数据是否为 Object 类型\r\n * ========================================================================\r\n * @method isObject\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isObject = (o) => {\r\n return (\r\n (toString(o) === '[object Object]' ||\r\n typeof o === 'object' ||\r\n isFunction(o)) &&\r\n o !== null\r\n )\r\n}\r\n\r\nexport default isObject\r\n","import isString from './utils/types/isString'\r\nimport hasOwn from './utils/lang/hasOwn'\r\nimport isObject from './utils/types/isObject'\r\nimport extend from './utils/lang/extend'\r\n\r\nclass Base {\r\n constructor(options) {\r\n this.attrs = {}\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n attr(prop, value) {\r\n const attrs = this.attrs\r\n\r\n if (isString(prop)) {\r\n // 只能扩展 attrs 中已有的属性\r\n if (value && hasOwn(attrs, prop)) {\r\n // 更新单个配置信息\r\n attrs[prop] = value\r\n return this\r\n }\r\n\r\n // 只传递 prop 参数,则返回对应的属性值\r\n return attrs[prop]\r\n } else if (isObject(prop)) {\r\n // 批量更新配置信息\r\n extend(attrs, prop)\r\n\r\n return this\r\n } else if (arguments.length === 0) {\r\n // 不传递参数,直接返回整个\r\n return attrs\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n return this\r\n }\r\n\r\n destroy() {\r\n this.removeListeners()\r\n return this\r\n }\r\n\r\n reload(options) {\r\n this.destroy().initialize(this.attr(options))\r\n return this\r\n }\r\n\r\n addListeners() {\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n return this\r\n }\r\n}\r\n\r\nexport default Base\r\n","import hasOwn from './hasOwn'\r\n\r\n/**\r\n * 扩展对象\r\n * ========================================================================\r\n * @method extend\r\n * @param {Object} origin\r\n * @param {Object} source\r\n */\r\nconst extend = (origin, source) => {\r\n const keys = Object.keys(source)\r\n\r\n keys.forEach((prop) => {\r\n if (hasOwn(source, prop)) {\r\n origin[prop] = source[prop]\r\n }\r\n })\r\n}\r\n\r\nexport default extend\r\n","import isObject from './isObject'\r\n\r\n/**\r\n * 检测数据是否为 HTMLElement DOM 节点\r\n * ========================================================================\r\n * @method isElement\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isElement = (o) => {\r\n return !!(isObject(o) && o.nodeName && o.tagName && o.nodeType === 1)\r\n}\r\n\r\nexport default isElement\r\n","import isFunction from '../types/isFunction'\r\n\r\n/**\r\n * later - 延迟执行方法\r\n * ========================================================================\r\n * @method later\r\n * @param {Function} fn\r\n * @param {Number} [delay]\r\n * @returns {number|boolean}\r\n */\r\nconst later = (fn, delay = 300) => {\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n return setTimeout(() => {\r\n fn()\r\n }, delay)\r\n}\r\n\r\nexport default later\r\n","/**\r\n * 返回给定值的平方值\r\n * ========================================================================\r\n * @method easeInQuad\r\n * @param {Number} x\r\n * @returns {number}\r\n */\r\nconst easeInQuad = (x) => {\r\n return x * x\r\n}\r\n\r\nexport default easeInQuad\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通过给的 scrollElement 参数,获取滚动 DOM 元素\r\n * ========================================================================\r\n * @method _getScrollElement\r\n * @param {String|HTMLElement} scrollElement\r\n * @returns {Element}\r\n * @private\r\n */\r\nconst _getScrollElement = (scrollElement = null) => {\r\n let $rootElements\r\n let $scrollElement\r\n\r\n if (!scrollElement) {\r\n $rootElements = document.querySelectorAll('html,body')\r\n $scrollElement =\r\n $rootElements[0].scrollTop - $rootElements[1].scrollTop >= 0\r\n ? $rootElements[0]\r\n : $rootElements[1]\r\n } else {\r\n if (isString(scrollElement)) {\r\n $scrollElement = document.querySelector(scrollElement)\r\n } else if (isElement(scrollElement)) {\r\n $scrollElement = scrollElement\r\n }\r\n }\r\n\r\n return $scrollElement\r\n}\r\n\r\nexport default _getScrollElement\r\n","import easeInQuad from '../lang/easeInQuad'\r\nimport isFunction from '../types/isFunction'\r\nimport _getScrollElement from './_getScrollElement'\r\n\r\n/**\r\n * 指定 rootElement DOM 节点滚动到指定 top 位置\r\n * ========================================================================\r\n * @method scrollTo\r\n * @param {HTMLElement|Object} [scrollElement] - (必须)要滚动的 DOM 节点\r\n * @param {Number} top - (必须)滚动的 scrollTop 数值\r\n * @param {Function} [afterStop] - (可选)滚动完成的回调函数\r\n */\r\nconst scrollTo = (scrollElement, top, afterStop) => {\r\n const $scrollElement = _getScrollElement(scrollElement)\r\n let scrollTop = $scrollElement.scrollTop\r\n let step = 0\r\n const distance = top - scrollTop\r\n const MAX_HEIGHT = $scrollElement.scrollHeight\r\n const MAX_TOP = top - MAX_HEIGHT <= 0 ? top : MAX_HEIGHT\r\n const stop = (top) => {\r\n if (isFunction(afterStop)) {\r\n afterStop(top)\r\n }\r\n\r\n return false\r\n }\r\n const play = () => {\r\n step += 1\r\n\r\n // 向上滚动\r\n if (distance < 0) {\r\n scrollTop -= easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop <= top) {\r\n $scrollElement.scrollTop = top\r\n return stop(top)\r\n }\r\n } else {\r\n scrollTop += easeInQuad(step)\r\n $scrollElement.scrollTop = scrollTop\r\n\r\n if (scrollTop >= MAX_TOP) {\r\n $scrollElement.scrollTop = MAX_TOP\r\n return stop(MAX_TOP)\r\n }\r\n }\r\n\r\n requestAnimationFrame(play)\r\n }\r\n\r\n requestAnimationFrame(play)\r\n}\r\n\r\nexport default scrollTo\r\n","/**\r\n * 获取 DOM 节点相对于窗口的 left (纵坐标)值\r\n * ========================================================================\r\n * @method offsetTop\r\n * @param {HTMLElement} el - DOM 节点\r\n * @returns {Number}\r\n */\r\nconst offsetTop = (el) => {\r\n let top = el.offsetTop\r\n\r\n if (el.offsetParent !== null) {\r\n top += offsetTop(el.offsetParent)\r\n }\r\n\r\n return top\r\n}\r\n\r\nexport default offsetTop\r\n","/**\r\n * 获取 options 节点下匹配 selector 选择器的 DOM 节点\r\n * ========================================================================\r\n * Element.matches() 方法可以用来判断 DOM 元素是否与给定的选择器匹配,事件代理判断是\r\n * 否触发绑定的代理事件回调函数,关键就是使用 Element.matches() 辨别当前事件触发的目\r\n * 标 DOM 元素是否为事件代理所期望触发的目标。\r\n * ========================================================================\r\n * @method matches\r\n * @see https://developer.mozilla.org/en-US/docs/web/api/element/matches\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)匹配 DOM 元素的选择器\r\n * @returns {Boolean}\r\n */\r\nconst matches = (el, selector = '') => {\r\n const sel = selector.replace(/^>/i, '')\r\n\r\n if (!selector || !sel || !el) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el.matches) {\r\n return el.matches(sel)\r\n } else if (el.msMatchesSelector) {\r\n return el.msMatchesSelector(sel)\r\n } else {\r\n return false\r\n }\r\n}\r\n\r\nexport default matches\r\n","/**\r\n * 获取 DOM 元素的父节点\r\n * ========================================================================\r\n * @method getParentOrHost\r\n * @param {*|HTMLElement} el - (必须)要获取父节点的 DOM 元素\r\n * @returns {*|HTMLElement}\r\n */\r\nconst getParentOrHost = (el) => {\r\n return el.host && el !== document && el.host.nodeType\r\n ? el.host\r\n : el.parentNode\r\n}\r\n\r\nexport default getParentOrHost\r\n","export const CAPTURE_EVENTS = [\r\n 'focusout',\r\n 'blur',\r\n 'focusin',\r\n 'focus',\r\n 'load',\r\n 'unload',\r\n 'mouseenter',\r\n 'mouseleave'\r\n]\r\n","import { CAPTURE_EVENTS } from './enum'\r\nimport _delete from './_delete'\r\n\r\n/**\r\n * (私有方法)取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method _off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} fn - (必须)事件处理器回调函数\r\n * @private\r\n */\r\nconst _off = (el, type, fn) => {\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n /* istanbul ignore else */\r\n if (fn._delegateListener) {\r\n fn = fn._delegateListener\r\n delete fn._delegateListener\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n _delete(el, type, fn)\r\n\r\n el.removeEventListener(type, fn, capture)\r\n}\r\n\r\nexport default _off\r\n","/**\r\n * 删除 DOM 元素缓存的 _listeners 数据\r\n * ========================================================================\r\n * @method _delete\r\n * @param {HTMLElement} el - 要删除 listener 的 DOM 元素\r\n * @param {String} type - 事件类型(名称)\r\n * @param {Function} [fn] - 事件处理器回调函数\r\n */\r\nconst _delete = function (el, type, fn) {\r\n const listeners = el._listeners\r\n let index = -1\r\n\r\n if (listeners.length < 1) {\r\n return false\r\n }\r\n\r\n // 移除缓存的 _listeners 数据\r\n listeners.forEach((listener, i) => {\r\n const handler = listener.fn\r\n\r\n if (type === listener.type) {\r\n index = i\r\n\r\n if (handler === fn) {\r\n index = i\r\n }\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (index > -1) {\r\n listeners.splice(index, 1)\r\n }\r\n}\r\n\r\nexport default _delete\r\n","import isString from '../types/isString'\r\nimport isElement from '../types/isElement'\r\nimport getListeners from './getListeners'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 销毁(type 类型的)代理事件绑定\r\n * ========================================================================\r\n * 1. 设置了事件类型 type,则销毁指定类型的事件绑定,否则清除所有代理事件绑定\r\n * 2. recurse 设置为 true,递归销毁子节点全部事件绑定\r\n * ========================================================================\r\n * @method purgeElement\r\n * @param {HTMLElement|String} el - (必须)DOM 元素或者其选择器\r\n * @param {String|Boolean} type - (必须)事件类型\r\n * @param {Boolean} [recurse] - (可选)是否递归销毁子节点所有事件绑定\r\n */\r\nconst purgeElement = function (el, type, recurse = false) {\r\n const $element = isString(el) ? document.querySelector(el) : el\r\n const $children = $element.childNodes\r\n const listeners = getListeners($element, type)\r\n\r\n listeners.forEach((listener) => {\r\n _off($element, listener.type, listener.fn)\r\n })\r\n\r\n if (\r\n (recurse || type === true || arguments.length === 1) &&\r\n $element &&\r\n $children\r\n ) {\r\n $children.forEach(($child) => {\r\n if (isElement($child)) {\r\n purgeElement($child, type, recurse)\r\n }\r\n })\r\n }\r\n}\r\n\r\nexport default purgeElement\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 获取 DOM 元素(type 事件类型)事件绑定信息\r\n * ========================================================================\r\n * 如果设置了事件类型 type, 则返回指定类型的事件绑定信息,否则返回所有事件绑定信息\r\n * ========================================================================\r\n * @methods getListeners\r\n * @param {HTMLElement} el - (必须)要获取事件绑定信息的 DOM 元素\r\n * @param {String} [type] - (可选)事件类型\r\n * @returns {Array} - 已绑定的事件信息\r\n */\r\nconst getListeners = (el, type) => {\r\n let listeners = el._listeners || []\r\n\r\n if (isString(type) && type) {\r\n listeners = listeners.filter((listener) => {\r\n return listener.type === type\r\n })\r\n }\r\n\r\n return listeners\r\n}\r\n\r\nexport default getListeners\r\n","import purgeElement from './purgeElement'\r\nimport isFunction from '../types/isFunction'\r\nimport _off from './_off'\r\n\r\n/**\r\n * 取消 type 类型的代理事件绑定\r\n * ========================================================================\r\n * 如果没有设置 handler,则销毁 this.$options 绑定的所有符合 type 事件类型的事件绑定\r\n * ========================================================================\r\n * @method off\r\n * @param {HTMLElement} el - (必须)取消事件绑定的 DOM 元素\r\n * @param {String} type - (必须)事件类型\r\n * @param {Function} [fn] - (可选)事件处理器回调函数\r\n */\r\nconst off = (el, type, fn) => {\r\n // 如果不设置 fn 参数,默认清除 el 元素上绑定的所有事件处理器\r\n if (!isFunction(fn)) {\r\n return purgeElement(el, type)\r\n }\r\n\r\n _off(el, type, fn)\r\n}\r\n\r\nexport default off\r\n","import closest from '../dom/closest'\r\nimport off from './off'\r\nimport getTarget from './getTarget'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定代理事件\r\n * ========================================================================\r\n * @method on\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String} selector - (必须)事件代理目标 DOM 元素的选择器\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (可选) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst on = (el, selector, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n\r\n const listener = function (evt) {\r\n const target = getTarget(evt)\r\n // 通过 Element.matches 方法获得点击的目标元素\r\n const delegateTarget = closest(target, selector, el)\r\n let overrideContext = context || el\r\n\r\n evt.delegateTarget = delegateTarget\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (delegateTarget) {\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n selector,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default on\r\n","import resolveTextNode from '../dom/resolveTextNode'\r\n\r\n/**\r\n * 返回触发事件的 target DOM 元素\r\n * ========================================================================\r\n * @method getTarget\r\n * @param {Event} evt - Event 对象\r\n * @return {HTMLElement} - Event 对象的 target DOM 元素\r\n */\r\nconst getTarget = function (evt) {\r\n const target = evt.target\r\n\r\n return resolveTextNode(target)\r\n}\r\n\r\nexport default getTarget\r\n","/**\r\n * 在某些情况下,某些浏览器(例如:Safari 浏览器)会返回实际的目标元素内部的文本节点。\r\n * resolveTextNode() 方法则会返回实际的目标节点。\r\n * ========================================================================\r\n * @method resolveTextNode\r\n * @param {HTMLElement|Text} el - 要解析的节点\r\n * @return {*|HTMLElement} - 实际的目标 DOM 节点\r\n */\r\nconst resolveTextNode = function (el) {\r\n if (el && el.nodeType === 3) {\r\n return el.parentNode\r\n }\r\n\r\n return el\r\n}\r\n\r\nexport default resolveTextNode\r\n","import matches from './matches'\r\nimport getParentOrHost from './getParentOrHost'\r\n\r\n/**\r\n * 获取 options 元素父元素最近的包含 selector 选择器的元素\r\n * ========================================================================\r\n * @method closest\r\n * @param {HTMLElement} el - (必须)DOM 元素\r\n * @param {String} selector - (必须)DOM 元素的选择其\r\n * @param {HTMLElement} [ctx] - (必须)比对的 DOM 元素\r\n * @param {Boolean} [includeCTX] - (必须)是否包含 context DOM 元素\r\n * @returns {null|HTMLElement} - 返回最接近的 DOM 元素\r\n */\r\nconst closest = (el, selector, ctx, includeCTX) => {\r\n const context = ctx || document\r\n\r\n if (!el) {\r\n return null\r\n }\r\n\r\n do {\r\n /* istanbul ignore else */\r\n if (\r\n (selector != null &&\r\n (selector[0] === '>'\r\n ? el.parentNode === context && matches(el, selector)\r\n : matches(el, selector))) ||\r\n (includeCTX && el === context)\r\n ) {\r\n return el\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (el === context) {\r\n break\r\n }\r\n\r\n /* jshint boss:true */\r\n } while ((el = getParentOrHost(el)))\r\n}\r\n\r\nexport default closest\r\n","/**\r\n * 停止事件(阻止默认行为和阻止事件的捕获或冒泡)\r\n * ========================================================================\r\n * @method stop\r\n * @param {Event} evt - 事件对象\r\n *\r\n * @example\r\n *
\r\n * Service\r\n * Help\r\n *
\r\n *\r\n * const $nav = document.querySelector('#nav')\r\n * const $service = document.querySelector('.anchor')\r\n *\r\n * on($nav, 'click', function(evt) {\r\n * console.log('你点击了导航栏')\r\n * })\r\n *\r\n * on($anchor, 'click', function(evt) {\r\n * console.log('tagName', this.tagName)\r\n *\r\n * // 工作台输出:'a'\r\n * // 不会触发事件冒泡,输出:'你点击了导航栏'\r\n * // 也不会切换到 href 属性的页面,阻止了点击链接的默认行为\r\n * stopEvent(evt)\r\n * })\r\n */\r\nconst stop = function (evt) {\r\n evt.stopPropagation()\r\n evt.preventDefault()\r\n}\r\n\r\nexport default stop\r\n","/**\r\n * 存储订阅者(主题和处理器的)私有对象\r\n * ========================================================================\r\n * @type {{}}\r\n * @private\r\n */\r\nconst _subscribers = {}\r\n\r\nexport default _subscribers\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 判断是否存在与给定 topic 完全匹配的订阅者信息\r\n * ========================================================================\r\n * @method _hasDirectSubscribersFor\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasDirectSubscribersFor = (topic) => {\r\n return hasOwn(_subscribers, topic) && _subscribers[topic].length > 0\r\n}\r\n\r\nexport default _hasDirectSubscribersFor\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\nimport _hasSubscribers from './_hasSubscribers'\r\n\r\n/**\r\n * 判断是否存在包含 topic 指定的订阅者信息\r\n * ========================================================================\r\n * @method has\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Boolean} [isDirect] - (可选)是否为直接的主题,默认值:true\r\n * @returns {Boolean}\r\n */\r\nconst has = (topic, isDirect = true) => {\r\n return isDirect ? _hasDirectSubscribersFor(topic) : _hasSubscribers(topic)\r\n}\r\n\r\nexport default has\r\n","import _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * 判断是否存在包含给定 topic 相关的订阅者信息\r\n * ========================================================================\r\n * @method _hasSubscribers\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _hasSubscribers = (topic) => {\r\n let found = _hasDirectSubscribersFor(topic)\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (!found && position !== -1) {\r\n topic = topic.substring(0, position)\r\n position = topic.lastIndexOf('.')\r\n found = _hasDirectSubscribersFor(topic)\r\n }\r\n\r\n return found\r\n}\r\n\r\nexport default _hasSubscribers\r\n","import isTypedArray from '../types/isTypedArray'\r\nimport _subscribers from './_subscribers'\r\nimport has from './has'\r\nimport _hasDirectSubscribersFor from './_hasDirectSubscribersFor'\r\n\r\n/**\r\n * (异步)发布订阅主题信息\r\n * ========================================================================\r\n * 主题默认是异步发布的。确保在消费者处理主题时,主题的发起者不会被阻止。\r\n * ========================================================================\r\n * @method emit\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Object} data - (必须)数据对象\r\n * @param {Boolean} async - (可选) 是否异步发布\r\n */\r\nconst emit = (topic, data, async = true) => {\r\n const execute = (topic) => {\r\n if (!_hasDirectSubscribersFor(topic)) {\r\n return false\r\n }\r\n\r\n _subscribers[topic].forEach((subscriber) => {\r\n // 针对 mqtt 消息服务返回的 Uint8Array 类似的 typed arrays 格式的数据\r\n // 采用 toString() 方法转化为普通(JSON)字符串\r\n const message = isTypedArray(data) ? data.toString() : data\r\n\r\n subscriber.callback.call(subscriber.context || subscriber, message)\r\n })\r\n }\r\n const deliver = () => {\r\n let subscriber = topic\r\n let position = topic.lastIndexOf('.')\r\n\r\n while (position !== -1) {\r\n subscriber = subscriber.substring(0, position)\r\n position = subscriber.lastIndexOf('.')\r\n\r\n execute(subscriber)\r\n }\r\n\r\n // 执行 topic 对应的处理器\r\n execute(topic)\r\n // 执行特殊 topic:'*'(监听全部消息的发布)\r\n execute('*')\r\n }\r\n\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (async) {\r\n setTimeout(deliver, 10)\r\n } else {\r\n deliver()\r\n }\r\n}\r\n\r\nexport default emit\r\n","import toString from '../lang/toString'\r\n/**\r\n * 判断检测数据是否为 Typed Arrays 类型的数据\r\n * ========================================================================\r\n * @param {*} val\r\n * @returns {boolean}\r\n */\r\nconst isTypedArray = (val) => {\r\n const TYPES = [\r\n '[object Int8Array]',\r\n '[object Uint8Array]',\r\n '[object Uint8ClampedArray]',\r\n '[object Int16Array]',\r\n '[object Uint16Array]',\r\n '[object Int32Array]',\r\n '[object Uint32Array]',\r\n '[object Float32Array]',\r\n '[object Float64Array]',\r\n '[object BigInt64Array]',\r\n '[object BigUint64Array]'\r\n ]\r\n\r\n return TYPES.indexOf(toString(val)) > -1\r\n}\r\n\r\nexport default isTypedArray\r\n","import toString from '../lang/toString'\r\n\r\n/**\r\n * 检测数据是否为 Array 类型\r\n * ========================================================================\r\n * @method isArray\r\n * @param {*} o\r\n * @returns {boolean}\r\n */\r\nconst isArray = (o) => {\r\n if (Array.isArray) {\r\n return Array.isArray(o)\r\n } else {\r\n return toString(o) === '[object Array]'\r\n }\r\n}\r\n\r\nexport default isArray\r\n","import isArray from './types/isArray'\r\n\r\n/**\r\n * 绘制 SVG Sprites 图标集\r\n * ========================================================================\r\n * @method paintSvgSprites\r\n * @param {Array} [symbols] - (可选)symbols 图标数组\r\n * 传递 symbols - 绘制 symbols + SYMBOLS 的图标集\r\n * 不传递 symbols - 仅绘制默认 SYMBOLS 图标集\r\n */\r\nexport const paintSvgSprites = (symbols = []) => {\r\n const SYMBOLS = [\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n '',\r\n ''\r\n ]\r\n const sprites =\r\n isArray(symbols) && symbols.length > 0 ? SYMBOLS.concat(symbols) : SYMBOLS\r\n const $body = document.body\r\n let $icons = document.querySelector('#svg-sprites')\r\n\r\n if ($icons) {\r\n $icons.innerHTML = sprites.join('')\r\n } else {\r\n $icons = document.createElement('div')\r\n $icons.innerHTML =\r\n ``\r\n $body.insertBefore($icons.firstChild, $body.firstChild)\r\n }\r\n}\r\n\r\n/**\r\n * 创建 SVG 图标 DOM 元素\r\n * ========================================================================\r\n * @method createSvgIcon\r\n * @param {String} name\r\n * @param {Number|String|Array} [size]\r\n * @param {String} [color]\r\n * @param {String} [iconSet]\r\n * @returns {HTMLElement}\r\n */\r\nexport const createSvgIcon = (\r\n name,\r\n size = 0,\r\n color = '',\r\n iconSet = 'outline'\r\n) => {\r\n const binds = iconSet\r\n ? `xlink:href=\"#${iconSet}-icon-${name}\"`\r\n : `xlink:href=\"#icon-${name}\"`\r\n const width = isArray(size) ? size[0] : size\r\n const height = isArray(size) ? size[1] : size\r\n const defaultRules = size ? `width:${width}px;height:${height}px;` : ''\r\n const cssRules = color ? defaultRules + `color:${color}` : defaultRules\r\n const svg =\r\n `` +\r\n `` +\r\n ``\r\n const $icon = document.createElement('i')\r\n\r\n $icon.className = 'outline-icon'\r\n $icon.innerHTML = svg\r\n\r\n return $icon\r\n}\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 清楚字符串起始位置所有的空格\r\n * ========================================================================\r\n * @method trim\r\n * @param {string} str\r\n * @returns {string|Boolean}\r\n */\r\nconst trim = (str) => {\r\n if (!isString(str)) {\r\n return false\r\n }\r\n return str.replace(/^\\s+|\\s+$/g, '')\r\n}\r\n\r\nexport default trim\r\n","import isObject from './isObject'\r\nimport isElement from './isElement'\r\nimport isHTMLCollection from './isHTMLCollection'\r\nimport isFragment from './isFragment'\r\nimport isTextNode from './isTextNode'\r\n\r\nconst isDOM = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (isElement(el) || isHTMLCollection(el) || isFragment(el) || isTextNode(el))\r\n )\r\n}\r\n\r\nexport default isDOM\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isHTMLCollection = (el) => {\r\n return !!(isObject(el) && toString(el) === '[object NodeList]')\r\n}\r\n\r\nexport default isHTMLCollection\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isFragment = (fragment) => {\r\n return !!(\r\n isObject(fragment) && toString(fragment) === '[object DocumentFragment]'\r\n )\r\n}\r\n\r\nexport default isFragment\r\n","import toString from '../lang/toString'\r\nimport isObject from './isObject'\r\n\r\nconst isTextNode = (el) => {\r\n return !!(\r\n isObject(el) &&\r\n (toString(el) === '[object Text]' || (el.tagName && el.nodeType === 3))\r\n )\r\n}\r\n\r\nexport default isTextNode\r\n","/**\r\n * 给 DOM 节点设置属性/值\r\n * ========================================================================\r\n * @method setAttribute\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} attr - 属性名称\r\n * @param {String|Number|Boolean} value - 属性值\r\n */\r\nconst setAttribute = (el, attr, value) => {\r\n let tagName = el.tagName.toLowerCase()\r\n\r\n switch (attr) {\r\n case 'style':\r\n el.style.cssText = value\r\n break\r\n case 'value':\r\n if (tagName === 'input' || tagName === 'textarea') {\r\n el.value = value\r\n } else {\r\n el.setAttribute(attr, value)\r\n }\r\n break\r\n case 'className':\r\n el.className = value\r\n break\r\n default:\r\n el.setAttribute(attr, value)\r\n break\r\n }\r\n}\r\n\r\nexport default setAttribute\r\n","import hasOwn from '../lang/hasOwn'\r\nimport isObject from '../types/isObject'\r\nimport isString from '../types/isString'\r\nimport isArray from '../types/isArray'\r\nimport isDOM from '../types/isDOM'\r\nimport setAttribute from './setAttribute'\r\n\r\n/**\r\n * 创建 DOM 节点,并添加属性和子节点\r\n * ========================================================================\r\n * @method createElement\r\n * @param {String} tagName - 标签名称\r\n * @param {Object|Array} attrs - 属性对象或者子节点\r\n * @param {Array} [children] - 子节点数组\r\n * @returns {HTMLElement}\r\n */\r\nconst createElement = (tagName, attrs, children) => {\r\n const $fragment = document.createDocumentFragment()\r\n const $el = document.createElement(tagName)\r\n const isValidChild = (child) => {\r\n return isDOM(child) || isString(child)\r\n }\r\n const append = (child) => {\r\n let $child\r\n\r\n if (!isValidChild(child)) {\r\n return false\r\n }\r\n\r\n if (isDOM(child)) {\r\n $child = child\r\n } else if (isString(child)) {\r\n $child = document.createTextNode(child)\r\n }\r\n\r\n $fragment.appendChild($child)\r\n }\r\n\r\n if (isObject(attrs)) {\r\n Object.keys(attrs).forEach((attr) => {\r\n if (hasOwn(attrs, attr)) {\r\n setAttribute($el, attr, attrs[attr])\r\n }\r\n })\r\n } else if (isArray(attrs) && attrs.every((attr) => isValidChild(attr))) {\r\n attrs.forEach((child) => {\r\n append(child)\r\n })\r\n }\r\n\r\n if (isArray(children)) {\r\n children.forEach((child) => {\r\n append(child)\r\n })\r\n } else {\r\n append(children)\r\n }\r\n\r\n $el.appendChild($fragment)\r\n\r\n return $el\r\n}\r\n\r\nexport default createElement\r\n","import isElement from '../types/isElement'\r\n/**\r\n * 检测 DOM 节点是否包含名为 className 的样式\r\n * ========================================================================\r\n * @method hasClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst hasClass = (el, className) => {\r\n const pattern = new RegExp('(\\\\s|^)' + className + '(\\\\s|$)')\r\n let allClass\r\n let classList\r\n\r\n if (!isElement(el)) {\r\n return false\r\n }\r\n\r\n allClass = el.className\r\n\r\n if (!allClass) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.contains) {\r\n return el.classList.contains(className)\r\n }\r\n\r\n return !!allClass.match(pattern)\r\n}\r\n\r\nexport default hasClass\r\n","import trim from '../lang/trim'\r\nimport hasClass from './hasClass'\r\n\r\n/**\r\n * 移除 DOM 节点的 className 样式\r\n * ========================================================================\r\n * @method removeClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst removeClass = (el, className) => {\r\n let allClass = el.className\r\n let classList\r\n\r\n if (!allClass || !hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.remove) {\r\n classList.remove(className)\r\n } else {\r\n allClass = trim(allClass.replace(className, ''))\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default removeClass\r\n","import removeClass from './utils/dom/removeClass'\r\nimport isEmpty from './utils/types/isEmpty'\r\nimport trim from './utils/lang/trim'\r\n\r\nconst _resetHeading = ($heading, hasAnchor = true, isAtStart = true) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const text = $heading.innerHTML\r\n let $anchor\r\n\r\n $heading.innerHTML = text.replace(/^\\d+(?:(\\.?\\d*)*\\s?)?/gi, '')\r\n $heading.removeAttribute('id')\r\n $heading.removeAttribute('data-id')\r\n\r\n removeClass($heading, CLS_HEADING)\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $anchor = $heading.querySelector(`.${CLS_HEADING}__anchor`)\r\n\r\n if (isAtStart) {\r\n removeClass($heading, `${CLS_HEADING}_start`)\r\n }\r\n\r\n if (isEmpty(trim($heading.className))) {\r\n $heading.removeAttribute('class')\r\n }\r\n\r\n $heading.removeChild($anchor)\r\n}\r\n\r\nexport default _resetHeading\r\n","import isString from './isString'\r\n/**\r\n * 检测数据是否为空字符串\r\n * ========================================================================\r\n * @method isEmpty\r\n * @param {String} str\r\n * @returns {boolean}\r\n */\r\nconst isEmpty = (str) => {\r\n return isString(str) && str === ''\r\n}\r\n\r\nexport default isEmpty\r\n","import trim from './utils/lang/trim'\r\nimport stripTags from './utils/lang/stripTags'\r\n\r\nimport _getChaptersWithCode from './_getChaptersWithCode'\r\nimport _getChapterParentIdByDiffer from './_getChapterParentIdByDiffer'\r\n\r\nconst getChapters = (headings, showCode = true) => {\r\n const chapters = []\r\n let previous = 1\r\n let level = 0\r\n\r\n headings.forEach((heading, i) => {\r\n const headingLevel = heading.tagName.replace(/h/i, '')\r\n let current = parseInt(headingLevel, 10)\r\n let pid = -1\r\n\r\n // 当前标题的(标题标签)序号 > 前一个标题的序号:两个相连的标题是父标题 -> 子标题关系;\r\n // h2 (前一个标题)\r\n // h3 (当前标题)\r\n if (current > previous) {\r\n level += 1\r\n\r\n // 第一层级的 pid 是 -1\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n pid = i - 1\r\n }\r\n }\r\n // 当前标题的(标题标签)序号 = 前一个标题的序号\r\n // h2 (前一个标题)\r\n // h2 (当前标题)\r\n // 当前标题的(标题标签)序号 < 前一个标题的序号,并且当前标题序号 > 当前的级别\r\n // h2\r\n // h4 (前一个标题)\r\n // h3 (当前标题:这种情况我们还是任务 h3 是 h2 的下一级章节)\r\n else if (current === previous || (current < previous && current > level)) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n pid = -1\r\n } else {\r\n pid = chapters[i - 1].pid\r\n }\r\n } else if (current <= level) {\r\n // H1 的层级肯定是 1\r\n if (current === 1) {\r\n level = 1\r\n } else {\r\n level = level - (previous - current)\r\n\r\n if (level <= 1) {\r\n level = 1\r\n }\r\n }\r\n\r\n // 第一级的标题\r\n if (level === 1) {\r\n pid = -1\r\n } else {\r\n // 通过当前标题和前一个标题之间的等级差,获得当前标题的父标题ID\r\n pid = _getChapterParentIdByDiffer(chapters, previous - current, i)\r\n }\r\n }\r\n\r\n previous = current\r\n\r\n chapters.push({\r\n id: i,\r\n pid: pid,\r\n level: level,\r\n rel: `heading-${i}`,\r\n text: stripTags(trim(heading.innerHTML))\r\n })\r\n })\r\n\r\n return showCode ? _getChaptersWithCode(chapters) : chapters\r\n}\r\n\r\nexport default getChapters\r\n","import isString from '../types/isString'\r\n\r\n/**\r\n * 过滤所有 HTML 标签\r\n * ========================================================================\r\n * @method stripTags\r\n * @param {string} str\r\n * @returns {string}\r\n */\r\nconst stripTags = (str) => {\r\n if (!isString(str)) {\r\n return ''\r\n }\r\n return str.replace(/<\\/?[^>]+(>|$)/g, '')\r\n}\r\n\r\nexport default stripTags\r\n","const _getChapterParentIdByDiffer = (chapters, differ, index) => {\r\n let previous = chapters[index - 1]\r\n let pid\r\n let i\r\n\r\n for (i = 0; i < differ; i += 1) {\r\n pid = previous.pid\r\n previous = chapters[pid]\r\n }\r\n\r\n pid = previous.pid\r\n\r\n return pid\r\n}\r\n\r\nexport default _getChapterParentIdByDiffer\r\n","const _getChaptersWithCode = (chapters) => {\r\n const groups = {}\r\n const cb = (o) => {\r\n return [o.pid]\r\n }\r\n\r\n chapters.forEach((o) => {\r\n const group = JSON.stringify(cb(o))\r\n\r\n groups[group] = groups[group] || []\r\n groups[group].push(o)\r\n\r\n o.index = groups[group].length\r\n if (o.pid === -1) {\r\n o.code = String(o.index)\r\n }\r\n })\r\n\r\n Object.keys(groups).forEach((group) => {\r\n groups[group].forEach((c, i) => {\r\n c.index = i + 1\r\n chapters.forEach((o) => {\r\n if (o.pid === c.id) {\r\n o.code = c.code + '.' + o.index\r\n }\r\n })\r\n })\r\n })\r\n\r\n return chapters\r\n}\r\n\r\nexport default _getChaptersWithCode\r\n","import Base from './base'\r\n\r\n// 在文章的标题生成 anchor 链接\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport toTree from './utils/lang/toTree'\r\nimport later from './utils/lang/later'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _updateHeading from './_updateHeading'\r\nimport _resetHeading from './_resetHeading'\r\nimport getChapters from './getChapters'\r\n\r\nclass Anchors extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Anchors.DEFAULTS\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n\r\n this.chapters = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let scrollElement\r\n let selector\r\n let $articleElement\r\n let articleElement\r\n\r\n this.attr(options)\r\n articleElement = this.attr('articleElement')\r\n scrollElement = this.attr('scrollElement')\r\n selector = this.attr('selector')\r\n created = this.attr('created')\r\n\r\n if (isString(articleElement)) {\r\n $articleElement = document.querySelector(articleElement)\r\n } else if (isElement(articleElement)) {\r\n $articleElement = articleElement\r\n }\r\n\r\n if (!$articleElement) {\r\n return this\r\n }\r\n\r\n this.$articleElement = $articleElement\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n this.$headings = [...$articleElement.querySelectorAll(selector)]\r\n\r\n if (this.$headings.length < 1) {\r\n return this\r\n }\r\n\r\n this.chapters = getChapters(this.$headings)\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n const chapters = this.chapters\r\n return isTreeStructured ? toTree(chapters, 'id', 'pid') : chapters\r\n }\r\n\r\n count() {\r\n return this.chapters.length\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const $headings = this.$headings\r\n const chapters = this.getChapters()\r\n\r\n paintSvgSprites()\r\n\r\n $headings.forEach(($heading, i) => {\r\n const chapterCode = chapters[i].code\r\n _updateHeading($heading, i, {\r\n hasAnchor,\r\n isAtStart,\r\n showCode,\r\n chapterCode,\r\n anchorURL\r\n })\r\n })\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const hasAnchor = this.attr('hasAnchor')\r\n const isAtStart = this.attr('isAtStart')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n const $headings = this.$headings\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n $headings.forEach(($heading) => {\r\n _resetHeading($heading, hasAnchor, isAtStart)\r\n })\r\n\r\n this.attr(Anchors.DEFAULTS)\r\n this.$articleElement = null\r\n this.$scrollElement = null\r\n this.$headings = []\r\n this.chapters = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onAnchorTrigger(evt) {\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const $heading = $anchor.parentNode\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const $scrollElement = this.$scrollElement\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'anchor')\r\n }\r\n\r\n later(() => {\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.scrollTo(top, after)\r\n\r\n if (!anchorURL) {\r\n stop(evt)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n on(\r\n $articleElement,\r\n '.outline-heading__anchor',\r\n 'click',\r\n this.onAnchorTrigger,\r\n this,\r\n true\r\n )\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $articleElement = this.$articleElement\r\n\r\n off($articleElement, 'click', this.onAnchorTrigger)\r\n\r\n return this\r\n }\r\n}\r\n\r\nAnchors.DEFAULTS = {\r\n scrollElement: 'html,body',\r\n articleElement: '#article',\r\n selector: 'h1,h2,h3,h4,h5,h6',\r\n stickyHeight: 0,\r\n anchorURL: '',\r\n hasAnchor: true,\r\n isAtStart: true,\r\n showCode: false,\r\n created: null,\r\n mounted: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Anchors\r\n","const toTree = (list, nodeKey, parentKey) => {\r\n const map = {}\r\n const roots = []\r\n\r\n list.forEach((item, i) => {\r\n // initialize the map\r\n map[item[nodeKey]] = i\r\n // initialize the children\r\n item.children = []\r\n })\r\n\r\n list.forEach((item) => {\r\n const node = list[map[item[parentKey]]]\r\n\r\n if (item[parentKey] !== -1) {\r\n // if you have dangling branches check that map[node.parentId] exists\r\n node.children.push(item)\r\n } else {\r\n roots.push(item)\r\n }\r\n })\r\n\r\n return roots\r\n}\r\n\r\nexport default toTree\r\n","import trim from './utils/lang/trim'\r\nimport createElement from './utils/dom/createElement'\r\nimport setAttribute from './utils/dom/setAttribute'\r\n\r\nimport { createSvgIcon } from './utils/icons'\r\n\r\nconst _updateHeading = ($heading, i, options) => {\r\n const CLS_HEADING = 'outline-heading'\r\n const hasAnchor = options.hasAnchor || true\r\n const isAtStart = options.isAtStart || true\r\n const showCode = options.showCode || false\r\n const chapterCode = options.chapterCode || ''\r\n const anchorURL = options.anchorURL || ''\r\n const headingId = `heading-${i}`\r\n const attrs = {\r\n id: headingId,\r\n className: isAtStart ? `${CLS_HEADING} ${CLS_HEADING}_start` : CLS_HEADING,\r\n 'data-id': i\r\n }\r\n const keys = Object.keys(attrs)\r\n const text = trim($heading.innerHTML)\r\n let $anchor\r\n let $icon\r\n\r\n keys.forEach((prop) => {\r\n setAttribute($heading, prop, attrs[prop])\r\n })\r\n\r\n if (showCode) {\r\n $heading.innerHTML = chapterCode + ' ' + text\r\n }\r\n\r\n if (!hasAnchor) {\r\n return false\r\n }\r\n\r\n $icon = createSvgIcon('hash')\r\n $anchor = createElement(\r\n 'a',\r\n {\r\n id: `anchor-${i}`,\r\n className: `${CLS_HEADING}__anchor anchor-${i}`,\r\n href: anchorURL ? anchorURL : `#${headingId}`,\r\n target: anchorURL ? '_blank' : 'self',\r\n 'data-id': i\r\n },\r\n [$icon]\r\n )\r\n $heading.appendChild($anchor)\r\n}\r\n\r\nexport default _updateHeading\r\n","import hasClass from './hasClass'\r\n\r\n/**\r\n * 给 DOM 节点添加名为 className 的样式\r\n * ========================================================================\r\n * @method addClass\r\n * @param {HTMLElement} el - DOM 节点\r\n * @param {String} className - 样式名称\r\n * @returns {Boolean}\r\n */\r\nconst addClass = (el, className) => {\r\n let classList\r\n let allClass\r\n\r\n if (hasClass(el, className)) {\r\n return false\r\n }\r\n\r\n classList = el.classList\r\n\r\n if (classList?.add) {\r\n classList.add(className)\r\n } else {\r\n allClass = el.className\r\n allClass += allClass.length > 0 ? ' ' + className : className\r\n el.className = allClass\r\n }\r\n}\r\n\r\nexport default addClass\r\n","const setProperty = (prop, value) => {\r\n const documentElement = document.documentElement\r\n documentElement.style.setProperty(prop, value)\r\n}\r\n\r\nexport default setProperty\r\n","import setProperty from './utils/dom/setProperty'\r\n\r\nlet index = 2000\r\n\r\nconst zIndex = (idx) => {\r\n if (idx) {\r\n index = idx\r\n } else {\r\n index += 1\r\n }\r\n\r\n setProperty('--outline-zIndex', `${index}`)\r\n\r\n return index\r\n}\r\n\r\nexport default zIndex\r\n","import Base from './base'\r\n\r\nimport later from './utils/lang/later'\r\nimport isFunction from './utils/types/isFunction'\r\nimport addClass from './utils/dom/addClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport createElement from './utils/dom/createElement'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\n\r\nimport { paintSvgSprites, createSvgIcon } from './utils/icons'\r\nimport zIndex from './zIndex'\r\n\r\nclass Drawer extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = true\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n this.zIndex = 0\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n\r\n this.title = this.attr('title')\r\n created = this.attr('created')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n return this\r\n }\r\n\r\n setTitle(title) {\r\n this.attr('title', title)\r\n this.title = title\r\n this.$title.innerHTML = title\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const size = this.attr('size')\r\n const placement = this.attr('placement')\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const hasOffset = this.attr('hasOffset')\r\n const hasPadding = this.attr('hasPadding')\r\n const autoHeight = this.attr('autoHeight')\r\n const customClass = this.attr('customClass')\r\n const $fragment = document.createDocumentFragment()\r\n let $el\r\n let $modal\r\n let $header\r\n let $title\r\n let $close\r\n let $main\r\n let $footer\r\n let $overlay\r\n\r\n paintSvgSprites()\r\n this.zIndex = zIndex()\r\n\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-drawer__title'\r\n },\r\n [this.title]\r\n )\r\n this.$title = $title\r\n\r\n if (hasClose) {\r\n $close = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__close'\r\n },\r\n [createSvgIcon('close', 20)]\r\n )\r\n this.$close = $close\r\n }\r\n\r\n $header = createElement(\r\n 'header',\r\n {\r\n className: 'outline-drawer__header'\r\n },\r\n [$title, $close]\r\n )\r\n this.$header = $header\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__main'\r\n },\r\n ['']\r\n )\r\n this.$main = $main\r\n\r\n if (!hasPadding) {\r\n addClass($main, 'outline-drawer_full')\r\n }\r\n\r\n $footer = createElement(\r\n 'footer',\r\n {\r\n className: 'outline-drawer__footer'\r\n },\r\n ['']\r\n )\r\n this.$footer = $footer\r\n\r\n $modal = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer__modal outline-drawer_${placement} outline-drawer_${size} outline-drawer_closed`\r\n },\r\n [$header, $main, $footer]\r\n )\r\n this.$modal = $modal\r\n\r\n if (hasOffset) {\r\n addClass($modal, 'outline-drawer_offset')\r\n }\r\n\r\n if (autoHeight) {\r\n addClass($modal, 'outline-drawer_auto')\r\n }\r\n\r\n if (customClass) {\r\n addClass($modal, customClass)\r\n }\r\n\r\n if (hasOverlay) {\r\n $overlay = createElement(\r\n 'div',\r\n {\r\n className: 'outline-drawer__overlay'\r\n },\r\n ['']\r\n )\r\n this.$overlay = $overlay\r\n }\r\n\r\n $el = createElement(\r\n 'div',\r\n {\r\n className: `outline-drawer`\r\n },\r\n [$modal, $overlay]\r\n )\r\n this.$el = $el\r\n $fragment.appendChild($el)\r\n document.body.appendChild($fragment)\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n open() {\r\n const opened = this.attr('afterOpened')\r\n const $modal = this.$modal\r\n\r\n addClass(this.$el, 'outline-drawer_opened')\r\n removeClass($modal, 'outline-drawer_closed')\r\n addClass($modal, 'outline-drawer_opened')\r\n\r\n later(() => {\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n close() {\r\n const closed = this.attr('afterClosed')\r\n const $modal = this.$modal\r\n\r\n removeClass($modal, 'outline-drawer_opened')\r\n addClass($modal, 'outline-drawer_closed')\r\n\r\n later(() => {\r\n removeClass(this.$el, 'outline-drawer_opened')\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const closed = this.isClosed()\r\n\r\n if (closed) {\r\n this.open()\r\n } else {\r\n this.close()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n afterToggle.call(this, closed)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const afterDestroy = this.attr('afterDestroy')\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n let index = this.zIndex\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n\r\n this.attrs = Drawer.DEFAULTS\r\n this.title = ''\r\n this.closed = false\r\n this.$el = null\r\n this.$modal = null\r\n this.$header = null\r\n this.$title = null\r\n this.$close = null\r\n this.$main = null\r\n this.$footer = null\r\n this.$overlay = null\r\n\r\n index -= 1\r\n zIndex(index)\r\n this.zIndex = 0\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (hasClose) {\r\n on($el, '.outline-drawer__close', 'click', this.onClose, this, true)\r\n }\r\n\r\n if (hasOverlay) {\r\n on($el, '.outline-drawer__overlay', 'click', this.onClose, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const hasClose = this.attr('hasClose')\r\n const hasOverlay = this.attr('hasOverlay')\r\n const $el = this.$el\r\n\r\n if (!hasClose && !hasOverlay) {\r\n return this\r\n }\r\n\r\n off($el, 'click', this.onClose)\r\n\r\n return this\r\n }\r\n\r\n onClose() {\r\n this.close()\r\n return this\r\n }\r\n}\r\n\r\nDrawer.DEFAULTS = {\r\n placement: 'rtl',\r\n title: '标题',\r\n size: 'regular',\r\n hasClose: true,\r\n hasOverlay: true,\r\n hasOffset: false,\r\n hasPadding: true,\r\n autoHeight: true,\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterToggle: null\r\n}\r\n\r\nexport default Drawer\r\n","import isFunction from '../types/isFunction'\r\nimport off from './off'\r\n\r\nimport { CAPTURE_EVENTS } from './enum'\r\n\r\n/**\r\n * 绑定事件\r\n * ========================================================================\r\n * @method at\r\n * @param {HTMLElement|String|Object} el - (必须)绑定代理事件的 DOM 节点\r\n * @param {String|Function} type - (必须)事件类型或者事件处理器回调函数\r\n * @param {Function|Object} fn - (必须) 事件处理器回调函数或者传递给事件处理器回调函数的数据对象\r\n * @param {Object|Boolean} [data] - (可选)传递给事件处理器回调函数的数据对象或者事件处理器回调函数的 this 上下文指向,\r\n * @param {Object|Boolean} [context] - (可选)事件处理器回调函数的 this 上下文指向,或者是否仅触发一次\r\n * 当设置为 true 时,则事件处理器回调函数的 this 上下文指向为 data 对象\r\n * @param {Boolean} once - (可选)是否仅触发一次\r\n */\r\nconst at = (el, type, fn, data, context, once = false) => {\r\n // CAPTURE_EVENTS 中的特殊事件,采用事件捕获模型\r\n const capture = CAPTURE_EVENTS.indexOf(type) > -1\r\n const listener = function (evt) {\r\n let overrideContext = context || el\r\n\r\n // 当设置为 true 时,则事件处理器回调函数的\r\n // this 上下文指向为 data 对象\r\n if (context === true) {\r\n overrideContext = data\r\n }\r\n\r\n // 仅触发一次\r\n /* istanbul ignore else */\r\n if (once === true) {\r\n off(el, type, listener)\r\n }\r\n\r\n fn.call(overrideContext, evt, data)\r\n }\r\n\r\n if (!isFunction(fn)) {\r\n return false\r\n }\r\n\r\n if (!el._listeners) {\r\n el._listeners = []\r\n }\r\n\r\n // 缓存 options 元素绑定的事件处理器\r\n el._listeners.push({\r\n el,\r\n type,\r\n fn: listener,\r\n data,\r\n context,\r\n capture\r\n })\r\n\r\n // 缓存包装后的事件处理器\r\n fn._delegateListener = listener\r\n\r\n el.addEventListener(type, listener, capture)\r\n}\r\n\r\nexport default at\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isElement from './utils/types/isElement'\r\nimport later from './utils/lang/later'\r\nimport at from './utils/event/at'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport stop from './utils/event/stop'\r\nimport createElement from './utils/dom/createElement'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport addClass from './utils/dom/addClass'\r\nimport intersection from './utils/dom/intersection'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport offsetTop from './utils/dom/offsetTop'\r\nimport setProperty from './utils/dom/setProperty'\r\nimport publish from './utils/observer/emit'\r\n\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport _paintChapters from './_paintChapters'\r\n\r\nclass Chapters extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Chapters.DEFAULTS\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.closed = false\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.offsetWidth = 0\r\n this.$active = null\r\n this.scrollTimer = null\r\n this.resizeTimer = null\r\n this.playing = false\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n let parentElement\r\n let scrollElement\r\n let $parent\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n parentElement = this.attr('parentElement')\r\n scrollElement = this.attr('scrollElement')\r\n\r\n if (isString(parentElement)) {\r\n $parent = document.querySelector(parentElement)\r\n } else if (isElement(parentElement)) {\r\n $parent = parentElement\r\n }\r\n this.$parentElement = $parent\r\n this.$scrollElement = _getScrollElement(scrollElement)\r\n\r\n this.chapters = this.attr('chapters')\r\n this.closed = this.attr('closed')\r\n this.active = this.attr('active')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n if (this.chapters.length < 1) {\r\n return this\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n this.$active = document.querySelector(`#chapter-${this.active}`)\r\n\r\n return this\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n isSticky() {\r\n const position = this.attr('position')\r\n return position === 'sticky'\r\n }\r\n\r\n isFixed() {\r\n const position = this.attr('position')\r\n return position === 'fixed'\r\n }\r\n\r\n isInside() {\r\n return this.isFixed() || this.isSticky()\r\n }\r\n\r\n isOutside() {\r\n return !this.isInside()\r\n }\r\n\r\n _paintEdge() {\r\n const STICKY = 'outline-chapters_sticky'\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const title = this.attr('title')\r\n const customClass = this.attr('customClass')\r\n const $parentElement = this.$parentElement\r\n const contents = []\r\n let $title = null\r\n let $el\r\n let $main\r\n let $list\r\n let $placeholder\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n if (this.isInside()) {\r\n $title = createElement(\r\n 'h2',\r\n {\r\n className: 'outline-chapters__title'\r\n },\r\n [title]\r\n )\r\n this.$title = $title\r\n contents.push($title)\r\n }\r\n\r\n $list = createElement(\r\n 'ul',\r\n {\r\n // 为优化性能,添加了 _fixed 和 _hidden\r\n // fixed 为了让 $list 脱离流布局\r\n // hidden 让 $list 不可见\r\n className: `outline-chapters__list ${FIXED} ${HIDDEN}`\r\n },\r\n ['']\r\n )\r\n this.$list = $list\r\n\r\n $placeholder = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__placeholder'\r\n },\r\n ['']\r\n )\r\n this.$placeholder = $placeholder\r\n\r\n $main = createElement(\r\n 'div',\r\n {\r\n className: 'outline-chapters__main'\r\n },\r\n [$list, $placeholder]\r\n )\r\n this.$main = $main\r\n contents.push($main)\r\n\r\n $el = createElement(\r\n 'nav',\r\n {\r\n id: 'outline-chapters',\r\n className: 'outline-chapters'\r\n },\r\n contents\r\n )\r\n this.$el = $el\r\n\r\n if (this.isSticky()) {\r\n this.calculateStickyHeight()\r\n addClass($el, STICKY)\r\n }\r\n\r\n if (customClass) {\r\n addClass($el, customClass)\r\n }\r\n\r\n $parentElement.appendChild($el)\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const FIXED = 'outline-chapters_fixed'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const showCode = this.attr('showCode')\r\n const mounted = this.attr('mounted')\r\n const $parentElement = this.$parentElement\r\n let $el\r\n let $list\r\n\r\n if (!$parentElement) {\r\n return this\r\n }\r\n\r\n this._paintEdge()\r\n\r\n $list = this.$list\r\n _paintChapters($list, this.chapters, showCode)\r\n removeClass($list, FIXED)\r\n removeClass($list, HIDDEN)\r\n\r\n $el = this.$el\r\n this.offsetTop = offsetTop($el)\r\n this.offsetWidth = $el.offsetWidth\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n setProperty('--outline-chapters-width', `${this.offsetWidth}px`)\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n this.onObserver()\r\n\r\n return this\r\n }\r\n\r\n highlight(id) {\r\n const $anchor = this.$el.querySelector(`#chapter__anchor-${id}`)\r\n const HIGHLIGHT = 'outline-chapters_active'\r\n const $placeholder = this.$placeholder\r\n let top\r\n\r\n if (this.$active) {\r\n removeClass(this.$active, HIGHLIGHT)\r\n }\r\n\r\n this.active = parseInt($anchor.getAttribute('data-id'), 10)\r\n this.$active = $anchor\r\n addClass(this.$active, HIGHLIGHT)\r\n\r\n top = 30 * this.active\r\n $placeholder.style.top = `calc(0.5em + ${top}px)`\r\n\r\n return this\r\n }\r\n\r\n sticky() {\r\n const afterSticky = this.attr('afterSticky')\r\n const FIXED = 'outline-chapters_fixed'\r\n const $el = this.$el\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (!this.isFixed()) {\r\n return this\r\n }\r\n\r\n isStickying = !!(scrollTop >= top)\r\n\r\n if (isStickying) {\r\n addClass($el, FIXED)\r\n } else {\r\n removeClass($el, FIXED)\r\n }\r\n\r\n if (isFunction(afterSticky)) {\r\n afterSticky.call(this, this.isClosed(), isStickying)\r\n }\r\n\r\n return this\r\n }\r\n\r\n calculateStickyHeight() {\r\n const documentElement = document.documentElement\r\n const height = Math.max(\r\n documentElement.clientHeight || 0,\r\n window.innerHeight || 0\r\n )\r\n setProperty('--outline-sticky-height', `${height}px`)\r\n return this\r\n }\r\n\r\n scrollTo(top, after) {\r\n const el = this.$scrollElement\r\n\r\n scrollTo(el, top, after)\r\n\r\n return this\r\n }\r\n\r\n show() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const opened = this.attr('afterOpened')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n removeClass($parent, HIDDEN)\r\n removeClass($el, HIDDEN)\r\n later(() => {\r\n removeClass($parent, FOLDED)\r\n removeClass($el, FOLDED)\r\n }, 30)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n }\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n opened.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide() {\r\n const FOLDED = 'outline-chapters_folded'\r\n const HIDDEN = 'outline-chapters_hidden'\r\n const closed = this.attr('afterClosed')\r\n const $el = this.$el\r\n const $parent = this.$parentElement\r\n\r\n if (this.isInside()) {\r\n addClass($parent, FOLDED)\r\n addClass($el, FOLDED)\r\n later(() => {\r\n addClass($parent, HIDDEN)\r\n addClass($el, HIDDEN)\r\n })\r\n } else {\r\n addClass($el, HIDDEN)\r\n }\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n closed.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n const afterToggle = this.attr('afterToggle')\r\n const top = this.offsetTop\r\n const scrollTop = this.$scrollElement.scrollTop\r\n let isStickying\r\n\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n if (isFunction(afterToggle)) {\r\n later(() => {\r\n isStickying = !!(scrollTop >= top)\r\n afterToggle.call(this, this.isClosed(), isStickying)\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n this.$parentElement.removeChild(this.$el)\r\n\r\n this.attr(Chapters.DEFAULTS)\r\n this.$el = null\r\n this.$title = null\r\n this.$main = null\r\n this.$list = null\r\n this.$placeholder = null\r\n this.$parentElement = null\r\n this.$scrollElement = null\r\n this.chapters = []\r\n this.active = 0\r\n this.offsetTop = 0\r\n this.$active = null\r\n this.closed = false\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n this.scrollTimer = null\r\n }\r\n\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n this.resizeTimer = null\r\n }\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n onObserver() {\r\n let timer = null\r\n\r\n intersection(\r\n ($heading) => {\r\n const id = $heading.getAttribute('data-id')\r\n\r\n if (this.playing) {\r\n return false\r\n }\r\n\r\n if (timer) {\r\n clearTimeout(timer)\r\n }\r\n\r\n timer = later(() => {\r\n this.highlight(id)\r\n }, 100)\r\n },\r\n { context: this }\r\n )\r\n\r\n return this\r\n }\r\n\r\n onSelect(evt) {\r\n const stickyHeight = this.attr('stickyHeight')\r\n const $anchor = evt.delegateTarget\r\n const id = $anchor.getAttribute('data-id')\r\n const headingId = $anchor.href.split('#')[1]\r\n const $heading = document.querySelector(`#${headingId}`)\r\n const top = offsetTop($heading) - (stickyHeight + 10)\r\n const min = 0\r\n const max = this.$scrollElement.scrollHeight\r\n const afterScroll = this.attr('afterScroll')\r\n const after = () => {\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(this, 'chapter')\r\n }\r\n\r\n later(() => {\r\n this.playing = false\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n })\r\n }\r\n\r\n this.playing = true\r\n if (this.isFixed()) {\r\n this.sticky()\r\n later(() => {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }, 10)\r\n } else {\r\n this.scrollTo(top, after)\r\n this.highlight(id)\r\n }\r\n\r\n stop(evt)\r\n\r\n return this\r\n }\r\n\r\n onScroll() {\r\n const $scrollElement = this.$scrollElement\r\n\r\n if (this.scrollTimer) {\r\n clearTimeout(this.scrollTimer)\r\n }\r\n\r\n this.scrollTimer = later(() => {\r\n const top = $scrollElement.scrollTop\r\n const min = 0\r\n const max = $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n\r\n if (this.isFixed()) {\r\n this.sticky()\r\n }\r\n\r\n publish('toolbar:update', {\r\n top,\r\n min,\r\n max\r\n })\r\n }, 50)\r\n\r\n return this\r\n }\r\n\r\n onResize() {\r\n if (this.resizeTimer) {\r\n clearTimeout(this.resizeTimer)\r\n }\r\n\r\n this.resizeTimer = later(() => {\r\n this.calculateStickyHeight()\r\n })\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n on($el, '.outline-chapters__anchor', 'click', this.onSelect, this, true)\r\n at($element, 'scroll', this.onScroll, this, true)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize, this, true)\r\n }\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const $el = this.$el\r\n const $scrollElement = this.$scrollElement\r\n const tagName = $scrollElement.tagName.toLowerCase()\r\n let $element = $scrollElement\r\n\r\n if (tagName === 'html' || tagName === 'body') {\r\n $element = window\r\n }\r\n\r\n off($el, 'click', this.onSelect)\r\n off($element, 'scroll', this.onScroll)\r\n if (this.isSticky()) {\r\n at($element, 'resize', this.onResize)\r\n }\r\n\r\n return this\r\n }\r\n}\r\n\r\nChapters.DEFAULTS = {\r\n parentElement: '',\r\n scrollElement: '',\r\n selector: '',\r\n active: 0,\r\n closed: false,\r\n showCode: true,\r\n position: 'relative',\r\n stickyHeight: 0,\r\n chapters: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterScroll: null,\r\n beforeDestroy: null,\r\n afterDestroy: null,\r\n afterSticky: null\r\n}\r\n\r\nexport default Chapters\r\n","import createElement from './utils/dom/createElement'\r\n\r\nconst _paintChapters = ($list, chapters, showCode = false) => {\r\n const byId = (id) => document.getElementById(id)\r\n\r\n chapters.forEach((chapter) => {\r\n const pid = chapter.pid\r\n const id = chapter.id\r\n const rel = chapter.rel\r\n const $text = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__text'\r\n },\r\n [chapter.text]\r\n )\r\n const $link = createElement(\r\n 'a',\r\n {\r\n id: `chapter__anchor-${id}`,\r\n className: 'outline-chapters__anchor',\r\n href: '#' + rel,\r\n rel: rel,\r\n 'data-id': id\r\n },\r\n [$text]\r\n )\r\n let $code\r\n let $li\r\n let $ul\r\n let $parent\r\n\r\n if (showCode) {\r\n $code = createElement(\r\n 'span',\r\n {\r\n className: 'outline-chapters__code',\r\n 'data-id': id\r\n },\r\n [chapter.code]\r\n )\r\n\r\n $link.insertBefore($code, $link.firstChild)\r\n }\r\n\r\n $li = createElement(\r\n 'li',\r\n {\r\n id: `chapter-${id}`,\r\n className: 'outline-chapters__item',\r\n 'data-id': id\r\n },\r\n [$link]\r\n )\r\n\r\n if (pid === -1) {\r\n $list.appendChild($li)\r\n } else {\r\n $parent = byId(`chapter-${pid}`)\r\n $ul = byId(`subject-${pid}`)\r\n\r\n if (!$ul) {\r\n $ul = createElement(\r\n 'ul',\r\n {\r\n id: 'subject-' + pid,\r\n className: 'outline-chapters__subject'\r\n },\r\n [$li]\r\n )\r\n\r\n $parent.appendChild($ul)\r\n } else {\r\n $ul.appendChild($li)\r\n }\r\n }\r\n })\r\n}\r\n\r\nexport default _paintChapters\r\n","import isFunction from '../types/isFunction'\r\nimport isElement from '../types/isElement'\r\n\r\n/**\r\n * 通用的 IntersectionObserver 观察者处理器\r\n * ========================================================================\r\n * @method intersection\r\n * @param {Function} fn\r\n * @param {Object} [props]\r\n * @param {Object|HTMLElement} [props.root]\r\n * @param {String} [props.selector]\r\n * @param {Object} [props.context]\r\n * @param {String} [props.attr]\r\n * @param {String} [props.rootMargin]\r\n */\r\nconst intersection = (fn, props = {}) => {\r\n const root = props.root || null\r\n const selector = props.selector || '.outline-heading'\r\n const context = props.context || null\r\n const rootMargin = props.rootMargin || '0px 0px -90% 0px'\r\n const options = {\r\n rootMargin: rootMargin\r\n }\r\n const Observer = new IntersectionObserver((entries) => {\r\n entries.forEach((entry) => {\r\n if (entry.intersectionRatio > 0) {\r\n if (isFunction(fn)) {\r\n fn.call(context || entry.target, entry.target)\r\n }\r\n }\r\n })\r\n }, options)\r\n const $root = isElement(root) ? root : document\r\n\r\n if (root) {\r\n options.root = root\r\n }\r\n\r\n $root.querySelectorAll(selector).forEach((section) => {\r\n Observer.observe(section)\r\n })\r\n}\r\n\r\nexport default intersection\r\n","import { createSvgIcon } from './utils/icons'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\n\r\nconst _createButton = (button, rounded = true) => {\r\n const $icon = createSvgIcon(button.icon, button.size)\r\n const $anchor = createElement(\r\n 'a',\r\n {\r\n className: `outline-toolbar__anchor`,\r\n href: button.link\r\n },\r\n [$icon]\r\n )\r\n const $button = createElement(\r\n 'div',\r\n {\r\n className: `outline-toolbar__button ${button.name}`\r\n },\r\n [button.link ? $anchor : $icon]\r\n )\r\n\r\n addClass($icon, 'outline-toolbar__icon')\r\n\r\n if (rounded) {\r\n addClass($button, 'outline-toolbar_rounded')\r\n }\r\n\r\n if (button.disabled) {\r\n addClass($button, 'outline-toolbar_disabled')\r\n }\r\n\r\n return $button\r\n}\r\n\r\nexport default _createButton\r\n","import Base from './base'\r\n\r\nimport isString from './utils/types/isString'\r\nimport isFunction from './utils/types/isFunction'\r\nimport isObject from './utils/types/isObject'\r\nimport isArray from './utils/types/isArray'\r\nimport later from './utils/lang/later'\r\nimport createElement from './utils/dom/createElement'\r\nimport addClass from './utils/dom/addClass'\r\nimport hasClass from './utils/dom/hasClass'\r\nimport removeClass from './utils/dom/removeClass'\r\nimport on from './utils/event/on'\r\nimport off from './utils/event/off'\r\nimport publish from './utils/observer/emit'\r\nimport { paintSvgSprites } from './utils/icons'\r\n\r\nimport _createButton from './_createButton'\r\n\r\nconst DISABLED = 'outline-toolbar_disabled'\r\nconst HIDDEN = 'outline-toolbar_hidden'\r\n\r\nclass Toolbar extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Toolbar.DEFAULTS\r\n this.$el = null\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n let created\r\n\r\n this.attr(options)\r\n created = this.attr('created')\r\n this.disabled = this.attr('disabled')\r\n this.closed = this.attr('closed')\r\n\r\n if (isFunction(created)) {\r\n created.call(this)\r\n }\r\n\r\n this.render().addListeners()\r\n\r\n return this\r\n }\r\n\r\n isDisabled(name) {\r\n const buttons = this.attr('buttons')\r\n let button\r\n\r\n if (name) {\r\n button = buttons.find((option) => option.name === name)\r\n\r\n return !!(button && button.disabled)\r\n }\r\n\r\n return this.disabled\r\n }\r\n\r\n isClosed() {\r\n return this.closed\r\n }\r\n\r\n highlight(name) {\r\n const button = this.buttons.find((item) => item.name === name)\r\n const ACTIVE = 'outline-toolbar_active'\r\n let $button\r\n\r\n if ($button) {\r\n return this\r\n }\r\n\r\n $button = button.$el\r\n\r\n if (hasClass($button, ACTIVE)) {\r\n removeClass($button, ACTIVE)\r\n } else {\r\n addClass($button, ACTIVE)\r\n }\r\n\r\n return this\r\n }\r\n\r\n render() {\r\n const mounted = this.attr('mounted')\r\n const buttons = this.attr('buttons') || []\r\n const rounded = this.attr('rounded')\r\n const placement = this.attr('placement')\r\n const $buttons = document.createDocumentFragment()\r\n const $fragment = document.createDocumentFragment()\r\n\r\n paintSvgSprites()\r\n\r\n buttons.forEach((button) => {\r\n const $button = _createButton(button, rounded)\r\n\r\n $buttons.appendChild($button)\r\n this.buttons.push({\r\n name: button.name,\r\n $el: $button\r\n })\r\n })\r\n\r\n this.$el = createElement(\r\n 'div',\r\n {\r\n id: 'outline-toolbar',\r\n className: `outline-toolbar outline-toolbar_${placement}`\r\n },\r\n [$buttons]\r\n )\r\n $fragment.appendChild(this.$el)\r\n document.body.appendChild($fragment)\r\n\r\n if (this.closed) {\r\n this.hide()\r\n }\r\n\r\n if (this.disabled) {\r\n this.disable()\r\n }\r\n\r\n if (isFunction(mounted)) {\r\n mounted.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n add(button) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const action = button.action\r\n const $fragment = document.createDocumentFragment()\r\n let type\r\n\r\n if (isObject(button)) {\r\n buttons.push(button)\r\n $fragment.appendChild(_createButton(button))\r\n } else if (isArray(button)) {\r\n button.forEach((item) => {\r\n $fragment.appendChild(_createButton(item))\r\n })\r\n }\r\n $el.appendChild($fragment)\r\n\r\n if (action && isFunction(action.handler)) {\r\n type = action.type || 'click'\r\n on($el, `.${button.name}`, type, action.handler)\r\n }\r\n\r\n return this\r\n }\r\n\r\n remove(name) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let index = -1\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button, i) => {\r\n if (button.name === name) {\r\n index = i\r\n }\r\n })\r\n\r\n if (index > -1) {\r\n this.attr().buttons.splice(index, 1)\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n this.switch(name, false)\r\n $el.removeChild($button)\r\n\r\n return this\r\n }\r\n\r\n switch(name, enabled) {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons')\r\n const button = buttons.find((option) => option.name === name)\r\n let action\r\n let type\r\n let listener\r\n let $button\r\n\r\n if (!button) {\r\n return this\r\n }\r\n\r\n buttons.forEach((option) => {\r\n if (option.name === name) {\r\n button.disabled = !enabled\r\n }\r\n })\r\n\r\n action = button.action\r\n $button = $el.querySelector(`.${name}`)\r\n\r\n if (action) {\r\n type = action.type || 'click'\r\n listener = action.handler\r\n }\r\n\r\n if (enabled) {\r\n removeClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n on($el, `.${name}`, type, listener)\r\n }\r\n } else {\r\n addClass($button, DISABLED)\r\n\r\n if (type && listener) {\r\n off($el, type, listener)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n disable(name) {\r\n const disabled = this.attr('afterDisabled')\r\n\r\n if (name) {\r\n this.switch(name, false)\r\n } else {\r\n addClass(this.$el, DISABLED)\r\n this.removeListeners()\r\n this.disabled = true\r\n\r\n if (isFunction(disabled)) {\r\n disabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n enable(name) {\r\n const enabled = this.attr('afterEnabled')\r\n\r\n if (name) {\r\n this.switch(name, true)\r\n } else {\r\n this.disabled = false\r\n removeClass(this.$el, DISABLED)\r\n this.addListeners()\r\n\r\n if (isFunction(enabled)) {\r\n enabled.call(this)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n show(name) {\r\n const opened = this.attr('afterOpened')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n\r\n $button = $el.querySelector(`.${name}`)\r\n removeClass($button, HIDDEN)\r\n } else {\r\n removeClass($el, HIDDEN)\r\n this.closed = false\r\n\r\n if (isFunction(opened)) {\r\n later(() => {\r\n opened.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n hide(name) {\r\n const closed = this.attr('afterClosed')\r\n const button = this.attr('buttons').find((option) => option.name === name)\r\n const $el = this.$el\r\n let $button\r\n\r\n if (name) {\r\n if (!button) {\r\n return this\r\n }\r\n $button = $el.querySelector(`.${name}`)\r\n addClass($button, HIDDEN)\r\n } else {\r\n addClass($el, HIDDEN)\r\n this.closed = true\r\n\r\n if (isFunction(closed)) {\r\n later(() => {\r\n closed.call(this)\r\n }, 310)\r\n }\r\n }\r\n\r\n return this\r\n }\r\n\r\n toggle() {\r\n if (this.isClosed()) {\r\n this.show()\r\n } else {\r\n this.hide()\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const beforeDestroy = this.attr('beforeDestroy')\r\n const afterDestroy = this.attr('afterDestroy')\r\n let $el = this.$el\r\n\r\n if (isFunction(beforeDestroy)) {\r\n beforeDestroy.call(this)\r\n }\r\n\r\n this.removeListeners()\r\n document.body.removeChild($el)\r\n $el = null\r\n\r\n this.attr(Toolbar.DEFAULTS)\r\n this.disabled = false\r\n this.closed = false\r\n this.buttons = []\r\n\r\n if (isFunction(afterDestroy)) {\r\n afterDestroy.call(this)\r\n }\r\n\r\n return this\r\n }\r\n\r\n refresh() {\r\n const $el = this.$el\r\n const buttons = this.attr('buttons') || []\r\n\r\n this.removeListeners()\r\n $el.innerHTML = ''\r\n\r\n buttons.forEach((button) => {\r\n this.$el.appendChild(_createButton(button))\r\n })\r\n\r\n this.addListeners()\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n let context\r\n let command\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n if (isString(listener)) {\r\n command = listener\r\n action.handler = function () {\r\n publish(command, button.name)\r\n }\r\n listener = action.handler\r\n }\r\n\r\n type = action.type || 'click'\r\n context = action.context\r\n }\r\n\r\n if (isFunction(listener)) {\r\n on($el, `.${button.name}`, type, listener, context || this, true)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n const buttons = this.attr('buttons')\r\n const $el = this.$el\r\n\r\n if (!buttons || buttons.length < 1) {\r\n return this\r\n }\r\n\r\n buttons.forEach((button) => {\r\n const action = button.action\r\n const disabled = this.disabled\r\n let type\r\n let listener\r\n\r\n if (disabled) {\r\n return false\r\n }\r\n\r\n if (action) {\r\n listener = action.handler\r\n type = action.type || 'click'\r\n }\r\n\r\n if (isFunction(listener)) {\r\n off($el, type, listener)\r\n }\r\n })\r\n\r\n return this\r\n }\r\n}\r\n\r\nToolbar.DEFAULTS = {\r\n placement: 'ltr',\r\n closed: false,\r\n disabled: false,\r\n rounded: true,\r\n buttons: [],\r\n created: null,\r\n mounted: null,\r\n afterClosed: null,\r\n afterOpened: null,\r\n afterDisabled: null,\r\n afterEnabled: null,\r\n beforeDestroy: null,\r\n afterDestroy: null\r\n}\r\n\r\nexport default Toolbar\r\n","/**\r\n * 生成唯一 id 字符串的函数\r\n * ========================================================================\r\n * @method guid\r\n * @param {String} [prefix] - 生成 id 的前缀字符串\r\n * @return {String} 返回一个表示唯一 id 的字符串\r\n */\r\nconst guid = (() => {\r\n let uuid = 0\r\n\r\n return (prefix) => {\r\n uuid += 1\r\n\r\n return prefix ? prefix + '-' + uuid : 'guid-' + uuid\r\n }\r\n})()\r\n\r\nexport default guid\r\n","import _subscribers from './_subscribers'\r\nimport isFunction from '../types/isFunction'\r\nimport guid from '../lang/guid'\r\n\r\n/**\r\n * 订阅主题,并给出处理器函数\r\n * ========================================================================\r\n * @method on\r\n * @param {String} topic - (必须)主题名称\r\n * @param {Function} handler - (必须)主题的处理器函数\r\n * @param {Object} [context] - (可选)指定 this 执行上下文\r\n * @return {String|Boolean} - 唯一的 token 字符串,例如:'guid-1'。\r\n */\r\nconst on = (topic, handler, context = null) => {\r\n const token = guid()\r\n let subject = typeof topic === 'symbol' ? topic.toString() : topic\r\n\r\n if (!isFunction(handler)) {\r\n return false\r\n }\r\n\r\n /* istanbul ignore else */\r\n if (!_subscribers[subject]) {\r\n _subscribers[subject] = []\r\n }\r\n\r\n _subscribers[subject].push({\r\n topic: subject,\r\n callback: handler,\r\n context,\r\n token\r\n })\r\n\r\n return token\r\n}\r\n\r\nexport default on\r\n","import _subscribers from './_subscribers'\r\nimport hasOwn from '../lang/hasOwn'\r\n\r\n/**\r\n * 删除与给定 topic 相同的订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriber\r\n * @param {String} topic - (必须)订阅主题字符串\r\n * @returns {Boolean}\r\n */\r\nconst _removeSubscriber = (topic) => {\r\n if (!hasOwn(_subscribers, topic)) {\r\n return false\r\n }\r\n\r\n delete _subscribers[topic]\r\n}\r\n\r\nexport default _removeSubscriber\r\n","import has from './has'\r\nimport _removeSubscriber from './_removeSubscriber'\r\nimport _removeSubscriberByToken from './_removeSubscriberByToken'\r\n\r\n/**\r\n * 取消订阅主题\r\n * ========================================================================\r\n * @method off\r\n * @param {String} topic - (必须)订阅的主题\r\n * @param {Function|String} [token] - (可选)订阅主题的处理器函数或者唯一 Id 值\r\n */\r\nconst off = (topic, token) => {\r\n if (!has(topic)) {\r\n return false\r\n }\r\n\r\n if (token) {\r\n _removeSubscriberByToken(token)\r\n } else {\r\n _removeSubscriber(topic)\r\n }\r\n}\r\n\r\nexport default off\r\n","import _subscribers from './_subscribers'\r\nimport _removeSubscriber from './_removeSubscriber'\r\n\r\n/**\r\n * 通过订阅者 token 值删除订阅者信息\r\n * ========================================================================\r\n * @method _removeSubscriberByToken\r\n * @param {String} token - 订阅者 token 字符串\r\n * @returns {boolean}\r\n * @private\r\n */\r\nconst _removeSubscriberByToken = (token) => {\r\n const keys = Object.keys(_subscribers)\r\n let index = -1\r\n\r\n if (!token || keys.length < 1) {\r\n return false\r\n }\r\n\r\n keys.forEach((subject) => {\r\n const subscriber = _subscribers[subject]\r\n let topic\r\n\r\n subscriber.forEach((execution, j) => {\r\n if (execution.callback === token || execution.token === token) {\r\n topic = execution.topic\r\n subscriber.splice(index, j)\r\n }\r\n })\r\n\r\n /* istanbul ignore else */\r\n if (subscriber.length < 1) {\r\n _removeSubscriber(topic)\r\n }\r\n })\r\n}\r\n\r\nexport default _removeSubscriberByToken\r\n","import Base from './base'\r\nimport Anchors from './anchors'\r\nimport Drawer from './drawer'\r\nimport Chapters from './chapters'\r\nimport Toolbar from './toolbar'\r\n\r\nimport later from './utils/lang/later'\r\nimport isFunction from './utils/types/isFunction'\r\nimport scrollTo from './utils/dom/scrollTo'\r\nimport _getScrollElement from './utils/dom/_getScrollElement'\r\nimport subscribe from './utils/observer/on'\r\nimport unsubscribe from './utils/observer/off'\r\n\r\nclass Outline extends Base {\r\n constructor(options) {\r\n super()\r\n\r\n this.attrs = Outline.DEFAULTS\r\n this.anchors = null\r\n this.drawer = null\r\n this.chapters = null\r\n this.toolbar = null\r\n\r\n if (options) {\r\n this.initialize(options)\r\n }\r\n }\r\n\r\n initialize(options) {\r\n this.attr(options).render().addListeners()\r\n return this\r\n }\r\n\r\n getChapters(isTreeStructured = false) {\r\n return this.anchors.getChapters(isTreeStructured)\r\n }\r\n\r\n count() {\r\n return this.anchors.count()\r\n }\r\n\r\n render() {\r\n this._renderAnchors()._renderChapters()._renderToolbar()\r\n\r\n return this\r\n }\r\n\r\n _renderAnchors() {\r\n const articleElement = this.attr('articleElement')\r\n const selector = this.attr('selector')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const showCode = this.attr('showCode')\r\n const anchorURL = this.attr('anchorURL')\r\n const afterScroll = this.attr('afterScroll')\r\n\r\n this.anchors = new Anchors({\r\n articleElement,\r\n stickyHeight,\r\n scrollElement,\r\n selector,\r\n showCode,\r\n anchorURL,\r\n afterScroll\r\n })\r\n\r\n return this\r\n }\r\n\r\n _renderChapters() {\r\n const title = this.attr('title')\r\n const stickyHeight = this.attr('stickyHeight')\r\n const scrollElement = this.attr('scrollElement')\r\n const customClass = this.attr('customClass')\r\n const showCode = this.attr('showCode')\r\n const position = this.attr('position')\r\n const placement = this.attr('placement')\r\n const afterSticky = this.attr('afterSticky')\r\n const afterToggle = this.attr('afterToggle')\r\n const afterScroll = this.attr('afterScroll')\r\n const count = this.count()\r\n let parentElement = this.attr('parentElement')\r\n let CHAPTERS_OPTIONS\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n CHAPTERS_OPTIONS = {\r\n scrollElement,\r\n showCode,\r\n position,\r\n title,\r\n stickyHeight,\r\n chapters: this.anchors.getChapters(),\r\n afterSticky,\r\n afterToggle,\r\n afterScroll\r\n }\r\n\r\n if (position === 'relative') {\r\n this.drawer = new Drawer({\r\n placement,\r\n title,\r\n size: 'tiny',\r\n hasOffset: true,\r\n hasPadding: false,\r\n customClass,\r\n afterClosed: () => {\r\n const toolbar = this.toolbar\r\n toolbar.toggle()\r\n }\r\n })\r\n parentElement = this.drawer.$main\r\n } else {\r\n CHAPTERS_OPTIONS.customClass = customClass\r\n }\r\n\r\n CHAPTERS_OPTIONS.parentElement = parentElement\r\n this.chapters = new Chapters(CHAPTERS_OPTIONS)\r\n\r\n return this\r\n }\r\n\r\n _renderToolbar() {\r\n const placement = this.attr('placement')\r\n const homepage = this.attr('homepage')\r\n const count = this.count()\r\n const UP = {\r\n name: 'up',\r\n icon: 'up',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:up'\r\n }\r\n }\r\n const HOME = {\r\n name: 'homepage',\r\n icon: 'homepage',\r\n size: 20,\r\n link: homepage\r\n }\r\n const MENU = {\r\n name: 'menu',\r\n icon: 'menu',\r\n size: 18,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:toggle'\r\n }\r\n }\r\n const DOWN = {\r\n name: 'down',\r\n icon: 'down',\r\n size: 20,\r\n action: {\r\n type: 'click',\r\n handler: 'toolbar:action:down'\r\n }\r\n }\r\n const buttons = []\r\n\r\n buttons.push(UP)\r\n if (homepage) {\r\n buttons.push(HOME)\r\n }\r\n if (count > 0) {\r\n buttons.push(MENU)\r\n }\r\n buttons.push(DOWN)\r\n\r\n this.toolbar = new Toolbar({\r\n placement,\r\n buttons: buttons\r\n })\r\n\r\n return this\r\n }\r\n\r\n toTop() {\r\n const afterScroll = this.attr('afterScroll')\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const afterTop = () => {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n\r\n if (count > 0) {\r\n chapters.highlight(0)\r\n }\r\n chapters.playing = false\r\n\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(toolbar, 'up')\r\n }\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(0, afterTop)\r\n\r\n return this\r\n }\r\n\r\n toBottom() {\r\n const afterScroll = this.attr('afterScroll')\r\n const $scrollElement = _getScrollElement(this.attr('scrollElement'))\r\n const toolbar = this.toolbar\r\n const chapters = this.chapters\r\n const count = this.count()\r\n const top = Math.floor(\r\n $scrollElement.scrollHeight - $scrollElement.clientHeight\r\n )\r\n const afterDown = () => {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n\r\n if (count > 1) {\r\n chapters.highlight(count - 1)\r\n }\r\n chapters.playing = false\r\n\r\n if (isFunction(afterScroll)) {\r\n afterScroll.call(toolbar, 'bottom')\r\n }\r\n }\r\n\r\n chapters.playing = true\r\n this.scrollTo(top, afterDown)\r\n\r\n return this\r\n }\r\n\r\n scrollTo(top, afterScroll) {\r\n const scrollElement = this.attr('scrollElement')\r\n scrollTo(scrollElement, top, afterScroll)\r\n return this\r\n }\r\n\r\n toggle() {\r\n const position = this.attr('position')\r\n const toolbar = this.toolbar\r\n const drawer = this.drawer\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n if (position !== 'relative') {\r\n chapters.toggle()\r\n toolbar.highlight('menu')\r\n } else {\r\n toolbar.toggle()\r\n\r\n if (count < 1) {\r\n return this\r\n }\r\n\r\n later(() => {\r\n if (chapters.isInside()) {\r\n chapters.toggle()\r\n } else {\r\n drawer.toggle()\r\n }\r\n })\r\n }\r\n\r\n return this\r\n }\r\n\r\n destroy() {\r\n const chapters = this.chapters\r\n const count = this.count()\r\n\r\n this.removeListeners()\r\n\r\n this.attr(Outline.DEFAULTS)\r\n this.anchors.destroy()\r\n if (count < 1) {\r\n chapters.destroy()\r\n if (chapters.isOutside()) {\r\n this.drawer.destroy()\r\n }\r\n }\r\n this.toolbar.destroy()\r\n\r\n return this\r\n }\r\n\r\n onToggle() {\r\n this.toggle()\r\n return this\r\n }\r\n\r\n onScrollTop() {\r\n this.toTop()\r\n return this\r\n }\r\n\r\n onScrollBottom() {\r\n this.toBottom()\r\n return this\r\n }\r\n\r\n onToolbarUpdate({ top, min, max }) {\r\n const toolbar = this.toolbar\r\n const current = Math.ceil(top)\r\n\r\n if (current <= min) {\r\n toolbar.hide('up')\r\n toolbar.show('down')\r\n } else if (current >= max) {\r\n toolbar.hide('down')\r\n toolbar.show('up')\r\n } else if (current > min && current < max) {\r\n toolbar.show('up')\r\n toolbar.show('down')\r\n }\r\n\r\n return this\r\n }\r\n\r\n addListeners() {\r\n subscribe('toolbar:update', this.onToolbarUpdate, this)\r\n subscribe('toolbar:action:up', this.onScrollTop, this)\r\n subscribe('toolbar:action:toggle', this.onToggle, this)\r\n subscribe('toolbar:action:down', this.onScrollBottom, this)\r\n return this\r\n }\r\n\r\n removeListeners() {\r\n unsubscribe('toolbar:update')\r\n unsubscribe('toolbar:action:up')\r\n unsubscribe('toolbar:action:toggle')\r\n unsubscribe('toolbar:action:down')\r\n return this\r\n }\r\n}\r\n\r\nOutline.DEFAULTS = {\r\n articleElement: '#article',\r\n selector: 'h2,h3,h4,h5,h6',\r\n title: '目录',\r\n scrollElement: 'html,body',\r\n position: 'relative',\r\n parentElement: '#aside',\r\n placement: 'rtl',\r\n showCode: true,\r\n anchorURL: '',\r\n stickyHeight: 0,\r\n customClass: '',\r\n afterSticky: null,\r\n afterToggle: null,\r\n afterScroll: null\r\n}\r\n\r\nif (window.jQuery) {\r\n // 将 Outline 扩展为一个 jquery 插件\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend(jQuery.fn, {\r\n outline: function (options) {\r\n // eslint-disable-next-line no-undef\r\n let $article = jQuery(this)\r\n\r\n return new Outline(\r\n // eslint-disable-next-line no-undef\r\n jQuery.extend({}, options, {\r\n articleElement: $article\r\n })\r\n )\r\n }\r\n })\r\n}\r\n\r\nexport default Outline\r\n"],"names":["isString","str","hasOwn","obj","prop","hasOwnProperty","Object","prototype","call","toString","val","apply","isFunction","isObject","o","Base","constructor","options","this","attrs","initialize","attr","render","addListeners","value","origin","source","keys","forEach","arguments","length","destroy","removeListeners","reload","isElement","nodeName","tagName","nodeType","later","fn","delay","setTimeout","easeInQuad","x","_getScrollElement","scrollElement","$rootElements","$scrollElement","document","querySelector","querySelectorAll","scrollTop","scrollTo","top","afterStop","step","distance","MAX_HEIGHT","scrollHeight","MAX_TOP","stop","play","requestAnimationFrame","offsetTop","el","offsetParent","matches","selector","sel","replace","msMatchesSelector","getParentOrHost","host","parentNode","CAPTURE_EVENTS","_off","type","capture","indexOf","_delegateListener","listeners","_listeners","index","listener","i","handler","splice","_delete","removeEventListener","purgeElement","recurse","$element","$children","childNodes","filter","getListeners","$child","off","on","data","context","once","evt","target","getTarget","delegateTarget","ctx","includeCTX","closest","overrideContext","push","addEventListener","stopPropagation","preventDefault","_subscribers","_hasDirectSubscribersFor","topic","has","isDirect","found","position","lastIndexOf","substring","_hasSubscribers","emit","async","execute","subscriber","message","callback","deliver","isArray","Array","paintSvgSprites","symbols","SYMBOLS","sprites","concat","$body","body","$icons","innerHTML","join","createElement","insertBefore","firstChild","createSvgIcon","name","size","color","iconSet","binds","width","height","defaultRules","svg","$icon","className","trim","isDOM","isHTMLCollection","fragment","isTextNode","setAttribute","toLowerCase","style","cssText","children","$fragment","createDocumentFragment","$el","isValidChild","child","append","createTextNode","appendChild","every","hasClass","pattern","RegExp","allClass","classList","contains","match","removeClass","remove","_resetHeading","$heading","hasAnchor","isAtStart","CLS_HEADING","text","$anchor","removeAttribute","removeChild","getChapters","headings","showCode","chapters","previous","level","heading","headingLevel","current","parseInt","pid","differ","_getChapterParentIdByDiffer","id","rel","groups","group","JSON","stringify","cb","code","String","c","_getChaptersWithCode","Anchors","super","DEFAULTS","$articleElement","$headings","created","articleElement","isTreeStructured","list","nodeKey","parentKey","map","roots","item","node","toTree","count","mounted","anchorURL","chapterCode","headingId","href","_updateHeading","after","beforeDestroy","afterDestroy","onAnchorTrigger","afterScroll","stickyHeight","max","clientHeight","publish","min","addClass","add","setProperty","documentElement","zIndex","idx","Drawer","title","closed","$modal","$header","$title","$close","$main","$footer","$overlay","setTitle","isClosed","placement","hasClose","hasOverlay","hasOffset","hasPadding","autoHeight","customClass","open","opened","close","toggle","afterToggle","onClose","afterClosed","afterOpened","at","Chapters","$list","$placeholder","$parentElement","active","offsetWidth","$active","scrollTimer","resizeTimer","playing","parentElement","$parent","isSticky","isFixed","isInside","isOutside","_paintEdge","contents","calculateStickyHeight","byId","getElementById","chapter","$text","$link","$code","$li","$ul","_paintChapters","sticky","onObserver","highlight","HIGHLIGHT","getAttribute","afterSticky","FIXED","isStickying","Math","window","innerHeight","show","FOLDED","HIDDEN","hide","clearTimeout","timer","props","root","rootMargin","Observer","IntersectionObserver","entries","entry","intersectionRatio","$root","section","observe","intersection","onSelect","split","onScroll","onResize","_createButton","button","rounded","icon","link","$button","disabled","DISABLED","Toolbar","buttons","isDisabled","find","option","ACTIVE","$buttons","disable","action","switch","enabled","enable","refresh","command","afterDisabled","afterEnabled","guid","uuid","prefix","token","subject","_removeSubscriber","execution","j","_removeSubscriberByToken","Outline","anchors","drawer","toolbar","_renderAnchors","_renderChapters","_renderToolbar","CHAPTERS_OPTIONS","homepage","HOME","MENU","toTop","toBottom","floor","onToggle","onScrollTop","onScrollBottom","onToolbarUpdate","ceil","subscribe","unsubscribe","jQuery","extend","outline","$article"],"mappings":"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"} \ No newline at end of file diff --git a/package.json b/package.json index 9798cba6..fd34adc3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@yaohaixiao/outline.js", - "version": "3.9.0", + "version": "3.10.0", "description": "outline.js - 自动生成文章导读(Table of Contents)导航的 JavaScript 工具。", "main": "outline.min.js", "scripts": { diff --git a/src/anchors.js b/src/anchors.js index 2332ff1f..6901b29e 100644 --- a/src/anchors.js +++ b/src/anchors.js @@ -164,7 +164,7 @@ class Anchors extends Base { const max = $scrollElement.scrollHeight - $scrollElement.clientHeight const after = () => { if (isFunction(afterScroll)) { - afterScroll.call(this) + afterScroll.call(this, 'anchor') } later(() => { diff --git a/src/chapters.js b/src/chapters.js index 03929109..35c2af5a 100644 --- a/src/chapters.js +++ b/src/chapters.js @@ -448,7 +448,7 @@ class Chapters extends Base { const afterScroll = this.attr('afterScroll') const after = () => { if (isFunction(afterScroll)) { - afterScroll.call(this) + afterScroll.call(this, 'chapter') } later(() => { diff --git a/src/outline.js b/src/outline.js index b0bab351..3a21f0e5 100644 --- a/src/outline.js +++ b/src/outline.js @@ -5,6 +5,7 @@ import Chapters from './chapters' import Toolbar from './toolbar' import later from './utils/lang/later' +import isFunction from './utils/types/isFunction' import scrollTo from './utils/dom/scrollTo' import _getScrollElement from './utils/dom/_getScrollElement' import subscribe from './utils/observer/on' @@ -51,6 +52,7 @@ class Outline extends Base { const scrollElement = this.attr('scrollElement') const showCode = this.attr('showCode') const anchorURL = this.attr('anchorURL') + const afterScroll = this.attr('afterScroll') this.anchors = new Anchors({ articleElement, @@ -58,7 +60,8 @@ class Outline extends Base { scrollElement, selector, showCode, - anchorURL + anchorURL, + afterScroll }) return this @@ -74,6 +77,7 @@ class Outline extends Base { const placement = this.attr('placement') const afterSticky = this.attr('afterSticky') const afterToggle = this.attr('afterToggle') + const afterScroll = this.attr('afterScroll') const count = this.count() let parentElement = this.attr('parentElement') let CHAPTERS_OPTIONS @@ -90,7 +94,8 @@ class Outline extends Base { stickyHeight, chapters: this.anchors.getChapters(), afterSticky, - afterToggle + afterToggle, + afterScroll } if (position === 'relative') { @@ -174,6 +179,7 @@ class Outline extends Base { } toTop() { + const afterScroll = this.attr('afterScroll') const toolbar = this.toolbar const chapters = this.chapters const count = this.count() @@ -185,6 +191,10 @@ class Outline extends Base { chapters.highlight(0) } chapters.playing = false + + if (isFunction(afterScroll)) { + afterScroll.call(toolbar, 'up') + } } chapters.playing = true @@ -194,6 +204,7 @@ class Outline extends Base { } toBottom() { + const afterScroll = this.attr('afterScroll') const $scrollElement = _getScrollElement(this.attr('scrollElement')) const toolbar = this.toolbar const chapters = this.chapters @@ -209,6 +220,10 @@ class Outline extends Base { chapters.highlight(count - 1) } chapters.playing = false + + if (isFunction(afterScroll)) { + afterScroll.call(toolbar, 'bottom') + } } chapters.playing = true @@ -334,7 +349,8 @@ Outline.DEFAULTS = { stickyHeight: 0, customClass: '', afterSticky: null, - afterToggle: null + afterToggle: null, + afterScroll: null } if (window.jQuery) {