Bug 1146926: Allow attaching a worker to a CPOW window without invoking CPOW operations. r=gabor

By sending the CPOW to the child processes the one that owns it will create the
child worker and then send back the url of the window to set up the parent
side of the worker.

There are two breaking changes here. Workers invoked in this way no longer
attach synchronously. We no longer pass the window through the attach event.

--HG--
extra : commitid : By30pJI1Lj9
extra : rebase_source : bbca0c512d9fb135d2ca9d5ad263e3f8f6c297b3
extra : histedit_source : e50c90e0f20d60ad94949758b28721301c52d60c
This commit is contained in:
Dave Townsend 2015-11-18 16:33:16 -08:00
Родитель 25404c599e
Коммит 53e0d3bab8
3 изменённых файлов: 32 добавлений и 38 удалений

Просмотреть файл

@ -134,12 +134,12 @@ function exceptions(key, value) {
// workers for windows in this tab
var keepAlive = new Map();
process.port.on('sdk/worker/create', (process, options) => {
options.window = getByInnerId(options.windowId);
if (!options.window)
return;
process.port.on('sdk/worker/create', (process, options, cpows) => {
options.window = cpows.window;
let worker = new WorkerChild(options);
let frame = frames.getFrameForWindow(options.window.top);
frame.port.emit('sdk/worker/connect', options.id, options.window.location.href);
});
when(reason => {

Просмотреть файл

@ -116,29 +116,21 @@ const Worker = Class({
exports.Worker = Worker;
attach.define(Worker, function(worker, window) {
// This method of attaching should be deprecated
if (Cu.isCrossProcessWrapper(window))
throw new Error("Attaching worker to a window from another " +
"process directly is not supported.");
let model = modelFor(worker);
if (model.attached)
detach(worker);
model.window = window;
let frame = null;
let tab = getTabForContentWindowNoShim(window);
if (tab)
frame = frames.getFrameForBrowser(getBrowserForTab(tab));
let childOptions = makeChildOptions(model.options);
childOptions.windowId = getInnerId(window);
processes.port.emitCPOW('sdk/worker/create', [childOptions], { window });
processes.port.emit('sdk/worker/create', childOptions);
connect(worker, frame, { id: childOptions.id, url: String(window.location) });
})
let listener = (frame, id, url) => {
if (id != childOptions.id)
return;
frames.port.off('sdk/worker/connect', listener);
connect(worker, frame, { id, url });
};
frames.port.on('sdk/worker/connect', listener);
});
connect.define(Worker, function(worker, frame, { id, url }) {
let model = modelFor(worker);
@ -159,7 +151,7 @@ connect.define(Worker, function(worker, frame, { id, url }) {
model.earlyEvents.forEach(args => worker.send(...args));
model.earlyEvents = [];
emit(worker, 'attach', model.window);
emit(worker, 'attach');
});
// unload and release the child worker, release window reference
@ -171,7 +163,6 @@ detach.define(Worker, function(worker) {
processes.port.off('sdk/worker/event', worker.receive);
model.attached = false;
model.destroyed = true;
model.window = null;
emit(worker, 'detach');
});

Просмотреть файл

@ -118,14 +118,15 @@ exports["test:sample"] = WorkerTest(
assert.equal(worker.url, window.location.href,
"worker.url still works");
done();
},
onAttach: function() {
assert.equal(worker.url, window.location.href,
"worker.url works");
assert.equal(worker.contentURL, window.location.href,
"worker.contentURL works");
worker.postMessage("hi!");
}
});
assert.equal(worker.url, window.location.href,
"worker.url works");
assert.equal(worker.contentURL, window.location.href,
"worker.contentURL works");
worker.postMessage("hi!");
}
);
@ -841,10 +842,9 @@ exports["test:worker events"] = WorkerTest(
contentScript: 'new ' + function WorkerScope() {
self.postMessage('start');
},
onAttach: win => {
onAttach: () => {
events.push('attach');
assert.pass('attach event called when attached');
assert.equal(window, win, 'attach event passes in attached window');
},
onError: err => {
assert.equal(err.message, 'Custom',
@ -876,13 +876,16 @@ exports["test:onDetach in contentScript on destroy"] = WorkerTest(
window.location.hash += '!' + reason;
})
},
onAttach: function() {
browser.contentWindow.addEventListener('hashchange', _ => {
assert.equal(browser.contentWindow.location.hash, '#detach!',
"location.href is as expected");
done();
})
worker.destroy();
}
});
browser.contentWindow.addEventListener('hashchange', _ => {
assert.equal(browser.contentWindow.location.hash, '#detach!',
"location.href is as expected");
done();
})
worker.destroy();
}
);