diff --git a/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js b/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
index 1418c52d456..8831b9312b4 100644
--- a/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
+++ b/addons/partner_autocomplete/static/src/js/partner_autocomplete_core.js
@@ -339,9 +339,8 @@ var PartnerAutocompleteMixin = {
});
self.displayNotification({
title,
- message: content,
+ message: utils.Markup(content),
className: 'o_partner_autocomplete_no_credits_notify',
- messageIsHtml: true, // the message is coming from a QWeb template using safe instructions
});
});
},
@@ -360,9 +359,8 @@ var PartnerAutocompleteMixin = {
});
self.displayNotification({
title,
- message: content,
+ message: utils.Markup(content),
className: 'o_partner_autocomplete_no_credits_notify',
- messageIsHtml: true, // the message is coming from a QWeb template using safe instructions
});
}
else {
diff --git a/addons/web/static/src/legacy/js/views/basic/basic_controller.js b/addons/web/static/src/legacy/js/views/basic/basic_controller.js
index 24daed9bcf7..356717500f3 100644
--- a/addons/web/static/src/legacy/js/views/basic/basic_controller.js
+++ b/addons/web/static/src/legacy/js/views/basic/basic_controller.js
@@ -11,6 +11,7 @@ var AbstractController = require('web.AbstractController');
var core = require('web.core');
var Dialog = require('web.Dialog');
var FieldManagerMixin = require('web.FieldManagerMixin');
+var {Markup} = require('web.utils');
var TranslationDialog = require('web.TranslationDialog');
var _t = core._t;
@@ -592,9 +593,8 @@ var BasicController = AbstractController.extend(FieldManagerMixin, {
warnings.push('');
this.displayNotification({
title: _t("Invalid fields:"),
- message: warnings.join(''),
+ message: Markup(warnings.join('')),
type: 'danger',
- messageIsHtml: true, // dynamic parts of the message are escaped above
});
},
/**
diff --git a/addons/web/static/src/legacy/js/widgets/attach_document.js b/addons/web/static/src/legacy/js/widgets/attach_document.js
index d84dcad9ac3..d206e2c8ac3 100644
--- a/addons/web/static/src/legacy/js/widgets/attach_document.js
+++ b/addons/web/static/src/legacy/js/widgets/attach_document.js
@@ -3,6 +3,7 @@ odoo.define('web.AttachDocument', function (require) {
var core = require('web.core');
var framework = require('web.framework');
+var {Markup} = require('web.utils');
var widgetRegistry = require('web.widget_registry');
var Widget = require('web.Widget');
@@ -64,9 +65,8 @@ var AttachDocument = Widget.extend({
warnings.push('');
this.displayNotification({
title: _t("Invalid fields:"),
- message: warnings.join(''),
+ message: Markup(warnings.join('')),
type: 'danger',
- messageIsHtml: true, // dynamic parts of the message are escaped above
});
},
diff --git a/addons/web/static/src/legacy/utils.js b/addons/web/static/src/legacy/utils.js
index 72ee1334671..af515c76bcb 100644
--- a/addons/web/static/src/legacy/utils.js
+++ b/addons/web/static/src/legacy/utils.js
@@ -211,7 +211,6 @@ export function makeLegacyNotificationService(legacyEnv) {
type,
className,
onClose,
- messageIsHtml,
}) {
if (subtitle) {
title = [title, subtitle].filter(Boolean).join(" ");
@@ -230,14 +229,14 @@ export function makeLegacyNotificationService(legacyEnv) {
};
});
- const removeFn = env.services.notification.add(message, {
+ const removeFn = env.services.notification.add(_.escape(message), {
sticky,
title,
type,
className,
onClose,
buttons,
- messageIsHtml,
+ messageIsHtml: true,
});
const id = ++notifId;
idsToRemoveFn[id] = removeFn;
diff --git a/addons/web/static/tests/legacy/fields/basic_fields_tests.js b/addons/web/static/tests/legacy/fields/basic_fields_tests.js
index 0e529cdb985..1c289277fb5 100644
--- a/addons/web/static/tests/legacy/fields/basic_fields_tests.js
+++ b/addons/web/static/tests/legacy/fields/basic_fields_tests.js
@@ -3923,7 +3923,7 @@ QUnit.module('basic_fields', {
if (ev.data.service === 'notification') {
assert.strictEqual(ev.data.method, 'notify');
assert.strictEqual(ev.data.args[0].title, 'Invalid fields:');
- assert.strictEqual(ev.data.args[0].message, '
');
+ assert.strictEqual(ev.data.args[0].message.toString(), '');
}
}
},
@@ -6102,7 +6102,7 @@ QUnit.module('basic_fields', {
if (ev.data.service === 'notification') {
assert.strictEqual(ev.data.method, 'notify');
assert.strictEqual(ev.data.args[0].title, 'Invalid fields:');
- assert.strictEqual(ev.data.args[0].message, '');
+ assert.strictEqual(ev.data.args[0].message.toString(), '');
}
}
},
diff --git a/addons/web/static/tests/legacy/views/form_tests.js b/addons/web/static/tests/legacy/views/form_tests.js
index cf9b2b61b77..a400a034ac4 100644
--- a/addons/web/static/tests/legacy/views/form_tests.js
+++ b/addons/web/static/tests/legacy/views/form_tests.js
@@ -3664,7 +3664,7 @@ QUnit.module('Views', {
}
assert.strictEqual(params.title, 'Invalid fields:',
"should have a warning with correct title");
- assert.strictEqual(params.message, '',
+ assert.strictEqual(params.message.toString(), '',
"should have a warning with correct message");
}
},
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 c9a9a4634bc..07c4d9e7b81 100644
--- a/addons/web_editor/static/src/js/editor/snippets.editor.js
+++ b/addons/web_editor/static/src/js/editor/snippets.editor.js
@@ -5,6 +5,7 @@ var concurrency = require('web.concurrency');
var core = require('web.core');
var Dialog = require('web.Dialog');
var dom = require('web.dom');
+const {Markup, sprintf} = require('web.utils');
var Widget = require('web.Widget');
var options = require('web_editor.snippets.options');
const {ColorPaletteWidget} = require('web_editor.ColorPalette');
@@ -2778,11 +2779,11 @@ var SnippetsMenu = Widget.extend({
}).guardedCatch(reason => {
reason.event.preventDefault();
this.close();
+ const message = sprintf(Markup(_t("Could not install module %s")), name);
self.displayNotification({
- message: _.str.sprintf(_t("Could not install module %s"), owl.utils.escape(name)),
+ message: message,
type: 'danger',
sticky: true,
- messageIsHtml: true, // dynamic parts of the message are escaped above
});
});
},
diff --git a/addons/web_editor/static/tests/field_html_tests.js b/addons/web_editor/static/tests/field_html_tests.js
index 18f3cd32ea5..7450d72ba19 100644
--- a/addons/web_editor/static/tests/field_html_tests.js
+++ b/addons/web_editor/static/tests/field_html_tests.js
@@ -198,7 +198,7 @@ QUnit.module('web_editor', {}, function () {
});
QUnit.test('check if required field is set', async function (assert) {
- assert.expect(1);
+ assert.expect(3);
var form = await testUtils.createView({
View: FormView,
@@ -212,12 +212,9 @@ QUnit.module('web_editor', {}, function () {
testUtils.mock.intercept(form, 'call_service', function (ev) {
if (ev.data.service === 'notification') {
- assert.deepEqual(ev.data.args[0], {
- "message": "",
- "messageIsHtml": true,
- "title": "Invalid fields:",
- "type": "danger"
- });
+ assert.strictEqual(ev.data.args[0].title, 'Invalid fields:');
+ assert.strictEqual(ev.data.args[0].message.toString(), '');
+ assert.strictEqual(ev.data.args[0].type, 'danger');
}
}, true);
diff --git a/addons/website/static/src/js/content/website_root.js b/addons/website/static/src/js/content/website_root.js
index a7710edb095..987b04d2e47 100644
--- a/addons/website/static/src/js/content/website_root.js
+++ b/addons/website/static/src/js/content/website_root.js
@@ -3,6 +3,7 @@
import ajax from 'web.ajax';
import { _t } from 'web.core';
import KeyboardNavigationMixin from 'web.KeyboardNavigationMixin';
+import {Markup} from 'web.utils';
import session from 'web.session';
import publicRootData from 'web.public.root';
import "web.zoomodoo";
@@ -146,19 +147,16 @@ export const WebsiteRoot = publicRootData.PublicRoot.extend(KeyboardNavigationMi
if (!key) {
if (!editableMode && session.is_admin) {
+ const message = _t("Cannot load google map.");
+ const urlTitle = _t("Check your configuration.");
this.displayNotification({
type: 'warning',
sticky: true,
message:
- $('').append(
- $('', {text: _t("Cannot load google map.")}),
- $('
'),
- $('', {
- href: "/web#action=website.action_website_configuration",
- text: _t("Check your configuration."),
- }),
- )[0].outerHTML,
- messageIsHtml: true, // HTML is built with only safe static parts
+ Markup``,
});
}
resolve(false);
diff --git a/addons/website/static/src/js/editor/snippets.options.js b/addons/website/static/src/js/editor/snippets.options.js
index bbed1a84b91..2415535bdb7 100644
--- a/addons/website/static/src/js/editor/snippets.options.js
+++ b/addons/website/static/src/js/editor/snippets.options.js
@@ -6,6 +6,7 @@ const {ColorpickerWidget} = require('web.Colorpicker');
const config = require('web.config');
var core = require('web.core');
var Dialog = require('web.Dialog');
+const {Markup, sprintf} = require('web.utils');
const weUtils = require('web_editor.utils');
var options = require('web_editor.snippets.options');
const wLinkPopoverWidget = require('@website/js/widgets/link_popover_widget')[Symbol.for("default")];
@@ -2188,11 +2189,11 @@ options.registry.anchor = options.Class.extend({
const clipboard = new ClipboardJS(this.$button[0], {text: () => this._getAnchorLink()});
clipboard.on('success', () => {
const anchor = decodeURIComponent(this._getAnchorLink());
+ const message = sprintf(Markup(_t("Anchor copied to clipboard
Link: %s")), anchor);
this.displayNotification({
type: 'success',
- message: _.str.sprintf(_t("Anchor copied to clipboard
Link: %s"), owl.utils.escape(anchor)),
+ message: message,
buttons: [{text: _t("Edit"), click: () => this.openAnchorDialog(), primary: true}],
- messageIsHtml: true, // dynamic parts of the message are escaped above
});
});
diff --git a/addons/website_event/static/src/js/register_toaster_widget.js b/addons/website_event/static/src/js/register_toaster_widget.js
index 798e484abe6..fd2f944c78d 100644
--- a/addons/website_event/static/src/js/register_toaster_widget.js
+++ b/addons/website_event/static/src/js/register_toaster_widget.js
@@ -2,6 +2,7 @@ odoo.define('website_event.register_toaster_widget', function (require) {
'use strict';
let core = require('web.core');
+const {Markup} = require('web.utils');
let _t = core._t;
let publicWidget = require('web.public.widget');
@@ -18,9 +19,8 @@ publicWidget.registry.RegisterToasterWidget = publicWidget.Widget.extend({
if (message && message.length) {
this.displayNotification({
title: _t("Register"),
- message: message,
+ message: Markup(message),
type: 'info',
- messageIsHtml: true, // the message is coming from a QWeb template using safe instructions
});
}
return this._super.apply(this, arguments);
diff --git a/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js b/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js
index 03775f68d8c..519af24a4b0 100644
--- a/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js
+++ b/addons/website_slides_survey/static/src/js/slides_certification_upload_toast.js
@@ -2,6 +2,7 @@ odoo.define('website_slides_survey.certification_upload_toast', function (requir
'use strict';
var publicWidget = require('web.public.widget');
+var {Markup, sprintf} = require('web.utils');
var sessionStorage = window.sessionStorage;
var core = require('web.core');
@@ -19,15 +20,13 @@ publicWidget.registry.CertificationUploadToast = publicWidget.Widget.extend({
this._super.apply(this, arguments).then(function () {
var url = sessionStorage.getItem("survey_certification_url");
if (url) {
+ var message = sprintf(Markup(
+ _t('Follow this link to add questions to your certification. Edit certification')), url);
self.displayNotification({
type: 'info',
title: _t('Certification created'),
- message: _.str.sprintf(
- _t('Follow this link to add questions to your certification. Edit certification'),
- _.escape(url)
- ),
+ message: message,
sticky: true,
- messageIsHtml: true, // dynamic parts of the message are escaped above
});
sessionStorage.removeItem("survey_certification_url");
}