This wins us 65 new WPT subtest passes! It also shows up that we're
doing the wrong thing in ShorthandStyleValue in places, notably with
the grid properties. However, having one place to fix instead of two
will make it easier to correct them. :^)
In order to be fully correct, we should use the algorithm here:
https://drafts.csswg.org/cssom/#serialize-a-css-value
However, it's quite hand-wavy. What we do have in the meantime is
`ShorthandStyleValue::to_string()`, where we special-case the
serialization rules for shorthands with a generic fallback that's
equivalent to what the previous `get_property_value()` code was doing.
When attempting to set `HTMLProgressElement.max` to a value not greater
than 0, we were previously setting the value to 1. We now retain the
previous value.
This change ensures that the correct default value of 0 is used and
that values greater than 2147483647 will fall back to the default value.
It also splits the display size concept into a separate method, as
this isn't supposed to be used when getting the IDL property.
Attempting to set `HTMLInputElement.size` to 0 via IDL now throws an
IndexSizeError DOMException. Attempting to set it to a value larger
than 2147483647 results in it being set to the default value.
If `HTMLMarqueeElemnt.scrollAmount` or `HTMLMarqueeElemnt.scrollDelay`
is set to a value larger than 2147483647, then it should be set to its
default value.
When serializing an sRGB color value that originated from a named color,
it should return the color name converted to ASCII lowercase. This
requires storing the color name (if it has one).
This change also requires explicitly removing the color names when
computing style, because computed color values do not retain their name.
It also requires removing a caching optimization in create_from_color(),
because adding the name means that the cached value might be wrong.
This fixes some WPT subtests, and also required updating some of our own
tests.
Previously, the list was copied when constructing the FormData object,
then the original list was passed to the event, meaning any changes to
the list that happened within the event would not be reflected outside
of it.
This is required by mini Cloudflare invisible challenges, as it will
only run if the readyState is not "loading". If it is "loading", then
it waits for readystatechange to check that it's not "loading" anymore.
Initial about:blank iframes do not go through the full navigation and
thus don't go through HTMLParser::the_end, which sets the ready state
to something other than "loading". Therefore, the challenge would never
run, as readyState would never change.
Seen on https://discord.com/login
The MessagePort one in particular is required by Cloudflare Turnstile,
as the method it takes to run JS in a worker is to `eval` the contents
of `MessageEvent.data`. However, it will only do this if
`MessageEvent.isTrusted` is true, `MessageEvent.origin` is the empty
string and `MessageEvent.source` is `null`.
The Window version is a quick fix whilst in the vicinity, as its
MessageEvent should also be trusted.
The insertion steps for iframes were following an old version of the
spec, where it was checking if the iframe was "in a document tree",
which doesn't cross shadow root boundaries. The spec has since been
updated to check the shadow including root instead.
This is now needed for Cloudflare Turnstile iframe widgets to appear,
as they are now inserted into a shadow root.
This was preventing https://ubereats.com/ from fully loading, because
they are attempting to overwrite setItem. They seem to be trying to add
error logging to setItem if it throws, as all they do is add a
try/catch block that emits an error log to their monitoring service if
it throws.
However, because Storage is a legacy platform object with a named
property setter (setItem), it will call setItem with the stringified
version of the function. This is actually expected as per the spec,
Firefox (Gecko) and Epiphany (WebKit) does this too, but Chromium does
not as it actually overwrites the function with the new function and
does not store the stringified function.
The problem is that we had the LegacyOverrideBuiltIns flag accidentally
set, so it would return the stored string instead of the built-in
function (hence the name), then it would try and call it and throw a
"not a function" error. This prevented their JS from going any further.
This fix allows their UI to fully load and be fully interactive, though
it is quite slow at the moment!
This is enough for a basic shadow realm to work :^)
There is more that we still need to implement here such as module
loading and fixing up the global object, but this is enough to get some
basic usage working.
If the attribute value is the empty string `(lang="")`, the language
is set to unknown. `lang` attribute higher up in the document tree
will no longer be applied to the content of that element.
We guarded one step against a null navigable, but the very next step
also needs to be protected. Let's just abort early instead. This was
caught by the following imported WPT test:
html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.html
This test adds a <frame> element and immediately removes it, but the
task to process the src attribute is already queued. Note that <iframe>
would have the same issue, but this test does not include them.
NavigableContainer is our home grown concept which already contains the
AOs needed for frame and iframe elements. This patch simply aligns our
HTMLFrameElement implementation with this class.
A couple of notes:
1. The <script> in the <head> element is intentional. The <frameset>
element effectively takes the place of the <body> element, and we
cannot add a <script> to a <frameset> element.
2. We don't render <frameset> or <frame> at all. Rendering is defined
in the following spec:
https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets
3. If you load the test page in your browser, you won't see anything,
regardless of (2). Our test infra adds a <pre> element to the "body"
element (which is the <frameset> element here). Such children will
never be rendered. In the future, we could come up with something
better for our test infra to do, but this isn't important anyways
for this test - we can still grab the <pre> element's innerText.
Stealing the callbacks from the AnimationFrameCallbackDriver made them
no longer safe from GC. Continue to store them on the class until we
have finished their execution.
Better support for CSS shorthands when setting the style attribute. This
improves some tests in WPT /css/css-align/default-alignment/*shorthand.
When setting the style attribute in JS via element.style = '..' or the
setAttribute method, shorthand properties were not expanded to longhand
properties.
Previously, attempting to parse a floating point number with an integer
part larger than `(2 ^ 31) - 1` would cause the browser to crash. We now
avoid this by converting the integer part of the number to a `double`
rather than an `i32`.
The spec says that "isTrusted is a convenience that indicates whether
an event is dispatched by the user agent (as opposed to using
dispatchEvent())"
But when dispatching a pageshow event the flag was incorrectly set
to false.
This fixes https://wpt.fyi/results/html/syntax/parsing/the-end.html
We were hard-coding "about:blank" as the document URL for parsed HTML
documents, which was definitely not correct.
This fixes a bunch of WPT tests under /domparsing/ :^)
This resolves all WPT timeouts in html/canvas/element/manual/imagebitmap
We can now run an additional 6 tests and 126 subtests :)
This also adds regression tests for this behavior.
InlinePaintable was an ad-hoc paintable type required to support the
fragmentation of inline nodes across multiple lines. It existed because
there was no way to associate multiple paintables with a single layout
node. This resulted in a lot of duplicated code between PaintableBox and
InlinePaintable. For example, most of the CSS properties like
background, border, shadows, etc. and hit-testing are almost identical
for both of them. However, the code had to be duplicated to account for
the fact that InlinePaintable creates a box for each line. And we had
quite many places that operate on paintables with a code like:
```
if (box.is_paintable_box()) {
// do something
} else (box.is_inline_paintable()) {
// do exactly the same as for paintable box but using InlinePaintable
}
```
This change replaces the usage of `InlinePaintable` with
`PaintableWithLines` created for each line, which is now possible
because we support having multiple paintables per layout node. By doing
that, we remove lots of duplicated code and bring our implementation
closer to the spec.
DedicatedWorkerGlobalScope is an object with a Global extended
attribute, but does not define any named property getters. This needs to
be handled by setting the prototype chain to:
DedicatedWorkerGlobalScope
^ DedicatedWorkerGlobalScopePrototype
^ WorkerGlobalScopePrototype
(This is different from something like Window, where there is an
intermediate WindowProperties object for named properties.)
Previously, we treated the GlobalMixin object as if it was a simple
prototype object, accidentally setting DedicatedWorkerGlobalScope's
prototype to WorkerGlobalScopePrototype. This caused the expression
self instanceof DedicatedWorkerGlobalScope
to return false inside workers.
This makes us pass many more of the "/xhr/idlharness.any.worker" WPT
tests than before, rather than failing early.
Fixes at least one WPT test that was previously timing out:
- html/semantics/document-metadata/the-base-element/base_target_does_not_affect_iframe_src_navigation.html
For example, in the following abbreviated test HTML:
<span>some text</span>
<script>println("whf")</script>
We would have to craft the expectation file to include the "some text"
segment, usually with some leading whitespace. This is a bit annoying,
and makes it difficult to manually craft expectation files.
So instead of comparing the expectation against the entire DOM inner
text, we now send the inner text of just the <pre> element containing
the test output when we invoke `internals.signalTextTestIsDone`.