diff --git a/addons/website/static/src/components/translator/translator.js b/addons/website/static/src/components/translator/translator.js index 20b6144d45e..10cb1a1b173 100644 --- a/addons/website/static/src/components/translator/translator.js +++ b/addons/website/static/src/components/translator/translator.js @@ -36,6 +36,7 @@ export class AttributeTranslateDialog extends Component { $originalNode.val(value).trigger('translate'); } $node.trigger('change'); + $originalNode[0].classList.add('oe_translated'); }); $group.append($label).append($input); } @@ -58,7 +59,7 @@ export class SelectTranslateDialog extends Component { const value = this.inputEl.el.value; this.optionEl.textContent = value; this.optionEl.classList.toggle( - 'o_option_translated', + 'oe_translated', value !== this.optionEl.dataset.initialTranslationValue ); } @@ -320,6 +321,13 @@ export class WebsiteTranslator extends WebsiteEditorComponent { Object.values(translation).forEach((node) => { var trans = self.getTranslationObject(node); trans.value = (trans.value ? trans.value : $node.html()).replace(/[ \t\n\r]+/, ' '); + trans.state = node.dataset.oeTranslationState; + // If a node has an already translated attribute, we don't + // need to update its state, since it can be set again as + // "to_translate" by other attributes... + if ($node[0].dataset.oeTranslationState === 'translated') { + return; + } $node.attr('data-oe-translation-state', (trans.state || 'to_translate')); }); }); diff --git a/addons/website/static/src/scss/website.wysiwyg.scss b/addons/website/static/src/scss/website.wysiwyg.scss index 1c7fa607db1..ec2c4f133ab 100644 --- a/addons/website/static/src/scss/website.wysiwyg.scss +++ b/addons/website/static/src/scss/website.wysiwyg.scss @@ -32,7 +32,7 @@ html[lang] > body.editor_enable [data-oe-translation-state] { } } - &.o_dirty, .o_option_translated { + &.o_dirty, &.oe_translated, .oe_translated { background: rgba($o-we-translated-content-color, 0.25) !important; } } diff --git a/addons/website/static/tests/tours/rte.js b/addons/website/static/tests/tours/rte.js index ee172906e4a..a1e594ffdc0 100644 --- a/addons/website/static/tests/tours/rte.js +++ b/addons/website/static/tests/tours/rte.js @@ -84,7 +84,7 @@ wTourUtils.registerWebsitePreviewTour('rte_translator', { run: function () { $('iframe:not(.o_ignore_in_tour)').contents().find("#wrap p:first").replaceWith('
Write one or two paragraphs describing your product or\ services. To be successful your content needs to be\ - useful to your readers.
\ + useful to your readers. \<b></b> is an HTML tag & is empty
'); $('iframe:not(.o_ignore_in_tour)').contents().find("#wrap img").attr("title", "test translate image title"); } @@ -141,10 +141,18 @@ wTourUtils.registerWebsitePreviewTour('rte_translator', { content: "translate placeholder", trigger: '.modal-dialog input:first', run: 'text test Parseltongue placeholder', +}, { + content: "translate default value", + trigger: '.modal-dialog input:last', + run: 'text test Parseltongue default value', }, { content: "close modal", trigger: '.modal-footer .btn-primary', extra_trigger: '.modal input:propValue(test Parseltongue placeholder)', +}, { + content: "check: input marked as translated", + trigger: 'iframe input[placeholder="test Parseltongue placeholder"].oe_translated', + run: () => {}, }, { content: "save translation", trigger: 'button[data-action=save]', @@ -162,7 +170,10 @@ wTourUtils.registerWebsitePreviewTour('rte_translator', { content: "check: placeholder translation", trigger: 'iframe input[placeholder="test Parseltongue placeholder"]', run: function () {}, // it's a check - +}, { + content: "check: default value translation", + trigger: 'iframe input[value="test Parseltongue default value"]', + run: () => {}, }, { content: "open language selector", trigger: 'iframe .js_language_selector button:first',