Handling tabs during text shaping caused issues because we tried to
index 'input_glyph_info' whilst iterating until 'glyph_count' and these
can be different sizes.
The difference is due to when one or more characters get
merged into the same glyph when calling 'input_glyph_info' (see
https://lazka.github.io/pgi-docs/HarfBuzz-0.0/classes/glyph_info_t.html).
We don't want to render tabs as they come up as tofu characters so
instead let's strip them out of the text chunk before starting text
shaping.
Platforms such as X11 will typically send repeated keyRelease/keyup
events as a result of auto-repeating:
* KeyPress (initial)
* KeyRelease (repeat)
* KeyPress (repeat)
* KeyRelease (repeat)
* ad infinitum
Make our EventHandler more spec-compliant by ignoring all repeated keyup
events. This fixes long-pressing the arrow keys on
https://playbiolab.com/.
When a platform key press or release event is repeated, we now pass
along a `repeat` flag to indicate that auto-repeating is happening. This
flag eventually ends up in `KeyboardEvent.repeat`.
We need this, because https://www.slatejs.org/ that is used by Discord
checks this function to decide whether a browser has "beforeinput" event
support.
We previously only supported enabling headless mode on a per-session
basis via the capabilities record. We don't have the ability to mutate
this record from WPT, so this adds a flag to set the default mode.
Previously, tests would intermittently fail because the current session
wasn't yet aware of a newly created window handle.
Co-authored-by: Timothy Flynn <trflynn89@pm.me>
With 6a549f6270 we need to check if
optional scrollable overflow exists for paintable box, because it's not
computed for inline nodes.
Fixes crashing after navigating into direct messages screen on Discord.
The reason we were keeping track of the pre-shaping buffer was to know
where we had tab characters in the input. This is a very strange way of
doing that, but since it broke the web, let's patch it up quickly.
Follow-up to #1870 which broke text layout on many web pages.
This fixes a browser crash as experienced on Wikipedia when encountering
the ≠ entity. As a side-effect, this also affects some tab-align and
-wrap tests.
Per css-ui-4, setting `appearance: none` is supposed to suppress the
creation of a native-looking widget for stuff like checkboxes, radio
buttons, etc.
This patch implements this behavior by simply falling back to creating
a layout node based on the CSS `display` property in such cases.
This fixes an issue on the hey.com imbox page where we were rendering
checkboxes on top of sender profile photos.
Some callers (namely WebDriver) will need access to the navigable opened
by these steps. But if the noopener parameter is set, the returned proxy
will always be null.
This splits some of the Window open steps into an internal method that
returns the chosen navigable.
This is strictly nicer than passing them around as i32 everywhere,
and by switching to i64 as the underlying type, ID allocation becomes as
simple as incrementing an integer.
On the view-source page, generate anchor tags for any 'href' or 'src'
attribute value we come across. This handles both when the attribute
contains an absolute URL and a URL relative to the page.
This requires sending the document's base URL over IPC to resolve
relative URLs.
These flags always propagate to the root, so once we encounter an
ancestor with the flag set, we can stop traversal since everything above
it will already be set as well.
For pseudo elements that represent a browser-generated shadow tree
element, such as ::placeholder, we were reparsing their style attribute
in StyleComputer for some reason.
Instead of doing this, just access the already-parsed version via
Element::inline_style().
We only supported named properties on Storage, and as a result
`localStorage[0]` would be disconnected from the Storage's backing map.
Fixes at least 20 subtests in WPT in /webstorage.
As efforts to begin porting to Windows is underway, doing so should be a
bit less daunting if we clean up syscall wrappers that aren't used.
Note: While this removes Serenity-only wrappers, it leaves the Serenity
implementations of used wrappers in place for now, to not needlessly
complicate merging between the two orgs.
After InlinePaintable is gone it's possible to make this function accept
a PaintableBox instead of more broad
Layout::NodeWithStyleAndBoxModelMetrics type.
We've added a few JS::Handle members to this class over time. Let's
avoid creating a new GC root for each of these, and explicitly add a
visitation method.
Some of this code is older than widespread use of GCPtr. These functions
returning raw pointers has been a point of confusion at times, so lets
just indicate that they are non-null.
Without this, a worker can be GC'd in a very simple script such as:
const worker = new Worker("script.js");
worker.onmessage = () => {};
Where script.js attempts to post a message back to the parent window.
When the Worker is GC'd, the IPC connection from the WebContent process
to the WebWorker process is closed. When this occurs, the WebWorker will
exit() from LibIPC, and any message from the worker to its parent does
not have a chance to run.
This just updates our copied spec steps - new steps are not implemented
here. This is mostly just to highlight new steps we are missing around
MessagePorts.
No behavior change, but this does resolve an outstanding FIXME around
spec step ordering.
1.25x speed-up on this microbenchmark:
let o = { get x() { return 1; } };
for (let i = 0; i < 10_000_000; ++i)
o.x;
I looked into this because I noticed getter invocation when profiling
long-running WPT tests. We already had the mechanism for non-getter
properties, and the change to support getters turned out to be trivial.
These are created when a style rule has properties listed after another
rule. For example:
```css
.test {
--a: 1;
--b: 1;
--c: 1;
.thing {
/* ... */
}
/* These are after a rule (.thing) so they're wrapped in a
CSSNestedDeclarations: */
--d: 1;
--e: 1;
--f: 1;
}
```
They're treated like a nested style rule with the exact same selectors
as their containing style rule.
For example, this:
```css
.foo {
color: red;
&:hover {
color: green;
}
}
```
now has the same effect as this:
```css
.foo {
color: red;
}
.foo:hover {
color: green;
}
```
CSSStyleRule now has "absolutized selectors", which are its selectors
with any `&`s resolved. We use these instead of the "real" selectors
when matching them, meaning the style computer doesn't have to know or
care about where the selector appears in the CSS document.
Through the CSSOM, rules can be moved around, and so anything cached
(for now just the qualified layer name) needs to be recalculated when
that happens. This method is virtual so that other rules will be able
to clear their cached data too.
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/ :^)
On any `display: list-item` Node a CSS pseudo element (`::marker`) needs
to be created. This commit allows the ::maker pseudo element to be
nested within other pseudo elements (e. g. ::before or ::after).
This fixes this WPT test:
http://wpt.live/css/CSS2/generated-content/after-content-display-003.xht
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.
CSS fragmentation implies 1:N relationship between layout nodes and
paintables. This change is a preparation for implementation of inline
fragmentation where InlinePaintable will be replaced with
PaintableWithLines corresponding to each line.
Always create a new formatting context for <math> elements. Previously
that didn't happen if they only had inline children, e.g. mtable.
This fixes a crash in the WPT MathML test
mathml/crashtests/children-with-negative-block-sizes.html
A couple of parts of this:
- Store the source text for Declarations of custom properties.
- Then save that in the UnresolvedStyleValue.
- Serialize UnresolvedStyleValue using the saved source when available -
that is, for custom properties but not for regular properties that
include var() or attr().
This is in a weird position where the spec tells us to discard the
comments, but then we have to preserve the original source text which
may include comments. As a compromise, I'm treating each comment as a
whitespace token - comments are functionally equivalent to whitespace
so this should not have any behaviour changes beyond preserving the
original text.
Previously we would serialize these as the empty string. eg, this:
```
<div style="grid-auto-columns: auto"></div>
```
would have a computed `grid-auto-columns` value of ``.
In order to know whether `calc(2.5)` is a number or an integer, we have
to see what the property will accept. So, add that knowledge to
`Parser::expand_unresolved_values()`.
This makes `counter-increment: foo calc(2 * var(--n));` work correctly,
in a test I'm working on.
Selectors and at-rules both made assumptions about their indentation
level, which made it difficult to read the dump output. It'll become
even worse once rules can be further nested within each other, so let's
fix it now. :^)
This will be the first step is making better use of system libraries
like fontconfig and CoreText to load system fonts for use by the UI
process and the CSS style computer.
This reverts 6d25bf3aac
Invalidating the style here means that transitions can cause an element
to leave style computation with its "needs style update" flag set to
true. This then causes a VERIFY to fail in the TreeBuilder.
This invalidation does not otherwise seem to have any effect. The
original commit suggests this was to fix a bug, but it's not clear what
bug that was. If it reappears, we can try to solve the issue in a
different way.
I had made a stab at implementing this to determine whether it could
assist in fixing an issue where scroll_to_the_fragment was not getting
called at the appropriate time. It did not fix that issue, and actually
ended up breaking one of our in tree tests. In the meantime, factor out
this method into a standalone function.
These don't have to worry about the input not being valid UTF-8 and
so can be infallible (and can even return self if no changes needed.)
We use this instead of Infra::to_ascii_{upper,lower}_case in LibWeb.
- Include vertical border spacing in row group offset calculation so
that they are axis-aligned with child row/cell elements. This makes it
so there isn't horizontal and vertical overflow caused by child
row/cell elements.
- Include horizontal border spacing in tr width calculations. This makes
it so tr elements don't have overflow anymore when there are multiple
columns.
- Apply vertical caption offset to row group top offset.
- Don't double-count top padding when calculating vertical offset for
tr and row groups.
Instead of re-symbolicating entire stacks from scratch every time
we want a JS VM backtrace, we now use the ExecutionContext object as
cache storage via a new CachedSourceRange object.
This means that once a stack frame has been symbolicated, we don't
have to resymbolicate it again (unless the program counter moves
within that stack frame).
This drastically reduces time spent in symbolication in some WPT tests.
Cookies have a minimum expiry resolution of 1 second. So to test cookie
expiration, the test had to idle for at least a second, which is quite a
noticeable delay now that LibWeb tests are parallelized.
Instead, we can add an internal API to expire cookies with a time offset
to avoid this idle delay.
CSS Syntax 3 (https://drafts.csswg.org/css-syntax) has changed
significantly since we implemented it a couple of years ago. Just about
every parsing algorithm has been rewritten in terms of the new token
stream concept, and to support nested styles. As all of those
algorithms call into each other, this is an unfortunately chonky diff.
As part of this, the transitory types (Declaration, Function, AtRule...)
have been rewritten. That's both because we have new requirements of
what they should be and contain, and also because the spec asks us to
create and then gradually modify them in place, which is easier if they
are plain structs.
This is an ad-hoc change to account for the fact that we may run
arbitrary code while waiting for the tasks in this function to complete.
I don't have a way to reproduce it, but I've seen trouble caused by
navigables disappearing, which causes the history step numbers to be
disturbed.
Previously Selection.extend() used only the relative node order to decide which
direction to extend the selection. This leads to incorrect behaviour if
both the existing and new boundary points are within the same DOM node
and the selection direction is reversed.
This change fixes all the failing subtests in the WPT extend-* test
suites.
Loading Ladybird on Github results in 37 debug logs about being unable
to parse an empty Date string. This log is intended to catch Date
formats we do not support to detect web compatability problems, which
makes this case not particuarly useful to log.
Instead of trying to parse all of the different date formats and
logging that the string is not valid, let's just return NAN immediately.
This was previously negated due to a misread of
https://url.spec.whatwg.org/#concept-url-equals. This change fixes a
bunch of WPT crashes such as
"/html/browsers/history/the-history-interface/001".
There was no need to use FlyString for error messages, and it just
caused a bunch of churn since these strings typically only existed
during the lifetime of the error.
If the image data to decode is incomplete, e.g. a corrupt image missing
its last scanlines the decoder would previously keep looping for ever.
By breaking out of the loop if no more scanlines were produced we can at
least display the partial image up to that point.
Contradictory to the spec, the Set Timeouts endpoint should update the
existing timeouts configuration in-place, rather than replacing it. WPT
expects this, and other browsers already implement this endpoint this
way.
This is a method defined in the WebDriver spec, but requires access to a
bunch of private fields in these classes, so this is implemented in the
same manner as the reset algorithm.
The "isCollapsed" attribute on a selection must "return true if and only
if the anchor and focus are the same".
In addition to checking that the anchor and focus belonged to the same
DOM node, we now also check that they refer to the same position within
the node.
With this change Ladybird passes all the subtests in the "isCollapsed"
WPT suite.
https://wpt.live/selection/isCollapsed.html
This way we don't have to allocate separate vector with both scroll and
sticky frame that is used for display list player (scroll and sticky
frames share id pool), so player could access offset by frame id.
No behavior change.
...and add display list item that does translation instead. By doing
that we no longer need to map each coordinate in display list by
translation in recorder state.
Set the connection timeout which only limits the connection phase of the
request.
Previously, CURLOPT_TIMEOUT would apply to all transfer operations which
could result in legitimate upload or download operations being
cancelled.
Printing the whole array causes wpt
console/console-log-large-array.any.html to crash.
This limits logged arrays to 100 elements and
truncates the rest with ...
The headless-browser source is getting a bit unwieldy. The ordering of
class and method definitions is fragile; e.g. the application and web
view classes each require full definitions of each other. So it has
reached the point where it makes sense to give headless-browser some
better file structure.
To prepare for that, this patch simply moves its source to live along-
side the other browser chromes. This location is a bit better prepared
for creating more files, as the Utilities folder doesn't even have its
own CMakeLists.txt.
- Add support for placement of abspos items into track formed by last
line and padding edge of grid container
- Correctly handle auto-positioned abspos items by placing them between
padding edges of grid container
Fixes crashing on https://wpt.live/css/css-grid/abspos/positioned-grid-descendants-001.html
We have support for using (shift+)tab to move focus to the next/previous
element on the page. However, there were several ways for this to crash
as written. This updates our implementation to check if we did not find
a node to move focus to, and to reset focus to the first/last node in
the document.
This doesn't seem to work when wrapping around from the first to the
last node. A FIXME has been added for that, as this would already not
work before this patch (the main focus here is not crashing).
The spec says we don't need to await navigations if we navigate to the
same URL that we are already on, but at least in our implementation, we
should still await the page load. Otherwise, we will invoke WebDriver
endpoints on the wrong page.
This is necessary when we add more ServiceWorker capabilities, that
actually check this value. The more this spoof functionality is used,
the more we'll need to actually support serving test files over https.
Our handling of left vs. right modifiers keys (shift, ctrl, etc.) was
largely not to spec. This patch adds explicit UIEvents::KeyCode values
for these keys, and updates the UI to match native key events to these
keys (as best as we are able).
...traversal. We've already fixed step 3 and 9 to not filter out
non-positioned stacking contexts, because modern CSS has more ways to
create stacking context besides being positioned with z-index (like by
using "transform", "filter" or "clip-path" properties).
See following spec issue for more details https://github.com/w3c/csswg-drafts/issues/2717
Visual improvement on https://basecamp.com/
Prior to this change, SVGs were following the CSS painting order, which
means SVG boxes could have established stacking context and be sorted by
z-index. There is a section in the spec that defines what kind of SVG
boxes should create a stacking context
https://www.w3.org/TR/SVG2/render.html#EstablishingStackingContex
Although this spec is marked as a draft and rendering order described in
this spec does not match what other engines do.
This spec issue comment has a good summary of what other engines
actually do regarding painting order
https://github.com/w3c/svgwg/issues/264#issuecomment-246432360
"as long as you're relying solely on the default z-index (which SVG1
does, by definition), nothing ever changes order when you apply
opacity/filter/etc".
This change aligns our implementation with other engines by forbidding
SVGs to create a formatting context and painting them in order they are
defined in tree tree.
When the TokenStream code was originally written, there was no such
concept in the CSS Syntax spec. But since then, it's been officially
added, (https://drafts.csswg.org/css-syntax/#css-token-stream) and the
parsing algorithms are described in terms of it. This patch brings our
implementation in line with the spec. A few deprecated TokenStream
methods are left around until their users are also updated to match the
newer spec.
There are a few differences:
- They name things differently. The main confusing one is we had
`next_token()` which consumed a token and returned it, but the spec
has a `next_token()` which peeks the next token. The spec names are
honestly better than what I'd come up with. (`discard_a_token()` is a
nice addition too!)
- We used to store the index of the token that was just consumed, and
they instead store the index of the token that will be consumed next.
This is a perfect breeding ground for off-by-one errors, so I've
finally added a test suite for TokenStream itself.
- We use a transaction system for rewinding, and the spec uses a stack
of "marks", which can be manually rewound to. These should be able to
coexist as long as we stick with marks in the parser spec algorithms,
and stick with transactions elsewhere.
We have a bit of forgiveness around allowing tests to pass with varying
trailing newlines. Only write a rebaselined test to disk if it would not
have passed under those conditions.
Before this change, we transferred the input element's line-height to
both the editable text *and* the placeholder. This caused some strange
doubling of the effective line-height when the editable text was empty,
pushing down the placeholder.
These were used to provide a layer of abstraction between ResourceLoader
and the networking backend. Now that we only have RequestServer, we can
remove these adapters to make the code a bit easier to follow.
Now that we use libcurl, there's no reason to keep Qt networking around.
Further, it doesn't support all features we need anyways, such as non-
buffered request handling for SSE.
The spec expects `postMessage()` to act as if it is invoked
immediately. Since `postMessage()` isn't actually invoked immediately,
keep tasks with source `PostedMessage` in the task queue, so that these
tasks are processed. Fixes a hang when `WorkerGlobalScope.close()` is
called immediately after `postMessage()`.
https://www.w3.org/TR/event-timing/#sec-performance-event-timing
Add idl, header and stubs for PerformanceEventTiming interface.
Two missing `PerformanceEntry` types that have come up in issues
are the `first-input` and the `event` entryTypes. Those are both
this.
Also, because both of those are this same interface, the static
methods from the parent class are difficult to implement because
of instance-specific details. Might either need subclasses or to
edit the parent and also everything that inherits from it :/
We don't create a ChromeProcess in headless-browser, so it is currently
not increasing it's open file limit. This is causing crashes on macOS,
which has a very low default limit.
Before this change viewport was allowed to be scrolled whenever it has a
scrollable overflow, which is not correct when overflow is specified to
be hidden.