Skip to content

Commit

Permalink
[IMP] web_editor, website: allow text options translation
Browse files Browse the repository at this point in the history
The goal of this commit is to add a minimal and stable compatible code
adaptation that allows to use text options (text animations & text
highlights) in the translation mode. Mainly by allowing the creation of
snippet editors if the target is a text option snippet.

opw-3686777

closes #158402

X-original-commit: fe1b89e
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
Signed-off-by: Outagant Mehdi (mou) <mou@odoo.com>
  • Loading branch information
xO-Tx committed May 15, 2024
1 parent 28efebf commit e8af80a
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 38 deletions.
109 changes: 71 additions & 38 deletions addons/web_editor/static/src/js/editor/snippets.editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,19 @@ var SnippetEditor = Widget.extend({
// As the 'd-none' class is added to option sections that have no visible
// options with 'updateOptionsUIVisibility', if no option section is
// visible, we prevent the activation of the options.
const optionsSectionVisible = editorUIsToUpdate.some(
editor => !editor.$optionsSection[0].classList.contains('d-none')
// Special case: For now, we only allow activating text options in
// translate mode (with no parent editors). These text options have a
// special way to be displayed in the editor: We add the options in the
// toolbar `onFocus()` and set them back `onBlur()`. Which means the
// options section will be empty and get a `d-none` class, while
// actually it has visible options (they are just added in the toolbar
// DOM). We need to take them into consideration to display options in
// translate mode correctly.
const optionsSectionVisible = editorUIsToUpdate.some(editor =>
!editor.$optionsSection[0].classList.contains("d-none") ||
Object.keys(editor.styles).some(key =>
editor.styles[key].el.closest(".oe-toolbar")
)
);
if (editorUIsToUpdate.length > 0 && !optionsSectionVisible) {
return null;
Expand Down Expand Up @@ -1955,33 +1966,6 @@ var SnippetsMenu = Widget.extend({
},
});

if (this.options.enableTranslation) {
// Load the sidebar with the style tab only.
await this._loadSnippetsTemplates();
defs.push(this._updateInvisibleDOM());
this.$el.find('.o_we_website_top_actions').removeClass('d-none');
this.$('.o_snippet_search_filter').addClass('d-none');
this.$('#o_scroll').addClass('d-none');
this.$('button[data-action="mobilePreview"]').addClass('d-none');
this.$('#snippets_menu button').removeClass('active').prop('disabled', true);
this.$('.o_we_customize_snippet_btn').addClass('active').prop('disabled', false);
this.$('o_we_ui_loading').addClass('d-none');
$(this.customizePanel).removeClass('d-none');
this.$('#o_we_editor_toolbar_container').hide();
this.$('#o-we-editor-table-container').addClass('d-none');
return Promise.all(defs);
}

this.emptyOptionsTabContent = document.createElement('div');
this.emptyOptionsTabContent.classList.add('text-center', 'pt-5');
this.emptyOptionsTabContent.append(_t("Select a block on your page to style it."));

// Fetch snippet templates and compute it
defs.push((async () => {
await this._loadSnippetsTemplates(this.options.invalidateSnippetCache);
await this._updateInvisibleDOM();
})());

// Active snippet editor on click in the page
this.$document.on('click.snippets_menu', '*', this._onClick);
// Needed as bootstrap stop the propagation of click events for dropdowns
Expand Down Expand Up @@ -2046,6 +2030,33 @@ var SnippetsMenu = Widget.extend({
// scrolling a modal)
this.$scrollingTarget[0].addEventListener('scroll', this._onScrollingElementScroll, {capture: true});

if (this.options.enableTranslation) {
// Load the sidebar with the style tab only.
await this._loadSnippetsTemplates();
defs.push(this._updateInvisibleDOM());
this.$el.find('.o_we_website_top_actions').removeClass('d-none');
this.$('.o_snippet_search_filter').addClass('d-none');
this.$('#o_scroll').addClass('d-none');
this.$('button[data-action="mobilePreview"]').addClass('d-none');
this.$('#snippets_menu button').removeClass('active').prop('disabled', true);
this.$('.o_we_customize_snippet_btn').addClass('active').prop('disabled', false);
this.$('o_we_ui_loading').addClass('d-none');
$(this.customizePanel).removeClass('d-none');
this.$('#o_we_editor_toolbar_container').hide();
this.$('#o-we-editor-table-container').addClass('d-none');
return Promise.all(defs).then(() => {});
}

this.emptyOptionsTabContent = document.createElement('div');
this.emptyOptionsTabContent.classList.add('text-center', 'pt-5');
this.emptyOptionsTabContent.append(_t("Select a block on your page to style it."));

// Fetch snippet templates and compute it
defs.push((async () => {
await this._loadSnippetsTemplates(this.options.invalidateSnippetCache);
await this._updateInvisibleDOM();
})());

// Auto-selects text elements with a specific class and remove this
// on text changes
const alreadySelectedElements = new Set();
Expand Down Expand Up @@ -2257,7 +2268,18 @@ var SnippetsMenu = Widget.extend({
}
this._mutex.exec(() => {
if (this._currentTab === this.tabs.OPTIONS && !this.snippetEditors.length) {
this._activateEmptyOptionsTab();
const selection = this.$body[0].ownerDocument.getSelection();
const range = selection?.rangeCount && selection.getRangeAt(0);
const currentlySelectedNode = range?.commonAncestorContainer;
// In some cases (e.g. in translation mode) it's possible to have
// all snippet editors destroyed after disabling text options.
// We still want to keep the toolbar available in this case.
const isEditableTextElementSelected =
currentlySelectedNode?.nodeType === Node.TEXT_NODE &&
!!currentlySelectedNode?.parentNode?.isContentEditable;
if (!isEditableTextElementSelected) {
this._activateEmptyOptionsTab();
}
}
});
},
Expand Down Expand Up @@ -2651,12 +2673,6 @@ var SnippetsMenu = Widget.extend({
* (might be async when an editor must be created)
*/
_activateSnippet: async function ($snippet, previewMode, ifInactiveOptions) {
if (this.options.enableTranslation) {
// In translate mode, do not activate the snippet when enabling its
// corresponding invisible element. Indeed, in translate mode, we
// only want to toggle its visibility.
return;
}
if (this._blockPreviewOverlays && previewMode) {
return;
}
Expand Down Expand Up @@ -3040,9 +3056,9 @@ var SnippetsMenu = Widget.extend({
}
return $target;
};
globalSelector.is = function ($from) {
globalSelector.is = function ($from, options = {}) {
for (var i = 0, len = selectors.length; i < len; i++) {
if (selectors[i].is($from)) {
if (options.onlyTextOptions ? $from.is(self.templateOptions[i].data.textSelector) : selectors[i].is($from)) {
return true;
}
}
Expand Down Expand Up @@ -3160,6 +3176,12 @@ var SnippetsMenu = Widget.extend({
return snippetEditor.__isStarted;
}

// In translate mode, only allow creating the editor if the target is a
// text option snippet.
if (this.options.enableTranslation && !this._allowInTranslationMode($snippet)) {
return Promise.resolve(null);
}

var def;
if (this._allowParentsEditors($snippet)) {
var $parent = globalSelector.closest($snippet.parent());
Expand Down Expand Up @@ -3611,6 +3633,11 @@ var SnippetsMenu = Widget.extend({
this._hideTooltips();
this._closeWidgets();

// In translation mode, only the options tab is available.
if (this.options.enableTranslation) {
tab = this.tabs.OPTIONS;
}

this._currentTab = tab || this.tabs.BLOCKS;

if (this._$toolbarContainer) {
Expand Down Expand Up @@ -3783,6 +3810,12 @@ var SnippetsMenu = Widget.extend({
_allowParentsEditors($snippet) {
return !this.options.enableTranslation;
},
/**
* @private
*/
_allowInTranslationMode($snippet) {
return globalSelector.is($snippet, { onlyTextOptions: true });
},

//--------------------------------------------------------------------------
// Handlers
Expand Down
14 changes: 14 additions & 0 deletions addons/website/static/src/js/editor/snippets.editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,17 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({
)[0];
element.remove();
});

// TODO remove in master: should be simply replaced by a
// `data-text-selector` attribute to mark text options.
const AnimationOptionEl = $html.find('[data-js="WebsiteAnimate"]')[0];
const HighlightOptionEl = $html.find('[data-js="TextHighlight"]')[0];
if (AnimationOptionEl) {
AnimationOptionEl.dataset.textSelector = ".o_animated_text";
}
if (HighlightOptionEl) {
HighlightOptionEl.dataset.textSelector = HighlightOptionEl.dataset.selector;
}
},
/**
* Depending of the demand, reconfigure they gmap key or configure it
Expand Down Expand Up @@ -465,6 +476,9 @@ const wSnippetMenu = weSnippetEditor.SnippetsMenu.extend({
this._disableTextOptions(targetEl);
this.options.wysiwyg.odooEditor.historyStep(true);
restoreCursor();
if (this.options.enableTranslation) {
$(selectedTextParent).trigger("content_changed");
}
} else {
if (sel.getRangeAt(0).collapsed) {
return;
Expand Down

0 comments on commit e8af80a

Please sign in to comment.