www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit e1f09d4655b777cd5a58a568bb4cee1267251050
parent dbeecb9b0a15d17ffda1065521e2442d2827a787
Author: Adomas Venčkauskas <adomas.ven@gmail.com>
Date:   Mon,  8 May 2017 14:38:03 +0300

Remove unneeded connector files, update connectorTypeSchemaData.js

Addresses zotero/zotero-connectors#121

Diffstat:
Achrome/content/zotero/tools/build_typeSchemaData.html | 90+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dchrome/content/zotero/xpcom/connector/cachedTypes.js | 184-------------------------------------------------------------------------------
Dchrome/content/zotero/xpcom/connector/connector.js | 338-------------------------------------------------------------------------------
Dchrome/content/zotero/xpcom/connector/connector_firefox.js | 53-----------------------------------------------------
Dchrome/content/zotero/xpcom/connector/repo.js | 212-------------------------------------------------------------------------------
Dchrome/content/zotero/xpcom/connector/translate_item.js | 727-------------------------------------------------------------------------------
Dchrome/content/zotero/xpcom/connector/translator.js | 474-------------------------------------------------------------------------------
Dchrome/content/zotero/xpcom/connector/typeSchemaData.js | 2--
Aresource/schema/connectorTypeSchemaData.js | 2++
9 files changed, 92 insertions(+), 1990 deletions(-)

