From f5acea7f9ce232773ec3adf1828a3d18bbedee1e Mon Sep 17 00:00:00 2001 From: Nicolas Lempereur Date: Tue, 3 Nov 2015 06:56:16 +0100 Subject: [PATCH] [FIX] web_editor: escape for xml in translation as done in ir.ui.view Currently server side there is two differents source for html content displayed on a qweb rendered page: 1) ir.ui.view arch value are stored as xml and are unescaped before being displayed, so we have to escape the text nodes before saving. e.g: *   should be stored as &nbsp; since it is an HTML entity but not a defined XML entity, * & should be stored as &amp; since when unescaping it, it would become & which is invalid in HTML, * < should be stored as &lt; since when unescaping it, it would become `<` so HTML text node could become HTML element node. The tag themselves can also be escaped but it often has the same result: <em&;gt;blah</em> is the same as blah when unescaping is applied to both. But it is required is some instance, e.g unescaped would be invalid xml. 2) openerp.fields.Html value are stored directly in HTML formatting and should, conversely, not be escaped before being stored. Thus when saving an ir.ui.view part modified thanks to the website editor, an escaping of text node content is carried out to take this into account, but the same was currently not done for the v9.0 new translation system. This commit apply the same logic when saving ir.ui.view as when saving ir.translation values. --- addons/web_editor/static/src/js/rte.js | 24 ++++++++++++------- addons/web_editor/static/src/js/translator.js | 3 ++- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/addons/web_editor/static/src/js/rte.js b/addons/web_editor/static/src/js/rte.js index 6f210e005ee..a87f9fcf1e8 100644 --- a/addons/web_editor/static/src/js/rte.js +++ b/addons/web_editor/static/src/js/rte.js @@ -420,14 +420,10 @@ var RTE = Widget.extend({ }); }, - saveElement: function ($el, context) { - // remove multi edition - if ($el.data('oe-model')) { - var key = $el.data('oe-model')+":"+$el.data('oe-id')+":"+$el.data('oe-field')+":"+$el.data('oe-type')+":"+$el.data('oe-expression'); - if (this.__saved[key]) return true; - this.__saved[key] = true; - } - // escape text nodes for xml saving + /** + * Get HTML cloned element with text nodes escaped for XML storage + */ + getEscapedElement: function($el) { var escaped_el = $el.clone(); var to_escape = escaped_el.find('*').addBack(); to_escape = to_escape.not(to_escape.filter('object,iframe,script,style,[data-oe-model][data-oe-model!="ir.ui.view"]').find('*').addBack()); @@ -436,7 +432,17 @@ var RTE = Widget.extend({ this.nodeValue = $('
').text(this.nodeValue).html(); } }); - var markup = escaped_el.prop('outerHTML'); + return escaped_el; + }, + + saveElement: function ($el, context) { + // remove multi edition + if ($el.data('oe-model')) { + var key = $el.data('oe-model')+":"+$el.data('oe-id')+":"+$el.data('oe-field')+":"+$el.data('oe-type')+":"+$el.data('oe-expression'); + if (this.__saved[key]) return true; + this.__saved[key] = true; + } + var markup = this.getEscapedElement($el).prop('outerHTML'); return ajax.jsonRpc('/web/dataset/call', 'call', { model: 'ir.ui.view', diff --git a/addons/web_editor/static/src/js/translator.js b/addons/web_editor/static/src/js/translator.js index b15e8278004..0d41699c3f3 100644 --- a/addons/web_editor/static/src/js/translator.js +++ b/addons/web_editor/static/src/js/translator.js @@ -41,13 +41,14 @@ var RTE_Translate = rte.Class.extend({ var key = 'translation:'+$el.data('oe-translation-id'); if (this.__saved[key]) return true; this.__saved[key] = true; + var translation_content = this.getEscapedElement($el).html(); return ajax.jsonRpc('/web/dataset/call', 'call', { model: 'ir.translation', method: 'write', args: [ [+$el.data('oe-translation-id')], - {value: $el.html(), state: 'translated'}, + {value: translation_content, state: 'translated'}, context || base.get_context() ], });