polotno 2.38.1 → 2.39.0

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 (47) hide show
  1. package/canvas/drawing-layer.js +1 -1
  2. package/canvas/html-element.js +17 -3
  3. package/canvas/rules.js +3 -1
  4. package/canvas/workspace-canvas.d.ts +2 -1
  5. package/canvas/workspace-canvas.js +1 -1
  6. package/model/group-model.d.ts +1 -0
  7. package/model/table-model.js +1 -1
  8. package/model/text-model.d.ts +1 -0
  9. package/model/text-model.js +1 -1
  10. package/package.json +3 -4
  11. package/polotno.bundle.js +143 -122
  12. package/side-panel/layers-panel.js +1 -1
  13. package/toolbar/image-remove-background-button.d.ts +1 -1
  14. package/toolbar/image-remove-background-button.js +1 -1
  15. package/toolbar/text-toolbar.js +2 -2
  16. package/utils/fonts.js +1 -1
  17. package/utils/html-to-svg/css-extractor.d.ts +4 -0
  18. package/utils/html-to-svg/css-extractor.js +1 -0
  19. package/utils/html-to-svg/font-inliner.d.ts +3 -0
  20. package/utils/html-to-svg/font-inliner.js +1 -0
  21. package/utils/html-to-svg/index.d.ts +18 -0
  22. package/utils/html-to-svg/index.js +1 -0
  23. package/utils/html-to-svg/lru-cache.d.ts +13 -0
  24. package/utils/html-to-svg/lru-cache.js +1 -0
  25. package/utils/html-to-svg/render-cache.d.ts +4 -0
  26. package/utils/html-to-svg/render-cache.js +1 -0
  27. package/utils/html-to-svg/svg-builder.d.ts +8 -0
  28. package/utils/html-to-svg/svg-builder.js +1 -0
  29. package/utils/html-to-svg/xhtml.d.ts +1 -0
  30. package/utils/html-to-svg/xhtml.js +1 -0
  31. package/utils/html2canvas.d.ts +2 -2
  32. package/utils/html2canvas.js +1 -1
  33. package/utils/text-html.js +1 -1
  34. package/utils/to-html.js +1 -1
  35. package/utils/validate-key.js +1 -1
  36. package/model/history.test.d.ts +0 -1
  37. package/model/store.test.d.ts +0 -1
  38. package/utils/__tests__/clipboard.test.d.ts +0 -1
  39. package/utils/__tests__/css-optimizer.test.d.ts +0 -1
  40. package/utils/__tests__/fonts.test.d.ts +0 -1
  41. package/utils/__tests__/gradient.test.d.ts +0 -1
  42. package/utils/__tests__/image-dpi.test.d.ts +0 -1
  43. package/utils/__tests__/loader.test.d.ts +0 -1
  44. package/utils/__tests__/luma.test.d.ts +0 -1
  45. package/utils/__tests__/measure-text.test.d.ts +0 -1
  46. package/utils/__tests__/svg.test.d.ts +0 -1
  47. package/utils/__tests__/text.test.d.ts +0 -1
@@ -1 +1 @@
1
- import e from"react";import{observer as t}from"mobx-react-lite";import{Group as r,Line as o,Rect as n}from"react-konva";import{pathToSVG as s}from"../utils/path-to-svg.js";export const DrawingLayer=t(({store:t,page:i,width:c,height:a,scale:l,xPadding:u,yPadding:h,bleed:g})=>{const[y,d]=e.useState(!1),[p,f]=e.useState([]),m=e.useRef(null),x="draw"===t.tool,{strokeWidth:k,stroke:w,opacity:$,brushType:b}=t.toolOptions,v=e.useCallback(e=>{if(!x){return}if(d(!0),e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f([{x:t.x,y:t.y}])},[x,l,u,h,g]),E=e.useCallback(e=>{if(!x||!y){return}if(e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f(e=>[...e,{x:t.x,y:t.y}])},[x,y,l,u,h,g]),S=e.useCallback(()=>{if(x&&y){if(d(!1),p.length>=1){try{const e=s(p,{stroke:w,strokeWidth:k,smooth:!0}),r=t.selectedElementsIds.slice();t.history.transaction(()=>{i.addElement({type:"svg",x:e.x,y:e.y,width:e.width,height:e.height,src:e.src,opacity:$},{skipSelect:!0})}),t.selectElements(r)}catch(e){console.error("Error creating path SVG:",e)}}f([])}},[x,y,p,w,k,$,i,t.history,t]),M=e.useMemo(()=>p.flatMap(e=>[e.x,e.y]),[p]);return e.useEffect(()=>{if(x&&m.current){const e=m.current.getStage();if(!e){return}const t=k*l;if(t>100||t<4){e.container().style.cursor="crosshair"}else{const r=t/2,o=t/2,n=`data:image/svg+xml;base64,${btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 ${t} ${t}">\n <circle cx="${o}" cy="${o}" r="${r-1}" fill="${w}" opacity="${$}" stroke="white" stroke-width="1"/>\n <circle cx="${o}" cy="${o}" r="${r-1}" fill="none" stroke="black" stroke-width="1" opacity="0.3"/>\n </svg>`)}`;e.container().style.cursor=`url("${n}") ${o} ${o}, crosshair`}return()=>{e.container()&&(e.container().style.cursor="")}}},[x,w,k,$,l]),x?e.createElement(r,{ref:m,listening:x,x:u+g*l,y:h+g*l,scaleX:l,scaleY:l},e.createElement(n,{x:-(u+g*l)/l,y:-(h+g*l)/l,width:c/l,height:a/l,fill:"transparent",onMouseDown:v,onMouseMove:E,onMouseUp:S,onTouchStart:v,onTouchMove:E,onTouchEnd:S}),p.length>0&&e.createElement(o,{points:M,stroke:w,strokeWidth:k,lineCap:"round",lineJoin:"round",opacity:$,tension:.5,listening:!1})):null});
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import{Group as r,Line as o,Rect as n}from"react-konva";import{pathToSVG as s}from"../utils/path-to-svg.js";export const DrawingLayer=t(({store:t,page:i,width:c,height:a,scale:l,xPadding:u,yPadding:h,bleed:d})=>{const[g,y]=e.useState(!1),[p,f]=e.useState([]),m=e.useRef(null),w="draw"===t.tool,{strokeWidth:v,stroke:x,opacity:k,brushType:$}=t.toolOptions,E=e.useCallback(e=>{if(!w){return}if(y(!0),e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f([{x:t.x,y:t.y}])},[w,l,u,h,d]),b=e.useCallback(e=>{if(!w||!g){return}if(e.cancelBubble=!0,!e.target.getStage()){return}const t=m.current.getRelativePointerPosition();t&&f(e=>[...e,{x:t.x,y:t.y}])},[w,g,l,u,h,d]),S=e.useCallback(()=>{if(w&&g){if(y(!1),p.length>=1){try{const e=s(p,{stroke:x,strokeWidth:v,smooth:!0}),r=t.selectedElementsIds.slice();t.history.transaction(()=>{i.addElement({type:"svg",x:e.x,y:e.y,width:e.width,height:e.height,src:e.src,opacity:k},{skipSelect:!0})}),t.selectElements(r)}catch(e){console.error("Error creating path SVG:",e)}}f([])}},[w,g,p,x,v,k,i,t.history,t]);e.useEffect(()=>{if(!g){return}const e=()=>S();return window.addEventListener("mouseup",e),window.addEventListener("touchend",e),()=>{window.removeEventListener("mouseup",e),window.removeEventListener("touchend",e)}},[g,S]);const M=e.useMemo(()=>p.flatMap(e=>[e.x,e.y]),[p]);return e.useEffect(()=>{if(w&&m.current){const e=m.current.getStage();if(!e){return}const t=v*l;if(t>100||t<4){e.container().style.cursor="crosshair"}else{const r=t/2,o=t/2,n=`data:image/svg+xml;base64,${btoa(`<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${t}" viewBox="0 0 ${t} ${t}">\n <circle cx="${o}" cy="${o}" r="${r-1}" fill="${x}" opacity="${k}" stroke="white" stroke-width="1"/>\n <circle cx="${o}" cy="${o}" r="${r-1}" fill="none" stroke="black" stroke-width="1" opacity="0.3"/>\n </svg>`)}`;e.container().style.cursor=`url("${n}") ${o} ${o}, crosshair`}return()=>{e.container()&&(e.container().style.cursor="")}}},[w,x,v,k,l]),w?e.createElement(r,{ref:m,listening:w,x:u+d*l,y:h+d*l,scaleX:l,scaleY:l},e.createElement(n,{x:-(u+d*l)/l,y:-(h+d*l)/l,width:c/l,height:a/l,fill:"transparent",onMouseDown:E,onMouseMove:b,onMouseUp:S,onTouchStart:E,onTouchMove:b,onTouchEnd:S}),p.length>0&&e.createElement(o,{points:M,stroke:x,strokeWidth:v,lineCap:"round",lineJoin:"round",opacity:k,tension:.5,listening:!1})):null});
@@ -1,4 +1,4 @@
1
- import t from"react";import{observer as e}from"mobx-react-lite";import{Group as o,Image as n,Path as i,Rect as r}from"react-konva";import a from"quill";import l from"konva";import*as s from"mobx";import{reaction as c}from"mobx";import{flags as d}from"../utils/flags.js";import{applyFilter as f}from"./apply-filters.js";import{getLineHeight as u,useFontLoader as h,usePrevious as g}from"./text-element.js";import{getCurvePath as m,getDir as p}from"../utils/text-html.js";import{useColor as x}from"./use-color.js";import{detectSize as w,htmlToCanvas as y,isContentWrapping as v}from"../utils/html2canvas.js";import{resetStyleContent as b}from"../utils/reset-style.js";import{useFadeIn as E}from"./use-fadein.js";import{Html as S}from"react-konva-utils";import F from"../utils/styled.js";import{incrementLoader as k,triggerLoadError as z}from"../utils/loader.js";import{removeTags as O}from"../utils/text.js";import*as R from"../utils/fonts.js";import{isTouchDevice as C}from"../utils/screen.js";import{getLimitedFontSize as T}from"./text-element/max-font-size.js";import{useDelayer as j}from"./use-delayer.js";import{getOptimalCaretColor as M}from"./text-element/caret-color.js";import{getHtml as P}from"../utils/text-html.js";function A(t,e){if(1===e){return t}const o=l.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}function Y(t){const e=(t||"").trim();if("<p><br></p>"===e||"<p></p>"===e){return""}if(e.startsWith("<p>")&&e.endsWith("</p>")){const t=e.slice(3,-4);if(!/(<\/?(p|div|h[1-6]|ul|ol|li|table|thead|tbody|tr|td|blockquote)\b)/i.test(t)){return t}}return t}export const quillRef=s.observable({enabled:!1,currentFormat:{},editor:s.observable.object({instance:null},{},{deep:!1})});const $=F("div",t.forwardRef)`
1
+ import t from"react";import{observer as e}from"mobx-react-lite";import{Group as o,Image as n,Path as i,Rect as r}from"react-konva";import a from"quill";import l from"konva";import*as s from"mobx";import{reaction as c}from"mobx";import{flags as d}from"../utils/flags.js";import{applyFilter as f}from"./apply-filters.js";import{getLineHeight as u,useFontLoader as h,usePrevious as g}from"./text-element.js";import{getCurvePath as m,getDir as p,getHtml as x}from"../utils/text-html.js";import{useColor as w}from"./use-color.js";import{detectSize as y,htmlToCanvas as v,isContentWrapping as b}from"../utils/html2canvas.js";import{resetStyleContent as E}from"../utils/reset-style.js";import{useFadeIn as S}from"./use-fadein.js";import{Html as k}from"react-konva-utils";import F from"../utils/styled.js";import{incrementLoader as O,triggerLoadError as z}from"../utils/loader.js";import{removeTags as R}from"../utils/text.js";import*as C from"../utils/fonts.js";import{isTouchDevice as j}from"../utils/screen.js";import{getLimitedFontSize as T}from"./text-element/max-font-size.js";import{useDelayer as M}from"./use-delayer.js";import{getOptimalCaretColor as q}from"./text-element/caret-color.js";function A(t,e){if(1===e){return t}const o=l.Util.colorToRGBA(t);return o?`rgba(${o.r}, ${o.g}, ${o.b}, ${o.a*e})`:t}function P(t){const e=(t||"").trim();if("<p><br></p>"===e||"<p></p>"===e){return""}if(e.startsWith("<p>")&&e.endsWith("</p>")){const t=e.slice(3,-4);if(!/(<\/?(p|div|h[1-6]|ul|ol|li|table|thead|tbody|tr|td|blockquote)\b)/i.test(t)){return t}}return t}export const quillRef=s.observable({enabled:!1,currentFormat:{},editor:s.observable.object({instance:null},{},{deep:!1})});const Y=F("div",t.forwardRef)`
2
2
  .ql-editor {
3
3
  outline: none;
4
4
  }
@@ -6,11 +6,25 @@ import t from"react";import{observer as e}from"mobx-react-lite";import{Group as
6
6
  pointer-events: none;
7
7
  opacity: 0;
8
8
  }
9
- ${b}
9
+ ${E}
10
10
  strong {
11
11
  font-weight: 700;
12
12
  }
13
13
  .ql-direction-rtl {
14
14
  direction: rtl;
15
15
  }
16
- `;let q=["bold","color","font","italic","size","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{q=t};export const createQuill=t=>new a(t,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:q});export const setQuillContent=(t,e)=>{var o=t.clipboard.convert("<div class='ql-editor' style='outline: none;'>"+e+"<p><br></p></div>");t.setContents(o),t.history.clear()};const L=({html:e,onBlur:o,onChange:n,element:i,clickCoords:r})=>{var l;const d=t.useRef(null);t.useEffect(()=>{if(!d.current){return}const t=(i=d.current,new a(i,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:q}));var i;s.runInAction(()=>{quillRef.editor.instance=t}),window.__polotnoQuill=t,t.on("text-change",()=>{t.getSelection()&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())}),setTimeout(()=>{var t;const e=null===(t=d.current)||void 0===t?void 0:t.childNodes[0];if(!e){return}const o=e.innerHTML;n(Y(o))},10)}),setQuillContent(t,e),r?setCursorFromCoords(t,r):t.setSelection(0,0,"api"),t.on("selection-change",(e,o,n)=>{e&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())})}),d.current.childNodes[0].addEventListener("blur",t=>{const e=t.relatedTarget;if(null==e?void 0:e.classList.contains("ql-clipboard")){return}const n=function(t){return!!t&&!!t.closest(".sketch-picker")}(e);n||o()});const l=d.current.childNodes[0],c=e=>{var o,n;const i=t.getSelection();if(!i||0===i.length){return}const r=t.getText(i.index,i.length).replace(/\n$/,""),a=window.getSelection();let l="";if(a&&a.rangeCount>0){const t=a.getRangeAt(0),e=document.createElement("div");e.appendChild(t.cloneContents()),l=e.innerHTML}if(null===(o=e.clipboardData)||void 0===o||o.setData("text/plain",r),l){const t='<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>\x3c!--StartFragment--\x3e<div style="white-space: pre-wrap; word-wrap: break-word;">'+l+"</div>\x3c!--EndFragment--\x3e</body></html>";null===(n=e.clipboardData)||void 0===n||n.setData("text/html",t)}e.preventDefault()},f=e=>{c(e);const o=t.getSelection();o&&o.length>0&&t.deleteText(o.index,o.length)};return l.addEventListener("copy",c),l.addEventListener("cut",f),()=>{l.removeEventListener("copy",c),l.removeEventListener("cut",f),s.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={}}),delete window.__polotnoQuill}},[]),t.useEffect(()=>c(()=>i.text,()=>{var t,o;const n=quillRef.editor.instance;if(!n){return}const r=n.getSelection(),a=null===(o=null===(t=d.current)||void 0===t?void 0:t.childNodes)||void 0===o?void 0:o[0];Y((null==a?void 0:a.innerHTML)||"")===i.text||(setQuillContent(n,e),r&&(n.setSelection(r.index,r.length),s.runInAction(()=>{quillRef.currentFormat=n.getFormat(n.getSelection())})))},{fireImmediately:!0}),[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=d.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]);const f={color:i.fill};i.fill.indexOf("gradient")>=0&&(f.backgroundColor=i.fill,f.backgroundImage=i.fill,f.backgroundSize="100% 100%",f.backgroundRepeat="repeat",f.webkitBackgroundClip="text",f.MozBackgroundClip="text",f.WebkitTextFillColor="transparent",f.MozTextFillColor="transparent");const u=M(i);return t.createElement($,{ref:d,style:Object.assign(Object.assign({},f),{fontSize:i.fontSize,fontWeight:i.fontWeight,textTransform:i.textTransform,width:i.a.width,fontFamily:'"'+i.fontFamily+'"',lineHeight:i.lineHeight,letterSpacing:i.letterSpacing*i.fontSize+"px",textAlign:i.align,opacity:Math.max(i.a.opacity,.2),textShadow:i.shadowEnabled?`${i.shadowOffsetX}px ${i.shadowOffsetY}px ${i.shadowBlur}px ${A(i.shadowColor,null!==(l=i.shadowOpacity)&&void 0!==l?l:1)}`:void 0,caretColor:u}),dir:p(O(i.text))})};function X(t){return!function(t){const e=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let o=0;o<e.length;o+=4){if(0!==e[o+3]){return!0}}return!1}(t)}const I=/^((?!chrome|android).)*safari/i.test(navigator.userAgent);export const HTMLElement=e(({element:e,store:a})=>{var c,p;const b=t.useRef(null),[F,M]=t.useState(),[Y,q]=t.useState(!1),[D,W]=t.useState(!1),B=t.useRef(e.height),H=a.selectedShapes.indexOf(e)>=0&&e.selectable,_=g(H),N=e.fontSize/3,{textVerticalResizeEnabled:Q}=d,J=d.autoDeleteEmptyText,V=g(e.fontFamily),[G]=h(a,e.fontFamily,e.fontStyle,e.fontWeight,e.text||e.placeholder),U=e._editModeEnabled;E(b);const K=G?e.fontFamily:V!==e.fontFamily?V:"Arial",Z=x(e).fill,tt=P(e,{fontFamily:K,color:Z}),et=P(e,{fontFamily:K,color:Z,forEditor:!0}),ot=t.useRef([]),[,nt]=t.useReducer(t=>t+1,0);t.useEffect(()=>{const t=ot.current;t.length>0&&(ot.current=[],t.forEach(t=>t()))});let{width:it,height:rt}=function(e,o,n){return t.useMemo(()=>w(e),[e,o.width,n])}(tt,e,G);t.useEffect(()=>{if(!G){return}const t=(t,o,n,i)=>{const r=k(`text ${e.id}`),l=()=>{a.history.ignore(t,o,n).then(()=>{ot.current.push(r),nt()})};i?queueMicrotask(l):l()};if(!e.height){return void t(()=>{e.height||e.set({height:rt})},void 0,void 0,!0)}const{textOverflow:o}=d;if("change-font-size"!==o||Y){"resize"===o&&(Q&&e.height<rt&&!Y&&t(()=>{e.set({height:rt})},!1,!0),Q||e.height===rt||Y||t(()=>{e.set({height:rt})},!1,!0))}else{const o=(t=>{let e=t.fontSize;for(let o=1;o<50;o++){const o=P(Object.assign(Object.assign({},t.toJSON()),{fontSize:e}),{fontFamily:t.fontFamily}),{height:n}=w(o);if(!(t.height&&n>t.height||!d.textSplitAllowed&&!t.curveEnabled&&v({html:o}))){break}e-=.5}return e})(e);o!==e.fontSize?t(()=>{e.set({fontSize:o})},!1,!0):e.height!==rt&&(Q&&e.height<rt?t(()=>{e.set({height:rt})},!1,!0):Q||t(()=>{e.set({height:rt})},!1,!0))}});const at=t.useMemo(()=>{const t={lastArgs:null,lastResult:null};return async function(e){return t.lastArgs&&t.lastResult&&(o=t.lastArgs,n=e,JSON.stringify(o)===JSON.stringify(n))||(t.lastResult=await y(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,n}},[]),lt=t.useRef(0),st=t.useRef(null);t.useEffect(()=>{Y||U||(async()=>{lt.current++;const t=lt.current;let o=k(`text ${e.id} ${t}`);st.current&&st.current(),st.current=o,W(!0);let n=null;const i=I?5:1;for(let l=0;l<i;l++){const o=l>0?at:y;try{if(n=await o({skipCache:l>0,html:tt,width:e.width||1,height:e.height||rt||1,fontFamily:K,padding:N,pixelRatio:a._elementsPixelRatio,font:a.fonts.find(t=>t.fontFamily===K)||R.globalFonts.find(t=>t.fontFamily===K)}),t!==lt.current){return}if(I&&n&&X(n)){await new Promise(t=>setTimeout(t,50*(l+1)));continue}break}catch(r){console.error(r),z(`Error rendering rich text with id ${e.id}`);break}}n?M(n):o?(o(),o=null):console.error("Finish function is called twice!"),W(!1)})()},[tt,Y,rt,U,K,e.height,a._elementsPixelRatio,G]);const[ct,dt]=j(D,300),[ft]=j(Y,300,!0),ut=ft||ct;t.useEffect(()=>{var t;if(!ut){return s.autorun(()=>{const t=b.current;f(t,e)})}null===(t=b.current)||void 0===t||t.clearCache()},[F,ut,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]),t.useEffect(()=>{F&&!D&&st.current&&(st.current(),st.current=null)},[F,D]),t.useLayoutEffect(()=>{if(!G){return}if(!e.curveEnabled){return}const t=new l.TextPath({data:m(e.a.width,e.a.height,e.curvePower,e.a.fontSize),text:O(e.text),letterSpacing:e.letterSpacing*e.a.fontSize,fontSize:e.a.fontSize,fontFamily:e.fontFamily,fontWeight:e.fontWeight,fontStyle:e.fontStyle,align:"center",textBaseline:"middle",fill:e.fill}),o=t.getSelfRect().width;if(o){const t=o-e.a.width,n=e.a.rotation*Math.PI/180,i=-t/2*Math.cos(n),r=-t/2*Math.sin(n);queueMicrotask(()=>{e.set({width:o,x:e.a.x+i,y:e.a.y+r})})}t.destroy()},[G,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useEffect(()=>()=>{st.current&&st.current()},[]),t.useEffect(()=>{_&&!H&&J&&""===O(e.text)&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[J,e.placeholder,e.removable,e.text,H,_]);let ht=0;"middle"===e.verticalAlign&&(ht=(e.height-rt)/2),"bottom"===e.verticalAlign&&(ht=e.height-rt);const gt=u({fontLoaded:G,fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:e.lineHeight}),mt=C(),pt=m(e.a.width,rt,e.curvePower,e.fontSize),xt=t.useRef(null),wt=t.useRef(null),yt=U&&e.strokeWidth>0&&!e.curveEnabled;return t.createElement(t.Fragment,null,t.createElement(r,{x:e.a.x,y:e.a.y,offsetX:e.backgroundPadding*(e.fontSize*gt*.5),offsetY:e.backgroundPadding*(e.fontSize*gt*.5),rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*e.a.opacity,fill:e.backgroundColor,width:e.a.width+e.backgroundPadding*(e.fontSize*gt),height:e.a.height+e.backgroundPadding*(e.fontSize*gt),cornerRadius:e.backgroundCornerRadius*(e.fontSize*gt*.5)}),t.createElement(i,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,data:pt,stroke:"red",strokeWidth:1,visible:!1}),t.createElement(r,{ref:b,name:"element",x:e.a.x,y:e.a.y,listening:e.selectable,rotation:e.a.rotation,width:e.a.width,height:e.a.height,visible:!ut,draggable:mt?e.draggable&&H:e.draggable,preventDefault:!mt||H,opacity:U?0:e.a.opacity,hideInExport:!e.showInExport,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},id:e.id,onDblClick:t=>{e.contentEditable&&(wt.current={x:t.evt.clientX,y:t.evt.clientY},e.toggleEditMode(!0))},onDblTap:t=>{var o;if(e.contentEditable){const n=null===(o=t.evt.changedTouches)||void 0===o?void 0:o[0];wt.current=n?{x:n.clientX,y:n.clientY}:null,e.toggleEditMode(!0)}},onTransformStart:t=>{q(!0),B.current=e.height},onTransform:t=>{var o;const n=t.target,i=(null===(o=n.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor(),r="middle-left"===i||"middle-right"===i,a="top-center"===i||"bottom-center"===i,l=n.scaleX();if(r){const t=n.scaleX(),o=n.width()*t,i=e.fontSize;let r=o;o<i&&(r=i,xt.current&&n.position(xt.current)),n.width(r),n.scaleX(1),n.scaleY(1);const a=P(Object.assign(Object.assign({},e.toJSON()),{width:r}),{fontFamily:K,color:Z}),l=w(a).height,s=d.textVerticalResizeEnabled?Math.max(l,B.current):l;n.height(s),e.set({width:n.width(),height:s,x:n.x(),y:n.y()})}else if(a){const o="resize"===d.textOverflow,i="number"==typeof e.lineHeight?e.lineHeight:1;let r=o?rt:i*e.fontSize;const a=Math.max(r,t.target.height()*t.target.scaleY());n.scaleY(1),e.set({x:n.x(),y:n.y(),height:a,rotation:n.rotation()})}else{n.scaleX(1),n.scaleY(1),e.set({fontSize:e.fontSize*l,letterSpacing:e.letterSpacing,width:n.width()*l,x:n.x(),y:n.y(),rotation:n.rotation(),height:n.height()*l})}xt.current=t.target.position()},onTransformEnd:t=>{q(!1),W(!0);const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.fontSize*o,width:t.target.width()*o,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o})}}),t.createElement(n,{ref:b,image:F,x:e.a.x,y:e.a.y,offsetX:N,offsetY:N-ht,listening:!1,rotation:e.a.rotation,width:e.a.width+2*N,height:(e.a.width+2*N)*((null!==(c=null==F?void 0:F.height)&&void 0!==c?c:0)/((null==F?void 0:F.width)||1)||1),visible:!ut&&!U,opacity:e.a.opacity,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled||Y||ut}),(ut||yt)&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-ht},t.createElement(S,{divProps:{style:{pointerEvents:"none"}}},t.createElement($,{dangerouslySetInnerHTML:{__html:tt},style:{pointerEvents:"none",opacity:e.a.opacity,textShadow:e.shadowEnabled?`${e.shadowOffsetX}px ${e.shadowOffsetY}px ${e.shadowBlur}px ${A(e.shadowColor,null!==(p=e.shadowOpacity)&&void 0!==p?p:1)}`:void 0}}))),U&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-ht},t.createElement(S,null,t.createElement(L,{html:et,element:e,onChange:t=>{const o=T({oldText:O(e.text),newText:O(t),element:e});e.set({text:t,fontSize:o})},onBlur:t=>{e.toggleEditMode(!1),dt(!0)},clickCoords:wt.current}))))});export function setCursorFromCoords(t,e){if(!t||!e){return}const{x:o,y:n}=e;try{let e=null;if(document.caretRangeFromPoint){e=document.caretRangeFromPoint(o,n)}else if(document.caretPositionFromPoint){const t=document.caretPositionFromPoint(o,n);t&&(e=document.createRange(),e.setStart(t.offsetNode,t.offset))}if(e){const o=a.find(e.startContainer,!0);if(o){const n=o.offset(t.scroll)+e.startOffset;return void t.setSelection(n,0,"api")}}}catch(i){}t.setSelection(0,0,"api")}
16
+ /* Apply gradient fill to all text-bearing elements when --polotno-gradient is set */
17
+ &[style*="--polotno-gradient"] .ql-editor,
18
+ &[style*="--polotno-gradient"] .ql-editor p,
19
+ &[style*="--polotno-gradient"] .ql-editor li,
20
+ &[style*="--polotno-gradient"] .ql-editor li::before {
21
+ background-image: var(--polotno-gradient);
22
+ background-size: 100% 100%;
23
+ background-repeat: repeat;
24
+ -webkit-background-clip: text;
25
+ -moz-background-clip: text;
26
+ background-clip: text;
27
+ -webkit-text-fill-color: transparent;
28
+ color: transparent;
29
+ }
30
+ `;let $=["bold","color","font","italic","size","strike","underline","indent","list","direction"];export const setQuillFormats=t=>{$=t};export const createQuill=t=>new a(t,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:$});export const setQuillContent=(t,e)=>{var o=t.clipboard.convert("<div class='ql-editor' style='outline: none;'>"+e+"<p><br></p></div>");t.setContents(o),t.history.clear()};const L=({html:e,onBlur:o,onChange:n,element:i,clickCoords:r})=>{var l;const d=t.useRef(null);t.useEffect(()=>{if(!d.current){return}const t=(l=d.current,new a(l,{toolbar:!1,keyboard:!1,clipboard:{matchVisual:!1},formats:$}));var l;s.runInAction(()=>{quillRef.editor.instance=t}),window.__polotnoQuill=t,t.on("text-change",()=>{t.getSelection()&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())}),setTimeout(()=>{var e,o;const r=null===(e=d.current)||void 0===e?void 0:e.childNodes[0];if(!r){return}const a=r.innerHTML;n(P(a));const l=t.getContents(),s=i.fill;let c=null,f=!0;for(const t of l.ops){if("string"!=typeof t.insert||"\n"===t.insert){continue}const e=(null===(o=t.attributes)||void 0===o?void 0:o.color)||s;if(null===c){c=e}else if(e!==c){f=!1;break}}f&&c&&i.set({fill:c})},10)}),setQuillContent(t,e),r?setCursorFromCoords(t,r):t.setSelection(0,0,"api"),t.on("selection-change",(e,o,n)=>{e&&s.runInAction(()=>{quillRef.currentFormat=t.getFormat(t.getSelection())})}),d.current.childNodes[0].addEventListener("blur",t=>{const e=t.relatedTarget;if(null==e?void 0:e.classList.contains("ql-clipboard")){return}const n=function(t){return!!t&&!!t.closest(".sketch-picker")}(e);n||o()});const c=d.current.childNodes[0],f=e=>{var o,n;const i=t.getSelection();if(!i||0===i.length){return}const r=t.getText(i.index,i.length).replace(/\n$/,""),a=window.getSelection();let l="";if(a&&a.rangeCount>0){const t=a.getRangeAt(0),e=document.createElement("div");e.appendChild(t.cloneContents()),l=e.innerHTML}if(null===(o=e.clipboardData)||void 0===o||o.setData("text/plain",r),l){const t='<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>\x3c!--StartFragment--\x3e<div style="white-space: pre-wrap; word-wrap: break-word;">'+l+"</div>\x3c!--EndFragment--\x3e</body></html>";null===(n=e.clipboardData)||void 0===n||n.setData("text/html",t)}e.preventDefault()},u=e=>{f(e);const o=t.getSelection();o&&o.length>0&&t.deleteText(o.index,o.length)};return c.addEventListener("copy",f),c.addEventListener("cut",u),()=>{c.removeEventListener("copy",f),c.removeEventListener("cut",u),s.runInAction(()=>{quillRef.editor.instance=null,quillRef.currentFormat={}}),delete window.__polotnoQuill}},[]),t.useEffect(()=>c(()=>i.text,()=>{var t,o;const n=quillRef.editor.instance;if(!n){return}const r=n.getSelection(),a=null===(o=null===(t=d.current)||void 0===t?void 0:t.childNodes)||void 0===o?void 0:o[0];P((null==a?void 0:a.innerHTML)||"")===i.text||(setQuillContent(n,e),r&&(n.setSelection(r.index,r.length),s.runInAction(()=>{quillRef.currentFormat=n.getFormat(n.getSelection())})))},{fireImmediately:!0}),[]),t.useEffect(()=>{window.addEventListener("blur",o);const t=t=>{var e;(null===(e=d.current)||void 0===e?void 0:e.contains(t.target))||o()};return window.addEventListener("touchstart",t),()=>{window.removeEventListener("blur",o),window.removeEventListener("touchstart",t)}},[]);const f={color:i.fill};i.fill.indexOf("gradient")>=0&&(f["--polotno-gradient"]=i.fill,f.color="transparent");const u=q(i);return t.createElement(Y,{ref:d,style:Object.assign(Object.assign({},f),{fontSize:i.fontSize,fontWeight:i.fontWeight,textTransform:i.textTransform,width:i.a.width,fontFamily:'"'+i.fontFamily+'"',lineHeight:i.lineHeight,letterSpacing:i.letterSpacing*i.fontSize+"px",textAlign:i.align,opacity:Math.max(i.a.opacity,.2),textShadow:i.shadowEnabled?`${i.shadowOffsetX}px ${i.shadowOffsetY}px ${i.shadowBlur}px ${A(i.shadowColor,null!==(l=i.shadowOpacity)&&void 0!==l?l:1)}`:void 0,caretColor:u}),dir:p(R(i.text))})};function X(t){const e=document.createElement("canvas"),o=e.getContext("2d");return null==o||o.drawImage(t,0,0,e.width,e.height),function(t){return!function(t){const e=t.getContext("2d").getImageData(0,0,t.width,t.height).data;for(let o=0;o<e.length;o+=4){if(0!==e[o+3]){return!0}}return!1}(t)}(e)}const I=/^((?!chrome|android).)*safari/i.test(navigator.userAgent),D=navigator.userAgent.includes("Firefox");export const HTMLElement=e(({element:e,store:a})=>{var c,p;const E=t.useRef(null),[F,q]=t.useState(),[P,$]=t.useState(!1),[W,H]=t.useState(!1),B=t.useRef(e.height),_=a.selectedShapes.indexOf(e)>=0&&e.selectable,N=g(_),Q=e.fontSize/3,{textVerticalResizeEnabled:J}=d,V=d.autoDeleteEmptyText,G=g(e.fontFamily),[U]=h(a,e.fontFamily,e.fontStyle,e.fontWeight,e.text||e.placeholder),K=e._editModeEnabled;S(E);const Z=U?e.fontFamily:G!==e.fontFamily?G:"Arial",tt=w(e).fill,et=x(e,{fontFamily:Z,color:tt}),ot=x(e,{fontFamily:Z,color:tt,forEditor:!0}),nt=t.useRef([]),[,it]=t.useReducer(t=>t+1,0);t.useEffect(()=>{const t=nt.current;t.length>0&&(nt.current=[],t.forEach(t=>t()))});let{width:rt,height:at}=function(e,o,n){return t.useMemo(()=>y(e),[e,o.width,n])}(et,e,U);t.useEffect(()=>{if(!U){return}const t=(t,o,n,i)=>{const r=O(`text ${e.id}`),l=()=>{a.history.ignore(t,o,n).then(()=>{nt.current.push(r),it()})};i?queueMicrotask(l):l()};if(!e.height){return void t(()=>{e.height||e.set({height:at})},void 0,void 0,!0)}const{textOverflow:o}=d;if("change-font-size"!==o||P){"resize"===o&&(J&&e.height<at&&!P&&t(()=>{e.set({height:at})},!1,!0),J||e.height===at||P||t(()=>{e.set({height:at})},!1,!0))}else{const o=(t=>{let e=t.fontSize;for(let o=1;o<50;o++){const o=x(Object.assign(Object.assign({},t.toJSON()),{fontSize:e}),{fontFamily:t.fontFamily}),{height:n}=y(o);if(!(t.height&&n>t.height||!d.textSplitAllowed&&!t.curveEnabled&&b({html:o}))){break}e-=.5}return e})(e);o!==e.fontSize?t(()=>{e.set({fontSize:o})},!1,!0):e.height!==at&&(J&&e.height<at?t(()=>{e.set({height:at})},!1,!0):J||t(()=>{e.set({height:at})},!1,!0))}});const lt=t.useMemo(()=>{const t={lastArgs:null,lastResult:null};return async function(e){return t.lastArgs&&t.lastResult&&(o=t.lastArgs,n=e,JSON.stringify(o)===JSON.stringify(n))||(t.lastResult=await v(e),t.lastArgs=Object.assign({},e)),t.lastResult;var o,n}},[]),st=t.useRef(0),ct=t.useRef(null);t.useEffect(()=>{P||K||(async()=>{st.current++;const t=st.current;let o=O(`text ${e.id} ${t}`);ct.current&&ct.current(),ct.current=o,H(!0);let n=null;const i=I?5:1;for(let l=0;l<i;l++){const o=l>0?lt:v;try{if(n=await o({skipCache:l>0,html:et,width:e.width||1,height:e.height||at||1,fontFamily:Z,padding:Q,pixelRatio:a._elementsPixelRatio,font:a.fonts.find(t=>t.fontFamily===Z)||C.globalFonts.find(t=>t.fontFamily===Z)}),t!==st.current){return}if((I||D)&&n&&X(n)){await new Promise(t=>setTimeout(t,50*(l+1)));continue}break}catch(r){console.error(r),z(`Error rendering rich text with id ${e.id}`);break}}n?q(n):o?(o(),o=null):console.error("Finish function is called twice!"),H(!1)})()},[et,P,at,K,Z,e.height,a._elementsPixelRatio,U]);const[dt,ft]=M(W,300),[ut]=M(P,300,!0),ht=ut||dt;t.useEffect(()=>{var t;if(!ht){return s.autorun(()=>{const t=E.current;f(t,e)})}null===(t=E.current)||void 0===t||t.clearCache()},[F,ht,e.shadowColor,e.shadowOffsetX,e.shadowOffsetY,e.shadowOpacity]),t.useEffect(()=>{F&&!W&&ct.current&&(ct.current(),ct.current=null)},[F,W]),t.useLayoutEffect(()=>{if(!U){return}if(!e.curveEnabled){return}const t=new l.TextPath({data:m(e.a.width,e.a.height,e.curvePower,e.a.fontSize),text:R(e.text),letterSpacing:e.letterSpacing*e.a.fontSize,fontSize:e.a.fontSize,fontFamily:e.fontFamily,fontWeight:e.fontWeight,fontStyle:e.fontStyle,align:"center",textBaseline:"middle",fill:e.fill}),o=t.getSelfRect().width;if(o){const t=o-e.a.width,n=e.a.rotation*Math.PI/180,i=-t/2*Math.cos(n),r=-t/2*Math.sin(n);queueMicrotask(()=>{e.set({width:o,x:e.a.x+i,y:e.a.y+r})})}t.destroy()},[U,e.curveEnabled,e.curvePower,e.text,e.fontSize,e.fontFamily,e.fontWeight,e.fontStyle,e.letterSpacing]),t.useEffect(()=>()=>{ct.current&&ct.current()},[]),t.useEffect(()=>{N&&!_&&V&&""===R(e.text)&&e.removable&&!e.placeholder&&a.deleteElements([e.id])},[V,e.placeholder,e.removable,e.text,_,N]);let gt=0;"middle"===e.verticalAlign&&(gt=(e.height-at)/2),"bottom"===e.verticalAlign&&(gt=e.height-at);const mt=u({fontLoaded:U,fontFamily:e.fontFamily,fontSize:e.fontSize,lineHeight:e.lineHeight}),pt=j(),xt=m(e.a.width,at,e.curvePower,e.fontSize),wt=t.useRef(null),yt=t.useRef(null),vt=K&&e.strokeWidth>0&&!e.curveEnabled;return t.createElement(t.Fragment,null,t.createElement(r,{x:e.a.x,y:e.a.y,offsetX:e.backgroundPadding*(e.fontSize*mt*.5),offsetY:e.backgroundPadding*(e.fontSize*mt*.5),rotation:e.a.rotation,hideInExport:!e.showInExport,listening:!1,visible:e.backgroundEnabled,opacity:e.backgroundOpacity*e.a.opacity,fill:e.backgroundColor,width:e.a.width+e.backgroundPadding*(e.fontSize*mt),height:e.a.height+e.backgroundPadding*(e.fontSize*mt),cornerRadius:e.backgroundCornerRadius*(e.fontSize*mt*.5)}),t.createElement(i,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,data:xt,stroke:"red",strokeWidth:1,visible:!1}),t.createElement(r,{ref:E,name:"element",x:e.a.x,y:e.a.y,listening:e.selectable,rotation:e.a.rotation,width:e.a.width,height:e.a.height,visible:!ht,draggable:pt?e.draggable&&_:e.draggable,preventDefault:!pt||_,opacity:K?0:e.a.opacity,hideInExport:!e.showInExport,onDragMove:t=>{e.set({x:t.target.x(),y:t.target.y()})},onDragEnd:t=>{e.set({x:t.target.x(),y:t.target.y()})},id:e.id,onDblClick:t=>{e.contentEditable&&(yt.current={x:t.evt.clientX,y:t.evt.clientY},e.toggleEditMode(!0))},onDblTap:t=>{var o;if(e.contentEditable){const n=null===(o=t.evt.changedTouches)||void 0===o?void 0:o[0];yt.current=n?{x:n.clientX,y:n.clientY}:null,e.toggleEditMode(!0)}},onTransformStart:t=>{$(!0),B.current=e.height},onTransform:t=>{var o;const n=t.target,i=(null===(o=n.getStage())||void 0===o?void 0:o.findOne("Transformer")).getActiveAnchor(),r="middle-left"===i||"middle-right"===i,a="top-center"===i||"bottom-center"===i,l=n.scaleX();if(r){const t=n.scaleX(),o=n.width()*t,i=e.fontSize;let r=o;o<i&&(r=i,wt.current&&n.position(wt.current)),n.width(r),n.scaleX(1),n.scaleY(1);const a=x(Object.assign(Object.assign({},e.toJSON()),{width:r}),{fontFamily:Z,color:tt}),l=y(a).height,s=d.textVerticalResizeEnabled?Math.max(l,B.current):l;n.height(s),e.set({width:n.width(),height:s,x:n.x(),y:n.y()})}else if(a){const o="resize"===d.textOverflow,i="number"==typeof e.lineHeight?e.lineHeight:1;let r=o?at:i*e.fontSize;const a=Math.max(r,t.target.height()*t.target.scaleY());n.scaleY(1),e.set({x:n.x(),y:n.y(),height:a,rotation:n.rotation()})}else{n.scaleX(1),n.scaleY(1),e.set({fontSize:e.fontSize*l,letterSpacing:e.letterSpacing,width:n.width()*l,x:n.x(),y:n.y(),rotation:n.rotation(),height:n.height()*l})}wt.current=t.target.position()},onTransformEnd:t=>{$(!1),H(!0);const o=t.target.scaleX();t.target.scaleX(1),t.target.scaleY(1),e.set({fontSize:e.fontSize*o,width:t.target.width()*o,x:t.target.x(),y:t.target.y(),rotation:t.target.rotation(),shadowBlur:e.shadowBlur*o,shadowOffsetX:e.shadowOffsetX*o,shadowOffsetY:e.shadowOffsetY*o,strokeWidth:e.strokeWidth*o})}}),t.createElement(n,{ref:E,image:F,x:e.a.x,y:e.a.y,offsetX:Q,offsetY:Q-gt,listening:!1,rotation:e.a.rotation,width:e.a.width+2*Q,height:(e.a.width+2*Q)*((null!==(c=null==F?void 0:F.height)&&void 0!==c?c:0)/((null==F?void 0:F.width)||1)||1),visible:!ht&&!K,opacity:e.a.opacity,shadowEnabled:e.shadowEnabled,shadowBlur:e.shadowBlur,shadowOffsetX:e.shadowOffsetX,shadowOffsetY:e.shadowOffsetY,shadowColor:e.shadowColor,shadowOpacity:e.shadowOpacity,hideInExport:!e.showInExport,editModeEnabled:e._editModeEnabled||P||ht}),(ht||vt)&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-gt},t.createElement(k,{divProps:{style:{pointerEvents:"none"}}},t.createElement(Y,{dangerouslySetInnerHTML:{__html:et},style:{pointerEvents:"none",opacity:e.a.opacity,textShadow:e.shadowEnabled?`${e.shadowOffsetX}px ${e.shadowOffsetY}px ${e.shadowBlur}px ${A(e.shadowColor,null!==(p=e.shadowOpacity)&&void 0!==p?p:1)}`:void 0}}))),K&&t.createElement(o,{x:e.a.x,y:e.a.y,rotation:e.a.rotation,offsetY:-gt},t.createElement(k,null,t.createElement(L,{html:ot,element:e,onChange:t=>{const o=T({oldText:R(e.text),newText:R(t),element:e});e.set({text:t,fontSize:o})},onBlur:t=>{e.toggleEditMode(!1),ft(!0)},clickCoords:yt.current}))))});export function setCursorFromCoords(t,e){if(!t||!e){return}const{x:o,y:n}=e;try{let e=null;if(document.caretRangeFromPoint){e=document.caretRangeFromPoint(o,n)}else if(document.caretPositionFromPoint){const t=document.caretPositionFromPoint(o,n);t&&(e=document.createRange(),e.setStart(t.offsetNode,t.offset))}if(e){const o=a.find(e.startContainer,!0);if(o){const n=o.offset(t.scroll)+e.startOffset;return void t.setSelection(n,0,"api")}}}catch(i){}t.setSelection(0,0,"api")}
package/canvas/rules.js CHANGED
@@ -14,6 +14,7 @@ import e from"react";import{getTotalClientRect as o}from"../utils/math.js";impor
14
14
  border-bottom: 1px solid grey;
15
15
  background-color: #e8e8e8;
16
16
  overflow: hidden;
17
+ box-sizing: border-box;
17
18
  `,s=l("div",e.forwardRef)`
18
19
  left: 0;
19
20
  width: 14px;
@@ -24,6 +25,7 @@ import e from"react";import{getTotalClientRect as o}from"../utils/math.js";impor
24
25
  border-right: 1px solid grey;
25
26
  background-color: #e8e8e8;
26
27
  overflow: hidden;
28
+ box-sizing: border-box;
27
29
  `,n=l("div",e.forwardRef)`
28
30
  position: absolute;
29
31
  border-left: 1px solid grey;
@@ -36,4 +38,4 @@ import e from"react";import{getTotalClientRect as o}from"../utils/math.js";impor
36
38
  transform: rotate(90deg);
37
39
  transform-origin: left top;
38
40
  overflow: hidden;
39
- `,p=[.1,.2,.5,1,2,5,10,20,25,50,100,200,500,1e3,2e3,5e3,1e4];export const TopRules=r(({store:r,width:l,height:c,pageSizes:u,layout:h="vertical",renderOnlyActivePage:x,rulerBackgroundColor:g,rulerTextColor:m,rulerBorderColor:f,rulerBorderSize:y,rulerTickColor:b,rulerTickSize:k})=>{const v=e.useRef(null);if(!r.activePage){return null}const w="horizontal"===h,$=r.activePage,E=(r.bleedVisible&&$.bleed,$.computedWidth*r.scale),N=$.computedHeight*r.scale,C=(l-E)/2,R=(c-N)/2,S=(z=e=>t({unitVal:e,dpi:r.dpi,unit:r.unit})*r.scale,p.find(e=>z(e)>30)||1e4);var z;const B=t({unitVal:S,dpi:r.dpi,unit:r.unit})*r.scale,F=Math.round(E/B)+1,M=Math.round(N/B)+1,A=o(r.selectedShapes),P=g||"#e8e8e8",T=m||"grey",L=f||"grey",j=null!=y?y:1,V=b||"grey",D=null!=k?k:1;return e.createElement(i,{ref:v,className:"polotno-rulers",style:{display:"flex",flexDirection:"column"}},w?e.createElement(e.Fragment,null,e.createElement("div",{style:{display:"flex",flexDirection:"row",position:"sticky",top:0,zIndex:1}},e.createElement("div",{className:"polotno-ruler-corner",style:{width:"14px",height:"14px",flexShrink:0,backgroundColor:P,borderRight:`${j}px solid ${L}`,borderBottom:`${j}px solid ${L}`,position:"sticky",left:0,zIndex:2}}),(x?[r.activePage]:r.pages).map((o,t)=>{var i;if(!o){return null}const s=u?u[t]:l,d=(s-o.computedWidth*r.scale)/2;return e.createElement(a,{key:o.id,style:{width:s+"px",flexShrink:0,position:"relative",backgroundColor:P,color:T,borderBottom:`${j}px solid ${L}`},className:"polotno-x-ruler"},[...Array(F)].map((o,t)=>e.createElement(n,{key:t,className:"polotno-ruler-tick",style:{left:d+t*B+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||S>=1?Math.round(S*t):(S*t).toFixed(1))),(null===(i=r.selectedShapes[0])||void 0===i?void 0:i.page)===o&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",left:d+A.x*r.scale+"px",height:"14px",width:A.width*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))})),e.createElement(s,{style:{height:c+"px",position:"sticky",left:0,marginTop:"-14px",backgroundColor:P,color:T,borderRight:`${j}px solid ${L}`},className:"polotno-y-ruler"},[...Array(M)].map((o,t)=>e.createElement(d,{key:t,className:"polotno-ruler-tick",style:{top:R+t*B+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||S>=1?Math.round(S*t):(S*t).toFixed(1))),!!r.selectedShapes.length&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",top:R+A.y*r.scale+"px",width:"14px",height:A.height*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))):e.createElement(e.Fragment,null,e.createElement(a,{style:{width:l+"px",backgroundColor:P,color:T,borderBottom:`${j}px solid ${L}`},className:"polotno-x-ruler"},[...Array(F)].map((o,t)=>e.createElement(n,{key:t,className:"polotno-ruler-tick",style:{left:C+t*B+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||S>=1?Math.round(S*t):(S*t).toFixed(1))),!!r.selectedShapes.length&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",left:C+A.x*r.scale+"px",height:"14px",width:A.width*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}})),(x?[r.activePage]:r.pages).map((o,t)=>{var l;if(!o){return null}const i=u?u[t]:c,a=(i-o.computedHeight*r.scale)/2,n=0===t?14:0;return e.createElement(s,{key:o.id,style:{height:i-n+"px",backgroundColor:P,color:T,borderRight:`${j}px solid ${L}`},className:"polotno-y-ruler"},[...Array(M)].map((o,t)=>e.createElement(d,{key:t,className:"polotno-ruler-tick",style:{top:a+t*B-n+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||S>=1?Math.round(S*t):(S*t).toFixed(1))),(null===(l=r.selectedShapes[0])||void 0===l?void 0:l.page)===o&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",top:a+A.y*r.scale-n+"px",width:"14px",height:A.height*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))})))});
41
+ `,p=[.1,.2,.5,1,2,5,10,20,25,50,100,200,500,1e3,2e3,5e3,1e4];export const TopRules=r(({store:r,width:l,height:c,pageSizes:u,layout:x="vertical",renderOnlyActivePage:h,rulerBackgroundColor:g,rulerTextColor:m,rulerBorderColor:f,rulerBorderSize:b,rulerTickColor:y,rulerTickSize:k})=>{const v=e.useRef(null);if(!r.activePage){return null}const w="horizontal"===x,$=r.activePage,E=(r.bleedVisible&&$.bleed,$.computedWidth*r.scale),N=$.computedHeight*r.scale,C=(l-E)/2,z=(c-N)/2,R=(S=e=>t({unitVal:e,dpi:r.dpi,unit:r.unit})*r.scale,p.find(e=>S(e)>30)||1e4);var S;const B=t({unitVal:R,dpi:r.dpi,unit:r.unit})*r.scale,F=Math.round(E/B)+1,M=Math.round(N/B)+1,A=o(r.selectedShapes),P=g||"#e8e8e8",T=m||"grey",L=f||"grey",j=null!=b?b:1,V=y||"grey",D=null!=k?k:1;return e.createElement(i,{ref:v,className:"polotno-rulers",style:{display:"flex",flexDirection:"column"}},w?e.createElement(e.Fragment,null,e.createElement("div",{style:{display:"flex",flexDirection:"row",position:"sticky",top:0,zIndex:1}},e.createElement("div",{className:"polotno-ruler-corner",style:{width:"14px",height:"14px",flexShrink:0,marginRight:"-14px",boxSizing:"border-box",backgroundColor:P,borderRight:`${j}px solid ${L}`,borderBottom:`${j}px solid ${L}`,position:"sticky",left:0,zIndex:2}}),(h?[r.activePage]:r.pages).map((o,t)=>{var i;if(!o){return null}const s=u?u[t]:l,d=(s-o.computedWidth*r.scale)/2;return e.createElement(a,{key:o.id,style:{width:s+"px",flexShrink:0,position:"relative",backgroundColor:P,color:T,borderBottom:`${j}px solid ${L}`},className:"polotno-x-ruler"},[...Array(F)].map((o,t)=>e.createElement(n,{key:t,className:"polotno-ruler-tick",style:{left:d+t*B+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||R>=1?Math.round(R*t):(R*t).toFixed(1))),(null===(i=r.selectedShapes[0])||void 0===i?void 0:i.page)===o&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",left:d+A.x*r.scale+"px",height:"14px",width:A.width*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))})),e.createElement(s,{style:{height:c+"px",position:"sticky",left:0,marginTop:"-14px",backgroundColor:P,color:T,borderRight:`${j}px solid ${L}`},className:"polotno-y-ruler"},[...Array(M)].map((o,t)=>e.createElement(d,{key:t,className:"polotno-ruler-tick",style:{top:z+t*B+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||R>=1?Math.round(R*t):(R*t).toFixed(1))),!!r.selectedShapes.length&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",top:z+A.y*r.scale+"px",width:"14px",height:A.height*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))):e.createElement(e.Fragment,null,e.createElement(a,{style:{width:l+"px",backgroundColor:P,color:T,borderBottom:`${j}px solid ${L}`},className:"polotno-x-ruler"},[...Array(F)].map((o,t)=>e.createElement(n,{key:t,className:"polotno-ruler-tick",style:{left:C+t*B+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||R>=1?Math.round(R*t):(R*t).toFixed(1))),!!r.selectedShapes.length&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",left:C+A.x*r.scale+"px",height:"14px",width:A.width*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}})),(h?[r.activePage]:r.pages).map((o,t)=>{var l;if(!o){return null}const i=u?u[t]:c,a=(i-o.computedHeight*r.scale)/2,n=0===t?14:0;return e.createElement(s,{key:o.id,style:{height:i-n+"px",backgroundColor:P,color:T,borderRight:`${j}px solid ${L}`},className:"polotno-y-ruler"},[...Array(M)].map((o,t)=>e.createElement(d,{key:t,className:"polotno-ruler-tick",style:{top:a+t*B-n+"px",width:B+"px",borderLeft:`${D}px solid ${V}`}},"px"===r.unit||R>=1?Math.round(R*t):(R*t).toFixed(1))),(null===(l=r.selectedShapes[0])||void 0===l?void 0:l.page)===o&&e.createElement("div",{className:"polotno-ruler-selection",style:{position:"absolute",top:a+A.y*r.scale-n+"px",width:"14px",height:A.height*r.scale,backgroundColor:"rgba(0,0,0,0.15)"}}))})))});
@@ -34,6 +34,7 @@ export type WorkspaceProps = {
34
34
  altCloneEnabled?: boolean;
35
35
  visiblePagesOffset?: number;
36
36
  renderOnlyActivePage?: boolean;
37
+ scrollToPageThreshold?: number;
37
38
  tooltipSafeArea?: {
38
39
  top?: number;
39
40
  bottom?: number;
@@ -41,7 +42,7 @@ export type WorkspaceProps = {
41
42
  right?: number;
42
43
  };
43
44
  };
44
- export declare const WorkspaceCanvas: (({ store, layout, pageControlsEnabled, backgroundColor, transparencyBackgroundColor, pageBorderColor, activePageBorderColor, bleedColor, snapGuideStroke, snapGuideStrokeWidth, snapGuideDash, selectionRectFill, selectionRectStroke, selectionRectStrokeWidth, transformLabelFill, transformLabelTextFill, distanceGuideStroke, distanceLabelFill, distanceLabelTextFill, rulerBackgroundColor, rulerTextColor, rulerBorderColor, rulerBorderSize, rulerTickColor, rulerTickSize, components, onKeyDown, paddingX, paddingY, pageGap, altCloneEnabled, visiblePagesOffset, renderOnlyActivePage, tooltipSafeArea, }: WorkspaceProps) => React.JSX.Element) & {
45
+ export declare const WorkspaceCanvas: (({ store, layout, pageControlsEnabled, backgroundColor, transparencyBackgroundColor, pageBorderColor, activePageBorderColor, bleedColor, snapGuideStroke, snapGuideStrokeWidth, snapGuideDash, selectionRectFill, selectionRectStroke, selectionRectStrokeWidth, transformLabelFill, transformLabelTextFill, distanceGuideStroke, distanceLabelFill, distanceLabelTextFill, rulerBackgroundColor, rulerTextColor, rulerBorderColor, rulerBorderSize, rulerTickColor, rulerTickSize, components, onKeyDown, paddingX, paddingY, pageGap, altCloneEnabled, visiblePagesOffset, renderOnlyActivePage, scrollToPageThreshold, tooltipSafeArea, }: WorkspaceProps) => React.JSX.Element) & {
45
46
  displayName: string;
46
47
  };
47
48
  export default WorkspaceCanvas;
@@ -1 +1 @@
1
- import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as n}from"./rules.js";import{AudioElement as o}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";const a=(e,t,r)=>Math.max(t,Math.min(r,e)),s=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),c=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),u=({width:t,height:r,xPadding:n,yPadding:o,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:n+"px",paddingRight:n+"px",paddingTop:o+"px",paddingBottom:o+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})),d=[4,6];export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:h,backgroundColor:g,transparencyBackgroundColor:p,pageBorderColor:f,activePageBorderColor:m,bleedColor:v,snapGuideStroke:b,snapGuideStrokeWidth:x,snapGuideDash:k,selectionRectFill:w,selectionRectStroke:E,selectionRectStrokeWidth:T,transformLabelFill:y,transformLabelTextFill:L,distanceGuideStroke:M,distanceLabelFill:C,distanceLabelTextFill:S,rulerBackgroundColor:P,rulerTextColor:R,rulerBorderColor:F,rulerBorderSize:W,rulerTickColor:B,rulerTickSize:z,components:O,onKeyDown:H,paddingX:N,paddingY:j,pageGap:G,altCloneEnabled:_=!0,visiblePagesOffset:Y,renderOnlyActivePage:D,tooltipSafeArea:X})=>{var A;const I="horizontal"===i,K=null!=N?N:20,q=null!=j?j:55,[V,J]=e.useState({width:100,height:100}),Q=e.useRef(V),U=e.useRef(null),Z=e.useRef(null),$=e.useRef(0),ee=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,te=Math.max(...t.pages.map(e=>e.computedWidth)),re=Math.max(...t.pages.map(e=>e.computedHeight)),ne=(null===(A=t.activePage)||void 0===A?void 0:A.computedHeight)||0,oe=te+2*ee,le=(D?ne:re)+2*ee,ie=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===U.current){return}const r=U.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(U.current));const n=Z.current.clientWidth||r.width,o={width:n,height:r.height};(Q.current.width!==o.width||Q.current.height!==o.height)&&(J(o),Q.current=o);const l=(n-2*K)/oe,i=t.pages.length>1?3.1:2,a=(r.height-q*i)/le,s=t.pages.length>1?3.1:2,c=(n-K*s)/oe,u=(r.height-2*q)/le,d=t.pages.length?Math.max(Math.min(I?c:l,I?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{ie({skipTimeout:!0})},[]),e.useEffect(()=>{ie()},[oe,le,j,N]),e.useLayoutEffect(()=>{ie({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=U.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{ie({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{ie({skipTimeout:!0})},100);return()=>clearInterval(e)}},[oe,le]);const ae=D?1:t.pages.length;let se,ce;if(I){const e=oe*t.scale*ae;se=Math.max(K,(V.width-e)/ae/2),ce=Math.max(q,(V.height-le*t.scale)/2)}else{se=Math.max(K,(V.width-oe*t.scale)/2);const e=le*t.scale*ae;ce=Math.max(q,(V.height-e)/ae/2)}Number.isNaN(se)&&(se=K),Number.isNaN(ce)&&(ce=q),e.useEffect(()=>{const e=e=>{(H||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const r=Math.max(5,t.scaleToFit);let n=Math.min(.1,t.scaleToFit);I&&oe>0&&Number.isFinite(oe)&&(n=Math.max(n,300/oe)),n=Math.max(n,.01);const o=.03,l=a(e.deltaY<0?t.scale*(1+o):t.scale/(1+o),n,r);return void t.setScale(l)}},r=Z.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[I,oe,t]),e.useEffect(()=>{const e=Z.current;if(!e){return}const r=e=>{2===e.touches.length&&($.current=s(e.touches[0],e.touches[1]))},n=r=>{if(2===r.touches.length&&$.current>0){r.preventDefault();const n=s(r.touches[0],r.touches[1]),o=n/$.current,l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);I&&oe>0&&Number.isFinite(oe)&&(i=Math.max(i,300/oe)),i=Math.max(i,.01);const c=t.scale,u=a(c*o,i,l),d=u/c,h=e.getBoundingClientRect(),g=(r.touches[0].clientX+r.touches[1].clientX)/2-h.left,p=(r.touches[0].clientY+r.touches[1].clientY)/2-h.top,f=e.scrollLeft+g,m=e.scrollTop+p;me.current=!0,t.setScale(u),e.scrollLeft=f*d-g,e.scrollTop=m*d-p,$.current=n}},o=()=>{$.current=0};return e.addEventListener("touchstart",r,{passive:!0}),e.addEventListener("touchmove",n,{passive:!1}),e.addEventListener("touchend",o,{passive:!0}),()=>{e.removeEventListener("touchstart",r),e.removeEventListener("touchmove",n),e.removeEventListener("touchend",o)}},[I,oe,t]);const ue=void 0!==G,de=t.pages.map(e=>{if(I){const r=(e.computedWidth+2*ee)*t.scale;return ue?r+G:r+2*se}{const r=(e.computedHeight+2*ee)*t.scale;return ue?r+G:r+2*ce}}),he=[];let ge=ue?I?se:ce:0;for(let e=0;e<de.length;e++){he.push(ge),ge+=de[e]}const pe=de.reduce((e,t)=>e+t,0),fe=ue?pe+(I?2*se:2*ce):pe,me=e.useRef(!1),[,ve]=e.useReducer(e=>e+1,0);((t,r,n,o,l)=>{const i=e.useRef(0),s=e.useRef(0),c=e.useRef(null),u=e.useRef(null),d=e.useRef(!1),h=e.useRef(o.pages.length);d.current=h.current!==o.pages.length,h.current=o.pages.length,e.useEffect(()=>{const e=t.current,r=()=>{i.current=e.scrollLeft,s.current=e.scrollTop,c.current=e.scrollWidth,u.current=e.scrollHeight};return e.addEventListener("scroll",r),r(),()=>{e.removeEventListener("scroll",r)}},[]),e.useLayoutEffect(()=>{if(!t.current){return}if(d.current){return}const e=t.current,r=c.current,n=u.current;if(null===r||null===n){return c.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,void(s.current=e.scrollTop)}l.current=!0;const o=e.offsetWidth,h=e.offsetHeight,g=(i.current+o/2)/r,p=(s.current+h/2)/n,f=Math.max(0,e.scrollWidth-o),m=Math.max(0,e.scrollHeight-h);e.scrollLeft=a(g*e.scrollWidth-o/2,0,f),e.scrollTop=a(p*e.scrollHeight-h/2,0,m),c.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,s.current=e.scrollTop},[n,r])})(Z,fe,t.scale,t,me);const{handleScroll:be}=((t,r,n,o,l,i,a,s,c)=>{const u=e.useRef(!1),d=e.useRef(null),h=e.useRef(!1),g="horizontal"===s;e.useEffect(()=>{const e=t.current,r=()=>{i.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const p=o.pages.indexOf(o.activePage);return e.useLayoutEffect(()=>{if(a){return}if(!o.activePage){return}if(!t.current){return}if(u.current){return}const e=t.current,l=o.pages.indexOf(o.activePage),i=r[l]||0,s=g?e.scrollLeft:e.scrollTop,d=g?e.scrollWidth-e.clientWidth:e.scrollHeight-e.clientHeight,p=Math.min(i,Math.max(0,d)),f=n[l]||n[0]||0;let m=()=>{};return(Math.abs(p-s)>.5*f||h.current)&&(h.current=!0,m=(({element:e,scrollTop:t,scrollLeft:r,duration:n=300,onFinish:o=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===n){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,n);l?e.scrollTop=t:e.scrollLeft=t,c<n?setTimeout(d,20):o()},h=(e,t,r,n)=>(e/=n/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},g?{scrollLeft:p}:{scrollTop:p}),{onFinish:()=>{h.current=!1,null==c||c()},duration:o.isPlaying?0:300}))),m},[o.activePage,p,o.isPlaying,a,s,r,n]),{handleScroll:e=>{if(a){return}if(h.current){return}u.current=!0,clearTimeout(d.current),d.current=setTimeout(()=>{u.current=!1},300);const t=(g?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(g?l.width:l.height)/3;let n=0;for(let o=r.length-1;o>=0;o--){if(t>=r[o]){n=o;break}}const i=o.pages[n];i&&o.activePage!==i&&i.select()}}})(Z,he,de,t,V,me,D,i,ve),xe=V.width>=oe*t.scale+2*se,ke=V.height>=le*t.scale+2*ce,we=g||"rgba(232, 232, 232, 0.9)",Ee=(null==O?void 0:O.NoPages)||c,Te=I?V.width:V.height,ye=Z.current?I?Z.current.scrollLeft:Z.current.scrollTop:0,Le=e=>{for(let t=he.length-1;t>=0;t--){if(e>=he[t]){return t}}return 0},Me=Math.max(0,Le(ye)),Ce=Math.min(t.pages.length-1,Le(ye+Te)),Se=null!=Y?Y:1,Pe=Math.max(0,Me-Se),Re=Math.min(t.pages.length-1,Ce+Se);return e.createElement("div",{ref:U,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:we,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:Z,onScroll:be,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:I?"row":"column",overflow:"auto",overflowX:I?"auto":xe?"hidden":"auto",overflowY:I&&ke?"hidden":"auto"},ue&&{paddingTop:I?0:ce,paddingBottom:I?0:ce,paddingLeft:I?se:0,paddingRight:I?se:0,boxSizing:"border-box"}),className:"polotno-workspace-inner"},t.pages.map((n,o)=>{const l=n===t.activePage;if(D&&!l&&!n._exportingOrRendering&&!n._forceMount){return null}const a=l||o>=Pe&&o<=Re||n._exportingOrRendering||n._forceMount,s=I?de[o]:oe*t.scale+2*se,c=I?le*t.scale+2*ce:de[o];if(!a){return e.createElement("div",{key:n.id,style:{flexShrink:0}},e.createElement(u,{width:s,height:c,backgroundColor:we,xPadding:se,yPadding:ce}))}const g=e.createElement(r,{key:n.id,page:n,xPadding:se,yPadding:ce,width:s,height:c,store:t,pageControlsEnabled:h,backColor:we,transparencyBackgroundColor:p,pageBorderColor:f||"lightgrey",activePageBorderColor:m||"rgb(0, 161, 255)",altCloneEnabled:_,bleedColor:v||"rgba(255, 0, 0, 0.1)",selectionRectFill:w,selectionRectStroke:E,selectionRectStrokeWidth:T,snapGuideStroke:b||"rgb(0, 161, 255)",snapGuideStrokeWidth:x||1,snapGuideDash:k||d,transformLabelFill:y,transformLabelTextFill:L,distanceGuideStroke:M||"rgb(0, 161, 255)",distanceLabelFill:C||"rgb(0, 161, 255)",distanceLabelTextFill:S||"white",components:O,viewportSize:V,layout:i,tooltipSafeArea:X});return(n._exportingOrRendering||n._forceMount)&&!l&&D?e.createElement("div",{style:{display:"none",flexShrink:0},key:n.id},g):g}),t.rulesVisible&&e.createElement(n,{store:t,xPadding:se,yPadding:ce,width:oe*t.scale+2*se,height:le*t.scale+2*ce,pageSizes:de,layout:i,renderOnlyActivePage:D,rulerBackgroundColor:P,rulerTextColor:R,rulerBorderColor:F,rulerBorderSize:W,rulerTickColor:B,rulerTickSize:z}),0===t.pages.length&&e.createElement(Ee,{store:t}),t.audios.map(r=>e.createElement(o,{key:r.id,audio:r,store:t}))))});export default WorkspaceCanvas;
1
+ import e from"react";import{observer as t}from"mobx-react-lite";import r from"./page.js";import{TopRules as o}from"./rules.js";import{AudioElement as n}from"./audio.js";import{handleHotkey as l}from"./hotkeys.js";import{t as i}from"../utils/l10n.js";const a=(e,t,r)=>Math.max(t,Math.min(r,e)),s=(e,t)=>Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2)),c=({store:t})=>e.createElement("div",{style:{position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",textAlign:"center"}},e.createElement("p",null,i("workspace.noPages")),e.createElement("button",{onClick:()=>{t.addPage()}},i("workspace.addPage"))),u=({width:t,height:r,xPadding:o,yPadding:n,backgroundColor:l})=>e.createElement("div",{style:{width:t+"px",height:r+"px",backgroundColor:l,paddingLeft:o+"px",paddingRight:o+"px",paddingTop:n+"px",paddingBottom:n+"px",flexShrink:0}},e.createElement("div",{style:{width:" 100%",height:"100%",backgroundColor:"white"}})),d=[4,6];export const WorkspaceCanvas=t(({store:t,layout:i="vertical",pageControlsEnabled:h,backgroundColor:g,transparencyBackgroundColor:p,pageBorderColor:f,activePageBorderColor:m,bleedColor:v,snapGuideStroke:b,snapGuideStrokeWidth:x,snapGuideDash:k,selectionRectFill:w,selectionRectStroke:T,selectionRectStrokeWidth:E,transformLabelFill:y,transformLabelTextFill:L,distanceGuideStroke:M,distanceLabelFill:C,distanceLabelTextFill:P,rulerBackgroundColor:S,rulerTextColor:R,rulerBorderColor:F,rulerBorderSize:W,rulerTickColor:B,rulerTickSize:z,components:O,onKeyDown:H,paddingX:N,paddingY:j,pageGap:G,altCloneEnabled:_=!0,visiblePagesOffset:Y,renderOnlyActivePage:D,scrollToPageThreshold:X=.5,tooltipSafeArea:A})=>{var I;const K="horizontal"===i,q=null!=N?N:20,V=null!=j?j:55,[J,Q]=e.useState({width:100,height:100}),U=e.useRef(J),Z=e.useRef(null),$=e.useRef(null),ee=e.useRef(0),te=t.bleedVisible?Math.max(0,...t.pages.map(e=>e.bleed)):0,re=Math.max(...t.pages.map(e=>e.computedWidth)),oe=Math.max(...t.pages.map(e=>e.computedHeight)),ne=(null===(I=t.activePage)||void 0===I?void 0:I.computedHeight)||0,le=re+2*te,ie=(D?ne:oe)+2*te,ae=async({skipTimeout:e}={skipTimeout:!1})=>{if(e||await new Promise(e=>setTimeout(e,50)),null===Z.current){return}const r=Z.current.getBoundingClientRect();0!==r.width&&0!==r.height||(console.warn("Polotno warning: <Workspace /> component can not automatically detect its size.\nWidth or height of parent elements is equal 0.\nPlease make sure it has non-zero size. You may need to adjust it with your styles. <Workspace /> will automatically fit into parent container.\nFor simpler debugging here is the log of the parent element:"),console.log(Z.current));const o=$.current.clientWidth||r.width,n={width:o,height:r.height};(U.current.width!==n.width||U.current.height!==n.height)&&(Q(n),U.current=n);const l=(o-2*q)/le,i=t.pages.length>1?3.1:2,a=(r.height-V*i)/ie,s=t.pages.length>1?3.1:2,c=(o-q*s)/le,u=(r.height-2*V)/ie,d=t.pages.length?Math.max(Math.min(K?c:l,K?u:a),.01):1;t.scaleToFit!==d&&(t.setScale(d),t._setScaleToFit(d))};e.useLayoutEffect(()=>{ae({skipTimeout:!0})},[]),e.useEffect(()=>{ae()},[le,ie,j,N]),e.useLayoutEffect(()=>{ae({skipTimeout:!0})},[t.openedSidePanel]),e.useEffect(()=>{t.__()},[]),e.useEffect(()=>{const e=Z.current;if(window.ResizeObserver){const t=new ResizeObserver(()=>{ae({skipTimeout:!0})});return t.observe(e),()=>t.unobserve(e)}{const e=setInterval(()=>{ae({skipTimeout:!0})},100);return()=>clearInterval(e)}},[le,ie]);const se=D?1:t.pages.length;let ce,ue;if(K){const e=le*t.scale*se;ce=Math.max(q,(J.width-e)/se/2),ue=Math.max(V,(J.height-ie*t.scale)/2)}else{ce=Math.max(q,(J.width-le*t.scale)/2);const e=ie*t.scale*se;ue=Math.max(V,(J.height-e)/se/2)}Number.isNaN(ce)&&(ce=q),Number.isNaN(ue)&&(ue=V),e.useEffect(()=>{const e=e=>{(H||l)(e,t)};return window.addEventListener("keydown",e),()=>window.removeEventListener("keydown",e)},[]),e.useEffect(()=>{const e=e=>{if(e.ctrlKey||e.metaKey){e.preventDefault();const r=Math.max(5,t.scaleToFit);let o=Math.min(.1,t.scaleToFit);K&&le>0&&Number.isFinite(le)&&(o=Math.max(o,300/le)),o=Math.max(o,.01);const n=.03,l=a(e.deltaY<0?t.scale*(1+n):t.scale/(1+n),o,r);return void t.setScale(l)}},r=$.current;return null==r||r.addEventListener("wheel",e),()=>null==r?void 0:r.removeEventListener("wheel",e)},[K,le,t]),e.useEffect(()=>{const e=$.current;if(!e){return}const r=e=>{2===e.touches.length&&(ee.current=s(e.touches[0],e.touches[1]))},o=r=>{if(2===r.touches.length&&ee.current>0){r.preventDefault();const o=s(r.touches[0],r.touches[1]),n=o/ee.current,l=Math.max(5,t.scaleToFit);let i=Math.min(.1,t.scaleToFit);K&&le>0&&Number.isFinite(le)&&(i=Math.max(i,300/le)),i=Math.max(i,.01);const c=t.scale,u=a(c*n,i,l),d=u/c,h=e.getBoundingClientRect(),g=(r.touches[0].clientX+r.touches[1].clientX)/2-h.left,p=(r.touches[0].clientY+r.touches[1].clientY)/2-h.top,f=e.scrollLeft+g,m=e.scrollTop+p;ve.current=!0,t.setScale(u),e.scrollLeft=f*d-g,e.scrollTop=m*d-p,ee.current=o}},n=()=>{ee.current=0};return e.addEventListener("touchstart",r,{passive:!0}),e.addEventListener("touchmove",o,{passive:!1}),e.addEventListener("touchend",n,{passive:!0}),()=>{e.removeEventListener("touchstart",r),e.removeEventListener("touchmove",o),e.removeEventListener("touchend",n)}},[K,le,t]);const de=void 0!==G,he=t.pages.map(e=>{if(K){const r=(e.computedWidth+2*te)*t.scale;return de?r+G:r+2*ce}{const r=(e.computedHeight+2*te)*t.scale;return de?r+G:r+2*ue}}),ge=[];let pe=de?K?ce:ue:0;for(let e=0;e<he.length;e++){ge.push(pe),pe+=he[e]}const fe=he.reduce((e,t)=>e+t,0),me=de?fe+(K?2*ce:2*ue):fe,ve=e.useRef(!1),[,be]=e.useReducer(e=>e+1,0);((t,r,o,n,l)=>{const i=e.useRef(0),s=e.useRef(0),c=e.useRef(null),u=e.useRef(null),d=e.useRef(!1),h=e.useRef(n.pages.length);d.current=h.current!==n.pages.length,h.current=n.pages.length,e.useEffect(()=>{const e=t.current,r=()=>{i.current=e.scrollLeft,s.current=e.scrollTop,c.current=e.scrollWidth,u.current=e.scrollHeight};return e.addEventListener("scroll",r),r(),()=>{e.removeEventListener("scroll",r)}},[]),e.useLayoutEffect(()=>{if(!t.current){return}if(d.current){return}const e=t.current,r=c.current,o=u.current;if(null===r||null===o){return c.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,void(s.current=e.scrollTop)}l.current=!0;const n=e.offsetWidth,h=e.offsetHeight,g=(i.current+n/2)/r,p=(s.current+h/2)/o,f=Math.max(0,e.scrollWidth-n),m=Math.max(0,e.scrollHeight-h);e.scrollLeft=a(g*e.scrollWidth-n/2,0,f),e.scrollTop=a(p*e.scrollHeight-h/2,0,m),c.current=e.scrollWidth,u.current=e.scrollHeight,i.current=e.scrollLeft,s.current=e.scrollTop},[o,r])})($,me,t.scale,t,ve);const{handleScroll:xe}=((t,r,o,n,l,i,a,s,c,u)=>{const d=e.useRef(!1),h=e.useRef(null),g=e.useRef(!1),p="horizontal"===c;e.useEffect(()=>{const e=t.current,r=()=>{a.current};return e.addEventListener("scroll",r),()=>{e.removeEventListener("scroll",r)}},[]);const f=n.pages.indexOf(n.activePage);return e.useLayoutEffect(()=>{if(s){return}if(!n.activePage){return}if(!t.current){return}if(d.current){return}const e=t.current,i=n.pages.indexOf(n.activePage),a=r[i]||0,c=p?e.scrollLeft:e.scrollTop,h=p?e.scrollWidth-e.clientWidth:e.scrollHeight-e.clientHeight,f=Math.min(a,Math.max(0,h)),m=o[i]||o[0]||0;let v=()=>{};return(Math.abs(f-c)>m*l||g.current)&&(g.current=!0,v=(({element:e,scrollTop:t,scrollLeft:r,duration:o=300,onFinish:n=()=>{}})=>{const l=void 0!==t,i=l?e.scrollTop:e.scrollLeft,a=l?t:r,s=a-i;let c=0,u=!1;if(0===o){return l?e.scrollTop=a:e.scrollLeft=a,()=>{}}const d=()=>{if(u){return}c+=20;const t=h(c,i,s,o);l?e.scrollTop=t:e.scrollLeft=t,c<o?setTimeout(d,20):n()},h=(e,t,r,o)=>(e/=o/2)<1?r/2*e*e+t:-r/2*(--e*(e-2)-1)+t;return d(),()=>{u=!0}})(Object.assign(Object.assign({element:e},p?{scrollLeft:f}:{scrollTop:f}),{onFinish:()=>{g.current=!1,null==u||u()},duration:n.isPlaying?0:300}))),v},[n.activePage,f,n.isPlaying,s,c,r,o]),{handleScroll:e=>{if(s){return}if(g.current){return}d.current=!0,clearTimeout(h.current),h.current=setTimeout(()=>{d.current=!1},300);const t=(p?e.currentTarget.scrollLeft:e.currentTarget.scrollTop)+(p?i.width:i.height)/3;let o=0;for(let n=r.length-1;n>=0;n--){if(t>=r[n]){o=n;break}}const l=n.pages[o];l&&n.activePage!==l&&l.select()}}})($,ge,he,t,X,J,ve,D,i,be),ke=J.width>=le*t.scale+2*ce,we=J.height>=ie*t.scale+2*ue,Te=g||"rgba(232, 232, 232, 0.9)",Ee=(null==O?void 0:O.NoPages)||c,ye=K?J.width:J.height,Le=$.current?K?$.current.scrollLeft:$.current.scrollTop:0,Me=e=>{for(let t=ge.length-1;t>=0;t--){if(e>=ge[t]){return t}}return 0},Ce=Math.max(0,Me(Le)),Pe=Math.min(t.pages.length-1,Me(Le+ye)),Se=null!=Y?Y:1,Re=Math.max(0,Ce-Se),Fe=Math.min(t.pages.length-1,Pe+Se);return e.createElement("div",{ref:Z,style:{width:"100%",height:"100%",position:"relative",outline:"none",flex:1,backgroundColor:Te,overflow:"hidden"},tabIndex:0,className:"polotno-workspace-container"},e.createElement("div",{ref:$,onScroll:xe,style:Object.assign({position:"absolute",top:0,left:0,width:"100%",height:"100%",display:"flex",flexDirection:K?"row":"column",overflow:"auto",overflowX:K?"auto":ke?"hidden":"auto",overflowY:K&&we?"hidden":"auto"},de&&{paddingTop:K?0:ue,paddingBottom:K?0:ue,paddingLeft:K?ce:0,paddingRight:K?ce:0,boxSizing:"border-box"}),className:"polotno-workspace-inner"},t.pages.map((o,n)=>{const l=o===t.activePage;if(D&&!l&&!o._exportingOrRendering&&!o._forceMount){return null}const a=l||n>=Re&&n<=Fe||o._exportingOrRendering||o._forceMount,s=K?he[n]:le*t.scale+2*ce,c=K?ie*t.scale+2*ue:he[n];if(!a){return e.createElement("div",{key:o.id,style:{flexShrink:0}},e.createElement(u,{width:s,height:c,backgroundColor:Te,xPadding:ce,yPadding:ue}))}const g=e.createElement(r,{key:o.id,page:o,xPadding:ce,yPadding:ue,width:s,height:c,store:t,pageControlsEnabled:h,backColor:Te,transparencyBackgroundColor:p,pageBorderColor:f||"lightgrey",activePageBorderColor:m||"rgb(0, 161, 255)",altCloneEnabled:_,bleedColor:v||"rgba(255, 0, 0, 0.1)",selectionRectFill:w,selectionRectStroke:T,selectionRectStrokeWidth:E,snapGuideStroke:b||"rgb(0, 161, 255)",snapGuideStrokeWidth:x||1,snapGuideDash:k||d,transformLabelFill:y,transformLabelTextFill:L,distanceGuideStroke:M||"rgb(0, 161, 255)",distanceLabelFill:C||"rgb(0, 161, 255)",distanceLabelTextFill:P||"white",components:O,viewportSize:J,layout:i,tooltipSafeArea:A});return(o._exportingOrRendering||o._forceMount)&&!l&&D?e.createElement("div",{style:{display:"none",flexShrink:0},key:o.id},g):g}),t.rulesVisible&&e.createElement(o,{store:t,xPadding:ce,yPadding:ue,width:le*t.scale+2*ce,height:ie*t.scale+2*ue,pageSizes:he,layout:i,renderOnlyActivePage:D,rulerBackgroundColor:S,rulerTextColor:R,rulerBorderColor:F,rulerBorderSize:W,rulerTickColor:B,rulerTickSize:z}),0===t.pages.length&&e.createElement(Ee,{store:t}),t.audios.map(r=>e.createElement(n,{key:r.id,audio:r,store:t}))))});export default WorkspaceCanvas;
@@ -356,6 +356,7 @@ export declare const TYPES_MAP: {
356
356
  setAnimation(type: any, attrs: any): void;
357
357
  setFilter(type: any, value: any): void;
358
358
  } & {
359
+ set(attrs: any): void;
359
360
  afterCreate(): void;
360
361
  toggleEditMode(editing?: boolean): void;
361
362
  }, import("mobx-state-tree").ModelCreationType<{
@@ -1 +1 @@
1
- import{types as e,getParent as t,getSnapshot as l,isAlive as o,getRoot as r,cast as n}from"mobx-state-tree";import{observable as s}from"mobx";import{nanoid as i}from"nanoid";import{Shape as d}from"./shape-model.js";const c=.05,a=e.enumeration(["solid","dashed","dotted","none"]);function g(e){return t(e,2)}function u(e,t,l){const r=e[`_${t}`];return null!=r?r:o(e)?g(e)[t]:l}function h(e){return t(e,1)}const f=e.model("BorderSide",{color:e.maybe(e.string),width:e.maybe(e.number),style:e.maybe(a)}).postProcessSnapshot(e=>{const t={};for(const[l,o]of Object.entries(e)){null!=o&&(t[l]=o)}return t}),b=e.model("CellBorders",{top:e.maybe(f),right:e.maybe(f),bottom:e.maybe(f),left:e.maybe(f)}).postProcessSnapshot(e=>{const t={};for(const[l,o]of Object.entries(e)){null!=o&&"object"==typeof o&&Object.keys(o).length>0&&(t[l]=o)}return t}),w=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],p=new Set(w),m=["blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","filters","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity"],_=["id","type","text","opacity","rowSpan","colSpan","mergedInto","name","custom","borders"],y=new Set(["row","col","x","y","width","height","rotation","draggable","resizable","selectable","removable","contentEditable","visible","showInExport","alwaysOnTop","backgroundEnabled","backgroundOpacity","backgroundColor","backgroundCornerRadius","backgroundPadding","curveEnabled","curvePower","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity","blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","placeholder","animations","filters"]),C={opacity:1,rowSpan:1,colSpan:1,name:""},v=[];export const TableCell=e.model("TableCell",{id:e.identifier,type:e.optional(e.literal("tablecell"),"tablecell"),text:"",_fontSize:e.maybe(e.number),_fontFamily:e.maybe(e.string),_fontWeight:e.maybe(e.string),_fontStyle:e.maybe(e.string),_textDecoration:e.maybe(e.string),_textTransform:e.maybe(e.string),_fill:e.maybe(e.string),_align:e.maybe(e.string),_verticalAlign:e.maybe(e.string),_lineHeight:e.maybe(e.union(e.number,e.string)),_letterSpacing:e.maybe(e.number),_strokeWidth:e.maybe(e.number),_stroke:e.maybe(e.string),_cellBackground:e.maybe(e.string),_cellPadding:e.maybe(e.number),opacity:1,rowSpan:1,colSpan:1,mergedInto:e.maybe(e.string),borders:e.maybe(b),name:"",custom:e.frozen()}).volatile(()=>({_editModeEnabled:!1,filters:s.map()})).preProcessSnapshot(e=>{if(!e){return e}for(const l in e){null===e[l]&&(e[l]=void 0)}const t={};for(const l of _){l in e&&(t[l]=e[l])}for(const l of w){void 0!==e[l]&&(t[`_${l}`]=e[l])}return t}).postProcessSnapshot(e=>{const t={};for(const[l,o]of Object.entries(e)){if(l.startsWith("_")){null!=o&&(t[l.slice(1)]=o)}else if("borders"===l){null!=o&&"object"==typeof o&&Object.keys(o).length>0&&(t.borders=o)}else{if(l in C&&o===C[l]){continue}t[l]=o}}return t}).views(e=>{const t={get row(){if(!o(e)){return 0}const t=g(e),l=h(e).indexOf(e);return-1===l?0:Math.floor(l/t.cols)},get col(){if(!o(e)){return 0}const t=g(e),l=h(e).indexOf(e);return-1===l?0:l%t.cols},get store(){return o(e)?r(e):null},get page(){if(!o(e)){return null}try{return g(e).page}catch(t){return null}},get fontSize(){return u(e,"fontSize",30)},get fontFamily(){return u(e,"fontFamily","Roboto")},get fontWeight(){return u(e,"fontWeight","normal")},get fontStyle(){return u(e,"fontStyle","normal")},get textDecoration(){return u(e,"textDecoration","")},get textTransform(){return u(e,"textTransform","none")},get fill(){return u(e,"fill","black")},get align(){return u(e,"align","left")},get verticalAlign(){return u(e,"verticalAlign","top")},get lineHeight(){return u(e,"lineHeight",1.2)},get letterSpacing(){return u(e,"letterSpacing",0)},get strokeWidth(){return u(e,"strokeWidth",0)},get stroke(){return u(e,"stroke","black")},get cellBackground(){return u(e,"cellBackground","transparent")},get cellPadding(){return u(e,"cellPadding",4)},get width(){if(!o(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).width}catch(l){return 100}},get height(){if(!o(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).height}catch(l){return 100}},get a(){var l;if(!o(e)){return{x:0,y:0,width:100,height:100,rotation:0,opacity:1,fontSize:16}}const r=g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan),n=t.cellPadding;return{x:r.x+n,y:r.y+n,width:r.width-2*n,height:r.height-2*n,rotation:0,opacity:null!==(l=e.opacity)&&void 0!==l?l:1,fontSize:t.fontSize}},getEffectiveBorder(t){var l,r,n,s,i,d,c;const a=o(e)?g(e):null,u=null===(l=e.borders)||void 0===l?void 0:l[t];return{color:null!==(n=null!==(r=null==u?void 0:u.color)&&void 0!==r?r:null==a?void 0:a.borderColor)&&void 0!==n?n:"#000000",width:null!==(i=null!==(s=null==u?void 0:u.width)&&void 0!==s?s:null==a?void 0:a.borderWidth)&&void 0!==i?i:1,style:null!==(c=null!==(d=null==u?void 0:u.style)&&void 0!==d?d:null==a?void 0:a.borderStyle)&&void 0!==c?c:"solid"}},get x(){return 0},get y(){return 0},get rotation(){return 0},get draggable(){return!1},get resizable(){return!1},get selectable(){return!1},get removable(){return!1},get contentEditable(){return!0},get visible(){return!0},get showInExport(){return!0},get alwaysOnTop(){return!1},get placeholder(){return""},get backgroundEnabled(){return!1},get backgroundOpacity(){return 1},get backgroundColor(){return"transparent"},get backgroundCornerRadius(){return 0},get backgroundPadding(){return 0},get curveEnabled(){return!1},get curvePower(){return 0},get shadowEnabled(){return!1},get shadowBlur(){return 0},get shadowOffsetX(){return 0},get shadowOffsetY(){return 0},get shadowColor(){return"black"},get shadowOpacity(){return 1},get blurEnabled(){return!1},get blurRadius(){return 0},get brightnessEnabled(){return!1},get brightness(){return 0},get sepiaEnabled(){return!1},get grayscaleEnabled(){return!1},get animations(){return v}};return t}).actions(e=>({toJSON:()=>Object.assign({},l(e)),set(t){const l={};for(const[e,o]of Object.entries(t)){p.has(e)?l[`_${e}`]=o:"borders"===e?l.borders=o?JSON.parse(JSON.stringify(o)):o:y.has(e)||(l[e]=o)}Object.assign(e,l)},setBorder(t,o){const r=e.borders?Object.assign({},l(e.borders)):{},s=r[t]||{},i=Object.assign({},s);void 0!==o.color&&(i.color=o.color),void 0!==o.width&&(i.width=o.width),void 0!==o.style&&(i.style=o.style),r[t]=i,e.borders=n(r)},toggleEditMode(t){const l=null!=t?t:!e._editModeEnabled;l!==e._editModeEnabled&&(e._editModeEnabled=l,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())}}));function H(e){return Array.from({length:e},()=>1/e)}function S(e){const t=e.reduce((e,t)=>e+t,0);return 0===t?H(e.length):e.map(e=>e/t)}export const TableElement=d.named("Table").props({type:"table",width:300,height:200,rows:3,cols:3,colWidths:e.array(e.number),rowHeights:e.array(e.number),cells:e.array(TableCell),borderColor:"#000000",borderWidth:1,borderStyle:e.optional(e.enumeration(["solid","dashed","dotted","none"]),"solid"),fontSize:30,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"left",verticalAlign:"top",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,strokeWidth:0,stroke:"black",cellBackground:"transparent",cellPadding:4}).postProcessSnapshot(e=>{e.cells&&((e=Object.assign({},e)).cells=e.cells.map(t=>{const l={};for(const[o,r]of Object.entries(t)){p.has(o)&&r===e[o]||(l[o]=r)}return l}));for(const t of m){delete e[t]}return e}).volatile(()=>({_focusedCellIds:[],_editingCellId:void 0,_anchorCellId:void 0,_cellContentHeights:s.map(),_baseRowHeights:null,_baseHeight:null,_isResizingRows:!1,_isTransforming:!1})).actions(e=>({afterCreate(){const t=e.rows*e.cols;if(0===e.cells.length){e.cells.replace(n(function(e,t){const l=[];for(let o=0;o<e*t;o++){l.push({id:i(10),text:""})}return l}(e.rows,e.cols)))}else if(e.cells.length<t){for(;e.cells.length<t;){e.cells.push(n({id:i(10),text:""}))}}else{e.cells.length>t&&e.cells.splice(t)}0===e.colWidths.length&&e.colWidths.replace(H(e.cols)),0===e.rowHeights.length&&e.rowHeights.replace(H(e.rows))}})).views(e=>({get _cellMap(){const t=new Map,l=e.cols;return e.cells.forEach((e,o)=>{t.set(`${Math.floor(o/l)}:${o%l}`,e)}),t},getActualRowHeight:t=>e.rowHeights[t]*e.height})).views(e=>{const t={getCell:(t,l)=>e._cellMap.get(`${t}:${l}`),get minWidth(){return 20*e.cols},get minHeight(){return 20*e.rows},get actualHeight(){let t=0;for(let l=0;l<e.rows;l++){t+=e.getActualRowHeight(l)}return t},getCellRect(t,l,o=1,r=1){let n=0;for(let c=0;c<l;c++){n+=e.colWidths[c]*e.width}let s=0;for(let c=0;c<t;c++){s+=e.getActualRowHeight(c)}let i=0;for(let c=l;c<l+r;c++){i+=(e.colWidths[c]||0)*e.width}let d=0;for(let c=t;c<t+o;c++){d+=e.getActualRowHeight(c)}return{x:n,y:s,width:i,height:d}},get visibleCells(){return e.cells.filter(e=>!e.mergedInto)},get focusedCells(){return e.cells.filter(t=>e._focusedCellIds.includes(t.id))},get editingCell(){if(e._editingCellId){return e.cells.find(t=>t.id===e._editingCellId)}},get _fitRowsToContent(){var l,o;if(e._isResizingRows){return null}if(e._isTransforming){return null}if(0===e._cellContentHeights.size){return null}const r=null!==(l=e._baseHeight)&&void 0!==l?l:e.height,n=null!==(o=e._baseRowHeights)&&void 0!==o?o:[...e.rowHeights];let s=!1;const i=[];for(let c=0;c<e.rows;c++){const l=e.rowHeights[c]*e.height,o=n[c]*r;let d=0;for(let r=0;r<e.cols;r++){const l=t.getCell(c,r);if(!l){continue}const o=e._cellContentHeights.get(l.id);if(void 0!==o){const e=o+2*l.cellPadding;d=Math.max(d,e)}}const a=Math.max(d,o);Math.abs(a-l)>1?(i.push(a),s=!0):i.push(l)}if(!s){return null}const d=i.reduce((e,t)=>e+t,0);return{rowHeights:i.map(e=>e/d),height:d}}};return t}).actions(e=>{const t={setCellContentHeight(t,l){e._cellContentHeights.set(t,l)},_applyFitRowsToContent(){null===e._baseRowHeights&&(e._baseRowHeights=[...e.rowHeights],e._baseHeight=e.height);const t=e._fitRowsToContent;t&&(e.height=t.height,e.rowHeights.replace(t.rowHeights))},focusCell(t,l=!1){l?e._focusedCellIds.includes(t)||(e._focusedCellIds=[...e._focusedCellIds,t]):(e._focusedCellIds=[t],e._anchorCellId=t)},focusCellRange(t,l){const o=e.cells.find(t=>t.id===e._anchorCellId);if(!o){return}const r=Math.min(o.row,t),n=Math.max(o.row,t),s=Math.min(o.col,l),i=Math.max(o.col,l),d=[];for(const c of e.cells){c.row>=r&&c.row<=n&&c.col>=s&&c.col<=i&&d.push(c.id)}e._focusedCellIds=d},clearCellFocus(){if(o(e)){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._focusedCellIds=[],e._editingCellId=void 0,e._anchorCellId=void 0}},enterCellEdit(t){e._editingCellId=t,e._focusedCellIds.includes(t)||(e._focusedCellIds=[t]);const l=e.cells.find(e=>e.id===t);l&&l.toggleEditMode(!0)},exitCellEdit(){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._editingCellId=void 0},_resetBaseRowHeights(){e._baseRowHeights=null,e._baseHeight=null},_setIsResizingRows(t){e._isResizingRows=t},_setIsTransforming(t){e._isTransforming=t},addRow(l){t._resetBaseRowHeights();const o=l>0?l-1:0,r=(e.rowHeights[o]||1/(e.rows+1))*e.height,s=e.height+r,d=[];for(let t=0;t<e.rows;t++){d.push(e.rowHeights[t]*e.height/s)}d.splice(l,0,r/s);const c=l*e.cols,a=Array.from({length:e.cols},()=>({id:i(10),text:""}));e.cells.splice(c,0,...n(a)),e.rows+=1,e.height=s,e.rowHeights.replace(S(d))},removeRow(l){if(e.rows<=1){return}t._resetBaseRowHeights();const o=l*e.cols,r=[];for(let t=o;t<o+e.cols;t++){r.push(e.cells[t].id)}if(e._editingCellId&&r.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!r.includes(e)),r.forEach(t=>e._cellContentHeights.delete(t)),e.cells.splice(o,e.cols);const n=[...e.rowHeights];n.splice(l,1),e.rows-=1,e.rowHeights.replace(S(n))},addColumn(t){const l=t>0?t-1:0,o=(e.colWidths[l]||1/(e.cols+1))*e.width,r=e.width+o,s=[];for(let n=0;n<e.cols;n++){s.push(e.colWidths[n]*e.width/r)}s.splice(t,0,o/r);const d=e.cols;for(let c=e.rows-1;c>=0;c--){e.cells.splice(c*d+t,0,n({id:i(10),text:""}))}e.cols+=1,e.width=r,e.colWidths.replace(S(s))},removeColumn(t){if(e.cols<=1){return}const l=e.cols,o=[];for(let n=0;n<e.rows;n++){o.push(e.cells[n*l+t].id)}if(e._editingCellId&&o.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!o.includes(e)),o.forEach(t=>e._cellContentHeights.delete(t));for(let n=e.rows-1;n>=0;n--){e.cells.splice(n*l+t,1)}const r=[...e.colWidths];r.splice(t,1),e.cols-=1,e.colWidths.replace(S(r))},distributeRowsEvenly(){t._resetBaseRowHeights(),e.rowHeights.replace(H(e.rows))},distributeColumnsEvenly(){e.colWidths.replace(H(e.cols))},resizeColumn(t,l){if(t>=e.cols-1){return}const o=[...e.colWidths],r=o[t]+o[t+1],n=o[t]+l,s=o[t+1]-l;n<c?(o[t]=c,o[t+1]=r-c):s<c?(o[t+1]=c,o[t]=r-c):(o[t]=n,o[t+1]=s),e.colWidths.replace(o)},resizeRow(t,l){if(t>=e.rows-1){return}const o=[...e.rowHeights],r=o[t]+o[t+1],n=o[t]+l,s=o[t+1]-l;n<c?(o[t]=c,o[t+1]=r-c):s<c?(o[t+1]=c,o[t]=r-c):(o[t]=n,o[t+1]=s),e.rowHeights.replace(o)},setCellBorders(t,l,o){const r={top:{side:"bottom",dr:-1,dc:0},bottom:{side:"top",dr:1,dc:0},left:{side:"right",dr:0,dc:-1},right:{side:"left",dr:0,dc:1}};for(const n of t){const t=e.cells.find(e=>e.id===n);if(t){for(const n of l){t.setBorder(n,o);const l=r[n],s=t.row+l.dr,i=t.col+l.dc,d=e.getCell(s,i);d&&d.setBorder(l.side,o)}}}}};return t}).actions(e=>({clone(t={},{skipSelect:l=!1}={}){const o=JSON.parse(JSON.stringify(e.toJSON()));if(t.id=t.id||i(10),o.cells){const e=new Map;o.cells.forEach(t=>{const l=t.id,o=i(10);e.set(l,o),t.id=o}),o.cells.forEach(t=>{t.mergedInto&&e.has(t.mergedInto)&&(t.mergedInto=e.get(t.mergedInto))})}return Object.assign(o,t),e.page.addElement(o,{skipSelect:l})}}));
1
+ import{types as e,getParent as t,getSnapshot as o,isAlive as l,getRoot as r,cast as n}from"mobx-state-tree";import{observable as s}from"mobx";import{nanoid as i}from"nanoid";import{Shape as d}from"./shape-model.js";const c=.05,a=e.enumeration(["solid","dashed","dotted","none"]);function g(e){return t(e,2)}function u(e,t,o){const r=e[`_${t}`];return null!=r?r:l(e)?g(e)[t]:o}function h(e){return t(e,1)}const f=e.model("BorderSide",{color:e.maybe(e.string),width:e.maybe(e.number),style:e.maybe(a)}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){null!=l&&(t[o]=l)}return t}),b=e.model("CellBorders",{top:e.maybe(f),right:e.maybe(f),bottom:e.maybe(f),left:e.maybe(f)}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){null!=l&&"object"==typeof l&&Object.keys(l).length>0&&(t[o]=l)}return t}),w=["fontSize","fontFamily","fontWeight","fontStyle","textDecoration","textTransform","fill","align","verticalAlign","lineHeight","letterSpacing","strokeWidth","stroke","cellBackground","cellPadding"],p=new Set(w),m=["blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","filters","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity"],_=["id","type","text","opacity","rowSpan","colSpan","mergedInto","name","custom","borders"],y=new Set(["row","col","x","y","width","height","rotation","draggable","resizable","selectable","removable","contentEditable","visible","showInExport","alwaysOnTop","backgroundEnabled","backgroundOpacity","backgroundColor","backgroundCornerRadius","backgroundPadding","curveEnabled","curvePower","shadowEnabled","shadowBlur","shadowOffsetX","shadowOffsetY","shadowColor","shadowOpacity","blurEnabled","blurRadius","brightnessEnabled","brightness","sepiaEnabled","grayscaleEnabled","placeholder","animations","filters"]),C={opacity:1,rowSpan:1,colSpan:1,name:""},v=[];export const TableCell=e.model("TableCell",{id:e.identifier,type:e.optional(e.literal("tablecell"),"tablecell"),text:"",_fontSize:e.maybe(e.number),_fontFamily:e.maybe(e.string),_fontWeight:e.maybe(e.string),_fontStyle:e.maybe(e.string),_textDecoration:e.maybe(e.string),_textTransform:e.maybe(e.string),_fill:e.maybe(e.string),_align:e.maybe(e.string),_verticalAlign:e.maybe(e.string),_lineHeight:e.maybe(e.union(e.number,e.string)),_letterSpacing:e.maybe(e.number),_strokeWidth:e.maybe(e.number),_stroke:e.maybe(e.string),_cellBackground:e.maybe(e.string),_cellPadding:e.maybe(e.number),opacity:1,rowSpan:1,colSpan:1,mergedInto:e.maybe(e.string),borders:e.maybe(b),name:"",custom:e.frozen()}).volatile(()=>({_editModeEnabled:!1,filters:s.map()})).preProcessSnapshot(e=>{if(!e){return e}for(const o in e){null===e[o]&&(e[o]=void 0)}const t={};for(const o of _){o in e&&(t[o]=e[o])}for(const o of w){void 0!==e[o]&&(t[`_${o}`]=e[o])}return t}).postProcessSnapshot(e=>{const t={};for(const[o,l]of Object.entries(e)){if(o.startsWith("_")){null!=l&&(t[o.slice(1)]=l)}else if("borders"===o){null!=l&&"object"==typeof l&&Object.keys(l).length>0&&(t.borders=l)}else{if(o in C&&l===C[o]){continue}t[o]=l}}return t}).views(e=>{const t={get row(){if(!l(e)){return 0}const t=g(e),o=h(e).indexOf(e);return-1===o?0:Math.floor(o/t.cols)},get col(){if(!l(e)){return 0}const t=g(e),o=h(e).indexOf(e);return-1===o?0:o%t.cols},get store(){return l(e)?r(e):null},get page(){if(!l(e)){return null}try{return g(e).page}catch(t){return null}},get fontSize(){return u(e,"fontSize",30)},get fontFamily(){return u(e,"fontFamily","Roboto")},get fontWeight(){return u(e,"fontWeight","normal")},get fontStyle(){return u(e,"fontStyle","normal")},get textDecoration(){return u(e,"textDecoration","")},get textTransform(){return u(e,"textTransform","none")},get fill(){return u(e,"fill","black")},get align(){return u(e,"align","left")},get verticalAlign(){return u(e,"verticalAlign","top")},get lineHeight(){return u(e,"lineHeight",1.2)},get letterSpacing(){return u(e,"letterSpacing",0)},get strokeWidth(){return u(e,"strokeWidth",0)},get stroke(){return u(e,"stroke","black")},get cellBackground(){return u(e,"cellBackground","transparent")},get cellPadding(){return u(e,"cellPadding",4)},get width(){if(!l(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).width}catch(o){return 100}},get height(){if(!l(e)){return 100}try{return g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan).height}catch(o){return 100}},get a(){var o;if(!l(e)){return{x:0,y:0,width:100,height:100,rotation:0,opacity:1,fontSize:16}}const r=g(e).getCellRect(t.row,t.col,e.rowSpan,e.colSpan),n=t.cellPadding;return{x:r.x+n,y:r.y+n,width:r.width-2*n,height:r.height-2*n,rotation:0,opacity:null!==(o=e.opacity)&&void 0!==o?o:1,fontSize:t.fontSize}},getEffectiveBorder(t){var o,r,n,s,i,d,c;const a=l(e)?g(e):null,u=null===(o=e.borders)||void 0===o?void 0:o[t];return{color:null!==(n=null!==(r=null==u?void 0:u.color)&&void 0!==r?r:null==a?void 0:a.borderColor)&&void 0!==n?n:"#000000",width:null!==(i=null!==(s=null==u?void 0:u.width)&&void 0!==s?s:null==a?void 0:a.borderWidth)&&void 0!==i?i:1,style:null!==(c=null!==(d=null==u?void 0:u.style)&&void 0!==d?d:null==a?void 0:a.borderStyle)&&void 0!==c?c:"solid"}},get x(){return 0},get y(){return 0},get rotation(){return 0},get draggable(){return!1},get resizable(){return!1},get selectable(){return!1},get removable(){return!1},get contentEditable(){return!0},get visible(){return!0},get showInExport(){return!0},get alwaysOnTop(){return!1},get placeholder(){return""},get backgroundEnabled(){return!1},get backgroundOpacity(){return 1},get backgroundColor(){return"transparent"},get backgroundCornerRadius(){return 0},get backgroundPadding(){return 0},get curveEnabled(){return!1},get curvePower(){return 0},get shadowEnabled(){return!1},get shadowBlur(){return 0},get shadowOffsetX(){return 0},get shadowOffsetY(){return 0},get shadowColor(){return"black"},get shadowOpacity(){return 1},get blurEnabled(){return!1},get blurRadius(){return 0},get brightnessEnabled(){return!1},get brightness(){return 0},get sepiaEnabled(){return!1},get grayscaleEnabled(){return!1},get animations(){return v}};return t}).actions(e=>({toJSON:()=>Object.assign({},o(e)),set(t){null!=t.fontSize&&t.fontSize<1&&(t=Object.assign(Object.assign({},t),{fontSize:1}));const o={};for(const[e,l]of Object.entries(t)){p.has(e)?o[`_${e}`]=l:"borders"===e?o.borders=l?JSON.parse(JSON.stringify(l)):l:y.has(e)||(o[e]=l)}Object.assign(e,o)},setBorder(t,l){const r=e.borders?Object.assign({},o(e.borders)):{},s=r[t]||{},i=Object.assign({},s);void 0!==l.color&&(i.color=l.color),void 0!==l.width&&(i.width=l.width),void 0!==l.style&&(i.style=l.style),r[t]=i,e.borders=n(r)},toggleEditMode(t){const o=null!=t?t:!e._editModeEnabled;o!==e._editModeEnabled&&(e._editModeEnabled=o,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())}}));function S(e){return Array.from({length:e},()=>1/e)}function H(e){const t=e.reduce((e,t)=>e+t,0);return 0===t?S(e.length):e.map(e=>e/t)}export const TableElement=d.named("Table").props({type:"table",width:300,height:200,rows:3,cols:3,colWidths:e.array(e.number),rowHeights:e.array(e.number),cells:e.array(TableCell),borderColor:"#000000",borderWidth:1,borderStyle:e.optional(e.enumeration(["solid","dashed","dotted","none"]),"solid"),fontSize:30,fontFamily:"Roboto",fontWeight:"normal",fontStyle:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"left",verticalAlign:"top",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,strokeWidth:0,stroke:"black",cellBackground:"transparent",cellPadding:4}).postProcessSnapshot(e=>{e.cells&&((e=Object.assign({},e)).cells=e.cells.map(t=>{const o={};for(const[l,r]of Object.entries(t)){p.has(l)&&r===e[l]||(o[l]=r)}return o}));for(const t of m){delete e[t]}return e}).volatile(()=>({_focusedCellIds:[],_editingCellId:void 0,_anchorCellId:void 0,_cellContentHeights:s.map(),_baseRowHeights:null,_baseHeight:null,_isResizingRows:!1,_isTransforming:!1})).actions(e=>({afterCreate(){const t=e.rows*e.cols;if(0===e.cells.length){e.cells.replace(n(function(e,t){const o=[];for(let l=0;l<e*t;l++){o.push({id:i(10),text:""})}return o}(e.rows,e.cols)))}else if(e.cells.length<t){for(;e.cells.length<t;){e.cells.push(n({id:i(10),text:""}))}}else{e.cells.length>t&&e.cells.splice(t)}0===e.colWidths.length&&e.colWidths.replace(S(e.cols)),0===e.rowHeights.length&&e.rowHeights.replace(S(e.rows))}})).views(e=>({get _cellMap(){const t=new Map,o=e.cols;return e.cells.forEach((e,l)=>{t.set(`${Math.floor(l/o)}:${l%o}`,e)}),t},getActualRowHeight:t=>e.rowHeights[t]*e.height})).views(e=>{const t={getCell:(t,o)=>e._cellMap.get(`${t}:${o}`),get minWidth(){return 20*e.cols},get minHeight(){return 20*e.rows},get actualHeight(){let t=0;for(let o=0;o<e.rows;o++){t+=e.getActualRowHeight(o)}return t},getCellRect(t,o,l=1,r=1){let n=0;for(let c=0;c<o;c++){n+=e.colWidths[c]*e.width}let s=0;for(let c=0;c<t;c++){s+=e.getActualRowHeight(c)}let i=0;for(let c=o;c<o+r;c++){i+=(e.colWidths[c]||0)*e.width}let d=0;for(let c=t;c<t+l;c++){d+=e.getActualRowHeight(c)}return{x:n,y:s,width:i,height:d}},get visibleCells(){return e.cells.filter(e=>!e.mergedInto)},get focusedCells(){return e.cells.filter(t=>e._focusedCellIds.includes(t.id))},get editingCell(){if(e._editingCellId){return e.cells.find(t=>t.id===e._editingCellId)}},get _fitRowsToContent(){var o,l;if(e._isResizingRows){return null}if(e._isTransforming){return null}if(0===e._cellContentHeights.size){return null}const r=null!==(o=e._baseHeight)&&void 0!==o?o:e.height,n=null!==(l=e._baseRowHeights)&&void 0!==l?l:[...e.rowHeights];let s=!1;const i=[];for(let c=0;c<e.rows;c++){const o=e.rowHeights[c]*e.height,l=n[c]*r;let d=0;for(let r=0;r<e.cols;r++){const o=t.getCell(c,r);if(!o){continue}const l=e._cellContentHeights.get(o.id);if(void 0!==l){const e=l+2*o.cellPadding;d=Math.max(d,e)}}const a=Math.max(d,l);Math.abs(a-o)>1?(i.push(a),s=!0):i.push(o)}if(!s){return null}const d=i.reduce((e,t)=>e+t,0);return{rowHeights:i.map(e=>e/d),height:d}}};return t}).actions(e=>{const t={setCellContentHeight(t,o){e._cellContentHeights.set(t,o)},_applyFitRowsToContent(){null===e._baseRowHeights&&(e._baseRowHeights=[...e.rowHeights],e._baseHeight=e.height);const t=e._fitRowsToContent;t&&(e.height=t.height,e.rowHeights.replace(t.rowHeights))},focusCell(t,o=!1){o?e._focusedCellIds.includes(t)||(e._focusedCellIds=[...e._focusedCellIds,t]):(e._focusedCellIds=[t],e._anchorCellId=t)},focusCellRange(t,o){const l=e.cells.find(t=>t.id===e._anchorCellId);if(!l){return}const r=Math.min(l.row,t),n=Math.max(l.row,t),s=Math.min(l.col,o),i=Math.max(l.col,o),d=[];for(const c of e.cells){c.row>=r&&c.row<=n&&c.col>=s&&c.col<=i&&d.push(c.id)}e._focusedCellIds=d},clearCellFocus(){if(l(e)){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._focusedCellIds=[],e._editingCellId=void 0,e._anchorCellId=void 0}},enterCellEdit(t){e._editingCellId=t,e._focusedCellIds.includes(t)||(e._focusedCellIds=[t]);const o=e.cells.find(e=>e.id===t);o&&o.toggleEditMode(!0)},exitCellEdit(){if(e._editingCellId){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1)}e._editingCellId=void 0},_resetBaseRowHeights(){e._baseRowHeights=null,e._baseHeight=null},_setIsResizingRows(t){e._isResizingRows=t},_setIsTransforming(t){e._isTransforming=t},addRow(o){t._resetBaseRowHeights();const l=o>0?o-1:0,r=(e.rowHeights[l]||1/(e.rows+1))*e.height,s=e.height+r,d=[];for(let t=0;t<e.rows;t++){d.push(e.rowHeights[t]*e.height/s)}d.splice(o,0,r/s);const c=o*e.cols,a=Array.from({length:e.cols},()=>({id:i(10),text:""}));e.cells.splice(c,0,...n(a)),e.rows+=1,e.height=s,e.rowHeights.replace(H(d))},removeRow(o){if(e.rows<=1){return}t._resetBaseRowHeights();const l=o*e.cols,r=[];for(let t=l;t<l+e.cols;t++){r.push(e.cells[t].id)}if(e._editingCellId&&r.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!r.includes(e)),r.forEach(t=>e._cellContentHeights.delete(t)),e.cells.splice(l,e.cols);const n=[...e.rowHeights];n.splice(o,1),e.rows-=1,e.rowHeights.replace(H(n))},addColumn(t){const o=t>0?t-1:0,l=(e.colWidths[o]||1/(e.cols+1))*e.width,r=e.width+l,s=[];for(let n=0;n<e.cols;n++){s.push(e.colWidths[n]*e.width/r)}s.splice(t,0,l/r);const d=e.cols;for(let c=e.rows-1;c>=0;c--){e.cells.splice(c*d+t,0,n({id:i(10),text:""}))}e.cols+=1,e.width=r,e.colWidths.replace(H(s))},removeColumn(t){if(e.cols<=1){return}const o=e.cols,l=[];for(let n=0;n<e.rows;n++){l.push(e.cells[n*o+t].id)}if(e._editingCellId&&l.includes(e._editingCellId)){const t=e.cells.find(t=>t.id===e._editingCellId);t&&t.toggleEditMode(!1),e._editingCellId=void 0}e._focusedCellIds=e._focusedCellIds.filter(e=>!l.includes(e)),l.forEach(t=>e._cellContentHeights.delete(t));for(let n=e.rows-1;n>=0;n--){e.cells.splice(n*o+t,1)}const r=[...e.colWidths];r.splice(t,1),e.cols-=1,e.colWidths.replace(H(r))},distributeRowsEvenly(){t._resetBaseRowHeights(),e.rowHeights.replace(S(e.rows))},distributeColumnsEvenly(){e.colWidths.replace(S(e.cols))},resizeColumn(t,o){if(t>=e.cols-1){return}const l=[...e.colWidths],r=l[t]+l[t+1],n=l[t]+o,s=l[t+1]-o;n<c?(l[t]=c,l[t+1]=r-c):s<c?(l[t+1]=c,l[t]=r-c):(l[t]=n,l[t+1]=s),e.colWidths.replace(l)},resizeRow(t,o){if(t>=e.rows-1){return}const l=[...e.rowHeights],r=l[t]+l[t+1],n=l[t]+o,s=l[t+1]-o;n<c?(l[t]=c,l[t+1]=r-c):s<c?(l[t+1]=c,l[t]=r-c):(l[t]=n,l[t+1]=s),e.rowHeights.replace(l)},setCellBorders(t,o,l){const r={top:{side:"bottom",dr:-1,dc:0},bottom:{side:"top",dr:1,dc:0},left:{side:"right",dr:0,dc:-1},right:{side:"left",dr:0,dc:1}};for(const n of t){const t=e.cells.find(e=>e.id===n);if(t){for(const n of o){t.setBorder(n,l);const o=r[n],s=t.row+o.dr,i=t.col+o.dc,d=e.getCell(s,i);d&&d.setBorder(o.side,l)}}}}};return t}).actions(e=>({clone(t={},{skipSelect:o=!1}={}){const l=JSON.parse(JSON.stringify(e.toJSON()));if(t.id=t.id||i(10),l.cells){const e=new Map;l.cells.forEach(t=>{const o=t.id,l=i(10);e.set(o,l),t.id=l}),l.cells.forEach(t=>{t.mergedInto&&e.has(t.mergedInto)&&(t.mergedInto=e.get(t.mergedInto))})}return Object.assign(l,t),e.page.addElement(l,{skipSelect:o})}}));
@@ -157,6 +157,7 @@ export declare const TextElement: import("mobx-state-tree").IModelType<{
157
157
  setAnimation(type: any, attrs: any): void;
158
158
  setFilter(type: any, value: any): void;
159
159
  } & {
160
+ set(attrs: any): void;
160
161
  afterCreate(): void;
161
162
  toggleEditMode(editing?: boolean): void;
162
163
  }, import("mobx-state-tree").ModelCreationType<{
@@ -1 +1 @@
1
- import{types as e}from"mobx-state-tree";import{Shape as t}from"./shape-model.js";export const TextElement=t.named("Text").props({type:"text",text:"",placeholder:"",fontSize:14,fontFamily:"Roboto",fontStyle:"normal",fontWeight:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"center",width:100,height:0,verticalAlign:"top",strokeWidth:0,stroke:"black",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,_editModeEnabled:!1,backgroundEnabled:!1,backgroundColor:"#7ED321",backgroundOpacity:1,backgroundCornerRadius:.5,backgroundPadding:.5,curveEnabled:!1,curvePower:.5}).preProcessSnapshot(e=>Object.assign({},e)).actions(e=>({afterCreate(){if(!e.height){const t=e.lineHeight,o="number"==typeof t?t:parseFloat(t)||1.2;e.height=Math.round(e.fontSize*o)}},toggleEditMode(t){const o=null!=t?t:!e._editModeEnabled;o!==e._editModeEnabled&&(e._editModeEnabled=o,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())}}));
1
+ import{types as e}from"mobx-state-tree";import{Shape as t}from"./shape-model.js";export const TextElement=t.named("Text").props({type:"text",text:"",placeholder:"",fontSize:14,fontFamily:"Roboto",fontStyle:"normal",fontWeight:"normal",textDecoration:"",textTransform:"none",fill:"black",align:"center",width:100,height:0,verticalAlign:"top",strokeWidth:0,stroke:"black",lineHeight:e.optional(e.union(e.number,e.string),1.2),letterSpacing:0,_editModeEnabled:!1,backgroundEnabled:!1,backgroundColor:"#7ED321",backgroundOpacity:1,backgroundCornerRadius:.5,backgroundPadding:.5,curveEnabled:!1,curvePower:.5}).preProcessSnapshot(e=>Object.assign(Object.assign({},e),{fontSize:null!=e.fontSize&&e.fontSize<1?1:e.fontSize})).actions(e=>{const t=e.set;return{set(e){null!=e.fontSize&&e.fontSize<1&&(e=Object.assign(Object.assign({},e),{fontSize:1})),t(e)},afterCreate(){if(!e.height){const t=e.lineHeight,o="number"==typeof t?t:parseFloat(t)||1.2;e.height=Math.round(e.fontSize*o)}},toggleEditMode(t){const o=null!=t?t:!e._editModeEnabled;o!==e._editModeEnabled&&(e._editModeEnabled=o,e._editModeEnabled?e.store.history.startTransaction():e.store.history.endTransaction())}}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polotno",
3
- "version": "2.38.1",
3
+ "version": "2.39.0",
4
4
  "description": "Design Editor Framework",
5
5
  "author": "Anton Lavrenov",
6
6
  "keywords": [
@@ -67,7 +67,7 @@
67
67
  "functions-have-names": "^1.2.3",
68
68
  "gifuct-js": "^2.1.2",
69
69
  "gradient-parser": "^1.1.1",
70
- "konva": "^10.2.0",
70
+ "konva": "^10.2.3",
71
71
  "mediabunny": "^1.24.1",
72
72
  "mensch": "^0.3.4",
73
73
  "mobx": "6.15.0",
@@ -75,7 +75,6 @@
75
75
  "mobx-state-tree": "7.0.2",
76
76
  "nanoid": "^3.3.11",
77
77
  "quill": "^1.3.7",
78
- "rasterizehtml": "^1.3.1",
79
78
  "react-color": "^2.19.3",
80
79
  "react-konva": "^18.2.14",
81
80
  "react-konva-utils": "^2.0.0",
@@ -160,7 +159,7 @@
160
159
  "minify": "node minify.cjs",
161
160
  "build:schema": "node scripts/generate-schema.cjs",
162
161
  "build": "npm run clean && npm run tsc && npm run add_version && node rename-imports.js && npm run minify && npm run build:bundle && node blueprint-scope.js && cp ./package.json ./lib && cp ./README.md ./lib && cp ./LICENSE.md ./lib && npm run remove-test-from-lib && npm run build:schema",
163
- "remove-test-from-lib": "find . -name \"*.test.js\" -type f -exec rm -f {} \\;",
162
+ "remove-test-from-lib": "find ./lib -type d -name \"__tests__\" -exec rm -rf {} + && find ./lib \\( -name \"*.test.js\" -o -name \"*.test.d.ts\" \\) -type f -delete",
164
163
  "add_version": "sed -i.bak 's/SDK_VERSION/'$npm_package_version'/' ./lib/utils/validate-key.js && rm -f ./lib/utils/validate-key.js.bak",
165
164
  "build:bundle": "parcel build && find ./lib -name '*.js.map' -type f -delete",
166
165
  "size": "npm run build && size-limit",