1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
7 ChromeUtils.defineModuleGetter(
9 "PrivateBrowsingUtils",
10 "resource://gre/modules/PrivateBrowsingUtils.jsm"
13 function nsWebHandlerApp() {}
15 nsWebHandlerApp.prototype = {
16 classDescription: "A web handler for protocols and content",
17 classID: Components.ID("8b1ae382-51a9-4972-b930-56977a57919d"),
18 contractID: "@mozilla.org/uriloader/web-handler-app;1",
19 QueryInterface: ChromeUtils.generateQI(["nsIWebHandlerApp", "nsIHandlerApp"]),
22 _detailedDescription: null,
35 get detailedDescription() {
36 return this._detailedDescription;
39 set detailedDescription(aDesc) {
40 this._detailedDescription = aDesc;
45 throw Components.Exception("", Cr.NS_ERROR_NULL_POINTER);
49 aHandlerApp instanceof Ci.nsIWebHandlerApp &&
50 aHandlerApp.uriTemplate &&
52 aHandlerApp.uriTemplate == this.uriTemplate
59 launchWithURI(aURI, aBrowsingContext) {
60 // XXX need to strip passwd & username from URI to handle, as per the
61 // WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get,
62 // can't do this directly. Ideally, we'd fix nsStandardURL to make it
63 // possible to turn off all of its quirks handling, and use that...
65 // encode the URI to be handled
66 var escapedUriSpecToHandle = encodeURIComponent(aURI.spec);
68 // insert the encoded URI and create the object version.
69 var uriSpecToSend = this.uriTemplate.replace("%s", escapedUriSpecToHandle);
70 var uriToSend = Services.io.newURI(uriSpecToSend);
72 let policy = WebExtensionPolicy.getByURI(uriToSend);
73 let privateAllowed = !policy || policy.privateBrowsingAllowed;
75 // If we're in a frame, check if we're a built-in scheme, in which case,
76 // override the target browsingcontext. It's not a good idea to try to
77 // load mail clients or other apps with potential for logged in data into
78 // iframes, and in any case it's unlikely to work due to framing
79 // restrictions employed by the target site.
80 if (aBrowsingContext && aBrowsingContext != aBrowsingContext.top) {
81 let { scheme } = aURI;
82 if (!scheme.startsWith("web+") && !scheme.startsWith("ext+")) {
83 aBrowsingContext = null;
87 // if we have a context, use the URI loader to load there
88 if (aBrowsingContext) {
89 if (aBrowsingContext.usePrivateBrowsing && !privateAllowed) {
90 throw Components.Exception(
91 "Extension not allowed in private windows.",
92 Cr.NS_ERROR_FILE_NOT_FOUND
96 let triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
97 Services.tm.dispatchToMainThread(() =>
98 aBrowsingContext.loadURI(uriSpecToSend, { triggeringPrincipal })
103 let win = Services.wm.getMostRecentWindow("navigator:browser");
105 // If this is an extension handler, check private browsing access.
106 if (!privateAllowed && PrivateBrowsingUtils.isWindowPrivate(win)) {
107 throw Components.Exception(
108 "Extension not allowed in private windows.",
109 Cr.NS_ERROR_FILE_NOT_FOUND
113 // If we get an exception, there are several possible reasons why:
114 // a) this gecko embedding doesn't provide an nsIBrowserDOMWindow
115 // implementation (i.e. doesn't support browser-style functionality),
116 // so we need to kick the URL out to the OS default browser. This is
117 // the subject of bug 394479.
118 // b) this embedding does provide an nsIBrowserDOMWindow impl, but
119 // there doesn't happen to be a browser window open at the moment; one
120 // should be opened. It's not clear whether this situation will really
121 // ever occur in real life. If it does, the only API that I can find
122 // that seems reasonably likely to work for most embedders is the
123 // command line handler.
124 // c) something else went wrong
126 // It's not clear how one would differentiate between the three cases
127 // above, so for now we don't catch the exception.
130 win.browserDOMWindow.openURI(
132 null, // no window.opener
133 Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW,
134 Ci.nsIBrowserDOMWindow.OPEN_NEW,
135 Services.scriptSecurityManager.getSystemPrincipal()
142 return this._uriTemplate;
145 set uriTemplate(aURITemplate) {
146 this._uriTemplate = aURITemplate;
150 var EXPORTED_SYMBOLS = ["nsWebHandlerApp"];