Components.classes firefox addon WebExtension

Hello. I am writing a Firefox addon using WebExtension. I want to create a hidden iframe, so I have the following code:

var hiddenWindow = Components.classes["@mozilla.org/appshell/appShellService;1"].getService(Components.interfaces.nsIAppShellService).hiddenDOMWindow;

I always get the error “Components.classes is undefined”. I had no luck in finding a solution… Hope someone can help me.

Thank you.

Don’t do this. In WEAPI this isn’t even possible, you can’t run code like this in that scope.

WEAPI

If you are using webextensions use a background page and you don’t have to worry about this: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Anatomy_of_a_WebExtension#Background_scripts

Bootstrap

In bootstrap you can do this, but don’t. In bootstrap use the same tech used by WEAPI which is windowless browsers which are supported since Firefox 23 -

 var webnav = Services.appShell.createWindowlessBrowser(true);
 var docshell = webnav.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDocShell);
 var systemPrincipal = Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal);
 docshell.createAboutBlankContentViewer(systemPrincipal);
 var contentWindow = docshell.contentViewer.DOMDocument.defaultView;

 // when you are done with it, destroy it
 if (webnav.close) { webnav.close() }; // only available in Firefox 46+, and is needed for good measure
 webnav = null; // in Firefox <= 45 setting to null will cause it to get GC'ed which will destroy it

Here’s another example, this is how webextenions use this code above:

let chromeWebNav = Services.appShell.createWindowlessBrowser(true);
this.chromeWebNav = chromeWebNav;

let url;
if (this.page) {
  url = this.extension.baseURI.resolve(this.page);
} else {
  // TODO: Chrome uses "_generated_background_page.html" for this.
  url = this.extension.baseURI.resolve("_blank.html");
}

if (!this.extension.isExtensionURL(url)) {
  this.extension.manifestError("Background page must be a file within the extension");
  url = this.extension.baseURI.resolve("_blank.html");
}

let system = Services.scriptSecurityManager.getSystemPrincipal();

let chromeShell = chromeWebNav.QueryInterface(Ci.nsIInterfaceRequestor)
                              .getInterface(Ci.nsIDocShell);
chromeShell.createAboutBlankContentViewer(system);

let chromeDoc = chromeWebNav.document;
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let browser = chromeDoc.createElementNS(XUL_NS, "browser");
browser.setAttribute("type", "content");
browser.setAttribute("disableglobalhistory", "true");
browser.setAttribute("webextension-view-type", "background");
chromeDoc.body.appendChild(browser);

let frameLoader = browser.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader;
let docShell = frameLoader.docShell;

let webNav = docShell.QueryInterface(Ci.nsIWebNavigation);
this.webNav = webNav;

webNav.loadURI(url, 0, null, null, null);

let window = webNav.document.defaultView;
this.contentWindow = window;

https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/ext-backgroundPage.js#25-64

3 Likes

Thanks a lot.