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

Unified Diff: safari/ext/background.js

Issue 6346177440120832: Added abstraction for frames, to fix domain-based rules, whitelisting and ad counter on Safari (Closed)
Patch Set: Rebased and addressed comments Created Jan. 19, 2014, 10:40 a.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
Index: safari/ext/background.js
===================================================================
--- a/safari/ext/background.js
+++ b/safari/ext/background.js
@@ -17,7 +17,7 @@
(function()
{
- /* Tabs */
+ /* Events */
var TabEventTarget = function()
{
@@ -51,16 +51,40 @@
}
};
+ var BackgroundMessageEventTarget = function()
+ {
+ MessageEventTarget.call(this, safari.application);
+ };
+ BackgroundMessageEventTarget.prototype = {
+ __proto__: MessageEventTarget.prototype,
+ _getResponseDispatcher: function(event)
+ {
+ return event.target.page;
+ },
+ _getSenderDetails: function(event)
+ {
+ return {
+ tab: new Tab(event.target),
+ frame: new Frame(
+ event.message.documentUrl,
+ event.message.isTopLevel,
+ event.target
+ )
+ };
+ }
+ };
+
+
+ /* Tabs */
+
Tab = function(tab)
{
this._tab = tab;
- this._eventTarget = tab;
- this._messageDispatcher = tab.page;
-
this.browserAction = new BrowserAction(this);
this.onLoading = new LoadingTabEventTarget(tab);
+ this.onBeforeNavigate = new TabEventTarget(tab, "beforeNavigate", false);
this.onCompleted = new TabEventTarget(tab, "navigate", false);
this.onActivated = new TabEventTarget(tab, "activate", false);
this.onRemoved = new TabEventTarget(tab, "close", false);
@@ -78,15 +102,22 @@
{
this._tab.activate();
},
- sendMessage: sendMessage
+ sendMessage: function(message, responseCallback)
+ {
+ _sendMessage(
+ message, responseCallback,
+ this._tab.page, this._tab
+ );
+ }
};
- TabMap = function()
+ TabMap = function(deleteTabOnBeforeNavigate)
{
this._tabs = [];
this._values = [];
- this._onClosed = this._onClosed.bind(this);
+ this._deleteOnEvent = this._deleteOnEvent.bind(this);
+ this._deleteTabOnBeforeNavigate = deleteTabOnBeforeNavigate;
};
TabMap.prototype =
{
@@ -109,7 +140,9 @@
this._tabs.push(tab._tab);
this._values.push(value);
- tab._tab.addEventListener("close", this._onClosed, false);
+ tab._tab.addEventListener("close", this._deleteOnEvent, false);
+ if (this._deleteTabOnBeforeNavigate)
+ tab._tab.addEventListener("beforeNavigate", this._deleteOnEvent, false);
}
},
has: function(tab)
@@ -130,12 +163,14 @@
this._tabs.splice(idx, 1);
this._values.splice(idx, 1);
- tab.removeEventListener("close", this._onClosed, false);
+ tab.removeEventListener("close", this._deleteOnEvent, false);
+ tab.removeEventListener("beforeNavigate", this._deleteOnEvent, false);
}
},
- _onClosed: function(event)
+ _deleteOnEvent: function(event)
{
- this._delete(event.target);
+ // delay so that other event handlers can still look this tab up
+ setTimeout(this._delete.bind(this, event.target), 0);
}
};
TabMap.prototype["delete"] = function(tab)
@@ -145,6 +180,7 @@
ext.tabs = {
onLoading: new LoadingTabEventTarget(safari.application),
+ onBeforeNavigate: new TabEventTarget(safari.application, "beforeNavigate", true),
onCompleted: new TabEventTarget(safari.application, "navigate", true),
onActivated: new TabEventTarget(safari.application, "activate", true),
onRemoved: new TabEventTarget(safari.application, "close", true)
@@ -268,6 +304,22 @@
};
+ /* Frames */
+
+ Frame = function(url, isTopLevel, tab)
+ {
+ this.url = url;
+
+ // there is no way to discover frames with Safari's API.
+ // so if this isn't the top level frame, assume that the parent is.
+ // this is the best we can do for Safari. :(
+ if (!isTopLevel)
+ this.parent = new Frame(tab.url, true);
+ else
+ this.parent = null;
+ };
+
+
/* Background page proxy */
var proxy = {
@@ -498,47 +550,29 @@
ext.webRequest = {
onBeforeRequest: {
_listeners: [],
- _urlPatterns: [],
- _handleMessage: function(message, tab)
+ _handleMessage: function(message, rawTab)
{
- tab = new Tab(tab);
+ var tab = new Tab(rawTab);
+ var frame = new Frame(message.documentUrl, message.isTopLevel, rawTab);
for (var i = 0; i < this._listeners.length; i++)
{
- var regex = this._urlPatterns[i];
-
- if ((!regex || regex.test(message.url)) && this._listeners[i](message.url, message.type, tab, 0, -1) === false)
+ if (this._listeners[i](message.url, message.type, tab, frame) === false)
return false;
}
return true;
},
- addListener: function(listener, urls)
+ addListener: function(listener)
{
- var regex;
-
- if (urls)
- regex = new RegExp("^(?:" + urls.map(function(url)
- {
- return url.split("*").map(function(s)
- {
- return s.replace(/([.?+^$[\]\\(){}|-])/g, "\\$1");
- }).join(".*");
- }).join("|") + ")($|[?#])");
-
this._listeners.push(listener);
- this._urlPatterns.push(regex);
},
removeListener: function(listener)
{
var idx = this._listeners.indexOf(listener);
-
if (idx != -1)
- {
this._listeners.splice(idx, 1);
- this._urlPatterns.splice(idx, 1);
- }
}
},
handlerBehaviorChanged: function() {}
@@ -591,7 +625,7 @@
}
};
- ext.onMessage = new MessageEventTarget(safari.application);
+ ext.onMessage = new BackgroundMessageEventTarget();
var contextMenu = [];
var isContextMenuHidden = false;
« chrome/ext/background.js ('K') | « popupBlocker.js ('k') | safari/ext/common.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld