markdown-text-editor 2.0.0-beta.0 → 2.0.0-beta.1

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.
Files changed (67) hide show
  1. package/README.md +78 -4
  2. package/dist/markdown-text-editor.es.js +23 -16
  3. package/dist/markdown-text-editor.es.js.map +1 -1
  4. package/dist/markdown-text-editor.min.js +6 -6
  5. package/dist/markdown-text-editor.min.js.map +1 -1
  6. package/dist/markdown-text-editor.umd.js +6 -6
  7. package/dist/markdown-text-editor.umd.js.map +1 -1
  8. package/locale/ar.js +55 -0
  9. package/locale/az.js +55 -0
  10. package/locale/bg.js +55 -0
  11. package/locale/bn.js +55 -0
  12. package/locale/bs.js +55 -0
  13. package/locale/ca.js +55 -0
  14. package/locale/cs.js +55 -0
  15. package/locale/da.js +55 -0
  16. package/locale/de.js +55 -0
  17. package/locale/el.js +55 -0
  18. package/locale/es.js +55 -0
  19. package/locale/et.js +55 -0
  20. package/locale/fa.js +55 -0
  21. package/locale/fi.js +55 -0
  22. package/locale/fil.js +55 -0
  23. package/locale/fr.js +55 -0
  24. package/locale/ga.js +55 -0
  25. package/locale/he.js +55 -0
  26. package/locale/hi.js +55 -0
  27. package/locale/hr.js +55 -0
  28. package/locale/hu.js +55 -0
  29. package/locale/hy.js +55 -0
  30. package/locale/id.js +55 -0
  31. package/locale/is.js +55 -0
  32. package/locale/it.js +55 -0
  33. package/locale/ja.js +55 -0
  34. package/locale/kn.js +55 -0
  35. package/locale/ko.js +55 -0
  36. package/locale/locale.d.ts +10 -0
  37. package/locale/lt.js +55 -0
  38. package/locale/lv.js +55 -0
  39. package/locale/mk.js +55 -0
  40. package/locale/mr.js +55 -0
  41. package/locale/ms.js +55 -0
  42. package/locale/mt.js +55 -0
  43. package/locale/nl.js +55 -0
  44. package/locale/no.js +55 -0
  45. package/locale/pl.js +55 -0
  46. package/locale/pt.js +55 -0
  47. package/locale/ro.js +55 -0
  48. package/locale/ru.js +55 -0
  49. package/locale/sk.js +55 -0
  50. package/locale/sl.js +55 -0
  51. package/locale/sq.js +55 -0
  52. package/locale/sr.js +55 -0
  53. package/locale/sv.js +55 -0
  54. package/locale/sw.js +55 -0
  55. package/locale/ta.js +55 -0
  56. package/locale/te.js +55 -0
  57. package/locale/template.js +62 -0
  58. package/locale/th.js +55 -0
  59. package/locale/tr.js +55 -0
  60. package/locale/uk.js +55 -0
  61. package/locale/ur.js +55 -0
  62. package/locale/uz.js +55 -0
  63. package/locale/vi.js +55 -0
  64. package/locale/zh-hk.js +55 -0
  65. package/locale/zh.js +55 -0
  66. package/package.json +13 -2
  67. package/types/index.d.ts +16 -5
@@ -151,8 +151,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
151
151
  | Cell | Cell | Cell |`,i=t===0||n[t-1]===`
152
152
  `?r:`\n${r}`;this.editor.insertText(i,i.length,0)}};function qn(e){let t=e=>e&&e.label&&typeof e.value==`string`,n=[];for(let r of Array.isArray(e)?e:[])r&&(Array.isArray(r.items)?n.push(...r.items.filter(t)):t(r)&&n.push(r));return n}function Jn(e,t){let n=qn(t).filter(e=>typeof e.sample==`string`);return n.length?n.slice().sort((e,t)=>t.value.length-e.value.length).reduce((e,t)=>e.split(t.value).join(t.sample),e):e}var Yn=`
153
153
  <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M7 4a2 2 0 0 0 -2 2v3a2 2 0 0 1 -2 2a2 2 0 0 1 2 2v3a2 2 0 0 0 2 2" /><path d="M17 4a2 2 0 0 1 2 2v3a2 2 0 0 0 2 2a2 2 0 0 0 -2 2v3a2 2 0 0 1 -2 2" /></svg>
