mirror of https://github.com/zulip/zulip.git
tsconfig: Enable noUncheckedIndexedAccess.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
4e91572c96
commit
804c3706ff
|
@ -26,6 +26,7 @@
|
|||
"forceConsistentCasingInFileNames": true,
|
||||
"isolatedModules": true,
|
||||
"noImplicitOverride": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
|
||||
/* Additional checks */
|
||||
"noUnusedLocals": true,
|
||||
|
|
|
@ -215,9 +215,9 @@ export function process_fenced_code(content: string): string {
|
|||
consume_line = function consume_line(output_lines: string[], line: string) {
|
||||
const match = fence_re.exec(line);
|
||||
if (match) {
|
||||
const fence = match[1];
|
||||
const lang = match[3];
|
||||
const header = match[5];
|
||||
const fence = match[1]!;
|
||||
const lang = match[3]!;
|
||||
const header = match[5]!;
|
||||
const handler = handler_for_fence(output_lines, fence, lang, header);
|
||||
handler_stack.push(handler);
|
||||
} else {
|
||||
|
@ -255,7 +255,7 @@ export function get_unused_fence(content: string): string {
|
|||
let match;
|
||||
fence_length_re.lastIndex = 0;
|
||||
while ((match = fence_length_re.exec(content)) !== null) {
|
||||
length = Math.max(length, match[1].length + 1);
|
||||
length = Math.max(length, match[1]!.length + 1);
|
||||
}
|
||||
return "`".repeat(length);
|
||||
}
|
||||
|
|
|
@ -68,12 +68,12 @@ export function last_prefix_match(prefix: string, words: string[]): number | nul
|
|||
let found = false;
|
||||
while (left < right) {
|
||||
const mid = Math.floor((left + right) / 2);
|
||||
if (words[mid].startsWith(prefix)) {
|
||||
if (words[mid]!.startsWith(prefix)) {
|
||||
// Note that left can never be 0 if `found` is true,
|
||||
// since it is incremented at least once here.
|
||||
left = mid + 1;
|
||||
found = true;
|
||||
} else if (words[mid] < prefix) {
|
||||
} else if (words[mid]! < prefix) {
|
||||
left = mid + 1;
|
||||
} else {
|
||||
right = mid;
|
||||
|
|
|
@ -19,12 +19,12 @@ export function launch(): void {
|
|||
|
||||
const zulip_version_clipboard = new ClipboardJS("#about-zulip .fa-copy.zulip-version");
|
||||
zulip_version_clipboard.on("success", () => {
|
||||
show_copied_confirmation($("#about-zulip .fa-copy.zulip-version")[0]);
|
||||
show_copied_confirmation($("#about-zulip .fa-copy.zulip-version")[0]!);
|
||||
});
|
||||
|
||||
const zulip_merge_base_clipboard = new ClipboardJS("#about-zulip .fa-copy.zulip-merge-base");
|
||||
zulip_merge_base_clipboard.on("success", () => {
|
||||
show_copied_confirmation($("#about-zulip .fa-copy.zulip-merge-base")[0]);
|
||||
show_copied_confirmation($("#about-zulip .fa-copy.zulip-merge-base")[0]!);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,6 @@ export function update_notification_sound_source(
|
|||
if (notification_sound !== "none") {
|
||||
// Load it so that it is ready to be played; without this the old sound
|
||||
// is played.
|
||||
$container_elem[0].load();
|
||||
$container_elem[0]!.load();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ export function update_discount_details(
|
|||
}
|
||||
|
||||
export function is_valid_input($elem: JQuery<HTMLFormElement>): boolean {
|
||||
return $elem[0].checkValidity();
|
||||
return $elem[0]!.checkValidity();
|
||||
}
|
||||
|
||||
export function redirect_to_billing_with_successful_upgrade(billing_base_url: string): void {
|
||||
|
|
|
@ -279,7 +279,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
}
|
||||
|
||||
select(e?: JQuery.ClickEvent | JQuery.KeyUpEvent | JQuery.KeyDownEvent): this {
|
||||
const val = this.values.get(this.$menu.find(".active")[0]);
|
||||
const val = this.values.get(this.$menu.find(".active")[0]!);
|
||||
assert(val !== undefined);
|
||||
if (this.input_element.type === "contenteditable") {
|
||||
this.input_element.$element
|
||||
|
@ -295,8 +295,8 @@ export class Typeahead<ItemType extends string | object> {
|
|||
const [from, to_before, to_after] = get_string_diff(element_val, after_text);
|
||||
const replacement = after_text.slice(from, to_after);
|
||||
// select / highlight the minimal text to be replaced
|
||||
this.input_element.$element[0].setSelectionRange(from, to_before);
|
||||
insertTextIntoField(this.input_element.$element[0], replacement);
|
||||
this.input_element.$element[0]!.setSelectionRange(from, to_before);
|
||||
insertTextIntoField(this.input_element.$element[0]!, replacement);
|
||||
this.input_element.$element.trigger("change");
|
||||
}
|
||||
|
||||
|
@ -304,7 +304,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
}
|
||||
|
||||
set_value(): void {
|
||||
const val = this.values.get(this.$menu.find(".active")[0]);
|
||||
const val = this.values.get(this.$menu.find(".active")[0]!);
|
||||
assert(typeof val === "string");
|
||||
if (this.input_element.type === "contenteditable") {
|
||||
this.input_element.$element.text(val);
|
||||
|
@ -340,7 +340,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
// We don't need tippy to position typeaheads which already know where they should be.
|
||||
return this;
|
||||
}
|
||||
this.instance = tippy.default(this.input_element.$element[0], {
|
||||
this.instance = tippy.default(this.input_element.$element[0]!, {
|
||||
// Lets typeahead take the width needed to fit the content
|
||||
// and wraps it if it overflows the visible container.
|
||||
maxWidth: "none",
|
||||
|
@ -371,7 +371,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
interactive: true,
|
||||
appendTo: () => document.body,
|
||||
showOnCreate: true,
|
||||
content: this.$container[0],
|
||||
content: this.$container[0]!,
|
||||
// We expect the typeahead creator to handle when to hide / show the typeahead.
|
||||
trigger: "manual",
|
||||
arrow: false,
|
||||
|
@ -449,7 +449,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
render(final_items: ItemType[], matching_items: ItemType[]): this {
|
||||
const $items: JQuery[] = final_items.map((item) => {
|
||||
const $i = $(ITEM_HTML);
|
||||
this.values.set($i[0], item);
|
||||
this.values.set($i[0]!, item);
|
||||
const item_html = this.highlighter_html(item, this.query) ?? "";
|
||||
const $item_html = $i.find("a").html(item_html);
|
||||
|
||||
|
@ -461,7 +461,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
return $i;
|
||||
});
|
||||
|
||||
$items[0].addClass("active");
|
||||
$items[0]!.addClass("active");
|
||||
this.$menu.empty().append($items);
|
||||
return this;
|
||||
}
|
||||
|
@ -621,12 +621,12 @@ export class Typeahead<ItemType extends string | object> {
|
|||
|
||||
this.select(e);
|
||||
|
||||
if (this.input_element.$element[0].id === "stream_message_recipient_topic") {
|
||||
if (this.input_element.$element[0]!.id === "stream_message_recipient_topic") {
|
||||
assert(this.input_element.type === "input");
|
||||
// Move the cursor to the end of the topic
|
||||
const topic_length = this.input_element.$element.val()!.length;
|
||||
this.input_element.$element[0].selectionStart = topic_length;
|
||||
this.input_element.$element[0].selectionEnd = topic_length;
|
||||
this.input_element.$element[0]!.selectionStart = topic_length;
|
||||
this.input_element.$element[0]!.selectionEnd = topic_length;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -653,7 +653,7 @@ export class Typeahead<ItemType extends string | object> {
|
|||
// when shift (keycode 16) + tabbing to the topic field
|
||||
if (
|
||||
pseudo_keycode === 16 &&
|
||||
this.input_element.$element[0].id === "stream_message_recipient_topic"
|
||||
this.input_element.$element[0]!.id === "stream_message_recipient_topic"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -170,7 +170,7 @@ export class BuddyList extends BuddyListConf {
|
|||
// This will default to "bottom" placement for this tooltip.
|
||||
placement = "auto";
|
||||
}
|
||||
tippy.default($elem[0], {
|
||||
tippy.default($elem[0]!, {
|
||||
// Because the buddy list subheadings are potential click targets
|
||||
// for purposes having nothing to do with the subscriber count
|
||||
// (collapsing/expanding), we delay showing the tooltip until the
|
||||
|
@ -765,7 +765,7 @@ export class BuddyList extends BuddyListConf {
|
|||
|
||||
const elem = scroll_util
|
||||
.get_scroll_element($(this.scroll_container_selector))
|
||||
.expectOne()[0];
|
||||
.expectOne()[0]!;
|
||||
|
||||
// Add a fudge factor.
|
||||
height += 10;
|
||||
|
|
|
@ -62,7 +62,7 @@ export function claim_colors(subs: {color: string}[]): void {
|
|||
}
|
||||
|
||||
export function pick_color(): string {
|
||||
const color = unused_colors[0];
|
||||
const color = unused_colors[0]!;
|
||||
|
||||
claim_color(color);
|
||||
|
||||
|
|
|
@ -108,7 +108,7 @@ function set_password_toggle_label(
|
|||
): void {
|
||||
$(password_selector).attr("aria-label", label);
|
||||
if (tippy_tooltips) {
|
||||
const element: tippy.ReferenceElement = $(password_selector)[0];
|
||||
const element: tippy.ReferenceElement = $(password_selector)[0]!;
|
||||
const tippy_instance = element._tippy ?? tippy.default(element);
|
||||
tippy_instance.setContent(label);
|
||||
} else {
|
||||
|
|
|
@ -82,7 +82,7 @@ export function toggle(opts: {
|
|||
|
||||
meta.idx = idx;
|
||||
if (opts.callback) {
|
||||
opts.callback(opts.values[idx].label, opts.values[idx].key);
|
||||
opts.callback(opts.values[idx]!.label, opts.values[idx]!.key);
|
||||
}
|
||||
|
||||
if (!opts.child_wants_focus) {
|
||||
|
@ -162,7 +162,7 @@ export function toggle(opts: {
|
|||
|
||||
value() {
|
||||
if (meta.idx >= 0) {
|
||||
return opts.values[meta.idx].label;
|
||||
return opts.values[meta.idx]!.label;
|
||||
}
|
||||
/* istanbul ignore next */
|
||||
return undefined;
|
||||
|
|
|
@ -213,7 +213,7 @@ export function update_rendered_message_groups(
|
|||
// the other code takes advantage of blocks beneath recipient bars.
|
||||
for (const message_group of message_groups) {
|
||||
const $elt = get_element(message_group);
|
||||
const first_message = message_group.message_containers[0].msg;
|
||||
const first_message = message_group.message_containers[0]!.msg;
|
||||
const should_fade = compose_fade_helper.should_fade_message(first_message);
|
||||
change_fade_state($elt, should_fade);
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ function on_hidden_callback(): void {
|
|||
// Always move focus to the topic input even if it's not empty,
|
||||
// since it's likely the user will want to update the topic
|
||||
// after updating the stream.
|
||||
ui_util.place_caret_at_end($("input#stream_message_recipient_topic")[0]);
|
||||
ui_util.place_caret_at_end($("input#stream_message_recipient_topic")[0]!);
|
||||
} else {
|
||||
if (compose_state.private_message_recipient().length === 0) {
|
||||
$("#private_message_recipient").trigger("focus").trigger("select");
|
||||
|
|
|
@ -98,9 +98,9 @@ export function insert_and_scroll_into_view(
|
|||
replace_all = false,
|
||||
): void {
|
||||
if (replace_all) {
|
||||
setFieldText($textarea[0], content);
|
||||
setFieldText($textarea[0]!, content);
|
||||
} else {
|
||||
insertTextIntoField($textarea[0], content);
|
||||
insertTextIntoField($textarea[0]!, content);
|
||||
}
|
||||
// Blurring and refocusing ensures the cursor / selection is in view
|
||||
// in chromium browsers.
|
||||
|
@ -275,7 +275,7 @@ export function replace_syntax(
|
|||
// for details.
|
||||
|
||||
const old_text = $textarea.val();
|
||||
replaceFieldText($textarea[0], old_syntax, () => new_syntax, "after-replacement");
|
||||
replaceFieldText($textarea[0]!, old_syntax, () => new_syntax, "after-replacement");
|
||||
const new_text = $textarea.val();
|
||||
|
||||
// When replacing content in a textarea, we need to move the cursor
|
||||
|
|
|
@ -250,7 +250,7 @@ function handle_bulleting_or_numbering(
|
|||
if (bulleted_numbered_list_util.strip_bullet(previous_line) === "") {
|
||||
// below we select and replace the last 2 characters in the textarea before
|
||||
// the cursor - the bullet syntax - with an empty string
|
||||
$textarea[0].setSelectionRange($textarea.caret() - 2, $textarea.caret());
|
||||
$textarea[0]!.setSelectionRange($textarea.caret() - 2, $textarea.caret());
|
||||
compose_ui.insert_and_scroll_into_view("", $textarea);
|
||||
e.preventDefault();
|
||||
return;
|
||||
|
@ -264,7 +264,7 @@ function handle_bulleting_or_numbering(
|
|||
if (bulleted_numbered_list_util.strip_numbering(previous_line) === "") {
|
||||
// below we select then replaces the last few characters in the textarea before
|
||||
// the cursor - the numbering syntax - with an empty string
|
||||
$textarea[0].setSelectionRange(
|
||||
$textarea[0]!.setSelectionRange(
|
||||
$textarea.caret() - previous_number_string.length - 2,
|
||||
$textarea.caret(),
|
||||
);
|
||||
|
@ -297,7 +297,7 @@ export function handle_enter($textarea: JQuery<HTMLTextAreaElement>, e: JQuery.K
|
|||
|
||||
// If the selectionStart and selectionEnd are not the same, that
|
||||
// means that some text was selected.
|
||||
if ($textarea[0].selectionStart !== $textarea[0].selectionEnd) {
|
||||
if ($textarea[0]!.selectionStart !== $textarea[0]!.selectionEnd) {
|
||||
// Replace it with the newline, remembering to resize the
|
||||
// textarea if needed.
|
||||
compose_ui.insert_and_scroll_into_view("\n", $textarea);
|
||||
|
@ -431,7 +431,7 @@ export function tokenize_compose_str(s: string): string {
|
|||
case "_":
|
||||
if (i === 0) {
|
||||
return s;
|
||||
} else if (/[\s"'(/<[{]/.test(s[i - 1])) {
|
||||
} else if (/[\s"'(/<[{]/.test(s[i - 1]!)) {
|
||||
return s.slice(i);
|
||||
}
|
||||
break;
|
||||
|
@ -775,7 +775,7 @@ export function get_candidates(
|
|||
|
||||
// We will likely want to extend this list to be more i18n-friendly.
|
||||
const terminal_symbols = ",.;?!()[]> \"'\n\t";
|
||||
if (rest !== "" && !terminal_symbols.includes(rest[0])) {
|
||||
if (rest !== "" && !terminal_symbols.includes(rest[0]!)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -1158,7 +1158,7 @@ export function content_typeahead_selected(
|
|||
$textbox.caret(beginning.length);
|
||||
compose_ui.autosize_textarea($textbox);
|
||||
};
|
||||
flatpickr.show_flatpickr(input_element.$element[0], on_timestamp_selection, timestamp);
|
||||
flatpickr.show_flatpickr(input_element.$element[0]!, on_timestamp_selection, timestamp);
|
||||
return beginning + rest;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -151,7 +151,7 @@ function get_message_height(elem: HTMLElement): number {
|
|||
// This needs to be very fast. This function runs hundreds of times
|
||||
// when displaying a message feed view that has hundreds of message
|
||||
// history, which ideally should render in <100ms.
|
||||
return $(elem).find(".message_content")[0].scrollHeight;
|
||||
return $(elem).find(".message_content")[0]!.scrollHeight;
|
||||
}
|
||||
|
||||
export function hide_message_expander($row: JQuery): void {
|
||||
|
|
|
@ -132,7 +132,7 @@ function select_div($div: JQuery, selection: Selection): void {
|
|||
background: "#FFF",
|
||||
}).attr("id", "copytempdiv");
|
||||
$("body").append($div);
|
||||
selection.selectAllChildren($div[0]);
|
||||
selection.selectAllChildren($div[0]!);
|
||||
}
|
||||
|
||||
function remove_div(_div: JQuery, ranges: Range[]): void {
|
||||
|
@ -591,7 +591,7 @@ function is_safe_url_paste_target($textarea: JQuery<HTMLTextAreaElement>): boole
|
|||
// Look at the two characters before the start of the original
|
||||
// range in search of the tell-tale `](` from existing Markdown
|
||||
// link syntax
|
||||
const possible_markdown_link_markers = $textarea[0].value.slice(range.start - 2, range.start);
|
||||
const possible_markdown_link_markers = $textarea[0]!.value.slice(range.start - 2, range.start);
|
||||
|
||||
if (possible_markdown_link_markers === "](") {
|
||||
return false;
|
||||
|
|
|
@ -367,7 +367,7 @@ function draft_notify(): void {
|
|||
content: $t({defaultMessage: "Saved as draft"}),
|
||||
arrow: true,
|
||||
placement: "right",
|
||||
})[0];
|
||||
})[0]!;
|
||||
instance.show();
|
||||
function remove_instance(): void {
|
||||
instance.destroy();
|
||||
|
|
|
@ -86,7 +86,7 @@ function zephyr_topic_name_match(message: Message & {type: "stream"}, operand: s
|
|||
const m = /^(.*?)(?:\.d)*$/i.exec(operand);
|
||||
// m should never be null because any string matches that regex.
|
||||
assert(m !== null);
|
||||
const base_topic = m[1];
|
||||
const base_topic = m[1]!;
|
||||
let related_regexp;
|
||||
|
||||
// Additionally, Zephyr users expect the empty instance and
|
||||
|
@ -257,7 +257,7 @@ export class Filter {
|
|||
constructor(terms: NarrowTerm[]) {
|
||||
this._terms = this.fix_terms(terms);
|
||||
if (this.has_operator("channel")) {
|
||||
this._sub = stream_data.get_sub_by_name(this.operands("channel")[0]);
|
||||
this._sub = stream_data.get_sub_by_name(this.operands("channel")[0]!);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -724,7 +724,7 @@ export class Filter {
|
|||
}
|
||||
|
||||
is_non_huddle_pm(): boolean {
|
||||
return this.has_operator("dm") && this.operands("dm")[0].split(",").length === 1;
|
||||
return this.has_operator("dm") && this.operands("dm")[0]!.split(",").length === 1;
|
||||
}
|
||||
|
||||
supports_collapsing_recipients(): boolean {
|
||||
|
@ -872,7 +872,7 @@ export class Filter {
|
|||
"/#narrow/" +
|
||||
CHANNEL_SYNONYM +
|
||||
"/" +
|
||||
stream_data.name_to_slug(this.operands("channel")[0]) +
|
||||
stream_data.name_to_slug(this.operands("channel")[0]!) +
|
||||
"/topic/" +
|
||||
this.operands("topic")[0]
|
||||
);
|
||||
|
@ -894,7 +894,7 @@ export class Filter {
|
|||
"/#narrow/" +
|
||||
CHANNEL_SYNONYM +
|
||||
"/" +
|
||||
stream_data.name_to_slug(this.operands("channel")[0])
|
||||
stream_data.name_to_slug(this.operands("channel")[0]!)
|
||||
);
|
||||
case "is-dm":
|
||||
return "/#narrow/is/dm";
|
||||
|
@ -911,7 +911,7 @@ export class Filter {
|
|||
// TODO: It is ambiguous how we want to handle the 'sender' case,
|
||||
// we may remove it in the future based on design decisions
|
||||
case "sender":
|
||||
return "/#narrow/sender/" + people.emails_to_slug(this.operands("sender")[0]);
|
||||
return "/#narrow/sender/" + people.emails_to_slug(this.operands("sender")[0]!);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -991,7 +991,7 @@ export class Filter {
|
|||
(term_types.length === 2 && _.isEqual(term_types, ["dm", "near"])) ||
|
||||
(term_types.length === 1 && _.isEqual(term_types, ["dm"]))
|
||||
) {
|
||||
const emails = this.operands("dm")[0].split(",");
|
||||
const emails = this.operands("dm")[0]!.split(",");
|
||||
const names = emails.map((email) => {
|
||||
const person = people.get_by_email(email);
|
||||
if (!person) {
|
||||
|
@ -1006,7 +1006,7 @@ export class Filter {
|
|||
return util.format_array_as_list(names, "long", "conjunction");
|
||||
}
|
||||
if (term_types.length === 1 && _.isEqual(term_types, ["sender"])) {
|
||||
const email = this.operands("sender")[0];
|
||||
const email = this.operands("sender")[0]!;
|
||||
const user = people.get_by_email(email);
|
||||
let sender = email;
|
||||
if (user) {
|
||||
|
|
|
@ -25,7 +25,7 @@ export function show_flatpickr(
|
|||
): flatpickr.Instance {
|
||||
const $flatpickr_input = $<HTMLInputElement>("<input>").attr("id", "#timestamp_flatpickr");
|
||||
|
||||
flatpickr_instance = flatpickr($flatpickr_input[0], {
|
||||
flatpickr_instance = flatpickr($flatpickr_input[0]!, {
|
||||
mode: "single",
|
||||
enableTime: true,
|
||||
clickOpens: false,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
export function get_hash_category(hash?: string): string {
|
||||
// given "#channels/subscribed", returns "channels"
|
||||
return hash ? hash.replace(/^#/, "").split(/\//)[0] : "";
|
||||
return hash ? hash.replace(/^#/, "").split(/\//)[0]! : "";
|
||||
}
|
||||
|
||||
export function get_hash_section(hash?: string): string {
|
||||
|
@ -88,7 +88,7 @@ export function is_editing_stream(desired_stream_id: number): boolean {
|
|||
|
||||
// if the string casted to a number is valid, and another component
|
||||
// after exists then it's a stream name/id pair.
|
||||
const stream_id = Number.parseFloat(hash_components[1]);
|
||||
const stream_id = Number.parseFloat(hash_components[1]!);
|
||||
|
||||
return stream_id === desired_stream_id;
|
||||
}
|
||||
|
|
|
@ -164,7 +164,7 @@ export function parse_narrow(hash: string[]): NarrowTerm[] | undefined {
|
|||
for (i = 1; i < hash.length; i += 2) {
|
||||
// We don't construct URLs with an odd number of components,
|
||||
// but the user might write one.
|
||||
let operator = internal_url.decodeHashComponent(hash[i]);
|
||||
let operator = internal_url.decodeHashComponent(hash[i]!);
|
||||
// Do not parse further if empty operator encountered.
|
||||
if (operator === "") {
|
||||
break;
|
||||
|
|
|
@ -324,7 +324,7 @@ function insert_dms(keys_to_insert: string[]): void {
|
|||
}
|
||||
|
||||
if (keys_to_insert.includes(key)) {
|
||||
const $previous_row = get_row_from_conversation_key(sorted_keys[i - 1]);
|
||||
const $previous_row = get_row_from_conversation_key(sorted_keys[i - 1]!);
|
||||
$previous_row.after($(render_inbox_row(dms_dict.get(key))));
|
||||
}
|
||||
}
|
||||
|
@ -462,7 +462,7 @@ function insert_stream(
|
|||
if (stream_index === 0) {
|
||||
$("#inbox-streams-container").prepend($(rendered_stream));
|
||||
} else {
|
||||
const previous_stream_key = sorted_stream_keys[stream_index - 1];
|
||||
const previous_stream_key = sorted_stream_keys[stream_index - 1]!;
|
||||
$(rendered_stream).insertAfter(get_stream_container(previous_stream_key));
|
||||
}
|
||||
return !streams_dict.get(stream_key)!.is_hidden;
|
||||
|
@ -486,7 +486,7 @@ function insert_topics(keys: string[], stream_key: string): void {
|
|||
}
|
||||
|
||||
if (keys.includes(key)) {
|
||||
const $previous_row = get_row_from_conversation_key(sorted_keys[i - 1]);
|
||||
const $previous_row = get_row_from_conversation_key(sorted_keys[i - 1]!);
|
||||
$previous_row.after($(render_inbox_row(stream_topics_data.get(key))));
|
||||
}
|
||||
}
|
||||
|
@ -1393,7 +1393,7 @@ function move_focus_to_visible_area(): void {
|
|||
}
|
||||
|
||||
const INBOX_ROW_HEIGHT = 30;
|
||||
const position = $("#inbox-filters")[0].getBoundingClientRect();
|
||||
const position = $("#inbox-filters")[0]!.getBoundingClientRect();
|
||||
const inbox_center_x = (position.left + position.right) / 2;
|
||||
// We are aiming to get the first row if it is completely visible or the second row.
|
||||
const inbox_row_below_filters = position.bottom + INBOX_ROW_HEIGHT;
|
||||
|
|
|
@ -225,10 +225,10 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
const idx = store.pills.findIndex((pill) => pill.$element[0] === element);
|
||||
|
||||
if (idx !== -1) {
|
||||
store.pills[idx].$element.remove();
|
||||
store.pills[idx]!.$element.remove();
|
||||
const pill = store.pills.splice(idx, 1);
|
||||
if (store.onPillRemove !== undefined) {
|
||||
store.onPillRemove(pill[0]);
|
||||
store.onPillRemove(pill[0]!);
|
||||
}
|
||||
|
||||
// This is needed to run the "change" event handler registered in
|
||||
|
@ -264,7 +264,7 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
this.removeLastPill(quiet);
|
||||
}
|
||||
|
||||
this.clear(store.$input[0]);
|
||||
this.clear(store.$input[0]!);
|
||||
},
|
||||
|
||||
insertManyPills(pills: string | string[]) {
|
||||
|
@ -285,7 +285,7 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
// when using the `text` insertion feature with jQuery the caret is
|
||||
// placed at the beginning of the input field, so this moves it to
|
||||
// the end.
|
||||
ui_util.place_caret_at_end(store.$input[0]);
|
||||
ui_util.place_caret_at_end(store.$input[0]!);
|
||||
|
||||
// this sends a flag if the operation wasn't completely successful,
|
||||
// which in this case is defined as some of the pills not autofilling
|
||||
|
@ -370,7 +370,7 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
// if the pill is successful, it will create the pill and clear
|
||||
// the input.
|
||||
if (funcs.appendPill(store.$input.text().trim())) {
|
||||
funcs.clear(store.$input[0]);
|
||||
funcs.clear(store.$input[0]!);
|
||||
}
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -399,7 +399,7 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
break;
|
||||
case "Backspace": {
|
||||
const $next = $pill.next();
|
||||
funcs.removePill($pill[0]);
|
||||
funcs.removePill($pill[0]!);
|
||||
$next.trigger("focus");
|
||||
// the "Backspace" key in Firefox will go back a page if you do
|
||||
// not prevent it.
|
||||
|
@ -439,7 +439,7 @@ export function create<T>(opts: InputPillCreateOptions<T>): InputPillContainer<T
|
|||
const $pill = $(this).closest(".pill");
|
||||
const $next = $pill.next();
|
||||
|
||||
funcs.removePill($pill[0]);
|
||||
funcs.removePill($pill[0]!);
|
||||
$next.trigger("focus");
|
||||
});
|
||||
|
||||
|
|
|
@ -52,7 +52,9 @@ export function show_generate_integration_url_modal(api_key: string): void {
|
|||
},
|
||||
});
|
||||
clipboard.on("success", () => {
|
||||
show_copied_confirmation($("#generate-integration-url-modal .dialog_submit_button")[0]);
|
||||
show_copied_confirmation(
|
||||
$("#generate-integration-url-modal .dialog_submit_button")[0]!,
|
||||
);
|
||||
});
|
||||
|
||||
$override_topic.on("change", function () {
|
||||
|
|
|
@ -206,7 +206,7 @@ function submit_invitation_form(): void {
|
|||
$("#invite-user-modal .dialog_submit_button").text($t({defaultMessage: "Invite"}));
|
||||
$("#invite-user-modal .dialog_submit_button").prop("disabled", false);
|
||||
$("#invite-user-modal .dialog_exit_button").prop("disabled", false);
|
||||
$invite_status[0].scrollIntoView();
|
||||
$invite_status[0]!.scrollIntoView();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -226,7 +226,7 @@ function generate_multiuse_invite(): void {
|
|||
clipboard.on("success", () => {
|
||||
const tippy_timeout_in_ms = 800;
|
||||
show_copied_confirmation(
|
||||
$("#copy_generated_invite_link")[0],
|
||||
$("#copy_generated_invite_link")[0]!,
|
||||
() => {
|
||||
// Do nothing on hide
|
||||
},
|
||||
|
@ -243,7 +243,7 @@ function generate_multiuse_invite(): void {
|
|||
);
|
||||
$("#invite-user-modal .dialog_submit_button").prop("disabled", false);
|
||||
$("#invite-user-modal .dialog_exit_button").prop("disabled", false);
|
||||
$invite_status[0].scrollIntoView();
|
||||
$invite_status[0]!.scrollIntoView();
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -308,7 +308,7 @@ function set_streams_to_join_list_visibility(): void {
|
|||
const realm_has_default_streams = stream_data.get_default_stream_ids().length !== 0;
|
||||
const hide_streams_list =
|
||||
realm_has_default_streams &&
|
||||
$<HTMLInputElement>("input#invite_select_default_streams")[0].checked;
|
||||
$<HTMLInputElement>("input#invite_select_default_streams")[0]!.checked;
|
||||
if (hide_streams_list) {
|
||||
$("#streams_to_add .invite-stream-controls").hide();
|
||||
$("#invite-stream-checkboxes").hide();
|
||||
|
|
|
@ -114,12 +114,12 @@ export class PanZoomControl {
|
|||
// See https://github.com/anvaka/panzoom/issues/112 for upstream discussion.
|
||||
|
||||
const {scale, x, y} = e.getTransform();
|
||||
const image_width = $(".zoom-element > img")[0].clientWidth * scale;
|
||||
const image_height = $(".zoom-element > img")[0].clientHeight * scale;
|
||||
const zoom_element_width = $(".zoom-element")[0].clientWidth * scale;
|
||||
const zoom_element_height = $(".zoom-element")[0].clientHeight * scale;
|
||||
const max_translate_x = $(".image-preview")[0].clientWidth;
|
||||
const max_translate_y = $(".image-preview")[0].clientHeight;
|
||||
const image_width = $(".zoom-element > img")[0]!.clientWidth * scale;
|
||||
const image_height = $(".zoom-element > img")[0]!.clientHeight * scale;
|
||||
const zoom_element_width = $(".zoom-element")[0]!.clientWidth * scale;
|
||||
const zoom_element_height = $(".zoom-element")[0]!.clientHeight * scale;
|
||||
const max_translate_x = $(".image-preview")[0]!.clientWidth;
|
||||
const max_translate_y = $(".image-preview")[0]!.clientHeight;
|
||||
|
||||
// When the image is dragged out of the image-preview container
|
||||
// (max_translate) it will be "snapped" back so that the number
|
||||
|
@ -377,7 +377,7 @@ export function build_open_media_function(
|
|||
payload = asset_map.get($preview_src);
|
||||
}
|
||||
if (payload === undefined) {
|
||||
payload = parse_media_data($media[0]);
|
||||
payload = parse_media_data($media[0]!);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,7 +562,7 @@ export function initialize(): void {
|
|||
|
||||
// Bind the pan/zoom control the newly created element.
|
||||
const pan_zoom_control = new PanZoomControl(
|
||||
$("#lightbox_overlay .image-preview > .zoom-element")[0],
|
||||
$("#lightbox_overlay .image-preview > .zoom-element")[0]!,
|
||||
);
|
||||
|
||||
const reset_lightbox_state = function (): void {
|
||||
|
|
|
@ -29,7 +29,7 @@ function python_to_js_linkifier(
|
|||
let current_group = 1;
|
||||
const group_number_to_name: Record<number, string> = {};
|
||||
while (match) {
|
||||
const name = match[1];
|
||||
const name = match[1]!;
|
||||
// Replace named group with regular matching group
|
||||
pattern = pattern.replace("(?P<" + name + ">", "(");
|
||||
// Map numbered reference to named reference for template expansion
|
||||
|
@ -49,7 +49,7 @@ function python_to_js_linkifier(
|
|||
// JS regexes only support i (case insensitivity) and m (multiline)
|
||||
// flags, so keep those and ignore the rest
|
||||
if (match) {
|
||||
const py_flags = match[1];
|
||||
const py_flags = match[1]!;
|
||||
|
||||
for (const flag of py_flags) {
|
||||
if ("im".includes(flag)) {
|
||||
|
|
|
@ -518,10 +518,10 @@ export function create<Key, Item = Key>(
|
|||
}
|
||||
const rendered_row = opts.modifier_html(item, meta.filter_value);
|
||||
if (insert_index === meta.filtered_list.length - 1) {
|
||||
const $target_row = opts.html_selector!(meta.filtered_list[insert_index - 1]);
|
||||
const $target_row = opts.html_selector!(meta.filtered_list[insert_index - 1]!);
|
||||
$target_row.after($(rendered_row));
|
||||
} else {
|
||||
const $target_row = opts.html_selector!(meta.filtered_list[insert_index + 1]);
|
||||
const $target_row = opts.html_selector!(meta.filtered_list[insert_index + 1]!);
|
||||
$target_row.before($(rendered_row));
|
||||
}
|
||||
widget.increase_rendered_offset();
|
||||
|
|
|
@ -250,7 +250,7 @@ function parse_with_options(
|
|||
misfeature).
|
||||
*/
|
||||
full_name = match[1];
|
||||
user_id = Number.parseInt(match[2], 10);
|
||||
user_id = Number.parseInt(match[2]!, 10);
|
||||
|
||||
if (full_name === undefined) {
|
||||
// For @**|id** syntax
|
||||
|
@ -420,7 +420,7 @@ export function get_topic_links(topic: string): TopicLink[] {
|
|||
const template_context = Object.fromEntries(
|
||||
match
|
||||
.slice(1)
|
||||
.map((matched_group, i) => [group_number_to_name[i + 1], matched_group]),
|
||||
.map((matched_group, i) => [group_number_to_name[i + 1]!, matched_group]),
|
||||
);
|
||||
const link_url = url_template.expand(template_context);
|
||||
// We store the starting index as well, to sort the order of occurrence of the links
|
||||
|
@ -563,7 +563,7 @@ function handleLinkifier({
|
|||
assert(item !== undefined);
|
||||
const {url_template, group_number_to_name} = item;
|
||||
const template_context = Object.fromEntries(
|
||||
matches.map((match, i) => [group_number_to_name[i + 1], match]),
|
||||
matches.map((match, i) => [group_number_to_name[i + 1]!, match]),
|
||||
);
|
||||
return url_template.expand(template_context);
|
||||
}
|
||||
|
|
|
@ -240,7 +240,7 @@ export function fetch_and_render_message_history(message: Message): void {
|
|||
.each(function () {
|
||||
rendered_markdown.update_elements($(this));
|
||||
});
|
||||
const first_element_id = content_edit_history[0].timestamp;
|
||||
const first_element_id = content_edit_history[0]!.timestamp;
|
||||
messages_overlay_ui.set_initial_element(
|
||||
String(first_element_id),
|
||||
keyboard_handling_context,
|
||||
|
|
|
@ -233,7 +233,7 @@ export class MessageListData {
|
|||
return true;
|
||||
}
|
||||
|
||||
const recipient_id = Number.parseInt(recipients[0], 10);
|
||||
const recipient_id = Number.parseInt(recipients[0]!, 10);
|
||||
return (
|
||||
!muted_users.is_user_muted(recipient_id) &&
|
||||
!muted_users.is_user_muted(message.sender_id)
|
||||
|
@ -487,7 +487,7 @@ export class MessageListData {
|
|||
|
||||
let idx = this.selected_idx() + 1;
|
||||
while (idx < this._items.length) {
|
||||
const msg_id = this._items[idx].id;
|
||||
const msg_id = this._items[idx]!.id;
|
||||
if (!id_set.has(msg_id)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -78,7 +78,7 @@ export function message_viewport_info(): MessageViewportInfo {
|
|||
export function at_rendered_bottom(): boolean {
|
||||
const bottom = scrollTop() + height();
|
||||
// This also includes bottom whitespace.
|
||||
const full_height = $scroll_container[0].scrollHeight;
|
||||
const full_height = $scroll_container[0]!.scrollHeight;
|
||||
|
||||
// We only know within a pixel or two if we're
|
||||
// exactly at the bottom, due to browser quirkiness,
|
||||
|
@ -94,7 +94,7 @@ export function bottom_rendered_message_visible(): boolean {
|
|||
const $last_row = rows.last_visible();
|
||||
if ($last_row[0] !== undefined) {
|
||||
const message_bottom = $last_row[0].getBoundingClientRect().bottom;
|
||||
const bottom_of_feed = $("#compose")[0].getBoundingClientRect().top;
|
||||
const bottom_of_feed = $("#compose")[0]!.getBoundingClientRect().top;
|
||||
return bottom_of_feed > message_bottom;
|
||||
}
|
||||
return false;
|
||||
|
@ -214,7 +214,7 @@ const top_of_feed = new util.CachedValue({
|
|||
|
||||
const bottom_of_feed = new util.CachedValue({
|
||||
compute_value() {
|
||||
return $("#compose")[0].getBoundingClientRect().top;
|
||||
return $("#compose")[0]!.getBoundingClientRect().top;
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -74,10 +74,10 @@ export function modals_handle_events(event_key: string, context: Context): void
|
|||
export function set_initial_element(element_id: string, context: Context): void {
|
||||
if (element_id) {
|
||||
const $current_element = get_element_by_id(element_id, context);
|
||||
const focus_element = $current_element[0].children[0];
|
||||
const focus_element = $current_element[0]!.children[0];
|
||||
assert(focus_element instanceof HTMLElement);
|
||||
activate_element(focus_element, context);
|
||||
$(`.${CSS.escape(context.items_list_selector)}`)[0].scrollTop = 0;
|
||||
$(`.${CSS.escape(context.items_list_selector)}`)[0]!.scrollTop = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ function initialize_focus(event_name: string, context: Context): void {
|
|||
}
|
||||
|
||||
const $element = get_element_by_id(id, context);
|
||||
const focus_element = $element[0].children[0];
|
||||
const focus_element = $element[0]!.children[0];
|
||||
assert(focus_element instanceof HTMLElement);
|
||||
activate_element(focus_element, context);
|
||||
}
|
||||
|
@ -152,28 +152,28 @@ function scroll_to_element($element: JQuery, context: Context): void {
|
|||
const $box_item = $(`.${CSS.escape(context.box_item_selector)}`);
|
||||
|
||||
// If focused element is first, scroll to the top.
|
||||
if ($box_item.first()[0].parentElement === $element[0]) {
|
||||
$items_list[0].scrollTop = 0;
|
||||
if ($box_item.first()[0]!.parentElement === $element[0]) {
|
||||
$items_list[0]!.scrollTop = 0;
|
||||
}
|
||||
|
||||
// If focused element is last, scroll to the bottom.
|
||||
if ($box_item.last()[0].parentElement === $element[0]) {
|
||||
$items_list[0].scrollTop = $items_list[0].scrollHeight - ($items_list.height() ?? 0);
|
||||
if ($box_item.last()[0]!.parentElement === $element[0]) {
|
||||
$items_list[0]!.scrollTop = $items_list[0]!.scrollHeight - ($items_list.height() ?? 0);
|
||||
}
|
||||
|
||||
// If focused element is cut off from the top, scroll up halfway in modal.
|
||||
if ($element.position().top < 55) {
|
||||
// 55 is the minimum distance from the top that will require extra scrolling.
|
||||
$items_list[0].scrollTop -= $items_list[0].clientHeight / 2;
|
||||
$items_list[0]!.scrollTop -= $items_list[0]!.clientHeight / 2;
|
||||
}
|
||||
|
||||
// If focused element is cut off from the bottom, scroll down halfway in modal.
|
||||
const dist_from_top = $element.position().top;
|
||||
const total_dist = dist_from_top + $element[0].clientHeight;
|
||||
const dist_from_bottom = $items_container[0].clientHeight - total_dist;
|
||||
const dist_from_bottom = $items_container[0]!.clientHeight - total_dist;
|
||||
if (dist_from_bottom < -4) {
|
||||
// -4 is the min dist from the bottom that will require extra scrolling.
|
||||
$items_list[0].scrollTop += $items_list[0].clientHeight / 2;
|
||||
$items_list[0]!.scrollTop += $items_list[0]!.clientHeight / 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ function retrieve_search_query_data(): SearchData {
|
|||
const current_filter = narrow_state.filter();
|
||||
assert(current_filter !== undefined);
|
||||
const search_query = current_filter.operands("search")[0];
|
||||
const query_words = search_query.split(" ");
|
||||
const query_words = search_query!.split(" ");
|
||||
|
||||
const search_string_result: SearchData = {
|
||||
query_words: [],
|
||||
|
@ -96,7 +96,7 @@ function pick_empty_narrow_banner(): NarrowBannerData {
|
|||
return default_banner;
|
||||
}
|
||||
|
||||
const first_term = current_filter.terms()[0];
|
||||
const first_term = current_filter.terms()[0]!;
|
||||
const first_operator = first_term.operator;
|
||||
const first_operand = first_term.operand;
|
||||
const num_terms = current_filter.terms().length;
|
||||
|
|
|
@ -47,7 +47,7 @@ export function compute_narrow_title(filter?: Filter): string {
|
|||
}
|
||||
|
||||
if (filter.has_operator("dm")) {
|
||||
const emails = filter.operands("dm")[0];
|
||||
const emails = filter.operands("dm")[0]!;
|
||||
const user_ids = people.emails_strings_to_user_ids_string(emails);
|
||||
|
||||
if (user_ids !== undefined) {
|
||||
|
@ -60,7 +60,7 @@ export function compute_narrow_title(filter?: Filter): string {
|
|||
}
|
||||
|
||||
if (filter.has_operator("sender")) {
|
||||
const user = people.get_by_email(filter.operands("sender")[0]);
|
||||
const user = people.get_by_email(filter.operands("sender")[0]!);
|
||||
if (user) {
|
||||
if (people.is_my_user_id(user.user_id)) {
|
||||
return $t({defaultMessage: "Messages sent by you"});
|
||||
|
|
|
@ -737,7 +737,7 @@ export function slug_to_emails(slug: string): string | undefined {
|
|||
*/
|
||||
const m = /^([\d,]+)(-.*)?/.exec(slug);
|
||||
if (m) {
|
||||
let user_ids_string = m[1];
|
||||
let user_ids_string = m[1]!;
|
||||
user_ids_string = exclude_me_from_string(user_ids_string);
|
||||
return user_ids_string_to_emails_string(user_ids_string);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ function register_click_handlers(): void {
|
|||
}
|
||||
const popover_target = $view_in_playground_button.find(
|
||||
".playground-links-popover-container",
|
||||
)[0];
|
||||
)[0]!;
|
||||
toggle_playground_links_popover(popover_target, playground_store);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -46,7 +46,7 @@ export function poll_options_setup(): void {
|
|||
|
||||
// setTimeout is needed to here to give time for simplebar to initialise
|
||||
setTimeout(() => {
|
||||
SortableJS.create($("#add-poll-form .poll-options-list .simplebar-content")[0], {
|
||||
SortableJS.create($("#add-poll-form .poll-options-list .simplebar-content")[0]!, {
|
||||
onUpdate() {
|
||||
// Do nothing on drag; the order is only processed on submission.
|
||||
},
|
||||
|
|
|
@ -192,7 +192,7 @@ export const default_popover_props: Partial<tippy.Props> = {
|
|||
// $tippy_box[0].hasAttribute("data-reference-hidden"); is the real check
|
||||
// but linter wants us to write it like this.
|
||||
const is_reference_outside_window = Object.hasOwn(
|
||||
$tippy_box[0].dataset,
|
||||
$tippy_box[0]!.dataset,
|
||||
"referenceHidden",
|
||||
);
|
||||
if (is_reference_outside_window) {
|
||||
|
@ -215,7 +215,7 @@ export const default_popover_props: Partial<tippy.Props> = {
|
|||
return;
|
||||
}
|
||||
|
||||
const reference_rect = $reference[0].getBoundingClientRect();
|
||||
const reference_rect = $reference[0]!.getBoundingClientRect();
|
||||
// This is the logic we want but since it is too expensive to run
|
||||
// on every scroll, we run a cheaper version of this to just check if
|
||||
// compose, sticky header or navbar are not obscuring the reference
|
||||
|
|
|
@ -8,7 +8,7 @@ function get_new_rand(old_random_int: number, max: number): number {
|
|||
|
||||
function get_random_item_from_array<T>(array: T[]): T {
|
||||
assert(array.length >= 1);
|
||||
return array[Math.floor(Math.random() * array.length)];
|
||||
return array[Math.floor(Math.random() * array.length)]!;
|
||||
}
|
||||
|
||||
const current_client_logo_class_names = new Set([
|
||||
|
@ -40,7 +40,7 @@ function update_client_logo(): void {
|
|||
current_client_logo_class_names_index,
|
||||
client_logos.length,
|
||||
);
|
||||
const client_logo_elt = client_logos[current_client_logo_class_names_index];
|
||||
const client_logo_elt = client_logos[current_client_logo_class_names_index]!;
|
||||
|
||||
const current_logo_class = client_logo_elt.className;
|
||||
current_client_logo_class_names.delete(current_logo_class);
|
||||
|
|
|
@ -58,7 +58,7 @@ export function activate_correct_tab($tabbed_section: JQuery): void {
|
|||
const $active_list_items = $li.filter(".active");
|
||||
if (!$active_list_items.length) {
|
||||
$li.first().addClass("active");
|
||||
const tab_key = $li.first()[0].dataset.tabKey;
|
||||
const tab_key = $li.first()[0]!.dataset.tabKey;
|
||||
if (tab_key) {
|
||||
$blocks.filter("[data-tab-key=" + tab_key + "]").addClass("active");
|
||||
} else {
|
||||
|
|
|
@ -89,7 +89,7 @@ export function show_user_list(message_id: number): void {
|
|||
$("#read_receipts_modal .read_receipts_list").html(
|
||||
render_read_receipts(context),
|
||||
);
|
||||
new SimpleBar($("#read_receipts_modal .modal__content")[0]);
|
||||
new SimpleBar($("#read_receipts_modal .modal__content")[0]!);
|
||||
}
|
||||
},
|
||||
error(xhr) {
|
||||
|
|
|
@ -340,7 +340,7 @@ function set_table_focus(row: number, col: number, using_keyboard = false): bool
|
|||
if (using_keyboard) {
|
||||
const scroll_element = $(
|
||||
"#recent_view_table .table_fix_head .simplebar-content-wrapper",
|
||||
)[0];
|
||||
)[0]!;
|
||||
const half_height_of_visible_area = scroll_element.offsetHeight / 2;
|
||||
const topic_offset = topic_offset_to_visible_area($topic_row);
|
||||
|
||||
|
@ -1093,14 +1093,14 @@ function topic_offset_to_visible_area($topic_row: JQuery): string | undefined {
|
|||
}
|
||||
const $scroll_container = $("#recent_view_table .table_fix_head");
|
||||
const thead_height = $scroll_container.find("thead").outerHeight(true)!;
|
||||
const scroll_container_props = $scroll_container[0].getBoundingClientRect();
|
||||
const scroll_container_props = $scroll_container[0]!.getBoundingClientRect();
|
||||
|
||||
// Since user cannot see row under thead, exclude it as part of the scroll container.
|
||||
const scroll_container_top = scroll_container_props.top + thead_height;
|
||||
const compose_height = $("#compose").outerHeight(true)!;
|
||||
const scroll_container_bottom = scroll_container_props.bottom - compose_height;
|
||||
|
||||
const topic_props = $topic_row[0].getBoundingClientRect();
|
||||
const topic_props = $topic_row[0]!.getBoundingClientRect();
|
||||
|
||||
// Topic is above the visible scroll region.
|
||||
if (topic_props.top < scroll_container_top) {
|
||||
|
@ -1119,7 +1119,7 @@ function recenter_focus_if_off_screen(): void {
|
|||
return;
|
||||
}
|
||||
|
||||
const table_wrapper_element = $("#recent_view_table .table_fix_head")[0];
|
||||
const table_wrapper_element = $("#recent_view_table .table_fix_head")[0]!;
|
||||
const $topic_rows = $("#recent_view_table table tbody tr");
|
||||
|
||||
if (row_focus >= $topic_rows.length) {
|
||||
|
|
|
@ -312,7 +312,7 @@ export const update_elements = ($content: JQuery): void => {
|
|||
$view_in_playground_button.attr("aria-label", title);
|
||||
}
|
||||
const $copy_button = $buttonContainer.find(".copy_codeblock");
|
||||
const clipboard = new ClipboardJS($copy_button[0], {
|
||||
const clipboard = new ClipboardJS($copy_button[0]!, {
|
||||
text(copy_element) {
|
||||
const $code = $(copy_element).parent().siblings("code");
|
||||
return $code.text();
|
||||
|
@ -320,7 +320,7 @@ export const update_elements = ($content: JQuery): void => {
|
|||
});
|
||||
|
||||
clipboard.on("success", () => {
|
||||
show_copied_confirmation($copy_button[0]);
|
||||
show_copied_confirmation($copy_button[0]!);
|
||||
});
|
||||
$codehilite.addClass("zulip-code-block");
|
||||
});
|
||||
|
|
|
@ -5,7 +5,7 @@ import SimpleBar from "simplebar";
|
|||
type JQueryOrZJQuery = {__zjquery?: true} & JQuery;
|
||||
|
||||
export function get_content_element($element: JQuery): JQuery {
|
||||
const element = $element.expectOne()[0];
|
||||
const element = $element.expectOne()[0]!;
|
||||
const sb = SimpleBar.instances.get(element);
|
||||
if (sb) {
|
||||
return $(sb.getContentElement()!);
|
||||
|
@ -19,7 +19,7 @@ export function get_scroll_element($element: JQueryOrZJQuery): JQuery {
|
|||
return $element;
|
||||
}
|
||||
|
||||
const element = $element.expectOne()[0];
|
||||
const element = $element.expectOne()[0]!;
|
||||
const sb = SimpleBar.instances.get(element);
|
||||
if (sb) {
|
||||
return $(sb.getScrollElement()!);
|
||||
|
@ -32,7 +32,7 @@ export function get_scroll_element($element: JQueryOrZJQuery): JQuery {
|
|||
}
|
||||
|
||||
export function reset_scrollbar($element: JQuery): void {
|
||||
const element = $element.expectOne()[0];
|
||||
const element = $element.expectOne()[0]!;
|
||||
const sb = SimpleBar.instances.get(element);
|
||||
if (sb) {
|
||||
sb.getScrollElement()!.scrollTop = 0;
|
||||
|
|
|
@ -187,7 +187,7 @@ export function extract_property_name($elem: JQuery, for_realm_default_settings?
|
|||
// "realm_{settings_name}}" because both user and realm default
|
||||
// settings use the same template and each element should have
|
||||
// unique id.
|
||||
return /^realm_(.*)$/.exec(elem_id.replaceAll("-", "_"))![1];
|
||||
return /^realm_(.*)$/.exec(elem_id.replaceAll("-", "_"))![1]!;
|
||||
}
|
||||
|
||||
if (elem_id.startsWith("id_authmethod")) {
|
||||
|
@ -197,14 +197,14 @@ export function extract_property_name($elem: JQuery, for_realm_default_settings?
|
|||
// The [\da-z]+ part of the regexp covers the auth method name itself.
|
||||
// We assume it's not an empty string and can contain only digits and lowercase ASCII letters,
|
||||
// this is ensured by a respective allowlist-based filter in populate_auth_methods().
|
||||
return /^id_authmethod[\da-z]+_(.*)$/.exec(elem_id)![1];
|
||||
return /^id_authmethod[\da-z]+_(.*)$/.exec(elem_id)![1]!;
|
||||
}
|
||||
|
||||
if (elem_id.startsWith("id-custom-profile-field")) {
|
||||
return /^id_custom_profile_field_(.*)$/.exec(elem_id.replaceAll("-", "_"))![1];
|
||||
return /^id_custom_profile_field_(.*)$/.exec(elem_id.replaceAll("-", "_"))![1]!;
|
||||
}
|
||||
|
||||
return /^id_(.*)$/.exec(elem_id.replaceAll("-", "_"))![1];
|
||||
return /^id_(.*)$/.exec(elem_id.replaceAll("-", "_"))![1]!;
|
||||
}
|
||||
|
||||
export function get_subsection_property_elements($subsection: JQuery): HTMLElement[] {
|
||||
|
@ -397,7 +397,7 @@ function read_select_field_data_from_form(
|
|||
}
|
||||
}
|
||||
$profile_field_form.find("div.choice-row").each(function (this: HTMLElement) {
|
||||
const text = $(this).find("input")[0].value;
|
||||
const text = $(this).find("input")[0]!.value;
|
||||
if (text) {
|
||||
let value = old_option_value_map.get(text);
|
||||
if (value !== undefined) {
|
||||
|
@ -753,7 +753,7 @@ export function get_auth_method_list_data(): Record<string, boolean> {
|
|||
for (const method_row of $auth_method_rows) {
|
||||
const method = $(method_row).attr("data-method");
|
||||
assert(method !== undefined);
|
||||
new_auth_methods[method] = $(method_row).find<HTMLInputElement>("input")[0].checked;
|
||||
new_auth_methods[method] = $(method_row).find<HTMLInputElement>("input")[0]!.checked;
|
||||
}
|
||||
|
||||
return new_auth_methods;
|
||||
|
@ -957,11 +957,11 @@ export function populate_data_for_request(
|
|||
$input_elem.attr("id")!,
|
||||
);
|
||||
assert(match_array !== null);
|
||||
property_name = match_array[1];
|
||||
property_name = match_array[1]!;
|
||||
} else {
|
||||
const match_array = /^id_realm_(.*)$/.exec($input_elem.attr("id")!);
|
||||
assert(match_array !== null);
|
||||
property_name = match_array[1];
|
||||
property_name = match_array[1]!;
|
||||
}
|
||||
|
||||
if (property_name === "stream_privacy") {
|
||||
|
@ -1146,7 +1146,7 @@ function enable_or_disable_save_button($subsection_elem: JQuery): void {
|
|||
const $button_wrapper = $subsection_elem.find<tippy.PopperElement>(
|
||||
".subsection-changes-save",
|
||||
);
|
||||
const tippy_instance = $button_wrapper[0]._tippy;
|
||||
const tippy_instance = $button_wrapper[0]!._tippy;
|
||||
if (disable_save_btn) {
|
||||
// avoid duplication of tippy
|
||||
if (!tippy_instance) {
|
||||
|
@ -1184,5 +1184,5 @@ export function initialize_disable_btn_hint_popover(
|
|||
if (hint_text !== undefined) {
|
||||
tippy_opts.content = hint_text;
|
||||
}
|
||||
tippy.default($btn_wrapper[0], tippy_opts);
|
||||
tippy.default($btn_wrapper[0]!, tippy_opts);
|
||||
}
|
||||
|
|
|
@ -265,7 +265,7 @@ function show_modal(): void {
|
|||
}
|
||||
|
||||
const formData = new FormData();
|
||||
const files = $<HTMLInputElement>("input#emoji_file_input")[0].files;
|
||||
const files = $<HTMLInputElement>("input#emoji_file_input")[0]!.files;
|
||||
assert(files !== null);
|
||||
for (const [i, file] of [...files].entries()) {
|
||||
formData.append("file-" + i, file);
|
||||
|
|
|
@ -194,7 +194,7 @@ export function populate_linkifiers(linkifiers_data: RealmLinkifiers): void {
|
|||
});
|
||||
|
||||
if (current_user.is_admin) {
|
||||
new SortableJS($linkifiers_table[0], {
|
||||
new SortableJS($linkifiers_table[0]!, {
|
||||
onUpdate: update_linkifiers_order,
|
||||
handle: ".move-handle",
|
||||
filter: "input",
|
||||
|
|
|
@ -421,7 +421,7 @@ function set_up_select_field_edit_form(
|
|||
|
||||
// Add blank choice at last
|
||||
create_choice_row($choice_list);
|
||||
SortableJS.create($choice_list[0], {
|
||||
SortableJS.create($choice_list[0]!, {
|
||||
onUpdate() {
|
||||
// Do nothing on drag. We process the order on submission
|
||||
},
|
||||
|
@ -706,7 +706,7 @@ export function do_populate_profile_fields(profile_fields_data: CustomProfileFie
|
|||
display_in_profile_summary_fields_limit_reached = display_in_profile_summary_fields_count >= 2;
|
||||
|
||||
if (current_user.is_admin) {
|
||||
const field_list = $("#admin_profile_fields_table")[0];
|
||||
const field_list = $("#admin_profile_fields_table")[0]!;
|
||||
SortableJS.create(field_list, {
|
||||
onUpdate: update_field_order,
|
||||
filter: "input",
|
||||
|
@ -724,7 +724,7 @@ function set_up_select_field(): void {
|
|||
create_choice_row($("#profile_field_choices"));
|
||||
|
||||
if (current_user.is_admin) {
|
||||
const choice_list = $("#profile_field_choices")[0];
|
||||
const choice_list = $("#profile_field_choices")[0]!;
|
||||
SortableJS.create(choice_list, {
|
||||
onUpdate() {
|
||||
// Do nothing on drag. We process the order on submission
|
||||
|
|
|
@ -114,7 +114,7 @@ export function setup_realm_domains_modal_handlers(): void {
|
|||
const domain = $widget.find(".new-realm-domain").val();
|
||||
const allow_subdomains = $widget.find<HTMLInputElement>(
|
||||
"input.new-realm-domain-allow-subdomains",
|
||||
)[0].checked;
|
||||
)[0]!.checked;
|
||||
const data = {
|
||||
domain,
|
||||
allow_subdomains: JSON.stringify(allow_subdomains),
|
||||
|
|
|
@ -25,7 +25,7 @@ $(() => {
|
|||
}
|
||||
|
||||
$.fn.get_offset_to_window = function () {
|
||||
return this[0].getBoundingClientRect();
|
||||
return this[0]!.getBoundingClientRect();
|
||||
};
|
||||
|
||||
$.fn.expectOne = function () {
|
||||
|
|
|
@ -21,7 +21,7 @@ function expand_spoiler($spoiler: JQuery): void {
|
|||
// of the content). CSS animations do not work with properties set to
|
||||
// `auto`, so we get the actual height of the content here and temporarily
|
||||
// put it explicitly on the element styling to allow the transition to work.
|
||||
const spoiler_height = $spoiler[0].scrollHeight;
|
||||
const spoiler_height = $spoiler[0]!.scrollHeight;
|
||||
$spoiler.height(`${spoiler_height}px`);
|
||||
// The `spoiler-content-open` class has CSS animations defined on it which
|
||||
// will trigger on the frame after this class change.
|
||||
|
|
|
@ -419,7 +419,7 @@ function populate_messages_sent_over_time(raw_data: unknown): void {
|
|||
.on("plotly_hover", (data) => {
|
||||
$("#hoverinfo").show();
|
||||
document.querySelector("#hover_date")!.textContent =
|
||||
data.points[0].data.text[data.points[0].pointNumber];
|
||||
data.points[0]!.data.text[data.points[0]!.pointNumber]!;
|
||||
const values: Plotly.Datum[] = [null, null, null];
|
||||
for (const trace of data.points) {
|
||||
values[trace.curveNumber] = trace.y;
|
||||
|
@ -432,16 +432,16 @@ function populate_messages_sent_over_time(raw_data: unknown): void {
|
|||
];
|
||||
for (const [i, value] of values.entries()) {
|
||||
if (value !== null) {
|
||||
document.querySelector<HTMLElement>(hover_text_ids[i])!.style.display =
|
||||
document.querySelector<HTMLElement>(hover_text_ids[i]!)!.style.display =
|
||||
"inline";
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i])!.style.display =
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i]!)!.style.display =
|
||||
"inline";
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i])!.textContent =
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i]!)!.textContent =
|
||||
value.toString();
|
||||
} else {
|
||||
document.querySelector<HTMLElement>(hover_text_ids[i])!.style.display =
|
||||
document.querySelector<HTMLElement>(hover_text_ids[i]!)!.style.display =
|
||||
"none";
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i])!.style.display =
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i]!)!.style.display =
|
||||
"none";
|
||||
}
|
||||
}
|
||||
|
@ -461,13 +461,13 @@ function populate_messages_sent_over_time(raw_data: unknown): void {
|
|||
let start;
|
||||
let is_boundary;
|
||||
if (aggregation === "day") {
|
||||
start = floor_to_local_day(start_dates[0]);
|
||||
start = floor_to_local_day(start_dates[0]!);
|
||||
is_boundary = function (date: Date) {
|
||||
return date.getHours() === 0;
|
||||
};
|
||||
} else {
|
||||
assert(aggregation === "week");
|
||||
start = floor_to_local_week(start_dates[0]);
|
||||
start = floor_to_local_week(start_dates[0]!);
|
||||
is_boundary = function (date: Date) {
|
||||
return date.getHours() === 0 && date.getDay() === 0;
|
||||
};
|
||||
|
@ -476,25 +476,25 @@ function populate_messages_sent_over_time(raw_data: unknown): void {
|
|||
const values: DataByUserType<number[]> = {human: [], bot: [], me: []};
|
||||
let current: DataByUserType<number> = {human: 0, bot: 0, me: 0};
|
||||
let i_init = 0;
|
||||
if (is_boundary(start_dates[0])) {
|
||||
if (is_boundary(start_dates[0]!)) {
|
||||
current = {
|
||||
human: data.everyone.human[0],
|
||||
bot: data.everyone.bot[0],
|
||||
me: data.user.human[0],
|
||||
human: data.everyone.human[0]!,
|
||||
bot: data.everyone.bot[0]!,
|
||||
me: data.user.human[0]!,
|
||||
};
|
||||
i_init = 1;
|
||||
}
|
||||
for (let i = i_init; i < start_dates.length; i += 1) {
|
||||
if (is_boundary(start_dates[i])) {
|
||||
dates.push(start_dates[i]);
|
||||
if (is_boundary(start_dates[i]!)) {
|
||||
dates.push(start_dates[i]!);
|
||||
values.human.push(current.human);
|
||||
values.bot.push(current.bot);
|
||||
values.me.push(current.me);
|
||||
current = {human: 0, bot: 0, me: 0};
|
||||
}
|
||||
current.human += data.everyone.human[i];
|
||||
current.bot += data.everyone.bot[i];
|
||||
current.me += data.user.human[i];
|
||||
current.human += data.everyone.human[i]!;
|
||||
current.bot += data.everyone.bot[i]!;
|
||||
current.me += data.user.human[i]!;
|
||||
}
|
||||
values.human.push(current.human);
|
||||
values.bot.push(current.bot);
|
||||
|
@ -563,9 +563,9 @@ function populate_messages_sent_over_time(raw_data: unknown): void {
|
|||
const plotDiv = document.querySelector<Plotly.PlotlyHTMLElement>(
|
||||
"#id_messages_sent_over_time",
|
||||
)!;
|
||||
assert("visible" in plotDiv.data[0]);
|
||||
assert("visible" in plotDiv.data[1]);
|
||||
assert("visible" in plotDiv.data[2]);
|
||||
assert("visible" in plotDiv.data[0]!);
|
||||
assert("visible" in plotDiv.data[1]!);
|
||||
assert("visible" in plotDiv.data[2]!);
|
||||
traces.me.visible = plotDiv.data[0].visible;
|
||||
traces.human.visible = plotDiv.data[1].visible;
|
||||
traces.bot.visible = plotDiv.data[2].visible;
|
||||
|
@ -730,8 +730,8 @@ function populate_messages_sent_by_client(raw_data: unknown): void {
|
|||
const label_values: {label: string; value: number}[] = [];
|
||||
for (let i = 0; i < everyone_month.values.length; i += 1) {
|
||||
label_values.push({
|
||||
label: everyone_month.labels[i],
|
||||
value: everyone_month.labels[i] === "Other" ? -1 : everyone_month.values[i],
|
||||
label: everyone_month.labels[i]!,
|
||||
value: everyone_month.labels[i] === "Other" ? -1 : everyone_month.values[i]!,
|
||||
});
|
||||
}
|
||||
label_values.sort((a, b) => b.value - a.value);
|
||||
|
@ -754,9 +754,9 @@ function populate_messages_sent_by_client(raw_data: unknown): void {
|
|||
text: [],
|
||||
};
|
||||
for (let i = 0; i < plot_data.values.length; i += 1) {
|
||||
if (plot_data.values[i] > 0) {
|
||||
annotations.values.push(plot_data.values[i]);
|
||||
annotations.labels.push(plot_data.labels[i]);
|
||||
if (plot_data.values[i]! > 0) {
|
||||
annotations.values.push(plot_data.values[i]!);
|
||||
annotations.labels.push(plot_data.labels[i]!);
|
||||
annotations.text.push(
|
||||
" " + plot_data.labels[i] + " (" + plot_data.percentages[i] + ")",
|
||||
);
|
||||
|
@ -1044,7 +1044,7 @@ function populate_number_of_users(raw_data: unknown): void {
|
|||
.on("plotly_hover", (data) => {
|
||||
$("#users_hover_info").show();
|
||||
document.querySelector("#users_hover_date")!.textContent =
|
||||
data.points[0].data.text[data.points[0].pointNumber];
|
||||
data.points[0]!.data.text[data.points[0]!.pointNumber]!;
|
||||
const values: Plotly.Datum[] = [null, null, null];
|
||||
for (const trace of data.points) {
|
||||
values[trace.curveNumber] = trace.y;
|
||||
|
@ -1056,11 +1056,11 @@ function populate_number_of_users(raw_data: unknown): void {
|
|||
];
|
||||
for (const [i, value] of values.entries()) {
|
||||
if (value !== null) {
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i])!.style.display =
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i]!)!.style.display =
|
||||
"inline";
|
||||
document.querySelector(hover_value_ids[i])!.textContent = value.toString();
|
||||
document.querySelector(hover_value_ids[i]!)!.textContent = value.toString();
|
||||
} else {
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i])!.style.display =
|
||||
document.querySelector<HTMLElement>(hover_value_ids[i]!)!.style.display =
|
||||
"none";
|
||||
}
|
||||
}
|
||||
|
@ -1185,7 +1185,7 @@ function populate_messages_read_over_time(raw_data: unknown): void {
|
|||
.on("plotly_hover", (data) => {
|
||||
$("#read_hover_info").show();
|
||||
document.querySelector("#read_hover_date")!.textContent =
|
||||
data.points[0].data.text[data.points[0].pointNumber];
|
||||
data.points[0]!.data.text[data.points[0]!.pointNumber]!;
|
||||
const values: Plotly.Datum[] = [null, null];
|
||||
for (const trace of data.points) {
|
||||
values[trace.curveNumber] = trace.y;
|
||||
|
@ -1194,18 +1194,20 @@ function populate_messages_read_over_time(raw_data: unknown): void {
|
|||
const read_hover_value_ids = ["#read_hover_me_value", "#read_hover_everyone_value"];
|
||||
for (const [i, value] of values.entries()) {
|
||||
if (value !== null) {
|
||||
document.querySelector<HTMLElement>(read_hover_text_ids[i])!.style.display =
|
||||
"inline";
|
||||
document.querySelector<HTMLElement>(
|
||||
read_hover_value_ids[i],
|
||||
read_hover_text_ids[i]!,
|
||||
)!.style.display = "inline";
|
||||
document.querySelector<HTMLElement>(read_hover_value_ids[i])!.textContent =
|
||||
document.querySelector<HTMLElement>(
|
||||
read_hover_value_ids[i]!,
|
||||
)!.style.display = "inline";
|
||||
document.querySelector<HTMLElement>(read_hover_value_ids[i]!)!.textContent =
|
||||
value.toString();
|
||||
} else {
|
||||
document.querySelector<HTMLElement>(read_hover_text_ids[i])!.style.display =
|
||||
"none";
|
||||
document.querySelector<HTMLElement>(
|
||||
read_hover_value_ids[i],
|
||||
read_hover_text_ids[i]!,
|
||||
)!.style.display = "none";
|
||||
document.querySelector<HTMLElement>(
|
||||
read_hover_value_ids[i]!,
|
||||
)!.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
@ -1225,13 +1227,13 @@ function populate_messages_read_over_time(raw_data: unknown): void {
|
|||
let start;
|
||||
let is_boundary;
|
||||
if (aggregation === "day") {
|
||||
start = floor_to_local_day(start_dates[0]);
|
||||
start = floor_to_local_day(start_dates[0]!);
|
||||
is_boundary = function (date: Date) {
|
||||
return date.getHours() === 0;
|
||||
};
|
||||
} else {
|
||||
assert(aggregation === "week");
|
||||
start = floor_to_local_week(start_dates[0]);
|
||||
start = floor_to_local_week(start_dates[0]!);
|
||||
is_boundary = function (date: Date) {
|
||||
return date.getHours() === 0 && date.getDay() === 0;
|
||||
};
|
||||
|
@ -1240,19 +1242,19 @@ function populate_messages_read_over_time(raw_data: unknown): void {
|
|||
const values: DataByEveryoneMe<number[]> = {everyone: [], me: []};
|
||||
let current: DataByEveryoneMe<number> = {everyone: 0, me: 0};
|
||||
let i_init = 0;
|
||||
if (is_boundary(start_dates[0])) {
|
||||
current = {everyone: data.everyone.read[0], me: data.user.read[0]};
|
||||
if (is_boundary(start_dates[0]!)) {
|
||||
current = {everyone: data.everyone.read[0]!, me: data.user.read[0]!};
|
||||
i_init = 1;
|
||||
}
|
||||
for (let i = i_init; i < start_dates.length; i += 1) {
|
||||
if (is_boundary(start_dates[i])) {
|
||||
dates.push(start_dates[i]);
|
||||
if (is_boundary(start_dates[i]!)) {
|
||||
dates.push(start_dates[i]!);
|
||||
values.everyone.push(current.everyone);
|
||||
values.me.push(current.me);
|
||||
current = {everyone: 0, me: 0};
|
||||
}
|
||||
current.everyone += data.everyone.read[i];
|
||||
current.me += data.user.read[i];
|
||||
current.everyone += data.everyone.read[i]!;
|
||||
current.me += data.user.read[i]!;
|
||||
}
|
||||
values.everyone.push(current.everyone);
|
||||
values.me.push(current.me);
|
||||
|
@ -1315,8 +1317,8 @@ function populate_messages_read_over_time(raw_data: unknown): void {
|
|||
const plotDiv = document.querySelector<Plotly.PlotlyHTMLElement>(
|
||||
"#id_messages_read_over_time",
|
||||
)!;
|
||||
assert("visible" in plotDiv.data[0]);
|
||||
assert("visible" in plotDiv.data[1]);
|
||||
assert("visible" in plotDiv.data[0]!);
|
||||
assert("visible" in plotDiv.data[1]!);
|
||||
traces.me.visible = plotDiv.data[0].visible;
|
||||
traces.everyone.visible = plotDiv.data[1].visible;
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ export function slug_to_name(slug: string): string {
|
|||
*/
|
||||
const m = /^(\d+)(-.*)?$/.exec(slug);
|
||||
if (m) {
|
||||
const stream_id = Number.parseInt(m[1], 10);
|
||||
const stream_id = Number.parseInt(m[1]!, 10);
|
||||
const sub = sub_store.get(stream_id);
|
||||
if (sub) {
|
||||
return sub.name;
|
||||
|
|
|
@ -285,7 +285,7 @@ export function initialize(): void {
|
|||
const second_line = $t({defaultMessage: "File name: {filename}"}, {filename});
|
||||
$markup.append($("<br>"), $("<span>").text(second_line));
|
||||
}
|
||||
instance.setContent($markup[0]);
|
||||
instance.setContent($markup[0]!);
|
||||
return undefined;
|
||||
},
|
||||
onHidden(instance) {
|
||||
|
|
|
@ -19,19 +19,19 @@ export function next_topic(
|
|||
const curr_stream_index = streams.indexOf(curr_stream); // -1 if not found
|
||||
|
||||
if (curr_stream_index >= 0) {
|
||||
const stream = streams[curr_stream_index];
|
||||
const stream = streams[curr_stream_index]!;
|
||||
const topics = get_topics(stream);
|
||||
const curr_topic_index = topics.indexOf(curr_topic); // -1 if not found
|
||||
|
||||
for (let i = curr_topic_index + 1; i < topics.length; i += 1) {
|
||||
const topic = topics[i];
|
||||
const topic = topics[i]!;
|
||||
if (has_unread_messages(stream, topic)) {
|
||||
return {stream, topic};
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < curr_topic_index; i += 1) {
|
||||
const topic = topics[i];
|
||||
const topic = topics[i]!;
|
||||
if (has_unread_messages(stream, topic)) {
|
||||
return {stream, topic};
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ export function next_topic(
|
|||
}
|
||||
|
||||
for (let i = curr_stream_index + 1; i < streams.length; i += 1) {
|
||||
const stream = streams[i];
|
||||
const stream = streams[i]!;
|
||||
for (const topic of get_topics(stream)) {
|
||||
if (has_unread_messages(stream, topic)) {
|
||||
return {stream, topic};
|
||||
|
@ -48,7 +48,7 @@ export function next_topic(
|
|||
}
|
||||
|
||||
for (let i = 0; i < curr_stream_index; i += 1) {
|
||||
const stream = streams[i];
|
||||
const stream = streams[i]!;
|
||||
for (const topic of get_topics(stream)) {
|
||||
if (has_unread_messages(stream, topic)) {
|
||||
return {stream, topic};
|
||||
|
@ -150,13 +150,13 @@ export function get_next_unread_pm_string(curr_pm: string): string | undefined {
|
|||
const curr_pm_index = my_pm_strings.indexOf(curr_pm); // -1 if not found
|
||||
|
||||
for (let i = curr_pm_index + 1; i < my_pm_strings.length; i += 1) {
|
||||
if (unread.num_unread_for_user_ids_string(my_pm_strings[i]) > 0) {
|
||||
if (unread.num_unread_for_user_ids_string(my_pm_strings[i]!) > 0) {
|
||||
return my_pm_strings[i];
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < curr_pm_index; i += 1) {
|
||||
if (unread.num_unread_for_user_ids_string(my_pm_strings[i]) > 0) {
|
||||
if (unread.num_unread_for_user_ids_string(my_pm_strings[i]!) > 0) {
|
||||
return my_pm_strings[i];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ export function highlight_with_escaping_and_regex(regex: RegExp, item: string):
|
|||
let result = "";
|
||||
|
||||
for (const [i, piece] of pieces.entries()) {
|
||||
if (regex.test(piece) && (i === 0 || pieces[i - 1].endsWith(" "))) {
|
||||
if (regex.test(piece) && (i === 0 || pieces[i - 1]!.endsWith(" "))) {
|
||||
// only highlight if the matching part is a word prefix, ie
|
||||
// if it is the 1st piece or if there was a space before it
|
||||
result += "<strong>" + Handlebars.Utils.escapeExpression(piece) + "</strong>";
|
||||
|
|
|
@ -72,7 +72,7 @@ export function build_widget(
|
|||
if (files === null || files === undefined || files.length === 0) {
|
||||
return false;
|
||||
}
|
||||
get_file_input()[0].files = files;
|
||||
get_file_input()[0]!.files = files;
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
@ -160,7 +160,7 @@ export function build_direct_upload_widget(
|
|||
if (files === null || files === undefined || files.length === 0) {
|
||||
return false;
|
||||
}
|
||||
get_file_input()[0].files = files;
|
||||
get_file_input()[0]!.files = files;
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
|
|
@ -35,7 +35,7 @@ export function lower_bound<T1, T2>(
|
|||
while (len > 0) {
|
||||
step = Math.floor(len / 2);
|
||||
middle = first + step;
|
||||
if (less(array[middle], value, middle)) {
|
||||
if (less(array[middle]!, value, middle)) {
|
||||
first = middle;
|
||||
first += 1;
|
||||
len = len - step - 1;
|
||||
|
@ -204,7 +204,7 @@ export function find_stream_wildcard_mentions(message_content: string): string |
|
|||
if (mention === null) {
|
||||
return null;
|
||||
}
|
||||
return mention[2];
|
||||
return mention[2]!;
|
||||
}
|
||||
|
||||
export const move_array_elements_to_front = function util_move_array_elements_to_front<T>(
|
||||
|
|
|
@ -38,7 +38,7 @@ export function eq_array<T>(
|
|||
return false;
|
||||
}
|
||||
|
||||
return a.every((item, i) => eq(item, b[i]));
|
||||
return a.every((item, i) => eq(item, b[i]!));
|
||||
}
|
||||
|
||||
export function ul<T>(opts: Options<T>): Tag<T> {
|
||||
|
@ -198,7 +198,7 @@ export function update<T>(
|
|||
const $child_elems = find().children();
|
||||
|
||||
for (const [i, new_node] of new_opts.keyed_nodes.entries()) {
|
||||
const old_node = old_opts.keyed_nodes[i];
|
||||
const old_node = old_opts.keyed_nodes[i]!;
|
||||
if (new_node.eq(old_node)) {
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue