When conditions are removed, shift conditionIDs so that
conditionIDs always go in increments of 1 (0, 1, 2 ...).
It prevents conditionIDs from conflicting with each other
when conditions are rearranged.
Fixes: #3434
After the first bubble is added, the focused input gets a placeholder
indicating that typing a number will add it as a page to the just-added
bubble. The placeholder is truncated if it's too close to the edge in
multi-item citations.
Also add a tip to the item details popup explaining that locators can
be typed into the main input field, with a link to the documentation.
The tip stops appearing once a typed locator has been used.
---------
Co-authored-by: Dan Stillman <dstillman@zotero.org>
- allow to accept the dialog via cmd/ctrl+Enter from
inside of a panel
- enable click-through on item details panel, so
one can click on the "Accept" button without having
to close the popup first
These two measures allow one to add a bubble, modify
the citation via item details popup, and accept it
with one less step (without having to close the popup first)
Zotero never sets a primary password, so if one is set on the NSS key
database, it was either corrupted or copied in from a Firefox profile,
and stored logins can never be decrypted, since there's no
primary-password prompt. This previously made it impossible to save
credentials without manually deleting cert9.db, key4.db, and
logins.json from the profile directory.
If reading or saving credentials fails and a primary password is set,
clear stored logins and reset the key database so that credentials can
be saved again. Saving the API key or WebDAV password is retried
automatically, so logging in completes without a manual fix, and if
previously stored credentials are lost to a reset, show a one-time
alert prompting the user to log in again.
The once-per-minute rate limit from e40fff6a7d (5.0.91) was inverted,
and the last-error time was never initialized, so the alert hasn't
appeared since 2020.
Wraps the values stored in nsILoginManager with OSKeyStore, which derives
its master key from Keychain on macOS, DPAPI on Windows, and libsecret on
Linux. A copy of the profile alone is no longer enough to extract these
credentials.
Existing plaintext entries are mirrored once per session to a new
"(encrypted)" realm but preserved in the original realm so a user can
still downgrade to a release that doesn't know about encryption. Active
credential changes (sign in, sign out, password change) write to the
encrypted realm only and remove the legacy entry. A future version can
clear any remaining legacy entries on startup.
Patches MOZ_APP_BASENAME in the bundled runtime so the keychain master
key is labeled "Zotero Encrypted Storage" rather than "Firefox Encrypted
Storage", with a check_line guard so a future Mozilla change to the
OSKeyStore label format fails the build instead of silently rebranding
the entry. Also fixes check_line to take an explicit file argument.
The local-file-change watcher added in f21e1b2d32 accumulated changed
item keys globally but was drained separately by each library's storage
engine, with the drained keys filtered to that library. The first
library to file-sync (normally My Library) consumed all pending events,
and keys belonging to other libraries were silently discarded, so files
modified on disk in group libraries were never marked for upload. The
initial and periodic full-scan fallbacks on Windows and Linux were
likewise global, so only the first library ever received them, and
changes made in other libraries while Zotero was closed were never
detected at all.
The sync runner now drains the watcher once per sync session and
immediately runs the modification check on the changed items across all
libraries, recording any changes in the database, and the per-library
storage engines skip the check entirely unless the watcher reports that
the library needs a full scan:
- On all platforms, a library that has never been scanned gets one full
scan, which also gives libraries one recovery scan for changes dropped
by affected releases.
- On Windows/Linux, where the watchers only capture events while Zotero
is running, each library gets a full scan on its first file sync of
the session, on every manual sync, and daily during background syncs
(instead of the previous 3-hour interval, which dated from when scans
were the primary detection mechanism).
- On macOS, libraries scanned since the last FSEvents journal
discontinuity are tracked in a pref, since the journal -- and
therefore the validity of previous scans -- survives restarts.
Also:
- Check FSEvents event flags and fall back to full scans when events
were dropped or coalesced (MustScanSubDirs/UserDropped/KernelDropped/
EventIdsWrapped), and skip HistoryDone sentinel events
- Disable the watcher for the session and fall back to legacy scanning
on backend errors, including when the inotify watch limit is reached,
instead of continuing with silently incomplete coverage
- Prune scan records for deleted libraries, since SQLite can reuse a
deleted library's libraryID
https://forums.zotero.org/discussion/132120/
On macOS 27 and later, the installer gets access to the Word startup
folder via a folder-selection dialog rather than an OS permission
prompt, so support an adjusted banner message and add strings for the
folder dialog.
createDirectoryForItem() wipes and recreates the item's storage
directory before moving in a downloaded file. If removeDir() failed
(e.g., a locked file on Windows), the error bubbled up to zfs.js and
became the generic sync error. Route it through checkFileAccessError()
instead, so the user gets the actionable locked-file message and a
Show Parent Directory button.
https://forums.zotero.org/discussion/132097/
In Add/Edit Citation mode, display a preview of the citation
in the bottom section. The section can be hidden/displayed
via the toggle in the right corner.
Remove io.preview from editor instance, so that citation
dialog knows not to show the preview even if the preference
is set.
A minor refactor to have resizeWindow() resolve
when the animation is fully over, and clear minHeight
on window in list mode before resizing, restoring
it when resizing animation is done, same as in library mode.
It allows us to fully expand the window in list mode before
showing the preview.
Fixes: zotero#5910
The item tree's DOM id carries a view-specific suffix (e.g.
"item-tree-main-default", "item-tree-main-recentlyRead"), but three
call sites compared against a single hardcoded "item-tree-main":
- Collection highlighting on Ctrl/Option (zoteroPane.js) -- match on
the "item-tree-main" prefix to cover all views. This restores
highlighting in Recently Read, where it silently failed.
- Focusing the items list after Add Item by Identifier (lookup.js) --
use the current view's tree id instead of a literal that resolved to
null and threw.
- Shift-Tab from the item tree to the toolbar (zoteroPane.js) -- key the
actionsMap on the current view's tree id.
Add a test confirming focus lands on the items list after a lookup.
https://forums.zotero.org/discussion/130968/collection-of-selected-papers-is-not-highlighted-in-recently-read-panel
The earlier fix (ef7896ab5f) migrated 9.0.x's "<id>-default" prefs
forward to the refactor's new "<id>" key, but that left 9.0.x and 10
beta keying differently in treePrefs.json, so switching between versions
always reset 9.0.x to defaults.
Put the `-default` suffix back so Z9 and Z10 read and write the same
key, and migrate any unsuffixed `<id>` data written by an earlier beta
back to `<id>-default` on first load. The migration runs once per
process and can be removed in a future release once beta users have all
updated.
https://forums.zotero.org/discussion/131653/zotero-10-beta-5-reinitializes-the-columns-in-main-pane
example:
"Atmospheric Chemistry and Physics" is currently incorrectly abbreviated as "Atmospheric Chem. Phys." should be abbreviated "Atmos. Chem. Phys."
Zotero.Tags.init() keyed the id cache by the raw tag name from the
database, but getID() and Items._loadTags() both normalize names via
cleanData() (trim + NFC). A tag stored in a non-normalized form (e.g.,
non-NFC or with surrounding whitespace) could therefore never be matched
by getID(), which returned false. When such a tag was removed from an
item, that false was bound as the tagID parameter in the DELETE FROM
itemTags query, throwing "Invalid boolean parameter 1 'false'" and
aborting the save. Since this fired while applying changes during sync,
it persistently blocked sync.
To fix, normalize names in init() to match getID()/_loadTags().
https://forums.zotero.org/discussion/131901/error-report-seems-to-be-preventing-sync
vacuum() and the APFS-cloning offline backup path both close and
reopen the SQLite connection, which drops all ATTACHed databases --
including the in-memory "indexing" alias used for the fulltextWords
scratch table set up in Fulltext.init(). Once the connection is
reopened, indexing queries fail with "no such table:
indexing.fulltextWords", and indexItems()'s ignoreErrors path
routes the error to logError(), so indexing silently stops working
for the rest of the session.
Add an onConnect() hook on Zotero.DBConnection for per-connection
state that doesn't persist across reopens, and use it from
Fulltext.init() to re-attach the indexing DB on each reconnect.
Regression sources:
- 67288047f3 ("Use APFS cloning for file copies on macOS") flips
online idle backups to offline-with-clone on APFS, so every idle
backup interval (24h default) closes and reopens the connection.
Affects Mac users on APFS.
- b27c4cb023 ("Enable SQLite WAL mode and add periodic VACUUM
INTO") adds the vacuum path, which closes and reopens on the
first idle period in a session that passes the freelist/time
gates. Affects all users with sufficient DB churn, roughly once
per 14 days.
https://forums.zotero.org/discussion/131576/debug-id-d848621212-indexing-of-pdfs-fail-zotero-9-0-3https://forums.zotero.org/discussion/131718/possible-bug-regression-report-search-unusable-on-macos-zotero-9-0-3-with-large-library
For a dependent CSL style with no default-locale of its own, citeproc-js
parses the parent's XML and silently uses the parent's default-locale
over any user-selected locale, making the locale dropdown a no-op. Add
a Zotero.Style.effectiveLocale getter that falls back to the parent's
locale, and use it in updateLocaleList and the locale-selector custom
element to disable the dropdown in that case.
https://forums.zotero.org/discussion/comment/512891/#Comment_512891
The general HTTP layer's automatic 429/Retry-After retry only retries
the one failed request, but the sync layer wants to pause its entire
batch of concurrent requests via concurrentCaller.pause(). Add a
noRetryOnThrottle option to Zotero.HTTP.request() that throws on 429 or
503 with Retry-After so the caller can apply its own throttling, and
have syncAPIClient set it. Extend sync's catch block to also honor
Retry-After on 503 (previously only invoked via _check429).
When a user's account is deleted and then undeleted on the server, the
dataserver creates a fresh shardLibraries row at a low version, while the
client still has a much higher local library version. Subsequent syncs
then throw "_libraryVersion cannot decrease" and the user is stuck.
Tag the cannot-decrease errors from the library version setters with a
named error, catch it in Engine.start(), reset libraryVersion and
storageVersion to -1, and restart. The retry hits the existing
libraryVersion == -1 branch and runs _fullSync(), which re-uploads the
local library against the recreated server library.
Previously only 503 + Retry-After was retried automatically; 429 was
handled only inside the sync API client. Extend _retryOnServerError()
to also retry on 429, honoring Retry-After on both 429 and 503 and
falling back to the existing exponential backoff otherwise.
In list mode, sort libraries by the count of their items
cited in the current document, falling back to alphabetic sorting
when counts are equal, with "My Library" always getting
priority over other groups.
Fixes: #5924
The test opened an advanced search window but never closed it, which
likely caused the intermittent failures in the ZoteroPane focus() test
"should shift-tab across the zotero pane".
Ignore persisted compatibility flag from previous app version in non-stable releases to fix disabled for wrongly using old flag
Ignore max version compatibility for plugin update check on non-stable releases
Relevant: https://forums.zotero.org/discussion/131096/
---------
Co-authored-by: Dan Stillman <dstillman@zotero.org>