Commit graph

16410 commits

Author SHA1 Message Date
Dan Stillman
aab912e4ee Support Select All (Cmd/Ctrl-A) in the collection tree
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
A plain select-all would mix uncombinable rows, so scope it to the
current selection's type: a library selection expands to all library
roots; a collection selection to every collection sharing a parent with
a selected one (so multi-level/multi-parent selections expand within
each branches); and a Recently Read selection to Recently Read in every
library. Other rows -- saved searches, Unfiled, Trash, etc. -- have no
useful expansion, so the tree's key handler leaves the selection
untouched instead of clearing it.
2026-06-24 14:23:08 -04:00
Dan Stillman
d7660f2f27
Add local-cache versioning for Read Aloud audio (#5967)
Version Read Aloud cache keys with the server-provided cacheVersion so
a version bump misses stale entries and re-fetches correct audio, prune
obsolete entries once per session, and skip caching responses sent with
Cache-Control: no-store.
2026-06-24 11:21:09 -04:00
Dan Stillman
962e1334c8 Inset item tree focus ring so its top isn't clipped
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
Regressed by f4adb452ee, which dropped the items-tree body's top padding
to 0 for sticky section headers; the scroll container's overflow then
clipped the top of the first row's focus ring, which drew outside the
row box.
2026-06-23 09:35:25 -04:00
Tom Najdek
40cb1cfa84
Fix stale itemType in _previousData (#5964)
Some checks failed
CI / Build, Upload, Test (push) Has been cancelled
This fixes a problem where, on subsequent item type changes, a stale itemType is reported and the filename is not updated.
2026-06-19 16:34:23 -04:00
Dan Stillman
35317982f5 Make the sticky library header opaque to pointer events
The pinned sticky section header was opaque to paint but had
pointer-events: none, so clicks, drag-starts, and drops fell through to
the item occluded underneath it.

Make the opaque content capture pointer events instead. Clicks no-op
(header rows aren't selectable), drags don't start (header rows aren't
draggable), and drops on the header are rejected so they're a no-op
rather than acting on the list underneath.

Also drop the index > 0 exception when skipping non-selectable rows in
_onSelection(), so clicking a non-selectable row at the top (i.e., the
first library's header) is a true no-op instead of scrolling to the top.

Also skip non-selectable rows in handleActivate(), since the header can
now be double-clicked; without this it would try to open the library as
an item.

Fixes #5960
2026-06-19 16:07:53 -04:00
Dan Stillman
bdf79336f9 Account for sticky section header when scrolling a row into view
Arrow-key navigation scrolled the newly selected row flush with the top
of the view, leaving it hidden behind the pinned sticky section header.
Reserve a row's worth of space at the top so the row lands below the
pinned header.

Fixes #5959
2026-06-19 14:28:40 -04:00
Tom Najdek
e71bd89e0d Add support for undo/redo (#5823)
---------

Co-authored-by: Dan Stillman <dstillman@zotero.org>
2026-06-19 14:12:54 -04:00
Tom Najdek
c92148c3ec Add batch editing support for fields (#5823)
---------

Co-authored-by: Dan Stillman <dstillman@zotero.org>
2026-06-19 14:12:54 -04:00
Dan Stillman
8d7f5a39f9 Don't include trashed items in Advanced Search outside the trash
#5658 added includeDeleted to the Advanced Search outside the trash, so
trashed items kept matching: trashing a result removed its row, but
re-running the search brought it back. Exclude deleted items by default,
the same as a quick search, and only include them when viewing the trash,
where the scope returns only deleted items.

Fixes #5956
2026-06-19 14:07:43 -04:00
Dan Stillman
ff094330f5 Don't show all trashed collections/searches during a search in trash
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
When viewing the trash, trashed collections and saved searches were appended
to the items list unconditionally, so every advanced search (and quick search)
in the trash matched all of them. Now they're filtered by name during a quick
search and excluded entirely when an advanced search or tag filter is active,
since they can't match item-level conditions or tags.

Fixes #5957
2026-06-19 13:43:53 -04:00
Dan Stillman
4a318617d6 Don't crash on unbalanced {{endif}} in template engine
An {{endif}} without a matching {{if}} popped the base level off the
stack, leaving it empty and throwing "level is undefined" on the next
part. A malformed filename format template could therefore break file
attaching entirely.

https://forums.zotero.org/discussion/132296/pdfs-have-stopped-attaching-after-upgrade-to-zotero-9
2026-06-19 13:05:19 -04:00
Tom Najdek
6092b0335c
Fix auto-renaming not triggering when parent item type changes 2026-06-19 15:04:56 +02:00
Dan Stillman
35c8448582 Advanced search: Move focus to next "-" button when removing row via keyboard 2026-06-19 00:14:06 -04:00
Dan Stillman
e37a7d8f06 Advanced search: Don't run the search on Shift-Enter 2026-06-19 00:14:06 -04:00
Dan Stillman
2e79bbe402 Advanced search: Focus condition drop-down when adding row via keyboard 2026-06-19 00:14:05 -04:00
Dan Stillman
e38f8f78b0 Advanced search: Add find-as-you-type for all conditions
Closes #5953
2026-06-19 00:14:05 -04:00
Dan Stillman
90aa5d33a0 Fix first-column (Title) header label alignment after item tree refactor
The refactor dropped the 8px (COLUMN_PADDING / 2) offset that makes up
for the inline-start padding the first cell omits, so the header label
sat 8px too far left of the item titles.
2026-06-18 23:32:47 -04:00
Dan Stillman
f4adb452ee Keep the sticky items-list section header clear of the scrollbar
Pin the header inside the scrolling body as a zero-height position:
sticky element so its width tracks the body's content box and it lines
up with the rows without any JS geometry. Reserve a scrollbar gutter so
the macOS overlay scrollbar doesn't float over the content (the opaque
header must paint above the rows to occlude them, and so above the
scrollbar, so it can't be put under it). Drop the body's top padding for
the item tree so rows clip exactly where the header pins, and keep the
gap below the column header as a margin outside the scroll area.

Fixes #5958
2026-06-18 23:25:22 -04:00
Dan Stillman
08d875c7f7 Handle multiple-library item selections dropped on a collection or library
Route each item by its own library -- items already in the target
library are added directly (or skipped, for a library root), while
items from other libraries are copied in -- instead of attempting an
invalid cross-library insert. Disallow a move of such a selection
rather than silently copying.

Fixes #5961
2026-06-18 16:13:16 -04:00
Dan Stillman
6d1cd85211 Skip retraction banner during initial sync on a new computer 2026-06-18 14:51:44 -04:00
Dan Stillman
39954dc437 Remove dead collection assignment for window-opened notes (#5954)
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-18 14:10:25 -04:00
Dan Stillman
20fd5fe3e2 Move tag selector view settings popup handler out of XHTML (#5954) 2026-06-18 14:09:49 -04:00
Dan Stillman
618fcfa49d Use one combined tag query for a multiple-row selection (#5954) 2026-06-18 14:09:44 -04:00
Dan Stillman
1c76195a7c Show library-aware section headers in the item tree for multi-row selections (#5954)
When multiple collection-list rows are selected, group the combined
items by library under sticky headers (e.g., "My Library", "Group X (2
collections selected)"), or show a single summary header for a multi-row
selection within one library, with blank spacer rows separating
libraries.
2026-06-18 14:09:36 -04:00
Dan Stillman
94c78759ab Add support for sticky section headers to VirtualizedTable (#5954)
When stickySectionHeaders is enabled, the header of the section at the
top of the view is pinned in an overlay that the rows scroll under,
pushed up as the next section's header arrives. Consumers identify
header rows via isSectionHeader. Row striping restarts at each section
header so every section's first row is the same shade.
stickySectionHeaders defaults to false, so existing tables are
unaffected.
2026-06-18 14:09:31 -04:00
Dan Stillman
b80fa996f5 Group the items list by library (#5954)
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.

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-18 14:09:17 -04:00
Dan Stillman
15c2c95470 Support multiple-collection selection (#5954)
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-18 14:05:55 -04:00
Dan Stillman
2ddb4e991b Show sort indicator on default-sorted column and fix first-click reverse
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
On a fresh profile, the default sort column had no explicit sortDirection,
so the first header click set the default direction instead of reversing
the sort, and no sort indicator was shown.
2026-06-17 15:33:37 -04:00
Abe Jellinek
e23a453e5c Recently Read: Show matching children as regular rows
Some checks are pending
CI / Build, Upload, Test (push) Waiting to run
In other words, don't show the children that make the parent "recently
read" as context rows.

Children that don't match the Recently Read condition (such as notes,
as well as other child attachments that weren't read since the cutoff)
are still shown as context rows.

And add tests for the new behavior, and clean up an unused local var.
2026-06-16 13:52:14 -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