154
- `,Xn=class extends ${constructor(e){super(e,`Variables`)}createButton(){let e=this.editor.variables??[];if(!qn(e).length)return null;let t=`variable-popover-${Math.random().toString(36).slice(2,7)}`,n=document.createElement(`button`);n.innerHTML=Yn,n.querySelector(`svg`)?.setAttribute(`aria-hidden`,`true`),n.type=`button`,n.title=this.editor.label(`Insert variable`),n.setAttribute(`aria-label`,this.editor.label(`Insert variable`)),n.setAttribute(`aria-haspopup`,`menu`),n.className=`markdown-btn variable-btn fj:me-btn fj:me-btn-xs fj:me-btn-square fj:me-btn-ghost fj:me-popover-toggle`,n.setAttribute(`popovertarget`,t);let r=document.createElement(`div`);r.id=t,r.setAttribute(`role`,`menu`),r.setAttribute(`aria-label`,this.editor.label(`Variables`)),r.className=`fj:me-popover-content`,r.setAttribute(`popover`,``);let i=document.createElement(`ul`);i.className=`fj:me-menu`,i.setAttribute(`role`,`presentation`);let a=e=>e&&e.label&&typeof e.value==`string`;for(let t of e)if(t){if(Array.isArray(t.items)){let e=t.items.filter(a);if(!e.length)continue;let n=document.createElement(`li`);n.className=`fj:me-menu-title`,n.setAttribute(`role`,`presentation`),n.textContent=t.label??``;let o=document.createElement(`ul`);o.setAttribute(`role`,`group`),t.label&&o.setAttribute(`aria-label`,t.label),e.forEach(e=>o.appendChild(this.createItem(e,r)));let s=document.createElement(`li`);s.setAttribute(`role`,`none`),s.appendChild(o),i.appendChild(n),i.appendChild(s)}else a(t)&&i.appendChild(this.createItem(t,r))}r.appendChild(i);let o=document.createElement(`div`);return o.className=`fj:me-popover`,o.appendChild(n),o.appendChild(r),o}createItem(e,t){let n=document.createElement(`li`);n.setAttribute(`role`,`none`);let r=document.createElement(`button`);return r.type=`button`,r.setAttribute(`role`,`menuitem`),r.className=`fj:me-menu-item`,r.textContent=e.label,r.title=e.value,r.addEventListener(`click`,()=>{this.editor.insertText(e.value,e.value.length,0),t.hidePopover()}),n.appendChild(r),n}applySyntax(){}},Zn=class extends ${constructor(e,t={}){super(e,t.title||`Custom`),this.action=t.action,this.button=typeof this.action==`function`?this.createButton(t.icon||``):null,this.shortcut=this.button?t.shortcut:void 0,this.button||console.warn(`[MarkdownEditor] A custom tool needs an action function. Skipping it.`,t)}applySyntax(e){this.action(this.editor,e)}},Qn=class{constructor(e,t,{standalone:n=!1}={}){this.editor=e,this.options=t,this.standalone=n,this.tools=[],this.toolbar=document.createElement(`div`),this.toolbar.className=n?`toolbar not-prose fj:flex fj:items-center fj:gap-x-1`:`toolbar not-prose fj:me-surface fj:me-surface-outline fj:border-base-soft fj:border-0 fj:border-b fj:flex fj:items-center fj:gap-x-1 fj:p-1.5 fj:overflow-x-auto`,this.toolbar.setAttribute(`role`,`toolbar`),this.toolbar.setAttribute(`aria-label`,e.label(`Editor toolbar`)),this.init()}destroy(){this.tools.forEach(e=>e.destroy?.())}init(){let e={heading:In,ul:Dn,ol:On,checklist:An,bold:wn,italic:Tn,strikethrough:En,blockquote:jn,code:Un,codeblock:Wn,hr:Gn,table:Kn,link:Nn,image:Rn,undo:zn,redo:Bn,indent:Vn,outdent:Hn,variables:Xn};if(this.options.forEach(t=>{let n,r;if(typeof t==`string`)n=e[t];else if(typeof t==`function`)n=t;else if(t&&typeof t.tool==`function`)n=t.tool,r=t.config;else if(t&&t.custom)n=Zn,r=t.custom;else if(typeof t==`object`){let i=Object.keys(t)[0];r=t[i],n=e[i]}if(n){let e=new n(this.editor,r);this.tools.push(e),e.button&&this.toolbar.appendChild(e.button)}}),!this.standalone){if(this.options.includes(`preview`)){let e=new kn(this.editor);this.editor.previewTool=e,this.toolbar.appendChild(e.button)}this.editor.editorContainer.insertBefore(this.toolbar,this.editor.markdownEditorDiv)}}},$n=class{constructor(e){this.previewContainer=document.createElement(`div`),this.previewContainer.className=`preview-wrapper fj:p-2 fj:hidden fj:me-surface fj:me-surface-outline fj:border-base-soft fj:border-0 fj:border-l`,this.previewContainer.setAttribute(`role`,`region`),this.previewContainer.setAttribute(`aria-label`,`Preview`),this.previewContent=document.createElement(`div`),this.previewContent.className=`preview-content fj:mte-prose fj:mte-prose-sm fj:md:mte-prose-base fj:me-prose-frutjam fj:p-1.5 fj:overflow-y-auto fj:h-full fj:max-w-full`,this.previewContainer.appendChild(this.previewContent),e.appendChild(this.previewContainer)}getPreviewContent(){return this.previewContent}},er=class{constructor(e,t={}){this.options=t,this.footer=document.createElement(`div`),this.footer.className=`editor-footer not-prose fj:me-surface fj:me-surface-outline fj:border-base-soft fj:border-0 fj:border-t fj:flex fj:justify-between fj:items-center fj:px-3 fj:py-1 fj:text-xs fj:opacity-60 fj:select-none`,this.footer.setAttribute(`aria-hidden`,`true`),this.positionEl=document.createElement(`span`),this.charsEl=document.createElement(`span`),this.wordsEl=document.createElement(`span`),(this.options.line||this.options.col)&&this.footer.appendChild(this.positionEl),this.options.chars&&this.footer.appendChild(this.charsEl),this.options.words&&this.footer.appendChild(this.wordsEl),e.appendChild(this.footer)}update(e){let t=e.value,n=e.selectionStart??0;if(this.options.line||this.options.col){let e=t.substring(0,n).split(`
155
- `),r=[];this.options.line&&r.push(`Ln ${e.length}`),this.options.col&&r.push(`Col ${e[e.length-1].length+1}`),this.positionEl.textContent=r.join(`, `)}if(this.options.chars&&(this.charsEl.textContent=`${t.length.toLocaleString()} chars`),this.options.words){let e=t.trim()?t.trim().split(/\s+/).length:0;this.wordsEl.textContent=`${e.toLocaleString()} words`}}},tr=class{diff(e,t,n={}){let r;typeof n==`function`?(r=n,n={}):`callback`in n&&(r=n.callback);let i=this.castInput(e,n),a=this.castInput(t,n),o=this.removeEmpty(this.tokenize(i,n)),s=this.removeEmpty(this.tokenize(a,n));return this.diffWithOptionsObj(o,s,n,r)}diffWithOptionsObj(e,t,n,r){let i=e=>{if(e=this.postProcess(e,n),r)setTimeout(function(){r(e)},0);else return e},a=t.length,o=e.length,s=1,c=a+o;n.maxEditLength!=null&&(c=Math.min(c,n.maxEditLength));let l=n.timeout??1/0,u=Date.now()+l,d=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(d[0],t,e,0,n);if(d[0].oldPos+1>=o&&f+1>=a)return i(this.buildValues(d[0].lastComponent,t,e));let p=-1/0,m=1/0,ee=()=>{for(let r=Math.max(p,-s);r<=Math.min(m,s);r+=2){let s,c=d[r-1],l=d[r+1];c&&(d[r-1]=void 0);let u=!1;if(l){let e=l.oldPos-r;u=l&&0<=e&&e<a}let ee=c&&c.oldPos+1<o;if(!u&&!ee)d[r]=void 0;else{if(s=!ee||u&&c.oldPos<l.oldPos?this.addToPath(l,!0,!1,0,n):this.addToPath(c,!1,!0,1,n),f=this.extractCommon(s,t,e,r,n),s.oldPos+1>=o&&f+1>=a)return i(this.buildValues(s.lastComponent,t,e))||!0;d[r]=s,s.oldPos+1>=o&&(m=Math.min(m,r-1)),f+1>=a&&(p=Math.max(p,r+1))}}s++};if(r)(function e(){setTimeout(function(){if(s>c||Date.now()>u)return r(void 0);ee()||e()},0)})();else for(;s<=c&&Date.now()<=u;){let e=ee();if(e)return e}}addToPath(e,t,n,r,i){let a=e.lastComponent;return a&&!i.oneChangePerToken&&a.added===t&&a.removed===n?{oldPos:e.oldPos+r,lastComponent:{count:a.count+1,added:t,removed:n,previousComponent:a.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:n,previousComponent:a}}}extractCommon(e,t,n,r,i){let a=t.length,o=n.length,s=e.oldPos,c=s-r,l=0;for(;c+1<a&&s+1<o&&this.equals(n[s+1],t[c+1],i);)c++,s++,l++,i.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return l&&!i.oneChangePerToken&&(e.lastComponent={count:l,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,c}equals(e,t,n){return n.comparator?n.comparator(e,t):e===t||!!n.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join(``)}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,n){let r=[],i;for(;e;)r.push(e),i=e.previousComponent,delete e.previousComponent,e=i;r.reverse();let a=r.length,o=0,s=0,c=0;for(;o<a;o++){let e=r[o];if(e.removed)e.value=this.join(n.slice(c,c+e.count)),c+=e.count;else{if(!e.added&&this.useLongestToken){let r=t.slice(s,s+e.count);r=r.map(function(e,t){let r=n[c+t];return r.length>e.length?r:e}),e.value=this.join(r)}else e.value=this.join(t.slice(s,s+e.count));s+=e.count,e.added||(c+=e.count)}}return r}},nr=new class extends tr{};function rr(e,t,n){return nr.diff(e,t,n)}function ir(e,t){let n=0;for(;n<e.length&&n<t.length;n++)if(e[n]!=t[n])return e.slice(0,n);return e.slice(0,n)}function ar(e,t){let n;if(!e||!t||e[e.length-1]!=t[t.length-1])return``;for(n=0;n<e.length&&n<t.length;n++)if(e[e.length-(n+1)]!=t[t.length-(n+1)])return e.slice(-n);return e.slice(-n)}function or(e,t,n){if(e.slice(0,t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't start with prefix ${JSON.stringify(t)}; this is a bug`);return n+e.slice(t.length)}function sr(e,t,n){if(!t)return e+n;if(e.slice(-t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't end with suffix ${JSON.stringify(t)}; this is a bug`);return e.slice(0,-t.length)+n}function cr(e,t){return or(e,t,``)}function lr(e,t){return sr(e,t,``)}function ur(e,t){return t.slice(0,dr(e,t))}function dr(e,t){let n=0;e.length>t.length&&(n=e.length-t.length);let r=t.length;e.length<t.length&&(r=e.length);let i=Array(r),a=0;i[0]=0;for(let e=1;e<r;e++){for(t[e]==t[a]?i[e]=i[a]:i[e]=a;a>0&&t[e]!=t[a];)a=i[a];t[e]==t[a]&&a++}a=0;for(let r=n;r<e.length;r++){for(;a>0&&e[r]!=t[a];)a=i[a];e[r]==t[a]&&a++}return a}function fr(e,t){let n=[];for(let r of Array.from(t.segment(e))){let e=r.segment;n.length&&/\s/.test(n[n.length-1])&&/\s/.test(e)?n[n.length-1]+=e:n.push(e)}return n}function pr(e,t){if(t)return hr(e,t)[1];let n;for(n=e.length-1;n>=0&&e[n].match(/\s/);n--);return e.substring(n+1)}function mr(e,t){if(t)return hr(e,t)[0];let n=e.match(/^\s*/);return n?n[0]:``}function hr(e,t){if(!t)return[mr(e),pr(e)];if(t.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);let n=fr(e,t),r=n[0],i=n[n.length-1];return[/\s/.test(r)?r:``,/\s/.test(i)?i:``]}var gr=`a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}`,_r=RegExp(`[${gr}]+|\\s+|[^${gr}]`,`ug`);new class extends tr{equals(e,t,n){return n.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let n;if(t.intlSegmenter){let r=t.intlSegmenter;if(r.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);n=fr(e,r)}else n=e.match(_r)||[];let r=[],i=null;return n.forEach(e=>{/\s/.test(e)?i==null?r.push(e):r.push(r.pop()+e):i!=null&&/\s/.test(i)?r[r.length-1]==i?r.push(r.pop()+e):r.push(i+e):r.push(e),i=e}),r}join(e){return e.map((e,t)=>t==0?e:e.replace(/^\s+/,``)).join(``)}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let n=null,r=null,i=null;return e.forEach(e=>{e.added?r=e:e.removed?i=e:((r||i)&&vr(n,i,r,e,t.intlSegmenter),n=e,r=null,i=null)}),(r||i)&&vr(n,i,r,null,t.intlSegmenter),e}};function vr(e,t,n,r,i){if(t&&n){let[a,o]=hr(t.value,i),[s,c]=hr(n.value,i);if(e){let r=ir(a,s);e.value=sr(e.value,s,r),t.value=cr(t.value,r),n.value=cr(n.value,r)}if(r){let e=ar(o,c);r.value=or(r.value,c,e),t.value=lr(t.value,e),n.value=lr(n.value,e)}}else if(n){if(e){let e=mr(n.value,i);n.value=n.value.substring(e.length)}if(r){let e=mr(r.value,i);r.value=r.value.substring(e.length)}}else if(e&&r){let n=mr(r.value,i),[a,o]=hr(t.value,i),s=ir(n,a);t.value=cr(t.value,s);let c=ar(cr(n,s),o);t.value=lr(t.value,c),r.value=or(r.value,n,c),e.value=sr(e.value,n,n.slice(0,n.length-c.length))}else if(r){let e=mr(r.value,i),n=ur(pr(t.value,i),e);t.value=lr(t.value,n)}else if(e){let n=ur(pr(e.value,i),mr(t.value,i));t.value=cr(t.value,n)}}new class extends tr{tokenize(e){let t=RegExp(`(\\r?\\n)|[${gr}]+|[^\\S\\n\\r]+|[^${gr}]`,`ug`);return e.match(t)||[]}},new class extends tr{constructor(){super(...arguments),this.tokenize=yr}equals(e,t,n){return n.ignoreWhitespace?((!n.newlineIsToken||!e.includes(`
154
+ `,Xn=class extends ${constructor(e){super(e,`Variables`)}createButton(){let e=this.editor.variables??[];if(!qn(e).length)return null;let t=`variable-popover-${Math.random().toString(36).slice(2,7)}`,n=document.createElement(`button`);n.innerHTML=Yn,n.querySelector(`svg`)?.setAttribute(`aria-hidden`,`true`),n.type=`button`,n.title=this.editor.label(`Insert variable`),n.setAttribute(`aria-label`,this.editor.label(`Insert variable`)),n.setAttribute(`aria-haspopup`,`menu`),n.className=`markdown-btn variable-btn fj:me-btn fj:me-btn-xs fj:me-btn-square fj:me-btn-ghost fj:me-popover-toggle`,n.setAttribute(`popovertarget`,t);let r=document.createElement(`div`);r.id=t,r.setAttribute(`role`,`menu`),r.setAttribute(`aria-label`,this.editor.label(`Variables`)),r.className=`fj:me-popover-content`,r.setAttribute(`popover`,``);let i=document.createElement(`ul`);i.className=`fj:me-menu`,i.setAttribute(`role`,`presentation`);let a=e=>e&&e.label&&typeof e.value==`string`;for(let t of e)if(t){if(Array.isArray(t.items)){let e=t.items.filter(a);if(!e.length)continue;let n=document.createElement(`li`);n.className=`fj:me-menu-title`,n.setAttribute(`role`,`presentation`),n.textContent=t.label??``;let o=document.createElement(`ul`);o.setAttribute(`role`,`group`),t.label&&o.setAttribute(`aria-label`,t.label),e.forEach(e=>o.appendChild(this.createItem(e,r)));let s=document.createElement(`li`);s.setAttribute(`role`,`none`),s.appendChild(o),i.appendChild(n),i.appendChild(s)}else a(t)&&i.appendChild(this.createItem(t,r))}r.appendChild(i);let o=document.createElement(`div`);return o.className=`fj:me-popover`,o.appendChild(n),o.appendChild(r),o}createItem(e,t){let n=document.createElement(`li`);n.setAttribute(`role`,`none`);let r=document.createElement(`button`);return r.type=`button`,r.setAttribute(`role`,`menuitem`),r.className=`fj:me-menu-item`,r.textContent=e.label,r.title=e.value,r.addEventListener(`click`,()=>{this.editor.insertText(e.value,e.value.length,0),t.hidePopover()}),n.appendChild(r),n}applySyntax(){}},Zn=class extends ${constructor(e,t={}){super(e,t.title||`Custom`),this.action=t.action,this.button=typeof this.action==`function`?this.createButton(t.icon||``):null,this.shortcut=this.button?t.shortcut:void 0,this.button||console.warn(`[MarkdownEditor] A custom tool needs an action function. Skipping it.`,t)}applySyntax(e){this.action(this.editor,e)}},Qn=class{constructor(e,t,{standalone:n=!1}={}){this.editor=e,this.options=t,this.standalone=n,this.tools=[],this.toolbar=document.createElement(`div`),this.toolbar.className=n?`toolbar not-prose fj:flex fj:items-center fj:gap-x-1`:`toolbar not-prose fj:me-surface fj:me-surface-outline fj:border-base-soft fj:border-0 fj:border-b fj:flex fj:items-center fj:gap-x-1 fj:p-1.5 fj:overflow-x-auto`,this.toolbar.setAttribute(`role`,`toolbar`),this.toolbar.setAttribute(`aria-label`,e.label(`Editor toolbar`)),this.init()}destroy(){this.tools.forEach(e=>e.destroy?.())}init(){let e={heading:In,ul:Dn,ol:On,checklist:An,bold:wn,italic:Tn,strikethrough:En,blockquote:jn,code:Un,codeblock:Wn,hr:Gn,table:Kn,link:Nn,image:Rn,undo:zn,redo:Bn,indent:Vn,outdent:Hn,variables:Xn};if(this.options.forEach(t=>{let n,r;if(typeof t==`string`)n=e[t];else if(typeof t==`function`)n=t;else if(t&&typeof t.tool==`function`)n=t.tool,r=t.config;else if(t&&t.custom)n=Zn,r=t.custom;else if(typeof t==`object`){let i=Object.keys(t)[0];r=t[i],n=e[i]}if(n){let e=new n(this.editor,r);this.tools.push(e),e.button&&this.toolbar.appendChild(e.button)}}),!this.standalone){if(this.options.includes(`preview`)){let e=new kn(this.editor);this.editor.previewTool=e,this.toolbar.appendChild(e.button)}this.editor.editorContainer.insertBefore(this.toolbar,this.editor.markdownEditorDiv)}}},$n=class{constructor(e){this.previewContainer=document.createElement(`div`),this.previewContainer.className=`preview-wrapper fj:p-2 fj:hidden fj:me-surface fj:me-surface-outline fj:border-base-soft fj:border-0 fj:border-l`,this.previewContainer.setAttribute(`role`,`region`),this.previewContainer.setAttribute(`aria-label`,`Preview`),this.previewContent=document.createElement(`div`),this.previewContent.className=`preview-content fj:mte-prose fj:mte-prose-sm fj:md:mte-prose-base fj:me-prose-frutjam fj:p-1.5 fj:overflow-y-auto fj:h-full fj:max-w-full`,this.previewContainer.appendChild(this.previewContent),e.appendChild(this.previewContainer)}getPreviewContent(){return this.previewContent}},er=class{constructor(e,t={},n=e=>e){this.options=t,this.label=n,this.footer=document.createElement(`div`),this.footer.className=`editor-footer not-prose fj:me-surface fj:me-surface-outline fj:border-base-soft fj:border-0 fj:border-t fj:flex fj:justify-between fj:items-center fj:px-3 fj:py-1 fj:text-xs fj:opacity-60 fj:select-none`,this.footer.setAttribute(`aria-hidden`,`true`),this.positionEl=document.createElement(`span`),this.charsEl=document.createElement(`span`),this.wordsEl=document.createElement(`span`),(this.options.line||this.options.col)&&this.footer.appendChild(this.positionEl),this.options.chars&&this.footer.appendChild(this.charsEl),this.options.words&&this.footer.appendChild(this.wordsEl),e.appendChild(this.footer)}update(e){let t=e.value,n=e.selectionStart??0;if(this.options.line||this.options.col){let e=t.substring(0,n).split(`
155
+ `),r=[];this.options.line&&r.push(this._count(`Ln {n}`,e.length)),this.options.col&&r.push(this._count(`Col {n}`,e[e.length-1].length+1)),this.positionEl.textContent=r.join(`, `)}if(this.options.chars&&(this.charsEl.textContent=this._count(`{n} chars`,t.length)),this.options.words){let e=t.trim()?t.trim().split(/\s+/).length:0;this.wordsEl.textContent=this._count(`{n} words`,e)}}_count(e,t){return this.label(e).replace(`{n}`,t.toLocaleString())}},tr=class{diff(e,t,n={}){let r;typeof n==`function`?(r=n,n={}):`callback`in n&&(r=n.callback);let i=this.castInput(e,n),a=this.castInput(t,n),o=this.removeEmpty(this.tokenize(i,n)),s=this.removeEmpty(this.tokenize(a,n));return this.diffWithOptionsObj(o,s,n,r)}diffWithOptionsObj(e,t,n,r){let i=e=>{if(e=this.postProcess(e,n),r)setTimeout(function(){r(e)},0);else return e},a=t.length,o=e.length,s=1,c=a+o;n.maxEditLength!=null&&(c=Math.min(c,n.maxEditLength));let l=n.timeout??1/0,u=Date.now()+l,d=[{oldPos:-1,lastComponent:void 0}],f=this.extractCommon(d[0],t,e,0,n);if(d[0].oldPos+1>=o&&f+1>=a)return i(this.buildValues(d[0].lastComponent,t,e));let p=-1/0,m=1/0,ee=()=>{for(let r=Math.max(p,-s);r<=Math.min(m,s);r+=2){let s,c=d[r-1],l=d[r+1];c&&(d[r-1]=void 0);let u=!1;if(l){let e=l.oldPos-r;u=l&&0<=e&&e<a}let ee=c&&c.oldPos+1<o;if(!u&&!ee)d[r]=void 0;else{if(s=!ee||u&&c.oldPos<l.oldPos?this.addToPath(l,!0,!1,0,n):this.addToPath(c,!1,!0,1,n),f=this.extractCommon(s,t,e,r,n),s.oldPos+1>=o&&f+1>=a)return i(this.buildValues(s.lastComponent,t,e))||!0;d[r]=s,s.oldPos+1>=o&&(m=Math.min(m,r-1)),f+1>=a&&(p=Math.max(p,r+1))}}s++};if(r)(function e(){setTimeout(function(){if(s>c||Date.now()>u)return r(void 0);ee()||e()},0)})();else for(;s<=c&&Date.now()<=u;){let e=ee();if(e)return e}}addToPath(e,t,n,r,i){let a=e.lastComponent;return a&&!i.oneChangePerToken&&a.added===t&&a.removed===n?{oldPos:e.oldPos+r,lastComponent:{count:a.count+1,added:t,removed:n,previousComponent:a.previousComponent}}:{oldPos:e.oldPos+r,lastComponent:{count:1,added:t,removed:n,previousComponent:a}}}extractCommon(e,t,n,r,i){let a=t.length,o=n.length,s=e.oldPos,c=s-r,l=0;for(;c+1<a&&s+1<o&&this.equals(n[s+1],t[c+1],i);)c++,s++,l++,i.oneChangePerToken&&(e.lastComponent={count:1,previousComponent:e.lastComponent,added:!1,removed:!1});return l&&!i.oneChangePerToken&&(e.lastComponent={count:l,previousComponent:e.lastComponent,added:!1,removed:!1}),e.oldPos=s,c}equals(e,t,n){return n.comparator?n.comparator(e,t):e===t||!!n.ignoreCase&&e.toLowerCase()===t.toLowerCase()}removeEmpty(e){let t=[];for(let n=0;n<e.length;n++)e[n]&&t.push(e[n]);return t}castInput(e,t){return e}tokenize(e,t){return Array.from(e)}join(e){return e.join(``)}postProcess(e,t){return e}get useLongestToken(){return!1}buildValues(e,t,n){let r=[],i;for(;e;)r.push(e),i=e.previousComponent,delete e.previousComponent,e=i;r.reverse();let a=r.length,o=0,s=0,c=0;for(;o<a;o++){let e=r[o];if(e.removed)e.value=this.join(n.slice(c,c+e.count)),c+=e.count;else{if(!e.added&&this.useLongestToken){let r=t.slice(s,s+e.count);r=r.map(function(e,t){let r=n[c+t];return r.length>e.length?r:e}),e.value=this.join(r)}else e.value=this.join(t.slice(s,s+e.count));s+=e.count,e.added||(c+=e.count)}}return r}},nr=new class extends tr{};function rr(e,t,n){return nr.diff(e,t,n)}function ir(e,t){let n=0;for(;n<e.length&&n<t.length;n++)if(e[n]!=t[n])return e.slice(0,n);return e.slice(0,n)}function ar(e,t){let n;if(!e||!t||e[e.length-1]!=t[t.length-1])return``;for(n=0;n<e.length&&n<t.length;n++)if(e[e.length-(n+1)]!=t[t.length-(n+1)])return e.slice(-n);return e.slice(-n)}function or(e,t,n){if(e.slice(0,t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't start with prefix ${JSON.stringify(t)}; this is a bug`);return n+e.slice(t.length)}function sr(e,t,n){if(!t)return e+n;if(e.slice(-t.length)!=t)throw Error(`string ${JSON.stringify(e)} doesn't end with suffix ${JSON.stringify(t)}; this is a bug`);return e.slice(0,-t.length)+n}function cr(e,t){return or(e,t,``)}function lr(e,t){return sr(e,t,``)}function ur(e,t){return t.slice(0,dr(e,t))}function dr(e,t){let n=0;e.length>t.length&&(n=e.length-t.length);let r=t.length;e.length<t.length&&(r=e.length);let i=Array(r),a=0;i[0]=0;for(let e=1;e<r;e++){for(t[e]==t[a]?i[e]=i[a]:i[e]=a;a>0&&t[e]!=t[a];)a=i[a];t[e]==t[a]&&a++}a=0;for(let r=n;r<e.length;r++){for(;a>0&&e[r]!=t[a];)a=i[a];e[r]==t[a]&&a++}return a}function fr(e,t){let n=[];for(let r of Array.from(t.segment(e))){let e=r.segment;n.length&&/\s/.test(n[n.length-1])&&/\s/.test(e)?n[n.length-1]+=e:n.push(e)}return n}function pr(e,t){if(t)return hr(e,t)[1];let n;for(n=e.length-1;n>=0&&e[n].match(/\s/);n--);return e.substring(n+1)}function mr(e,t){if(t)return hr(e,t)[0];let n=e.match(/^\s*/);return n?n[0]:``}function hr(e,t){if(!t)return[mr(e),pr(e)];if(t.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);let n=fr(e,t),r=n[0],i=n[n.length-1];return[/\s/.test(r)?r:``,/\s/.test(i)?i:``]}var gr=`a-zA-Z0-9_\\u{AD}\\u{C0}-\\u{D6}\\u{D8}-\\u{F6}\\u{F8}-\\u{2C6}\\u{2C8}-\\u{2D7}\\u{2DE}-\\u{2FF}\\u{1E00}-\\u{1EFF}`,_r=RegExp(`[${gr}]+|\\s+|[^${gr}]`,`ug`);new class extends tr{equals(e,t,n){return n.ignoreCase&&(e=e.toLowerCase(),t=t.toLowerCase()),e.trim()===t.trim()}tokenize(e,t={}){let n;if(t.intlSegmenter){let r=t.intlSegmenter;if(r.resolvedOptions().granularity!=`word`)throw Error(`The segmenter passed must have a granularity of "word"`);n=fr(e,r)}else n=e.match(_r)||[];let r=[],i=null;return n.forEach(e=>{/\s/.test(e)?i==null?r.push(e):r.push(r.pop()+e):i!=null&&/\s/.test(i)?r[r.length-1]==i?r.push(r.pop()+e):r.push(i+e):r.push(e),i=e}),r}join(e){return e.map((e,t)=>t==0?e:e.replace(/^\s+/,``)).join(``)}postProcess(e,t){if(!e||t.oneChangePerToken)return e;let n=null,r=null,i=null;return e.forEach(e=>{e.added?r=e:e.removed?i=e:((r||i)&&vr(n,i,r,e,t.intlSegmenter),n=e,r=null,i=null)}),(r||i)&&vr(n,i,r,null,t.intlSegmenter),e}};function vr(e,t,n,r,i){if(t&&n){let[a,o]=hr(t.value,i),[s,c]=hr(n.value,i);if(e){let r=ir(a,s);e.value=sr(e.value,s,r),t.value=cr(t.value,r),n.value=cr(n.value,r)}if(r){let e=ar(o,c);r.value=or(r.value,c,e),t.value=lr(t.value,e),n.value=lr(n.value,e)}}else if(n){if(e){let e=mr(n.value,i);n.value=n.value.substring(e.length)}if(r){let e=mr(r.value,i);r.value=r.value.substring(e.length)}}else if(e&&r){let n=mr(r.value,i),[a,o]=hr(t.value,i),s=ir(n,a);t.value=cr(t.value,s);let c=ar(cr(n,s),o);t.value=lr(t.value,c),r.value=or(r.value,n,c),e.value=sr(e.value,n,n.slice(0,n.length-c.length))}else if(r){let e=mr(r.value,i),n=ur(pr(t.value,i),e);t.value=lr(t.value,n)}else if(e){let n=ur(pr(e.value,i),mr(t.value,i));t.value=cr(t.value,n)}}new class extends tr{tokenize(e){let t=RegExp(`(\\r?\\n)|[${gr}]+|[^\\S\\n\\r]+|[^${gr}]`,`ug`);return e.match(t)||[]}},new class extends tr{constructor(){super(...arguments),this.tokenize=yr}equals(e,t,n){return n.ignoreWhitespace?((!n.newlineIsToken||!e.includes(`
156
156
  `))&&(e=e.trim()),(!n.newlineIsToken||!t.includes(`
157
157
  `))&&(t=t.trim())):n.ignoreNewlineAtEof&&!n.newlineIsToken&&(e.endsWith(`
158
158
  `)&&(e=e.slice(0,-1)),t.endsWith(`
@@ -172,10 +172,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
172
172
  `);this._applyChange(r.substring(0,i)+l+r.substring(a),Math.max(i,t-s),Math.max(i,n-c))}_applyChange(e,t,n){this.textarea.value=e,this.textarea.setSelectionRange(t,n)}},wr=class{constructor(e){this.editor=e,this.textarea=e.usertextarea,this._keydownHandler=e=>{e.key===`Enter`&&this.handleEnter(e)},this.textarea.addEventListener(`keydown`,this._keydownHandler)}destroy(){this.textarea.removeEventListener(`keydown`,this._keydownHandler)}handleEnter(e){let{selectionStart:t,value:n}=this.textarea,r=n.lastIndexOf(`
173
173
  `,t-1)+1,i=n.substring(r,t),a=i.match(/^(\s*)(\d+)\.\s/),o=i.match(/^(\s*)([\-\*] )\[[\s xX]\] /),s=i.match(/^(\s*)([\-\*] )\s*/);if(i.match(/^(\s*)(\d+\.\s|[\-\*] \[[\s xX]\] |[\-\*]\s)$/)){e.preventDefault();let i=n.substring(0,r),a=n.substring(t);this.textarea.value=i+`
174
174
  `+a,this.textarea.setSelectionRange(r+1,r+1),this.editor.render(),this.editor.notifyChange();return}let c=null;if(a?c=`${a[1]}${parseInt(a[2])+1}. `:o?c=`${o[1]}${o[2]}[ ] `:s&&(c=`${s[1]}${s[2]}`),c){e.preventDefault();let r=`\n${c}`,i=n.substring(0,t),a=n.substring(t);this.textarea.value=i+r+a;let o=t+r.length;this.textarea.setSelectionRange(o,o),this.editor.render(),this.editor.notifyChange()}}},Tr=[{key:`b`,ctrl:!0,shift:!1,ToolClass:wn,label:`Ctrl+B`,btnClass:`bold-btn`},{key:`i`,ctrl:!0,shift:!1,ToolClass:Tn,label:`Ctrl+I`,btnClass:`italic-btn`},{key:`k`,ctrl:!0,shift:!1,ToolClass:Nn,label:`Ctrl+K`,btnClass:`link-btn`},{key:"`",ctrl:!0,shift:!1,ToolClass:Un,label:"Ctrl+`",btnClass:`code-btn`},{key:`s`,ctrl:!0,shift:!0,ToolClass:En,label:`Ctrl+Shift+S`,btnClass:`strikethrough-btn`},{key:`l`,ctrl:!0,shift:!1,ToolClass:Dn,label:`Ctrl+L`,btnClass:`ul-btn`}];function Er(e){let t=String(e).split(`+`).map(e=>e.trim().toLowerCase()),n=t.pop();return n?{key:n,ctrl:t.includes(`ctrl`)||t.includes(`cmd`)||t.includes(`meta`),shift:t.includes(`shift`),alt:t.includes(`alt`)}:null}var Dr=class{constructor(e){this.editor=e,this.toolShortcuts=(e.toolbarInstance?.tools??[]).filter(e=>e.shortcut).map(e=>({tool:e,combo:Er(e.shortcut)})).filter(e=>e.combo);let t=(e.toolbarInstance?.tools??[]).find(e=>e instanceof In);this.headingLevels=t?.levels??[1,2,3,4,5,6],this._handler=this._onKeyDown.bind(this),this._docHandler=this._onDocKeyDown.bind(this),e.usertextarea.addEventListener(`keydown`,this._handler),document.addEventListener(`keydown`,this._docHandler),this._updateTooltips()}_onKeyDown(e){let t=e.ctrlKey||e.metaKey,n=e.shiftKey,r=e.key.toLowerCase();if(t&&n&&r===`f`)e.preventDefault(),this.editor.editorContainer.querySelector(`.preview-btn`)?.click();else if(t&&!n&&[`1`,`2`,`3`].includes(e.key)&&this.headingLevels.includes(parseInt(e.key)))e.preventDefault(),new In(this.editor).applyHeading(parseInt(e.key));else{for(let{tool:i,combo:a}of this.toolShortcuts)if(r===a.key&&t===a.ctrl&&n===a.shift&&e.altKey===a.alt){e.preventDefault(),i.applySyntax(e);return}for(let i of Tr)if(r===i.key&&t===i.ctrl&&n===i.shift){e.preventDefault(),new i.ToolClass(this.editor).applySyntax(e);return}}}_onDocKeyDown(e){if(e.key===`F11`){let t=this.editor.editorContainer.contains(document.activeElement),n=this.editor.editorContainer.classList.contains(`is-fullscreen`);(t||n)&&(e.preventDefault(),this.editor.editorContainer.querySelector(`.preview-btn`)?.click())}}_updateTooltips(){for(let{btnClass:e,label:t}of Tr){let n=this.editor.editorContainer.querySelector(`.${e}`);n&&(n.title+=` (${t})`)}let e=this.editor.editorContainer.querySelector(`.heading-btn`),t=this.headingLevels.filter(e=>e<=3);e&&t.length&&(e.title+=` (Ctrl+${t.join(`/`)})`);let n=this.editor.editorContainer.querySelector(`.preview-btn`);n&&(n.title+=` (F11)`);for(let{tool:e}of this.toolShortcuts)e.button&&(e.button.title+=` (${e.shortcut})`)}destroy(){this.editor.usertextarea.removeEventListener(`keydown`,this._handler),document.removeEventListener(`keydown`,this._docHandler)}},Or=class{constructor(e){this.editor=e,this._matches=[],this._currentIndex=-1,this._caseSensitive=!1,this._panel=null,this._findInput=null,this._replaceInput=null,this._countEl=null,this._replaceRow=null,this._caseSensitiveBtn=null,this._highlightEl=null,this._scrollHandler=null,this._taHandler=this._onTextareaKeyDown.bind(this),e.usertextarea.addEventListener(`keydown`,this._taHandler)}_onTextareaKeyDown(e){let t=e.ctrlKey||e.metaKey;t&&e.key===`f`?(e.preventDefault(),this.open(!1)):t&&e.key===`h`&&(e.preventDefault(),this.open(!0))}open(e=!1){this._panel||this._buildPanel(),this._panel.hidden=!1,e&&(this._replaceRow.hidden=!1),this._findInput.focus(),this._findInput.select();let t=this.editor.usertextarea.value.substring(this.editor.usertextarea.selectionStart,this.editor.usertextarea.selectionEnd);t&&!t.includes(`
175
- `)&&(this._findInput.value=t),this._scrollHandler||(this._scrollHandler=()=>this._showMatchHighlight(),this.editor.usertextarea.addEventListener(`scroll`,this._scrollHandler)),this._search()}close(){if(!this._panel)return;this._panel.hidden=!0,this._clearMatchHighlight(),this._scrollHandler&&=(this.editor.usertextarea.removeEventListener(`scroll`,this._scrollHandler),null);let e=this.editor.usertextarea;if(this._currentIndex!==-1&&this._matches.length){let{start:t,end:n}=this._matches[this._currentIndex];e.focus(),e.setSelectionRange(t,n)}else e.focus();this._matches=[],this._currentIndex=-1}_buildPanel(){let e=document.createElement(`div`);e.className=`find-replace-panel fj:absolute fj:top-1 fj:right-1 fj:z-20 fj:me-surface fj:me-surface-outline fj:me-surface-rounded fj:p-1.5 fj:flex fj:flex-col fj:gap-1 fj:shadow-lg`,e.setAttribute(`role`,`search`),e.setAttribute(`aria-label`,`Find and replace`);let t=document.createElement(`div`);t.className=`fj:flex fj:items-center fj:gap-1`,this._findInput=document.createElement(`input`),this._findInput.type=`text`,this._findInput.placeholder=`Find`,this._findInput.className=`fj:me-input fj:me-input-xs fj:w-36`,this._findInput.setAttribute(`aria-label`,`Find`),this._findInput.addEventListener(`input`,()=>this._search()),this._findInput.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.shiftKey?this._prev():this._next()),e.key===`Escape`&&(e.preventDefault(),this.close())}),this._countEl=document.createElement(`span`),this._countEl.className=`fj:text-xs fj:opacity-50 fj:whitespace-nowrap fj:min-w-[3.5rem] fj:text-center fj:select-none`,this._countEl.setAttribute(`aria-live`,`polite`);let n=this._iconBtn(`Previous match`,`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>`);n.addEventListener(`click`,()=>this._prev());let r=this._iconBtn(`Next match`,`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>`);r.addEventListener(`click`,()=>this._next()),this._caseSensitiveBtn=document.createElement(`button`),this._caseSensitiveBtn.type=`button`,this._caseSensitiveBtn.className=`fj:me-btn fj:me-btn-xs fj:me-btn-square fj:me-btn-ghost fj:text-xs fj:font-bold`,this._caseSensitiveBtn.textContent=`Aa`,this._caseSensitiveBtn.setAttribute(`aria-label`,`Match case`),this._caseSensitiveBtn.setAttribute(`aria-pressed`,`false`),this._caseSensitiveBtn.title=`Match case`,this._caseSensitiveBtn.addEventListener(`click`,()=>{this._caseSensitive=!this._caseSensitive,this._caseSensitiveBtn.setAttribute(`aria-pressed`,String(this._caseSensitive)),this._caseSensitiveBtn.classList.toggle(`fj:me-btn-active`,this._caseSensitive),this._search()});let i=document.createElement(`button`);i.type=`button`,i.className=`fj:me-btn fj:me-btn-xs fj:me-btn-ghost fj:text-xs fj:px-1.5`,i.textContent=`Replace`,i.setAttribute(`aria-label`,`Toggle replace row`),i.addEventListener(`click`,()=>{this._replaceRow.hidden=!this._replaceRow.hidden,this._replaceRow.hidden||this._replaceInput.focus()});let a=this._iconBtn(`Close`,`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`);a.addEventListener(`click`,()=>this.close()),t.append(this._findInput,this._countEl,n,r,this._caseSensitiveBtn,i,a),this._replaceRow=document.createElement(`div`),this._replaceRow.className=`fj:flex fj:items-center fj:gap-1`,this._replaceRow.hidden=!0,this._replaceInput=document.createElement(`input`),this._replaceInput.type=`text`,this._replaceInput.placeholder=`Replace`,this._replaceInput.className=`fj:me-input fj:me-input-xs fj:w-36`,this._replaceInput.setAttribute(`aria-label`,`Replace with`),this._replaceInput.addEventListener(`keydown`,e=>{e.key===`Enter`&&this._replace(),e.key===`Escape`&&(e.preventDefault(),this.close())});let o=document.createElement(`button`);o.type=`button`,o.className=`fj:me-btn fj:me-btn-xs fj:me-btn-ghost fj:text-xs fj:px-1.5`,o.textContent=`Replace`,o.addEventListener(`click`,()=>this._replace());let s=document.createElement(`button`);s.type=`button`,s.className=`fj:me-btn fj:me-btn-xs fj:me-btn-ghost fj:text-xs fj:px-1.5`,s.textContent=`All`,s.setAttribute(`aria-label`,`Replace all`),s.addEventListener(`click`,()=>this._replaceAll()),this._replaceRow.append(this._replaceInput,o,s),e.append(t,this._replaceRow),this.editor.markdownEditorDiv.appendChild(e),this._panel=e}_iconBtn(e,t){let n=document.createElement(`button`);n.type=`button`,n.className=`fj:me-btn fj:me-btn-xs fj:me-btn-square fj:me-btn-ghost`,n.setAttribute(`aria-label`,e),n.innerHTML=t;let r=n.querySelector(`svg`);return r&&r.setAttribute(`aria-hidden`,`true`),n}_search(){let e=this._findInput?.value??``,t=this.editor.usertextarea.value;if(!e){this._matches=[],this._currentIndex=-1,this._clearMatchHighlight(),this._updateCount();return}let n=this._caseSensitive?t:t.toLowerCase(),r=this._caseSensitive?e:e.toLowerCase();this._matches=[];let i=0;for(;i<=n.length-r.length;){let t=n.indexOf(r,i);if(t===-1)break;this._matches.push({start:t,end:t+e.length}),i=t+1}this._currentIndex=this._matches.length>0?Math.min(Math.max(this._currentIndex,0),this._matches.length-1):-1,this._selectCurrent(),this._updateCount()}_next(){this._matches.length!==0&&(this._currentIndex=(this._currentIndex+1)%this._matches.length,this._selectCurrent(),this._updateCount())}_prev(){this._matches.length!==0&&(this._currentIndex=(this._currentIndex-1+this._matches.length)%this._matches.length,this._selectCurrent(),this._updateCount())}_selectCurrent(){if(this._currentIndex===-1||this._matches.length===0){this._clearMatchHighlight();return}let{start:e}=this._matches[this._currentIndex];this._scrollToMatch(this.editor.usertextarea,e),this._showMatchHighlight()}_scrollToMatch(e,t){let n=parseInt(window.getComputedStyle(e).lineHeight)||20,r=e.value.substring(0,t).split(`
176
- `).length-1,i=Math.floor(e.clientHeight/n);e.scrollTop=Math.max(0,(r-Math.floor(i/2))*n)}_showMatchHighlight(){if(this._clearMatchHighlight(),this._currentIndex===-1||!this._matches.length)return;let{start:e,end:t}=this._matches[this._currentIndex],n=this.editor.usertextarea,r=window.getComputedStyle(n),i=n.parentElement,a=document.createElement(`div`);Object.assign(a.style,{position:`absolute`,visibility:`hidden`,pointerEvents:`none`,top:`0`,left:`0`,right:`0`,whiteSpace:`pre-wrap`,wordBreak:`break-word`,overflowWrap:`break-word`,font:r.font,lineHeight:r.lineHeight,paddingTop:r.paddingTop,paddingRight:r.paddingRight,paddingBottom:r.paddingBottom,paddingLeft:r.paddingLeft,boxSizing:`border-box`});let o=document.createElement(`span`);o.textContent=n.value.substring(e,t)||`​`,a.appendChild(document.createTextNode(n.value.substring(0,e))),a.appendChild(o),a.appendChild(document.createTextNode(n.value.substring(t))),i.appendChild(a);try{let e=i.getBoundingClientRect(),t=o.getBoundingClientRect(),r=document.createElement(`div`);Object.assign(r.style,{position:`absolute`,top:t.top-e.top-n.scrollTop+`px`,left:t.left-e.left+`px`,width:Math.max(t.width,2)+`px`,height:t.height+`px`,background:`color-mix(in oklch, var(--color-primary, oklch(0.6 0.2 250)), transparent 55%)`,borderRadius:`2px`,pointerEvents:`none`,zIndex:`2`}),i.appendChild(r),this._highlightEl=r}finally{i.removeChild(a)}}_clearMatchHighlight(){this._highlightEl?.remove(),this._highlightEl=null}_updateCount(){this._countEl&&(this._matches.length===0?this._countEl.textContent=this._findInput?.value?`No results`:``:this._countEl.textContent=`${this._currentIndex+1} of ${this._matches.length}`)}_replace(){if(this._currentIndex===-1)return;let{start:e,end:t}=this._matches[this._currentIndex],n=this.editor.usertextarea,r=this._replaceInput.value;n.value=n.value.substring(0,e)+r+n.value.substring(t),this.editor.render(),this.editor.notifyChange(),this._search()}_replaceAll(){let e=this._findInput?.value;if(!e)return;let t=this._replaceInput.value,n=this.editor.usertextarea,r=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),i=this._caseSensitive?`g`:`gi`;n.value=n.value.replace(new RegExp(r,i),t),this.editor.render(),this.editor.notifyChange(),this._currentIndex=0,this._search()}destroy(){this.editor.usertextarea.removeEventListener(`keydown`,this._taHandler),this._scrollHandler&&this.editor.usertextarea.removeEventListener(`scroll`,this._scrollHandler),this._clearMatchHighlight(),this._panel?.remove()}},kr=/^https?:\/\/\S+$/i,Ar=class{constructor(e){this.editor=e,this.textarea=e.usertextarea,this._pasteHandler=e=>this._onPaste(e),this._dropHandler=e=>this._onDrop(e),this._dragOverHandler=e=>{this._carriesFiles(e.dataTransfer)&&e.preventDefault()},this.textarea.addEventListener(`paste`,this._pasteHandler),this.textarea.addEventListener(`drop`,this._dropHandler),this.textarea.addEventListener(`dragover`,this._dragOverHandler)}destroy(){this.textarea.removeEventListener(`paste`,this._pasteHandler),this.textarea.removeEventListener(`drop`,this._dropHandler),this.textarea.removeEventListener(`dragover`,this._dragOverHandler)}_carriesFiles(e){return Array.from(e?.types??[]).includes(`Files`)}_imageFiles(e){return Array.from(e?.files??[]).filter(e=>e.type?.startsWith(`image/`))}_onPaste(e){let t=this._imageFiles(e.clipboardData);if(t.length){if(!this.editor.imageUpload){console.warn(`[MarkdownEditor] An image was pasted but no upload endpoint is configured. Add { image: { fileInput: { uploadUrl: "..." } } } to the toolbar to enable it.`);return}e.preventDefault(),this._uploadAll(t);return}let n=e.clipboardData?.getData(`text/plain`)?.trim(),{selectionStart:r,selectionEnd:i}=this.textarea;if(n&&i>r&&kr.test(n)){e.preventDefault();let t=`[${this.textarea.value.slice(r,i)}](${n})`;this.editor.insertText(t,t.length,0)}}_onDrop(e){if(!this._carriesFiles(e.dataTransfer))return;e.preventDefault();let t=this._imageFiles(e.dataTransfer);t.length&&(this.editor.imageUpload?this._uploadAll(t):console.warn(`[MarkdownEditor] An image was dropped but no upload endpoint is configured. Add { image: { fileInput: { uploadUrl: "..." } } } to the toolbar to enable it.`))}async _uploadAll(e){for(let t of e){let e=`![${this.editor.label(`Uploading...`)}]()`;this.editor.insertText(e,e.length,0);try{let{path:n,alt:r}=await Ln(t,this.editor.imageUpload);this._replace(e,`![${r}](${n})`)}catch(t){this._replace(e,`![${this.editor.label(`Upload failed`)}]()`),console.error(`[MarkdownEditor] Image upload failed.`,t)}}}_replace(e,t){let n=this.textarea,r=n.value.indexOf(e);if(r===-1)return;n.value=n.value.slice(0,r)+t+n.value.slice(r+e.length);let i=r+t.length;n.setSelectionRange(i,i),this.editor.render(),this.editor.notifyChange()}},jr=new rt({breaks:!0}),Mr=class e{constructor(e,t={}){this.usertextarea=typeof e==`string`?document.querySelector(e):e,this.options=t,this.mode=t.mode||`plain`,this.preview=!this.options.toolbar||this.options.toolbar.includes(`preview`),this.footerOptions=this._parseFooterOptions(t.footer),this.variables=this._parseVariables(t.toolbar),this.imageUpload=this._parseImageUpload(t.toolbar),this.previewTimer=null,this.init(),this.undoRedoManager=new Sr(this),this.listManager=new wr(this),this.indentManager=new Cr(this),this.shortcutManager=new Dr(this),this.findReplace=new Or(this),this.pasteManager=new Ar(this),this._warnIfStylesheetMissing()}_warnIfStylesheetMissing(){e._cssWarned||this.editorContainer?.isConnected&&(getComputedStyle(this.editorContainer).getPropertyValue(`--mte-css`).trim()||(e._cssWarned=!0,console.error(`[MarkdownEditor] Stylesheet not loaded, so the editor will look unstyled.
175
+ `)&&(this._findInput.value=t),this._scrollHandler||(this._scrollHandler=()=>this._showMatchHighlight(),this.editor.usertextarea.addEventListener(`scroll`,this._scrollHandler)),this._search()}close(){if(!this._panel)return;this._panel.hidden=!0,this._clearMatchHighlight(),this._scrollHandler&&=(this.editor.usertextarea.removeEventListener(`scroll`,this._scrollHandler),null);let e=this.editor.usertextarea;if(this._currentIndex!==-1&&this._matches.length){let{start:t,end:n}=this._matches[this._currentIndex];e.focus(),e.setSelectionRange(t,n)}else e.focus();this._matches=[],this._currentIndex=-1}_buildPanel(){let e=document.createElement(`div`);e.className=`find-replace-panel fj:absolute fj:top-1 fj:right-1 fj:z-20 fj:me-surface fj:me-surface-outline fj:me-surface-rounded fj:p-1.5 fj:flex fj:flex-col fj:gap-1 fj:shadow-lg`,e.setAttribute(`role`,`search`),e.setAttribute(`aria-label`,this.editor.label(`Find and replace`));let t=document.createElement(`div`);t.className=`fj:flex fj:items-center fj:gap-1`,this._findInput=document.createElement(`input`),this._findInput.type=`text`,this._findInput.placeholder=this.editor.label(`Find`),this._findInput.className=`fj:me-input fj:me-input-xs fj:w-36`,this._findInput.setAttribute(`aria-label`,this.editor.label(`Find`)),this._findInput.addEventListener(`input`,()=>this._search()),this._findInput.addEventListener(`keydown`,e=>{e.key===`Enter`&&(e.shiftKey?this._prev():this._next()),e.key===`Escape`&&(e.preventDefault(),this.close())}),this._countEl=document.createElement(`span`),this._countEl.className=`fj:text-xs fj:opacity-50 fj:whitespace-nowrap fj:min-w-[3.5rem] fj:text-center fj:select-none`,this._countEl.setAttribute(`aria-live`,`polite`);let n=this._iconBtn(`Previous match`,`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m18 15-6-6-6 6"/></svg>`);n.addEventListener(`click`,()=>this._prev());let r=this._iconBtn(`Next match`,`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="m6 9 6 6 6-6"/></svg>`);r.addEventListener(`click`,()=>this._next()),this._caseSensitiveBtn=document.createElement(`button`),this._caseSensitiveBtn.type=`button`,this._caseSensitiveBtn.className=`fj:me-btn fj:me-btn-xs fj:me-btn-square fj:me-btn-ghost fj:text-xs fj:font-bold`,this._caseSensitiveBtn.textContent=`Aa`,this._caseSensitiveBtn.setAttribute(`aria-label`,this.editor.label(`Match case`)),this._caseSensitiveBtn.setAttribute(`aria-pressed`,`false`),this._caseSensitiveBtn.title=this.editor.label(`Match case`),this._caseSensitiveBtn.addEventListener(`click`,()=>{this._caseSensitive=!this._caseSensitive,this._caseSensitiveBtn.setAttribute(`aria-pressed`,String(this._caseSensitive)),this._caseSensitiveBtn.classList.toggle(`fj:me-btn-active`,this._caseSensitive),this._search()});let i=document.createElement(`button`);i.type=`button`,i.className=`fj:me-btn fj:me-btn-xs fj:me-btn-ghost fj:text-xs fj:px-1.5`,i.textContent=this.editor.label(`Replace`),i.setAttribute(`aria-label`,this.editor.label(`Toggle replace row`)),i.addEventListener(`click`,()=>{this._replaceRow.hidden=!this._replaceRow.hidden,this._replaceRow.hidden||this._replaceInput.focus()});let a=this._iconBtn(`Close`,`<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>`);a.addEventListener(`click`,()=>this.close()),t.append(this._findInput,this._countEl,n,r,this._caseSensitiveBtn,i,a),this._replaceRow=document.createElement(`div`),this._replaceRow.className=`fj:flex fj:items-center fj:gap-1`,this._replaceRow.hidden=!0,this._replaceInput=document.createElement(`input`),this._replaceInput.type=`text`,this._replaceInput.placeholder=this.editor.label(`Replace`),this._replaceInput.className=`fj:me-input fj:me-input-xs fj:w-36`,this._replaceInput.setAttribute(`aria-label`,this.editor.label(`Replace with`)),this._replaceInput.addEventListener(`keydown`,e=>{e.key===`Enter`&&this._replace(),e.key===`Escape`&&(e.preventDefault(),this.close())});let o=document.createElement(`button`);o.type=`button`,o.className=`fj:me-btn fj:me-btn-xs fj:me-btn-ghost fj:text-xs fj:px-1.5`,o.textContent=this.editor.label(`Replace`),o.addEventListener(`click`,()=>this._replace());let s=document.createElement(`button`);s.type=`button`,s.className=`fj:me-btn fj:me-btn-xs fj:me-btn-ghost fj:text-xs fj:px-1.5`,s.textContent=this.editor.label(`All`),s.setAttribute(`aria-label`,this.editor.label(`Replace all`)),s.addEventListener(`click`,()=>this._replaceAll()),this._replaceRow.append(this._replaceInput,o,s),e.append(t,this._replaceRow),this.editor.markdownEditorDiv.appendChild(e),this._panel=e}_iconBtn(e,t){let n=document.createElement(`button`);n.type=`button`,n.className=`fj:me-btn fj:me-btn-xs fj:me-btn-square fj:me-btn-ghost`,n.setAttribute(`aria-label`,this.editor.label(e)),n.innerHTML=t;let r=n.querySelector(`svg`);return r&&r.setAttribute(`aria-hidden`,`true`),n}_search(){let e=this._findInput?.value??``,t=this.editor.usertextarea.value;if(!e){this._matches=[],this._currentIndex=-1,this._clearMatchHighlight(),this._updateCount();return}let n=this._caseSensitive?t:t.toLowerCase(),r=this._caseSensitive?e:e.toLowerCase();this._matches=[];let i=0;for(;i<=n.length-r.length;){let t=n.indexOf(r,i);if(t===-1)break;this._matches.push({start:t,end:t+e.length}),i=t+1}this._currentIndex=this._matches.length>0?Math.min(Math.max(this._currentIndex,0),this._matches.length-1):-1,this._selectCurrent(),this._updateCount()}_next(){this._matches.length!==0&&(this._currentIndex=(this._currentIndex+1)%this._matches.length,this._selectCurrent(),this._updateCount())}_prev(){this._matches.length!==0&&(this._currentIndex=(this._currentIndex-1+this._matches.length)%this._matches.length,this._selectCurrent(),this._updateCount())}_selectCurrent(){if(this._currentIndex===-1||this._matches.length===0){this._clearMatchHighlight();return}let{start:e}=this._matches[this._currentIndex];this._scrollToMatch(this.editor.usertextarea,e),this._showMatchHighlight()}_scrollToMatch(e,t){let n=parseInt(window.getComputedStyle(e).lineHeight)||20,r=e.value.substring(0,t).split(`
176
+ `).length-1,i=Math.floor(e.clientHeight/n);e.scrollTop=Math.max(0,(r-Math.floor(i/2))*n)}_showMatchHighlight(){if(this._clearMatchHighlight(),this._currentIndex===-1||!this._matches.length)return;let{start:e,end:t}=this._matches[this._currentIndex],n=this.editor.usertextarea,r=window.getComputedStyle(n),i=n.parentElement,a=document.createElement(`div`);Object.assign(a.style,{position:`absolute`,visibility:`hidden`,pointerEvents:`none`,top:`0`,left:`0`,right:`0`,whiteSpace:`pre-wrap`,wordBreak:`break-word`,overflowWrap:`break-word`,font:r.font,lineHeight:r.lineHeight,paddingTop:r.paddingTop,paddingRight:r.paddingRight,paddingBottom:r.paddingBottom,paddingLeft:r.paddingLeft,boxSizing:`border-box`});let o=document.createElement(`span`);o.textContent=n.value.substring(e,t)||`​`,a.appendChild(document.createTextNode(n.value.substring(0,e))),a.appendChild(o),a.appendChild(document.createTextNode(n.value.substring(t))),i.appendChild(a);try{let e=i.getBoundingClientRect(),t=o.getBoundingClientRect(),r=document.createElement(`div`);Object.assign(r.style,{position:`absolute`,top:t.top-e.top-n.scrollTop+`px`,left:t.left-e.left+`px`,width:Math.max(t.width,2)+`px`,height:t.height+`px`,background:`color-mix(in oklch, var(--color-primary, oklch(0.6 0.2 250)), transparent 55%)`,borderRadius:`2px`,pointerEvents:`none`,zIndex:`2`}),i.appendChild(r),this._highlightEl=r}finally{i.removeChild(a)}}_clearMatchHighlight(){this._highlightEl?.remove(),this._highlightEl=null}_updateCount(){this._countEl&&(this._matches.length===0?this._countEl.textContent=this._findInput?.value?`No results`:``:this._countEl.textContent=`${this._currentIndex+1} of ${this._matches.length}`)}_replace(){if(this._currentIndex===-1)return;let{start:e,end:t}=this._matches[this._currentIndex],n=this.editor.usertextarea,r=this._replaceInput.value;n.value=n.value.substring(0,e)+r+n.value.substring(t),this.editor.render(),this.editor.notifyChange(),this._search()}_replaceAll(){let e=this._findInput?.value;if(!e)return;let t=this._replaceInput.value,n=this.editor.usertextarea,r=e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`),i=this._caseSensitive?`g`:`gi`;n.value=n.value.replace(new RegExp(r,i),t),this.editor.render(),this.editor.notifyChange(),this._currentIndex=0,this._search()}destroy(){this.editor.usertextarea.removeEventListener(`keydown`,this._taHandler),this._scrollHandler&&this.editor.usertextarea.removeEventListener(`scroll`,this._scrollHandler),this._clearMatchHighlight(),this._panel?.remove()}},kr=/^https?:\/\/\S+$/i,Ar=class{constructor(e){this.editor=e,this.textarea=e.usertextarea,this._pasteHandler=e=>this._onPaste(e),this._dropHandler=e=>this._onDrop(e),this._dragOverHandler=e=>{this._carriesFiles(e.dataTransfer)&&e.preventDefault()},this.textarea.addEventListener(`paste`,this._pasteHandler),this.textarea.addEventListener(`drop`,this._dropHandler),this.textarea.addEventListener(`dragover`,this._dragOverHandler)}destroy(){this.textarea.removeEventListener(`paste`,this._pasteHandler),this.textarea.removeEventListener(`drop`,this._dropHandler),this.textarea.removeEventListener(`dragover`,this._dragOverHandler)}_carriesFiles(e){return Array.from(e?.types??[]).includes(`Files`)}_imageFiles(e){return Array.from(e?.files??[]).filter(e=>e.type?.startsWith(`image/`))}_onPaste(e){let t=this._imageFiles(e.clipboardData);if(t.length){if(!this.editor.imageUpload){console.warn(`[MarkdownEditor] An image was pasted but no upload endpoint is configured. Add { image: { fileInput: { uploadUrl: "..." } } } to the toolbar to enable it.`);return}e.preventDefault(),this._uploadAll(t);return}let n=e.clipboardData?.getData(`text/plain`)?.trim(),{selectionStart:r,selectionEnd:i}=this.textarea;if(n&&i>r&&kr.test(n)){e.preventDefault();let t=`[${this.textarea.value.slice(r,i)}](${n})`;this.editor.insertText(t,t.length,0)}}_onDrop(e){if(!this._carriesFiles(e.dataTransfer))return;e.preventDefault();let t=this._imageFiles(e.dataTransfer);t.length&&(this.editor.imageUpload?this._uploadAll(t):console.warn(`[MarkdownEditor] An image was dropped but no upload endpoint is configured. Add { image: { fileInput: { uploadUrl: "..." } } } to the toolbar to enable it.`))}async _uploadAll(e){for(let t of e){let e=`![${this.editor.label(`Uploading...`)}]()`;this.editor.insertText(e,e.length,0);try{let{path:n,alt:r}=await Ln(t,this.editor.imageUpload);this._replace(e,`![${r}](${n})`)}catch(t){this._replace(e,`![${this.editor.label(`Upload failed`)}]()`),console.error(`[MarkdownEditor] Image upload failed.`,t)}}}_replace(e,t){let n=this.textarea,r=n.value.indexOf(e);if(r===-1)return;n.value=n.value.slice(0,r)+t+n.value.slice(r+e.length);let i=r+t.length;n.setSelectionRange(i,i),this.editor.render(),this.editor.notifyChange()}},jr=new rt({breaks:!0}),Mr=class e{constructor(e,t={}){this.usertextarea=typeof e==`string`?document.querySelector(e):e,this.options=t,this.mode=t.mode||`plain`,this.preview=!this.options.toolbar||this.options.toolbar.includes(`preview`),this.footerOptions=this._parseFooterOptions(t.footer),this.variables=this._parseVariables(t.toolbar),this.imageUpload=this._parseImageUpload(t.toolbar),this.previewTimer=null,this.init(),this.undoRedoManager=new Sr(this),this.listManager=new wr(this),this.indentManager=new Cr(this),this.shortcutManager=new Dr(this),this.findReplace=new Or(this),this.pasteManager=new Ar(this),this._warnIfStylesheetMissing(),this._warnIfLocaleIsACode()}_warnIfLocaleIsACode(){let e=this.options.locale;typeof e==`string`&&console.error(`[MarkdownEditor] locale: '${e}' has no effect. It takes the strings, not a code:\n import ${/^[a-z]{2}$/i.test(e)?e:`strings`} from 'markdown-text-editor/locale/${e}.js'\n new MarkdownEditor(el, { locale: ${/^[a-z]{2}$/i.test(e)?e:`strings`} })`)}_warnIfStylesheetMissing(){e._cssWarned||this.editorContainer?.isConnected&&(getComputedStyle(this.editorContainer).getPropertyValue(`--mte-css`).trim()||(e._cssWarned=!0,console.error(`[MarkdownEditor] Stylesheet not loaded, so the editor will look unstyled.
177
177
  Bundlers: import 'markdown-text-editor/style.css'
178
- Browsers: <link rel="stylesheet" href=".../dist/markdown-text-editor.css">`)))}label(e){return this.options.labels?.[e]??e}_parseImageUpload(e){let t=(Array.isArray(e)?e:[]).find(e=>e&&typeof e==`object`&&e.image)?.image?.fileInput;return t?.uploadUrl?t:null}_parseVariables(e){let t=(Array.isArray(e)?e:[]).find(e=>e&&typeof e==`object`&&Array.isArray(e.variables));return t?t.variables:[]}_parseFooterOptions(e){if(e===!1)return null;let t=e??{};return{line:t.line!==!1,col:t.col!==!1,chars:t.chars!==!1,words:t.words===!0}}init(){this.createEditor(),this.addToolbar(),this.addFooter(),this._toolbarH=this.editorContainer.querySelector(`.toolbar`)?.offsetHeight??0,this._footerH=this.editorContainer.querySelector(`.editor-footer`)?.offsetHeight??0,this._autoGrow()}createEditor(){this.isTextareaValid()&&(this.applyDefaultAttributes(),this.buildEditorLayout(),this.addInputListener(),this.render())}isTextareaValid(){return this.usertextarea.tagName===`TEXTAREA`}applyDefaultAttributes(){this.usertextarea.id&&document.querySelector(`label[for="${this.usertextarea.id}"]`)||this.usertextarea.getAttribute(`aria-label`)||this.usertextarea.getAttribute(`aria-labelledby`)||(this.usertextarea.setAttribute(`aria-label`,this.options.label||`Markdown editor`),this._addedAriaLabel=!0),this.usertextarea.classList.add(`editor-textarea`,`fj:focus:ring-0`,`fj:focus:outline-0`,`fj:border-0`,`fj:border-base-soft`,`fj:px-4`,`fj:py-2`,`fj:max-w-full`,`fj:w-full`,`fj:h-full`,`fj:bg-transparent`,`fj:outline-0`,`fj:appearance-none`,`fj:overflow-y-auto`),this.usertextarea.hasAttribute(`placeholder`)||(this.usertextarea.placeholder=this.options.placeholder||`Write your markdown...`)}buildEditorLayout(){this.editorContainer=document.createElement(`div`),this.editorContainer.className=`
178
+ Browsers: <link rel="stylesheet" href=".../dist/markdown-text-editor.css">`)))}label(e){return(this.options.locale??this.options.labels)?.[e]??e}_parseImageUpload(e){let t=(Array.isArray(e)?e:[]).find(e=>e&&typeof e==`object`&&e.image)?.image?.fileInput;return t?.uploadUrl?t:null}_parseVariables(e){let t=(Array.isArray(e)?e:[]).find(e=>e&&typeof e==`object`&&Array.isArray(e.variables));return t?t.variables:[]}_parseFooterOptions(e){if(e===!1)return null;let t=e??{};return{line:t.line!==!1,col:t.col!==!1,chars:t.chars!==!1,words:t.words===!0}}init(){this.createEditor(),this.addToolbar(),this.addFooter(),this._toolbarH=this.editorContainer.querySelector(`.toolbar`)?.offsetHeight??0,this._footerH=this.editorContainer.querySelector(`.editor-footer`)?.offsetHeight??0,this._autoGrow()}createEditor(){this.isTextareaValid()&&(this.applyDefaultAttributes(),this.buildEditorLayout(),this.addInputListener(),this.render())}isTextareaValid(){return this.usertextarea.tagName===`TEXTAREA`}applyDefaultAttributes(){this.usertextarea.id&&document.querySelector(`label[for="${this.usertextarea.id}"]`)||this.usertextarea.getAttribute(`aria-label`)||this.usertextarea.getAttribute(`aria-labelledby`)||(this.usertextarea.setAttribute(`aria-label`,this.options.label||`Markdown editor`),this._addedAriaLabel=!0),this.usertextarea.classList.add(`editor-textarea`,`fj:focus:ring-0`,`fj:focus:outline-0`,`fj:border-0`,`fj:border-base-soft`,`fj:px-4`,`fj:py-2`,`fj:max-w-full`,`fj:w-full`,`fj:h-full`,`fj:bg-transparent`,`fj:outline-0`,`fj:appearance-none`,`fj:overflow-y-auto`),this.usertextarea.hasAttribute(`placeholder`)||(this.usertextarea.placeholder=this.options.placeholder||`Write your markdown...`)}buildEditorLayout(){this.editorContainer=document.createElement(`div`),this.editorContainer.className=`
179
179
  markdown-editor-wrapper
180
180
  fj:me-surface
181
181
  fj:me-surface-outline
@@ -221,7 +221,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
221
221
  fj:z-10
222
222
  `,e.appendChild(this.displayLayer)),e.appendChild(this.usertextarea),this.markdownEditorDiv.appendChild(e)}addPreviewWrapper(){let e=new $n(this.markdownEditorDiv);this.previewContent=e.getPreviewContent()}addInputListener(){this._inputHandler=()=>{this._autoGrow(),this.renderHybrid(),this.debouncedPreview(),this.notifyChange()},this._scrollHandler=()=>{this._scrollRaf||=requestAnimationFrame(()=>{if(this._scrollRaf=null,this.mode===`hybrid`&&(this.displayLayer.scrollTop=this.usertextarea.scrollTop,this.displayLayer.scrollLeft=this.usertextarea.scrollLeft),this.preview&&this.previewContent){let e=this.usertextarea,t=e.scrollTop/(e.scrollHeight-e.clientHeight);this.previewContent.scrollTop=t*(this.previewContent.scrollHeight-this.previewContent.clientHeight)}})},this.usertextarea.addEventListener(`input`,this._inputHandler),this.usertextarea.addEventListener(`scroll`,this._scrollHandler)}debouncedPreview(){this.preview&&(clearTimeout(this.previewTimer),this.previewTimer=setTimeout(()=>{this.previewContent.innerHTML=this._renderMarkdown(this.usertextarea.value),this.wirePreviewCheckboxes();let e=this.usertextarea,t=e.scrollTop/(e.scrollHeight-e.clientHeight);this.previewContent.scrollTop=t*(this.previewContent.scrollHeight-this.previewContent.clientHeight)},150))}renderMarkdown(e){return this._renderMarkdown(e)}createToolbar(e,t=[`bold`,`italic`,`strikethrough`]){let n=Object.create(this);return n.usertextarea=e,n.scrollToView=()=>{},n.render=()=>{},n.notifyChange=()=>{},n.insertText=(t,n=0,r=0)=>{let{selectionStart:i,selectionEnd:a,value:o}=e;e.value=o.slice(0,i)+t+o.slice(a),e.focus(),e.setSelectionRange(i+n,i+t.length-r)},new Qn(n,t,{standalone:!0}).toolbar}_renderMarkdown(e){let t=this.options.renderer??(e=>jr.parse(e)),n=this.options.sanitizer??(e=>Cn.sanitize(e)),r=Jn(e,this.variables),i=t(r);return this.options.renderer&&!this._taskListWarned&&/^\s*[-*] \[[ xX]\] /m.test(r)&&!/type=["']?checkbox/.test(i)&&(this._taskListWarned=!0,console.warn(`[MarkdownEditor] Task list syntax found, but the custom renderer emitted no checkboxes. Clickable checkboxes in the preview need a task-list plugin, e.g. markdown-it-task-lists.`)),n(i)}wirePreviewCheckboxes(){this.previewContent.querySelectorAll(`input[type="checkbox"]`).forEach((e,t)=>{e.removeAttribute(`disabled`),e.addEventListener(`click`,n=>{n.preventDefault();let r=this.usertextarea.value.split(`
223
223
  `),i=0;for(let n=0;n<r.length;n++)if(/^(\s*)([-*] \[[ xX]\] )/.test(r[n])){if(i===t){e.checked?r[n]=r[n].replace(/\[ \]/,`[x]`):r[n]=r[n].replace(/\[[xX]\]/,`[ ]`);break}i++}this.usertextarea.value=r.join(`
224
- `),this.render(),this.notifyChange()})})}addFooter(){if(!this.footerOptions)return;let{line:e,col:t,chars:n,words:r}=this.footerOptions;(e||t||n||r)&&(this.footer=new er(this.editorContainer,this.footerOptions),this.footer.update(this.usertextarea),this._footerUpdate=()=>this.footer.update(this.usertextarea),this.usertextarea.addEventListener(`input`,this._footerUpdate),this.usertextarea.addEventListener(`click`,this._footerUpdate),this.usertextarea.addEventListener(`keyup`,this._footerUpdate),this.usertextarea.addEventListener(`focus`,this._footerUpdate))}addToolbar(){this.toolbarInstance=new Qn(this,this.options.toolbar||[`undo`,`redo`,`heading`,`blockquote`,`ul`,`ol`,`checklist`,`outdent`,`indent`,`bold`,`italic`,`strikethrough`,`code`,`codeblock`,`hr`,`table`,`link`,`image`,`preview`])}insertText(e,t=0,n=0){let{selectionStart:r,selectionEnd:i}=this.usertextarea,a=this.usertextarea.value;this.usertextarea.value=`${a.substring(0,r)}${e}${a.substring(i)}`,this.usertextarea.focus(),this.usertextarea.setSelectionRange(r+t,r+e.length-n),this.scrollToView(),this.render(),this.notifyChange()}scrollToView(){let e=this.usertextarea,t=e.selectionStart,n=parseInt(window.getComputedStyle(e).lineHeight),r=e.value.substring(0,t).split(`
224
+ `),this.render(),this.notifyChange()})})}addFooter(){if(!this.footerOptions)return;let{line:e,col:t,chars:n,words:r}=this.footerOptions;(e||t||n||r)&&(this.footer=new er(this.editorContainer,this.footerOptions,e=>this.label(e)),this.footer.update(this.usertextarea),this._footerUpdate=()=>this.footer.update(this.usertextarea),this.usertextarea.addEventListener(`input`,this._footerUpdate),this.usertextarea.addEventListener(`click`,this._footerUpdate),this.usertextarea.addEventListener(`keyup`,this._footerUpdate),this.usertextarea.addEventListener(`focus`,this._footerUpdate))}addToolbar(){this.toolbarInstance=new Qn(this,this.options.toolbar||[`undo`,`redo`,`heading`,`blockquote`,`ul`,`ol`,`checklist`,`outdent`,`indent`,`bold`,`italic`,`strikethrough`,`code`,`codeblock`,`hr`,`table`,`link`,`image`,`preview`])}insertText(e,t=0,n=0){let{selectionStart:r,selectionEnd:i}=this.usertextarea,a=this.usertextarea.value;this.usertextarea.value=`${a.substring(0,r)}${e}${a.substring(i)}`,this.usertextarea.focus(),this.usertextarea.setSelectionRange(r+t,r+e.length-n),this.scrollToView(),this.render(),this.notifyChange()}scrollToView(){let e=this.usertextarea,t=e.selectionStart,n=parseInt(window.getComputedStyle(e).lineHeight),r=e.value.substring(0,t).split(`
225
225
  `).length-1,i=Math.floor(e.clientHeight/n);e.scrollTop=(r-Math.floor(i/2))*n}_highlight(e){let t=e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`);return t=t.replace(/```(\w+)?\n([\s\S]*?)```/g,'<span class="fj:opacity-30">```$1</span>\n$2<span class="fj:opacity-30">```</span>').replace(/`([^`\n]+)`/g,'<span class="fj:opacity-40">`</span><span class="fj:text-accent">$1</span><span class="fj:opacity-40">`</span>').replace(/^(#+ )(.*)$/gm,`<span class="fj:text-primary"><span class="fj:opacity-40">$1</span><span class="faux-bold">$2</span></span>`).replace(/\*\*(.*?)\*\*/g,`<span class="fj:text-secondary"><span class="fj:opacity-40">**</span><span class="faux-bold">$1</span><span class="fj:opacity-40">**</span></span>`).replace(/^([\s]*)([\-\*] |[\d]+\. |\[[\s xX]\] )(.*)$/gm,`$1<span class="fj:text-primary">$2</span>$3`).replace(/(\*|_)(.*?)\1/g,`<span class="fj:text-accent"><span class="fj:opacity-40">$1</span>$2<span class="fj:opacity-40">$1</span></span>`).replace(/~~(.*?)~~/g,`<span class="fj:line-through fj:opacity-70"><span class="fj:opacity-40">~~</span>$1<span class="fj:opacity-40">~~</span></span>`).replace(/(?<!~)(~)([^~]+)\1(?!~)/g,`<span class="fj:line-through fj:opacity-70"><span class="fj:opacity-40">$1</span>$2<span class="fj:opacity-40">$1</span></span>`).replace(/(!?\[)(.*?)(\]\()(.*?)(\))/g,`<span class="fj:opacity-40">$1</span><span class="fj:text-primary">$2</span><span class="fj:opacity-40">$3</span><span class="fj:underline fj:opacity-50">$4</span><span class="fj:opacity-50">$5</span>`),e.endsWith(`
226
226
  `)&&(t+=` `),t}renderHybrid(){if(this.mode!==`hybrid`)return;let e=this.usertextarea.value;if(e===this._lastRaw)return;this._lastRaw=e;let t=this._highlight(e).split(`
227
227
  `),n=this._lastLines;if(!n||n.length!==t.length)this.displayLayer.innerHTML=``,this._lineNodes=t.map((e,n)=>{let r=document.createElement(`span`);return r.innerHTML=e+(n<t.length-1?`