This fixes a bug when using the <kbd>Home</kbd> and <kbd>End</kbd> keyboard shortcuts to navigate through a `Menu` instance. These two buttons didn't update the `#lastIndex` field, which means that e.g. a following <kbd>ArrowDown</kbd> or <kbd>ArrowUp</kbd> press could make focus "jump" to an unexpected menu-item.
Also, the helper method reduces a little bit of code duplication in the event handlers.
Matching the name with a leading `.+` is quadratic in the length of
a component which doesn't end with a position, and every AcroForm
field name goes through this.
`toFixed(10)` switches to the exponential notation from 1e21 on, which isn't
valid PDF syntax, and removing the trailing zeros then dropped a digit of the
exponent: 1e30 was written "1e+3" and 1e100 "1e+1". Such a number, necessarily
an integer, is now written with all its digits.
The trailing zeros are removed with a backward scan, since `toFixed(10)` always
produces exactly 10 decimals. Below the 1e21 limit its output is at most 33
characters long, so the previous `$`-anchored regex wasn't a performance issue.
The local part and the domain labels were unbounded, making the
search quadratic in the length of a run of characters preceding
an "@": scanning the text of a single page could take seconds.
Compared to regular Objects there's a number of advantages to using Maps:
- They support proper iteration.
- They have a simple way to check for the existence of data.
- They have a simple/efficient way to check the number of elements.
If this functionality was added today, I cannot imagine that we'd choose an Object for this data.
In the Firefox PDF Viewer sending Maps to the scripting-implementation should be fine, since it uses the browser `Cu.cloneInto` functionality; see https://searchfox.org/firefox-main/source/toolkit/components/pdfjs/content/PdfSandbox.sys.mjs
However with QuickJS, used by the GENERIC viewer, all data needs to be stringified and Maps are converted into regular Objects (see also PR 21664). Hence the `objects` property, in the scripting-implementation, is converted back into a Map using the (renamed) `createMap` helper function.
In PR 12569 the `_actions` class-field was changed from an Object into a Map, with *most* of the code updated to reflect that.
However, in the `setAction` method it's still treated as an Object which means that any added script will simply be ignored. Most likely that part of the scripting-implementation isn't being used, since this code has been "wrong" for close to six years now.
Scanning to the end of the string for every "&" made the entity
resolution quadratic. Stopping at the next "&" also fixes a bare
ampersand swallowing the reference which follows it.
Finding the word to delete with a regex is quadratic in the value
length, so each "delete word backward" keystroke could take a long
time in a large field.
Searching for a name followed by ".pdf" is quadratic on a hash which
doesn't contain one, so locate the last ".pdf" first and then extend
it to the left.
Removing the trailing whitespace with a `$`-anchored regex is
quadratic in the length of the run, which a server controls.
The helper lives in network_utils.js, to be unit testable.
`String.fromCodePoint` throws on anything which isn't a code point,
so e.g. "&#xZZ;" or "�" aborted the whole parsing. Such a
reference is now kept as-is, like an unknown named entity.
During two-finger gestures, keep preventing the default action on pointerup/pointercancel, but don't stop propagation. Resize/drag sessions need those bubble events to clean up.
`TouchManager` computes the pinch distances with the screen coordinates, but it
was passing the pinch center in that space too, while the viewer expects a
client coordinate, like the origin coming from a wheel event.
Since a two-finger gesture can be synthesized with WebDriver BiDi, the
pinch-zoom test doesn't have to rely on CDP anymore and can run in Chrome, where
it fails without the above fix.
In a couple of cases, where a boolean is returned, it's also possible to use an OR operator rather a ternary.
*Note:* This patch reduces the size of the `gulp mozcentral` bundle by `960` bytes.
The chrome is now authored against Firefox design-token names with the shipped
value as a fallback `var(--fx-token, <literal>)` so colors, borders and radii
follow Firefox instead of having to be re-synced by hand.
In MOZCENTRAL viewer.css imports chrome://global/skin/design-system/tokens-brand.css,
gated on the new pdfjs.enableNova pref (default false, read straight from CSS via -moz-pref()).
With the pref off the sheet isn't applied, every fallback resolves, and the
viewer renders as before, as it also does in the GENERIC and components builds,
which never see the chrome sheet.
Consuming a token means never declaring its name in an unlayered rule, which
would shadow Firefox's for the whole subtree; --focus-outline, --border-color and
--text-color/--button-border-color are therefore renamed to
--editor-selection-outline, --signature-border-color and --views-*. In forced
colors each state reads a matching background/foreground/border triple so it
can't collapse to a single system color.
The dialog button styling also moves out of `.dialog .mainContainer button` into
a shared .primaryButton/.secondaryButton primitive (buttons.css, imported from
pdf_viewer.css so the components build gets it too). The password,
document-properties, print and undo-bar buttons use it in place of .dialogButton,
and the custom radio appearance gives way to native controls tinted with
accent-color.