This is closer to what the spec instructs us to do, and matches how
associations are maintained in the timelines. Also note that the removed
destructor logic is not necessary since we visit the associated
animations anyways.
We create labels in the Browser from text on web documents, which may
use carriage returns. LibGfx will split lines on CR already, but LibGUI
would not consider CRs when computing the height of the containing
widget. The result was text that would not fit in the label's box.
Fixes pages 17-19 on
https://www.iro.umontreal.ca/~feeley/papers/ChevalierBoisvertFeeleyECOOP15.pdf
Calling the fill handler after painting the stroke as previously doesn't
work, since we need to set up the clip before both stroke and fill, and
unset it after both. The duplication is a bit unfortunate, but also
minor.
ObservableArray inherits from JS::Array and overrides `internal_set`
and `internal_delete` to run an interceptor callback when an indexed
item is added or deleted.
This is for validating that a decoder with a weak or nonexistent
sniff() method thinks it can decode an image. This should not be
treated as an error.
No behavior change.
We are currently using Core::DateTime, which is meant to represent local
time. However, we are doing no conversion between the parsed time in UTC
and local time, so we end up comparing time stamps from different time
zones.
Instead, store the parsed times as UnixDateTime, which is UTC. Then we
can always compare the parsed times against the current UTC time.
This also lets us store parsed milliseconds.
Displaying a GML preview in HackStudio seems to be broken at the moment,
but this change will be needed once it does work again, so might as well
make it now, while I'm aware of the issue.
When in permissive mode, the ConfigServer will not treat reads and
writes to non-pledged domains as errors, but instead turns them into
no-ops: Reads will act as if the key was not found, and writes will do
nothing. Permissive mode must be enabled before pledging any domains.
This is needed to make GUI Widgets nicer to work with in GML Playground:
a few Widgets include reads and writes to LibConfig in order to load
system settings (eg, GUI::Calendar) or to save and restore state
(eg, GUI::DynamicWidgetContainer). Without this change, editing a
layout that includes one of these Widgets will cause GML Playground to
crash when they try to access config domains that are not pledged.
The solution used previously is to make Playground pledge more domains,
but not only does this mean Playground has to know about these cases,
but also that working on a layout file can alter the user's settings in
other arbitrary apps, which is not something we want.
By simply ignoring these config accesses, we avoid those downsides, and
Widgets will simply use the fallback values they already have to provide
to Config::read_foo_value().
Turns out the spec didn't mean that the whole range is populated,
but that one of these ranges is populated. So take the argmax.
As fallout, explicitly mark the Liberation fonts as nonsymbolic
when we use them for the 14 standard fonts. Else, we'd regress
"PostScrõpt", since the Liberation fonts would otherwise go down
the "is symbolic or doesn't have explicit encoding" codepath,
since the standard fonts usually don't have an explicit encoding.
As a fallout from _that_, since the 14 standard fonts now go down
the regular truetype rendering path, and since we don't implement
lookup by postscript name yet, glyphs not present in Liberation
now cause text to stop rendering with a diag, instead of rendering
a "glyph not found" symbol. That isn't super common, only an
additional 4 files appear for the "'post' table not yet implemented"
diag. Since we'll implement that soon, this seems fine until then.
...from try_create_for_raw_bytes().
If a plugin returns `true` from sniff but then fails when calling
its `create()` method, we now no longer swallow that error.
Allows `image` (and other places in the system) to print a more
actionable error if early image headers are invalid.
(We now no longer try to find another plugin that can also handle
the image.)
Fixes a regression from #20063 / #19893 -- before then, we didn't
do fallible work this early.
When placement position is found we always want to do following:
- Mark the occupied cells in the occupation grid
- Add the item to the list of placed items
Therefore, having helper that does both is useful
With this change we use the same code to resolve (start, end, span)
based on computed values in all cases:
- When only column is definite
- When only row is definite
- When both are definite
Moves the code that identifies (start, end, span) for a grid item into
a separate function. By doing so, we can eliminate the duplicated code
between the placement of grid items with definite columns and those
with definite rows.
This change omits some of the comments that reference the spec, as they
were largely irrelevant and unhelpful for making changes or diagnosing
issues.
Table wrappers don't quite behave the same as most elements, in that
their computed height and width are not meant to be used for layout.
Instead, we now calculate suitable widths and heights based on the
contents of the table wrapper when performing absolute layout.
Fixes the layout of
http://wpt.live/css/css-position/position-absolute-center-007.html
These are invoked by GitHub when submitting a comment. Stub them out for
now, as this is enough to let GitHub proceed with (attempting) to submit
the comment.
Note no test here, because this early return involves HTTP-only cookies,
which we don't have the infrastructure to test (we would need to support
custom HTTP headers in tests).
It's no change in application behavior to have these objects owned by
the function-scope static map in Protocol.cpp, while allowing us to
remove some ugly FIXMEs from time immemorial.
Now that all input events are handled by LibWebView, replace the IPCs
which send the fields of Web::KeyEvent / Web::MouseEvent individually
with one IPC per event type (key or mouse).
We can also replace the ad-hoc queued input structure with a smaller
struct that simply holds the tranferred Web::KeyEvent / Web::MouseEvent.
In the future, we can also adapt Web::EventHandler to use these structs.
The Serenity chrome is the only chrome thus far that sends all input key
and mouse events to WebContent, including shortcut activations. This is
necessary for all chromes - we must give web pages a chance to intercept
input events before handling them ourselves.
To make this easier for other chromes, this patch moves Serenity's input
event handling to LibWebView. To do so, we add the Web::InputEvent type,
which models the event data we need within LibWeb. Chromes will then be
responsible for converting between this type and their native events.
This class lives in LibWeb (rather than LibWebView) because the plan is
to use it wholesale throughout the Page's event handler and across IPC.
Right now, we still send the individual fields of the event over IPC,
but it will be an easy refactor to send the event itself. We just can't
do this until all chromes have been ported to this event queueing.
Also note that we now only handle key input events back in the chrome.
WebContent handles all mouse events that it possibly can. If it was not
able to handle a mouse event, there's nothing for the chrome to do (i.e.
there is no clicking, scrolling, etc. the chrome is able to do if the
WebContent couldn't).
Animation::play_state() does not consider the fill state, and thus will
not return "Playing" for a fill-forward animation in the after phase.
It is still valid for paused, as pausing is not affected by the fill
mode.
All of this error propogation came from a single call to
HashMap::try_ensure_capacity! As part of the ongoing effort to ignore
small allocation failures, lets just assert this works. This has the
nice side-effect of propogating out to a few other classes.
Before this change, we only considering `grid-auto-flow` to determine
whether a row or column should be added when there was not enough space
in the implicit grid to fit the next unplaced item.
Now, we also choose the direction in which the "auto placement cursor"
is moved, based on the auto flow property.
This involves plumbing the perform the fetch hook argument throughout
all of the module fetch implementation AOs, where it was left as a FIXME
before.
With this change we can load module scripts in DedicatedWorkers.
This will be used to transfer information about the parent context to
DedicatedWorkers and future out-of-process Worker/Worklet
implementations for fetching purposes. In order to properly check
same-origin and other policies, we need to know more about the outside
settings than we were previously passing to the WebWorker process.
We previously used an empty optional to denote that a ReferrerPolicy is
in the default empty string state. However, later additions added an
explicit EmptyString state. This patch moves all users to the explicit
state, and stops using `Optional<ReferrerPolicy>` everywhere except for
when an option not being passed from JavaScript has meaning.
When buffering is enabled for the entire protocol request, it's possible
that the entirety of the file data might be available on the first read
of the pipe passed from RequestServer. If the file is then closed on the
RequestServer end, the client would never realize that the file is EOF
and call the user-provided on_finish callback.
By reading until there's an error, we expect to get an EAGAIN or similar
non-blocking pipe error message if there is still more data.
Also add a note to the Concepts header that the reason we have all the
strange concepts in place for container types is to work around the
language limitation that we cannot partially specialize function
templates.
The semantics of BGRx8888 aren't super clear and it means different
things for different parts of the codebase. In particular, the PNG
writer still writes the x channel to the alpha channel of its output.
In BMPs, the 4th palette byte is usually 0, which means after #21412 we
started writing all .bmp files with <= 8bpp as completely transparent
to PNGs.
This works around that.
(See also #19464 for previous similar workarounds.)
The added `bitmap.bmp` is a 1bpp file I drew in Photoshop and saved
using its "Save as..." saving path.
As long as the inputs are Int32, we can convert them to UInt32 in a
spec-compliant way with a simple static_cast<u32>.
This allows calculations like `-3 >>> 2` to take the fast path as well,
which is extremely valuable for stuff like crypto code.
While we're doing this, also remove the fast paths from the generic
shift functions in Value.cpp, since we only end up there if we *didn't*
take the same fast path in the interpreter.
Since get() returns an empty Optional if the index is not present, we
can combine these two into a single get() operation and save the cost of
a virtual call.
This patch adds a new "Peephole" pass for performing small, local
optimizations to bytecode.
We also introduce the first such optimization, fusing a sequence of
some comparison instruction FooCompare followed by a JumpIf into a
new set of JumpFooCompare instructions.
This gives a ~50% speed-up on the following microbenchmark:
for (let i = 0; i < 10_000_000; ++i) {
}
But more traditional benchmarks see a pretty sizable speed-up as well,
for example 15% on Kraken/ai-astar.js and 16% on Kraken/audio-dft.js :^)
The entry block must stay in place, although it's okay to merge stuff
into it.
This fixes 4 test262 tests and brings us to parity with optimization
disabled. :^)
There is a limit of 3 attempts before quitting, but the user can try
again after that.
The error messages now display to help the user understand the issue.
With this the `<circle>` element now correctly parses percentage sizes,
and resolves them relative to the viewport.
The rest of the geometry elements are still left TODO.
This will allow resolving paths that use sizes that are relative to the
viewport. This necessarily removes the on element caching, which has
been redundant for a while as computed paths are stored on the
paintable.
This was seen in Browser when hotkey activations were processed twice.
If we open the Inspector with a hotkey (F12) and quickly activate that
hotkey again, we could try sending a JS command (inspector.loadDOMTree)
before the inspector.js file was actually loaded in the WebContent.
The window for this bug is larger on Serenity, where loading WebContent
is a bit slower than on Linux. So even with the Browser bug fixed, it is
pretty easy to hit this window still.
This reverts commit 2e8ff1855c.
We had some awkward timing around the merging of this commit and commit
b073fdd570. With both commits in tree, we
are now processing hotkey activations twice. For example, ctrl+t will
open 2 tabs.
Instead of emitting a NewBigInt instruction to construct a primitive
bigint from a parsed literal, we now instantiate the BigInt on the heap
during codegen.
Instead of emitting a NewString instruction to construct a primitive
string from a parsed literal, we now instantiate the PrimitiveString on
the heap during codegen.
The property values here will always be StyleValueLists and not
TransformationStyleValues. The handling of interpolation in this case
gets quite a bit more complex, so let's just remove the dead code for
now and attempt this optimization again in the future if it's needed.
An array image mask contains a min/max range for each channel,
and if each channel of a given pixel is in that channel's range,
that pixel is masked out (i.e. transparent). (It's similar to
having a single color or palette index be transparent, but it
supports a range of transparent colors if desired.)
What makes this a bit awkward is that the range is relative to the
origin bits per pixel and the inputs to the image's color space.
So an indexed (palettized) image with 4bpp has a 2-element mask
array where both entries are between 0 and 15.
We currently apply masks after converting images to a Gfx::Bitmap,
that is after converting to 8bpp sRGB. And we do this by mapping
everything to 8bpp very early on in load_image().
This leaves us with a bunch of options that are all a bit awkward:
1. Make load_image() store the up- (or for 16bpp inputs, down-)
sampled-to-8bpp pixel data. And also return if we expanded the
pixel range while resampling (for color values) or not (for
palettized images). Then, when applying the image filter,
resample the array bounds in exactly the same way. This requires
passing around more stuff.
2. Like 1, but pass in the mask array to load_image() and apply
the mask right there and then. This means we'd apply mask arrays
at a different time than other masks.
3. Make the function that computes the mask from the mask array
work from the original, unprocessed image data. This is the most
local change, but probably also requires the largest amount of
code (in return, the color mask for 16bpp images is precise, in
addition that it separates concerns the most nicely).
This goes with 3 for now.
From https://drafts.csswg.org/css-backgrounds-4/#background-clip
"The background is painted within (clipped to) the intersection of the
border box and the geometry of the text in the element and its in-flow
and floated descendants"
This change implements it in the following way:
1. Traverse the descendants of the element, collecting the Gfx::Path of
glyphs into a vector.
2. The vector of collected paths is saved in the background painting
command.
3. The painting commands executor uses the list of glyphs to paint a
mask for background clipping.
Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
In the situation where the amount of content preceeding the hunk was
greater than the max context of the hunk there would be an unsigned
underflow, as the logic was assuming signed arithmitic.
This underflow would result in the patch not applying, as patch would
assume the massive calculated fuzz would result in the patch matching
against any file.
While StringView does have a null state, we have been moving away from
this in our other String classes. To represent a StringView not being
given at all on the commandline, use an Optional.
This is still a very naive implementation and there are plenty of other
cases that we should handle (like a quoted path) - but just looking for
a tab handles the common case.
This allows us to avoid the need for costly traversals to gather
boxes that have been saved during the construction of the stacking
context tree.
No behavior change intended.
To avoid differing logic for serializing and deserializing similar
types, move the logic into separate helpers.
Also, adds security checks like VERIFY to avoid reading past the end of
the serialized data. If we try to read past the end of the serialized
data, either our program logic is wrong or our serialized data has
somehow been corrupted. Therefore, at least currently, it is better to
crash by VERIFYing.
To avoid differing logic for deserializing similar types, move the logic
into separate helpers.
Also, adds security checks like VERIFY to avoid reading past the end of
the serialized data. If we try to read past the end of the serialized
data, either our program logic is wrong or our serialized data has
somehow been corrupted. Therefore, at least currently, it is better to
crash by VERIFYing.
It was possible to reach this via the timer itself (when the client is
only slightly busy), and then to have the timer fire before the deferred
invocation fires.
This commit removes the race by disabling the timer when the final
deferred-accept state is reached.
Skipping all stacking contexts with a size larger than 10000px in one
dimension was a mistake because it also affects pages that are simply
tall due to having a lot of content. Instead, we only need to skip if
the stacking context requires the allocation of a framebuffer that
could possibly fail.
Fixes https://github.com/SerenityOS/serenity/issues/23397
By caching the layout node and its computed values in locals, we can
avoid the small amount of redundant work needed to look them up every
single time.
This removes indirection when asking if a paintable is positioned,
floating, etc.
Removes a bunch of 1-1.5% items in the profile when hovering links
on ziglang.org.
Update to the latest version of the spec which was refactored to use
time zone methods record. This requires updating a whole bunch of
callers to pass through a record too.
This also ends up improving exceptions on a missing
getOffsetNanosecondsFor method.
This can be perfectly valid, and depends on the property being animated.
For example, interpolating between the StyleValue "none" (an identifier)
and a TransformationStyleValue is perfectly defined.
In the upcoming commits where we properly handle transformation
interpolation, it actually becomes easier to change this back to custom,
so lets do that since its more correct anyways.