Bug 452317 - FeedConverter.js: QueryInterface should throw NS_ERROR_NO_INTERFACE...
[wine-gecko.git] / toolkit / mozapps / handling / content / dialog.js
blob993af9858b6752c24435251fc803f31fd70c34e4
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is the Protocol Handler Dialog.
15  *
16  * The Initial Developer of the Original Code is
17  *   Mozilla Corporation.
18  * Portions created by the Initial Developer are Copyright (C) 2007
19  * the Initial Developer. All Rights Reserved.
20  *
21  * Contributor(s):
22  *   Shawn Wilsher <me@shawnwilsher.com> (original author)
23  *   Dan Mosedale <dmose@mozilla.org>
24  *   Florian Queze <florian@queze.net>
25  *
26  * Alternatively, the contents of this file may be used under the terms of
27  * either the GNU General Public License Version 2 or later (the "GPL"), or
28  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29  * in which case the provisions of the GPL or the LGPL are applicable instead
30  * of those above. If you wish to allow use of your version of this file only
31  * under the terms of either the GPL or the LGPL, and not to allow others to
32  * use your version of this file under the terms of the MPL, indicate your
33  * decision by deleting the provisions above and replace them with the notice
34  * and other provisions required by the GPL or the LGPL. If you do not delete
35  * the provisions above, a recipient may use your version of this file under
36  * the terms of any one of the MPL, the GPL or the LGPL.
37  *
38  * ***** END LICENSE BLOCK ***** */
40 /**
41  * This dialog builds its content based on arguments passed into it.
42  * window.arguments[0]:
43  *   The title of the dialog.
44  * window.arguments[1]:
45  *   The url of the image that appears to the left of the description text
46  * window.arguments[2]:
47  *   The text of the description that will appear above the choices the user
48  *   can choose from.
49  * window.arguments[3]:
50  *   The text of the label directly above the choices the user can choose from.
51  * window.arguments[4]:
52  *   This is the text to be placed in the label for the checkbox.  If no text is
53  *   passed (ie, it's an empty string), the checkbox will be hidden.
54  * window.arguments[5]:
55  *   The accesskey for the checkbox
56  * window.arguments[6]:
57  *   This is the text that is displayed below the checkbox when it is checked.
58  * window.arguments[7]:
59  *   This is the nsIHandlerInfo that gives us all our precious information.
60  * window.arguments[8]:
61  *   This is the nsIURI that we are being brought up for in the first place.
62  * window.arguments[9]:
63  *   The nsIInterfaceRequestor of the parent window; may be null
64  */
66 const Cc = Components.classes;
67 const Ci = Components.interfaces;
68 const Cr = Components.results;
70 var dialog = {
71   //////////////////////////////////////////////////////////////////////////////
72   //// Member Variables
74   _handlerInfo: null,
75   _URI: null,
76   _itemChoose: null,
77   _okButton: null,
78   _windowCtxt: null,
79   
80   //////////////////////////////////////////////////////////////////////////////
81   //// Methods
83  /**
84   * This function initializes the content of the dialog.
85   */
86   initialize: function initialize()
87   {
88     this._handlerInfo = window.arguments[7].QueryInterface(Ci.nsIHandlerInfo);
89     this._URI         = window.arguments[8].QueryInterface(Ci.nsIURI);
90     this._windowCtxt  = window.arguments[9];
91     if (this._windowCtxt)
92       this._windowCtxt.QueryInterface(Ci.nsIInterfaceRequestor);
93     this._itemChoose  = document.getElementById("item-choose");
94     this._okButton    = document.documentElement.getButton("accept");
96     this.updateOKButton();
98     var description = {
99       image: document.getElementById("description-image"),
100       text:  document.getElementById("description-text")
101     };
102     var options = document.getElementById("item-action-text");
103     var checkbox = {
104       desc: document.getElementById("remember"),
105       text:  document.getElementById("remember-text")
106     };
108     // Setting values
109     document.title               = window.arguments[0];
110     description.image.src        = window.arguments[1];
111     description.text.textContent = window.arguments[2];
112     options.value                = window.arguments[3];
113     checkbox.desc.label          = window.arguments[4];
114     checkbox.desc.accessKey      = window.arguments[5];
115     checkbox.text.textContent    = window.arguments[6];
117     // Hide stuff that needs to be hidden
118     if (!checkbox.desc.label)
119       checkbox.desc.hidden = true;
121     // UI is ready, lets populate our list
122     this.populateList();
123   },
125  /**
126   * Populates the list that a user can choose from.
127   */
128   populateList: function populateList()
129   {
130     var items = document.getElementById("items");
131     var possibleHandlers = this._handlerInfo.possibleApplicationHandlers;
132     var preferredHandler = this._handlerInfo.preferredApplicationHandler;
133     var ios = Cc["@mozilla.org/network/io-service;1"].
134               getService(Ci.nsIIOService);
135     for (let i = possibleHandlers.length - 1; i >= 0; --i) {
136       let app = possibleHandlers.queryElementAt(i, Ci.nsIHandlerApp);
137       let elm = document.createElement("richlistitem");
138       elm.setAttribute("type", "handler");
139       elm.setAttribute("name", app.name);
140       elm.obj = app;
142       if (app instanceof Ci.nsILocalHandlerApp) {
143         // See if we have an nsILocalHandlerApp and set the icon
144         let uri = ios.newFileURI(app.executable);
145         elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
146       }
147       else if (app instanceof Ci.nsIWebHandlerApp) {
148         let uri = ios.newURI(app.uriTemplate, null, null);
149         if (/^https?/.test(uri.scheme)) {
150           let iconURI;
151           try {
152             iconURI = Cc["@mozilla.org/browser/favicon-service;1"].
153                       getService(Ci.nsIFaviconService).
154                       getFaviconForPage(ios.newURI(uri.prePath, null, null)).
155                       spec;
156           }
157           catch (e) {
158             iconURI = uri.prePath + "/favicon.ico";
159           }
160           elm.setAttribute("image", iconURI);
161         }
162         elm.setAttribute("description", uri.prePath);
163       }
164       else if (app instanceof Ci.nsIDBusHandlerApp){
165           elm.setAttribute("description", app.method);  
166       }
167       else
168         throw "unknown handler type";
170       items.insertBefore(elm, this._itemChoose);
171       if (preferredHandler && app == preferredHandler)
172         this.selectedItem = elm;
173     }
175     if (this._handlerInfo.hasDefaultHandler) {
176       let elm = document.createElement("richlistitem");
177       elm.setAttribute("type", "handler");
178       elm.id = "os-default-handler";
179       elm.setAttribute("name", this._handlerInfo.defaultDescription);
180     
181       items.insertBefore(elm, items.firstChild);
182       if (this._handlerInfo.preferredAction == 
183           Ci.nsIHandlerInfo.useSystemDefault) 
184           this.selectedItem = elm;
185     }
186     items.ensureSelectedElementIsVisible();
187   },
188   
189  /**
190   * Brings up a filepicker and allows a user to choose an application.
191   */
192   chooseApplication: function chooseApplication()
193   {
194     var bundle = document.getElementById("base-strings");
195     var title = bundle.getString("choose.application.title");
197     var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
198     fp.init(window, title, Ci.nsIFilePicker.modeOpen);
199     fp.appendFilters(Ci.nsIFilePicker.filterApps);
201     if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) {
202       let uri = Cc["@mozilla.org/network/util;1"].
203                 getService(Ci.nsIIOService).
204                 newFileURI(fp.file);
206       let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
207                        createInstance(Ci.nsILocalHandlerApp);
208       handlerApp.executable = fp.file;
210       // if this application is already in the list, select it and don't add it again
211       let parent = document.getElementById("items");
212       for (let i = 0; i < parent.childNodes.length; ++i) {
213         let elm = parent.childNodes[i];
214         if (elm.obj instanceof Ci.nsILocalHandlerApp && elm.obj.equals(handlerApp)) {
215           parent.selectedItem = elm;
216           parent.ensureSelectedElementIsVisible();
217           return;
218         }
219       }
221       let elm = document.createElement("richlistitem");
222       elm.setAttribute("type", "handler");
223       elm.setAttribute("name", fp.file.leafName);
224       elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
225       elm.obj = handlerApp;
227       parent.selectedItem = parent.insertBefore(elm, parent.firstChild);
228       parent.ensureSelectedElementIsVisible();
229     }
230   },
232  /**
233   * Function called when the OK button is pressed.
234   */
235   onAccept: function onAccept()
236   {
237     var checkbox = document.getElementById("remember");
238     if (!checkbox.hidden) {
239       // We need to make sure that the default is properly set now
240       if (this.selectedItem.obj) {
241         // default OS handler doesn't have this property
242         this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
243         this._handlerInfo.preferredApplicationHandler = this.selectedItem.obj;
244       }
245       else
246         this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useSystemDefault;
247     }
248     this._handlerInfo.alwaysAskBeforeHandling = !checkbox.checked;
250     var hs = Cc["@mozilla.org/uriloader/handler-service;1"].
251              getService(Ci.nsIHandlerService);
252     hs.store(this._handlerInfo);
254     this._handlerInfo.launchWithURI(this._URI, this._windowCtxt);
256     return true;
257   },
259  /**
260   * Determines if the OK button should be disabled or not
261   */
262   updateOKButton: function updateOKButton()
263   {
264     this._okButton.disabled = this._itemChoose.selected;
265   },
267  /**
268   * Updates the UI based on the checkbox being checked or not.
269   */
270   onCheck: function onCheck()
271   {
272     if (document.getElementById("remember").checked)
273       document.getElementById("remember-text").setAttribute("visible", "true");
274     else
275       document.getElementById("remember-text").removeAttribute("visible");
276   },
278   /**
279    * Function called when the user double clicks on an item of the list
280    */
281   onDblClick: function onDblClick()
282   {
283     if (this.selectedItem == this._itemChoose)
284       this.chooseApplication();
285     else
286       document.documentElement.acceptDialog();
287   },
289   /////////////////////////////////////////////////////////////////////////////
290   //// Getters / Setters
292  /**
293   * Returns/sets the selected element in the richlistbox
294   */
295   get selectedItem()
296   {
297     return document.getElementById("items").selectedItem;
298   },
299   set selectedItem(aItem)
300   {
301     return document.getElementById("items").selectedItem = aItem;
302   }
303