diff --git a/.eslintrc.json b/.eslintrc.json
index 6a578d7c46..802f87aea0 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -73,6 +73,7 @@
"no-implied-eval": "error",
"no-inner-declarations": "off",
"no-iterator": "error",
+ "no-jquery/no-parse-html-literal": "error",
"no-label-var": "error",
"no-labels": "error",
"no-loop-func": "error",
diff --git a/frontend_tests/node_tests/components.js b/frontend_tests/node_tests/components.js
index ec89dac22d..694b948ec0 100644
--- a/frontend_tests/node_tests/components.js
+++ b/frontend_tests/node_tests/components.js
@@ -121,11 +121,10 @@ mock_jquery((sel, attributes) => {
}
switch (sel) {
- case "
":
- return env.switcher;
- case "":
- return env.switcher;
case "": {
+ if (attributes.class === "tab-switcher") {
+ return env.switcher;
+ }
const tab_id = attributes["data-tab-id"];
assert.deepEqual(
attributes,
diff --git a/frontend_tests/node_tests/compose_validate.js b/frontend_tests/node_tests/compose_validate.js
index 06847db66b..a74f792033 100644
--- a/frontend_tests/node_tests/compose_validate.js
+++ b/frontend_tests/node_tests/compose_validate.js
@@ -736,7 +736,7 @@ test_ui("warn_if_mentioning_unsubscribed_user", ({override, override_rewire, moc
}
// Simulate that the row was added to the DOM.
- const $warning_row = $("
");
+ const $warning_row = $("");
let looked_for_existing;
$warning_row.data = (field) => {
diff --git a/frontend_tests/node_tests/drafts.js b/frontend_tests/node_tests/drafts.js
index 926d213b10..523dd3bef2 100644
--- a/frontend_tests/node_tests/drafts.js
+++ b/frontend_tests/node_tests/drafts.js
@@ -120,7 +120,7 @@ test("draft_model add", ({override}) => {
const ls = localstorage();
assert.equal(ls.get("draft"), undefined);
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
override(Date, "now", () => 1);
@@ -136,7 +136,7 @@ test("draft_model edit", () => {
assert.equal(ls.get("draft"), undefined);
let id;
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
with_overrides(({override}) => {
@@ -161,7 +161,7 @@ test("draft_model delete", ({override}) => {
const ls = localstorage();
assert.equal(ls.get("draft"), undefined);
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
override(Date, "now", () => 1);
@@ -212,7 +212,7 @@ test("initialize", ({override_rewire}) => {
assert.ok(called);
};
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
drafts.initialize();
@@ -239,7 +239,7 @@ test("remove_old_drafts", () => {
ls.set("drafts", data);
assert.deepEqual(draft_model.get(), data);
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
drafts.remove_old_drafts();
@@ -313,7 +313,7 @@ test("delete_all_drafts", () => {
ls.set("drafts", data);
assert.deepEqual(draft_model.get(), data);
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
drafts.delete_all_drafts();
@@ -451,7 +451,7 @@ test("format_drafts", ({override_rewire, mock_template}) => {
expected[0].stream_name = "stream-rename";
- const $unread_count = $('');
+ const $unread_count = $("");
$(".top_left_drafts").set_find_results(".unread_count", $unread_count);
drafts.launch();
diff --git a/frontend_tests/node_tests/narrow.js b/frontend_tests/node_tests/narrow.js
index a2c75b9b7d..e79882a7f5 100644
--- a/frontend_tests/node_tests/narrow.js
+++ b/frontend_tests/node_tests/narrow.js
@@ -449,7 +449,6 @@ run_test("show_empty_narrow_message_with_search", ({mock_template}) => {
});
run_test("hide_empty_narrow_message", () => {
- $(".empty_feed_notice_main").html("Nothing here
");
narrow_banner.hide_empty_narrow_message();
assert.equal($(".empty_feed_notice").text(), "never-been-set");
});
diff --git a/frontend_tests/node_tests/reactions.js b/frontend_tests/node_tests/reactions.js
index 09df3c30e7..6e0ce70b18 100644
--- a/frontend_tests/node_tests/reactions.js
+++ b/frontend_tests/node_tests/reactions.js
@@ -624,11 +624,11 @@ test("view.insert_new_reaction (me w/unicode emoji)", ({override_rewire, mock_te
reaction_type: opts.reaction_type,
is_realm_emoji: false,
});
- return "";
+ return "";
});
let insert_called;
- $("").insertBefore = (element) => {
+ $("").insertBefore = (element) => {
assert.equal(element, "reaction-button-stub");
insert_called = true;
};
@@ -673,11 +673,11 @@ test("view.insert_new_reaction (them w/zulip emoji)", ({override_rewire, mock_te
still_url: undefined,
reaction_type: opts.reaction_type,
});
- return "";
+ return "";
});
let insert_called;
- $("").insertBefore = (element) => {
+ $("").insertBefore = (element) => {
assert.equal(element, "reaction-button-stub");
insert_called = true;
};
diff --git a/frontend_tests/node_tests/settings_org.js b/frontend_tests/node_tests/settings_org.js
index d47a7dcb86..4a99c38f6d 100644
--- a/frontend_tests/node_tests/settings_org.js
+++ b/frontend_tests/node_tests/settings_org.js
@@ -131,7 +131,7 @@ function createSaveButtons(subsection) {
const $stub_save_button_text = $(".save-discard-widget-button-text");
$stub_save_button_header.set_find_results(
".subsection-failed-status p",
- $(""),
+ $(""),
);
$stub_save_button.closest = () => $stub_save_button_header;
$save_button_controls.set_find_results(".save-button", $stub_save_button);
diff --git a/frontend_tests/node_tests/stream_list.js b/frontend_tests/node_tests/stream_list.js
index b35b7394f6..f096217259 100644
--- a/frontend_tests/node_tests/stream_list.js
+++ b/frontend_tests/node_tests/stream_list.js
@@ -50,14 +50,14 @@ function create_devel_sidebar_row({mock_template}) {
const $devel_count = $.create("devel-count");
const $subscription_block = $.create("devel-block");
- const $sidebar_row = $("");
+ const $sidebar_row = $("");
$sidebar_row.set_find_results(".subscription_block", $subscription_block);
$subscription_block.set_find_results(".unread_count", $devel_count);
mock_template("stream_sidebar_row.hbs", false, (data) => {
assert.equal(data.uri, "#narrow/stream/100-devel");
- return "";
+ return "";
});
num_unread_for_stream = 42;
@@ -69,14 +69,14 @@ function create_social_sidebar_row({mock_template}) {
const $social_count = $.create("social-count");
const $subscription_block = $.create("social-block");
- const $sidebar_row = $("");
+ const $sidebar_row = $("");
$sidebar_row.set_find_results(".subscription_block", $subscription_block);
$subscription_block.set_find_results(".unread_count", $social_count);
mock_template("stream_sidebar_row.hbs", false, (data) => {
assert.equal(data.uri, "#narrow/stream/200-social");
- return "";
+ return "";
});
num_unread_for_stream = 99;
@@ -105,8 +105,8 @@ test_ui("create_sidebar_row", ({override_rewire, mock_template}) => {
create_social_sidebar_row({mock_template});
const split = '
';
- const $devel_sidebar = $("");
- const $social_sidebar = $("");
+ const $devel_sidebar = $("");
+ const $social_sidebar = $("");
let appended_elems;
$("#stream_filters").append = (elems) => {
@@ -130,7 +130,7 @@ test_ui("create_sidebar_row", ({override_rewire, mock_template}) => {
assert.deepEqual(appended_elems, expected_elems);
- const $social_li = $("");
+ const $social_li = $("");
const stream_id = social.stream_id;
$social_li.length = 0;
@@ -183,7 +183,7 @@ test_ui("pinned_streams_never_inactive", ({override_rewire, mock_template}) => {
create_social_sidebar_row({mock_template});
// non-pinned streams can be made inactive
- const $social_sidebar = $("");
+ const $social_sidebar = $("");
let stream_id = social.stream_id;
let row = stream_list.stream_sidebar.get_row(stream_id);
override_rewire(stream_data, "is_active", () => false);
@@ -200,7 +200,7 @@ test_ui("pinned_streams_never_inactive", ({override_rewire, mock_template}) => {
assert.ok($social_sidebar.hasClass("inactive_stream"));
// pinned streams can never be made inactive
- const $devel_sidebar = $("");
+ const $devel_sidebar = $("");
stream_id = devel.stream_id;
row = stream_list.stream_sidebar.get_row(stream_id);
override_rewire(stream_data, "is_active", () => false);
@@ -217,7 +217,7 @@ function add_row(sub) {
const row = {
update_whether_active() {},
get_li() {
- const html = "<" + sub.name + " sidebar row html>";
+ const html = "<" + sub.name + "-sidebar-row-stub>";
const $obj = $(html);
$obj.length = 1; // bypass blueslip error
@@ -372,7 +372,7 @@ test_ui("narrowing", ({override_rewire}) => {
topic_list.get_stream_li = noop;
override_rewire(scroll_util, "scroll_element_into_container", noop);
- assert.ok(!$("").hasClass("active-filter"));
+ assert.ok(!$("").hasClass("active-filter"));
stream_list.set_event_handlers();
@@ -380,7 +380,7 @@ test_ui("narrowing", ({override_rewire}) => {
filter = new Filter([{operator: "stream", operand: "devel"}]);
stream_list.handle_narrow_activated(filter);
- assert.ok($("").hasClass("active-filter"));
+ assert.ok($("").hasClass("active-filter"));
filter = new Filter([
{operator: "stream", operand: "cars"},
@@ -388,12 +388,12 @@ test_ui("narrowing", ({override_rewire}) => {
]);
stream_list.handle_narrow_activated(filter);
assert.ok(!$("ul.filters li").hasClass("active-filter"));
- assert.ok(!$("").hasClass("active-filter")); // false because of topic
+ assert.ok(!$("").hasClass("active-filter")); // false because of topic
filter = new Filter([{operator: "stream", operand: "cars"}]);
stream_list.handle_narrow_activated(filter);
assert.ok(!$("ul.filters li").hasClass("active-filter"));
- assert.ok($("").hasClass("active-filter"));
+ assert.ok($("").hasClass("active-filter"));
let removed_classes;
$("ul#stream_filters li").removeClass = (classes) => {
@@ -450,14 +450,14 @@ test_ui("sort_streams", ({override_rewire}) => {
const split = '
';
const expected_elems = [
- $(""),
- $(""),
- $(""),
+ $(""),
+ $(""),
+ $(""),
split,
- $(""),
- $(""),
+ $(""),
+ $(""),
split,
- $(""),
+ $(""),
];
assert.deepEqual(appended_elems, expected_elems);
@@ -529,11 +529,11 @@ test_ui("separators_only_pinned_and_dormant", ({override_rewire}) => {
const split = '
';
const expected_elems = [
// pinned
- $(""),
- $(""),
+ $(""),
+ $(""),
split,
// dormant
- $(""),
+ $(""),
];
assert.deepEqual(appended_elems, expected_elems);
@@ -573,8 +573,8 @@ test_ui("separators_only_pinned", () => {
const expected_elems = [
// pinned
- $(""),
- $(""),
+ $(""),
+ $(""),
// no separator at the end as no stream follows
];
diff --git a/frontend_tests/node_tests/timerender.js b/frontend_tests/node_tests/timerender.js
index 6e43ce78f6..c3c94310e7 100644
--- a/frontend_tests/node_tests/timerender.js
+++ b/frontend_tests/node_tests/timerender.js
@@ -210,7 +210,7 @@ run_test("render_date_renders_time_html", () => {
const expected_html = $t({defaultMessage: "Today"});
const attrs = {};
- const $span_stub = $("");
+ const $span_stub = $("");
$span_stub.attr = (name, val) => {
attrs[name] = val;
@@ -234,7 +234,7 @@ run_test("render_date_renders_time_above_html", () => {
const message_time = today;
const message_time_above = add(today, {days: -1});
- const $span_stub = $("");
+ const $span_stub = $("");
let appended_val;
$span_stub.append = (...val) => {
@@ -243,10 +243,10 @@ run_test("render_date_renders_time_above_html", () => {
};
const expected = [
- '',
+ $(""),
$t({defaultMessage: "Yesterday"}),
- '
',
- '',
+ $("
"),
+ $(""),
$t({defaultMessage: "Today"}),
];
diff --git a/frontend_tests/node_tests/zjquery.js b/frontend_tests/node_tests/zjquery.js
index 51fdcdd78c..2bf865561b 100644
--- a/frontend_tests/node_tests/zjquery.js
+++ b/frontend_tests/node_tests/zjquery.js
@@ -59,7 +59,7 @@ run_test("basics", () => {
assert.equal($widget.attr("data-department-name"), "hr");
assert.equal($widget.data("department-name"), "hr");
- $widget.html("hello");
+ $widget.html("hello"); // eslint-disable-line no-jquery/no-parse-html-literal
assert.equal($widget.html(), "hello");
$widget.prop("title", "My widget");
@@ -84,7 +84,7 @@ run_test("finding_related_objects", () => {
// But you can set up your tests to simulate DOM relationships.
//
// We will use set_find_results(), which is a special zjquery helper.
- const $emoji = $('');
+ const $emoji = $("
");
$("#my-message").set_find_results(".emoji", $emoji);
// And then calling the function produces the desired effect:
diff --git a/static/js/blueslip_stacktrace.ts b/static/js/blueslip_stacktrace.ts
index 4422077462..f4a721c503 100644
--- a/static/js/blueslip_stacktrace.ts
+++ b/static/js/blueslip_stacktrace.ts
@@ -102,7 +102,7 @@ export async function display_stacktrace(error: string, stack: string): Promise<
}),
);
- const $alert = $("").html(
+ const $alert = $("
", {class: "stacktrace"}).html(
render_blueslip_stacktrace({error, stackframes}),
);
$(".alert-box").append($alert);
diff --git a/static/js/components.ts b/static/js/components.ts
index a20fd854e9..796a9bf551 100644
--- a/static/js/components.ts
+++ b/static/js/components.ts
@@ -32,7 +32,7 @@ export function toggle(opts: {
child_wants_focus?: boolean;
selected?: number;
}): Toggle {
- const $component = $("
");
+ const $component = $("
", {class: "tab-switcher"});
if (opts.html_class) {
// add a check inside passed arguments in case some extra
// classes need to be added for correct alignment or other purposes
diff --git a/static/js/flatpickr.js b/static/js/flatpickr.js
index 1fd27f7f62..cdd12e7656 100644
--- a/static/js/flatpickr.js
+++ b/static/js/flatpickr.js
@@ -10,7 +10,7 @@ function is_numeric_key(key) {
}
export function show_flatpickr(element, callback, default_timestamp, options = {}) {
- const $flatpickr_input = $("
");
+ const $flatpickr_input = $("
", {id: "#timestamp_flatpickr"});
const instance = $flatpickr_input.flatpickr({
mode: "single",
diff --git a/static/js/lightbox.js b/static/js/lightbox.js
index d3ceeb1d3c..257a23e7e5 100644
--- a/static/js/lightbox.js
+++ b/static/js/lightbox.js
@@ -183,7 +183,7 @@ export function render_lightbox_list_images(preview_source) {
const src = img.getAttribute("src");
const className = preview_source === src ? "image selected" : "image";
- const $node = $("
", {
+ const $node = $("
", {
class: className,
"data-src": src,
}).css({backgroundImage: "url(" + src + ")"});
@@ -244,7 +244,7 @@ function display_video(payload) {
break;
}
- const $iframe = $("
");
+ const $iframe = $("