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.
This commit is contained in:
Dan Stillman 2012-01-20 15:23:06 -05:00
parent 20afa7e561
commit 79b1fe30dc
2 changed files with 121 additions and 41 deletions

View file

@ -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,17 +3401,64 @@ 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
this.launchFile(file);
}
}
else {
this.showAttachmentNotFoundDialog(itemID, noLocateOnMissing);
}
}
}
/**
* Launch a file, the best way we can
*/
this.launchFile = function (file) {
try {
file.launch();
}
catch (e) {
Zotero.debug("launch() not supported -- passing file to loadUrl()");
Zotero.debug("launch() not supported -- trying fallback executable");
var uri = Components.classes["@mozilla.org/network/standard-url;1"].
createInstance(Components.interfaces.nsIURI);
uri.spec = attachment.getLocalFileURL();
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);
@ -3426,8 +3466,56 @@ var ZoteroPane = new function()
}
}
}
/**
* 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 {
this.showAttachmentNotFoundDialog(itemID, noLocateOnMissing);
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);
}
}
}
@ -3451,21 +3539,9 @@ var ZoteroPane = new function()
}
catch (e) {
// On platforms that don't support nsILocalFile.reveal() (e.g. Linux),
// "double-click" the parent directory
try {
// launch the parent directory
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);
}
this.launchFile(parent);
}
}
else {

View file

@ -162,3 +162,7 @@ pref("extensions.zotero.ingester.allowedSites", "");
// Connector
pref("extensions.zotero.connector.repo.lastCheck.localTime", 0);
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", "");