Fix Bug 1509755 - Wait for browser initialization to finish before adding CFR trigger listeners (#4580)
This commit is contained in:
Родитель
35b5b9a35d
Коммит
abb7a49a25
|
@ -430,7 +430,7 @@ class _ASRouter {
|
|||
const unseenListeners = new Set(ASRouterTriggerListeners.keys());
|
||||
for (const {trigger} of newState.messages) {
|
||||
if (trigger && ASRouterTriggerListeners.has(trigger.id)) {
|
||||
ASRouterTriggerListeners.get(trigger.id).init(this._triggerHandler, trigger.params);
|
||||
await ASRouterTriggerListeners.get(trigger.id).init(this._triggerHandler, trigger.params);
|
||||
unseenListeners.delete(trigger.id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,30 @@ this.ASRouterTriggerListeners = new Map([
|
|||
_triggerHandler: null,
|
||||
_hosts: null,
|
||||
|
||||
/**
|
||||
* Wait for browser startup to finish to avoid accessing uninitialized
|
||||
* properties
|
||||
*/
|
||||
async _checkStartupFinished(win) {
|
||||
if (!win.gBrowserInit.delayedStartupFinished) {
|
||||
await new Promise(resolve => {
|
||||
let delayedStartupObserver = (subject, topic) => {
|
||||
if (topic === "browser-delayed-startup-finished" && subject === win) {
|
||||
Services.obs.removeObserver(delayedStartupObserver, "browser-delayed-startup-finished");
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
|
||||
Services.obs.addObserver(delayedStartupObserver, "browser-delayed-startup-finished");
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* If the listener is already initialised, `init` will replace the trigger
|
||||
* handler and add any new hosts to `this._hosts`.
|
||||
*/
|
||||
init(triggerHandler, hosts = []) {
|
||||
async init(triggerHandler, hosts = []) {
|
||||
if (!this._initialized) {
|
||||
this.onLocationChange = this.onLocationChange.bind(this);
|
||||
|
||||
|
@ -40,6 +59,7 @@ this.ASRouterTriggerListeners = new Map([
|
|||
if (win.closed || PrivateBrowsingUtils.isWindowPrivate(win)) {
|
||||
continue;
|
||||
}
|
||||
await this._checkStartupFinished(win);
|
||||
win.gBrowser.addTabsProgressListener(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ describe("ASRouterTriggerListeners", () => {
|
|||
sandbox = sinon.createSandbox();
|
||||
registerWindowNotificationStub = sandbox.stub(global.Services.ww, "registerNotification");
|
||||
unregisterWindoNotificationStub = sandbox.stub(global.Services.ww, "unregisterNotification");
|
||||
existingWindow = {gBrowser: {addTabsProgressListener: sandbox.stub(), removeTabsProgressListener: sandbox.stub()}};
|
||||
existingWindow = {gBrowser: {addTabsProgressListener: sandbox.stub(), removeTabsProgressListener: sandbox.stub()}, gBrowserInit: {delayedStartupFinished: true}};
|
||||
windowEnumeratorStub = sandbox.stub(global.Services.wm, "getEnumerator");
|
||||
resetEnumeratorStub([existingWindow]);
|
||||
sandbox.spy(openURLListener, "init");
|
||||
|
@ -37,8 +37,8 @@ describe("ASRouterTriggerListeners", () => {
|
|||
});
|
||||
|
||||
describe("#init", () => {
|
||||
beforeEach(() => {
|
||||
openURLListener.init(triggerHandler, hosts);
|
||||
beforeEach(async () => {
|
||||
await openURLListener.init(triggerHandler, hosts);
|
||||
});
|
||||
afterEach(() => {
|
||||
openURLListener.uninit();
|
||||
|
@ -77,8 +77,8 @@ describe("ASRouterTriggerListeners", () => {
|
|||
});
|
||||
|
||||
describe("#uninit", () => {
|
||||
beforeEach(() => {
|
||||
openURLListener.init(triggerHandler, hosts);
|
||||
beforeEach(async () => {
|
||||
await openURLListener.init(triggerHandler, hosts);
|
||||
// Ensure that the window enumerator will return the existing window for uninit as well
|
||||
resetEnumeratorStub([existingWindow]);
|
||||
openURLListener.uninit();
|
||||
|
@ -113,9 +113,13 @@ describe("ASRouterTriggerListeners", () => {
|
|||
});
|
||||
|
||||
describe("#onLocationChange", () => {
|
||||
it("should call the ._triggerHandler with the right arguments", () => {
|
||||
afterEach(() => {
|
||||
openURLListener.uninit();
|
||||
});
|
||||
|
||||
it("should call the ._triggerHandler with the right arguments", async () => {
|
||||
const newTriggerHandler = sinon.stub();
|
||||
openURLListener.init(newTriggerHandler, hosts);
|
||||
await openURLListener.init(newTriggerHandler, hosts);
|
||||
|
||||
const browser = {};
|
||||
const webProgress = {isTopLevel: true};
|
||||
|
@ -125,5 +129,21 @@ describe("ASRouterTriggerListeners", () => {
|
|||
assert.calledWithExactly(newTriggerHandler, browser, {id: "openURL", param: "www.mozilla.org"});
|
||||
});
|
||||
});
|
||||
|
||||
describe("delayed startup finished", () => {
|
||||
beforeEach(() => {
|
||||
existingWindow.gBrowserInit.delayedStartupFinished = false;
|
||||
sandbox.stub(global.Services.obs, "addObserver").callsFake(fn => fn(existingWindow, "browser-delayed-startup-finished"));
|
||||
});
|
||||
afterEach(() => {
|
||||
openURLListener.uninit();
|
||||
});
|
||||
|
||||
it("should wait for startup and then add the tabs listener", async () => {
|
||||
await openURLListener.init(triggerHandler, hosts);
|
||||
|
||||
assert.calledOnce(existingWindow.gBrowser.addTabsProgressListener);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче