Commit graph

16388 commits

Author SHA1 Message Date
Dan Stillman
206ab311db Clear stale collection-tree selection when filtering
Filtering rebuilds the rows, but the selected indices from before pointed at
different (or out-of-range) rows afterward, so a multi-selection rendered the
wrong rows as selected. Clear the selection after the rebuild and re-select the
focused row, collapsing a multi-selection to that row while filtering.
2026-06-16 12:32:36 -04:00
Dan Stillman
bd606f76e7 Don't open the item context menu on a library section header
In a grouped cross-library view, right-clicking a library header row opened the
item context menu (acting on the current selection, or showing stray options
with none). Library headers aren't items, so ignore the right-click.
2026-06-16 12:27:00 -04:00
Dan Stillman
2e41d080dd Keep at least one collection-tree row selected
Cmd-clicking (or Space on) the last selected row deselected it, leaving the
collection tree with no selection while its items stayed shown. Add an opt-in
requireSelection option to VirtualizedTable that refuses to toggle off the last
remaining row, and enable it for the collection tree.
2026-06-16 12:23:27 -04:00
Dan Stillman
9e324fe62b Ignore collection-tree activation when multiple rows are selected
Pressing Enter (or double-clicking) edited the focused row -- renaming a
collection or opening the saved-search/feed editor -- even with several rows
selected. Activation acts on one row, so ignore it for multi-selection.
2026-06-16 12:11:24 -04:00
Dan Stillman
ee24c0b468 Remove dead collection plumbing for window-opened notes
The collections passed through Notes.open into the note window were never
read -- the note editor has no collections setter and EditorInstance.collection
is never assigned on this path -- so they had no effect. New notes are still
added to the selected collection(s) directly in newNote().
2026-06-16 12:02:00 -04:00
Dan Stillman
cda229509a Group the items list by library
When the items list contains items from more than one library, group them by
library -- in collections-list order, independent of the active sort -- with a
section heading above each library's items. The first heading sits flush at the
top; each later one has a gap above it and a hairline below separating it from
its items.

Grouping is triggered automatically by an items list spanning more than
one library, not the kind of selection behind it, so any future source
of multi-library items would be separated the same way. Today the
cross-library collection selection is the only such source.
2026-06-16 00:36:19 -04:00
Dan Stillman
d7770a9d11 Support multiple-collection selection
Allow selecting multiple collections, saved searches, or library roots in the
collection tree -- within a library or across libraries -- and show the union
of their items. The selection is threaded through the pane as an array
(getCollectionTreeRows(), changeCollectionTreeRows(), etc.); the item pane, tag
selector, reports, and export operate on all selected rows.

Adding items (new items and notes, drag-and-drop, the attachment dialog,
import, Add by Identifier) targets every selected collection. Only rows that can
share an items view may be combined: collections, saved searches, and library
roots mix freely, and multiple Recently Read rows can be combined across
libraries, but other special views (Trash, Duplicates, etc.) and rows from
different visibility groups can't be shown together, so a selection mixing them
keeps only the focused row. In-window advanced search runs across all selected
collections.

Advanced search value autocomplete is now scoped to the searched library, fixing
a long-standing TODO where suggestions were drawn from all libraries regardless
of the search scope; for a cross-library selection it spans the selected
libraries.

