commit cfc1b56ca6eab5c8b2634a57b962869a9f32a300
parent 302e31ebffe244d1ba1b0005ed888b8f66c96c98
Author: Dan Stillman <dstillman@zotero.org>
Date: Tue, 4 Oct 2016 02:59:11 -0400
Merge pull request #1104 from adomasven/feature/connector-targetAll-support
Connector targetAll support
Diffstat:
3 files changed, 95 insertions(+), 69 deletions(-)
diff --git a/chrome/content/zotero/xpcom/connector/translator.js b/chrome/content/zotero/xpcom/connector/translator.js
@@ -141,76 +141,98 @@ Zotero.Translators = new function() {
* @return {Promise<Array[]>} - A promise for a 2-item array containing an array of translators and
* an array of functions for converting URLs from proper to proxied forms
*/
- this.getWebTranslatorsForLocation = Zotero.Promise.method(function (uri) {
+ this.getWebTranslatorsForLocation = Zotero.Promise.method(function (URI, rootURI) {
+ var isFrame = URI !== rootURI;
if(!_initialized) Zotero.Translators.init();
var allTranslators = _cache["web"];
var potentialTranslators = [];
- var searchURIs = [uri];
+ var converterFunctions = [];
- Zotero.debug("Translators: Looking for translators for "+uri);
+ var rootSearchURIs = this.getSearchURIs(rootURI);
+ var frameSearchURIs = isFrame ? this.getSearchURIs(URI) : rootSearchURIs;
+
+ Zotero.debug("Translators: Looking for translators for "+Object.keys(frameSearchURIs).join(', '));
+
+ for(var i=0; i<allTranslators.length; i++) {
+ var translator = allTranslators[i];
+ if (isFrame && !translator.webRegexp.all) {
+ continue;
+ }
+ rootURIsLoop:
+ for(var rootSearchURI in rootSearchURIs) {
+ var isGeneric = !allTranslators[i].webRegexp.root;
+ // don't attempt to use generic translators that can't be run in this browser
+ // since that would require transmitting every page to Zotero host
+ if(isGeneric && allTranslators[i].runMode !== Zotero.Translator.RUN_MODE_IN_BROWSER) {
+ continue;
+ }
+
+ var rootURIMatches = isGeneric || rootSearchURI.length < 8192 && translator.webRegexp.root.test(rootSearchURI);
+ if (translator.webRegexp.all && rootURIMatches) {
+ for (var frameSearchURI in frameSearchURIs) {
+ var frameURIMatches = frameSearchURI.length < 8192 && translator.webRegexp.all.test(frameSearchURI);
+
+ if (frameURIMatches) {
+ potentialTranslators.push(translator);
+ converterFunctions.push(frameSearchURIs[frameSearchURI]);
+ // prevent adding the translator multiple times
+ break rootURIsLoop;
+ }
+ }
+ } else if(!isFrame && (isGeneric || rootURIMatches)) {
+ potentialTranslators.push(translator);
+ converterFunctions.push(rootSearchURIs[rootSearchURI]);
+ break;
+ }
+ }
+ }
+
+ var codeGetter = new Zotero.Translators.CodeGetter(potentialTranslators);
+ return codeGetter.getAll().then(function () {
+ return [potentialTranslators, converterFunctions];
+ });
+ });
+
+ /**
+ * Get the array of searchURIs and related proxy converter functions
+ *
+ * @param {String} URI to get searchURIs and converterFunctions for
+ */
+ this.getSearchURIs = function(URI) {
+ var searchURIs = {};
+ searchURIs[URI] = null;
// if there is a subdomain that is also a TLD, also test against URI with the domain
// dropped after the TLD
// (i.e., www.nature.com.mutex.gmu.edu => www.nature.com)
- var m = /^(https?:\/\/)([^\/]+)/i.exec(uri);
- var properHosts = [];
- var proxyHosts = [];
- if(m) {
+ var m = /^(https?:\/\/)([^\/]+)/i.exec(URI);
+ if (m) {
// First, drop the 0- if it exists (this is an III invention)
var host = m[2];
if(host.substr(0, 2) === "0-") host = host.substr(2);
var hostnames = host.split(".");
- for(var i=1; i<hostnames.length-2; i++) {
- if(TLDS[hostnames[i].toLowerCase()]) {
+ for (var i=1; i<hostnames.length-2; i++) {
+ if (TLDS[hostnames[i].toLowerCase()]) {
var properHost = hostnames.slice(0, i+1).join(".");
- searchURIs.push(m[1]+properHost+uri.substr(m[0].length));
- properHosts.push(properHost);
- proxyHosts.push(hostnames.slice(i+1).join("."));
- }
- }
- }
-
- var converterFunctions = [];
- for(var i=0; i<allTranslators.length; i++) {
- for(var j=0; j<searchURIs.length; j++) {
- // don't attempt to use translators with no target that can't be run in this browser
- // since that would require transmitting every page to Zotero host
- if(!allTranslators[i].webRegexp
- && allTranslators[i].runMode !== Zotero.Translator.RUN_MODE_IN_BROWSER) {
- continue;
- }
-
- if(!allTranslators[i].webRegexp
- || (uri.length < 8192 && allTranslators[i].webRegexp.test(searchURIs[j]))) {
- // add translator to list
- potentialTranslators.push(allTranslators[i]);
-
- if(j === 0) {
- converterFunctions.push(null);
- } else if(Zotero.isBrowserExt || Zotero.isSafari) {
+ var proxyHost = hostnames.slice(i+1).join(".");
+ var searchURI = m[1]+properHost+URI.substr(m[0].length);
+ if(Zotero.isBrowserExt || Zotero.isSafari) {
// in Chrome/Safari, the converterFunction needs to be passed as JSON, so
// just push an array with the proper and proxyHosts
- converterFunctions.push([properHosts[j-1], proxyHosts[j-1]]);
+ searchURIs[searchURI] = [properHost, proxyHost];
} else {
- // in Firefox, push the converterFunction
- converterFunctions.push(new function() {
- var re = new RegExp('^https?://(?:[^/]\\.)?'+Zotero.Utilities.quotemeta(properHosts[j-1])+'(?=/)', "gi");
- var proxyHost = proxyHosts[j-1].replace(/\$/g, "$$$$");
- return function(uri) { return uri.replace(re, "$&."+proxyHost) };
- });
+ // in Firefox, add a converterFunction
+ searchURIs[searchURI] = new function() {
+ var re = new RegExp('^https?://(?:[^/]+\\.)?'+Zotero.Utilities.quotemeta(properHost)+'(?=/)', "gi");
+ var _proxyHost = proxyHost.replace(/\$/g, "$$$$");
+ return function(uri) { return uri.replace(re, "$&."+_proxyHost) };
+ };
}
-
- // don't add translator more than once
- break;
}
}
}
-
- var codeGetter = new Zotero.Translators.CodeGetter(potentialTranslators);
- return codeGetter.getAll().then(function () {
- return [potentialTranslators, converterFunctions];
- });
- });
+ return searchURIs;
+ };
/**
* Converts translators to JSON-serializable objects
@@ -361,9 +383,12 @@ Zotero.Translators.CodeGetter.prototype.getAll = function () {
var TRANSLATOR_REQUIRED_PROPERTIES = ["translatorID", "translatorType", "label", "creator", "target",
"priority", "lastUpdated"];
+var TRANSLATOR_OPTIONAL_PROPERTIES = ["targetAll", "browserSupport", "minVersion", "maxVersion",
+ "inRepository", "configOptions", "displayOptions",
+ "hiddenPrefs", "itemType"];
var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES
.concat(["targetAll", "browserSupport", "code", "runMode", "itemType"]);
-var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport"]);
+var TRANSLATOR_SAVE_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES.concat(["browserSupport", "targetAll"]);
/**
* @class Represents an individual translator
* @constructor
@@ -407,6 +432,12 @@ Zotero.Translator.prototype.init = function(info) {
this[property] = info[property];
}
}
+ for(var i=0; i<TRANSLATOR_OPTIONAL_PROPERTIES.length; i++) {
+ var property = TRANSLATOR_OPTIONAL_PROPERTIES[i];
+ if(info[property] !== undefined) {
+ this[property] = info[property];
+ }
+ }
this.browserSupport = info["browserSupport"] ? info["browserSupport"] : "g";
diff --git a/chrome/content/zotero/xpcom/server_connector.js b/chrome/content/zotero/xpcom/server_connector.js
@@ -89,7 +89,7 @@ Zotero.Server.Connector.GetTranslators.prototype = {
// Translator data
var me = this;
if(data.url) {
- Zotero.Translators.getWebTranslatorsForLocation(data.url).then(function(data) {
+ Zotero.Translators.getWebTranslatorsForLocation(data.url, data.rootUrl).then(function(data) {
sendResponseCallback(200, "application/json",
JSON.stringify(me._serializeTranslators(data[0])));
});
@@ -106,13 +106,10 @@ Zotero.Server.Connector.GetTranslators.prototype = {
"_serializeTranslators":function(translators) {
var responseData = [];
- for each(var translator in translators) {
- let serializableTranslator = {};
- for (let key of ["translatorID", "translatorType", "label", "creator", "target",
- "minVersion", "maxVersion", "priority", "browserSupport", "inRepository", "lastUpdated"]) {
- serializableTranslator[key] = translator[key];
- }
- responseData.push(serializableTranslator);
+ let properties = ["translatorID", "translatorType", "label", "creator", "target", "targetAll",
+ "minVersion", "maxVersion", "priority", "browserSupport", "inRepository", "lastUpdated"];
+ for (var translator of translators) {
+ responseData.push(translator.serialize(properties));
}
return responseData;
}
diff --git a/chrome/content/zotero/xpcom/translation/translators.js b/chrome/content/zotero/xpcom/translation/translators.js
@@ -278,7 +278,7 @@ Zotero.Translators = new function() {
return this.getAllForType(type).then(function(allTranslators) {
var potentialTranslators = [];
- var translatorConverterFunctions = [];
+ var converterFunctions = [];
var rootSearchURIs = this.getSearchURIs(rootURI);
var frameSearchURIs = isFrame ? this.getSearchURIs(URI) : rootSearchURIs;
@@ -286,12 +286,10 @@ Zotero.Translators = new function() {
Zotero.debug("Translators: Looking for translators for "+Object.keys(frameSearchURIs).join(', '));
for (let translator of allTranslators) {
- translatorLoop:
+ rootURIsLoop:
for (let rootSearchURI in rootSearchURIs) {
- let isGeneric = (!translator.webRegexp.root && translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER);
- if (!isGeneric && !translator.webRegexp.root) {
- continue;
- }
+ let isGeneric = !translator.webRegexp.root;
+
let rootURIMatches = isGeneric || rootSearchURI.length < 8192 && translator.webRegexp.root.test(rootSearchURI);
if (translator.webRegexp.all && rootURIMatches) {
for (let frameSearchURI in frameSearchURIs) {
@@ -299,21 +297,21 @@ Zotero.Translators = new function() {
if (frameURIMatches) {
potentialTranslators.push(translator);
- translatorConverterFunctions.push(frameSearchURIs[frameSearchURI]);
+ converterFunctions.push(frameSearchURIs[frameSearchURI]);
// prevent adding the translator multiple times
- break translatorLoop;
+ break rootURIsLoop;
}
}
}
else if(!isFrame && (isGeneric || rootURIMatches)) {
potentialTranslators.push(translator);
- translatorConverterFunctions.push(rootSearchURIs[rootSearchURI]);
+ converterFunctions.push(rootSearchURIs[rootSearchURI]);
break;
}
}
}
- return [potentialTranslators, translatorConverterFunctions];
+ return [potentialTranslators, converterFunctions];
}.bind(this));
},