The web library will probably still display the old tag in addition to
the new one, at least until browser restart. We'll have to deal with
that separately.
Closes#1205
When refreshing, if fewer than 100 tags to show, just create them from
scratch instead of updating the full set. Otherwise, remove the full set
from DOM and add it back in after updates to avoid reflows (from #1204).
There are various things that could be done to optimize this further
(avoiding unnecessary sorting during full refreshes, calculating a hash
of the full set and not updating it every time), but we should probably
just replace it with @tnajdek's React version first.
Closes#1204
Changes `libraryTreeView::addEventListener('load')` and similar to
`libraryTreeView::onLoad.addListener(listener, once)`, etc. `once` is an
optional boolean that, when true, causes the listener to fire once and
then be removed. This is implicit for 'load'.
'load' maintains its special behavior of running immediately if the
treeview has already been loaded.
Also adds `waitForLoad()` and `waitForSelect()` functions that return
promises on event completion, since most uses of those events were just
resolving deferreds.
TODO: Add text fields for controlling number of items and chunk size
(Chunk size should be small for testing UI interactions and performance
but large for generating lots of data.)
For building up a big library and testing UI interaction during writes
To use, load chrome://zotero/content/tools/data_generator.html in
Firefox (for now).
Could be improved a bit to add other kinds of data (collections,
child items, relations)
The items list is generated from the database (via search), but new
items may have been added to the database but not yet been registered,
causing unloaded-data errors during sorting. Avoid that by not showing
unregistered items when generating the items list.
Additional protections are necessary -- it's still possible to get
errors, and maybe a crash, if an item has been registered but not yet
fully loaded -- but this addresses the most common one.
We could monkey-patch a finally function in connectors as described in
this gist https://gist.github.com/jish/e9bcd75e391a2b21206b , but it
appears to silence propogation of unhandled rejections
and it could later come back to bite us in the butt.
Native and proper support for finally is, however, planned in ES7.
When dragging an item to another library, we have to check if there's a
linked item in the target library, but items might not yet be laoded in
the other library, so item.getLinkedItem() can fail with "Item [n] not
yet loaded].
Fixing required asyncifying the follow functions:
- Zotero.Item::getLinkedItem()
- Zotero.Collection::getLinkedCollection()
- Zotero.URI.getURIItem()
- Zotero.URI.getURICollection()
- Various integration functions
As noted in 27cb099c82, import translators should be rewritten to return
a promise from doImport() and wait for promises from successive
item.complete() calls. They should then be marked as minVersion: "5.0"
to be handled properly by this new code.
(But this tries to account, albeit with somewhat worse behavior, for
translators that haven't been rewritten and sandboxes without Promise
(which is currently the case with child sandboxes in the client).)
(Oh, and I haven't tested this at all in the connectors.)
Function that automatically follows Link headers and makes additional
requests as necessary, feeding the XMLHTTPRequest object from each
request to a reducer function.
- Archive remotely missing that user chooses to keep
- Ignore archived groups that don't existing remotely
- Unarchive groups that become available again
This can happen because objects are uploaded in batches, but the version
number from the last batch is used for all objects (since
APIClient.uploadObjects() handles batching internally).
Previously on Windows, where we don't have /bin/mv, we were recursing
into the data directory and copying files individually, which is very
slow, so automatic migration was disabled. Instead, try moving
directories with OS.File.move() with the `noCopy` flag. Moving
directories is technically unsupported by OS.File, but probably only
because of the possibility of a cross-volume copy (which is only
implemented for some platforms), and using `noCopy` hopefully prevents
that. If someone does have their data directory or storage directory on
a different volume, the migration might be quite slow, but leaving a
data directory behind in the Firefox profile directory (where it can be
easily misplaced with a seemingly unrelated Firefox reset) is worse.
E.g., moving 3,600 items to the trash now takes 4 seconds instead of 62
Instead of saving each item, update internal state and database directly
(which is more brittle but worth it). Also avoid unnecessary sorting
after removing an item from the items tree.
This allows for imported items to be saved individually instead of being
saved in a batch after processing the entire imported file (which for
large imports would hang the UI, even if the actual saving was
asynchronous). This also fixes the progress meter during asynchronous
saves.
To take advantage of this, import translators will need to return a
promise when available (using the native Promise object) from doImport()
and wait for optional promises from item.complete().
The logic here can probably be streamlined further. (E.g., we might be
able to say that item.complete() always returns a promise.) It's
complicated by the fact that, at the moment, Promise isn't available in
child sandboxes, though this can probably be fixed.
Tests forthcoming, but they require a translator that supports this,
which needs to be committed separately.
View with -w for a cleaner diff.
There seems to be a bug here where, if the item is off-screen when
modified, it doesn't become visible, but it now does stay visible when
it's on-screen to begin with.
At least until we have a better interface for setting library-specific
sync settings
Previously, if My Library file syncing was disabled or set to WebDAV, My
Publications files wouldn't be uploaded.
When adding many search conditions (e.g., when matching many items with the
`key` condition), the query can fail due to either the bound parameter limit or
the expression tree size limit.
To avoid this, add support for an 'inlineFilter' property on search conditions
when using the 'is' or 'isNot' operator. 'inlineFilter' is a function that
returns a quoted value suitable for direct embedding in the SQL statement, or
false if not valid. Multiple consecutive conditions for the same 'inlineFilter'
field are combined into an `IN (x, y, z)` condition.
- Add Cmd/Ctrl-Shift-I for "Import…"
- Cmd/Ctrl-Shift-V apparently pastes without formatting, so don't override it.
Instead, add a shortcut key to the menu option, defaulting to
Cmd-Option-Shift-I/Ctrl-Alt-Shift-I
- The I in both is now localizable
- Make version copyable
- Include "What's new" link to changelog
- Update some links and descriptions
To-do:
- Replace dev credits with a nice statement like in the Firefox About pane
Before 3.4.2, `yield` in a Bluebird `coroutine()` released Zalgo if an
already-resolved promise (e.g., from `Promise.resolve()`) was yielded,
continuing immediately instead of on the next turn of the event loop. We
apparently relied on that broken behavior in a few places, particularly from
`Zotero.DB.waitForTransaction()`. All the transaction-queueing stuff probably
needs to be reevaluated in general, but for now, mirror the previous possibly
ill-advised behavior by checking explicitly for a transaction before yielding
on `waitForTransaction()` (as well as the result of a 'load' event from
`libraryTreeView`).
Since 1) debug output logging via the prefs isn't necessarily possible
for startup errors in Standalone, 2) real-time output is prohibitively
slow and has a miniscule scrollback buffer on Windows unless you use a
Cygwin or Git terminal, and 3) copying/pasting/emailing was annoying
anyway, make -ZoteroDebug open a popup window that shows errors and
debug output and allows submitting straight to the server with a Debug
ID.
This should replace the existing debug output viewer as well, but that's
less of a priority.
-ZoteroDebugText or the debug.log pref can still be used to dump to the
terminal.
(Borrowing a technique from Thunderbird.)
This only affects the splitters in standard view. The splitter between the top
and bottom panes in stacked view still has a 1px draggable area.
We can probably do a similar thing to slim down splitters on Windows, as
planned in #367.
Apparently in 4.0 we defaulted to 'author' if a creatorType wasn't
passed. To avoid lots of errors like the one fixed in
dd0094893a,
add a similar fallback for 5.0 and log a warning (though not with the
translator name, unfortunately).
Month values from the Firefox language packs are included in a
JSON file used by `Zotero.Date.getMonths()`. `getMonths(true)` includes
English months as well.
The JSON file should be bundled with the connectors as well, and
Zotero.Date.init() should be updated to populate the month data from
that.
- Fixes errors in previous commits 55bfe54a and 9431e0de, to wit ...
- Apply unescapeHTML after RTF tag and entity conversions
- Remove high-bit character escape from entity converter,
and apply separately after remaining HTML entities are
decoded by unescapeHTML
- Tabs missing styling
- Preferences: Notes font menulist dropmarker missing (left border still
missing, could not find any CSS to help that out)
- Preferences: Numberbox background gray
For the tabs styling issue see
https://bugzilla.mozilla.org/show_bug.cgi?id=1306425
When "Get Additional Styles…" is clicked, open a stripped-down version
of the Zotero styles page in a window. When a style is clicked on,
install it and close the window.
I'm going to say that this closes#767, but as Aurimas notes there, if
you know the style you're looking for, being able to just type the name
in a dialog would be faster, so further improvements could be made. But
as it stands, this is much better than clicking through to a browser
(and hoping that it's one with the new connector with style installation
support).
Immediate sync triggering on remote library change using WebSocket API.
Currently kicks off a normal sync process for the modified library --
actual object data isn't pushed.
(This might not stay enabled for 5.0 Final.)