mirror of https://github.com/zulip/zulip.git
js: Enable no-jquery/no-constructor-attributes.
https://github.com/wikimedia/eslint-plugin-no-jquery/blob/master/docs/rules/no-constructor-attributes.md The motivation for this rule is a subtle caveat buried in the documentation: https://api.jquery.com/jquery/#jQuery-html-attributes “While the second argument is convenient, its flexibility can lead to unintended consequences (e.g. $( "<input>", {size: "4"} ) calling the .size() method instead of setting the size attribute).” Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
098effe0a6
commit
e8a30060ee
|
@ -73,6 +73,7 @@
|
|||
"no-implied-eval": "error",
|
||||
"no-inner-declarations": "off",
|
||||
"no-iterator": "error",
|
||||
"no-jquery/no-constructor-attributes": "error",
|
||||
"no-jquery/no-parse-html-literal": "error",
|
||||
"no-label-var": "error",
|
||||
"no-labels": "error",
|
||||
|
|
|
@ -115,35 +115,38 @@ function make_switcher() {
|
|||
return $self;
|
||||
}
|
||||
|
||||
mock_jquery((sel, attributes) => {
|
||||
mock_jquery((sel) => {
|
||||
if (sel.stub) {
|
||||
// The component often redundantly re-wraps objects.
|
||||
return sel;
|
||||
}
|
||||
|
||||
switch (sel) {
|
||||
case "<div>": {
|
||||
if (attributes.class === "tab-switcher") {
|
||||
case "<div>":
|
||||
return {
|
||||
addClass(className) {
|
||||
if (className === "tab-switcher") {
|
||||
return env.switcher;
|
||||
}
|
||||
|
||||
assert.equal(className, "ind-tab");
|
||||
return {
|
||||
attr(attributes) {
|
||||
const tab_id = attributes["data-tab-id"];
|
||||
assert.deepEqual(
|
||||
attributes,
|
||||
[
|
||||
{
|
||||
class: "ind-tab",
|
||||
"data-tab-key": "keyboard-shortcuts",
|
||||
"data-tab-id": 0,
|
||||
tabindex: 0,
|
||||
},
|
||||
{
|
||||
class: "ind-tab",
|
||||
"data-tab-key": "message-formatting",
|
||||
"data-tab-id": 1,
|
||||
tabindex: 0,
|
||||
},
|
||||
{
|
||||
class: "ind-tab",
|
||||
"data-tab-key": "search-operators",
|
||||
"data-tab-id": 2,
|
||||
tabindex: 0,
|
||||
|
@ -151,7 +154,10 @@ mock_jquery((sel, attributes) => {
|
|||
][tab_id],
|
||||
);
|
||||
return make_tab(tab_id);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
/* istanbul ignore next */
|
||||
default:
|
||||
throw new Error("unknown selector: " + sel);
|
||||
|
|
|
@ -22,6 +22,9 @@ mock_jquery((arg) => {
|
|||
}
|
||||
|
||||
return {
|
||||
addClass() {
|
||||
return this;
|
||||
},
|
||||
replace: (regex, string) => {
|
||||
arg = arg.replace(regex, string);
|
||||
},
|
||||
|
|
|
@ -102,9 +102,9 @@ export async function display_stacktrace(error: string, stack: string): Promise<
|
|||
}),
|
||||
);
|
||||
|
||||
const $alert = $("<div>", {class: "stacktrace"}).html(
|
||||
render_blueslip_stacktrace({error, stackframes}),
|
||||
);
|
||||
const $alert = $("<div>")
|
||||
.addClass("stacktrace")
|
||||
.html(render_blueslip_stacktrace({error, stackframes}));
|
||||
$(".alert-box").append($alert);
|
||||
$alert.addClass("show");
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ export function toggle(opts: {
|
|||
child_wants_focus?: boolean;
|
||||
selected?: number;
|
||||
}): Toggle {
|
||||
const $component = $("<div>", {class: "tab-switcher"});
|
||||
const $component = $("<div>").addClass("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
|
||||
|
@ -41,12 +41,9 @@ export function toggle(opts: {
|
|||
for (const [i, value] of opts.values.entries()) {
|
||||
// create a tab with a tab-id so they don't have to be referenced
|
||||
// by text value which can be inconsistent.
|
||||
const $tab = $("<div>", {
|
||||
class: "ind-tab",
|
||||
"data-tab-key": value.key,
|
||||
"data-tab-id": i,
|
||||
tabindex: 0,
|
||||
});
|
||||
const $tab = $("<div>")
|
||||
.addClass("ind-tab")
|
||||
.attr({"data-tab-key": value.key, "data-tab-id": i, tabindex: 0});
|
||||
|
||||
/* istanbul ignore if */
|
||||
if (value.label_html !== undefined) {
|
||||
|
|
|
@ -415,7 +415,7 @@ export class MultiSelectDropdownListWidget extends DropdownListWidget {
|
|||
add_check_mark($element) {
|
||||
const value = $element.attr("data-value");
|
||||
const $link_elem = $element.find("a").expectOne();
|
||||
$link_elem.prepend($("<i>", {class: "fa fa-check"}));
|
||||
$link_elem.prepend($("<i>").addClass(["fa", "fa-check"]));
|
||||
$element.addClass("checked");
|
||||
this.data_selected.push(value);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ function is_numeric_key(key) {
|
|||
}
|
||||
|
||||
export function show_flatpickr(element, callback, default_timestamp, options = {}) {
|
||||
const $flatpickr_input = $("<input>", {id: "#timestamp_flatpickr"});
|
||||
const $flatpickr_input = $("<input>").attr("id", "#timestamp_flatpickr");
|
||||
|
||||
const instance = $flatpickr_input.flatpickr({
|
||||
mode: "single",
|
||||
|
|
|
@ -183,10 +183,10 @@ export function render_lightbox_list_images(preview_source) {
|
|||
const src = img.getAttribute("src");
|
||||
const className = preview_source === src ? "image selected" : "image";
|
||||
|
||||
const $node = $("<div>", {
|
||||
class: className,
|
||||
"data-src": src,
|
||||
}).css({backgroundImage: "url(" + src + ")"});
|
||||
const $node = $("<div>")
|
||||
.addClass(className)
|
||||
.attr("data-src", src)
|
||||
.css({backgroundImage: "url(" + src + ")"});
|
||||
|
||||
$image_list.append($node);
|
||||
|
||||
|
|
|
@ -202,7 +202,7 @@ export function create($container, list, opts) {
|
|||
if ($list_item.length) {
|
||||
const $link_elem = $list_item.find("a").expectOne();
|
||||
$list_item.addClass("checked");
|
||||
$link_elem.prepend($("<i>", {class: "fa fa-check"}));
|
||||
$link_elem.prepend($("<i>").addClass(["fa", "fa-check"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,21 +21,23 @@ export function make_indicator(
|
|||
// Create some additional containers to facilitate absolutely
|
||||
// positioned spinners.
|
||||
const container_id = $container.attr("id")!;
|
||||
let $inner_container = $("<div>", {id: `${container_id}_box_container`});
|
||||
let $inner_container = $("<div>").attr("id", `${container_id}_box_container`);
|
||||
$container.append($inner_container);
|
||||
$container = $inner_container;
|
||||
$inner_container = $("<div>", {id: `${container_id}_box`});
|
||||
$inner_container = $("<div>").attr("id", `${container_id}_box`);
|
||||
$container.append($inner_container);
|
||||
$container = $inner_container;
|
||||
}
|
||||
|
||||
const $spinner_elem = $("<div>", {class: "loading_indicator_spinner", ["aria-hidden"]: "true"});
|
||||
const $spinner_elem = $("<div>")
|
||||
.addClass("loading_indicator_spinner")
|
||||
.attr("aria-hidden", "true");
|
||||
$spinner_elem.html(render_loader({container_id: $outer_container.attr("id")}));
|
||||
$container.append($spinner_elem);
|
||||
let text_width = 0;
|
||||
|
||||
if (text !== undefined) {
|
||||
const $text_elem = $("<span>", {class: "loading_indicator_text"});
|
||||
const $text_elem = $("<span>").addClass("loading_indicator_text");
|
||||
$text_elem.text(text);
|
||||
$container.append($text_elem);
|
||||
// See note, below
|
||||
|
|
|
@ -156,8 +156,13 @@ function hide_catalog_show_integration() {
|
|||
link = name;
|
||||
}
|
||||
}
|
||||
const $category_el = $("<a>", {href: "/integrations/" + link}).append(
|
||||
$("<h3>", {class: "integration-category", ["data-category"]: link}).text(category),
|
||||
const $category_el = $("<a>")
|
||||
.attr("href", "/integrations/" + link)
|
||||
.append(
|
||||
$("<h3>")
|
||||
.addClass("integration-category")
|
||||
.attr("data-category", link)
|
||||
.text(category),
|
||||
);
|
||||
$("#integration-instructions-group .categories").append($category_el);
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ export function update_view_on_deactivate(user_id) {
|
|||
$row.find("i.deactivated-user-icon").show();
|
||||
$button.addClass("btn-warning reactivate");
|
||||
$button.removeClass("deactivate btn-danger");
|
||||
$button.empty().append($("<i>", {class: "fa fa-user-plus", ["aria-hidden"]: "true"}));
|
||||
$button.empty().append($("<i>").addClass(["fa", "fa-user-plus"]).attr("aria-hidden", "true"));
|
||||
$button.attr("title", "Reactivate");
|
||||
$row.addClass("deactivated_user");
|
||||
|
||||
|
@ -115,7 +115,7 @@ function update_view_on_reactivate($row) {
|
|||
$button.addClass("btn-danger deactivate");
|
||||
$button.removeClass("btn-warning reactivate");
|
||||
$button.attr("title", "Deactivate");
|
||||
$button.empty().append($("<i>", {class: "fa fa-user-times", ["aria-hidden"]: "true"}));
|
||||
$button.empty().append($("<i>").addClass(["fa", "fa-user-times"]).attr("aria-hidden", "true"));
|
||||
$row.removeClass("deactivated_user");
|
||||
|
||||
if ($user_role) {
|
||||
|
|
|
@ -24,7 +24,7 @@ export function initialize_disable_btn_hint_popover(
|
|||
$disabled_btn.css("pointer-events", "none");
|
||||
$popover_btn.popover({
|
||||
placement: "bottom",
|
||||
content: $("<div>", {class: "sub_disable_btn_hint"}).text(hint_text).prop("outerHTML"),
|
||||
content: $("<div>").addClass("sub_disable_btn_hint").text(hint_text).prop("outerHTML"),
|
||||
trigger: "manual",
|
||||
html: true,
|
||||
animation: false,
|
||||
|
|
|
@ -65,10 +65,10 @@ export function success(response_html: string, $status_box: JQuery, remove_after
|
|||
}
|
||||
|
||||
export function generic_embed_error(error_html: string): void {
|
||||
const $alert = $("<div>", {class: "alert home-error-bar show"});
|
||||
const $exit = $("<div>", {class: "exit"});
|
||||
const $alert = $("<div>").addClass(["alert", "home-error-bar", "show"]);
|
||||
const $exit = $("<div>").addClass("exit");
|
||||
|
||||
$(".alert-box").append($alert.append($exit, $("<div>", {class: "content"}).html(error_html)));
|
||||
$(".alert-box").append($alert.append($exit, $("<div>").addClass("content").html(error_html)));
|
||||
}
|
||||
|
||||
export function generic_row_button_error(xhr: JQuery.jqXHR, $btn: JQuery): void {
|
||||
|
|
Loading…
Reference in New Issue