overtype 1.1.5 → 1.1.6
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/README.md +4 -1
- package/dist/overtype.esm.js +12 -7
- package/dist/overtype.esm.js.map +2 -2
- package/dist/overtype.js +12 -7
- package/dist/overtype.js.map +2 -2
- package/dist/overtype.min.js +2 -2
- package/package.json +1 -1
- package/src/parser.js +26 -11
package/dist/overtype.min.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* OverType v1.1.
|
|
2
|
+
* OverType v1.1.6
|
|
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 P=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var je=Object.prototype.hasOwnProperty;var Oe=(n,e,t)=>e in n?P(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var Ne=(n,e)=>{for(var t in e)P(n,t,{get:e[t],enumerable:!0})},Pe=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Be(e))!je.call(n,i)&&i!==t&&P(n,i,{get:()=>e[i],enumerable:!(o=Ie(e,i))||o.enumerable});return n};var ze=n=>Pe(P({},"__esModule",{value:!0}),n);var M=(n,e,t)=>(Oe(n,typeof e!="symbol"?e+"":e,t),t);var Xe={};Ne(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 parseLinks(e){return e.replace(/\[(.+?)\]\((.+?)\)/g,(t,o,i)=>{let r=`--link-${this.linkIndex++}`;return`<a href="${i}" style="anchor-name: ${r}"><span class="syntax-marker">[</span>${o}<span class="syntax-marker">](</span><span class="syntax-marker">${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=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(`
|
|
8
|
+
var OverType=(()=>{var P=Object.defineProperty;var Ie=Object.getOwnPropertyDescriptor;var Be=Object.getOwnPropertyNames;var je=Object.prototype.hasOwnProperty;var Oe=(n,e,t)=>e in n?P(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var Ne=(n,e)=>{for(var t in e)P(n,t,{get:e[t],enumerable:!0})},Pe=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Be(e))!je.call(n,i)&&i!==t&&P(n,i,{get:()=>e[i],enumerable:!(o=Ie(e,i))||o.enumerable});return n};var ze=n=>Pe(P({},"__esModule",{value:!0}),n);var M=(n,e,t)=>(Oe(n,typeof e!="symbol"?e+"":e,t),t);var Xe={};Ne(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 parseLinks(e){return e.replace(/\[(.+?)\]\((.+?)\)/g,(t,o,i)=>{let r=`--link-${this.linkIndex++}`;return`<a href="${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(`
|
package/package.json
CHANGED
package/src/parser.js
CHANGED
|
@@ -165,7 +165,8 @@ export class MarkdownParser {
|
|
|
165
165
|
static parseLinks(html) {
|
|
166
166
|
return html.replace(/\[(.+?)\]\((.+?)\)/g, (match, text, url) => {
|
|
167
167
|
const anchorName = `--link-${this.linkIndex++}`;
|
|
168
|
-
|
|
168
|
+
// Don't double-escape - url is already escaped from parseLine
|
|
169
|
+
return `<a href="${url}" 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>`;
|
|
169
170
|
});
|
|
170
171
|
}
|
|
171
172
|
|
|
@@ -176,30 +177,44 @@ export class MarkdownParser {
|
|
|
176
177
|
*/
|
|
177
178
|
static parseInlineElements(text) {
|
|
178
179
|
let html = text;
|
|
179
|
-
// Order matters: parse code first
|
|
180
|
+
// Order matters: parse code first
|
|
180
181
|
html = this.parseInlineCode(html);
|
|
182
|
+
|
|
181
183
|
// Use placeholders to protect inline code while preserving formatting spans
|
|
182
184
|
// We use Unicode Private Use Area (U+E000-U+F8FF) as placeholders because:
|
|
183
185
|
// 1. These characters are reserved for application-specific use
|
|
184
186
|
// 2. They'll never appear in user text
|
|
185
187
|
// 3. They maintain single-character width (important for alignment)
|
|
186
188
|
// 4. They're invisible if accidentally rendered
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
189
|
+
const sanctuaries = new Map();
|
|
190
|
+
|
|
191
|
+
// Protect code blocks
|
|
190
192
|
html = html.replace(/(<code>.*?<\/code>)/g, (match) => {
|
|
191
|
-
const placeholder = `\uE000${
|
|
192
|
-
|
|
193
|
+
const placeholder = `\uE000${sanctuaries.size}\uE001`;
|
|
194
|
+
sanctuaries.set(placeholder, match);
|
|
193
195
|
return placeholder;
|
|
194
196
|
});
|
|
195
|
-
|
|
197
|
+
|
|
198
|
+
// Parse links AFTER protecting code but BEFORE bold/italic
|
|
199
|
+
// This ensures link URLs don't get processed as markdown
|
|
196
200
|
html = this.parseLinks(html);
|
|
201
|
+
|
|
202
|
+
// Protect entire link elements (not just the URL part)
|
|
203
|
+
html = html.replace(/(<a[^>]*>.*?<\/a>)/g, (match) => {
|
|
204
|
+
const placeholder = `\uE000${sanctuaries.size}\uE001`;
|
|
205
|
+
sanctuaries.set(placeholder, match);
|
|
206
|
+
return placeholder;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Process other inline elements on text with placeholders
|
|
197
210
|
html = this.parseBold(html);
|
|
198
211
|
html = this.parseItalic(html);
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
212
|
+
|
|
213
|
+
// Restore all sanctuaries
|
|
214
|
+
sanctuaries.forEach((content, placeholder) => {
|
|
215
|
+
html = html.replace(placeholder, content);
|
|
202
216
|
});
|
|
217
|
+
|
|
203
218
|
return html;
|
|
204
219
|
}
|
|
205
220
|
|