UNPKG

@silexlabs/grapesjs-fonts

Version:
81 lines (77 loc) 25 kB
/*! @silexlabs/grapesjs-fonts - 1.2.2 */ !function(t,e){'object'==typeof exports&&'object'==typeof module?module.exports=e():'function'==typeof define&&define.amd?define([],e):'object'==typeof exports?exports["@silexlabs/grapesjs-fonts"]=e():t["@silexlabs/grapesjs-fonts"]=e()}('undefined'!=typeof globalThis?globalThis:'undefined'!=typeof window?window:this,(()=>(()=>{"use strict";var t={d:(e,s)=>{for(var n in s)t.o(s,n)&&!t.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:s[n]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{'undefined'!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:'Module'}),Object.defineProperty(t,'__esModule',{value:!0})}},e={};t.r(e),t.d(e,{cmdFontsAvailable:()=>St,cmdFontsInstall:()=>kt,cmdFontsInstalled:()=>Nt,cmdFontsRemove:()=>Mt,cmdGetCss:()=>jt,cmdGetHtml:()=>It,cmdOpenFonts:()=>ot,default:()=>Pt,fontsDialogPlugin:()=>ut,getApiUrl:()=>ht,getAvailableFonts:()=>gt,getHtml:()=>Ct,loadFontList:()=>pt,refresh:()=>wt});const s=globalThis,n=s.trustedTypes,o=n?n.createPolicy("lit-html",{createHTML:t=>t}):void 0,i="$lit$",r=`lit$${Math.random().toFixed(9).slice(2)}$`,a="?"+r,l=`<${a}>`,c=document,d=()=>c.createComment(""),f=t=>null===t||"object"!=typeof t&&"function"!=typeof t,g=Array.isArray,h=t=>g(t)||"function"==typeof t?.[Symbol.iterator],p="[ \t\n\f\r]",u=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,m=/-->/g,$=/>/g,v=RegExp(`>|${p}(?:([^\\s"'>=/]+)(${p}*=${p}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),y=/'/g,A=/"/g,_=/^(?:script|style|textarea|title)$/i,b=t=>(e,...s)=>({_$litType$:t,strings:e,values:s}),x=b(1),w=(b(2),b(3),Symbol.for("lit-noChange")),C=Symbol.for("lit-nothing"),j=new WeakMap,I=c.createTreeWalker(c,129);function N(t,e){if(!g(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==o?o.createHTML(e):e}const S=(t,e)=>{const s=t.length-1,n=[];let o,a=2===e?"<svg>":3===e?"<math>":"",c=u;for(let e=0;e<s;e++){const s=t[e];let d,f,g=-1,h=0;for(;h<s.length&&(c.lastIndex=h,f=c.exec(s),null!==f);)h=c.lastIndex,c===u?"!--"===f[1]?c=m:void 0!==f[1]?c=$:void 0!==f[2]?(_.test(f[2])&&(o=RegExp("</"+f[2],"g")),c=v):void 0!==f[3]&&(c=v):c===v?">"===f[0]?(c=o??u,g=-1):void 0===f[1]?g=-2:(g=c.lastIndex-f[2].length,d=f[1],c=void 0===f[3]?v:'"'===f[3]?A:y):c===A||c===y?c=v:c===m||c===$?c=u:(c=v,o=void 0);const p=c===v&&t[e+1].startsWith("/>")?" ":"";a+=c===u?s+l:g>=0?(n.push(d),s.slice(0,g)+i+s.slice(g)+r+p):s+r+(-2===g?e:p)}return[N(t,a+(t[s]||"<?>")+(2===e?"</svg>":3===e?"</math>":"")),n]};class k{constructor({strings:t,_$litType$:e},s){let o;this.parts=[];let l=0,c=0;const f=t.length-1,g=this.parts,[h,p]=S(t,e);if(this.el=k.createElement(h,s),I.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(o=I.nextNode())&&g.length<f;){if(1===o.nodeType){if(o.hasAttributes())for(const t of o.getAttributeNames())if(t.endsWith(i)){const e=p[c++],s=o.getAttribute(t).split(r),n=/([.?@])?(.*)/.exec(e);g.push({type:1,index:l,name:n[2],strings:s,ctor:"."===n[1]?E:"?"===n[1]?F:"@"===n[1]?G:P}),o.removeAttribute(t)}else t.startsWith(r)&&(g.push({type:6,index:l}),o.removeAttribute(t));if(_.test(o.tagName)){const t=o.textContent.split(r),e=t.length-1;if(e>0){o.textContent=n?n.emptyScript:"";for(let s=0;s<e;s++)o.append(t[s],d()),I.nextNode(),g.push({type:2,index:++l});o.append(t[e],d())}}}else if(8===o.nodeType)if(o.data===a)g.push({type:2,index:l});else{let t=-1;for(;-1!==(t=o.data.indexOf(r,t+1));)g.push({type:7,index:l}),t+=r.length-1}l++}}static createElement(t,e){const s=c.createElement("template");return s.innerHTML=t,s}}function M(t,e,s=t,n){if(e===w)return e;let o=void 0!==n?s._$Co?.[n]:s._$Cl;const i=f(e)?void 0:e._$litDirective$;return o?.constructor!==i&&(o?._$AO?.(!1),void 0===i?o=void 0:(o=new i(t),o._$AT(t,s,n)),void 0!==n?(s._$Co??=[])[n]=o:s._$Cl=o),void 0!==o&&(e=M(t,o._$AS(t,e.values),o,n)),e}class T{constructor(t,e){this._$AV=[],this._$AN=void 0,this._$AD=t,this._$AM=e}get parentNode(){return this._$AM.parentNode}get _$AU(){return this._$AM._$AU}u(t){const{el:{content:e},parts:s}=this._$AD,n=(t?.creationScope??c).importNode(e,!0);I.currentNode=n;let o=I.nextNode(),i=0,r=0,a=s[0];for(;void 0!==a;){if(i===a.index){let e;2===a.type?e=new H(o,o.nextSibling,this,t):1===a.type?e=new a.ctor(o,a.name,a.strings,this,t):6===a.type&&(e=new O(o,this,t)),this._$AV.push(e),a=s[++r]}i!==a?.index&&(o=I.nextNode(),i++)}return I.currentNode=c,n}p(t){let e=0;for(const s of this._$AV)void 0!==s&&(void 0!==s.strings?(s._$AI(t,s,e),e+=s.strings.length-2):s._$AI(t[e])),e++}}class H{get _$AU(){return this._$AM?._$AU??this._$Cv}constructor(t,e,s,n){this.type=2,this._$AH=C,this._$AN=void 0,this._$AA=t,this._$AB=e,this._$AM=s,this.options=n,this._$Cv=n?.isConnected??!0}get parentNode(){let t=this._$AA.parentNode;const e=this._$AM;return void 0!==e&&11===t?.nodeType&&(t=e.parentNode),t}get startNode(){return this._$AA}get endNode(){return this._$AB}_$AI(t,e=this){t=M(this,t,e),f(t)?t===C||null==t||""===t?(this._$AH!==C&&this._$AR(),this._$AH=C):t!==this._$AH&&t!==w&&this._(t):void 0!==t._$litType$?this.$(t):void 0!==t.nodeType?this.T(t):h(t)?this.k(t):this._(t)}O(t){return this._$AA.parentNode.insertBefore(t,this._$AB)}T(t){this._$AH!==t&&(this._$AR(),this._$AH=this.O(t))}_(t){this._$AH!==C&&f(this._$AH)?this._$AA.nextSibling.data=t:this.T(c.createTextNode(t)),this._$AH=t}$(t){const{values:e,_$litType$:s}=t,n="number"==typeof s?this._$AC(t):(void 0===s.el&&(s.el=k.createElement(N(s.h,s.h[0]),this.options)),s);if(this._$AH?._$AD===n)this._$AH.p(e);else{const t=new T(n,this),s=t.u(this.options);t.p(e),this.T(s),this._$AH=t}}_$AC(t){let e=j.get(t.strings);return void 0===e&&j.set(t.strings,e=new k(t)),e}k(t){g(this._$AH)||(this._$AH=[],this._$AR());const e=this._$AH;let s,n=0;for(const o of t)n===e.length?e.push(s=new H(this.O(d()),this.O(d()),this,this.options)):s=e[n],s._$AI(o),n++;n<e.length&&(this._$AR(s&&s._$AB.nextSibling,n),e.length=n)}_$AR(t=this._$AA.nextSibling,e){for(this._$AP?.(!1,!0,e);t&&t!==this._$AB;){const e=t.nextSibling;t.remove(),t=e}}setConnected(t){void 0===this._$AM&&(this._$Cv=t,this._$AP?.(t))}}class P{get tagName(){return this.element.tagName}get _$AU(){return this._$AM._$AU}constructor(t,e,s,n,o){this.type=1,this._$AH=C,this._$AN=void 0,this.element=t,this.name=e,this._$AM=n,this.options=o,s.length>2||""!==s[0]||""!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=C}_$AI(t,e=this,s,n){const o=this.strings;let i=!1;if(void 0===o)t=M(this,t,e,0),i=!f(t)||t!==this._$AH&&t!==w,i&&(this._$AH=t);else{const n=t;let r,a;for(t=o[0],r=0;r<o.length-1;r++)a=M(this,n[s+r],e,r),a===w&&(a=this._$AH[r]),i||=!f(a)||a!==this._$AH[r],a===C?t=C:t!==C&&(t+=(a??"")+o[r+1]),this._$AH[r]=a}i&&!n&&this.j(t)}j(t){t===C?this.element.removeAttribute(this.name):this.element.setAttribute(this.name,t??"")}}class E extends P{constructor(){super(...arguments),this.type=3}j(t){this.element[this.name]=t===C?void 0:t}}class F extends P{constructor(){super(...arguments),this.type=4}j(t){this.element.toggleAttribute(this.name,!!t&&t!==C)}}class G extends P{constructor(t,e,s,n,o){super(t,e,s,n,o),this.type=5}_$AI(t,e=this){if((t=M(this,t,e,0)??C)===w)return;const s=this._$AH,n=t===C&&s!==C||t.capture!==s.capture||t.once!==s.once||t.passive!==s.passive,o=t!==C&&(s===C||n);n&&this.element.removeEventListener(this.name,this,s),o&&this.element.addEventListener(this.name,this,t),this._$AH=t}handleEvent(t){"function"==typeof this._$AH?this._$AH.call(this.options?.host??this.element,t):this._$AH.handleEvent(t)}}class O{constructor(t,e,s){this.element=t,this.type=6,this._$AN=void 0,this._$AM=e,this.options=s}get _$AU(){return this._$AM._$AU}_$AI(t){M(this,t)}}const R={M:i,P:r,A:a,C:1,L:S,R:T,D:h,V:M,I:H,H:P,N:F,U:G,B:E,F:O},U=s.litHtmlPolyfillSupport;U?.(k,H),(s.litHtmlVersions??=[]).push("3.3.0");function*L(t,e){if(void 0!==t){let s=0;for(const n of t)yield e(n,s++)}}const{I:V}=R,B=2;class z{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,s){this._$Ct=t,this._$AM=e,this._$Ci=s}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}const D=(t,e)=>{const s=t._$AN;if(void 0===s)return!1;for(const t of s)t._$AO?.(e,!1),D(t,e);return!0},W=t=>{let e,s;do{if(void 0===(e=t._$AM))break;s=e._$AN,s.delete(t),t=e}while(0===s?.size)},q=t=>{for(let e;e=t._$AM;t=e){let s=e._$AN;if(void 0===s)e._$AN=s=new Set;else if(s.has(t))break;s.add(t),K(e)}};function J(t){void 0!==this._$AN?(W(this),this._$AM=t,q(this)):this._$AM=t}function Y(t,e=!1,s=0){const n=this._$AH,o=this._$AN;if(void 0!==o&&0!==o.size)if(e)if(Array.isArray(n))for(let t=s;t<n.length;t++)D(n[t],!1),W(n[t]);else null!=n&&(D(n,!1),W(n));else D(this,t)}const K=t=>{t.type==B&&(t._$AP??=Y,t._$AQ??=J)};class Z extends z{constructor(){super(...arguments),this._$AN=void 0}_$AT(t,e,s){super._$AT(t,e,s),q(this),this.isConnected=t._$AU}_$AO(t,e=!0){t!==this.isConnected&&(this.isConnected=t,t?this.reconnected?.():this.disconnected?.()),e&&(D(this,t),W(this))}setValue(t){if((t=>void 0===t.strings)(this._$Ct))this._$Ct._$AI(t,this);else{const e=[...this._$Ct._$AH];e[this._$Ci]=t,this._$Ct._$AI(e,this,0)}}disconnected(){}reconnected(){}}class Q{}const X=new WeakMap,tt=(t=>(...e)=>({_$litDirective$:t,values:e}))(class extends Z{render(t){return C}update(t,[e]){const s=e!==this.G;return s&&void 0!==this.G&&this.rt(void 0),(s||this.lt!==this.ct)&&(this.G=e,this.ht=t.options?.host,this.rt(this.ct=t.element)),C}rt(t){if(this.isConnected||(t=void 0),"function"==typeof this.G){const e=this.ht??globalThis;let s=X.get(e);void 0===s&&(s=new WeakMap,X.set(e,s)),void 0!==s.get(this.G)&&this.G.call(this.ht,void 0),s.set(this.G,t),void 0!==t&&this.G.call(this.ht,t)}else this.G.value=t}get lt(){return"function"==typeof this.G?X.get(this.ht??globalThis)?.get(this.G):this.G?.value}disconnected(){this.lt===this.ct&&this.rt(void 0)}reconnected(){this.rt(this.ct)}}),et=document.createElement('div'),st=document.createElement('style');let nt;st.textContent=`\n .gfonts-section { padding: 8px 0 }\n .gfonts-list { list-style: none; padding: 0; margin: 0 }\n .gfonts-item { padding: 10px 12px; border: 1px solid var(--gjs-light-border); border-radius: 8px; margin-bottom: 10px; background: transparent; color: var(--gjs-font-color) }\n .gfonts-item strong { display: block; font-size: 14px; margin-bottom: 4px; color: var(--gjs-font-color-active) }\n .gfonts-item p { margin: 0 0 8px 0; color: var(--gjs-font-color); font-size: 12px }\n .variants-toolbar { display: flex; align-items: center; gap: 8px; margin: 6px 0 }\n .variants-grid { display: flex; flex-wrap: wrap; gap: 6px }\n .variants-grid label { background: var(--gjs-soft-light-color); border-radius: 4px; padding: 4px 6px; cursor: pointer; border: 1px solid transparent; color: var(--gjs-font-color) }\n .variants-grid input { margin: 0 }\n .gfonts-preview { padding: 6px; border: 1px solid var(--gjs-light-border); border-radius: 8px; background: var(--gjs-soft-light-color); margin: 6px 0 8px }\n .preview-iframe { width: 100%; border: 0; height: 56px; background: transparent }\n .silex-bar, .pagination-controls { display: flex; gap: 8px; align-items: center }\n .silex-list { list-style: none; margin: 0; padding: 0 }\n .silex-list > li { list-style: none }\n fieldset.silex-group--simple { border: 0; padding: 0; margin: 0 }\n fieldset.silex-group--simple legend { margin: 0; color: var(--gjs-font-color); font-size: 12px }\n .gfonts-toolbar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap }\n .gfonts-toolbar select, .gfonts-toolbar input { background: var(--gjs-main-light-color); color: var(--gjs-font-color); border: 1px solid var(--gjs-light-border); border-radius: 4px; padding: 4px 6px }\n .gfonts-toolbar .silex-button { background: var(--gjs-main-light-color); color: var(--gjs-font-color); border: 1px solid var(--gjs-light-border) }\n .gfonts-pager { margin-left: auto; display: inline-flex; gap: 6px; align-items: center; color: var(--gjs-font-color) }\n .gfonts-pager .page { opacity: .8 }\n .gfonts-actions { display: flex; gap: 8px; margin-top: 6px }\n .gfonts-btn--ghost { background: transparent; border: 1px solid var(--gjs-light-border); color: var(--gjs-font-color); padding: 2px 6px; font-size: 11px }\n .gfonts-btn--danger { background: transparent; border: 1px solid var(--gjs-color-red); color: var(--gjs-color-red) }\n`,document.head.appendChild(st);const ot='open-fonts',it='silex-loaded-fonts-list';let rt,at=[],lt=[],ct='https://fonts.googleapis.com',dt='https://www.googleapis.com';try{rt=JSON.parse(localStorage.getItem(it))}catch(i){console.error('Could not get fonts from local storage:',i)}function ft(t,e){t.getModel().set('fonts',at),_t(t,at),bt(t,at,e)}function gt(){return rt}function ht(){return dt}async function pt(t){return rt=rt??(await(await fetch(t)).json())?.items,localStorage.setItem(it,JSON.stringify(rt)),await async function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return new Promise((e=>setTimeout((()=>e()),t)))}(),rt}const ut=(t,e)=>{if(lt=t.StyleManager.getBuiltIn('font-family').options||[],e.server_url&&(ct=e.server_url),e.api_url&&(dt=e.api_url),!e.api_key)throw new Error(t.I18n.t('grapesjs-fonts.You must provide Google font api key'));let s;t.Commands.add(ot,{run:()=>(nt=t.Modal.open({title:t.I18n.t('grapesjs-fonts.Fonts'),content:'',attributes:{class:'fonts-dialog'}}).onceClose((()=>{t.stopCommand(ot)})),nt.setContent(et),async function(t){at=structuredClone(t.getModel().get('fonts')||[]).map((t=>({...t,variants:t.variants||[]})))}(t),yt(t,e),pt(`${dt}/webfonts/v1/webfonts?key=${e.api_key}`).then((s=>{yt(t,e,s)})),nt),stop:()=>{nt.close()}}),t.on('storage:start:store',(e=>{e.fonts=t.getModel().get('fonts')}));const n=()=>{clearTimeout(s),s=setTimeout((()=>wt(t,e)),50)};t.on('storage:end:load',(e=>{const s=e.fonts||[];t.getModel().set('fonts',s),n()})),t.on('canvas:frame:load',(()=>{n()})),t.on('page',(()=>{n()}))},mt=new Q;let $t=0,vt='';function yt(t,e){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[];const n=mt.value,o=10;let i=JSON.parse(JSON.stringify(s));const r=i.filter((t=>{const e=function(t,e){return t.toLowerCase().includes(e.toLowerCase())}(t.family,n?.value||''),s=!vt||t.category===vt;return e&&s}));let a=Math.ceil(r.length/o);const l=Array.from(new Set((s||[]).map((t=>t.category)).filter(Boolean))).sort();$t>=a&&($t=Math.max(0,a-1));const c=r.slice($t*o,($t+1)*o);((t,e,s)=>{const n=s?.renderBefore??e;let o=n._$litPart$;if(void 0===o){const t=s?.renderBefore??null;n._$litPart$=o=new H(e.insertBefore(d(),t),t,void 0,s??{})}o._$AI(t)})(x` <div> <div class="silex-form__element"> <h2>${t.I18n.t('grapesjs-fonts.Installed fonts')}</h2> <ul class="silex-list"> ${at&&at.length?L(at,(n=>x` <li class="gfonts-item"> <strong>${n.family||'Unknown Font'}</strong> <p>${n.category||(rt||[]).find((t=>t.family===n.family))?.category||'No category'} - ${n.variants?.length||0} variants</p> <div class="gfonts-preview"> ${At(n)} </div> <fieldset class="silex-group--simple full-width"> <div class="variants-toolbar"> <legend>${t.I18n.t('grapesjs-fonts.Variants')||'Variants'}</legend> <button class="silex-button gfonts-btn--ghost" type="button" @click=${()=>{const o=(rt||[]).find((t=>t.family===n.family))?.variants||[],i=Array.isArray(n.variants)&&o.length&&o.every((t=>n.variants.includes(t)));n.variants=i?[]:[...o],ft(t,e),yt(t,e,s)}}>${t.I18n.t('grapesjs-fonts.Toggle all')||'Toggle all'}</button> </div> <div class="variants-grid"> ${L((rt||[]).find((t=>t.family===n.family))?.variants||[],(o=>x` <label> <input type="checkbox" .checked=${(n.variants||[]).includes(o)} @change=${i=>{const r=i.target.checked;n.variants=Array.isArray(n.variants)?n.variants:[];const a=n.variants.includes(o);r&&!a&&(n.variants=[...n.variants,o]),!r&&a&&(n.variants=n.variants.filter((t=>t!==o))),ft(t,e),yt(t,e,s)}} /> ${o} </label> `))} </div> </fieldset> <div class="gfonts-actions"> <button class="silex-button gfonts-btn--danger" type="button" @click=${()=>{at=at.filter((t=>t.family!==n.family)),ft(t,e),yt(t,e,s)}}>${t.I18n.t('grapesjs-fonts.Remove')}</button> </div> </li> `)):x`<li class="gfonts-item" style="border-style:dashed; text-align:center; font-style:italic; color: var(--gjs-secondary-light-color)">${t.I18n.t('grapesjs-fonts.No installed fonts')||'No installed fonts yet'}</li>`} </ul> </div> <div> <h2>${t.I18n.t('grapesjs-fonts.All fonts')||'All fonts'}</h2> <div class="silex-bar gfonts-toolbar"> <select @change=${n=>{vt=n.target.value||'',$t=0,yt(t,e,s)}}> <option value="">All categories</option> ${l.map((t=>x`<option value=${t} ?selected=${vt===t}>${t}</option>`))} </select> <input type="text" ${tt(mt)} @input=${()=>{$t=0,yt(t,e,s)}} placeholder="${t.I18n.t('grapesjs-fonts.Search')}" /> <div class="gfonts-pager"> <button class="silex-button" ?disabled=${0===$t} @click=${()=>{$t>0&&($t--,yt(t,e,s))}}>${t.I18n.t('grapesjs-fonts.Previous Page')}</button> <span class="page">Page ${$t+1} / ${a}</span> <button class="silex-button" ?disabled=${$t===a-1} @click=${()=>{$t<a-1&&($t++,yt(t,e,s))}}>${t.I18n.t('grapesjs-fonts.Next Page')}</button> </div> </div> <ul class="silex-list"> ${L(c,(s=>x` <li class="gfonts-item"> <strong>${s.family}</strong> <p>${s.category} - ${s.variants.length} variants</p> <div class="gfonts-preview"> ${At(s)} </div> <button class="silex-button" @click=${()=>function(t,e,s,n){const o=at.find((t=>t.family===s.family));o||at.push({family:s.family,name:s.family,category:s.category,variants:s.variants,value:`"${s.family}", ${s.category}`});ft(t,e),yt(t,e,n)}(t,e,s,i)}>${t.I18n.t('grapesjs-fonts.Add font')}</button> </li> `))} </ul> </div> </div> `,et)}function At(t){const e=t.family||t.name||'',s=e.replace(/ /g,'+'),n=(getComputedStyle(document.documentElement).getPropertyValue('--gjs-font-color')||'').trim()||getComputedStyle(et).color||'#ddd',o=(rt||[]).find((t=>t.family===e)),i=Array.isArray(t.variants)&&t.variants.length?t.variants:o?.variants||['regular'],r=[];i.forEach((t=>{const e=/italic/i.test(t)?1:0,s=String(t).match(/\d+/),n=`${e},${s?parseInt(s[0],10):400}`;r.includes(n)||r.push(n)}));const a=r.length?`:ital,wght@${r.join(';')}`:'',l=r.map((t=>{const[s,n]=t.split(',');return`<p style="margin:0; line-height:1.5; font-style:${'1'===s?'italic':'normal'}; font-weight:${n}">${e} — Sphinx of black quartz, judge my vow. 0123456789</p>`})).join('');return x` <iframe class="preview-iframe" srcdoc="<html><head><link href='https://fonts.googleapis.com/css2?family=${s}${a}&display=swap' rel='stylesheet'><style>body { margin: 0; color: ${n}; font-family: '${e}', sans-serif }</style></head><body>${l}</body></html>"></iframe> `}function _t(t,e){const s=t.Canvas.getDocument();if(!s)return;!function(t,e){const s=t.head.querySelectorAll(`[${e}]`);Array.from(s).forEach((t=>t.remove()))}(s,xt);const n=Ct(e,xt);s.head.insertAdjacentHTML('beforeend',n)}function bt(t,e,s){const n=t.StyleManager.getProperty('typography','font-family');if(!n)return;let o=e;s&&s.preserveDefaultFonts?o=lt.concat(e||[]):e&&0!==e.length||(o=lt),n.setOptions(o)}const xt='data-silex-gstatic';function wt(t,e){const s=t.getModel().get('fonts')||[];_t(t,s),bt(t,s,e)}function Ct(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:'';const s=t.length?`<link href="${ct}" rel="preconnect" ${e}><link href="${ct}/css2" rel="preconnect" crossorigin ${e}>`:'',n=t.map((t=>`<link href="${ct}/css2?family=${t.name.replace(/ /g,'+')}&display=swap" rel="stylesheet" ${e}>`)).join('');return s+n}const jt='get-fonts-css',It='get-fonts-html',Nt='fonts:installed',St='fonts:available',kt='fonts:install',Mt='fonts:remove';const Tt={'grapesjs-fonts':{Fonts:'Fonts','You must provide Google font api key':'You must provide Google font api key, see https://developers.google.com/fonts/docs/developer_api#APIKey',Search:'Search fonts...','Add font':'Install font',Remove:'Remove',Save:'Save',Cancel:'Cancel','Installed fonts':'Installed fonts','All fonts':'All fonts',Variants:'Variants','Toggle all':'Toggle all','No installed fonts':'No installed fonts yet','Previous Page':'Previous','Next Page':'Next'}},Ht={'grapesjs-fonts':{Fonts:'Polices','You must provide Google font api key':'Vous devez fournir une clé API Google font, voir https://developers.google.com/fonts/docs/developer_api#APIKey',Family:'Famille',Search:'Rechercher une police','Add font':'Installer la police',Remove:'Supprimer',Save:'Enregistrer',Cancel:'Annuler','Installed fonts':'Polices installées','All fonts':'Toutes les polices',Variants:'Variantes','Toggle all':'Tout sélectionner','No installed fonts':'Aucune police installée','Previous Page':'Précédent','Next Page':'Suivant'}},Pt=function(t){const e={i18n:{},preserveDefaultFonts:!0,...arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}};t.I18n&&t.I18n.addMessages({en:Tt,fr:Ht,...e.i18n}),function(t,e){t.Commands.add(jt,(()=>{throw new Error('get-fonts-css is not implemented. Use get-fonts-html instead.')})),t.Commands.add(It,(t=>Ct(t.getModel().get('fonts')||[]))),t.Commands.add(Nt,(()=>(t.getModel().get('fonts')||[]).map((t=>({family:t.family,category:t.category,variants:t.variants||[]}))))),t.Commands.add(St,(async function(t,s){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=gt();if(!o){if(!e||!e.api_key)throw new Error('Font list not loaded and no api_key configured. Provide api_key in plugin options to enable Google Fonts.');o=await pt(`${ht()}/webfonts/v1/webfonts?key=${encodeURIComponent(e.api_key)}`)}if(!o)throw new Error('Could not load font list from Google Fonts API. Check api_key and network.');const{search:i,category:r}=n;let a=o;if(i){const t=i.toLowerCase();a=a.filter((e=>e.family.toLowerCase().includes(t)))}return r&&(a=a.filter((t=>t.category===r))),a.map((t=>({family:t.family,category:t.category,variants:t.variants})))})),t.Commands.add(kt,(function(t,s){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{family:o}=n;if(!o)throw new Error('Required: family (e.g. "Roboto", "Open Sans"). Use fonts:available to search.');const i=t.getModel().get('fonts')||[];if(i.find((t=>t.family.toLowerCase()===o.toLowerCase())))throw new Error(`Font "${o}" already installed. Use fonts:installed to list installed fonts.`);const r=(gt()||[]).find((t=>t.family.toLowerCase()===o.toLowerCase()));if(!r)throw new Error(`Font "${o}" not found in available fonts. Run fonts:available to load the font list first, then retry.`);const a={family:r.family,name:r.family,category:r.category,variants:r.variants,value:`"${r.family}", ${r.category}`};return i.push(a),t.getModel().set('fonts',[...i]),wt(t,e),{family:a.family,category:a.category,variants:a.variants}})),t.Commands.add(Mt,(function(t,s){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{family:o}=n;if(!o)throw new Error('Required: family (e.g. "Roboto"). Use fonts:installed to list installed fonts.');const i=t.getModel().get('fonts')||[],r=i.findIndex((t=>t.family===o));if(-1===r)throw new Error(`Font "${o}" not installed. Use fonts:installed to list installed fonts.`);i.splice(r,1),t.getModel().set('fonts',[...i]),wt(t,e)}))}(t,e),ut(t,e),t.on('ai-capabilities:ready',(t=>{!function(t){t({id:It,command:It,description:'Get HTML imports for installed fonts',readOnly:!0,tags:['fonts']}),t({id:Nt,command:Nt,description:'List installed fonts',readOnly:!0,tags:['fonts']}),t({id:St,command:St,description:'List available Google Fonts',readOnly:!0,openWorld:!0,inputSchema:{type:'object',properties:{search:{type:'string'},category:{type:'string',enum:['serif','sans-serif','display','handwriting','monospace']}}},tags:['fonts']}),t({id:kt,command:kt,description:'Install a Google Font by family name',openWorld:!0,inputSchema:{type:'object',required:['family'],properties:{family:{type:'string'}}},tags:['fonts']}),t({id:Mt,command:Mt,description:'Remove an installed font',destructive:!0,inputSchema:{type:'object',required:['family'],properties:{family:{type:'string'}}},tags:['fonts']})}(t)}))};return e})())); //# sourceMappingURL=index.js.map