diff --git a/chrome/content/zotero/tools/build_typeSchemaData.html b/chrome/content/zotero/tools/build_typeSchemaData.html
new file mode 100644
index 0000000000..9ef4f169b3
--- /dev/null
+++ b/chrome/content/zotero/tools/build_typeSchemaData.html
@@ -0,0 +1,90 @@
+
+
+ Build schemaData.js
+
+
+This script builds schemaData.js, which contains Zotero schema information for the connector.
+
+
+
+
+
diff --git a/chrome/content/zotero/xpcom/connector/cachedTypes.js b/chrome/content/zotero/xpcom/connector/cachedTypes.js
deleted file mode 100644
index 7cc1c12419..0000000000
--- a/chrome/content/zotero/xpcom/connector/cachedTypes.js
+++ /dev/null
@@ -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 .
-
- ***** 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.
-
- ***** 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 : "");
- }
- }
- } 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.
-
- ***** 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
deleted file mode 100644
index b2560ab177..0000000000
--- a/chrome/content/zotero/xpcom/connector/repo.js
+++ /dev/null
@@ -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 .
-
- ***** 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
deleted file mode 100644
index 9aeeadb1b6..0000000000
--- a/chrome/content/zotero/xpcom/connector/translate_item.js
+++ /dev/null
@@ -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 .
-
- ***** END LICENSE BLOCK *****
-*/
-
-/**
- * Save translator items.
- *
- * @constructor
- * @param {Object} options
- * libraryID - ID of library in which items should be saved
- * collections - New collections to create (used during Import translation
- * attachmentMode - One of Zotero.Translate.ItemSaver.ATTACHMENT_* specifying how attachments should be saved
- * forceTagType - Force tags to specified tag type
- * cookieSandbox - Cookie sandbox for attachment requests
- * proxy - A proxy to deproxify item URLs
- * baseURI - URI to which attachment paths should be relative
- *
- */
-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@,;:\\"\/\[\]?={} ]+\/[^\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
- Chris G Jones
- Shaon Barman
- Vivien Nicolas <21@vingtetun.org>
- Justin D'Arcangelo
- Yury Delendik
- Kalervo Kujala
- Adil Allawi <@ironymark>
- Jakob Miland
- Artur Adib
- Brendan Dahl
- David Quintana
-
- 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
deleted file mode 100644
index ff050acd8b..0000000000
--- a/chrome/content/zotero/xpcom/connector/translator.js
+++ /dev/null
@@ -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 .
-
- ***** 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 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} - 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 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} - 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
deleted file mode 100644
index 74e6bbaff9..0000000000
--- a/chrome/content/zotero/xpcom/connector/typeSchemaData.js
+++ /dev/null
@@ -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
new file mode 100644
index 0000000000..1aa28b02e8
--- /dev/null
+++ 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