Some tests take longer than others, and so may want to set a custom
timeout so that they pass, without increasing the timeout for all other
tests. For example, this is done in WPT.
Add an `internals.setTestTimeout(milliseconds)` method that overrides
the test runner's default timeout for the currently-run test.
That is what the spec calls it, at least.
In code, this manifests as making the offset very aware
of the element's transform, because the click position comes
relative to the viewport, not to the transformed element.
There are essentially 3 URL parsing AOs defined by the spec:
1. Parse a URL
2. Encoding parse a URL
3. Encoding parse a URL and serialize the result
Further, these are replicated between the Document and the ESO.
This patch defines these methods in accordance with the spec and updates
existing users to invoke the correct method. In places where the correct
method is ambiguous, we use the encoding parser to preserve existing ad-
hoc behavior.
The DOM spec defines what it means for an element to be an "editing
host", and the Editing spec does the same for the "editable" concept.
Replace our `Node::is_editable()` implementation with these
spec-compliant algorithms.
An editing host is an element that has the properties to make its
contents effectively editable. Editable elements are descendants of an
editing host. Concepts like the inheritable contenteditable attribute
are propagated through the editable algorithm.
Before, on a mouse-move event, if the hovered html element did not have
a tooltip or it was not a link, `page_did_leave_tooltip_area()` and
`page_did_unhover_link()` virtual functions would get called.
Now, the page remembers if it is in a tooltip area or hovering a link
and only informs of leaving or unhovering only if it was.
Before, on *every* mouse-move event, `page_did_request_cursor_change()`
virtual function would get called, requesting to change cursor to the
event's mouse position's cursor.
Now, the page keeps track of the last cursor change that was requested
("page's current cursor") and only requests cursor change again if and
only if the current cursor is not already the one that is required.
Now, along with the mouse events we also dispatch pointerup, pointerdown
and pointermove.
With this change shape painting works on https://excalidraw.com/
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.
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
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:
* JS::NonnullGCPtr -> GC::Ref
* JS::GCPtr -> GC::Ptr
* JS::HeapFunction -> GC::Function
* JS::CellImpl -> GC::Cell
* JS::Handle -> GC::Root
Now that the heap has no knowledge about a JavaScript realm and is
purely for managing the memory of the heap, it does not make sense
to name this function to say that it is a non-realm variant.
Having the text cursor disappear during rapid continuous editing is
quite jarring, so let's make sure we always restart the blink cycle
whenever the user performs some kind of editing action in a frame.
Problem:
- `(void)` simply casts the expression to void. This is understood to
indicate that it is ignored, but this is really a compiler trick to
get the compiler to not generate a warning.
Solution:
- Use the `[[maybe_unused]]` attribute to indicate the value is unused.
Note:
- Functions taking a `(void)` argument list have also been changed to
`()` because this is not needed and shows up in the same grep
command.
FrameLoader now begins by constructing a DOM::Document, and then builds
a document tree inside it based on the MIME type. For text/html we pass
control to the HTMLDocumentParser as before.
This gives us access to things like window.alert() during parsing.
Fixes#3973.
Instead of storing them as CSS::Lengths, we now store the resolved
values for margin/padding/border/offset top/right/bottom/left with
each Layout::NodeWithStyleAndBoxModelMetrics.
This simplifies a lot of code since it's no longer necessary to
resolve values before using them.
This isn't entirely symmetrical with on_load_start as it will also fire
on reloads and back/forward navigations. However, it's good enough for
some basic use cases, and we can do more sophisticated notifications
later on when we need them.
Layout was using an outdated viewport rect that we set *after* doing
a layout due to resize. That meant that layout-in-response-to-resize
was always lagging behind the current size of the view.
The root of this problem was how Frame kept both a viewport rect
(with both scroll offset and size) and a frame size. To fix this,
only store the viewport scroll offset, and always use the frame size.
This way they can't get out of sync and the problem goes away. :^)
Fixes#4250.
We didn't notice that the layout tree had disappeared after dispatching
a mousedown event, because we only checked EventHandler::layout_root()
which happily returned the *new* layout tree after a window.reload().
This patch fixes that by verifying that the frame is still showing the
same DOM's layout tree after event dispatch.
Fixes#4224.
Bring the names of various boxes closer to spec language. This should
hopefully make things easier to understand and hack on. :^)
Some notable changes:
- LayoutNode -> Layout::Node
- LayoutBox -> Layout::Box
- LayoutBlock -> Layout::BlockBox
- LayoutReplaced -> Layout::ReplacedBox
- LayoutDocument -> Layout::InitialContainingBlockBox
- LayoutText -> Layout::TextNode
- LayoutInline -> Layout::InlineNode
Note that this is not strictly a "box tree" as we also hang inline/text
nodes in the same tree, and they don't generate boxes. (Instead, they
contribute line box fragments to their containing block!)
This patch makes Page weakable and allows page-less frames to exist.
Page is single-owner, and Frame is multiple-owner, so it's not sound
for Frame to assume its containing Page will stick around for its own
entire lifetime.
Fixes#3976.
This makes most operations thread safe, especially so that they
can safely be used in the Kernel. This includes obtaining a strong
reference from a weak reference, which now requires an explicit
call to WeakPtr::strong_ref(). Another major change is that
Weakable::make_weak_ref() may require the explicit target type.
Previously we used reinterpret_cast in WeakPtr, assuming that it
can be properly converted. But WeakPtr does not necessarily have
the knowledge to be able to do this. Instead, we now ask the class
itself to deliver a WeakPtr to the type that we want.
Also, WeakLink is no longer specific to a target type. The reason
for this is that we want to be able to safely convert e.g. WeakPtr<T>
to WeakPtr<U>, and before this we just reinterpret_cast the internal
WeakLink<T> to WeakLink<U>, which is a bold assumption that it would
actually produce the correct code. Instead, WeakLink now operates
on just a raw pointer and we only make those constructors/operators
available if we can verify that it can be safely cast.
In order to guarantee thread safety, we now use the least significant
bit in the pointer for locking purposes. This also means that only
properly aligned pointers can be used.
When the user right-clicks on an image, you might want to show a
special context menu, separate from the regular link context menu.
This patch only implements enough of the functionality to get this
working in a single-process context.