[FIX] website: fix adding same font family twice

Steps to reproduce the bug :

- Add the same google font twice with the font family selector in the
option tab of the editor panel.
- The font will be displayed only once in the font selector menu but 2
trash icons will be added, one for the added font and one for the font
that was already there.

This commit fix this and allows now the user to add the same font twice,
but only to replace a served font by a local font. The opposite does not
make sense, but if the user really wants to replace a local font with a
served, it is always possible by deleting the locale beforehand.

In addition, this commit adds a cloud icon next to the default fonts of
the theme. Since these fonts are served by Google, it is logical to have
the cloud icon. This is consistent with the cloud icon that is present
when the user adds a font served by Google.

task-2998689

closes odoo/odoo#122652

X-original-commit: 948ff01e64e5d71d60d209d074dd6be6510fe794
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
This commit is contained in:
Benjamin Vray
2023-05-30 13:03:28 +02:00
parent a89af09120
commit 5fd185ef85
4 changed files with 53 additions and 4 deletions
+9
View File
@@ -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
@@ -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 {
@@ -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),
@@ -69,10 +69,10 @@
</div>
</div>
<t t-name="website.delete_google_font_btn">
<i t-if="!local" role="button" class="text-info ms-2 fa fa-cloud" title="This font is hosted and served to your visitors by Google servers"/>
<i t-if="!local" role="button" class="text-info me-2 fa fa-cloud" title="This font is hosted and served to your visitors by Google servers"/>
<t t-set="delete_font_title">Delete this font</t>
<i role="button"
class="text-danger ms-2 fa fa-trash-o o_we_delete_google_font_btn"
class="text-danger fa fa-trash-o o_we_delete_google_font_btn"
t-att-aria-label="delete_font_title"
t-att-title="delete_font_title"
t-att-data-local-font="local"