diff --git a/platform/safari/vapi-background.js b/platform/safari/vapi-background.js index 4976eb1df..620a878fc 100644 --- a/platform/safari/vapi-background.js +++ b/platform/safari/vapi-background.js @@ -187,12 +187,9 @@ vAPI.tabs.registerListeners = function() { safari.application.addEventListener('navigate', this.onNavigation, true); } - // ?? - /* if (typeof this.onUpdated === 'function') { } */ - // onClosed handled in the main tab-close event - // onPopup is handled in window.open on web-pages? - /* if (typeof onPopup === 'function') { } */ + // onUpdated handled via monitoring the history.pushState on web-pages + // onPopup is handled in window.open on web-pages }; /******************************************************************************/ @@ -603,8 +600,17 @@ vAPI.net.registerListeners = function() { return e.message; } + // when the URL changes, but the document doesn't + if (e.message.type === 'popstate') { + vAPI.tabs.onUpdated( + vAPI.tabs.getTabId(e.target), + {url: e.message.url}, + {url: e.message.url} + ); + return; + } // blocking unwanted pop-ups - if (e.message.type === 'popup') { + else if (e.message.type === 'popup') { if (typeof vAPI.tabs.onPopup === 'function') { e.message.type = 'main_frame'; e.message.sourceTabId = vAPI.tabs.getTabId(e.target); diff --git a/platform/safari/vapi-client.js b/platform/safari/vapi-client.js index ca4e0b826..e0af31ee6 100644 --- a/platform/safari/vapi-client.js +++ b/platform/safari/vapi-client.js @@ -330,28 +330,51 @@ var firstMutation = function() { // the extension context is unable to reach the page context, // also this only works when Content Security Policy allows inline scripts var tmpJS = document.createElement('script'); - var tmpScript = ["(function() {", - "var block = function(u, t) {", - "var e = document.createEvent('CustomEvent'),", - "d = {url: u, type: t};", - "e.initCustomEvent('" + randEventName + "', !1, !1, d);", - "dispatchEvent(e);", - "return d.url === !1;", - "}, wo = open, xo = XMLHttpRequest.prototype.open;", - "open = function(u) {", - "return block(u, 'popup') ? null : wo.apply(this, [].slice.call(arguments));", - "};", - "XMLHttpRequest.prototype.open = function(m, u, s) {", - "return xo.apply(this, block(u, 'xmlhttprequest') ? ['HEAD', u, s] : [].slice.call(arguments));", - "};" + var tmpScript = ['(function() {', + 'var block = function(u, t) {', + 'var e = document.createEvent("CustomEvent"),', + 'd = {url: u, type: t};', + 'e.initCustomEvent("' + randEventName + '", !1, !1, d);', + 'dispatchEvent(e);', + 'return d.url === !1;', + '}, wo = open, xo = XMLHttpRequest.prototype.open;', + 'open = function(u) {', + 'return block(u, "popup") ? null : wo.apply(this, arguments);', + '};', + 'XMLHttpRequest.prototype.open = function(m, u, s) {', + 'return xo.apply(this, block(u, "xmlhttprequest") ? ["HEAD", u, s] : arguments);', + '};' ]; - if (vAPI.sitePatch - && !safari.self.tab.canLoad(beforeLoadEvent, {isWhiteListed: location.href})) { + if (frameId === 0) { + tmpScript.push( + 'var pS = history.pushState, rS = history.replaceState,', + 'onpopstate = function(e) {', + 'if (!e || e.state !== null) block(location.href, "popstate");', + '};', + 'window.addEventListener("popstate", onpopstate, true);', + 'history.pushState = function() {', + 'var r = pS.apply(this, arguments);', + 'onpopstate();', + 'return r;', + '};', + 'history.replaceState = function() {', + 'var r = pR.apply(this, arguments);', + 'onpopstate();', + 'return r;', + '};' + ); + } + + var block = safari.self.tab.canLoad(beforeLoadEvent, { + isWhiteListed: location.href + }); + + if (vAPI.sitePatch && !block) { tmpScript.push('(' + vAPI.sitePatch + ')();'); } - tmpScript.push("})();"); + tmpScript.push('})();'); tmpJS.textContent = tmpScript.join(''); document.documentElement.removeChild(document.documentElement.appendChild(tmpJS)); };