Implements `table.get`, `table.set`, `elem.drop`, `table.size`,
and `table.grow`. Also fixes a few issues when generating ref-related
spectests. Also changes the `TableInstance` type to use
`Vector<Reference>` instead of `Vector<Optional<Reference>>`, because
the ability to be null is already encoded in the `Reference` type.
This allows searching for text with case-insensitivity. As this is
probably what most users expect, the default behavior is changes to
perform case-insensitive lookups. Chromes may add UI to change the
behavior as they see fit.
This allows the browser to send a query to the WebContent process,
which will search the page for the given string and highlight any
occurrences of that string.
This adds a `--experimental-cpu-transforms` option to Ladybird and
WebContent (which defaults to false/off).
When enabled the AffineCommandExecutorCPU will be used to handle
painting transformed stacking contexts (i.e. stacking contexts where
the transform is something other than a simple translation). The regular
command executor will still handle the non-transformed cases.
This is hidden under a flag as the `AffineCommandExecutorCPU` is very
incomplete now. It missing support for clipping, text, and other basic
commands. Once most common commands have been implemented this flag
will be removed.
This CommandExecutor is intended to provide better support for painting
stacking contexts where the transform is not a simple translation. It
is not intended to replace the CPU command executor (as its methods of
painting will likely be slower for the non-transformed case), instead,
it will function as a companion executor to handle transformations.
This is only intended to properly handle 2D transformations (skews,
rotations, scaling, etc). Full support for 3D transformations would
need further changes in LibGfx.
As it stands this is (very) incomplete and experimental, but hopefully,
this can be fleshed out to the point where it supports most common
painting commands.
This adds two new CommandResults: ContinueWithNestedExecutor and
ContinueWithParentExecutor.
ContinueWithNestedExecutor switches the command executor to the result
of calling `.nested_executor()` on the current CommandExecutor.
ContinueWithParentExecutor returns to the previous command executor
(i.e. what it was before the last ContinueWithNestedExecutor).
`Painting::paint_all_borders()` only uses `.draw_line()` for simple
borders and `.fill_path()` for more complex cases. These are both
already supported by the `RecordingPainter` so removing this command
simplifies the painting API.
Two test changes:
css-background-clip-text: Borders are now drawn via the AA painter
(which makes them closer to how they appear in other browsers).
corner-clip-inside-scrollable: Borders removed (does not change test)
due to imperceptible sub-pixel changes.
...instead of scheduling repaint timer in PageClient.
This change fixes flickering on Discord that happened because:
- Event loop schedules repainting by activating repaint timer
- `Document::tear_down_layout_tree()` destroys paintable tree
- Repaint timer invokes callback and renders an empty frame because
paintable tree was destroyed
Although refreshing is cheap, it was performed before each hit-testing
and was 2-4% in profiles on Discord and Twitter.
Now clip and scroll states are refreshed only if scroll offset has
changed.
Previously, we always cast to a HTMLInputElement when getting the value
of an auto directionality form associated element. This caused
undefined behavior when determining the directionality of an element
that wasn't a HTMLInputElement.
Previously, we assumed that all label control paintables were of type
`LabelablePaintable`. This caused a crash when clicking on a label with
a text input control.
As with all other current audio nodes we still need to wire up the
inputs and outputs so it can be properly used in an audio context - but
this is enough to implement the public IDL interface.
...instead of allocating separate BorderRadiusCornerClipper for each
executed sample/blit commands pair.
With this change a vector of BorderRadiusCornerClipper has far fewer
items. For example on twitter profile page its size goes down from
~3000 to ~3 items.
Before, this check was needed to prevent crashing when attempting to
allocate zero-size bitmap for sampled corners, which could have happened
if a corner had 0 radius in one axis.
Now, since SampleUnderCorners command is not emmited when radius is 0
in one axis, this check is no longer needed.
This reverts commit 6b7b9ca1c4b32e76e0afef6bca0cb300e615b576.
The whole corner radius is invisible if it has 0 radius in any axis, so
the reverted commit was a mistake that led to error checking during
painting command execution b61aab66d9 to
avoid crashing on attempt to allocate 0 size bitmap.
EventSource allows opening a persistent HTTP connection to a server over
which events are continuously streamed.
Unfortunately, our test infrastructure does not allow for automating any
tests of this feature yet. It only works with HTTP connections.
Supporting unbuffered fetches is actually part of the fetch spec in its
HTTP-network-fetch algorithm. We had previously implemented this method
in a very ad-hoc manner as a simple wrapper around ResourceLoader. This
is still the case, but we now implement a good amount of these steps
according to spec, using ResourceLoader's unbuffered API. The response
data is forwarded through to the fetch response using streams.
This will eventually let us remove the use of ResourceLoader's buffered
API, as all responses should just be streamed this way. The streams spec
then supplies ways to wait for completion, thus allowing fully buffered
responses. However, we have more work to do to make the other parts of
our fetch implementation (namely, Body::fully_read) use streams before
we can do this.
This adds an alternate API to ResourceLoader to load HTTP/HTTPS/Gemini
requests unbuffered. Most of the changes here are moving parts of the
existing ResourceLoader::load method to helper methods so they can be
re-used by the new ResourceLoader::load_unbuffered.
LibWeb will need to use unbuffered requests to support server-sent
events. Connection for such events remain open and the remote end sends
data as HTTP bodies at its leisure. The browser needs to be able to
handle this data as it arrives, as the request essentially never
finishes.
To support this, this make Protocol::Request operate in one of two
modes: buffered or unbuffered. The existing mechanism for setting up a
buffered request was a bit awkward; you had to set specific callbacks,
but be sure not to set some others, and then set a flag. The new
mechanism is to set the mode and the callbacks that the mode needs in
one API.
This is to avoid including any LibProtocol header in Objective-C source
files, which will cause a conflict between the Protocol namespace and a
@Protocol interface.
See Ladybird/AppKit/Application/ApplicationBridge.cpp for why this
conflict unfortunately cannot be worked around.
All painting commands except SetClipRect are shifted by scroll offset
before command list execution. This change removes scroll offset
translation for sample/blit corner commands in
`PaintableWithLines::paint` so it is only applied once in
`CommandList::apply_scroll_offsets()`.
Currently, these only work when there are no CSS transforms (as the
stacking context painting is not set up to handle that case yet). This
is still enough to get most chat/comment markers working on GitHub
though :^)
- Less allocations
- Optimization pass that skips unnecessary sample/blit corner commands
could be more effecient by ignoring corner radius clipping for empty
painting commands
Both page target bitmap and mask bitmap are always BGRA8888, so we can
use `get_pixel<StorageFormat::BGRA8888>` and
`set_pixel<StorageFormat::BGRA8888>` to avoid branching by not
checking a bitmap format.
The if statement in the dispatch implies we are in the idle state, so of
course the active time will always be undefined. If this was cancelled
via a call to cancel(), we can save the time at that point. Otherwise,
just send 0.
I saw a null pointer dereference here on GitHub once, but don't know how
to reproduce, or how we'd get here. Nevertheless, null-checking the
navigable is reasonable so let's do it.
This patch fixes two issues:
- Animation events that should go to the target element now do
(some were previously being dispatched on the animation itself.)
- We update the "previous phase" and "previous iteration" fields of
animation effects, so that we can actually detect phase changes.
This means we stop thinking animations always just started,
something that caused each animation to send 60 animationstart
events every second (to the wrong target!)
We enqueue a microtask for this readable stream AO, and the methods that
we call from the chunk steps manipulate promises. As such, we need to
enable callbacks for the entire microtask's temporary execution
context.
By using separate struct we can avoid updating AST node and
ECMAScriptFunctionObject constructors every time there is a need to
add or remove some additional information colllected during parsing.
As it's not uncommon for users to drop the module instance on the floor
after having grabbed the few exports they need to hold on to.
Fixes a few UAFs that show up as "invalid" accesses to
memory/tables/etc.
Allows to skip function environment allocation for non-arrow functions
if the only reason it is needed is to hold `this` binding.
The parser is changed to do following:
- If a function is an arrow function and uses `this` then all functions
in a scope chain are marked to allocate function environment for
`this` binding.
- If a function uses `new.target` then all functions in a scope chain
are marked to allocate function environment.
`ordinary_call_bind_this()` is changed to put `this` value in execution
context when function environment allocation is skipped.
35% improvement in Octane/typescript.js
50% improvement in Octane/deltablue.js
19% improvement in Octane/raytrace.js
This change adds the `width` and `height` properties to
`HTMLVideoElement` and `HTMLSourceElement`. These properties reflect
their respective content attribute values.
ReadLoopReadRequest::on_chunk expects an UInt8Array, so make sure we
convert the passed in ByteBuffer to an UInt8Array before passing it to
the AO writable_stream_default_writer_write.
Co-authored-by: Timothy Flynn <trflynn89@pm.me>
This callback is meant to be triggered by streams, which does not always
provide a WebIDL::DOMException. Pass a plain value instead. Of all the
users of this callback, only one actually uses the value, and already
converts the DOMException to a plain value.
This returns the secondary target of a mouse event. For `onmouseenter`
and `onmouseover` events, this is the EventTarget the mouse exited
from. For `onmouseleave` and `onmouseout` events, this is the
EventTarget the mouse entered to.
I saw that this not being implemented was causing a javascript exception
to be thrown when loading https://profiler.firefox.com/.
I was hoping that like the last time that partially implementing this
interface would allow the page to load further, but it seems that this
is unfortunately not the case this time!
However, this may help other pages load slightly further, and puts some
of the scaffolding in place for a proper implementation :^)
For now, this slot is always 0 - (the default value per spec). But
once we start actually processing audio streams this internal slot
should be changed correspondingly.
This will help us in detecting potential web compatability issues from
not having this implemented.
While we're at it, update the spec link, as it was moved from the DOM
parsing spec to the HTML one, and implement this function in a manner
that closr resembles spec text.
Previously, when looking for the labeled control of a label element, we
were only checking its child elements. The specification says we should
check all elements in the same tree as the label element.
It is now possible to pass an optional `ImageDataSettings` object to
the `CanvasImageData.createImageData()` and
`CanvasImageData.getImageData()` methods.
We'll want to explicitly load fonts from FontFace and other Web APIs
in the future. A future refactor should also move this completely away
from StyleComputer and call it something like 'FontCache'.
Instead of copying the image data pixel-by-pixel, we can memcpy full
scanlines at a time.
This knocks a 4% item down to <1% in profiles of Another World JS.
Performing a lookup in the blob URL registry does not work in the case
of a web worker - as the registry is not shared between processes.
However - the URL itself passed to a worker has the blob attached to it,
which we can pull out of the URL on a fetch.
Implement this function to the spec, and use the full blown URL parser
that handles blob URLs, instead of the basic-url-parser.
Also clean up a FIXME that does not seem relevant any more.
This matches the IDL definition. Without this we experience a compile
time error when adding the WheelEvent constructor due to a mimatched
type between the enum class and UnsignedLong that the prototype is
passing through to the event init struct for the constructor.
This was an unfortunate artifact from development. I originally added
this class in the DOM namespace alongside HTMLCollection until I
realized it was defined by the HTML spec instead. To remind myself to
move it over to the HTML namespace, I left this comment. It was moved
to the correct namespace before upstreaming to the main repo, but I
forgot to remove this comment!
For bitmap fonts, we will often not have an exact match for requested
sizes. Return the closest match instead of a nullptr.
LibWeb is currently the only user of this API. If it needs to be
configurable in the future to only allow exact matches, we can add a
parameter or another method at that time.
This makes sure `get_mask_type_of_svg()` finds the mask or clipPath by
looking at its child layout nodes. Previously, it went via the DOM node
of the mask or clipPath, which is not always correct as there is not a
1-to-1 mapping from mask DOM node to SVGMaskBox (or SVGClipBox).
Fixes#24186
We can now tell the difference between an own property access and a
subsequent (automatic) prototype chain access.
This will be used to implement caching of prototype chain accesses.
Previously, the SVGPathPaintable walked up the DOM tree to find the
containing SVG, however, this does not hold for masks/clipPaths that
are not local to the current SVG. Instead, we should walk the layout
tree where we should always be able to find the current SVG as an
ancestor.
The spec isn't _super_ clear on how this is meant to be done, but the
way I understand this is that we should simply clamp the returned
'current value' between 'min' and 'max'.
Firefox does not appear to do this clamping, but Chrome does.
I can't actually spot in the spec where it explicitly says to pass this
through (unlike the AudioContext constructor) - but clearly this needs
to be passed through for an OfflineAudioContext to actually have a
sample rate!
This is a simple getter and setter of the OscillatorType enum, with
error checking to not allow 'custom', as that should only be changed
through 'setPeriodicWave()'.
This is still missing a bunch of spec steps to construct the
audio node based on the parameters of the OscillatorNode, but it is at
least enough to construct an object to be able to add a basic test which
can get built upon as more is implemented.
If a function has the following properties:
- uses only local variables and registers
- does not use `this`
- does not use `new.target`
- does not use `super`
- does not use direct eval() calls
then it is possible to entirely skip function environment allocation
because it will never be used
This change adds gathering of information whether a function needs to
access `this` from environment and updates `prepare_for_ordinary_call()`
to skip allocation when possible.
For now, this optimisation is too aggressively blocked; e.g. if `this`
is used in a function scope, then all functions in outer scopes have to
allocate an environment. It could be improved in the future, although
this implementation already allows skipping >80% of environment
allocations on Discord, GitHub and Twitter.
Which currently will always throw an exception as it is unimplemented
under the hood - but this gives all of the plumbing we need in order to
create a oscillator node as used in the reduced turnstyle testcase.
An AudioNode is the fundamental building block used in 'Audio
Contexts'. In our immediate case, the audio node we are working towards
implementing is an oscillating source node.
The ReadableStreamPipeTo AO requires reading all chunks from a stream.
There actually isn't an AO defined to do that, so the "read all bytes"
implementation was changed to provide each chunk in a vector in commit
12cfa08a09.
This change makes reading all bytes a bit more uncomfortable in normal
use cases, as we now have to manually join the vector we receive. This
can also cause churn with huge allocations.
So instead, let's just provide an ad-hoc callback to receive each chunk
as they arrive.