Merge pull request #1104 from adomasven/feature/connector-targetAll-support

Connector targetAll support
This commit is contained in:
Dan Stillman 2016-10-04 02:59:11 -04:00 committed by GitHub
commit cfc1b56ca6
3 changed files with 96 additions and 70 deletions

View File

@ -141,66 +141,47 @@ Zotero.Translators = new function() {
* @return {Promise<Array[]>} - A promise for a 2-item array containing an array of translators and * @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 * 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(); if(!_initialized) Zotero.Translators.init();
var allTranslators = _cache["web"]; var allTranslators = _cache["web"];
var potentialTranslators = []; var potentialTranslators = [];
var searchURIs = [uri];
Zotero.debug("Translators: Looking for translators for "+uri);
// 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) {
// 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()]) {
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 = []; var converterFunctions = [];
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++) { for(var i=0; i<allTranslators.length; i++) {
for(var j=0; j<searchURIs.length; j++) { var translator = allTranslators[i];
// don't attempt to use translators with no target that can't be run in this browser 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 // since that would require transmitting every page to Zotero host
if(!allTranslators[i].webRegexp if(isGeneric && allTranslators[i].runMode !== Zotero.Translator.RUN_MODE_IN_BROWSER) {
&& allTranslators[i].runMode !== Zotero.Translator.RUN_MODE_IN_BROWSER) {
continue; continue;
} }
if(!allTranslators[i].webRegexp var rootURIMatches = isGeneric || rootSearchURI.length < 8192 && translator.webRegexp.root.test(rootSearchURI);
|| (uri.length < 8192 && allTranslators[i].webRegexp.test(searchURIs[j]))) { if (translator.webRegexp.all && rootURIMatches) {
// add translator to list for (var frameSearchURI in frameSearchURIs) {
potentialTranslators.push(allTranslators[i]); var frameURIMatches = frameSearchURI.length < 8192 && translator.webRegexp.all.test(frameSearchURI);
if(j === 0) { if (frameURIMatches) {
converterFunctions.push(null); potentialTranslators.push(translator);
} else if(Zotero.isBrowserExt || Zotero.isSafari) { converterFunctions.push(frameSearchURIs[frameSearchURI]);
// in Chrome/Safari, the converterFunction needs to be passed as JSON, so // prevent adding the translator multiple times
// just push an array with the proper and proxyHosts break rootURIsLoop;
converterFunctions.push([properHosts[j-1], proxyHosts[j-1]]); }
} 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) };
});
} }
} else if(!isFrame && (isGeneric || rootURIMatches)) {
// don't add translator more than once potentialTranslators.push(translator);
converterFunctions.push(rootSearchURIs[rootSearchURI]);
break; break;
} }
} }
@ -212,6 +193,47 @@ Zotero.Translators = new function() {
}); });
}); });
/**
* 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);
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()]) {
var properHost = hostnames.slice(0, i+1).join(".");
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
searchURIs[searchURI] = [properHost, proxyHost];
} else {
// 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) };
};
}
}
}
}
return searchURIs;
};
/** /**
* Converts translators to JSON-serializable objects * 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", var TRANSLATOR_REQUIRED_PROPERTIES = ["translatorID", "translatorType", "label", "creator", "target",
"priority", "lastUpdated"]; "priority", "lastUpdated"];
var TRANSLATOR_OPTIONAL_PROPERTIES = ["targetAll", "browserSupport", "minVersion", "maxVersion",
"inRepository", "configOptions", "displayOptions",
"hiddenPrefs", "itemType"];
var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES var TRANSLATOR_PASSING_PROPERTIES = TRANSLATOR_REQUIRED_PROPERTIES
.concat(["targetAll", "browserSupport", "code", "runMode", "itemType"]); .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 * @class Represents an individual translator
* @constructor * @constructor
@ -407,6 +432,12 @@ Zotero.Translator.prototype.init = function(info) {
this[property] = info[property]; 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"; this.browserSupport = info["browserSupport"] ? info["browserSupport"] : "g";

View File

@ -89,7 +89,7 @@ Zotero.Server.Connector.GetTranslators.prototype = {
// Translator data // Translator data
var me = this; var me = this;
if(data.url) { 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", sendResponseCallback(200, "application/json",
JSON.stringify(me._serializeTranslators(data[0]))); JSON.stringify(me._serializeTranslators(data[0])));
}); });
@ -106,13 +106,10 @@ Zotero.Server.Connector.GetTranslators.prototype = {
"_serializeTranslators":function(translators) { "_serializeTranslators":function(translators) {
var responseData = []; var responseData = [];
for each(var translator in translators) { let properties = ["translatorID", "translatorType", "label", "creator", "target", "targetAll",
let serializableTranslator = {}; "minVersion", "maxVersion", "priority", "browserSupport", "inRepository", "lastUpdated"];
for (let key of ["translatorID", "translatorType", "label", "creator", "target", for (var translator of translators) {
"minVersion", "maxVersion", "priority", "browserSupport", "inRepository", "lastUpdated"]) { responseData.push(translator.serialize(properties));
serializableTranslator[key] = translator[key];
}
responseData.push(serializableTranslator);
} }
return responseData; return responseData;
} }

View File

@ -278,7 +278,7 @@ Zotero.Translators = new function() {
return this.getAllForType(type).then(function(allTranslators) { return this.getAllForType(type).then(function(allTranslators) {
var potentialTranslators = []; var potentialTranslators = [];
var translatorConverterFunctions = []; var converterFunctions = [];
var rootSearchURIs = this.getSearchURIs(rootURI); var rootSearchURIs = this.getSearchURIs(rootURI);
var frameSearchURIs = isFrame ? this.getSearchURIs(URI) : rootSearchURIs; 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(', ')); Zotero.debug("Translators: Looking for translators for "+Object.keys(frameSearchURIs).join(', '));
for (let translator of allTranslators) { for (let translator of allTranslators) {
translatorLoop: rootURIsLoop:
for (let rootSearchURI in rootSearchURIs) { for (let rootSearchURI in rootSearchURIs) {
let isGeneric = (!translator.webRegexp.root && translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER); let isGeneric = !translator.webRegexp.root;
if (!isGeneric && !translator.webRegexp.root) {
continue;
}
let rootURIMatches = isGeneric || rootSearchURI.length < 8192 && translator.webRegexp.root.test(rootSearchURI); let rootURIMatches = isGeneric || rootSearchURI.length < 8192 && translator.webRegexp.root.test(rootSearchURI);
if (translator.webRegexp.all && rootURIMatches) { if (translator.webRegexp.all && rootURIMatches) {
for (let frameSearchURI in frameSearchURIs) { for (let frameSearchURI in frameSearchURIs) {
@ -299,21 +297,21 @@ Zotero.Translators = new function() {
if (frameURIMatches) { if (frameURIMatches) {
potentialTranslators.push(translator); potentialTranslators.push(translator);
translatorConverterFunctions.push(frameSearchURIs[frameSearchURI]); converterFunctions.push(frameSearchURIs[frameSearchURI]);
// prevent adding the translator multiple times // prevent adding the translator multiple times
break translatorLoop; break rootURIsLoop;
} }
} }
} }
else if(!isFrame && (isGeneric || rootURIMatches)) { else if(!isFrame && (isGeneric || rootURIMatches)) {
potentialTranslators.push(translator); potentialTranslators.push(translator);
translatorConverterFunctions.push(rootSearchURIs[rootSearchURI]); converterFunctions.push(rootSearchURIs[rootSearchURI]);
break; break;
} }
} }
} }
return [potentialTranslators, translatorConverterFunctions]; return [potentialTranslators, converterFunctions];
}.bind(this)); }.bind(this));
}, },