Also removing a FIXME about not covering all of the event names as it is
not exactly clear when such a FIXME would be addressed, especially as
these come from multiple specifications.
Now, along with the mouse events we also dispatch pointerup, pointerdown
and pointermove.
With this change shape painting works on https://excalidraw.com/
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 commit introduces proper handling of three intrinsic size keywords
when used for CSS heights:
- min-content
- max-content
- fit-content
This necessitated a few plumbing changes, since we can't resolve these
values without having access to containing block widths.
This fixes some visual glitches on https://www.supabase.com/ as well
as a number of WPT tests. It also improves the appearance of dialogs.
For example, in the following HTML:
```html
<label>
<input type="radio" name="fruit" value="apple" id="radio1">
<span class="box"></span>
</label>
```
When any descendant of a <label> element is clicked, a "click" event
must be dispatched on the <input> element nested within the <label>, in
addition to the "click" event dispatched on the clicked descendant.
Previously, this behavior was implemented only for text node descendants
by "overriding" the mouse event target using `mouse_event_target()` in
the TextPaintable. This approach was incorrect because it was limited to
text nodes, whereas the behavior should apply to any box. Moreover, the
"click" event for the input control must be dispatched *in addition* to
the event on the clicked element, rather than redirecting it.
The clientX and clientY values are, as per the spec, the offset from
the viewport.
This makes them actually be that and also fixes up the calculations
for offsetX, offsetY, pageX and pageY.
I assume all of these got messed up in some sort of refactor in the
past.
The spec comment from the now-removed
compute_mouse_event_client_offset() function sadly has no convenient
place to be anymore so, for now, it is just gone as well.
Personally, I think it'd make sense to refactor a lot of this file so
that not every mouse event repeats a large chunk of (almost) identical
code. That way there'd be a nice place to put the comment without
repeating it all over the file.
But that is out of the scope of this PR.
Also: I know, offsetX and Y are not fully fixed yet, they still
don't ignore the element's CSS transforms but I am working on that
in a new PR.
This change fixes unhoverable toolbar on https://excalidraw.com/
The problem was that React.js uses setProperty() to add style properties
specified in the "style" attribute in the virtual DOM, and we were
failing to add the CSS variable used to set the "pointer-events" value
to "all".
See previous the commit description for more details about the floating
points operations.
The hwb test cases in `css-color-functions` are now rendered identically
to what firefox does (I haven't checked the others tests, but they
aren't affected by this commit).
In line with the ShadowRealm proposal changes in the WebIDL spec:
webidl#1437 and supporting changes in HTML spec.
This is required for ShadowRealms as they have no relevant settings
object on the shadow realm, so fixes a crash in the QueueingStrategy
test in this commit.
These interfaces are exposed on *, meaning it should work for workers
and our newly added shadow realm global object by being stored on the
universal global scope mixin.
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
CDATASection inherits from Text, and so it was incorrect for them to
claim not to be Text nodes.
This fixes at least two WPT subtests. :^)
It also exposed a bug in the DOM Parsing and Serialization spec,
where we're not told how to serialize CDATASection nodes.
Spec bug: https://github.com/w3c/DOM-Parsing/issues/38
Instead of checking the header in ZlibDecompressor::create(), we now
check it in read_some() when it is called for the first time. This
resolves a FIXME in the new DecompressionStream implementation.
Implemented by reusing AddMask display list item that was initially
added for `background-clip` property.
Progress on flashlight effect on https://null.com/games/athena-crisis
I believe this is an error in the UI Events spec, and it should be
updated to match the HTML spec (which uses WindowProxy everywhere).
This fixes a bunch of issues already covered by existing WPT tests.
Spec bug: https://github.com/w3c/uievents/issues/388
Note that WebKit has been using WindowProxy instead of Window in
UI Events IDL since 2018:
816158b4aa
TL;DR: There are two available sets of coefficients for the conversion
matrices from XYZ to sRGB. We switched from one set to the other, which
is what the WPT tests are expecting.
All RGB color spaces, like display-p3 or rec2020, are defined by their
three color chromacities and a white point. This is also the case for
the video color space Rec. 709, from which the sRGB color space is
derived. The sRGB specification is however a bit different.
In 1996, when formalizing the sRGB spec the authors published a draft
that is still available here [1]. In this document, they also provide
the matrix to convert from the XYZ color space to sRGB. This matrix can
be verified quite easily by using the usual math equations. But hold on,
here come the plot twist: at the time of publication, the spec contained
a different matrix than the one in the draft (the spec is obviously
behind a pay wall, but the numbers are also reported in this official
document [2]). This official matrix, is at a first glance simply a
wrongly rounded version of the one in the draft publication. It however
has some interesting properties: it can be inverted twice (so a
roundtrip) in 8 bits and not suffer from any errors from the
calculations.
So, we are here with two versions of the XYZ -> sRGB matrix, the one
from the spec, which is:
- better for computations in 8 bits,
- and official. This is the one that, by authority, we should use.
And a second version, that can be found in the draft, which:
- makes sense, as directly derived from the chromacities,
- is publicly available,
- and (thus?) used in most places.
The old coefficients were the one from the spec, this commit change them
for the one derived from the mathematical formulae. The Python script to
compute these values is available at the end of the commit description.
More details about this subject can be found here [3].
[1] https://www.w3.org/Graphics/Color/sRGB.html
[2] https://color.org/chardata/rgb/sRGB.pdf
[3] https://photosauce.net/blog/post/making-a-minimal-srgb-icc-profile-part-3-choose-your-colors-carefully
The Python script:
```python
# http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html
from numpy.typing import NDArray
import numpy as np
### sRGB
# https://www.w3.org/TR/css-color-4/#predefined-sRGB
srgb_r_chromacity = np.array([0.640, 0.330])
srgb_g_chromacity = np.array([0.300, 0.600])
srgb_b_chromacity = np.array([0.150, 0.060])
##
## White points
white_point_d50 = np.array([0.345700, 0.358500])
white_point_d65 = np.array([0.312700, 0.329000])
#
r_chromacity = srgb_r_chromacity
g_chromacity = srgb_g_chromacity
b_chromacity = srgb_b_chromacity
white_point = white_point_d65
def tristmimulus_vector(chromacity: NDArray) -> NDArray:
return np.array([
chromacity[0] /chromacity[1],
1,
(1 - chromacity[0] - chromacity[1]) / chromacity[1]
])
tristmimulus_matrix = np.hstack((
tristmimulus_vector(r_chromacity).reshape(3, 1),
tristmimulus_vector(g_chromacity).reshape(3, 1),
tristmimulus_vector(b_chromacity).reshape(3, 1),
))
scaling_factors = (np.linalg.inv(tristmimulus_matrix) @
tristmimulus_vector(white_point))
M = tristmimulus_matrix * scaling_factors
np.set_printoptions(formatter={'float_kind':'{:.6f}'.format})
xyz_65_to_srgb = np.linalg.inv(M)
# http://www.brucelindbloom.com/index.html?Eqn_ChromAdapt.html
# Let's convert from D50 to D65 using the Bradford method.
m_a = np.array([
[0.8951000, 0.2664000, -0.1614000],
[-0.7502000, 1.7135000, 0.0367000],
[0.0389000, -0.0685000, 1.0296000]
])
cone_response_source = m_a @ tristmimulus_vector(white_point_d50)
cone_response_destination = m_a @ tristmimulus_vector(white_point_d65)
cone_response_ratio = cone_response_destination / cone_response_source
m = np.linalg.inv(m_a) @ np.diagflat(cone_response_ratio) @ m_a
D50_to_D65 = m
xyz_50_to_srgb = xyz_65_to_srgb @ D50_to_D65
print(xyz_50_to_srgb)
print(xyz_65_to_srgb)
```