Fx60 compatibility: Fix snapshot filenames
nsIURL doesn't seem to work anymore, so add Zotero.Utilities.parseURL(), which uses the `url` package from NPM and adds fileName, fileExtension, and fileBaseName.
This commit is contained in:
parent
ea77b407a3
commit
77a6af9e5b
|
@ -1131,53 +1131,43 @@ Zotero.Attachments = new function(){
|
||||||
|
|
||||||
|
|
||||||
function _getFileNameFromURL(url, contentType){
|
function _getFileNameFromURL(url, contentType){
|
||||||
var nsIURL = Components.classes["@mozilla.org/network/standard-url;1"]
|
url = Zotero.Utilities.parseURL(url);
|
||||||
.createInstance(Components.interfaces.nsIURL);
|
|
||||||
nsIURL.spec = url;
|
|
||||||
|
|
||||||
var ext = Zotero.MIME.getPrimaryExtension(contentType, nsIURL.fileExtension);
|
var fileBaseName = url.fileBaseName;
|
||||||
|
var fileExt = Zotero.MIME.getPrimaryExtension(contentType, url.fileExtension);
|
||||||
|
|
||||||
if (!nsIURL.fileName) {
|
if (!fileBaseName) {
|
||||||
var matches = nsIURL.directory.match(/\/([^\/]+)\/$/);
|
let matches = url.pathname.match(/\/([^\/]+)\/$/);
|
||||||
// If no filename, use the last part of the path if there is one
|
// If no filename, use the last part of the path if there is one
|
||||||
if (matches) {
|
if (matches) {
|
||||||
nsIURL.fileName = matches[1];
|
fileBaseName = matches[1];
|
||||||
}
|
}
|
||||||
// Or just use the host
|
// Or just use the host
|
||||||
else {
|
else {
|
||||||
nsIURL.fileName = nsIURL.host;
|
fileBaseName = url.hostname;
|
||||||
var tld = nsIURL.fileExtension;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we found a better extension, use that
|
|
||||||
if (ext && (!nsIURL.fileExtension || nsIURL.fileExtension != ext)) {
|
|
||||||
nsIURL.fileExtension = ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we replaced the TLD (which would've been interpreted as the extension), add it back
|
|
||||||
if (tld && tld != nsIURL.fileExtension) {
|
|
||||||
nsIURL.fileBaseName = nsIURL.fileBaseName + '.' + tld;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test unencoding fileBaseName
|
// Test unencoding fileBaseName
|
||||||
try {
|
try {
|
||||||
decodeURIComponent(nsIURL.fileBaseName);
|
decodeURIComponent(fileBaseName);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
if (e.name == 'URIError') {
|
if (e.name == 'URIError') {
|
||||||
// If we got a 'malformed URI sequence' while decoding,
|
// If we got a 'malformed URI sequence' while decoding,
|
||||||
// use MD5 of fileBaseName
|
// use MD5 of fileBaseName
|
||||||
nsIURL.fileBaseName = Zotero.Utilities.Internal.md5(nsIURL.fileBaseName, false);
|
fileBaseName = Zotero.Utilities.Internal.md5(fileBaseName, false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fileName = fileBaseName + (fileExt ? '.' + fileExt : '');
|
||||||
|
|
||||||
// Pass unencoded name to getValidFileName() so that percent-encoded
|
// Pass unencoded name to getValidFileName() so that percent-encoded
|
||||||
// characters aren't stripped to just numbers
|
// characters aren't stripped to just numbers
|
||||||
return Zotero.File.getValidFileName(decodeURIComponent(nsIURL.fileName));
|
return Zotero.File.getValidFileName(decodeURIComponent(fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1861,6 +1861,21 @@ Zotero.Utilities = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
parseURL: function (url) {
|
||||||
|
var parts = require('url').parse(url);
|
||||||
|
// fileName
|
||||||
|
parts.fileName = parts.pathname.split('/').pop();
|
||||||
|
// fileExtension
|
||||||
|
var pos = parts.fileName.lastIndexOf('.');
|
||||||
|
parts.fileExtension = pos == -1 ? '' : parts.fileName.substr(pos + 1);
|
||||||
|
// fileBaseName
|
||||||
|
parts.fileBaseName = parts.fileName
|
||||||
|
// filename up to the period before the file extension, if there is one
|
||||||
|
.substr(0, parts.fileName.length - (parts.fileExtension ? parts.fileExtension.length + 1 : 0));
|
||||||
|
return parts;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the real target URL from an intermediate URL
|
* Get the real target URL from an intermediate URL
|
||||||
*/
|
*/
|
||||||
|
|
7
package-lock.json
generated
7
package-lock.json
generated
|
@ -3637,8 +3637,7 @@
|
||||||
"querystring": {
|
"querystring": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
|
||||||
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
|
"integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"querystring-es3": {
|
"querystring-es3": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
|
@ -4553,7 +4552,6 @@
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
|
||||||
"integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
|
"integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"punycode": "1.3.2",
|
"punycode": "1.3.2",
|
||||||
"querystring": "0.2.0"
|
"querystring": "0.2.0"
|
||||||
|
@ -4562,8 +4560,7 @@
|
||||||
"punycode": {
|
"punycode": {
|
||||||
"version": "1.3.2",
|
"version": "1.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
|
||||||
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
|
"integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
|
||||||
"dev": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
"bluebird": "^3.5.1",
|
"bluebird": "^3.5.1",
|
||||||
"react": "^15.6.2",
|
"react": "^15.6.2",
|
||||||
"react-dom": "^15.6.2",
|
"react-dom": "^15.6.2",
|
||||||
|
"url": "^0.11.0",
|
||||||
"zotero-web-library": "^0.9.4-alpha"
|
"zotero-web-library": "^0.9.4-alpha"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -31,6 +31,13 @@ const symlinkFiles = [
|
||||||
|
|
||||||
// these files will be browserified during the build
|
// these files will be browserified during the build
|
||||||
const browserifyConfigs = [
|
const browserifyConfigs = [
|
||||||
|
{
|
||||||
|
src: 'node_modules/url/url.js',
|
||||||
|
dest: 'resource/url.js',
|
||||||
|
config: {
|
||||||
|
standalone: 'url'
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
src: 'node_modules/sinon/lib/sinon.js',
|
src: 'node_modules/sinon/lib/sinon.js',
|
||||||
dest: 'test/resource/sinon.js',
|
dest: 'test/resource/sinon.js',
|
||||||
|
|
|
@ -430,6 +430,52 @@ describe("Zotero.Utilities", function() {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("#parseURL()", function () {
|
||||||
|
var f;
|
||||||
|
before(() => {
|
||||||
|
f = Zotero.Utilities.parseURL;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#fileName", function () {
|
||||||
|
it("should contain filename", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/def.html?foo=bar'), 'fileName', 'def.html');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be empty if no filename", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/'), 'fileName', '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#fileExtension", function () {
|
||||||
|
it("should contain extension", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/def.html?foo=bar'), 'fileExtension', 'html');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be empty if no extension", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/def'), 'fileExtension', '');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be empty if no filename", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/'), 'fileExtension', '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("#fileBaseName", function () {
|
||||||
|
it("should contain base name", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/def.html?foo=bar'), 'fileBaseName', 'def');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should equal filename if no extension", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/def'), 'fileBaseName', 'def');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should be empty if no filename", function () {
|
||||||
|
assert.propertyVal(f('http://example.com/abc/'), 'fileBaseName', '');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("#ellipsize()", function () {
|
describe("#ellipsize()", function () {
|
||||||
describe("with wordBoundary", function () {
|
describe("with wordBoundary", function () {
|
||||||
it("should truncate at word boundary", function* () {
|
it("should truncate at word boundary", function* () {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user