Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: safari/ext/background.js

Issue 5092502491103232: Deal with preloadded pages in Safari 7.0 (Closed)
Patch Set: Created Jan. 23, 2014, 3:21 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | safari/ext/common.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: safari/ext/background.js
===================================================================
--- a/safari/ext/background.js
+++ b/safari/ext/background.js
@@ -17,6 +17,19 @@
(function()
{
+ var isTabVisible = function(tab)
+ {
+ return tab.browserWindow.visible && tab.browserWindow.activeTab == tab;
+ };
+
+ var sentByPreloadedPage = function(message, tab)
+ {
+ // the message was sent by a preloaded page if document.hidden was set,
+ // despite the tab is visible
+ return message.isDocumentHidden && isTabVisible(tab);
+ };
+
+
/* Events */
var TabEventTarget = function()
@@ -38,6 +51,7 @@
var LoadingTabEventTarget = function(target)
{
WrappedEventTarget.call(this, target, "message", false);
+ this._preloadedTabs = new TabMap();
};
LoadingTabEventTarget.prototype = {
__proto__: WrappedEventTarget.prototype,
@@ -45,9 +59,35 @@
{
return function (event)
{
- if (event.name == "loading")
- listener(new Tab(event.target));
- };
+ switch (event.name)
+ {
+ case "loading":
+ var tab = new Tab(event.target);
+
+ // when the "loading" message was sent form a preloaded
+ // page in Safari 7.0, we have to wait until the page is
+ // shown, before calling the listener. The high-level code
+ // doesn't know anything about preloaded pages and expects
+ // all events to be related to the current visible page.
+ if (sentByPreloadedPage(event.message, event.target))
+ this._preloadedTabs.set(tab, null);
+ else
+ {
+ this._preloadedTabs.delete(tab);
+ listener(tab);
+ }
+
+ break;
+ case "show":
+ var tab = new Tab(event.target);
+
+ if (this._preloadedTabs.has(tab))
+ {
+ this._preloadedTabs.delete(tab);
+ listener(tab);
+ }
+ }
+ }.bind(this);
}
};
@@ -71,6 +111,23 @@
event.target
)
};
+ },
+ _ignoreIf: function(event)
+ {
+ // when receiving a message from a preloaded page in Safari 7.0, we
+ // have to defer procesing of that message, until the page is shown.
+ // The high-level code doesn't know anything about preloaded pages
+ // and expects all message to be sent from the current visible page.
+ if (sentByPreloadedPage(event.message, event.target))
+ {
+ event.target.page.dispatchMessage("response", {
+ requestId: event.message.requestId,
+ deferred: true
+ });
+ return true;
+ }
+
+ return false;
}
};
@@ -104,8 +161,18 @@
sendMessage: function(message, responseCallback)
{
_sendMessage(
- message, responseCallback,
- this._tab.page, this._tab
+ // message payload
+ message,
+ // response callback
+ responseCallback && function(response) { responseCallback(response.payload); },
+ // message dispatcher
+ this._tab.page,
+ // response event target
+ this._tab,
+ // extra data
+ {
+ isTabVisible: isTabVisible(this._tab)
+ }
);
}
};
@@ -574,16 +641,23 @@
_handleMessage: function(message, rawTab)
{
+ // we have to defer loading of resources on preloaded pages
+ // in Safari 7.0, until the page is shown. The high-level code
+ // doesn't know anything about preloaded pages and expects all
+ // web requests to be related to the current visible page.
+ if (sentByPreloadedPage(message, rawTab))
+ return "deferred";
+
var tab = new Tab(rawTab);
var frame = new Frame(message.documentUrl, message.isTopLevel, rawTab);
for (var i = 0; i < this._listeners.length; i++)
{
if (this._listeners[i](message.url, message.type, tab, frame) === false)
- return false;
+ return "blocked";
}
- return true;
+ return "ok";
},
addListener: function(listener)
{
« no previous file with comments | « no previous file | safari/ext/common.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld