|
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 /** |
|
6 * This dialog builds its content based on arguments passed into it. |
|
7 * window.arguments[0]: |
|
8 * The title of the dialog. |
|
9 * window.arguments[1]: |
|
10 * The url of the image that appears to the left of the description text |
|
11 * window.arguments[2]: |
|
12 * The text of the description that will appear above the choices the user |
|
13 * can choose from. |
|
14 * window.arguments[3]: |
|
15 * The text of the label directly above the choices the user can choose from. |
|
16 * window.arguments[4]: |
|
17 * This is the text to be placed in the label for the checkbox. If no text is |
|
18 * passed (ie, it's an empty string), the checkbox will be hidden. |
|
19 * window.arguments[5]: |
|
20 * The accesskey for the checkbox |
|
21 * window.arguments[6]: |
|
22 * This is the text that is displayed below the checkbox when it is checked. |
|
23 * window.arguments[7]: |
|
24 * This is the nsIHandlerInfo that gives us all our precious information. |
|
25 * window.arguments[8]: |
|
26 * This is the nsIURI that we are being brought up for in the first place. |
|
27 * window.arguments[9]: |
|
28 * The nsIInterfaceRequestor of the parent window; may be null |
|
29 */ |
|
30 |
|
31 const Cc = Components.classes; |
|
32 const Ci = Components.interfaces; |
|
33 const Cr = Components.results; |
|
34 |
|
35 var dialog = { |
|
36 ////////////////////////////////////////////////////////////////////////////// |
|
37 //// Member Variables |
|
38 |
|
39 _handlerInfo: null, |
|
40 _URI: null, |
|
41 _itemChoose: null, |
|
42 _okButton: null, |
|
43 _windowCtxt: null, |
|
44 |
|
45 ////////////////////////////////////////////////////////////////////////////// |
|
46 //// Methods |
|
47 |
|
48 /** |
|
49 * This function initializes the content of the dialog. |
|
50 */ |
|
51 initialize: function initialize() |
|
52 { |
|
53 this._handlerInfo = window.arguments[7].QueryInterface(Ci.nsIHandlerInfo); |
|
54 this._URI = window.arguments[8].QueryInterface(Ci.nsIURI); |
|
55 this._windowCtxt = window.arguments[9]; |
|
56 if (this._windowCtxt) |
|
57 this._windowCtxt.QueryInterface(Ci.nsIInterfaceRequestor); |
|
58 this._itemChoose = document.getElementById("item-choose"); |
|
59 this._okButton = document.documentElement.getButton("accept"); |
|
60 |
|
61 this.updateOKButton(); |
|
62 |
|
63 var description = { |
|
64 image: document.getElementById("description-image"), |
|
65 text: document.getElementById("description-text") |
|
66 }; |
|
67 var options = document.getElementById("item-action-text"); |
|
68 var checkbox = { |
|
69 desc: document.getElementById("remember"), |
|
70 text: document.getElementById("remember-text") |
|
71 }; |
|
72 |
|
73 // Setting values |
|
74 document.title = window.arguments[0]; |
|
75 description.image.src = window.arguments[1]; |
|
76 description.text.textContent = window.arguments[2]; |
|
77 options.value = window.arguments[3]; |
|
78 checkbox.desc.label = window.arguments[4]; |
|
79 checkbox.desc.accessKey = window.arguments[5]; |
|
80 checkbox.text.textContent = window.arguments[6]; |
|
81 |
|
82 // Hide stuff that needs to be hidden |
|
83 if (!checkbox.desc.label) |
|
84 checkbox.desc.hidden = true; |
|
85 |
|
86 // UI is ready, lets populate our list |
|
87 this.populateList(); |
|
88 }, |
|
89 |
|
90 /** |
|
91 * Populates the list that a user can choose from. |
|
92 */ |
|
93 populateList: function populateList() |
|
94 { |
|
95 var items = document.getElementById("items"); |
|
96 var possibleHandlers = this._handlerInfo.possibleApplicationHandlers; |
|
97 var preferredHandler = this._handlerInfo.preferredApplicationHandler; |
|
98 var ios = Cc["@mozilla.org/network/io-service;1"]. |
|
99 getService(Ci.nsIIOService); |
|
100 for (let i = possibleHandlers.length - 1; i >= 0; --i) { |
|
101 let app = possibleHandlers.queryElementAt(i, Ci.nsIHandlerApp); |
|
102 let elm = document.createElement("richlistitem"); |
|
103 elm.setAttribute("type", "handler"); |
|
104 elm.setAttribute("name", app.name); |
|
105 elm.obj = app; |
|
106 |
|
107 if (app instanceof Ci.nsILocalHandlerApp) { |
|
108 // See if we have an nsILocalHandlerApp and set the icon |
|
109 let uri = ios.newFileURI(app.executable); |
|
110 elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32"); |
|
111 } |
|
112 else if (app instanceof Ci.nsIWebHandlerApp) { |
|
113 let uri = ios.newURI(app.uriTemplate, null, null); |
|
114 if (/^https?/.test(uri.scheme)) { |
|
115 // Unfortunately we can't use the favicon service to get the favicon, |
|
116 // because the service looks for a record with the exact URL we give |
|
117 // it, and users won't have such records for URLs they don't visit, |
|
118 // and users won't visit the handler's URL template, they'll only |
|
119 // visit URLs derived from that template (i.e. with %s in the template |
|
120 // replaced by the URL of the content being handled). |
|
121 elm.setAttribute("image", uri.prePath + "/favicon.ico"); |
|
122 } |
|
123 elm.setAttribute("description", uri.prePath); |
|
124 } |
|
125 else if (app instanceof Ci.nsIDBusHandlerApp){ |
|
126 elm.setAttribute("description", app.method); |
|
127 } |
|
128 else |
|
129 throw "unknown handler type"; |
|
130 |
|
131 items.insertBefore(elm, this._itemChoose); |
|
132 if (preferredHandler && app == preferredHandler) |
|
133 this.selectedItem = elm; |
|
134 } |
|
135 |
|
136 if (this._handlerInfo.hasDefaultHandler) { |
|
137 let elm = document.createElement("richlistitem"); |
|
138 elm.setAttribute("type", "handler"); |
|
139 elm.id = "os-default-handler"; |
|
140 elm.setAttribute("name", this._handlerInfo.defaultDescription); |
|
141 |
|
142 items.insertBefore(elm, items.firstChild); |
|
143 if (this._handlerInfo.preferredAction == |
|
144 Ci.nsIHandlerInfo.useSystemDefault) |
|
145 this.selectedItem = elm; |
|
146 } |
|
147 items.ensureSelectedElementIsVisible(); |
|
148 }, |
|
149 |
|
150 /** |
|
151 * Brings up a filepicker and allows a user to choose an application. |
|
152 */ |
|
153 chooseApplication: function chooseApplication() |
|
154 { |
|
155 var bundle = document.getElementById("base-strings"); |
|
156 var title = bundle.getString("choose.application.title"); |
|
157 |
|
158 var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); |
|
159 fp.init(window, title, Ci.nsIFilePicker.modeOpen); |
|
160 fp.appendFilters(Ci.nsIFilePicker.filterApps); |
|
161 |
|
162 if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) { |
|
163 let uri = Cc["@mozilla.org/network/util;1"]. |
|
164 getService(Ci.nsIIOService). |
|
165 newFileURI(fp.file); |
|
166 |
|
167 let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]. |
|
168 createInstance(Ci.nsILocalHandlerApp); |
|
169 handlerApp.executable = fp.file; |
|
170 |
|
171 // if this application is already in the list, select it and don't add it again |
|
172 let parent = document.getElementById("items"); |
|
173 for (let i = 0; i < parent.childNodes.length; ++i) { |
|
174 let elm = parent.childNodes[i]; |
|
175 if (elm.obj instanceof Ci.nsILocalHandlerApp && elm.obj.equals(handlerApp)) { |
|
176 parent.selectedItem = elm; |
|
177 parent.ensureSelectedElementIsVisible(); |
|
178 return; |
|
179 } |
|
180 } |
|
181 |
|
182 let elm = document.createElement("richlistitem"); |
|
183 elm.setAttribute("type", "handler"); |
|
184 elm.setAttribute("name", fp.file.leafName); |
|
185 elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32"); |
|
186 elm.obj = handlerApp; |
|
187 |
|
188 parent.selectedItem = parent.insertBefore(elm, parent.firstChild); |
|
189 parent.ensureSelectedElementIsVisible(); |
|
190 } |
|
191 }, |
|
192 |
|
193 /** |
|
194 * Function called when the OK button is pressed. |
|
195 */ |
|
196 onAccept: function onAccept() |
|
197 { |
|
198 var checkbox = document.getElementById("remember"); |
|
199 if (!checkbox.hidden) { |
|
200 // We need to make sure that the default is properly set now |
|
201 if (this.selectedItem.obj) { |
|
202 // default OS handler doesn't have this property |
|
203 this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp; |
|
204 this._handlerInfo.preferredApplicationHandler = this.selectedItem.obj; |
|
205 } |
|
206 else |
|
207 this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useSystemDefault; |
|
208 } |
|
209 this._handlerInfo.alwaysAskBeforeHandling = !checkbox.checked; |
|
210 |
|
211 var hs = Cc["@mozilla.org/uriloader/handler-service;1"]. |
|
212 getService(Ci.nsIHandlerService); |
|
213 hs.store(this._handlerInfo); |
|
214 |
|
215 this._handlerInfo.launchWithURI(this._URI, this._windowCtxt); |
|
216 |
|
217 return true; |
|
218 }, |
|
219 |
|
220 /** |
|
221 * Determines if the OK button should be disabled or not |
|
222 */ |
|
223 updateOKButton: function updateOKButton() |
|
224 { |
|
225 this._okButton.disabled = this._itemChoose.selected; |
|
226 }, |
|
227 |
|
228 /** |
|
229 * Updates the UI based on the checkbox being checked or not. |
|
230 */ |
|
231 onCheck: function onCheck() |
|
232 { |
|
233 if (document.getElementById("remember").checked) |
|
234 document.getElementById("remember-text").setAttribute("visible", "true"); |
|
235 else |
|
236 document.getElementById("remember-text").removeAttribute("visible"); |
|
237 }, |
|
238 |
|
239 /** |
|
240 * Function called when the user double clicks on an item of the list |
|
241 */ |
|
242 onDblClick: function onDblClick() |
|
243 { |
|
244 if (this.selectedItem == this._itemChoose) |
|
245 this.chooseApplication(); |
|
246 else |
|
247 document.documentElement.acceptDialog(); |
|
248 }, |
|
249 |
|
250 ///////////////////////////////////////////////////////////////////////////// |
|
251 //// Getters / Setters |
|
252 |
|
253 /** |
|
254 * Returns/sets the selected element in the richlistbox |
|
255 */ |
|
256 get selectedItem() |
|
257 { |
|
258 return document.getElementById("items").selectedItem; |
|
259 }, |
|
260 set selectedItem(aItem) |
|
261 { |
|
262 return document.getElementById("items").selectedItem = aItem; |
|
263 } |
|
264 |
|
265 }; |