Instead of focusing the first condition, which ends up placing
focus in the middle of the new window or modal. It is best
to focus the first node, which is the general convention,
per https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/, and
what many screen reader users expect. When we focus a field in
the middle of the window/dialog, it makes it seem for some users
that this is the first node, which will make them miss all the
fields above it.
Also, linked search name input to its label in searchDialog.xhtml.
<panel> takes over Escape handling by just closing the popup via
what looks like a capturing listener on document, since Escape
keydown events never even reach the popup itself. When the popup
is just closed like that, tagsBox is blurred so all unwanted edits get saved.
To properly handle Escape, attach our own capturing listener that will
reset all edits before the popup is closed.
Fixes: #4398
- Mozilla's ActorManagerParent was only being imported when devtools
were initialized (either by opening the Error Console or by connecting
via remote debugging). Import it in our ActorManager so Mozilla
actors, including AutoScroll, are always registered.
- This may have other effects! I'm assuming most of us test with
the error console visible, though, so we would've had Mozilla
actors, while users running without devtools wouldn't have. We
definitely want those actors. (Most of them, at least.)
- Don't override autoscroller styles with our panel customizations.
After react 18 update, the tab node may not yet be rendered
by tabBar.jsx when we try to scroll it into view in Zotero_Tabs.select.
- To make sure scrolling happens when rendering is done, move scroll-related
logic into a useEffect of tabBar.jxs. It also makes sure that we'll scroll to
a selected tab if it is moved via context menu to the very beginning or the end.
- Added a small scroll-padding to tabs container to make sure the border
does not get cutoff after the tab is scrolled into view instead of
JS code accounting for the border.
- Fixed a glitch where the pinned library tab would not get selected
on shift-tab from opened tabs menu.
Fixes: #4382
* vpat 48: announce selection for default virt table
For simpler virtualized tables
(e.g. style manager in Zotero_Preferences.Cite), the table
does not get re-rendered when selection changes, so
aria-activedescendant does not get updated in render().
- a single function to update aria-activedescendant of the table
- call it in _updateTree of the tree selection because _onSelection
is not called the very first time a table is rendered. In that case, after
restart, collectionTree would have a selected row but no aria-activedescendant
- remove this.forceUpdate() from selection handlers of itemTree and
collectionTree because judging by the coment it's main purpose was to set
aria-activedescendant through render()
- set aria-activedescendant in _onSelection handler
of virtualized table.
- construct and set aria-label for rows build via
makeRowRenderer of VirtualizedTable so that is is
announced when the row is selected.
- remove earlier shift-Enter behavior that makes tag's
input multiline.
- shift-Enter will function just as Enter by saving the
tag and allowing focus to return to reader or itemTree.
- except after pasting multiple tags which will still turn
the tags input into a multiline field. Then, shift-enter
will add a new line, just as with any other multiline
editable-text.
- focus will always enter the tagsBox popup opened from the reader
- escape from within the popup with tagsBox will close the popup (vpat
67)
- one should not be able to collapse the tagsBox. Added `collapsible`
getter and setters to the collapsible panel to prevent the section
from changing its open status. This may be also used in other cases,
such as to prevent itemBox from being collapsed in duplicates mode.
- patched a glitch where tab from the last empty tab input would loose
focus.
- changed the `menupopup` for `panel` to display the `tagsbox` because
`menupopup` has implicit `role="menu"` which is not meant to contain
inputs, so voiceover completely looses cursor when inputs are focused
inside of the popup. Also, tweaked spacing a bit to avoid the
focus-ring getting cutoff.
Addresses: #4222Fixes: #4230Fixes: #4226
Addresses: #4388
As opposed to 'change' event.
Because if the field is editted and another window is focused
while the cursor is in the field, the change event will be
swallowed and when the field finally looses focus, it will not
be saved.
This may address the reported issue of edits not being saved in
title and abstract fields.
Addresses: #4388
- display the first continuous span of emojis in the primary cell of
the itemTree for non-colored tags.
- the emojis appear after the colored tags' circles (if any)
- to keep things consistent with itemTree, sort tags in the tagsBox in
the following order: colored tags first sorted by their position,
emoji tags after sorted alphabetically, followed by remaining tags sorted
alphabetically.
By moving the setAutoAttachmentTitle() calls to importFromFile() /
_addToDB().
Also:
- Chop off file extension when setting the parent's title based on the
filename in Create Parent Item -> Manual Entry.
- Fix Manual Entry not renaming the attachment correctly by awaiting
createEmptyParent().
When tabs' state is updated, refresh library tab's icon.
Do not skip it if the icon already exists (as for reader tabs).
Otherwise, when selected row from collectionTree changes,
the icons in the library tab will not update.
Fixes: #4385
- remove padding between the <dialog> and the window edges
- explicit width for all zoterosearch fields because otherwise
a menulist with a long content (e.g. longer collection name) name
can push the + and - buttons outside of the window
Fixes: #4374
- properly determine between which two bubbles a click landed
- set input direction
- delete the bubble on the left of the cursor
- in rtl, use selectionStart as the expected end of the input
and selectionEnd as the start. It fixes the issue of the
cursor getting stuck at the end of the input, as well as
fixes the Home/End not working from the right end.
- fix spacing issues for item descriptions in both layouts
Fixes: #4371
* Multiple accessiblity fixes
* Increase font size
* Nicer layout of the welcome screen
* Fix description in the welcome screen
* Add stripes to the table in citations matching screen
* Change icons for accept and resolve manually buttons
- getDOMElement relied on React.renderToStaticMarkup,
which is react 18 was moved to a different file than the
one exposed with react-dom-server. To not add another
file just for that one function, replace getDOMElement
with getCSSIcon.
- getDOMElement was mainly used for a few remaining
png icons that were not replaced with svg. For those
few icons, just record which background-url should be
set when the module loads and add it in getCSSIcon if
applicable. Alternatively, background-image setting
could be moved into a stylesheet?
- a few hardcoded twisty svgs in icons.jsx are not used anywhere
(they would be fetched via IconTwisty), so those are
removed
- await for promise that is resolved in ref attribute
of root.render() as an alternative for removed callback
from ReactDOM.render
- await-ing for promise every time when ref needs to be
used after render (e.g. tag selector container), otherwise
ref will be undefined
- additional window.sizeToContent calls to properly size
dialogs with react-rendered content (e.g. create parent),
otherwise the window can cut off some of the content.
- revert change from 2401a34031
that only loads un-trashed collections in _loadCollections.
If an item only belongs to deleted collections, item._loaded.collections = true
from _loadCollections will never run, so an exception
will be thrown in item.toJSON() when syncing happens.
Instead, to address the problem of item.getCollections()
having stale data #4307, add 'includeTrashed' parameter to
item.getCollections() based on which item._collections
will be filtered. Fixes: #4346
- revert earlier, no more necessary, changes from a532cfb475
to not alter item._collections cache when collections are being trashed or restored.
Collection is removed from item._collections only when it is permanently
erased.
- removed unnecessary test checking for consistent item._collections
value before and after reload, since item._collections is no longer
modified
- fix encountered bug where a trashed child collection is not
unloaded if a parent collection is erased without being trashed first.
- tweaked Zotero.Search sql construction to count items
that only belong to trashed collections into 'unfiled'. Fixes: #4347
---------
Co-authored-by: Dan Stillman
Now we give the caller control over whether the pane should still be
shown after it loads. We're fine with showing in all cases when handling
a search, but we don't want to show when handling a navigation select
if the user already selected something else while the pane was still
loading.
Fixes#4357
By extracting Tab into a separate, memoized component, caching handlers
and tweaking how icons and other props are passed, we're able to only
re-render tabs that actually changed, rather than re-rendering the
entire tab bar all the time. This should be especially noticeable when
dragging tabs around but will reduce CPU cycles used in general.
- listen to 'collection' notifier events and re-render
the section if a relevant collection is moved to trash or
modified. That way, a deleted collection will be removed,
a restored collection will be added back, and renaming a
collection will update the name.
- fixed a bug where a restored collection would not
be added into item._collections cache. Fixed false-positive
test for it.
- do not add deleted collections into items. _collections cache in
Zotero.Items._loadCollections. Otherwise, deleted collections will
appear in librariesCollectionsBox after the app is restarted.
Should reduce jank when opening the item context menu and sidenav
Locate menu, especially on Windows (where the flash of blank menuitems
lasted an especially long time for some reason).
Since the header of the collapsible section is not visible,
there is no way to expand the itemBox if it was collapsed
before dulicate items are selected. With this, itembox
is always opened when a new set of duplicate items is selected.
Fixes: #4318
- added dynamic tooltip whose label is set only when it appears.
It allows us to have a visible tooltip without screen readers
announcing it
- fetch the pane name string and pass it as an argument to
fluent to set the appropriate label on expand/collapse buttons
- tooltiptext is set dynamically on expand/collapse buttons to
avoid having screen readers read both the label and the tooltip text
that are almost identical
used to announce which annotation is selected during
keyboard navigation, as well as the index of the current
search result
Followup to zotero/reader#130
- always render options and link buttons - just do
not display them if their respective field is empty.
That allows us to easily handle focus after refresh
because otherwise, the node may does not exist.
If we try to restore focus to such hidden component,
simulate a "tab" from it to focus the next possible node.
This fixes the issue of focus being lost on tab after all
content of editable-text is cleared.
- add tabindex=0 to itemType menulist, otherwise it was
not perceived as a candidate to return focus to.
- somewhat special treatment for restoring focus to
creator rows. If the desired node is not found, we'll
try to focus the respective node in the last creator row.
It prevents focus from being lost on tab after clearing
the very last creator.
Fixes: #4241
this._addCreatorRow needs to be properly initialized to
false (as opposed to being undefined) because 'false'
is the value we check against to decide if an empty
row should be added and focused after rendering.
Fixes: #4268
- only have enabled "Permanently delete" and "Restore to library"
options in the context menu for collections and searches in the trash
- display the custom header with buttons to delete or restore
in the itemPane when a collection or search in the trash is selected
Fixes: #4295
a532cfb475 added `isCollection()`, `isSearch()`, and `isItem()` methods
to data objects to handle collections and searches in the trash, with
`isItem()` checking whether `._ObjectType` was `Item`. That left out
feed items (`._ObjectType` == `FeedItem`), and when c384fef867 made
`getSelectedItems()` return only items, it used `isItem()`, so feed
items were excluded, which broke feed-item toggling between read and
unread [1] and possibly some other things.
The simple fix would be to make `isItem` match feed items as well (which
could potentially fix other bugs related to feed items), but there was
actually no need to add new methods (which can get confused with
`CollectionTreeRow` methods) when we can just check the object type with
`obj instanceof Zotero.Item`, which gets the benefit of inheritance and
matches `Zotero.FeedItem` instances as well.
[1] https://forums.zotero.org/discussion/115571/cannot-change-the-status-of-title-in-subscribtion
Fix to breakage after 3f45def that would not open a duplicate
tab but instead create another reader instance in the same tab.
Instead of finding a tab for a specific item, use tabID that
is passed when reader should be loaded in an unloaded tab. That
allows us to know if the tab is being duplicated or not.
Fixes: #4272
Sidenav button pane IDs usually correspond to sections with the same
IDs, but `context-notes` actually corresponds to two sections
(`context-all-notes` and `context-item-notes`). We were preventing
those sections from being pinned, but not the button that reveals them.
Fixes#4283
This adds an explicit function on ZoteroPane and the item tree for
getting objects -- including collections and searches in the trash --
and limits `getSelectedItems()` to returning actual items from the
selection. We shim various item properties on the collections and
searches in the trash, but code that's getting the selection should be
explicit about what it wants. Outside of the trash, they're equivalent,
except `getSelectedObjects()` does have an `asIDs` mode.
This switches to using getSelectedObjects() in various places and fixes
collections in the trash appearing as belonging to My Publications when
using the collections-containing-an-item highlight [1].
This also adds support for highlighting the parent collections of
collections in the trash.
[1] https://forums.zotero.org/discussion/115449/zotero-7-beta-deleted-collection-appears-as-belonging-to-my-publications
- Remove unsaved creator row on blur or escape
- Rename "unsavedRow" for "position" as we want to be able to find
the relative position of creators after the next refresh not only
for unsaved rows. In many cases "unsavedRow" as returned by getCreatorFields
is the actual index of the creator row.
- Calculate and use "position" in getCreatorFields for all creator rows, not
only unsaved one, when a new row is being added.
This fixed a bug where wrong row gets focused if an unsaved creator row is
added, some text is typed and then another creator row below this unsaved row is clicked.
- fixed a bug where autocomplete options would not be updated after creator mode
is switched for the default empty row (if there are no creators)
- simplified paste handler of creators to use modifyCreator that
also shifts creators if a creator is unsaved. Fixed bug brought up in
https://github.com/zotero/zotero/pull/4165#issue-2313280474 where
pasting creators does not always focus the last added creator.
- Fixed another bug brought up in https://github.com/zotero/zotero/pull/4165#issue-2313280474
where shift-enter from creator before "_ more creators" label
will add a new row in the end instead of focusing the next creator.
- Fixed bug where adding a row right before "_ more creators" label
and blurring it will remove all creators after it. Now, clicking +
on a creator right before the "_ more creators" label will display
all creators and add a row after it.
- Fixed a bug where if "_ more creators" is present, editing
a creator name and pressing shift-enter would loose focus
instead of adding and focusing a new row in the end.
- Fixed a bug where focus got lost from some buttons
Fixes#4143Fixes#4241
- linked color scheme radio buttons to their label. Using
aria-describedby on individual radio buttons instead of
linking color scheme label to radiogroup because voiceover
does not announce the label in that case.
- linked item pane header dropdown to its label
- linked markdown and richtext note format checkboxes to their labels.
- added aria description to linked attachments base directory
so the input and "choose" button
- linked virtualized tables to their labels
Data directory location setting needs some more labeling as well
but it's mechanics should be generally reworked per vpat 50.
- if an unloaded tab is being opened, do not close the
tab and have reader re-open a fresh tab. Instead, keep the
tab as is, have reader use the tab as a container and
just change the tab's type. It should fix a glitch on
windows when if you click on a tab during initial loading,
it will disappear until reader re-adds it. A few tweaks
to allow unloaded tabs be generally "selectable".
Fixes: #4149
- during startup loading, select the yet-unloaded tab right
away. That way, a tab is almost immediately selected,
instead of being stuck on the library tab until the reader is ready.
- if the items are not loaded yet, use a placeholder
icon for tabs. Fixes: #4150
- special handling for reader loading message during initial
load. When an unloaded tab is selected, the loading message
needs to be displayed but, since there is no reader yet, we
add it in Zotero_Tabs.select and try to remove by the reader
when it's loaded.
- Use SVG icons
- Show "[x] collection selected" or "[x] searches selected" in the item pane
- Show "[x] objects selected" if multiple types are selected, which I
don't love, but I don't have a better idea
- Use existing strings for ARIA labels
When a collection or a saved search is deleted, it appears in
trash among other trashed items. From there, it can be restored
or permanently deleted.
Items of trashed collections are not affected my the trashing/permanent
deletion of a collection and need to be deleted separately like before.
Subcollections of a trashed collection do not appear in the trash and
are restored or permanently deleted with the top-most trashed parent.
Previously we were redownloading only `SYNC_STATE_TO_DOWNLOAD` files,
not `SYNC_STATE_FORCE_DOWNLOAD`, because the latter gets downloaded even
when using on-demand file syncing, but if the download fails for some
reason, it should be retried on a manual open.
If the header is in bibliography entry mode.
Instead of trying to focus editable-text of the header (which
may not be possible), just focus the next node after the header.
- Add pagination, limits, and Link header
- Add schema endpoints and dummy /settings endpoint
- Add /file endpoints
- Browser security restrictions prevent the web library from actually loading
the file: URIs that the local API returns, but out-of-browser use will work
fine
- Add toResponseJSONAsync() DataObject function: delegates to toResponseJSON()
by default, adds information that requires awaiting promises
- Best attachment (links.attachment) and file size (links.enclosure.length)
for items, meta.numItems for groups
- Separate function for compatibility with the existing test code that uses
toResponseJSON(), but we could consider unifying
This commit does not add the Access-Control headers that allow webpages to make
requests to the local API, since I don't think we actually want that.
This required some tweaks to other parts of Zotero infrastructure:
- Search:
- Add 'includeDeleted' condition to match behavior of 'includeTrashed' API
parameter in a single search
- Data objects:
- Improve toResponseJSON() implementations so output better matches the web
API
- Add toResponseJSON() to Zotero.Tags - has to be async so it can query the
database and generally works differently from other toResponseJSON()
functions, but accomplishes the same task
- Remove unused getAPIData() and apiDataGenerator() DataObject functions. They
aren't functional and wouldn't really make implementing the local server
easier, so now seemed like a decent time to remove them
- Server:
- Support resolving routes using pathparser.jsm
- Add allowMissingParams option to PathParser#add(): prevents /route from
matching /route/:param
- Replace the query property of the data object sent to endpoint init()s with
searchParams, an instance of URLSearchParams - supports #getAll() for
repeatable parameters
- URIs:
- Make getObjectURI() public, add utilities for converting URIs to API
endpoints and web library URLs
- Set the window minimum size to 700px x 500px.
- Fix a regression where non-applicable operators remain visible.
- Fix the "✔️" appearing next to multiple operators in the operator popup menu.
- Include the "Year" and "Attachments" columns by default in the results table.
- richlistbox shift-click selects a range starting with
_selectionStart. After a few cmd/ctrl clicks, _selectionStart
ends up not being correct - it can even point at an unselected item.
To help richlistbox properly select a range, before each click is
processed, reset _selectionStart to be either the first
or last selected item, depending on where shift-click landed.
- also, fixed a small glitch where inputs would be created if
you click on the red border outside of the actual editor.
Fixes: #4206
Use a regular paragraph for the intro text rather than an input
placeholder, which gets cut off it's too long, and allow the window to
be sized dynamically based on the title and localized strings.
Fixes#4109
"Note format" section in "Export" tab is technically a table and is
announced as such by screen readers, which is misleading.
It also opens a menulist when a checkbox is clicked, which is
not an expected behavior and can shift focus.
This refactors the "Note format" section to be a vbox container
with <checkbox>es and labels, which is more correct semantically and
does not confuse screen readers. In addition, when a chekbox is
clicked, dispatch a "change" event instead of unnecessarily open
up a menu.
- linked input/output file labels to the input fields so
they have descriptive names
- added more detailed button labels
- fixed "No file selected" not appearing if no file is selected
In libraries, notes and tags boxes, do not hide the actual
"-" toolbarbutton, hide the <image> inside of it. Visually,
it looks the same but the button can be focused via tab
without having to expicitly make it visible. It means that
shift-tab from the section header will not skip the "-" button.
Also, make "remove" toolbarbutton from tagsbox focusable like all
others for consistency.
- Linked remaining found inputs/menulists to their labels.
- Made the "Choose resolver" a proper visible
label, so that it does not oddly disappear if you click
on the dropdown with "Custom" showing after even if the
selection did not change. For the purpose of VPAT, a
visible label is always good for success criteria 3.3.2
https://www.w3.org/WAI/WCAG21/Understanding/labels-or-instructions
- Added explicit names to +/- buttons
- aria-labelledBy for inputs surrounded by text
- fluent strings for resolver preferences
- remove openURL.version preference, hardcode "1.0"
- added 8px padding around text on linux. Mac and win already have some
padding around text through --panel-padding. Fixes: zotero#4187
- guidancePanel.js fetches text from .ftl file instead of zotero.properties
- added first-run-guidance-quickFormat to zotero.ftl with updated
text to better reflect current functionality. Fixes: zotero#4191
- removed unnecessary special treatment for qf guidance panel on mac
- moved guidance panel text for itemBox creator menu into zotero.ftl
---------
strings tweaked by @dstillman
- multiple reference items can be selected with
shift-arrowUp/Down or Cmd/Ctrl-click and added as bubbles
via Enter or click on one of selected items
- Shift-click can be used to select the range of items
- if there is a retracted item among multiselected
that is not OK'd (cancel or view in library clicked),
no bubbles are added and the item is removed from
the multiselection
- added a red note to item's description indicating
if an item is retracted
* Improve feed item pane header (fixes#4141)
* Show item pane custom head when headerMode is none (fixes#4116)
* fx115: Fix button style on windows (fixes#4120)
* Move split-menu-button styles to SCSS
isSnapshotAttachment() checks the link mode (needs to be IMPORTED_URL),
but we actually allow viewing all attachments with text/html MIME types
as "snapshots" in the reader. Don't throw on any HTML attachment that
the reader is willing to open.
- 59afef6 added a duplicate assignment to item.rights that was putting
a TextConstruct(!!!!) in the item JSON field instead of a string
- info.rights was being set to a TextConstruct (preexisting issue!)
The 'blur' event needs to be dispatched by editable-text
before its state is reset (not after) because tagsbox uses
.initialValue in the 'blur' handler.
followup to 101e6d55d5Fixes: #3575