--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -229,16 +229,17 @@ bin/components/nsURLFormatter.js
bin/components/urlformatter.xpt
bin/components/libbrowserdirprovider.so
bin/components/libbrowsercomps.so
bin/components/txEXSLTRegExFunctions.js
bin/components/nsLivemarkService.js
bin/components/nsTaggingService.js
bin/components/nsDefaultCLH.js
bin/components/nsContentPrefService.js
+bin/components/nsContentDispatchChooser.js
; Modules
bin/modules/*
; Safe Browsing
bin/components/nsSafebrowsingApplication.js
bin/components/safebrowsing.xpt
bin/components/nsUrlClassifierListManager.js
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -229,16 +229,17 @@ bin\components\nsURLFormatter.js
bin\components\urlformatter.xpt
bin\components\browserdirprovider.dll
bin\components\brwsrcmp.dll
bin\components\txEXSLTRegExFunctions.js
bin\components\nsLivemarkService.js
bin\components\nsTaggingService.js
bin\components\nsDefaultCLH.js
bin\components\nsContentPrefService.js
+bin\components\nsContentDispatchChooser.js
; Modules
bin\modules\*
; Safe Browsing
bin\components\nsSafebrowsingApplication.js
bin\components\safebrowsing.xpt
bin\components\nsUrlClassifierListManager.js
--- a/toolkit/mozapps/Makefile.in
+++ b/toolkit/mozapps/Makefile.in
@@ -15,16 +15,17 @@
#
# The Initial Developer of the Original Code is
# Netscape Communications Corporation.
# Portions created by the Initial Developer are Copyright (C) 2002
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ben Goodger <ben@bengoodger.com>
+# Shawn Wilsher <me@shawnwilsher.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
@@ -37,11 +38,11 @@
DEPTH = ../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
-DIRS = downloads extensions update xpinstall plugins
+DIRS = downloads extensions update xpinstall plugins handling
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/Makefile.in
@@ -0,0 +1,48 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is protocol handling code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DIRS = src
+
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/content/dialog.js
@@ -0,0 +1,230 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Protocol Handler Dialog.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * This dialog builds its content based on arguments passed into it.
+ * window.arguments[0]:
+ * The title of the dialog.
+ * window.arguments[1]:
+ * The url of the image that appears to the left of the description text
+ * window.arguments[2]:
+ * The text of the description that will appear above the choices the user
+ * can choose from.
+ * window.arguments[3]:
+ * The text of the label directly above the choices the user can choose from.
+ * window.arguments[4]:
+ * This is the text to be placed in the label for the checkbox. If no text is
+ * passed (ie, it's an empty string), the checkbox will be hidden.
+ * window.arguments[5]:
+ * This is the text that is displayed below the checkbox when it is checked.
+ * window.arguments[6]:
+ * This is the nsIHandlerInfo that gives us all our precious information.
+ * window.arguments[7]:
+ * This is the nsIURI that we are being brought up for in the first place.
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+var dialog = {
+ //////////////////////////////////////////////////////////////////////////////
+ //// Member Variables
+
+ _handlerInfo: null,
+ _URI: null,
+ _itemChoose: null,
+ _okButton: null,
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// Methods
+
+ /**
+ * This function initializes the content of the dialog.
+ */
+ initialize: function initialize()
+ {
+ this._handlerInfo = window.arguments[6].QueryInterface(Ci.nsIHandlerInfo);
+ this._URI = window.arguments[7].QueryInterface(Ci.nsIURI);
+ this._itemChoose = document.getElementById("item-choose");
+ this._okButton = document.documentElement.getButton("accept");
+
+ this.updateOKButton();
+
+ let description = {
+ image: document.getElementById("description-image"),
+ text: document.getElementById("description-text")
+ };
+ let options = document.getElementById("item-action-text");
+ let checkbox = {
+ desc: document.getElementById("remember"),
+ text: document.getElementById("remember-text")
+ };
+
+ // Setting values
+ document.title = window.arguments[0];
+ description.image.src = window.arguments[1];
+ description.text.textContent = window.arguments[2];
+ options.value = window.arguments[3];
+ checkbox.desc.label = window.arguments[4];
+ checkbox.text.textContent = window.arguments[5];
+
+ // Hide stuff that needs to be hidden
+ if (!checkbox.desc.label)
+ checkbox.desc.hidden = true;
+
+ // UI is ready, lets populate our list
+ this.populateList();
+ },
+
+ /**
+ * Populates the list that a user can choose from.
+ */
+ populateList: function populateList()
+ {
+ // TODO: make this work with more than one (depends on Bug 385740)
+ let app = this._handlerInfo.preferredApplicationHandler;
+
+ if (app) {
+ let elm = document.createElement("richlistitem");
+ elm.setAttribute("type", "handler");
+ elm.setAttribute("name", app.name);
+ elm.object = app;
+
+ document.getElementById("items").insertBefore(elm, this._itemChoose);
+ }
+
+ if (this._handlerInfo.hasDefaultHandler) {
+ let elm = document.createElement("richlistitem");
+ elm.setAttribute("type", "handler");
+ elm.id = "os-default-handler";
+ elm.setAttribute("name", this._handlerInfo.defaultDescription);
+
+ document.getElementById("items").insertBefore(elm, this._itemChoose);
+ }
+ },
+
+ /**
+ * Brings up a filepicker and allows a user to choose an application.
+ */
+ chooseApplication: function chooseApplication()
+ {
+ let bundle = document.getElementById("base-strings");
+ let title = bundle.getString("choose.application.title");
+
+ let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+ fp.init(window, title, Ci.nsIFilePicker.modeOpen);
+ fp.appendFilters(Ci.nsIFilePicker.filterApps);
+
+ if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file) {
+ let uri = Cc["@mozilla.org/network/util;1"].
+ getService(Ci.nsIIOService).
+ newFileURI(fp.file);
+ let elm = document.createElement("richlistitem");
+ elm.setAttribute("type", "handler");
+ elm.setAttribute("name", fp.file.leafName);
+ elm.setAttribute("image", "moz-icon://" + uri.spec + "?size=32");
+
+ let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
+ createInstance(Ci.nsILocalHandlerApp);
+ handlerApp.executable = fp.file;
+ elm.obj = handlerApp;
+
+ let parent = document.getElementById("items");
+ parent.selectedItem = parent.insertBefore(elm, parent.firstChild);
+ parent.ensureSelectedElementIsVisible();
+ }
+ },
+
+ /**
+ * Function called when the OK button is pressed.
+ */
+ onAccept: function onAccept()
+ {
+ let checkbox = document.getElementById("remember");
+ if (!checkbox.hidden) {
+ // We need to make sure that the default is properly set now
+ if (this.selectedItem.obj) {
+ // default OS handler doesn't have this property
+ this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useHelperApp;
+ this._handlerInfo.preferredApplicationHandler = this.selectedItem.obj;
+ }
+ else
+ this._handlerInfo.preferredAction = Ci.nsIHandlerInfo.useSystemDefault;
+ }
+ this._handlerInfo.alwaysAskBeforeHandling = !checkbox.checked;
+
+ let hs = Cc["@mozilla.org/uriloader/handler-service;1"].
+ getService(Ci.nsIHandlerService);
+ hs.store(this._handlerInfo);
+
+ this._handlerInfo.launchWithURI(this._URI);
+
+ return true;
+ },
+
+ /**
+ * Determines if the OK button should be disabled or not
+ */
+ updateOKButton: function updateOKButton()
+ {
+ this._okButton.disabled = this._itemChoose.selected;
+ },
+
+ /**
+ * Updates the UI based on the checkbox being checked or not.
+ */
+ onCheck: function onCheck()
+ {
+ document.getElementById("remember-text").hidden =
+ !document.getElementById("remember").checked;
+
+ window.sizeToContent();
+ },
+
+ /////////////////////////////////////////////////////////////////////////////
+ //// Getters / Setters
+
+ /**
+ * Returns the selected element in the richlistbox
+ */
+ get selectedItem()
+ {
+ return document.getElementById("items").selectedItem;
+ }
+};
+
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/content/dialog.xul
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/global.css"?>
+<?xml-stylesheet href="chrome://mozapps/content/handling/handler.css"?>
+<?xml-stylesheet href="chrome://mozapps/skin/handling/handling.css"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is the Protocol Handler Dialog.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2007
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the LGPL or the GPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!-- TODO this needs to move to locale/ once we are certain of the strings -->
+<!DOCTYPE dialog SYSTEM "chrome://mozapps/content/handling/handling.dtd">
+
+<dialog id="handling"
+ ondialogaccept="return dialog.onAccept();"
+ onload="dialog.initialize();"
+ style="width: 320px;"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script src="chrome://mozapps/content/handling/dialog.js" type="application/javascript"/>
+
+ <stringbundleset id="strings">
+ <stringbundle id="base-strings"
+ src="chrome://mozapps/content/handling/handling.properties"/>
+ </stringbundleset>
+
+ <hbox>
+ <image id="description-image"/>
+ <description id="description-text"/>
+ </hbox>
+
+ <vbox flex="1">
+ <description id="item-action-text"/>
+ <richlistbox id="items" flex="1"
+ onselect="dialog.updateOKButton();">
+ <richlistitem id="item-choose" orient="horizontal" selected="true">
+ <label value="&ChooseApp.description;" flex="1"/>
+ <button oncommand="dialog.chooseApplication();"
+ label="&ChooseApp.label;" accesskey="&ChooseApp.accessKey;"/>
+ </richlistitem>
+ </richlistbox>
+ </vbox>
+
+ <checkbox id="remember" oncommand="dialog.onCheck();"/>
+ <description id="remember-text" hidden="true"/>
+
+</dialog>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/content/handler.css
@@ -0,0 +1,3 @@
+richlistitem[type="handler"] {
+ -moz-binding: url('chrome://mozapps/content/handling/handler.xml#handler');
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/content/handler.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0"?>
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is the Protocol Handler Dialog.
+ -
+ - The Initial Developer of the Original Code is
+ - Mozilla Corporation.
+ - Portions created by the Initial Developer are Copyright (C) 2007
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ -
+ - Alternatively, the contents of this file may be used under the terms of
+ - either the GNU General Public License Version 2 or later (the "GPL"), or
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ - in which case the provisions of the GPL or the LGPL are applicable instead
+ - of those above. If you wish to allow use of your version of this file only
+ - under the terms of either the GPL or the LGPL, and not to allow others to
+ - use your version of this file under the terms of the MPL, indicate your
+ - decision by deleting the provisions above and replace them with the notice
+ - and other provisions required by the LGPL or the GPL. If you do not delete
+ - the provisions above, a recipient may use your version of this file under
+ - the terms of any one of the MPL, the GPL or the LGPL.
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<bindings id="hanlder-bindings"
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:xbl="http://www.mozilla.org/xbl">
+
+ <binding id="handler"
+ extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
+
+ <content>
+ <xul:vbox pack="center">
+ <xul:image xbl:inherits="src=image" height="32" width="32"/>
+ </xul:vbox>
+ <xul:vbox flex="1">
+ <xul:label xbl:inherits="value=name"/>
+ <xul:label xbl:inherits="value=description"/>
+ </xul:vbox>
+ </content>
+ </binding>
+
+</bindings>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/content/handling.dtd
@@ -0,0 +1,3 @@
+<!ENTITY ChooseApp.description "Choose an Application">
+<!ENTITY ChooseApp.label "Choose...">
+<!ENTITY ChooseApp.accessKey "C">
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/content/handling.properties
@@ -0,0 +1,7 @@
+protocol.title=Launch Application
+protocol.description=This link needs to be opened with an application.
+protocol.choices.label=Send to:
+protocol.checkbox.label=Remember my choice for %S links.
+protocol.checkbox.extra=This can be changed in %S's preferences.
+
+choose.application.title=Another Application...
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/src/Makefile.in
@@ -0,0 +1,51 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is protocol handling code.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Corporation.
+# Portions created by the Initial Developer are Copyright (C) 2007
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either the GNU General Public License Version 2 or later (the "GPL"), or
+# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+# in which case the provisions of the GPL or the LGPL are applicable instead
+# of those above. If you wish to allow use of your version of this file only
+# under the terms of either the GPL or the LGPL, and not to allow others to
+# use your version of this file under the terms of the MPL, indicate your
+# decision by deleting the provisions above and replace them with the notice
+# and other provisions required by the GPL or the LGPL. If you do not delete
+# the provisions above, a recipient may use your version of this file under
+# the terms of any one of the MPL, the GPL or the LGPL.
+#
+# ***** END LICENSE BLOCK *****
+
+DEPTH = ../../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = contentDispatchChooser
+
+EXTRA_COMPONENTS = nsContentDispatchChooser.js
+GARBAGE += nsContentDispatchChooser.js
+
+include $(topsrcdir)/config/rules.mk
+
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/handling/src/nsContentDispatchChooser.js
@@ -0,0 +1,127 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is nsContentDispatchChooser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+////////////////////////////////////////////////////////////////////////////////
+//// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+const CONTENT_HANDLING_URL = "chrome://mozapps/content/handling/dialog.xul";
+// TODO this needs to move to locale, but l10n folks want to wait until we
+// finalize these for sure before doing so
+const STRINGBUNDLE_URL = "chrome://mozapps/content/handling/handling.properties";
+
+////////////////////////////////////////////////////////////////////////////////
+//// nsContentDispatchChooser class
+
+function nsContentDispatchChooser()
+{
+}
+
+nsContentDispatchChooser.prototype =
+{
+ classDescription: "Used to handle different types of content",
+ classID: Components.ID("e35d5067-95bc-4029-8432-e8f1e431148d"),
+ contractID: "@mozilla.org/content-dispatch-chooser;1",
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsIContentDispatchChooser
+
+ ask: function ask(aHandler, aWindowContext, aURI, aReason)
+ {
+ let window = null;
+ try {
+ if (aWindowContext)
+ window = aWindowContext.getInterface(Ci.nsIDOMWindow);
+ } catch (e) { /* it's OK to not have a window */ }
+
+ let sbs = Cc["@mozilla.org/intl/stringbundle;1"].
+ getService(Ci.nsIStringBundleService);
+ let bundle = sbs.createBundle(STRINGBUNDLE_URL);
+
+ let xai = Cc["@mozilla.org/xre/app-info;1"].
+ getService(Ci.nsIXULAppInfo);
+ // TODO when this is hooked up for content, we will need different strings
+ // for most of these
+ let arr = [bundle.GetStringFromName("protocol.title"),
+ "",
+ bundle.GetStringFromName("protocol.description"),
+ bundle.GetStringFromName("protocol.choices.label"),
+ bundle.formatStringFromName("protocol.checkbox.label",
+ [aURI.scheme], 1),
+ bundle.formatStringFromName("protocol.checkbox.extra",
+ [xai.name], 1)];
+
+ let params = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+ for each (let text in arr) {
+ let string = Cc["@mozilla.org/supports-string;1"].
+ createInstance(Ci.nsISupportsString);
+ string.data = text;
+ params.appendElement(string, false);
+ }
+ params.appendElement(aHandler, false);
+ params.appendElement(aURI, false);
+
+ let ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
+ getService(Ci.nsIWindowWatcher);
+ ww.openWindow(window,
+ CONTENT_HANDLING_URL,
+ null,
+ "chrome,dialog=yes,resizable,centerscreen",
+ params);
+ },
+
+ //////////////////////////////////////////////////////////////////////////////
+ //// nsISupports
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentDispatchChooser])
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//// Module
+
+let components = [nsContentDispatchChooser];
+
+function NSGetModule(compMgr, fileSpec)
+{
+ return XPCOMUtils.generateModule(components);
+}
+
--- a/toolkit/mozapps/jar.mn
+++ b/toolkit/mozapps/jar.mn
@@ -23,8 +23,14 @@ toolkit.jar:
* content/mozapps/shared/richview.xml (shared/content/richview.xml)
content/mozapps/plugins/pluginInstallerWizard.xul (plugins/content/pluginInstallerWizard.xul)
content/mozapps/plugins/pluginInstallerWizard.js (plugins/content/pluginInstallerWizard.js)
content/mozapps/plugins/pluginInstallerWizard.css (plugins/content/pluginInstallerWizard.css)
content/mozapps/plugins/pluginInstallerDatasource.js (plugins/content/pluginInstallerDatasource.js)
content/mozapps/plugins/pluginInstallerService.js (plugins/content/pluginInstallerService.js)
content/mozapps/plugins/missingPlugin.xml (plugins/content/missingPlugin.xml)
content/mozapps/plugins/missingPluginBinding.css (plugins/content/missingPluginBinding.css)
+ content/mozapps/handling/handler.css (handling/content/handler.css)
+ content/mozapps/handling/handler.xml (handling/content/handler.xml)
+ content/mozapps/handling/handling.properties (handling/content/handling.properties)
+ content/mozapps/handling/handling.dtd (handling/content/handling.dtd)
+ content/mozapps/handling/dialog.xul (handling/content/dialog.xul)
+ content/mozapps/handling/dialog.js (handling/content/dialog.js)
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/pinstripe/mozapps/handling/handling.css
@@ -0,0 +1,13 @@
+#description-image:not([src]) {
+ height: 32px;
+ width: 32px;
+}
+
+richlistitem {
+ min-height: 36px; /* Don't forget to update the richlistbox height! */
+}
+
+richlistbox {
+ /* 3 items high, plus 4px for top and bottom margins, less 2px for border */
+ min-height: 110px;
+}
--- a/toolkit/themes/pinstripe/mozapps/jar.mn
+++ b/toolkit/themes/pinstripe/mozapps/jar.mn
@@ -1,16 +1,20 @@
classic.jar:
% skin mozapps classic/1.0 %skin/classic/mozapps/
#ifndef MINIMO
- skin/classic/mozapps/downloads/progress-bar-paused.gif (downloads/progress-bar-paused.gif)
- skin/classic/mozapps/downloads/progress-bar.gif (downloads/progress-bar.gif)
- skin/classic/mozapps/downloads/progress-remainder.gif (downloads/progress-remainder.gif)
- skin/classic/mozapps/downloads/background-gradient.gif (downloads/background-gradient.gif)
- skin/classic/mozapps/downloads/background-stripe.gif (downloads/background-stripe.gif)
+ skin/classic/mozapps/downloads/pause.png (downloads/pause.png)
+ skin/classic/mozapps/downloads/remove.png (downloads/remove.png)
+ skin/classic/mozapps/downloads/reload.png (downloads/reload.png)
+ skin/classic/mozapps/downloads/cancel.png (downloads/cancel.png)
+ skin/classic/mozapps/downloads/open.png (downloads/open.png)
+ skin/classic/mozapps/downloads/start.png (downloads/start.png)
+ skin/classic/mozapps/downloads/info.png (downloads/info.png)
+ skin/classic/mozapps/downloads/link.png (downloads/link.png)
+ skin/classic/mozapps/downloads/location.png (downloads/location.png)
skin/classic/mozapps/downloads/download-inprogress.png (downloads/download-inprogress.png)
skin/classic/mozapps/downloads/downloadIcon.png (downloads/downloadIcon.png)
skin/classic/mozapps/downloads/downloads.css (downloads/downloads.css)
skin/classic/mozapps/downloads/unknownContentType.css (downloads/unknownContentType.css)
skin/classic/mozapps/downloads/downloads.xml (downloads/downloads.xml)
skin/classic/mozapps/extensions/extensionItem.png (extensions/extensionItem.png)
skin/classic/mozapps/extensions/itemDisabledFader.png (extensions/itemDisabledFader.png)
skin/classic/mozapps/extensions/itemEnabledFader.png (extensions/itemEnabledFader.png)
@@ -33,9 +37,10 @@ classic.jar:
skin/classic/mozapps/update/updates.css (update/updates.css)
skin/classic/mozapps/update/update.png (update/update.png)
skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png (xpinstall/xpinstallItemGeneric.png)
skin/classic/mozapps/xpinstall/xpinstallConfirm.css (xpinstall/xpinstallConfirm.css)
#ifdef MOZ_PLACES
skin/classic/mozapps/places/defaultFavicon.png (places/defaultFavicon.png)
skin/classic/mozapps/places/tagContainerIcon.png (places/tagContainerIcon.png)
#endif
+ skin/classic/mozapps/handling/handling.css (handling/handling.css)
#endif
new file mode 100644
--- /dev/null
+++ b/toolkit/themes/winstripe/mozapps/handling/handling.css
@@ -0,0 +1,13 @@
+#description-image:not([src]) {
+ height: 32px;
+ width: 32px;
+}
+
+richlistitem {
+ min-height: 36px; /* Don't forget to update the richlistbox height! */
+}
+
+richlistbox {
+ /* 3 items high, plus 4px for top and bottom margins, less 2px for border */
+ min-height: 110px;
+}
--- a/toolkit/themes/winstripe/mozapps/jar.mn
+++ b/toolkit/themes/winstripe/mozapps/jar.mn
@@ -34,9 +34,10 @@ classic.jar:
skin/classic/mozapps/update/warning.gif (update/warning.gif)
skin/classic/mozapps/update/updates.css (update/updates.css)
skin/classic/mozapps/xpinstall/xpinstallConfirm.css (xpinstall/xpinstallConfirm.css)
skin/classic/mozapps/xpinstall/xpinstallItemGeneric.png (xpinstall/xpinstallItemGeneric.png)
#ifdef MOZ_PLACES
skin/classic/mozapps/places/defaultFavicon.png (places/defaultFavicon.png)
skin/classic/mozapps/places/tagContainerIcon.png (places/tagContainerIcon.png)
#endif
+ skin/classic/mozapps/handling/handling.css (handling/handling.css)
#endif
--- a/uriloader/exthandler/Makefile.in
+++ b/uriloader/exthandler/Makefile.in
@@ -106,16 +106,17 @@ OSHELPER += nsInternetConfig.cpp \
nsMIMEInfoMac.cpp \
$(NULL)
endif
LOCAL_INCLUDES = -I$(srcdir)
ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
OSHELPER += nsGNOMERegistry.cpp
+OSHELPER += nsMIMEInfoUnix.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),beos)
OSHELPER += nsMIMEInfoBeOS.cpp
endif
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
OSHELPER += nsMIMEInfoWin.cpp
@@ -130,16 +131,17 @@ EXPORTS = \
$(OSDIR)/nsOSHelperAppService.h \
$(NULL)
XPIDLSRCS = \
nsCExternalHandlerService.idl \
nsIExternalProtocolService.idl \
nsIExternalHelperAppService.idl \
nsIHelperAppLauncherDialog.idl \
+ nsIContentDispatchChooser.idl \
nsIHandlerService.idl \
$(NULL)
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
XPIDLSRCS += nsIInternetConfigService.idl
endif
CPPSRCS = \
--- a/uriloader/exthandler/beos/nsMIMEInfoBeOS.cpp
+++ b/uriloader/exthandler/beos/nsMIMEInfoBeOS.cpp
@@ -53,8 +53,41 @@ nsMIMEInfoBeOS::LaunchDefaultWithFile(ns
PRBool executable = PR_TRUE;
local->IsExecutable(&executable);
if (executable)
return NS_ERROR_FAILURE;
return local->Launch();
}
+
+nsresult
+nsMIMEInfoBeOS::LoadUriInternal(nsIURI * aURL)
+{
+ nsresult rv = NS_OK;
+
+ if (aURL) {
+ // Get the Protocol
+ nsCAutoString scheme;
+ aURL->GetScheme(scheme);
+ BString protoStr(scheme.get());
+ protoStr.Prepend("application/x-vnd.Be.URL.");
+ // Get the Spec
+ nsCAutoString spec;
+ aURL->GetSpec(spec);
+ const char* args[] = { spec.get() };
+
+ //Launch the app
+ BMimeType protocol;
+ bool isInstalled = false;
+ if (protocol.SetTo(protoStr.String()) == B_OK)
+ {
+ if(protocol.IsInstalled())
+ {
+ isInstalled = true;
+ be_roster->Launch(protoStr.String(), NS_ARRAY_LENGTH(args), (char **)args);
+ }
+ }
+ if ((!isInstalled) && (!strcmp("mailto", scheme.get())))
+ be_roster->Launch("text/x-email", NS_ARRAY_LENGTH(args), (char **)args);
+ }
+ return rv;
+}
--- a/uriloader/exthandler/beos/nsMIMEInfoBeOS.h
+++ b/uriloader/exthandler/beos/nsMIMEInfoBeOS.h
@@ -44,11 +44,12 @@ class nsMIMEInfoBeOS : public nsMIMEInfo
nsMIMEInfoBeOS(const char* aType = "") : nsMIMEInfoImpl(aType) {}
nsMIMEInfoBeOS(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoBeOS(const nsACString& aType, HandlerClass aClass) :
nsMIMEInfoImpl(aType, aClass) {}
virtual ~nsMIMEInfoBeOS();
protected:
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile);
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
};
#endif
--- a/uriloader/exthandler/beos/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/beos/nsOSHelperAppService.cpp
@@ -87,49 +87,16 @@ nsresult nsOSHelperAppService::OSProtoco
*aHandlerExists = PR_TRUE;
}
}
}
return NS_OK;
}
-nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
-{
- LOG(("-- nsOSHelperAppService::LoadUrl\n"));
- nsresult rv = NS_OK;
-
- if (aURL) {
- // Get the Protocol
- nsCAutoString scheme;
- aURL->GetScheme(scheme);
- BString protoStr(scheme.get());
- protoStr.Prepend("application/x-vnd.Be.URL.");
- // Get the Spec
- nsCAutoString spec;
- aURL->GetSpec(spec);
- const char* args[] = { spec.get() };
-
- //Launch the app
- BMimeType protocol;
- bool isInstalled = false;
- if (protocol.SetTo(protoStr.String()) == B_OK)
- {
- if(protocol.IsInstalled())
- {
- isInstalled = true;
- be_roster->Launch(protoStr.String(), NS_ARRAY_LENGTH(args), (char **)args);
- }
- }
- if ((!isInstalled) && (!strcmp("mailto", scheme.get())))
- be_roster->Launch("text/x-email", NS_ARRAY_LENGTH(args), (char **)args);
- }
- return rv;
-}
-
nsresult nsOSHelperAppService::SetMIMEInfoForType(const char *aMIMEType, nsMIMEInfoBeOS**_retval) {
LOG(("-- nsOSHelperAppService::SetMIMEInfoForType: %s\n",aMIMEType));
nsresult rv = NS_ERROR_FAILURE;
nsMIMEInfoBeOS* mimeInfo = new nsMIMEInfoBeOS(aMIMEType);
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.cpp
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.cpp
@@ -39,16 +39,17 @@
*
* ***** END LICENSE BLOCK ***** */
#include <LaunchServices.h>
#include "nsMIMEInfoMac.h"
#include "nsILocalFileMac.h"
#include "nsIFileURL.h"
+#include "nsIInternetConfigService.h"
NS_IMETHODIMP
nsMIMEInfoMac::LaunchWithURI(nsIURI* aURI)
{
nsCOMPtr<nsIFile> application;
nsresult rv;
if (mPreferredAction == useHelperApp) {
@@ -68,20 +69,23 @@ nsMIMEInfoMac::LaunchWithURI(nsIURI* aUR
rv = localHandlerApp->GetExecutable(getter_AddRefs(application));
NS_ENSURE_SUCCESS(rv, rv);
} else if (mPreferredAction == useSystemDefault)
application = mDefaultApplication;
else
return NS_ERROR_INVALID_ARG;
+ if (mClass == eProtocolInfo)
+ return LoadUriInternal(aURI);
+
// get the nsILocalFile version of the doc to launch with
nsCOMPtr<nsILocalFile> docToLoad;
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
- if (NS_FAILED(rv)) return rv;
+ NS_ENSURE_SUCCESS(rv, rv);
// if we've already got an app, just QI so we have the launchWithDoc method
nsCOMPtr<nsILocalFileMac> app;
if (application) {
app = do_QueryInterface(application, &rv);
if (NS_FAILED(rv)) return rv;
} else {
// otherwise ask LaunchServices for an app directly
@@ -99,8 +103,34 @@ nsMIMEInfoMac::LaunchWithURI(nsIURI* aUR
app->InitWithFSRef(&appFSRef);
} else {
return NS_ERROR_FAILURE;
}
}
return app->LaunchWithDoc(docToLoad, PR_FALSE);
}
+
+nsresult
+nsMIMEInfoMac::LoadUriInternal(nsIURI *aURI)
+{
+ NS_ENSURE_ARG_POINTER(aURI);
+ nsresult rv = NS_ERROR_FAILURE;
+
+ nsCAutoString uri;
+ aURI->GetSpec(uri);
+ if (!uri.IsEmpty()) {
+ nsCOMPtr<nsIInternetConfigService> icService =
+ do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID);
+ if (icService)
+ rv = icService->LaunchURL(uri.get());
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMIMEInfoMac::GetHasDefaultHandler(PRBool *_retval)
+{
+ // We have a default application if we have a description
+ *_retval = !mDefaultAppDescription.IsEmpty();
+ return NS_OK;
+}
+
--- a/uriloader/exthandler/mac/nsMIMEInfoMac.h
+++ b/uriloader/exthandler/mac/nsMIMEInfoMac.h
@@ -42,19 +42,20 @@
class nsMIMEInfoMac : public nsMIMEInfoImpl {
public:
nsMIMEInfoMac(const char* aMIMEType = "") : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoMac(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoMac(const nsACString& aType, HandlerClass aClass) :
nsMIMEInfoImpl(aType, aClass) {}
NS_IMETHOD LaunchWithURI(nsIURI* aURI);
-
+ NS_IMETHOD GetHasDefaultHandler(PRBool *_retval);
+ protected:
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
#ifdef DEBUG
- protected:
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile) {
NS_NOTREACHED("do not call this method, use LaunchWithFile");
return NS_ERROR_UNEXPECTED;
}
#endif
};
--- a/uriloader/exthandler/mac/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/mac/nsOSHelperAppService.cpp
@@ -164,34 +164,16 @@ NS_IMETHODIMP nsOSHelperAppService::GetA
}
::CFRelease(schemeCFString);
}
return rv;
}
-nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
-{
- nsCAutoString url;
- nsresult rv = NS_ERROR_FAILURE;
-
- if (aURL)
- {
- aURL->GetSpec(url);
- if (!url.IsEmpty())
- {
- nsCOMPtr<nsIInternetConfigService> icService (do_GetService(NS_INTERNETCONFIGSERVICE_CONTRACTID));
- if (icService)
- rv = icService->LaunchURL(url.get());
- }
- }
- return rv;
-}
-
nsresult nsOSHelperAppService::GetFileTokenForPath(const PRUnichar * aPlatformAppPath, nsIFile ** aFile)
{
nsresult rv;
nsCOMPtr<nsILocalFileMac> localFile (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv,rv);
CFURLRef pathAsCFURL;
CFStringRef pathAsCFString = ::CFStringCreateWithCharacters(NULL,
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -72,16 +72,17 @@
#include "nsIRDFService.h"
#include "nsIRDFRemoteDataSource.h"
#include "nsHelperAppRDF.h"
#endif //MOZ_RDF
#include "nsIMIMEInfo.h"
#include "nsIRefreshURI.h" // XXX needed to redirect according to Refresh: URI
#include "nsIDocumentLoader.h" // XXX needed to get orig. channel and assoc. refresh uri
#include "nsIHelperAppLauncherDialog.h"
+#include "nsIContentDispatchChooser.h"
#include "nsNetUtil.h"
#include "nsIIOService.h"
#include "nsNetCID.h"
#include "nsChannelProperties.h"
#include "nsMimeTypes.h"
// used for header disposition information.
#include "nsIHttpChannel.h"
@@ -994,22 +995,22 @@ nsresult nsExternalHelperAppService::Fil
return FillHandlerInfoForTypeFromDS(typeNodeResource.get(), type, rdf,
NC_SCHEME_NODE_PREFIX, aHandlerInfo);
#else
return NS_ERROR_NOT_AVAILABLE;
#endif
}
-#ifdef MOZ_RDF
nsresult nsExternalHelperAppService::FillHandlerInfoForTypeFromDS(
nsIRDFResource *aTypeNodeResource, const nsCAutoString &aType,
nsIRDFService *rdf, const char *aTypeNodePrefix,
nsIHandlerInfo * aHandlerInfo)
{
+#ifdef MOZ_RDF
// we need a way to determine if this type resource is really in the graph
// or not... Test that there's a #value arc from the type resource to the
// type literal string.
nsCOMPtr<nsIRDFLiteral> typeLiteral;
NS_ConvertUTF8toUTF16 UTF16Type(aType);
nsresult rv = rdf->GetLiteral( UTF16Type.get(),
getter_AddRefs( typeLiteral ) );
@@ -1034,18 +1035,20 @@ nsresult nsExternalHelperAppService::Fil
} // if we have a node in the graph for this content type
// If we had success, but entry doesn't exist, we don't want to return success
else if (NS_SUCCEEDED(rv)) {
rv = NS_ERROR_NOT_AVAILABLE;
}
return rv;
+#else
+ return NS_ERROR_NOT_AVAILABLE;
+#endif /* MOZ_RDF */
}
-#endif /* MOZ_RDF */
nsresult nsExternalHelperAppService::FillMIMEInfoForExtensionFromDS(
const nsACString& aFileExtension, nsIMIMEInfo * aMIMEInfo)
{
nsCAutoString type;
PRBool found = GetTypeFromDS(aFileExtension, type);
if (!found)
return NS_ERROR_NOT_AVAILABLE;
@@ -1183,251 +1186,86 @@ NS_IMETHODIMP nsExternalHelperAppService
return NS_OK;
}
NS_IMETHODIMP nsExternalHelperAppService::LoadUrl(nsIURI * aURL)
{
return LoadURI(aURL, nsnull);
}
-
-// nsExternalHelperAppService::LoadURI() may now pose a confirm dialog
-// that existing callers aren't expecting. We must do it on an event
-// callback to make sure we don't hang someone up.
-
-class nsExternalLoadRequest : public nsRunnable {
- public:
- nsExternalLoadRequest(nsIURI *uri, nsIPrompt *prompt)
- : mURI(uri), mPrompt(prompt) {}
-
- NS_IMETHOD Run() {
- if (gExtProtSvc && gExtProtSvc->isExternalLoadOK(mURI, mPrompt))
- gExtProtSvc->LoadUriInternal(mURI);
- return NS_OK;
- }
-
- private:
- nsCOMPtr<nsIURI> mURI;
- nsCOMPtr<nsIPrompt> mPrompt;
-};
-
-NS_IMETHODIMP nsExternalHelperAppService::LoadURI(nsIURI * aURL, nsIPrompt * aPrompt)
-{
- nsCAutoString spec;
- aURL->GetSpec(spec);
-
- if (spec.Find("%00") != -1)
- return NS_ERROR_MALFORMED_URI;
-
- spec.ReplaceSubstring("\"", "%22");
- spec.ReplaceSubstring("`", "%60");
-
- nsCOMPtr<nsIIOService> ios(do_GetIOService());
- nsCOMPtr<nsIURI> uri;
- nsresult rv = ios->NewURI(spec, nsnull, nsnull, getter_AddRefs(uri));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIRunnable> event = new nsExternalLoadRequest(uri, aPrompt);
- return NS_DispatchToCurrentThread(event);
-}
-
// helper routines used by LoadURI to check whether we're allowed
// to load external schemes and whether or not to warn the user
static const char kExternalProtocolPrefPrefix[] = "network.protocol-handler.external.";
static const char kExternalProtocolDefaultPref[] = "network.protocol-handler.external-default";
static const char kExternalWarningPrefPrefix[] = "network.protocol-handler.warn-external.";
static const char kExternalWarningDefaultPref[] = "network.protocol-handler.warn-external-default";
-
-PRBool nsExternalHelperAppService::isExternalLoadOK(nsIURI* aURL, nsIPrompt* aPrompt)
+NS_IMETHODIMP
+nsExternalHelperAppService::LoadURI(nsIURI *aURI,
+ nsIInterfaceRequestor *aWindowContext)
{
- if (!aURL)
- return PR_FALSE;
+ NS_ENSURE_ARG_POINTER(aURI);
nsCAutoString scheme;
- aURL->GetScheme(scheme);
+ (void)aURI->GetScheme(scheme);
if (scheme.IsEmpty())
- return PR_FALSE; // must have a scheme
+ return NS_OK; // must have a scheme
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
if (!prefs)
- return PR_FALSE; // deny if we can't check prefs
-
+ return NS_OK; // deny if we can't check prefs
// Deny load if the prefs say to do so
nsCAutoString externalPref(kExternalProtocolPrefPrefix);
externalPref += scheme;
PRBool allowLoad = PR_FALSE;
nsresult rv = prefs->GetBoolPref(externalPref.get(), &allowLoad);
if (NS_FAILED(rv))
{
// no scheme-specific value, check the default
rv = prefs->GetBoolPref(kExternalProtocolDefaultPref, &allowLoad);
}
if (NS_FAILED(rv) || !allowLoad)
- return PR_FALSE; // explicitly denied or missing default pref
-
+ return NS_OK; // explicitly denied or missing default pref
// allowLoad is now true. See whether we have to ask the user
nsCAutoString warningPref(kExternalWarningPrefPrefix);
warningPref += scheme;
PRBool warn = PR_TRUE;
rv = prefs->GetBoolPref(warningPref.get(), &warn);
if (NS_FAILED(rv))
{
// no scheme-specific value, check the default
- rv = prefs->GetBoolPref(kExternalWarningDefaultPref, &warn);
- }
-
-
- if (NS_FAILED(rv) || warn)
- {
- // explicit "warn" setting or missing default pref:
- // we must ask the user before loading this type externally
- PRBool remember = PR_FALSE;
- allowLoad = promptForScheme(aURL, aPrompt, &remember);
-
- if (remember)
- {
- if (allowLoad)
- // suppress future warnings for this scheme
- prefs->SetBoolPref(warningPref.get(), PR_FALSE);
- else
- // prevent externally loading this scheme in the future
- prefs->SetBoolPref(externalPref.get(), PR_FALSE);
- }
- }
-
- return allowLoad;
-}
-
-PRBool nsExternalHelperAppService::promptForScheme(nsIURI* aURI,
- nsIPrompt* aPrompt,
- PRBool *aRemember)
-{
- // if no prompt passed in get one from the windowwatcher
- nsCOMPtr<nsIPrompt> prompt(aPrompt);
- if (!prompt)
- {
- nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID));
- if (wwatch)
- wwatch->GetNewPrompter(0, getter_AddRefs(prompt));
- }
- if (!prompt) {
- NS_ERROR("No prompt to warn user about external load, denying");
- return PR_FALSE; // told to warn but no prompt: deny
- }
-
- // load the strings we need
- nsCOMPtr<nsIStringBundleService> sbSvc(do_GetService(NS_STRINGBUNDLE_CONTRACTID));
- if (!sbSvc) {
- NS_ERROR("Couldn't load StringBundleService");
- return PR_FALSE;
- }
-
- nsCOMPtr<nsIStringBundle> appstrings;
- nsresult rv = sbSvc->CreateBundle("chrome://global/locale/appstrings.properties",
- getter_AddRefs(appstrings));
- if (NS_FAILED(rv) || !appstrings) {
- NS_ERROR("Failed to create appstrings.properties bundle");
- return PR_FALSE;
+ prefs->GetBoolPref(kExternalWarningDefaultPref, &warn);
}
-
- nsCAutoString spec;
- aURI->GetSpec(spec);
- NS_ConvertUTF8toUTF16 uri(spec);
-
- // The maximum amount of space the URI should take up in the dialog.
- const PRUint32 maxWidth = 75;
- const PRUint32 maxLines = 12; // (not counting ellipsis line)
- const PRUint32 maxLength = maxWidth * maxLines;
-
- // If the URI seems too long, insert zero-width spaces to make it wrappable
- // and crop it in the middle (replacing the cropped portion with an ellipsis),
- // so the dialog doesn't grow so wide or tall it renders buttons off-screen.
- if (uri.Length() > maxWidth) {
- PRUint32 charIdx = maxWidth;
- PRUint32 lineIdx = 1;
-
- PRInt32 numCharsToCrop = uri.Length() - maxLength;
-
- while (charIdx < uri.Length()) {
- // Don't insert characters in the middle of a surrogate pair.
- if (NS_IS_LOW_SURROGATE(uri[charIdx]))
- --charIdx;
-
- if (numCharsToCrop > 0 && lineIdx == maxLines / 2) {
- NS_NAMED_LITERAL_STRING(ellipsis, "\n...\n");
-
- // Don't end the crop in the middle of a surrogate pair.
- if (NS_IS_HIGH_SURROGATE(uri[charIdx + numCharsToCrop - 1]))
- ++numCharsToCrop;
-
- uri.Replace(charIdx, numCharsToCrop, ellipsis);
- charIdx += ellipsis.Length();
- }
- else {
- // 0x200B is the zero-width breakable space character.
- uri.Insert(PRUnichar(0x200B), charIdx);
- charIdx += 1;
- }
+
+ nsCOMPtr<nsIHandlerInfo> handler;
+ rv = GetProtocolHandlerInfo(scheme, getter_AddRefs(handler));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsHandlerInfoAction preferredAction;
+ handler->GetPreferredAction(&preferredAction);
+ PRBool alwaysAsk = PR_TRUE;
+ handler->GetAlwaysAskBeforeHandling(&alwaysAsk);
+
+ // if we are not supposed to warn, or we are not supposed to always ask and
+ // the preferred action is to use a helper app or the system default, we just
+ // launch the URI.
+ if (!warn ||
+ !alwaysAsk && (preferredAction == nsIHandlerInfo::useHelperApp ||
+ preferredAction == nsIHandlerInfo::useSystemDefault))
+ return handler->LaunchWithURI(aURI);
- charIdx += maxWidth;
- ++lineIdx;
- }
- }
-
- nsCAutoString asciischeme;
- aURI->GetScheme(asciischeme);
- NS_ConvertUTF8toUTF16 scheme(asciischeme);
-
- nsXPIDLString desc;
- GetApplicationDescription(asciischeme, desc);
-
- nsXPIDLString title;
- appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolTitle").get(),
- getter_Copies(title));
- nsXPIDLString checkMsg;
- appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolChkMsg").get(),
- getter_Copies(checkMsg));
- nsXPIDLString launchBtn;
- appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolLaunchBtn").get(),
- getter_Copies(launchBtn));
-
- if (desc.IsEmpty())
- appstrings->GetStringFromName(NS_LITERAL_STRING("externalProtocolUnknown").get(),
- getter_Copies(desc));
-
- nsXPIDLString message;
- const PRUnichar* msgArgs[] = { scheme.get(), uri.get(), desc.get() };
- appstrings->FormatStringFromName(NS_LITERAL_STRING("externalProtocolPrompt").get(),
- msgArgs,
- NS_ARRAY_LENGTH(msgArgs),
- getter_Copies(message));
-
- if (scheme.IsEmpty() || uri.IsEmpty() || title.IsEmpty() ||
- checkMsg.IsEmpty() || launchBtn.IsEmpty() || message.IsEmpty() ||
- desc.IsEmpty())
- return PR_FALSE;
-
- // all pieces assembled, now we can pose the dialog
- PRInt32 choice = 1; // assume "cancel" in case of failure
- rv = prompt->ConfirmEx(title.get(), message.get(),
- nsIPrompt::BUTTON_DELAY_ENABLE +
- nsIPrompt::BUTTON_POS_1_DEFAULT +
- (nsIPrompt::BUTTON_TITLE_IS_STRING * nsIPrompt::BUTTON_POS_0) +
- (nsIPrompt::BUTTON_TITLE_CANCEL * nsIPrompt::BUTTON_POS_1),
- launchBtn.get(), 0, 0, checkMsg.get(),
- aRemember, &choice);
-
- if (NS_SUCCEEDED(rv) && choice == 0)
- return PR_TRUE;
-
- return PR_FALSE;
+ nsCOMPtr<nsIContentDispatchChooser> chooser =
+ do_CreateInstance("@mozilla.org/content-dispatch-chooser;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return chooser->Ask(handler, aWindowContext, aURI,
+ nsIContentDispatchChooser::REASON_CANNOT_HANDLE);
}
NS_IMETHODIMP nsExternalHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
{
// this method should only be implemented by each OS specific implementation of this service.
return NS_ERROR_NOT_IMPLEMENTED;
}
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -346,23 +346,16 @@ protected:
* Functions related to the tempory file cleanup service provided by
* nsExternalHelperAppService
*/
NS_HIDDEN_(nsresult) ExpungeTemporaryFiles();
/**
* Array for the files that should be deleted
*/
nsCOMArray<nsILocalFile> mTemporaryFilesList;
-
- /**
- * OS-specific loading of external URLs
- */
- virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI * aURL) = 0;
- NS_HIDDEN_(PRBool) isExternalLoadOK(nsIURI* aURI, nsIPrompt* aPrompt);
- NS_HIDDEN_(PRBool) promptForScheme(nsIURI* aURI, nsIPrompt* aPrompt, PRBool *aRemember);
};
/**
* We need to read the data out of the incoming stream into a buffer which we
* can then use to write the data into the output stream representing the
* temp file.
*/
#define DATA_BUFFER_SIZE (4096*2)
--- a/uriloader/exthandler/nsExternalProtocolHandler.cpp
+++ b/uriloader/exthandler/nsExternalProtocolHandler.cpp
@@ -183,20 +183,17 @@ nsresult nsExtProtocolChannel::OpenURL()
#ifdef DEBUG
nsCAutoString urlScheme;
mUrl->GetScheme(urlScheme);
PRBool haveHandler = PR_FALSE;
extProtService->ExternalProtocolHandlerExists(urlScheme.get(), &haveHandler);
NS_ASSERTION(haveHandler, "Why do we have a channel for this url if we don't support the protocol?");
#endif
- // get an nsIPrompt from the channel if we can
- nsCOMPtr<nsIPrompt> prompt;
- NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, prompt);
- rv = extProtService->LoadURI(mUrl, prompt);
+ rv = extProtService->LoadURI(mUrl, nsnull);
}
// Drop notification callbacks to prevent cycles.
mCallbacks = 0;
return rv;
}
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/nsIContentDispatchChooser.idl
@@ -0,0 +1,78 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsISupports.idl"
+
+interface nsIHandlerInfo;
+interface nsIHelperAppLauncher;
+interface nsIURI;
+interface nsIInterfaceRequestor;
+
+/**
+ * This is used to ask a user what they would like to do with a given piece of
+ * content.
+ */
+[scriptable, uuid(456ca3b2-02be-4f97-89a2-08c08d3ad88f)]
+interface nsIContentDispatchChooser : nsISupports {
+ /**
+ * This request is passed to the helper app dialog because Gecko can not
+ * handle content of this type.
+ */
+ const unsigned long REASON_CANNOT_HANDLE = 0;
+
+ /**
+ * Asks the user what to do with the content.
+ *
+ * @param aHander
+ * The interface describing the details of how this content should or
+ * can be handled.
+ * @param aWindowContext
+ * The parent window context to show this chooser. This can be null,
+ * and some implementations may not care about it. Generally, you'll
+ * want to pass an nsIDOMWindow in so the chooser can be properly
+ * parented when opened.
+ * @param aURI
+ * The URI of the resource that we are asking about.
+ * @param aReason
+ * The reason why we are asking (see above).
+ */
+ void ask(in nsIHandlerInfo aHandler,
+ in nsIInterfaceRequestor aWindowContext,
+ in nsIURI aURI,
+ in unsigned long aReason);
+};
+
--- a/uriloader/exthandler/nsIExternalProtocolService.idl
+++ b/uriloader/exthandler/nsIExternalProtocolService.idl
@@ -36,28 +36,28 @@
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
interface nsIURI;
interface nsIFile;
-interface nsIPrompt;
+interface nsIInterfaceRequestor;
/**
* The external protocol service is used for finding and launching
* web handlers (a la registerProtocolHandler in the HTML5 draft) or
* platform-specific applications for handling particular protocols.
*
* You can ask the external protocol service if it has an external
* handler for a given protocol scheme. And you can ask it to load
* the url using the default handler.
*/
-[scriptable, uuid(a49813a4-98b7-4bdb-998c-8bd9704af0c0)]
+[scriptable, uuid(01e9ce6e-1c81-4f1a-b128-2f2526ec40e3)]
interface nsIExternalProtocolService : nsISupports
{
/**
* Check whether a handler for a specific protocol exists.
* @param aProtocolScheme The scheme from a url: http, ftp, mailto, etc.
* @return true if we have a handler and false otherwise.
*/
boolean externalProtocolHandlerExists(in string aProtocolScheme);
@@ -71,28 +71,31 @@ interface nsIExternalProtocolService : n
* application. For example, a non-exposed protocol would not be loaded by the
* application in response to a link click or a X-remote openURL command.
* Instead, it would be deferred to the system's external protocol handler.
*/
boolean isExposedProtocol(in string aProtocolScheme);
/**
* Used to load a url via an external protocol handler (if one exists)
+ *
* @param aURL The url to load
+ * @deprecated Use LoadURI instead (See Bug 389565 for removal)
*/
- void loadUrl (in nsIURI aURL);
+ void loadUrl (in nsIURI aURL);
/**
* Used to load a URI via an external application. Might prompt the user for
- * permission to load the external application. Replaces loadUrl()
+ * permission to load the external application.
*
- * @param aURI The URI to load
- * @param aPrompt If null we grab one from windowwatcher if we need it
+ * @param aURI The URI to load
+ * @param aWindowContext The parent window to open the dialog with.
*/
- void loadURI(in nsIURI aURI, in nsIPrompt aPrompt);
+ void loadURI(in nsIURI aURI,
+ [optional] in nsIInterfaceRequestor aWindowContext);
/**
* Gets a human-readable description for the application responsible for
* handling a specific protocol.
*
* @param aScheme The scheme to look up. For example, "mms".
*
* @throw NS_ERROR_NOT_IMPLEMENTED
--- a/uriloader/exthandler/nsMIMEInfoImpl.cpp
+++ b/uriloader/exthandler/nsMIMEInfoImpl.cpp
@@ -1,10 +1,10 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=4 sw=4 sts=4 et: */
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
@@ -359,16 +359,19 @@ nsMIMEInfoBase::LaunchWithURI(nsIURI* aU
NS_ENSURE_SUCCESS(rv, rv);
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
NS_ENSURE_SUCCESS(rv, rv);
return LaunchWithIProcess(executable, docToLoad);
}
else if (mPreferredAction == useSystemDefault) {
+ if (mClass == eProtocolInfo)
+ return LoadUriInternal(aURI);
+
rv = GetLocalFileFromURI(aURI, getter_AddRefs(docToLoad));
NS_ENSURE_SUCCESS(rv, rv);
return LaunchDefaultWithFile(docToLoad);
}
return NS_ERROR_INVALID_ARG;
}
--- a/uriloader/exthandler/nsMIMEInfoImpl.h
+++ b/uriloader/exthandler/nsMIMEInfoImpl.h
@@ -128,16 +128,23 @@ class nsMIMEInfoBase : public nsIMIMEInf
* For even more control over the launching, override launchWithFile.
* Also see the comment about nsIMIMEInfo in general, above.
*
* @param aFile The file that should be opened
*/
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile) = 0;
/**
+ * Loads the URI with the OS default app.
+ *
+ * @param aURI The URI to pass off to the OS.
+ */
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI) = 0;
+
+ /**
* This method can be used to launch the file using nsIProcess, with the
* path of the file being the first parameter to the executable. This is
* meant as a helper method for implementations of
* LaunchWithFile/LaunchDefaultWithFile.
* Neither aApp nor aFile may be null.
*
* @param aApp The application to launch
* @param aFile The file to open in the application
@@ -196,21 +203,27 @@ class nsMIMEInfoImpl : public nsMIMEInfo
NS_IMETHOD GetDefaultDescription(nsAString& aDefaultDescription);
// additional methods
/**
* Sets the default application. Supposed to be only called by the OS Helper
* App Services; the default application is immutable after it is first set.
*/
void SetDefaultApplication(nsIFile* aApp) { if (!mDefaultApplication) mDefaultApplication = aApp; }
+
protected:
// nsMIMEInfoBase methods
/**
* The base class implementation is to use LaunchWithIProcess in combination
* with mDefaultApplication. Subclasses can override that behaviour.
*/
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile);
+ /**
+ * Loads the URI with the OS default app. This should be overridden by each
+ * OS's implementation.
+ */
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI) = 0;
nsCOMPtr<nsIFile> mDefaultApplication; ///< default application associated with this type.
};
#endif //__nsmimeinfoimpl_h___
--- a/uriloader/exthandler/os2/nsMIMEInfoOS2.cpp
+++ b/uriloader/exthandler/os2/nsMIMEInfoOS2.cpp
@@ -149,8 +149,260 @@ NS_IMETHODIMP nsMIMEInfoOS2::LaunchWithU
// make the registry call to launch the app
nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID);
if (NS_FAILED(rv = process->Init(application)))
return rv;
PRUint32 pid;
return process->Run(PR_FALSE, &strPath, 1, &pid);
}
+nsresult nsMIMEInfoOS2::LoadUriInternal(nsIURI * aURL)
+{
+ LOG(("-- nsOSHelperAppService::LoadUriInternal\n"));
+ nsCOMPtr<nsIPref> thePrefsService(do_GetService(NS_PREF_CONTRACTID));
+ if (!thePrefsService) {
+ return NS_ERROR_FAILURE;
+ }
+
+ /* Convert SimpleURI to StandardURL */
+ nsresult rv;
+ nsCOMPtr<nsIURI> uri = do_CreateInstance(kStandardURLCID, &rv);
+ if (NS_FAILED(rv)) {
+ return NS_ERROR_FAILURE;
+ }
+ nsCAutoString urlSpec;
+ aURL->GetSpec(urlSpec);
+ uri->SetSpec(urlSpec);
+
+ /* Get the protocol so we can look up the preferences */
+ nsCAutoString uProtocol;
+ uri->GetScheme(uProtocol);
+
+ nsCAutoString prefName;
+ prefName = NS_LITERAL_CSTRING("applications.") + uProtocol;
+ nsXPIDLCString prefString;
+
+ nsCAutoString applicationName;
+ nsCAutoString parameters;
+
+ rv = thePrefsService->CopyCharPref(prefName.get(), getter_Copies(prefString));
+ if (NS_FAILED(rv) || prefString.IsEmpty()) {
+ char szAppFromINI[CCHMAXPATH];
+ char szParamsFromINI[MAXINIPARAMLENGTH];
+ /* did OS2.INI contain application? */
+ rv = GetApplicationAndParametersFromINI(uProtocol,
+ szAppFromINI, sizeof(szAppFromINI),
+ szParamsFromINI, sizeof(szParamsFromINI));
+ if (NS_SUCCEEDED(rv)) {
+ applicationName = szAppFromINI;
+ parameters = szParamsFromINI;
+ } else {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Dissect the URI
+ nsCAutoString uURL, uUsername, uPassword, uHost, uPort, uPath;
+ nsCAutoString uEmail, uGroup;
+ PRInt32 iPort;
+
+ // when passing to OS/2 apps later, we need ASCII URLs,
+ // UTF-8 would probably not get handled correctly
+ aURL->GetAsciiSpec(uURL);
+ uri->GetAsciiHost(uHost);
+ uri->GetUsername(uUsername);
+ NS_UnescapeURL(uUsername);
+ uri->GetPassword(uPassword);
+ NS_UnescapeURL(uPassword);
+ uri->GetPort(&iPort);
+ /* GetPort returns -1 if there is no port in the URI */
+ if (iPort != -1)
+ uPort.AppendInt(iPort);
+ uri->GetPath(uPath);
+ NS_UnescapeURL(uPath);
+
+ // One could use nsIMailtoUrl to get email and newsgroup,
+ // but it is probably easier to do that quickly by hand here
+ // uEmail is both email address and message id for news
+ uEmail = uUsername + NS_LITERAL_CSTRING("@") + uHost;
+ // uPath can almost be used as newsgroup and as channel for IRC
+ // but strip leading "/"
+ uGroup = Substring(uPath, 1, uPath.Length());
+
+ NS_NAMED_LITERAL_CSTRING(url, "%url%");
+ NS_NAMED_LITERAL_CSTRING(username, "%username%");
+ NS_NAMED_LITERAL_CSTRING(password, "%password%");
+ NS_NAMED_LITERAL_CSTRING(host, "%host%");
+ NS_NAMED_LITERAL_CSTRING(port, "%port%");
+ NS_NAMED_LITERAL_CSTRING(email, "%email%");
+ NS_NAMED_LITERAL_CSTRING(group, "%group%");
+ NS_NAMED_LITERAL_CSTRING(msgid, "%msgid%");
+ NS_NAMED_LITERAL_CSTRING(channel, "%channel%");
+
+ if (applicationName.IsEmpty() && parameters.IsEmpty()) {
+ /* Put application name in parameters */
+ applicationName.Append(prefString);
+
+ prefName.Append(".");
+ nsCOMPtr<nsIPrefBranch> prefBranch;
+ rv = thePrefsService->GetBranch(prefName.get(), getter_AddRefs(prefBranch));
+ if (NS_SUCCEEDED(rv) && prefBranch) {
+ rv = prefBranch->GetCharPref("parameters", getter_Copies(prefString));
+ /* If parameters have been specified, use them instead of the separate entities */
+ if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
+ parameters.Append(" ");
+ parameters.Append(prefString);
+
+ PRInt32 pos = parameters.Find(url.get());
+ if (pos != kNotFound) {
+ nsCAutoString uURL;
+ aURL->GetSpec(uURL);
+ NS_UnescapeURL(uURL);
+ uURL.Cut(0, uProtocol.Length()+1);
+ parameters.Replace(pos, url.Length(), uURL);
+ }
+ } else {
+ /* port */
+ if (!uPort.IsEmpty()) {
+ rv = prefBranch->GetCharPref("port", getter_Copies(prefString));
+ if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
+ parameters.Append(" ");
+ parameters.Append(prefString);
+ }
+ }
+ /* username */
+ if (!uUsername.IsEmpty()) {
+ rv = prefBranch->GetCharPref("username", getter_Copies(prefString));
+ if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
+ parameters.Append(" ");
+ parameters.Append(prefString);
+ }
+ }
+ /* password */
+ if (!uPassword.IsEmpty()) {
+ rv = prefBranch->GetCharPref("password", getter_Copies(prefString));
+ if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
+ parameters.Append(" ");
+ parameters.Append(prefString);
+ }
+ }
+ /* host */
+ if (!uHost.IsEmpty()) {
+ rv = prefBranch->GetCharPref("host", getter_Copies(prefString));
+ if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
+ parameters.Append(" ");
+ parameters.Append(prefString);
+ }
+ }
+ }
+ }
+ }
+
+#ifdef DEBUG_peter
+ printf("uURL=%s\n", uURL.get());
+ printf("uUsername=%s\n", uUsername.get());
+ printf("uPassword=%s\n", uPassword.get());
+ printf("uHost=%s\n", uHost.get());
+ printf("uPort=%s\n", uPort.get());
+ printf("uPath=%s\n", uPath.get());
+ printf("uEmail=%s\n", uEmail.get());
+ printf("uGroup=%s\n", uGroup.get());
+#endif
+
+ PRInt32 pos;
+ PRBool replaced = PR_FALSE;
+ pos = parameters.Find(url.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, url.Length(), uURL);
+ }
+ pos = parameters.Find(username.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, username.Length(), uUsername);
+ }
+ pos = parameters.Find(password.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, password.Length(), uPassword);
+ }
+ pos = parameters.Find(host.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, host.Length(), uHost);
+ }
+ pos = parameters.Find(port.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, port.Length(), uPort);
+ }
+ pos = parameters.Find(email.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, email.Length(), uEmail);
+ }
+ pos = parameters.Find(group.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, group.Length(), uGroup);
+ }
+ pos = parameters.Find(msgid.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, msgid.Length(), uEmail);
+ }
+ pos = parameters.Find(channel.get());
+ if (pos != kNotFound) {
+ replaced = PR_TRUE;
+ parameters.Replace(pos, channel.Length(), uGroup);
+ }
+ // If no replacement variable was used, the user most likely uses the WPS URL
+ // object and does not know about the replacement variables.
+ // Just append the full URL.
+ if (!replaced) {
+ parameters.Append(" ");
+ parameters.Append(uURL);
+ }
+
+ const char *params[3];
+ params[0] = parameters.get();
+#ifdef DEBUG_peter
+ printf("params[0]=%s\n", params[0]);
+#endif
+ PRInt32 numParams = 1;
+
+ nsCOMPtr<nsILocalFile> application;
+ rv = NS_NewNativeLocalFile(nsDependentCString(applicationName.get()), PR_FALSE, getter_AddRefs(application));
+ if (NS_FAILED(rv)) {
+ /* Maybe they didn't qualify the name - search path */
+ char szAppPath[CCHMAXPATH];
+ APIRET rc = DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT,
+ "PATH", applicationName.get(),
+ szAppPath, sizeof(szAppPath));
+ if (rc == NO_ERROR) {
+ rv = NS_NewNativeLocalFile(nsDependentCString(szAppPath), PR_FALSE, getter_AddRefs(application));
+ }
+ if (NS_FAILED(rv) || (rc != NO_ERROR)) {
+ /* Try just launching it with COMSPEC */
+ rv = NS_NewNativeLocalFile(nsDependentCString(getenv("COMSPEC")), PR_FALSE, getter_AddRefs(application));
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ params[0] = "/c";
+ params[1] = applicationName.get();
+ params[2] = parameters.get();
+ numParams = 3;
+ }
+ }
+
+ nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID);
+
+ if (NS_FAILED(rv = process->Init(application)))
+ return rv;
+
+ PRUint32 pid;
+ if (NS_FAILED(rv = process->Run(PR_FALSE, params, numParams, &pid)))
+ return rv;
+
+ return NS_OK;
+}
+
--- a/uriloader/exthandler/os2/nsMIMEInfoOS2.h
+++ b/uriloader/exthandler/os2/nsMIMEInfoOS2.h
@@ -44,19 +44,19 @@ class nsMIMEInfoOS2 : public nsMIMEInfoI
public:
nsMIMEInfoOS2(const char* aType = "") : nsMIMEInfoImpl(aType) {}
nsMIMEInfoOS2(const nsACString& aMIMEType) : nsMIMEInfoImpl(aMIMEType) {}
nsMIMEInfoOS2(const nsACString& aType, HandlerClass aClass) :
nsMIMEInfoImpl(aType, aClass) {}
virtual ~nsMIMEInfoOS2();
NS_IMETHOD LaunchWithURI(nsIURI* aURI);
-
+ protected:
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
#ifdef DEBUG
- protected:
virtual NS_HIDDEN_(nsresult) LaunchDefaultWithFile(nsIFile* aFile) {
NS_NOTREACHED("Do not call this, use LaunchWithFile");
return NS_ERROR_UNEXPECTED;
}
#endif
};
#endif
--- a/uriloader/exthandler/os2/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/os2/nsOSHelperAppService.cpp
@@ -1269,268 +1269,16 @@ nsresult nsOSHelperAppService::OSProtoco
if (NS_SUCCEEDED(rv)) {
*aHandlerExists = PR_TRUE;
return NS_OK;
}
return NS_ERROR_FAILURE;
}
-nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
-{
- LOG(("-- nsOSHelperAppService::LoadUriInternal\n"));
- nsCOMPtr<nsIPref> thePrefsService(do_GetService(NS_PREF_CONTRACTID));
- if (!thePrefsService) {
- return NS_ERROR_FAILURE;
- }
-
- /* Convert SimpleURI to StandardURL */
- nsresult rv;
- nsCOMPtr<nsIURI> uri = do_CreateInstance(kStandardURLCID, &rv);
- if (NS_FAILED(rv)) {
- return NS_ERROR_FAILURE;
- }
- nsCAutoString urlSpec;
- aURL->GetSpec(urlSpec);
- uri->SetSpec(urlSpec);
-
- /* Get the protocol so we can look up the preferences */
- nsCAutoString uProtocol;
- uri->GetScheme(uProtocol);
-
- nsCAutoString prefName;
- prefName = NS_LITERAL_CSTRING("applications.") + uProtocol;
- nsXPIDLCString prefString;
-
- nsCAutoString applicationName;
- nsCAutoString parameters;
-
- rv = thePrefsService->CopyCharPref(prefName.get(), getter_Copies(prefString));
- if (NS_FAILED(rv) || prefString.IsEmpty()) {
- char szAppFromINI[CCHMAXPATH];
- char szParamsFromINI[MAXINIPARAMLENGTH];
- /* did OS2.INI contain application? */
- rv = GetApplicationAndParametersFromINI(uProtocol,
- szAppFromINI, sizeof(szAppFromINI),
- szParamsFromINI, sizeof(szParamsFromINI));
- if (NS_SUCCEEDED(rv)) {
- applicationName = szAppFromINI;
- parameters = szParamsFromINI;
- } else {
- return NS_ERROR_FAILURE;
- }
- }
-
- // Dissect the URI
- nsCAutoString uURL, uUsername, uPassword, uHost, uPort, uPath;
- nsCAutoString uEmail, uGroup;
- PRInt32 iPort;
-
- // when passing to OS/2 apps later, we need ASCII URLs,
- // UTF-8 would probably not get handled correctly
- aURL->GetAsciiSpec(uURL);
- uri->GetAsciiHost(uHost);
- uri->GetUsername(uUsername);
- NS_UnescapeURL(uUsername);
- uri->GetPassword(uPassword);
- NS_UnescapeURL(uPassword);
- uri->GetPort(&iPort);
- /* GetPort returns -1 if there is no port in the URI */
- if (iPort != -1)
- uPort.AppendInt(iPort);
- uri->GetPath(uPath);
- NS_UnescapeURL(uPath);
-
- // One could use nsIMailtoUrl to get email and newsgroup,
- // but it is probably easier to do that quickly by hand here
- // uEmail is both email address and message id for news
- uEmail = uUsername + NS_LITERAL_CSTRING("@") + uHost;
- // uPath can almost be used as newsgroup and as channel for IRC
- // but strip leading "/"
- uGroup = Substring(uPath, 1, uPath.Length());
-
- NS_NAMED_LITERAL_CSTRING(url, "%url%");
- NS_NAMED_LITERAL_CSTRING(username, "%username%");
- NS_NAMED_LITERAL_CSTRING(password, "%password%");
- NS_NAMED_LITERAL_CSTRING(host, "%host%");
- NS_NAMED_LITERAL_CSTRING(port, "%port%");
- NS_NAMED_LITERAL_CSTRING(email, "%email%");
- NS_NAMED_LITERAL_CSTRING(group, "%group%");
- NS_NAMED_LITERAL_CSTRING(msgid, "%msgid%");
- NS_NAMED_LITERAL_CSTRING(channel, "%channel%");
-
- if (applicationName.IsEmpty() && parameters.IsEmpty()) {
- /* Put application name in parameters */
- applicationName.Append(prefString);
-
- prefName.Append(".");
- nsCOMPtr<nsIPrefBranch> prefBranch;
- rv = thePrefsService->GetBranch(prefName.get(), getter_AddRefs(prefBranch));
- if (NS_SUCCEEDED(rv) && prefBranch) {
- rv = prefBranch->GetCharPref("parameters", getter_Copies(prefString));
- /* If parameters have been specified, use them instead of the separate entities */
- if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
- parameters.Append(" ");
- parameters.Append(prefString);
-
- PRInt32 pos = parameters.Find(url.get());
- if (pos != kNotFound) {
- nsCAutoString uURL;
- aURL->GetSpec(uURL);
- NS_UnescapeURL(uURL);
- uURL.Cut(0, uProtocol.Length()+1);
- parameters.Replace(pos, url.Length(), uURL);
- }
- } else {
- /* port */
- if (!uPort.IsEmpty()) {
- rv = prefBranch->GetCharPref("port", getter_Copies(prefString));
- if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
- parameters.Append(" ");
- parameters.Append(prefString);
- }
- }
- /* username */
- if (!uUsername.IsEmpty()) {
- rv = prefBranch->GetCharPref("username", getter_Copies(prefString));
- if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
- parameters.Append(" ");
- parameters.Append(prefString);
- }
- }
- /* password */
- if (!uPassword.IsEmpty()) {
- rv = prefBranch->GetCharPref("password", getter_Copies(prefString));
- if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
- parameters.Append(" ");
- parameters.Append(prefString);
- }
- }
- /* host */
- if (!uHost.IsEmpty()) {
- rv = prefBranch->GetCharPref("host", getter_Copies(prefString));
- if (NS_SUCCEEDED(rv) && !prefString.IsEmpty()) {
- parameters.Append(" ");
- parameters.Append(prefString);
- }
- }
- }
- }
- }
-
-#ifdef DEBUG_peter
- printf("uURL=%s\n", uURL.get());
- printf("uUsername=%s\n", uUsername.get());
- printf("uPassword=%s\n", uPassword.get());
- printf("uHost=%s\n", uHost.get());
- printf("uPort=%s\n", uPort.get());
- printf("uPath=%s\n", uPath.get());
- printf("uEmail=%s\n", uEmail.get());
- printf("uGroup=%s\n", uGroup.get());
-#endif
-
- PRInt32 pos;
- PRBool replaced = PR_FALSE;
- pos = parameters.Find(url.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, url.Length(), uURL);
- }
- pos = parameters.Find(username.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, username.Length(), uUsername);
- }
- pos = parameters.Find(password.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, password.Length(), uPassword);
- }
- pos = parameters.Find(host.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, host.Length(), uHost);
- }
- pos = parameters.Find(port.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, port.Length(), uPort);
- }
- pos = parameters.Find(email.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, email.Length(), uEmail);
- }
- pos = parameters.Find(group.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, group.Length(), uGroup);
- }
- pos = parameters.Find(msgid.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, msgid.Length(), uEmail);
- }
- pos = parameters.Find(channel.get());
- if (pos != kNotFound) {
- replaced = PR_TRUE;
- parameters.Replace(pos, channel.Length(), uGroup);
- }
- // If no replacement variable was used, the user most likely uses the WPS URL
- // object and does not know about the replacement variables.
- // Just append the full URL.
- if (!replaced) {
- parameters.Append(" ");
- parameters.Append(uURL);
- }
-
- const char *params[3];
- params[0] = parameters.get();
-#ifdef DEBUG_peter
- printf("params[0]=%s\n", params[0]);
-#endif
- PRInt32 numParams = 1;
-
- nsCOMPtr<nsILocalFile> application;
- rv = NS_NewNativeLocalFile(nsDependentCString(applicationName.get()), PR_FALSE, getter_AddRefs(application));
- if (NS_FAILED(rv)) {
- /* Maybe they didn't qualify the name - search path */
- char szAppPath[CCHMAXPATH];
- APIRET rc = DosSearchPath(SEARCH_IGNORENETERRS | SEARCH_ENVIRONMENT,
- "PATH", applicationName.get(),
- szAppPath, sizeof(szAppPath));
- if (rc == NO_ERROR) {
- rv = NS_NewNativeLocalFile(nsDependentCString(szAppPath), PR_FALSE, getter_AddRefs(application));
- }
- if (NS_FAILED(rv) || (rc != NO_ERROR)) {
- /* Try just launching it with COMSPEC */
- rv = NS_NewNativeLocalFile(nsDependentCString(getenv("COMSPEC")), PR_FALSE, getter_AddRefs(application));
- if (NS_FAILED(rv)) {
- return rv;
- }
-
- params[0] = "/c";
- params[1] = applicationName.get();
- params[2] = parameters.get();
- numParams = 3;
- }
- }
-
- nsCOMPtr<nsIProcess> process = do_CreateInstance(NS_PROCESS_CONTRACTID);
-
- if (NS_FAILED(rv = process->Init(application)))
- return rv;
-
- PRUint32 pid;
- if (NS_FAILED(rv = process->Run(PR_FALSE, params, numParams, &pid)))
- return rv;
-
- return NS_OK;
-}
-
already_AddRefed<nsMIMEInfoOS2>
nsOSHelperAppService::GetFromExtension(const nsCString& aFileExt) {
// if the extension is empty, return immediately
if (aFileExt.IsEmpty())
return nsnull;
LOG(("Here we do an extension lookup for '%s'\n", aFileExt.get()));
--- a/uriloader/exthandler/os2/nsOSHelperAppService.h
+++ b/uriloader/exthandler/os2/nsOSHelperAppService.h
@@ -59,17 +59,16 @@ public:
virtual ~nsOSHelperAppService();
// method overrides for mime.types and mime.info look up steps
already_AddRefed<nsIMIMEInfo> GetMIMEInfoFromOS(const nsACString& aMimeType,
const nsACString& aFileExt,
PRBool *aFound);
// override nsIExternalProtocolService methods
- nsresult LoadUriInternal(nsIURI * aURL);
NS_IMETHODIMP GetApplicationDescription(const nsACString& aScheme, nsAString& _retval);
nsresult OSProtocolHandlerExists(const char * aProtocolScheme, PRBool * aHandlerExists);
protected:
already_AddRefed<nsMIMEInfoOS2> GetFromType(const nsCString& aMimeType);
already_AddRefed<nsMIMEInfoOS2> GetFromExtension(const nsCString& aFileExt);
private:
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/unix/nsMIMEInfoUnix.cpp
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsMIMEInfoWin.h"
+
+nsresult
+nsMIMEInfoUnix::LoadUriInternal(nsIURI * aURI)
+{
+ return nsGNOMERegistry::LoadURL(aURI);
+}
+
new file mode 100644
--- /dev/null
+++ b/uriloader/exthandler/unix/nsMIMEInfoUnix.h
@@ -0,0 +1,51 @@
+/* -*- Mode: C++; tab-width: 3; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Mozilla browser.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Shawn Wilsher <me@shawnwilsher.com> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsMIMEInfoUnix_h_
+#define nsMIMEInfoUnix_h_
+
+#include "nsMIMEInfoImpl.h"
+
+class nsMIMEInfoUnix : public nsMIMEInfoBase
+{
+protected:
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
+};
+
+#endif // nsMIMEInfoUnix_h_
--- a/uriloader/exthandler/unix/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/unix/nsOSHelperAppService.cpp
@@ -1253,56 +1253,16 @@ nsresult nsOSHelperAppService::OSProtoco
// Check the GConf registry for a protocol handler
if (!*aHandlerExists)
*aHandlerExists = nsGNOMERegistry::HandlerExists(aProtocolScheme);
#endif
return NS_OK;
}
-nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURI)
-{
- // Gets a string pref network.protocol-handler.app.<scheme>
- // and executes it
- LOG(("-- nsOSHelperAppService::LoadUrl\n"));
-
- nsCAutoString scheme;
- nsresult rv = aURI->GetScheme(scheme);
- if (NS_FAILED(rv)) // need a scheme
- return rv;
-
- nsCOMPtr<nsIFile> appFile;
- rv = GetHandlerAppFromPrefs(scheme.get(), getter_AddRefs(appFile));
- if (NS_SUCCEEDED(rv)) {
- // Let's not support passing arguments for now
- nsCOMPtr<nsIProcess> proc(do_CreateInstance("@mozilla.org/process/util;1", &rv));
- if (NS_FAILED(rv))
- return rv;
-
- rv = proc->Init(appFile);
- if (NS_FAILED(rv))
- return rv;
-
- nsCAutoString spec;
- rv = aURI->GetAsciiSpec(spec);
- if (NS_FAILED(rv))
- return rv;
-
- const char* args[] = { spec.get() };
- PRUint32 tmp;
- return proc->Run(/*blocking*/PR_FALSE, args, NS_ARRAY_LENGTH(args), &tmp);
- }
-
-#ifdef MOZ_WIDGET_GTK2
- return nsGNOMERegistry::LoadURL(aURI);
-#else
- return rv;
-#endif
-}
-
NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
{
nsCOMPtr<nsIFile> appFile;
nsresult rv = GetHandlerAppFromPrefs(PromiseFlatCString(aScheme).get(),
getter_AddRefs(appFile));
if (NS_SUCCEEDED(rv))
return appFile->GetLeafName(_retval);
--- a/uriloader/exthandler/win/nsMIMEInfoWin.cpp
+++ b/uriloader/exthandler/win/nsMIMEInfoWin.cpp
@@ -39,16 +39,17 @@
* ***** END LICENSE BLOCK ***** */
#include "nsArrayEnumerator.h"
#include "nsCOMArray.h"
#include "nsILocalFile.h"
#include "nsIVariant.h"
#include "nsMIMEInfoWin.h"
#include "nsNetUtil.h"
+#include <shellapi.h>
NS_IMPL_ISUPPORTS_INHERITED1(nsMIMEInfoWin, nsMIMEInfoBase, nsIPropertyBag)
nsMIMEInfoWin::~nsMIMEInfoWin()
{
}
nsresult
@@ -127,8 +128,44 @@ nsMIMEInfoWin::GetProperty(const nsAStri
rv = GetIconURLVariant(executable, _retval);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
+// this implementation was pretty much copied verbatime from
+// Tony Robinson's code in nsExternalProtocolWin.cpp
+nsresult
+nsMIMEInfoWin::LoadUriInternal(nsIURI * aURL)
+{
+ nsresult rv = NS_OK;
+
+ // 1. Find the default app for this protocol
+ // 2. Set up the command line
+ // 3. Launch the app.
+
+ // For now, we'll just cheat essentially, check for the command line
+ // then just call ShellExecute()!
+
+ if (aURL)
+ {
+ // extract the url spec from the url
+ nsCAutoString urlSpec;
+ aURL->GetAsciiSpec(urlSpec);
+
+ // Some versions of windows (Win2k before SP3, Win XP before SP1)
+ // crash in ShellExecute on long URLs (bug 161357).
+ // IE 5 and 6 support URLS of 2083 chars in length, 2K is safe
+ const PRUint32 maxSafeURL(2048);
+ if (urlSpec.Length() > maxSafeURL)
+ return NS_ERROR_FAILURE;
+
+ LONG r = (LONG) ::ShellExecute(NULL, "open", urlSpec.get(), NULL, NULL,
+ SW_SHOWNORMAL);
+ if (r < 32)
+ rv = NS_ERROR_FAILURE;
+ }
+
+ return rv;
+}
+
--- a/uriloader/exthandler/win/nsMIMEInfoWin.h
+++ b/uriloader/exthandler/win/nsMIMEInfoWin.h
@@ -52,16 +52,18 @@ class nsMIMEInfoWin : public nsMIMEInfoB
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIPROPERTYBAG
void SetDefaultApplicationHandler(nsIFile* aDefaultApplication)
{
mDefaultApplication = aDefaultApplication;
}
+
protected:
+ virtual NS_HIDDEN_(nsresult) LoadUriInternal(nsIURI *aURI);
virtual nsresult LaunchDefaultWithFile(nsIFile* aFile);
private:
nsCOMPtr<nsIFile> mDefaultApplication;
};
#endif
--- a/uriloader/exthandler/win/nsOSHelperAppService.cpp
+++ b/uriloader/exthandler/win/nsOSHelperAppService.cpp
@@ -152,52 +152,16 @@ nsresult nsOSHelperAppService::OSProtoco
// close the key
::RegCloseKey(hKey);
}
}
return NS_OK;
}
-// this implementation was pretty much copied verbatime from
-// Tony Robinson's code in nsExternalProtocolWin.cpp
-
-nsresult nsOSHelperAppService::LoadUriInternal(nsIURI * aURL)
-{
- nsresult rv = NS_OK;
-
- // 1. Find the default app for this protocol
- // 2. Set up the command line
- // 3. Launch the app.
-
- // For now, we'll just cheat essentially, check for the command line
- // then just call ShellExecute()!
-
- if (aURL)
- {
- // extract the url spec from the url
- nsCAutoString urlSpec;
- aURL->GetAsciiSpec(urlSpec);
-
- // Some versions of windows (Win2k before SP3, Win XP before SP1)
- // crash in ShellExecute on long URLs (bug 161357).
- // IE 5 and 6 support URLS of 2083 chars in length, 2K is safe
- const PRUint32 maxSafeURL(2048);
- if (urlSpec.Length() > maxSafeURL)
- return NS_ERROR_FAILURE;
-
- LONG r = (LONG) ::ShellExecute(NULL, "open", urlSpec.get(), NULL, NULL,
- SW_SHOWNORMAL);
- if (r < 32)
- rv = NS_ERROR_FAILURE;
- }
-
- return rv;
-}
-
NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString& aScheme, nsAString& _retval)
{
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (!regKey)
return NS_ERROR_NOT_AVAILABLE;
NS_ConvertASCIItoUTF16 buf(aScheme);