From 1b473cf0db4d85c2b523ac87fbab533bce5f3e21 Mon Sep 17 00:00:00 2001 From: "Chong Wang (cwg)" Date: Wed, 7 Sep 2022 21:13:34 +0200 Subject: [PATCH] [IMP] website, web_editor: frontend for new translate api --- .../static/src/js/editor/snippets.editor.js | 4 +- .../static/src/js/wysiwyg/wysiwyg.js | 39 ++++++++++++------- .../src/components/translator/translator.js | 25 ++++++------ addons/website/static/tests/tours/rte.js | 2 +- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/addons/web_editor/static/src/js/editor/snippets.editor.js b/addons/web_editor/static/src/js/editor/snippets.editor.js index 97aa04f1424..d78b0b5ff0b 100644 --- a/addons/web_editor/static/src/js/editor/snippets.editor.js +++ b/addons/web_editor/static/src/js/editor/snippets.editor.js @@ -3818,8 +3818,8 @@ var SnippetsMenu = Widget.extend({ } if (!range || !$currentSelectionTarget.parents('#wrapwrap, .iframe-editor-wrapper .o_editable').length || - $(selection.anchorNode).parent('[data-oe-model]:not([data-oe-type="html"]):not([data-oe-field="arch"]):not([data-oe-translation-id])').length || - $(selection.focusNode).parent('[data-oe-model]:not([data-oe-type="html"]):not([data-oe-field="arch"]):not([data-oe-translation-id])').length || + $(selection.anchorNode).parent('[data-oe-model]:not([data-oe-type="html"]):not([data-oe-field="arch"]):not([data-oe-translation-initial-sha])').length || + $(selection.focusNode).parent('[data-oe-model]:not([data-oe-type="html"]):not([data-oe-field="arch"]):not([data-oe-translation-initial-sha])').length || (e && $(e.target).closest('.fa, img').length || this.options.wysiwyg.lastMediaClicked && $(this.options.wysiwyg.lastMediaClicked).is('.fa, img')) || (this.options.wysiwyg.lastElement && !this.options.wysiwyg.lastElement.isContentEditable) diff --git a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js index b3feab5dd75..74dfd68141a 100644 --- a/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js +++ b/addons/web_editor/static/src/js/wysiwyg/wysiwyg.js @@ -1016,7 +1016,7 @@ const Wysiwyg = Widget.extend({ observerData.observer.observe(observerData.field, observerOptions); } } else { - const odooFieldSelector = '[data-oe-model], [data-oe-translation-id]'; + const odooFieldSelector = '[data-oe-model], [data-oe-translation-initial-sha]'; const $odooFields = this.$editable.find(odooFieldSelector); this.odooFieldObservers = []; @@ -1032,8 +1032,8 @@ const Wysiwyg = Widget.extend({ .filter('[data-oe-field="' + $node.data('oe-field') + '"]'); } - if ($node.data('oe-translation-id')) { - $nodes = $nodes.filter('[data-oe-translation-id="' + $node.data('oe-translation-id') + '"]'); + if ($node.data('oe-translation-initial-sha')) { + $nodes = $nodes.filter('[data-oe-translation-initial-sha="' + $node.data('oe-translation-initial-sha') + '"]'); } if ($node.data('oe-type')) { $nodes = $nodes.filter('[data-oe-type="' + $node.data('oe-type') + '"]'); @@ -1922,13 +1922,21 @@ const Wysiwyg = Widget.extend({ * @override */ _saveTranslationElement: function ($el, context, withLang = true) { - if ($el.data('oe-translation-id')) { + if ($el.data('oe-translation-initial-sha')) { + const $els = $el; + const translations = {}; + translations[context.lang] = Object.assign({}, ...$els.toArray().map( + (x) => ({ + [$(x).data('oe-translation-initial-sha')]: this._getEscapedElement($(x)).html() + }) + )); return this._rpc({ - model: 'ir.translation', - method: 'save_html', + model: $els.data('oe-model'), + method: 'update_field_translations_sha', args: [ - [+$el.data('oe-translation-id')], - this._getEscapedElement($el).html() + [+$els.data('oe-id')], + $els.data('oe-field'), + translations, ], context: context, }); @@ -2151,10 +2159,13 @@ const Wysiwyg = Widget.extend({ $('.o_editable') .removeClass('o_editable o_is_inline_editable o_editable_date_field_linked o_editable_date_field_format_changed'); - const defs = _.map($allBlocks, (el) => { - const $el = $(el); + const defs = _.map(_.groupBy($allBlocks.toArray(), + function($obj) { + return $obj.dataset['oe-model'] + $obj.dataset['oe-field'] + $obj.dataset['oe-id'] + }), (els) => { + const $els = $(els); - $el.find('[class]').filter(function () { + $els.find('[class]').filter(function () { if (!this.getAttribute('class').match(/\S/)) { this.removeAttribute('class'); } @@ -2166,16 +2177,16 @@ const Wysiwyg = Widget.extend({ if (this.options.enableTranslation) { saveElement = '_saveTranslationElement'; } - return this[saveElement]($el, context || this.options.context) + return this[saveElement]($els, context || this.options.context) .then(function () { - $el.removeClass('o_dirty'); + $els.removeClass('o_dirty'); }).guardedCatch(function (response) { // because ckeditor regenerates all the dom, we can't just // setup the popover here as everything will be destroyed by // the DOM regeneration. Add markings instead, and returns a // new rejection with all relevant info var id = _.uniqueId('carlos_danger_'); - $el.addClass('o_dirty o_editable oe_carlos_danger ' + id); + $els.addClass('o_dirty o_editable oe_carlos_danger ' + id); $('.o_editable.' + id) .removeClass(id) .popover({ diff --git a/addons/website/static/src/components/translator/translator.js b/addons/website/static/src/components/translator/translator.js index 828a66f67d6..63d5b0002ca 100644 --- a/addons/website/static/src/components/translator/translator.js +++ b/addons/website/static/src/components/translator/translator.js @@ -53,13 +53,13 @@ export class TranslatorInfoDialog extends Component { TranslatorInfoDialog.components = { WebsiteDialog }; TranslatorInfoDialog.template = 'website.TranslatorInfoDialog'; -const savableSelector = '[data-oe-translation-id], ' + +const savableSelector = '[data-oe-translation-initial-sha], ' + '[data-oe-model][data-oe-id][data-oe-field], ' + - '[placeholder*="data-oe-translation-id="], ' + - '[title*="data-oe-translation-id="], ' + - '[value*="data-oe-translation-id="], ' + - 'textarea:contains(data-oe-translation-id), ' + - '[alt*="data-oe-translation-id="]'; + '[placeholder*="data-oe-translation-initial-sha="], ' + + '[title*="data-oe-translation-initial-sha="], ' + + '[value*="data-oe-translation-initial-sha="], ' + + 'textarea:contains(data-oe-translation-initial-sha), ' + + '[alt*="data-oe-translation-initial-sha="]'; export class WebsiteTranslator extends WebsiteEditorComponent { setup() { @@ -110,11 +110,8 @@ export class WebsiteTranslator extends WebsiteEditorComponent { } getTranslationObject(nodeEl) { - let { oeTranslationId: id } = nodeEl.dataset; - if (!id) { - const { oeModel, oeId, oeField } = nodeEl.dataset; - id = [oeModel, oeId, oeField].join(','); - } + const { oeModel, oeId, oeField, oeTranslationInitialMd5 } = nodeEl.dataset; + const id = [oeModel, oeId, oeField, oeTranslationInitialMd5].join(','); let translation = this.translations.filter(t => t.id === id)[0]; if (!translation) { translation = { id }; @@ -128,10 +125,10 @@ export class WebsiteTranslator extends WebsiteEditorComponent { const self = this; var attrs = ['placeholder', 'title', 'alt', 'value']; const $editable = this.getEditableArea(); - const translationRegex = /]*data-oe-translation-id="([0-9]+)"[^>]*>(.*)<\/span>/; + const translationRegex = /]*data-oe-translation-initial-sha="([^"]+)"[^>]*>(.*)<\/span>/; let $edited = $(); _.each(attrs, function (attr) { - const attrEdit = $editable.filter('[' + attr + '*="data-oe-translation-id="]').filter(':empty, input, select, textarea, img'); + const attrEdit = $editable.filter('[' + attr + '*="data-oe-translation-initial-sha="]').filter(':empty, input, select, textarea, img'); attrEdit.each(function () { var $node = $(this); var translation = $node.data('translation') || {}; @@ -147,7 +144,7 @@ export class WebsiteTranslator extends WebsiteEditorComponent { }); $edited = $edited.add(attrEdit); }); - const textEdit = $editable.filter('textarea:contains(data-oe-translation-id)'); + const textEdit = $editable.filter('textarea:contains(data-oe-translation-initial-sha)'); textEdit.each(function () { var $node = $(this); var translation = $node.data('translation') || {}; diff --git a/addons/website/static/tests/tours/rte.js b/addons/website/static/tests/tours/rte.js index c516e790078..a7f6fff87e2 100644 --- a/addons/website/static/tests/tours/rte.js +++ b/addons/website/static/tests/tours/rte.js @@ -89,7 +89,7 @@ wTourUtils.registerWebsitePreviewTour('rte_translator', { trigger: '.modal-footer .btn-secondary', }, { content: "check if translation is activate", - trigger: 'iframe [data-oe-translation-id]', + trigger: 'iframe [data-oe-translation-initial-sha]', }, { content: "translate text", extra_trigger: '#oe_snippets.o_loaded',