fx115: Move Zotero object initialization to zotero.mjs

This commit is contained in:
Dan Stillman 2023-11-06 01:26:47 -05:00
parent c0aab70e03
commit 2051f08b4c
19 changed files with 450 additions and 490 deletions

View file

@ -253,7 +253,7 @@ function modify_omni {
cp "$APP_ROOT_DIR/assets/multilocale.txt" res/multilocale.txt cp "$APP_ROOT_DIR/assets/multilocale.txt" res/multilocale.txt
# Use Zotero URL opening in Mozilla dialogs (e.g., app update dialog) # Use Zotero URL opening in Mozilla dialogs (e.g., app update dialog)
replace_line 'function openURL\(aURL\) \{' 'function openURL(aURL) {let {Zotero} = ChromeUtils.import("chrome:\/\/zotero\/content\/include.jsm"); Zotero.launchURL(aURL); if (true) { return; }' chrome/toolkit/content/global/contentAreaUtils.js replace_line 'function openURL\(aURL\) \{' 'function openURL(aURL) {let {Zotero} = ChromeUtils.importESModule("chrome:\/\/zotero\/content\/zotero.mjs"); Zotero.launchURL(aURL); if (true) { return; }' chrome/toolkit/content/global/contentAreaUtils.js
# #
# Modify Add-ons window # Modify Add-ons window

View file

@ -63,9 +63,7 @@ locale zotero zh-TW chrome/locale/zh-TW/zotero/
skin zotero default chrome/skin/default/zotero/ skin zotero default chrome/skin/default/zotero/
component {e4c61080-ec2d-11da-8ad9-0800200c9a66} components/zotero-service.js
component {531828f8-a16c-46be-b9aa-14845c3b010f} components/zotero-service.js component {531828f8-a16c-46be-b9aa-14845c3b010f} components/zotero-service.js
contract @zotero.org/Zotero;1 {e4c61080-ec2d-11da-8ad9-0800200c9a66}
contract @mozilla.org/browser/clh;1 {531828f8-a16c-46be-b9aa-14845c3b010f} contract @mozilla.org/browser/clh;1 {531828f8-a16c-46be-b9aa-14845c3b010f}
category command-line-handler m-zotero @mozilla.org/browser/clh;1 category command-line-handler m-zotero @mozilla.org/browser/clh;1

View file

@ -29,14 +29,9 @@ var { Subprocess } = ChromeUtils.import("resource://gre/modules/Subprocess.jsm")
var { RemoteTranslate } = ChromeUtils.import("chrome://zotero/content/RemoteTranslate.jsm"); var { RemoteTranslate } = ChromeUtils.import("chrome://zotero/content/RemoteTranslate.jsm");
var { ContentDOMReference } = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm"); var { ContentDOMReference } = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm");
var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
import FilePicker from 'zotero/modules/filePicker'; import FilePicker from 'zotero/modules/filePicker';
var Zotero = Components.classes["@zotero.org/Zotero;1"]
// Currently uses only nsISupports
//.getService(Components.interfaces.chnmIZoteroService).
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
// Fix JSON stringify 2028/2029 "bug" // Fix JSON stringify 2028/2029 "bug"
// Borrowed from http://stackoverflow.com/questions/16686687/json-stringify-and-u2028-u2029-check // Borrowed from http://stackoverflow.com/questions/16686687/json-stringify-and-u2028-u2029-check
if (JSON.stringify(["\u2028\u2029"]) !== '["\\u2028\\u2029"]') { if (JSON.stringify(["\u2028\u2029"]) !== '["\\u2028\\u2029"]') {

View file

@ -25,9 +25,8 @@
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(this, { ChromeUtils.defineESModuleGetters(this, {
Services: "resource://gre/modules/Services.jsm", Zotero: "chrome://zotero/content/zotero.mjs",
Zotero: "chrome://zotero/content/include.jsm"
}); });
var EXPORTED_SYMBOLS = ["BlockingObserver"]; var EXPORTED_SYMBOLS = ["BlockingObserver"];

View file

@ -25,10 +25,8 @@
var EXPORTED_SYMBOLS = ["EPUB"]; var EXPORTED_SYMBOLS = ["EPUB"];
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); ChromeUtils.defineESModuleGetters(this, {
Zotero: "chrome://zotero/content/zotero.mjs",
XPCOMUtils.defineLazyModuleGetters(this, {
Zotero: "chrome://zotero/content/include.jsm"
}); });
const ZipReader = Components.Constructor( const ZipReader = Components.Constructor(

View file

@ -35,7 +35,9 @@ XPCOMUtils.defineLazyModuleGetters(this, {
HiddenFrame: "resource://gre/modules/HiddenFrame.jsm", HiddenFrame: "resource://gre/modules/HiddenFrame.jsm",
Services: "resource://gre/modules/Services.jsm", Services: "resource://gre/modules/Services.jsm",
setTimeout: "resource://gre/modules/Timer.jsm", setTimeout: "resource://gre/modules/Timer.jsm",
Zotero: "chrome://zotero/content/include.jsm" });
ChromeUtils.defineESModuleGetters(this, {
Zotero: "chrome://zotero/content/zotero.mjs"
}); });
ChromeUtils.registerWindowActor("PageData", { ChromeUtils.registerWindowActor("PageData", {

View file

@ -36,8 +36,10 @@ ChromeUtils.registerWindowActor("Translation", {
} }
}); });
ChromeUtils.defineESModuleGetters(this, {
Zotero: "chrome://zotero/content/zotero.mjs",
});
XPCOMUtils.defineLazyModuleGetters(this, { XPCOMUtils.defineLazyModuleGetters(this, {
Zotero: "chrome://zotero/content/include.jsm",
TranslationManager: "chrome://zotero/content/actors/TranslationParent.jsm", TranslationManager: "chrome://zotero/content/actors/TranslationParent.jsm",
}); });

View file

@ -1,8 +1,6 @@
var EXPORTED_SYMBOLS = ["TranslationParent", "TranslationManager"]; var EXPORTED_SYMBOLS = ["TranslationParent", "TranslationManager"];
const Zotero = Components.classes['@zotero.org/Zotero;1'] var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
const TranslationManager = new class { const TranslationManager = new class {
_registeredRemoteTranslates = new Map(); _registeredRemoteTranslates = new Map();

View file

@ -24,11 +24,10 @@
windowtype="zotero:search" windowtype="zotero:search"
style="display: flex;"> style="display: flex;">
<script src="include.js"/>
<script> <script>
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
</script> </script>
<script src="include.js"/>
<script src="customElements.js"/> <script src="customElements.js"/>
<script src="advancedSearch.js"/> <script src="advancedSearch.js"/>

View file

@ -25,6 +25,8 @@
'use strict'; 'use strict';
var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
Services.scriptloader.loadSubScript("resource://zotero/require.js", this); Services.scriptloader.loadSubScript("resource://zotero/require.js", this);
Services.scriptloader.loadSubScript("chrome://global/content/customElements.js", this); Services.scriptloader.loadSubScript("chrome://global/content/customElements.js", this);

View file

@ -17,9 +17,10 @@
</linkset> </linkset>
<script> <script>
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/customElements.js", this); Services.scriptloader.loadSubScript("chrome://zotero/content/customElements.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/fileInterface.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/import/importWizard.js", this);
</script> </script>
<wizard id="import-wizard" class="import-wizard" width="600" height="400"> <wizard id="import-wizard" class="import-wizard" width="600" height="400">
@ -114,7 +115,4 @@
</div> </div>
</wizardpage> </wizardpage>
</wizard> </wizard>
<script src="../fileInterface.js"/>
<script src="./importWizard.js" />
</window> </window>

View file

@ -1,9 +1,4 @@
/* global Components:false */ var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
/* eslint-disable no-unused-vars */
var Zotero = Components.classes['@zotero.org/Zotero;1']
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
// Components.utils.import('resource://zotero/require.js'); // Components.utils.import('resource://zotero/require.js');
// Not using Cu.import here since we don't want the require module to be cached // Not using Cu.import here since we don't want the require module to be cached
@ -22,5 +17,5 @@ if (typeof require == "undefined") {
} }
if (winName) { if (winName) {
window.name = winName; window.name = winName;
} }

View file

@ -1,5 +0,0 @@
var EXPORTED_SYMBOLS = ["Zotero"];
var Zotero = Components.classes['@zotero.org/Zotero;1']
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;

View file

@ -8,7 +8,7 @@
/* import-globals-from ../../../content/contentAreaUtils.js */ /* import-globals-from ../../../content/contentAreaUtils.js */
/* globals DownloadUtils, Services, AUSTLMY */ /* globals DownloadUtils, Services, AUSTLMY */
const { Zotero } = ChromeUtils.import("chrome://zotero/content/include.jsm"); const { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
const { DownloadUtils } = ChromeUtils.import( const { DownloadUtils } = ChromeUtils.import(
"resource://gre/modules/DownloadUtils.jsm" "resource://gre/modules/DownloadUtils.jsm"

View file

@ -26,8 +26,6 @@
***** END LICENSE BLOCK ***** ***** END LICENSE BLOCK *****
*/ */
var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(globalThis, { XPCOMUtils.defineLazyModuleGetters(globalThis, {
Subprocess: "resource://gre/modules/Subprocess.jsm", Subprocess: "resource://gre/modules/Subprocess.jsm",
}); });

View file

@ -32,6 +32,7 @@ Components.classes["@mozilla.org/net/osfileconstantsservice;1"]
.getService(Components.interfaces.nsIOSFileConstantsService) .getService(Components.interfaces.nsIOSFileConstantsService)
.init(); .init();
const { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetters(globalThis, { XPCOMUtils.defineLazyModuleGetters(globalThis, {
AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm", AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
}); });

View file

@ -0,0 +1,425 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2023 Corporation for Digital Scholarship
Vienna, Virginia, USA
https://www.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 Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
/** XPCOM files to be loaded for all modes **/
const xpcomFilesAll = [
'zotero',
'intl',
'prefs',
'dataDirectory',
'debug',
'error',
'utilities/date',
'utilities/utilities',
'utilities/utilities_item',
'utilities/openurl',
'utilities/xregexp-all',
'utilities/xregexp-unicode-zotero',
'utilities_internal',
'translate/src/utilities_translate',
'file',
'http',
'mimeTypeHandler',
'pdfWorker/manager',
'ipc',
'prompt',
'profile',
'progressWindow',
'proxy',
'translate/src/translation/translate',
'translate/src/translator',
'translate/src/tlds',
'translation/translate_firefox',
'isbn',
'preferencePanes',
'uiProperties',
];
/** XPCOM files to be loaded only for local translation and DB access **/
const xpcomFilesLocal = [
'collectionTreeRow',
'annotations',
'api',
'attachments',
'browserDownload',
'cite',
'citeprocRsBridge',
'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/search',
'data/searchConditions',
'data/searches',
'data/tags',
'db',
'dictionaries',
'duplicates',
'editorInstance',
'feedReader',
'fileDragDataProvider',
'fulltext',
'id',
'integration',
'itemTreeManager',
'locale',
'locateManager',
'mime',
'notifier',
'fileHandlers',
'plugins',
'reader',
'progressQueue',
'progressQueueDialog',
'quickCopy',
'recognizeDocument',
'report',
'retractions',
'router',
'schema',
'server',
'server_integration',
'session',
'streamer',
'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',
'connector/httpIntegrationClient',
'connector/server_connector',
'connector/server_connectorIntegration',
];
Components.utils.import("resource://gre/modules/ComponentUtils.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const { CommandLineOptions } = ChromeUtils.importESModule("chrome://zotero/content/modules/commandLineOptions.mjs");
var instanceID = (new Date()).getTime();
var isFirstLoadThisSession = true;
var zContext = null;
var initCallbacks = [];
// Components.utils.import('resource://zotero/require.js');
// Not using Cu.import here since we don't want the require module to be cached
// for includes within ZoteroPane or other code, where we want the window instance available to modules.
Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript('resource://zotero/require.js');
var ZoteroContext = function() {}
ZoteroContext.prototype = {
require,
/**
* 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, options = {}) {
Services.obs.notifyObservers(zContext.Zotero, "zotero-before-reload");
return zContext.Zotero.shutdown().then(function() {
return cb ? cb() : false;
}).finally(function() {
makeZoteroContext();
var o = {};
Object.assign(o, CommandLineOptions);
Object.assign(o, options);
return zContext.Zotero.init(o);
});
}
};
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(ZoteroContext.prototype, {
setTimeout: "resource://gre/modules/Timer.jsm",
clearTimeout: "resource://gre/modules/Timer.jsm",
setInterval: "resource://gre/modules/Timer.jsm",
clearInterval: "resource://gre/modules/Timer.jsm",
requestIdleCallback: "resource://gre/modules/Timer.jsm",
cancelIdleCallback: "resource://gre/modules/Timer.jsm",
});
/**
* 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() {
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, 'utf-8');
// Load CiteProc into Zotero.CiteProc namespace
zContext.Zotero.CiteProc = {"Zotero":zContext.Zotero};
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/citeproc.js", zContext.Zotero.CiteProc, 'utf-8');
// Load XRegExp object into Zotero.XRegExp
const xregexpFiles = [
/**Core functions**/
'xregexp-all',
'xregexp-unicode-zotero' //adds support for some Unicode categories used in Zotero
];
for (var i=0; i<xregexpFiles.length; i++) {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/utilities/" + xregexpFiles[i] + ".js", zContext, 'utf-8');
}
// Load remaining xpcomFiles
for (var i=1; i<xpcomFilesAll.length; i++) {
try {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFilesAll[i] + ".js", zContext, 'utf-8');
}
catch (e) {
Components.utils.reportError("Error loading " + xpcomFilesAll[i] + ".js");
throw (e);
}
}
// Load xpcomFiles for specific mode
for (let xpcomFile of xpcomFilesLocal) {
try {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFile + ".js", zContext, "utf-8");
}
catch (e) {
dump("Error loading " + xpcomFile + ".js\n\n");
dump(e + "\n\n");
Components.utils.reportError("Error loading " + xpcomFile + ".js");
throw (e);
}
}
// Load RDF files into Zotero.RDF.AJAW namespace (easier than modifying all of the references)
const rdfXpcomFiles = [
'rdf/init',
'rdf/uri',
'rdf/term',
'rdf/identity',
'rdf/n3parser',
'rdf/rdfparser',
'rdf/serialize'
];
zContext.Zotero.RDF = {Zotero:zContext.Zotero};
for (var i=0; i<rdfXpcomFiles.length; i++) {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/translate/src/" + rdfXpcomFiles[i] + ".js", zContext.Zotero.RDF, 'utf-8');
}
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/standalone.js", zContext);
// add connector-related properties
zContext.Zotero.instanceID = instanceID;
zContext.Zotero.__defineGetter__("isFirstLoadThisSession", function() { return isFirstLoadThisSession; });
};
/**
* The class representing the Zotero service, and affiliated XPCOM goop
*/
try {
var start = Date.now();
if(isFirstLoadThisSession) {
makeZoteroContext(false);
zContext.Zotero.init(CommandLineOptions)
.catch(function (e) {
dump(e + "\n\n");
Components.utils.reportError(e);
if (!zContext.Zotero.startupError) {
zContext.Zotero.startupError = e.stack || e;
}
})
.then(async function () {
if (zContext.Zotero.startupErrorHandler || zContext.Zotero.startupError) {
if (zContext.Zotero.startupErrorHandler) {
await zContext.Zotero.startupErrorHandler();
}
else if (zContext.Zotero.startupError) {
// Try to repair the DB on the next startup, in case it helps resolve
// the error
try {
zContext.Zotero.Schema.setIntegrityCheckRequired(true);
}
catch (e) {}
try {
zContext.Zotero.startupError =
zContext.Zotero.Utilities.Internal.filterStack(
zContext.Zotero.startupError
);
}
catch (e) {}
let ps = Services.prompt;
let buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_IS_STRING);
// Get the stringbundle manually
let errorStr = "Error";
let quitStr = "Quit";
let checkForUpdateStr = "Check for Update";
try {
let src = 'chrome://zotero/locale/zotero.properties';
let stringBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
let stringBundle = stringBundleService.createBundle(src);
errorStr = stringBundle.GetStringFromName('general.error');
checkForUpdateStr = stringBundle.GetStringFromName('general.checkForUpdate');
quitStr = stringBundle.GetStringFromName('general.quit');
}
catch (e) {}
let index = ps.confirmEx(
null,
errorStr,
zContext.Zotero.startupError,
buttonFlags,
checkForUpdateStr,
quitStr,
null,
null,
{}
);
if (index == 0) {
Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher)
.openWindow(null, 'chrome://mozapps/content/update/updates.xhtml',
'updateChecker', 'chrome,centerscreen,modal', null);
}
}
zContext.Zotero.Utilities.Internal.quitZotero();
}
});
let cb;
while (cb = initCallbacks.shift()) {
cb(zContext.Zotero);
}
}
else {
zContext.Zotero.debug("Already initialized");
}
//this.wrappedJSObject = zContext.Zotero;
}
catch (e) {
var msg = e instanceof Error
? e.name + ': ' + e.message + '\n' + e.fileName + ':' + e.lineNumber + '\n' + e.stack
: '' + e;
dump(msg + '\n');
Components.utils.reportError(e);
throw e;
}
function addInitCallback(callback) {
if (zContext && zContext.Zotero) {
callback(zContext.Zotero);
}
else {
initCallbacks.push(callback);
}
}
/**
* Determine whether Zotero Standalone is running
*/
function isStandalone() {
return true;
}
function getOS() {
return Services.appinfo.OS;
}
function isMac() {
return getOS() == "Darwin";
}
function isWin() {
return getOS() == "WINNT";
}
function isLinux() {
return getOS() == "Linux";
}
export const Zotero = zContext.Zotero;

View file

@ -60,7 +60,7 @@
<script> <script>
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
Services.scriptloader.loadSubScript("chrome://zotero/content/include.js", this); var { Zotero } = ChromeUtils.importESModule("chrome://zotero/content/zotero.mjs");
Services.scriptloader.loadSubScript("resource://zotero/require.js", this); Services.scriptloader.loadSubScript("resource://zotero/require.js", this);
Services.scriptloader.loadSubScript("chrome://zotero/content/standalone/standalone.js", this); Services.scriptloader.loadSubScript("chrome://zotero/content/standalone/standalone.js", this);

View file

@ -27,451 +27,6 @@
***** END LICENSE BLOCK ***** ***** END LICENSE BLOCK *****
*/ */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
/** XPCOM files to be loaded for all modes **/
const xpcomFilesAll = [
'zotero',
'intl',
'prefs',
'dataDirectory',
'debug',
'error',
'utilities/date',
'utilities/utilities',
'utilities/utilities_item',
'utilities/openurl',
'utilities/xregexp-all',
'utilities/xregexp-unicode-zotero',
'utilities_internal',
'translate/src/utilities_translate',
'file',
'http',
'mimeTypeHandler',
'pdfWorker/manager',
'ipc',
'prompt',
'profile',
'progressWindow',
'proxy',
'translate/src/translation/translate',
'translate/src/translator',
'translate/src/tlds',
'translation/translate_firefox',
'isbn',
'preferencePanes',
'uiProperties',
];
/** XPCOM files to be loaded only for local translation and DB access **/
const xpcomFilesLocal = [
'collectionTreeRow',
'annotations',
'api',
'attachments',
'browserDownload',
'cite',
'citeprocRsBridge',
'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/search',
'data/searchConditions',
'data/searches',
'data/tags',
'db',
'dictionaries',
'duplicates',
'editorInstance',
'feedReader',
'fileDragDataProvider',
'fulltext',
'id',
'integration',
'locale',
'locateManager',
'mime',
'notifier',
'fileHandlers',
'plugins',
'reader',
'progressQueue',
'progressQueueDialog',
'quickCopy',
'recognizeDocument',
'report',
'retractions',
'router',
'schema',
'server',
'server_integration',
'session',
'streamer',
'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',
'connector/httpIntegrationClient',
'connector/server_connector',
'connector/server_connectorIntegration',
'itemTreeManager',
];
Components.utils.import("resource://gre/modules/ComponentUtils.jsm");
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var instanceID = (new Date()).getTime();
var isFirstLoadThisSession = true;
var zContext = null;
var initCallbacks = [];
var zInitOptions = {};
// Components.utils.import('resource://zotero/require.js');
// Not using Cu.import here since we don't want the require module to be cached
// for includes within ZoteroPane or other code, where we want the window instance available to modules.
Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript('resource://zotero/require.js');
var ZoteroContext = function() {}
ZoteroContext.prototype = {
require,
/**
* 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,
/**
* 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);
return zContext.Zotero.init(o);
});
}
};
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(ZoteroContext.prototype, {
setTimeout: "resource://gre/modules/Timer.jsm",
clearTimeout: "resource://gre/modules/Timer.jsm",
setInterval: "resource://gre/modules/Timer.jsm",
clearInterval: "resource://gre/modules/Timer.jsm",
requestIdleCallback: "resource://gre/modules/Timer.jsm",
cancelIdleCallback: "resource://gre/modules/Timer.jsm",
});
/**
* 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, 'utf-8');
// Load CiteProc into Zotero.CiteProc namespace
zContext.Zotero.CiteProc = {"Zotero":zContext.Zotero};
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/citeproc.js", zContext.Zotero.CiteProc, 'utf-8');
// Load XRegExp object into Zotero.XRegExp
const xregexpFiles = [
/**Core functions**/
'xregexp-all',
'xregexp-unicode-zotero' //adds support for some Unicode categories used in Zotero
];
for (var i=0; i<xregexpFiles.length; i++) {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/utilities/" + xregexpFiles[i] + ".js", zContext, 'utf-8');
}
// Load remaining xpcomFiles
for (var i=1; i<xpcomFilesAll.length; i++) {
try {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFilesAll[i] + ".js", zContext, 'utf-8');
}
catch (e) {
Components.utils.reportError("Error loading " + xpcomFilesAll[i] + ".js", zContext);
throw (e);
}
}
// Load xpcomFiles for specific mode
for (let xpcomFile of (isConnector ? xpcomFilesConnector : xpcomFilesLocal)) {
try {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFile + ".js", zContext, "utf-8");
}
catch (e) {
dump("Error loading " + xpcomFile + ".js\n\n");
dump(e + "\n\n");
Components.utils.reportError("Error loading " + xpcomFile + ".js");
throw (e);
}
}
// Load RDF files into Zotero.RDF.AJAW namespace (easier than modifying all of the references)
const rdfXpcomFiles = [
'rdf/init',
'rdf/uri',
'rdf/term',
'rdf/identity',
'rdf/n3parser',
'rdf/rdfparser',
'rdf/serialize'
];
zContext.Zotero.RDF = {Zotero:zContext.Zotero};
for (var i=0; i<rdfXpcomFiles.length; i++) {
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/translate/src/" + rdfXpcomFiles[i] + ".js", zContext.Zotero.RDF, 'utf-8');
}
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/standalone.js", zContext);
// add connector-related properties
zContext.Zotero.isConnector = isConnector;
zContext.Zotero.instanceID = instanceID;
zContext.Zotero.__defineGetter__("isFirstLoadThisSession", function() { return isFirstLoadThisSession; });
};
/**
* The class representing the Zotero service, and affiliated XPCOM goop
*/
function ZoteroService() {
try {
var start = Date.now();
if(isFirstLoadThisSession) {
makeZoteroContext(false);
zContext.Zotero.init(zInitOptions)
.catch(function (e) {
dump(e + "\n\n");
Components.utils.reportError(e);
if (!zContext.Zotero.startupError) {
zContext.Zotero.startupError = e.stack || e;
}
})
.then(async function () {
if (zContext.Zotero.startupErrorHandler || zContext.Zotero.startupError) {
if (zContext.Zotero.startupErrorHandler) {
await zContext.Zotero.startupErrorHandler();
}
else if (zContext.Zotero.startupError) {
// Try to repair the DB on the next startup, in case it helps resolve
// the error
try {
zContext.Zotero.Schema.setIntegrityCheckRequired(true);
}
catch (e) {}
try {
zContext.Zotero.startupError =
zContext.Zotero.Utilities.Internal.filterStack(
zContext.Zotero.startupError
);
}
catch (e) {}
let ps = Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService);
let buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING)
+ (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_IS_STRING);
// Get the stringbundle manually
let errorStr = "Error";
let quitStr = "Quit";
let checkForUpdateStr = "Check for Update";
try {
let src = 'chrome://zotero/locale/zotero.properties';
let stringBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
let stringBundle = stringBundleService.createBundle(src);
errorStr = stringBundle.GetStringFromName('general.error');
checkForUpdateStr = stringBundle.GetStringFromName('general.checkForUpdate');
quitStr = stringBundle.GetStringFromName('general.quit');
}
catch (e) {}
let index = ps.confirmEx(
null,
errorStr,
zContext.Zotero.startupError,
buttonFlags,
checkForUpdateStr,
quitStr,
null,
null,
{}
);
if (index == 0) {
Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher)
.openWindow(null, 'chrome://zotero/content/update/updates.xhtml',
'updateChecker', 'chrome,centerscreen,modal', null);
}
}
zContext.Zotero.Utilities.Internal.quitZotero();
}
});
let cb;
while (cb = initCallbacks.shift()) {
cb(zContext.Zotero);
}
}
else {
zContext.Zotero.debug("Already initialized");
}
this.wrappedJSObject = zContext.Zotero;
} catch(e) {
var msg = e instanceof Error
? e.name + ': ' + e.message + '\n' + e.fileName + ':' + e.lineNumber + '\n' + e.stack
: '' + e;
dump(msg + '\n');
Components.utils.reportError(e);
throw e;
}
}
ZoteroService.prototype = {
classID: Components.ID('{e4c61080-ec2d-11da-8ad9-0800200c9a66}'),
QueryInterface: ChromeUtils.generateQI([])
}
function addInitCallback(callback) {
if (zContext && zContext.Zotero) {
callback(zContext.Zotero);
}
else {
initCallbacks.push(callback);
}
}
/**
* Determine whether Zotero Standalone is running
*/
function isStandalone() {
return true;
}
function getOS() {
return Services.appinfo.OS;
}
function isMac() {
return getOS() == "Darwin";
}
function isWin() {
return getOS() == "WINNT";
}
function isLinux() {
return getOS() == "Linux";
}
/** /**
* The class representing the Zotero command line handler * The class representing the Zotero command line handler
*/ */