10 lines
17 KiB
JavaScript
10 lines
17 KiB
JavaScript
/*!
|
|
* Tiny Table of Contents plugin
|
|
*
|
|
* Copyright (c) 2023 Ephox Corporation DBA Tiny Technologies, Inc.
|
|
* Licensed under the Tiny commercial license. See https://www.tiny.cloud/legal/
|
|
*
|
|
* Version: 8.3.0-112
|
|
*/
|
|
|
|
!function(){"use strict";const e=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(n=o=e,(r=String).prototype.isPrototypeOf(n)||o.constructor?.name===r.name)?"string":t;var n,o,r})(t)===e,t=e=>t=>typeof t===e,n=e("string"),o=e("object"),r=e=>null==e,s=e=>!r(e),a=t("function"),l=t("number"),c=()=>{},i=()=>false;class d{tag;value;static singletonNone=new d(!1);constructor(e,t){this.tag=e,this.value=t}static some(e){return new d(!0,e)}static none(){return d.singletonNone}fold(e,t){return this.tag?t(this.value):e()}isSome(){return this.tag}isNone(){return!this.tag}map(e){return this.tag?d.some(e(this.value)):d.none()}bind(e){return this.tag?e(this.value):d.none()}exists(e){return this.tag&&e(this.value)}forall(e){return!this.tag||e(this.value)}filter(e){return!this.tag||e(this.value)?this:d.none()}getOr(e){return this.tag?this.value:e}or(e){return this.tag?this:e}getOrThunk(e){return this.tag?this.value:e()}orThunk(e){return this.tag?this:e()}getOrDie(e){if(this.tag)return this.value;throw new Error(e??"Called getOrDie on None")}static from(e){return s(e)?d.some(e):d.none()}getOrNull(){return this.tag?this.value:null}getOrUndefined(){return this.value}each(e){this.tag&&e(this.value)}toArray(){return this.tag?[this.value]:[]}toString(){return this.tag?`some(${this.value})`:"none()"}}const u=(e,t)=>{for(let n=0,o=e.length;n<o;n++)if(t(e[n],n))return!0;return!1},p=(e,t)=>{for(let n=0,o=e.length;n<o;n++)t(e[n],n)},g=Object.keys,m=(e,t)=>f(e,((e,n)=>({k:n,v:t(e,n)}))),f=(e,t)=>{const n={};return((e,t)=>{const n=g(e);for(let o=0,r=n.length;o<r;o++){const r=n[o];t(e[r],r)}})(e,((e,o)=>{const r=t(e,o);n[r.k]=r.v})),n},h="undefined"!=typeof window?window:Function("return this;")(),v=(e,t)=>((e,t)=>{let n=null!=t?t:h;for(let t=0;t<e.length&&null!=n;++t)n=n[e[t]];return n})(e.split("."),t),y=(e,t)=>{const{type:n,message:o}=t;e.notificationManager.open({type:n,text:o})},C=e=>{(e=>{switch(e){case"error":return console.error;case"info":return console.info;case"warn":return console.warn;default:return console.log}})(e.type)(e.message)},b=(e,t)=>{const{protect:n,allowList:o=[],blockList:r=[]}=null!=e?e:{};let a;return a=s(n)?n:o.length>0||r.length>0||t,{protect:a,allowList:o,blockList:r}},S=e=>{const{protect:t,allowList:n,blockList:o}=null!=e?e:{};return e=>{const r=e.toLowerCase();return n.length>0?!u(n,(e=>e.toLowerCase()===r)):o.length>0?u(o,(e=>e.toLowerCase()===r)):t}},w=e=>{const t=S(e);return(e,n)=>{const o=((e,t)=>`${e}:${t}`)(n,e.toLowerCase());return t(o)}},x=(e,t,n,o)=>{const r=Reflect.get(e,"on"),s={protectedEventHandlers:[],cleanupScheduled:!1},a=(e,t)=>{o&&console.log(`[EventsProxy] ${e}`,t||"")},l=t=>{"invalid"===t&&s.protectedEventHandlers.length>0&&(a("Removing event handlers",s.protectedEventHandlers),p(s.protectedEventHandlers,(t=>{e.off(t.name,t.callback)})),s.protectedEventHandlers=[])},i=t.onStatusChange(l);return e.on("remove",i),(o,i,d)=>{a(`Adding event listener: ${o}`,{shouldProtect:n(o)});const u=((e,o)=>{const r=n(e),a=t.getStatus(),l=r&&"invalid"===a?c:o;return r&&s.protectedEventHandlers.push({name:e,callback:l}),l})(o,i);return s.cleanupScheduled||(s.cleanupScheduled=!0,window.setTimeout((()=>{l(t.getStatus()),s.cleanupScheduled=!1}),0)),Reflect.apply(r,e,[o,u,d])}},P=(e,t,n)=>o=>{const r="invalid"!==t.getStatus()&&s(n)?n(o):c,a=((e,t,n)=>{const o=e=>{"invalid"===e&&n.setEnabled(!1)},r=()=>o(t.getStatus());o(t.getStatus()),e.on("NodeChange",r);const s=t.onStatusChange(o);return()=>{e.off("NodeChange",r),s()}})(e,t,o);return e=>{null==r||r(e),a()}},$=(e,t,n)=>(...o)=>{var r;return"invalid"===e.getStatus()?n:null!==(r=null==t?void 0:t(...o))&&void 0!==r?r:n},R=(e,t)=>$(e,t,Promise.resolve([])),E=(e,t)=>$(e,t,[]),T=(e,t)=>$(e,t,!1),L=(e,t,o,r)=>{const s=t=>{const{command:s,value:a}=t,l=d.from(a).filter(n).map((e=>e.toLowerCase())),c=s.toLowerCase()===r.toLowerCase(),i=l.exists((e=>o.has(e))),u=l.exists((t=>t===e.queryCommandValue(r)));c&&i&&!u&&t.preventDefault()},a=t.onStatusChange((t=>{if("invalid"===t){e.on("BeforeExecCommand",s);const t=()=>{const t=e.queryCommandValue(r);o.has(t.toLowerCase())&&e.execCommand(r,!1,t)};e.initialized?t():e.on("init",t)}}));e.on("remove",(()=>{a(),e.off("BeforeExecCommand",s)}))},k=(e,t,o,r,s,a=!1)=>{const l=new Set,c=new Set,i=(e,t)=>{a&&console.log(`[UiProxy] ${e}`,t||"")};((e,t,n)=>{L(e,t,n,"ToggleView")})(e,o,l),((e,t,n)=>{L(e,t,n,"ToggleSidebar")})(e,o,c);const d=(t,n,a,l)=>{const c=s(t,a);return i(`${l}: ${t}`,{spec:n,context:r,shouldProtect:c}),c?{...n,onSetup:P(e,o,n.onSetup)}:n};return new Proxy(t,{get:(e,t,a)=>{const u=Reflect.get(e,t,a);if(!n(t))return u;switch(t){case"addButton":case"addGroupToolbarButton":case"addToggleButton":case"addMenuButton":case"addSplitButton":return(...n)=>{const[o,r,...s]=n,a=d(o,r,"button",String(t));return Reflect.apply(u,e,[o,a,...s])};case"addMenuItem":case"addToggleMenuItem":case"addNestedMenuItem":return(...n)=>{const[o,r,...s]=n,a=d(o,r,"menuitem",String(t));return Reflect.apply(u,e,[o,a,...s])};case"addAutocompleter":return(...n)=>{const[a,l,...c]=n,d=s(a,"autocompleter");if(i(`${String(t)}: ${a}`,{spec:l,context:r,shouldProtect:d}),d){const t={...l,fetch:R(o,l.fetch)};return Reflect.apply(u,e,[a,t,...c])}return Reflect.apply(u,e,[a,l,...c])};case"addSidebar":return(...n)=>{const[o,a,...l]=n,d=s(o,"sidebar");if(i(`${String(t)}: ${o}`,{spec:a,context:r,shouldProtect:d}),d){c.add(o.toLowerCase());const t={...a};return Reflect.apply(u,e,[o,t,...l])}return Reflect.apply(u,e,[o,a,...l])};case"addView":return(...n)=>{const[o,a,...c]=n,d=s(o,"view");if(i(`${String(t)}: ${o}`,{spec:a,context:r,shouldProtect:d}),d){l.add(o.toLowerCase());const t={...a};return Reflect.apply(u,e,[o,t,...c])}return Reflect.apply(u,e,[o,a,...c])};case"addContextMenu":return(...n)=>{const[a,l,...c]=n,d=s(a,"contextmenu");if(i(`${String(t)}: ${a}`,{spec:l,context:r,shouldProtect:d}),d){const t={...l,update:E(o,l.update)};return Reflect.apply(u,e,[a,t,...c])}return Reflect.apply(u,e,[a,l,...c])};case"addContextToolbar":case"addContextForm":return(...n)=>{const[a,l,...c]=n,d=s(a,"contexttoolbar");if(i(`${String(t)}: ${a}`,{spec:l,context:r,shouldProtect:d}),d){const t={...l,predicate:T(o,l.predicate)};return Reflect.apply(u,e,[a,t,...c])}return Reflect.apply(u,e,[a,l,...c])};case"addIcon":case"getAll":case"addContext":return u}}})},A=new Set(["addCommand","addCommands","addQueryStateHandler","addQueryValueHandler"]),O=e=>(t,n)=>{e&&console.log(`[EditorProxy] ${t}`,n||"")},M=(e,t)=>{const{statusProvider:n,uiContext:o,protection:r,debug:s=!1}=t,{events:l,commands:i,ui:d}=r;O(s)("Creating enhanced editor with options:",{hasStatusProvider:!!n,uiContext:o,debug:s,protection:r});const{editorUiProxy:u,editorCommandsProxy:g,editorEventListenerProxy:f}=((e,t,n,o,r,s,a)=>{const l=s.protect?{...e.ui,registry:k(e,e.ui.registry,t,n,w(s),a)}:e.ui,i=o.protect?((e,t,n,o,r)=>{const s={protectedCommands:[],cleanupScheduled:!1},a=(e,t)=>{r&&console.log(`[CommandsProxy] ${e}`,t||"")},l=(e,t)=>{const r=o(e),a=n.getStatus();return r&&s.protectedCommands.push(e),r&&"invalid"===a?c:t},i=t=>{"invalid"===t&&s.protectedCommands.length>0&&(a("Removing commands",s.protectedCommands),p(s.protectedCommands,(t=>{e.editorCommands.removeCommand(t)})),s.protectedCommands=[])},d=()=>{s.cleanupScheduled||(s.cleanupScheduled=!0,window.setTimeout((()=>{i(n.getStatus()),s.cleanupScheduled=!1}),0))},u=n.onStatusChange(i);return e.on("remove",u),new Proxy(t,{get:(e,n,r)=>{if(a(`Accessing property: ${String(n)}`),"addCommand"===n){const s=Reflect.get(e,n,r);return(e,n,...r)=>{a(`Adding command: ${e}`,{shouldProtect:o(e)});const c=l(e,n);return d(),Reflect.apply(s,t,[e,c,...r])}}if("addCommands"===n){const o=Reflect.get(e,n,r);return(e,n="exec")=>{a(`Adding commands (${n})`,{commandCount:Object.keys(e).length,willApplyEnforcement:"exec"===n});const r="exec"!==n?e:m(e,((e,t)=>l(t,e)));return d(),Reflect.apply(o,t,[r,n])}}return Reflect.get(e,n,r)}})})(e,e.editorCommands,t,S(o),a):e.editorCommands;return{editorUiProxy:l,editorCommandsProxy:i,editorEventListenerProxy:r.protect?x(e,t,S(r),a):e.on.bind(e)}})(e,n,o||"",i,l,d,s),h=((e,t,n,o)=>(r,s,l)=>{const c=String(s);if("on"===s)return O(o)("on intercepted"),n;if(A.has(c))return O(o)(`${c} intercepted`),t[c].bind(t);if("editorCommands"===s)return O(o)("editorCommands accessed"),t;if("ui"===s)return O(o)("ui accessed"),e;const i=Reflect.get(r,s,l);return a(i)?i.bind(r):i})(u,g,f,s);return new Proxy(e,{get:h,set:(e,t,n,o)=>Reflect.set(e,t,n,o),has:(e,t)=>Reflect.has(e,t),ownKeys:e=>Reflect.ownKeys(e),getOwnPropertyDescriptor:(e,t)=>Reflect.getOwnPropertyDescriptor(e,t),defineProperty:(e,t,n)=>Reflect.defineProperty(e,t,n),deleteProperty:(e,t)=>Reflect.deleteProperty(e,t),isExtensible:e=>Reflect.isExtensible(e),preventExtensions:e=>Reflect.preventExtensions(e),getPrototypeOf:e=>Reflect.getPrototypeOf(e),setPrototypeOf:(e,t)=>Reflect.setPrototypeOf(e,t)})},_=e=>parseInt(e,10),j=(e,t)=>{const n=e-t;return 0===n?0:n>0?1:-1},H=(e,t,n)=>({major:e,minor:t,patch:n}),I=e=>{const t=/([0-9]+)\.([0-9]+)\.([0-9]+)(?:(\-.+)?)/.exec(e);return t?H(_(t[1]),_(t[2]),_(t[3])):H(0,0,0)},N=(e,t)=>!!e&&-1===((e,t)=>{const n=j(e.major,t.major);if(0!==n)return n;const o=j(e.minor,t.minor);if(0!==o)return o;const r=j(e.patch,t.patch);return 0!==r?r:0})((e=>I((e=>[e.majorVersion,e.minorVersion].join(".").split(".").slice(0,3).join("."))(e)))(e),I(t)),B=I("8.3.0"),z=`${B.major}.${B.minor}.0`,D=`${B.major+1}.0.0`,U=(e,t)=>{const{setup:n,protection:o}=t;return(l,c)=>{if(!((e,t)=>N(e,z)?(console.error(`The "${t}" plugin requires at least version ${z} of TinyMCE.`),!1):!!N(e,D)||(console.error(`The "${t}" plugin requires at least version ${z} of TinyMCE but less than ${D}.`),!1))(tinymce,e)||((e,t)=>!!(e=>{var t;const n=null===(t=e.options.get("license_key"))||void 0===t?void 0:t.toLowerCase(),o=e.options.get("online_license_key");return r(o)&&"gpl"===n})(e)&&(((e,t)=>{const{console:n,editor:o}=t;s(o)&&(e._skinLoaded?y(e,o):e.on("SkinLoaded",(()=>{y(e,o)}))),s(n)&&C(n)})(e,{console:{type:"error",message:[`The "${t}" plugin requires a valid TinyMCE license key.`,"Read more: https://www.tiny.cloud/docs/tinymce/latest/license-key/"].join(" ")}}),!0))(l,e))return{};const i=(e=>{const{protect:t=!0,events:n,commands:o,ui:r,api:s}=null!=e?e:{};return{protect:t,events:b(n,false),commands:b(o,true),ui:b(r,true),api:b(s,true)}})(o),d=((e="pre-validation")=>{const t=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})(e),n=new Set;let o=!1;const{enableLogging:r=!1}={},s=(e,...t)=>{r&&console.log(`[StatusProvider] ${e}`,...t)};return{setStatus:e=>{const o=t.get();if(o===e)return s("Status unchanged:",e),!1;t.set(e),s("Status changed:",o,"->",e);const r={currentStatus:e,previousStatus:o},a=Array.from(n);return p(a,(e=>{e(r.currentStatus,r.previousStatus)})),!0},onStatusChange:e=>(n.add(e),s("Callback registered, total listeners:",n.size),()=>{n.delete(e)&&s("Callback unregistered, remaining listeners:",n.size)}),getStatus:t.get,hasListeners:()=>n.size>0,destroy:()=>{o||(s("Destroying StatusProvider, clearing",n.size,"listeners"),n.clear(),o=!0)}}})(),u=((e,t,n)=>{const o=`commercial-license-${t}`;return e.ui.registry.addContext(o,(()=>"invalid"!==n.getStatus()&&!e.mode.isReadOnly())),e.licenseKeyManager.validate({plugin:t}).then((e=>{n.setStatus(e?"valid":"invalid")}),(e=>{console.error(e),console.error(`An unknown error occurred when trying to validate "${t}" plugin.`),n.setStatus("invalid")})),{ui:{context:o}}})(l,e,d),g=i.protect?M(l,{statusProvider:d,uiContext:u.ui.context,debug:t.debug||!1,protection:i}):l,f=((e,t)=>({pluginCode:e,enforcer:{isInvalid:()=>"invalid"===t.getStatus(),onInvalid:e=>t.onStatusChange(((t,n)=>{"invalid"===t&&e(t,n)}))}}))(e,d);return((e,t,n,o)=>{if(t.protect&&t.api.protect&&s(e)){const l=S(t.api);return(r=e=>"invalid"===n.getStatus()&&l(e),(e,t)=>m(e,((e,n)=>a(e)?(...o)=>{if(r(n.toLowerCase())){const e=`Method "${s(t)?`${t}.`:""}${n}" is not available due to license key restrictions.`,o=new Error(e);throw console.error(e),o}return e(...o)}:e)))(e,o)}var r;return e})(n(g,c,f),i,d,e)}},V=e=>{if(null==e)throw new Error("Node cannot be null or undefined");return{dom:e}},q=V,K=Object.getPrototypeOf,F=e=>{const t=v("ownerDocument.defaultView",e);return o(e)&&((e=>((e,t)=>{const n=((e,t)=>v(e,t))(e,t);if(null==n)throw new Error(e+" not available on this browser");return n})("HTMLElement",e))(t).prototype.isPrototypeOf(e)||/^HTML\w*Element$/.test(K(e).constructor.name))},G=e=>Q(e)&&F(e.dom),Q=e=>1===(e=>e.dom.nodeType)(e);const W=e=>t=>t.options.get(e),J=W("tableofcontents_class"),X=W("tableofcontents_header"),Y=W("tableofcontents_depth"),Z=W("tableofcontents_includeheader"),ee=W("tableofcontents_orderedlist"),te=W("tableofcontents_orderedlist_type"),ne=e=>{return(o=q(e),r=G,(t=o.dom.childNodes,n=e=>r(q(e)),((e,t,n)=>{for(let o=0,r=e.length;o<r;o++){const r=e[o];if(t(r,o))return d.some(r);if(n(r,o))break}return d.none()})(t,n,i)).map(q)).map((e=>e.dom.innerHTML));var t,n,o,r},oe=(()=>{let e=0;return()=>"mcetoc_"+(new Date).getTime().toString(32)+(e++).toString(32)})(),re=e=>{const t=J(e),n=X(e),o=(e=>{const t=[];for(let n=1;n<=e;n++)t.push("h"+n);return t.join(",")})(Y(e));let r=e.dom.select(o);return r.length&&/^h[1-9]$/i.test(n)&&(r=((e,t)=>{const n=[];for(let o=0,r=e.length;o<r;o++){const r=e[o];t(r)&&n.push(r)}return n})(r,(n=>{const o=n.parentElement;return s(o)&&!e.dom.hasClass(o,t)&&!e.dom.isEmpty(n)}))),((e,t)=>{const n=e.length,o=new Array(n);for(let r=0;r<n;r++){const n=e[r];o[r]=t(n)}return o})(r,(e=>({id:e.id||oe(),level:parseInt(e.nodeName.replace(/^H/i,""),10),title:e.innerText,element:e})))},se=(e,t)=>{let n="";const o=re(e),r=ee(e)?"ol":"ul",s=[r];let a=(e=>{let t=9;for(const n of e)if(n.level<t&&(t=n.level),1===t)return t;return t})(o)-1;if(!o.length)return"";if(ee(e)&&s.push(`type="${te(e)}"`),Z(e)){const o=t.getOr(e.translate("Table of Contents"));n+=((e,t)=>"<"+e+' contenteditable="true">'+t+"</"+e+">")(X(e),o)}for(let t=0;t<o.length;t++){const l=o[t];l.element.id=l.id;const c=o[t+1]&&o[t+1].level;if(a===l.level)n+="<li>";else for(let e=a;e<l.level;e++)n+=`<${s.join(" ")}><li>`;if(n+='<a href="#'+l.id+'">'+e.dom.encode(l.title)+"</a>",c!==l.level&&c)for(let e=l.level;e>c;e--)n+=e===c+1?`</li></${r}><li>`:`</li></${r}>`;else n+="</li>",c||(n+=`</${r}>`);a=l.level}return n},ae=e=>{const t=J(e),n=e.dom.select("."+t);n.length&&e.undoManager.transact((()=>{e.dom.setHTML(n,se(e,ne(n[0])))}))},le=e=>t=>{const n=()=>{const n=e.selection.isEditable();t.setEnabled(!e.readonly&&n&&(e=>re(e).length>0)(e))};return e.on("NodeChange LoadContent SetContent change",n),n(),()=>e.off("NodeChange LoadContent SetContent change",n)},ce=e=>t=>e.dom.is(t,"."+J(e))&&e.getBody().contains(t);((e,t)=>{const{i18n:n=!0}=t;n&&tinymce.PluginManager.requireLangPack(e,"ar,bg-BG,ca,cs,da,de,el,es,eu,fa,fi,fr-FR,he-IL,hi,hr,hu-HU,id,it,ja,kk,ko-KR,ms,nb-NO,nl,pl,pt-BR,pt-PT,ro,ru,sk,sl-SI,sv-SE,th-TH,tr,uk,vi,zh-CN,zh-TW"),tinymce.PluginManager.add(e,U(e,t))})("tableofcontents",{setup:e=>{(e=>{const t=e.options.register;t("tableofcontents_class",{processor:"string",default:"mce-toc"}),t("tableofcontents_header",{processor:e=>n(e)&&/^h[1-6]$/.test(e),default:"h2"}),t("tableofcontents_depth",{processor:e=>l(e)&&e>=1&&e<=9,default:3}),t("tableofcontents_includeheader",{processor:"boolean",default:!0}),t("tableofcontents_orderedlist",{processor:"boolean",default:!1}),t("tableofcontents_orderedlist_type",{processor:e=>n(e)&&["1","A","a","I","i"].includes(e),default:"1"})})(e),(e=>{e.addCommand("mceInsertToc",(()=>{(e=>{const t=J(e),n=e.dom.select("."+t);((e,t)=>!t.length||e.dom.getParents(t[0],".mce-offscreen-selection").length>0)(e,n)?e.insertContent(((e,t)=>{const n=se(e,t);return'<div class="'+e.dom.encode(J(e))+'" contenteditable="false" data-mce-toc="true">'+n+"</div>"})(e,d.none())):ae(e)})(e)})),e.addCommand("mceUpdateToc",(()=>{ae(e)}))})(e),(e=>{const t=()=>e.execCommand("mceInsertToc");e.ui.registry.addButton("tableofcontents",{icon:"toc",tooltip:"Table of contents",onAction:t,onSetup:le(e)}),e.ui.registry.addButton("tableofcontentsupdate",{icon:"reload",tooltip:"Update",onAction:()=>e.execCommand("mceUpdateToc")}),e.ui.registry.addMenuItem("tableofcontents",{icon:"toc",text:"Table of contents",onAction:t,onSetup:le(e)}),e.ui.registry.addContextToolbar("tableofcontents",{items:"tableofcontentsupdate",predicate:ce(e),scope:"node",position:"node"})})(e),(e=>{const t=J(e),n="data-mce-toc";e.on("PreProcess",(n=>{const o=e.dom,r=o.select("."+t,n.node)[0];if(r){const e=[r].concat(o.select("[contenteditable]",r));p(e,(e=>{o.setAttrib(e,"contentEditable",null)}))}})),e.on("PreInit",(()=>{e.serializer.addTempAttr(n)})),e.on("SetContent",(()=>{const o=e.dom,r=o.select("."+t)[0];if(r){o.setAttribs(r,{contentEditable:!1,[n]:!0});const e=r.firstElementChild;s(e)&&o.setAttrib(e,"contentEditable",!0)}}))})(e)}})}(); |