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

Unified Diff: chrome/background.js

Issue 16067002: Added Safari Support (Closed)
Patch Set: Created Oct. 21, 2013, 8:11 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
« block.js ('K') | « block.js ('k') | chrome/common.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/background.js
===================================================================
new file mode 100644
--- /dev/null
+++ b/chrome/background.js
@@ -0,0 +1,286 @@
+(function() {
Felix Dahlke 2013/10/24 16:30:34 Opening braces should go on their own line, likewi
+ /* Events */
+
+ var TabEventTarget = function() {
+ WrappedEventTarget.apply(this, arguments);
+
+ this._tabs = {};
+
+ this._sharedListener = this._sharedListener.bind(this);
+ this._removeTab = this._removeTab.bind(this);
+ };
+ TabEventTarget.prototype = {
+ __proto__: WrappedEventTarget.prototype,
+ _bindToTab: function(tab) {
+ return {
+ addListener: function(listener) {
+ var listeners = this._tabs[tab._id];
+
+ if (!listeners) {
+ this._tabs[tab._id] = listeners = [];
+
+ if (Object.keys(this._tabs).length == 1)
+ this.addListener(this._sharedListener);
+
+ tab.onRemoved.addListener(this._removeTab);
+ }
+
+ listeners.push(listener);
+ }.bind(this),
+ removeListener: function(listener) {
+ var listeners = this._tabs[tab._id];
+ if (!listeners)
+ return;
+
+ var idx = listeners.indexOf(listener);
+ if (idx == -1)
+ return;
+
+ listeners.splice(idx, 1);
+
+ if (listeners.length == 0)
+ tab.onRemoved.removeListener(this._removeTab);
+ else {
+ if (listeners.length > 1)
+ return;
+ if (listeners[0] != this._removeTab)
+ return;
+ }
+
+ this._removeTab(tab);
+ }.bind(this)
+ };
+ },
+ _sharedListener: function(tab) {
+ var listeners = this._tabs[tab._id];
+
+ if (!listeners)
+ return;
+
+ // copy listeners before calling them, because of they
Felix Dahlke 2013/10/24 16:30:34 s/because of/because/
+ // might add or remove other listeners, which must not be
+ // taken into account before the next occurrance of the event
Felix Dahlke 2013/10/24 16:30:34 s/occureace/occurence/
+ listeners = listeners.slice(0);
+
+ for (var i = 0; i < listeners.length; i++)
+ listeners[i](tab);
+ },
+ _removeTab: function(tab) {
+ delete this._tabs[tab._id];
+
+ if (Object.keys(this._tabs).length == 0)
+ this.removeListener(this._sharedListener);
+ }
+ };
+
+ var BeforeNavigateTabEventTarget = function() {
+ TabEventTarget.call(this, chrome.tabs.onUpdated);
+ };
+ BeforeNavigateTabEventTarget.prototype = {
+ __proto__: TabEventTarget.prototype,
+ _wrapListener: function(listener) {
+ return function(id, info, tab) {
+ if ("url" in info)
+ listener(new Tab(tab));
+ };
+ }
+ };
+
+ var CompletedTabEventTarget = function() {
+ TabEventTarget.call(this, chrome.tabs.onUpdated);
+ };
+ CompletedTabEventTarget.prototype = {
+ __proto__: TabEventTarget.prototype,
+ _wrapListener: function(listener) {
+ return function(id, info, tab) {
+ if (info.status == "complete")
+ listener(new Tab(tab));
+ };
+ }
+ };
+
+ var ActivatedTabEventTarget = function() {
+ TabEventTarget.call(this, chrome.tabs.onActivated);
+ };
+ ActivatedTabEventTarget.prototype = {
+ __proto__: TabEventTarget.prototype,
+ _wrapListener: function(listener) {
+ return function(info) {
+ chrome.tabs.get(info.tabId, function(tab) {
+ listener(new Tab(tab));
+ });
+ };
+ }
+ }
+
+ var RemovedTabEventTarget = function() {
+ TabEventTarget.call(this, chrome.tabs.onRemoved);
+ };
+ RemovedTabEventTarget.prototype = {
+ __proto__: TabEventTarget.prototype,
+ _wrapListener: function(listener) {
+ return function(id) {
+ listener(new Tab({id: id}));
+ };
+ }
+ };
+
+ var BeforeRequestEventTarget = function() {
+ WrappedEventTarget.call(this, chrome.webRequest.onBeforeRequest);
+ };
+ BeforeRequestEventTarget.prototype = {
+ __proto__: WrappedEventTarget.prototype,
+ _wrapListener: function(listener) {
+ return function(details) {
+ var tab = null;
+
+ if (details.tabId != -1)
+ tab = new Tab({id: details.tabId});
+
+ return {cancel: listener(
+ details.url,
+ details.type,
+ tab,
+ details.frameId,
+ details.parentFrameId
+ ) === false};
+ };
+ },
+ _prepareExtraArguments: function(urls) {
+ return [urls ? {urls: urls} : {}, ["blocking"]];
+ }
+ };
+
+
+ /* Tabs */
+
+ var PageAction = function(tabId) {
+ this._tabId = tabId;
+ };
+ PageAction.prototype = {
+ setIcon: function(path) {
+ chrome.pageAction.setIcon({tabId: this._tabId, path: path});
+ },
+ setTitle: function(title) {
+ chrome.pageAction.setTitle({tabId: this._tabId, title: title});
+ },
+ hide: function() {
+ chrome.pageAction.hide(this._tabId);
+ },
+ show: function() {
+ chrome.pageAction.show(this._tabId);
+ }
+ };
+
+ Tab = function(tab) {
+ this._id = tab.id;
+
+ this.url = tab.url;
+ this.pageAction = new PageAction(tab.id);
+
+ this.onBeforeNavigate = ext.tabs.onBeforeNavigate._bindToTab(this);
+ this.onCompleted = ext.tabs.onCompleted._bindToTab(this);
+ this.onActivated = ext.tabs.onActivated._bindToTab(this);
+ this.onRemoved = ext.tabs.onRemoved._bindToTab(this);
+ };
+ Tab.prototype = {
+ close: function() {
+ chrome.tabs.remove(this._id);
+ },
+ activate: function() {
+ chrome.tabs.update(this._id, {selected: true});
+ },
+ sendMessage: function(message, responseCallback) {
+ chrome.tabs.sendMessage(this._id, message, responseCallback);
+ }
+ };
+
+ TabMap = function() {
+ this._map = {};
+ this.delete = this.delete.bind(this);
+ };
+ TabMap.prototype = {
+ get: function(tab) {
+ return (this._map[tab._id] || {}).value;
+ },
+ set: function(tab, value) {
+ if (!(tab._id in this._map))
+ tab.onRemoved.addListener(this.delete);
+
+ this._map[tab._id] = {tab: tab, value: value};
+ },
+ has: function(tab) {
+ return tab._id in this._map;
+ },
+ clear: function() {
+ for (var id in this._map)
+ this.delete(this._map[id].tab);
+ }
+ };
+ TabMap.prototype["delete"] = function(tab) {
+ delete this._map[tab._id];
+ tab.onRemoved.removeListener(this.delete);
+ };
+
+
+ /* Windows */
+
+ Window = function(win) {
+ this._id = win.id;
+ this.visible = win.status != "minimized";
+ };
+ Window.prototype = {
+ getAllTabs: function(callback) {
+ chrome.tabs.query({windowId: this._id}, function(tabs) {
+ callback(tabs.map(function(tab) {
+ return new Tab(tab);
+ }));
+ });
+ },
+ getActiveTab: function(callback) {
+ chrome.tabs.query({windowId: this._id, active: true}, function(tabs) {
+ callback(new Tab(tabs[0]));
+ });
+ },
+ openTab: function(url, callback) {
+ var props = {windowId: this._id, url: url};
+
+ if (!callback)
+ chrome.tabs.create(props);
+ else
+ chrome.tabs.create(props, function(tab) {
+ callback(new Tab(tab));
+ });
+ }
+ };
+
+
+ /* API */
+
+ ext.windows = {
+ getAll: function(callback) {
+ chrome.windows.getAll(function(windows) {
+ callback(windows.map(function(win) {
+ return new Window(win);
+ }));
+ });
+ },
+ getLastFocused: function(callback) {
+ chrome.windows.getLastFocused(function(win) {
+ callback(new Window(win));
+ });
+ }
+ };
+
+ ext.tabs = {
+ onBeforeNavigate: new BeforeNavigateTabEventTarget(),
+ onCompleted: new CompletedTabEventTarget(),
+ onActivated: new ActivatedTabEventTarget(),
+ onRemoved: new RemovedTabEventTarget()
+ };
+
+ ext.webRequest = {
+ onBeforeRequest: new BeforeRequestEventTarget(),
+ handlerBehaviorChanged: chrome.webRequest.handlerBehaviorChanged
+ };
+})();
« block.js ('K') | « block.js ('k') | chrome/common.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld