dopecanvas 0.1.2 → 0.1.3
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/dopecanvas.cjs +8 -3
- package/dist/dopecanvas.cjs.map +1 -1
- package/dist/dopecanvas.js +777 -458
- package/dist/dopecanvas.js.map +1 -1
- package/package.json +1 -1
package/dist/dopecanvas.cjs
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
`);
|
|
3
|
-
`),f.appendChild(T);const j=s.measureBlocks(T),w=j.map(y=>y.element.cloneNode(!0).outerHTML),L=s.paginate(j);f.innerHTML="";const A=L.pages.map(y=>({blocks:y.blockIndices.map(R=>w[R])})),W=b.current.map(y=>y.blocks.length),O=A.map(y=>y.blocks.length);(W.length!==O.length||W.some((y,R)=>y!==O[R]))&&(C.current=!0,m.current=M,b.current=A,v(A),a?.(L))},[e,s,a]),h=o.useRef(F);h.current=F;const H=o.useCallback(()=>{if(!c.current)return;const p=c.current,M=s.getContentAreaWidth();if(p.style.width=`${M}px`,p.style.position="absolute",p.style.left="-9999px",p.style.top="0",p.style.visibility="hidden",p.innerHTML="",e){const L=document.createElement("style");L.textContent=e,p.appendChild(L)}const k=new DOMParser().parseFromString(i,"text/html");k.head.querySelectorAll('style, link[rel="stylesheet"]').forEach(L=>{k.body.insertBefore(L,k.body.firstChild)});const x=k.body.innerHTML,f=document.createElement("div");f.innerHTML=x,p.appendChild(f);const E=s.measureBlocks(f),T=E.map(L=>L.element.cloneNode(!0).outerHTML),j=s.paginate(E),w=j.pages.map(L=>({blocks:L.blockIndices.map(A=>T[A])}));p.innerHTML="",b.current=w,v(w),a?.(j)},[i,e,s,a]);return o.useEffect(()=>{H()},[H]),o.useEffect(()=>{const p=d.current;if(!p)return;S.current&&S.current.disconnect(),p.querySelectorAll(".dopecanvas-block-wrapper").forEach(E=>{const T=E.firstElementChild;T&&(T.tagName==="TABLE"?T.querySelectorAll("td, th").forEach(w=>{w.contentEditable="true"}):T.tagName==="SCRIPT"||T.tagName==="STYLE"||(T.contentEditable="true"))});const k=ne(p);let x=null;const f=new MutationObserver(()=>{C.current||(x&&clearTimeout(x),x=setTimeout(()=>{_(),h.current()},300))});return f.observe(p,{childList:!0,subtree:!0,characterData:!0,attributes:!1}),S.current=f,m.current?requestAnimationFrame(()=>{m.current&&d.current&&(re(d.current,m.current),m.current=null),C.current=!1}):C.current=!1,()=>{f.disconnect(),k.forEach(E=>E.remove()),x&&clearTimeout(x)}},[g,_]),r.jsxs("div",{className:"dopecanvas-paged-view",style:oe,children:[r.jsx("div",{ref:c,"aria-hidden":"true"}),r.jsxs("div",{ref:d,style:ae,children:[e&&r.jsx("style",{dangerouslySetInnerHTML:{__html:e}}),g.map((p,M)=>r.jsx($,{dimensions:D,margins:t.margins,pageNumber:M+1,totalPages:g.length,children:p.blocks.map((k,x)=>r.jsx("div",{className:"dopecanvas-block-wrapper",dangerouslySetInnerHTML:{__html:k}},`${M}-${x}`))},M)),g.length===0&&r.jsx($,{dimensions:D,margins:t.margins,pageNumber:1,totalPages:1,children:r.jsx("div",{contentEditable:"true",style:{minHeight:"1em",outline:"none"},"data-placeholder":"Start typing..."})})]})]})},oe={flex:1,overflow:"auto",backgroundColor:"#e8e8e8",display:"flex",flexDirection:"column",alignItems:"center"},ae={display:"flex",flexDirection:"column",alignItems:"center",gap:"24px",padding:"24px 0"};class B{config;constructor(e=I){this.config={...e}}getConfig(){return{...this.config}}setConfig(e){e.size!==void 0&&(this.config.size=e.size),e.margins!==void 0&&(this.config.margins={...e.margins})}getPageDimensions(){return typeof this.config.size=="string"?z[this.config.size]:this.config.size}getContentAreaHeight(){return this.getPageDimensions().height-this.config.margins.top-this.config.margins.bottom}getContentAreaWidth(){return this.getPageDimensions().width-this.config.margins.left-this.config.margins.right}measureBlocks(e){const t=Array.from(e.children),s=[];for(let n=0;n<t.length;n++){const l=t[n],a=window.getComputedStyle(l),c=a.getPropertyValue("break-before")==="page"||a.getPropertyValue("page-break-before")==="always",d=a.getPropertyValue("break-after")==="page"||a.getPropertyValue("page-break-after")==="always",S=l.getBoundingClientRect(),u=parseFloat(a.marginTop)||0,g=parseFloat(a.marginBottom)||0,v=S.height+u+g;s.push({index:n,height:v,element:l,breakBefore:c,breakAfter:d})}return s}paginate(e){if(e.length===0)return{pages:[{blockIndices:[]}],pageCount:1};const t=this.getContentAreaHeight(),s=[];let n=[],l=0;for(let a=0;a<e.length;a++){const c=e[a];c.breakBefore&&n.length>0&&(s.push({blockIndices:n}),n=[],l=0),l+c.height>t&&n.length>0&&(s.push({blockIndices:n}),n=[],l=0),n.push(c.index),l+=c.height,c.breakAfter&&(s.push({blockIndices:n}),n=[],l=0)}return n.length>0&&s.push({blockIndices:n}),s.length===0&&s.push({blockIndices:[]}),{pages:s,pageCount:s.length}}}class P{observer=null;changeCallbacks=new Set;contextCallbacks=new Set;undoStack=[];redoStack=[];container=null;debounceTimer=null;selectionHandler=null;currentContext="none";static MAX_UNDO_STACK=100;static DEBOUNCE_MS=150;attach(e){this.detach(),this.container=e,this.makeChildrenEditable(e),this.pushUndoSnapshot(),this.observer=new MutationObserver(this.handleMutations),this.observer.observe(e,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["style","class"]}),this.selectionHandler=this.handleSelectionChange.bind(this),document.addEventListener("selectionchange",this.selectionHandler)}detach(){this.observer&&(this.observer.disconnect(),this.observer=null),this.selectionHandler&&(document.removeEventListener("selectionchange",this.selectionHandler),this.selectionHandler=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.container=null}makeChildrenEditable(e){const t=Array.from(e.children);for(const s of t)s.tagName==="TABLE"?this.makeTableCellsEditable(s):s.contentEditable="true"}makeTableCellsEditable(e){e.querySelectorAll("td, th").forEach(s=>{s.contentEditable="true"})}handleMutations=e=>{this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.pushUndoSnapshot(),this.notifyChange()},P.DEBOUNCE_MS)};handleSelectionChange(){const e=window.getSelection();if(!e||e.rangeCount===0||!this.container){this.setContext("none");return}const s=e.getRangeAt(0).startContainer;let n=s;for(;n&&n!==this.container;){if(n instanceof HTMLElement){const l=n.tagName;if(l==="TD"||l==="TH"||l==="TABLE"){this.setContext("table");return}if(l==="IMG"){this.setContext("image");return}if(n.dataset?.dopecanvasChart){this.setContext("chart");return}}n=n.parentNode}this.container.contains(s)?this.setContext("text"):this.setContext("none")}setContext(e){e!==this.currentContext&&(this.currentContext=e,this.contextCallbacks.forEach(t=>t(e)))}getContext(){return this.currentContext}pushUndoSnapshot(){if(!this.container)return;const e=this.container.innerHTML,t=this.undoStack[this.undoStack.length-1];t&&t.html===e||(this.undoStack.push({html:e,timestamp:Date.now()}),this.redoStack=[],this.undoStack.length>P.MAX_UNDO_STACK&&this.undoStack.shift())}undo(){if(!this.container||this.undoStack.length<=1)return!1;const e=this.undoStack.pop();this.redoStack.push(e);const t=this.undoStack[this.undoStack.length-1];return this.pauseObserver(()=>{this.container.innerHTML=t.html,this.makeChildrenEditable(this.container)}),this.notifyChange(),!0}redo(){if(!this.container||this.redoStack.length===0)return!1;const e=this.redoStack.pop();return this.undoStack.push(e),this.pauseObserver(()=>{this.container.innerHTML=e.html,this.makeChildrenEditable(this.container)}),this.notifyChange(),!0}pauseObserver(e){this.observer&&this.observer.disconnect(),e(),this.observer&&this.container&&this.observer.observe(this.container,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["style","class"]})}onChange(e){return this.changeCallbacks.add(e),()=>{this.changeCallbacks.delete(e)}}onContextChange(e){return this.contextCallbacks.add(e),()=>{this.contextCallbacks.delete(e)}}notifyChange(){this.changeCallbacks.forEach(e=>e())}execCommand(e,t){return document.execCommand(e,!1,t)}queryCommandState(e){return document.queryCommandState(e)}queryCommandValue(e){return document.queryCommandValue(e)}getHTML(){return this.container?this.container.innerHTML:""}getPlainText(){return this.container&&(this.container.innerText||this.container.textContent)||""}}const le=o.forwardRef(({html:i="",css:e,pageConfig:t,onContentChange:s,onPageConfigChange:n,style:l},a)=>{const[c,d]=o.useState(t||I),[S,u]=o.useState({pages:[],pageCount:0}),g=o.useRef(i),v=o.useRef(s);v.current=s;const m=t||c,C=o.useMemo(()=>new B(m),[]),b=o.useMemo(()=>new P,[]);o.useEffect(()=>{C.setConfig(m)},[m,C]);const D=o.useCallback(h=>{g.current=h,v.current?.(h)},[]),_=o.useCallback(h=>{const H={...m,...h,margins:{...m.margins,...h.margins||{}}};d(H),C.setConfig(H),n?.(H)},[m,C,n]),F=o.useCallback(h=>{u(h)},[]);return o.useImperativeHandle(a,()=>({execCommand:(h,H)=>b.execCommand(h,H),queryCommandState:h=>b.queryCommandState(h),queryCommandValue:h=>b.queryCommandValue(h),getPageConfig:()=>({...m}),setPageConfig:h=>{_(h)},getPageCount:()=>S.pageCount,getHTML:()=>g.current,getPlainText:()=>{const h=document.createElement("div");return h.innerHTML=g.current,h.innerText||h.textContent||""},undo:()=>b.undo(),redo:()=>b.redo()}),[b,m,S.pageCount,_]),r.jsx("div",{className:"dopecanvas-root",style:{display:"flex",flexDirection:"column",height:"100%",width:"100%",fontFamily:"system-ui, -apple-system, BlinkMacSystemFont, sans-serif",...l},children:r.jsx(ie,{html:i,css:e,pageConfig:m,layoutEngine:C,editableManager:b,onContentChange:D,onPaginationChange:F})})});class J{layoutEngine;editableManager;sourceHTML="";sourceCSS="";measureContainer=null;contentContainer=null;paginationResult={pages:[],pageCount:0};paginationCallbacks=new Set;changeCallbacks=new Set;constructor(e=I){this.layoutEngine=new B(e),this.editableManager=new P}getLayoutEngine(){return this.layoutEngine}getEditableManager(){return this.editableManager}getPaginationResult(){return this.paginationResult}getSourceHTML(){return this.sourceHTML}getPageConfig(){return this.layoutEngine.getConfig()}loadHTML(e,t){this.sourceHTML=e,this.sourceCSS=t||""}setMeasureContainer(e){this.measureContainer=e}setContentContainer(e){this.contentContainer&&this.editableManager.detach(),this.contentContainer=e}runPagination(){if(!this.measureContainer)return{result:{pages:[{blockIndices:[]}],pageCount:1},measurements:[]};const e=this.layoutEngine.getContentAreaWidth();this.measureContainer.style.width=`${e}px`,this.measureContainer.style.position="absolute",this.measureContainer.style.left="-9999px",this.measureContainer.style.top="0",this.measureContainer.style.visibility="hidden";let t=null;this.sourceCSS&&(t=document.createElement("style"),t.textContent=this.sourceCSS,this.measureContainer.appendChild(t));const s=document.createElement("div");s.innerHTML=this.sourceHTML,this.measureContainer.appendChild(s);const n=this.layoutEngine.measureBlocks(s);return this.paginationResult=this.layoutEngine.paginate(n),this.measureContainer.innerHTML="",this.paginationCallbacks.forEach(l=>l(this.paginationResult)),{result:this.paginationResult,measurements:n}}rePaginate(){if(!this.contentContainer)return this.paginationResult;const e=this.layoutEngine.measureBlocks(this.contentContainer);return this.paginationResult=this.layoutEngine.paginate(e),this.paginationCallbacks.forEach(t=>t(this.paginationResult)),this.paginationResult}attachEditing(e){this.contentContainer=e,this.editableManager.attach(e),this.editableManager.onChange(()=>{this.sourceHTML=e.innerHTML,this.changeCallbacks.forEach(t=>t(this.sourceHTML))})}setPageConfig(e){this.layoutEngine.setConfig(e)}onPagination(e){return this.paginationCallbacks.add(e),()=>{this.paginationCallbacks.delete(e)}}onChange(e){return this.changeCallbacks.add(e),()=>{this.changeCallbacks.delete(e)}}getHTML(){return this.contentContainer?this.contentContainer.innerHTML:this.sourceHTML}getPlainText(){return this.contentContainer&&(this.contentContainer.innerText||this.contentContainer.textContent)||""}destroy(){this.editableManager.detach(),this.paginationCallbacks.clear(),this.changeCallbacks.clear(),this.measureContainer=null,this.contentContainer=null}}class ce{_html="";_css="";_pageConfig=null;_paginationResult={pages:[],pageCount:0};_changeCallbacks=new Set;_loadCallbacks=new Set;_pageConfigCallbacks=new Set;_getHTMLFn=null;_getPlainTextFn=null;loadHTML(e,t){this._html=e,this._css=t||"",this._loadCallbacks.forEach(s=>s(e,t))}getHTML(){return this._getHTMLFn?this._getHTMLFn():this._html}getPlainText(){if(this._getPlainTextFn)return this._getPlainTextFn();const e=document.createElement("div");return e.innerHTML=this._html,e.innerText||e.textContent||""}onChange(e){return this._changeCallbacks.add(e),()=>{this._changeCallbacks.delete(e)}}onLoad(e){return this._loadCallbacks.add(e),()=>{this._loadCallbacks.delete(e)}}onPageConfigChange(e){return this._pageConfigCallbacks.add(e),()=>{this._pageConfigCallbacks.delete(e)}}getPageCount(){return this._paginationResult.pageCount}getPageConfig(){return this._pageConfig}setPageConfig(e){this._pageConfig&&(this._pageConfig={...this._pageConfig,...e,margins:{...this._pageConfig.margins,...e.margins||{}}},this._pageConfigCallbacks.forEach(t=>t(this._pageConfig)))}querySelectorAll(e){const t=document.createElement("div");return t.innerHTML=this.getHTML(),Array.from(t.querySelectorAll(e))}getElementContent(e){const t=document.createElement("div");t.innerHTML=this.getHTML();const s=t.querySelector(`#${e}`);return s?s.innerHTML:null}setElementContent(e,t){const s=document.createElement("div");s.innerHTML=this.getHTML();const n=s.querySelector(`#${e}`);n&&(n.innerHTML=t,this.loadHTML(s.innerHTML,this._css))}_connectGetHTML(e){this._getHTMLFn=e}_connectGetPlainText(e){this._getPlainTextFn=e}_notifyChange(e){this._html=e,this._changeCallbacks.forEach(t=>t(e))}_updatePagination(e){this._paginationResult=e}_updatePageConfig(e){this._pageConfig=e}}function ue(i){const[e,t]=o.useState("none");return o.useEffect(()=>i?i.onContextChange(n=>{t(n)}):void 0,[i]),e}function Q(){const[i,e]=o.useState({bold:!1,italic:!1,underline:!1,strikethrough:!1,justifyLeft:!1,justifyCenter:!1,justifyRight:!1,justifyFull:!1}),t=o.useCallback(()=>{e({bold:document.queryCommandState("bold"),italic:document.queryCommandState("italic"),underline:document.queryCommandState("underline"),strikethrough:document.queryCommandState("strikethrough"),justifyLeft:document.queryCommandState("justifyLeft"),justifyCenter:document.queryCommandState("justifyCenter"),justifyRight:document.queryCommandState("justifyRight"),justifyFull:document.queryCommandState("justifyFull")})},[]);return o.useEffect(()=>(document.addEventListener("selectionchange",t),()=>{document.removeEventListener("selectionchange",t)}),[t]),i}const ee=({onExecCommand:i})=>{const e=Q(),t=o.useRef(null),s=o.useCallback(()=>{const u=window.getSelection();u&&u.rangeCount>0&&(t.current=u.getRangeAt(0).cloneRange())},[]),n=o.useCallback(()=>{const u=t.current;if(!u)return;const g=window.getSelection();g&&(g.removeAllRanges(),g.addRange(u))},[]),l=o.useCallback((u,g)=>v=>{v.preventDefault(),i(u,g)},[i]),a=o.useCallback(u=>{n(),i("fontSize",u.target.value)},[i,n]),c=o.useCallback(u=>{n();const g=u.target.value;g==="p"?i("formatBlock","p"):i("formatBlock",g)},[i,n]),d=o.useCallback(u=>{n(),i("foreColor",u.target.value)},[i,n]),S=o.useCallback(u=>{n(),i("hiliteColor",u.target.value)},[i,n]);return r.jsxs("div",{style:he,children:[r.jsxs("select",{onChange:c,defaultValue:"p",style:G,title:"Block Format",onMouseDown:s,children:[r.jsx("option",{value:"p",children:"Paragraph"}),r.jsx("option",{value:"h1",children:"Heading 1"}),r.jsx("option",{value:"h2",children:"Heading 2"}),r.jsx("option",{value:"h3",children:"Heading 3"}),r.jsx("option",{value:"h4",children:"Heading 4"}),r.jsx("option",{value:"h5",children:"Heading 5"}),r.jsx("option",{value:"h6",children:"Heading 6"})]}),r.jsx("div",{style:N}),r.jsxs("select",{onChange:a,defaultValue:"3",style:G,title:"Font Size",onMouseDown:s,children:[r.jsx("option",{value:"1",children:"8pt"}),r.jsx("option",{value:"2",children:"10pt"}),r.jsx("option",{value:"3",children:"12pt"}),r.jsx("option",{value:"4",children:"14pt"}),r.jsx("option",{value:"5",children:"18pt"}),r.jsx("option",{value:"6",children:"24pt"}),r.jsx("option",{value:"7",children:"36pt"})]}),r.jsx("div",{style:N}),r.jsx(V,{icon:"B",title:"Bold (Ctrl+B)",active:e.bold,onMouseDown:l("bold"),extraStyle:{fontWeight:"bold"}}),r.jsx(V,{icon:"I",title:"Italic (Ctrl+I)",active:e.italic,onMouseDown:l("italic"),extraStyle:{fontStyle:"italic"}}),r.jsx("div",{style:N}),r.jsxs("label",{style:U,title:"Text Color",onMouseDown:s,children:["A",r.jsx("input",{type:"color",defaultValue:"#000000",onChange:d,style:X})]}),r.jsxs("label",{style:U,title:"Highlight Color",onMouseDown:s,children:[r.jsx("span",{style:{backgroundColor:"#ffff00",padding:"0 2px"},children:"A"}),r.jsx("input",{type:"color",defaultValue:"#ffff00",onChange:S,style:X})]})]})},V=({icon:i,title:e,active:t,onMouseDown:s,extraStyle:n})=>r.jsx("button",{type:"button",title:e,onMouseDown:s,style:{width:"28px",height:"28px",borderWidth:"1px",borderStyle:"solid",borderColor:t?"#b0b5bd":"transparent",borderRadius:"3px",backgroundColor:t?"#d0d5dd":"transparent",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"13px",color:"#333",padding:0,fontFamily:"inherit",...n},dangerouslySetInnerHTML:{__html:i}}),he={display:"flex",alignItems:"center",gap:"2px",flexWrap:"wrap"},G={height:"28px",borderWidth:"1px",borderStyle:"solid",borderColor:"#ccc",borderRadius:"3px",fontSize:"12px",padding:"0 4px",cursor:"pointer",backgroundColor:"#fff"},N={width:"1px",height:"20px",backgroundColor:"#ddd",margin:"0 4px"},U={position:"relative",width:"28px",height:"28px",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},X={position:"absolute",bottom:0,left:0,width:"100%",height:"4px",padding:0,borderWidth:0,borderStyle:"none",cursor:"pointer"},te=({pageConfig:i,pageCount:e,onPageConfigChange:t})=>{const s=o.useCallback(a=>{const c=a.target.value;t({size:c})},[t]),n=o.useCallback(a=>c=>{const d=Math.max(0,parseInt(c.target.value)||0);t({margins:{...i.margins,[a]:d}})},[i.margins,t]),l=typeof i.size=="string"?i.size:"custom";return r.jsxs("div",{style:de,children:[r.jsxs("label",{style:ge,children:["Page:",r.jsxs("select",{value:l,onChange:s,style:pe,children:[r.jsx("option",{value:"letter",children:"Letter (8.5 x 11)"}),r.jsx("option",{value:"a4",children:"A4 (210 x 297mm)"}),r.jsx("option",{value:"legal",children:"Legal (8.5 x 14)"})]})]}),r.jsx("div",{style:K}),r.jsx("span",{style:{fontSize:"12px",color:"#666"},children:"Margins (px):"}),r.jsx(q,{label:"T",value:i.margins.top,onChange:n("top")}),r.jsx(q,{label:"R",value:i.margins.right,onChange:n("right")}),r.jsx(q,{label:"B",value:i.margins.bottom,onChange:n("bottom")}),r.jsx(q,{label:"L",value:i.margins.left,onChange:n("left")}),r.jsx("div",{style:K}),r.jsxs("span",{style:{fontSize:"12px",color:"#666"},children:[e," ",e===1?"page":"pages"]})]})},q=({label:i,value:e,onChange:t})=>r.jsxs("label",{style:fe,title:`${i} margin`,children:[i,":",r.jsx("input",{type:"number",value:e,onChange:t,style:me,min:0,max:300,step:12})]}),de={display:"flex",alignItems:"center",gap:"6px",flexWrap:"wrap"},ge={display:"flex",alignItems:"center",gap:"4px",fontSize:"12px",color:"#666"},pe={height:"26px",borderWidth:"1px",borderStyle:"solid",borderColor:"#ccc",borderRadius:"3px",fontSize:"12px",padding:"0 4px",cursor:"pointer",backgroundColor:"#fff"},K={width:"1px",height:"20px",backgroundColor:"#ddd",margin:"0 4px"},fe={display:"flex",alignItems:"center",gap:"2px",fontSize:"11px",color:"#666"},me={width:"44px",height:"24px",borderWidth:"1px",borderStyle:"solid",borderColor:"#ccc",borderRadius:"3px",fontSize:"11px",textAlign:"center",padding:"0 2px"},Ce=({pageConfig:i,pageCount:e,onExecCommand:t,onPageConfigChange:s})=>r.jsxs("div",{style:be,children:[r.jsx("div",{style:Z,children:r.jsx(ee,{onExecCommand:t})}),r.jsx("div",{style:Z,children:r.jsx(te,{pageConfig:i,pageCount:e,onPageConfigChange:s})})]}),be={borderBottomWidth:"1px",borderBottomStyle:"solid",borderBottomColor:"#d0d0d0",backgroundColor:"#f8f8f8",padding:"4px 8px",display:"flex",flexDirection:"column",gap:"4px",flexShrink:0,zIndex:10},Z={display:"flex",alignItems:"center",gap:"4px",minHeight:"32px"};function xe(i={}){const{initialHTML:e="",initialCSS:t="",initialConfig:s=I}=i,n=o.useRef(new J(s)),[l,a]=o.useState({pages:[{blockIndices:[]}],pageCount:1}),[c,d]=o.useState(s),S=o.useCallback((C,b)=>{n.current.loadHTML(C,b)},[]),u=o.useCallback(C=>{n.current.setPageConfig(C),d(n.current.getPageConfig())},[]),g=o.useCallback(()=>{const{result:C}=n.current.runPagination();a(C)},[]),v=o.useCallback(()=>n.current.getHTML(),[]),m=o.useCallback(()=>n.current.getPlainText(),[]);return o.useEffect(()=>{e&&n.current.loadHTML(e,t)},[e,t]),o.useEffect(()=>n.current.onPagination(b=>{a(b)}),[]),o.useEffect(()=>()=>{n.current.destroy()},[]),{engine:n.current,paginationResult:l,pageConfig:c,loadHTML:S,setPageConfig:u,triggerPagination:g,getHTML:v,getPlainText:m}}exports.DEFAULT_MARGINS=Y;exports.DEFAULT_PAGE_CONFIG=I;exports.DocumentAPI=ce;exports.DocumentEngine=J;exports.DopeCanvas=le;exports.EditableManager=P;exports.PAGE_SIZE_PRESETS=z;exports.PageLayoutEngine=B;exports.PageSetupToolbar=te;exports.TextToolbar=ee;exports.Toolbar=Ce;exports.useDocumentEngine=xe;exports.useFormattingState=Q;exports.useSelectionContext=ue;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),r=require("react"),be=require("react-dom"),ee=({dimensions:a,margins:e,pageNumber:t,totalPages:o,children:s})=>n.jsxs("div",{className:"dopecanvas-page",style:{width:`${a.width}px`,height:`${a.height}px`,backgroundColor:"#ffffff",boxShadow:"0 2px 8px rgba(0, 0, 0, 0.15), 0 0 1px rgba(0, 0, 0, 0.1)",position:"relative",overflow:"hidden",flexShrink:0},children:[n.jsx("div",{className:"dopecanvas-page-content",style:{paddingTop:`${e.top}px`,paddingRight:`${e.right}px`,paddingBottom:`${e.bottom}px`,paddingLeft:`${e.left}px`,height:"100%",boxSizing:"border-box",overflow:"hidden"},children:s}),n.jsxs("div",{className:"dopecanvas-page-number",style:{position:"absolute",bottom:`${Math.max(e.bottom/3,16)}px`,left:0,right:0,textAlign:"center",fontSize:"11px",color:"#999",fontFamily:"system-ui, -apple-system, sans-serif",pointerEvents:"none",userSelect:"none"},children:[t," / ",o]})]}),xe=({visible:a,onAddBelow:e,onEditHTML:t,onDelete:o})=>n.jsxs("div",{className:"dopecanvas-block-toolbar",style:{...Se,display:a?"flex":"none"},onMouseDown:s=>s.preventDefault(),children:[n.jsx(V,{onClick:e,title:"Add block below",children:n.jsx(Ce,{})}),n.jsx(V,{onClick:t,title:"Edit HTML",children:n.jsx(ye,{})}),n.jsx(V,{onClick:o,title:"Delete block",danger:!0,children:n.jsx(ke,{})})]}),Ce=()=>n.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",children:[n.jsx("line",{x1:"7",y1:"3",x2:"7",y2:"11"}),n.jsx("line",{x1:"3",y1:"7",x2:"11",y2:"7"})]}),ye=()=>n.jsxs("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[n.jsx("polyline",{points:"4.5,3 1.5,7 4.5,11"}),n.jsx("polyline",{points:"9.5,3 12.5,7 9.5,11"})]}),ke=()=>n.jsx("svg",{width:"14",height:"14",viewBox:"0 0 14 14",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:n.jsx("path",{d:"M2.5 4h9M5 4V2.5h4V4M3.5 4l.5 8h6l.5-8"})}),V=({onClick:a,title:e,children:t,danger:o})=>{const[s,l]=r.useState(!1);return n.jsx("button",{onClick:a,title:e,onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),style:{...ve,background:s?o?"#fff0f0":"#f0f0f0":"transparent",color:s&&o?"#d32f2f":"#666"},children:t})},Se={position:"absolute",top:0,left:-40,flexDirection:"column",gap:"1px",zIndex:100,background:"#fff",borderRadius:"6px",boxShadow:"0 1px 5px rgba(0,0,0,0.12)",padding:"3px",paddingRight:"6px"},ve={width:"30px",height:"26px",border:"none",cursor:"pointer",borderRadius:"4px",fontSize:"13px",fontFamily:"system-ui, -apple-system, sans-serif",display:"flex",alignItems:"center",justifyContent:"center",padding:0,transition:"background 0.1s, color 0.1s"},Te=({html:a,onSave:e,onCancel:t})=>{const[o,s]=r.useState(a),l=i=>{if(i.key==="Enter"&&(i.metaKey||i.ctrlKey)&&(i.preventDefault(),e(o)),i.key==="Escape"&&(i.preventDefault(),t()),i.key==="Tab"){i.preventDefault();const u=i.target,g=u.selectionStart,k=u.selectionEnd,h=o.substring(0,g)+" "+o.substring(k);s(h),requestAnimationFrame(()=>{u.selectionStart=u.selectionEnd=g+2})}};return be.createPortal(n.jsx("div",{style:Me,onClick:t,children:n.jsxs("div",{style:je,onClick:i=>i.stopPropagation(),children:[n.jsxs("div",{style:Ee,children:[n.jsx("span",{style:{fontWeight:600,fontSize:"14px"},children:"Edit Block HTML"}),n.jsx("span",{style:{fontSize:"11px",color:"#888"},children:"⌘Enter to save · Escape to cancel"})]}),n.jsx("textarea",{style:Le,value:o,onChange:i=>s(i.target.value),onKeyDown:l,spellCheck:!1,autoFocus:!0}),n.jsxs("div",{style:He,children:[n.jsx("button",{style:we,onClick:t,onMouseEnter:i=>{i.target.style.borderColor="#888"},onMouseLeave:i=>{i.target.style.borderColor="#555"},children:"Cancel"}),n.jsx("button",{style:Re,onClick:()=>e(o),onMouseEnter:i=>{i.target.style.background="#0055dd"},onMouseLeave:i=>{i.target.style.background="#0066ff"},children:"Save"})]})]})}),document.body)},Me={position:"fixed",inset:0,background:"rgba(0, 0, 0, 0.5)",display:"flex",alignItems:"center",justifyContent:"center",zIndex:1e4},je={width:"min(800px, 90vw)",height:"min(600px, 80vh)",background:"#1e1e1e",borderRadius:"10px",display:"flex",flexDirection:"column",overflow:"hidden",boxShadow:"0 20px 60px rgba(0, 0, 0, 0.4)"},Ee={display:"flex",justifyContent:"space-between",alignItems:"center",padding:"12px 16px",background:"#2d2d2d",color:"#ccc",borderBottom:"1px solid #444"},Le={flex:1,background:"#1e1e1e",color:"#d4d4d4",border:"none",padding:"16px",fontFamily:"'SF Mono', 'Fira Code', 'Consolas', 'Monaco', monospace",fontSize:"13px",lineHeight:"1.6",resize:"none",outline:"none",tabSize:2},He={display:"flex",justifyContent:"flex-end",gap:"8px",padding:"12px 16px",background:"#2d2d2d",borderTop:"1px solid #444"},we={padding:"6px 16px",border:"1px solid #555",borderRadius:"6px",background:"transparent",color:"#ccc",cursor:"pointer",fontSize:"13px",transition:"border-color 0.15s"},Re={padding:"6px 16px",border:"none",borderRadius:"6px",background:"#0066ff",color:"#fff",cursor:"pointer",fontSize:"13px",fontWeight:500,transition:"background 0.15s"},U={letter:{width:816,height:1056},a4:{width:794,height:1123},legal:{width:816,height:1344}},ae={top:96,right:96,bottom:96,left:96},N={size:"letter",margins:{...ae}};function Pe(a){const e=[];return a.querySelectorAll("script").forEach(t=>{const o=document.createElement("script");Array.from(t.attributes).forEach(s=>o.setAttribute(s.name,s.value)),o.textContent=t.textContent||"",t.parentNode?.replaceChild(o,t),e.push(o)}),e}function _e(a){const e=window.getSelection();if(!e||e.rangeCount===0)return null;const t=e.getRangeAt(0),o=t.startContainer,s=Array.from(a.querySelectorAll(".dopecanvas-block-content")),l=s.findIndex(i=>i.contains(o));if(l===-1)return null;try{const i=document.createRange();i.selectNodeContents(s[l]),i.setEnd(t.startContainer,t.startOffset);const u=i.toString().length;return{blockIndex:l,textOffset:u}}catch{return null}}function Ae(a,e){const t=a.querySelectorAll(".dopecanvas-block-content");if(e.blockIndex>=t.length)return;const o=t[e.blockIndex],s=document.createTreeWalker(o,NodeFilter.SHOW_TEXT);let l=e.textOffset;for(;s.nextNode();){const i=s.currentNode;if(l<=i.length){try{const u=document.createRange();u.setStart(i,l),u.collapse(!0);const g=window.getSelection();g?.removeAllRanges(),g?.addRange(u)}catch{}return}l-=i.length}try{const i=document.createRange();i.selectNodeContents(o),i.collapse(!1);const u=window.getSelection();u?.removeAllRanges(),u?.addRange(i)}catch{}}const De=r.memo(({html:a,isEditable:e,isTable:t})=>n.jsx("div",{className:"dopecanvas-block-content",contentEditable:e&&!t?!0:void 0,suppressContentEditableWarning:!0,dangerouslySetInnerHTML:{__html:a}})),Ie=({html:a,css:e,pageConfig:t,layoutEngine:o,editableManager:s,onContentChange:l,onPaginationChange:i})=>{const u=r.useRef(null),g=r.useRef(null),k=r.useRef(null),h=r.useRef(l);h.current=l;const[p,S]=r.useState([]),w=r.useRef(null),x=r.useRef(!1),j=r.useRef([]),[R,D]=r.useState(null),[_,z]=r.useState(null),[m,C]=r.useState(""),L=r.useRef(null),P=typeof t.size=="string"?U[t.size]:t.size,W=r.useCallback(()=>{if(!g.current)return;const d=g.current.querySelectorAll(".dopecanvas-block-content"),c=[];d.forEach(b=>{const f=b.firstElementChild;f&&c.push(f.outerHTML)});const E=c.join(`
|
|
2
|
+
`);h.current?.(E)},[]),H=r.useCallback(d=>{if(!u.current)return;const c=u.current;if(c.style.width=`${o.getContentAreaWidth()}px`,c.style.position="absolute",c.style.left="-9999px",c.style.top="0",c.style.visibility="hidden",c.innerHTML="",e){const T=document.createElement("style");T.textContent=e,c.appendChild(T)}const E=document.createElement("div");E.innerHTML=d,c.appendChild(E);const b=o.measureBlocks(E),f=b.map(T=>T.element.cloneNode(!0).outerHTML),y=o.paginate(b),v=y.pages.map(T=>({blocks:T.blockIndices.map(I=>f[I])}));c.innerHTML="",j.current=v,S(v),i?.(y),h.current?.(d)},[e,o,i]),X=r.useCallback(()=>{if(!g.current||!u.current)return;const d=g.current,c=_e(d),E=d.querySelectorAll(".dopecanvas-block-content"),b=[];if(E.forEach(M=>{const B=M.firstElementChild;B&&b.push(B.outerHTML)}),b.length===0)return;const f=u.current,y=o.getContentAreaWidth();if(f.style.width=`${y}px`,f.style.position="absolute",f.style.left="-9999px",f.style.top="0",f.style.visibility="hidden",f.innerHTML="",e){const M=document.createElement("style");M.textContent=e,f.appendChild(M)}const v=document.createElement("div");v.innerHTML=b.join(`
|
|
3
|
+
`),f.appendChild(v);const T=o.measureBlocks(v),I=T.map(M=>M.element.cloneNode(!0).outerHTML),q=o.paginate(T);f.innerHTML="";const $=q.pages.map(M=>({blocks:M.blockIndices.map(B=>I[B])})),Q=j.current.map(M=>M.blocks.length),Y=$.map(M=>M.blocks.length);(Q.length!==Y.length||Q.some((M,B)=>M!==Y[B]))&&(x.current=!0,w.current=c,j.current=$,S($),i?.(q))},[e,o,i]),Z=r.useRef(X);Z.current=X;const J=r.useCallback(()=>{const d=new DOMParser().parseFromString(a,"text/html");d.head.querySelectorAll('style, link[rel="stylesheet"]').forEach(c=>{d.body.insertBefore(c,d.body.firstChild)}),H(d.body.innerHTML)},[a,H]);r.useEffect(()=>{J()},[J]);const A=r.useCallback(()=>{if(!g.current)return[];const d=g.current.querySelectorAll(".dopecanvas-block-content"),c=[];return d.forEach(E=>{const b=E.firstElementChild;b&&c.push(b.outerHTML)}),c},[]),he=r.useCallback(d=>{const c=A();c.splice(d+1,0,'<p style="min-height: 1.5em; line-height: 1.6;"> </p>'),D(null),H(c.join(`
|
|
4
|
+
`))},[A,H]),ge=r.useCallback(d=>{const c=A();c.length<=1||(c.splice(d,1),D(null),H(c.join(`
|
|
5
|
+
`)))},[A,H]),pe=r.useCallback(d=>{const c=A();d<c.length&&(z(d),C(c[d]))},[A]),fe=r.useCallback(d=>{if(_===null)return;const c=A();_<c.length&&(c[_]=d),z(null),C(""),D(null),H(c.join(`
|
|
6
|
+
`))},[_,A,H]),me=r.useCallback(()=>{z(null),C("")},[]);return r.useEffect(()=>{const d=g.current;if(!d)return;k.current&&k.current.disconnect(),d.querySelectorAll(".dopecanvas-block-content").forEach(y=>{const v=y.firstElementChild;v&&v.tagName==="TABLE"&&v.querySelectorAll("td, th").forEach(I=>{I.contentEditable="true"})});const E=Pe(d);let b=null;const f=new MutationObserver(()=>{x.current||(b&&clearTimeout(b),b=setTimeout(()=>{W(),Z.current()},300))});return f.observe(d,{childList:!0,subtree:!0,characterData:!0,attributes:!1}),k.current=f,w.current?requestAnimationFrame(()=>{w.current&&g.current&&(Ae(g.current,w.current),w.current=null),x.current=!1}):x.current=!1,()=>{f.disconnect(),E.forEach(y=>y.remove()),b&&clearTimeout(b)}},[p,W]),n.jsxs("div",{className:"dopecanvas-paged-view",style:Be,children:[n.jsx("div",{ref:u,"aria-hidden":"true"}),n.jsxs("div",{ref:g,style:Fe,children:[e&&n.jsx("style",{dangerouslySetInnerHTML:{__html:e}}),p.map((d,c)=>{const E=p.slice(0,c).reduce((b,f)=>b+f.blocks.length,0);return n.jsx(ee,{dimensions:P,margins:t.margins,pageNumber:c+1,totalPages:p.length,children:d.blocks.map((b,f)=>{const y=E+f,v=b.trim().toLowerCase(),T=!v.startsWith("<script")&&!v.startsWith("<style"),I=v.startsWith("<table");return n.jsxs("div",{className:"dopecanvas-block-wrapper",style:{position:"relative"},onMouseEnter:()=>{T&&(L.current&&(clearTimeout(L.current),L.current=null),D(y))},onMouseLeave:()=>{L.current=setTimeout(()=>{D(q=>q===y?null:q)},250)},children:[n.jsx(De,{html:b,isEditable:T,isTable:I}),T&&n.jsx(xe,{visible:R===y,onAddBelow:()=>he(y),onEditHTML:()=>pe(y),onDelete:()=>ge(y)})]},`${c}-${f}`)})},c)}),p.length===0&&n.jsx(ee,{dimensions:P,margins:t.margins,pageNumber:1,totalPages:1,children:n.jsx("div",{contentEditable:"true",style:{minHeight:"1em",outline:"none"},"data-placeholder":"Start typing..."})})]}),_!==null&&n.jsx(Te,{html:m,onSave:fe,onCancel:me})]})},Be={flex:1,overflow:"auto",backgroundColor:"#e8e8e8",display:"flex",flexDirection:"column",alignItems:"center"},Fe={display:"flex",flexDirection:"column",alignItems:"center",gap:"24px",padding:"24px 0"};class K{config;constructor(e=N){this.config={...e}}getConfig(){return{...this.config}}setConfig(e){e.size!==void 0&&(this.config.size=e.size),e.margins!==void 0&&(this.config.margins={...e.margins})}getPageDimensions(){return typeof this.config.size=="string"?U[this.config.size]:this.config.size}getContentAreaHeight(){return this.getPageDimensions().height-this.config.margins.top-this.config.margins.bottom}getContentAreaWidth(){return this.getPageDimensions().width-this.config.margins.left-this.config.margins.right}measureBlocks(e){const t=Array.from(e.children),o=[];for(let s=0;s<t.length;s++){const l=t[s],i=window.getComputedStyle(l),u=i.getPropertyValue("break-before")==="page"||i.getPropertyValue("page-break-before")==="always",g=i.getPropertyValue("break-after")==="page"||i.getPropertyValue("page-break-after")==="always",k=l.getBoundingClientRect(),h=parseFloat(i.marginTop)||0,p=parseFloat(i.marginBottom)||0,S=k.height+h+p;o.push({index:s,height:S,element:l,breakBefore:u,breakAfter:g})}return o}paginate(e){if(e.length===0)return{pages:[{blockIndices:[]}],pageCount:1};const t=this.getContentAreaHeight(),o=[];let s=[],l=0;for(let i=0;i<e.length;i++){const u=e[i];u.breakBefore&&s.length>0&&(o.push({blockIndices:s}),s=[],l=0),l+u.height>t&&s.length>0&&(o.push({blockIndices:s}),s=[],l=0),s.push(u.index),l+=u.height,u.breakAfter&&(o.push({blockIndices:s}),s=[],l=0)}return s.length>0&&o.push({blockIndices:s}),o.length===0&&o.push({blockIndices:[]}),{pages:o,pageCount:o.length}}}class F{observer=null;changeCallbacks=new Set;contextCallbacks=new Set;undoStack=[];redoStack=[];container=null;debounceTimer=null;selectionHandler=null;currentContext="none";static MAX_UNDO_STACK=100;static DEBOUNCE_MS=150;attach(e){this.detach(),this.container=e,this.makeChildrenEditable(e),this.pushUndoSnapshot(),this.observer=new MutationObserver(this.handleMutations),this.observer.observe(e,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["style","class"]}),this.selectionHandler=this.handleSelectionChange.bind(this),document.addEventListener("selectionchange",this.selectionHandler)}detach(){this.observer&&(this.observer.disconnect(),this.observer=null),this.selectionHandler&&(document.removeEventListener("selectionchange",this.selectionHandler),this.selectionHandler=null),this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.container=null}makeChildrenEditable(e){const t=Array.from(e.children);for(const o of t)o.tagName==="TABLE"?this.makeTableCellsEditable(o):o.contentEditable="true"}makeTableCellsEditable(e){e.querySelectorAll("td, th").forEach(o=>{o.contentEditable="true"})}handleMutations=e=>{this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.pushUndoSnapshot(),this.notifyChange()},F.DEBOUNCE_MS)};handleSelectionChange(){const e=window.getSelection();if(!e||e.rangeCount===0||!this.container){this.setContext("none");return}const o=e.getRangeAt(0).startContainer;let s=o;for(;s&&s!==this.container;){if(s instanceof HTMLElement){const l=s.tagName;if(l==="TD"||l==="TH"||l==="TABLE"){this.setContext("table");return}if(l==="IMG"){this.setContext("image");return}if(s.dataset?.dopecanvasChart){this.setContext("chart");return}}s=s.parentNode}this.container.contains(o)?this.setContext("text"):this.setContext("none")}setContext(e){e!==this.currentContext&&(this.currentContext=e,this.contextCallbacks.forEach(t=>t(e)))}getContext(){return this.currentContext}pushUndoSnapshot(){if(!this.container)return;const e=this.container.innerHTML,t=this.undoStack[this.undoStack.length-1];t&&t.html===e||(this.undoStack.push({html:e,timestamp:Date.now()}),this.redoStack=[],this.undoStack.length>F.MAX_UNDO_STACK&&this.undoStack.shift())}undo(){if(!this.container||this.undoStack.length<=1)return!1;const e=this.undoStack.pop();this.redoStack.push(e);const t=this.undoStack[this.undoStack.length-1];return this.pauseObserver(()=>{this.container.innerHTML=t.html,this.makeChildrenEditable(this.container)}),this.notifyChange(),!0}redo(){if(!this.container||this.redoStack.length===0)return!1;const e=this.redoStack.pop();return this.undoStack.push(e),this.pauseObserver(()=>{this.container.innerHTML=e.html,this.makeChildrenEditable(this.container)}),this.notifyChange(),!0}pauseObserver(e){this.observer&&this.observer.disconnect(),e(),this.observer&&this.container&&this.observer.observe(this.container,{childList:!0,subtree:!0,characterData:!0,attributes:!0,attributeFilter:["style","class"]})}onChange(e){return this.changeCallbacks.add(e),()=>{this.changeCallbacks.delete(e)}}onContextChange(e){return this.contextCallbacks.add(e),()=>{this.contextCallbacks.delete(e)}}notifyChange(){this.changeCallbacks.forEach(e=>e())}execCommand(e,t){return document.execCommand(e,!1,t)}queryCommandState(e){return document.queryCommandState(e)}queryCommandValue(e){return document.queryCommandValue(e)}getHTML(){return this.container?this.container.innerHTML:""}getPlainText(){return this.container&&(this.container.innerText||this.container.textContent)||""}}const ze=r.forwardRef(({html:a="",css:e,pageConfig:t,onContentChange:o,onPageConfigChange:s,style:l},i)=>{const[u,g]=r.useState(t||N),[k,h]=r.useState({pages:[],pageCount:0}),p=r.useRef(a),S=r.useRef(null),w=r.useRef(o);w.current=o;const x=t||u,j=r.useMemo(()=>new K(x),[]),R=r.useMemo(()=>new F,[]);r.useEffect(()=>{j.setConfig(x)},[x,j]);const D=r.useCallback(m=>{p.current=m,w.current?.(m)},[]),_=r.useCallback(m=>{const C={...x,...m,margins:{...x.margins,...m.margins||{}}};g(C),j.setConfig(C),s?.(C)},[x,j,s]),z=r.useCallback(m=>{h(m)},[]);return r.useImperativeHandle(i,()=>({execCommand:(m,C)=>R.execCommand(m,C),queryCommandState:m=>R.queryCommandState(m),queryCommandValue:m=>R.queryCommandValue(m),getPageConfig:()=>({...x}),setPageConfig:m=>{_(m)},getPageCount:()=>k.pageCount,getHTML:()=>{if(S.current){const m=S.current.querySelectorAll(".dopecanvas-block-content");if(m.length>0){const C=[];if(m.forEach(L=>{const P=L.firstElementChild;P&&C.push(P.outerHTML)}),C.length>0){const L=C.join(`
|
|
7
|
+
`);return p.current=L,L}}}return p.current},getPlainText:()=>{const m=S.current?(()=>{const L=S.current.querySelectorAll(".dopecanvas-block-content"),P=[];return L.forEach(W=>{const H=W.firstElementChild;H&&P.push(H.outerHTML)}),P.length>0?P.join(`
|
|
8
|
+
`):p.current})():p.current,C=document.createElement("div");return C.innerHTML=m,C.innerText||C.textContent||""},undo:()=>R.undo(),redo:()=>R.redo()}),[R,x,k.pageCount,_]),n.jsx("div",{ref:S,className:"dopecanvas-root",style:{display:"flex",flexDirection:"column",height:"100%",width:"100%",fontFamily:"system-ui, -apple-system, BlinkMacSystemFont, sans-serif",...l},children:n.jsx(Ie,{html:a,css:e,pageConfig:x,layoutEngine:j,editableManager:R,onContentChange:D,onPaginationChange:z})})});class le{layoutEngine;editableManager;sourceHTML="";sourceCSS="";measureContainer=null;contentContainer=null;paginationResult={pages:[],pageCount:0};paginationCallbacks=new Set;changeCallbacks=new Set;constructor(e=N){this.layoutEngine=new K(e),this.editableManager=new F}getLayoutEngine(){return this.layoutEngine}getEditableManager(){return this.editableManager}getPaginationResult(){return this.paginationResult}getSourceHTML(){return this.sourceHTML}getPageConfig(){return this.layoutEngine.getConfig()}loadHTML(e,t){this.sourceHTML=e,this.sourceCSS=t||""}setMeasureContainer(e){this.measureContainer=e}setContentContainer(e){this.contentContainer&&this.editableManager.detach(),this.contentContainer=e}runPagination(){if(!this.measureContainer)return{result:{pages:[{blockIndices:[]}],pageCount:1},measurements:[]};const e=this.layoutEngine.getContentAreaWidth();this.measureContainer.style.width=`${e}px`,this.measureContainer.style.position="absolute",this.measureContainer.style.left="-9999px",this.measureContainer.style.top="0",this.measureContainer.style.visibility="hidden";let t=null;this.sourceCSS&&(t=document.createElement("style"),t.textContent=this.sourceCSS,this.measureContainer.appendChild(t));const o=document.createElement("div");o.innerHTML=this.sourceHTML,this.measureContainer.appendChild(o);const s=this.layoutEngine.measureBlocks(o);return this.paginationResult=this.layoutEngine.paginate(s),this.measureContainer.innerHTML="",this.paginationCallbacks.forEach(l=>l(this.paginationResult)),{result:this.paginationResult,measurements:s}}rePaginate(){if(!this.contentContainer)return this.paginationResult;const e=this.layoutEngine.measureBlocks(this.contentContainer);return this.paginationResult=this.layoutEngine.paginate(e),this.paginationCallbacks.forEach(t=>t(this.paginationResult)),this.paginationResult}attachEditing(e){this.contentContainer=e,this.editableManager.attach(e),this.editableManager.onChange(()=>{this.sourceHTML=e.innerHTML,this.changeCallbacks.forEach(t=>t(this.sourceHTML))})}setPageConfig(e){this.layoutEngine.setConfig(e)}onPagination(e){return this.paginationCallbacks.add(e),()=>{this.paginationCallbacks.delete(e)}}onChange(e){return this.changeCallbacks.add(e),()=>{this.changeCallbacks.delete(e)}}getHTML(){return this.contentContainer?this.contentContainer.innerHTML:this.sourceHTML}getPlainText(){return this.contentContainer&&(this.contentContainer.innerText||this.contentContainer.textContent)||""}destroy(){this.editableManager.detach(),this.paginationCallbacks.clear(),this.changeCallbacks.clear(),this.measureContainer=null,this.contentContainer=null}}class qe{_html="";_css="";_pageConfig=null;_paginationResult={pages:[],pageCount:0};_changeCallbacks=new Set;_loadCallbacks=new Set;_pageConfigCallbacks=new Set;_getHTMLFn=null;_getPlainTextFn=null;loadHTML(e,t){this._html=e,this._css=t||"",this._loadCallbacks.forEach(o=>o(e,t))}getHTML(){return this._getHTMLFn?this._getHTMLFn():this._html}getPlainText(){if(this._getPlainTextFn)return this._getPlainTextFn();const e=document.createElement("div");return e.innerHTML=this._html,e.innerText||e.textContent||""}onChange(e){return this._changeCallbacks.add(e),()=>{this._changeCallbacks.delete(e)}}onLoad(e){return this._loadCallbacks.add(e),()=>{this._loadCallbacks.delete(e)}}onPageConfigChange(e){return this._pageConfigCallbacks.add(e),()=>{this._pageConfigCallbacks.delete(e)}}getPageCount(){return this._paginationResult.pageCount}getPageConfig(){return this._pageConfig}setPageConfig(e){this._pageConfig&&(this._pageConfig={...this._pageConfig,...e,margins:{...this._pageConfig.margins,...e.margins||{}}},this._pageConfigCallbacks.forEach(t=>t(this._pageConfig)))}querySelectorAll(e){const t=document.createElement("div");return t.innerHTML=this.getHTML(),Array.from(t.querySelectorAll(e))}getElementContent(e){const t=document.createElement("div");t.innerHTML=this.getHTML();const o=t.querySelector(`#${e}`);return o?o.innerHTML:null}setElementContent(e,t){const o=document.createElement("div");o.innerHTML=this.getHTML();const s=o.querySelector(`#${e}`);s&&(s.innerHTML=t,this.loadHTML(o.innerHTML,this._css))}_connectGetHTML(e){this._getHTMLFn=e}_connectGetPlainText(e){this._getPlainTextFn=e}_notifyChange(e){this._html=e,this._changeCallbacks.forEach(t=>t(e))}_updatePagination(e){this._paginationResult=e}_updatePageConfig(e){this._pageConfig=e}}function Ne(a){const[e,t]=r.useState("none");return r.useEffect(()=>a?a.onContextChange(s=>{t(s)}):void 0,[a]),e}function ce(){const[a,e]=r.useState({bold:!1,italic:!1,underline:!1,strikethrough:!1,justifyLeft:!1,justifyCenter:!1,justifyRight:!1,justifyFull:!1}),t=r.useCallback(()=>{e({bold:document.queryCommandState("bold"),italic:document.queryCommandState("italic"),underline:document.queryCommandState("underline"),strikethrough:document.queryCommandState("strikethrough"),justifyLeft:document.queryCommandState("justifyLeft"),justifyCenter:document.queryCommandState("justifyCenter"),justifyRight:document.queryCommandState("justifyRight"),justifyFull:document.queryCommandState("justifyFull")})},[]);return r.useEffect(()=>(document.addEventListener("selectionchange",t),()=>{document.removeEventListener("selectionchange",t)}),[t]),a}const ue=({onExecCommand:a})=>{const e=ce(),t=r.useRef(null),o=r.useCallback(()=>{const h=window.getSelection();h&&h.rangeCount>0&&(t.current=h.getRangeAt(0).cloneRange())},[]),s=r.useCallback(()=>{const h=t.current;if(!h)return;const p=window.getSelection();p&&(p.removeAllRanges(),p.addRange(h))},[]),l=r.useCallback((h,p)=>S=>{S.preventDefault(),a(h,p)},[a]),i=r.useCallback(h=>{s(),a("fontSize",h.target.value)},[a,s]),u=r.useCallback(h=>{s();const p=h.target.value;p==="p"?a("formatBlock","p"):a("formatBlock",p)},[a,s]),g=r.useCallback(h=>{s(),a("foreColor",h.target.value)},[a,s]),k=r.useCallback(h=>{s(),a("hiliteColor",h.target.value)},[a,s]);return n.jsxs("div",{style:We,children:[n.jsxs("select",{onChange:u,defaultValue:"p",style:ne,title:"Block Format",onMouseDown:o,children:[n.jsx("option",{value:"p",children:"Paragraph"}),n.jsx("option",{value:"h1",children:"Heading 1"}),n.jsx("option",{value:"h2",children:"Heading 2"}),n.jsx("option",{value:"h3",children:"Heading 3"}),n.jsx("option",{value:"h4",children:"Heading 4"}),n.jsx("option",{value:"h5",children:"Heading 5"}),n.jsx("option",{value:"h6",children:"Heading 6"})]}),n.jsx("div",{style:G}),n.jsxs("select",{onChange:i,defaultValue:"3",style:ne,title:"Font Size",onMouseDown:o,children:[n.jsx("option",{value:"1",children:"8pt"}),n.jsx("option",{value:"2",children:"10pt"}),n.jsx("option",{value:"3",children:"12pt"}),n.jsx("option",{value:"4",children:"14pt"}),n.jsx("option",{value:"5",children:"18pt"}),n.jsx("option",{value:"6",children:"24pt"}),n.jsx("option",{value:"7",children:"36pt"})]}),n.jsx("div",{style:G}),n.jsx(te,{icon:"B",title:"Bold (Ctrl+B)",active:e.bold,onMouseDown:l("bold"),extraStyle:{fontWeight:"bold"}}),n.jsx(te,{icon:"I",title:"Italic (Ctrl+I)",active:e.italic,onMouseDown:l("italic"),extraStyle:{fontStyle:"italic"}}),n.jsx("div",{style:G}),n.jsxs("label",{style:oe,title:"Text Color",onMouseDown:o,children:["A",n.jsx("input",{type:"color",defaultValue:"#000000",onChange:g,style:se})]}),n.jsxs("label",{style:oe,title:"Highlight Color",onMouseDown:o,children:[n.jsx("span",{style:{backgroundColor:"#ffff00",padding:"0 2px"},children:"A"}),n.jsx("input",{type:"color",defaultValue:"#ffff00",onChange:k,style:se})]})]})},te=({icon:a,title:e,active:t,onMouseDown:o,extraStyle:s})=>n.jsx("button",{type:"button",title:e,onMouseDown:o,style:{width:"28px",height:"28px",borderWidth:"1px",borderStyle:"solid",borderColor:t?"#b0b5bd":"transparent",borderRadius:"3px",backgroundColor:t?"#d0d5dd":"transparent",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",fontSize:"13px",color:"#333",padding:0,fontFamily:"inherit",...s},dangerouslySetInnerHTML:{__html:a}}),We={display:"flex",alignItems:"center",gap:"2px",flexWrap:"wrap"},ne={height:"28px",borderWidth:"1px",borderStyle:"solid",borderColor:"#ccc",borderRadius:"3px",fontSize:"12px",padding:"0 4px",cursor:"pointer",backgroundColor:"#fff"},G={width:"1px",height:"20px",backgroundColor:"#ddd",margin:"0 4px"},oe={position:"relative",width:"28px",height:"28px",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",fontSize:"13px",fontWeight:"bold"},se={position:"absolute",bottom:0,left:0,width:"100%",height:"4px",padding:0,borderWidth:0,borderStyle:"none",cursor:"pointer"},de=({pageConfig:a,pageCount:e,onPageConfigChange:t})=>{const o=r.useCallback(i=>{const u=i.target.value;t({size:u})},[t]),s=r.useCallback(i=>u=>{const g=Math.max(0,parseInt(u.target.value)||0);t({margins:{...a.margins,[i]:g}})},[a.margins,t]),l=typeof a.size=="string"?a.size:"custom";return n.jsxs("div",{style:Oe,children:[n.jsxs("label",{style:$e,children:["Page:",n.jsxs("select",{value:l,onChange:o,style:Ve,children:[n.jsx("option",{value:"letter",children:"Letter (8.5 x 11)"}),n.jsx("option",{value:"a4",children:"A4 (210 x 297mm)"}),n.jsx("option",{value:"legal",children:"Legal (8.5 x 14)"})]})]}),n.jsx("div",{style:re}),n.jsx("span",{style:{fontSize:"12px",color:"#666"},children:"Margins (px):"}),n.jsx(O,{label:"T",value:a.margins.top,onChange:s("top")}),n.jsx(O,{label:"R",value:a.margins.right,onChange:s("right")}),n.jsx(O,{label:"B",value:a.margins.bottom,onChange:s("bottom")}),n.jsx(O,{label:"L",value:a.margins.left,onChange:s("left")}),n.jsx("div",{style:re}),n.jsxs("span",{style:{fontSize:"12px",color:"#666"},children:[e," ",e===1?"page":"pages"]})]})},O=({label:a,value:e,onChange:t})=>n.jsxs("label",{style:Ge,title:`${a} margin`,children:[a,":",n.jsx("input",{type:"number",value:e,onChange:t,style:Ue,min:0,max:300,step:12})]}),Oe={display:"flex",alignItems:"center",gap:"6px",flexWrap:"wrap"},$e={display:"flex",alignItems:"center",gap:"4px",fontSize:"12px",color:"#666"},Ve={height:"26px",borderWidth:"1px",borderStyle:"solid",borderColor:"#ccc",borderRadius:"3px",fontSize:"12px",padding:"0 4px",cursor:"pointer",backgroundColor:"#fff"},re={width:"1px",height:"20px",backgroundColor:"#ddd",margin:"0 4px"},Ge={display:"flex",alignItems:"center",gap:"2px",fontSize:"11px",color:"#666"},Ue={width:"44px",height:"24px",borderWidth:"1px",borderStyle:"solid",borderColor:"#ccc",borderRadius:"3px",fontSize:"11px",textAlign:"center",padding:"0 2px"},Ke=({pageConfig:a,pageCount:e,onExecCommand:t,onPageConfigChange:o})=>n.jsxs("div",{style:Xe,children:[n.jsx("div",{style:ie,children:n.jsx(ue,{onExecCommand:t})}),n.jsx("div",{style:ie,children:n.jsx(de,{pageConfig:a,pageCount:e,onPageConfigChange:o})})]}),Xe={borderBottomWidth:"1px",borderBottomStyle:"solid",borderBottomColor:"#d0d0d0",backgroundColor:"#f8f8f8",padding:"4px 8px",display:"flex",flexDirection:"column",gap:"4px",flexShrink:0,zIndex:10},ie={display:"flex",alignItems:"center",gap:"4px",minHeight:"32px"};function Ze(a={}){const{initialHTML:e="",initialCSS:t="",initialConfig:o=N}=a,s=r.useRef(new le(o)),[l,i]=r.useState({pages:[{blockIndices:[]}],pageCount:1}),[u,g]=r.useState(o),k=r.useCallback((x,j)=>{s.current.loadHTML(x,j)},[]),h=r.useCallback(x=>{s.current.setPageConfig(x),g(s.current.getPageConfig())},[]),p=r.useCallback(()=>{const{result:x}=s.current.runPagination();i(x)},[]),S=r.useCallback(()=>s.current.getHTML(),[]),w=r.useCallback(()=>s.current.getPlainText(),[]);return r.useEffect(()=>{e&&s.current.loadHTML(e,t)},[e,t]),r.useEffect(()=>s.current.onPagination(j=>{i(j)}),[]),r.useEffect(()=>()=>{s.current.destroy()},[]),{engine:s.current,paginationResult:l,pageConfig:u,loadHTML:k,setPageConfig:h,triggerPagination:p,getHTML:S,getPlainText:w}}exports.DEFAULT_MARGINS=ae;exports.DEFAULT_PAGE_CONFIG=N;exports.DocumentAPI=qe;exports.DocumentEngine=le;exports.DopeCanvas=ze;exports.EditableManager=F;exports.PAGE_SIZE_PRESETS=U;exports.PageLayoutEngine=K;exports.PageSetupToolbar=de;exports.TextToolbar=ue;exports.Toolbar=Ke;exports.useDocumentEngine=Ze;exports.useFormattingState=ce;exports.useSelectionContext=Ne;
|
|
4
9
|
//# sourceMappingURL=dopecanvas.cjs.map
|