|
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/. */ |
|
4 |
|
5 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); |
|
6 |
|
7 //////////////////////////////////////////////////////////////////////////////// |
|
8 //// Constants |
|
9 |
|
10 const Ci = Components.interfaces; |
|
11 const Cr = Components.results; |
|
12 const Cc = Components.classes; |
|
13 |
|
14 //////////////////////////////////////////////////////////////////////////////// |
|
15 //// nsWebHandler class |
|
16 |
|
17 function nsWebHandlerApp() {} |
|
18 |
|
19 nsWebHandlerApp.prototype = { |
|
20 ////////////////////////////////////////////////////////////////////////////// |
|
21 //// nsWebHandler |
|
22 |
|
23 classDescription: "A web handler for protocols and content", |
|
24 classID: Components.ID("8b1ae382-51a9-4972-b930-56977a57919d"), |
|
25 contractID: "@mozilla.org/uriloader/web-handler-app;1", |
|
26 |
|
27 _name: null, |
|
28 _detailedDescription: null, |
|
29 _uriTemplate: null, |
|
30 |
|
31 ////////////////////////////////////////////////////////////////////////////// |
|
32 //// nsIHandlerApp |
|
33 |
|
34 get name() { |
|
35 return this._name; |
|
36 }, |
|
37 |
|
38 set name(aName) { |
|
39 this._name = aName; |
|
40 }, |
|
41 |
|
42 get detailedDescription() { |
|
43 return this._detailedDescription; |
|
44 }, |
|
45 |
|
46 set detailedDescription(aDesc) { |
|
47 this._detailedDescription = aDesc; |
|
48 }, |
|
49 |
|
50 equals: function(aHandlerApp) { |
|
51 if (!aHandlerApp) |
|
52 throw Cr.NS_ERROR_NULL_POINTER; |
|
53 |
|
54 if (aHandlerApp instanceof Ci.nsIWebHandlerApp && |
|
55 aHandlerApp.uriTemplate && |
|
56 this.uriTemplate && |
|
57 aHandlerApp.uriTemplate == this.uriTemplate) |
|
58 return true; |
|
59 |
|
60 return false; |
|
61 }, |
|
62 |
|
63 launchWithURI: function nWHA__launchWithURI(aURI, aWindowContext) { |
|
64 |
|
65 // XXX need to strip passwd & username from URI to handle, as per the |
|
66 // WhatWG HTML5 draft. nsSimpleURL, which is what we're going to get, |
|
67 // can't do this directly. Ideally, we'd fix nsStandardURL to make it |
|
68 // possible to turn off all of its quirks handling, and use that... |
|
69 |
|
70 // encode the URI to be handled |
|
71 var escapedUriSpecToHandle = encodeURIComponent(aURI.spec); |
|
72 |
|
73 // insert the encoded URI and create the object version |
|
74 var uriSpecToSend = this.uriTemplate.replace("%s", escapedUriSpecToHandle); |
|
75 var ioService = Cc["@mozilla.org/network/io-service;1"]. |
|
76 getService(Ci.nsIIOService); |
|
77 var uriToSend = ioService.newURI(uriSpecToSend, null, null); |
|
78 |
|
79 // if we have a window context, use the URI loader to load there |
|
80 if (aWindowContext) { |
|
81 |
|
82 // create a channel from this URI |
|
83 var channel = ioService.newChannelFromURI(uriToSend); |
|
84 channel.loadFlags = Ci.nsIChannel.LOAD_DOCUMENT_URI; |
|
85 |
|
86 // load the channel |
|
87 var uriLoader = Cc["@mozilla.org/uriloader;1"]. |
|
88 getService(Ci.nsIURILoader); |
|
89 // XXX ideally, whether to pass the IS_CONTENT_PREFERRED flag should be |
|
90 // passed in from above. Practically, the flag is probably a reasonable |
|
91 // default since browsers don't care much, and link click is likely to be |
|
92 // the more interesting case for non-browser apps. See |
|
93 // <https://bugzilla.mozilla.org/show_bug.cgi?id=392957#c9> for details. |
|
94 uriLoader.openURI(channel, Ci.nsIURILoader.IS_CONTENT_PREFERRED, |
|
95 aWindowContext); |
|
96 return; |
|
97 } |
|
98 |
|
99 // since we don't have a window context, hand it off to a browser |
|
100 var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]. |
|
101 getService(Ci.nsIWindowMediator); |
|
102 |
|
103 // get browser dom window |
|
104 var browserDOMWin = windowMediator.getMostRecentWindow("navigator:browser") |
|
105 .QueryInterface(Ci.nsIDOMChromeWindow) |
|
106 .browserDOMWindow; |
|
107 |
|
108 // if we got an exception, there are several possible reasons why: |
|
109 // a) this gecko embedding doesn't provide an nsIBrowserDOMWindow |
|
110 // implementation (i.e. doesn't support browser-style functionality), |
|
111 // so we need to kick the URL out to the OS default browser. This is |
|
112 // the subject of bug 394479. |
|
113 // b) this embedding does provide an nsIBrowserDOMWindow impl, but |
|
114 // there doesn't happen to be a browser window open at the moment; one |
|
115 // should be opened. It's not clear whether this situation will really |
|
116 // ever occur in real life. If it does, the only API that I can find |
|
117 // that seems reasonably likely to work for most embedders is the |
|
118 // command line handler. |
|
119 // c) something else went wrong |
|
120 // |
|
121 // it's not clear how one would differentiate between the three cases |
|
122 // above, so for now we don't catch the exception |
|
123 |
|
124 // openURI |
|
125 browserDOMWin.openURI(uriToSend, |
|
126 null, // no window.opener |
|
127 Ci.nsIBrowserDOMWindow.OPEN_DEFAULTWINDOW, |
|
128 Ci.nsIBrowserDOMWindow.OPEN_NEW); |
|
129 |
|
130 return; |
|
131 }, |
|
132 |
|
133 ////////////////////////////////////////////////////////////////////////////// |
|
134 //// nsIWebHandlerApp |
|
135 |
|
136 get uriTemplate() { |
|
137 return this._uriTemplate; |
|
138 }, |
|
139 |
|
140 set uriTemplate(aURITemplate) { |
|
141 this._uriTemplate = aURITemplate; |
|
142 }, |
|
143 |
|
144 ////////////////////////////////////////////////////////////////////////////// |
|
145 //// nsISupports |
|
146 |
|
147 QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebHandlerApp, Ci.nsIHandlerApp]) |
|
148 }; |
|
149 |
|
150 //////////////////////////////////////////////////////////////////////////////// |
|
151 //// Module |
|
152 |
|
153 this.NSGetFactory = XPCOMUtils.generateNSGetFactory([nsWebHandlerApp]); |
|
154 |