From 9c70f92514fedc0a4759bc793064aeb9886d8575 Mon Sep 17 00:00:00 2001 From: Anders Kaseorg Date: Fri, 6 Oct 2023 00:04:22 -0700 Subject: [PATCH] reload: Move initialize to new reload_setup module. Signed-off-by: Anders Kaseorg --- docs/subsystems/hashchange-system.md | 2 +- tools/test-js-with-node | 1 + web/src/reload.js | 88 --------------------------- web/src/reload_setup.js | 91 ++++++++++++++++++++++++++++ web/src/ui_init.js | 4 +- 5 files changed, 95 insertions(+), 91 deletions(-) create mode 100644 web/src/reload_setup.js diff --git a/docs/subsystems/hashchange-system.md b/docs/subsystems/hashchange-system.md index 56c381e952..cd8137a2d8 100644 --- a/docs/subsystems/hashchange-system.md +++ b/docs/subsystems/hashchange-system.md @@ -109,7 +109,7 @@ Here are some key functions in the reload system: - `reload.preserve_state` is called when a server-initiated browser reload happens, and encodes a bunch of data like the current scroll position into the hash. -- `reload.initialize` handles restoring the preserved state after a +- `reload_setup.initialize` handles restoring the preserved state after a reload where the hash starts with `/#reload`. ## All reloads diff --git a/tools/test-js-with-node b/tools/test-js-with-node index a19763311d..88441bbfa2 100755 --- a/tools/test-js-with-node +++ b/tools/test-js-with-node @@ -165,6 +165,7 @@ EXEMPT_FILES = make_set( "web/src/recent_view_ui.js", "web/src/recent_view_util.js", "web/src/reload.js", + "web/src/reload_setup.js", "web/src/reminder.js", "web/src/resize.js", "web/src/resize_handler.js", diff --git a/web/src/reload.js b/web/src/reload.js index d15310b26c..04e4360e20 100644 --- a/web/src/reload.js +++ b/web/src/reload.js @@ -1,18 +1,13 @@ import $ from "jquery"; -import * as activity from "./activity"; import * as blueslip from "./blueslip"; -import * as compose from "./compose"; -import * as compose_actions from "./compose_actions"; import * as compose_state from "./compose_state"; import {csrf_token} from "./csrf"; import * as drafts from "./drafts"; import * as hash_util from "./hash_util"; -import * as hashchange from "./hashchange"; import {localstorage} from "./localstorage"; import * as message_lists from "./message_lists"; import * as narrow_state from "./narrow_state"; -import {page_params} from "./page_params"; import * as reload_state from "./reload_state"; import * as ui_report from "./ui_report"; import * as util from "./util"; @@ -146,89 +141,6 @@ function delete_stale_tokens(ls) { ); } -// Check if we're doing a compose-preserving reload. This must be -// done before the first call to get_events -export function initialize() { - // location.hash should be e.g. `#reload:12345123412312` - if (!location.hash.startsWith("#reload:")) { - return; - } - const hash_fragment = location.hash.slice("#".length); - - // Using the token, recover the saved pre-reload data from local - // storage. Afterwards, we clear the reload entry from local - // storage to avoid a local storage space leak. - const ls = localstorage(); - let fragment = ls.get(hash_fragment); - if (fragment === undefined) { - // Since this can happen sometimes with hand-reloading, it's - // not really worth throwing an exception if these don't - // exist, but be log it so that it's available for future - // debugging if an exception happens later. - blueslip.info("Invalid hash change reload token"); - hashchange.changehash(""); - return; - } - ls.remove(hash_fragment); - - // TODO/compatibility: `fragment` was changed from a string - // to a map containing the string and a timestamp. For now we'll - // delete all tokens that only contain the url. Remove the - // `|| fragment` once you can no longer directly upgrade - // from Zulip 5.x to the current version. - [, fragment] = /^#reload:(.*)/.exec(fragment.url || fragment); - const keyvals = fragment.split("+"); - const vars = {}; - - for (const str of keyvals) { - const pair = str.split("="); - vars[pair[0]] = decodeURIComponent(pair[1]); - } - - if (vars.msg !== undefined) { - const send_now = Number.parseInt(vars.send_after_reload, 10); - - try { - compose_actions.start(vars.msg_type, { - stream: vars.stream || "", - topic: vars.topic || "", - private_message_recipient: vars.recipient || "", - content: vars.msg || "", - draft_id: vars.draft_id || "", - }); - if (send_now) { - compose.finish(); - } - } catch (error) { - // We log an error if we can't open the compose box, but otherwise - // we continue, since this is not critical. - blueslip.warn(error.toString()); - } - } - - const pointer = Number.parseInt(vars.pointer, 10); - - if (pointer) { - page_params.initial_pointer = pointer; - } - const offset = Number.parseInt(vars.offset, 10); - if (offset) { - page_params.initial_offset = offset; - } - - const narrow_pointer = Number.parseInt(vars.narrow_pointer, 10); - if (narrow_pointer) { - page_params.initial_narrow_pointer = narrow_pointer; - } - const narrow_offset = Number.parseInt(vars.narrow_offset, 10); - if (narrow_offset) { - page_params.initial_narrow_offset = narrow_offset; - } - - activity.set_new_user_input(false); - hashchange.changehash(vars.oldhash); -} - function do_reload_app(send_after_reload, save_pointer, save_narrow, save_compose, message_html) { if (reload_state.is_in_progress()) { blueslip.log("do_reload_app: Doing nothing since reload_in_progress"); diff --git a/web/src/reload_setup.js b/web/src/reload_setup.js new file mode 100644 index 0000000000..103e051837 --- /dev/null +++ b/web/src/reload_setup.js @@ -0,0 +1,91 @@ +import * as activity from "./activity"; +import * as blueslip from "./blueslip"; +import * as compose from "./compose"; +import * as compose_actions from "./compose_actions"; +import * as hashchange from "./hashchange"; +import {localstorage} from "./localstorage"; +import {page_params} from "./page_params"; + +// Check if we're doing a compose-preserving reload. This must be +// done before the first call to get_events + +export function initialize() { + // location.hash should be e.g. `#reload:12345123412312` + if (!location.hash.startsWith("#reload:")) { + return; + } + const hash_fragment = location.hash.slice("#".length); + + // Using the token, recover the saved pre-reload data from local + // storage. Afterwards, we clear the reload entry from local + // storage to avoid a local storage space leak. + const ls = localstorage(); + let fragment = ls.get(hash_fragment); + if (fragment === undefined) { + // Since this can happen sometimes with hand-reloading, it's + // not really worth throwing an exception if these don't + // exist, but be log it so that it's available for future + // debugging if an exception happens later. + blueslip.info("Invalid hash change reload token"); + hashchange.changehash(""); + return; + } + ls.remove(hash_fragment); + + // TODO/compatibility: `fragment` was changed from a string + // to a map containing the string and a timestamp. For now we'll + // delete all tokens that only contain the url. Remove the + // `|| fragment` once you can no longer directly upgrade + // from Zulip 5.x to the current version. + [, fragment] = /^#reload:(.*)/.exec(fragment.url || fragment); + const keyvals = fragment.split("+"); + const vars = {}; + + for (const str of keyvals) { + const pair = str.split("="); + vars[pair[0]] = decodeURIComponent(pair[1]); + } + + if (vars.msg !== undefined) { + const send_now = Number.parseInt(vars.send_after_reload, 10); + + try { + compose_actions.start(vars.msg_type, { + stream: vars.stream || "", + topic: vars.topic || "", + private_message_recipient: vars.recipient || "", + content: vars.msg || "", + draft_id: vars.draft_id || "", + }); + if (send_now) { + compose.finish(); + } + } catch (error) { + // We log an error if we can't open the compose box, but otherwise + // we continue, since this is not critical. + blueslip.warn(error.toString()); + } + } + + const pointer = Number.parseInt(vars.pointer, 10); + + if (pointer) { + page_params.initial_pointer = pointer; + } + const offset = Number.parseInt(vars.offset, 10); + if (offset) { + page_params.initial_offset = offset; + } + + const narrow_pointer = Number.parseInt(vars.narrow_pointer, 10); + if (narrow_pointer) { + page_params.initial_narrow_pointer = narrow_pointer; + } + const narrow_offset = Number.parseInt(vars.narrow_offset, 10); + if (narrow_offset) { + page_params.initial_narrow_offset = narrow_offset; + } + + activity.set_new_user_input(false); + hashchange.changehash(vars.oldhash); +} diff --git a/web/src/ui_init.js b/web/src/ui_init.js index d368900596..0fbc9c3a31 100644 --- a/web/src/ui_init.js +++ b/web/src/ui_init.js @@ -85,7 +85,7 @@ import * as realm_logo from "./realm_logo"; import * as realm_playground from "./realm_playground"; import * as realm_user_settings_defaults from "./realm_user_settings_defaults"; import * as recent_view_ui from "./recent_view_ui"; -import * as reload from "./reload"; +import * as reload_setup from "./reload_setup"; import * as rendered_markdown from "./rendered_markdown"; import * as resize_handler from "./resize_handler"; import * as scheduled_messages from "./scheduled_messages"; @@ -638,7 +638,7 @@ export function initialize_everything() { on_pill_create_or_remove: compose_recipient.update_placeholder_text, }); compose_closed_ui.initialize(); - reload.initialize(); + reload_setup.initialize(); unread.initialize(unread_params); bot_data.initialize(bot_params); // Must happen after people.initialize() message_fetch.initialize(server_events.home_view_loaded);