From 9ecadd06ace2d66beb9b6b06bca912bf59d58e9b Mon Sep 17 00:00:00 2001 From: "Michael Mattiello (mcm)" Date: Fri, 18 Jun 2021 08:37:44 +0000 Subject: [PATCH] [IMP] web: add messageIsHtml option for rainbowman Before this commit, rainbowman message was displayed using `t-raw` in template. Now, the message is escaped by default and needs to be marked as HTML to be displayed as well. closes odoo/odoo#72392 Task-id: 2575435 Related: odoo/enterprise#19121 Signed-off-by: Aaron Bohy (aab) --- .../legacy/frontend/rainbowman/rainbow_man.js | 12 +++++++++++- .../frontend/rainbowman/rainbowman_service.js | 4 +--- .../src/webclient/effects/effect_service.js | 3 +++ .../static/src/webclient/effects/rainbow_man.xml | 5 ++++- .../tests/webclient/effects/rainbow_man_tests.js | 16 ++++++++++++++++ addons/web_tour/static/src/js/tour_manager.js | 7 ++++++- 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/addons/web/static/src/legacy/frontend/rainbowman/rainbow_man.js b/addons/web/static/src/legacy/frontend/rainbowman/rainbow_man.js index 9cd1346b40c..7816a58abad 100644 --- a/addons/web/static/src/legacy/frontend/rainbowman/rainbow_man.js +++ b/addons/web/static/src/legacy/frontend/rainbowman/rainbow_man.js @@ -35,6 +35,7 @@ var RainbowMan = Widget.extend({ fadeout: 'medium', img_url: '/web/static/img/smile.svg', message: _t('Well Done!'), + messageIsHtml: false, }); this.delay = rainbowDelay[this.options.fadeout]; }, @@ -61,7 +62,16 @@ var RainbowMan = Widget.extend({ }, 600); // destroy only after fadeout animation is completed }, this.delay); } - this.$('.o_reward_msg_content').append(this.options.message); + let message = this.options.message; + if (!this.options.messageIsHtml) { + if (message instanceof jQuery) { + message = message.text(); + } else if (message instanceof Element) { + message = message.textContent; + } + message = document.createTextNode(message); + } + this.$('.o_reward_msg_content').append(message); return this._super.apply(this, arguments); } }); diff --git a/addons/web/static/src/legacy/frontend/rainbowman/rainbowman_service.js b/addons/web/static/src/legacy/frontend/rainbowman/rainbowman_service.js index 86f61508d1b..458cc75167f 100644 --- a/addons/web/static/src/legacy/frontend/rainbowman/rainbowman_service.js +++ b/addons/web/static/src/legacy/frontend/rainbowman/rainbowman_service.js @@ -7,7 +7,5 @@ import { bus } from "web.core"; * isn't a parent of the current context. Like in the tour manager in website. */ bus.on("show-effect", this, (payload) => { - new RainbowMan({ message: payload.message, fadeout: payload.fadeout }).appendTo( - document.getElementsByTagName("body")[0] - ); + new RainbowMan(payload).appendTo(document.getElementsByTagName("body")[0]); }); diff --git a/addons/web/static/src/webclient/effects/effect_service.js b/addons/web/static/src/webclient/effects/effect_service.js index 11d2dd1f00f..cf344dd08af 100644 --- a/addons/web/static/src/webclient/effects/effect_service.js +++ b/addons/web/static/src/webclient/effects/effect_service.js @@ -54,6 +54,8 @@ export const effectService = { * Can be a simple a string * Can be a string representation of html (prefer component if you want interactions in the DOM) * Can be a function returning a string (like _t) + * @param {boolean} [params.messageIsHtml] + * The message can be a string representation of html but it needs to be marked as well * @param {"slow"|"medium"|"fast"|"no"} [params.fadeout="medium"] * Delay for rainbowman to disappear * 'fast' will make rainbowman dissapear quickly @@ -72,6 +74,7 @@ export const effectService = { fadeout: params.fadeout, id: ++effectId, message: convertRainBowMessage(params.message) || env._t("Well Done!"), + messageIsHtml: params.messageIsHtml || false, Component: params.Component, props: params.props, }); diff --git a/addons/web/static/src/webclient/effects/rainbow_man.xml b/addons/web/static/src/webclient/effects/rainbow_man.xml index dbc1abf6b82..cf38ce7df0a 100644 --- a/addons/web/static/src/webclient/effects/rainbow_man.xml +++ b/addons/web/static/src/webclient/effects/rainbow_man.xml @@ -35,7 +35,10 @@
- + + + +
diff --git a/addons/web/static/tests/webclient/effects/rainbow_man_tests.js b/addons/web/static/tests/webclient/effects/rainbow_man_tests.js index 820c2f599ce..892048171e3 100644 --- a/addons/web/static/tests/webclient/effects/rainbow_man_tests.js +++ b/addons/web/static/tests/webclient/effects/rainbow_man_tests.js @@ -27,6 +27,7 @@ QUnit.module("RainbowMan", (hooks) => { hooks.beforeEach(async () => { rainbowManDefault = { message: "
Congrats!
", + messageIsHtml: true, fadeout: "nextTick", }; target = getFixture(); @@ -72,4 +73,19 @@ QUnit.module("RainbowMan", (hooks) => { assert.containsNone(target, ".o_reward"); parent.destroy(); }); + + QUnit.test("rendering a rainbowman with an escaped message", async function (assert) { + assert.expect(3); + const env = await makeTestEnv({ serviceRegistry }); + const parent = await mount(Parent, { env, target }); + env.services.effect.add("rainbowman", { ...rainbowManDefault, messageIsHtml: false }); + await nextTick(); + assert.containsOnce(parent.el, ".o_reward"); + assert.containsOnce(parent.el, ".o_reward_rainbow"); + assert.strictEqual( + parent.el.querySelector(".o_reward_msg_content").textContent, + "
Congrats!
" + ); + parent.destroy(); + }); }); diff --git a/addons/web_tour/static/src/js/tour_manager.js b/addons/web_tour/static/src/js/tour_manager.js index 5ccdf631fac..d85a89e426f 100644 --- a/addons/web_tour/static/src/js/tour_manager.js +++ b/addons/web_tour/static/src/js/tour_manager.js @@ -432,7 +432,12 @@ return core.Class.extend(mixins.EventDispatcherMixin, ServicesMixin, { message = _t('Good job! You went through all steps of this tour.'); } const fadeout = this.tours[tour_name].fadeout; - core.bus.trigger('show-effect', {type: "rainbowman", message, fadeout}); + core.bus.trigger('show-effect', { + type: "rainbowman", + message, + fadeout, + messageIsHtml: true, + }); } this.tours[tour_name].current_step = 0; local_storage.removeItem(get_step_key(tour_name));