Bug 1066433 - Make shims work when contentWindow is unavailable (r=mconley)

This commit is contained in:
Bill McCloskey 2014-09-15 16:42:27 -07:00
parent 19ad8ca141
commit b0e50c22c2
2 changed files with 60 additions and 6 deletions

View File

@ -627,19 +627,69 @@ RemoteBrowserElementInterposition.getters.docShell = function(addon, target) {
return remoteChromeGlobal.docShell;
};
// We use this in place of the real browser.contentWindow if we
// haven't yet received a CPOW for the child process's window. This
// happens if the tab has just started loading.
function makeDummyContentWindow(browser) {
let dummyContentWindow = {
set location(url) {
browser.loadURI(url, null, null);
}
};
return dummyContentWindow;
}
RemoteBrowserElementInterposition.getters.contentWindow = function(addon, target) {
// If we don't have a CPOW yet, just return something we can use for
// setting the location. This is useful for tests that create a tab
// and immediately set contentWindow.location.
if (!target.contentWindowAsCPOW) {
return makeDummyContentWindow(target);
}
return target.contentWindowAsCPOW;
};
let DummyContentDocument = {
readyState: "loading"
};
RemoteBrowserElementInterposition.getters.contentDocument = function(addon, target) {
// If we don't have a CPOW yet, just return something we can use to
// examine readyState. This is useful for tests that create a new
// tab and then immediately start polling readyState.
if (!target.contentDocumentAsCPOW) {
return DummyContentDocument;
}
return target.contentDocumentAsCPOW;
};
let TabBrowserElementInterposition = new Interposition("TabBrowserElementInterposition",
EventTargetInterposition);
TabBrowserElementInterposition.getters.contentWindow = function(addon, target) {
if (!target.selectedBrowser.contentWindowAsCPOW) {
return makeDummyContentWindow(target.selectedBrowser);
}
return target.selectedBrowser.contentWindowAsCPOW;
};
TabBrowserElementInterposition.getters.contentDocument = function(addon, target) {
let browser = target.selectedBrowser;
if (!browser.contentDocumentAsCPOW) {
return DummyContentDocument;
}
return browser.contentDocumentAsCPOW;
};
let ChromeWindowInterposition = new Interposition("ChromeWindowInterposition",
EventTargetInterposition);
ChromeWindowInterposition.getters.content = function(addon, target) {
return target.gBrowser.selectedBrowser.contentWindowAsCPOW;
let browser = target.gBrowser.selectedBrowser;
if (!browser.contentWindowAsCPOW) {
return makeDummyContentWindow(browser);
}
return browser.contentWindowAsCPOW;
};
let RemoteAddonsParent = {
@ -677,6 +727,7 @@ let RemoteAddonsParent = {
register("ContentDocShellTreeItem", ContentDocShellTreeItemInterposition);
register("ContentDocument", ContentDocumentInterposition);
register("RemoteBrowserElement", RemoteBrowserElementInterposition);
register("TabBrowserElement", TabBrowserElementInterposition);
register("ChromeWindow", ChromeWindowInterposition);
return result;

View File

@ -87,11 +87,14 @@ AddonInterpositionService.prototype = {
}
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
if ((target instanceof Ci.nsIDOMXULElement) &&
target.localName == "browser" &&
target.namespaceURI == XUL_NS &&
target.getAttribute("remote") == "true") {
return "RemoteBrowserElement";
if (target instanceof Ci.nsIDOMXULElement) {
if (target.localName == "browser" && target.isRemoteBrowser) {
return "RemoteBrowserElement";
}
if (target.localName == "tabbrowser") {
return "TabBrowserElement";
}
}
if (target instanceof Ci.nsIDOMChromeWindow) {