├── .eslintrc.json ├── .github └── workflows │ └── npm-publish.yml ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── _index.html ├── dist ├── index.js └── index.js.map ├── package-lock.json ├── package.json ├── src ├── commands.js ├── fonts.js ├── index.js └── locale │ ├── en.js │ ├── fr.js │ └── ptbr.js └── tsconfig.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true 5 | }, 6 | "extends": "eslint:recommended", 7 | "overrides": [ 8 | ], 9 | "parserOptions": { 10 | "ecmaVersion": "latest", 11 | "sourceType": "module" 12 | }, 13 | "rules": { 14 | "indent": [ 15 | "error", 16 | 4 17 | ], 18 | "linebreak-style": [ 19 | "error", 20 | "unix" 21 | ], 22 | "quotes": [ 23 | "error", 24 | "single" 25 | ], 26 | "semi": [ 27 | "error", 28 | "never" 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish to npm 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | publish: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | with: 14 | fetch-depth: 0 15 | 16 | - uses: actions/setup-node@v4 17 | with: 18 | node-version: '20' 19 | registry-url: 'https://registry.npmjs.org' 20 | 21 | - run: npm ci 22 | - run: npm run lint --if-present 23 | - run: npm run build --if-present 24 | - run: npm test --if-present 25 | 26 | - name: Extract version and tag 27 | id: version 28 | run: | 29 | VERSION=$(node -p "require('./package.json').version") 30 | if [[ "$VERSION" == *-* ]]; then 31 | echo "tag=prerelease" >> $GITHUB_OUTPUT 32 | else 33 | echo "tag=latest" >> $GITHUB_OUTPUT 34 | fi 35 | echo "version=$VERSION" >> $GITHUB_OUTPUT 36 | 37 | - name: Publish to npm 38 | run: npm publish --tag ${{ steps.version.outputs.tag }} --access public 39 | env: 40 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | private/ 3 | /locale 4 | node_modules/ 5 | *.log 6 | stats.json 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | *.log 3 | *.html 4 | **/tsconfig.json 5 | **/webpack.config.js 6 | node_modules 7 | 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-current Grapesjs Fonts 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Grapesjs Fonts 2 | 3 | Custom Fonts plugin for grapesjs 4 | 5 | > This code is part of a bigger project: [about Silex v3](https://www.silexlabs.org/silex-v3-kickoff/) 6 | 7 | ## About this plugin 8 | 9 | Links 10 | 11 | * [DEMO on Codepen](https://codepen.io/lexoyo/full/zYLWdxY) 12 | * [Npm package](https://www.npmjs.com/package/@silexlabs/grapesjs-fonts) 13 | * [Discussion about ongoing developments](https://github.com/artf/grapesjs/discussions/4858#discussioncomment-4756119) 14 | 15 | It looks like this: 16 | 17 | ![Screenshot from 2023-01-20 16-20-56](https://user-images.githubusercontent.com/715377/213734511-7e66175b-cb72-4a61-b215-2af64f5d532c.png) 18 | ![Screenshot from 2023-01-20 16-19-41](https://user-images.githubusercontent.com/715377/213734520-adc1072f-ed94-4a01-b1e0-3560a6816083.png) 19 | 20 | 21 | The plugin currently has these features 22 | 23 | * [x] API to add / remove fonts from the site (from goole font name) 24 | * [x] Updates the DOM and the "font family" dropdown 25 | * [x] Save the fonts with the site data 26 | * [x] Load the fonts when site data is loaded (add to the DOM on load) 27 | * [x] UI to manage fonts 28 | * [x] Integration with google API 29 | * [x] Store google fonts list in local storage for performance and API quotas 30 | * [x] Generate HTML imports for the final website 31 | * [x] Support [Google fonts proxies, e.g fontlay](https://fontlay.com/) and a [privacy-friendly drop-in replacement for Google Fonts, e.g coollabsio's fonts server](https://github.com/coollabsio/fonts) 32 | * [ ] Generate CSS imports for the final website 33 | * [ ] Handle variants and weights 34 | * [ ] Google fonts V3 API 35 | 36 | ### Limitations 37 | 38 | For now this plugin supports only Goolge fonts and use the V2 API. It should be upgraded to V3 and take advantage of variable fonts. 39 | 40 | ### Export / publication 41 | 42 | In your app you probaly publish / export the website to a final format (html, css, js, images, etc). 43 | 44 | You need to add the font to the final website when you publish/export it, this is not done by the plugin. You can use the provided commands `get-fonts-css` OR `get-fonts-html` to get the code to add to the final website. 45 | 46 | ```js 47 | // get the CSS to add to the final website 48 | const css = editor.runCommand('get-fonts-css') 49 | // Here css is like @import url('https://fonts.googleapis.com/css2?family=Protest+Strike&display=swap') 50 | ``` 51 | 52 | Or ues the `get-fonts-import-html` command to get the HTML to add to the final website 53 | 54 | ```js 55 | // get the HTML to add to the final website 56 | const html = editor.runCommand('get-fonts-html') 57 | // Here html is like 58 | ``` 59 | 60 | You can check how it is done in [Silex website builder](https://github.com/silexlabs/Silex/blob/dev/src/ts/client/publish-fonts.ts) 61 | 62 | ### Motivations 63 | 64 | I saw discussions and issues like "How can i add custom fonts in grapesjs editor? #4563" 65 | 66 | What seems to work for me is 67 | 68 | 1. update the "font family" dropdown 69 | ``` 70 | const styleManager = editor.StyleManager 71 | const fontProperty = styleManager.getProperty('typography', 'font-family') 72 | fontProperty.setOptions(fonts) 73 | styleManager.render() 74 | ``` 75 | 1. update the DOM to display the font correctly: add style elements to the editor.Canvas.getDocument() 76 | 77 | This is quite easy but here are the things which took me time as I implemented google fonts 78 | 79 | * use google fonts api to select fonts and get their name, variants, weights 80 | * build the URL of the fonts to load 81 | * the UI to manage and install fonts 82 | 83 | ## Use the plugin in your website builder 84 | 85 | ### HTML 86 | 87 | ```html 88 | 89 | 90 | 91 | 92 |
93 | ``` 94 | 95 | ### JS 96 | ```js 97 | const editor = grapesjs.init({ 98 | container: '#gjs', 99 | height: '100%', 100 | fromElement: true, 101 | storageManager: false, 102 | plugins: ['@silexlabs/grapesjs-fonts'], 103 | }); 104 | ``` 105 | 106 | This will make sure the fonts are saved and loaded with the website data 107 | 108 | Here is how to open the fonts dialog: 109 | 110 | ```js 111 | editor.runCommand('open-fonts') 112 | ``` 113 | 114 | ### CSS 115 | 116 | ```css 117 | body, html { 118 | margin: 0; 119 | height: 100%; 120 | } 121 | ``` 122 | 123 | Also you should style the dialog: 124 | 125 | ```css 126 | .silex-form select { 127 | ... 128 | } 129 | ``` 130 | 131 | ## Options 132 | 133 | The options `api_url` and `server_url` are used to support Google fonts proxies, e.g fontlay and a privacy-friendly drop-in replacement for Google Fonts, e.g coollabsio's fonts server. Their default values are the Google fonts API and server. 134 | 135 | | Option | Description | Default | 136 | |-|-|- 137 | | `api_key` | Google fonts API key, [see this doc to get an API key](https://developers.google.com/fonts/docs/developer_api#APIKey) | Required | 138 | | `api_url` | Fonts API | `https://www.googleapis.com` | 139 | | `server_url` | Fonts server | `https://fonts.googleapis.com` | 140 | 141 | ## Download 142 | 143 | * CDN 144 | * `https://unpkg.com/@silexlabs/grapesjs-fonts` 145 | * NPM 146 | * `npm i @silexlabs/grapesjs-fonts` 147 | * GIT 148 | * `git clone https://github.com/silexlabs/grapesjs-fonts.git` 149 | 150 | 151 | 152 | ## Usage 153 | 154 | Directly in the browser 155 | ```html 156 | 157 | 158 | 159 | 160 |
161 | 162 | 174 | ``` 175 | 176 | Modern javascript 177 | 178 | ```js 179 | import grapesjs from 'grapesjs'; 180 | import plugin from '@silexlabs/grapesjs-fonts'; 181 | import 'grapesjs/dist/css/grapes.min.css'; 182 | 183 | const editor = grapesjs.init({ 184 | container : '#gjs', 185 | // ... 186 | plugins: [plugin], 187 | pluginsOpts: { 188 | [plugin]: { 189 | api_key: '...', 190 | } 191 | } 192 | // or 193 | plugins: [ 194 | editor => plugin(editor, { 195 | api_key: '...', 196 | }), 197 | ], 198 | }); 199 | ``` 200 | 201 | ## Development 202 | 203 | Clone the repository 204 | 205 | ```sh 206 | $ git clone https://github.com/silexlabs/grapesjs-fonts.git 207 | $ cd grapesjs-fonts 208 | ``` 209 | 210 | Install dependencies 211 | 212 | ```sh 213 | $ npm i 214 | ``` 215 | 216 | Start the dev server 217 | 218 | ```sh 219 | $ npm start 220 | ``` 221 | 222 | Build the source 223 | 224 | ```sh 225 | $ npm run build 226 | ``` 227 | 228 | ## License 229 | 230 | MIT 231 | 232 | -------------------------------------------------------------------------------- /_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test fonts 6 | 7 | 8 | 9 | 52 | 53 | 54 |
55 |
56 | 94 | 95 | -------------------------------------------------------------------------------- /dist/index.js: -------------------------------------------------------------------------------- 1 | /*! @silexlabs/grapesjs-fonts - 1.0.20 */ 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,{cmdGetCss:()=>Tt,cmdGetHtml:()=>jt,cmdOpenFonts:()=>pt,default:()=>Et,fontsDialogPlugin:()=>bt,getHtml:()=>Nt,refresh:()=>Mt});const s=globalThis,n=s.trustedTypes,i=n?n.createPolicy("lit-html",{createHTML:t=>t}):void 0,o="$lit$",r=`lit$${Math.random().toFixed(9).slice(2)}$`,l="?"+r,a=`<${l}>`,c=document,h=()=>c.createComment(""),d=t=>null===t||"object"!=typeof t&&"function"!=typeof t,u=Array.isArray,f=t=>u(t)||"function"==typeof t?.[Symbol.iterator],p="[ \t\n\f\r]",$=/<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g,g=/-->/g,_=/>/g,v=RegExp(`>|${p}(?:([^\\s"'>=/]+)(${p}*=${p}*(?:[^ \t\n\f\r"'\`<>=]|("|')|))|$)`,"g"),A=/'/g,m=/"/g,y=/^(?: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"),S=new WeakMap,H=c.createTreeWalker(c,129);function I(t,e){if(!u(t)||!t.hasOwnProperty("raw"))throw Error("invalid template strings array");return void 0!==i?i.createHTML(e):e}const M=(t,e)=>{const s=t.length-1,n=[];let i,l=2===e?"":3===e?"":"",c=$;for(let e=0;e"===d[0]?(c=i??$,u=-1):void 0===d[1]?u=-2:(u=c.lastIndex-d[2].length,h=d[1],c=void 0===d[3]?v:'"'===d[3]?m:A):c===m||c===A?c=v:c===g||c===_?c=$:(c=v,i=void 0);const p=c===v&&t[e+1].startsWith("/>")?" ":"";l+=c===$?s+a:u>=0?(n.push(h),s.slice(0,u)+o+s.slice(u)+r+p):s+r+(-2===u?e:p)}return[I(t,l+(t[s]||"")+(2===e?"":3===e?"":"")),n]};class N{constructor({strings:t,_$litType$:e},s){let i;this.parts=[];let a=0,c=0;const d=t.length-1,u=this.parts,[f,p]=M(t,e);if(this.el=N.createElement(f,s),H.currentNode=this.el.content,2===e||3===e){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(i=H.nextNode())&&u.length0){i.textContent=n?n.emptyScript:"";for(let s=0;s2||""!==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 i=this.strings;let o=!1;if(void 0===i)t=T(this,t,e,0),o=!d(t)||t!==this._$AH&&t!==w,o&&(this._$AH=t);else{const n=t;let r,l;for(t=i[0],r=0;r(...e)=>({_$litDirective$:t,values:e});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{I:G}=D,q=t=>void 0===t.strings,Z={},J=V(class extends z{constructor(t){if(super(t),t.type!==W&&t.type!==B&&t.type!==L)throw Error("The `live` directive is not allowed on child or event bindings");if(!q(t))throw Error("`live` bindings can only contain a single expression")}render(t){return t}update(t,[e]){if(e===w||e===C)return e;const s=t.element,n=t.name;if(t.type===W){if(e===s[n])return w}else if(t.type===L){if(!!e===s.hasAttribute(n))return w}else if(t.type===B&&s.getAttribute(n)===e+"")return w;return((t,e=Z)=>{t._$AH=e})(t),e}});function*K(t,e){if(void 0!==t){let s=0;for(const n of t)yield e(n,s++)}}const Q="important",X=" !"+Q,tt=V(class extends z{constructor(t){if(super(t),t.type!==B||"style"!==t.name||t.strings?.length>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(t){return Object.keys(t).reduce(((e,s)=>{const n=t[s];return null==n?e:e+`${s=s.includes("-")?s:s.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${n};`}),"")}update(t,[e]){const{style:s}=t.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(e)),this.render(e);for(const t of this.ft)null==e[t]&&(this.ft.delete(t),t.includes("-")?s.removeProperty(t):s[t]=null);for(const t in e){const n=e[t];if(null!=n){this.ft.add(t);const e="string"==typeof n&&n.endsWith(X);t.includes("-")||e?s.setProperty(t,e?n.slice(0,-11):n,e?Q:""):s[t]=n}}return w}}),et=(t,e)=>{const s=t._$AN;if(void 0===s)return!1;for(const t of s)t._$AO?.(e,!1),et(t,e);return!0},st=t=>{let e,s;do{if(void 0===(e=t._$AM))break;s=e._$AN,s.delete(t),t=e}while(0===s?.size)},nt=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),rt(e)}};function it(t){void 0!==this._$AN?(st(this),this._$AM=t,nt(this)):this._$AM=t}function ot(t,e=!1,s=0){const n=this._$AH,i=this._$AN;if(void 0!==i&&0!==i.size)if(e)if(Array.isArray(n))for(let t=s;t{t.type==F&&(t._$AP??=ot,t._$AQ??=it)};class lt extends z{constructor(){super(...arguments),this._$AN=void 0}_$AT(t,e,s){super._$AT(t,e,s),nt(this),this.isConnected=t._$AU}_$AO(t,e=!0){t!==this.isConnected&&(this.isConnected=t,t?this.reconnected?.():this.disconnected?.()),e&&(et(this,t),st(this))}setValue(t){if(q(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(){}}const at=()=>new ct;class ct{}const ht=new WeakMap,dt=V(class extends lt{render(t){return C}update(t,[e]){const s=e!==this.Y;return s&&void 0!==this.Y&&this.rt(void 0),(s||this.lt!==this.ct)&&(this.Y=e,this.ht=t.options?.host,this.rt(this.ct=t.element)),C}rt(t){if(this.isConnected||(t=void 0),"function"==typeof this.Y){const e=this.ht??globalThis;let s=ht.get(e);void 0===s&&(s=new WeakMap,ht.set(e,s)),void 0!==s.get(this.Y)&&this.Y.call(this.ht,void 0),s.set(this.Y,t),void 0!==t&&this.Y.call(this.ht,t)}else this.Y.value=t}get lt(){return"function"==typeof this.Y?ht.get(this.ht??globalThis)?.get(this.Y):this.Y?.value}disconnected(){this.lt===this.ct&&this.rt(void 0)}reconnected(){this.rt(this.ct)}}),ut=document.createElement('div');let ft;const pt='open-fonts',$t='silex-loaded-fonts-list';let gt,_t,vt=[],At='https://fonts.googleapis.com',mt='https://www.googleapis.com';try{gt=JSON.parse(localStorage.getItem($t))}catch(o){console.error('Could not get fonts from local storage:',o)}async function yt(t){return gt=gt??(await(await fetch(t)).json())?.items,localStorage.setItem($t,JSON.stringify(gt)),await async function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;return new Promise((e=>setTimeout((()=>e()),t)))}(),gt}const bt=(t,e)=>{if(vt=t.StyleManager.getBuiltIn('font-family').options,e.server_url&&(At=e.server_url),e.api_url&&(mt=e.api_url),!e.api_key)throw new Error(t.I18n.t('grapesjs-fonts.You must provide Google font api key'));t.Commands.add(pt,{run:(s,n)=>(ft=t.Modal.open({title:t.I18n.t('grapesjs-fonts.Fonts'),content:'',attributes:{class:'fonts-dialog'}}).onceClose((()=>{t.stopCommand(pt)})),ft.setContent(ut),async function(t){_t=structuredClone(t.getModel().get('fonts')||[])}(t),Ct(t,e,[]),yt(`${mt}/webfonts/v1/webfonts?key=${e.api_key}`).then((s=>{Ct(t,e,s);const n=ut.querySelector('form');n.onsubmit=s=>{s.preventDefault(),function(t,e){const s=t.getModel();s.set('fonts',_t),Ht(t,_t),It(t,_t,e),s.set('changesCount',t.getDirtyCount()+1)}(t,e),t.stopCommand(pt)},n.querySelector('input')?.focus()})),ft),stop:()=>{ft.close()}}),t.on('storage:start:store',(e=>{e.fonts=t.getModel().get('fonts')})),t.on('storage:end:load',(s=>{const n=s.fonts||[];t.getModel().set('fonts',n),setTimeout((()=>Mt(t,e)),1e3)})),t.on('canvas:frame:load',(()=>Mt(t,e))),t.on('page',(()=>Mt(t,e)))};const xt=at(),wt=at();function Ct(t,e,s){const n=xt.value,i=s.filter((t=>function(t,e){const s=new RegExp(e,'i');return-1!==t.search(s)}(t.family,n?.value||'')));n?.focus(),((t,e,s)=>{const n=s?.renderBefore??e;let i=n._$litPart$;if(void 0===i){const t=s?.renderBefore??null;n._$litPart$=i=new k(e.insertBefore(h(),t),t,void 0,s??{})}i._$AI(t)})(x` 3 |
4 |
5 |
6 | {setTimeout((()=>Ct(t,e,s)))}}/> 12 | 20 | 25 |
26 |
27 |
28 |
30 |

${t.I18n.t('grapesjs-fonts.Installed fonts')}

31 |
    32 | ${K(_t,(n=>{return x` 33 |
  1. 34 |
    35 |

    ${n.name}

    36 |
    37 |
    38 |
    39 | CSS rules 40 | {var o,r;o=n,r=i.target.value,o.value=r,Ct(t,e,s)}} 46 | /> 47 |
    48 |
    49 | Variants 50 | ${K((i=n,s.find((t=>i.name===t.family)))?.variants.filter((t=>''===t.replace(/[a-z]/g,''))),(i=>x` 51 |
    52 | {!function(t,e,s,n,i){const o=s.variants?.includes(n);o&&!i?s.variants=s.variants.filter((t=>t!==n)):!o&&i&&s.variants.push(n)}(0,0,n,i,o.target.checked),Ct(t,e,s)}} 58 | /> 59 |
    60 | `))} 61 |
    62 |
    63 | 66 |
  2. 67 | `;var i}))} 68 |
69 |
70 |
71 | t.stopCommand(pt)} value="${t.I18n.t('grapesjs-fonts.Cancel')}"> 72 | 73 |
74 |
75 | `,ut)}const St='data-silex-gstatic';function Ht(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,St);const n=Nt(e,St);s.head.insertAdjacentHTML('beforeend',n)}function It(t,e,s){const n=t.StyleManager.getProperty('typography','font-family');n&&(s.preserveDefaultFonts?e=vt.concat(e):0===e.length&&(e=vt),n.setOptions(e))}function Mt(t,e){const s=t.getModel().get('fonts')||[];Ht(t,s),It(t,s,e)}function Nt(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:'';const s=``,n=t.map((t=>{const s=(t.variants.length?':':'')+t.variants.map((t=>t.replace(/\d+/g,''))).filter((t=>!!t)).join(',');return``})).join('');return s+n}const Tt='get-fonts-css',jt='get-fonts-html';const kt={'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'}},Pt={'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'}},Et=function(t){const e={i18n:{},preserveDefaultFonts:!0,...arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}};t.I18n&&t.I18n.addMessages({en:kt,fr:Pt,...e.i18n}),function(t){t.Commands.add(Tt,(()=>{throw new Error('Not implemented')})),t.Commands.add(jt,(t=>Nt(t.getModel().get('fonts')||[])))}(t),bt(t,e)};return e})())); 76 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /dist/index.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"index.js","mappings":"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","sources":["webpack://@silexlabs/grapesjs-fonts/webpack/universalModuleDefinition","webpack://@silexlabs/grapesjs-fonts/webpack/bootstrap","webpack://@silexlabs/grapesjs-fonts/webpack/runtime/define property getters","webpack://@silexlabs/grapesjs-fonts/webpack/runtime/hasOwnProperty shorthand","webpack://@silexlabs/grapesjs-fonts/webpack/runtime/make namespace object","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/lit-html.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/directive.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/directive-helpers.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/directives/live.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/directives/map.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/directives/style-map.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/async-directive.js","webpack://@silexlabs/grapesjs-fonts/../../node_modules/lit-html/directives/ref.js","webpack://@silexlabs/grapesjs-fonts/./src/fonts.js","webpack://@silexlabs/grapesjs-fonts/./src/commands.js","webpack://@silexlabs/grapesjs-fonts/./src/locale/en.js","webpack://@silexlabs/grapesjs-fonts/./src/locale/fr.js","webpack://@silexlabs/grapesjs-fonts/./src/index.js"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"@silexlabs/grapesjs-fonts\"] = factory();\n\telse\n\t\troot[\"@silexlabs/grapesjs-fonts\"] = factory();\n})(typeof globalThis !== 'undefined' ? globalThis : (typeof window !== 'undefined' ? window : this), () => {\nreturn ","// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t=globalThis,i=t.trustedTypes,s=i?i.createPolicy(\"lit-html\",{createHTML:t=>t}):void 0,e=\"$lit$\",h=`lit$${Math.random().toFixed(9).slice(2)}$`,o=\"?\"+h,n=`<${o}>`,r=document,l=()=>r.createComment(\"\"),c=t=>null===t||\"object\"!=typeof t&&\"function\"!=typeof t,a=Array.isArray,u=t=>a(t)||\"function\"==typeof t?.[Symbol.iterator],d=\"[ \\t\\n\\f\\r]\",f=/<(?:(!--|\\/[^a-zA-Z])|(\\/?[a-zA-Z][^>\\s]*)|(\\/?$))/g,v=/-->/g,_=/>/g,m=RegExp(`>|${d}(?:([^\\\\s\"'>=/]+)(${d}*=${d}*(?:[^ \\t\\n\\f\\r\"'\\`<>=]|(\"|')|))|$)`,\"g\"),p=/'/g,g=/\"/g,$=/^(?:script|style|textarea|title)$/i,y=t=>(i,...s)=>({_$litType$:t,strings:i,values:s}),x=y(1),b=y(2),w=y(3),T=Symbol.for(\"lit-noChange\"),E=Symbol.for(\"lit-nothing\"),A=new WeakMap,C=r.createTreeWalker(r,129);function P(t,i){if(!a(t)||!t.hasOwnProperty(\"raw\"))throw Error(\"invalid template strings array\");return void 0!==s?s.createHTML(i):i}const V=(t,i)=>{const s=t.length-1,o=[];let r,l=2===i?\"\":3===i?\"\":\"\",c=f;for(let i=0;i\"===u[0]?(c=r??f,d=-1):void 0===u[1]?d=-2:(d=c.lastIndex-u[2].length,a=u[1],c=void 0===u[3]?m:'\"'===u[3]?g:p):c===g||c===p?c=m:c===v||c===_?c=f:(c=m,r=void 0);const x=c===m&&t[i+1].startsWith(\"/>\")?\" \":\"\";l+=c===f?s+n:d>=0?(o.push(a),s.slice(0,d)+e+s.slice(d)+h+x):s+h+(-2===d?i:x)}return[P(t,l+(t[s]||\"\")+(2===i?\"\":3===i?\"\":\"\")),o]};class N{constructor({strings:t,_$litType$:s},n){let r;this.parts=[];let c=0,a=0;const u=t.length-1,d=this.parts,[f,v]=V(t,s);if(this.el=N.createElement(f,n),C.currentNode=this.el.content,2===s||3===s){const t=this.el.content.firstChild;t.replaceWith(...t.childNodes)}for(;null!==(r=C.nextNode())&&d.length0){r.textContent=i?i.emptyScript:\"\";for(let i=0;i2||\"\"!==s[0]||\"\"!==s[1]?(this._$AH=Array(s.length-1).fill(new String),this.strings=s):this._$AH=E}_$AI(t,i=this,s,e){const h=this.strings;let o=!1;if(void 0===h)t=S(this,t,i,0),o=!c(t)||t!==this._$AH&&t!==T,o&&(this._$AH=t);else{const e=t;let n,r;for(t=h[0],n=0;n{const e=s?.renderBefore??i;let h=e._$litPart$;if(void 0===h){const t=s?.renderBefore??null;e._$litPart$=h=new R(i.insertBefore(l(),t),t,void 0,s??{})}return h._$AI(t),h};export{Z as _$LH,x as html,w as mathml,T as noChange,E as nothing,B as render,b as svg};\n//# sourceMappingURL=lit-html.js.map\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{_$LH as o}from\"./lit-html.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const{I:t}=o,i=o=>null===o||\"object\"!=typeof o&&\"function\"!=typeof o,n={HTML:1,SVG:2,MATHML:3},e=(o,t)=>void 0===t?void 0!==o?._$litType$:o?._$litType$===t,l=o=>null!=o?._$litType$?.h,c=o=>void 0!==o?._$litDirective$,d=o=>o?._$litDirective$,f=o=>void 0===o.strings,s=()=>document.createComment(\"\"),r=(o,i,n)=>{const e=o._$AA.parentNode,l=void 0===i?o._$AB:i._$AA;if(void 0===n){const i=e.insertBefore(s(),l),c=e.insertBefore(s(),l);n=new t(i,c,o,o.options)}else{const t=n._$AB.nextSibling,i=n._$AM,c=i!==o;if(c){let t;n._$AQ?.(o),n._$AM=o,void 0!==n._$AP&&(t=o._$AU)!==i._$AU&&n._$AP(t)}if(t!==l||c){let o=n._$AA;for(;o!==t;){const t=o.nextSibling;e.insertBefore(o,l),o=t}}}return n},v=(o,t,i=o)=>(o._$AI(t,i),o),u={},m=(o,t=u)=>o._$AH=t,p=o=>o._$AH,M=o=>{o._$AP?.(!1,!0);let t=o._$AA;const i=o._$AB.nextSibling;for(;t!==i;){const o=t.nextSibling;t.remove(),t=o}},h=o=>{o._$AR()};export{n as TemplateResultType,h as clearPart,p as getCommittedValue,d as getDirectiveClass,r as insertPart,l as isCompiledTemplateResult,c as isDirectiveResult,i as isPrimitive,f as isSingleExpression,e as isTemplateResult,M as removePart,v as setChildPartValue,m as setCommittedValue};\n//# sourceMappingURL=directive-helpers.js.map\n","import{noChange as r,nothing as e}from\"../lit-html.js\";import{directive as i,Directive as t,PartType as n}from\"../directive.js\";import{isSingleExpression as o,setCommittedValue as s}from\"../directive-helpers.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const l=i(class extends t{constructor(r){if(super(r),r.type!==n.PROPERTY&&r.type!==n.ATTRIBUTE&&r.type!==n.BOOLEAN_ATTRIBUTE)throw Error(\"The `live` directive is not allowed on child or event bindings\");if(!o(r))throw Error(\"`live` bindings can only contain a single expression\")}render(r){return r}update(i,[t]){if(t===r||t===e)return t;const o=i.element,l=i.name;if(i.type===n.PROPERTY){if(t===o[l])return r}else if(i.type===n.BOOLEAN_ATTRIBUTE){if(!!t===o.hasAttribute(l))return r}else if(i.type===n.ATTRIBUTE&&o.getAttribute(l)===t+\"\")return r;return s(i),t}});export{l as live};\n//# sourceMappingURL=live.js.map\n","/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nfunction*o(o,f){if(void 0!==o){let i=0;for(const t of o)yield f(t,i++)}}export{o as map};\n//# sourceMappingURL=map.js.map\n","import{noChange as t}from\"../lit-html.js\";import{directive as e,Directive as r,PartType as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const n=\"important\",i=\" !\"+n,o=e(class extends r{constructor(t){if(super(t),t.type!==s.ATTRIBUTE||\"style\"!==t.name||t.strings?.length>2)throw Error(\"The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.\")}render(t){return Object.keys(t).reduce(((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes(\"-\")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,\"-$&\").toLowerCase()}:${s};`}),\"\")}update(e,[r]){const{style:s}=e.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(r)),this.render(r);for(const t of this.ft)null==r[t]&&(this.ft.delete(t),t.includes(\"-\")?s.removeProperty(t):s[t]=null);for(const t in r){const e=r[t];if(null!=e){this.ft.add(t);const r=\"string\"==typeof e&&e.endsWith(i);t.includes(\"-\")||r?s.setProperty(t,r?e.slice(0,-11):e,r?n:\"\"):s[t]=e}}return t}});export{o as styleMap};\n//# sourceMappingURL=style-map.js.map\n","import{isSingleExpression as i}from\"./directive-helpers.js\";import{Directive as t,PartType as e}from\"./directive.js\";export{directive}from\"./directive.js\";\n/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const s=(i,t)=>{const e=i._$AN;if(void 0===e)return!1;for(const i of e)i._$AO?.(t,!1),s(i,t);return!0},o=i=>{let t,e;do{if(void 0===(t=i._$AM))break;e=t._$AN,e.delete(i),i=t}while(0===e?.size)},r=i=>{for(let t;t=i._$AM;i=t){let e=t._$AN;if(void 0===e)t._$AN=e=new Set;else if(e.has(i))break;e.add(i),c(t)}};function h(i){void 0!==this._$AN?(o(this),this._$AM=i,r(this)):this._$AM=i}function n(i,t=!1,e=0){const r=this._$AH,h=this._$AN;if(void 0!==h&&0!==h.size)if(t)if(Array.isArray(r))for(let i=e;i{i.type==e.CHILD&&(i._$AP??=n,i._$AQ??=h)};class f extends t{constructor(){super(...arguments),this._$AN=void 0}_$AT(i,t,e){super._$AT(i,t,e),r(this),this.isConnected=i._$AU}_$AO(i,t=!0){i!==this.isConnected&&(this.isConnected=i,i?this.reconnected?.():this.disconnected?.()),t&&(s(this,i),o(this))}setValue(t){if(i(this._$Ct))this._$Ct._$AI(t,this);else{const i=[...this._$Ct._$AH];i[this._$Ci]=t,this._$Ct._$AI(i,this,0)}}disconnected(){}reconnected(){}}export{f as AsyncDirective,t as Directive,e as PartType};\n//# sourceMappingURL=async-directive.js.map\n","import{nothing as t}from\"../lit-html.js\";import{AsyncDirective as i}from\"../async-directive.js\";import{directive as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2020 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const e=()=>new h;class h{}const o=new WeakMap,n=s(class extends i{render(i){return t}update(i,[s]){const e=s!==this.Y;return e&&void 0!==this.Y&&this.rt(void 0),(e||this.lt!==this.ct)&&(this.Y=s,this.ht=i.options?.host,this.rt(this.ct=i.element)),t}rt(t){if(this.isConnected||(t=void 0),\"function\"==typeof this.Y){const i=this.ht??globalThis;let s=o.get(i);void 0===s&&(s=new WeakMap,o.set(i,s)),void 0!==s.get(this.Y)&&this.Y.call(this.ht,void 0),s.set(this.Y,t),void 0!==t&&this.Y.call(this.ht,t)}else this.Y.value=t}get lt(){return\"function\"==typeof this.Y?o.get(this.ht??globalThis)?.get(this.Y):this.Y?.value}disconnected(){this.lt===this.ct&&this.rt(void 0)}reconnected(){this.rt(this.ct)}});export{e as createRef,n as ref};\n//# sourceMappingURL=ref.js.map\n","import {html, render} from 'lit-html'\nimport {live} from 'lit-html/directives/live.js'\nimport { map } from 'lit-html/directives/map.js'\nimport {styleMap} from 'lit-html/directives/style-map.js'\nimport {ref, createRef} from 'lit-html/directives/ref.js'\n\nconst el = document.createElement('div')\nlet modal\n\nexport const cmdOpenFonts = 'open-fonts'\n\n/**\n * Constants\n */\nconst LS_FONTS = 'silex-loaded-fonts-list'\n\n/**\n * Module variables\n */\nlet _fontsList\nlet fonts\nlet defaults = []\n\n/**\n * Options\n */\nlet fontServer = 'https://fonts.googleapis.com'\nlet fontApi = 'https://www.googleapis.com'\n\n/**\n * Load available fonts only once per session\n * Use local storage\n */\ntry {\n _fontsList = JSON.parse(localStorage.getItem(LS_FONTS))\n} catch(e) {\n console.error('Could not get fonts from local storage:', e)\n}\n\n/**\n * Promised wait function\n */\nasync function wait(ms = 0) {\n return new Promise(resolve => setTimeout(() => resolve(), ms))\n}\n\n/**\n * When the dialog is opened\n */\nasync function loadFonts(editor) {\n fonts = structuredClone(editor.getModel().get('fonts') || [])\n}\n\n/**\n * When the dialog is closed\n */\nfunction saveFonts(editor, opts) {\n const model = editor.getModel()\n\n // Store the modified fonts\n model.set('fonts', fonts)\n\n // Update the HTML head with style sheets to load\n updateHead(editor, fonts)\n\n // Update the \"font family\" dropdown\n updateUi(editor, fonts, opts)\n\n // Save website if auto save is on\n model.set('changesCount', editor.getDirtyCount() + 1)\n}\n\n/**\n * Load the available fonts from google\n */\nasync function loadFontList(url) {\n _fontsList = _fontsList ?? (await (await fetch(url)).json())?.items\n localStorage.setItem(LS_FONTS, JSON.stringify(_fontsList))\n await wait() // let the dialog open\n return _fontsList\n}\n\nexport const fontsDialogPlugin = (editor, opts) => {\n defaults = editor.StyleManager.getBuiltIn('font-family').options\n if(opts.server_url) fontServer = opts.server_url\n if(opts.api_url) fontApi = opts.api_url\n if(!opts.api_key) throw new Error(editor.I18n.t('grapesjs-fonts.You must provide Google font api key'))\n editor.Commands.add(cmdOpenFonts, {\n /* eslint-disable-next-line */\n run: (_, sender) => {\n modal = editor.Modal.open({\n title: editor.I18n.t('grapesjs-fonts.Fonts'),\n content: '',\n attributes: { class: 'fonts-dialog' },\n })\n .onceClose(() => {\n editor.stopCommand(cmdOpenFonts) // apparently this is needed to be able to run the command several times\n })\n modal.setContent(el)\n loadFonts(editor)\n displayFonts(editor, opts, [])\n loadFontList(`${ fontApi }/webfonts/v1/webfonts?key=${ opts.api_key }`)\n .then(fontsList => { // the run command will terminate before this is done, better for performance\n displayFonts(editor, opts, fontsList)\n const form = el.querySelector('form')\n form.onsubmit = event => {\n event.preventDefault()\n saveFonts(editor, opts)\n editor.stopCommand(cmdOpenFonts)\n }\n form.querySelector('input')?.focus()\n })\n return modal\n },\n stop: () => {\n modal.close()\n },\n })\n // add fonts to the website on save\n editor.on('storage:start:store', (data) => {\n data.fonts = editor.getModel().get('fonts')\n })\n // add fonts to the website on load\n editor.on('storage:end:load', (data) => {\n const fonts = data.fonts || []\n editor.getModel().set('fonts', fonts)\n // FIXME: remove this timeout which is a workaround for issues in Silex storage providers\n setTimeout(() => refresh(editor, opts), 1000)\n })\n // update the head and the ui when the frame is loaded\n editor.on('canvas:frame:load', () => refresh(editor, opts))\n // When the page changes, update the dom\n editor.on('page', () => refresh(editor, opts))\n}\n\nfunction match(hay, s) {\n const regExp = new RegExp(s, 'i')\n return hay.search(regExp) !== -1\n}\n\nconst searchInputRef = createRef()\nconst fontRef = createRef()\n\nfunction displayFonts(editor, config, fontsList) {\n const searchInput = searchInputRef.value\n const activeFonts = fontsList.filter(f => match(f.family, searchInput?.value || ''))\n searchInput?.focus()\n function findFont(font) {\n return fontsList.find(f => font.name === f.family)\n }\n render(html`\n
\n
\n
\n {\n //(fontRef.value as HTMLSelectElement).selectedIndex = 0\n setTimeout(() => displayFonts(editor, config, fontsList))\n }}/>\n \n ${ map(activeFonts, f => html`\n \n `)}\n \n \n
\n
\n
\n \n

${editor.I18n.t('grapesjs-fonts.Installed fonts')}

\n
    \n ${ map(fonts, f => html`\n
  1. \n
    \n

    ${f.name}

    \n
    \n
    \n
    \n CSS rules\n {\n updateRules(editor, fonts, f, e.target.value)\n displayFonts(editor, config, fontsList)\n }}\n />\n
    \n
    \n Variants\n ${ map(\n // keep only variants which are letters, no numbers\n // FIXME: we need the weights\n findFont(f)?.variants.filter(v => v.replace(/[a-z]/g, '') === ''),\n v => html`\n
    \n {\n updateVariant(editor, fonts, f, v, e.target.checked)\n displayFonts(editor, config, fontsList)\n }}\n />\n
    \n `)}\n
    \n
    \n
    \n \n
    \n
  2. \n `) }\n
\n \n
\n editor.stopCommand(cmdOpenFonts)} value=\"${editor.I18n.t('grapesjs-fonts.Cancel')}\">\n \n
\n \n `, el)\n}\n\nfunction addFont(editor, config, fonts, font) {\n const name = font.family\n const value = `\"${font.family}\", ${font.category}`\n fonts.push({ name, value, variants: [] })\n}\n\nfunction removeFont(editor, fonts, font) {\n const idx = fonts.findIndex(f => f === font)\n fonts.splice(idx, 1)\n}\n\nfunction removeAll(doc, attr) {\n const all = doc.head.querySelectorAll(`[${ attr }]`)\n Array.from(all)\n .forEach((el) => el.remove())\n}\n\nconst GOOGLE_FONTS_ATTR = 'data-silex-gstatic'\nfunction updateHead(editor, fonts) {\n const doc = editor.Canvas.getDocument()\n if(!doc) {\n // This happens while grapesjs is not ready\n return\n }\n removeAll(doc, GOOGLE_FONTS_ATTR)\n const html = getHtml(fonts, GOOGLE_FONTS_ATTR)\n doc.head.insertAdjacentHTML('beforeend', html)\n}\n\nfunction updateUi(editor, fonts, opts) {\n const styleManager = editor.StyleManager\n const fontProperty = styleManager.getProperty('typography', 'font-family')\n if(!fontProperty) {\n // This happens while grapesjs is not ready\n return\n }\n if (opts.preserveDefaultFonts) {\n fonts = defaults.concat(fonts)\n } else if (fonts.length === 0) {\n fonts = defaults\n }\n fontProperty.setOptions(fonts)\n}\n\nexport function refresh(editor, opts) {\n const fonts = editor.getModel().get('fonts') || []\n updateHead(editor, fonts)\n updateUi(editor, fonts, opts)\n}\n\nfunction updateRules(editor, fonts, font, value) {\n font.value = value\n}\n\nfunction updateVariant(editor, fonts, font, variant, checked) {\n const has = font.variants?.includes(variant)\n if(has && !checked) font.variants = font.variants.filter(v => v !== variant)\n else if(!has && checked) font.variants.push(variant)\n}\n\nexport function getHtml(fonts, attr = '') {\n // FIXME: how to use google fonts v2?\n // google fonts V2: https://developers.google.com/fonts/docs/css2\n //fonts.forEach(f => {\n // const prefix = f.variants.length ? ':' : ''\n // const variants = prefix + f.variants.map(v => {\n // const weight = parseInt(v)\n // const axis = v.replace(/\\d+/g, '')\n // return `${axis},wght@${weight}`\n // }).join(',')\n // insert(doc, GOOGLE_FONTS_ATTR, 'link', { 'href': `${ fontServer }/css2?family=${f.name.replace(/ /g, '+')}${variants}&display=swap`, 'rel': 'stylesheet' })\n //})\n\n // Google fonts v1\n // https://developers.google.com/fonts/docs/getting_started#a_quick_example\n const preconnect = ``\n const links = fonts\n .map(f => {\n const prefix = f.variants.length ? ':' : ''\n const variants = prefix + f.variants.map(v => v.replace(/\\d+/g, '')).filter(v => !!v).join(',')\n return ``\n })\n .join('')\n\n return preconnect + links\n}","import { getHtml } from './fonts'\n\nexport const cmdGetCss = 'get-fonts-css'\nexport const cmdGetHtml = 'get-fonts-html'\n\nexport default function (editor) {\n editor.Commands.add(cmdGetCss, () => {\n throw new Error('Not implemented')\n })\n editor.Commands.add(cmdGetHtml, (editor) => {\n const fonts = editor.getModel().get('fonts') || []\n return getHtml(fonts)\n })\n}\n","export default {\n 'grapesjs-fonts': {\n 'Fonts': 'Fonts',\n 'You must provide Google font api key': 'You must provide Google font api key, see https://developers.google.com/fonts/docs/developer_api#APIKey',\n 'Search': 'Search fonts...',\n 'Add font': 'Install font',\n 'Remove': 'Remove',\n 'Save': 'Save',\n 'Cancel': 'Cancel',\n 'Installed fonts': 'Installed fonts',\n },\n}\n\n","export default {\n 'grapesjs-fonts': {\n 'Fonts': 'Polices',\n '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',\n 'Family': 'Famille',\n 'Search': 'Rechercher une police',\n 'Add font': 'Installer la police',\n 'Remove': 'Supprimer',\n 'Save': 'Enregistrer',\n 'Cancel': 'Annuler',\n 'Installed fonts': 'Polices installées',\n },\n}\n\n\n","import { fontsDialogPlugin } from './fonts.js'\nimport commands from './commands.js'\nimport en from './locale/en.js'\nimport fr from './locale/fr.js'\n\nexport default (editor, opts = {}) => {\n\n const options = { ...{\n // default options\n i18n: {},\n preserveDefaultFonts: true,\n }, ...opts }\n\n \n // Load i18n files\n editor.I18n && editor.I18n.addMessages({\n en,\n fr,\n ...options.i18n,\n })\n\n commands(editor, options)\n fontsDialogPlugin(editor, options)\n}\n\n// Expose commands to the app\nexport * from './fonts.js'\nexport * from './commands.js'\n"],"names":["root","factory","exports","module","define","amd","globalThis","window","this","__webpack_require__","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","t","i","trustedTypes","s","createPolicy","createHTML","e","h","Math","random","toFixed","slice","n","r","document","l","createComment","c","a","Array","isArray","u","iterator","d","f","v","_","m","RegExp","p","g","$","y","_$litType$","strings","values","x","T","for","E","A","WeakMap","C","createTreeWalker","P","Error","V","length","lastIndex","exec","test","startsWith","push","N","constructor","parts","el","createElement","currentNode","content","firstChild","replaceWith","childNodes","nextNode","nodeType","hasAttributes","getAttributeNames","endsWith","getAttribute","split","type","index","name","ctor","H","I","L","k","removeAttribute","tagName","textContent","emptyScript","append","data","indexOf","innerHTML","S","_$Co","_$Cl","_$litDirective$","_$AO","_$AT","_$AS","M","_$AV","_$AN","_$AD","_$AM","parentNode","_$AU","creationScope","importNode","R","nextSibling","z","_$AI","_$Cv","_$AH","_$AA","_$AB","options","isConnected","startNode","endNode","_$AR","O","insertBefore","createTextNode","_$AC","set","_$AP","remove","setConnected","element","fill","String","j","setAttribute","super","arguments","toggleAttribute","capture","once","passive","removeEventListener","addEventListener","handleEvent","host","Z","D","U","B","F","litHtmlPolyfillSupport","litHtmlVersions","_$Ct","_$Ci","update","render","hasAttribute","keys","reduce","includes","replace","toLowerCase","style","ft","Set","delete","removeProperty","add","setProperty","size","has","_$AQ","reconnected","disconnected","setValue","Y","rt","lt","ct","ht","modal","cmdOpenFonts","LS_FONTS","_fontsList","fonts","defaults","fontServer","fontApi","JSON","parse","localStorage","getItem","console","error","async","loadFontList","url","fetch","json","items","setItem","stringify","ms","undefined","Promise","resolve","setTimeout","wait","fontsDialogPlugin","editor","opts","StyleManager","getBuiltIn","server_url","api_url","api_key","I18n","Commands","run","sender","Modal","open","title","attributes","class","onceClose","stopCommand","setContent","structuredClone","getModel","loadFonts","displayFonts","then","fontsList","form","querySelector","onsubmit","event","preventDefault","model","updateHead","updateUi","getDirtyCount","saveFonts","focus","stop","close","on","refresh","searchInputRef","createRef","fontRef","config","searchInput","activeFonts","filter","hay","regExp","search","match","family","renderBefore","_$litPart$","html","styleMap","width","ref","map","font","category","variants","addFont","selectedIndex","live","target","find","variant","checked","updateVariant","idx","findIndex","splice","removeFont","GOOGLE_FONTS_ATTR","doc","Canvas","getDocument","attr","all","head","querySelectorAll","from","forEach","removeAll","getHtml","insertAdjacentHTML","fontProperty","getProperty","preserveDefaultFonts","concat","setOptions","preconnect","links","join","cmdGetCss","cmdGetHtml","i18n","addMessages","en","fr","commands"],"sourceRoot":""} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@silexlabs/grapesjs-fonts", 3 | "version": "1.1.0", 4 | "description": "GrapesJS Fonts", 5 | "main": "dist/index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/silexlabs/grapesjs-fonts.git" 9 | }, 10 | "engines": { 11 | "node": ">=16.0.0" 12 | }, 13 | "scripts": { 14 | "start": "grapesjs-cli serve", 15 | "build": "grapesjs-cli build --patch=false", 16 | "lint": "eslint src" 17 | }, 18 | "keywords": [ 19 | "silex", 20 | "grapesjs", 21 | "grapesjs-plugin", 22 | "plugin", 23 | "font", 24 | "typography" 25 | ], 26 | "devDependencies": { 27 | "eslint": "^8.57.0", 28 | "grapesjs-cli": "^4.1.3" 29 | }, 30 | "peerDependencies": { 31 | "backbone": "*", 32 | "grapesjs": ">=0.19.0 <0.23.0", 33 | "lit-html": "*" 34 | }, 35 | "license": "GPL-3.0" 36 | } 37 | -------------------------------------------------------------------------------- /src/commands.js: -------------------------------------------------------------------------------- 1 | import { getHtml } from './fonts' 2 | 3 | export const cmdGetCss = 'get-fonts-css' 4 | export const cmdGetHtml = 'get-fonts-html' 5 | 6 | export default function (editor) { 7 | editor.Commands.add(cmdGetCss, () => { 8 | throw new Error('Not implemented') 9 | }) 10 | editor.Commands.add(cmdGetHtml, (editor) => { 11 | const fonts = editor.getModel().get('fonts') || [] 12 | return getHtml(fonts) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /src/fonts.js: -------------------------------------------------------------------------------- 1 | import {html, render} from 'lit-html' 2 | import {live} from 'lit-html/directives/live.js' 3 | import { map } from 'lit-html/directives/map.js' 4 | import {styleMap} from 'lit-html/directives/style-map.js' 5 | import {ref, createRef} from 'lit-html/directives/ref.js' 6 | 7 | const el = document.createElement('div') 8 | let modal 9 | 10 | export const cmdOpenFonts = 'open-fonts' 11 | 12 | /** 13 | * Constants 14 | */ 15 | const LS_FONTS = 'silex-loaded-fonts-list' 16 | 17 | /** 18 | * Module variables 19 | */ 20 | let _fontsList 21 | let fonts 22 | let defaults = [] 23 | 24 | /** 25 | * Options 26 | */ 27 | let fontServer = 'https://fonts.googleapis.com' 28 | let fontApi = 'https://www.googleapis.com' 29 | 30 | /** 31 | * Load available fonts only once per session 32 | * Use local storage 33 | */ 34 | try { 35 | _fontsList = JSON.parse(localStorage.getItem(LS_FONTS)) 36 | } catch(e) { 37 | console.error('Could not get fonts from local storage:', e) 38 | } 39 | 40 | /** 41 | * Promised wait function 42 | */ 43 | async function wait(ms = 0) { 44 | return new Promise(resolve => setTimeout(() => resolve(), ms)) 45 | } 46 | 47 | /** 48 | * When the dialog is opened 49 | */ 50 | async function loadFonts(editor) { 51 | fonts = structuredClone(editor.getModel().get('fonts') || []) 52 | } 53 | 54 | /** 55 | * When the dialog is closed 56 | */ 57 | function saveFonts(editor, opts) { 58 | const model = editor.getModel() 59 | 60 | // Store the modified fonts 61 | model.set('fonts', fonts) 62 | 63 | // Update the HTML head with style sheets to load 64 | updateHead(editor, fonts) 65 | 66 | // Update the "font family" dropdown 67 | updateUi(editor, fonts, opts) 68 | 69 | // Save website if auto save is on 70 | model.set('changesCount', editor.getDirtyCount() + 1) 71 | } 72 | 73 | /** 74 | * Load the available fonts from google 75 | */ 76 | async function loadFontList(url) { 77 | _fontsList = _fontsList ?? (await (await fetch(url)).json())?.items 78 | localStorage.setItem(LS_FONTS, JSON.stringify(_fontsList)) 79 | await wait() // let the dialog open 80 | return _fontsList 81 | } 82 | 83 | export const fontsDialogPlugin = (editor, opts) => { 84 | defaults = editor.StyleManager.getBuiltIn('font-family').options 85 | if(opts.server_url) fontServer = opts.server_url 86 | if(opts.api_url) fontApi = opts.api_url 87 | if(!opts.api_key) throw new Error(editor.I18n.t('grapesjs-fonts.You must provide Google font api key')) 88 | editor.Commands.add(cmdOpenFonts, { 89 | /* eslint-disable-next-line */ 90 | run: (_, sender) => { 91 | modal = editor.Modal.open({ 92 | title: editor.I18n.t('grapesjs-fonts.Fonts'), 93 | content: '', 94 | attributes: { class: 'fonts-dialog' }, 95 | }) 96 | .onceClose(() => { 97 | editor.stopCommand(cmdOpenFonts) // apparently this is needed to be able to run the command several times 98 | }) 99 | modal.setContent(el) 100 | loadFonts(editor) 101 | displayFonts(editor, opts, []) 102 | loadFontList(`${ fontApi }/webfonts/v1/webfonts?key=${ opts.api_key }`) 103 | .then(fontsList => { // the run command will terminate before this is done, better for performance 104 | displayFonts(editor, opts, fontsList) 105 | const form = el.querySelector('form') 106 | form.onsubmit = event => { 107 | event.preventDefault() 108 | saveFonts(editor, opts) 109 | editor.stopCommand(cmdOpenFonts) 110 | } 111 | form.querySelector('input')?.focus() 112 | }) 113 | return modal 114 | }, 115 | stop: () => { 116 | modal.close() 117 | }, 118 | }) 119 | // add fonts to the website on save 120 | editor.on('storage:start:store', (data) => { 121 | data.fonts = editor.getModel().get('fonts') 122 | }) 123 | // add fonts to the website on load 124 | editor.on('storage:end:load', (data) => { 125 | const fonts = data.fonts || [] 126 | editor.getModel().set('fonts', fonts) 127 | // FIXME: remove this timeout which is a workaround for issues in Silex storage providers 128 | setTimeout(() => refresh(editor, opts), 1000) 129 | }) 130 | // update the head and the ui when the frame is loaded 131 | editor.on('canvas:frame:load', () => refresh(editor, opts)) 132 | // When the page changes, update the dom 133 | editor.on('page', () => refresh(editor, opts)) 134 | } 135 | 136 | function match(hay, s) { 137 | const regExp = new RegExp(s, 'i') 138 | return hay.search(regExp) !== -1 139 | } 140 | 141 | const searchInputRef = createRef() 142 | const fontRef = createRef() 143 | 144 | function displayFonts(editor, config, fontsList) { 145 | const searchInput = searchInputRef.value 146 | const activeFonts = fontsList.filter(f => match(f.family, searchInput?.value || '')) 147 | searchInput?.focus() 148 | function findFont(font) { 149 | return fontsList.find(f => font.name === f.family) 150 | } 151 | render(html` 152 |
153 |
154 |
155 | { 163 | //(fontRef.value as HTMLSelectElement).selectedIndex = 0 164 | setTimeout(() => displayFonts(editor, config, fontsList)) 165 | }}/> 166 | 176 | 189 |
190 |
191 |
192 |
194 |

${editor.I18n.t('grapesjs-fonts.Installed fonts')}

195 |
    196 | ${ map(fonts, f => html` 197 |
  1. 198 |
    199 |

    ${f.name}

    200 |
    201 |
    202 |
    203 | CSS rules 204 | { 210 | updateRules(editor, fonts, f, e.target.value) 211 | displayFonts(editor, config, fontsList) 212 | }} 213 | /> 214 |
    215 |
    216 | Variants 217 | ${ map( 218 | // keep only variants which are letters, no numbers 219 | // FIXME: we need the weights 220 | findFont(f)?.variants.filter(v => v.replace(/[a-z]/g, '') === ''), 221 | v => html` 222 |
    223 | { 229 | updateVariant(editor, fonts, f, v, e.target.checked) 230 | displayFonts(editor, config, fontsList) 231 | }} 232 | /> 233 |
    234 | `)} 235 |
    236 |
    237 | 243 |
  2. 244 | `) } 245 |
246 |
247 |
248 | editor.stopCommand(cmdOpenFonts)} value="${editor.I18n.t('grapesjs-fonts.Cancel')}"> 249 | 250 |
251 |
252 | `, el) 253 | } 254 | 255 | function addFont(editor, config, fonts, font) { 256 | const name = font.family 257 | const value = `"${font.family}", ${font.category}` 258 | fonts.push({ name, value, variants: [] }) 259 | } 260 | 261 | function removeFont(editor, fonts, font) { 262 | const idx = fonts.findIndex(f => f === font) 263 | fonts.splice(idx, 1) 264 | } 265 | 266 | function removeAll(doc, attr) { 267 | const all = doc.head.querySelectorAll(`[${ attr }]`) 268 | Array.from(all) 269 | .forEach((el) => el.remove()) 270 | } 271 | 272 | const GOOGLE_FONTS_ATTR = 'data-silex-gstatic' 273 | function updateHead(editor, fonts) { 274 | const doc = editor.Canvas.getDocument() 275 | if(!doc) { 276 | // This happens while grapesjs is not ready 277 | return 278 | } 279 | removeAll(doc, GOOGLE_FONTS_ATTR) 280 | const html = getHtml(fonts, GOOGLE_FONTS_ATTR) 281 | doc.head.insertAdjacentHTML('beforeend', html) 282 | } 283 | 284 | function updateUi(editor, fonts, opts) { 285 | const styleManager = editor.StyleManager 286 | const fontProperty = styleManager.getProperty('typography', 'font-family') 287 | if(!fontProperty) { 288 | // This happens while grapesjs is not ready 289 | return 290 | } 291 | if (opts.preserveDefaultFonts) { 292 | fonts = defaults.concat(fonts) 293 | } else if (fonts.length === 0) { 294 | fonts = defaults 295 | } 296 | fontProperty.setOptions(fonts) 297 | } 298 | 299 | export function refresh(editor, opts) { 300 | const fonts = editor.getModel().get('fonts') || [] 301 | updateHead(editor, fonts) 302 | updateUi(editor, fonts, opts) 303 | } 304 | 305 | function updateRules(editor, fonts, font, value) { 306 | font.value = value 307 | } 308 | 309 | function updateVariant(editor, fonts, font, variant, checked) { 310 | const has = font.variants?.includes(variant) 311 | if(has && !checked) font.variants = font.variants.filter(v => v !== variant) 312 | else if(!has && checked) font.variants.push(variant) 313 | } 314 | 315 | export function getHtml(fonts, attr = '') { 316 | // FIXME: how to use google fonts v2? 317 | // google fonts V2: https://developers.google.com/fonts/docs/css2 318 | //fonts.forEach(f => { 319 | // const prefix = f.variants.length ? ':' : '' 320 | // const variants = prefix + f.variants.map(v => { 321 | // const weight = parseInt(v) 322 | // const axis = v.replace(/\d+/g, '') 323 | // return `${axis},wght@${weight}` 324 | // }).join(',') 325 | // insert(doc, GOOGLE_FONTS_ATTR, 'link', { 'href': `${ fontServer }/css2?family=${f.name.replace(/ /g, '+')}${variants}&display=swap`, 'rel': 'stylesheet' }) 326 | //}) 327 | 328 | // Google fonts v1 329 | // https://developers.google.com/fonts/docs/getting_started#a_quick_example 330 | const preconnect = `` 331 | const links = fonts 332 | .map(f => { 333 | const prefix = f.variants.length ? ':' : '' 334 | const variants = prefix + f.variants.map(v => v.replace(/\d+/g, '')).filter(v => !!v).join(',') 335 | return `` 336 | }) 337 | .join('') 338 | 339 | return preconnect + links 340 | } -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { fontsDialogPlugin } from './fonts.js' 2 | import commands from './commands.js' 3 | import en from './locale/en.js' 4 | import fr from './locale/fr.js' 5 | 6 | export default (editor, opts = {}) => { 7 | 8 | const options = { ...{ 9 | // default options 10 | i18n: {}, 11 | preserveDefaultFonts: true, 12 | }, ...opts } 13 | 14 | 15 | // Load i18n files 16 | editor.I18n && editor.I18n.addMessages({ 17 | en, 18 | fr, 19 | ...options.i18n, 20 | }) 21 | 22 | commands(editor, options) 23 | fontsDialogPlugin(editor, options) 24 | } 25 | 26 | // Expose commands to the app 27 | export * from './fonts.js' 28 | export * from './commands.js' 29 | -------------------------------------------------------------------------------- /src/locale/en.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'grapesjs-fonts': { 3 | 'Fonts': 'Fonts', 4 | 'You must provide Google font api key': 'You must provide Google font api key, see https://developers.google.com/fonts/docs/developer_api#APIKey', 5 | 'Search': 'Search fonts...', 6 | 'Add font': 'Install font', 7 | 'Remove': 'Remove', 8 | 'Save': 'Save', 9 | 'Cancel': 'Cancel', 10 | 'Installed fonts': 'Installed fonts', 11 | }, 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/locale/fr.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'grapesjs-fonts': { 3 | 'Fonts': 'Polices', 4 | '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', 5 | 'Family': 'Famille', 6 | 'Search': 'Rechercher une police', 7 | 'Add font': 'Installer la police', 8 | 'Remove': 'Supprimer', 9 | 'Save': 'Enregistrer', 10 | 'Cancel': 'Annuler', 11 | 'Installed fonts': 'Polices installées', 12 | }, 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/locale/ptbr.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 'grapesjs-fonts': { 3 | 'Fonts': 'Fontes', 4 | 'You must provide Google font api key': 'Você deve fornecer uma chave de api: https://developers.google.com/fonts/docs/developer_api#APIKey', 5 | 'Search': 'Procurar fontes...', 6 | 'Add font': 'Instalar fonte', 7 | 'Remove': 'Remover', 8 | 'Save': 'Salvar', 9 | 'Cancel': 'Cancelar', 10 | 'Installed fonts': 'Fontes instaladas', 11 | }, 12 | } 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "sourceMap": true, 11 | "skipLibCheck": true, 12 | "esModuleInterop": true, 13 | "allowSyntheticDefaultImports": true, 14 | "strict": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "noFallthroughCasesInSwitch": true, 17 | "module": "esnext", 18 | "moduleResolution": "node", 19 | "resolveJsonModule": true, 20 | "isolatedModules": true, 21 | "noEmit": false 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------