mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 785920 - reload for workers. r=gavin.sharp
This commit is contained in:
parent
31d9b62d0d
commit
ccbe60c88d
@ -71,24 +71,39 @@ function FrameWorker(url, name) {
|
||||
this.loaded = false;
|
||||
|
||||
this.frame = makeHiddenFrame();
|
||||
|
||||
var self = this;
|
||||
Services.obs.addObserver(function injectController(doc, topic, data) {
|
||||
if (!doc.defaultView || doc.defaultView != self.frame.contentWindow) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(injectController, "document-element-inserted", false);
|
||||
try {
|
||||
self.createSandbox();
|
||||
} catch (e) {
|
||||
Cu.reportError("FrameWorker: failed to create sandbox for " + url + ". " + e);
|
||||
}
|
||||
}, "document-element-inserted", false);
|
||||
|
||||
this.frame.setAttribute("src", url);
|
||||
this.load();
|
||||
}
|
||||
|
||||
FrameWorker.prototype = {
|
||||
load: function FrameWorker_loadWorker() {
|
||||
var self = this;
|
||||
Services.obs.addObserver(function injectController(doc, topic, data) {
|
||||
if (!doc.defaultView || doc.defaultView != self.frame.contentWindow) {
|
||||
return;
|
||||
}
|
||||
Services.obs.removeObserver(injectController, "document-element-inserted", false);
|
||||
try {
|
||||
self.createSandbox();
|
||||
} catch (e) {
|
||||
Cu.reportError("FrameWorker: failed to create sandbox for " + url + ". " + e);
|
||||
}
|
||||
}, "document-element-inserted", false);
|
||||
|
||||
this.frame.setAttribute("src", this.url);
|
||||
},
|
||||
|
||||
reload: function FrameWorker_reloadWorker() {
|
||||
// push all the ports into pending ports, they will be re-entangled
|
||||
// during the call to createSandbox after the document is reloaded
|
||||
for (let [portid, port] in Iterator(this.ports)) {
|
||||
port._window = null;
|
||||
this.pendingPorts.push(port);
|
||||
}
|
||||
this.ports = {};
|
||||
this.loaded = false;
|
||||
this.load();
|
||||
},
|
||||
|
||||
createSandbox: function createSandbox() {
|
||||
let workerWindow = this.frame.contentWindow;
|
||||
let sandbox = new Cu.Sandbox(workerWindow);
|
||||
@ -139,10 +154,10 @@ FrameWorker.prototype = {
|
||||
|
||||
// and we delegate ononline and onoffline events to the worker.
|
||||
// See http://www.whatwg.org/specs/web-apps/current-work/multipage/workers.html#workerglobalscope
|
||||
this.frame.addEventListener('offline', function fw_onoffline(event) {
|
||||
workerWindow.addEventListener('offline', function fw_onoffline(event) {
|
||||
Cu.evalInSandbox("onoffline();", sandbox);
|
||||
}, false);
|
||||
this.frame.addEventListener('online', function fw_ononline(event) {
|
||||
workerWindow.addEventListener('online', function fw_ononline(event) {
|
||||
Cu.evalInSandbox("ononline();", sandbox);
|
||||
}, false);
|
||||
|
||||
@ -248,15 +263,12 @@ function makeHiddenFrame() {
|
||||
return iframe;
|
||||
}
|
||||
|
||||
// public methods on WorkerHandle should conform to the SharedWorker api
|
||||
function WorkerHandle(port, worker) {
|
||||
this.port = port;
|
||||
this._worker = worker;
|
||||
}
|
||||
WorkerHandle.prototype = {
|
||||
get document() {
|
||||
return this._worker.frame.contentDocument;
|
||||
},
|
||||
|
||||
// XXX - workers have no .close() method, but *do* have a .terminate()
|
||||
// method which we should implement. However, the worker spec doesn't define
|
||||
// a callback to be made in the worker when this happens - it all just dies.
|
||||
|
@ -27,9 +27,6 @@ function WorkerAPI(provider, port) {
|
||||
// used for the api.
|
||||
// later we might even include an API version - version 0 for now!
|
||||
this._port.postMessage({topic: "social.initialize"});
|
||||
|
||||
// backwards compat, remove after Aug 1.
|
||||
this._port.postMessage({topic: "social.cookie-changed"});
|
||||
}
|
||||
|
||||
WorkerAPI.prototype = {
|
||||
@ -52,6 +49,13 @@ WorkerAPI.prototype = {
|
||||
},
|
||||
|
||||
handlers: {
|
||||
"social.reload-worker": function(data) {
|
||||
getFrameWorkerHandle(this._provider.workerURL, null)._worker.reload();
|
||||
// the frameworker is going to be reloaded, send the initialization
|
||||
// so it can have the same startup sequence as if it were loaded
|
||||
// the first time. This will be queued until the frameworker is ready.
|
||||
this._port.postMessage({topic: "social.initialize"});
|
||||
},
|
||||
"social.user-profile": function (data) {
|
||||
this._provider.updateUserProfile(data);
|
||||
},
|
||||
@ -59,7 +63,8 @@ WorkerAPI.prototype = {
|
||||
this._provider.setAmbientNotification(data);
|
||||
},
|
||||
"social.cookies-get": function(data) {
|
||||
let document = getFrameWorkerHandle(this._provider.workerURL, null).document;
|
||||
let document = getFrameWorkerHandle(this._provider.workerURL, null).
|
||||
_worker.frame.contentDocument;
|
||||
let cookies = document.cookie.split(";");
|
||||
let results = [];
|
||||
cookies.forEach(function(aCookie) {
|
||||
|
@ -102,6 +102,43 @@ let tests = {
|
||||
Services.cookies.add('.example.com', '/', 'cheez', 'burger', false, false, true, MAX_EXPIRY);
|
||||
port.postMessage({topic: "test-initialization"});
|
||||
port.postMessage({topic: "test.cookies-get"});
|
||||
}
|
||||
},
|
||||
|
||||
testWorkerReload: function(next) {
|
||||
let fw = {};
|
||||
Cu.import("resource://gre/modules/FrameWorker.jsm", fw);
|
||||
|
||||
// get a real handle to the worker so we can watch the unload event
|
||||
// we watch for the unload of the worker to know it is infact being
|
||||
// unloaded, after that if we get worker.connected we know that
|
||||
// the worker was loaded again and ports reconnected
|
||||
let reloading = false;
|
||||
let worker = fw.getFrameWorkerHandle(provider.workerURL, undefined, "testWorkerReload");
|
||||
let win = worker._worker.frame.contentWindow;
|
||||
win.addEventListener("unload", function workerUnload(e) {
|
||||
win.removeEventListener("unload", workerUnload);
|
||||
ok(true, "worker unload event has fired");
|
||||
reloading = true;
|
||||
});
|
||||
let port = provider.getWorkerPort();
|
||||
ok(port, "provider has a port");
|
||||
port.onmessage = function (e) {
|
||||
let topic = e.data.topic;
|
||||
switch (topic) {
|
||||
case "test-initialization-complete":
|
||||
// tell the worker to send the reload msg
|
||||
port.postMessage({topic: "test-reload-init"});
|
||||
break;
|
||||
case "worker.connected":
|
||||
// we'll get this message from the worker on every load of the worker,
|
||||
// so we need to ignore it unless we have requested the reload.
|
||||
if (reloading) {
|
||||
ok(true, "worker reloaded and testPort was reconnected");
|
||||
next();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
port.postMessage({topic: "test-initialization"});
|
||||
}
|
||||
};
|
||||
|
@ -33,6 +33,17 @@ onconnect = function(e) {
|
||||
break;
|
||||
case "social.cookies-get-response":
|
||||
testerPort.postMessage({topic: "test.cookies-get-response", data: data});
|
||||
break;
|
||||
case "test-reload-init":
|
||||
// browser_social_sidebar.js started test, tell the sidebar to
|
||||
// start
|
||||
apiPort.postMessage({topic: 'social.reload-worker'});
|
||||
break;
|
||||
}
|
||||
}
|
||||
// used for "test-reload-worker"
|
||||
if (apiPort && apiPort != port) {
|
||||
port.postMessage({topic: "worker.connected"})
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user