From b0e5aeb313fbbca4f69c275fca17603611d49ffd Mon Sep 17 00:00:00 2001 From: Brock Whittaker Date: Mon, 13 Mar 2017 14:02:31 -0700 Subject: [PATCH] Consolidate JavaScript modal closing in modals.js. This consolidates all actions to close modals into modals.js and triggers the correct cleaning/collapsing function dependent on what the data-overlay attribute is labeled as. It also ensures these all have an e.stopPropagation(). Fixes #4029. --- .eslintrc.json | 1 + static/js/click_handlers.js | 22 -------- static/js/drafts.js | 7 +-- static/js/hashchange.js | 4 +- static/js/hotkey.js | 12 ++--- static/js/modals.js | 70 ++++++++++++++++++++++++++ static/js/subs.js | 1 - static/js/ui.js | 10 ---- templates/zerver/index.html | 2 +- templates/zerver/lightbox_overlay.html | 4 +- zproject/settings.py | 1 + 11 files changed, 83 insertions(+), 51 deletions(-) create mode 100644 static/js/modals.js diff --git a/.eslintrc.json b/.eslintrc.json index b556c687ec..0ad7365c35 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -33,6 +33,7 @@ "loading": false, "compose": false, "compose_fade": false, + "modals": false, "subs": false, "timerender": false, "message_live_update": false, diff --git a/static/js/click_handlers.js b/static/js/click_handlers.js index 8282bd6683..4882d1868a 100644 --- a/static/js/click_handlers.js +++ b/static/js/click_handlers.js @@ -11,8 +11,6 @@ $(function () { var clicking = false; var mouse_moved = false; - var meta = {}; - function mousedown() { mouse_moved = false; clicking = true; @@ -261,12 +259,6 @@ $(function () { } }); - $("#drafts_table").on("click", ".exit, #draft_overlay", function (e) { - if ($(e.target).is(".exit, .exit-sign, #draft_overlay, #draft_overlay > .flex")) { - drafts.close(); - } - }); - // HOME // Capture both the left-sidebar Home click and the tab breadcrumb Home @@ -338,12 +330,6 @@ $(function () { e.preventDefault(); }); - $(".informational-overlays").click(function (e) { - if ($(e.target).is(".informational-overlays, .exit")) { - ui.hide_info_overlay(); - } - }); - $("body").on("click", "[data-overlay-trigger]", function () { ui.show_info_overlay($(this).attr("data-overlay-trigger")); }); @@ -551,14 +537,6 @@ $(function () { } }); - $("#overlay .exit, #overlay .image-preview").click(function (e) { - if ($(e.target).is(".exit, .image-preview")) { - ui.exit_lightbox_photo(); - } - e.preventDefault(); - e.stopPropagation(); - }); - $("#overlay .download").click(function () { this.blur(); }); diff --git a/static/js/drafts.js b/static/js/drafts.js index 1d58f5a7a2..78ac941831 100644 --- a/static/js/drafts.js +++ b/static/js/drafts.js @@ -105,7 +105,7 @@ exports.restore_draft = function (draft_id) { draft_copy); } - exports.close(); + modals.close_modal("drafts"); compose_fade.clear_compose(); if (draft.type === "stream" && draft.stream === "") { draft_copy.subject = ""; @@ -209,11 +209,6 @@ exports.launch = function () { }); }; -exports.close = function () { - hashchange.exit_modal(); - $("#draft_overlay").removeClass("show"); -}; - $(function () { window.addEventListener("beforeunload", function () { exports.update_draft(); diff --git a/static/js/hashchange.js b/static/js/hashchange.js index df8c615888..5bc5057c4c 100644 --- a/static/js/hashchange.js +++ b/static/js/hashchange.js @@ -323,7 +323,7 @@ exports.initialize = function () { }; exports.close_modals = function () { - $("[data-overlay]").removeClass("show"); + $(".overlay.show").removeClass("show"); }; exports.exit_modal = function (callback) { @@ -334,8 +334,6 @@ exports.exit_modal = function (callback) { if (typeof callback === "function") { callback(); } - - exports.close_modals(); } }; diff --git a/static/js/hotkey.js b/static/js/hotkey.js index 4fa084e195..35c8165b32 100644 --- a/static/js/hotkey.js +++ b/static/js/hotkey.js @@ -157,27 +157,27 @@ exports.process_escape_key = function (e) { } if ($("#overlay").hasClass("show")) { - ui.exit_lightbox_photo(); + modals.close_modal("lightbox"); return true; } if ($("#subscription_overlay").hasClass("show")) { - subs.close(); + modals.close_modal("subscriptions"); return true; } if ($("#draft_overlay").hasClass("show")) { - drafts.close(); + modals.close_modal("drafts"); return true; } if ($(".informational-overlays").hasClass("show")) { - ui.hide_info_overlay(); + modals.close_modal("informationalOverlays"); return true; } - if ($("#invite-user").css("display") === "block") { - $("#invite-user").modal("hide"); + if ($("#invite-user.show").length) { + modals.close_modal("invite"); return true; } diff --git a/static/js/modals.js b/static/js/modals.js new file mode 100644 index 0000000000..068fbddfd5 --- /dev/null +++ b/static/js/modals.js @@ -0,0 +1,70 @@ +var modals = (function () { + "use strict"; + + var exports = { + close: { + subscriptions: function () { + subs.close(); + }, + + drafts: function () { + hashchange.exit_modal(); + }, + + informationalOverlays: function () { + $(".informational-overlays").removeClass("show"); + }, + + settings: function () { + hashchange.exit_modal(); + }, + + lightbox: function () { + $(".player-container iframe").remove(); + document.activeElement.blur(); + }, + }, + + close_modal: function (name) { + $("[data-overlay='" + name + "']").removeClass("show"); + + if (exports.close[name]) { + exports.close[name](); + } + }, + }; + + $(function () { + $("body").on("click", ".overlay, .overlay .exit", function (e) { + var $target = $(e.target); + + // if the target is not the .overlay element, search up the node tree + // until it is found. + if ($target.is(".exit, .exit-sign, .overlay-content")) { + $target = $target.closest("[data-overlay]"); + } else if (!$target.is(".overlay")) { + // not a valid click target then. + return; + } + + var target_name = $target.attr("data-overlay"); + + $target.removeClass("show"); + + // if an appropriate clearing/closing function for a modal exists, + // execute it. + if (exports.close[target_name]) { + exports.close[target_name](); + } + + e.preventDefault(); + e.stopPropagation(); + }); + }); + + return exports; +}()); + +if (typeof module !== 'undefined') { + module.exports = modals; +} diff --git a/static/js/subs.js b/static/js/subs.js index e454c51414..8df18c028b 100644 --- a/static/js/subs.js +++ b/static/js/subs.js @@ -823,7 +823,6 @@ Object.defineProperty(exports, "is_open", { exports.close = function () { hashchange.exit_modal(); meta.is_open = false; - $("#subscription_overlay").removeClass("show"); subs.remove_miscategorized_streams(); }; diff --git a/static/js/ui.js b/static/js/ui.js index 46ddc84daa..c681347e3a 100644 --- a/static/js/ui.js +++ b/static/js/ui.js @@ -313,10 +313,6 @@ exports.show_info_overlay = function (target) { } }; -exports.hide_info_overlay = function () { - $(".informational-overlays").removeClass("show"); -}; - exports.lightbox_photo = function (image, user) { // image should be an Image Object in JavaScript. var url = $(image).attr("src"); @@ -336,12 +332,6 @@ exports.lightbox_photo = function (image, user) { $(".image-actions .open, .image-actions .download").attr("href", url); }; -exports.exit_lightbox_photo = function () { - $("#overlay").removeClass("show"); - $(".player-container iframe").remove(); - document.activeElement.blur(); -}; - exports.youtube_video = function (id) { $("#overlay .image-preview, .image-description, .download").hide(); diff --git a/templates/zerver/index.html b/templates/zerver/index.html index 6f45d2eecf..998fe991b8 100644 --- a/templates/zerver/index.html +++ b/templates/zerver/index.html @@ -124,7 +124,7 @@ var page_params = {{ page_params }}; {% include "zerver/subscriptions.html" %} {% include "zerver/drafts.html" %} -
+
diff --git a/templates/zerver/lightbox_overlay.html b/templates/zerver/lightbox_overlay.html index a398570048..8a206f1126 100644 --- a/templates/zerver/lightbox_overlay.html +++ b/templates/zerver/lightbox_overlay.html @@ -1,4 +1,4 @@ -
+
@@ -16,6 +16,6 @@
-
+
diff --git a/zproject/settings.py b/zproject/settings.py index d9d6b5b3f8..8db3640061 100644 --- a/zproject/settings.py +++ b/zproject/settings.py @@ -852,6 +852,7 @@ JS_SPECS = { 'js/copy_and_paste.js', 'js/stream_popover.js', 'js/popovers.js', + 'js/modals.js', 'js/typeahead_helper.js', 'js/search_suggestion.js', 'js/search.js',