Every user of HTMLCollection does not expect the root node to be a
potential match, so let's avoid it by using non-inclusive sub-tree
traversal. This avoids matching the element that getElementsByTagName
was called on for example, which is required by Ruffle:
da689b7687/web/packages/core/src/ruffle-object.ts (L321-L329)
Log a FIXME on the debug log, along with a layout tree dump of the box
that we didn't expect to see. This will be annoying (until fixed),
but far less so than crashing the browser.
Some of these are allocated upon initialization of the intrinsics, and
some lazily, but in neither case the getters actually return a nullptr.
This saves us a whole bunch of pointer dereferences (as NonnullGCPtr has
an `operator T&()`), and also has the interesting side effect of forcing
us to explicitly use the FunctionObject& overload of call(), as passing
a NonnullGCPtr is ambigous - it could implicitly be turned into a Value
_or_ a FunctionObject& (so we have to dereference manually).
VALUES-4 defines the internal representation of `calc()` as a tree of
calculation nodes. ( https://www.w3.org/TR/css-values-4/#calc-internal )
VALUES-3 lacked any definition here, so we had our own ad-hoc
implementation based around the spec grammar. This commit replaces that
with CalculationNodes representing each possible node in the tree.
There are no intended functional changes, though we do now support
nested calc() which previously did not work. For example:
`width: calc( 42 * calc(3 + 7) );`
I have added an example of this to our test page.
A couple of the layout tests that used `calc()` now return values that
are 0.5px different from before. There's no visual difference, so I
have updated the tests to use the new results.
This makes it possible to do arithmetic on them without having to
resolve to their canonical unit, which often requires context
information that is not available until the last minute. For example, a
Length cannot be resolved to px without knowing the font size, parent
element's size, etc.
Only Length currently requires such context, but treating all these
types the same means that code that manipulates them does not need to
know or care if a new unit gets added that does require contextual
information.
Level 4 drops the limitations of what types can be a denominator, which
means `<calc-number-sum>`, `<calc-number-product>` and
`<calc-number-value>` all go away.
This is not documented yet, but the preferred style is getting both
upfront instead of inlining various kinds of calls in places that use
the realm and vm.
read_webp_first_chunk() sensibly assumes that if decode_webp_header()
succeeds, there are at least sizeof(WebPFileHeader) bytes available.
But if the file size in the header was less than the size of the header,
decode_webp_header() would truncate the data to less than that and
happily report success. Now it no longer does that.
Found by clusterfuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=57843&sort=-opened&can=1&q=proj%3Aserenity
No behavior change.
(Well, technically mix() uses the other simple implementation of lerp
and the two have slightly different behavior if the arguments are of
very different magnitude and in various corner cases. But in practice,
for ICC profiles, it shouldn't matter. For a few profiles I tested, it
didn't have a measurable effect.)
PR #18166 introduced the ability to parse ECC certificates. If we
now fail here the reason is mostlikely something new and we should
prevent this rabbit hole from happening.
Some refactoring of our root ca loading process:
- Remove duplicate code
- Remove duplicate calls to `parse_root_ca`
- Load user imported certificates in Browser/RequestServer
StartingStateHandler and SeekingStateHandler were declaring their own
`bool m_playing` fields (from previous code where there was no base
class).
In the case of SeekingStateHandler, this only made the logging wrong.
For StartingStateHandler, however, this meant that it was not using
the boolean passed as a parameter to the constructor to define the
state that would be transitioned to after the Starting state finished.
This meant that when the Stopping state replaced itself with the
Starting state, playback would not resume when Starting state exits.
This is needed for hit testing the directional arrows on the Street
View office tour, and generally makes SVG hit testing more precise.
Note: The rough bounding box is hit test first, so this should not
be a load more overhead.
This also combines the viewbox mapping into the same transform and
reuses some code by using Path::copy_transformed() rather than manually
mapping each segment of the path.
Previously, if you had an SVG with a viewbox and a definite width
and height, then all SVGGeometryBox boxes within that SVG would
have a width and height set to the size of the parent SVG.
This broke hit testing for SVG paths, and didn't make much sense.
It seems like the SVG sizing hack was patching over the incorrect
logic in viewbox_scaling() and the incorrect path sizing (which was
never reached).
Before this change the view box scaling was:
element_dimension / viewbox_dimension
Which only seemed to work because of the SVG sizing hack that made
all paths the size of the containing SVG.
After this change SVGGeometryBoxes are (in most cases) sized correctly
based on their bounding boxes, which allows hit testing to function,
and the view box scaling is updated now to:
containing_SVG_dimension / viewbox_dimension
Which works with one less hack :^)
This now also handles centering the viewbox within the parent SVG
element and applying any tranforms to the bounding box. This still
a bit ad-hoc, but much more closely matches other browsers now.
This uses the new attribute parser functionality, and then resolves the
transform list into a single Gfx::AffineTransform.
This also adds a .get_transform() function which resolves the final
transform, by applying all parent transforms.
This parses SVG transforms using the syntax from CSS Transforms
Module Level 1. Note: This looks very similar to CSS tranforms, but
the syntax is not compatible. For example, SVG rotate() is
rotate(<a> <x> <y>) where all parameters are unitless numbers whereas
CSS rotate() is rotate(<angle> unit) along with separate rotateX/Y/Z().
(At the same time AttributeParser is updated to use GenericLexer which
makes for easier string matching).
There is work needed for error handling (which AttributeParser does not
deal with very gracefully right now).