diff --git a/addons/website/i18n/website.pot b/addons/website/i18n/website.pot index 833a3cdd710..9a28d8f92f5 100644 --- a/addons/website/i18n/website.pot +++ b/addons/website/i18n/website.pot @@ -9430,6 +9430,15 @@ msgid "" " Useful to (soft) reset a broken view." msgstr "" +#. module: website +#. odoo-javascript +#: code:addons/website/static/src/js/editor/snippets.options.js:0 +#, python-format +msgid "" +"This font already exists, you can only add it as a local font to replace the" +" server version." +msgstr "" + #. module: website #. odoo-javascript #: code:addons/website/static/src/xml/website.editor.xml:0 diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js index 60f40e714a3..18e66dff155 100644 --- a/addons/website/static/src/js/editor/snippets.options.js +++ b/addons/website/static/src/js/editor/snippets.options.js @@ -112,12 +112,22 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ start: async function () { const style = window.getComputedStyle(this.$target[0].ownerDocument.documentElement); const nbFonts = parseInt(weUtils.getCSSVariableValue('number-of-fonts', style)); + // User fonts served by google server. const googleFontsProperty = weUtils.getCSSVariableValue('google-fonts', style); this.googleFonts = googleFontsProperty ? googleFontsProperty.split(/\s*,\s*/g) : []; this.googleFonts = this.googleFonts.map(font => font.substring(1, font.length - 1)); // Unquote + // Local user fonts. const googleLocalFontsProperty = weUtils.getCSSVariableValue('google-local-fonts', style); this.googleLocalFonts = googleLocalFontsProperty ? googleLocalFontsProperty.slice(1, -1).split(/\s*,\s*/g) : []; + // If a same font exists both remotely and locally, we remove the remote + // font to prioritize the local font. The remote one will never be + // displayed or loaded as long as the local one exists. + this.googleFonts = this.googleFonts.filter(font => { + const localFonts = this.googleLocalFonts.map(localFont => localFont.split(":")[0]); + return localFonts.indexOf(`'${font}'`) === -1; + }); + this.allFonts = []; await this._super(...arguments); @@ -140,12 +150,15 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ const fontEls = []; const methodName = this.el.dataset.methodName || 'customizeWebsiteVariable'; const variable = this.el.dataset.variable; + const themeFontsNb = nbFonts - (this.googleLocalFonts.length + this.googleFonts.length); for (let fontNb = 0; fontNb < nbFonts; fontNb++) { const realFontNb = fontNb + 1; const fontKey = weUtils.getCSSVariableValue(`font-number-${realFontNb}`, style); + this.allFonts.push(fontKey); let fontName = fontKey.slice(1, -1); // Unquote let fontFamily = fontName; - if (fontName === "SYSTEM_FONTS") { + const isSystemFonts = fontName === "SYSTEM_FONTS"; + if (isSystemFonts) { fontName = _t("System Fonts"); fontFamily = 'var(--o-system-fonts)'; } @@ -154,6 +167,15 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ fontEl.dataset.variable = variable; fontEl.dataset[methodName] = fontKey; fontEl.dataset.fontFamily = fontFamily; + if ((realFontNb <= themeFontsNb) && !isSystemFonts) { + // Add the "cloud" icon next to the theme's default fonts + // because they are served by Google. + fontEl.appendChild(Object.assign(document.createElement('i'), { + role: 'button', + className: 'text-info me-2 fa fa-cloud', + title: _t("This font is hosted and served to your visitors by Google servers"), + })); + } fontEls.push(fontEl); this.menuEl.appendChild(fontEl); }; @@ -251,6 +273,20 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ const font = m[1].replace(/\+/g, ' '); const googleFontServe = dialog.el.querySelector('#google_font_serve').checked; + const fontName = `'${font}'`; + // If the font already exists, it will only be added if + // the user chooses to add it locally when it is already + // imported from the Google Fonts server. + const fontExistsLocally = this.googleLocalFonts.some(localFont => localFont.split(':')[0] === fontName); + const fontExistsOnServer = this.allFonts.includes(fontName); + const preventFontAddition = fontExistsLocally || (fontExistsOnServer && googleFontServe); + if (preventFontAddition) { + inputEl.classList.add('is-invalid'); + // Show custom validity error message. + inputEl.setCustomValidity(_t("This font already exists, you can only add it as a local font to replace the server version.")); + inputEl.reportValidity(); + return; + } if (googleFontServe) { this.googleFonts.push(font); } else { @@ -295,7 +331,8 @@ const FontFamilyPickerUserValueWidget = SelectUserValueWidget.extend({ let googleFontName; if (isLocalFont) { const googleFont = this.googleLocalFonts[googleFontIndex].split(':'); - googleFontName = googleFont[0]; + // Remove double quotes + googleFontName = googleFont[0].substring(1, googleFont[0].length - 1); values['delete-font-attachment-id'] = googleFont[1]; this.googleLocalFonts.splice(googleFontIndex, 1); } else { diff --git a/addons/website/static/src/scss/secondary_variables.scss b/addons/website/static/src/scss/secondary_variables.scss index 46b47bde464..c43f5e60382 100644 --- a/addons/website/static/src/scss/secondary_variables.scss +++ b/addons/website/static/src/scss/secondary_variables.scss @@ -233,6 +233,9 @@ $o-theme-font-configs: map-merge($o-base-theme-font-configs, $o-theme-font-confi // Add locally hosted google fonts @each $font-name, $font-attach-id in (o-website-value('google-local-fonts') or ()) { + // If a font exists both remotely and locally, we remove the remote font to + // prioritize the local font. + $o-theme-font-configs: map-remove($o-theme-font-configs, $font-name); $o-theme-font-configs: map-merge($o-theme-font-configs, ( $font-name: ( 'family': (quote($font-name), sans-serif), diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml index a6b3abb345a..ca63e9bcb6a 100644 --- a/addons/website/static/src/xml/website.editor.xml +++ b/addons/website/static/src/xml/website.editor.xml @@ -69,10 +69,10 @@ - + Delete this font