getComputedStyle(element) now returns a ComputedCSSStyleDeclaration
object, which is a live view of the computed style of a given element.
This works by ComputedCSSStyleDeclaration being a wrapper around an
element pointer. When you ask it for a CSS property, it gets the latest
computed style values from the element and returns them as a
CSS::StyleProperty object.
This first cut adds support for computed 'color' and 'display'.
In case the element doesn't have a corresponding node in the layout
tree, we fall back to using specified style instead. This is achieved by
performing an on-the-fly style resolution for the individual element and
then grabbing the requested property from that resolved style.
This patch moves the CSS property+value storage down to a new subclass
of CSSStyleDeclaration called PropertyOwningCSSStyleDeclaration.
The JavaScript wrapper for CSSStyleDeclaration now calls virtual
functions on the C++ object.
This is preparation for supporting computed style CSSStyleDeclaration
objects which won't have internal property storage, but rather an
internal element pointer. :^)
When debugging why your website isn't loading in LibWeb the
resource loader is a blind spot as we don't have much logging
except on certain error paths. This can lead to confusing situations
where the browser just appears to hang.
This changes attempts to fix that by adding common success and
failure logging handlers so all resource loading outcomes can
are logged.
The StyleProperties code for opacity existed before NumericStyleValue
was a thing, and was affected by over-enthusiastic unitless-length
parsing, so it assumed everything was a length. Now it matches the
Color4 spec instead, accepting either a number, or a percentage.
We also get to remove the hack! :^)
Previously, we applied the unitless length quirk to all numbers in
quirks mode. Now, we correctly only do so for the set of properties
listed in the quirks-mode spec:
https://quirks.spec.whatwg.org/#quirky-length-value
However, we do not yet prevent this quirk inside CSS expressions (like
`calc()`) as the spec directs.
After `parse_css_value(PropertyID, TokenStream)`, we only need to know
the current PropertyID when checking for property-specific quirks, which
will take place in only 2 places, which happen deep down. Making the
current PropertyID part of the context means that those places can check
it easily, without us having to pass it to every one of the parsing
functions, which otherwise do not care.
Two CSS quirks are specced to only apply to specific properties:
- The hashless hex color quirk
https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
- The unitless length quirk
https://quirks.spec.whatwg.org/#the-unitless-length-quirk
These are now represented in `Properties.json` like so:
```json
"property-name-here": {
"quirks": [
"hashless-hex-color",
"unitless-length"
]
}
```
Every property that either of those two quirks applies to is included in
`Properties.json` and now has their quirks listed. :^)
This fixes#9978.
When a TokenStream is empty, reading its `current_token()` still returns
a token (for EOF) so it makes sense to allow users to
`reconsume_current_input_token()` that token, so they do not have to
handle that themselves. Instead of VERIFY()ing, we can just no-op when
reconsuming token 0.
There were a few calls to the standalone version of dump_tree() inside
the recursive version of dump_tree(), which led to the output getting
jumbled out of order.
This is the result of debugging React DOM, which would throw a TypeError
when assigning to window.event in strict mode and then not complete
rendering - here:
cae6350/packages/shared/invokeGuardedCallbackImpl.js (L134)
With this change, the following minimal React example now works!
<div id="app"></div>
<script src="react.development.js"></script>
<script src="react-dom.development.js"></script>
<script>
ReactDOM.render(
React.createElement("h1", null, "Hello World"),
document.getElementById("app")
);
</script>
The [Replaceable] attribute "indicates that setting the corresponding
property on the platform object will result in an own property with the
same name being created on the object which has the value being
assigned. This property will shadow the accessor property corresponding
to the attribute, which exists on the interface prototype object."
(https://heycam.github.io/webidl/#Replaceable)
The spec doesn't tell how exactly this is supposed to be done, but other
engines just have a setter as well that just redefines the property
as a data descriptor when called, and returns undefined.
It's bound to the property name and requires an object of the correct
type, so I mirrored these constraints here. Storing the setter and
calling it multiple times will therefore just work.
Implementing this in the wrapper generator is left as an exercise for
the reader, this is going to be used in WindowObject, which isn't
generated from IDL yet.
We need both a GlobalObject and Realm now, but can get the former from
the latter (once initialized).
This also fixes JS execution in LibWeb, as we failed to set the Realm of
the newly created Interpreter in this function.
The spec allows us to optionally return from these for any reason.
Our reason is that we don't have all the infrastructure in place yet to
implement them.
... and `Window.scrollTo()`, which is an alias for `scroll()`.
There is still work that needs to be done here, regarding bringing the
scroll position calculation in line with the spec. Currently we get the
viewport rect from outside, and treat it as if it was the result of
calculating steps 5-9 of the `scroll()` method. But it works. :^)
This is in preparation for implementing JS scrolling functions, which
specify both x and y scrolling deltas. The visible behavior has not
changed.
Also, moved the "mouse wheel delta * 20" calculation to the
`EventHandler` since the JS calls will want to work directly in pixels.
This just returns an empty CSSStyleDeclaration for now. The real thing
needs to be a live object that provides a view onto the computed style
of a given element. This is far from that, but it's something. :^)
Any browsing context that doesn't have a parent browsing context is now
considered a top-level browsing context. This matches the HTML spec.
This means we no longer keep a pointer to the top-level context, since
we can simply walk the parent chain until we find the topmost ancestor.
Before this patch, HTMLScriptElement would cache the full script source
text in a String member, and parse that just-in-time via Document's
run_javascript() helpers.
We now follow the spec more closely and turn the incoming source text
into a ClassicScript object ("the script's script" in the spec.)
Let's err on the side of caution and use a WeakPtr instead of a
DOM::Document&. Even if the object lifetimes involved here should be
well-defined, they are fairly complicated.