diff --git a/chrome/content/zotero/tools/build_typeSchemaData.html b/chrome/content/zotero/tools/build_typeSchemaData.html @@ -0,0 +1,90 @@ +<html> +<head> + <title>Build schemaData.js</title> +</head> +<body> +<p>This script builds schemaData.js, which contains Zotero schema information for the connector.</p> +<p id="result"></p> +<script src="../include.js"></script> +<script type="text/javascript"> + Zotero.Promise.coroutine(function* (){ + // Create schema + var schema = {"itemTypes":{}, "creatorTypes":{}, "fields":{}}; + var types = Zotero.ItemTypes.getTypes(); + + var fieldIDs = yield Zotero.DB.columnQueryAsync("SELECT fieldID FROM fieldsCombined"); + var baseMappedFields = Zotero.ItemFields.getBaseMappedFields(); + + for (let fieldID of fieldIDs) { + var fieldObj = [/* name */Zotero.ItemFields.getName(fieldID)]; + try { + fieldObj.push(/* localizedString */Zotero.getString("itemFields." + fieldObj.name)); + } catch(e) { + fieldObj.push(/* name -> localizedString */fieldObj[0]); + } + fieldObj.push(/* isBaseField */ !baseMappedFields.includes(fieldID)); + schema.fields[fieldID] = fieldObj; + } + + // names, localizedStrings, creatorTypes, and fields for each item type + for (let type of types) { + var fieldIDs = Zotero.ItemFields.getItemTypeFields(type.id); + var baseFields = {}; + for (let fieldID in fieldIDs) { + if (baseMappedFields.includes(fieldID)) { + baseFields[fieldID] = Zotero.ItemFields.getBaseIDFromTypeAndField(type.id, fieldID); + } + } + + var icon = Zotero.ItemTypes.getImageSrc(type.name); + icon = icon.substr(icon.lastIndexOf("/")+1); + + try { + var creatorTypes = Zotero.CreatorTypes.getTypesForItemType(type.id).map((creatorType) => creatorType.id); + } catch (e) { + creatorTypes = []; + } + var primaryCreatorType = Zotero.CreatorTypes.getPrimaryIDForType(type.id); + if(creatorTypes[0] != primaryCreatorType) { + creatorTypes.splice(creatorTypes.indexOf(primaryCreatorType), 1); + creatorTypes.unshift(primaryCreatorType); + } + + schema.itemTypes[type.id] = [ + /* name */type.name, + /* localizedString */Zotero.ItemTypes.getLocalizedString(type.name), + /* creatorTypes */creatorTypes, + /* fields */ fieldIDs, + /* baseFields */baseFields, + /* icon */icon + ]; + + } + + var types = Zotero.CreatorTypes.getTypes(); + for (let type of types) { + schema.creatorTypes[type.id] = [ + /* name */type.name, + /* localizedString */Zotero.CreatorTypes.getLocalizedString(type.name) + ]; + } + + // Write to file + var nsIFilePicker = Components.interfaces.nsIFilePicker; + var fp = Components.classes["@mozilla.org/filepicker;1"] + .createInstance(nsIFilePicker); + fp.init(window, Zotero.getString('dataDir.selectDir'), nsIFilePicker.modeGetFolder); + + let resultElem = document.getElementById('result'); + if (fp.show() != nsIFilePicker.returnOK) { + result.innerHTML = '<p>Failed.</p>'; + } else { + let schemaFile = fp.file; + schemaFile.append("connectorTypeSchemaData.js"); + Zotero.File.putContents(schemaFile, `Zotero.Connector_Types.schema = ${JSON.stringify(schema)}`); + result.innerHTML = `<p>Wrote ${schemaFile.path} successfully.</p>`; + } + })(); +</script> +</body> +</html> diff --git a/chrome/content/zotero/xpcom/connector/cachedTypes.js b/chrome/content/zotero/xpcom/connector/cachedTypes.js @@ -1,183 +0,0 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - - Copyright © 2011 Center for History and New Media - George Mason University, Fairfax, Virginia, USA - http://zotero.org - - This file is part of Zotero. - - Zotero is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Zotero is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Zotero. If not, see <http://www.gnu.org/licenses/>. - - ***** END LICENSE BLOCK ***** -*/ - -/** - * Emulates very small parts of cachedTypes.js and itemFields.js APIs for use with connector - */ - -/** - * @namespace - */ -Zotero.Connector_Types = new function() { - /** - * Initializes types - * @param {Object} typeSchema typeSchema generated by Zotero.Connector.GetData#_generateTypeSchema - */ - this.init = function() { - const schemaTypes = ["itemTypes", "creatorTypes", "fields"]; - - // attach IDs and make referenceable by either ID or name - for(var i=0; i<schemaTypes.length; i++) { - var schemaType = schemaTypes[i]; - this[schemaType] = Zotero.Utilities.deepCopy(Zotero.Connector_Types.schema[schemaType]); - for(var id in Zotero.Connector_Types.schema[schemaType]) { - var entry = this[schemaType][id]; - entry.unshift(parseInt(id, 10)); - this[schemaType][entry[1]/* name */] = entry; - } - } - - var itemTypes = Zotero.Connector_Types["itemTypes"]; - var creatorTypes = Zotero.Connector_Types["creatorTypes"]; - var fields = Zotero.Connector_Types["fields"]; - - Zotero.CachedTypes = function() { - var thisType = Zotero.Connector_Types[this.schemaType]; - - this.getID = function(idOrName) { - var type = thisType[idOrName]; - return (type ? type[0]/* id */ : false); - }; - - this.getName = function(idOrName) { - var type = thisType[idOrName]; - return (type ? type[1]/* name */ : false); - }; - - this.getLocalizedString = function(idOrName) { - var type = thisType[idOrName]; - return (type ? type[2]/* localizedString */ : false); - }; - } - - Zotero.ItemTypes = new function() { - this.schemaType = "itemTypes"; - Zotero.CachedTypes.call(this); - - this.getImageSrc = function(idOrName) { - var itemType = Zotero.Connector_Types["itemTypes"][idOrName]; - var icon = itemType ? itemType[6]/* icon */ : "treeitem-"+idOrName+".png"; - - if(Zotero.isBookmarklet) { - return ZOTERO_CONFIG.BOOKMARKLET_URL+"images/"+icon; - } else if(Zotero.isFx) { - return "chrome://zotero/skin/"+icon; - } else if(Zotero.isBrowserExt) { - return chrome.extension.getURL("images/"+icon); - } else if(Zotero.isSafari) { - return safari.extension.baseURI+"images/"+icon; - } - }; - } - - Zotero.CreatorTypes = new function() { - this.schemaType = "creatorTypes"; - Zotero.CachedTypes.call(this); - - this.getTypesForItemType = function(idOrName) { - var itemType = itemTypes[idOrName]; - if(!itemType) return false; - - var itemCreatorTypes = itemType[3]; // creatorTypes - if (!itemCreatorTypes - // TEMP: 'note' and 'attachment' have an array containing false - || (itemCreatorTypes.length == 1 && !itemCreatorTypes[0])) { - return []; - } - var n = itemCreatorTypes.length; - var outputTypes = new Array(n); - - for(var i=0; i<n; i++) { - var creatorType = creatorTypes[itemCreatorTypes[i]]; - outputTypes[i] = {"id":creatorType[0]/* id */, - "name":creatorType[1]/* name */}; - } - return outputTypes; - }; - - this.getPrimaryIDForType = function(idOrName) { - var itemType = itemTypes[idOrName]; - if(!itemType) return false; - return itemType[3]/* creatorTypes */[0]; - }; - } - - Zotero.ItemFields = new function() { - this.schemaType = "fields"; - Zotero.CachedTypes.call(this); - - this.isValidForType = function(fieldIdOrName, typeIdOrName) { - var field = fields[fieldIdOrName], itemType = itemTypes[typeIdOrName]; - - // mimics itemFields.js - if(!field || !itemType) return false; - - /* fields */ /* id */ - return itemType[4].indexOf(field[0]) !== -1; - }; - - this.getFieldIDFromTypeAndBase = function(typeIdOrName, fieldIdOrName) { - var baseField = fields[fieldIdOrName], itemType = itemTypes[typeIdOrName]; - - if(!baseField || !itemType) return false; - - // get as ID - baseField = baseField[0]/* id */; - - // loop through base fields for item type - var baseFields = itemType[5]; - for(var i in baseFields) { - if(baseFields[i] === baseField) { - return i; - } - } - - return false; - }; - - this.getBaseIDFromTypeAndField = function(typeIdOrName, fieldIdOrName) { - var field = fields[fieldIdOrName], itemType = itemTypes[typeIdOrName]; - if(!field || !itemType) { - throw new Error("Invalid field or type ID"); - } - - var baseField = itemType[5]/* baseFields */[field[0]/* id */]; - return baseField ? baseField : false; - }; - - this.getItemTypeFields = function(typeIdOrName) { - return itemTypes[typeIdOrName][4]/* fields */.slice(); - }; - } - }; - - /** - * Passes schema to a callback - * @param {Function} callback - */ - this.getSchema = function(callback) { - callback(Zotero.Connector_Types.schema); - }; -} -\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/connector/connector.js b/chrome/content/zotero/xpcom/connector/connector.js @@ -1,338 +0,0 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - - Copyright © 2011 Center for History and New Media - George Mason University, Fairfax, Virginia, USA - http://zotero.org - - This file is part of Zotero. - - Zotero is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Zotero is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Zotero. If not, see <http://www.gnu.org/licenses/>. - - ***** END LICENSE BLOCK ***** -*/ - -Zotero.Connector = new function() { - const CONNECTOR_URI = "http://127.0.0.1:23119/"; - const CONNECTOR_API_VERSION = 2; - - var _ieStandaloneIframeTarget, _ieConnectorCallbacks; - // As of Chrome 38 (and corresponding Opera version 24?) pages loaded over - // https (i.e. the zotero bookmarklet iframe) can not send requests over - // http, so pinging Standalone at http://127.0.0.1 fails. - // Disable for all browsers, except IE, which may be used frequently with ZSA - this.isOnline = Zotero.isBookmarklet && !Zotero.isIE ? false : null; - - /** - * Checks if Zotero is online and passes current status to callback - * @param {Function} callback - */ - this.checkIsOnline = function(callback) { - // Only check once in bookmarklet - if(Zotero.isBookmarklet && this.isOnline !== null) { - callback(this.isOnline); - return; - } - - if(Zotero.isIE) { - if(window.location.protocol !== "http:") { - this.isOnline = false; - callback(false); - return; - } - - Zotero.debug("Connector: Looking for Zotero Standalone"); - var me = this; - var fail = function() { - if(me.isOnline !== null) return; - Zotero.debug("Connector: Zotero Standalone is not online or cannot be contacted"); - me.isOnline = false; - callback(false); - }; - - window.setTimeout(fail, 1000); - try { - var xdr = new XDomainRequest(); - xdr.timeout = 700; - xdr.open("POST", "http://127.0.0.1:23119/connector/ping", true); - xdr.onerror = function() { - Zotero.debug("Connector: XDomainRequest to Zotero Standalone experienced an error"); - fail(); - }; - xdr.ontimeout = function() { - Zotero.debug("Connector: XDomainRequest to Zotero Standalone timed out"); - fail(); - }; - xdr.onload = function() { - if(me.isOnline !== null) return; - me.isOnline = true; - Zotero.debug("Connector: Standalone found; trying IE hack"); - - _ieConnectorCallbacks = []; - var listener = function(event) { - if(event.origin !== "http://127.0.0.1:23119" - || event.source !== iframe.contentWindow) return; - if(event.stopPropagation) { - event.stopPropagation(); - } else { - event.cancelBubble = true; - } - - // If this is the first time the target was loaded, then this is a loaded - // event - if(!_ieStandaloneIframeTarget) { - Zotero.debug("Connector: Standalone loaded"); - _ieStandaloneIframeTarget = iframe.contentWindow; - callback(true); - return; - } - - // Otherwise, this is a response event - try { - var data = JSON.parse(event.data); - } catch(e) { - Zotero.debug("Invalid JSON received: "+event.data); - return; - } - var xhrSurrogate = { - "status":data[1], - "responseText":data[2], - "getResponseHeader":function(x) { return data[3][x.toLowerCase()] } - }; - _ieConnectorCallbacks[data[0]](xhrSurrogate); - delete _ieConnectorCallbacks[data[0]]; - }; - - if(window.addEventListener) { - window.addEventListener("message", listener, false); - } else { - window.attachEvent("onmessage", function() { listener(event); }); - } - - var iframe = document.createElement("iframe"); - iframe.src = "http://127.0.0.1:23119/connector/ieHack"; - document.documentElement.appendChild(iframe); - }; - xdr.send(""); - } catch(e) { - Zotero.logError(e); - fail(); - } - } else { - Zotero.Connector.callMethod("ping", {}, function(status) { - callback(status !== false); - }); - } - } - - /** - * Sends the XHR to execute an RPC call. - * - * @param {String|Object} options - The method name as a string or an object with the - * following properties: - * method - method name - * headers - an object of HTTP headers to send - * queryString - a query string to pass on the HTTP call - * @param {Object} data - RPC data to POST. If null or undefined, a GET request is sent. - * @param {Function} callback - Function to be called when requests complete. - */ - this.callMethod = function(options, data, callback, tab) { - // Don't bother trying if not online in bookmarklet - if(Zotero.isBookmarklet && this.isOnline === false) { - callback(false, 0); - return; - } - if (typeof options == 'string') { - options = {method: options}; - } - var method = options.method; - var headers = Object.assign({ - "Content-Type":"application/json", - "X-Zotero-Version":Zotero.version, - "X-Zotero-Connector-API-Version":CONNECTOR_API_VERSION - }, options.headers || {}); - var queryString = options.queryString ? ("?" + options.queryString) : ""; - - var newCallback = function(req) { - try { - var isOnline = req.status !== 0 && req.status !== 403 && req.status !== 412; - - if(Zotero.Connector.isOnline !== isOnline) { - Zotero.Connector.isOnline = isOnline; - if(Zotero.Connector_Browser && Zotero.Connector_Browser.onStateChange) { - Zotero.Connector_Browser.onStateChange(isOnline); - } - } - var val = null; - if(req.responseText) { - if(req.getResponseHeader("Content-Type") === "application/json") { - val = JSON.parse(req.responseText); - } else { - val = req.responseText; - } - } - if(req.status == 0 || req.status >= 400) { - Zotero.debug("Connector: Method "+method+" failed with status "+req.status); - if(callback) callback(false, req.status, val); - - // Check for incompatible version - if(req.status === 412) { - if(Zotero.Connector_Browser && Zotero.Connector_Browser.onIncompatibleStandaloneVersion) { - var standaloneVersion = req.getResponseHeader("X-Zotero-Version"); - Zotero.Connector_Browser.onIncompatibleStandaloneVersion(Zotero.version, standaloneVersion); - throw "Connector: Version mismatch: Connector version "+Zotero.version - +", Standalone version "+(standaloneVersion ? standaloneVersion : "<unknown>"); - } - } - } else { - Zotero.debug("Connector: Method "+method+" succeeded"); - if(callback) callback(val, req.status); - } - } catch(e) { - Zotero.logError(e); - return; - } - }; - - if(Zotero.isIE) { // IE requires XDR for CORS - if(_ieStandaloneIframeTarget) { - var requestID = Zotero.Utilities.randomString(); - _ieConnectorCallbacks[requestID] = newCallback; - _ieStandaloneIframeTarget.postMessage(JSON.stringify([null, "connectorRequest", - [requestID, method, JSON.stringify(data)]]), "http://127.0.0.1:23119/connector/ieHack"); - } else { - Zotero.debug("Connector: No iframe target; not sending to Standalone"); - callback(false, 0); - } - } else { // Other browsers can use plain doPost - var uri = CONNECTOR_URI + "connector/" + method + queryString; - if (headers["Content-Type"] == 'application/json') { - data = JSON.stringify(data); - } - if (data == null || data == undefined) { - Zotero.HTTP.doGet(uri, newCallback, headers); - } else { - Zotero.HTTP.doPost(uri, data, newCallback, headers); - } - } - }, - - /** - * Adds detailed cookies to the data before sending "saveItems" request to - * the server/Standalone - * - * @param {Object} data RPC data. See documentation above. - * @param {Function} callback Function to be called when requests complete. - */ - this.setCookiesThenSaveItems = function(data, callback, tab) { - if(Zotero.isFx && !Zotero.isBookmarklet && data.uri) { - var host = Services.io.newURI(data.uri, null, null).host; - var cookieEnum = Services.cookies.getCookiesFromHost(host); - var cookieHeader = ''; - while(cookieEnum.hasMoreElements()) { - var cookie = cookieEnum.getNext().QueryInterface(Components.interfaces.nsICookie2); - cookieHeader += '\n' + cookie.name + '=' + cookie.value - + ';Domain=' + cookie.host - + (cookie.path ? ';Path=' + cookie.path : '') - + (!cookie.isDomain ? ';hostOnly' : '') //not a legit flag, but we have to use it internally - + (cookie.isSecure ? ';secure' : ''); - } - - if(cookieHeader) { - data.detailedCookies = cookieHeader.substr(1); - } - - this.callMethod("saveItems", data, callback, tab); - return; - } else if(Zotero.isBrowserExt && !Zotero.isBookmarklet) { - var self = this; - chrome.cookies.getAll({url: tab.url}, function(cookies) { - var cookieHeader = ''; - for(var i=0, n=cookies.length; i<n; i++) { - cookieHeader += '\n' + cookies[i].name + '=' + cookies[i].value - + ';Domain=' + cookies[i].domain - + (cookies[i].path ? ';Path=' + cookies[i].path : '') - + (cookies[i].hostOnly ? ';hostOnly' : '') //not a legit flag, but we have to use it internally - + (cookies[i].secure ? ';secure' : ''); - } - - if(cookieHeader) { - data.detailedCookies = cookieHeader.substr(1); - } - - // Cookie URI needed to set up the cookie sandbox on standalone - data.uri = tab.url; - - self.callMethod("saveItems", data, callback, tab); - }); - return; - } - - this.callMethod("saveItems", data, callback, tab); - } -} - -Zotero.Connector_Debug = new function() { - /** - * Call a callback depending upon whether debug output is being stored - */ - this.storing = function(callback) { - callback(Zotero.Debug.storing); - } - - /** - * Call a callback with the lines themselves - */ - this.get = function(callback) { - Zotero.Debug.get().then(callback); - }; - - /** - * Call a callback with the number of lines of output - */ - this.count = function(callback) { - callback(Zotero.Debug.count()); - } - - /** - * Submit data to the server - */ - this.submitReport = function(callback) { - Zotero.Debug.get().then(function(output){ - return Zotero.HTTP.request( - ZOTERO_CONFIG.REPOSITORY_URL + "report?debug=1", - { - headers: { - "Content-Type": "text/plain" - }, - body: output, - successCodes: false - } - ); - }).then(function(xmlhttp){ - if (!xmlhttp.responseXML) { - callback(false, 'Invalid response from server'); - return; - } - var reported = xmlhttp.responseXML.getElementsByTagName('reported'); - if (reported.length != 1) { - callback(false, 'The server returned an error. Please try again.'); - return; - } - - var reportID = reported[0].getAttribute('reportID'); - callback(true, reportID); - }); - }; -} diff --git a/chrome/content/zotero/xpcom/connector/connector_firefox.js b/chrome/content/zotero/xpcom/connector/connector_firefox.js @@ -1,52 +0,0 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - - Copyright © 2011 Center for History and New Media - George Mason University, Fairfax, Virginia, USA - http://zotero.org - - This file is part of Zotero. - - Zotero is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Zotero is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Zotero. If not, see <http://www.gnu.org/licenses/>. - - ***** END LICENSE BLOCK ***** -*/ - -Zotero.Connector_Browser = new function() { - /** - * Called if Zotero version is determined to be incompatible with Standalone - */ - this.onIncompatibleStandaloneVersion = function(zoteroVersion, standaloneVersion) { - Zotero.startupError = 'Zotero for Firefox '+Zotero.version+' is incompatible with the running '+ - 'version of Zotero Standalone'+(standaloneVersion ? " ("+standaloneVersion+")" : "")+ - '.\n\nPlease ensure that you have installed the latest version of these components. See '+ - 'http://www.zotero.org/support/standalone for more details.'; - Zotero.initialized = false; - } - - /** - * Called if connector is offline. This should only happen if Zotero is getting a DB busy - * message and no connector is open, so use the DB busy error message here. - */ - this.onStateChange = function(isOnline) { - if(isOnline) return; - - var msg = Zotero.localeJoin([ - Zotero.getString('startupError.databaseInUse'), - Zotero.getString(Zotero.isStandalone ? 'startupError.closeFirefox' : 'startupError.closeStandalone') - ]); - Zotero.startupError = msg; - Zotero.initialized = false; - } -} -\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/connector/repo.js b/chrome/content/zotero/xpcom/connector/repo.js @@ -1,211 +0,0 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - - Copyright © 2011 Center for History and New Media - George Mason University, Fairfax, Virginia, USA - http://zotero.org - - This file is part of Zotero. - - Zotero is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Zotero is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Zotero. If not, see <http://www.gnu.org/licenses/>. - - ***** END LICENSE BLOCK ***** -*/ - -const TRANSLATOR_CODE_PREFIX = "translatorCode-"; -Zotero.Repo = new function() { - var _nextCheck; - var _timeoutID; - const infoRe = /^\s*{[\S\s]*?}\s*?[\r\n]/; - - this.SOURCE_ZOTERO_STANDALONE = 1; - this.SOURCE_REPO = 2; - - /** - * Try to retrieve translator metadata from Zotero Standalone and initialize repository check - * timer - */ - this.init = function() { - // get time of next check - _nextCheck = Zotero.Prefs.get("connector.repo.lastCheck.localTime") - +ZOTERO_CONFIG.REPOSITORY_CHECK_INTERVAL*1000; - - // update from standalone, but only cascade to repo if we are overdue - _updateFromStandalone(_nextCheck <= Date.now()); - }; - - /** - * Force updating translators - */ - var update = this.update = function(reset) { - _updateFromStandalone(true, reset); - }; - - /** - * Get translator code from repository - * @param {String} translatorID ID of the translator to retrieve code for - */ - this.getTranslatorCode = Zotero.Promise.method(function (translatorID, debugMode) { - var deferred = Zotero.Promise.defer(); - - // try standalone - Zotero.Connector.callMethod("getTranslatorCode", {"translatorID":translatorID}, function(result) { - if(result) { - deferred.resolve( - Zotero.Promise.all( - [ - _haveCode(result, translatorID), - Zotero.Repo.SOURCE_ZOTERO_STANDALONE - ] - ) - ); - return; - } - // Don't fetch from repo in debug mode - if (debugMode) { - deferred.resolve([false, Zotero.Repo.SOURCE_ZOTERO_STANDALONE]); - return; - } - - - // then try repo - Zotero.HTTP.doGet( - ZOTERO_CONFIG.REPOSITORY_URL + "code/" + translatorID + "?version=" + Zotero.version, - function(xmlhttp) { - deferred.resolve( - Zotero.Promise.all( - [ - _haveCode( - xmlhttp.status === 200 ? xmlhttp.responseText : false, - translatorID - ), - Zotero.Repo.SOURCE_REPO - ] - ) - ); - } - ); - }); - - return deferred.promise; - }); - - /** - * Called when code has been retrieved from standalone or repo - */ - function _haveCode(code, translatorID) { - if(!code) { - Zotero.logError(new Error("Code could not be retrieved for " + translatorID)); - return false; - } - - if(!Zotero.isFx) { - code = Zotero.Translators.preprocessCode(code); - - var m = infoRe.exec(code); - if (!m) { - Zotero.logError(new Error("Invalid or missing translator metadata JSON object for " + translatorID)); - return false; - } - - try { - var metadata = JSON.parse(m[0]); - } catch(e) { - Zotero.logError(new Error("Invalid or missing translator metadata JSON object for " + translatorID)); - return false; - } - - var translator = Zotero.Translators.getWithoutCode(translatorID); - - if(metadata.lastUpdated !== translator.lastUpdated) { - if(Zotero.Date.sqlToDate(metadata.lastUpdated) > Zotero.Date.sqlToDate(translator.lastUpdated)) { - Zotero.debug("Repo: Retrieved code for "+metadata.label+" newer than stored metadata; updating"); - Zotero.Translators.update([metadata]); - } else { - Zotero.debug("Repo: Retrieved code for "+metadata.label+" older than stored metadata; not caching"); - } - } - } - return code; - } - - /** - * Retrieve translator metadata from Zotero Standalone - * @param {Boolean} [tryRepoOnFailure] If true, run _updateFromRepo() if standalone cannot be - * contacted - */ - function _updateFromStandalone(tryRepoOnFailure, reset, callback) { - Zotero.Connector.callMethod("getTranslators", {}, function(result) { - if(!result && tryRepoOnFailure) { - _updateFromRepo(reset, callback); - } else { - // Standalone always returns all translators without .deleted property - _handleResponse(result, true); - if(callback) callback(!!result); - } - }); - } - - /** - * Retrieve metadata from repository - */ - function _updateFromRepo(reset, callback) { - var url = ZOTERO_CONFIG.REPOSITORY_URL + "metadata?version=" + Zotero.version + "&last="+ - (reset ? "0" : Zotero.Prefs.get("connector.repo.lastCheck.repoTime")); - - Zotero.HTTP.doGet(url, function(xmlhttp) { - var success = xmlhttp.status === 200; - _handleResponse(success ? JSON.parse(xmlhttp.responseText) : false, reset); - - if(success) { - var date = xmlhttp.getResponseHeader("Date"); - Zotero.Prefs.set("connector.repo.lastCheck.repoTime", - Math.floor(Date.parse(date)/1000)); - } - if(callback) callback(!!result); - }); - } - - /** - * Handle response from Zotero Standalone or repository and set timer for next update - */ - function _handleResponse(result, reset) { - // set up timer - var now = Date.now(); - - if(result) { - Zotero.Translators.update(result, reset); - Zotero.Prefs.set("connector.repo.lastCheck.localTime", now); - Zotero.debug("Repo: Check succeeded"); - } else { - Zotero.debug("Repo: Check failed"); - } - - if(result || _nextCheck <= now) { - // if we failed a scheduled check, then use retry interval - _nextCheck = now+(result - ? ZOTERO_CONFIG.REPOSITORY_CHECK_INTERVAL - : ZOTERO_CONFIG.REPOSITORY_RETRY_INTERVAL)*1000; - } else if(_timeoutID) { - // if we didn't fail a scheduled check and another is already scheduled, leave it - return; - } - - // remove old timeout and create a new one - if(_timeoutID) clearTimeout(_timeoutID); - var nextCheckIn = (_nextCheck-now+2000); - _timeoutID = setTimeout(update, nextCheckIn); - Zotero.debug("Repo: Next check in "+nextCheckIn); - } -} -\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/connector/translate_item.js b/chrome/content/zotero/xpcom/connector/translate_item.js @@ -1,726 +0,0 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - - Copyright © 2012 Center for History and New Media - George Mason University, Fairfax, Virginia, USA - http://zotero.org - - This file is part of Zotero. - - Zotero is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Zotero is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Zotero. If not, see <http://www.gnu.org/licenses/>. - - ***** END LICENSE BLOCK ***** -*/ - -/** - * Save translator items. - * - * @constructor - * @param {Object} options - * <li>libraryID - ID of library in which items should be saved</li> - * <li>collections - New collections to create (used during Import translation</li> - * <li>attachmentMode - One of Zotero.Translate.ItemSaver.ATTACHMENT_* specifying how attachments should be saved</li> - * <li>forceTagType - Force tags to specified tag type</li> - * <li>cookieSandbox - Cookie sandbox for attachment requests</li> - * <li>proxy - A proxy to deproxify item URLs</li> - * <li>baseURI - URI to which attachment paths should be relative</li> - * - */ -Zotero.Translate.ItemSaver = function(options) { - this.newItems = []; - this._proxy = options.proxy; - this._baseURI = options.baseURI; - - // Add listener for callbacks, but only for Safari or the bookmarklet. In Chrome, we - // (have to) save attachments from the inject page. - if(Zotero.Messaging && !Zotero.Translate.ItemSaver._attachmentCallbackListenerAdded - && (Zotero.isBookmarklet || Zotero.isSafari)) { - Zotero.Messaging.addMessageListener("attachmentCallback", function(data) { - var id = data[0], - status = data[1]; - var callback = Zotero.Translate.ItemSaver._attachmentCallbacks[id]; - if(callback) { - if(status === false || status === 100) { - delete Zotero.Translate.ItemSaver._attachmentCallbacks[id]; - } else { - data[1] = 50+data[1]/2; - } - callback(data[1], data[2]); - } - }); - Zotero.Translate.ItemSaver._attachmentCallbackListenerAdded = true; - } -} -Zotero.Translate.ItemSaver._attachmentCallbackListenerAdded = false; -Zotero.Translate.ItemSaver._attachmentCallbacks = {}; - -Zotero.Translate.ItemSaver.ATTACHMENT_MODE_IGNORE = 0; -Zotero.Translate.ItemSaver.ATTACHMENT_MODE_DOWNLOAD = 1; -Zotero.Translate.ItemSaver.ATTACHMENT_MODE_FILE = 2; - -Zotero.Translate.ItemSaver.prototype = { - /** - * Saves items to Standalone or the server - * @param items Items in Zotero.Item.toArray() format - * @param {Function} [attachmentCallback] A callback that receives information about attachment - * save progress. The callback will be called as attachmentCallback(attachment, false, error) - * on failure or attachmentCallback(attachment, progressPercent) periodically during saving. - */ - saveItems: function (items, attachmentCallback) { - var deferred = Zotero.Promise.defer(); - // first try to save items via connector - var payload = { items, uri: this._baseURI }; - if (Zotero.isSafari) { - // This is the best in terms of cookies we can do in Safari - payload.cookie = document.cookie; - } - payload.proxy = this._proxy && this._proxy.toJSON(); - Zotero.Connector.setCookiesThenSaveItems(payload, function(data, status) { - if(data !== false) { - Zotero.debug("Translate: Save via Standalone succeeded"); - var haveAttachments = false; - if(data && data.items) { - for(var i=0; i<data.items.length; i++) { - var attachments = items[i].attachments = data.items[i].attachments; - for(var j=0; j<attachments.length; j++) { - if(attachments[j].id) { - attachmentCallback(attachments[j], 0); - haveAttachments = true; - } - } - } - } - deferred.resolve(items); - if (haveAttachments) this._pollForProgress(items, attachmentCallback); - } else if(Zotero.isFx) { - deferred.reject(new Error("Save via Standalone failed with " + status)); - } else { - deferred.resolve(this._saveToServer(items, attachmentCallback)); - } - }.bind(this)); - return deferred.promise; - }, - - /** - * Polls for updates to attachment progress - * @param items Items in Zotero.Item.toArray() format - * @param {Function} attachmentCallback A callback that receives information about attachment - * save progress. The callback will be called as attachmentCallback(attachment, false, error) - * on failure or attachmentCallback(attachment, progressPercent) periodically during saving. - * attachmentCallback() will be called with all attachments that will be saved - */ - "_pollForProgress":function(items, attachmentCallback) { - var attachments = []; - var progressIDs = []; - var previousStatus = []; - for(var i=0; i<items.length; i++) { - var itemAttachments = items[i].attachments; - for(var j=0; j<itemAttachments.length; j++) { - if(itemAttachments[j].id) { - attachments.push(itemAttachments[j]); - progressIDs.push(itemAttachments[j].id); - previousStatus.push(0); - } - } - } - - var nPolls = 0; - var poll = function() { - Zotero.Connector.callMethod("attachmentProgress", progressIDs, function(currentStatus, status) { - if(currentStatus) { - for(var i=0; i<attachments.length; i++) { - if(currentStatus[i] === 100 || currentStatus[i] === false) { - attachmentCallback(attachments[i], currentStatus[i]); - attachments.splice(i, 1); - progressIDs.splice(i, 1); - previousStatus.splice(i, 1); - currentStatus.splice(i, 1); - i--; - } else if(currentStatus[i] !== previousStatus[i]) { - attachmentCallback(attachments[i], currentStatus[i]); - previousStatus[i] = currentStatus[i]; - } - } - - if(nPolls++ < 60 && attachments.length) { - setTimeout(poll, 1000); - } - } else { - for(var i=0; i<attachments.length; i++) { - attachmentCallback(attachments[i], false, "Lost connection to Zotero Standalone"); - } - } - }); - }; - poll(); - }, - - // ALL CODE BELOW THIS POINT IS EXECUTED ONLY IN NON-FIREFOX ENVIRONMENTS - - /** - * Saves items to server - * @param items Items in Zotero.Item.toArray() format - * @param {Function} attachmentCallback A callback that receives information about attachment - * save progress. The callback will be called as attachmentCallback(attachment, false, error) - * on failure or attachmentCallback(attachment, progressPercent) periodically during saving. - * attachmentCallback() will be called with all attachments that will be saved - */ - _saveToServer: function (items, attachmentCallback) { - var newItems = [], itemIndices = [], typedArraysSupported = false; - try { - typedArraysSupported = !!(new Uint8Array(1) && new Blob()); - } catch(e) {} - - for(var i=0, n=items.length; i<n; i++) { - var item = items[i]; - // deproxify url - if (this._proxy && item.url) { - item.url = this._proxy.toProper(item.url); - } - itemIndices[i] = newItems.length; - newItems = newItems.concat(Zotero.Utilities.itemToServerJSON(item)); - if(typedArraysSupported) { - for(var j=0; j<item.attachments.length; j++) { - item.attachments[j].id = Zotero.Utilities.randomString(); - } - } else { - item.attachments = []; - } - } - - var deferred = Zotero.Promise.defer(); - Zotero.API.createItem({"items":newItems}, function(statusCode, response) { - if(statusCode !== 200) { - deferred.reject(new Error("Save to server failed with " + statusCode + " " + response)); - return; - } - - try { - var resp = JSON.parse(response); - } catch(e) { - deferred.reject(new Error("Unexpected response received from server")); - return; - } - for(var i in resp.failed) { - deferred.reject(new Error("Save to server failed with " + statusCode + " " + response)); - return; - } - - Zotero.debug("Translate: Save to server complete"); - Zotero.Prefs.getCallback( - ["downloadAssociatedFiles", "automaticSnapshots"], - function (prefs) { - if(typedArraysSupported) { - for(var i=0; i<items.length; i++) { - var item = items[i], key = resp.success[itemIndices[i]]; - if(item.attachments && item.attachments.length) { - this._saveAttachmentsToServer(key, this._getFileBaseNameFromItem(item), - item.attachments, prefs, attachmentCallback); - } - } - } - deferred.resolve(items); - }.bind(this) - ); - }.bind(this)); - return deferred.promise; - }, - - /** - * Saves an attachment to server - * @param {String} itemKey The key of the parent item - * @param {String} baseName A string to use as the base name for attachments - * @param {Object[]} attachments An array of attachment objects - * @param {Object} prefs An object with the values of the downloadAssociatedFiles and automaticSnapshots preferences - * @param {Function} attachmentCallback A callback that receives information about attachment - * save progress. The callback will be called as attachmentCallback(attachment, false, error) - * on failure or attachmentCallback(attachment, progressPercent) periodically during saving. - */ - "_saveAttachmentsToServer":function(itemKey, baseName, attachments, prefs, attachmentCallback) { - var me = this, - uploadAttachments = [], - retrieveHeadersForAttachments = attachments.length; - - /** - * Creates attachments on the z.org server. This is executed after we have received - * headers for all attachments to be downloaded, but before they are uploaded to - * z.org. - * @inner - */ - var createAttachments = function() { - if(uploadAttachments.length === 0) return; - var attachmentPayload = []; - for(var i=0; i<uploadAttachments.length; i++) { - var attachment = uploadAttachments[i]; - // deproxify url - if (this._proxy && attachment.url) { - attachment.url = this._proxy.toProper(attachment.url); - } - attachmentPayload.push({ - "itemType":"attachment", - "parentItem":itemKey, - "linkMode":attachment.linkMode, - "title":(attachment.title ? attachment.title.toString() : "Untitled Attachment"), - "accessDate":"CURRENT_TIMESTAMP", - "url":attachment.url, - "note":(attachment.note ? attachment.note.toString() : ""), - "tags":(attachment.tags && attachment.tags instanceof Array ? attachment.tags : []) - }); - } - - Zotero.API.createItem({"items":attachmentPayload}, function(statusCode, response) { - var resp; - if(statusCode === 200) { - try { - resp = JSON.parse(response); - if(!resp.success) resp = undefined; - } catch(e) {}; - } - - Zotero.debug("Finished creating items"); - for(var i=0; i<uploadAttachments.length; i++) { - var attachment = uploadAttachments[i]; - if(!resp || !resp.success[i]) { - attachmentCallback(attachment, false, - new Error("Unexpected response received from server "+statusCode+" "+response)); - } else { - attachment.key = resp.success[i]; - - if(attachment.linkMode === "linked_url") { - attachmentCallback(attachment, 100); - } else if("data" in attachment) { - me._uploadAttachmentToServer(attachment, attachmentCallback); - } - } - } - }); - }; - - for(var i=0; i<attachments.length; i++) { - // Also begin to download attachments - (function(attachment) { - var headersValidated = null; - - // Ensure these are undefined before continuing, since we'll use them to determine - // whether an attachment has been created on the Zotero server and downloaded from - // the host - delete attachment.key; - delete attachment.data; - - var isSnapshot = false; - if(attachment.mimeType) { - switch(attachment.mimeType.toLowerCase()) { - case "text/html": - case "application/xhtml+xml": - isSnapshot = true; - } - } - - if((isSnapshot && !prefs.automaticSnapshots) || (!isSnapshot && !prefs.downloadAssociatedFiles)) { - // Check preferences to see if we should download this file - if(--retrieveHeadersForAttachments === 0) createAttachments(); - return; - } else if(attachment.snapshot === false && attachment.mimeType) { - // If we aren't taking a snapshot and we have the MIME type, we don't need - // to retrieve anything - attachment.linkMode = "linked_url"; - uploadAttachments.push(attachment); - if(attachmentCallback) attachmentCallback(attachment, 0); - if(--retrieveHeadersForAttachments === 0) createAttachments(); - return; - } - - /** - * Checks headers to ensure that they reflect our expectations. When headers have - * been checked for all attachments, creates new items on the z.org server and - * begins uploading them. - * @inner - */ - var checkHeaders = function() { - if(headersValidated !== null) return headersValidated; - - retrieveHeadersForAttachments--; - headersValidated = false; - - var err = null, - status = xhr.status; - - // Validate status - if(status === 0 || attachment.snapshot === false) { - // Failed due to SOP, or we are supposed to be getting a snapshot - attachment.linkMode = "linked_url"; - } else if(status !== 200) { - err = new Error("Server returned unexpected status code "+status); - } else { - // Validate content type - var contentType = "application/octet-stream", - charset = null, - contentTypeHeader = xhr.getResponseHeader("Content-Type"); - if(contentTypeHeader) { - // See RFC 2616 sec 3.7 - var m = /^[^\x00-\x1F\x7F()<>@,;:\\"\/\[\]?={} ]+\/[^\x00-\x1F\x7F()<>@,;:\\"\/\[\]?={} ]+/.exec(contentTypeHeader); - if(m) contentType = m[0].toLowerCase(); - m = /;\s*charset\s*=\s*("[^"]+"|[^\x00-\x1F\x7F()<>@,;:\\"\/\[\]?={} ]+)/.exec(contentTypeHeader); - if(m) { - charset = m[1]; - if(charset[0] === '"') charset = charset.substring(1, charset.length-1); - } - - if(attachment.mimeType - && attachment.mimeType.toLowerCase() !== contentType.toLowerCase()) { - err = new Error("Attachment MIME type "+contentType+ - " does not match specified type "+attachment.mimeType); - } - } - - if(!err) { - attachment.mimeType = contentType; - attachment.linkMode = "imported_url"; - switch(contentType.toLowerCase()) { - case "application/pdf": - attachment.filename = baseName+".pdf"; - break; - case "text/html": - case "application/xhtml+xml": - attachment.filename = baseName+".html"; - break; - default: - attachment.filename = baseName; - } - if(charset) attachment.charset = charset; - headersValidated = true; - } - } - - // If we didn't validate the headers, cancel the request - if(headersValidated === false && "abort" in xhr) xhr.abort(); - - // Add attachments to attachment payload if there was no error - if(!err) { - uploadAttachments.push(attachment); - } - - // If we have retrieved the headers for all attachments, create items on z.org - // server - if(retrieveHeadersForAttachments === 0) createAttachments(); - - // If there was an error, throw it now - if(err) { - attachmentCallback(attachment, false, err); - Zotero.logError(err); - } - return headersValidated; - }; - - var xhr = new XMLHttpRequest(); - xhr.open((attachment.snapshot === false ? "HEAD" : "GET"), attachment.url, true); - xhr.responseType = (isSnapshot ? "document" : "arraybuffer"); - xhr.onreadystatechange = function() { - if(xhr.readyState !== 4 || !checkHeaders()) return; - - attachmentCallback(attachment, 50); - attachment.data = xhr.response; - // If item already created, head to upload - if("key" in attachment) { - me._uploadAttachmentToServer(attachment, attachmentCallback); - } - }; - xhr.onprogress = function(event) { - if(xhr.readyState < 2 || !checkHeaders()) return; - - if(event.total && attachmentCallback) { - attachmentCallback(attachment, event.loaded/event.total*50); - } - }; - xhr.send(); - - if(attachmentCallback) attachmentCallback(attachment, 0); - })(attachments[i]); - } - }, - - /** - * Uploads an attachment to the Zotero server - * @param {Object} attachment Attachment object, including - * @param {Function} attachmentCallback A callback that receives information about attachment - * save progress. The callback will be called as attachmentCallback(attachment, false, error) - * on failure or attachmentCallback(attachment, progressPercent) periodically during saving. - */ - "_uploadAttachmentToServer":function(attachment, attachmentCallback) { - Zotero.debug("Uploading attachment to server"); - switch(attachment.mimeType.toLowerCase()) { - case "text/html": - case "application/xhtml+xml": - // It's possible that we didn't know if this was a snapshot until after the - // download began. If this is the case, we need to convert it to a document. - if(attachment.data instanceof ArrayBuffer) { - var me = this, - blob = new Blob([attachment.data], {"type":attachment.mimeType}), - reader = new FileReader(); - reader.onloadend = function() { - if(reader.error) { - attachmentCallback(attachment, false, reader.error); - } else { - // Convert to an HTML document - var result = reader.result, doc; - try { - // First try using DOMParser - doc = (new DOMParser()).parseFromString(result, "text/html"); - } catch(e) {} - - // If DOMParser fails, use document.implementation.createHTMLDocument, - // as documented at https://developer.mozilla.org/en-US/docs/Web/API/DOMParser - if(!doc) { - doc = document.implementation.createHTMLDocument(""); - var docEl = doc.documentElement; - // AMO reviewer: This code is not run in Firefox, and the document - // is never rendered anyway - docEl.innerHTML = result; - if(docEl.children.length === 1 && docEl.firstElementChild === "html") { - doc.replaceChild(docEl.firstElementChild, docEl); - } - } - - attachment.data = doc; - me._uploadAttachmentToServer(attachment, attachmentCallback); - } - } - reader.readAsText(blob, attachment.charset || "iso-8859-1"); - return; - } - - // We are now assured that attachment.data is an HTMLDocument, so we can - // add a base tag - - // Get the head tag - var doc = attachment.data, - head = doc.getElementsByTagName("head"); - if(!head.length) { - head = doc.createElement("head"); - var docEl = attachment.data.documentElement; - docEl.insertBefore(head, docEl.firstChildElement); - } else { - head = head[0]; - } - - // Add the base tag - var base = doc.createElement("base"); - base.href = attachment.url; - head.appendChild(base); - - // Remove content type tags - var metaTags = doc.getElementsByTagName("meta"), metaTag; - for(var i=0; i<metaTags.length; i++) { - metaTag = metaTags[i]; - var attr = metaTag.getAttribute("http-equiv"); - if(attr && attr.toLowerCase() === "content-type") { - metaTag.parentNode.removeChild(metaTag); - } - } - - // Add UTF-8 content type - metaTag = doc.createElement("meta"); - metaTag.setAttribute("http-equiv", "Content-Type"); - metaTag.setAttribute("content", attachment.mimeType+"; charset=UTF-8"); - head.insertBefore(metaTag, head.firstChild); - - // Serialize document to UTF-8 - var src = new XMLSerializer().serializeToString(doc), - srcLength = Zotero.Utilities.getStringByteLength(src), - srcArray = new Uint8Array(srcLength); - Zotero.Utilities.stringToUTF8Array(src, srcArray); - - // Rewrite data - attachment.data = srcArray.buffer; - attachment.charset = "UTF-8"; - break; - } - - var binaryHash = this._md5(new Uint8Array(attachment.data), 0, attachment.data.byteLength), - hash = ""; - for(var i=0; i<binaryHash.length; i++) { - if(binaryHash[i] < 16) hash += "0"; - hash += binaryHash[i].toString(16); - } - attachment.md5 = hash; - - if(Zotero.isBrowserExt && !Zotero.isBookmarklet) { - // In Chrome, we don't use messaging for Zotero.API.uploadAttachment, since - // we can't pass ArrayBuffers to the background page - Zotero.API.uploadAttachment(attachment, attachmentCallback.bind(this, attachment)); - } else { - // In Safari and the connectors, we can pass ArrayBuffers - Zotero.Translate.ItemSaver._attachmentCallbacks[attachment.id] = function(status, error) { - attachmentCallback(attachment, status, error); - }; - Zotero.API.uploadAttachment(attachment); - } - }, - - /** - * Gets the base name for an attachment from an item object. This mimics the default behavior - * of Zotero.Attachments.getFileBaseNameFromItem - * @param {Object} item - */ - "_getFileBaseNameFromItem":function(item) { - var parts = []; - if(item.creators && item.creators.length) { - if(item.creators.length === 1) { - parts.push(item.creators[0].lastName); - } else if(item.creators.length === 2) { - parts.push(item.creators[0].lastName+" and "+item.creators[1].lastName); - } else { - parts.push(item.creators[0].lastName+" et al."); - } - } - - if(item.date) { - var date = Zotero.Date.strToDate(item.date); - if(date.year) parts.push(date.year); - } - - if(item.title) { - parts.push(item.title.substr(0, 50)); - } - - if(parts.length) return parts.join(" - "); - return "Attachment"; - }, - - /* - pdf.js MD5 implementation - Copyright (c) 2011 Mozilla Foundation - - Contributors: Andreas Gal <gal@mozilla.com> - Chris G Jones <cjones@mozilla.com> - Shaon Barman <shaon.barman@gmail.com> - Vivien Nicolas <21@vingtetun.org> - Justin D'Arcangelo <justindarc@gmail.com> - Yury Delendik - Kalervo Kujala - Adil Allawi <@ironymark> - Jakob Miland <saebekassebil@gmail.com> - Artur Adib <aadib@mozilla.com> - Brendan Dahl <bdahl@mozilla.com> - David Quintana <gigaherz@gmail.com> - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - "_md5":(function calculateMD5Closure() { - // Don't throw if typed arrays are not supported - try { - var r = new Uint8Array([ - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]); - - var k = new Int32Array([ - -680876936, -389564586, 606105819, -1044525330, -176418897, 1200080426, - -1473231341, -45705983, 1770035416, -1958414417, -42063, -1990404162, - 1804603682, -40341101, -1502002290, 1236535329, -165796510, -1069501632, - 643717713, -373897302, -701558691, 38016083, -660478335, -405537848, - 568446438, -1019803690, -187363961, 1163531501, -1444681467, -51403784, - 1735328473, -1926607734, -378558, -2022574463, 1839030562, -35309556, - -1530992060, 1272893353, -155497632, -1094730640, 681279174, -358537222, - -722521979, 76029189, -640364487, -421815835, 530742520, -995338651, - -198630844, 1126891415, -1416354905, -57434055, 1700485571, -1894986606, - -1051523, -2054922799, 1873313359, -30611744, -1560198380, 1309151649, - -145523070, -1120210379, 718787259, -343485551]); - } catch(e) {}; - - function hash(data, offset, length) { - var h0 = 1732584193, h1 = -271733879, h2 = -1732584194, h3 = 271733878; - // pre-processing - var paddedLength = (length + 72) & ~63; // data + 9 extra bytes - var padded = new Uint8Array(paddedLength); - var i, j, n; - if (offset || length != data.byteLength) { - padded.set(new Uint8Array(data.buffer, offset, length)); - } else { - padded.set(data); - } - i = length; - padded[i++] = 0x80; - n = paddedLength - 8; - while (i < n) - padded[i++] = 0; - padded[i++] = (length << 3) & 0xFF; - padded[i++] = (length >> 5) & 0xFF; - padded[i++] = (length >> 13) & 0xFF; - padded[i++] = (length >> 21) & 0xFF; - padded[i++] = (length >>> 29) & 0xFF; - padded[i++] = 0; - padded[i++] = 0; - padded[i++] = 0; - // chunking - // TODO ArrayBuffer ? - var w = new Int32Array(16); - for (i = 0; i < paddedLength;) { - for (j = 0; j < 16; ++j, i += 4) { - w[j] = (padded[i] | (padded[i + 1] << 8) | - (padded[i + 2] << 16) | (padded[i + 3] << 24)); - } - var a = h0, b = h1, c = h2, d = h3, f, g; - for (j = 0; j < 64; ++j) { - if (j < 16) { - f = (b & c) | ((~b) & d); - g = j; - } else if (j < 32) { - f = (d & b) | ((~d) & c); - g = (5 * j + 1) & 15; - } else if (j < 48) { - f = b ^ c ^ d; - g = (3 * j + 5) & 15; - } else { - f = c ^ (b | (~d)); - g = (7 * j) & 15; - } - var tmp = d, rotateArg = (a + f + k[j] + w[g]) | 0, rotate = r[j]; - d = c; - c = b; - b = (b + ((rotateArg << rotate) | (rotateArg >>> (32 - rotate)))) | 0; - a = tmp; - } - h0 = (h0 + a) | 0; - h1 = (h1 + b) | 0; - h2 = (h2 + c) | 0; - h3 = (h3 + d) | 0; - } - return new Uint8Array([ - h0 & 0xFF, (h0 >> 8) & 0xFF, (h0 >> 16) & 0xFF, (h0 >>> 24) & 0xFF, - h1 & 0xFF, (h1 >> 8) & 0xFF, (h1 >> 16) & 0xFF, (h1 >>> 24) & 0xFF, - h2 & 0xFF, (h2 >> 8) & 0xFF, (h2 >> 16) & 0xFF, (h2 >>> 24) & 0xFF, - h3 & 0xFF, (h3 >> 8) & 0xFF, (h3 >> 16) & 0xFF, (h3 >>> 24) & 0xFF - ]); - } - return hash; - })() -}; -\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/connector/translator.js b/chrome/content/zotero/xpcom/connector/translator.js @@ -1,473 +0,0 @@ -/* - ***** BEGIN LICENSE BLOCK ***** - - Copyright © 2009 Center for History and New Media - George Mason University, Fairfax, Virginia, USA - http://zotero.org - - This file is part of Zotero. - - Zotero is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Zotero is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with Zotero. If not, see <http://www.gnu.org/licenses/>. - - ***** END LICENSE BLOCK ***** -*/ - -// Enumeration of types of translators -var TRANSLATOR_TYPES = {"import":1, "export":2, "web":4, "search":8}; - -/** - * Singleton to handle loading and caching of translators - * @namespace - */ -Zotero.Translators = new function() { - var _cache, _translators; - var _initialized = false; - - /** - * Initializes translator cache, loading all relevant translators into memory - * @param {Zotero.Translate[]} [translators] List of translators. If not specified, it will be - * retrieved from storage. - */ - this.init = function(translators) { - if(!translators) { - translators = []; - if((Zotero.isBrowserExt || Zotero.isSafari) && localStorage["translatorMetadata"]) { - try { - translators = JSON.parse(localStorage["translatorMetadata"]); - if(typeof translators !== "object") { - translators = []; - } - } catch(e) {} - } - } - - _cache = {"import":[], "export":[], "web":[], "search":[]}; - _translators = {}; - _initialized = true; - - // Build caches - for(var i=0; i<translators.length; i++) { - try { - var translator = new Zotero.Translator(translators[i]); - _translators[translator.translatorID] = translator; - - for(var type in TRANSLATOR_TYPES) { - if(translator.translatorType & TRANSLATOR_TYPES[type]) { - _cache[type].push(translator); - } - } - } catch(e) { - Zotero.logError(e); - try { - Zotero.logError("Could not load translator "+JSON.stringify(translators[i])); - } catch(e) {} - } - } - - // Sort by priority - var cmp = function (a, b) { - if (a.priority > b.priority) { - return 1; - } - else if (a.priority < b.priority) { - return -1; - } - } - for(var type in _cache) { - _cache[type].sort(cmp); - } - } - - /** - * Gets the translator that corresponds to a given ID, without attempting to retrieve code - * @param {String} id The ID of the translator - */ - this.getWithoutCode = function(id) { - if(!_initialized) Zotero.Translators.init(); - return _translators[id] ? _translators[id] : false; - } - - /** - * Gets the translator that corresponds to a given ID - * - * @param {String} id The ID of the translator - */ - this.get = Zotero.Promise.method(function (id) { - if(!_initialized) Zotero.Translators.init(); - var translator = _translators[id]; - if(!translator) { - return false; - } - - // only need to get code if it is of some use - if(translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER - && !translator.hasOwnProperty("code")) { - return translator.getCode().then(() => translator); - } else { - return translator; - } - }); - - /** - * Gets all translators for a specific type of translation - * @param {String} type The type of translators to get (import, export, web, or search) - * @param {Boolean} [debugMode] Whether to assume debugging mode. If true, code is included for - * unsupported translators, and code originally retrieved from the - * repo is re-retrieved from Zotero Standalone. - */ - this.getAllForType = Zotero.Promise.method(function (type, debugMode) { - if(!_initialized) Zotero.Translators.init() - var translators = _cache[type].slice(0); - var codeGetter = new Zotero.Translators.CodeGetter(translators, debugMode); - return codeGetter.getAll().then(function() { - return translators; - });; - }); - - /** - * Gets web translators for a specific location - * @param {String} uri The URI for which to look for translators - * @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, rootURI) { - var isFrame = URI !== rootURI; - if(!_initialized) Zotero.Translators.init(); - var allTranslators = _cache["web"]; - var potentialTranslators = []; - var proxies = []; - - var rootSearchURIs = Zotero.Proxies.getPotentialProxies(rootURI); - var frameSearchURIs = isFrame ? Zotero.Proxies.getPotentialProxies(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); - proxies.push(frameSearchURIs[frameSearchURI]); - // prevent adding the translator multiple times - break rootURIsLoop; - } - } - } else if(!isFrame && (isGeneric || rootURIMatches)) { - potentialTranslators.push(translator); - proxies.push(rootSearchURIs[rootSearchURI]); - break; - } - } - } - - var codeGetter = new Zotero.Translators.CodeGetter(potentialTranslators); - return codeGetter.getAll().then(function () { - return [potentialTranslators, proxies]; - }); - }); - - /** - * Converts translators to JSON-serializable objects - */ - this.serialize = function(translator, properties) { - // handle translator arrays - if(translator.length !== undefined) { - var newTranslators = new Array(translator.length); - for(var i in translator) { - newTranslators[i] = Zotero.Translators.serialize(translator[i], properties); - } - return newTranslators; - } - - // handle individual translator - var newTranslator = {}; - for(var i in properties) { - var property = properties[i]; - newTranslator[property] = translator[property]; - } - return newTranslator; - } - - /** - * Saves all translator metadata to localStorage - * @param {Object[]} newMetadata Metadata for new translators - * @param {Boolean} reset Whether to clear all existing translators and overwrite them with - * the specified translators. - */ - this.update = function(newMetadata, reset) { - if (!_initialized) Zotero.Translators.init(); - if (!newMetadata.length) return; - var serializedTranslators = []; - - if (reset) { - serializedTranslators = newMetadata.map((t) => new Zotero.Translator(t)); - } - else { - var hasChanged = false; - - // Update translators with new metadata - for(var i in newMetadata) { - var newTranslator = newMetadata[i]; - - if(_translators.hasOwnProperty(newTranslator.translatorID)) { - var oldTranslator = _translators[newTranslator.translatorID]; - - // check whether translator has changed - if(oldTranslator.lastUpdated !== newTranslator.lastUpdated) { - // check whether newTranslator is actually newer than the existing - // translator, and if not, don't update - if(Zotero.Date.sqlToDate(newTranslator.lastUpdated) < Zotero.Date.sqlToDate(oldTranslator.lastUpdated)) { - continue; - } - - Zotero.debug(`Translators: Updating ${newTranslator.label}`); - oldTranslator.init(newTranslator); - hasChanged = true; - } - } else { - Zotero.debug(`Translators: Adding ${newTranslator.label}`); - _translators[newTranslator.translatorID] = new Zotero.Translator(newTranslator); - hasChanged = true; - } - } - - let deletedTranslators = Object.keys(_translators).filter(id => _translators[id].deleted); - if (deletedTranslators.length) { - hasChanged = true; - for (let id of deletedTranslators) { - Zotero.debug(`Translators: Removing ${_translators[id].label}`); - delete _translators[id]; - } - } - - if(!hasChanged) return; - - // Serialize translators - for(var i in _translators) { - var serializedTranslator = this.serialize(_translators[i], TRANSLATOR_SAVE_PROPERTIES); - - // don't save run mode - delete serializedTranslator.runMode; - - serializedTranslators.push(serializedTranslator); - } - } - - // Store - if (Zotero.isBrowserExt || Zotero.isSafari) { - var serialized = JSON.stringify(serializedTranslators); - localStorage["translatorMetadata"] = serialized; - Zotero.debug("Translators: Saved updated translator list ("+serialized.length+" characters)"); - } - - // Reinitialize - Zotero.Translators.init(serializedTranslators); - } - - /** - * Preprocesses code for a translator - */ - this.preprocessCode = function(code) { - if(!Zotero.isFx) { - const foreach = /^(\s*)for each\s*\((var )?([^ ]+) in (.*?)\)(\s*){/gm; - code = code.replace(foreach, "$1var $3_zForEachSubject = $4; "+ - "for(var $3_zForEachIndex in $3_zForEachSubject)$5{ "+ - "$2$3 = $3_zForEachSubject[$3_zForEachIndex];", code); - } - return code; - } -} - -/** - * A class to get the code for a set of translators at once - * - * @param {Zotero.Translator[]} translators Translators for which to retrieve code - * @param {Boolean} [debugMode] If true, include code for unsupported translators - */ -Zotero.Translators.CodeGetter = function(translators, debugMode) { - this._translators = translators; - this._debugMode = debugMode; - this._concurrency = 1; -}; - -Zotero.Translators.CodeGetter.prototype.getCodeFor = Zotero.Promise.method(function(i) { - let translator = this._translators[i]; - // retrieve code if no code and translator is supported locally - if((translator.runMode === Zotero.Translator.RUN_MODE_IN_BROWSER && !translator.hasOwnProperty("code")) - // or if debug mode is enabled (even if unsupported locally) - || (this._debugMode && (!translator.hasOwnProperty("code") - // or if in debug mode and the code we have came from the repo (which doesn't - // include test cases) - || (Zotero.Repo && translator.codeSource === Zotero.Repo.SOURCE_REPO)))) { - // get code - return translator.getCode().catch((e) => Zotero.debug(`Failed to retrieve code for ${translator.translatorID}`)); - } -}); - -Zotero.Translators.CodeGetter.prototype.getAll = function () { - var codes = []; - // Chain promises with some level of concurrency. If unchained, fires - // off hundreds of xhttprequests on connectors and crashes the extension - for (let i = 0; i < this._translators.length; i++) { - if (i < this._concurrency) { - codes.push(this.getCodeFor(i)); - } else { - codes.push(codes[i-this._concurrency].then(() => this.getCodeFor(i))); - } - } - return Promise.all(codes); -}; - -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", "targetAll"]); -/** - * @class Represents an individual translator - * @constructor - * @property {String} translatorID Unique GUID of the translator - * @property {Integer} translatorType Type of the translator (use bitwise & with TRANSLATOR_TYPES to read) - * @property {String} label Human-readable name of the translator - * @property {String} creator Author(s) of the translator - * @property {String} target Location that the translator processes - * @property {String} minVersion Minimum Zotero version - * @property {String} maxVersion Minimum Zotero version - * @property {Integer} priority Lower-priority translators will be selected first - * @property {String} browserSupport String indicating browser supported by the translator - * g = Gecko (Firefox) - * c = Google Chrome (WebKit & V8) - * s = Safari (WebKit & Nitro/Squirrelfish Extreme) - * i = Internet Explorer - * b = Bookmarklet - * v = Server - * @property {Object} configOptions Configuration options for import/export - * @property {Object} displayOptions Display options for export - * @property {Object} hiddenPrefs Hidden preferences configurable through about:config - * @property {Boolean} inRepository Whether the translator may be found in the repository - * @property {String} lastUpdated SQL-style date and time of translator's last update - * @property {String} code The executable JavaScript for the translator - */ -Zotero.Translator = function(info) { - this.init(info); -} - -/** - * Initializes a translator from a set of info, clearing code if it is set - */ -Zotero.Translator.prototype.init = function(info) { - // make sure we have all the properties - for(var i in TRANSLATOR_REQUIRED_PROPERTIES) { - var property = TRANSLATOR_REQUIRED_PROPERTIES[i]; - if(info[property] === undefined) { - Zotero.logError(new Error('Missing property "'+property+'" in translator metadata JSON object in ' + info.label)); - break; - } else { - 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"; - - if(this.browserSupport.indexOf(Zotero.browser) !== -1) { - this.runMode = Zotero.Translator.RUN_MODE_IN_BROWSER; - } else { - this.runMode = Zotero.Translator.RUN_MODE_ZOTERO_STANDALONE; - } - - if(this.translatorType & TRANSLATOR_TYPES["import"]) { - // compile import regexp to match only file extension - this.importRegexp = this.target ? new RegExp("\\."+this.target+"$", "i") : null; - } else if(this.hasOwnProperty("importRegexp")) { - delete this.importRegexp; - } - - if(this.translatorType & TRANSLATOR_TYPES["web"]) { - // compile web regexp - this.webRegexp = { - root: this.target ? new RegExp(this.target, "i") : null, - all: this.targetAll ? new RegExp(this.targetAll, "i") : null - }; - } else if(this.hasOwnProperty("webRegexp")) { - delete this.webRegexp; - } - - if(info.code) { - this.code = Zotero.Translators.preprocessCode(info.code); - } else if(this.hasOwnProperty("code")) { - delete this.code; - } -} - -/** - * Retrieves code for this translator - * - * @return {Promise<String|false>} - Promise for translator code or false if none - */ -Zotero.Translator.prototype.getCode = function (debugMode) { - return Zotero.Repo.getTranslatorCode(this.translatorID, debugMode) - .then(function (args) { - var code = args[0]; - var source = args[1]; - if (!code) { - return false; - } - - // cache code for session only (we have standalone anyway) - this.code = code; - this.codeSource = source; - return code; - }.bind(this)); -} - -/** - * Log a translator-related error - * @param {String} message The error message - * @param {String} [type] The error type ("error", "warning", "exception", or "strict") - * @param {String} [line] The text of the line on which the error occurred - * @param {Integer} lineNumber - * @param {Integer} colNumber - */ -Zotero.Translator.prototype.logError = function(message, type, line, lineNumber, colNumber) { - Zotero.logError(message); -} - -Zotero.Translator.RUN_MODE_IN_BROWSER = 1; -Zotero.Translator.RUN_MODE_ZOTERO_STANDALONE = 2; -Zotero.Translator.RUN_MODE_ZOTERO_SERVER = 4; -\ No newline at end of file diff --git a/chrome/content/zotero/xpcom/connector/typeSchemaData.js b/chrome/content/zotero/xpcom/connector/typeSchemaData.js @@ -1 +0,0 @@ -Zotero.Connector_Types.schema = {"itemTypes":{"1":["note","Note",[false],[],{},"treeitem-note.png"],"2":["book","Book",[1,2,3,5,4],[110,90,3,30,4,45,6,7,8,14,118,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-book.png"],"3":["bookSection","Book Section",[1,29,2,3,5,4],[110,90,115,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{"115":12},"treeitem-bookSection.png"],"4":["journalArticle","Journal Article",[1,2,3,27,4],[110,90,12,4,5,10,14,3,28,29,25,87,26,13,116,1,27,123,19,62,18,2,22],{},"treeitem-journalArticle.png"],"5":["magazineArticle","Magazine Article",[1,2,27,4],[110,90,12,4,5,14,10,87,13,116,1,27,123,19,62,18,2,22],{},"treeitem-magazineArticle.png"],"6":["newspaperArticle","Newspaper Article",[1,2,27,4],[110,90,12,7,6,14,15,10,87,116,13,1,27,123,19,62,18,2,22],{},"treeitem-newspaperArticle.png"],"7":["thesis","Thesis",[1,2],[110,90,69,89,7,14,118,87,116,1,27,123,19,62,18,2,22],{"69":108,"89":8},"treeitem-thesis.png"],"8":["letter","Letter",[1,2,16],[110,90,65,14,87,116,1,27,123,19,62,18,2,22],{"65":108},"treeitem-letter.png"],"9":["manuscript","Manuscript",[1,2,4],[110,90,66,7,14,118,87,116,1,27,123,19,62,18,2,22],{"66":108},"treeitem-manuscript.png"],"10":["interview","Interview",[6,2,7,4],[110,90,14,64,87,116,1,27,123,19,62,18,2,22],{"64":109},"treeitem-interview.png"],"11":["film","Film",[8,2,10,9],[110,90,21,14,122,63,77,87,116,1,27,123,19,62,18,2,22],{"21":8,"122":108,"63":109},"treeitem-film.png"],"12":["artwork","Artwork",[22,2],[110,90,59,61,14,87,116,123,19,62,18,1,27,2,22],{"59":109},"treeitem-artwork.png"],"13":["webpage","Web Page",[1,2,4],[110,90,91,70,14,116,1,27,87,2,22],{"91":12,"70":108},"treeitem-webpage.png"],"14":["attachment","Attachment",[false],[110,27,1],{},"treeitem.png"],"15":["report","Report",[1,2,5,4],[110,90,92,32,28,7,31,14,10,87,116,1,27,123,19,62,18,2,22],{"92":60,"32":108,"31":8},"treeitem-report.png"],"16":["bill","Bill",[12,2,28],[110,90,93,36,94,15,95,41,40,42,14,87,1,27,116,2,22],{"93":60,"94":4,"95":10},"treeitem-bill.png"],"17":["case","Case",[1,2,13],[111,90,43,97,44,117,98,42,96,87,116,1,27,2,22],{"111":110,"97":4,"117":60,"98":10,"96":14},"treeitem-case.png"],"18":["hearing","Hearing",[2],[110,90,46,7,8,45,99,10,41,40,42,14,87,116,1,27,2,22],{"99":60},"treeitem-hearing.png"],"19":["patent","Patent",[14,15,2],[110,90,7,102,48,120,50,121,10,103,51,52,53,54,87,116,1,27,2,22],{"50":60,"52":14},"treeitem-patent.png"],"20":["statute","Statute",[1,2],[112,90,36,55,101,100,10,15,40,42,87,116,1,27,2,22],{"112":110,"101":60,"100":14},"treeitem-statute.png"],"21":["email","E-mail",[1,2,16],[113,90,14,116,1,27,87,2,22],{"113":110},"treeitem-email.png"],"22":["map","Map",[20,2,5],[110,90,67,68,28,6,7,8,14,87,11,116,1,27,123,19,62,18,2,22],{"67":108},"treeitem-map.png"],"23":["blogPost","Blog Post",[1,23,2],[110,90,107,70,14,1,27,87,116,2,22],{"107":12,"70":108},"treeitem-blogPost.png"],"24":["instantMessage","Instant Message",[1,2,16],[110,90,14,87,116,1,27,2,22],{},"treeitem-instantMessage.png"],"25":["forumPost","Forum Post",[1,2],[110,90,104,79,14,87,116,1,27,2,22],{"104":12,"79":108},"treeitem-forumPost.png"],"26":["audioRecording","Audio Recording",[17,18,2,19],[110,90,71,28,4,45,7,72,14,77,87,11,116,123,19,62,18,1,27,2,22],{"71":109,"72":8},"treeitem-audioRecording.png"],"27":["presentation","Presentation",[24,2],[110,90,74,14,7,75,1,27,87,116,2,22],{"74":108},"treeitem-presentation.png"],"28":["videoRecording","Video Recording",[8,11,2,10,9],[110,90,63,28,4,45,7,76,14,77,87,11,116,1,27,123,19,62,18,2,22],{"63":109,"76":8},"treeitem-videoRecording.png"],"29":["tvBroadcast","TV Broadcast",[8,11,2,25,10,9],[110,90,119,105,63,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{"119":12,"105":60,"63":109,"78":8},"treeitem-tvBroadcast.png"],"30":["radioBroadcast","Radio Broadcast",[8,11,2,25,10,9],[110,90,119,105,71,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{"119":12,"105":60,"71":109,"78":8},"treeitem-radioBroadcast.png"],"31":["podcast","Podcast",[26,2,25],[110,90,28,105,80,77,1,27,87,116,2,22],{"105":60,"80":109},"treeitem-podcast.png"],"32":["computerProgram","Computer Program",[21,2],[110,90,28,81,14,82,7,83,88,11,116,1,2,123,19,62,18,27,22],{"83":8},"treeitem-computerProgram.png"],"33":["conferencePaper","Conference Paper",[1,2,3,5,4],[110,90,14,114,84,7,8,4,10,3,87,26,11,116,1,27,123,19,62,18,2,22],{"114":12},"treeitem-conferencePaper.png"],"34":["document","Document",[1,2,3,27,4],[110,90,8,14,87,116,1,27,123,19,62,18,2,22],{},"treeitem-document.png"],"35":["encyclopediaArticle","Encyclopedia Article",[1,2,3,5,4],[110,90,85,3,30,4,45,6,7,8,14,10,11,116,1,27,87,123,19,62,18,2,22],{"85":12},"treeitem-encyclopediaArticle.png"],"36":["dictionaryEntry","Dictionary Entry",[1,2,3,5,4],[110,90,86,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{"86":12},"treeitem-dictionaryEntry.png"]},"creatorTypes":{"1":["author","Author"],"2":["contributor","Contributor"],"3":["editor","Editor"],"4":["translator","Translator"],"5":["seriesEditor","Series Editor"],"6":["interviewee","Interview With"],"7":["interviewer","Interviewer"],"8":["director","Director"],"9":["scriptwriter","Scriptwriter"],"10":["producer","Producer"],"11":["castMember","Cast Member"],"12":["sponsor","Sponsor"],"13":["counsel","Counsel"],"14":["inventor","Inventor"],"15":["attorneyAgent","Attorney/Agent"],"16":["recipient","Recipient"],"17":["performer","Performer"],"18":["composer","Composer"],"19":["wordsBy","Words By"],"20":["cartographer","Cartographer"],"21":["programmer","Programmer"],"22":["artist","Artist"],"23":["commenter","Commenter"],"24":["presenter","Presenter"],"25":["guest","Guest"],"26":["podcaster","Podcaster"],"27":["reviewedAuthor","Reviewed Author"],"28":["cosponsor","Cosponsor"],"29":["bookAuthor","Book Author"]},"fields":{"1":["url"],"2":["rights"],"3":["series"],"4":["volume"],"5":["issue"],"6":["edition"],"7":["place"],"8":["publisher"],"10":["pages"],"11":["ISBN"],"12":["publicationTitle"],"13":["ISSN"],"14":["date"],"15":["section"],"18":["callNumber"],"19":["archiveLocation"],"21":["distributor"],"22":["extra"],"25":["journalAbbreviation"],"26":["DOI"],"27":["accessDate"],"28":["seriesTitle"],"29":["seriesText"],"30":["seriesNumber"],"31":["institution"],"32":["reportType"],"36":["code"],"40":["session"],"41":["legislativeBody"],"42":["history"],"43":["reporter"],"44":["court"],"45":["numberOfVolumes"],"46":["committee"],"48":["assignee"],"50":["patentNumber"],"51":["priorityNumbers"],"52":["issueDate"],"53":["references"],"54":["legalStatus"],"55":["codeNumber"],"59":["artworkMedium"],"60":["number"],"61":["artworkSize"],"62":["libraryCatalog"],"63":["videoRecordingFormat"],"64":["interviewMedium"],"65":["letterType"],"66":["manuscriptType"],"67":["mapType"],"68":["scale"],"69":["thesisType"],"70":["websiteType"],"71":["audioRecordingFormat"],"72":["label"],"74":["presentationType"],"75":["meetingName"],"76":["studio"],"77":["runningTime"],"78":["network"],"79":["postType"],"80":["audioFileType"],"81":["version"],"82":["system"],"83":["company"],"84":["conferenceName"],"85":["encyclopediaTitle"],"86":["dictionaryTitle"],"87":["language"],"88":["programmingLanguage"],"89":["university"],"90":["abstractNote"],"91":["websiteTitle"],"92":["reportNumber"],"93":["billNumber"],"94":["codeVolume"],"95":["codePages"],"96":["dateDecided"],"97":["reporterVolume"],"98":["firstPage"],"99":["documentNumber"],"100":["dateEnacted"],"101":["publicLawNumber"],"102":["country"],"103":["applicationNumber"],"104":["forumTitle"],"105":["episodeNumber"],"107":["blogTitle"],"108":["type"],"109":["medium"],"110":["title"],"111":["caseName"],"112":["nameOfAct"],"113":["subject"],"114":["proceedingsTitle"],"115":["bookTitle"],"116":["shortTitle"],"117":["docketNumber"],"118":["numPages"],"119":["programTitle"],"120":["issuingAuthority"],"121":["filingDate"],"122":["genre"],"123":["archive"]}} -\ No newline at end of file diff --git a/resource/schema/connectorTypeSchemaData.js b/resource/schema/connectorTypeSchemaData.js @@ -0,0 +1 @@ +Zotero.Connector_Types.schema = {"itemTypes":{"1":["note","Note",[false],[],{},"treeitem-note.png"],"2":["book","Book",[1,2,3,5,4],[110,90,3,30,4,45,6,7,8,14,118,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-book.png"],"3":["bookSection","Book Section",[1,29,2,3,5,4],[110,90,115,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-bookSection.png"],"4":["journalArticle","Journal Article",[1,2,3,27,4],[110,90,12,4,5,10,14,3,28,29,25,87,26,13,116,1,27,123,19,62,18,2,22],{},"treeitem-journalArticle.png"],"5":["magazineArticle","Magazine Article",[1,2,27,4],[110,90,12,4,5,14,10,87,13,116,1,27,123,19,62,18,2,22],{},"treeitem-magazineArticle.png"],"6":["newspaperArticle","Newspaper Article",[1,2,27,4],[110,90,12,7,6,14,15,10,87,116,13,1,27,123,19,62,18,2,22],{},"treeitem-newspaperArticle.png"],"7":["thesis","Thesis",[1,2],[110,90,69,89,7,14,118,87,116,1,27,123,19,62,18,2,22],{},"treeitem-thesis.png"],"8":["letter","Letter",[1,2,16],[110,90,65,14,87,116,1,27,123,19,62,18,2,22],{},"treeitem-letter.png"],"9":["manuscript","Manuscript",[1,2,4],[110,90,66,7,14,118,87,116,1,27,123,19,62,18,2,22],{},"treeitem-manuscript.png"],"10":["interview","Interview",[6,2,7,4],[110,90,14,64,87,116,1,27,123,19,62,18,2,22],{},"treeitem-interview.png"],"11":["film","Film",[8,2,10,9],[110,90,21,14,122,63,77,87,116,1,27,123,19,62,18,2,22],{},"treeitem-film.png"],"12":["artwork","Artwork",[22,2],[110,90,59,61,14,87,116,123,19,62,18,1,27,2,22],{},"treeitem-artwork.png"],"13":["webpage","Web Page",[1,2,4],[110,90,91,70,14,116,1,27,87,2,22],{},"treeitem-webpage.png"],"14":["attachment","Attachment",[false],[110,27,1],{},"treeitem.png"],"15":["report","Report",[1,2,5,4],[110,90,92,32,28,7,31,14,10,87,116,1,27,123,19,62,18,2,22],{},"treeitem-report.png"],"16":["bill","Bill",[12,2,28],[110,90,93,36,94,15,95,41,40,42,14,87,1,27,116,2,22],{},"treeitem-bill.png"],"17":["case","Case",[1,2,13],[111,90,44,96,117,43,97,98,42,87,116,1,27,2,22],{},"treeitem-case.png"],"18":["hearing","Hearing",[2],[110,90,46,7,8,45,99,10,41,40,42,14,87,116,1,27,2,22],{},"treeitem-hearing.png"],"19":["patent","Patent",[14,15,2],[110,90,7,102,48,120,50,121,10,103,51,52,53,54,87,116,1,27,2,22],{},"treeitem-patent.png"],"20":["statute","Statute",[1,2],[112,90,36,55,101,100,10,15,40,42,87,116,1,27,2,22],{},"treeitem-statute.png"],"21":["email","E-mail",[1,2,16],[113,90,14,116,1,27,87,2,22],{},"treeitem-email.png"],"22":["map","Map",[20,2,5],[110,90,67,68,28,6,7,8,14,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-map.png"],"23":["blogPost","Blog Post",[1,23,2],[110,90,107,70,14,1,27,87,116,2,22],{},"treeitem-blogPost.png"],"24":["instantMessage","Instant Message",[1,2,16],[110,90,14,87,116,1,27,2,22],{},"treeitem-instantMessage.png"],"25":["forumPost","Forum Post",[1,2],[110,90,104,79,14,87,116,1,27,2,22],{},"treeitem-forumPost.png"],"26":["audioRecording","Audio Recording",[17,18,2,19],[110,90,71,28,4,45,7,72,14,77,87,11,116,123,19,62,18,1,27,2,22],{},"treeitem-audioRecording.png"],"27":["presentation","Presentation",[24,2],[110,90,74,14,7,75,1,27,87,116,2,22],{},"treeitem-presentation.png"],"28":["videoRecording","Video Recording",[8,11,2,10,9],[110,90,63,28,4,45,7,76,14,77,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-videoRecording.png"],"29":["tvBroadcast","TV Broadcast",[8,11,2,25,10,9],[110,90,119,105,63,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{},"treeitem-tvBroadcast.png"],"30":["radioBroadcast","Radio Broadcast",[8,11,2,25,10,9],[110,90,119,105,71,7,78,14,77,87,116,1,27,123,19,62,18,2,22],{},"treeitem-radioBroadcast.png"],"31":["podcast","Podcast",[26,2,25],[110,90,28,105,80,77,1,27,87,116,2,22],{},"treeitem-podcast.png"],"32":["computerProgram","Computer Program",[21,2],[110,90,28,81,14,82,7,83,88,11,116,1,2,123,19,62,18,27,22],{},"treeitem-computerProgram.png"],"33":["conferencePaper","Conference Paper",[1,2,3,5,4],[110,90,14,114,84,7,8,4,10,3,87,26,11,116,1,27,123,19,62,18,2,22],{},"treeitem-conferencePaper.png"],"34":["document","Document",[1,2,3,27,4],[110,90,8,14,87,116,1,27,123,19,62,18,2,22],{},"treeitem.png"],"35":["encyclopediaArticle","Encyclopedia Article",[1,2,3,5,4],[110,90,85,3,30,4,45,6,7,8,14,10,11,116,1,27,87,123,19,62,18,2,22],{},"treeitem-encyclopediaArticle.png"],"36":["dictionaryEntry","Dictionary Entry",[1,2,3,5,4],[110,90,86,3,30,4,45,6,7,8,14,10,87,11,116,1,27,123,19,62,18,2,22],{},"treeitem-dictionaryEntry.png"]},"creatorTypes":{"1":["author","Author"],"2":["contributor","Contributor"],"3":["editor","Editor"],"4":["translator","Translator"],"5":["seriesEditor","Series Editor"],"6":["interviewee","Interview With"],"7":["interviewer","Interviewer"],"8":["director","Director"],"9":["scriptwriter","Scriptwriter"],"10":["producer","Producer"],"11":["castMember","Cast Member"],"12":["sponsor","Sponsor"],"13":["counsel","Counsel"],"14":["inventor","Inventor"],"15":["attorneyAgent","Attorney/Agent"],"16":["recipient","Recipient"],"17":["performer","Performer"],"18":["composer","Composer"],"19":["wordsBy","Words By"],"20":["cartographer","Cartographer"],"21":["programmer","Programmer"],"22":["artist","Artist"],"23":["commenter","Commenter"],"24":["presenter","Presenter"],"25":["guest","Guest"],"26":["podcaster","Podcaster"],"27":["reviewedAuthor","Reviewed Author"],"28":["cosponsor","Cosponsor"],"29":["bookAuthor","Book Author"]},"fields":{"1":["url","url",true],"2":["rights","rights",true],"3":["series","series",true],"4":["volume","volume",true],"5":["issue","issue",true],"6":["edition","edition",true],"7":["place","place",true],"8":["publisher","publisher",true],"10":["pages","pages",true],"11":["ISBN","ISBN",true],"12":["publicationTitle","publicationTitle",true],"13":["ISSN","ISSN",true],"14":["date","date",true],"15":["section","section",true],"18":["callNumber","callNumber",true],"19":["archiveLocation","archiveLocation",true],"21":["distributor","distributor",false],"22":["extra","extra",true],"25":["journalAbbreviation","journalAbbreviation",true],"26":["DOI","DOI",true],"27":["accessDate","accessDate",true],"28":["seriesTitle","seriesTitle",true],"29":["seriesText","seriesText",true],"30":["seriesNumber","seriesNumber",true],"31":["institution","institution",false],"32":["reportType","reportType",false],"36":["code","code",true],"40":["session","session",true],"41":["legislativeBody","legislativeBody",true],"42":["history","history",true],"43":["reporter","reporter",true],"44":["court","court",true],"45":["numberOfVolumes","numberOfVolumes",true],"46":["committee","committee",true],"48":["assignee","assignee",true],"50":["patentNumber","patentNumber",false],"51":["priorityNumbers","priorityNumbers",true],"52":["issueDate","issueDate",false],"53":["references","references",true],"54":["legalStatus","legalStatus",true],"55":["codeNumber","codeNumber",true],"59":["artworkMedium","artworkMedium",false],"60":["number","number",true],"61":["artworkSize","artworkSize",true],"62":["libraryCatalog","libraryCatalog",true],"63":["videoRecordingFormat","videoRecordingFormat",false],"64":["interviewMedium","interviewMedium",false],"65":["letterType","letterType",false],"66":["manuscriptType","manuscriptType",false],"67":["mapType","mapType",false],"68":["scale","scale",true],"69":["thesisType","thesisType",false],"70":["websiteType","websiteType",false],"71":["audioRecordingFormat","audioRecordingFormat",false],"72":["label","label",false],"74":["presentationType","presentationType",false],"75":["meetingName","meetingName",true],"76":["studio","studio",false],"77":["runningTime","runningTime",true],"78":["network","network",false],"79":["postType","postType",false],"80":["audioFileType","audioFileType",false],"81":["versionNumber","versionNumber",true],"82":["system","system",true],"83":["company","company",false],"84":["conferenceName","conferenceName",true],"85":["encyclopediaTitle","encyclopediaTitle",false],"86":["dictionaryTitle","dictionaryTitle",false],"87":["language","language",true],"88":["programmingLanguage","programmingLanguage",true],"89":["university","university",false],"90":["abstractNote","abstractNote",true],"91":["websiteTitle","websiteTitle",false],"92":["reportNumber","reportNumber",false],"93":["billNumber","billNumber",false],"94":["codeVolume","codeVolume",false],"95":["codePages","codePages",false],"96":["dateDecided","dateDecided",false],"97":["reporterVolume","reporterVolume",false],"98":["firstPage","firstPage",false],"99":["documentNumber","documentNumber",false],"100":["dateEnacted","dateEnacted",false],"101":["publicLawNumber","publicLawNumber",false],"102":["country","country",true],"103":["applicationNumber","applicationNumber",true],"104":["forumTitle","forumTitle",false],"105":["episodeNumber","episodeNumber",false],"107":["blogTitle","blogTitle",false],"108":["type","type",true],"109":["medium","medium",true],"110":["title","title",true],"111":["caseName","caseName",false],"112":["nameOfAct","nameOfAct",false],"113":["subject","subject",false],"114":["proceedingsTitle","proceedingsTitle",false],"115":["bookTitle","bookTitle",false],"116":["shortTitle","shortTitle",true],"117":["docketNumber","docketNumber",false],"118":["numPages","numPages",true],"119":["programTitle","programTitle",false],"120":["issuingAuthority","issuingAuthority",true],"121":["filingDate","filingDate",true],"122":["genre","genre",false],"123":["archive","archive",true]}} +\ No newline at end of file