mirror of https://github.com/zulip/zulip.git
narrow: Cut import of hashchange.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
4adfd57378
commit
564e91f3a8
|
@ -61,6 +61,7 @@ EXEMPT_FILES = make_set(
|
|||
"web/src/billing/upgrade.ts",
|
||||
"web/src/blueslip.ts",
|
||||
"web/src/blueslip_stacktrace.ts",
|
||||
"web/src/browser_history.ts",
|
||||
"web/src/click_handlers.js",
|
||||
"web/src/compose.js",
|
||||
"web/src/compose_actions.js",
|
||||
|
|
|
@ -102,3 +102,54 @@ export function update_hash_internally_if_required(hash: string): void {
|
|||
export function return_to_web_public_hash(): void {
|
||||
window.location.hash = state.spectator_old_hash ?? `#${user_settings.default_view}`;
|
||||
}
|
||||
|
||||
export function get_full_url(hash: string): string {
|
||||
const location = window.location;
|
||||
|
||||
if (hash.charAt(0) !== "#" && hash !== "") {
|
||||
hash = "#" + hash;
|
||||
}
|
||||
|
||||
// IE returns pathname as undefined and missing the leading /
|
||||
let pathname = location.pathname;
|
||||
if (pathname === undefined) {
|
||||
pathname = "/";
|
||||
} else if (pathname === "" || pathname.charAt(0) !== "/") {
|
||||
pathname = "/" + pathname;
|
||||
}
|
||||
|
||||
// Build a full URL to not have same origin problems
|
||||
const url = location.protocol + "//" + location.host + pathname + hash;
|
||||
return url;
|
||||
}
|
||||
|
||||
export function set_hash(hash: string): void {
|
||||
if (hash === window.location.hash) {
|
||||
// Avoid adding duplicate entries in browser history.
|
||||
return;
|
||||
}
|
||||
if (history.pushState) {
|
||||
const url = get_full_url(hash);
|
||||
try {
|
||||
history.pushState(null, "", url);
|
||||
update_web_public_hash(hash);
|
||||
} catch (error) {
|
||||
if (error instanceof TypeError) {
|
||||
// The window has been destroyed and the history object has been marked dead, so cannot
|
||||
// be updated. Silently do nothing, since there's nothing we can do.
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// pushState has 97% global support according to caniuse. So, we will ideally never reach here.
|
||||
// TODO: Delete this case if we don't see any error reports in a while.
|
||||
if (hash === "" || hash === "#") {
|
||||
// Setting empty hash here would scroll to the top.
|
||||
hash = user_settings.default_view;
|
||||
}
|
||||
|
||||
blueslip.error("browser does not support pushState");
|
||||
window.location.hash = hash;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,57 +35,6 @@ import {user_settings} from "./user_settings";
|
|||
// Read https://zulip.readthedocs.io/en/latest/subsystems/hashchange-system.html
|
||||
// or locally: docs/subsystems/hashchange-system.md
|
||||
|
||||
function get_full_url(hash) {
|
||||
const location = window.location;
|
||||
|
||||
if (hash.charAt(0) !== "#" && hash !== "") {
|
||||
hash = "#" + hash;
|
||||
}
|
||||
|
||||
// IE returns pathname as undefined and missing the leading /
|
||||
let pathname = location.pathname;
|
||||
if (pathname === undefined) {
|
||||
pathname = "/";
|
||||
} else if (pathname === "" || pathname.charAt(0) !== "/") {
|
||||
pathname = "/" + pathname;
|
||||
}
|
||||
|
||||
// Build a full URL to not have same origin problems
|
||||
const url = location.protocol + "//" + location.host + pathname + hash;
|
||||
return url;
|
||||
}
|
||||
|
||||
function set_hash(hash) {
|
||||
if (hash === window.location.hash) {
|
||||
// Avoid adding duplicate entries in browser history.
|
||||
return;
|
||||
}
|
||||
if (history.pushState) {
|
||||
const url = get_full_url(hash);
|
||||
try {
|
||||
history.pushState(null, null, url);
|
||||
browser_history.update_web_public_hash(hash);
|
||||
} catch (error) {
|
||||
if (error instanceof TypeError) {
|
||||
// The window has been destroyed and the history object has been marked dead, so cannot
|
||||
// be updated. Silently do nothing, since there's nothing we can do.
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// pushState has 97% global support according to caniuse. So, we will ideally never reach here.
|
||||
// TODO: Delete this case if we don't see any error reports in a while.
|
||||
if (hash === "" || hash === "#") {
|
||||
// Setting empty hash here would scroll to the top.
|
||||
hash = user_settings.default_view;
|
||||
}
|
||||
|
||||
blueslip.error("browser does not support pushState");
|
||||
window.location.hash = hash;
|
||||
}
|
||||
}
|
||||
|
||||
function maybe_hide_recent_view() {
|
||||
if (recent_view_util.is_visible()) {
|
||||
recent_view_ui.hide();
|
||||
|
@ -102,22 +51,6 @@ function maybe_hide_inbox() {
|
|||
return false;
|
||||
}
|
||||
|
||||
export function changehash(newhash) {
|
||||
if (browser_history.state.changing_hash) {
|
||||
return;
|
||||
}
|
||||
message_viewport.stop_auto_scrolling();
|
||||
set_hash(newhash);
|
||||
}
|
||||
|
||||
export function save_narrow(operators) {
|
||||
if (browser_history.state.changing_hash) {
|
||||
return;
|
||||
}
|
||||
const new_hash = hash_util.operators_to_hash(operators);
|
||||
changehash(new_hash);
|
||||
}
|
||||
|
||||
function show_all_message_view() {
|
||||
const coming_from_recent_view = maybe_hide_recent_view();
|
||||
const coming_from_inbox = maybe_hide_inbox();
|
||||
|
@ -140,7 +73,7 @@ export function set_hash_to_default_view() {
|
|||
// hash. So, we use `pushState` which simply updates the current URL
|
||||
// but doesn't trigger `hashchange`. So, we trigger hashchange directly
|
||||
// here to let it handle the whole rendering process for us.
|
||||
set_hash("");
|
||||
browser_history.set_hash("");
|
||||
hashchanged(false);
|
||||
}
|
||||
}
|
||||
|
@ -310,12 +243,12 @@ function do_hashchange_overlay(old_hash) {
|
|||
history.replaceState(
|
||||
null,
|
||||
"",
|
||||
get_full_url(base + "/" + settings_panel_object.current_tab()),
|
||||
browser_history.get_full_url(base + "/" + settings_panel_object.current_tab()),
|
||||
);
|
||||
}
|
||||
|
||||
if (base === "streams" && !section) {
|
||||
history.replaceState(null, "", get_full_url("streams/subscribed"));
|
||||
history.replaceState(null, "", browser_history.get_full_url("streams/subscribed"));
|
||||
}
|
||||
|
||||
// Start by handling the specific case of going
|
||||
|
|
|
@ -14,7 +14,7 @@ import * as compose_state from "./compose_state";
|
|||
import * as condense from "./condense";
|
||||
import {Filter} from "./filter";
|
||||
import * as hash_parser from "./hash_parser";
|
||||
import * as hashchange from "./hashchange";
|
||||
import * as hash_util from "./hash_util";
|
||||
import * as inbox_ui from "./inbox_ui";
|
||||
import * as inbox_util from "./inbox_util";
|
||||
import * as left_sidebar_navigation_area from "./left_sidebar_navigation_area";
|
||||
|
@ -28,6 +28,7 @@ import {MessageListData} from "./message_list_data";
|
|||
import * as message_lists from "./message_lists";
|
||||
import * as message_store from "./message_store";
|
||||
import * as message_view_header from "./message_view_header";
|
||||
import * as message_viewport from "./message_viewport";
|
||||
import * as narrow_banner from "./narrow_banner";
|
||||
import * as narrow_history from "./narrow_history";
|
||||
import * as narrow_state from "./narrow_state";
|
||||
|
@ -90,6 +91,22 @@ export function handle_middle_pane_transition() {
|
|||
}
|
||||
}
|
||||
|
||||
export function changehash(newhash) {
|
||||
if (browser_history.state.changing_hash) {
|
||||
return;
|
||||
}
|
||||
message_viewport.stop_auto_scrolling();
|
||||
browser_history.set_hash(newhash);
|
||||
}
|
||||
|
||||
export function save_narrow(operators) {
|
||||
if (browser_history.state.changing_hash) {
|
||||
return;
|
||||
}
|
||||
const new_hash = hash_util.operators_to_hash(operators);
|
||||
changehash(new_hash);
|
||||
}
|
||||
|
||||
export function activate(raw_operators, opts) {
|
||||
/* Main entry point for switching to a new view / message list.
|
||||
Note that for historical reasons related to the current
|
||||
|
@ -479,7 +496,7 @@ export function activate(raw_operators, opts) {
|
|||
// Disabled when the URL fragment was the source
|
||||
// of this narrow.
|
||||
if (opts.change_hash) {
|
||||
hashchange.save_narrow(operators);
|
||||
save_narrow(operators);
|
||||
}
|
||||
|
||||
handle_post_view_change(msg_list);
|
||||
|
@ -1019,7 +1036,7 @@ export function deactivate(coming_from_all_messages = true, is_actively_scrollin
|
|||
|
||||
reset_ui_state();
|
||||
handle_middle_pane_transition();
|
||||
hashchange.save_narrow();
|
||||
save_narrow();
|
||||
|
||||
if (message_lists.current.selected_id() !== -1) {
|
||||
const preserve_pre_narrowing_screen_position =
|
||||
|
|
|
@ -2,8 +2,8 @@ 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 * as narrow from "./narrow";
|
||||
import {page_params} from "./page_params";
|
||||
|
||||
// Check if we're doing a compose-preserving reload. This must be
|
||||
|
@ -27,7 +27,7 @@ export function initialize() {
|
|||
// 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("");
|
||||
narrow.changehash("");
|
||||
return;
|
||||
}
|
||||
ls.remove(hash_fragment);
|
||||
|
@ -87,5 +87,5 @@ export function initialize() {
|
|||
}
|
||||
|
||||
activity.set_new_user_input(false);
|
||||
hashchange.changehash(vars.oldhash);
|
||||
narrow.changehash(vars.oldhash);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ const admin = mock_esm("../src/admin");
|
|||
const drafts_overlay_ui = mock_esm("../src/drafts_overlay_ui");
|
||||
const info_overlay = mock_esm("../src/info_overlay");
|
||||
const message_viewport = mock_esm("../src/message_viewport");
|
||||
const narrow = mock_esm("../src/narrow");
|
||||
const overlays = mock_esm("../src/overlays");
|
||||
const popovers = mock_esm("../src/popovers");
|
||||
const recent_view_ui = mock_esm("../src/recent_view_ui");
|
||||
|
@ -32,6 +31,7 @@ const browser_history = zrequire("browser_history");
|
|||
const people = zrequire("people");
|
||||
const hash_util = zrequire("hash_util");
|
||||
const hashchange = zrequire("hashchange");
|
||||
const narrow = zrequire("../src/narrow");
|
||||
const stream_data = zrequire("stream_data");
|
||||
|
||||
run_test("operators_round_trip", () => {
|
||||
|
@ -120,7 +120,7 @@ run_test("people_slugs", () => {
|
|||
assert.deepEqual(narrow, [{operator: "pm-with", operand: "alice@example.com", negated: false}]);
|
||||
});
|
||||
|
||||
function test_helper({override, change_tab}) {
|
||||
function test_helper({override, override_rewire, change_tab}) {
|
||||
let events = [];
|
||||
let narrow_terms;
|
||||
|
||||
|
@ -143,7 +143,7 @@ function test_helper({override, change_tab}) {
|
|||
stub(ui_report, "error");
|
||||
|
||||
if (change_tab) {
|
||||
override(narrow, "activate", (terms) => {
|
||||
override_rewire(narrow, "activate", (terms) => {
|
||||
narrow_terms = terms;
|
||||
events.push("narrow.activate");
|
||||
});
|
||||
|
@ -164,11 +164,11 @@ function test_helper({override, change_tab}) {
|
|||
};
|
||||
}
|
||||
|
||||
run_test("hash_interactions", ({override}) => {
|
||||
run_test("hash_interactions", ({override, override_rewire}) => {
|
||||
$window_stub = $.create("window-stub");
|
||||
user_settings.default_view = "recent_topics";
|
||||
|
||||
const helper = test_helper({override, change_tab: true});
|
||||
const helper = test_helper({override, override_rewire, change_tab: true});
|
||||
|
||||
let recent_view_ui_shown = false;
|
||||
override(recent_view_ui, "show", () => {
|
||||
|
@ -331,13 +331,13 @@ run_test("hash_interactions", ({override}) => {
|
|||
helper.assert_events([[ui_util, "blur_active_element"]]);
|
||||
});
|
||||
|
||||
run_test("save_narrow", ({override}) => {
|
||||
const helper = test_helper({override});
|
||||
run_test("save_narrow", ({override, override_rewire}) => {
|
||||
const helper = test_helper({override, override_rewire});
|
||||
|
||||
let operators = [{operator: "is", operand: "dm"}];
|
||||
|
||||
blueslip.expect("error", "browser does not support pushState");
|
||||
hashchange.save_narrow(operators);
|
||||
narrow.save_narrow(operators);
|
||||
|
||||
helper.assert_events([[message_viewport, "stop_auto_scrolling"]]);
|
||||
assert.equal(window.location.hash, "#narrow/is/dm");
|
||||
|
@ -350,7 +350,7 @@ run_test("save_narrow", ({override}) => {
|
|||
operators = [{operator: "is", operand: "starred"}];
|
||||
|
||||
helper.clear_events();
|
||||
hashchange.save_narrow(operators);
|
||||
narrow.save_narrow(operators);
|
||||
helper.assert_events([[message_viewport, "stop_auto_scrolling"]]);
|
||||
assert.equal(url_pushed, "http://zulip.zulipdev.com/#narrow/is/starred");
|
||||
});
|
||||
|
|
|
@ -11,11 +11,13 @@ mock_esm("../src/resize", {
|
|||
});
|
||||
|
||||
const all_messages_data = mock_esm("../src/all_messages_data");
|
||||
const browser_history = mock_esm("../src/browser_history", {
|
||||
state: {changing_hash: false},
|
||||
});
|
||||
const compose_actions = mock_esm("../src/compose_actions");
|
||||
const compose_banner = mock_esm("../src/compose_banner");
|
||||
const compose_closed_ui = mock_esm("../src/compose_closed_ui");
|
||||
const compose_recipient = mock_esm("../src/compose_recipient");
|
||||
const hashchange = mock_esm("../src/hashchange");
|
||||
const message_fetch = mock_esm("../src/message_fetch");
|
||||
const message_list = mock_esm("../src/message_list");
|
||||
const message_lists = mock_esm("../src/message_lists", {
|
||||
|
@ -28,6 +30,7 @@ const message_lists = mock_esm("../src/message_lists", {
|
|||
const message_feed_top_notices = mock_esm("../src/message_feed_top_notices");
|
||||
const message_feed_loading = mock_esm("../src/message_feed_loading");
|
||||
const message_view_header = mock_esm("../src/message_view_header");
|
||||
const message_viewport = mock_esm("../src/message_viewport");
|
||||
const narrow_history = mock_esm("../src/narrow_history");
|
||||
const narrow_title = mock_esm("../src/narrow_title");
|
||||
const stream_list = mock_esm("../src/stream_list");
|
||||
|
@ -76,16 +79,17 @@ function test_helper({override}) {
|
|||
});
|
||||
}
|
||||
|
||||
stub(browser_history, "set_hash");
|
||||
stub(compose_banner, "clear_message_sent_banners");
|
||||
stub(compose_actions, "on_narrow");
|
||||
stub(compose_closed_ui, "update_reply_recipient_label");
|
||||
stub(narrow_history, "save_narrow_state_and_flush");
|
||||
stub(hashchange, "save_narrow");
|
||||
stub(message_feed_loading, "hide_indicators");
|
||||
stub(message_feed_top_notices, "hide_top_of_narrow_notices");
|
||||
stub(narrow_title, "update_narrow_title");
|
||||
stub(stream_list, "handle_narrow_activated");
|
||||
stub(message_view_header, "render_title_area");
|
||||
stub(message_viewport, "stop_auto_scrolling");
|
||||
stub(left_sidebar_navigation_area, "handle_narrow_activated");
|
||||
stub(typing_events, "render_notifications_for_narrow");
|
||||
stub(compose_recipient, "update_narrow_to_recipient_visibility");
|
||||
|
@ -185,7 +189,8 @@ run_test("basics", ({override}) => {
|
|||
[compose_banner, "clear_message_sent_banners"],
|
||||
[unread_ops, "process_visible"],
|
||||
[narrow_history, "save_narrow_state_and_flush"],
|
||||
[hashchange, "save_narrow"],
|
||||
[message_viewport, "stop_auto_scrolling"],
|
||||
[browser_history, "set_hash"],
|
||||
[typing_events, "render_notifications_for_narrow"],
|
||||
[compose_closed_ui, "update_buttons_for_stream"],
|
||||
[compose_closed_ui, "update_reply_recipient_label"],
|
||||
|
|
Loading…
Reference in New Issue