1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/mozapps/handling/content/dialog.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,265 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/** 1.9 + * This dialog builds its content based on arguments passed into it. 1.10 + * window.arguments[0]: 1.11 + * The title of the dialog. 1.12 + * window.arguments[1]: 1.13 + * The url of the image that appears to the left of the description text 1.14 + * window.arguments[2]: 1.15 + * The text of the description that will appear above the choices the user 1.16 + * can choose from. 1.17 + * window.arguments[3]: 1.18 + * The text of the label directly above the choices the user can choose from. 1.19 + * window.arguments[4]: 1.20 + * This is the text to be placed in the label for the checkbox. If no text is 1.21 + * passed (ie, it's an empty string), the checkbox will be hidden. 1.22 + * window.arguments[5]: 1.23 + * The accesskey for the checkbox 1.24 + * window.arguments[6]: 1.25 + * This is the text that is displayed below the checkbox when it is checked. 1.26 + * window.arguments[7]: 1.27 + * This is the nsIHandlerInfo that gives us all our precious information. 1.28 + * window.arguments[8]: 1.29 + * This is the nsIURI that we are being brought up for in the first place. 1.30 + * window.arguments[9]: 1.31 + * The nsIInterfaceRequestor of the parent window; may be null 1.32 + */ 1.33 + 1.34 +const Cc = Components.classes; 1.35 +const Ci = Components.interfaces; 1.36 +const Cr = Components.results; 1.37 + 1.38 +var dialog = { 1.39 + ////////////////////////////////////////////////////////////////////////////// 1.40 + //// Member Variables 1.41 + 1.42 + _handlerInfo: null, 1.43 + _URI: null, 1.44 + _itemChoose: null, 1.45 + _okButton: null, 1.46 + _windowCtxt: null, 1.47 + 1.48 + ////////////////////////////////////////////////////////////////////////////// 1.49 + //// Methods 1.50 + 1.51 + /** 1.52 + * This function initializes the content of the dialog. 1.53 + */ 1.54 + initialize: function initialize() 1.55 + { 1.56 + this._handlerInfo = window.arguments[7].QueryInterface(Ci.nsIHandlerInfo); 1.57 + this._URI = window.arguments[8].QueryInterface(Ci.nsIURI); 1.58 + this._windowCtxt = window.arguments[9]; 1.59 + if (this._windowCtxt) 1.60 + this._windowCtxt.QueryInterface(Ci.nsIInterfaceRequestor); 1.61 + this._itemChoose = document.getElementById("item-choose"); 1.62 + this._okButton = document.documentElement.getButton("accept"); 1.63 + 1.64 + this.updateOKButton(); 1.65 + 1.66 + var description = { 1.67 + image: document.getElementById("description-image"), 1.68 + text: document.getElementById("description-text") 1.69 + }; 1.70 + var options = document.getElementById("item-action-text"); 1.71 + var checkbox = { 1.72 + desc: document.getElementById("remember"), 1.73 + text: document.getElementById("remember-text") 1.74 + }; 1.75 + 1.76 + // Setting values 1.77 + document.title = window.arguments[0]; 1.78 + description.image.src = window.arguments[1]; 1.79 + description.text.textContent = window.arguments[2]; 1.80 + options.value = window.arguments[3]; 1.81 + checkbox.desc.label = window.arguments[4]; 1.82 + checkbox.desc.accessKey = window.arguments[5]; 1.83 + checkbox.text.textContent = window.arguments[6]; 1.84 + 1.85 + // Hide stuff that needs to be hidden 1.86 + if (!checkbox.desc.label) 1.87 + checkbox.desc.hidden = true; 1.88 + 1.89 + // UI is ready, lets populate our list 1.90 + this.populateList(); 1.91 + }, 1.92 + 1.93 + /** 1.94 + * Populates the list that a user can choose from. 1.95 + */ 1.96 + populateList: function populateList() 1.97 + { 1.98 + var items = document.getElementById("items"); 1.99 + var possibleHandlers = this._handlerInfo.possibleApplicationHandlers; 1.100 + var preferredHandler = this._handlerInfo.preferredApplicationHandler; 1.101 + var ios = Cc["@mozilla.org/network/io-service;1"]. 1.102 + getService(Ci.nsIIOService); 1.103 + for (let i = possibleHandlers.length - 1; i >= 0; --i) { 1.104 + let app = possibleHandlers.queryElementAt(i, Ci.nsIHandlerApp); 1.105 + let elm = document.createElement("richlistitem"); 1.106 + elm.setAttribute("type", "handler"); 1.107 + elm.setAttribute("name", app.name); 1.108 + elm.obj = app; 1.109 + 1.110 + if (app instanceof Ci.nsILocalHandlerApp) { 1.111 + // See if we have an nsILocalHandlerApp and set the icon 1.112 + let uri = ios.newFileURI(app.executable); 1.113 + elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32"); 1.114 + } 1.115 + else if (app instanceof Ci.nsIWebHandlerApp) { 1.116 + let uri = ios.newURI(app.uriTemplate, null, null); 1.117 + if (/^https?/.test(uri.scheme)) { 1.118 + // Unfortunately we can't use the favicon service to get the favicon, 1.119 + // because the service looks for a record with the exact URL we give 1.120 + // it, and users won't have such records for URLs they don't visit, 1.121 + // and users won't visit the handler's URL template, they'll only 1.122 + // visit URLs derived from that template (i.e. with %s in the template 1.123 + // replaced by the URL of the content being handled). 1.124 + elm.setAttribute("image", uri.prePath + "/favicon.ico"); 1.125 + } 1.126 + elm.setAttribute("description", uri.prePath); 1.127 + } 1.128 + else if (app instanceof Ci.nsIDBusHandlerApp){ 1.129 + elm.setAttribute("description", app.method); 1.130 + } 1.131 + else 1.132 + throw "unknown handler type"; 1.133 + 1.134 + items.insertBefore(elm, this._itemChoose); 1.135 + if (preferredHandler && app == preferredHandler) 1.136 + this.selectedItem = elm; 1.137 + } 1.138 + 1.139 + if (this._handlerInfo.hasDefaultHandler) { 1.140 + let elm = document.createElement("richlistitem"); 1.141 + elm.setAttribute("type", "handler"); 1.142 + elm.id = "os-default-handler"; 1.143 + elm.setAttribute("name", this._handlerInfo.defaultDescription); 1.144 + 1.145 + items.insertBefore(elm, items.firstChild); 1.146 + if (this._handlerInfo.preferredAction == 1.147 + Ci.nsIHandlerInfo.useSystemDefault) 1.148 + this.selectedItem = elm; 1.149 + } 1.150 + items.ensureSelectedElementIsVisible(); 1.151 + }, 1.152 + 1.153 + /** 1.154 + * Brings up a filepicker and allows a user to choose an application. 1.155 + */ 1.156 + chooseApplication: function chooseApplication() 1.157 + { 1.158 + var bundle = document.getElementById("base-strings"); 1.159 + var title = bundle.getString("choose.application.title"); 1.160 + 1.161 + var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); 1.162 + fp.init(window, title, Ci.nsIFilePicker.modeOpen); 1.163 + fp.appendFilters(Ci.nsIFilePicker.filterApps); 1.164 + 1.165 + if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) { 1.166 + let uri = Cc["@mozilla.org/network/util;1"]. 1.167 + getService(Ci.nsIIOService). 1.168 + newFileURI(fp.file); 1.169 + 1.170 + let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"]. 1.171 + createInstance(Ci.nsILocalHandlerApp); 1.172 + handlerApp.executable = fp.file; 1.173 + 1.174 + // if this application is already in the list, select it and don't add it again 1.175 + let parent = document.getElementById("items"); 1.176 + for (let i = 0; i < parent.childNodes.length; ++i) { 1.177 + let elm = parent.childNodes[i]; 1.178 + if (elm.obj instanceof Ci.nsILocalHandlerApp && elm.obj.equals(handlerApp)) { 1.179 + parent.selectedItem = elm; 1.180 + parent.ensureSelectedElementIsVisible(); 1.181 + return; 1.182 + } 1.183 + } 1.184 + 1.185 + let elm = document.createElement("richlistitem"); 1.186 + elm.setAttribute("type", "handler"); 1.187 + elm.setAttribute("name", fp.file.leafName); 1.188 + elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32"); 1.189 + elm.obj = handlerApp; 1.190 + 1.191 + parent.selectedItem = parent.insertBefore(elm, parent.firstChild); 1.192 + parent.ensureSelectedElementIsVisible(); 1.193 + } 1.194 + }, 1.195 + 1.196 + /** 1.197 + * Function called when the OK button is pressed. 1.198 + */ 1.199 + onAccept: function onAccept() 1.200 + { 1.201 + var checkbox = document.getElementById("remember"); 1.202 + if (!checkbox.hidden) { 1.203 + // We need to make sure that the default is properly set now 1.204 + if (this.selectedItem.obj) { 1.205 + // default OS handler doesn't have this property 1.206 + this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp; 1.207 + this._handlerInfo.preferredApplicationHandler = this.selectedItem.obj; 1.208 + } 1.209 + else 1.210 + this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useSystemDefault; 1.211 + } 1.212 + this._handlerInfo.alwaysAskBeforeHandling = !checkbox.checked; 1.213 + 1.214 + var hs = Cc["@mozilla.org/uriloader/handler-service;1"]. 1.215 + getService(Ci.nsIHandlerService); 1.216 + hs.store(this._handlerInfo); 1.217 + 1.218 + this._handlerInfo.launchWithURI(this._URI, this._windowCtxt); 1.219 + 1.220 + return true; 1.221 + }, 1.222 + 1.223 + /** 1.224 + * Determines if the OK button should be disabled or not 1.225 + */ 1.226 + updateOKButton: function updateOKButton() 1.227 + { 1.228 + this._okButton.disabled = this._itemChoose.selected; 1.229 + }, 1.230 + 1.231 + /** 1.232 + * Updates the UI based on the checkbox being checked or not. 1.233 + */ 1.234 + onCheck: function onCheck() 1.235 + { 1.236 + if (document.getElementById("remember").checked) 1.237 + document.getElementById("remember-text").setAttribute("visible", "true"); 1.238 + else 1.239 + document.getElementById("remember-text").removeAttribute("visible"); 1.240 + }, 1.241 + 1.242 + /** 1.243 + * Function called when the user double clicks on an item of the list 1.244 + */ 1.245 + onDblClick: function onDblClick() 1.246 + { 1.247 + if (this.selectedItem == this._itemChoose) 1.248 + this.chooseApplication(); 1.249 + else 1.250 + document.documentElement.acceptDialog(); 1.251 + }, 1.252 + 1.253 + ///////////////////////////////////////////////////////////////////////////// 1.254 + //// Getters / Setters 1.255 + 1.256 + /** 1.257 + * Returns/sets the selected element in the richlistbox 1.258 + */ 1.259 + get selectedItem() 1.260 + { 1.261 + return document.getElementById("items").selectedItem; 1.262 + }, 1.263 + set selectedItem(aItem) 1.264 + { 1.265 + return document.getElementById("items").selectedItem = aItem; 1.266 + } 1.267 + 1.268 +};