diff --git a/dashboard-ui/components/paperdialoghelper.js b/dashboard-ui/components/paperdialoghelper.js index 2c360d8df3..5d7b0816bf 100644 --- a/dashboard-ui/components/paperdialoghelper.js +++ b/dashboard-ui/components/paperdialoghelper.js @@ -2,18 +2,21 @@ function paperDialogHashHandler(dlg, hash, resolve, lockDocumentScroll) { + var self = this; + self.originalUrl = window.location.href; + var activeElement = document.activeElement; + function onHashChange(e) { - var data = e.detail.state || {}; - var isActive = data.hash == '#' + hash; + var isBack = self.originalUrl == window.location.href; - if (data.direction == 'back') { - if (dlg) { - if (!isActive) { - dlg.close(); - dlg = null; - } - } + if (isBack || !dlg.opened) { + window.removeEventListener('popstate', onHashChange); + } + + if (isBack) { + self.closedByBack = true; + dlg.close(); } } @@ -23,14 +26,29 @@ Dashboard.onPopupClose(); } - dlg = null; - if (enableHashChange()) { - window.removeEventListener('navigate', onHashChange); + window.removeEventListener('popstate', onHashChange); - if (window.location.hash == '#' + hash) { + if (!self.closedByBack) { + var state = history.state || {}; + if (state.dialogId == hash) { history.back(); } } + + activeElement.focus(); + + if (dlg.getAttribute('data-removeonclose') == 'true') { + dlg.parentNode.removeChild(dlg); + } + + //resolve(); + // if we just called history.back(), then use a timeout to allow the history events to fire first + setTimeout(function () { + resolve({ + element: dlg, + closedByBack: self.closedByBack + }); + }, 1); } dlg.addEventListener('iron-overlay-closed', onDialogClosed); @@ -40,23 +58,15 @@ Dashboard.onPopupOpen(); } - if (enableHashChange()) { + var state = { + dialogId: hash, + navigate: false + }; + history.pushState(state, "Dialog", hash); - window.location.hash = hash; + jQuery.onStatePushed(state); - window.addEventListener('navigate', onHashChange); - } - } - - function enableHashChange() { - // It's not firing popstate in response to hashbang changes - if (browserInfo.msie) { - return false; - } - if (browserInfo.edge) { - return false; - } - return true; + window.addEventListener('popstate', onHashChange); } function open(dlg) { diff --git a/dashboard-ui/scripts/site.js b/dashboard-ui/scripts/site.js index 3db9b3c098..16856549fb 100644 --- a/dashboard-ui/scripts/site.js +++ b/dashboard-ui/scripts/site.js @@ -457,6 +457,7 @@ var Dashboard = { // This is just an attempt to prevent the fade-in animation from running repeating and causing flickering elem.active = true; + elem.classList.remove('hide'); } else { @@ -479,6 +480,7 @@ var Dashboard = { if (elem) { elem.active = false; + elem.classList.add('hide'); } }, diff --git a/dashboard-ui/thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.js b/dashboard-ui/thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.js index cd00ced91e..df6fc2d158 100644 --- a/dashboard-ui/thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.js +++ b/dashboard-ui/thirdparty/jquerymobile-1.4.5/jquery.mobile.custom.js @@ -85,23 +85,41 @@ })(jQuery, this); - window.addEventListener('popstate', function (event) { + var previousState = {}; + + // This is just a temporary api until jquery mobile is eventually deprecated and we have an actual routing library + jQuery.onStatePushed = function(state) { + previousState = state; + }; + + function ignorePopState(event) { + var state = event.state || {}; - setTimeout(function () { + if (previousState.navigate === false) { + // Ignore + previousState = state; + return true; + } - if (event.historyState) { - $.extend(state, event.historyState); + previousState = state; + return false; + } + + function fireNavigateFromPopstateEvent(event) { + + var state = event.state || {}; + if (event.historyState) { + $.extend(state, event.historyState); + } + + window.dispatchEvent(new CustomEvent("navigate", { + detail: { + state: state, + originalEvent: event } - - window.dispatchEvent(new CustomEvent("navigate", { - detail: { - state: state, - originalEvent: event - } - })); - }, 0); - }); + })); + } jQuery.mobile.widgets = {}; @@ -785,8 +803,16 @@ // TODO grab the original event here and use it for the synthetic event in the // second half of the navigate execution that will follow this binding popstate: function (event) { - var hash, state; + if (ignorePopState(event)) { + return; + } + + setTimeout(function () { + fireNavigateFromPopstateEvent(event); + }, 0); + + var hash, state; // If this is the popstate triggered by the actual alteration of the hash // prevent it completely. History is tracked manually if (this.preventHashAssignPopState) {