Previously, we used `on_load_finish` to determine when the text test
was completed. This method did not allow testing of async functions
because there was no way to indicate that the runner should wait for
the async call to end.
This change introduces a function in the `internals` object that is
intended to be called when the text test execution is completed. The
text test runner will now ignore `on_load_finish` which means a test
will timeout if this new function is never called.
`test(f)` function in `include.js` has been modified to automatically
terminate a test once `load` event is fired on `window`.
new `asyncTest(f)` function has been introduces. `f` receives function
that will terminate a test as a first argument.
Every test is expected to call either `test()` or `asyncTest()` to
complete. If not, it will remain hanging until a timeout occurs.
This fixes the sizing of the arrow icons displayed to the left of
parent sections on a table of contents on Wikipedia articles, which
are sized using the equation `calc(max(0.75em, 12px))`. Now, the icon
will not expand past the edges of the box they are within, avoiding
clipping the edges of the arrows.
We shouldn't be putting generated pseudo elements inside elements that
can't have children in the first place.
This patch fixes two issues:
- We stop generating pseudo elements for layout nodes that can't have
children anyway.
- We mark Layout::BreakNode as not being able to have children.
These apply to any elements that have some kind of open/closed state.
The spec suggests `<details>`, `<dialog>`, and `<select>`, so that's
what I've supported here. Only `<details>` is fleshed out right now,
but once the others are, these pseudo-classes should work
automatically. :^)
The spec requires that details elements be assigned a shadow tree with
two slots. The first slot is assigned the first summary child element of
the details element. The second slot is assigned all other children.
Each ref test now links to its reference page with a link tag, in the
same format as WPT:
`<link rel="match" href="reference-page.html" />`
The reference pages have all been moved into a separate `reference/` dir
so that we can just treat every file in `ref/` as a test. There's no
filter to only look at .html files, because we also have a .svg file in
there, and there may be other formats we want to use too. But it's not
too hard to add one if we need it.
We skip serializing any of the internal state of the Regex<ECMA262>
object, because that state is all computable from the input pattern
and flags. If it turns out that this is really, really slow, we can add
some optimizations to serialize more of the regex parse result.
In order to access the string's contents, use the new
`StringStyleValue::string_value()` method.
I think I found all the existing places that relied on
`StringStyleValue::to_string()` returning an unquoted string, but it's
hard to know for sure until things break.
When calculating the edge offset of the next floating item based on the
offset of the preceding floating item, we need to ensure that the
preceding offset is always > 0. This isn't explicitly written in the
spec, but all other popular engines do that.
Fixes https://github.com/SerenityOS/serenity/issues/21023
Before, we completely ignored clearance for block-level boxes if they
were floated. This was incorrect because it is valid for a block-level
box to be floated and still have clearance. However, unlike clearance
on normal flow boxes, clearance on floating boxes does not affect the
y-position of subsequent normal flow boxes. Instead, it pushes the
box's position to the very beginning of an edge.
Work towards https://github.com/SerenityOS/serenity/issues/21023
This is a simple mapping of some code-points to others.
I was going to use a ref test for this, but without knowing that the
font contains the code-points (which SerenitySans does not) we'd be
comparing a series of replacement characters to a series of replacement
characters, which doesn't tell you if they're the right code-points
underneath.
This one is a bit fun because it can be `add(<integer>)` or `auto-add`,
but children have to inherit the computed value not the specified one.
We also have to compute it before computing the font-size, because of
`font-size: math` which will be implemented later.
Previously we were overly generous in what we accepted for `display`.
For example, we accepted:
- Multiple outside or inside identifiers
- Unrecognized identifiers
- Non-identifier tokens
Now, we reject all these cases. This makes us stop accepting the
`display: block math;` declaration in `MathML/Default.css`, and so the
one layout test we have containing MathML elements has changed to
reflect that.
When a button should use flex for alignment and also has ::before
and/or ::after, we previously did the following:
1. Prepended/appended the button's children with boxes for
pseudo-elements.
2. Replaced the button's direct children with a flex container that
contains its children.
As a result, the generated boxes for ::before/::after ended up as
children of the generated flex item, instead of being direct children
of the button layout box as they were supposed to be.
This change reverses these steps, ensuring that boxes for
pseudo-elements are generated only after modifications inside the
button layout are completed.
When modifying the button layout during tree building to use flex for
vertical alignment, let's explicitly set the button box's children to
be non-inline. It doesn't make sense to layout the button as an IFC
when its only child is a flex container.
`i` is used as the index for 'old lines' in diff generation, not 'new
lines'. Using the wrong index would mean that for certain diffs the
prefixed context information would have wrong content, and could even
result in a crash.
Fix this, and add a test for an input which was previously crashing.
https://developer.apple.com/documentation/audiounit
Apple has a number of audio frameworks we could use. This uses the Audio
Unit framework, as it gives us most control over the rendering of the
audio frames (such as being able to quickly pause / discard buffers).
From some reading, we could implement niceties such as fading playback
in and out while seeking over a short (10ms) period. This patch does not
implement such fancy features though.
Co-Authored-By: Andrew Kaster <akaster@serenityos.org>
Before, we were using the line height from NodeWithStyle::line_height()
to calculate the y offset for floats inside the IFC. However, this
value doesn't always correspond to the actual height of a line box. For
instance, adding a fragment for an inline-block might change the height
of the line box. With this change, we recalculate the height of the
line box after adding a new fragment and use this recalculated height
value to determine the y position for floats.
Fixes https://github.com/SerenityOS/serenity/issues/20982
If an element is created from JS, it might have its contents modified
before it is inserted into the document. In this case, we don't have a
shadow tree yet and so trying to set m_text_node's text content would
cause a null dereference. So let's not do that. :^)
That case also means that by the time we do create the shadow tree, we
have the text content already, so we can set it there.
Added a test to verify that we don't crash, and that the text content
appears in the textarea whether it was inserted by JS or by the HTML
parser.
There are a bunch of tests that check for time_t handling 64-bit values
properly. This makes sense, but also obviously doesn't work when time_t
is 32-bit, and causes compile-time errors. Compile these tests out in
that case.
Since there's no straightforward way to check sizeof(time_t) inside the
proprocessor, only do this when glibc's __TIMESIZE is defined.
This change allows IDL interfaces to be compiled using new AK String
which have a attribute in the interface that may return null.
Without this change we would run into a compile error from code such as
the following example:
```
auto retval = impl->deprecated_attribute(HTML::AttributeNames::ref);
if (!retval.has_value()) {
return JS::js_null();
}
return JS::PrimitiveString::create(vm, retval.release_value());
```
As `deprecated_attribute` returns a `DeprecatedString` instead of an
`Optional<String>`. Fix that by using the non-deprecated attribute
implementation, and falling back to the empty string for where we cannot
return null.
Also add a test here to cover a regression I almost introduced here
which was not previously covered by our test suite.
Ideally, all of this should actually just be calling
Element::get_attribute_value, but I'm not entirely sure at this stage
what the behavioral change would be to test for here. Since this
implementation preserves the previous behavior, stick with it, and add a
FIXME for now.
Previously, the code assumed that in dividing up the space in the
affected tracks there would never be an overshoot. Instead, we can
check for each track how much extra space is left and never consume any
extra.
In the same way, we can ensure that all extra space is consumed by
distributing all remaining extra space starting from the first track.
Thus, if there is no growth limit, the space distribution should always
consume all the extra space.
The spec says that the sum of affected size + item-incurred increase
should reach the limit, rather than just the item-incurred increase.
This seems to improve layout on the testcase `row-span-2-with-gaps`.
The extra line of space at the bottom of the left div
(`div.grid-item.item-span-two`) is not present anymore, matching other
browsers' layout much more closely.
Support the optional `<attr-type>` parameter to the `attr()` function,
which allows parsing the attribute's value as a variety of types,
instead of always as a string.
The final used values for these properties is stored in the layout node,
so we need to make sure they are propagated there as well when doing
table box fixup.
Some replaced elements can have intrinsic aspect ratios but no
intrinsic size. In these cases, the tentative sizes are undefined, and
can therefore sometimes be zero. However, when resolving the size
constraints, we are already guaranteed to have an intrinsic aspect
ratio, so let's use that instead to calculate the resolved sizes.
This allows us to retain perfect precision for aspect ratios derived
from either the intrinsic sizes of replaced elements, or the
`aspect-ratio` CSS property.
There's a particularly awkward case where the static position of an
abspos child of a flex container is dependent on its height. This can
happen when `align-items: center` is in effect, as we have to adjust
the abspos child's Y position by half of its height.
This patch solves the issue by reordering operations in the abspos
height resolution algorithm, to make sure that height is resolved
before the static position is calculated.
Using flex layout inside button solves the issue with wrongly calculated
height when it has: pseudo element and whitespaces inside.
Also using flex instead of a table layout allows for the same vertical
alignment but with fewer layout nodes: a flex container and anonymous
wrapper for content instead of a table wrapper, table, row, and cell.
MAP_FILE is not in POSIX, and is simply in most LibCs as a "default"
mode. Our own LibC defines it as 0, meaning "no flags". It is also not
defined in some OS's, such as Haiku. Let's be more portable and not use
the unnecessary flag.
Before this change, we were creating a new anonymous flex item for every
inline-level child of a flex container, even when we had a sequence of
inline-level children.
The fix here is to simply keep putting things in the last child of the
flex container, if that child is already an anonymous flex item.
Previously we always set the height of the HTML element equal to the
viewport height but now this will only happen in quirks mode as it is
intended. Otherwise the html element height will be computed as auto.
Rather than modify the transform of the parent (which could change
independently), this adds a new override element_transform() where
element specific tranfroms can be applied. This will always stay in
sync with the attributes.
A ref test comparing a .svg and .html version of the same file is
added as due to differences in attribute parsing order, the .svg version
was previously drawn incorrectly.
Fixes#20859
None of the existing tests contain a URL which has a fragment in them,
but this does verify that the URL parser does not actually find any!
Also, this should let us verify the correctness of URLs which actually
do contain fragments.
Since we always pass the px value as an argument to resolved(), we can
pass it directly as CSSPixels instead of wrapping it in Length. This
approach allows us to avoid converting to a double, resulting in fewer
precision issues.
When text paintables shift around in the tree due to line wrapping,
we may end up in a situation where some text node does not generate
a paintable (due to being all whitespace, for example), even though
in the previous layout pass, it *did* generate a paintable.
To prevent holding on to old paintables in such cases, we now do a
pass in LayoutState::commit() where we explicitly detach all old
paintables from the layout tree.
We need to start looking from the beginning of current row if adding
new implicit column track made enough space to accomodate spanning item
This fixes placement for spanning grid items when `grid-auto-flow` is
specified to `column`.
This implementation is very naive compared to the PulseAudio one.
Instead of using a callback implemented by the audio server connection
to push audio to the buffer, we have to poll on a timer to check when
we need to push the audio buffers. Implementing cross-process condition
variables into the audio queue class could allow us to avoid polling,
which may prove beneficial to CPU usage.
Audio timestamps will be accurate to the number of samples available,
but will count in increments of about 100ms and run ahead of the actual
audio being pushed to the device by the server.
Buffer underruns are completely ignored for now as well, since the
`AudioServer` has no way to know how many samples are actually written
in a single audio buffer.
The main change is the simplification of the expression
`(10^precision * fraction) / 2^precision` to `5^precision * fraction`.
Those expressions overflow or not depends on the value of `precision`
and `fraction`. For the maximum value of `fraction`, the following table
shows for which value of `precision` overflow will occur.
Old New
u32 08 10
u64 15 20
u128 30 39
As of now `u64` type is used to calculate the result of the expression.
Meaning that before, only FixedPoints with `precision` less than 15
could be accurately rendered (for every value of fraction) in decimal.
Now, this limit gets increased to 20.
This refactor also fixes, broken decimal render for explicitly specified
precision width in format string, and broken hexadecimal render.
Because of the off-by-one error, the second bit of the fraction was
getting ignored in differentiating between fractions equal to 0.5 or
greater than 0.5. This resulted in numbers like 2.75 being considered
as having fraction equal to 0.5 and getting rounded incorrectly (to 2).
If the table used width has to be adjusted because of a cell with
percentage width, add back the undistributable space due to border
spacing. This is consistent with the width distribution algorithm, which
sets aside the undistributable space and the behavior of other browsers.
When the grid layout gets to
`resolve_items_box_metrics(GridDimension::Column)`, we've already
determined the width of each column. However, the widths of the
individual grid items themselves haven't been set. Rather than using
`get_available_space_for_item()`, which returns an indefinite size if
an item's width/height hasn't been set, we should use the already
known track width as the available size to calculate the fit-content
width.
In general it is not safe to convert any arbitrary floating-point value
to CSSPixels. CSSPixels has a resolution of 0.015625, which for small
values (e.g. scale factors between 0 and 1), can produce bad results
if converted to CSSPixels then scaled back up. In the worst case values
can underflow to zero and produce incorrect results.
This means StyleComputer::resolve_unresolved_style_value() always
returns a value, so we can change its return type.
However, it does still return an UnresolvedStyleValue sometimes, so we
can't remove those checks from the user code.
- Ambiguous `raw_value()` method is replaced with `line_number()` and
`span()`.
- `line_name()` that before returned either line name or area name is
replaced with `line_name()` and `area_name()`.
- `Position` type is replaced with `Line` and `Area` type so we don't
have to guess while doing layout.
Affected test expectations:
- `template-lines-and-areas` - improvement over what we had before.
- `named-tracks` - rebaseline a giant test. will have to split it into
smaller tests in the future.
The invariants for these property getters are supposed to be checked by
the has_entries_and_events_disabled AO, but we don't have all the
plumbing hooked up between Navigables and Navigation yet.
Add a test to make sure that these methods don't assert when calling
them on a fresh page.
The resolution is simply 1dppx * device pixel ratio.
This makes high resolution images show up on https://apple.com/
when running on a high-DPI display. :^)
These syscalls are not necessary on their own, and they give the false
impression that a caller could set or get the thread name of any process
in the system, which is not true.
Therefore, move the functionality of these syscalls to be options in the
prctl syscall, which makes it abundantly clear that these operations
could only occur from a running thread in a process that sees other
threads in that process only.
Note that we don't load the local font as specified, but at least we no
longer reject such src properties in the CSS parser.
This makes the custom fonts used on http://apple.com/ actually load. :^)
We were previously setting the end position of attribute names in self-
closing HTML tags to the end of the attribute value. To illustrate the
previous behavior, consider this tag and its attribute's start and end
positions (shown inclusively below):
<meta charset="UTF-8" />
^ name start
^ value start
^ value end
^ name end
Rather than setting the end position of the attribute name when we parse
the closing slash, ensure the end position is already set while we are
in the AttributeName state. We now have:
<meta charset="UTF-8" />
^ name start
^ name end
^ value start
^ value end
The tokenizer unit test has been extended to test these positions.
To illustrate the previous behavior, consider these tags and their start
and end positions (shown inclusively below):
Start tag: End tag:
<span> </span>
^ start ^ start
^end ^end
The start position of a tag is the first ASCII-alpha code point after
the opening brace. The start position of a close tag is the slash just
before the first ASCII-alpha code point. And the end position of both
is the closing brace. So the opening brace is not included in the
emitted tag, but the closing brace is. And the end tag including the
slash is an oddity that had to be worked around in its only use case
(syntax highlighting).
We now consistently exclude the braces from the emitted tag, and also
exclude the slash from the end tag, so that it does not need to be
accounted for in syntax highlighting. That is, we now have:
Start tag: End tag:
<span> </span>
^ start ^ start
^end ^end
The tokenizer unit test has been extended to test these positions.
`DeprecatedString::to_int` calls `StringUtils::convert_to_int`
internally. However, the integer parsing is not done in an HTML
spec-compliant way. For example, `colspan="2;"` is valid according to
the spec. But, with the current implementation, we will fail to parse
"2;", and instead fall back to using 1 as the colspan value.
This patch changes the `HTMLTableCellElement::col_span` and
`HTMLTableCellElement::row_span` methods to use the
`Web::HTML::parse_non_negative_integer` function that will parse the
attribute value in an HTML spec-compliant way.
We have code inside LibWeb that uses the
`AK::StringUtils::convert_to_uint`and `AK::StringUtils::convert_to_int`
methods for parsing integers. This works well for the most part, but
according to the spec, trailing characters are allowed and should be
ignored, but this is not how the `StringUtil` methods are implemented.
This patch adds two new methods named `parse_integer` and
`parse_non_negative_integer` inside the `Web::HTML` namespace that uses
`StringUtils` under the hood but adds a bit more logic to make it spec
compliant.
This giant grid test has been a source of problems while iterating on
GFC for a long time. Let's split it into smaller tests to make it
easier to identify issues without needing further reductions on the
test.
These two ref-tests involve two boxes positioned in the same place, with
outlines. Outlines always have a border-radius, meaning that the corner
pixels are not 100% opaque. (It seems to be 254 instead of 255.) With
the test files painting two outlines, and the ref test only painting
one, slight changes in the background color of the page would make that
slight variation visible sometimes. So, let's avoid that inconsistency
by always painting one outline instead of two.
We were relying on the table fixup algorithm to insert the missing table
row, which fails to do so when we only have an image in the button.
While that might be a problem with the table fixup algorithm, we should
build a correct layout tree explicitly anyway.
Fixes crashes on GitHub.
There was a small mishmash of argument order, as seen on the table:
| Traits<T>::equals(U, T) | Traits<T>::equals(T, U)
============= | ======================= | =======================
uses equals() | HashMap | Vector, HashTable
defines equals() | *String[^1] | ByteBuffer
[^1]: String, DeprecatedString, their Fly-type equivalents and KString.
This mostly meant that you couldn't use a StringView for finding a value
in Vector<String>.
I'm changing the order of arguments to make the trait type itself first
(`Traits<T>::equals(T, U)`), as I think it's more expected and makes us
more consistent with the rest of the functions that put the stored type
first (like StringUtils functions and binary_serach). I've also renamed
the variable name "other" in find functions to "entry" to give more
importance to the value.
With this change, each of the following lines will now compile
successfully:
Vector<String>().contains_slow("WHF!"sv);
HashTable<String>().contains("WHF!"sv);
HashMap<ByteBuffer, int>().contains("WHF!"sv.bytes());
Fixes bug when "clip" property does not affect abspos children.
This change makes "clip" property to be applied together with
"overflow: hidden" in `apply_clip_overflow_rect()` that already
handles abspos children correctly.
This matches if the element has a placeholder, and that placeholder is
currently visible. This applies to `<input>` and `<textarea>` elements,
but our `<textarea>` is very limited so does not support placeholders.
These APIs only perform small allocations, and are only used by LibJS
and the time zone settings widget. Callers which could only have failed
from these APIs are also made to be infallible here.
These APIs only perform small allocations, and are only used by LibJS.
Callers which could only have failed from these APIs are also made to
be infallible here.
Grid specification https://www.w3.org/TR/css-grid-2/#z-order defines
special painting order for grid items which should be the same as for
defined for inline-blocks in CSS2.
Check the width of the next token after white space to decide line
breaks. The next width can also be the total width of multiple tokens.
This better follows the CSS Text specification and matches behavior of
other browsers.
Fixes#20388.
We still don't know how to resolve font-relative lengths in <img sizes>
since we don't always have font size information available at this stage
in the pipeline, but we can at least handle viewport-relative lengths.
This fixes an issue on many websites where low-resolution images were
loaded (appropriate for a small viewport) even when the viewport is big.
And treat them as "auto" for now, per CSS-SIZING-3, with a FIXME about
supporting more layout directions.
This fixes an issue on MDN where `height: max-content` was not
overriding height from non-CSS presentational hints.
CSS-ALIGN-3 tells us that `normal` behavior inside flex containers is
simply to behave as `stretch` so this patch makes them behave the same
inside FFC.
Furthermore, we change the `align-items` initial value to `normal`,
matching other engines.
I'm about to make StackingContext traverse the paintable tree instead of
actually traversing the layout tree, and it turns out we were not
creating paintables for these SVG elements.
Also switch them to Layout::Box instead of the default InlineNode to
make the trees look a bit less weird. Ultimately, we should do something
specialized for these subtrees, but for now this'll do.
This patch just adds the new root paintable and updates the tests
expectations. The next patch will move painting logic from the layout
viewport to the paint viewport.
Instead of assuming that the WebDriver binary is in PATH or the two
most common build directories for our scripts, add a command line
argument to the script to pass a WebDriver binary.
We should be documenting required pacakges elsewhere and installing them
in the setup step of CI.
This also fixes a problem where the run script would fail if you already
had a cloned wpt directory.
The setup is a bit peculiar: both the definition and the use site of
these TLS variables have to be in a shared library, otherwise the linker
might relax the global-dynamic access mode to something that doesn't
require a `__tls_get_addr` call.
This has to cheat and use a screenshot but thanks to the "Take Full
Screenshot" feature of Ladybird, it is very easy to update this test.
The steps are documented in the test.
When a box is sized under max-content constraint, any percentage value
set for max-width should be considered as if it were infinite. In other
words, it should have no effect on restricting the box's width.
This doesn't seem to actually have fixed any bugs, as having
FillOpacity instead of StrokeOpacity in the call to parse_css_value
doesn't seem to have actually been causing bugs. But, I still think it's
worthwhile correcting.
The reason that it wasn't causing bugs is that having FillOpacity
instead of StrokeOpacity in the call to parse_css_value means that when
parsing the value is compared to the acceptable values for that property
(for example the value can only be a percentage, or a number, etc.). In
this case both FillOpacity and StrokeOpacity seem to accept the same
values.
The SVG G container should have the same size as its children. This
fixes a bug when there was an opacity value on the G element, as in
StackingContext it would try and get a bitmap of the element which would
be empty due to it having no size.