Here's a reasonably faithful implementation of ECMAScript 2021 18.2.5.
Some corner cases are not covered, I've left them as FIXME's in the
included unit test.
Also I had to tweak JS::Value::to_i32() to always convert infinity to
zero, which is in accordance with ToInt32 AFAICT.
We were not accounting for space occupied by borders when computing
the vertical (y) position of blocks. This meant that blocks with wide
top/bottom borders could bleed into each other incorrectly.
Fix this by using the combined padding+border geometry instead of just
the padding when placing blocks on the y axis.
We were incorrectly resolving relative length units (ex, em, etc.)
against the containing block in many cases. Fix this to resolve them
against the descendant box we're currently processing.
Instead of doing a CSS property lookup for the line style of each
border edge during paint, we now cache the final CSS::LineStyle to use
in the Layout::BorderData.
TerminalWidget will now automatically scroll up or down when the user
drags the mouse out of its bounds while selecting text. This happens
at a fixed speed.
In order for inline elements (e.g <span>) to contribute padding etc.
to line boxes, we now create special "leading" and "trailing" fragments
for Layout::InlineNode and size them according to the horizontal
padding values.
The height of these fragments is taken from the tallest fragment on the
line. (Perhaps we should stop having per-fragment heights and just keep
a single height per line box, but that's a separate issue.)
In order to make things look nice, we now also adjust the height of all
fragments on a line so that nobody is shorter than the CSS line-height.
Fragment painting was very limited by only being called during the
foreground paint phase. We now paint fragments as part of every phase
(and the phase is passed to paint_fragment() of course!)
We were rejecting perfectly valid z-index values like '1000' since we
were passing all CSS values through the length parser and unit-less
lengths are not valid in this context.
It's yet another hack for the ad-hoc CSS parser (its days are numbered)
but this makes the top header links on google.com actually work. :^)
Calling Frame::set_size() already triggered a relayout, so calling
layout() again right after meant we did all the work one more time.
Not being dumb like this makes resizing significantly smoother. :^)
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.
This is how the spec describes it, and it allows sharing data between
multiple typed arrays.
Typed arrays now support constructing from an existing ArrayBuffer,
and has been prepared for constructing from another typed array or
iterator as well.
We should pay more attention to using the well-defined abstract
operations from the spec rather than making up our own, often slightly
different rules. This is another step in that direction.
We have multiple array types now, so ArrayInvalidLength has been
replaced with a generic InvalidLength.
Also fixes a small issue in the Array constructor, it should throw
RangeError for invalid lengths, not TypeError.
Previously, in the case of RLE4, parsing took suspiciously long.
What happened was that 'pixel_count' was 255, and 'i' was incremented
by *two* in each iteration, so the for-loop continued until the
entire output buffer was full, and then rejected the RLE data
as bogus.
This little diff allows pixel_count to reach 256, be greater than
pixel_count, and thus terminate the loop in the intended way.
The Audio::Loader class is able to load different types of audio files
by using a generic plugin interface for all file formats. Every new
loader will have to derive from Audio::LoaderPlugin to provide a common
API.
This makes it easy to add support for more audio file formats in the future.
We need to call waitpid until no more waitable children are available.
This is necessary because SIGCHLD signals may coalesce into one when
multiple children terminate almost simultaneously.
Also, switch to EventLoop's asynchronous signal handling mechanism,
which allows more complex operations in the signal handler.
- Calling without 'new' is an error
- If the first argument is an object, we need a separate code path to
initialize from TypedArray, ArrayBuffer, Iterable or Array-like
object (marked TODO for now)
- Don't insert values into array if more than one argument is present
(that's not part of the spec)
The current implementation is not entirely correct yet. Two classes have
been added:
- TypedArrayConstructor, which the various typed array constructors now
inherit from. Calling or constructing this class (from JS, that is)
directly is not possible, we might want to move this abstract class
functionality to NativeFunction at a later point.
- TypedArrayPrototype, which the various typed array prototypes now have
as their own prototype. This will be the place where most of the
functionality is being shared.
Relevant parts from the spec:
22.2.1 The %TypedArray% Intrinsic Object
The %TypedArray% intrinsic object:
- is a constructor function object that all of the TypedArray
constructor objects inherit from.
- along with its corresponding prototype object, provides common
properties that are inherited by all TypedArray constructors and their
instances.
22.2.2 Properties of the %TypedArray% Intrinsic Object
The %TypedArray% intrinsic object:
- has a [[Prototype]] internal slot whose value is %Function.prototype%.
22.2.2.3 %TypedArray%.prototype
The initial value of %TypedArray%.prototype is the %TypedArray%
prototype object.
22.2.6 Properties of the TypedArray Constructors
Each TypedArray constructor:
- has a [[Prototype]] internal slot whose value is %TypedArray%.
22.2.6.2 TypedArray.prototype
The initial value of TypedArray.prototype is the corresponding
TypedArray prototype intrinsic object (22.2.7).
22.2.7 Properties of the TypedArray Prototype Objects
Each TypedArray prototype object:
- has a [[Prototype]] internal slot whose value is %TypedArray.prototype%.
22.2.7.2 TypedArray.prototype.constructor
The initial value of a TypedArray.prototype.constructor is the
corresponding %TypedArray% intrinsic object.
- OSv2 DIBs were not checked at all
- Regular Info DIBs had the compression checked after applying a 0xFF mask,
which let many invalid compression values pass.
- There may still be a separate latent bug that causes mask_sizes and mask_shifts to be empty.