For a cross-library selection, the tag selector shows the union of tags
(colored tags only when a single library is in scope, since colors are
per-library), and deleting a tag spans all selected libraries while
rename/color/split are disabled. If advanced search is open, the
collection and saved-search conditions are omitted, since each is scoped
to a single library.
2026-06-16 00:36:19 -04:00
Dan Stillman
4d38970ef0 Center the Advanced Search filter button's focus ring on the field edge
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-06-15 20:38:37 -04:00
Bogdan Abaev
e6f82dabfd fix keyboard nav through advanced search btns+deck (#5955)
- Include the Advanced Search button in the quick-search tab sequence
- Tab: quick-search textbox -> Advanced Search button -> item tree
- Shift-Tab: Advanced Search button -> quick-search textbox
- Shift-Tab: item tree -> Advanced Search button (when the deck is
  closed)
- Shift-Tab: Advanced Search collapse button -> New Item button
- Fix Shift-Tab from the item tree doing nothing when the Advanced
  Search deck is open; now moves focus to the deck's last focusable
  element
- add tooltiptext to expand/collapse and close btns
2026-06-15 20:38:27 -04:00
Dan Stillman
cf876033f6 Fix join-mode menulist clipping at top of Advanced Search 2026-06-15 15:22:16 -04:00
pi-dal
f03004bb9e
fix(attachments): add PMCID fallback for PubMed resolver lookup (#5906)
PubMed saves can include a PMCID even when DOI-based full-text lookup
fails to produce a PDF. In that case the connector asks the desktop
attachment resolver flow for fallback sources, but getFileResolvers()
only considered DOI and URL data, so Zotero never tried the matching
PMC article URL.

Treat PMCID as a valid signal for file lookup eligibility and add a
PubMed Central OA resolver before DOI-based OA lookup. Cover the new
fallback path in attachment resolver tests and the connector
hasAttachmentResolvers endpoint.
2026-06-15 14:57:49 -04:00
Abe Jellinek
80ca898a74 Preferences: Fix search not filtering and not highlighting results
1. 862573eab added references to fileRenaming.ftl strings but didn't
   add a <link> to it, so document.l10n.formatMessages() returned
   nothing. It fell back to Zotero.getString(), which threw an error
   due to a missing string in en-US. We didn't catch that, so the entire
   search process aborted every time.
2. message.attributes is an optional array of { name, value } objects,
   not an object itself, so we were never successfully adding FTL .title
   and .label attributes to the parsed strings.

This fixes the 862573eab regression, and makes search match FTL
attributes as it was always intended to.

Fixes #5947
2026-06-15 13:55:06 -04:00
Dan Stillman
7eef2fb3f0 Don't let a failed database backup block a schema upgrade or startup
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
During a schema upgrade, a failed backup aborted the upgrade and blocked
startup on every launch. Automatic backups are best-effort, so just log
the error and skip the backup instead.

https://forums.zotero.org/discussion/132201/errorunknownerror-could-not-stat-ns-error-generate-failure-44-4350
2026-06-15 11:53:01 -04:00
Dan Stillman
22055d92b7 Fix opening the DB on network filesystems (e.g., SMB) on macOS/Linux
(Confirmed on macOS, but probably Linux too)

Pass openNotExclusive to avoid acquiring an exclusive lock at the OS level
at open time, which fails with an I/O error on network shares. We still set
locking_mode=EXCLUSIVE, so the connection holds an exclusive SQLite lock for
its lifetime and keeps the WAL index in heap memory (no -shm file).

Regression in Zotero 7 (Fx115)

Fixes #4860
2026-06-15 11:16:54 -04:00
Dan Stillman
39d7835472 Don't show post-upgrade banner for source and dev builds 2026-06-15 09:57:45 -04:00
Dan Stillman
e41c788c4c Don't show standalone attachments open in tabs in the citation dialog 2026-06-14 23:24:22 -04:00
Dan Stillman
580e423d4c Fix failing saved-search test
The new Save Search name prompt blocked deck.pane.save().
2026-06-14 16:18:05 -04:00
Dan Stillman
27560d9476 Prompt for a name when saving a new advanced search
The temporary advanced search saved silently under an auto-generated
"Untitled" name. Prompt for a name instead (defaulting to that name),
and label its button "Save Search…" to signal the dialog. The saved-search
editor's button, which saves changes directly, is now just "Save".

https://github.com/zotero/zotero/pull/5658#issuecomment-4696398750
2026-06-14 15:17:25 -04:00
Dan Stillman
81b3c13b13 Close the saved-search editor when the edited search is deleted
Deleting the saved search being edited triggered onCollectionSelected's
save-changes prompt, which doesn't make sense for a search that's gone.
Detect the deleted search and close the editor without prompting.
2026-06-14 15:02:40 -04:00
Dan Stillman
a3180d87c5 Show focus ring on the advanced-search condition menu when opened
The menu was focused programmatically (in response to the filter-button
click), so :focus-visible wasn't set and no focus ring showed. Pass
focusVisible to force the ring.
2026-06-14 14:53:11 -04:00
Dan Stillman
8ed617ae53 Allow removing the last advanced-search condition to reset it
The remove button on the sole remaining condition is now enabled once a
value is entered, and clicking it replaces the condition with the default
empty one shown when the pane is first opened, instead of staying
disabled.
2026-06-13 19:33:31 -04:00
Dan Stillman
97aa4f93ea Restore saving advanced searches in editable group libraries
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
Regression in #5658
2026-06-13 19:21:35 -04:00
Dan Stillman
3d334dc244 Align Advanced Search close button with the filter button's right edge
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
2026-06-13 11:03:58 -04:00
Dan Stillman
18d332ec5e Patch out native control margins in Advanced Search
macOS-normalize-controls zeros margins on inputs and checkboxes but not
menulists or buttons, so their native platform margins threw off the
spacing. Zero them and restore spacing via the containers' gaps.

https://github.com/zotero/zotero/pull/5658#issuecomment-4696398750
2026-06-13 09:47:37 -04:00
Dan Stillman
702094f703 Shift Advanced Search filter button to center its icon
https://github.com/zotero/zotero/pull/5658#issuecomment-4696398750
2026-06-13 09:47:25 -04:00
Dan Stillman
40851e1f58 Add bottom border to Advanced Search area
https://github.com/zotero/zotero/pull/5658#issuecomment-4696398750
2026-06-13 09:47:20 -04:00
Dan Stillman
2689997c50 Fix Advanced Search area height calculation
The inner <deck> stacks both panes in one grid cell, so the area was
always sized to the taller (saved-search) pane and never shrank back.
The non-selected pane is now removed from layout entirely.

https://github.com/zotero/zotero/pull/5658#issuecomment-4696398750
2026-06-13 09:47:11 -04:00
Abe Jellinek
00527332c4 Move Advanced Search and saved search editing to the main window (#5658)
---------

Co-authored-by: Dan Stillman <dstillman@zotero.org>
2026-06-12 15:21:59 -04:00
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