@grapesjs/studio-sdk-plugins 1.0.22 → 1.0.23

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.
@@ -1,10 +1,11 @@
1
- (function(T,E){typeof exports=="object"&&typeof module<"u"?module.exports=E():typeof define=="function"&&define.amd?define(E):(T=typeof globalThis<"u"?globalThis:T||self,T.StudioSdkPlugins_presetPrintable=E())})(this,function(){"use strict";const T="app.grapesjs.com",E="app-stage.grapesjs.com",H=[T,E,"localhost","127.0.0.1",".local-credentialless.webcontainer.io",".local.webcontainer.io","-sandpack.codesandbox.io"],N="license:check:start",z="license:check:end",K=()=>typeof window<"u",_=(e,n={})=>{const t=V(e)?{id:e,src:e}:e;return new Promise((s,a)=>{var p,d;const o=document.querySelector(`script[src="${t.src}"]`),{id:i}=t;if(o)return(p=n.onScript)==null||p.call(n,o),s(i);const r=document.createElement("script");r.src=t.src,r.onload=()=>s(i),r.onerror=()=>a(i),document.head.appendChild(r),(d=n.onScript)==null||d.call(n,r)})},C=({isDev:e,isStage:n})=>`${e?"":`https://${n?E:T}`}/api`,q=()=>{const e=K()&&window.location.hostname;return!!e&&(H.includes(e)||H.some(n=>e.endsWith(n)))},V=e=>typeof e=="string";async function Y({path:e,baseApiUrl:n,method:t="GET",headers:s={},params:a,body:o}){const r=`${n||C({isDev:!1,isStage:!1})}${e}`,p={method:t,headers:{"Content-Type":"application/json",...s}};o&&(p.body=JSON.stringify(o));const d=a?new URLSearchParams(a).toString():"",c=d?`?${d}`:"",u=await fetch(`${r}${c}`,p);if(!u.ok)throw new Error(`HTTP error! status: ${u.status}`);return u.json()}var k=(e=>(e.free="free",e.startup="startup",e.business="business",e.enterprise="enterprise",e))(k||{}),M=(e=>(e.toastAdd="studio:toastAdd",e.dialogOpen="studio:dialogOpen",e.dialogClose="studio:dialogClose",e.sidebarLeftSet="studio:sidebarLeft:set",e.sidebarLeftGet="studio:sidebarLeft:get",e.sidebarLeftToggle="studio:sidebarLeft:toggle",e.sidebarRightSet="studio:sidebarRight:set",e.sidebarRightGet="studio:sidebarRight:get",e.sidebarRightToggle="studio:sidebarRight:toggle",e.sidebarTopSet="studio:sidebarTop:set",e.sidebarTopGet="studio:sidebarTop:get",e.sidebarTopToggle="studio:sidebarTop:toggle",e.sidebarBottomSet="studio:sidebarBottom:set",e.sidebarBottomGet="studio:sidebarBottom:get",e.sidebarBottomToggle="studio:sidebarBottom:toggle",e.symbolAdd="studio:symbolAdd",e.symbolDetach="studio:symbolDetach",e.symbolOverride="studio:symbolOverride",e.symbolPropagateStyles="studio:propagateStyles",e.getPagesConfig="studio:getPagesConfig",e.setPagesConfig="studio:setPagesConfig",e.getPageSettings="studio:getPageSettings",e.setPageSettings="studio:setPageSettings",e.projectFiles="studio:projectFiles",e.canvasReload="studio:canvasReload",e.getBlocksPanel="studio:getBlocksPanel",e.setBlocksPanel="studio:setBlocksPanel",e.getStateContextMenu="studio:getStateContextMenu",e.setStateContextMenu="studio:setStateContextMenu",e.contextMenuComponent="studio:contextMenuComponent",e.layoutAdd="studio:layoutAdd",e.layoutRemove="studio:layoutRemove",e.layoutToggle="studio:layoutToggle",e.layoutUpdate="studio:layoutUpdate",e.layoutGet="studio:layoutGet",e.layoutConfigGet="studio:layoutConfigGet",e.layoutConfigSet="studio:layoutConfigSet",e.getStateTheme="studio:getStateTheme",e.setStateTheme="studio:setStateTheme",e.assetProviderGet="studio:assetProviderGet",e.assetProviderAdd="studio:assetProviderAdd",e.assetProviderRemove="studio:assetProviderRemove",e.fontGet="studio:fontGet",e.fontAdd="studio:fontAdd",e.fontRemove="studio:fontRemove",e.fontManagerOpen="studio:fontManagerOpen",e.menuFontLoad="studio:menuFontLoad",e.toggleStateDataSource="studio:toggleStateDataSource",e.getStateDataSource="studio:getStateDataSource",e.dataSourceSetGlobalData="studio:dataSourceSetGlobalData",e.dataSourceSetImporter="studio:dataSourceSetImporter",e.dataSourceSetExporter="studio:dataSourceSetExporter",e.setDragAbsolute="studio:setDragAbsolute",e))(M||{});const U={[k.free]:0,[k.startup]:10,[k.business]:20,[k.enterprise]:30};function J(e){const n=e;return n.init=t=>s=>e(s,t),n}const X=e=>J(e);async function Z({editor:e,plan:n,pluginName:t,licenseKey:s,cleanup:a}){let o="",i=!1;const r=q(),p=c=>{console.warn("Cleanup plugin:",t,"Reason:",c),a()},d=(c={})=>{var l;const{error:u,sdkLicense:g}=c,f=(l=c.plan)==null?void 0:l.category;if(!(g||c.license)||u)p(u||"Invalid license");else if(f){const b=U[n],B=U[f];b>B&&p({pluginRequiredPlan:n,licensePlan:f})}};e.on(N,c=>{o=c==null?void 0:c.baseApiUrl,i=!0}),e.on(z,c=>{d(c)}),setTimeout(async()=>{if(!i){if(r)return;if(s){const c=await Q({licenseKey:s,pluginName:t,baseApiUrl:o});c&&d(c)}else p("The `licenseKey` option not provided")}},2e3)}async function Q(e){const{licenseKey:n,pluginName:t,baseApiUrl:s}=e;try{return(await Y({baseApiUrl:s,path:`/sdk/${n||"na"}`,method:"POST",params:{d:window.location.hostname,pn:t}})).result||{}}catch(a){return console.error("Error during SDK license check:",a),!1}}const ee=e=>n=>{var t;return((t=n.getAttribute)==null?void 0:t.call(n,F))===e},te=(...e)=>(n,t)=>e.some(s=>t.is(s)),G=(e,n,t)=>{const{doc:s=document}=t,a=t.target||s.head,o=a.querySelector(`style[${e}]`)||s.createElement("style");o.setAttribute(e,"true"),o.innerHTML=n,!a.contains(o)&&a.appendChild(o)},se="gjs-plg-",O="data-gs-plg-",F="data-type-role";function I(e,n,t){let s,a,o,i,r;const p=n===void 0?100:n;function d(){const u=Date.now()-i;u<p&&u>=0?s=setTimeout(d,p-u):(s=null,r=e.apply(o,a),o=a=null)}const c=function(){return o=this,a=arguments,i=Date.now(),s||(s=setTimeout(d,p)),r};return c.clear=function(){s&&(clearTimeout(s),s=null)},c.flush=function(){s&&(r=e.apply(o,a),o=a=null,clearTimeout(s),s=null)},c}const P="page-break";function $(e,n){const s={mm:3.7795275590551185,cm:37.79527559055118,in:96,pt:1.3333333333333333,pc:16};return s[n]?e*s[n]:null}const ne=(e,n)=>{const{name:t,id:s,width:a,height:o,unit:i}=e,{fixedHeight:r}=n,p=`${a}${i}`,d=`${o}${i}`;return{id:s||t.toLowerCase().replace(/\s/g,"-"),name:`${t} (${p} x ${d})`,sizeH:o,sizeW:a,sizeUnit:i,widthMedia:"",width:p,minHeight:r?"0":`${$(o,i)}px`,height:r?d:void 0}},D="page-breaks",R="gjs-page-breaks-spot",x=e=>e.type===D;function oe(e){const{Devices:n}=e,{height:t,minHeight:s}=n.getSelected().attributes,o=parseFloat(`${t&&t!=="auto"?t:s}`),i=e.getWrapper(),r=i==null?void 0:i.getEl(),p=[];if(!i||!r)return p;const d=r.getBoundingClientRect().height,u=i.findType(P).map(f=>f.getEl()).filter(Boolean).map(f=>({top:f.offsetTop,height:f.offsetHeight}));let g=0;for(;g<d;){const f=u.find(m=>m.top>g&&m.top<g+o);f?(g=f.top+f.height,p.push(f.top)):(g+=o,g<d&&p.push(g))}return p}function ae(e,n){const{Canvas:t}=e,s=t.events,a=e.events;let o;const i=()=>{G(`${O}preset-printable-spots`,`.${R} {
1
+ (function(B,k){typeof exports=="object"&&typeof module<"u"?module.exports=k():typeof define=="function"&&define.amd?define(k):(B=typeof globalThis<"u"?globalThis:B||self,B.StudioSdkPlugins_presetPrintable=k())})(this,function(){"use strict";const B="app.grapesjs.com",k="app-stage.grapesjs.com",M=[B,k,"localhost","127.0.0.1",".local-credentialless.webcontainer.io",".local.webcontainer.io","-sandpack.codesandbox.io"],V="license:check:start",Y="license:check:end",J=()=>typeof window<"u",O=(e,n={})=>{const t=Q(e)?{id:e,src:e}:e;return new Promise((s,a)=>{var l,p;const o=document.querySelector(`script[src="${t.src}"]`),{id:i}=t;if(o)return(l=n.onScript)==null||l.call(n,o),s(i);const r=document.createElement("script");r.src=t.src,r.onload=()=>s(i),r.onerror=()=>a(i),document.head.appendChild(r),(p=n.onScript)==null||p.call(n,r)})},X=({isDev:e,isStage:n})=>`${e?"":`https://${n?k:B}`}/api`,Z=()=>{const e=J()&&window.location.hostname;return!!e&&(M.includes(e)||M.some(n=>e.endsWith(n)))},Q=e=>typeof e=="string";async function ee({path:e,baseApiUrl:n,method:t="GET",headers:s={},params:a,body:o}){const r=`${n||X({isDev:!1,isStage:!1})}${e}`,l={method:t,headers:{"Content-Type":"application/json",...s}};o&&(l.body=JSON.stringify(o));const p=a?new URLSearchParams(a).toString():"",d=p?`?${p}`:"",g=await fetch(`${r}${d}`,l);if(!g.ok)throw new Error(`HTTP error! status: ${g.status}`);return g.json()}var R=(e=>(e.free="free",e.startup="startup",e.business="business",e.enterprise="enterprise",e))(R||{}),I=(e=>(e.toastAdd="studio:toastAdd",e.dialogOpen="studio:dialogOpen",e.dialogClose="studio:dialogClose",e.sidebarLeftSet="studio:sidebarLeft:set",e.sidebarLeftGet="studio:sidebarLeft:get",e.sidebarLeftToggle="studio:sidebarLeft:toggle",e.sidebarRightSet="studio:sidebarRight:set",e.sidebarRightGet="studio:sidebarRight:get",e.sidebarRightToggle="studio:sidebarRight:toggle",e.sidebarTopSet="studio:sidebarTop:set",e.sidebarTopGet="studio:sidebarTop:get",e.sidebarTopToggle="studio:sidebarTop:toggle",e.sidebarBottomSet="studio:sidebarBottom:set",e.sidebarBottomGet="studio:sidebarBottom:get",e.sidebarBottomToggle="studio:sidebarBottom:toggle",e.symbolAdd="studio:symbolAdd",e.symbolDetach="studio:symbolDetach",e.symbolOverride="studio:symbolOverride",e.symbolPropagateStyles="studio:propagateStyles",e.getPagesConfig="studio:getPagesConfig",e.setPagesConfig="studio:setPagesConfig",e.getPageSettings="studio:getPageSettings",e.setPageSettings="studio:setPageSettings",e.projectFiles="studio:projectFiles",e.canvasReload="studio:canvasReload",e.getBlocksPanel="studio:getBlocksPanel",e.setBlocksPanel="studio:setBlocksPanel",e.getStateContextMenu="studio:getStateContextMenu",e.setStateContextMenu="studio:setStateContextMenu",e.contextMenuComponent="studio:contextMenuComponent",e.layoutAdd="studio:layoutAdd",e.layoutRemove="studio:layoutRemove",e.layoutToggle="studio:layoutToggle",e.layoutUpdate="studio:layoutUpdate",e.layoutGet="studio:layoutGet",e.layoutConfigGet="studio:layoutConfigGet",e.layoutConfigSet="studio:layoutConfigSet",e.getStateTheme="studio:getStateTheme",e.setStateTheme="studio:setStateTheme",e.assetProviderGet="studio:assetProviderGet",e.assetProviderAdd="studio:assetProviderAdd",e.assetProviderRemove="studio:assetProviderRemove",e.fontGet="studio:fontGet",e.fontAdd="studio:fontAdd",e.fontRemove="studio:fontRemove",e.fontManagerOpen="studio:fontManagerOpen",e.menuFontLoad="studio:menuFontLoad",e.toggleStateDataSource="studio:toggleStateDataSource",e.getStateDataSource="studio:getStateDataSource",e.dataSourceSetGlobalData="studio:dataSourceSetGlobalData",e.dataSourceSetImporter="studio:dataSourceSetImporter",e.dataSourceSetExporter="studio:dataSourceSetExporter",e.setDragAbsolute="studio:setDragAbsolute",e))(I||{});const F={[R.free]:0,[R.startup]:10,[R.business]:20,[R.enterprise]:30};function te(e){const n=e;return n.init=t=>s=>e(s,t),n}const se=e=>te(e);async function ne({editor:e,plan:n,pluginName:t,licenseKey:s,cleanup:a}){let o="",i=!1;const r=Z(),l=d=>{console.warn("Cleanup plugin:",t,"Reason:",d),a()},p=(d={})=>{var w;const{error:g,sdkLicense:u}=d,f=(w=d.plan)==null?void 0:w.category;if(!(u||d.license)||g)l(g||"Invalid license");else if(f){const c=F[n],h=F[f];c>h&&l({pluginRequiredPlan:n,licensePlan:f})}};e.on(V,d=>{o=d==null?void 0:d.baseApiUrl,i=!0}),e.on(Y,d=>{p(d)}),setTimeout(async()=>{if(!i){if(r)return;if(s){const d=await oe({licenseKey:s,pluginName:t,baseApiUrl:o});d&&p(d)}else l("The `licenseKey` option not provided")}},2e3)}async function oe(e){const{licenseKey:n,pluginName:t,baseApiUrl:s}=e;try{return(await ee({baseApiUrl:s,path:`/sdk/${n||"na"}`,method:"POST",params:{d:window.location.hostname,pn:t}})).result||{}}catch(a){return console.error("Error during SDK license check:",a),!1}}const ae=e=>n=>{var t;return((t=n.getAttribute)==null?void 0:t.call(n,z))===e},ie=(...e)=>(n,t)=>e.some(s=>t.is(s)),N=(e,n,t)=>{const{doc:s=document}=t,a=t.target||s.head,o=a.querySelector(`style[${e}]`)||s.createElement("style");o.setAttribute(e,"true"),o.innerHTML=n,!a.contains(o)&&a.appendChild(o)},re="gjs-plg-",W="data-gs-plg-",z="data-type-role";function K(e,n,t){let s,a,o,i,r;const l=n===void 0?100:n;function p(){const g=Date.now()-i;g<l&&g>=0?s=setTimeout(p,l-g):(s=null,r=e.apply(o,a),o=a=null)}const d=function(){return o=this,a=arguments,i=Date.now(),s||(s=setTimeout(p,l)),r};return d.clear=function(){s&&(clearTimeout(s),s=null)},d.flush=function(){s&&(r=e.apply(o,a),o=a=null,clearTimeout(s),s=null)},d}const T="page-break";var m=(e=>(e.A5="a5",e.A5Portrait="a5-portrait",e.A4="a4",e.A3="a3",e.B5="b5",e.B4="b4",e.letter="letter",e.legal="legal",e.ledger="ledger",e))(m||{});function _(e,n){const s={mm:3.7795275590551185,cm:37.79527559055118,in:96,pt:1.3333333333333333,pc:16};return s[n]?e*s[n]:null}const ce=(e,n)=>{const{name:t,id:s,width:a,height:o,unit:i}=e,{fixedHeight:r}=n,l=`${a}${i}`,p=`${o}${i}`;return{id:s||t.toLowerCase().replace(/\s/g,"-"),name:`${t} (${l} x ${p})`,sizeH:o,sizeW:a,sizeUnit:i,widthMedia:"",width:l,minHeight:r?"0":`${_(o,i)}px`,height:r?p:void 0}},D="page-breaks",x="gjs-page-breaks-spot",H=e=>e.type===D;function le(e){const{Devices:n}=e,{height:t,minHeight:s}=n.getSelected().attributes,o=parseFloat(`${t&&t!=="auto"?t:s}`),i=e.getWrapper(),r=i==null?void 0:i.getEl(),l=[];if(!i||!r)return l;const p=r.getBoundingClientRect().height,g=i.findType(T).map(f=>f.getEl()).filter(Boolean).map(f=>({top:f.offsetTop,height:f.offsetHeight}));let u=0;for(;u<p;){const f=g.find(y=>y.top>u&&y.top<u+o);f?(u=f.top+f.height,l.push(f.top)):(u+=o,u<p&&l.push(u))}return l}function pe(e,n){const{Canvas:t}=e,s=t.events,a=e.events;let o;const i=()=>{N(`${W}preset-printable-spots`,`.${x} {
2
2
  position: absolute;
3
3
  left: 0;
4
4
  width: 100%;
5
5
  border-top: 1px dashed var(--gs-theme-cl-cmp-bg2, var(--gjs-color-blue));
6
+ color: var(--gs-theme-cl-prm-txt, var(--gjs-font-color));
6
7
  }
7
- .${R}::after {
8
+ .${x}::after {
8
9
  background-color: var(--gs-theme-cl-cmp-bg1, var(--gjs-color-highlight));
9
10
  content: attr(data-page-number);
10
11
  display: block;
@@ -15,9 +16,9 @@
15
16
  right: 0;
16
17
  transform: translate(100%, -50%);
17
18
  }
18
- `,{target:window.document.head})},r=()=>{if(n.enablePageBreaksSpot===!1)return;const l={id:D,type:D,component:e.getWrapper()};return t.getSpots(l).pop()||t.addSpot(l)},p=({spot:l})=>{const{spotEl:b}=l.attributes;!x(l)||!b||!o||o.removeChild(b)},d=({spot:l})=>{if(!x(l)||!o)return;let{spotEl:b}=l.attributes;b||(b=document.createElement("div"),b.className=`${R}__items`,l.set({spotEl:b})),o.appendChild(b)},c=({spot:l})=>{const{spotEl:b,pageBreaks:B=[]}=l.attributes;!x(l)||!b||!o||(Object.entries(l.getStyle()).forEach(([A,v])=>b.style.setProperty(A,v)),b.innerHTML="",B.forEach((A,v)=>{const h=document.createElement("div");h.setAttribute("data-page-number",`${v+2}`),h.className=R,h.style.top=`${A}px`,b.appendChild(h)}))},u=I(()=>{if(e.em.destroyed)return;const l=r();l&&l.set({pageBreaks:oe(e),up:(l.attributes.up||0)+1})},150),g=I(u,200),f=()=>{o=t.getSpotsEl(),r()},m=[["component:input",u],[a.update,u],[s.spotAdd,d],[s.spotUpdate,c],[s.spotRemove,p],[s.frameLoadBody,f]];return m.forEach(([l,b])=>e.on(l,b)),e.onReady(()=>{i(),new ResizeObserver(g).observe(t.getElement().parentElement)}),()=>{m.forEach(([l,b])=>e.off(l,b)),u.clear(),g.clear()}}var j=(e=>(e.print="presetPrintable:print",e))(j||{});const W=e=>new Promise(n=>{const t=document.createElement("iframe");t.style.cssText="position: absolute; width: 0; height: 0; border: 0; opacity: 0; pointer-events: none;",t.srcdoc=e.content,t.onload=()=>n(t),document.body.appendChild(t)});function ie(e,n){const{Commands:t,Pages:s}=e;return t.add(j.print,async(a,o,i={})=>{const r={page:i.allPages?void 0:s.getSelected(),styles:"inline",optionsHtml:{exporter:null}},d=(await t.run(M.projectFiles,r)).filter(g=>g.filename.endsWith(".html")),c=d.map(g=>g.content).join('<div style="break-before: page;"></div>'),u=[];if(i.separatePrints)for(const g of d)u.push(await W(g));else u.push(await W({content:c,filename:"",mimeType:""}));for(const g of u){const f=g.contentWindow;f.focus(),f.print()}setTimeout(()=>u.forEach(g=>g.remove()),1e3)}),t.add("presetPrintable:exp",async a=>{await _("https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"),await _("https://cdn.jsdelivr.net/npm/jspdf@3.0.0/dist/jspdf.umd.min.js");const{Devices:o,Canvas:i}=a,{sizeW:r,sizeH:p,sizeUnit:d}=o.getSelected().attributes,c=i.getFrameEl().contentDocument,u="px",g=[$(r,d),$(p,d)],f=new window.jspdf.jsPDF({unit:u,format:g}),m=c.body;f.html(m,{callback:l=>l.save()})}),()=>{delete e.Commands.commands[j.print]}}function re(e,n){const{blockPageBreak:t={}}=n,{Components:s,Blocks:a}=e,o="Page Break",i=`${se}${P}`;return s.addType(P,{block:t&&{label:o,media:'<svg viewBox="0 0 24 24"><path d="M18 20H6v-2H4v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2h-2v2M14 2H6a2 2 0 0 0-2 2v8h2V4h8v4h4v4h2V8l-6-6m-3 14H8v-2h3v2m5 0h-3v-2h3v2M3 14h3v2H3v-2m18 2h-3v-2h3v2Z"/></svg>',category:"Extra",select:!0,...t},isComponent:ee(P),model:{defaults:{name:o,classes:i,attributes:{[F]:P},emptyState:!0,stylable:!1,droppable:!1,draggable:te("wrapper"),styles:`.${i} { break-before: page; }`,traits:[]}}}),()=>{s.removeType(P),a.remove(P)}}const ce="presetPrintable";return X(function(e,n={}){const t={selectedDevice:"a4",...n},{Canvas:s,Devices:a}=e,o=s.events,i=e.events,r=t.selectedDevice||a.getConfig().default,d=[{name:"A5",width:148,height:210,unit:"mm"},{name:"A5 Portrait",width:210,height:148,unit:"mm"},{name:"A4",width:210,height:297,unit:"mm"},{name:"A3",width:297,height:420,unit:"mm"},{name:"B5",width:176,height:250,unit:"mm"},{name:"B4",width:250,height:353,unit:"mm"},{name:"Letter",width:8.5,height:11,unit:"in"},{name:"Legal",width:8.5,height:14,unit:"in"},{name:"Ledger",width:11,height:17,unit:"in"}].map(v=>ne(v,t));a.devices.reset(d);const c=r&&a.get(r)||a.getAll().at(0);a.select(c);const u=()=>{const v="page-rule",{rules:h}=e.Css,{width:w,height:y,minHeight:S}=a.getSelected().attributes,L=y&&y!=="auto"?y:S;(h.where({id:v}).pop()||h.add({id:v,selectors:[],selectorsAdd:"@page"},{at:0})).setStyle({size:`${w} ${L}`,margin:"0"})},g=v=>{const h=v.document,{minHeight:w}=a.getSelected().attributes,S=`
19
- ${!!parseFloat(`${w}`)?`
20
- [data-gjs-type="wrapper"] { min-height: ${w}; }
19
+ `,{target:window.document.head})},r=()=>{if(n.enablePageBreaksSpot===!1)return;const c={id:D,type:D,component:e.getWrapper()};return t.getSpots(c).pop()||t.addSpot(c)},l=({spot:c})=>{const{spotEl:h}=c.attributes;!H(c)||!h||!o||o.removeChild(h)},p=({spot:c})=>{if(!H(c)||!o)return;let{spotEl:h}=c.attributes;h||(h=document.createElement("div"),h.className=`${x}__items`,c.set({spotEl:h})),o.appendChild(h)},d=({spot:c})=>{const{spotEl:h,pageBreaks:G=[]}=c.attributes;!H(c)||!h||!o||(Object.entries(c.getStyle()).forEach(([S,L])=>h.style.setProperty(S,L)),h.innerHTML="",G.forEach((S,L)=>{const E=document.createElement("div");E.setAttribute("data-page-number",`${L+2}`),E.className=x,E.style.top=`${S}px`,h.appendChild(E)}))},g=K(()=>{if(e.em.destroyed)return;const c=r();c&&c.set({pageBreaks:le(e),up:(c.attributes.up||0)+1})},150),u=K(g,200),f=()=>{o=t.getSpotsEl(),r()},y=()=>{const c=r();c&&c.set({up:(c.attributes.up||0)+1})},w=[["component:input",g],["frame:scroll",y],[a.update,g],[s.spotAdd,p],[s.spotUpdate,d],[s.spotRemove,l],[s.frameLoadBody,f]];return w.forEach(([c,h])=>e.on(c,h)),e.onReady(()=>{i(),new ResizeObserver(y).observe(t.getElement().parentElement)}),()=>{w.forEach(([c,h])=>e.off(c,h)),g.clear(),u.clear()}}var U=(e=>(e.print="presetPrintable:print",e))(U||{});const C=e=>new Promise(n=>{const t=document.createElement("iframe");t.style.cssText="position: absolute; width: 0; height: 0; border: 0; opacity: 0; pointer-events: none;",t.srcdoc=e.content,t.onload=()=>n(t),document.body.appendChild(t)});function de(e,n){const{Commands:t,Pages:s}=e;return t.add(U.print,async(a,o,i={})=>{const r={page:i.allPages?void 0:s.getSelected(),styles:"inline",optionsHtml:{exporter:null}},p=(await t.run(I.projectFiles,r)).filter(u=>u.filename.endsWith(".html")),d=p.map(u=>u.content).join('<div style="break-before: page;"></div>'),g=[];if(i.separatePrints)for(const u of p)g.push(await C(u));else g.push(await C({content:d,filename:"",mimeType:""}));for(const u of g){const f=u.contentWindow;f.focus(),f.print()}setTimeout(()=>g.forEach(u=>u.remove()),1e3)}),t.add("presetPrintable:exp",async a=>{await O("https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"),await O("https://cdn.jsdelivr.net/npm/jspdf@3.0.0/dist/jspdf.umd.min.js");const{Devices:o,Canvas:i}=a,{sizeW:r,sizeH:l,sizeUnit:p}=o.getSelected().attributes,d=i.getFrameEl().contentDocument,g="px",u=[_(r,p),_(l,p)],f=new window.jspdf.jsPDF({unit:g,format:u}),y=d.body;f.html(y,{callback:w=>w.save()})}),()=>{delete e.Commands.commands[U.print]}}function ge(e,n){const{blockPageBreak:t={}}=n,{Components:s,Blocks:a}=e,o="Page Break",i=`${re}${T}`;return s.addType(T,{block:t&&{label:o,media:'<svg viewBox="0 0 24 24"><path d="M18 20H6v-2H4v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2h-2v2M14 2H6a2 2 0 0 0-2 2v8h2V4h8v4h4v4h2V8l-6-6m-3 14H8v-2h3v2m5 0h-3v-2h3v2M3 14h3v2H3v-2m18 2h-3v-2h3v2Z"/></svg>',category:"Extra",select:!0,...t},isComponent:ae(T),model:{defaults:{name:o,classes:i,attributes:{[z]:T},emptyState:!0,stylable:!1,droppable:!1,draggable:ie("wrapper"),styles:`.${i} { break-before: page; }`,traits:[]}}}),()=>{s.removeType(T),a.remove(T)}}const ue="presetPrintable",he=R.free;return se(function(e,n={}){var q;const t={selectedDevice:m.A4,...n},{Canvas:s,Devices:a,Blocks:o}=e,i=s.events,r=e.events,l=t.selectedDevice||a.getConfig().default,p=[{id:m.A5,name:"A5",width:148,height:210,unit:"mm"},{id:m.A5Portrait,name:"A5 Portrait",width:210,height:148,unit:"mm"},{id:m.A4,name:"A4",width:210,height:297,unit:"mm"},{id:m.A3,name:"A3",width:297,height:420,unit:"mm"},{id:m.B5,name:"B5",width:176,height:250,unit:"mm"},{id:m.B4,name:"B4",width:250,height:353,unit:"mm"},{id:m.letter,name:"Letter",width:8.5,height:11,unit:"in"},{id:m.legal,name:"Legal",width:8.5,height:14,unit:"in"},{id:m.ledger,name:"Ledger",width:11,height:17,unit:"in"}],g=(((q=t.devices)==null?void 0:q.call(t,{items:p}))||p).map(v=>ce(v,t));a.devices.reset(g);const u=l&&a.get(l)||a.getAll().at(0);a.select(u),["map","video"].forEach(v=>o.remove(v));const y=()=>{const v="page-rule",{rules:b}=e.Css,{width:A,height:P,minHeight:$}=a.getSelected().attributes,j=P&&P!=="auto"?P:$;(b.where({id:v}).pop()||b.add({id:v,selectors:[],selectorsAdd:"@page"},{at:0})).setStyle({size:`${A} ${j}`,margin:"0"})},w=v=>{const b=v.document,{minHeight:A}=a.getSelected().attributes,$=`
20
+ ${!!parseFloat(`${A}`)?`
21
+ [data-gjs-type="wrapper"] { min-height: ${A}; }
21
22
  `:`
22
23
  body {
23
24
  overflow: hidden;
@@ -28,4 +29,4 @@
28
29
  height: 100dvh;
29
30
  }
30
31
  `}
31
- `;G(`${O}preset-printable`,S,{doc:h,target:h.head}),u()};e.on(o.frameLoadBody,v=>{const h=v.window;if(g(h),t.fixedHeight){const y=v.model.getComponent().getEl();y==null||y.addEventListener("scroll",S=>{const L=S.target;L.scrollTop>0&&L.scrollTo(0,0)})}}),e.on(a.events.select,()=>{var h;const v=(h=s.getFrameEl().contentDocument)==null?void 0:h.defaultView;v&&g(v)});const f=()=>{const h=e.Css.getRules().filter(w=>w.selectorsToString()==="body").pop();h==null||h.addStyle({"margin-top":"","margin-right":"","margin-bottom":"","margin-left":"",margin:"0"})},m=[[i.projectLoad,f]];m.forEach(([v,h])=>e.on(v,h));const l=ae(e,t),b=ie(e),B=re(e,t);e.onReady(()=>{e.UndoManager.clear()});const A=()=>{m.forEach(([v,h])=>e.off(v,h)),l(),b(),B()};e.on(i.destroy,A),Z({editor:e,licenseKey:t.licenseKey,plan:k.startup,pluginName:ce,cleanup:A})})});
32
+ `;N(`${W}preset-printable`,$,{doc:b,target:b.head}),y()};e.on(i.frameLoadBody,v=>{const b=v.window;if(w(b),t.fixedHeight){const P=v.model.getComponent().getEl();P==null||P.addEventListener("scroll",$=>{const j=$.target;j.scrollTop>0&&j.scrollTo(0,0)})}}),e.on(a.events.select,()=>{var b;const v=(b=s.getFrameEl().contentDocument)==null?void 0:b.defaultView;v&&w(v)});const c=()=>{const b=e.Css.getRules().filter(A=>A.selectorsToString()==="body").pop();b==null||b.addStyle({"margin-top":"","margin-right":"","margin-bottom":"","margin-left":"",margin:"0"})},h=[[r.projectLoad,c]];h.forEach(([v,b])=>e.on(v,b));const G=pe(e,t),S=de(e),L=ge(e,t);e.onReady(()=>{e.UndoManager.clear()});const E=()=>{h.forEach(([v,b])=>e.off(v,b)),G(),S(),L()};e.on(r.destroy,E),ne({editor:e,licenseKey:t.licenseKey,plan:he,pluginName:ue,cleanup:E})})});
@@ -0,0 +1,3 @@
1
+ import { SdkPlanCategories } from '../utils';
2
+ export declare const PLUGIN_NAME = "presetPrintable";
3
+ export declare const PLUGIN_PLAN = SdkPlanCategories.free;
@@ -1,7 +1,10 @@
1
1
  import { BlockProperties, CanvasSpotProps, DeviceProperties } from 'grapesjs';
2
2
  import { PresetPrintableOptions as PresetPrintableOptionsSchema } from './typesSchema';
3
- export interface PresetPrintableOptions extends Omit<PresetPrintableOptionsSchema, 'blockPageBreak'> {
3
+ export interface PresetPrintableOptions extends Omit<PresetPrintableOptionsSchema, 'blockPageBreak' | 'devices'> {
4
4
  blockPageBreak?: Partial<BlockProperties> | false;
5
+ devices?: (props: {
6
+ items: CreateDevicePrintableProps[];
7
+ }) => CreateDevicePrintableProps[];
5
8
  }
6
9
  export interface DevicePrintableProps extends DeviceProperties {
7
10
  minHeight?: string;
@@ -11,8 +11,26 @@ export interface PresetPrintableOptions extends SDKPluginOptions {
11
11
  * @default false
12
12
  */
13
13
  fixedHeight?: boolean;
14
+ /**
15
+ * Customize the printable devices.
16
+ * @examples
17
+ * devices: ({ items }) => {
18
+ * return [
19
+ * ...items,
20
+ * {
21
+ * id: 'custom',
22
+ * name: 'Custom',
23
+ * width: 100,
24
+ * height: 200,
25
+ * unit: 'mm'
26
+ * }
27
+ * ]
28
+ * }
29
+ */
30
+ devices?: '__fn__';
14
31
  /**
15
32
  * Selected device id.
33
+ * Available printable sizes: 'a5', 'a5-portrait', 'a4', 'a3', 'b5', 'b4', 'letter', 'legal', 'ledger'.
16
34
  * @default "a4"
17
35
  */
18
36
  selectedDevice?: string;
@@ -1,4 +1,15 @@
1
1
  import { CreateDevicePrintableProps, DevicePrintableProps, PresetPrintableOptions } from './types';
2
2
  export declare const typePageBreak = "page-break";
3
+ export declare enum PrintableDevices {
4
+ A5 = "a5",
5
+ A5Portrait = "a5-portrait",
6
+ A4 = "a4",
7
+ A3 = "a3",
8
+ B5 = "b5",
9
+ B4 = "b4",
10
+ letter = "letter",
11
+ legal = "legal",
12
+ ledger = "ledger"
13
+ }
3
14
  export declare function convertToPx(value: number, unit: string): number | null;
4
15
  export declare const createDevicePrintable: (props: CreateDevicePrintableProps, opts: PresetPrintableOptions) => DevicePrintableProps;
package/jest.config.js ADDED
@@ -0,0 +1,9 @@
1
+ /** @type {import('ts-jest').JestConfigWithTsJest} */
2
+ module.exports = {
3
+ preset: 'ts-jest',
4
+ testEnvironment: 'jsdom',
5
+ moduleNameMapper: {
6
+ '^@/(.*)$': '<rootDir>/src/$1'
7
+ },
8
+ testMatch: ['**/*.test.ts']
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grapesjs/studio-sdk-plugins",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org"
6
6
  },
@@ -16,10 +16,12 @@
16
16
  "sideEffects": false,
17
17
  "scripts": {
18
18
  "build": "tsx build",
19
- "buid:main": "tsx build-main"
19
+ "build:main": "tsx build-main",
20
+ "test": "jest"
20
21
  },
21
22
  "devDependencies": {
22
23
  "grapesjs": "^0.22.7",
24
+ "jest-environment-jsdom": "^30.0.0-beta.3",
23
25
  "tinymce": "^6.8.5",
24
26
  "tsx": "^4.19.1",
25
27
  "typescript": "^5.6.2",