Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FW][IMP] website: handle text options in translation mode #158378

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
109 changes: 71 additions & 38 deletions addons/web_editor/static/src/js/editor/snippets.editor.js
Expand Up @@ -586,8 +586,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 @@ -1963,33 +1974,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 @@ -2054,6 +2038,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 @@ -2265,7 +2276,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 @@ -2659,12 +2681,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 @@ -3048,9 +3064,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 @@ -3168,6 +3184,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 @@ -3619,6 +3641,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 @@ -3791,6 +3818,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
Expand Up @@ -195,6 +195,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 @@ -486,6 +497,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