[FIX] web,*_*: fix the html content in notification

Currently markup-ification of the legacy notifications system
display the html content in notification layout for some of the
notification of document and planning from commit: https://github.com/odoo/enterprise/commit/ba44461fea337ed2e5adbdfa1e8eede00b036def

So here in this commit, we make the method `makeLegacyNotificationService`
always `_.escape(message)` and pass `messageIsHtml: true` to the owl
notifications system so notification with html content will be displayed
properly.

Task-2657391

closes odoo/odoo#78627

X-original-commit: 7ce6d8d70be79c9c626865598b898dce9a18b045
Related: odoo/enterprise#21782
Signed-off-by: LTU-Odoo <IT-Ideas@users.noreply.github.com>
This commit is contained in:
Barad Mahendra
2021-10-19 14:43:42 +00:00
parent 5e7297a01a
commit 281b65a943
12 changed files with 34 additions and 41 deletions
@@ -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 {
@@ -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('</ul>');
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
});
},
/**
@@ -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('</ul>');
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
});
},
+2 -3
View File
@@ -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;
@@ -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, '<ul><li>A date</li></ul>');
assert.strictEqual(ev.data.args[0].message.toString(), '<ul><li>A date</li></ul>');
}
}
},
@@ -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, '<ul><li>Qux</li></ul>');
assert.strictEqual(ev.data.args[0].message.toString(), '<ul><li>Qux</li></ul>');
}
}
},
@@ -3664,7 +3664,7 @@ QUnit.module('Views', {
}
assert.strictEqual(params.title, 'Invalid fields:',
"should have a warning with correct title");
assert.strictEqual(params.message, '<ul><li>Foo</li></ul>',
assert.strictEqual(params.message.toString(), '<ul><li>Foo</li></ul>',
"should have a warning with correct message");
}
},
@@ -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 <strong>%s</strong>")), name);
self.displayNotification({
message: _.str.sprintf(_t("Could not install module <strong>%s</strong>"), owl.utils.escape(name)),
message: message,
type: 'danger',
sticky: true,
messageIsHtml: true, // dynamic parts of the message are escaped above
});
});
},
@@ -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": "<ul><li>Header</li></ul>",
"messageIsHtml": true,
"title": "Invalid fields:",
"type": "danger"
});
assert.strictEqual(ev.data.args[0].title, 'Invalid fields:');
assert.strictEqual(ev.data.args[0].message.toString(), '<ul><li>Header</li></ul>');
assert.strictEqual(ev.data.args[0].type, 'danger');
}
}, true);
@@ -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:
$('<div/>').append(
$('<span/>', {text: _t("Cannot load google map.")}),
$('<br/>'),
$('<a/>', {
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`<div>
<span>${message}</span><br/>
<a href="/web#action=website.action_website_configuration">${urlTitle}</a>
</div>`,
});
}
resolve(false);
@@ -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<br>Link: %s")), anchor);
this.displayNotification({
type: 'success',
message: _.str.sprintf(_t("Anchor copied to clipboard<br>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
});
});
@@ -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);
@@ -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. <a href="%s">Edit certification</a>')), url);
self.displayNotification({
type: 'info',
title: _t('Certification created'),
message: _.str.sprintf(
_t('Follow this link to add questions to your certification. <a href="%s">Edit certification</a>'),
_.escape(url)
),
message: message,
sticky: true,
messageIsHtml: true, // dynamic parts of the message are escaped above
});
sessionStorage.removeItem("survey_certification_url");
}