2010-07-06 09:02:35 +00:00
|
|
|
/*
|
|
|
|
***** BEGIN LICENSE BLOCK *****
|
|
|
|
|
2010-12-26 19:05:52 +00:00
|
|
|
Copyright © 2009 Center for History and New Media
|
2010-07-06 09:02:35 +00:00
|
|
|
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
|
2011-05-18 18:34:22 +00:00
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
2010-07-06 09:02:35 +00:00
|
|
|
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
|
2011-05-18 18:34:22 +00:00
|
|
|
GNU Affero General Public License for more details.
|
2010-07-06 09:02:35 +00:00
|
|
|
|
2011-05-18 18:34:22 +00:00
|
|
|
You should have received a copy of the GNU Affero General Public License
|
2010-07-06 09:02:35 +00:00
|
|
|
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
|
|
Based on nsChromeExtensionHandler example code by Ed Anuff at
|
|
|
|
http://kb.mozillazine.org/Dev_:_Extending_the_Chrome_Protocol
|
|
|
|
|
|
|
|
***** END LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2006-05-27 00:20:27 +00:00
|
|
|
const Cc = Components.classes;
|
|
|
|
const Ci = Components.interfaces;
|
2018-09-11 05:23:15 +00:00
|
|
|
const Cr = Components.results;
|
|
|
|
const Cu = Components.utils;
|
2006-05-27 00:20:27 +00:00
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
/** XPCOM files to be loaded for all modes **/
|
|
|
|
const xpcomFilesAll = [
|
2008-08-13 06:38:47 +00:00
|
|
|
'zotero',
|
2018-07-28 16:01:46 +00:00
|
|
|
'intl',
|
2018-07-11 12:53:46 +00:00
|
|
|
'prefs',
|
2016-11-27 03:41:26 +00:00
|
|
|
'dataDirectory',
|
2011-06-14 00:36:21 +00:00
|
|
|
'debug',
|
|
|
|
'error',
|
2021-07-26 10:14:56 +00:00
|
|
|
'utilities/date',
|
|
|
|
'utilities/utilities',
|
|
|
|
'utilities/utilities_item',
|
|
|
|
'utilities/openurl',
|
|
|
|
'utilities/xregexp-all',
|
|
|
|
'utilities/xregexp-unicode-zotero',
|
2018-08-06 09:24:17 +00:00
|
|
|
'utilities_internal',
|
2021-07-26 10:14:56 +00:00
|
|
|
'translate/src/utilities_translate',
|
2011-06-14 00:36:21 +00:00
|
|
|
'file',
|
|
|
|
'http',
|
|
|
|
'mimeTypeHandler',
|
2020-09-21 11:33:11 +00:00
|
|
|
'pdfWorker/manager',
|
2011-06-14 00:36:21 +00:00
|
|
|
'ipc',
|
2022-12-14 14:20:04 +00:00
|
|
|
'prompt',
|
2016-11-27 03:41:26 +00:00
|
|
|
'profile',
|
2011-06-14 00:36:21 +00:00
|
|
|
'progressWindow',
|
2016-12-12 12:29:59 +00:00
|
|
|
'proxy',
|
2021-07-26 10:14:56 +00:00
|
|
|
'translate/src/translation/translate',
|
|
|
|
'translate/src/translator',
|
|
|
|
'translate/src/tlds',
|
2011-06-14 00:36:21 +00:00
|
|
|
'translation/translate_firefox',
|
2015-02-19 08:25:15 +00:00
|
|
|
'isbn',
|
2022-08-10 22:26:23 +00:00
|
|
|
'preferencePanes',
|
2011-06-14 00:36:21 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
/** XPCOM files to be loaded only for local translation and DB access **/
|
|
|
|
const xpcomFilesLocal = [
|
2015-11-03 22:06:18 +00:00
|
|
|
'collectionTreeRow',
|
2020-06-20 05:29:32 +00:00
|
|
|
'annotations',
|
Update zotero:// extensions (report, timeline, etc.) for async DB, and more
- Protocol handler extensions can now handle promises and can also make
data available as it's ready instead of all at once (e.g., reports now
output one entry at a time)
- zotero:// URL syntaxes are now more consistent and closer to the web
API (old URLs should work, but some may currently be broken)
Also:
- Code to generate server API, currently available for testing via
zotero://data URLs but eventually moving to HTTP -- zotero://data URLs match
web API URLs, with a different prefix for the personal library (/library vs.
/users/12345)
- Miscellaneous fixes to data objects
Under the hood:
- Extensions now return an AsyncChannel, which is an nsIChannel implementation
that takes a promise-yielding generator that returns a string,
nsIAsyncInputStream, or file that will be used for the channel's data
- New function Zotero.Utilities.Internal.getAsyncInputStream() takes a
generator that yields either promises or strings and returns an async input
stream filled with the yielded strings
- Zotero.Router parsers URLs and extract parameters
- Zotero.Item.toResponseJSON()
2014-09-08 20:51:05 +00:00
|
|
|
'api',
|
2008-08-13 06:38:47 +00:00
|
|
|
'attachments',
|
2010-05-30 11:25:25 +00:00
|
|
|
'cite',
|
2021-12-15 22:28:41 +00:00
|
|
|
'citeprocRsBridge',
|
2011-07-19 03:52:02 +00:00
|
|
|
'cookieSandbox',
|
2015-06-02 04:29:40 +00:00
|
|
|
'data/library',
|
|
|
|
'data/libraries',
|
Async DB megacommit
Promise-based rewrite of most of the codebase, with asynchronous database and file access -- see https://github.com/zotero/zotero/issues/518 for details.
WARNING: This includes backwards-incompatible schema changes.
An incomplete list of other changes:
- Schema overhaul
- Replace main tables with new versions with updated schema
- Enable real foreign key support and remove previous triggers
- Don't use NULLs for local libraryID, which broke the UNIQUE index
preventing object key duplication. All code (Zotero and third-party)
using NULL for the local library will need to be updated to use 0
instead (already done for Zotero code)
- Add 'compatibility' DB version that can be incremented manually to break DB
compatibility with previous versions. 'userdata' upgrades will no longer
automatically break compatibility.
- Demote creators and tags from first-class objects to item properties
- New API syncing properties
- 'synced'/'version' properties to data objects
- 'etag' to groups
- 'version' to libraries
- Create Zotero.DataObject that other objects inherit from
- Consolidate data object loading into Zotero.DataObjects
- Change object reloading so that only the loaded and changed parts of objects are reloaded, instead of reloading all data from the database (with some exceptions, including item primary data)
- Items and collections now have .parentItem and .parentKey properties, replacing item.getSource() and item.getSourceKey()
- New function Zotero.serial(fn), to wrap an async function such that all calls are run serially
- New function Zotero.Utilities.Internal.forEachChunkAsync(arr, chunkSize, func)
- Add tag selector loading message
- Various API and name changes, since everything was breaking anyway
Known broken things:
- Syncing (will be completely rewritten for API syncing)
- Translation architecture (needs promise-based rewrite)
- Duplicates view
- DB integrity check (from schema changes)
- Dragging (may be difficult to fix)
Lots of other big and little things are certainly broken, particularly with the UI, which can be affected by async code in all sorts of subtle ways.
2014-08-06 21:38:05 +00:00
|
|
|
'data/dataObject',
|
2008-08-13 06:38:47 +00:00
|
|
|
'data/dataObjects',
|
2014-08-06 21:38:04 +00:00
|
|
|
'data/dataObjectUtilities',
|
2008-08-13 06:38:47 +00:00
|
|
|
'data/cachedTypes',
|
Async DB megacommit
Promise-based rewrite of most of the codebase, with asynchronous database and file access -- see https://github.com/zotero/zotero/issues/518 for details.
WARNING: This includes backwards-incompatible schema changes.
An incomplete list of other changes:
- Schema overhaul
- Replace main tables with new versions with updated schema
- Enable real foreign key support and remove previous triggers
- Don't use NULLs for local libraryID, which broke the UNIQUE index
preventing object key duplication. All code (Zotero and third-party)
using NULL for the local library will need to be updated to use 0
instead (already done for Zotero code)
- Add 'compatibility' DB version that can be incremented manually to break DB
compatibility with previous versions. 'userdata' upgrades will no longer
automatically break compatibility.
- Demote creators and tags from first-class objects to item properties
- New API syncing properties
- 'synced'/'version' properties to data objects
- 'etag' to groups
- 'version' to libraries
- Create Zotero.DataObject that other objects inherit from
- Consolidate data object loading into Zotero.DataObjects
- Change object reloading so that only the loaded and changed parts of objects are reloaded, instead of reloading all data from the database (with some exceptions, including item primary data)
- Items and collections now have .parentItem and .parentKey properties, replacing item.getSource() and item.getSourceKey()
- New function Zotero.serial(fn), to wrap an async function such that all calls are run serially
- New function Zotero.Utilities.Internal.forEachChunkAsync(arr, chunkSize, func)
- Add tag selector loading message
- Various API and name changes, since everything was breaking anyway
Known broken things:
- Syncing (will be completely rewritten for API syncing)
- Translation architecture (needs promise-based rewrite)
- Duplicates view
- DB integrity check (from schema changes)
- Dragging (may be difficult to fix)
Lots of other big and little things are certainly broken, particularly with the UI, which can be affected by async code in all sorts of subtle ways.
2014-08-06 21:38:05 +00:00
|
|
|
'data/notes',
|
2008-08-13 06:38:47 +00:00
|
|
|
'data/item',
|
|
|
|
'data/items',
|
|
|
|
'data/collection',
|
|
|
|
'data/collections',
|
2015-06-02 04:29:40 +00:00
|
|
|
'data/feedItem',
|
|
|
|
'data/feedItems',
|
|
|
|
'data/feed',
|
|
|
|
'data/feeds',
|
2008-08-13 06:38:47 +00:00
|
|
|
'data/creators',
|
2.0b3 megacommit
- Support for group libraries
- General support for multiple libraries of different types
- Streamlined sync support
- Using solely libraryID and key rather than itemID, and removed all itemID-changing code
- Combined two requests for increased performance and decreased server load
- Added warning on user account change
- Provide explicit error message on SSL failure
- Removed snapshot and link toolbar buttons and changed browser context menu options and drags to create parent items + snapshots
- Closes #786, Add numPages field
- Fixes #1063, Duplicate item with tags broken in Sync Preview
- Added better purging of deleted tags
- Added local user key before first sync
- Add clientDateModified to all objects for more flexibility in syncing
- Added new triples-based Relation object type, currently used to store links between items copied between local and group libraries
- Updated zotero.org translator for groups
- Additional trigger-based consistency checks
- Fixed broken URL drag in Firefox 3.5
- Disabled zeroconf menu option (no longer functional)
Developer-specific changes:
- Overhauled data layer
- Data object constructors no longer take arguments (return to 1.0-like API)
- Existing objects can be retrieved by setting id or library/key properties
- id/library/key must be set for new objects before other fields
- New methods:
- ZoteroPane.getSelectedLibraryID()
- ZoteroPane.getSelectedGroup(asID)
- ZoteroPane.addItemFromDocument(doc, itemType, saveSnapshot)
- ZoteroPane.addItemFromURL(url, itemType)
- ZoteroPane.canEdit()
- Zotero.CollectionTreeView.selectLibrary(libraryID)
- New Zotero.URI methods
- Changed methods
- Many data object methods now take a libraryID
- ZoteroPane.addAttachmentFromPage(link, itemID)
- Removed saveItem and saveAttachments parameters from Zotero.Translate constructor
- translate() now takes a libraryID, null for local library, or false to not save items (previously on constructor)
- saveAttachments is now a translate() parameter
- Zotero.flattenArguments() better handles passed objects
- Zotero.File.getFileHash() (not currently used)
2009-05-14 18:23:40 +00:00
|
|
|
'data/group',
|
|
|
|
'data/groups',
|
2008-08-13 06:38:47 +00:00
|
|
|
'data/itemFields',
|
2.0b3 megacommit
- Support for group libraries
- General support for multiple libraries of different types
- Streamlined sync support
- Using solely libraryID and key rather than itemID, and removed all itemID-changing code
- Combined two requests for increased performance and decreased server load
- Added warning on user account change
- Provide explicit error message on SSL failure
- Removed snapshot and link toolbar buttons and changed browser context menu options and drags to create parent items + snapshots
- Closes #786, Add numPages field
- Fixes #1063, Duplicate item with tags broken in Sync Preview
- Added better purging of deleted tags
- Added local user key before first sync
- Add clientDateModified to all objects for more flexibility in syncing
- Added new triples-based Relation object type, currently used to store links between items copied between local and group libraries
- Updated zotero.org translator for groups
- Additional trigger-based consistency checks
- Fixed broken URL drag in Firefox 3.5
- Disabled zeroconf menu option (no longer functional)
Developer-specific changes:
- Overhauled data layer
- Data object constructors no longer take arguments (return to 1.0-like API)
- Existing objects can be retrieved by setting id or library/key properties
- id/library/key must be set for new objects before other fields
- New methods:
- ZoteroPane.getSelectedLibraryID()
- ZoteroPane.getSelectedGroup(asID)
- ZoteroPane.addItemFromDocument(doc, itemType, saveSnapshot)
- ZoteroPane.addItemFromURL(url, itemType)
- ZoteroPane.canEdit()
- Zotero.CollectionTreeView.selectLibrary(libraryID)
- New Zotero.URI methods
- Changed methods
- Many data object methods now take a libraryID
- ZoteroPane.addAttachmentFromPage(link, itemID)
- Removed saveItem and saveAttachments parameters from Zotero.Translate constructor
- translate() now takes a libraryID, null for local library, or false to not save items (previously on constructor)
- saveAttachments is now a translate() parameter
- Zotero.flattenArguments() better handles passed objects
- Zotero.File.getFileHash() (not currently used)
2009-05-14 18:23:40 +00:00
|
|
|
'data/relations',
|
2016-10-05 03:44:07 +00:00
|
|
|
'data/search',
|
|
|
|
'data/searchConditions',
|
|
|
|
'data/searches',
|
2008-08-13 06:38:47 +00:00
|
|
|
'data/tags',
|
|
|
|
'db',
|
2021-05-07 07:18:14 +00:00
|
|
|
'dictionaries',
|
Duplicate detection:
- Adds a per-library "Duplicate Items" virtual search to the source list -- shows up by default for "My Library" but can be added to and removed from all libraries
- Current matching algorithm is very basic: finds exact title matches (after normalizing case/diacritics/punctuation/spacing) and DOI/ISBN matches (untested)
- In duplicates view, sets are selected automatically; in other views, duplicate items can be selected manually and the merge interface can be brought up with "Merge Items" in the context menu
- Can select a master item and individual fields to merge from other versions
- Word processor integration code will automatically find mapped replacements and update documents with new item keys
Possible future improvements:
- Improved detection algorithms
- UI tweaks
- Currently if any items differ, all available versions will be shown as master item options, even if only one item is different; probably the earliest equivalent item should be shown for each distinct version
- Caching of results for performance
- Confidence scale
- Creator version selection (currently the creators from the chosen master item are kept)
- Merging of matching child items
- Better sorting of duplicates if not clustered together by the selected sort column
- Relation path compression when merging items that are already mapped to previously removed duplicates
Other changes in this commit:
- Don't show Trash in word processor integration windows
- Consider items in trash to be missing in word processor documents
- Selection of special views (Trash, Unfiled, Duplicates) is now restored properly in new windows
- Disabled field transform context menu when item isn't editable
- Left/right arrow now expands/collapses all selected items instead of just the last-selected row
- Relation deletions are now synced
- The same items row is now reselected after item deletion
- (dev) Zotero.Item.getNotes(), Zotero.Item.getAttachments(), and Zotero.Item.getTags() now return empty arrays rather than FALSE if no matches -- tests on those return values in third-party code will need to be changed
- (dev) New function Zotero.Utilities.removeDiacritics(str, lowercaseOnly) -- could be used to generate ASCII BibTeX keys
- (dev) New 'tempTable' search condition can take a table to join against -- useful for implementing virtual source lists
- (dev) Significant UI code cleanup
- (dev) Moved all item pane content into itemPane.xul
- Probably various other things
Needless to say, this needs testing.
2011-07-22 21:24:38 +00:00
|
|
|
'duplicates',
|
2020-08-26 14:58:03 +00:00
|
|
|
'editorInstance',
|
2014-11-07 04:08:56 +00:00
|
|
|
'feedReader',
|
XUL -> JS tree megacommit
- Just a single huge commit. This has been developed over too long a
time, required many tiny changes across too many files and has seen too
many iterations to be separated into separate commits.
The original branch with all the messy commits will be kept around for
posterity
https://github.com/zotero/zotero/compare/bb220ad0f2d6bf0eca6df6d225d3d358cb50a27b...adomasven:feature/react-item-tree
- Replaces XUL <tree> element across the whole zotero client codebase
with a custom supermegafast virtualized-table inspired by
react-virtualized yet mimicking old XUL treeview API. The
virtualized-table sits on top on a raw-to-the-metal,
interpreted-at-runtime JS based windowing solution inspired by
react-window. React-based solutions could not be used because they were
slow and Zotero UI needs to be responsive and be able to
display thousands of rows in a treeview without any slowdowns.
- Attempts were made at making this screen-reader friendly, but yet to
be tested with something like JAWS
- RTL-friendly
- Styling and behaviour across all platforms was copied as closely as
possible to the original XUL tree
- Instead of row-based scroll snapping this has smooth-scrolling. If
you're using arrow keys to browse through the tree then it effectively
snap-scrolls. Current CSS snap scroll attributes do not seem to work in
the way we would require even on up-to-date browsers, yet alone the ESR
version of FX that Zotero is on. JS solutions are either terrible for
performance or produce inexcusable jitter.
- When dragging-and-dropping items the initial drag freezes the UI for
a fairly jarring amount of time. Does not seem to be fixable due to
the synchronous code that needs to be run in the dragstart handler.
Used to be possible to run that code async with the XUL tree.
- Item tree column picker no longer has a dedicated button. Just
right-click the columns. The column preferences (width, order, etc) are
no longer handled by XUL, which required a custom serialization and
storage solution that throws warnings in the developer console due to
the amount of data being stored. Might cause temporary freezing on HDDs
upon column resize/reorder/visibility toggling.
- Context menu handling code basically unchanged, but any UI changes
that plugins may have wanted to do (including adding new columns) will
have to be redone by them. No serious thought has gone into how plugin
developers would achieve that yet.
- Opens up the possibility for awesome alternative ways to render the
tree items, including things like multiple-row view for the item tree,
which has been requested for a long while especially by users switching
from other referencing software
2020-06-03 07:29:46 +00:00
|
|
|
'fileDragDataProvider',
|
2008-08-13 06:38:47 +00:00
|
|
|
'fulltext',
|
|
|
|
'id',
|
|
|
|
'integration',
|
2017-07-21 09:30:49 +00:00
|
|
|
'locale',
|
2011-02-09 03:22:06 +00:00
|
|
|
'locateManager',
|
2008-08-13 06:38:47 +00:00
|
|
|
'mime',
|
|
|
|
'notifier',
|
2018-05-04 23:14:28 +00:00
|
|
|
'openPDF',
|
2022-08-05 04:43:42 +00:00
|
|
|
'plugins',
|
2020-09-08 13:28:06 +00:00
|
|
|
'reader',
|
2018-10-05 05:56:46 +00:00
|
|
|
'progressQueue',
|
|
|
|
'progressQueueDialog',
|
2008-08-13 06:38:47 +00:00
|
|
|
'quickCopy',
|
2018-01-20 08:45:00 +00:00
|
|
|
'recognizePDF',
|
2008-08-13 06:38:47 +00:00
|
|
|
'report',
|
2019-06-06 12:47:43 +00:00
|
|
|
'retractions',
|
Update zotero:// extensions (report, timeline, etc.) for async DB, and more
- Protocol handler extensions can now handle promises and can also make
data available as it's ready instead of all at once (e.g., reports now
output one entry at a time)
- zotero:// URL syntaxes are now more consistent and closer to the web
API (old URLs should work, but some may currently be broken)
Also:
- Code to generate server API, currently available for testing via
zotero://data URLs but eventually moving to HTTP -- zotero://data URLs match
web API URLs, with a different prefix for the personal library (/library vs.
/users/12345)
- Miscellaneous fixes to data objects
Under the hood:
- Extensions now return an AsyncChannel, which is an nsIChannel implementation
that takes a promise-yielding generator that returns a string,
nsIAsyncInputStream, or file that will be used for the channel's data
- New function Zotero.Utilities.Internal.getAsyncInputStream() takes a
generator that yields either promises or strings and returns an async input
stream filled with the yielded strings
- Zotero.Router parsers URLs and extract parameters
- Zotero.Item.toResponseJSON()
2014-09-08 20:51:05 +00:00
|
|
|
'router',
|
2008-08-13 06:38:47 +00:00
|
|
|
'schema',
|
2011-06-14 00:36:21 +00:00
|
|
|
'server',
|
2023-06-15 09:03:47 +00:00
|
|
|
'server_integration',
|
2021-08-23 17:02:57 +00:00
|
|
|
'session',
|
2017-07-04 22:03:13 +00:00
|
|
|
'streamer',
|
2008-09-16 19:14:52 +00:00
|
|
|
'style',
|
2008-08-13 06:38:47 +00:00
|
|
|
'sync',
|
2015-07-20 21:27:55 +00:00
|
|
|
'sync/syncAPIClient',
|
|
|
|
'sync/syncEngine',
|
2016-05-06 07:08:22 +00:00
|
|
|
'sync/syncExceptions',
|
2015-07-20 21:27:55 +00:00
|
|
|
'sync/syncEventListeners',
|
2015-11-12 07:54:51 +00:00
|
|
|
'sync/syncFullTextEngine',
|
2015-07-20 21:27:55 +00:00
|
|
|
'sync/syncLocal',
|
|
|
|
'sync/syncRunner',
|
|
|
|
'sync/syncUtilities',
|
2008-08-31 23:36:01 +00:00
|
|
|
'storage',
|
2015-10-29 07:41:54 +00:00
|
|
|
'storage/storageEngine',
|
|
|
|
'storage/storageLocal',
|
|
|
|
'storage/storageRequest',
|
|
|
|
'storage/storageResult',
|
|
|
|
'storage/storageUtilities',
|
2011-11-14 08:42:06 +00:00
|
|
|
'storage/streamListener',
|
Zotero File Storage megacommit
- Group file sync via Zotero File Storage
- Split file syncing into separate modules for ZFS and WebDAV
- Dragging items between libraries copies child notes, snapshots/files, and links based on checkboxes for each (enabled by default) in the Zotero preferences
- Sync errors now trigger an exclamation/error icon separate from the sync icon, with a popup window displaying the error and an option to report it
- Various errors that could cause perpetual sync icon spinning now stop the sync properly
- Zotero.Utilities.md5(str) is now md5(strOrFile, base64)
- doPost(), doHead(), and retrieveSource() now takes a headers parameter instead of requestContentType
- doHead() can now accept an nsIURI (with login credentials), is a background request, and isn't cached
- When library access or file writing access is denied during sync, display a warning and then reset local group to server version
- Perform additional steps (e.g., removing local groups) when switching sync users to prevent errors
- Compare hash as well as mod time when checking for modified local files
- Don't trigger notifications when removing groups from the client
- Clear relation links to items in removed groups
- Zotero.Item.attachmentHash property to get file MD5
- importFromFile() now takes libraryID as a third parameter
- Zotero.Attachments.getNumFiles() returns the number of files in the attachment directory
- Zotero.Attachments.copyAttachmentToLibrary() copies an attachment item, including files, to another library
- Removed Zotero.File.getFileHash() in favor of updated Zotero.Utilities.md5()
- Zotero.File.copyDirectory(dir, newDir) copies all files from dir into newDir
- Preferences shuffling: OpenURL to Advanced, import/export character set options to Export, "Include URLs of paper articles in references" to Styles
- Other stuff I don't remember
Suffice it to say, this could use testing.
2009-09-13 07:23:29 +00:00
|
|
|
'storage/zfs',
|
|
|
|
'storage/webdav',
|
2013-03-03 08:38:02 +00:00
|
|
|
'syncedSettings',
|
2008-08-13 06:38:47 +00:00
|
|
|
'timeline',
|
2.0b3 megacommit
- Support for group libraries
- General support for multiple libraries of different types
- Streamlined sync support
- Using solely libraryID and key rather than itemID, and removed all itemID-changing code
- Combined two requests for increased performance and decreased server load
- Added warning on user account change
- Provide explicit error message on SSL failure
- Removed snapshot and link toolbar buttons and changed browser context menu options and drags to create parent items + snapshots
- Closes #786, Add numPages field
- Fixes #1063, Duplicate item with tags broken in Sync Preview
- Added better purging of deleted tags
- Added local user key before first sync
- Add clientDateModified to all objects for more flexibility in syncing
- Added new triples-based Relation object type, currently used to store links between items copied between local and group libraries
- Updated zotero.org translator for groups
- Additional trigger-based consistency checks
- Fixed broken URL drag in Firefox 3.5
- Disabled zeroconf menu option (no longer functional)
Developer-specific changes:
- Overhauled data layer
- Data object constructors no longer take arguments (return to 1.0-like API)
- Existing objects can be retrieved by setting id or library/key properties
- id/library/key must be set for new objects before other fields
- New methods:
- ZoteroPane.getSelectedLibraryID()
- ZoteroPane.getSelectedGroup(asID)
- ZoteroPane.addItemFromDocument(doc, itemType, saveSnapshot)
- ZoteroPane.addItemFromURL(url, itemType)
- ZoteroPane.canEdit()
- Zotero.CollectionTreeView.selectLibrary(libraryID)
- New Zotero.URI methods
- Changed methods
- Many data object methods now take a libraryID
- ZoteroPane.addAttachmentFromPage(link, itemID)
- Removed saveItem and saveAttachments parameters from Zotero.Translate constructor
- translate() now takes a libraryID, null for local library, or false to not save items (previously on constructor)
- saveAttachments is now a translate() parameter
- Zotero.flattenArguments() better handles passed objects
- Zotero.File.getFileHash() (not currently used)
2009-05-14 18:23:40 +00:00
|
|
|
'uri',
|
2014-08-09 22:01:28 +00:00
|
|
|
'users',
|
2011-06-14 00:36:21 +00:00
|
|
|
'translation/translate_item',
|
2013-08-17 07:08:59 +00:00
|
|
|
'translation/translators',
|
2018-03-28 13:22:52 +00:00
|
|
|
'connector/httpIntegrationClient',
|
|
|
|
'connector/server_connector',
|
|
|
|
'connector/server_connectorIntegration',
|
2023-07-25 04:47:12 +00:00
|
|
|
'itemTreeManager',
|
2011-06-14 00:36:21 +00:00
|
|
|
];
|
2010-05-30 11:25:25 +00:00
|
|
|
|
2022-05-03 08:57:32 +00:00
|
|
|
Components.utils.import("resource://gre/modules/ComponentUtils.jsm");
|
|
|
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
2010-05-30 11:25:25 +00:00
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
var instanceID = (new Date()).getTime();
|
|
|
|
var isFirstLoadThisSession = true;
|
|
|
|
var zContext = null;
|
2016-12-16 08:18:29 +00:00
|
|
|
var initCallbacks = [];
|
2013-11-30 06:55:48 +00:00
|
|
|
var zInitOptions = {};
|
2019-01-21 09:01:04 +00:00
|
|
|
|
|
|
|
// 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');
|
2011-06-14 00:36:21 +00:00
|
|
|
|
2018-02-24 09:54:53 +00:00
|
|
|
var ZoteroContext = function() {}
|
2011-06-14 00:36:21 +00:00
|
|
|
ZoteroContext.prototype = {
|
2017-05-31 15:28:47 +00:00
|
|
|
require,
|
2017-05-24 04:58:41 +00:00
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
/**
|
|
|
|
* 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) {
|
2013-11-05 20:52:40 +00:00
|
|
|
Services.obs.notifyObservers(zContext.Zotero, "zotero-before-reload", isConnector ? "connector" : "full");
|
2013-08-09 15:10:38 +00:00
|
|
|
zContext.Zotero.shutdown().then(function() {
|
|
|
|
// create a new zContext
|
|
|
|
makeZoteroContext(isConnector);
|
2014-04-08 22:47:32 +00:00
|
|
|
return zContext.Zotero.init(zInitOptions);
|
2013-08-09 15:10:38 +00:00
|
|
|
}).done();
|
2011-06-14 00:36:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return zContext;
|
2015-03-09 18:25:49 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Shuts down Zotero, calls a callback (that may return a promise),
|
|
|
|
* then reinitializes Zotero. Returns a promise that is resolved
|
|
|
|
* when this process completes.
|
|
|
|
*/
|
2015-07-19 21:58:58 +00:00
|
|
|
"reinit":function(cb, isConnector, options = {}) {
|
2015-03-09 18:25:49 +00:00
|
|
|
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);
|
2015-07-19 21:58:58 +00:00
|
|
|
var o = {};
|
|
|
|
Object.assign(o, zInitOptions);
|
|
|
|
Object.assign(o, options);
|
2022-06-09 07:12:32 +00:00
|
|
|
return zContext.Zotero.init(o);
|
2015-03-09 18:25:49 +00:00
|
|
|
});
|
2011-06-14 00:36:21 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-05-28 08:48:31 +00:00
|
|
|
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",
|
|
|
|
});
|
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
/**
|
|
|
|
* 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() {};
|
|
|
|
}
|
|
|
|
|
2013-01-21 06:58:01 +00:00
|
|
|
var subscriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
|
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
// Load zotero.js first
|
2019-07-25 11:39:32 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFilesAll[0] + ".js", zContext, 'utf-8');
|
2011-06-14 00:36:21 +00:00
|
|
|
|
|
|
|
// Load CiteProc into Zotero.CiteProc namespace
|
|
|
|
zContext.Zotero.CiteProc = {"Zotero":zContext.Zotero};
|
2019-07-25 11:39:32 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/citeproc.js", zContext.Zotero.CiteProc, 'utf-8');
|
2013-01-21 06:58:01 +00:00
|
|
|
|
|
|
|
// Load XRegExp object into Zotero.XRegExp
|
|
|
|
const xregexpFiles = [
|
|
|
|
/**Core functions**/
|
2021-07-26 10:14:56 +00:00
|
|
|
'xregexp-all',
|
|
|
|
'xregexp-unicode-zotero' //adds support for some Unicode categories used in Zotero
|
2013-01-21 06:58:01 +00:00
|
|
|
];
|
|
|
|
for (var i=0; i<xregexpFiles.length; i++) {
|
2021-07-26 10:14:56 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/utilities/" + xregexpFiles[i] + ".js", zContext, 'utf-8');
|
2012-12-19 12:36:08 +00:00
|
|
|
}
|
2011-06-14 00:36:21 +00:00
|
|
|
|
|
|
|
// Load remaining xpcomFiles
|
|
|
|
for (var i=1; i<xpcomFilesAll.length; i++) {
|
|
|
|
try {
|
2019-07-25 11:39:32 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFilesAll[i] + ".js", zContext, 'utf-8');
|
2011-06-14 00:36:21 +00:00
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
Components.utils.reportError("Error loading " + xpcomFilesAll[i] + ".js", zContext);
|
|
|
|
throw (e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load xpcomFiles for specific mode
|
2016-05-03 21:51:12 +00:00
|
|
|
for (let xpcomFile of (isConnector ? xpcomFilesConnector : xpcomFilesLocal)) {
|
2011-06-14 00:36:21 +00:00
|
|
|
try {
|
2019-07-25 11:39:32 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/" + xpcomFile + ".js", zContext, "utf-8");
|
2011-06-14 00:36:21 +00:00
|
|
|
}
|
|
|
|
catch (e) {
|
2016-04-04 10:33:15 +00:00
|
|
|
dump("Error loading " + xpcomFile + ".js\n\n");
|
|
|
|
dump(e + "\n\n");
|
2022-09-09 20:48:03 +00:00
|
|
|
Components.utils.reportError("Error loading " + xpcomFile + ".js");
|
2011-06-14 00:36:21 +00:00
|
|
|
throw (e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load RDF files into Zotero.RDF.AJAW namespace (easier than modifying all of the references)
|
|
|
|
const rdfXpcomFiles = [
|
2012-04-26 22:36:17 +00:00
|
|
|
'rdf/init',
|
2011-06-14 00:36:21 +00:00
|
|
|
'rdf/uri',
|
|
|
|
'rdf/term',
|
|
|
|
'rdf/identity',
|
|
|
|
'rdf/n3parser',
|
|
|
|
'rdf/rdfparser',
|
2012-04-30 01:30:37 +00:00
|
|
|
'rdf/serialize'
|
2011-06-14 00:36:21 +00:00
|
|
|
];
|
2012-05-05 20:53:00 +00:00
|
|
|
zContext.Zotero.RDF = {Zotero:zContext.Zotero};
|
2011-06-14 00:36:21 +00:00
|
|
|
for (var i=0; i<rdfXpcomFiles.length; i++) {
|
2021-07-26 10:14:56 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/translate/src/" + rdfXpcomFiles[i] + ".js", zContext.Zotero.RDF, 'utf-8');
|
2009-07-06 10:13:02 +00:00
|
|
|
}
|
2011-06-14 00:36:21 +00:00
|
|
|
|
2023-07-11 09:34:04 +00:00
|
|
|
subscriptLoader.loadSubScript("chrome://zotero/content/xpcom/standalone.js", zContext);
|
2012-02-09 04:05:34 +00:00
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
// add connector-related properties
|
|
|
|
zContext.Zotero.isConnector = isConnector;
|
|
|
|
zContext.Zotero.instanceID = instanceID;
|
2016-10-15 19:20:09 +00:00
|
|
|
zContext.Zotero.__defineGetter__("isFirstLoadThisSession", function() { return isFirstLoadThisSession; });
|
2011-06-14 00:36:21 +00:00
|
|
|
};
|
2006-05-27 00:20:27 +00:00
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
/**
|
|
|
|
* The class representing the Zotero service, and affiliated XPCOM goop
|
|
|
|
*/
|
2011-07-02 22:04:04 +00:00
|
|
|
function ZoteroService() {
|
2008-07-03 16:44:52 +00:00
|
|
|
try {
|
2011-08-24 01:59:56 +00:00
|
|
|
var start = Date.now();
|
|
|
|
|
2011-06-14 00:36:21 +00:00
|
|
|
if(isFirstLoadThisSession) {
|
|
|
|
makeZoteroContext(false);
|
Async DB megacommit
Promise-based rewrite of most of the codebase, with asynchronous database and file access -- see https://github.com/zotero/zotero/issues/518 for details.
WARNING: This includes backwards-incompatible schema changes.
An incomplete list of other changes:
- Schema overhaul
- Replace main tables with new versions with updated schema
- Enable real foreign key support and remove previous triggers
- Don't use NULLs for local libraryID, which broke the UNIQUE index
preventing object key duplication. All code (Zotero and third-party)
using NULL for the local library will need to be updated to use 0
instead (already done for Zotero code)
- Add 'compatibility' DB version that can be incremented manually to break DB
compatibility with previous versions. 'userdata' upgrades will no longer
automatically break compatibility.
- Demote creators and tags from first-class objects to item properties
- New API syncing properties
- 'synced'/'version' properties to data objects
- 'etag' to groups
- 'version' to libraries
- Create Zotero.DataObject that other objects inherit from
- Consolidate data object loading into Zotero.DataObjects
- Change object reloading so that only the loaded and changed parts of objects are reloaded, instead of reloading all data from the database (with some exceptions, including item primary data)
- Items and collections now have .parentItem and .parentKey properties, replacing item.getSource() and item.getSourceKey()
- New function Zotero.serial(fn), to wrap an async function such that all calls are run serially
- New function Zotero.Utilities.Internal.forEachChunkAsync(arr, chunkSize, func)
- Add tag selector loading message
- Various API and name changes, since everything was breaking anyway
Known broken things:
- Syncing (will be completely rewritten for API syncing)
- Translation architecture (needs promise-based rewrite)
- Duplicates view
- DB integrity check (from schema changes)
- Dragging (may be difficult to fix)
Lots of other big and little things are certainly broken, particularly with the UI, which can be affected by async code in all sorts of subtle ways.
2014-08-06 21:38:05 +00:00
|
|
|
zContext.Zotero.init(zInitOptions)
|
2013-08-12 00:51:16 +00:00
|
|
|
.catch(function (e) {
|
2016-09-06 00:41:35 +00:00
|
|
|
dump(e + "\n\n");
|
|
|
|
Components.utils.reportError(e);
|
2016-12-05 10:17:21 +00:00
|
|
|
if (!zContext.Zotero.startupError) {
|
2017-09-11 07:52:10 +00:00
|
|
|
zContext.Zotero.startupError = e.stack || e;
|
2016-12-06 11:12:54 +00:00
|
|
|
}
|
2013-08-12 00:51:16 +00:00
|
|
|
})
|
|
|
|
.then(function () {
|
2023-07-11 09:34:04 +00:00
|
|
|
if (zContext.Zotero.startupErrorHandler || zContext.Zotero.startupError) {
|
|
|
|
if (zContext.Zotero.startupErrorHandler) {
|
|
|
|
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);
|
2016-11-22 09:35:57 +00:00
|
|
|
}
|
2023-07-11 09:34:04 +00:00
|
|
|
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://mozapps/content/update/updates.xul',
|
|
|
|
'updateChecker', 'chrome,centerscreen,modal', null);
|
2016-11-22 09:35:57 +00:00
|
|
|
}
|
|
|
|
}
|
2023-07-11 09:34:04 +00:00
|
|
|
zContext.Zotero.Utilities.Internal.quitZotero();
|
2016-11-22 09:35:57 +00:00
|
|
|
}
|
2015-02-25 03:06:18 +00:00
|
|
|
});
|
2016-12-16 08:18:29 +00:00
|
|
|
|
|
|
|
let cb;
|
|
|
|
while (cb = initCallbacks.shift()) {
|
|
|
|
cb(zContext.Zotero);
|
|
|
|
}
|
2011-06-14 00:36:21 +00:00
|
|
|
}
|
2013-08-12 00:51:16 +00:00
|
|
|
else {
|
|
|
|
zContext.Zotero.debug("Already initialized");
|
|
|
|
}
|
2011-06-14 00:36:21 +00:00
|
|
|
this.wrappedJSObject = zContext.Zotero;
|
|
|
|
} catch(e) {
|
2015-04-11 00:46:57 +00:00
|
|
|
var msg = e instanceof Error
|
|
|
|
? e.name + ': ' + e.message + '\n' + e.fileName + ':' + e.lineNumber + '\n' + e.stack
|
|
|
|
: '' + e;
|
|
|
|
dump(msg + '\n');
|
2008-07-03 16:44:52 +00:00
|
|
|
Components.utils.reportError(e);
|
2011-06-14 00:36:21 +00:00
|
|
|
throw e;
|
2008-07-03 16:44:52 +00:00
|
|
|
}
|
2006-05-27 00:20:27 +00:00
|
|
|
}
|
2010-07-06 09:02:35 +00:00
|
|
|
ZoteroService.prototype = {
|
2011-07-02 22:04:04 +00:00
|
|
|
classID: Components.ID('{e4c61080-ec2d-11da-8ad9-0800200c9a66}'),
|
2020-06-30 06:08:08 +00:00
|
|
|
QueryInterface: ChromeUtils.generateQI([])
|
2010-07-06 09:02:35 +00:00
|
|
|
}
|
2006-05-27 00:20:27 +00:00
|
|
|
|
2016-12-16 08:18:29 +00:00
|
|
|
function addInitCallback(callback) {
|
|
|
|
if (zContext && zContext.Zotero) {
|
|
|
|
callback(zContext.Zotero);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
initCallbacks.push(callback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-03 00:07:56 +00:00
|
|
|
/**
|
|
|
|
* Determine whether Zotero Standalone is running
|
|
|
|
*/
|
|
|
|
function isStandalone() {
|
2022-08-08 08:22:29 +00:00
|
|
|
return true;
|
2011-07-03 00:07:56 +00:00
|
|
|
}
|
|
|
|
|
2016-12-26 22:09:29 +00:00
|
|
|
function getOS() {
|
|
|
|
return Services.appinfo.OS;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isMac() {
|
|
|
|
return getOS() == "Darwin";
|
|
|
|
}
|
|
|
|
|
|
|
|
function isWin() {
|
|
|
|
return getOS() == "WINNT";
|
|
|
|
}
|
|
|
|
|
|
|
|
function isLinux() {
|
|
|
|
return getOS() == "Linux";
|
|
|
|
}
|
|
|
|
|
2011-07-02 22:04:04 +00:00
|
|
|
/**
|
|
|
|
* The class representing the Zotero command line handler
|
|
|
|
*/
|
|
|
|
function ZoteroCommandLineHandler() {}
|
|
|
|
ZoteroCommandLineHandler.prototype = {
|
|
|
|
/* nsICommandLineHandler */
|
2020-07-05 21:44:26 +00:00
|
|
|
handle: async function (cmdLine) {
|
2017-01-14 22:03:22 +00:00
|
|
|
// Force debug output to window
|
2015-03-24 07:38:11 +00:00
|
|
|
if (cmdLine.handleFlag("ZoteroDebug", false)) {
|
2017-01-14 22:03:22 +00:00
|
|
|
zInitOptions.forceDebugLog = 2;
|
|
|
|
}
|
|
|
|
// Force debug output to text console
|
|
|
|
else if (cmdLine.handleFlag("ZoteroDebugText", false)) {
|
|
|
|
zInitOptions.forceDebugLog = 1;
|
2013-11-30 06:55:48 +00:00
|
|
|
}
|
2022-06-23 09:33:47 +00:00
|
|
|
// Pressing Ctrl-C via the terminal is interpreted as a crash, and after three crashes
|
|
|
|
// Firefox starts up in automatic safe mode. To avoid this, we clear the crash counter when
|
|
|
|
// using one of the debug-logging flags, which generally imply terminal usage.
|
|
|
|
if (zInitOptions.forceDebugLog) {
|
|
|
|
Services.prefs.getBranch("toolkit.startup.").clearUserPref('recent_crashes');
|
|
|
|
}
|
2013-11-30 06:55:48 +00:00
|
|
|
|
2017-09-11 07:49:06 +00:00
|
|
|
zInitOptions.forceDataDir = cmdLine.handleFlagWithParam("datadir", false);
|
|
|
|
|
2016-12-16 08:18:29 +00:00
|
|
|
if (cmdLine.handleFlag("ZoteroTest", false)) {
|
|
|
|
zInitOptions.test = true;
|
|
|
|
}
|
|
|
|
if (cmdLine.handleFlag("ZoteroAutomatedTest", false)) {
|
|
|
|
zInitOptions.automatedTest = true;
|
|
|
|
}
|
|
|
|
if (cmdLine.handleFlag("ZoteroSkipBundledFiles", false)) {
|
|
|
|
zInitOptions.skipBundledFiles = true;
|
|
|
|
}
|
|
|
|
|
2011-07-02 22:04:04 +00:00
|
|
|
// handler for Zotero integration commands
|
|
|
|
// this is typically used on Windows only, via WM_COPYDATA rather than the command line
|
|
|
|
var agent = cmdLine.handleFlagWithParam("ZoteroIntegrationAgent", false);
|
|
|
|
if(agent) {
|
|
|
|
// Don't open a new window
|
|
|
|
cmdLine.preventDefault = true;
|
|
|
|
|
|
|
|
var command = cmdLine.handleFlagWithParam("ZoteroIntegrationCommand", false);
|
|
|
|
var docId = cmdLine.handleFlagWithParam("ZoteroIntegrationDocument", false);
|
2021-02-10 09:31:06 +00:00
|
|
|
var templateVersion = parseInt(cmdLine.handleFlagWithParam("ZoteroIntegrationTemplateVersion", false));
|
|
|
|
templateVersion = isNaN(templateVersion) ? 0 : templateVersion;
|
2011-07-02 22:04:04 +00:00
|
|
|
|
2021-02-10 09:31:06 +00:00
|
|
|
zContext.Zotero.Integration.execCommand(agent, command, docId, templateVersion);
|
2011-07-02 22:04:04 +00:00
|
|
|
}
|
2023-02-14 00:18:40 +00:00
|
|
|
|
2023-07-11 09:34:04 +00:00
|
|
|
var fileToOpen;
|
|
|
|
// Handle zotero:// and file URIs and prevent them from opening a new window
|
|
|
|
var param = cmdLine.handleFlagWithParam("url", false);
|
|
|
|
if (param) {
|
|
|
|
cmdLine.preventDefault = true;
|
2017-03-17 21:08:03 +00:00
|
|
|
|
2023-07-11 09:34:04 +00:00
|
|
|
var uri = cmdLine.resolveURI(param);
|
|
|
|
if (uri.schemeIs("zotero")) {
|
2016-12-16 08:18:29 +00:00
|
|
|
addInitCallback(function (Zotero) {
|
|
|
|
Zotero.uiReadyPromise
|
|
|
|
.then(function () {
|
2023-07-11 09:34:04 +00:00
|
|
|
// Check for existing window and focus it
|
|
|
|
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
|
|
|
.getService(Components.interfaces.nsIWindowMediator);
|
|
|
|
var win = wm.getMostRecentWindow("navigator:browser");
|
|
|
|
if (win) {
|
|
|
|
win.focus();
|
|
|
|
win.ZoteroPane.loadURI(uri.spec)
|
2016-12-16 08:18:29 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
2023-07-11 09:34:04 +00:00
|
|
|
// See below
|
|
|
|
else if (uri.schemeIs("file")) {
|
|
|
|
Components.utils.import("resource://gre/modules/osfile.jsm")
|
|
|
|
fileToOpen = OS.Path.fromFileURI(uri.spec)
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
dump(`Not handling URL: ${uri.spec}\n\n`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
param = cmdLine.handleFlag("debugger", false);
|
|
|
|
if (param) {
|
|
|
|
try {
|
|
|
|
let portOrPath = Services.prefs.getBranch('').getIntPref('devtools.debugger.remote-port');
|
|
|
|
|
|
|
|
const { DevToolsLoader } = ChromeUtils.import(
|
|
|
|
"resource://devtools/shared/loader/Loader.jsm"
|
|
|
|
);
|
|
|
|
const loader = new DevToolsLoader({
|
|
|
|
freshCompartment: true,
|
|
|
|
});
|
|
|
|
const { DevToolsServer } = loader.require("devtools/server/devtools-server");
|
|
|
|
const { SocketListener } = loader.require("devtools/shared/security/socket");
|
|
|
|
|
|
|
|
if (DevToolsServer.initialized) {
|
|
|
|
dump("Debugger server already initialized\n\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
DevToolsServer.init();
|
|
|
|
DevToolsServer.registerAllActors();
|
|
|
|
DevToolsServer.allowChromeProcess = true;
|
|
|
|
const socketOptions = { portOrPath };
|
|
|
|
const listener = new SocketListener(DevToolsServer, socketOptions);
|
|
|
|
await listener.open();
|
|
|
|
if (!DevToolsServer.listeningSockets) {
|
|
|
|
throw new Error("No listening sockets");
|
|
|
|
}
|
|
|
|
|
|
|
|
dump(`Debugger server started on ${portOrPath}\n\n`);
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
dump(e + "\n\n");
|
|
|
|
Components.utils.reportError(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// In Fx49-based Mac Standalone, if Zotero is closed, an associated file is launched, and
|
|
|
|
// Zotero hasn't been opened before, a -file parameter is passed and two main windows open.
|
|
|
|
// Subsequent file openings when closed result in -url with file:// URLs (converted above)
|
|
|
|
// and don't result in two windows. Here we prevent the double window.
|
|
|
|
param = fileToOpen;
|
|
|
|
if (!param) {
|
|
|
|
param = cmdLine.handleFlagWithParam("file", false);
|
|
|
|
if (param && isMac()) {
|
|
|
|
cmdLine.preventDefault = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (param) {
|
|
|
|
addInitCallback(function (Zotero) {
|
|
|
|
// Wait to handle things that require the UI until after it's loaded
|
|
|
|
Zotero.uiReadyPromise
|
|
|
|
.then(function () {
|
|
|
|
var file = Zotero.File.pathToFile(param);
|
|
|
|
|
|
|
|
if(file.leafName.substr(-4).toLowerCase() === ".csl"
|
|
|
|
|| file.leafName.substr(-8).toLowerCase() === ".csl.txt") {
|
|
|
|
// Install CSL file
|
|
|
|
Zotero.Styles.install({ file: file.path }, file.path);
|
|
|
|
} else {
|
|
|
|
// Ask before importing
|
|
|
|
var checkState = {
|
|
|
|
value: Zotero.Prefs.get('import.createNewCollection.fromFileOpenHandler')
|
|
|
|
};
|
|
|
|
if (Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
|
|
.getService(Components.interfaces.nsIPromptService)
|
|
|
|
.confirmCheck(null, Zotero.getString('ingester.importFile.title'),
|
|
|
|
Zotero.getString('ingester.importFile.text', [file.leafName]),
|
|
|
|
Zotero.getString('ingester.importFile.intoNewCollection'),
|
|
|
|
checkState)) {
|
|
|
|
Zotero.Prefs.set(
|
|
|
|
'import.createNewCollection.fromFileOpenHandler', checkState.value
|
|
|
|
);
|
|
|
|
|
|
|
|
// Perform file import in front window
|
|
|
|
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
|
|
|
.getService(Components.interfaces.nsIWindowMediator);
|
|
|
|
var browserWindow = wm.getMostRecentWindow("navigator:browser");
|
|
|
|
browserWindow.Zotero_File_Interface.importFile({
|
|
|
|
file,
|
|
|
|
createNewCollection: checkState.value
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2015-04-16 21:35:38 +00:00
|
|
|
}
|
2011-07-02 22:04:04 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
classID: Components.ID("{531828f8-a16c-46be-b9aa-14845c3b010f}"),
|
|
|
|
service: true,
|
|
|
|
_xpcom_categories: [{category:"command-line-handler", entry:"m-zotero"}],
|
2020-06-30 06:08:08 +00:00
|
|
|
QueryInterface: ChromeUtils.generateQI([Components.interfaces.nsICommandLineHandler])
|
2011-07-02 22:04:04 +00:00
|
|
|
};
|
|
|
|
|
2022-05-03 08:57:32 +00:00
|
|
|
var NSGetFactory = ComponentUtils.generateNSGetFactory([ZoteroService, ZoteroCommandLineHandler]);
|