summaryrefslogtreecommitdiffstats
path: root/toolkit/components/apppicker
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/apppicker')
-rw-r--r--toolkit/components/apppicker/content/appPicker.js226
-rw-r--r--toolkit/components/apppicker/content/appPicker.xhtml44
-rw-r--r--toolkit/components/apppicker/jar.mn8
-rw-r--r--toolkit/components/apppicker/moz.build10
4 files changed, 288 insertions, 0 deletions
diff --git a/toolkit/components/apppicker/content/appPicker.js b/toolkit/components/apppicker/content/appPicker.js
new file mode 100644
index 0000000000..70227c4276
--- /dev/null
+++ b/toolkit/components/apppicker/content/appPicker.js
@@ -0,0 +1,226 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+
+function AppPicker() {}
+
+AppPicker.prototype = {
+ // Class members
+ _incomingParams: null,
+
+ /**
+ * Init the dialog and populate the application list
+ */
+ appPickerLoad: function appPickerLoad() {
+ const nsILocalHandlerApp = Ci.nsILocalHandlerApp;
+
+ document.addEventListener("dialogaccept", function() {
+ g_dialog.appPickerOK();
+ });
+ document.addEventListener("dialogcancel", function() {
+ g_dialog.appPickerCancel();
+ });
+ document.addEventListener("dialogextra2", function() {
+ g_dialog.appPickerBrowse();
+ });
+
+ this._incomingParams = window.arguments[0];
+ this._incomingParams.handlerApp = null;
+
+ document.title = this._incomingParams.title;
+
+ // Header creation - at the very least, we must have
+ // a mime type:
+ //
+ // (icon) Zip File
+ // (icon) filename
+ //
+ // (icon) Web Feed
+ // (icon) mime/type
+ //
+ // (icon) mime/type
+ // (icon)
+
+ var mimeInfo = this._incomingParams.mimeInfo;
+ var filename = this._incomingParams.filename;
+ if (!filename) {
+ filename = mimeInfo.MIMEType;
+ }
+ var description = this._incomingParams.description;
+ if (!description) {
+ description = filename;
+ filename = "";
+ }
+
+ // Setup the dialog header information
+ document
+ .getElementById("content-description")
+ .setAttribute("value", description);
+ document
+ .getElementById("suggested-filename")
+ .setAttribute("value", filename || "");
+ document
+ .getElementById("content-icon")
+ .setAttribute(
+ "src",
+ "moz-icon://" + filename + "?size=32&contentType=" + mimeInfo.MIMEType
+ );
+
+ // Grab a list of nsILocalHandlerApp application helpers to list
+ var fileList = mimeInfo.possibleLocalHandlers;
+
+ var list = document.getElementById("app-picker-listbox");
+
+ var primaryCount = 0;
+
+ if (!fileList || !fileList.length) {
+ // display a message saying nothing is configured
+ document.getElementById("app-picker-notfound").removeAttribute("hidden");
+ return;
+ }
+
+ for (var idx = 0; idx < fileList.length; idx++) {
+ var file = fileList.queryElementAt(idx, nsILocalHandlerApp);
+ try {
+ if (!file.executable || !file.executable.isFile()) {
+ continue;
+ }
+ } catch (err) {
+ continue;
+ }
+
+ var item = document.createXULElement("richlistitem");
+ item.handlerApp = file;
+ list.appendChild(item);
+
+ var image = document.createXULElement("image");
+ image.setAttribute("src", this.getFileIconURL(file.executable));
+ item.appendChild(image);
+
+ var label = document.createXULElement("label");
+ label.setAttribute("value", this.getFileDisplayName(file.executable));
+ item.appendChild(label);
+
+ primaryCount++;
+ }
+
+ if (primaryCount == 0) {
+ // display a message saying nothing is configured
+ document.getElementById("app-picker-notfound").removeAttribute("hidden");
+ }
+ },
+
+ /**
+ * Retrieve the moz-icon for the app
+ */
+ getFileIconURL: function getFileIconURL(file) {
+ const nsIFileProtocolHandler = Ci.nsIFileProtocolHandler;
+
+ var fph = Services.io
+ .getProtocolHandler("file")
+ .QueryInterface(nsIFileProtocolHandler);
+ if (!fph) {
+ return "";
+ }
+
+ var urlSpec = fph.getURLSpecFromActualFile(file);
+ return "moz-icon://" + urlSpec + "?size=32";
+ },
+
+ /**
+ * Retrieve the pretty description from the file
+ */
+ getFileDisplayName: function getFileDisplayName(file) {
+ if (AppConstants.platform == "win") {
+ if (file instanceof Ci.nsILocalFileWin) {
+ try {
+ return file.getVersionInfoField("FileDescription");
+ } catch (e) {}
+ }
+ } else if (AppConstants.platform == "macosx") {
+ if (file instanceof Ci.nsILocalFileMac) {
+ try {
+ return file.bundleDisplayName;
+ } catch (e) {}
+ }
+ }
+ return file.leafName;
+ },
+
+ /**
+ * Double click accepts an app
+ */
+ appDoubleClick: function appDoubleClick() {
+ var list = document.getElementById("app-picker-listbox");
+ var selItem = list.selectedItem;
+
+ if (!selItem) {
+ this._incomingParams.handlerApp = null;
+ return true;
+ }
+
+ this._incomingParams.handlerApp = selItem.handlerApp;
+ window.close();
+
+ return true;
+ },
+
+ appPickerOK: function appPickerOK() {
+ if (this._incomingParams.handlerApp) {
+ return;
+ }
+
+ var list = document.getElementById("app-picker-listbox");
+ var selItem = list.selectedItem;
+
+ if (!selItem) {
+ this._incomingParams.handlerApp = null;
+ return;
+ }
+ this._incomingParams.handlerApp = selItem.handlerApp;
+ },
+
+ appPickerCancel: function appPickerCancel() {
+ this._incomingParams.handlerApp = null;
+ },
+
+ /**
+ * User browse for an app.
+ */
+ appPickerBrowse: function appPickerBrowse() {
+ var nsIFilePicker = Ci.nsIFilePicker;
+ var fp = Cc["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+
+ fp.init(window, this._incomingParams.title, nsIFilePicker.modeOpen);
+ fp.appendFilters(nsIFilePicker.filterApps);
+
+ var startLocation;
+ if (AppConstants.platform == "win") {
+ startLocation = "ProgF"; // Program Files
+ } else if (AppConstants.platform == "macosx") {
+ startLocation = "LocApp"; // Local Applications
+ } else {
+ startLocation = "Home";
+ }
+ fp.displayDirectory = Services.dirsvc.get(startLocation, Ci.nsIFile);
+
+ fp.open(rv => {
+ if (rv == nsIFilePicker.returnOK && fp.file) {
+ var localHandlerApp = Cc[
+ "@mozilla.org/uriloader/local-handler-app;1"
+ ].createInstance(Ci.nsILocalHandlerApp);
+ localHandlerApp.executable = fp.file;
+
+ this._incomingParams.handlerApp = localHandlerApp;
+ window.close();
+ }
+ });
+ },
+};
+
+// Global object
+var g_dialog = new AppPicker();
diff --git a/toolkit/components/apppicker/content/appPicker.xhtml b/toolkit/components/apppicker/content/appPicker.xhtml
new file mode 100644
index 0000000000..c22441ec3e
--- /dev/null
+++ b/toolkit/components/apppicker/content/appPicker.xhtml
@@ -0,0 +1,44 @@
+<?xml version="1.0"?>
+
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+ <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
+ <?xml-stylesheet href="chrome://global/skin/appPicker.css" type="text/css"?>
+
+ <!DOCTYPE window>
+
+ <window
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ onload="g_dialog.appPickerLoad();"
+ aria-describedby="content-description suggested-filename"
+ persist="screenX screenY">
+ <dialog id="app-picker"
+ buttons="accept,cancel,extra2"
+ data-l10n-id="app-picker-browse-button"
+ data-l10n-attrs="buttonlabelextra2"
+ defaultButton="accept">
+
+ <linkset>
+ <html:link rel="localization" href="toolkit/global/appPicker.ftl"/>
+ </linkset>
+ <script src="chrome://global/content/appPicker.js"/>
+
+ <hbox id="file-info" align="center">
+ <image id="content-icon" src=""/>
+ <vbox flex="1">
+ <label id="content-description" crop="center" value=""/>
+ <label id="suggested-filename" crop="center" value=""/>
+ </vbox>
+ </hbox>
+
+ <label id="sendto-message" data-l10n-id="app-picker-send-msg" control="app-picker-listbox"/>
+
+ <richlistbox id="app-picker-listbox"
+ ondblclick="g_dialog.appDoubleClick();"/>
+
+ <label id="app-picker-notfound" data-l10n-id="app-picker-no-app-found" hidden="true"/>
+ </dialog>
+ </window>
diff --git a/toolkit/components/apppicker/jar.mn b/toolkit/components/apppicker/jar.mn
new file mode 100644
index 0000000000..6ca9a04c88
--- /dev/null
+++ b/toolkit/components/apppicker/jar.mn
@@ -0,0 +1,8 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+toolkit.jar:
+ content/global/appPicker.xhtml (content/appPicker.xhtml)
+ content/global/appPicker.js (content/appPicker.js)
+
diff --git a/toolkit/components/apppicker/moz.build b/toolkit/components/apppicker/moz.build
new file mode 100644
index 0000000000..199926b764
--- /dev/null
+++ b/toolkit/components/apppicker/moz.build
@@ -0,0 +1,10 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files("**"):
+ BUG_COMPONENT = ("Toolkit", "Preferences")
+
+JAR_MANIFESTS += ["jar.mn"]