/*
***** 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 .
Based on nsChromeExtensionHandler example code by Ed Anuff at
http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol
***** END LICENSE BLOCK *****
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
/** XPCOM files to be loaded for all modes **/
const xpcomFilesAll = [
'zotero',
'date',
'debug',
'error',
'file',
'http',
'mimeTypeHandler',
'openurl',
'ipc',
'progressWindow',
'translation/translate',
'translation/translate_firefox',
'translation/translator',
'translation/tlds',
'utilities',
'isbn',
'utilities_internal',
'utilities_translate'
];
/** XPCOM files to be loaded only for local translation and DB access **/
const xpcomFilesLocal = [
'libraryTreeView',
'collectionTreeView',
'collectionTreeRow',
'annotate',
'api',
'attachments',
'cite',
'cookieSandbox',
'data/library',
'data/libraries',
'data/dataObject',
'data/dataObjects',
'data/dataObjectUtilities',
'data/cachedTypes',
'data/notes',
'data/item',
'data/items',
'data/collection',
'data/collections',
'data/feedItem',
'data/feedItems',
'data/feed',
'data/feeds',
'data/creators',
'data/group',
'data/groups',
'data/itemFields',
'data/relations',
'data/tags',
'db',
'duplicates',
'feedReader',
'fulltext',
'id',
'integration',
'itemTreeView',
'locateManager',
'mime',
'notifier',
'proxy',
'quickCopy',
'report',
'router',
'schema',
'search',
'server',
'style',
'sync',
'sync/syncAPIClient',
'sync/syncEngine',
'sync/syncExceptions',
'sync/syncEventListeners',
'sync/syncFullTextEngine',
'sync/syncLocal',
'sync/syncRunner',
'sync/syncUtilities',
'storage',
'storage/storageEngine',
'storage/storageLocal',
'storage/storageRequest',
'storage/storageResult',
'storage/storageUtilities',
'storage/streamListener',
'storage/zfs',
'storage/webdav',
'syncedSettings',
'timeline',
'uri',
'users',
'translation/translate_item',
'translation/translators',
'server_connector'
];
/** XPCOM files to be loaded only for connector translation and DB access **/
const xpcomFilesConnector = [
'connector/translate_item',
'connector/translator',
'connector/connector',
'connector/connector_firefox',
'connector/cachedTypes',
'connector/repo',
'connector/typeSchemaData'
];
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
var instanceID = (new Date()).getTime();
var isFirstLoadThisSession = true;
var zContext = null;
var zInitOptions = {};
ZoteroContext = function() {}
ZoteroContext.prototype = {
/**
* Convenience method to replicate window.alert()
**/
// TODO: is this still used? if so, move to zotero.js
"alert":function alert(msg){
this.Zotero.debug("alert() is deprecated from Zotero XPCOM");
Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService)
.alert(null, "", msg);
},
/**
* Convenience method to replicate window.confirm()
**/
// TODO: is this still used? if so, move to zotero.js
"confirm":function confirm(msg){
this.Zotero.debug("confirm() is deprecated from Zotero XPCOM");
return Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService)
.confirm(null, "", msg);
},
"Cc":Cc,
"Ci":Ci,
/**
* Convenience method to replicate window.setTimeout()
**/
"setTimeout":function setTimeout(func, ms){
this.Zotero.setTimeout(func, ms);
},
/**
* Switches in or out of connector mode
*/
"switchConnectorMode":function(isConnector) {
if(isConnector !== this.isConnector) {
Services.obs.notifyObservers(zContext.Zotero, "zotero-before-reload", isConnector ? "connector" : "full");
zContext.Zotero.shutdown().then(function() {
// create a new zContext
makeZoteroContext(isConnector);
return zContext.Zotero.init(zInitOptions);
}).done();
}
return zContext;
},
/**
* Shuts down Zotero, calls a callback (that may return a promise),
* then reinitializes Zotero. Returns a promise that is resolved
* when this process completes.
*/
"reinit":function(cb, isConnector, options = {}) {
Services.obs.notifyObservers(zContext.Zotero, "zotero-before-reload", isConnector ? "connector" : "full");
return zContext.Zotero.shutdown().then(function() {
return cb ? cb() : false;
}).finally(function() {
makeZoteroContext(isConnector);
var o = {};
Object.assign(o, zInitOptions);
Object.assign(o, options);
zContext.Zotero.init(o);
});
}
};
/**
* The class from which the Zotero global XPCOM context is constructed
*
* @constructor
* This runs when ZoteroService is first requested to load all applicable scripts and initialize
* Zotero. Calls to other XPCOM components must be in here rather than in top-level code, as other
* components may not have yet been initialized.
*/
function makeZoteroContext(isConnector) {
if(zContext) {
// Swap out old zContext
var oldzContext = zContext;
// Create new zContext
zContext = new ZoteroContext();
// Swap in old Zotero object, so that references don't break, but empty it
zContext.Zotero = oldzContext.Zotero;
for(var key in zContext.Zotero) delete zContext.Zotero[key];
} else {
zContext = new ZoteroContext();
zContext.Zotero = function() {};
}
var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
// Load zotero.js first
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFilesAll[0] + ".js", zContext);
// Load CiteProc into Zotero.CiteProc namespace
zContext.Zotero.CiteProc = {"Zotero":zContext.Zotero};
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/citeproc-prereqs.js", zContext.Zotero.CiteProc);
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/citeproc.js", zContext.Zotero.CiteProc);
// Load XRegExp object into Zotero.XRegExp
const xregexpFiles = [
/**Core functions**/
'xregexp',
/**Addons**/
'addons/build', //adds ability to "build regular expressions using named subpatterns, for readability and pattern reuse"
'addons/matchrecursive', //adds ability to "match recursive constructs using XRegExp pattern strings as left and right delimiters"
/**Unicode support**/
'addons/unicode/unicode-base', //required for all other unicode packages. Adds \p{Letter} category
//'addons/unicode/unicode-blocks', //adds support for all Unicode blocks (e.g. InArabic, InCyrillic_Extended_A, etc.)
'addons/unicode/unicode-categories', //adds support for all Unicode categories (e.g. Punctuation, Lowercase_Letter, etc.)
//'addons/unicode/unicode-properties', //adds Level 1 Unicode properties (e.g. Uppercase, White_Space, etc.)
//'addons/unicode/unicode-scripts' //adds support for all Unicode scripts (e.g. Gujarati, Cyrillic, etc.)
'addons/unicode/unicode-zotero' //adds support for some Unicode categories used in Zotero
];
for (var i=0; i