2020-08-01 03:43:15 +02:00
|
|
|
"use strict";
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
let active_overlay;
|
|
|
|
let close_handler;
|
|
|
|
let open_overlay_name;
|
2017-05-06 02:27:40 +02:00
|
|
|
|
|
|
|
function reset_state() {
|
|
|
|
active_overlay = undefined;
|
|
|
|
close_handler = undefined;
|
2017-05-27 15:40:54 +02:00
|
|
|
open_overlay_name = undefined;
|
2017-05-06 02:27:40 +02:00
|
|
|
}
|
2017-05-05 23:43:05 +02:00
|
|
|
|
2017-05-06 02:40:32 +02:00
|
|
|
exports.is_active = function () {
|
2020-10-07 12:54:16 +02:00
|
|
|
return Boolean(open_overlay_name);
|
2017-05-06 02:40:32 +02:00
|
|
|
};
|
|
|
|
|
2017-08-29 19:05:05 +02:00
|
|
|
exports.is_modal_open = function () {
|
|
|
|
return $(".modal").hasClass("in");
|
|
|
|
};
|
|
|
|
|
2017-05-09 16:45:02 +02:00
|
|
|
exports.info_overlay_open = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
return open_overlay_name === "informationalOverlays";
|
2017-05-09 16:45:02 +02:00
|
|
|
};
|
|
|
|
|
2017-05-10 00:37:08 +02:00
|
|
|
exports.settings_open = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
return open_overlay_name === "settings";
|
2017-05-10 00:37:08 +02:00
|
|
|
};
|
|
|
|
|
2017-05-16 05:28:14 +02:00
|
|
|
exports.streams_open = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
return open_overlay_name === "subscriptions";
|
2017-05-16 05:28:14 +02:00
|
|
|
};
|
|
|
|
|
2017-05-10 15:43:36 +02:00
|
|
|
exports.lightbox_open = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
return open_overlay_name === "lightbox";
|
2017-05-10 15:43:36 +02:00
|
|
|
};
|
|
|
|
|
2017-10-03 00:41:43 +02:00
|
|
|
exports.drafts_open = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
return open_overlay_name === "drafts";
|
2017-10-03 00:41:43 +02:00
|
|
|
};
|
|
|
|
|
2020-04-08 13:59:56 +02:00
|
|
|
exports.recent_topics_open = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
return open_overlay_name === "recent_topics";
|
2020-04-08 13:59:56 +02:00
|
|
|
};
|
|
|
|
|
2020-03-30 13:16:06 +02:00
|
|
|
// To address bugs where mouse might apply to the streams/settings
|
|
|
|
// overlays underneath an open modal within those settings UI, we add
|
|
|
|
// this inline style to '.overlay.show', overriding the
|
2020-09-15 22:23:01 +02:00
|
|
|
// "pointer-events: all" style in app_components.css.
|
2020-03-30 13:16:06 +02:00
|
|
|
//
|
|
|
|
// This is kinda hacky; it only works for modals within overlays, and
|
|
|
|
// we need to make sure it gets re-enabled when the modal closes.
|
|
|
|
exports.disable_background_mouse_events = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
$(".overlay.show").attr("style", "pointer-events: none");
|
2020-03-30 13:16:06 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// This removes only the inline-style of the element that
|
|
|
|
// was added in disable_background_mouse_events and
|
|
|
|
// enables the background mouse events.
|
|
|
|
exports.enable_background_mouse_events = function () {
|
2020-07-15 01:29:15 +02:00
|
|
|
$(".overlay.show").attr("style", null);
|
2020-03-30 13:16:06 +02:00
|
|
|
};
|
|
|
|
|
2017-08-29 19:05:05 +02:00
|
|
|
exports.active_modal = function () {
|
|
|
|
if (!exports.is_modal_open()) {
|
2017-10-03 00:41:43 +02:00
|
|
|
blueslip.error("Programming error — Called active_modal when there is no modal open");
|
2020-09-24 07:50:36 +02:00
|
|
|
return undefined;
|
2017-08-29 19:05:05 +02:00
|
|
|
}
|
2021-02-03 23:23:32 +01:00
|
|
|
return `#${CSS.escape($(".modal.in").attr("id"))}`;
|
2017-08-29 19:05:05 +02:00
|
|
|
};
|
|
|
|
|
2017-05-06 00:37:33 +02:00
|
|
|
exports.open_overlay = function (opts) {
|
2017-10-31 14:36:54 +01:00
|
|
|
popovers.hide_all();
|
|
|
|
|
2017-05-06 00:37:33 +02:00
|
|
|
if (!opts.name || !opts.overlay || !opts.on_close) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error("Programming error in open_overlay");
|
2017-05-06 00:37:33 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-27 15:40:54 +02:00
|
|
|
if (active_overlay || open_overlay_name || close_handler) {
|
2020-07-15 00:34:28 +02:00
|
|
|
blueslip.error(
|
|
|
|
"Programming error — trying to open " +
|
|
|
|
opts.name +
|
|
|
|
" before closing " +
|
|
|
|
open_overlay_name,
|
|
|
|
);
|
2017-05-06 02:27:40 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.debug("open overlay: " + opts.name);
|
2017-06-15 17:03:29 +02:00
|
|
|
|
2017-05-06 00:37:33 +02:00
|
|
|
// Our overlays are kind of crufty...we have an HTML id
|
|
|
|
// attribute for them and then a data-overlay attribute for
|
|
|
|
// them. Make sure they match.
|
2020-07-15 01:29:15 +02:00
|
|
|
if (opts.overlay.attr("data-overlay") !== opts.name) {
|
|
|
|
blueslip.error("Bad overlay setup for " + opts.name);
|
2017-05-06 00:37:33 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-27 15:40:54 +02:00
|
|
|
open_overlay_name = opts.name;
|
2017-05-06 02:27:40 +02:00
|
|
|
active_overlay = opts.overlay;
|
2020-07-15 01:29:15 +02:00
|
|
|
opts.overlay.addClass("show");
|
2017-06-22 17:27:53 +02:00
|
|
|
|
|
|
|
opts.overlay.attr("aria-hidden", "false");
|
2020-07-15 01:29:15 +02:00
|
|
|
$(".app").attr("aria-hidden", "true");
|
|
|
|
$(".fixed-app").attr("aria-hidden", "true");
|
|
|
|
$(".header").attr("aria-hidden", "true");
|
2017-05-06 00:37:33 +02:00
|
|
|
|
2017-05-06 02:27:40 +02:00
|
|
|
close_handler = function () {
|
2017-05-06 00:37:33 +02:00
|
|
|
opts.on_close();
|
2017-05-06 02:27:40 +02:00
|
|
|
reset_state();
|
2017-05-06 00:37:33 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-05-09 15:45:54 +02:00
|
|
|
exports.open_modal = function (selector) {
|
|
|
|
if (selector === undefined) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error("Undefined selector was passed into open_modal");
|
2020-05-09 15:45:54 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
if (selector[0] !== "#") {
|
|
|
|
blueslip.error("Non-id-based selector passed in to open_modal: " + selector);
|
2017-08-29 19:05:05 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exports.is_modal_open()) {
|
2020-07-15 00:34:28 +02:00
|
|
|
blueslip.error(
|
|
|
|
"open_modal() was called while " + exports.active_modal() + " modal was open.",
|
|
|
|
);
|
2017-08-29 19:05:05 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.debug("open modal: " + selector);
|
2017-08-29 19:05:05 +02:00
|
|
|
|
2020-05-09 15:45:54 +02:00
|
|
|
const elem = $(selector).expectOne();
|
|
|
|
elem.modal("show").attr("aria-hidden", false);
|
2018-12-06 20:57:01 +01:00
|
|
|
// Disable background mouse events when modal is active
|
2020-03-30 13:16:06 +02:00
|
|
|
exports.disable_background_mouse_events();
|
2020-03-28 01:25:56 +01:00
|
|
|
// Remove previous alert messages from modal, if exists.
|
2020-05-09 15:45:54 +02:00
|
|
|
elem.find(".alert").hide();
|
|
|
|
elem.find(".alert-notification").html("");
|
2017-08-29 19:05:05 +02:00
|
|
|
};
|
|
|
|
|
2017-05-27 15:40:54 +02:00
|
|
|
exports.close_overlay = function (name) {
|
2020-06-26 13:22:11 +02:00
|
|
|
popovers.hide_all();
|
|
|
|
|
2017-05-27 15:40:54 +02:00
|
|
|
if (name !== open_overlay_name) {
|
2017-10-06 21:36:39 +02:00
|
|
|
blueslip.error("Trying to close " + name + " when " + open_overlay_name + " is open.");
|
2017-05-06 02:27:40 +02:00
|
|
|
return;
|
2017-05-05 23:43:05 +02:00
|
|
|
}
|
2017-05-06 02:27:40 +02:00
|
|
|
|
2017-06-15 17:03:29 +02:00
|
|
|
if (name === undefined) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error("Undefined name was passed into close_overlay");
|
2017-06-15 17:03:29 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.debug("close overlay: " + name);
|
2017-06-15 17:03:29 +02:00
|
|
|
|
2017-05-06 02:27:40 +02:00
|
|
|
active_overlay.removeClass("show");
|
2017-06-22 17:27:53 +02:00
|
|
|
|
|
|
|
active_overlay.attr("aria-hidden", "true");
|
2020-07-15 01:29:15 +02:00
|
|
|
$(".app").attr("aria-hidden", "false");
|
|
|
|
$(".fixed-app").attr("aria-hidden", "false");
|
|
|
|
$(".header").attr("aria-hidden", "false");
|
2017-05-06 02:27:40 +02:00
|
|
|
|
2017-05-12 17:24:16 +02:00
|
|
|
if (!close_handler) {
|
2020-10-13 23:50:18 +02:00
|
|
|
blueslip.error("Overlay close handler for " + name + " not properly set up.");
|
2017-05-12 17:24:16 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-06 02:27:40 +02:00
|
|
|
close_handler();
|
|
|
|
};
|
|
|
|
|
2017-05-10 00:37:28 +02:00
|
|
|
exports.close_active = function () {
|
2017-05-27 15:40:54 +02:00
|
|
|
if (!open_overlay_name) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.warn("close_active() called without checking is_active()");
|
2017-05-10 00:37:28 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-05-27 15:40:54 +02:00
|
|
|
exports.close_overlay(open_overlay_name);
|
2017-05-10 00:37:28 +02:00
|
|
|
};
|
|
|
|
|
2020-05-09 15:45:54 +02:00
|
|
|
exports.close_modal = function (selector) {
|
|
|
|
if (selector === undefined) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.error("Undefined selector was passed into close_modal");
|
2017-08-29 19:05:05 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!exports.is_modal_open()) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.warn("close_active_modal() called without checking is_modal_open()");
|
2017-08-29 19:05:05 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-05-09 15:45:54 +02:00
|
|
|
if (exports.active_modal() !== selector) {
|
2020-07-15 00:34:28 +02:00
|
|
|
blueslip.error(
|
|
|
|
"Trying to close " + selector + " modal when " + exports.active_modal() + " is open.",
|
|
|
|
);
|
2017-08-29 19:05:05 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.debug("close modal: " + selector);
|
2017-08-29 19:05:05 +02:00
|
|
|
|
2020-05-09 15:45:54 +02:00
|
|
|
const elem = $(selector).expectOne();
|
|
|
|
elem.modal("hide").attr("aria-hidden", true);
|
2018-12-06 20:57:01 +01:00
|
|
|
// Enable mouse events for the background as the modal closes.
|
2020-03-30 13:16:06 +02:00
|
|
|
exports.enable_background_mouse_events();
|
2017-08-29 19:05:05 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
exports.close_active_modal = function () {
|
|
|
|
if (!exports.is_modal_open()) {
|
2020-07-15 01:29:15 +02:00
|
|
|
blueslip.warn("close_active_modal() called without checking is_modal_open()");
|
2017-08-29 19:05:05 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
$(".modal.in").modal("hide").attr("aria-hidden", true);
|
|
|
|
};
|
|
|
|
|
2017-05-06 02:27:40 +02:00
|
|
|
exports.close_for_hash_change = function () {
|
|
|
|
$(".overlay.show").removeClass("show");
|
2020-12-01 09:35:33 +01:00
|
|
|
if (active_overlay) {
|
|
|
|
close_handler();
|
|
|
|
}
|
2017-05-05 23:43:05 +02:00
|
|
|
};
|
|
|
|
|
2017-05-06 01:04:45 +02:00
|
|
|
exports.open_settings = function () {
|
2019-10-25 09:45:13 +02:00
|
|
|
exports.open_overlay({
|
2020-07-15 01:29:15 +02:00
|
|
|
name: "settings",
|
2017-05-06 01:04:45 +02:00
|
|
|
overlay: $("#settings_overlay_container"),
|
2020-07-20 22:18:43 +02:00
|
|
|
on_close() {
|
2017-05-27 18:55:41 +02:00
|
|
|
hashchange.exit_overlay();
|
2017-05-06 01:04:45 +02:00
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2018-05-15 22:03:14 +02:00
|
|
|
exports.initialize = function () {
|
2020-07-02 01:45:54 +02:00
|
|
|
$("body").on("click", ".overlay, .overlay .exit", (e) => {
|
2019-11-02 00:06:25 +01:00
|
|
|
let $target = $(e.target);
|
2017-05-05 23:43:05 +02:00
|
|
|
|
|
|
|
// if the target is not the .overlay element, search up the node tree
|
|
|
|
// until it is found.
|
2017-07-07 17:30:22 +02:00
|
|
|
if ($target.is(".exit, .exit-sign, .overlay-content, .exit span")) {
|
2017-05-05 23:43:05 +02:00
|
|
|
$target = $target.closest("[data-overlay]");
|
|
|
|
} else if (!$target.is(".overlay")) {
|
|
|
|
// not a valid click target then.
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-11-02 00:06:25 +01:00
|
|
|
const target_name = $target.attr("data-overlay");
|
2017-05-05 23:43:05 +02:00
|
|
|
|
2017-05-27 15:40:54 +02:00
|
|
|
exports.close_overlay(target_name);
|
2017-05-05 23:43:05 +02:00
|
|
|
|
|
|
|
e.preventDefault();
|
|
|
|
e.stopPropagation();
|
2017-03-13 22:02:31 +01:00
|
|
|
});
|
2018-05-15 22:03:14 +02:00
|
|
|
};
|
2017-05-05 23:43:05 +02:00
|
|
|
|
2019-10-25 09:45:13 +02:00
|
|
|
window.overlays = exports;
|