Absolutely positioned elements should have their percentage sizes
resolved against the padding box of the containing block, not the
content box.
From CSS-POSITION-3 <https://www.w3.org/TR/css-position-3/#def-cb>
"..the containing block is formed by the padding edge of the ancestor.."
Now that we support audio, we can start correctly reporting we support
certain audio mime types!
Required by certain sites like Gartic Phone, which fails to load audio
because we didn't return a non-empty string for `audio/mpeg`:
```
"https://garticphone.com/sounds/turnundefined", Error: Load failed: 404
```
```js
(new Audio).canPlayType("audio/mpeg") && (this._extension = ".mp3"),
```
Many operations in JavaScript may incur side effects, including calling
arbitrary user code. Since the user code will clobber the accumulator,
we have to take care to extract anything we need from the accumulator
before doing anything that may have side effects.
Fixes 3 test262 tests. :^)
The transform can change between path building operations (and before
the path is filled or stroked). This fixes the sun ray backgroun on
the https://www.kevs3d.co.uk/dev/html5logo/ canvas demo.
The fix for this was to port the "don't create unnecessary FooObject
for property access on primitives" optimization from Reference,
which also brings us the correct behavior.
Since we no longer need to create or leave var environments directly
in bytecode, we can streamline the two instructions by making them
always operate on the lexical environment.
Instead of implementing this AO in bytecode, we now have an instruction
for it that simply invokes the C++ implementation.
This allows us to simplify Bytecode::Generator quite a bit by removing
all the variable scope tracking.
The data we want to send out of the WebContent process is identical for
audio and video elements. Rather than just duplicating all of this for
audio, generalize the names used for this IPC for all media elements.
This also encapsulates that data into a struct. This makes adding new
fields to be sent much easier (such as an upcoming field for muting the
element).
The audio element behaves a bit differently than the video element in
that the audio element drives itself on a timer (as opposed to LibVideo
notifying the video element when a frame is available). So if an audio
element is paused while seeking, we wouldn't receive an updated playback
position until the element is unpaused.
This fixes an issue where you would have to click the play button twice
to re-start an audio track after it reached the end.
Previously, using an identifier color like `currentColor` would fail to
parse, since we look at ident tokens (and reject unrecognised ones)
before trying to parse colors.
When resolving a percentage min-width or min-height size against a
containing block currently under a min-content constraint, we should act
as if the containing block has zero size in that axis.
The idea here is to let us decide ahead of time what components to paint
depending on the size available. We currently paint each component left-
to-right, until we run out of room. This implicitly gives priority to
the left-most components.
We will soon paint volume controls on the right-side of the timeline.
Subjectively, they should have a higher priority than, say, the timeline
scrubbing bar (i.e. it's more important to be able to mute audio than to
seek). By computing these components before painting, we can more easily
allocate sections to the components in priority order, until the area
remaining has been depleted.
It can take some time to download / decode a media resource. During this
time, its duration is set to NaN. The media control box would then have
some odd rendering glitches as it tried to treat NaN as an actual time.
Once we do have a duration, we also must ensure the media control box is
updated.
When the user hits <Ctrl-Backspace> where the previous content has the
format [Punctuation|Seperator]+ before the cursor, there will be a
size_t index underflow in TextDocument::first_word_break_before,
which returns an invalid word break position with a huge column index
(18446744073709551615, -1 in size_t). The invalid text position later
used for executing RemoveTextCommand will cause a crash.
The while loop condition in TextDocument::first_word_break_before is
not right, the loop will never stop when the target.column() becomes
0 inside.
Don't try to implement this AO in bytecode. Instead, the bytecode
Interpreter class now has a run() API with the same inputs as the AST
interpreter. It sets up the necessary environments etc, including
invoking the GlobalDeclarationInstantiation AO.
Instead of trying to implement this AO in bytecode, we can just let it
be a C++ thing. Once we implement fast uncaptured locals, we won't even
be calling it super often.
Note that this does not change cycle-detection.
This is also was an unnecessary copy, since there is an easier, less
memory-intense way to do cycle detection than copying the entire
visited_set all the time.
This is technically "undefined behavior" per CSS 2.2, but it seems
sensible to mirror the behavior of max-height in the same situation.
It also appears to match how other engines behave.
Fixes#19242
Since these are stored as numbers, and "1,2,3,5,6" is a bit meaningless
to anyone who looks at this code, the default set of visible columns is
provided as it was before, by them all being visible except a couple
that are specifically hidden.
The callback is wrapped in a debounce() so that if set_visible_columns
() is called, we'll just save the value once instead of doing so for
each column changed.
Specifically, this is to make it easier to save and restore this state
to a config file. I had hoped to use the column names instead of their
IDs, but some columns have an empty string as their name so we wouldn't
be able to distinguish between those.
As it turns out, making everyone piggyback on HTML::ImageRequest had
some major flaws, as HTMLImageElement may decide to abort an ongoing
fetch or wipe out image data, even when someone else is using the same
image request.
To avoid this issue, this patch introduces SharedImageRequest, and then
implements ImageRequest on top of that.
Other clients of the ImageRequest API are moved to SharedImageRequest
as well, and ImageRequest is now only used by HTMLImageElement.
This fixes an issue with image data disappearing and leading to asserts
and/or visually absent images.
The margin from the containing blocks shouldn't be included in the
amount by which we increment x after a float was places. That coordinate
should be relative to the containing block.
Fixes the comments layout on https://lobste.rs.
I didn't put this as a method on Bitmap since it doesn't seem generally
useful. Easy to move the impl over to Bitmap in the future if we want
to use it elsewhere.
Methods defined in header files should generally be `inline`,
not `static`.
`static` means that each translation unit will have its own local copy
of the function when the function isn't inlined and it's up to the
linker's identical code folding to hopefully merge the potentially many
copies in the program. `inline` means that the linker can put the
identical copies in a comdat and merge them by name, without having to
compare contents.
No behavior change.
This AO will be used in the Web::FileAPI::Blob::get_stream()
implementation to enqueue all data in the blob to the stream.
There are still plenty of cases to handle, but this appears to be enough
for the basic case of reading all chunks from a readable stream until it
is done.
Both `Database` and `Heap` were allowed to be opened twice. Prevent
this, and change SQLServer to only open databases that are not already
opened.
This fixes a Ladybird crash where opening the application twice would
erroneously duplicate free heap block indices.
The spec says the result of this algorithm is undefined in such cases,
and it appears that other engines yield a zero size.
More importantly, this prevents us from leaking a non-finite value into
the layout tree.
We used to call `did_exit()` directly with the status returned from
`waitpid` but the function expected an exit code. We now use several
of `wait`-related macros to deduce the correct information.
Previously, all StackingContexts which were scaled using CSS transforms
were hard-coded to use BilinearBlend. This fix maps specified
image-rendering properties to reasonable ScalingModes for painting.
This creates (and installs upon WebContent startup) a platform plugin to
play audio data.
On Serenity, we use AudioServer to play audio over IPC. Unfortunately,
AudioServer is currently coupled with Serenity's audio devices, and thus
cannot be used in Ladybird on Lagom. Instead, we use a Qt audio device
to play the audio, which requires the Qt multimedia package.
While we use Qt to play the audio, note that we can still use LibAudio
to decode the audio data and retrieve samples - we simply send Qt the
raw PCM signals.
This moves the painting of the media timeout out of VideoPaintable into
a base MediaPaintable. This is to allow re-using the same timeline logic
and controls for audio elements.
It seems for very narrow tall paths it is possible for the dxdy value
to round to a value (that after many repeated additions) overshoots
the desired end x. This caused a (rather rare) crash on this 3D canvas
demo: https://www.kevs3d.co.uk/dev/html5logo/. For now, lets just avoid
a crash here. This does not make any noticeable visual differences on
the demos I tired.
Although DistinctNumeric, which is supposed to abstract the underlying
type, was used to represent CSSPixels, we have a whole bunch of places
in the layout code that assume CSSPixels::value() returns a
floating-point type. This assumption makes it difficult to replace the
underlying type in CSSPixels with a non-floating type.
To make it easier to transition CSSPixels to fixed-point math, one step
we can take is to prevent access to the underlying type using value()
and instead use explicit conversions with the to_float(), to_double(),
and to_int() methods.
Calling `from_utf8` with a DeprecatedString will hide the fact that we
have a DeprecatedString, while using `from_deprecated_string` with a
StringView will silently and needlessly allocate a DeprecatedString,
so let's forbid that.
Instead of hard-coding a check for "calc", we now call out to
parse_dynamic_value() which allows use of other functions like min(),
max(), clamp(), etc.
Add logic to compute {min, max}-height and use min-height when
calculating table height, per specifications.
Fixes some issues with phylogenetic tree visualizations on Wikipedia.
Handle available space more carefully when computing a table width, in
order to avoid creating a definite infinite width when available space
width is max-content, as it's the case in calculate_max_content_width.
The constraint is thus correctly propagated by the time we cache the
computed value, which was previously rejected by the hash function due
to being definite but infinite instead of max-content.
In GlobalEnvironment::get_binding_value(), we can avoid an extra walk
of the declarative environment record if has_binding() returns a
cacheable environment coordinate.
Most JS::Objects don't have lazily-allocated intrinsic properties,
so let's avoid doing hash lookups by putting a flag on JS::Object that
tells us whether it's present in s_intrinsics.
Takes CPU time spent in those hash lookups from 1-2.5% to nothing on
various JS heavy pages.
Like the piggybacking in CSS, this is also totally ad-hoc, since there's
no spec to follow.
The code here is weird and definitely sub-optimal as we do a second load
if it turns out the loaded resource is an image, but given that object
elements are rarely used nowadays, I doubt we'll even notice.
That said, we should of course improve this code as we move forward.
This is all ad-hoc since no spec currently exists for this behavior.
Basically, ImageStyleValue now uses ImageRequest for fetching and
decoding of images.
This already leads to visible improvements on many websites.
This forces us to diverge from the spec, but it's for a good cause:
by moving it into ImageRequest, we'll be able to reuse fetching and
decoding logic from CSS and other places.
This patch also makes ImageRequests shareable, currently keyed by
the URL (this part needs improvement!)
Previously, we did an evenodd fill for everything which while for most
SVGs works, it is not correct default (it should be nonzero), and broke
some SVGs. This fixes a few of the icons on https://shopify.com/.
Before this change we always returned the font's point size as the
x-height which was basically never correct.
We now get it from the OS/2 table (if one with version >= 2 is available
in the file). Otherwise we fall back to using the ascent of the 'x'
glyph. Most fonts appear to have a sufficiently modern OS/2 table.
Some of these functions can be called millions of times even for images
of moderate size. Inlining these functions really helps the compiler and
gives performance improvements up to 10%.
Inside each scan, raw data is read with the following rules:
- Each `0x00` that is preceded by `0xFF` should be discarded
- If multiple `0xFF` are following, only consider one.
That, plus the fact that we don't know the size of the scan beforehand
made us put a prepared stream in a vector for an easy, later on, usage.
This patch remove this duplication by realizing these operations in a
stream-friendly way.
This class is similar to some extent to an implementation of `Stream`,
but specialized for JPEG reading.
Technically, it is composed of a `Vector` to bufferize the input and
provides a simple interface to read bytes.
This patch aims for a future better and specialized control over the
input data. The encapsulation already allows us to get rid of the last
`seek` in the decoder, thus the ability to use the decoder with a raw
`Stream`.
As it provides faster `read` routines, this patch already reduces time
spend on reading.
Previously we were unable to parse code like `yield/2` because `/2`
was parsed as a regex. At the same time `for (a in / b/)` was parsed
as a division.
This is solved by defaulting to division in the lexer, but calling
`force_slash_as_regex()` from the parser whenever an IdentifierName
is parsed as a ReservedWord.
We need to add another pair of parenthesizes when propagating an
initialization of ItemListModel, because a comma in a template argument
would work as a separator of macro arguments, leading to a compile
error.
Bionic warns on this, but not passing the mode argument is technically
undefined behaviour (depending on the libc implementation of open), as
our LibC reads `mode` unconditionally (yolo!), just pass a zero to avoid
the UB.
Errors are now deferred until `finish_decode()` is finished, meaning
branches to return errors only need to occur at the end of a ranged
decode. If VPX_DEBUG is enabled, a debug message will be printed
immediately when an overread occurs.
Average decoding times for `Tests/LibGfx/test-inputs/4.webp` improve
by about 4.7% with this change, absolute decode times changing from
27.4ms±1.1ms down to 26.1ms±1.0ms.
This does a few things:
- The decoder uses a 32- or 64-bit integer as a reservoir of the data
being decoded, rather than one single byte as it was previously.
- `read_bool()` only refills the reservoir (value) when the size drops
below one byte. Previously, it would read out a bit-sized range from
the data to completely refill the 8-bit value, doing much more work
than necessary for each individual read.
- VP9-specific code for reading the marker bit was moved to its own
function in Context.h.
- A debug flag `VPX_DEBUG` was added to optionally enable checking of
the final bits in a VPX ranged arithmetic decode and ensure that it
contains all zeroes. These zeroes are a bitstream requirement for
VP9, and are also present for all our lossy WebP test inputs
currently. This can be useful to test whether all the data present in
the range has been consumed.
A lot of the size of this diff comes from the removal of error handling
from all the range decoder reads in LibVideo/VP9 and LibGfx/WebP (VP8),
since it is now checked only at the end of the range.
In a benchmark decoding `Tests/LibGfx/test-inputs/4.webp`, decode times
are improved by about 22.8%, reducing average runtime from 35.5ms±1.1ms
down to 27.4±1.1ms.
This should cause no behavioral changes.
This fixes an issue where man breaks if you symlink `sh` to a different
shell because:
1: The target of the symlink isn't `unveil`ed.
2: The option `--skip--shellrc` isn't understood by other shells while
at the same time being required for Shell when invoked in POSIX
compatibility mode.
This also restores the shell used by man to the non-POSIX mode as before
beaae6b420.
The specification isn't explicit about it, but the contribution we
compute should be distributed to all columns, not just the first one.
The first reason for it is symmetry, it doesn't make sense for the
increased width of the spanning column to only affect the first column
in the span.
The second reason is the formula for the cell contribution, which is
weighted by the non-spanning width of the cell relative to the total
width of the columns in the same row. This only covers a fraction of the
gap, in order to fully cover it we have to add it to all columns in the
span. For this to be exactly the case when the columns don't all have
the same width, we'd have to add additional weighting based on the width
ratios, but given that the specification doesn't suggest it at all we'll
leave it out for now.
We now check if the WebContent is executable before passing it to
the valgrind wrapper. We can't rely on exec() to fail here, since it
will always succeed even when passing a bad WebContent path to valgrind.
Change the name and return type of
`IPv6Address::to_deprecated_string()` to `IPv6Address::to_string()`
with return type `ErrorOr<String>`.
It will now propagate errors that occur when writing to the
StringBuilder.
There are two users of `to_deprecated_string()` that now use
`to_string()`:
1. `Formatted<IPv6Address>`: it now propagates errors.
2. `inet_ntop`: it now sets errno to ENOMEM and returns.
When comparing an ipv6 address against '::1', then compare against
the value object from `IPv6Address::loopback()`, instead of parsing the
string "::1" to an IPv6Address.
Calculate a "preferred aspect ratio" based on the value of
`aspect-ratio` and the presence of a natural aspect ratio, and use that
in layout.
This is by no means complete or perfect, but we do now apply the given
aspect-ratio to things.
The spec is a bit vague, just saying to calculate sizes for
aspect-ratio'ed boxes the same as you would for replaced elements. My
naive solution here is to find everywhere we were checking for a
ReplacedBox, and then also accept a regular Box with a preferred aspect
ratio. This gets us pretty far. :^)
https://www.w3.org/TR/css-sizing-4/#aspect-ratio-minimum is not at all
implemented.
Having this here instead of in ReplacedBox means we can access it when
figuring out what the "preferred aspect ratio" is.
There's some inconsistency between specs about what this is called, but
they're moving towards referring to this as "natural width/height/
aspect-ratio", so let's copy that terminology.
Anywhere that `<number>` appears in the grammar, `calc()` that resolves
to a number is valid, including inside the `<ratio>` grammar.
Thankfully, a calculation that produces a number cannot rely on any
context information for the calculation, so we can resolve them
straight away and just pretend they were a `<number>` the whole
time. :^)
`foo.is(Token::Type::Delim) && foo.token().delim() == '!'` becomes
`foo.is_delim('!')`, which is a lot less verbose. I really should have
done this ages ago.
The implementation of painting for SVG text follows the same pattern
as the implementation of painting for SVG geometries. However, instead
of reusing the existing PaintableWithLines to draw text, a new class
called SVGTextPaintable is introduced. because everything that is
painted inside an SVG is expected to inherit from SVGGraphicsPaintable.
Therefore reusing the text painting from regular text nodes would
require significant refactoring.
The `<style>` element is allowed to be in the SVG namespace, so we now
support this element.
It has the same behaviour as the HTML namespace `<style>` element as
described in the spec.
"The semantics and processing of a ‘style’ and its attributes must be
the same as is defined for the HTML ‘style’ element."