Adjust URL launching behavior

- Support launching plausible HTTP URLs without schemes from
  Zotero.loadURI(), and use that when launching from URL field
- Show correct cursor feedback on URL label -- only show pointer if the
  URL is launchable
- Don't launch non-HTTP URLs (e.g., zotero://) from URL field
- Don't open HTTP URLs in viewer when using ZoteroPane.launchURI()
This commit is contained in:
Dan Stillman 2019-12-16 14:49:47 -05:00
parent 537aa15842
commit df40ee7216
5 changed files with 48 additions and 8 deletions

View file

@ -416,10 +416,12 @@
}
// TEMP - NSF (homepage)
if ((fieldName == 'url' || fieldName == 'homepage') && val) {
if ((fieldName == 'url' || fieldName == 'homepage')
// Only make plausible HTTP URLs clickable
&& Zotero.Utilities.isHTTPURL(val, true)) {
label.classList.add("pointer");
// TODO: make getFieldValue non-private and use below instead
label.setAttribute("onclick", "ZoteroPane_Local.loadURI(this.nextSibling.firstChild ? this.nextSibling.firstChild.nodeValue : this.nextSibling.value, event)");
label.setAttribute("onclick", "Zotero.launchURL(this.nextSibling.firstChild ? this.nextSibling.firstChild.nodeValue : this.nextSibling.value)");
label.setAttribute("tooltiptext", Zotero.getString('locate.online.tooltip'));
}
else if (fieldName == 'DOI' && val && typeof val == 'string') {

View file

@ -183,7 +183,13 @@ Zotero.Utilities = {
var x = x.replace(/^[\x00-\x27\x29-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F\s]+/, "");
return x.replace(/[\x00-\x28\x2A-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F\s]+$/, "");
},
isHTTPURL: function (url, allowNoScheme = false) {
// From https://stackoverflow.com/a/3809435
var noSchemeRE = /^[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/;
return /^https?:\/\//.test(url) || (allowNoScheme && noSchemeRE.test(url));
},
/**
* Cleans a http url string
* @param url {String}

View file

@ -1028,8 +1028,13 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
* Used only by Standalone
*/
this.launchURL = function (url) {
if (!url.match(/^https?/)) {
throw new Error("launchURL() requires an HTTP(S) URL");
if (!Zotero.Utilities.isHTTPURL(url)) {
if (Zotero.Utilities.isHTTPURL(url, true)) {
url = 'http://' + url;
}
else {
throw new Error("launchURL() requires an HTTP(S) URL");
}
}
try {

View file

@ -3270,8 +3270,8 @@ var ZoteroPane = new function()
return;
}
if(uri.match(/^https?/)) {
this.launchURL(uri);
if (uri.match(/^(chrome|resource):/)) {
Zotero.openInViewer(uri);
continue;
}
@ -3287,7 +3287,7 @@ var ZoteroPane = new function()
}
}
Zotero.openInViewer(uri);
this.launchURL(uri);
}
}

View file

@ -34,6 +34,33 @@ describe("Zotero.Utilities", function() {
});
describe("#isHTTPURL()", function () {
it("should return true for HTTP URL", function () {
assert.isTrue(Zotero.Utilities.isHTTPURL('http://example.com'));
});
it("should return true for HTTPS URL", function () {
assert.isTrue(Zotero.Utilities.isHTTPURL('https://example.com'));
});
it("should return false for plausible HTTP URL if allowNoScheme not provided", function () {
assert.isFalse(Zotero.Utilities.isHTTPURL('example.com'));
});
it("should return false for plausible HTTP URL if allowNoScheme is true", function () {
assert.isTrue(Zotero.Utilities.isHTTPURL('example.com', true));
});
it("should return false for file URL", function () {
assert.isFalse(Zotero.Utilities.isHTTPURL('file:///c:/path/to/file.txt'));
});
it("should return false for zotero: URL", function () {
assert.isFalse(Zotero.Utilities.isHTTPURL('zotero://select/library/items/AAAAAAAA'));
});
});
describe("#cleanDOI()", function () {
var cleanDOI = Zotero.Utilities.cleanDOI;
var doi = '10.1088/1748-9326/11/4/048002';