overtype 1.1.6 → 1.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/overtype.esm.js +25 -2
- package/dist/overtype.esm.js.map +2 -2
- package/dist/overtype.js +25 -2
- package/dist/overtype.js.map +2 -2
- package/dist/overtype.min.js +10 -10
- package/package.json +1 -1
- package/src/parser.js +41 -1
package/dist/overtype.min.js
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OverType v1.1.
|
|
2
|
+
* OverType v1.1.7
|
|
3
3
|
* A lightweight markdown editor library with perfect WYSIWYG alignment
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @author Demo User
|
|
6
6
|
* https://github.com/demo/overtype
|
|
7
7
|
*/
|
|
8
|
-
var OverType=(()=>{var
|
|
8
|
+
var OverType=(()=>{var N=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var je=Object.prototype.hasOwnProperty;var Oe=(n,e,t)=>e in n?N(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var Pe=(n,e)=>{for(var t in e)N(n,t,{get:e[t],enumerable:!0})},Ne=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Be(e))!je.call(n,i)&&i!==t&&N(n,i,{get:()=>e[i],enumerable:!(o=Ie(e,i))||o.enumerable});return n};var ze=n=>Ne(N({},"__esModule",{value:!0}),n);var M=(n,e,t)=>(Oe(n,typeof e!="symbol"?e+"":e,t),t);var Xe={};Pe(Xe,{OverType:()=>A,default:()=>Ge});var I=class{static resetLinkIndex(){this.linkIndex=0}static escapeHtml(e){let t={"&":"&","<":"<",">":">",'"':""","'":"'"};return e.replace(/[&<>"']/g,o=>t[o])}static preserveIndentation(e,t){let i=t.match(/^(\s*)/)[1].replace(/ /g," ");return e.replace(/^\s*/,i)}static parseHeader(e){return e.replace(/^(#{1,3})\s(.+)$/,(t,o,i)=>{let r=o.length;return`<span class="header ${["h1","h2","h3"][r-1]}"><span class="syntax-marker">${o}</span> ${i}</span>`})}static parseHorizontalRule(e){return e.match(/^(-{3,}|\*{3,}|_{3,})$/)?`<div><span class="hr-marker">${e}</span></div>`:null}static parseBlockquote(e){return e.replace(/^> (.+)$/,(t,o)=>`<span class="blockquote"><span class="syntax-marker">></span> ${o}</span>`)}static parseBulletList(e){return e.replace(/^((?: )*)([-*])\s(.+)$/,(t,o,i,r)=>`${o}<span class="syntax-marker">${i}</span> ${r}`)}static parseNumberedList(e){return e.replace(/^((?: )*)(\d+\.)\s(.+)$/,(t,o,i,r)=>`${o}<span class="syntax-marker">${i}</span> ${r}`)}static parseCodeBlock(e){return/^`{3}[^`]*$/.test(e)?`<div><span class="code-fence">${e}</span></div>`:null}static parseBold(e){return e=e.replace(/\*\*(.+?)\*\*/g,'<strong><span class="syntax-marker">**</span>$1<span class="syntax-marker">**</span></strong>'),e=e.replace(/__(.+?)__/g,'<strong><span class="syntax-marker">__</span>$1<span class="syntax-marker">__</span></strong>'),e}static parseItalic(e){return e=e.replace(new RegExp("(?<!\\*)\\*(?!\\*)(.+?)(?<!\\*)\\*(?!\\*)","g"),'<em><span class="syntax-marker">*</span>$1<span class="syntax-marker">*</span></em>'),e=e.replace(new RegExp("(?<!_)_(?!_)(.+?)(?<!_)_(?!_)","g"),'<em><span class="syntax-marker">_</span>$1<span class="syntax-marker">_</span></em>'),e}static parseInlineCode(e){return e.replace(new RegExp("(?<!`)(`+)(?!`)((?:(?!\\1).)+?)(\\1)(?!`)","g"),'<code><span class="syntax-marker">$1</span>$2<span class="syntax-marker">$3</span></code>')}static sanitizeUrl(e){let t=e.trim(),o=t.toLowerCase(),r=["http://","https://","mailto:","ftp://","ftps://"].some(s=>o.startsWith(s)),a=t.startsWith("/")||t.startsWith("#")||t.startsWith("?")||t.startsWith(".")||!t.includes(":")&&!t.includes("//");return r||a?e:"#"}static parseLinks(e){return e.replace(/\[(.+?)\]\((.+?)\)/g,(t,o,i)=>{let r=`--link-${this.linkIndex++}`;return`<a href="${this.sanitizeUrl(i)}" style="anchor-name: ${r}"><span class="syntax-marker">[</span>${o}<span class="syntax-marker">](</span><span class="syntax-marker link-url">${i}</span><span class="syntax-marker">)</span></a>`})}static parseInlineElements(e){let t=e;t=this.parseInlineCode(t);let o=new Map;return t=t.replace(/(<code>.*?<\/code>)/g,i=>{let r=`\uE000${o.size}\uE001`;return o.set(r,i),r}),t=this.parseLinks(t),t=t.replace(/(<a[^>]*>.*?<\/a>)/g,i=>{let r=`\uE000${o.size}\uE001`;return o.set(r,i),r}),t=this.parseBold(t),t=this.parseItalic(t),o.forEach((i,r)=>{t=t.replace(r,i)}),t}static parseLine(e){let t=this.escapeHtml(e);t=this.preserveIndentation(t,e);let o=this.parseHorizontalRule(t);if(o)return o;let i=this.parseCodeBlock(t);return i||(t=this.parseHeader(t),t=this.parseBlockquote(t),t=this.parseBulletList(t),t=this.parseNumberedList(t),t=this.parseInlineElements(t),t.trim()===""?"<div> </div>":`<div>${t}</div>`)}static parse(e,t=-1,o=!1){return this.resetLinkIndex(),e.split(`
|
|
9
9
|
`).map((a,s)=>o&&s===t?`<div class="raw-line">${this.escapeHtml(a)||" "}</div>`:this.parseLine(a)).join("")}};M(I,"linkIndex",0);var _e=Object.defineProperty,Y=Object.getOwnPropertySymbols,Fe=Object.prototype.hasOwnProperty,Re=Object.prototype.propertyIsEnumerable,ee=(n,e,t)=>e in n?_e(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t,te=(n,e)=>{for(var t in e||(e={}))Fe.call(e,t)&&ee(n,t,e[t]);if(Y)for(var t of Y(e))Re.call(e,t)&&ee(n,t,e[t]);return n},S={bold:{prefix:"**",suffix:"**",trimFirst:!0},italic:{prefix:"_",suffix:"_",trimFirst:!0},code:{prefix:"`",suffix:"`",blockPrefix:"```",blockSuffix:"```"},link:{prefix:"[",suffix:"](url)",replaceNext:"url",scanFor:"https?://"},bulletList:{prefix:"- ",multiline:!0,unorderedList:!0},numberedList:{prefix:"1. ",multiline:!0,orderedList:!0},quote:{prefix:"> ",multiline:!0,surroundWithNewlines:!0},taskList:{prefix:"- [ ] ",multiline:!0,surroundWithNewlines:!0},header1:{prefix:"# "},header2:{prefix:"## "},header3:{prefix:"### "},header4:{prefix:"#### "},header5:{prefix:"##### "},header6:{prefix:"###### "}};function Ve(){return{prefix:"",suffix:"",blockPrefix:"",blockSuffix:"",multiline:!1,replaceNext:"",prefixSpace:!1,scanFor:"",surroundWithNewlines:!1,orderedList:!1,unorderedList:!1,trimFirst:!1}}function E(n){return te(te({},Ve()),n)}var _=!1;function De(){return _}function g(n,e,t){_&&(console.group(`\u{1F50D} ${n}`),console.log(e),t&&console.log("Data:",t),console.groupEnd())}function z(n,e){if(!_)return;let t=n.value.slice(n.selectionStart,n.selectionEnd);console.group(`\u{1F4CD} Selection: ${e}`),console.log("Position:",`${n.selectionStart}-${n.selectionEnd}`),console.log("Selected text:",JSON.stringify(t)),console.log("Length:",t.length);let o=n.value.slice(Math.max(0,n.selectionStart-10),n.selectionStart),i=n.value.slice(n.selectionEnd,Math.min(n.value.length,n.selectionEnd+10));console.log("Context:",JSON.stringify(o)+"[SELECTION]"+JSON.stringify(i)),console.groupEnd()}function re(n){_&&(console.group("\u{1F4DD} Result"),console.log("Text to insert:",JSON.stringify(n.text)),console.log("New selection:",`${n.selectionStart}-${n.selectionEnd}`),console.groupEnd())}var C=null;function H(n,{text:e,selectionStart:t,selectionEnd:o}){let i=De();i&&(console.group("\u{1F527} insertText"),console.log("Current selection:",`${n.selectionStart}-${n.selectionEnd}`),console.log("Text to insert:",JSON.stringify(e)),console.log("New selection to set:",t,"-",o)),n.focus();let r=n.selectionStart,a=n.selectionEnd,s=n.value.slice(0,r),l=n.value.slice(a);i&&(console.log("Before text (last 20):",JSON.stringify(s.slice(-20))),console.log("After text (first 20):",JSON.stringify(l.slice(0,20))),console.log("Selected text being replaced:",JSON.stringify(n.value.slice(r,a))));let d=n.value,p=r!==a;if(C===null||C===!0){n.contentEditable="true";try{C=document.execCommand("insertText",!1,e),i&&console.log("execCommand returned:",C,"for text with",e.split(`
|
|
10
10
|
`).length,"lines")}catch(c){C=!1,i&&console.log("execCommand threw error:",c)}n.contentEditable="false"}if(i&&(console.log("canInsertText before:",C),console.log("execCommand result:",C)),C){let c=s+e+l,m=n.value;i&&(console.log("Expected length:",c.length),console.log("Actual length:",m.length)),m!==c&&i&&(console.log("execCommand changed the value but not as expected"),console.log("Expected:",JSON.stringify(c.slice(0,100))),console.log("Actual:",JSON.stringify(m.slice(0,100))))}if(!C)if(i&&console.log("Using manual insertion"),n.value===d){i&&console.log("Value unchanged, doing manual replacement");try{document.execCommand("ms-beginUndoUnit")}catch(c){}n.value=s+e+l;try{document.execCommand("ms-endUndoUnit")}catch(c){}n.dispatchEvent(new CustomEvent("input",{bubbles:!0,cancelable:!0}))}else i&&console.log("Value was changed by execCommand, skipping manual insertion");i&&console.log("Setting selection range:",t,o),t!=null&&o!=null?n.setSelectionRange(t,o):n.setSelectionRange(r,n.selectionEnd),i&&(console.log("Final value length:",n.value.length),console.groupEnd())}function ne(n){return n.trim().split(`
|
|
11
11
|
`).length>1}function qe(n,e){let t=e;for(;n[t]&&n[t-1]!=null&&!n[t-1].match(/\s/);)t--;return t}function We(n,e,t){let o=e,i=t?/\n/:/\s/;for(;n[o]&&!n[o].match(i);)o++;return o}function se(n){let e=n.value.split(`
|
|
12
|
-
`),t=0;for(let o=0;o<e.length;o++){let i=e[o].length+1;n.selectionStart>=t&&n.selectionStart<t+i&&(n.selectionStart=t),n.selectionEnd>=t&&n.selectionEnd<t+i&&(o===e.length-1?n.selectionEnd=Math.min(t+e[o].length,n.value.length):n.selectionEnd=t+i-1),t+=i}}function
|
|
12
|
+
`),t=0;for(let o=0;o<e.length;o++){let i=e[o].length+1;n.selectionStart>=t&&n.selectionStart<t+i&&(n.selectionStart=t),n.selectionEnd>=t&&n.selectionEnd<t+i&&(o===e.length-1?n.selectionEnd=Math.min(t+e[o].length,n.value.length):n.selectionEnd=t+i-1),t+=i}}function Ue(n,e,t,o=!1){if(n.selectionStart===n.selectionEnd)n.selectionStart=qe(n.value,n.selectionStart),n.selectionEnd=We(n.value,n.selectionEnd,o);else{let i=n.selectionStart-e.length,r=n.selectionEnd+t.length,a=n.value.slice(i,n.selectionStart)===e,s=n.value.slice(n.selectionEnd,r)===t;a&&s&&(n.selectionStart=i,n.selectionEnd=r)}return n.value.slice(n.selectionStart,n.selectionEnd)}function J(n){let e=n.value.slice(0,n.selectionStart),t=n.value.slice(n.selectionEnd),o=e.match(/\n*$/),i=t.match(/^\n*/),r=o?o[0].length:0,a=i?i[0].length:0,s="",l="";return e.match(/\S/)&&r<2&&(s=`
|
|
13
13
|
`.repeat(2-r)),t.match(/\S/)&&a<2&&(l=`
|
|
14
14
|
`.repeat(2-a)),{newlinesToAppend:s,newlinesToPrepend:l}}function F(n,e,t={}){let o=n.selectionStart,i=n.selectionEnd,r=o===i,a=n.value,s=o;for(;s>0&&a[s-1]!==`
|
|
15
15
|
`;)s--;if(r){let d=o;for(;d<a.length&&a[d]!==`
|
|
16
16
|
`;)d++;n.selectionStart=s,n.selectionEnd=d}else se(n);let l=e(n);if(t.adjustSelection){let p=n.value.slice(n.selectionStart,n.selectionEnd).startsWith(t.prefix),c=t.adjustSelection(p,o,i,s);l.selectionStart=c.start,l.selectionEnd=c.end}else if(t.prefix){let p=n.value.slice(n.selectionStart,n.selectionEnd).startsWith(t.prefix);r?p?(l.selectionStart=Math.max(o-t.prefix.length,s),l.selectionEnd=l.selectionStart):(l.selectionStart=o+t.prefix.length,l.selectionEnd=l.selectionStart):p?(l.selectionStart=Math.max(o-t.prefix.length,s),l.selectionEnd=Math.max(i-t.prefix.length,s)):(l.selectionStart=o+t.prefix.length,l.selectionEnd=i+t.prefix.length)}return l}function R(n,e){let t,o,{prefix:i,suffix:r,blockPrefix:a,blockSuffix:s,replaceNext:l,prefixSpace:d,scanFor:p,surroundWithNewlines:c,trimFirst:m}=e,h=n.selectionStart,v=n.selectionEnd,f=n.value.slice(n.selectionStart,n.selectionEnd),u=ne(f)&&a&&a.length>0?`${a}
|
|
17
17
|
`:i,b=ne(f)&&s&&s.length>0?`
|
|
18
|
-
${s}`:r;if(d){let x=n.value[n.selectionStart-1];n.selectionStart!==0&&x!=null&&!x.match(/\s/)&&(u=` ${u}`)}f=
|
|
18
|
+
${s}`:r;if(d){let x=n.value[n.selectionStart-1];n.selectionStart!==0&&x!=null&&!x.match(/\s/)&&(u=` ${u}`)}f=Ue(n,u,b,e.multiline);let y=n.selectionStart,w=n.selectionEnd,T=l&&l.length>0&&b.indexOf(l)>-1&&f.length>0;if(c){let x=J(n);t=x.newlinesToAppend,o=x.newlinesToPrepend,u=t+i,b+=o}if(f.startsWith(u)&&f.endsWith(b)){let x=f.slice(u.length,f.length-b.length);if(h===v){let L=h-u.length;L=Math.max(L,y),L=Math.min(L,y+x.length),y=w=L}else w=y+x.length;return{text:x,selectionStart:y,selectionEnd:w}}else if(T)if(p&&p.length>0&&f.match(p)){b=b.replace(l,f);let x=u+b;return y=w=y+u.length,{text:x,selectionStart:y,selectionEnd:w}}else{let x=u+f+b;return y=y+u.length+f.length+b.indexOf(l),w=y+l.length,{text:x,selectionStart:y,selectionEnd:w}}else{let x=u+f+b;y=h+u.length,w=v+u.length;let L=f.match(/^\s*|\s*$/g);if(m&&L){let G=L[0]||"",X=L[1]||"";x=G+u+f.trim()+b+X,y+=G.length,w-=X.length}return{text:x,selectionStart:y,selectionEnd:w}}}function ae(n,e){let{prefix:t,suffix:o,surroundWithNewlines:i}=e,r=n.value.slice(n.selectionStart,n.selectionEnd),a=n.selectionStart,s=n.selectionEnd,l=r.split(`
|
|
19
19
|
`);if(l.every(p=>p.startsWith(t)&&(!o||p.endsWith(o))))r=l.map(p=>{let c=p.slice(t.length);return o&&(c=c.slice(0,c.length-o.length)),c}).join(`
|
|
20
20
|
`),s=a+r.length;else if(r=l.map(p=>t+p+(o||"")).join(`
|
|
21
21
|
`),i){let{newlinesToAppend:p,newlinesToPrepend:c}=J(n);a+=p.length,s=a+r.length,r=p+r+c}return{text:r,selectionStart:a,selectionEnd:s}}function oe(n){let e=n.split(`
|
|
22
22
|
`),t=/^\d+\.\s+/,o=e.every(r=>t.test(r)),i=e;return o&&(i=e.map(r=>r.replace(t,""))),{text:i.join(`
|
|
23
23
|
`),processed:o}}function ie(n){let e=n.split(`
|
|
24
24
|
`),t="- ",o=e.every(r=>r.startsWith(t)),i=e;return o&&(i=e.map(r=>r.slice(t.length))),{text:i.join(`
|
|
25
|
-
`),processed:o}}function j(n,e){return e?"- ":`${n+1}. `}function
|
|
25
|
+
`),processed:o}}function j(n,e){return e?"- ":`${n+1}. `}function Ke(n,e){let t,o,i;return n.orderedList?(t=oe(e),o=ie(t.text),i=o.text):(t=ie(e),o=oe(t.text),i=o.text),[t,o,i]}function Ze(n,e){let t=n.selectionStart===n.selectionEnd,o=n.selectionStart,i=n.selectionEnd;se(n);let r=n.value.slice(n.selectionStart,n.selectionEnd),[a,s,l]=Ke(e,r),d=l.split(`
|
|
26
26
|
`).map((f,u)=>`${j(u,e.unorderedList)}${f}`),p=d.reduce((f,u,b)=>f+j(b,e.unorderedList).length,0),c=d.reduce((f,u,b)=>f+j(b,!e.unorderedList).length,0);if(a.processed)return t?(o=Math.max(o-j(0,e.unorderedList).length,0),i=o):(o=n.selectionStart,i=n.selectionEnd-p),{text:l,selectionStart:o,selectionEnd:i};let{newlinesToAppend:m,newlinesToPrepend:h}=J(n),v=m+d.join(`
|
|
27
27
|
`)+h;return t?(o=Math.max(o+j(0,e.unorderedList).length+m.length,0),i=o):s.processed?(o=Math.max(n.selectionStart+m.length,0),i=n.selectionEnd+m.length+p-c):(o=Math.max(n.selectionStart+m.length,0),i=n.selectionEnd+m.length+p),{text:v,selectionStart:o,selectionEnd:i}}function le(n,e){let t=F(n,o=>Ze(o,e),{adjustSelection:(o,i,r,a)=>{let s=n.value.slice(a,n.selectionEnd),l=/^\d+\.\s+/,d=/^- /,p=l.test(s),c=d.test(s),m=e.orderedList&&p||e.unorderedList&&c;if(i===r)if(m){let h=s.match(e.orderedList?l:d),v=h?h[0].length:0;return{start:Math.max(i-v,a),end:Math.max(i-v,a)}}else if(p||c){let h=s.match(p?l:d),v=h?h[0].length:0,u=(e.unorderedList?2:3)-v;return{start:i+u,end:i+u}}else{let h=e.unorderedList?2:3;return{start:i+h,end:i+h}}else if(m){let h=s.match(e.orderedList?l:d),v=h?h[0].length:0;return{start:Math.max(i-v,a),end:Math.max(r-v,a)}}else if(p||c){let h=s.match(p?l:d),v=h?h[0].length:0,u=(e.unorderedList?2:3)-v;return{start:i+u,end:r+u}}else{let h=e.unorderedList?2:3;return{start:i+h,end:r+h}}}});H(n,t)}function Je(n){if(!n)return[];let e=[],{selectionStart:t,selectionEnd:o,value:i}=n,r=i.split(`
|
|
28
|
-
`),a=0,s="";for(let c of r){if(t>=a&&t<=a+c.length){s=c;break}a+=c.length+1}s.startsWith("- ")&&(s.startsWith("- [ ] ")||s.startsWith("- [x] ")?e.push("task-list"):e.push("bullet-list")),/^\d+\.\s/.test(s)&&e.push("numbered-list"),s.startsWith("> ")&&e.push("quote"),s.startsWith("# ")&&e.push("header"),s.startsWith("## ")&&e.push("header-2"),s.startsWith("### ")&&e.push("header-3");let l=Math.max(0,t-10),d=Math.min(i.length,o+10),p=i.slice(l,d);if(p.includes("**")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100)),h=c.lastIndexOf("**"),v=m.indexOf("**");h!==-1&&v!==-1&&e.push("bold")}if(p.includes("_")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100)),h=c.lastIndexOf("_"),v=m.indexOf("_");h!==-1&&v!==-1&&e.push("italic")}if(p.includes("`")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100));c.includes("`")&&m.includes("`")&&e.push("code")}if(p.includes("[")&&p.includes("]")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100)),h=c.lastIndexOf("["),v=m.indexOf("]");h!==-1&&v!==-1&&i.slice(o+v+1,o+v+10).startsWith("(")&&e.push("link")}return e}function V(n){if(!n||n.disabled||n.readOnly)return;g("toggleBold","Starting"),z(n,"Before");let e=E(S.bold),t=R(n,e);re(t),H(n,t),z(n,"After")}function D(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.italic),t=R(n,e);H(n,t)}function ce(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.code),t=R(n,e);H(n,t)}function q(n,e={}){if(!n||n.disabled||n.readOnly)return;let t=n.value.slice(n.selectionStart,n.selectionEnd),o=E(S.link);if(t&&t.match(/^https?:\/\//)&&!e.url?(o.suffix=`](${t})`,o.replaceNext=""):e.url&&(o.suffix=`](${e.url})`,o.replaceNext=""),e.text&&!t){let a=n.selectionStart;n.value=n.value.slice(0,a)+e.text+n.value.slice(a),n.selectionStart=a,n.selectionEnd=a+e.text.length}let r=R(n,o);H(n,r)}function W(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.bulletList);le(n,e)}function
|
|
28
|
+
`),a=0,s="";for(let c of r){if(t>=a&&t<=a+c.length){s=c;break}a+=c.length+1}s.startsWith("- ")&&(s.startsWith("- [ ] ")||s.startsWith("- [x] ")?e.push("task-list"):e.push("bullet-list")),/^\d+\.\s/.test(s)&&e.push("numbered-list"),s.startsWith("> ")&&e.push("quote"),s.startsWith("# ")&&e.push("header"),s.startsWith("## ")&&e.push("header-2"),s.startsWith("### ")&&e.push("header-3");let l=Math.max(0,t-10),d=Math.min(i.length,o+10),p=i.slice(l,d);if(p.includes("**")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100)),h=c.lastIndexOf("**"),v=m.indexOf("**");h!==-1&&v!==-1&&e.push("bold")}if(p.includes("_")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100)),h=c.lastIndexOf("_"),v=m.indexOf("_");h!==-1&&v!==-1&&e.push("italic")}if(p.includes("`")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100));c.includes("`")&&m.includes("`")&&e.push("code")}if(p.includes("[")&&p.includes("]")){let c=i.slice(Math.max(0,t-100),t),m=i.slice(o,Math.min(i.length,o+100)),h=c.lastIndexOf("["),v=m.indexOf("]");h!==-1&&v!==-1&&i.slice(o+v+1,o+v+10).startsWith("(")&&e.push("link")}return e}function V(n){if(!n||n.disabled||n.readOnly)return;g("toggleBold","Starting"),z(n,"Before");let e=E(S.bold),t=R(n,e);re(t),H(n,t),z(n,"After")}function D(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.italic),t=R(n,e);H(n,t)}function ce(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.code),t=R(n,e);H(n,t)}function q(n,e={}){if(!n||n.disabled||n.readOnly)return;let t=n.value.slice(n.selectionStart,n.selectionEnd),o=E(S.link);if(t&&t.match(/^https?:\/\//)&&!e.url?(o.suffix=`](${t})`,o.replaceNext=""):e.url&&(o.suffix=`](${e.url})`,o.replaceNext=""),e.text&&!t){let a=n.selectionStart;n.value=n.value.slice(0,a)+e.text+n.value.slice(a),n.selectionStart=a,n.selectionEnd=a+e.text.length}let r=R(n,o);H(n,r)}function W(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.bulletList);le(n,e)}function U(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.numberedList);le(n,e)}function pe(n){if(!n||n.disabled||n.readOnly)return;g("toggleQuote","Starting"),z(n,"Initial");let e=E(S.quote),t=F(n,o=>ae(o,e),{prefix:e.prefix});re(t),H(n,t),z(n,"Final")}function de(n){if(!n||n.disabled||n.readOnly)return;let e=E(S.taskList),t=F(n,o=>ae(o,e),{prefix:e.prefix});H(n,t)}function Q(n,e=1,t=!1){if(!n||n.disabled||n.readOnly)return;(e<1||e>6)&&(e=1),g("insertHeader","============ START ============"),g("insertHeader",`Level: ${e}, Toggle: ${t}`),g("insertHeader",`Initial cursor: ${n.selectionStart}-${n.selectionEnd}`);let o=`header${e===1?"1":e}`,i=E(S[o]||S.header1);g("insertHeader",`Style prefix: "${i.prefix}"`);let r=n.value,a=n.selectionStart,s=n.selectionEnd,l=a;for(;l>0&&r[l-1]!==`
|
|
29
29
|
`;)l--;let d=s;for(;d<r.length&&r[d]!==`
|
|
30
|
-
`;)d++;let p=r.slice(l,d);g("insertHeader",`Current line (before): "${p}"`);let c=p.match(/^(#{1,6})\s*/),m=c?c[1].length:0,h=c?c[0].length:0;g("insertHeader","Existing header check:"),g("insertHeader",` - Match: ${c?`"${c[0]}"`:"none"}`),g("insertHeader",` - Existing level: ${m}`),g("insertHeader",` - Existing prefix length: ${h}`),g("insertHeader",` - Target level: ${e}`);let v=t&&m===e;g("insertHeader",`Should toggle OFF: ${v} (toggle=${t}, existingLevel=${m}, level=${e})`);let f=F(n,u=>{let b=u.value.slice(u.selectionStart,u.selectionEnd);g("insertHeader",`Line in operation: "${b}"`);let y=b.replace(/^#{1,6}\s*/,"");g("insertHeader",`Cleaned line: "${y}"`);let w;return v?(g("insertHeader","ACTION: Toggling OFF - removing header"),w=y):m>0?(g("insertHeader",`ACTION: Replacing H${m} with H${e}`),w=i.prefix+y):(g("insertHeader","ACTION: Adding new header"),w=i.prefix+y),g("insertHeader",`New line: "${w}"`),{text:w,selectionStart:u.selectionStart,selectionEnd:u.selectionEnd}},{prefix:i.prefix,adjustSelection:(u,b,y,w)=>{if(g("insertHeader","Adjusting selection:"),g("insertHeader",` - isRemoving param: ${u}`),g("insertHeader",` - shouldToggleOff: ${v}`),g("insertHeader",` - selStart: ${b}, selEnd: ${y}`),g("insertHeader",` - lineStartPos: ${w}`),v){let T=Math.max(b-h,w);return g("insertHeader",` - Removing header, adjusting by -${h}`),{start:T,end:b===y?T:Math.max(y-h,w)}}else if(h>0){let T=i.prefix.length-h;return g("insertHeader",` - Replacing header, adjusting by ${T}`),{start:b+T,end:y+T}}else return g("insertHeader",` - Adding header, adjusting by +${i.prefix.length}`),{start:b+i.prefix.length,end:y+i.prefix.length}}});g("insertHeader",`Final result: text="${f.text}", cursor=${f.selectionStart}-${f.selectionEnd}`),g("insertHeader","============ END ============"),H(n,f)}function he(n){Q(n,1,!0)}function ue(n){Q(n,2,!0)}function me(n){Q(n,3,!0)}function fe(n){return Je(n)}var O=class{constructor(e){this.editor=e,this.textarea=e.textarea}handleKeydown(e){if(!(navigator.platform.toLowerCase().includes("mac")?e.metaKey:e.ctrlKey))return!1;let i=null;switch(e.key.toLowerCase()){case"b":e.shiftKey||(i="toggleBold");break;case"i":e.shiftKey||(i="toggleItalic");break;case"k":e.shiftKey||(i="insertLink");break;case"7":e.shiftKey&&(i="toggleNumberedList");break;case"8":e.shiftKey&&(i="toggleBulletList");break}return i?(e.preventDefault(),this.editor.toolbar?this.editor.toolbar.handleAction(i):this.handleAction(i),!0):!1}async handleAction(e){let t=this.textarea;if(t){t.focus();try{switch(e){case"toggleBold":V(t);break;case"toggleItalic":D(t);break;case"insertLink":q(t);break;case"toggleBulletList":W(t);break;case"toggleNumberedList":
|
|
30
|
+
`;)d++;let p=r.slice(l,d);g("insertHeader",`Current line (before): "${p}"`);let c=p.match(/^(#{1,6})\s*/),m=c?c[1].length:0,h=c?c[0].length:0;g("insertHeader","Existing header check:"),g("insertHeader",` - Match: ${c?`"${c[0]}"`:"none"}`),g("insertHeader",` - Existing level: ${m}`),g("insertHeader",` - Existing prefix length: ${h}`),g("insertHeader",` - Target level: ${e}`);let v=t&&m===e;g("insertHeader",`Should toggle OFF: ${v} (toggle=${t}, existingLevel=${m}, level=${e})`);let f=F(n,u=>{let b=u.value.slice(u.selectionStart,u.selectionEnd);g("insertHeader",`Line in operation: "${b}"`);let y=b.replace(/^#{1,6}\s*/,"");g("insertHeader",`Cleaned line: "${y}"`);let w;return v?(g("insertHeader","ACTION: Toggling OFF - removing header"),w=y):m>0?(g("insertHeader",`ACTION: Replacing H${m} with H${e}`),w=i.prefix+y):(g("insertHeader","ACTION: Adding new header"),w=i.prefix+y),g("insertHeader",`New line: "${w}"`),{text:w,selectionStart:u.selectionStart,selectionEnd:u.selectionEnd}},{prefix:i.prefix,adjustSelection:(u,b,y,w)=>{if(g("insertHeader","Adjusting selection:"),g("insertHeader",` - isRemoving param: ${u}`),g("insertHeader",` - shouldToggleOff: ${v}`),g("insertHeader",` - selStart: ${b}, selEnd: ${y}`),g("insertHeader",` - lineStartPos: ${w}`),v){let T=Math.max(b-h,w);return g("insertHeader",` - Removing header, adjusting by -${h}`),{start:T,end:b===y?T:Math.max(y-h,w)}}else if(h>0){let T=i.prefix.length-h;return g("insertHeader",` - Replacing header, adjusting by ${T}`),{start:b+T,end:y+T}}else return g("insertHeader",` - Adding header, adjusting by +${i.prefix.length}`),{start:b+i.prefix.length,end:y+i.prefix.length}}});g("insertHeader",`Final result: text="${f.text}", cursor=${f.selectionStart}-${f.selectionEnd}`),g("insertHeader","============ END ============"),H(n,f)}function he(n){Q(n,1,!0)}function ue(n){Q(n,2,!0)}function me(n){Q(n,3,!0)}function fe(n){return Je(n)}var O=class{constructor(e){this.editor=e,this.textarea=e.textarea}handleKeydown(e){if(!(navigator.platform.toLowerCase().includes("mac")?e.metaKey:e.ctrlKey))return!1;let i=null;switch(e.key.toLowerCase()){case"b":e.shiftKey||(i="toggleBold");break;case"i":e.shiftKey||(i="toggleItalic");break;case"k":e.shiftKey||(i="insertLink");break;case"7":e.shiftKey&&(i="toggleNumberedList");break;case"8":e.shiftKey&&(i="toggleBulletList");break}return i?(e.preventDefault(),this.editor.toolbar?this.editor.toolbar.handleAction(i):this.handleAction(i),!0):!1}async handleAction(e){let t=this.textarea;if(t){t.focus();try{switch(e){case"toggleBold":V(t);break;case"toggleItalic":D(t);break;case"insertLink":q(t);break;case"toggleBulletList":W(t);break;case"toggleNumberedList":U(t);break}t.dispatchEvent(new Event("input",{bubbles:!0}))}catch(o){console.error("Error in markdown action:",o)}}}destroy(){}};var $={name:"solar",colors:{bgPrimary:"#faf0ca",bgSecondary:"#ffffff",text:"#0d3b66",h1:"#f95738",h2:"#ee964b",h3:"#3d8a51",strong:"#ee964b",em:"#f95738",link:"#0d3b66",code:"#0d3b66",codeBg:"rgba(244, 211, 94, 0.4)",blockquote:"#5a7a9b",hr:"#5a7a9b",syntaxMarker:"rgba(13, 59, 102, 0.52)",cursor:"#f95738",selection:"rgba(244, 211, 94, 0.4)",listMarker:"#ee964b",toolbarBg:"#ffffff",toolbarBorder:"rgba(13, 59, 102, 0.15)",toolbarIcon:"#0d3b66",toolbarHover:"#f5f5f5",toolbarActive:"#faf0ca"}},ve={name:"cave",colors:{bgPrimary:"#141E26",bgSecondary:"#1D2D3E",text:"#c5dde8",h1:"#d4a5ff",h2:"#f6ae2d",h3:"#9fcfec",strong:"#f6ae2d",em:"#9fcfec",link:"#9fcfec",code:"#c5dde8",codeBg:"#1a232b",blockquote:"#9fcfec",hr:"#c5dde8",syntaxMarker:"rgba(159, 207, 236, 0.73)",cursor:"#f26419",selection:"rgba(51, 101, 138, 0.4)",listMarker:"#f6ae2d",toolbarBg:"#1D2D3E",toolbarBorder:"rgba(197, 221, 232, 0.1)",toolbarIcon:"#c5dde8",toolbarHover:"#243546",toolbarActive:"#2a3f52"}},ye={solar:$,cave:ve,light:$,dark:ve};function B(n){return typeof n=="string"?{...ye[n]||ye.solar,name:n}:n}function P(n){let e=[];for(let[t,o]of Object.entries(n)){let i=t.replace(/([A-Z])/g,"-$1").toLowerCase();e.push(`--${i}: ${o};`)}return e.join(`
|
|
31
31
|
`)}function be(n,e={}){return{...n,colors:{...n.colors,...e}}}function ke(n={}){let{fontSize:e="14px",lineHeight:t=1.6,fontFamily:o='"SF Mono", SFMono-Regular, Menlo, Monaco, "Cascadia Code", Consolas, "Roboto Mono", "Noto Sans Mono", "Droid Sans Mono", "Ubuntu Mono", "DejaVu Sans Mono", "Liberation Mono", "Courier New", Courier, monospace',padding:i="20px",theme:r=null,mobile:a={}}=n,s=Object.keys(a).length>0?`
|
|
32
32
|
@media (max-width: 640px) {
|
|
33
33
|
.overtype-wrapper .overtype-input,
|
|
@@ -36,7 +36,7 @@ ${s}`:r;if(d){let x=n.value[n.selectionStart-1];n.selectionStart!==0&&x!=null&&!
|
|
|
36
36
|
`)}
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
`:"",l=r&&r.colors?
|
|
39
|
+
`:"",l=r&&r.colors?P(r.colors):"";return`
|
|
40
40
|
/* OverType Editor Styles */
|
|
41
41
|
.overtype-container {
|
|
42
42
|
display: grid !important;
|
|
@@ -526,7 +526,7 @@ ${s}`:r;if(d){let x=n.value[n.selectionStart-1];n.selectionStart!==0&&x!=null&&!
|
|
|
526
526
|
<rect stroke="currentColor" fill="none" stroke-width="1.5" x="2" y="3" width="3" height="3" rx="0.5"></rect>
|
|
527
527
|
<rect stroke="currentColor" fill="none" stroke-width="1.5" x="2" y="13" width="3" height="3" rx="0.5"></rect>
|
|
528
528
|
<polyline stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" points="2.65 9.5 3.5 10.5 5 8.5"></polyline>
|
|
529
|
-
</svg>`;var
|
|
529
|
+
</svg>`;var K=class{constructor(e){this.editor=e,this.container=null,this.buttons={}}create(){this.container=document.createElement("div"),this.container.className="overtype-toolbar",this.container.setAttribute("role","toolbar"),this.container.setAttribute("aria-label","Text formatting"),[{name:"bold",icon:we,title:"Bold (Ctrl+B)",action:"toggleBold"},{name:"italic",icon:xe,title:"Italic (Ctrl+I)",action:"toggleItalic"},{separator:!0},{name:"h1",icon:Se,title:"Heading 1",action:"insertH1"},{name:"h2",icon:Le,title:"Heading 2",action:"insertH2"},{name:"h3",icon:Ce,title:"Heading 3",action:"insertH3"},{separator:!0},{name:"link",icon:Ee,title:"Insert Link (Ctrl+K)",action:"insertLink"},{name:"code",icon:Ae,title:"Code (Ctrl+`)",action:"toggleCode"},{separator:!0},{name:"quote",icon:$e,title:"Quote",action:"toggleQuote"},{separator:!0},{name:"bulletList",icon:Te,title:"Bullet List",action:"toggleBulletList"},{name:"orderedList",icon:He,title:"Numbered List",action:"toggleNumberedList"},{name:"taskList",icon:Me,title:"Task List",action:"toggleTaskList"}].forEach(i=>{if(i.separator){let r=document.createElement("div");r.className="overtype-toolbar-separator",r.setAttribute("role","separator"),this.container.appendChild(r)}else{let r=this.createButton(i);this.buttons[i.name]=r,this.container.appendChild(r)}});let t=this.editor.element.querySelector(".overtype-container"),o=this.editor.element.querySelector(".overtype-wrapper");return t&&o&&t.insertBefore(this.container,o),this.container}createButton(e){let t=document.createElement("button");return t.className="overtype-toolbar-button",t.type="button",t.title=e.title,t.setAttribute("aria-label",e.title),t.setAttribute("data-action",e.action),t.innerHTML=e.icon,t.addEventListener("click",o=>{o.preventDefault(),this.handleAction(e.action)}),t}async handleAction(e){let t=this.editor.textarea;if(t){t.focus();try{switch(e){case"toggleBold":V(t);break;case"toggleItalic":D(t);break;case"insertH1":he(t);break;case"insertH2":ue(t);break;case"insertH3":me(t);break;case"insertLink":q(t);break;case"toggleCode":ce(t);break;case"toggleBulletList":W(t);break;case"toggleNumberedList":U(t);break;case"toggleQuote":pe(t);break;case"toggleTaskList":de(t);break}t.dispatchEvent(new Event("input",{bubbles:!0}))}catch(o){console.error("Error loading markdown-actions:",o)}}}async updateButtonStates(){let e=this.editor.textarea;if(e)try{let t=fe(e);Object.entries(this.buttons).forEach(([o,i])=>{let r=!1;switch(o){case"bold":r=t.includes("bold");break;case"italic":r=t.includes("italic");break;case"code":r=!1;break;case"bulletList":r=t.includes("bullet-list");break;case"orderedList":r=t.includes("numbered-list");break;case"quote":r=t.includes("quote");break;case"taskList":r=t.includes("task-list");break;case"h1":r=t.includes("header");break;case"h2":r=t.includes("header-2");break;case"h3":r=t.includes("header-3");break}i.classList.toggle("active",r),i.setAttribute("aria-pressed",r.toString())})}catch(t){}}destroy(){this.container&&(this.container.remove(),this.container=null,this.buttons={})}};var Z=class{constructor(e){this.editor=e,this.tooltip=null,this.currentLink=null,this.hideTimeout=null,this.init()}init(){CSS.supports("position-anchor: --x")&&CSS.supports("position-area: center")&&(this.createTooltip(),this.editor.textarea.addEventListener("selectionchange",()=>this.checkCursorPosition()),this.editor.textarea.addEventListener("keyup",t=>{(t.key.includes("Arrow")||t.key==="Home"||t.key==="End")&&this.checkCursorPosition()}),this.editor.textarea.addEventListener("input",()=>this.hide()),this.editor.textarea.addEventListener("scroll",()=>this.hide()),this.tooltip.addEventListener("mouseenter",()=>this.cancelHide()),this.tooltip.addEventListener("mouseleave",()=>this.scheduleHide()))}createTooltip(){this.tooltip=document.createElement("div"),this.tooltip.className="overtype-link-tooltip";let e=document.createElement("style");e.textContent=`
|
|
530
530
|
@supports (position-anchor: --x) and (position-area: center) {
|
|
531
531
|
.overtype-link-tooltip {
|
|
532
532
|
position: absolute;
|
|
@@ -565,7 +565,7 @@ ${s}`:r;if(d){let x=n.value[n.selectionStart-1];n.selectionStart!==0&&x!=null&&!
|
|
|
565
565
|
</svg>
|
|
566
566
|
<span class="overtype-link-tooltip-url"></span>
|
|
567
567
|
</span>
|
|
568
|
-
`,this.tooltip.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.currentLink&&(window.open(this.currentLink.url,"_blank"),this.hide())}),this.editor.container.appendChild(this.tooltip)}checkCursorPosition(){let e=this.editor.textarea.selectionStart,t=this.editor.textarea.value,o=this.findLinkAtPosition(t,e);o?(!this.currentLink||this.currentLink.url!==o.url||this.currentLink.index!==o.index)&&this.show(o):this.scheduleHide()}findLinkAtPosition(e,t){let o=/\[([^\]]+)\]\(([^)]+)\)/g,i,r=0;for(;(i=o.exec(e))!==null;){let a=i.index,s=i.index+i[0].length;if(t>=a&&t<=s)return{text:i[1],url:i[2],index:r,start:a,end:s};r++}return null}show(e){this.currentLink=e,this.cancelHide();let t=this.tooltip.querySelector(".overtype-link-tooltip-url");t.textContent=e.url,this.tooltip.style.setProperty("--target-anchor",`--link-${e.index}`),this.tooltip.classList.add("visible")}hide(){this.tooltip.classList.remove("visible"),this.currentLink=null}scheduleHide(){this.cancelHide(),this.hideTimeout=setTimeout(()=>this.hide(),300)}cancelHide(){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null)}destroy(){this.cancelHide(),this.tooltip&&this.tooltip.parentNode&&this.tooltip.parentNode.removeChild(this.tooltip),this.tooltip=null,this.currentLink=null}};var k=class k{constructor(e,t={}){let o;if(typeof e=="string"){if(o=document.querySelectorAll(e),o.length===0)throw new Error(`No elements found for selector: ${e}`);o=Array.from(o)}else if(e instanceof Element)o=[e];else if(e instanceof NodeList)o=Array.from(e);else if(Array.isArray(e))o=e;else throw new Error("Invalid target: must be selector string, Element, NodeList, or Array");return o.map(r=>{if(r.overTypeInstance)return r.overTypeInstance.reinit(t),r.overTypeInstance;let a=Object.create(k.prototype);return a._init(r,t),r.overTypeInstance=a,k.instances.set(r,a),a})}_init(e,t={}){this.element=e,this.instanceTheme=t.theme||null,this.options=this._mergeOptions(t),this.instanceId=++k.instanceCount,this.initialized=!1,k.injectStyles(),k.initGlobalListeners();let o=e.querySelector(".overtype-container"),i=e.querySelector(".overtype-wrapper");o||i?this._recoverFromDOM(o,i):this._buildFromScratch(),this.shortcuts=new O(this),this.linkTooltip=new Z(this),this.options.toolbar&&(this.toolbar=new
|
|
568
|
+
`,this.tooltip.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),this.currentLink&&(window.open(this.currentLink.url,"_blank"),this.hide())}),this.editor.container.appendChild(this.tooltip)}checkCursorPosition(){let e=this.editor.textarea.selectionStart,t=this.editor.textarea.value,o=this.findLinkAtPosition(t,e);o?(!this.currentLink||this.currentLink.url!==o.url||this.currentLink.index!==o.index)&&this.show(o):this.scheduleHide()}findLinkAtPosition(e,t){let o=/\[([^\]]+)\]\(([^)]+)\)/g,i,r=0;for(;(i=o.exec(e))!==null;){let a=i.index,s=i.index+i[0].length;if(t>=a&&t<=s)return{text:i[1],url:i[2],index:r,start:a,end:s};r++}return null}show(e){this.currentLink=e,this.cancelHide();let t=this.tooltip.querySelector(".overtype-link-tooltip-url");t.textContent=e.url,this.tooltip.style.setProperty("--target-anchor",`--link-${e.index}`),this.tooltip.classList.add("visible")}hide(){this.tooltip.classList.remove("visible"),this.currentLink=null}scheduleHide(){this.cancelHide(),this.hideTimeout=setTimeout(()=>this.hide(),300)}cancelHide(){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=null)}destroy(){this.cancelHide(),this.tooltip&&this.tooltip.parentNode&&this.tooltip.parentNode.removeChild(this.tooltip),this.tooltip=null,this.currentLink=null}};var k=class k{constructor(e,t={}){let o;if(typeof e=="string"){if(o=document.querySelectorAll(e),o.length===0)throw new Error(`No elements found for selector: ${e}`);o=Array.from(o)}else if(e instanceof Element)o=[e];else if(e instanceof NodeList)o=Array.from(e);else if(Array.isArray(e))o=e;else throw new Error("Invalid target: must be selector string, Element, NodeList, or Array");return o.map(r=>{if(r.overTypeInstance)return r.overTypeInstance.reinit(t),r.overTypeInstance;let a=Object.create(k.prototype);return a._init(r,t),r.overTypeInstance=a,k.instances.set(r,a),a})}_init(e,t={}){this.element=e,this.instanceTheme=t.theme||null,this.options=this._mergeOptions(t),this.instanceId=++k.instanceCount,this.initialized=!1,k.injectStyles(),k.initGlobalListeners();let o=e.querySelector(".overtype-container"),i=e.querySelector(".overtype-wrapper");o||i?this._recoverFromDOM(o,i):this._buildFromScratch(),this.shortcuts=new O(this),this.linkTooltip=new Z(this),this.options.toolbar&&(this.toolbar=new K(this),this.toolbar.create(),this.textarea.addEventListener("selectionchange",()=>{this.toolbar.updateButtonStates()}),this.textarea.addEventListener("input",()=>{this.toolbar.updateButtonStates()})),this.initialized=!0,this.options.onChange&&this.options.onChange(this.getValue(),this)}_mergeOptions(e){let t={fontSize:"14px",lineHeight:1.6,fontFamily:"ui-monospace, 'SFMono-Regular', 'Menlo', 'Consolas', 'Liberation Mono', monospace",padding:"16px",mobile:{fontSize:"16px",padding:"12px",lineHeight:1.5},textareaProps:{},autofocus:!1,autoResize:!1,minHeight:"100px",maxHeight:null,placeholder:"Start typing...",value:"",onChange:null,onKeydown:null,showActiveLineRaw:!1,showStats:!1,toolbar:!1,statsFormatter:null},{theme:o,colors:i,...r}=e;return{...t,...r}}_recoverFromDOM(e,t){if(e&&e.classList.contains("overtype-container"))this.container=e,this.wrapper=e.querySelector(".overtype-wrapper");else if(t){this.wrapper=t,this.container=document.createElement("div"),this.container.className="overtype-container";let o=this.instanceTheme||k.currentTheme||$,i=typeof o=="string"?o:o.name;if(i&&this.container.setAttribute("data-theme",i),this.instanceTheme){let r=typeof this.instanceTheme=="string"?B(this.instanceTheme):this.instanceTheme;if(r&&r.colors){let a=P(r.colors);this.container.style.cssText+=a}}t.parentNode.insertBefore(this.container,t),this.container.appendChild(t)}if(!this.wrapper){e&&e.remove(),t&&t.remove(),this._buildFromScratch();return}if(this.textarea=this.wrapper.querySelector(".overtype-input"),this.preview=this.wrapper.querySelector(".overtype-preview"),!this.textarea||!this.preview){this.container.remove(),this._buildFromScratch();return}this.wrapper._instance=this,this.options.fontSize&&this.wrapper.style.setProperty("--instance-font-size",this.options.fontSize),this.options.lineHeight&&this.wrapper.style.setProperty("--instance-line-height",String(this.options.lineHeight)),this.options.padding&&this.wrapper.style.setProperty("--instance-padding",this.options.padding),this._configureTextarea(),this._applyOptions()}_buildFromScratch(){let e=this._extractContent();this.element.innerHTML="",this._createDOM(),(e||this.options.value)&&this.setValue(e||this.options.value),this._applyOptions()}_extractContent(){let e=this.element.querySelector(".overtype-input");return e?e.value:this.element.textContent||""}_createDOM(){this.container=document.createElement("div"),this.container.className="overtype-container";let e=this.instanceTheme||k.currentTheme||$,t=typeof e=="string"?e:e.name;if(t&&this.container.setAttribute("data-theme",t),this.instanceTheme){let o=typeof this.instanceTheme=="string"?B(this.instanceTheme):this.instanceTheme;if(o&&o.colors){let i=P(o.colors);this.container.style.cssText+=i}}this.wrapper=document.createElement("div"),this.wrapper.className="overtype-wrapper",this.options.fontSize&&this.wrapper.style.setProperty("--instance-font-size",this.options.fontSize),this.options.lineHeight&&this.wrapper.style.setProperty("--instance-line-height",String(this.options.lineHeight)),this.options.padding&&this.wrapper.style.setProperty("--instance-padding",this.options.padding),this.wrapper._instance=this,this.textarea=document.createElement("textarea"),this.textarea.className="overtype-input",this.textarea.placeholder=this.options.placeholder,this._configureTextarea(),this.options.textareaProps&&Object.entries(this.options.textareaProps).forEach(([o,i])=>{o==="className"||o==="class"?this.textarea.className+=" "+i:o==="style"&&typeof i=="object"?Object.assign(this.textarea.style,i):this.textarea.setAttribute(o,i)}),this.preview=document.createElement("div"),this.preview.className="overtype-preview",this.preview.setAttribute("aria-hidden","true"),this.wrapper.appendChild(this.textarea),this.wrapper.appendChild(this.preview),this.container.appendChild(this.wrapper),this.options.showStats&&(this.statsBar=document.createElement("div"),this.statsBar.className="overtype-stats",this.container.appendChild(this.statsBar),this._updateStats()),this.element.appendChild(this.container),window.location.pathname.includes("demo.html")&&console.log("_createDOM completed:",{elementId:this.element.id,autoResize:this.options.autoResize,containerClasses:this.container.className,hasStats:!!this.statsBar,hasToolbar:this.options.toolbar}),this.options.autoResize?this._setupAutoResize():(this.container.classList.remove("overtype-auto-resize"),window.location.pathname.includes("demo.html")&&console.log("Removed auto-resize class from:",this.element.id))}_configureTextarea(){this.textarea.setAttribute("autocomplete","off"),this.textarea.setAttribute("autocorrect","off"),this.textarea.setAttribute("autocapitalize","off"),this.textarea.setAttribute("spellcheck","false"),this.textarea.setAttribute("data-gramm","false"),this.textarea.setAttribute("data-gramm_editor","false"),this.textarea.setAttribute("data-enable-grammarly","false")}_applyOptions(){this.options.autofocus&&this.textarea.focus(),this.options.autoResize?this.container.classList.contains("overtype-auto-resize")||this._setupAutoResize():this.container.classList.remove("overtype-auto-resize"),this.updatePreview()}updatePreview(){let e=this.textarea.value,t=this.textarea.selectionStart,o=this._getCurrentLine(e,t),i=I.parse(e,o,this.options.showActiveLineRaw);this.preview.innerHTML=i||'<span style="color: #808080;">Start typing...</span>',this._applyCodeBlockBackgrounds(),this.options.showStats&&this.statsBar&&this._updateStats(),this.options.onChange&&this.initialized&&this.options.onChange(e,this)}_applyCodeBlockBackgrounds(){let e=this.preview.querySelectorAll(".code-fence");for(let t=0;t<e.length-1;t+=2){let o=e[t],i=e[t+1],r=o.parentElement,a=i.parentElement;if(!r||!a)continue;o.style.display="block",i.style.display="block",r.classList.add("code-block-line"),a.classList.add("code-block-line");let s=r.nextElementSibling;for(;s&&s!==a;){if(s.tagName==="DIV"){s.classList.add("code-block-line");let l=s.textContent;s.textContent=l}if(s=s.nextElementSibling,!s)break}}}_getCurrentLine(e,t){return e.substring(0,t).split(`
|
|
569
569
|
`).length-1}handleInput(e){this.updatePreview()}handleKeydown(e){if(e.key==="Tab"){e.preventDefault();let o=this.textarea.selectionStart,i=this.textarea.selectionEnd,r=this.textarea.value;if(o!==i&&e.shiftKey){let a=r.substring(0,o),s=r.substring(o,i),l=r.substring(i),p=s.split(`
|
|
570
570
|
`).map(c=>c.replace(/^ /,"")).join(`
|
|
571
571
|
`);this.textarea.value=a+p+l,this.textarea.selectionStart=o,this.textarea.selectionEnd=o+p.length}else if(o!==i){let a=r.substring(0,o),s=r.substring(o,i),l=r.substring(i),p=s.split(`
|
package/package.json
CHANGED
package/src/parser.js
CHANGED
|
@@ -157,6 +157,44 @@ export class MarkdownParser {
|
|
|
157
157
|
return html.replace(/(?<!`)(`+)(?!`)((?:(?!\1).)+?)(\1)(?!`)/g, '<code><span class="syntax-marker">$1</span>$2<span class="syntax-marker">$3</span></code>');
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Sanitize URL to prevent XSS attacks
|
|
162
|
+
* @param {string} url - URL to sanitize
|
|
163
|
+
* @returns {string} Safe URL or '#' if dangerous
|
|
164
|
+
*/
|
|
165
|
+
static sanitizeUrl(url) {
|
|
166
|
+
// Trim whitespace and convert to lowercase for protocol check
|
|
167
|
+
const trimmed = url.trim();
|
|
168
|
+
const lower = trimmed.toLowerCase();
|
|
169
|
+
|
|
170
|
+
// Allow safe protocols
|
|
171
|
+
const safeProtocols = [
|
|
172
|
+
'http://',
|
|
173
|
+
'https://',
|
|
174
|
+
'mailto:',
|
|
175
|
+
'ftp://',
|
|
176
|
+
'ftps://'
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
// Check if URL starts with a safe protocol
|
|
180
|
+
const hasSafeProtocol = safeProtocols.some(protocol => lower.startsWith(protocol));
|
|
181
|
+
|
|
182
|
+
// Allow relative URLs (starting with / or # or no protocol)
|
|
183
|
+
const isRelative = trimmed.startsWith('/') ||
|
|
184
|
+
trimmed.startsWith('#') ||
|
|
185
|
+
trimmed.startsWith('?') ||
|
|
186
|
+
trimmed.startsWith('.') ||
|
|
187
|
+
(!trimmed.includes(':') && !trimmed.includes('//'));
|
|
188
|
+
|
|
189
|
+
// If safe protocol or relative URL, return as-is
|
|
190
|
+
if (hasSafeProtocol || isRelative) {
|
|
191
|
+
return url;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Block dangerous protocols (javascript:, data:, vbscript:, etc.)
|
|
195
|
+
return '#';
|
|
196
|
+
}
|
|
197
|
+
|
|
160
198
|
/**
|
|
161
199
|
* Parse links
|
|
162
200
|
* @param {string} html - HTML with potential link markdown
|
|
@@ -165,8 +203,10 @@ export class MarkdownParser {
|
|
|
165
203
|
static parseLinks(html) {
|
|
166
204
|
return html.replace(/\[(.+?)\]\((.+?)\)/g, (match, text, url) => {
|
|
167
205
|
const anchorName = `--link-${this.linkIndex++}`;
|
|
206
|
+
// Sanitize URL to prevent XSS attacks
|
|
207
|
+
const safeUrl = this.sanitizeUrl(url);
|
|
168
208
|
// Don't double-escape - url is already escaped from parseLine
|
|
169
|
-
return `<a href="${
|
|
209
|
+
return `<a href="${safeUrl}" style="anchor-name: ${anchorName}"><span class="syntax-marker">[</span>${text}<span class="syntax-marker">](</span><span class="syntax-marker link-url">${url}</span><span class="syntax-marker">)</span></a>`;
|
|
170
210
|
});
|
|
171
211
|
}
|
|
172
212
|
|