Commit graph

16360 commits

Author SHA1 Message Date
Bogdan Abaev
d2f1c56250 keep search conditionIDs in arithmetic sequence
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
2026-06-12 15:16:46 -04:00
Dan Stillman
cd29a818b0 Don't let hover background override selected item background 2026-06-12 15:07:17 -04:00
Bogdan Abaev
0f2d3e103d Citation dialog: show placeholder after a new bubble is added (#5932)
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>
2026-06-12 15:07:17 -04:00
Bogdan Abaev
40f949ba94 Citation dialog: allow accepting while details popup is open
- 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)
2026-06-12 15:02:14 -04:00
Dan Stillman
c72d80f22b Update Word for Windows submodule 2026-06-12 12:58:00 -04:00
Dan Stillman
cd39445b94 Automatically repair unusable login manager
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
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.
2026-06-12 11:17:00 -04:00
Dan Stillman
632f11db74 Fix corrupted-login-manager warning never appearing
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.
2026-06-12 11:17:00 -04:00
Dan Stillman
55434d14a1
Encrypt API key and WebDAV password using OS keychain (#5897)
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.
2026-06-12 11:16:22 -04:00
Martynas Bagdonas
98d82d2909 Add SDT support 2026-06-12 13:47:08 +03:00
Abe Jellinek
982c00aaf6
Add by Identifier: Stay open with input, don't clear unless submitted (#5949) 2026-06-11 11:54:42 -04:00
Dan Stillman
06e16c297c Fix file-change detection in all libraries after the first one synced
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
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/
2026-06-10 22:26:13 -04:00
Dan Stillman
de1bf1cec1 Update Mac Word plugin install flow for macOS 27 Golden Gate
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.
2026-06-10 15:06:01 -04:00
Dan Stillman
4e3baf09a0 Add okButtonLabel support to FilePicker
Maps to nsIFilePicker.okButtonLabel, which customizes the label of the
button used to accept the dialog, where supported by the platform.
2026-06-10 15:06:01 -04:00
Dan Stillman
fde4086e08 Show file-access error when storage directory can't be cleared on download
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/
2026-06-10 08:07:32 -04:00
Adomas Venčkauskas
3e7030a642 Update Word for Windows submodule
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-06-10 12:31:08 +03:00
abaevbog
fa3e0f683f
Citation dialog: display preview of the citation (#5916)
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
2026-06-09 12:35:30 -04:00
Abe Jellinek
dcf5010415
Info box: Optimize rendering of many creator rows (#5939)
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-06-08 15:43:32 -04:00
Dan Stillman
31d9e89165 Fix item tree focus checks broken by view-specific tree IDs
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
2026-06-08 13:21:15 -04:00
Dan Stillman
d0507e02c8
Restore -default suffix on item tree column-prefs keys (#5941)
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
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
2026-06-05 13:10:01 -04:00
Christopher Holmes
31b3ead557
Abbreviate Atmospheric as Atmos. (#5938)
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
example: 
"Atmospheric Chemistry and Physics" is currently incorrectly abbreviated as "Atmospheric Chem. Phys." should be abbreviated "Atmos. Chem. Phys."
2026-06-04 15:38:42 -04:00
Adomas Venčkauskas
615ba3c178
Improve Add/Edit Citation button behaviour when cursor is in a non-citation Zotero field (#5935)
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
When in bibliography, show an appropriate message. When in any other
non-citation Zotero field - just open an empty edit citation dialog.
2026-06-03 03:51:26 -04:00
Abe Jellinek
e029354a35
Fix US-formatted Last Read dates in en-* alias locales (#5934) 2026-06-03 02:35:15 -04:00
Dan Stillman
87901c1c21 Fix error when removing a tag stored in a non-normalized form
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
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
2026-05-31 17:07:13 +02:00
Adomas Venčkauskas
8cf5c9b3d1 Fix ctrl-arrow navigation in item tree with no selection causing a select
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
Regression 4a003049
2026-05-28 15:17:45 +03:00
Adomas Venčkauskas
c838e9b29e Fix double-indent on collection tree (regression 5ca1fbb1)
Closes #5915
2026-05-28 15:17:45 +03:00
Adomas Venčkauskas
8277277948 Make Item Pane display the item count on Zotero startup 2026-05-28 15:17:45 +03:00
Adomas Venčkauskas
786960079b Fix item pane lagging 'items in this view' count by one view
Closes #5913
2026-05-28 15:17:45 +03:00
Dan Stillman
70c4cadab1 Fix full-text indexing failing silently after periodic vacuum or backup
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
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-3
https://forums.zotero.org/discussion/131718/possible-bug-regression-report-search-unusable-on-macos-zotero-9-0-3-with-large-library
2026-05-22 10:59:43 -04:00
Abe Jellinek
bf8c6f2027 Revert "Read Aloud: Fix 402 handling"
This reverts commit a692ca3493.

Not necessary on main.
2026-05-22 10:27:40 -04:00
Dan Stillman
cfd5596814 Disable locale selector when parent style specifies default-locale
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
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
2026-05-21 22:32:23 -04:00
Abe Jellinek
a692ca3493 Read Aloud: Fix 402 handling 2026-05-21 15:10:32 -04:00
Dan Stillman
9ca79a2cb1 Update Mac and Linux builds to Firefox 140.11.0esr 2026-05-21 10:43:53 -04:00
Dan Stillman
d2631cc614 Don't mark group attachment as unsynced when opened
For group items, attachmentLastRead is stored in a synced setting in My
Library rather than on the item itself, but since we didn't pass
skipSyncedUpdate, the item was being marked as needing sync, resulting
in a permission-denied error in read-only libraries.

https://forums.zotero.org/discussion/131717/opening-pdf-in-read-only-group-library-triggers-permission-denied-on-sync
2026-05-21 09:58:34 -04:00
Dan Stillman
ad4caa8688 Let sync API client handle its own 429/Retry-After throttling
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).
2026-05-21 09:15:04 -04:00
Dan Stillman
37bf9d0965 Trigger full sync when server library version goes backward
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
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.
2026-05-20 23:11:35 -04:00
Dan Stillman
f81e7cb5da Handle 429 and Retry-After in general HTTP layer
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.
2026-05-20 15:08:52 -04:00
abaevbog
8f44172342
citation dlg: sort libraries by cited count (#5925)
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
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
2026-05-19 15:40:55 -04:00
Abe Jellinek
b7437faf55 Convert ItemPane{SectionElement,Container}Base to ES modules
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-05-18 15:48:31 -04:00
Abe Jellinek
c2a9ea2687 Add Abstract section to merge pane with value chooser 2026-05-18 15:48:31 -04:00
abaevbog
5c232d65c0
Citation dialog: display first run guidance panel when the first item is added vs on initial open (#5917)
Display the first run guidance panel when the first
item is added to the citation vs on initial open.
2026-05-18 14:28:32 -04:00
Dan Stillman
596882980d Update reader submodule 2026-05-18 14:19:53 -04:00
Abe Jellinek
714d4416f8 Suppress Crash Reports and RemoteSettings console spam
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
2026-05-13 14:40:51 -04:00
Abe Jellinek
ba7e036582 Devtools: Fix profiler (Performance tab)
Fixes #5111
2026-05-13 14:01:55 -04:00
Adomas Venčkauskas
431e1dabde Fix first-column sizing after tree refactor. Closes #5908
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-05-12 10:35:05 +03:00
Martynas Bagdonas
789c83249c Avoid selecting tabs queued for close
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
When closing multiple tabs, close() could choose another tab from the same close set as the replacement selection. If that tab was an unloaded note, it could load during shutdown or bulk close and open separately. Choose only from tabs that will remain open.

Fixes https://forums.zotero.org/discussion/131203/closing-zotero-with-a-note-opened-as-a-tab-opens-the-note-in-a-separate-window
2026-05-11 19:54:11 +03:00
Dan Stillman
504447de41 Close advanced search window in collectionViewItemTree notify() test
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
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".
2026-05-07 14:25:58 -04:00
Dan Stillman
ddf2419e78 Update Windows builds with Word template compatibility fix from #5904
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-05-06 10:51:13 -04:00
Adomas Venčkauskas
d66682b04e
Undo Mozilla changes that allow non-UTF-16 command line args (#5904)
To allow old Word Zotero.dotm to continue to work
2026-05-06 10:27:13 -04:00
windingwind
fda72a3434
Fix beta build plugin max version compatibility check (#5903)
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
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>
2026-05-05 14:26:50 -04:00
Wuy
575dc5351c Fix reader cleanup on tab close and event listener removal 2026-05-05 14:30:26 +03:00