medium-proeditor
Version:
A powerful & customizable Medium-style rich text editor
2 lines (1 loc) • 37.4 kB
JavaScript
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).HighlightMenu={})}(this,(function(t){"use strict";function e(t){return"Object"===function(t){return Object.prototype.toString.call(t).slice(8,-1)}(t)&&(t.constructor===Object&&Object.getPrototypeOf(t)===Object.prototype)}function n(t,r){const i={...t};if(e(t)&&e(r))for(const o of Object.keys(r))e(r[o])&&e(t[o])?i[o]=n(t[o],r[o]):i[o]=r[o];return i}class r{config;options;storage;constructor(t){this.config={...t},t.addOptions&&(this.options=t.addOptions.call({name:t.name})),t.addStorage&&(this.storage=t.addStorage.call({name:t.name,options:this.options}))}static create(t){return new r(t)}configure(t={}){return new r({...this.config,addOptions:()=>n(this.options,t)})}}function i(t,e,n){for(let r=0;;r++){if(r==t.childCount||r==e.childCount)return t.childCount==e.childCount?null:n;let o=t.child(r),s=e.child(r);if(o!=s){if(!o.sameMarkup(s))return n;if(o.isText&&o.text!=s.text){for(let t=0;o.text[t]==s.text[t];t++)n++;return n}if(o.content.size||s.content.size){let t=i(o.content,s.content,n+1);if(null!=t)return t}n+=o.nodeSize}else n+=o.nodeSize}}function o(t,e,n,r){for(let i=t.childCount,s=e.childCount;;){if(0==i||0==s)return i==s?null:{a:n,b:r};let a=t.child(--i),l=e.child(--s),h=a.nodeSize;if(a!=l){if(!a.sameMarkup(l))return{a:n,b:r};if(a.isText&&a.text!=l.text){let t=0,e=Math.min(a.text.length,l.text.length);for(;t<e&&a.text[a.text.length-t-1]==l.text[l.text.length-t-1];)t++,n--,r--;return{a:n,b:r}}if(a.content.size||l.content.size){let t=o(a.content,l.content,n-1,r-1);if(t)return t}n-=h,r-=h}else n-=h,r-=h}}class s{constructor(t,e){if(this.content=t,this.size=e||0,null==e)for(let e=0;e<t.length;e++)this.size+=t[e].nodeSize}nodesBetween(t,e,n,r=0,i){for(let o=0,s=0;s<e;o++){let a=this.content[o],l=s+a.nodeSize;if(l>t&&!1!==n(a,r+s,i||null,o)&&a.content.size){let i=s+1;a.nodesBetween(Math.max(0,t-i),Math.min(a.content.size,e-i),n,r+i)}s=l}}descendants(t){this.nodesBetween(0,this.size,t)}textBetween(t,e,n,r){let i="",o=!0;return this.nodesBetween(t,e,((s,a)=>{let l=s.isText?s.text.slice(Math.max(t,a)-a,e-a):s.isLeaf?r?"function"==typeof r?r(s):r:s.type.spec.leafText?s.type.spec.leafText(s):"":"";s.isBlock&&(s.isLeaf&&l||s.isTextblock)&&n&&(o?o=!1:i+=n),i+=l}),0),i}append(t){if(!t.size)return this;if(!this.size)return t;let e=this.lastChild,n=t.firstChild,r=this.content.slice(),i=0;for(e.isText&&e.sameMarkup(n)&&(r[r.length-1]=e.withText(e.text+n.text),i=1);i<t.content.length;i++)r.push(t.content[i]);return new s(r,this.size+t.size)}cut(t,e=this.size){if(0==t&&e==this.size)return this;let n=[],r=0;if(e>t)for(let i=0,o=0;o<e;i++){let s=this.content[i],a=o+s.nodeSize;a>t&&((o<t||a>e)&&(s=s.isText?s.cut(Math.max(0,t-o),Math.min(s.text.length,e-o)):s.cut(Math.max(0,t-o-1),Math.min(s.content.size,e-o-1))),n.push(s),r+=s.nodeSize),o=a}return new s(n,r)}cutByIndex(t,e){return t==e?s.empty:0==t&&e==this.content.length?this:new s(this.content.slice(t,e))}replaceChild(t,e){let n=this.content[t];if(n==e)return this;let r=this.content.slice(),i=this.size+e.nodeSize-n.nodeSize;return r[t]=e,new s(r,i)}addToStart(t){return new s([t].concat(this.content),this.size+t.nodeSize)}addToEnd(t){return new s(this.content.concat(t),this.size+t.nodeSize)}eq(t){if(this.content.length!=t.content.length)return!1;for(let e=0;e<this.content.length;e++)if(!this.content[e].eq(t.content[e]))return!1;return!0}get firstChild(){return this.content.length?this.content[0]:null}get lastChild(){return this.content.length?this.content[this.content.length-1]:null}get childCount(){return this.content.length}child(t){let e=this.content[t];if(!e)throw new RangeError("Index "+t+" out of range for "+this);return e}maybeChild(t){return this.content[t]||null}forEach(t){for(let e=0,n=0;e<this.content.length;e++){let r=this.content[e];t(r,n,e),n+=r.nodeSize}}findDiffStart(t,e=0){return i(this,t,e)}findDiffEnd(t,e=this.size,n=t.size){return o(this,t,e,n)}findIndex(t,e=-1){if(0==t)return l(0,t);if(t==this.size)return l(this.content.length,t);if(t>this.size||t<0)throw new RangeError(`Position ${t} outside of fragment (${this})`);for(let n=0,r=0;;n++){let i=r+this.child(n).nodeSize;if(i>=t)return i==t||e>0?l(n+1,i):l(n,r);r=i}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map((t=>t.toJSON())):null}static fromJSON(t,e){if(!e)return s.empty;if(!Array.isArray(e))throw new RangeError("Invalid input for Fragment.fromJSON");return new s(e.map(t.nodeFromJSON))}static fromArray(t){if(!t.length)return s.empty;let e,n=0;for(let r=0;r<t.length;r++){let i=t[r];n+=i.nodeSize,r&&i.isText&&t[r-1].sameMarkup(i)?(e||(e=t.slice(0,r)),e[e.length-1]=i.withText(e[e.length-1].text+i.text)):e&&e.push(i)}return new s(e||t,n)}static from(t){if(!t)return s.empty;if(t instanceof s)return t;if(Array.isArray(t))return this.fromArray(t);if(t.attrs)return new s([t],t.nodeSize);throw new RangeError("Can not convert "+t+" to a Fragment"+(t.nodesBetween?" (looks like multiple versions of prosemirror-model were loaded)":""))}}s.empty=new s([],0);const a={index:0,offset:0};function l(t,e){return a.index=t,a.offset=e,a}function h(t,e){if(t===e)return!0;if(!t||"object"!=typeof t||!e||"object"!=typeof e)return!1;let n=Array.isArray(t);if(Array.isArray(e)!=n)return!1;if(n){if(t.length!=e.length)return!1;for(let n=0;n<t.length;n++)if(!h(t[n],e[n]))return!1}else{for(let n in t)if(!(n in e)||!h(t[n],e[n]))return!1;for(let n in e)if(!(n in t))return!1}return!0}class c{constructor(t,e){this.type=t,this.attrs=e}addToSet(t){let e,n=!1;for(let r=0;r<t.length;r++){let i=t[r];if(this.eq(i))return t;if(this.type.excludes(i.type))e||(e=t.slice(0,r));else{if(i.type.excludes(this.type))return t;!n&&i.type.rank>this.type.rank&&(e||(e=t.slice(0,r)),e.push(this),n=!0),e&&e.push(i)}}return e||(e=t.slice()),n||e.push(this),e}removeFromSet(t){for(let e=0;e<t.length;e++)if(this.eq(t[e]))return t.slice(0,e).concat(t.slice(e+1));return t}isInSet(t){for(let e=0;e<t.length;e++)if(this.eq(t[e]))return!0;return!1}eq(t){return this==t||this.type==t.type&&h(this.attrs,t.attrs)}toJSON(){let t={type:this.type.name};for(let e in this.attrs){t.attrs=this.attrs;break}return t}static fromJSON(t,e){if(!e)throw new RangeError("Invalid input for Mark.fromJSON");let n=t.marks[e.type];if(!n)throw new RangeError(`There is no mark type ${e.type} in this schema`);let r=n.create(e.attrs);return n.checkAttrs(r.attrs),r}static sameSet(t,e){if(t==e)return!0;if(t.length!=e.length)return!1;for(let n=0;n<t.length;n++)if(!t[n].eq(e[n]))return!1;return!0}static setFrom(t){if(!t||Array.isArray(t)&&0==t.length)return c.none;if(t instanceof c)return[t];let e=t.slice();return e.sort(((t,e)=>t.type.rank-e.type.rank)),e}}c.none=[];class p extends Error{}class u{constructor(t,e,n){this.content=t,this.openStart=e,this.openEnd=n}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(t,e){let n=f(this.content,t+this.openStart,e);return n&&new u(n,this.openStart,this.openEnd)}removeBetween(t,e){return new u(d(this.content,t+this.openStart,e+this.openStart),this.openStart,this.openEnd)}eq(t){return this.content.eq(t.content)&&this.openStart==t.openStart&&this.openEnd==t.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let t={content:this.content.toJSON()};return this.openStart>0&&(t.openStart=this.openStart),this.openEnd>0&&(t.openEnd=this.openEnd),t}static fromJSON(t,e){if(!e)return u.empty;let n=e.openStart||0,r=e.openEnd||0;if("number"!=typeof n||"number"!=typeof r)throw new RangeError("Invalid input for Slice.fromJSON");return new u(s.fromJSON(t,e.content),n,r)}static maxOpen(t,e=!0){let n=0,r=0;for(let r=t.firstChild;r&&!r.isLeaf&&(e||!r.type.spec.isolating);r=r.firstChild)n++;for(let n=t.lastChild;n&&!n.isLeaf&&(e||!n.type.spec.isolating);n=n.lastChild)r++;return new u(t,n,r)}}function d(t,e,n){let{index:r,offset:i}=t.findIndex(e),o=t.maybeChild(r),{index:s,offset:a}=t.findIndex(n);if(i==e||o.isText){if(a!=n&&!t.child(s).isText)throw new RangeError("Removing non-flat range");return t.cut(0,e).append(t.cut(n))}if(r!=s)throw new RangeError("Removing non-flat range");return t.replaceChild(r,o.copy(d(o.content,e-i-1,n-i-1)))}function f(t,e,n,r){let{index:i,offset:o}=t.findIndex(e),s=t.maybeChild(i);if(o==e||s.isText)return r&&!r.canReplace(i,i,n)?null:t.cut(0,e).append(n).append(t.cut(e));let a=f(s.content,e-o-1,n);return a&&t.replaceChild(i,s.copy(a))}u.empty=new u(s.empty,0,0);const m=Math.pow(2,16);function g(t){return 65535&t}class w{constructor(t,e,n){this.pos=t,this.delInfo=e,this.recover=n}get deleted(){return(8&this.delInfo)>0}get deletedBefore(){return(5&this.delInfo)>0}get deletedAfter(){return(6&this.delInfo)>0}get deletedAcross(){return(4&this.delInfo)>0}}class y{constructor(t,e=!1){if(this.ranges=t,this.inverted=e,!t.length&&y.empty)return y.empty}recover(t){let e=0,n=g(t);if(!this.inverted)for(let t=0;t<n;t++)e+=this.ranges[3*t+2]-this.ranges[3*t+1];return this.ranges[3*n]+e+function(t){return(t-(65535&t))/m}(t)}mapResult(t,e=1){return this._map(t,e,!1)}map(t,e=1){return this._map(t,e,!0)}_map(t,e,n){let r=0,i=this.inverted?2:1,o=this.inverted?1:2;for(let s=0;s<this.ranges.length;s+=3){let a=this.ranges[s]-(this.inverted?r:0);if(a>t)break;let l=this.ranges[s+i],h=this.ranges[s+o],c=a+l;if(t<=c){let i=a+r+((l?t==a?-1:t==c?1:e:e)<0?0:h);if(n)return i;let o=t==(e<0?a:c)?null:s/3+(t-a)*m,p=t==a?2:t==c?1:4;return(e<0?t!=a:t!=c)&&(p|=8),new w(i,p,o)}r+=h-l}return n?t+r:new w(t+r,0,null)}touches(t,e){let n=0,r=g(e),i=this.inverted?2:1,o=this.inverted?1:2;for(let e=0;e<this.ranges.length;e+=3){let s=this.ranges[e]-(this.inverted?n:0);if(s>t)break;let a=this.ranges[e+i];if(t<=s+a&&e==3*r)return!0;n+=this.ranges[e+o]-a}return!1}forEach(t){let e=this.inverted?2:1,n=this.inverted?1:2;for(let r=0,i=0;r<this.ranges.length;r+=3){let o=this.ranges[r],s=o-(this.inverted?i:0),a=o+(this.inverted?0:i),l=this.ranges[r+e],h=this.ranges[r+n];t(s,s+l,a,a+h),i+=h-l}}invert(){return new y(this.ranges,!this.inverted)}toString(){return(this.inverted?"-":"")+JSON.stringify(this.ranges)}static offset(t){return 0==t?y.empty:new y(t<0?[0,-t,0]:[0,0,t])}}y.empty=new y([]);const k=Object.create(null);class S{getMap(){return y.empty}merge(t){return null}static fromJSON(t,e){if(!e||!e.stepType)throw new RangeError("Invalid input for Step.fromJSON");let n=k[e.stepType];if(!n)throw new RangeError(`No step type ${e.stepType} defined`);return n.fromJSON(t,e)}static jsonID(t,e){if(t in k)throw new RangeError("Duplicate use of step JSON ID "+t);return k[t]=e,e.prototype.jsonID=t,e}}class v{constructor(t,e){this.doc=t,this.failed=e}static ok(t){return new v(t,null)}static fail(t){return new v(null,t)}static fromReplace(t,e,n,r){try{return v.ok(t.replace(e,n,r))}catch(t){if(t instanceof p)return v.fail(t.message);throw t}}}function x(t,e,n){let r=[];for(let i=0;i<t.childCount;i++){let o=t.child(i);o.content.size&&(o=o.copy(x(o.content,e,o))),o.isInline&&(o=e(o,n,i)),r.push(o)}return s.fromArray(r)}class T extends S{constructor(t,e,n){super(),this.from=t,this.to=e,this.mark=n}apply(t){let e=t.slice(this.from,this.to),n=t.resolve(this.from),r=n.node(n.sharedDepth(this.to)),i=new u(x(e.content,((t,e)=>t.isAtom&&e.type.allowsMarkType(this.mark.type)?t.mark(this.mark.addToSet(t.marks)):t),r),e.openStart,e.openEnd);return v.fromReplace(t,this.from,this.to,i)}invert(){return new b(this.from,this.to,this.mark)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted||e.pos>=n.pos?null:new T(e.pos,n.pos,this.mark)}merge(t){return t instanceof T&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new T(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new T(e.from,e.to,t.markFromJSON(e.mark))}}S.jsonID("addMark",T);class b extends S{constructor(t,e,n){super(),this.from=t,this.to=e,this.mark=n}apply(t){let e=t.slice(this.from,this.to),n=new u(x(e.content,(t=>t.mark(this.mark.removeFromSet(t.marks))),t),e.openStart,e.openEnd);return v.fromReplace(t,this.from,this.to,n)}invert(){return new T(this.from,this.to,this.mark)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted||e.pos>=n.pos?null:new b(e.pos,n.pos,this.mark)}merge(t){return t instanceof b&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new b(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new b(e.from,e.to,t.markFromJSON(e.mark))}}S.jsonID("removeMark",b);class M extends S{constructor(t,e){super(),this.pos=t,this.mark=e}apply(t){let e=t.nodeAt(this.pos);if(!e)return v.fail("No node at mark step's position");let n=e.type.create(e.attrs,null,this.mark.addToSet(e.marks));return v.fromReplace(t,this.pos,this.pos+1,new u(s.from(n),0,e.isLeaf?0:1))}invert(t){let e=t.nodeAt(this.pos);if(e){let t=this.mark.addToSet(e.marks);if(t.length==e.marks.length){for(let n=0;n<e.marks.length;n++)if(!e.marks[n].isInSet(t))return new M(this.pos,e.marks[n]);return new M(this.pos,this.mark)}}return new O(this.pos,this.mark)}map(t){let e=t.mapResult(this.pos,1);return e.deletedAfter?null:new M(e.pos,this.mark)}toJSON(){return{stepType:"addNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(t,e){if("number"!=typeof e.pos)throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");return new M(e.pos,t.markFromJSON(e.mark))}}S.jsonID("addNodeMark",M);class O extends S{constructor(t,e){super(),this.pos=t,this.mark=e}apply(t){let e=t.nodeAt(this.pos);if(!e)return v.fail("No node at mark step's position");let n=e.type.create(e.attrs,null,this.mark.removeFromSet(e.marks));return v.fromReplace(t,this.pos,this.pos+1,new u(s.from(n),0,e.isLeaf?0:1))}invert(t){let e=t.nodeAt(this.pos);return e&&this.mark.isInSet(e.marks)?new M(this.pos,this.mark):this}map(t){let e=t.mapResult(this.pos,1);return e.deletedAfter?null:new O(e.pos,this.mark)}toJSON(){return{stepType:"removeNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(t,e){if("number"!=typeof e.pos)throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");return new O(e.pos,t.markFromJSON(e.mark))}}S.jsonID("removeNodeMark",O);class N extends S{constructor(t,e,n,r=!1){super(),this.from=t,this.to=e,this.slice=n,this.structure=r}apply(t){return this.structure&&I(t,this.from,this.to)?v.fail("Structure replace would overwrite content"):v.fromReplace(t,this.from,this.to,this.slice)}getMap(){return new y([this.from,this.to-this.from,this.slice.size])}invert(t){return new N(this.from,this.from+this.slice.size,t.slice(this.from,this.to))}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deletedAcross&&n.deletedAcross?null:new N(e.pos,Math.max(e.pos,n.pos),this.slice)}merge(t){if(!(t instanceof N)||t.structure||this.structure)return null;if(this.from+this.slice.size!=t.from||this.slice.openEnd||t.slice.openStart){if(t.to!=this.from||this.slice.openStart||t.slice.openEnd)return null;{let e=this.slice.size+t.slice.size==0?u.empty:new u(t.slice.content.append(this.slice.content),t.slice.openStart,this.slice.openEnd);return new N(t.from,this.to,e,this.structure)}}{let e=this.slice.size+t.slice.size==0?u.empty:new u(this.slice.content.append(t.slice.content),this.slice.openStart,t.slice.openEnd);return new N(this.from,this.to+(t.to-t.from),e,this.structure)}}toJSON(){let t={stepType:"replace",from:this.from,to:this.to};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for ReplaceStep.fromJSON");return new N(e.from,e.to,u.fromJSON(t,e.slice),!!e.structure)}}S.jsonID("replace",N);class E extends S{constructor(t,e,n,r,i,o,s=!1){super(),this.from=t,this.to=e,this.gapFrom=n,this.gapTo=r,this.slice=i,this.insert=o,this.structure=s}apply(t){if(this.structure&&(I(t,this.from,this.gapFrom)||I(t,this.gapTo,this.to)))return v.fail("Structure gap-replace would overwrite content");let e=t.slice(this.gapFrom,this.gapTo);if(e.openStart||e.openEnd)return v.fail("Gap is not a flat range");let n=this.slice.insertAt(this.insert,e.content);return n?v.fromReplace(t,this.from,this.to,n):v.fail("Content does not fit in gap")}getMap(){return new y([this.from,this.gapFrom-this.from,this.insert,this.gapTo,this.to-this.gapTo,this.slice.size-this.insert])}invert(t){let e=this.gapTo-this.gapFrom;return new E(this.from,this.from+this.slice.size+e,this.from+this.insert,this.from+this.insert+e,t.slice(this.from,this.to).removeBetween(this.gapFrom-this.from,this.gapTo-this.from),this.gapFrom-this.from,this.structure)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1),r=this.from==this.gapFrom?e.pos:t.map(this.gapFrom,-1),i=this.to==this.gapTo?n.pos:t.map(this.gapTo,1);return e.deletedAcross&&n.deletedAcross||r<e.pos||i>n.pos?null:new E(e.pos,n.pos,r,i,this.slice,this.insert,this.structure)}toJSON(){let t={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to||"number"!=typeof e.gapFrom||"number"!=typeof e.gapTo||"number"!=typeof e.insert)throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new E(e.from,e.to,e.gapFrom,e.gapTo,u.fromJSON(t,e.slice),e.insert,!!e.structure)}}function I(t,e,n){let r=t.resolve(e),i=n-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let t=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!t||t.isLeaf)return!0;t=t.firstChild,i--}}return!1}S.jsonID("replaceAround",E);class R extends S{constructor(t,e,n){super(),this.pos=t,this.attr=e,this.value=n}apply(t){let e=t.nodeAt(this.pos);if(!e)return v.fail("No node at attribute step's position");let n=Object.create(null);for(let t in e.attrs)n[t]=e.attrs[t];n[this.attr]=this.value;let r=e.type.create(n,null,e.marks);return v.fromReplace(t,this.pos,this.pos+1,new u(s.from(r),0,e.isLeaf?0:1))}getMap(){return y.empty}invert(t){return new R(this.pos,this.attr,t.nodeAt(this.pos).attrs[this.attr])}map(t){let e=t.mapResult(this.pos,1);return e.deletedAfter?null:new R(e.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(t,e){if("number"!=typeof e.pos||"string"!=typeof e.attr)throw new RangeError("Invalid input for AttrStep.fromJSON");return new R(e.pos,e.attr,e.value)}}S.jsonID("attr",R);class z extends S{constructor(t,e){super(),this.attr=t,this.value=e}apply(t){let e=Object.create(null);for(let n in t.attrs)e[n]=t.attrs[n];e[this.attr]=this.value;let n=t.type.create(e,t.content,t.marks);return v.ok(n)}getMap(){return y.empty}invert(t){return new z(this.attr,t.attrs[this.attr])}map(t){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(t,e){if("string"!=typeof e.attr)throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new z(e.attr,e.value)}}S.jsonID("docAttr",z);let C=class extends Error{};C=function t(e){let n=Error.call(this,e);return n.__proto__=t.prototype,n},(C.prototype=Object.create(Error.prototype)).constructor=C,C.prototype.name="TransformError";const J=Object.create(null);class A{constructor(t,e,n){this.$anchor=t,this.$head=e,this.ranges=n||[new $(t.min(e),t.max(e))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let t=this.ranges;for(let e=0;e<t.length;e++)if(t[e].$from.pos!=t[e].$to.pos)return!1;return!0}content(){return this.$from.doc.slice(this.from,this.to,!0)}replace(t,e=u.empty){let n=e.content.lastChild,r=null;for(let t=0;t<e.openEnd;t++)r=n,n=n.lastChild;let i=t.steps.length,o=this.ranges;for(let s=0;s<o.length;s++){let{$from:a,$to:l}=o[s],h=t.mapping.slice(i);t.replaceRange(h.map(a.pos),h.map(l.pos),s?u.empty:e),0==s&&W(t,i,(n?n.isInline:r&&r.isTextblock)?-1:1)}}replaceWith(t,e){let n=t.steps.length,r=this.ranges;for(let i=0;i<r.length;i++){let{$from:o,$to:s}=r[i],a=t.mapping.slice(n),l=a.map(o.pos),h=a.map(s.pos);i?t.deleteRange(l,h):(t.replaceRangeWith(l,h,e),W(t,n,e.isInline?-1:1))}}static findFrom(t,e,n=!1){let r=t.parent.inlineContent?new j(t):P(t.node(0),t.parent,t.pos,t.index(),e,n);if(r)return r;for(let r=t.depth-1;r>=0;r--){let i=e<0?P(t.node(0),t.node(r),t.before(r+1),t.index(r),e,n):P(t.node(0),t.node(r),t.after(r+1),t.index(r)+1,e,n);if(i)return i}return null}static near(t,e=1){return this.findFrom(t,e)||this.findFrom(t,-e)||new q(t.node(0))}static atStart(t){return P(t,t,0,0,1)||new q(t)}static atEnd(t){return P(t,t,t.content.size,t.childCount,-1)||new q(t)}static fromJSON(t,e){if(!e||!e.type)throw new RangeError("Invalid input for Selection.fromJSON");let n=J[e.type];if(!n)throw new RangeError(`No selection type ${e.type} defined`);return n.fromJSON(t,e)}static jsonID(t,e){if(t in J)throw new RangeError("Duplicate use of selection JSON ID "+t);return J[t]=e,e.prototype.jsonID=t,e}getBookmark(){return j.between(this.$anchor,this.$head).getBookmark()}}A.prototype.visible=!0;class ${constructor(t,e){this.$from=t,this.$to=e}}let L=!1;function F(t){L||t.parent.inlineContent||(L=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+t.parent.type.name+")"))}class j extends A{constructor(t,e=t){F(t),F(e),super(t,e)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(t,e){let n=t.resolve(e.map(this.head));if(!n.parent.inlineContent)return A.near(n);let r=t.resolve(e.map(this.anchor));return new j(r.parent.inlineContent?r:n,n)}replace(t,e=u.empty){if(super.replace(t,e),e==u.empty){let e=this.$from.marksAcross(this.$to);e&&t.ensureMarks(e)}}eq(t){return t instanceof j&&t.anchor==this.anchor&&t.head==this.head}getBookmark(){return new D(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(t,e){if("number"!=typeof e.anchor||"number"!=typeof e.head)throw new RangeError("Invalid input for TextSelection.fromJSON");return new j(t.resolve(e.anchor),t.resolve(e.head))}static create(t,e,n=e){let r=t.resolve(e);return new this(r,n==e?r:t.resolve(n))}static between(t,e,n){let r=t.pos-e.pos;if(n&&!r||(n=r>=0?1:-1),!e.parent.inlineContent){let t=A.findFrom(e,n,!0)||A.findFrom(e,-n,!0);if(!t)return A.near(e,n);e=t.$head}return t.parent.inlineContent||(0==r||(t=(A.findFrom(t,-n,!0)||A.findFrom(t,n,!0)).$anchor).pos<e.pos!=r<0)&&(t=e),new j(t,e)}}A.jsonID("text",j);class D{constructor(t,e){this.anchor=t,this.head=e}map(t){return new D(t.map(this.anchor),t.map(this.head))}resolve(t){return j.between(t.resolve(this.anchor),t.resolve(this.head))}}class B extends A{constructor(t){let e=t.nodeAfter,n=t.node(0).resolve(t.pos+e.nodeSize);super(t,n),this.node=e}map(t,e){let{deleted:n,pos:r}=e.mapResult(this.anchor),i=t.resolve(r);return n?A.near(i):new B(i)}content(){return new u(s.from(this.node),0,0)}eq(t){return t instanceof B&&t.anchor==this.anchor}toJSON(){return{type:"node",anchor:this.anchor}}getBookmark(){return new H(this.anchor)}static fromJSON(t,e){if("number"!=typeof e.anchor)throw new RangeError("Invalid input for NodeSelection.fromJSON");return new B(t.resolve(e.anchor))}static create(t,e){return new B(t.resolve(e))}static isSelectable(t){return!t.isText&&!1!==t.type.spec.selectable}}B.prototype.visible=!1,A.jsonID("node",B);class H{constructor(t){this.anchor=t}map(t){let{deleted:e,pos:n}=t.mapResult(this.anchor);return e?new D(n,n):new H(n)}resolve(t){let e=t.resolve(this.anchor),n=e.nodeAfter;return n&&B.isSelectable(n)?new B(e):A.near(e)}}class q extends A{constructor(t){super(t.resolve(0),t.resolve(t.content.size))}replace(t,e=u.empty){if(e==u.empty){t.delete(0,t.doc.content.size);let e=A.atStart(t.doc);e.eq(t.selection)||t.setSelection(e)}else super.replace(t,e)}toJSON(){return{type:"all"}}static fromJSON(t){return new q(t)}map(t){return new q(t)}eq(t){return t instanceof q}getBookmark(){return _}}A.jsonID("all",q);const _={map(){return this},resolve:t=>new q(t)};function P(t,e,n,r,i,o=!1){if(e.inlineContent)return j.create(t,n);for(let s=r-(i>0?0:1);i>0?s<e.childCount:s>=0;s+=i){let r=e.child(s);if(r.isAtom){if(!o&&B.isSelectable(r))return B.create(t,n-(i<0?r.nodeSize:0))}else{let e=P(t,r,n+i,i<0?r.childCount:0,i,o);if(e)return e}n+=r.nodeSize*i}return null}function W(t,e,n){let r=t.steps.length-1;if(r<e)return;let i,o=t.steps[r];(o instanceof N||o instanceof E)&&(t.mapping.maps[r].forEach(((t,e,n,r)=>{null==i&&(i=r)})),t.setSelection(A.near(t.doc.resolve(i),n)))}function U(t,e){return e&&t?t.bind(e):t}class Y{constructor(t,e,n){this.name=t,this.init=U(e.init,n),this.apply=U(e.apply,n)}}function V(t,e,n){for(let r in t){let i=t[r];i instanceof Function?i=i.bind(e):"handleDOMEvents"==r&&(i=V(i,e,{})),n[r]=i}return n}new Y("doc",{init:t=>t.doc||t.schema.topNodeType.createAndFill(),apply:t=>t.doc}),new Y("selection",{init:(t,e)=>t.selection||A.atStart(e.doc),apply:t=>t.selection}),new Y("storedMarks",{init:t=>t.storedMarks||null,apply:(t,e,n,r)=>r.selection.$cursor?t.storedMarks:null}),new Y("scrollToSelection",{init:()=>0,apply:(t,e)=>t.scrolledIntoView?e+1:e});class Z{constructor(t){this.spec=t,this.props={},t.props&&V(t.props,this,this.props),this.key=t.key?t.key.key:K("plugin")}getState(t){return t[this.key]}}const G=Object.create(null);function K(t){return t in G?t+"$"+ ++G[t]:(G[t]=0,t+"$")}class X{constructor(t="key"){this.key=K(t)}get(t){return t.config.pluginsByKey[this.key]}getState(t){return t[this.key]}}function Q(t,e){const n=Object.keys(e);return!n.length||n.every((n=>e[n]===t[n]))}function tt(t,e,n={}){return t.find((t=>t.type===e&&Q(Object.fromEntries(Object.keys(n).map((e=>[e,t.attrs[e]]))),n)))}function et(t,e,n={}){return!!tt(t,e,n)}function nt(t,e,n){if(!t||!e)return;let r=t.parent.childAfter(t.parentOffset);if(r.node&&r.node.marks.some((t=>t.type===e))||(r=t.parent.childBefore(t.parentOffset)),!r.node||!r.node.marks.some((t=>t.type===e)))return;const i=n||r.node.marks[0]?.attrs;if(!tt([...r.node.marks],e,i))return;let o=r.index,s=t.start()+r.offset,a=o+1,l=s+r.node.nodeSize;for(;o>0&&et([...t.parent.child(o-1).marks],e,i);)o-=1,s-=t.parent.child(o).nodeSize;for(;a<t.parent.childCount&&et([...t.parent.child(a).marks],e,i);)l+=t.parent.child(a).nodeSize,a+=1;return{from:s,to:l}}function rt(t,e={}){const n=document.createElement(t);e.className&&(n.className=e.className);for(const[t,r]of Object.entries(e.attributes||{}))null!==r&&"null"!==r&&void 0!==r&&"undefined"!==r&&n.setAttribute(t,r);for(const t of e.children||[])n.append("string"==typeof t?document.createTextNode(t):t);return n}const it=(ot=/[\dA-Za-z]/,function(t){return null!==t&&t>-1&&ot.test(String.fromCharCode(t))});var ot;const st={'"':"quot","&":"amp","<":"lt",">":"gt"};function at(t,e){const n=function(t){return t.replace(/["&<>]/g,(function(t){return"&"+st[t]+";"}))}(function(t){const e=[];let n=-1,r=0,i=0;for(;++n<t.length;){const o=t.charCodeAt(n);let s="";if(37===o&&it(t.charCodeAt(n+1))&&it(t.charCodeAt(n+2)))i=2;else if(o<128)/[!#$&-;=?-Z_a-z~]/.test(String.fromCharCode(o))||(s=String.fromCharCode(o));else if(o>55295&&o<57344){const e=t.charCodeAt(n+1);o<56320&&e>56319&&e<57344?(s=String.fromCharCode(o,e),i=1):s="�"}else s=String.fromCharCode(o);s&&(e.push(t.slice(r,n),encodeURIComponent(s)),r=n+i+1,s=""),i&&(n+=i,i=0)}return e.join("")+t.slice(r)}(t||""));if(!e)return n;const r=n.indexOf(":"),i=n.indexOf("?"),o=n.indexOf("#"),s=n.indexOf("/");return r<0||s>-1&&r>s||i>-1&&r>i||o>-1&&r>o||e.test(n.slice(0,r))?n:""}const lt=t=>("string"==typeof t&&(t=t.trim()),function(t,e="http"){if(!t)return;if(/^(https?:\/\/|\/|\/\/|#)/.test(t))return t;return`${e}://${encodeURIComponent(t)}`}(at(t,/^https?$/i)));class ht{editor;view;menuItems;textTooltip;mediaTooltip;linkInputField;updateLock=!1;windowHandlers={};constructor({editor:t,view:e,menuitems:n}){this.editor=t,this.view=e,this.menuItems=Object.fromEntries(n.map((t=>[t.name,t]))),this.textTooltip=this.createTooltip(n.filter((t=>"text"===t.type))),this.mediaTooltip=this.createTooltip(n.filter((t=>"media"===t.type)),"highlightMenu-media"),this.view.dom.parentElement?.append(this.textTooltip,this.mediaTooltip),this.attachEventListeners()}createTooltip(t,e=""){const n=rt("div",{className:`highlightMenu ${e}`}),r=rt("div",{className:"highlightMenu-inner"}),i=rt("div",{className:"buttonSet"});if(this.createMenuButtons(t,i),t.some((t=>"link"===t.name))){const t=this.createLinkInput();r.append(i,t),this.linkInputField=t.querySelector("input")}else r.appendChild(i);const o=rt("div",{className:"highlightMenu-arrowClip"});return o.appendChild(rt("span",{className:"highlightMenu-arrow"})),n.append(r,o),n}createMenuButtons(t,e){for(const n of t)e.appendChild(this.createButton(n)),n.divider&&e.appendChild(rt("div",{className:"buttonSet-separator"}))}createButton(t){const e=rt("button",{className:"button--highlightMenu",attributes:{"data-action":t.name,title:t.title}});return t.icon&&(e.innerHTML=t.icon),e}createLinkInput(){const t=rt("div",{className:"highlightMenu-linkinput"}),e=rt("input",{className:"highlightMenu-linkinputField",attributes:{type:"text",placeholder:this.editor.options.messages.linkPlaceholder}});e.addEventListener("blur",(()=>this.handleLinkBlur())),e.addEventListener("keyup",(t=>{"Enter"===t.key?this.handleSetLink():"Escape"===t.key&&this.handleLinkBlur()}));const n=this.createButton({name:"cancelLink",title:"",icon:this.editor.options.icons.removeThin});return t.append(e,n),t}attachEventListeners(){this.windowHandlers={blur:()=>this.hideTooltip(),focus:()=>this.update(),visibilitychange:()=>!document.hidden&&this.update(),mousedown:this.onDocumentMouseDown.bind(this),mouseup:this.onDocumentMouseUp.bind(this)},window.addEventListener("blur",this.windowHandlers.blur),window.addEventListener("focus",this.windowHandlers.focus),document.addEventListener("visibilitychange",this.windowHandlers.visibilitychange),document.addEventListener("mousedown",this.windowHandlers.mousedown),document.addEventListener("mouseup",this.windowHandlers.mouseup),this.textTooltip.addEventListener("mousedown",(t=>t.preventDefault())),this.mediaTooltip.addEventListener("mousedown",(t=>t.preventDefault()))}onDocumentMouseDown(t){const e=t.target;this.updateLock=this.view.dom.contains(e)||this.textTooltip.contains(e)||this.mediaTooltip.contains(e),this.updateLock||this.hideTooltip()}onDocumentMouseUp(t){this.updateLock=!1;const e=t.target;this.textTooltip.contains(e)||this.mediaTooltip.contains(e)?this.handleTooltipClick(e):this.update()}handleTooltipClick(t){const e=t.closest("button.button--highlightMenu");if(!e)return;const n=e.dataset.action;if(!n)return;const{state:r,dispatch:i}=this.view;"link"===n?this.handleLinkAction(r,i):this.menuItems[n]?.execute?.(r,i),this.update()}handleLinkAction(t,e){!function(t,e,n={},r=!0){const{empty:i,ranges:o}=t.selection;if(i)return!!(t.storedMarks||t.selection.$from.marks()).filter((t=>!e||e.name===t.type.name)).find((t=>Q(t.attrs,n)));let s=0;const a=[];for(const{$from:e,$to:n}of o){const r=e.pos,i=n.pos;t.doc.nodesBetween(r,i,((t,e)=>{if(!t.isText&&!t.marks.length)return;const n=Math.max(r,e),o=Math.min(i,e+t.nodeSize);s+=o-n,a.push(...t.marks.map((t=>({mark:t,from:n,to:o}))))}))}if(0===s)return!1;const l=a.filter((t=>!e||e.name===t.mark.type.name)).filter((t=>Q(t.mark.attrs,n))).reduce(((t,e)=>t+e.to-e.from),0);if(!r)return l>0;const h=a.filter((t=>!e||t.mark.type!==e&&t.mark.type.excludes(e))).reduce(((t,e)=>t+e.to-e.from),0);return(l>0?l+h:l)>=s}(t,t.schema.marks.link,{},!1)?(this.updateLock=!0,this.textTooltip.classList.add("highlightMenu--linkMode"),this.linkInputField.focus()):((t,e={})=>(n,r)=>{const{extendEmptyMarkRange:i=!1,fullyRemoveMark:o=!1}=e,{selection:s,tr:a}=n,{$from:l,empty:h,ranges:c}=s;if(!r)return!0;if(h&&i){let{from:e,to:n}=s;const r=l.marks().find((e=>e.type===t))?.attrs,i=nt(l,t,r);i&&(e=i.from,n=i.to),a.removeMark(e,n,t)}else if(o)for(const{$from:e,$to:n}of c){let r=e.pos,i=n.pos;const o=nt(e,t),s=nt(n,t);o&&(r=Math.min(r,o.from)),s&&(i=Math.max(i,s.to)),a.removeMark(r,i,t)}else for(const{$from:e,$to:n}of c)a.removeMark(e.pos,n.pos,t);return a.removeStoredMark(t),r(a),!0})(t.schema.marks.link,{fullyRemoveMark:!0})(t,e)}handleSetLink(){this.updateLock=!1;const t=this.linkInputField.value.trim();this.linkInputField.blur();const e=lt(t);if(e){const{state:t,dispatch:n}=this.view;((t,e={})=>(n,r)=>{const{selection:i,tr:o}=n,{empty:s,ranges:a}=i;if(r){if(s){const r=function(t,e){const{from:n,to:r,empty:i}=t.selection,o=[];i?(t.storedMarks&&o.push(...t.storedMarks),o.push(...t.selection.$head.marks())):t.doc.nodesBetween(n,r,(t=>{o.push(...t.marks)}));const s=o.find((t=>t.type.name===e.name));return s?{...s.attrs}:{}}(n,t);o.addStoredMark(t.create({...r,...e}))}else for(const r of a){const i=r.$from.pos,s=r.$to.pos;n.doc.nodesBetween(i,s,((n,r)=>{const a=Math.max(r,i),l=Math.min(r+n.nodeSize,s);if(n.marks.find((e=>e.type===t)))for(const r of n.marks)t===r.type&&o.addMark(a,l,t.create({...r.attrs,...e}));else o.addMark(a,l,t.create(e))}))}r(o)}return!1})(t.schema.marks.link,{class:"markup--anchor markup--p-anchor",href:e,"data-tooltip":e,"data-tooltip-position":"bottom",target:"_blank"})(t,n);const r=window.getSelection();if(r){const t=r.getRangeAt(0);t.collapse(!0),r.removeAllRanges(),r.addRange(t)}}this.linkInputField.value=""}handleLinkBlur(){this.hideTooltip(),this.view.focus(),this.update()}showTooltip(t){const e=window.getSelection()?.getRangeAt(0);if(e){const n=e.getBoundingClientRect();t.style.display="inline-block";const{top:r,left:i}=this.calculateTooltipPosition(t,n);t.style.removeProperty("display"),t.style.top=`${r}px`,t.style.left=`${i}px`,t.offsetWidth,t.classList.add("highlightMenu--active")}}updateTooltipItemsStatus(t){const{state:e}=this.view,n=t.querySelectorAll(".buttonSet > button");for(const t of n){const n=t.dataset.action,r=this.menuItems[n],i=r.isVisible?.(e)??!0;if(t.style.display=i?"":"none",i){const n=r.canActivate?.(e)??!0;t.toggleAttribute("disabled",!n),t.classList.toggle("is-active",r.isActive?.(e)??!0)}}}calculateTooltipPosition(t,e){const n=t.offsetWidth,r=t===this.textTooltip?6:20,i=t.offsetHeight+r,o=window.innerWidth,s=e.top+window.scrollY-i;let a=e.left+window.scrollX-n/2+e.width/2;return a=Math.max(10,Math.min(a,o-n-10)),{top:s,left:a}}handleDblClick(){}hideTooltip(t){t?t.classList.remove("highlightMenu--active","highlightMenu--linkMode"):(this.textTooltip.classList.remove("highlightMenu--active","highlightMenu--linkMode"),this.mediaTooltip.classList.remove("highlightMenu--active"))}scrollToMedia(t){const e=(this.editor.storage?.media?.mediaFocusOffset??0)+50,n=t.getBoundingClientRect(),r=window.innerHeight;let i=0;n.top<e?i=window.scrollY+n.top-e:n.bottom>r-e&&(i=window.scrollY+(n.bottom-r)+e),0!==i&&window.scrollTo({top:i,behavior:this.editor.storage?.media?.mediaFocusScrollBehavior??"smooth"})}update(){if(this.updateLock)return;const{state:t}=this.view,{selection:e,schema:n}=t,{$from:r}=e;if(!e.empty&&this.view.hasFocus()){if(!r.parent.type.spec.code){if(e instanceof B){const t=e.node.type.name;if("image"===t||"iframe"===t){const t=this.view.nodeDOM(e.from);this.scrollToMedia(t);const n=t.parentElement?.parentElement;return n?.classList.contains("images-grid")?void this.hideTooltip():(this.hideTooltip(this.textTooltip),this.updateTooltipItemsStatus(this.mediaTooltip),void this.showTooltip(this.mediaTooltip))}}this.hideTooltip(this.mediaTooltip),this.updateTooltipItemsStatus(this.textTooltip),this.showTooltip(this.textTooltip)}}else this.hideTooltip()}destroy(){this.textTooltip.remove(),this.mediaTooltip.remove(),window.removeEventListener("blur",this.windowHandlers.blur),window.removeEventListener("focus",this.windowHandlers.focus),document.removeEventListener("visibilitychange",this.windowHandlers.visibilitychange),document.removeEventListener("mousedown",this.windowHandlers.mousedown),document.removeEventListener("mouseup",this.windowHandlers.mouseup)}}const ct=r.create({name:"highlightMenu",priority:-100,addPlugins(){const t=this.features.flatMap((t=>t.config?.addHighlightMenuItems?t.config.addHighlightMenuItems.call({name:t.config.name,editor:this.editor,options:t.options,storage:t.storage,schema:this.schema,view:this.view,commands:this.commands,features:this.features}):[])).filter((t=>t&&!1!==this.options?.[t.name])).map((t=>({...t,...this.options?.[t.name]||{}}))).sort(((t,e)=>(e.priority||100)-(t.priority||100)));return[(e={menuitems:t,editor:this.editor,view:this.view},new Z({key:new X("highlightMenu"),view:()=>new ht(e)}))];var e}});t.HighlightMenu=ct,Object.defineProperty(t,"__esModule",{value:!0})}));