From fc3ab45b46bd4ad94a5a8aa2bd8072ff2e7dec9e Mon Sep 17 00:00:00 2001 From: evykassirer Date: Fri, 29 Mar 2024 17:35:01 -0700 Subject: [PATCH] typeahead: Pass input element to source instead of using hacky this. --- web/src/bootstrap_typeahead.ts | 6 ++--- web/src/composebox_typeahead.js | 15 +++++------ web/tests/composebox_typeahead.test.js | 36 +++++++------------------- 3 files changed, 20 insertions(+), 37 deletions(-) diff --git a/web/src/bootstrap_typeahead.ts b/web/src/bootstrap_typeahead.ts index 110aec0154..04e68eaad1 100644 --- a/web/src/bootstrap_typeahead.ts +++ b/web/src/bootstrap_typeahead.ts @@ -203,7 +203,7 @@ class Typeahead { $container: JQuery; $menu: JQuery; $header: JQuery; - source: (query: string) => ItemType[]; + source: (query: string, input_element: InputElement) => ItemType[]; dropup: boolean; fixed: boolean; automated: () => boolean; @@ -377,7 +377,7 @@ class Typeahead { return this.shown ? this.hide() : this; } - const items = this.source(this.query); + const items = this.source(this.query, this.input_element); if (!items && this.shown) { this.hide(); @@ -694,7 +694,7 @@ class Typeahead { type TypeaheadOptions = { highlighter_html: (item: ItemType, query: string) => string | undefined; items: number; - source: (query: string) => ItemType[]; + source: (query: string, input_element: InputElement) => ItemType[]; // optional options advanceKeyCodes?: number[]; automated?: () => boolean; diff --git a/web/src/composebox_typeahead.js b/web/src/composebox_typeahead.js index bd9a3200be..a16886b975 100644 --- a/web/src/composebox_typeahead.js +++ b/web/src/composebox_typeahead.js @@ -600,9 +600,9 @@ export function get_person_suggestions(query, opts) { }); } -export function get_stream_topic_data(hacky_this) { +export function get_stream_topic_data(input_element) { const opts = {}; - const $message_row = hacky_this.input_element.$element.closest(".message_row"); + const $message_row = input_element.$element.closest(".message_row"); if ($message_row.length === 1) { // we are editing a message so we try to use its keys. const msg = message_store.get(rows.id($message_row)); @@ -617,7 +617,7 @@ export function get_stream_topic_data(hacky_this) { return opts; } -export function get_sorted_filtered_items(query) { +export function get_sorted_filtered_items(query, input_element) { /* This is just a "glue" function to work around bootstrap. We want to control these @@ -641,14 +641,13 @@ export function get_sorted_filtered_items(query) { several years ago.) */ - const fetcher = get_candidates.bind(this); - const big_results = fetcher(query); + const big_results = get_candidates(query, input_element); if (!big_results) { return false; } - const opts = get_stream_topic_data(this); + const opts = get_stream_topic_data(input_element); if (completing === "mention" || completing === "silent_mention") { return filter_and_sort_mentions(big_results.is_silent, token, opts); @@ -678,8 +677,8 @@ const ALLOWED_MARKDOWN_FEATURES = { timestamp: true, }; -export function get_candidates(query) { - const split = split_at_cursor(query, this.input_element.$element); +export function get_candidates(query, input_element) { + const split = split_at_cursor(query, input_element.$element); let current_token = tokenize_compose_str(split[0]); if (current_token === "") { return false; diff --git a/web/tests/composebox_typeahead.test.js b/web/tests/composebox_typeahead.test.js index 573df57dee..aa3413424a 100644 --- a/web/tests/composebox_typeahead.test.js +++ b/web/tests/composebox_typeahead.test.js @@ -987,19 +987,17 @@ test("initialize", ({override, override_rewire, mock_template}) => { // For now we only test that get_sorted_filtered_items has been // properly set as the .source(). All its features are tested later on // in test_begins_typeahead(). - const fake_this = { - input_element: { - $element: {}, - type: "input", - }, + const input_element = { + $element: {}, + type: "input", }; let caret_called = false; - fake_this.input_element.$element.caret = () => { + input_element.$element.caret = () => { caret_called = true; return 7; }; - fake_this.input_element.$element.closest = () => []; - let actual_value = options.source.call(fake_this, "test #s"); + input_element.$element.closest = () => []; + let actual_value = options.source("test #s", input_element); assert.deepEqual(sorted_names_from(actual_value), ["Sweden", "The Netherlands"]); assert.ok(caret_called); @@ -1330,29 +1328,15 @@ test("begins_typeahead", ({override, override_rewire}) => { }); override(stream_topic_history_util, "get_server_history", noop); - const begin_typehead_this = { - input_element: { - $element: {}, - type: "input", - }, - options: { - completions: { - emoji: true, - mention: true, - silent_mention: true, - slash: true, - stream: true, - syntax: true, - topic: true, - timestamp: true, - }, - }, + const input_element = { + $element: {}, + type: "input", }; function get_values(input, rest) { // Stub out split_at_cursor that uses $(':focus') override_rewire(ct, "split_at_cursor", () => [input, rest]); - const values = ct.get_candidates.call(begin_typehead_this, input); + const values = ct.get_candidates(input, input_element); return values; }