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

Unified Diff: safari/ext/background.js

Issue 5220277533278208: Made the bubble use the ext object from the background page instead of including ext/background.js (Closed)
Patch Set: Rebased and moved imports to the bottom Created Jan. 15, 2014, 4:38 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 | « popup.html ('k') | safari/ext/popup.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
@@ -188,307 +188,305 @@
}
};
- if (safari.extension.globalPage.contentWindow == window)
- {
- /* Background page proxy */
- var proxy = {
- tabs: [],
- objects: [],
+ /* Background page proxy */
- registerObject: function(obj, objects)
+ var proxy = {
+ tabs: [],
+ objects: [],
+
+ registerObject: function(obj, objects)
+ {
+ var objectId = objects.indexOf(obj);
+
+ if (objectId == -1)
+ objectId = objects.push(obj) - 1;
+
+ return objectId;
+ },
+ serializeSequence: function(sequence, objects, memo)
+ {
+ if (!memo)
+ memo = {specs: [], arrays: []};
+
+ var items = [];
+ for (var i = 0; i < sequence.length; i++)
+ items.push(this.serialize(sequence[i], objects, memo));
+
+ return items;
+ },
+ serialize: function(obj, objects, memo)
+ {
+ if (typeof obj == "object" && obj != null || typeof obj == "function")
{
- var objectId = objects.indexOf(obj);
+ if (obj.constructor == Array)
+ {
+ if (!memo)
+ memo = {specs: [], arrays: []};
- if (objectId == -1)
- objectId = objects.push(obj) - 1;
+ var idx = memo.arrays.indexOf(obj);
+ if (idx != -1)
+ return memo.specs[idx];
- return objectId;
- },
- serializeSequence: function(sequence, objects, memo)
+ var spec = {type: "array"};
+ memo.specs.push(spec);
+ memo.arrays.push(obj);
+
+ spec.items = this.serializeSequence(obj, objects, memo);
+ return spec;
+ }
+
+ if (obj.constructor != Date && obj.constructor != RegExp)
+ return {type: "object", objectId: this.registerObject(obj, objects)};
+ }
+
+ return {type: "value", value: obj};
+ },
+ createCallback: function(callbackId, tab)
+ {
+ var proxy = this;
+
+ return function()
{
- if (!memo)
- memo = {specs: [], arrays: []};
+ var idx = proxy.tabs.indexOf(tab);
- var items = [];
- for (var i = 0; i < sequence.length; i++)
- items.push(this.serialize(sequence[i], objects, memo));
+ if (idx != -1) {
+ var objects = proxy.objects[idx];
- return items;
- },
- serialize: function(obj, objects, memo)
+ tab.page.dispatchMessage("proxyCallback",
+ {
+ callbackId: callbackId,
+ contextId: proxy.registerObject(this, objects),
+ args: proxy.serializeSequence(arguments, objects)
+ });
+ }
+ };
+ },
+ deserialize: function(spec, objects, tab, memo)
+ {
+ switch (spec.type)
{
- if (typeof obj == "object" && obj != null || typeof obj == "function")
+ case "value":
+ return spec.value;
+ case "hosted":
+ return objects[spec.objectId];
+ case "callback":
+ return this.createCallback(spec.callbackId, tab);
+ case "object":
+ case "array":
+ if (!memo)
+ memo = {specs: [], objects: []};
+
+ var idx = memo.specs.indexOf(spec);
+ if (idx != -1)
+ return memo.objects[idx];
+
+ var obj;
+ if (spec.type == "array")
+ obj = [];
+ else
+ obj = {};
+
+ memo.specs.push(spec);
+ memo.objects.push(obj);
+
+ if (spec.type == "array")
+ for (var i = 0; i < spec.items.length; i++)
+ obj.push(this.deserialize(spec.items[i], objects, tab, memo));
+ else
+ for (var k in spec.properties)
+ obj[k] = this.deserialize(spec.properties[k], objects, tab, memo);
+
+ return obj;
+ }
+ },
+ createObjectCache: function(tab)
+ {
+ var objects = [window];
+
+ this.tabs.push(tab);
+ this.objects.push(objects);
+
+ tab.addEventListener("close", function()
+ {
+ var idx = this.tabs.indexOf(tab);
+
+ if (idx != -1)
{
- if (obj.constructor == Array)
+ this.tabs.splice(idx, 1);
+ this.objects.splice(idx, 1);
+ }
+ }.bind(this));
+
+ return objects;
+ },
+ getObjectCache: function(tab)
+ {
+ var idx = this.tabs.indexOf(tab);
+ var objects;
+
+ if (idx != -1)
+ objects = this.objects[idx];
+ else
+ objects = this.objects[idx] = this.createObjectCache(tab);
+
+ return objects;
+ },
+ fail: function(error)
+ {
+ if (error instanceof Error)
+ error = error.message;
+ return {succeed: false, error: error};
+ },
+ _handleMessage: function(message, tab)
+ {
+ var objects = this.getObjectCache(tab);
+
+ switch (message.type)
+ {
+ case "getProperty":
+ var obj = objects[message.objectId];
+
+ try
{
- if (!memo)
- memo = {specs: [], arrays: []};
-
- var idx = memo.arrays.indexOf(obj);
- if (idx != -1)
- return memo.specs[idx];
-
- var spec = {type: "array"};
- memo.specs.push(spec);
- memo.arrays.push(obj);
-
- spec.items = this.serializeSequence(obj, objects, memo);
- return spec;
+ var value = obj[message.property];
+ }
+ catch (e)
+ {
+ return this.fail(e);
}
- if (obj.constructor != Date && obj.constructor != RegExp)
- return {type: "object", objectId: this.registerObject(obj, objects)};
+ return {succeed: true, result: this.serialize(value, objects)};
+ case "setProperty":
+ var obj = objects[message.objectId];
+ var value = this.deserialize(message.value, objects, tab);
+
+ try
+ {
+ obj[message.property] = value;
+ }
+ catch (e)
+ {
+ return this.fail(e);
+ }
+
+ return {succeed: true};
+ case "callFunction":
+ var func = objects[message.functionId];
+ var context = objects[message.contextId];
+
+ var args = [];
+ for (var i = 0; i < message.args.length; i++)
+ args.push(this.deserialize(message.args[i], objects, tab));
+
+ try
+ {
+ var result = func.apply(context, args);
+ }
+ catch (e)
+ {
+ return this.fail(e);
+ }
+
+ return {succeed: true, result: this.serialize(result, objects)};
+ case "inspectObject":
+ var obj = objects[message.objectId];
+ var objectInfo = {properties: {}, isFunction: typeof obj == "function"};
+
+ Object.getOwnPropertyNames(obj).forEach(function(prop)
+ {
+ objectInfo.properties[prop] = {
+ enumerable: Object.prototype.propertyIsEnumerable.call(obj, prop)
+ };
+ });
+
+ if (obj.__proto__)
+ objectInfo.prototypeId = this.registerObject(obj.__proto__, objects);
+
+ if (obj == Object.prototype)
+ objectInfo.prototypeOf = "Object";
+ if (obj == Function.prototype)
+ objectInfo.prototypeOf = "Function";
+
+ return objectInfo;
+ }
+ }
+ };
+
+
+ /* Web request blocking */
+
+ ext.webRequest = {
+ onBeforeRequest: {
+ _listeners: [],
+ _urlPatterns: [],
+
+ _handleMessage: function(message, tab)
+ {
+ tab = new Tab(tab);
+
+ 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)
+ return false;
}
- return {type: "value", value: obj};
+ return true;
},
- createCallback: function(callbackId, tab)
+ addListener: function(listener, urls)
{
- var proxy = this;
+ var regex;
- return function()
- {
- var idx = proxy.tabs.indexOf(tab);
+ if (urls)
+ regex = new RegExp("^(?:" + urls.map(function(url)
+ {
+ return url.split("*").map(function(s)
+ {
+ return s.replace(/([.?+^$[\]\\(){}|-])/g, "\\$1");
+ }).join(".*");
+ }).join("|") + ")($|[?#])");
- if (idx != -1) {
- var objects = proxy.objects[idx];
-
- tab.page.dispatchMessage("proxyCallback",
- {
- callbackId: callbackId,
- contextId: proxy.registerObject(this, objects),
- args: proxy.serializeSequence(arguments, objects)
- });
- }
- };
+ this._listeners.push(listener);
+ this._urlPatterns.push(regex);
},
- deserialize: function(spec, objects, tab, memo)
+ removeListener: function(listener)
{
- switch (spec.type)
- {
- case "value":
- return spec.value;
- case "hosted":
- return objects[spec.objectId];
- case "callback":
- return this.createCallback(spec.callbackId, tab);
- case "object":
- case "array":
- if (!memo)
- memo = {specs: [], objects: []};
-
- var idx = memo.specs.indexOf(spec);
- if (idx != -1)
- return memo.objects[idx];
-
- var obj;
- if (spec.type == "array")
- obj = [];
- else
- obj = {};
-
- memo.specs.push(spec);
- memo.objects.push(obj);
-
- if (spec.type == "array")
- for (var i = 0; i < spec.items.length; i++)
- obj.push(this.deserialize(spec.items[i], objects, tab, memo));
- else
- for (var k in spec.properties)
- obj[k] = this.deserialize(spec.properties[k], objects, tab, memo);
-
- return obj;
- }
- },
- createObjectCache: function(tab)
- {
- var objects = [window];
-
- this.tabs.push(tab);
- this.objects.push(objects);
-
- tab.addEventListener("close", function()
- {
- var idx = this.tabs.indexOf(tab);
-
- if (idx != -1)
- {
- this.tabs.splice(idx, 1);
- this.objects.splice(idx, 1);
- }
- }.bind(this));
-
- return objects;
- },
- getObjectCache: function(tab)
- {
- var idx = this.tabs.indexOf(tab);
- var objects;
+ var idx = this._listeners.indexOf(listener);
if (idx != -1)
- objects = this.objects[idx];
- else
- objects = this.objects[idx] = this.createObjectCache(tab);
-
- return objects;
- },
- fail: function(error)
- {
- if (error instanceof Error)
- error = error.message;
- return {succeed: false, error: error};
- },
- _handleMessage: function(message, tab)
- {
- var objects = this.getObjectCache(tab);
-
- switch (message.type)
{
- case "getProperty":
- var obj = objects[message.objectId];
-
- try
- {
- var value = obj[message.property];
- }
- catch (e)
- {
- return this.fail(e);
- }
-
- return {succeed: true, result: this.serialize(value, objects)};
- case "setProperty":
- var obj = objects[message.objectId];
- var value = this.deserialize(message.value, objects, tab);
-
- try
- {
- obj[message.property] = value;
- }
- catch (e)
- {
- return this.fail(e);
- }
-
- return {succeed: true};
- case "callFunction":
- var func = objects[message.functionId];
- var context = objects[message.contextId];
-
- var args = [];
- for (var i = 0; i < message.args.length; i++)
- args.push(this.deserialize(message.args[i], objects, tab));
-
- try
- {
- var result = func.apply(context, args);
- }
- catch (e)
- {
- return this.fail(e);
- }
-
- return {succeed: true, result: this.serialize(result, objects)};
- case "inspectObject":
- var obj = objects[message.objectId];
- var objectInfo = {properties: {}, isFunction: typeof obj == "function"};
-
- Object.getOwnPropertyNames(obj).forEach(function(prop)
- {
- objectInfo.properties[prop] = {
- enumerable: Object.prototype.propertyIsEnumerable.call(obj, prop)
- };
- });
-
- if (obj.__proto__)
- objectInfo.prototypeId = this.registerObject(obj.__proto__, objects);
-
- if (obj == Object.prototype)
- objectInfo.prototypeOf = "Object";
- if (obj == Function.prototype)
- objectInfo.prototypeOf = "Function";
-
- return objectInfo;
+ this._listeners.splice(idx, 1);
+ this._urlPatterns.splice(idx, 1);
}
}
- };
+ },
+ handlerBehaviorChanged: function() {}
+ };
- /* Web request blocking */
+ /* Synchronous messaging */
- ext.webRequest = {
- onBeforeRequest: {
- _listeners: [],
- _urlPatterns: [],
+ safari.application.addEventListener("message", function(event)
+ {
+ if (event.name == "canLoad")
+ {
+ var handler;
- _handleMessage: function(message, tab)
- {
- tab = new Tab(tab);
+ switch (event.message.type)
+ {
+ case "proxy":
+ handler = proxy;
+ break;
+ case "webRequest":
+ handler = ext.webRequest.onBeforeRequest;
+ break;
+ }
- 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)
- return false;
- }
-
- return true;
- },
- addListener: function(listener, urls)
- {
- 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() {}
- };
-
-
- /* Synchronous messaging */
-
- safari.application.addEventListener("message", function(event)
- {
- if (event.name == "canLoad")
- {
- var handler;
-
- switch (event.message.type)
- {
- case "proxy":
- handler = proxy;
- break;
- case "webRequest":
- handler = ext.webRequest.onBeforeRequest;
- break;
- }
-
- event.message = handler._handleMessage(event.message.payload, event.target);
- }
- }, true);
- }
+ event.message = handler._handleMessage(event.message.payload, event.target);
+ }
+ }, true);
/* API */
@@ -528,15 +526,4 @@
create: function(title, contexts, onclick) {},
removeAll: function(callback) {}
};
-
- // Safari will load the bubble once, and then show it everytime the icon is
- // clicked. While Chrome loads it everytime you click the icon. So in order to
- // force the same behavior in Safari, we are going to reload the page of the
- // bubble everytime it is shown.
- if (safari.extension.globalPage.contentWindow != window)
- safari.application.addEventListener("popover", function()
- {
- document.documentElement.style.display = "none";
- document.location.reload();
- }, true);
})();
« no previous file with comments | « popup.html ('k') | safari/ext/popup.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld