From 81d21068b52de1f6d2c5f3958ab4e623a3c16576 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Wed, 7 Oct 2020 04:17:55 -0700 Subject: [PATCH] eslint: Fix no-useless-concat. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .eslintrc.json | 1 + frontend_tests/node_tests/compose.js | 2 +- frontend_tests/node_tests/list_render.js | 4 +- frontend_tests/node_tests/markdown.js | 8 +- frontend_tests/node_tests/people.js | 2 +- frontend_tests/node_tests/vdom.js | 22 ++---- static/js/alert_words.js | 5 +- static/js/blueslip.js | 2 +- static/js/hash_util.js | 2 +- static/js/markdown.js | 82 ++++++--------------- static/js/portico/integrations_dev_panel.js | 2 +- static/js/sent_messages.js | 2 +- static/js/settings_streams.js | 2 +- 13 files changed, 41 insertions(+), 95 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index d0b9e04b87..f74366a20c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -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", diff --git a/frontend_tests/node_tests/compose.js b/frontend_tests/node_tests/compose.js index f310cbb2a4..1686389188 100644 --- a/frontend_tests/node_tests/compose.js +++ b/frontend_tests/node_tests/compose.js @@ -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); diff --git a/frontend_tests/node_tests/list_render.js b/frontend_tests/node_tests/list_render.js index 2f4380497d..384150030f 100644 --- a/frontend_tests/node_tests/list_render.js +++ b/frontend_tests/node_tests/list_render.js @@ -223,7 +223,7 @@ run_test("filtering", () => { const new_data = ["greta", "faye", "gary", "frank", "giraffe", "fox"]; widget.replace_list_data(new_data); - expected_html = "
greta
" + "
gary
" + "
giraffe
"; + expected_html = "
greta
gary
giraffe
"; 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 = "
apple
" + "
banana
"; + const expected_html = "
apple
banana
"; assert.deepEqual(container.appended_data.html(), expected_html); }); diff --git a/frontend_tests/node_tests/markdown.js b/frontend_tests/node_tests/markdown.js index c815311b3c..fce285420e 100644 --- a/frontend_tests/node_tests/markdown.js +++ b/frontend_tests/node_tests/markdown.js @@ -364,12 +364,12 @@ run_test("marked", () => { { input: "This is a #**Denmark>some topic** stream_topic link", expected: - '

This is a #Denmark > some topic stream_topic link

', + '

This is a #Denmark > some topic stream_topic link

', }, { input: "This has two links: #**Denmark>some topic** and #**social>other topic**.", expected: - '

This has two links: #Denmark > some topic and #social > other topic.

', + '

This has two links: #Denmark > some topic and #social > other topic.

', }, { input: "This is not a #**Denmark>** stream_topic link", @@ -512,7 +512,7 @@ run_test("marked", () => { { input: "#**Bobby

Tables

**", expected: - '

#Bobby <h1 > Tables</h1>

', + '

#Bobby <h1 > Tables</h1>

', }, { input: "#**& & &amp;**", @@ -522,7 +522,7 @@ run_test("marked", () => { { input: "#**& & &amp;>& & &amp;**", expected: - '

#& & &amp; > & & &amp;

', + '

#& & &amp; > & & &amp;

', }, ]; diff --git a/frontend_tests/node_tests/people.js b/frontend_tests/node_tests/people.js index ad895263d0..5793bf006c 100644 --- a/frontend_tests/node_tests/people.js +++ b/frontend_tests/node_tests/people.js @@ -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); diff --git a/frontend_tests/node_tests/vdom.js b/frontend_tests/node_tests/vdom.js index f64899d9b6..0ca5b50494 100644 --- a/frontend_tests/node_tests/vdom.js +++ b/frontend_tests/node_tests/vdom.js @@ -15,10 +15,7 @@ run_test("basics", () => { const html = vdom.render_tag(ul); - assert.equal( - html, - '", - ); + assert.equal(html, ''); }); run_test("attribute escaping", () => { @@ -59,7 +56,7 @@ run_test("attribute updates", () => { const html = vdom.render_tag(ul); - assert.equal(html, '"); + assert.equal(html, ''); let updated; let removed; @@ -135,10 +132,7 @@ run_test("children", () => { vdom.update(replace_content, find, ul); - assert.equal( - rendered_html, - "", - ); + assert.equal(rendered_html, ""); // 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, - '", - ); + assert.equal(rendered_html, ''); }); run_test("partial updates", () => { @@ -176,10 +167,7 @@ run_test("partial updates", () => { vdom.update(replace_content, find, ul); - assert.equal( - rendered_html, - "", - ); + assert.equal(rendered_html, ""); replace_content = () => { throw new Error("should not replace entire html"); diff --git a/static/js/alert_words.js b/static/js/alert_words.js index 96e4a3e64d..ce2941af7a 100644 --- a/static/js/alert_words.js +++ b/static/js/alert_words.js @@ -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) => { diff --git a/static/js/blueslip.js b/static/js/blueslip.js index c60c98365e..62d8189ea2 100644 --- a/static/js/blueslip.js +++ b/static/js/blueslip.js @@ -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", ); diff --git a/static/js/hash_util.js b/static/js/hash_util.js index ed84eac58c..7db2bc8594 100644 --- a/static/js/hash_util.js +++ b/static/js/hash_util.js @@ -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; }; diff --git a/static/js/markdown.js b/static/js/markdown.js index ea0bcdef8c..d84d52cae6 100644 --- a/static/js/markdown.js +++ b/static/js/markdown.js @@ -102,7 +102,7 @@ exports.apply_markdown = function (message) { userMentionHandler(mention, silently) { if (mention === "all" || mention === "everyone" || mention === "stream") { message.mentioned = true; - return '' + "@" + mention + ""; + return `@${_.escape(mention)}`; } let full_name; @@ -160,15 +160,15 @@ exports.apply_markdown = function (message) { } let str = ""; if (silently) { - str += ''; + str += ``; } else { - str += '@'; + str += `@`; } // 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) + ""; + return `${str}${_.escape(actual_full_name)}`; }, 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 ( - '' + - "@" + - _.escape(group.name) + - "" - ); + return `@${_.escape(group.name)}`; } return undefined; }, @@ -251,19 +246,9 @@ exports.is_status_message = function (raw_content) { }; function make_emoji_span(codepoint, title, alt_text) { - return ( - '' + - alt_text + - "" - ); + return `${_.escape(alt_text)}`; } 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 ( - '' +
-            alt_text +
-            '' - ); + return `${_.escape(alt_text)}`; } 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 ( - '" + - "#" + - _.escape(stream.name) + - "" - ); + return `#${_.escape(stream.name)}`; } 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 ( - '" + - text + - "" - ); + const text = `#${stream.name} > ${topic}`; + return `${_.escape(text)}`; } 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 '' + _.escape(fullmatch) + ""; + return `${_.escape(fullmatch)}`; } blueslip.error(error); return undefined; diff --git a/static/js/portico/integrations_dev_panel.js b/static/js/portico/integrations_dev_panel.js index 87a0e4cab6..fc0a078bb4 100644 --- a/static/js/portico/integrations_dev_panel.js +++ b/static/js/portico/integrations_dev_panel.js @@ -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 diff --git a/static/js/sent_messages.js b/static/js/sent_messages.js index c2e9702a2b..de81dea53a 100644 --- a/static/js/sent_messages.js +++ b/static/js/sent_messages.js @@ -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(); diff --git a/static/js/settings_streams.js b/static/js/settings_streams.js index 233b181294..a06e77f4af 100644 --- a/static/js/settings_streams.js +++ b/static/js/settings_streams.js @@ -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); },