eslint: Fix no-useless-concat.

https://eslint.org/docs/rules/no-useless-concat

And add some escaping to static/js/markdown.js while I’m here.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
Anders Kaseorg 2020-10-07 04:17:55 -07:00 committed by Tim Abbott
parent 043c34d944
commit 81d21068b5
13 changed files with 41 additions and 95 deletions

View File

@ -85,6 +85,7 @@
}
],
"no-use-before-define": ["error", {"functions": false}],
"no-useless-concat": "error",
"no-useless-constructor": "error",
"no-var": "error",
"object-shorthand": "error",

View File

@ -690,7 +690,7 @@ run_test("send_message", () => {
// Setting message content with a host server link and we will assert
// later that this has been converted to a relative link.
$("#compose-textarea").val("[foobar]" + "(https://foo.com/user_uploads/123456)");
$("#compose-textarea").val("[foobar](https://foo.com/user_uploads/123456)");
$("#compose-textarea").trigger("blur");
$("#compose-send-status").show();
$("#compose-send-button").prop("disabled", true);

View File

@ -223,7 +223,7 @@ run_test("filtering", () => {
const new_data = ["greta", "faye", "gary", "frank", "giraffe", "fox"];
widget.replace_list_data(new_data);
expected_html = "<div>greta</div>" + "<div>gary</div>" + "<div>giraffe</div>";
expected_html = "<div>greta</div><div>gary</div><div>giraffe</div>";
assert.deepEqual(container.appended_data.html(), expected_html);
});
@ -240,7 +240,7 @@ run_test("no filtering", () => {
const widget = list_render.create(container, ["apple", "banana"], opts);
widget.render();
const expected_html = "<div>apple</div>" + "<div>banana</div>";
const expected_html = "<div>apple</div><div>banana</div>";
assert.deepEqual(container.appended_data.html(), expected_html);
});

View File

@ -364,12 +364,12 @@ run_test("marked", () => {
{
input: "This is a #**Denmark>some topic** stream_topic link",
expected:
'<p>This is a <a class="stream-topic" data-stream-id="1" href="/#narrow/stream/1-Denmark/topic/some.20topic">#Denmark > some topic</a> stream_topic link</p>',
'<p>This is a <a class="stream-topic" data-stream-id="1" href="/#narrow/stream/1-Denmark/topic/some.20topic">#Denmark &gt; some topic</a> stream_topic link</p>',
},
{
input: "This has two links: #**Denmark>some topic** and #**social>other topic**.",
expected:
'<p>This has two links: <a class="stream-topic" data-stream-id="1" href="/#narrow/stream/1-Denmark/topic/some.20topic">#Denmark > some topic</a> and <a class="stream-topic" data-stream-id="2" href="/#narrow/stream/2-social/topic/other.20topic">#social > other topic</a>.</p>',
'<p>This has two links: <a class="stream-topic" data-stream-id="1" href="/#narrow/stream/1-Denmark/topic/some.20topic">#Denmark &gt; some topic</a> and <a class="stream-topic" data-stream-id="2" href="/#narrow/stream/2-social/topic/other.20topic">#social &gt; other topic</a>.</p>',
},
{
input: "This is not a #**Denmark>** stream_topic link",
@ -512,7 +512,7 @@ run_test("marked", () => {
{
input: "#**Bobby <h1>Tables</h1>**",
expected:
'<p><a class="stream-topic" data-stream-id="4" href="/#narrow/stream/4-Bobby-.3Ch1/topic/Tables.3C.2Fh1.3E">#Bobby &lt;h1 > Tables&lt;/h1&gt;</a></p>',
'<p><a class="stream-topic" data-stream-id="4" href="/#narrow/stream/4-Bobby-.3Ch1/topic/Tables.3C.2Fh1.3E">#Bobby &lt;h1 &gt; Tables&lt;/h1&gt;</a></p>',
},
{
input: "#**& &amp; &amp;amp;**",
@ -522,7 +522,7 @@ run_test("marked", () => {
{
input: "#**& &amp; &amp;amp;>& &amp; &amp;amp;**",
expected:
'<p><a class="stream-topic" data-stream-id="5" href="/#narrow/stream/5-.26-.26.20.26amp.3B/topic/.26.20.26.20.26amp.3B">#&amp; &amp; &amp;amp; > &amp; &amp; &amp;amp;</a></p>',
'<p><a class="stream-topic" data-stream-id="5" href="/#narrow/stream/5-.26-.26.20.26amp.3B/topic/.26.20.26.20.26amp.3B">#&amp; &amp; &amp;amp; &gt; &amp; &amp; &amp;amp;</a></p>',
},
];

View File

@ -885,7 +885,7 @@ run_test("updates", () => {
// old email.
blueslip.expect(
"warn",
"Obsolete email passed to get_by_email: " + "FOO@example.com new email = bar@example.com",
"Obsolete email passed to get_by_email: FOO@example.com new email = bar@example.com",
);
person = people.get_by_email(old_email);
assert.equal(person.user_id, user_id);

View File

@ -15,10 +15,7 @@ run_test("basics", () => {
const html = vdom.render_tag(ul);
assert.equal(
html,
'<ul class="foo" title="cats &amp; &lt;&quot;dogs&quot;&gt;">\n\n' + "</ul>",
);
assert.equal(html, '<ul class="foo" title="cats &amp; &lt;&quot;dogs&quot;&gt;">\n\n</ul>');
});
run_test("attribute escaping", () => {
@ -59,7 +56,7 @@ run_test("attribute updates", () => {
const html = vdom.render_tag(ul);
assert.equal(html, '<ul class="same" color="blue" id="101">\n\n' + "</ul>");
assert.equal(html, '<ul class="same" color="blue" id="101">\n\n</ul>');
let updated;
let removed;
@ -135,10 +132,7 @@ run_test("children", () => {
vdom.update(replace_content, find, ul);
assert.equal(
rendered_html,
"<ul>\n" + "<li>foo1</li>\n" + "<li>foo2</li>\n" + "<li>foo3</li>\n" + "</ul>",
);
assert.equal(rendered_html, "<ul>\n<li>foo1</li>\n<li>foo2</li>\n<li>foo3</li>\n</ul>");
// Force a complete redraw.
const new_nodes = make_children([4, 5]);
@ -150,10 +144,7 @@ run_test("children", () => {
const new_ul = vdom.ul(new_opts);
vdom.update(replace_content, find, new_ul, ul);
assert.equal(
rendered_html,
'<ul class="main">\n' + "<li>foo4</li>\n" + "<li>foo5</li>\n" + "</ul>",
);
assert.equal(rendered_html, '<ul class="main">\n<li>foo4</li>\n<li>foo5</li>\n</ul>');
});
run_test("partial updates", () => {
@ -176,10 +167,7 @@ run_test("partial updates", () => {
vdom.update(replace_content, find, ul);
assert.equal(
rendered_html,
"<ul>\n" + "<li>foo1</li>\n" + "<li>foo2</li>\n" + "<li>foo3</li>\n" + "</ul>",
);
assert.equal(rendered_html, "<ul>\n<li>foo1</li>\n<li>foo2</li>\n<li>foo3</li>\n</ul>");
replace_content = () => {
throw new Error("should not replace entire html");

View File

@ -37,10 +37,7 @@ exports.process_message = function (message) {
const before_punctuation = "\\s|^|>|[\\(\\\".,';\\[]";
const after_punctuation = "\\s|$|<|[\\)\\\"\\?!:.,';\\]!]";
const regex = new RegExp(
"(" + before_punctuation + ")" + "(" + clean + ")" + "(" + after_punctuation + ")",
"ig",
);
const regex = new RegExp(`(${before_punctuation})(${clean})(${after_punctuation})`, "ig");
message.content = message.content.replace(
regex,
(match, before, word, after, offset, content) => {

View File

@ -155,7 +155,7 @@ function report_error(msg, stack, opts) {
error() {
if (opts.show_ui_msg && ui_report !== undefined) {
ui_report.message(
"Oops. It seems something has gone wrong. " + "Please try reloading the page.",
"Oops. It seems something has gone wrong. Please try reloading the page.",
$("#home-error"),
"alert-error",
);

View File

@ -166,7 +166,7 @@ exports.by_conversation_and_time_uri = function (message) {
};
exports.stream_edit_uri = function (sub) {
const hash = "#streams" + "/" + sub.stream_id + "/" + exports.encodeHashComponent(sub.name);
const hash = `#streams/${sub.stream_id}/${exports.encodeHashComponent(sub.name)}`;
return hash;
};

View File

@ -102,7 +102,7 @@ exports.apply_markdown = function (message) {
userMentionHandler(mention, silently) {
if (mention === "all" || mention === "everyone" || mention === "stream") {
message.mentioned = true;
return '<span class="user-mention" data-user-id="*">' + "@" + mention + "</span>";
return `<span class="user-mention" data-user-id="*">@${_.escape(mention)}</span>`;
}
let full_name;
@ -160,15 +160,15 @@ exports.apply_markdown = function (message) {
}
let str = "";
if (silently) {
str += '<span class="user-mention silent" data-user-id="' + user_id + '">';
str += `<span class="user-mention silent" data-user-id="${_.escape(user_id)}">`;
} else {
str += '<span class="user-mention" data-user-id="' + user_id + '">@';
str += `<span class="user-mention" data-user-id="${_.escape(user_id)}">@`;
}
// If I mention "@aLiCe sMITH", I still want "Alice Smith" to
// show in the pill.
const actual_full_name = helpers.get_actual_name_from_user_id(user_id);
return str + _.escape(actual_full_name) + "</span>";
return `${str}${_.escape(actual_full_name)}</span>`;
},
groupMentionHandler(name) {
const group = helpers.get_user_group_from_name(name);
@ -176,14 +176,9 @@ exports.apply_markdown = function (message) {
if (helpers.is_member_of_user_group(group.id, helpers.my_user_id())) {
message.mentioned = true;
}
return (
'<span class="user-group-mention" data-user-group-id="' +
group.id +
'">' +
"@" +
_.escape(group.name) +
"</span>"
);
return `<span class="user-group-mention" data-user-group-id="${_.escape(
group.id,
)}">@${_.escape(group.name)}</span>`;
}
return undefined;
},
@ -251,19 +246,9 @@ exports.is_status_message = function (raw_content) {
};
function make_emoji_span(codepoint, title, alt_text) {
return (
'<span aria-label="' +
title +
'"' +
' class="emoji emoji-' +
codepoint +
'"' +
' role="img" title="' +
title +
'">' +
alt_text +
"</span>"
);
return `<span aria-label="${_.escape(title)}" class="emoji emoji-${_.escape(
codepoint,
)}" role="img" title="${_.escape(title)}">${_.escape(alt_text)}</span>`;
}
function handleUnicodeEmoji(unicode_emoji) {
@ -293,17 +278,9 @@ function handleEmoji(emoji_name) {
const emoji_url = emoji.get_realm_emoji_url(emoji_name);
if (emoji_url) {
return (
'<img alt="' +
alt_text +
'"' +
' class="emoji" src="' +
emoji_url +
'"' +
' title="' +
title +
'">'
);
return `<img alt="${_.escape(alt_text)}" class="emoji" src="${_.escape(
emoji_url,
)}" title="${_.escape(title)}">`;
}
const codepoint = emoji.get_emoji_codepoint(emoji_name);
@ -350,18 +327,9 @@ function handleStream(stream_name) {
return undefined;
}
const href = helpers.stream_hash(stream.stream_id);
return (
'<a class="stream" data-stream-id="' +
stream.stream_id +
'" ' +
'href="/' +
href +
'"' +
">" +
"#" +
_.escape(stream.name) +
"</a>"
);
return `<a class="stream" data-stream-id="${_.escape(stream.stream_id)}" href="/${_.escape(
href,
)}">#${_.escape(stream.name)}</a>`;
}
function handleStreamTopic(stream_name, topic) {
@ -370,18 +338,10 @@ function handleStreamTopic(stream_name, topic) {
return undefined;
}
const href = helpers.stream_topic_hash(stream.stream_id, topic);
const text = "#" + _.escape(stream.name) + " > " + _.escape(topic);
return (
'<a class="stream-topic" data-stream-id="' +
stream.stream_id +
'" ' +
'href="/' +
href +
'"' +
">" +
text +
"</a>"
);
const text = `#${stream.name} > ${topic}`;
return `<a class="stream-topic" data-stream-id="${_.escape(
stream.stream_id,
)}" href="/${_.escape(href)}">${_.escape(text)}</a>`;
}
function handleRealmFilter(pattern, matches) {
@ -404,7 +364,7 @@ function handleTex(tex, fullmatch) {
} catch (error) {
if (error.message.startsWith("KaTeX parse error")) {
// TeX syntax error
return '<span class="tex-error">' + _.escape(fullmatch) + "</span>";
return `<span class="tex-error">${_.escape(fullmatch)}</span>`;
}
blueslip.error(error);
return undefined;

View File

@ -188,7 +188,7 @@ function handle_unsuccessful_response(response) {
try {
const status_code = response.statusCode().status;
response = JSON.parse(response.responseText);
set_results_notice("Result: " + "(" + status_code + ") " + response.msg, "warning");
set_results_notice(`Result: (${status_code}) ${response.msg}`, "warning");
} catch {
// If the response is not a JSON response, then it is probably
// Django returning an HTML response containing a stack trace

View File

@ -73,7 +73,7 @@ class MessageState {
}
blueslip.log(
"Restarting get_events due to " + "delayed receipt of sent message " + this.local_id,
`Restarting get_events due to delayed receipt of sent message ${this.local_id}`,
);
server_events.restart_get_events();

View File

@ -81,7 +81,7 @@ function make_stream_default(stream_id) {
exports.delete_default_stream = function (stream_id, default_stream_row, alert_element) {
channel.del({
url: "/json/default_streams" + "?" + $.param({stream_id}),
url: "/json/default_streams?" + $.param({stream_id}),
error(xhr) {
ui_report.generic_row_button_error(xhr, alert_element);
},