They currently assume the DOM node is an HTMLImageElement with respect
to handling the alt attribute. The HTMLInputElement will require the
same behavior.
We already have the src attribute stored as a String, so it's completely
wasteful to convert it to a ByteString. We were even doing it twice when
loading each image.
The BatchingDispatcher mechanism is used by HTMLImageElement to avoid
decoding one image at a time, since interleaving decode/layout/repaint
over and over takes way more time than doing many decodes followed by
a single layout/repaint pair.
Before this change, we didn't have a limit on how many batched loads
we'd allow ourselves to queue up, which could lead to situations where
more and more images kept being added to the queue, and never getting
processed.
This fixes the issue by putting an arbitrary limit (16) on the number
of batched image loads, and then allowing the flush to happen after
that instead of re-deferring processing.
Instead of making the "Entry" inner struct GC-allocated and marking
*that*, we now mark the image instead.
This fixes an issue found by ASAN on https://mozilla.com/
In a bunch of cases, this actually ends up simplifying the code as
to_number will handle something such as:
```
Optional<I> opt;
if constexpr (IsSigned<I>)
opt = view.to_int<I>();
else
opt = view.to_uint<I>();
```
For us.
The main goal here however is to have a single generic number conversion
API between all of the String classes.
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).
This commit is auto-generated:
$ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
Meta Ports Ladybird Tests Kernel)
$ perl -pie 's/\bDeprecatedString\b/ByteString/g;
s/deprecated_string/byte_string/g' $xs
$ clang-format --style=file -i \
$(git diff --name-only | grep \.cpp\|\.h)
$ gn format $(git ls-files '*.gn' '*.gni')
This change fixes GC-leak caused by following mutual dependency:
- SVGDecodedImageData owns JS::Handle for Page.
- SVGDecodedImageData is owned by visited objects.
by making everything inherited from HTML::DecodedImageData and
ListOfAvailableImages to be GC-allocated.
Generally, if visited object has a handle, very likely we leak
everything visited from object in a handle.
`<iframe>` and `<img>` tags share the same spec for several aspects of
lazy-loading: how the `loading` attribute works, the "will lazy load
element" steps, and a member for storing the lazy-load resumption
steps. So let's share the implementation by using a base class.
This mostly involves moving things around. However, we also change the
`start_intersection_observing_a_lazy_loading_element()` method to take
a LazyLoadingElement, and operate on one, instead of always casting to
HTMLImageElement.
We do unfortunately have to do some shenanigans to make the cast work,
by adding a virtual function stub in DOM::Element.
Before this change, we used Gfx::Bitmap to represent both decoded
images that are not going to be mutated and bitmaps corresponding
to canvases that could be mutated.
This change introduces a wrapper for bitmaps that are not going to be
mutated, so the painter could do caching: texture caching in the case
of GPU painter and potentially scaled bitmap caching in the case of CPU
painter.
With this change, we now have ~1200 CellAllocators across both LibJS and
LibWeb in a normal WebContent instance.
This gives us a minimum heap size of 4.7 MiB in the scenario where we
only have one cell allocated per type. Of course, in practice there will
be many more of each type, so the effective overhead is quite a bit
smaller than that in practice.
I left a few types unconverted to this mechanism because I got tired of
doing this. :^)
This commit removes DeprecatedString's "null" state, and replaces all
its users with one of the following:
- A normal, empty DeprecatedString
- Optional<DeprecatedString>
Note that null states of DeprecatedFlyString/StringView/etc are *not*
affected by this commit. However, DeprecatedString::empty() is now
considered equal to a null StringView.
Renaming the DeprecatedString version of this function to
Element::get_deprecated_attribute.
While performing this rename, port over functions where it is trivial to
do so to the Optional<String> version of this function.
This should allow us to add a Element::attribute which returns an
Optional<String>. Eventually all callers should be ported to switch from
the DeprecatedString version, but in the meantime, this should allow us
to port some more IDL interfaces away from DeprecatedString.
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.
With this change, elements that want to receive viewport rect updates
will need to register on document instead of the browsing context.
This change solves the problem where a browsing context for a document
is guaranteed to exist only while the document is active so browsing
context might not exit by the time DOM node that want to register is
constructed.
This is a part of preparation work before switching to navigables where
this issue becomes more visible.
This allows to partially solve the problem of cyclic dependency between
HTMLImageElement and SharedImageRequest that prevents all image
elements from being deallocated.
Stop worrying about tiny OOMs. Work towards #20449.
While going through these, I also changed the function signature in many
places where returning ThrowCompletionOr<T> is no longer necessary.
Reactive images that had an image source selected based on viewport
size would only update when the images were first fetched, meaning the
last valid image source would become stuck in an image element. By
implementing the last step for reacting to environment changes, we can
run the proper updates even when the image does not need to be fetched.
This patch implements "react to changes in the environment" from the
HTML spec and hooks HTMLImageElement up with viewport rect change
notifications (from the browsing context).
This fixes the issue where we'd load a low-resolution image and not
switch to a high-resolution image after resizing the window.
Note that we currently can't resolve calc() values without a layout
node, so when normalizing an image's source set, we'll flush any pending
layout updates and hope that gives us an up-to-date layout node.
I've left a FIXME about implementing this in a more elegant and less
layout-thrashy way, as that will require more architectural work.
Before this change, we would process each image as it finished
downloading. This often led to a situation where we'd decode 1 image,
schedule a layout, do the layout, then decode another image, schedule
a layout, do the layout, etc. Basically decoding and layouts would get
interleaved even though we had multiple images fetched and ready for
decoding.
This patch adds a simple BatchingDispatcher thingy that HTMLImageElement
uses to batch the handling of successful fetches.
With this, the number of layouts while loading https://shopify.com/ goes
from 48 to 6, and the page loads noticeably faster. :^)
Now that we use the HTML image loading algorithm from spec, we can
implement complete correctly.
This (finally) fixes an issue where images were not loading on
https://twinings.co.uk/ :^)
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.
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.
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!)
Now that the processResponseConsumeBody algorithm receives the internal
response body of the fetched object, we do not need to go out of our way
to read its body from outside of fetch.
However, several elements do still need to manually inspect the internal
response for other data, such as response headers and status. Note that
HTMLScriptElement already does the new workaround as a proper spec step.
In order to separate the SVG content from the rest of the engine, it
gets its very own Page, PageClient, top-level browsing context, etc.
Unfortunately, we do have to get the palette and CSS/device pixel ratios
from the host Page for now, maybe that's something we could refactor in
the future.
Note that this doesn't work visually yet, since we don't calculate the
intrinsic sizes & ratio for SVG images. That comes next. :^)
This allows the painting subsystem to request a bitmap with the exact
size needed for painting, instead of being limited to "just give me a
bitmap" (which was perfectly enough for raster images, but not for
vector graphics).