commit 79b1fe30dcb36b810fae27bbae4e1197688bae52
parent 20afa7e5610847b90534c5ef1a07c0149d483fa5
Author: Dan Stillman <dstillman@zotero.org>
Date: Fri, 20 Jan 2012 15:23:06 -0500
Workaround for broken file/URL launching in Standalone on Linux
Falls back to /usr/bin/xdg-open by default, configurable via
extensions.zotero.fallbackLauncher.unix (or .windows, though that
should be much rarer). Also used for file revealing.
If xdg-open fails, files launch via the external helper app dialog and
URLs just don't work.
Diffstat:
2 files changed, 122 insertions(+), 42 deletions(-)
diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js
@@ -2682,14 +2682,7 @@ var ZoteroPane = new function()
if (Zotero.isStandalone) {
if(uri.match(/^https?/)) {
- var io = Components.classes['@mozilla.org/network/io-service;1']
- .getService(Components.interfaces.nsIIOService);
- var uri = io.newURI(uri, null, null);
- var handler = Components.classes['@mozilla.org/uriloader/external-protocol-service;1']
- .getService(Components.interfaces.nsIExternalProtocolService)
- .getProtocolHandlerInfo('http');
- handler.preferredAction = Components.interfaces.nsIHandlerInfo.useSystemDefault;
- handler.launchWithURI(uri, null);
+ this.launchURL(uri);
} else {
ZoteroStandalone.openInViewer(uri);
}
@@ -3408,22 +3401,7 @@ var ZoteroPane = new function()
this.loadURI(url, event);
}
else {
- // Some platforms don't have nsILocalFile.launch, so we just
- // let the Firefox external helper app window handle it
- try {
- file.launch();
- }
- catch (e) {
- Zotero.debug("launch() not supported -- passing file to loadUrl()");
-
- var uri = Components.classes["@mozilla.org/network/standard-url;1"].
- createInstance(Components.interfaces.nsIURI);
- uri.spec = attachment.getLocalFileURL();
-
- var nsIEPS = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
- getService(Components.interfaces.nsIExternalProtocolService);
- nsIEPS.loadUrl(uri);
- }
+ this.launchFile(file);
}
}
else {
@@ -3433,6 +3411,116 @@ var ZoteroPane = new function()
}
+ /**
+ * Launch a file, the best way we can
+ */
+ this.launchFile = function (file) {
+ try {
+ file.launch();
+ }
+ catch (e) {
+ Zotero.debug("launch() not supported -- trying fallback executable");
+
+ try {
+ if (Zotero.isWin) {
+ var pref = "fallbackLauncher.windows";
+ }
+ else {
+ var pref = "fallbackLauncher.unix";
+ }
+ var path = Zotero.Prefs.get(pref);
+
+ var exec = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ exec.initWithPath(path);
+ if (!exec.exists()) {
+ throw (path + " does not exist");
+ }
+
+ var proc = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ proc.init(exec);
+
+ var args = [file.path];
+ if (!Zotero.isFx36) {
+ proc.runw(true, args, args.length);
+ }
+ else {
+ proc.run(true, args, args.length);
+ }
+ }
+ catch (e) {
+ Zotero.debug(e);
+ Zotero.debug("Launching via executable failed -- passing to loadUrl()");
+
+ // If nsILocalFile.launch() isn't available and the fallback
+ // executable doesn't exist, we just let the Firefox external
+ // helper app window handle it
+ var nsIFPH = Components.classes["@mozilla.org/network/protocol;1?name=file"]
+ .getService(Components.interfaces.nsIFileProtocolHandler);
+ var uri = nsIFPH.newFileURI(file);
+
+ var nsIEPS = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
+ getService(Components.interfaces.nsIExternalProtocolService);
+ nsIEPS.loadUrl(uri);
+ }
+ }
+ }
+
+
+ /**
+ * Launch an HTTP URL externally, the best way we can
+ *
+ * Used only by Standalone
+ */
+ this.launchURL = function (url) {
+ if (!url.match(/^https?/)) {
+ throw new Error("launchURL() requires an HTTP(S) URL");
+ }
+
+ try {
+ var io = Components.classes['@mozilla.org/network/io-service;1']
+ .getService(Components.interfaces.nsIIOService);
+ var uri = io.newURI(url, null, null);
+ var handler = Components.classes['@mozilla.org/uriloader/external-protocol-service;1']
+ .getService(Components.interfaces.nsIExternalProtocolService)
+ .getProtocolHandlerInfo('http');
+ handler.preferredAction = Components.interfaces.nsIHandlerInfo.useSystemDefault;
+ handler.launchWithURI(uri, null);
+ }
+ catch (e) {
+ Zotero.debug("launchWithURI() not supported -- trying fallback executable");
+
+ if (Zotero.isWin) {
+ var pref = "fallbackLauncher.windows";
+ }
+ else {
+ var pref = "fallbackLauncher.unix";
+ }
+ var path = Zotero.Prefs.get(pref);
+
+ var exec = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(Components.interfaces.nsILocalFile);
+ exec.initWithPath(path);
+ if (!exec.exists()) {
+ throw ("Fallback executable not found -- check extensions.zotero." + pref + " in about:config");
+ }
+
+ var proc = Components.classes["@mozilla.org/process/util;1"]
+ .createInstance(Components.interfaces.nsIProcess);
+ proc.init(exec);
+
+ var args = [url];
+ if (!Zotero.isFx36) {
+ proc.runw(true, args, args.length);
+ }
+ else {
+ proc.run(true, args, args.length);
+ }
+ }
+ }
+
+
function viewSelectedAttachment(event, noLocateOnMissing)
{
if (this.itemsView && this.itemsView.selection.count == 1) {
@@ -3445,27 +3533,15 @@ var ZoteroPane = new function()
var attachment = Zotero.Items.get(itemID)
if (attachment.attachmentLinkMode != Zotero.Attachments.LINK_MODE_LINKED_URL) {
var file = attachment.getFile();
- if (file){
+ if (file) {
try {
file.reveal();
}
catch (e) {
// On platforms that don't support nsILocalFile.reveal() (e.g. Linux),
- // "double-click" the parent directory
- try {
- var parent = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
- parent.launch();
- }
- // If launch also fails, try the OS handler
- catch (e) {
- var uri = Components.classes["@mozilla.org/network/io-service;1"].
- getService(Components.interfaces.nsIIOService).
- newFileURI(parent);
- var protocolService =
- Components.classes["@mozilla.org/uriloader/external-protocol-service;1"].
- getService(Components.interfaces.nsIExternalProtocolService);
- protocolService.loadUrl(uri);
- }
+ // launch the parent directory
+ var parent = file.parent.QueryInterface(Components.interfaces.nsILocalFile);
+ this.launchFile(parent);
}
}
else {
diff --git a/defaults/preferences/zotero.js b/defaults/preferences/zotero.js
@@ -161,4 +161,8 @@ pref("extensions.zotero.ingester.allowedSites", "");
// Connector
pref("extensions.zotero.connector.repo.lastCheck.localTime", 0);
-pref("extensions.zotero.connector.repo.lastCheck.repoTime", 0);
-\ No newline at end of file
+pref("extensions.zotero.connector.repo.lastCheck.repoTime", 0);
+
+// File/URL opening executable if launch() fails
+pref("extensions.zotero.fallbackLauncher.unix", "/usr/bin/xdg-open");
+pref("extensions.zotero.fallbackLauncher.windows", "");
+\ No newline at end of file