FIX: Do not escape `fancy_title` again. (#8095)

`fancy_title` is already escaped by Rails. Escaping it again would print
the HTML entity as-is, e.g. `"` instead of `"`.

This fixes the issue by introducing a new `escapedContent` attribute on
the `QuickAccessItem` widget.
This commit is contained in:
Kyle Zhao 2019-09-13 07:04:14 -07:00 committed by Robin Ward
parent 6bbda8eae9
commit f0f03acb2c
3 changed files with 55 additions and 5 deletions

View File

@ -3,7 +3,22 @@ import RawHtml from "discourse/widgets/raw-html";
import { createWidget } from "discourse/widgets/widget";
import { emojiUnescape } from "discourse/lib/text";
import { iconNode } from "discourse-common/lib/icon-library";
import { escapeExpression } from "discourse/lib/utilities";
/**
* This helper widget tries to enforce a consistent look and behavior for any
* item under any quick access panels.
*
* It accepts the following attributes:
* action
* actionParam
* content
* escapedContent
* href
* icon
* read
* username
*/
createWidget("quick-access-item", {
tagName: "li",
@ -18,13 +33,11 @@ createWidget("quick-access-item", {
return result;
},
html({ icon, href, content }) {
html({ icon, href }) {
return h("a", { attributes: { href } }, [
iconNode(icon),
new RawHtml({
html: `<div>${this._usernameHtml()}${emojiUnescape(
Handlebars.Utils.escapeExpression(content)
)}</div>`
html: `<div>${this._usernameHtml()}${this._contentHtml()}</div>`
})
]);
},
@ -37,6 +50,12 @@ createWidget("quick-access-item", {
}
},
_contentHtml() {
const content =
this.attrs.escapedContent || escapeExpression(this.attrs.content);
return emojiUnescape(content);
},
_usernameHtml() {
return this.attrs.username ? `<span>${this.attrs.username}</span> ` : "";
}

View File

@ -12,7 +12,7 @@ function toItem(message) {
);
return {
content: message.fancy_title,
escapedContent: message.fancy_title,
href: postUrl(message.slug, message.id, nextUnreadPostNumber),
icon: ICON,
read: message.last_read_post_number >= message.highest_post_number,

View File

@ -0,0 +1,31 @@
import { moduleForWidget, widgetTest } from "helpers/widget-test";
moduleForWidget("quick-access-item");
const CONTENT_DIV_SELECTOR = "li > a > div";
widgetTest("content attribute is escaped", {
template: '{{mount-widget widget="quick-access-item" args=args}}',
beforeEach() {
this.set("args", { content: "<b>bold</b>" });
},
test(assert) {
const contentDiv = find(CONTENT_DIV_SELECTOR)[0];
assert.equal(contentDiv.innerText, "<b>bold</b>");
}
});
widgetTest("escapedContent attribute is not escaped", {
template: '{{mount-widget widget="quick-access-item" args=args}}',
beforeEach() {
this.set("args", { escapedContent: "&quot;quote&quot;" });
},
test(assert) {
const contentDiv = find(CONTENT_DIV_SELECTOR)[0];
assert.equal(contentDiv.innerText, '"quote"');
}
});