Commit graph

1454 commits

Author SHA1 Message Date
Sam Atkins
88e11eea2d LibWeb: Implement functional pseudo-element parsing
"Functional" as in "it's a function token" and not "it works", because
the behaviour for these is unimplemented. :^)

This is modeled after the pseudo-class parsing, but with some changes
based on things I don't like about that implementation. I've
implemented the `<pt-name-selector>` parameter used by view-transitions
for now, but nothing else.
2025-03-25 07:54:13 +00:00
Andreas Kling
46a5710238 LibJS: Use FlyString in PropertyKey instead of DeprecatedFlyString
This required dealing with *substantial* fallout.
2025-03-24 22:27:17 +00:00
Andreas Kling
53da8893ac LibJS: Replace PropertyKey(char[]) with PropertyKey(FlyString)
...and deal with the fallout.
2025-03-24 22:27:17 +00:00
Sam Atkins
1108988656 LibWeb/CSS: Generate property-filtering code for pseudo-elements
Pseudo-elements have specific rules about which CSS properties can be
applied to them. This is a first step to supporting that.

- If a property whitelist isn't present, all properties are allowed.
- Properties are named as in CSS.
- Names of property groups are prefixed with `#`, which makes this match
  the spec more clearly. These groups are implemented directly in the
  code generator for now.
- Any property name beginning with "FIXME:" is ignored, so we can mark
  properties we don't implement yet.
2025-03-24 09:49:50 +00:00
Sam Atkins
193adee164 LibWeb/CSS: Implement aliases for pseudo-elements
We previously supported a few -webkit vendor-prefixed pseudo-elements.
This patch adds those back, along with -moz equivalents, by aliasing
them to standard ones. They behave identically, except for serializing
with their original name, just like for unrecognized -webkit
pseudo-elements.

It's likely to be a while before the forms spec settles and authors
start using the new pseudo-elements, so until then, we can still make
use of styles they've written for the non-standard ones.
2025-03-24 09:49:50 +00:00
Sam Atkins
2c86fd539d LibWeb: Generate an enum for generated pseudo-elements 2025-03-24 09:49:50 +00:00
Sam Atkins
021e3f5c7d LibWeb/CSS: Generate is_has_allowed_pseudo_element() 2025-03-24 09:49:50 +00:00
Sam Atkins
ffa1dba96a LibWeb: Generate pseudo-element code from JSON
Initially, this generates the enum and to/from-string functions. The
JSON itself contains more data than that, but it's unused for now.
2025-03-24 09:49:50 +00:00
Ryan Liptak
0b0f47e320 LibWeb: Make named character references more spec-compliant & efficient
There are two changes happening here: a correctness fix, and an
optimization. In theory they are unrelated, but the optimization
actually paves the way for the correctness fix.

Before this commit, the HTML tokenizer would attempt to look for named
character references by checking from after the `&` until the end of
m_decoded_input, which meant that it was unable to recognize things like
named character references that are inserted via `document.write` one
byte at a time. For example, if `&notin;` was written one-byte-at-a-time
with `document.write`, then the tokenizer would only check against `n`
since that's all that would exist at the time of the check and therefore
erroneously conclude that it was an invalid named character reference.

This commit modifies the approach taken for named character reference
matching by using a trie-like structure (specifically, a deterministic
acyclic finite state automaton or DAFSA), which allows for efficiently
matching one-character-at-a-time and therefore it is able to pick up
matching where it left off after each code point is consumed.

Note: Because it's possible for a partial match to not actually develop
into a full match (e.g. `&notindo` which could lead to `&notindot;`),
some backtracking is performed after-the-fact in order to only consume
the code points within the longest match found (e.g. `&notindo` would
backtrack back to `&not`).

With this new approach, `document.write` being called one-byte-at-a-time
is handled correctly, which allows for passing more WPT tests, with the
most directly relevant tests being
`/html/syntax/parsing/html5lib_entities01.html`
and
`/html/syntax/parsing/html5lib_entities02.html`
when run with `?run_type=write_single`. Additionally, the implementation
now better conforms to the language of the spec (and resolves a FIXME)
because exactly the matched characters are consumed and nothing more, so
SWITCH_TO is able to be used as the spec says instead of RECONSUME_IN.

The new approach is also an optimization:

- Instead of a linear search using `starts_with`, the usage of a DAFSA
  means that it is always aware of which characters can lead to a match
  at any given point, and will bail out whenever a match is no longer
  possible.
- The DAFSA is able to take advantage of the note in the section
  `13.5 Named character references` that says "This list is static and
  will not be expanded or changed in the future." and tailor its Node
  struct accordingly to tightly pack each node's data into 32-bits.
  Together with the inherent DAFSA property of redundant node
  deduplication, the amount of data stored for named character reference
  matching is minimized.

In my testing:

- A benchmark tokenizing an arbitrary set of HTML test files was about
  1.23x faster (2070ms to 1682ms).
- A benchmark tokenizing a file with tens of thousands of named
  character references mixed in with truncated named character
  references and arbitrary ASCII characters/ampersands runs about 8x
  faster (758ms to 93ms).
- The size of `liblagom-web.so` was reduced by 94.96KiB.

Some technical details:

A DAFSA (deterministic acyclic finite state automaton) is essentially a
trie flattened into an array, but it also uses techniques to minimize
redundant nodes. This provides fast lookups while minimizing the
required data size, but normally does not allow for associating data
related to each word. However, by adding a count of the number of
possible words from each node, it becomes possible to also use it to
achieve minimal perfect hashing for the set of words (which allows going
from word -> unique index as well as unique index -> word). This allows
us to store a second array of data so that the DAFSA can be used as a
lookup for e.g. the associated code points.

For the Swift implementation, the new NamedCharacterReferenceMatcher
was used to satisfy the previous API and the tokenizer was left alone
otherwise. In the future, the Swift implementation should be updated to
use the same implementation for its NamedCharacterReference state as
the updated C++ implementation.
2025-03-22 16:03:44 +01:00
Sam Atkins
a28197669a LibWeb/CSS: Move property code from CSSStyleDeclaration to *Properties
CSSStyleDeclaration is a base class that's used by various collections
of style properties or descriptors. This commit moves all
style-property-related code into CSSStyleProperties, where it belongs.

As noted in the previous commit, we also apply the CSSStyleProperties
prototype now.
2025-03-19 13:53:00 +00:00
Luke Wilde
02236be737 LibWeb/CSP: Implement SecurityPolicyViolationEvent
This is used to report violations of policies to the element/global
object that caused it.
2025-03-19 00:55:14 +01:00
Timothy Flynn
0e057d3a36 LibIPC: Don't generate "take" methods for primitive/simple types 2025-03-09 11:14:20 -04:00
Timothy Flynn
cf69f52d53 LibIPC+Everywhere: Always pass ownership of transferred data to clients
This has been a longstanding ergonomic issue with our IPC compiler. Non-
trivial types were previously passed by const&. So if we wanted to avoid
expensive copies, we would have to const_cast and move the data.

We now pass ownership of all transferred data to the client subclasses.
This allows us to remove const_cast from these methods, and allows us to
avoid some trivial expensive copies that we didn't bother to const_cast.
2025-03-09 11:14:20 -04:00
Timothy Flynn
68947d55d9 LibIPC: Do not require constructing containers when sending IPC messages
For example, consider the following IPC message:

    do_something(u64 page_id, String string, Vector<Data> data) =|

We would previously generate the following C++ method to encode/transfer
this message:

    void do_something(u64 page_id, String string, Vector<Data> data);

This required the caller to either have to copy the non-trivial types or
`move` them in. In some places, this meant we had to construct temporary
vectors just to send an IPC.

This isn't necessary because we weren't holding onto these parameters
anyways. We would construct an IPC::Message subclass with them (which
does require owning types), but then immediate encode the message to
an IPC::MessageBuffer and send it.

We now generate code such that we don't need to construct a Message. We
can simply encode the parameters directly without needing ownership.
This allows us to take view-types to IPC parameters.

So the above example now becomes:

    void do_something(u64, StringView, ReadonlySpan<Data>);
2025-03-09 11:14:20 -04:00
Timothy Flynn
da6c6487e5 LibIPC: Extract helper lambda to its own method
This will be needed in an upcoming commit so that this method may call
itself recursively to generate overloads. Doing this extraction ahead of
time will simply make that diff easier to grok.
2025-03-09 11:14:20 -04:00
Timothy Flynn
8277f42812 LibIPC: Remove some unnecessary newlines in generated IPC files
This isn't particularly important, but when staring at generated IPC
files, it's nice not to have an extra newline after every line of code
throughout the files.
2025-03-09 11:14:20 -04:00
Luke Wilde
6d1f78198d LibWeb: Implement Resource Timing 2025-03-06 09:00:53 -07:00
Sam Atkins
f148af0a93 LibWeb: Move XMLSerializer into HTML directory
The DOMParsing spec is in the process of being merged into the HTML one,
gradually. The linked spec change moves XMLSerializer, but many of the
algorithms are still in the DOMParsing spec so I've left the links to
those alone.

I've done my best to update the GN build but since I'm not actually
using it, I might have done that wrong.

Corresponds to 2edb8cc7ee
2025-03-04 16:44:41 +00:00
Sam Atkins
a11848f163 IDLGenerators: Allow DOMString? reflection on non-enumerated attributes
Corresponds to ef2fba2a3b
2025-03-04 16:44:41 +00:00
Totto16
4c54fa10ed LibWeb: Improve Enum generation in IDLGenerator
Generated enums have no underlying type specifier, this adds one
It uses the smallest available, which is mostly u8
2025-03-04 16:35:04 +00:00
Luke Wilde
6cb0f41c57 LibWeb/WebGL: Return from uniform methods if location is null
If location is null, the spec simply tells us to return and ignore the
passed in data.

Fixes #3708.
2025-03-03 08:43:33 +01:00
Sam Atkins
f97ac33cb3 LibWeb/CSS: Use NumericCalculationNode for constants
Having multiple kinds of node that hold numeric values made things more
complicated than they needed to be, and we were already converting
ConstantCalculationNodes to NumericCalculationNodes in the first
simplification pass that happens at parse-time, so they didn't exist
after that.

As noted, the spec allows for other contexts to introduce their own
numeric keywords, which might be resolved later than parse-time. We'll
need a different mechanism to support those, but
ConstantCalculationNode could not have done so anyway.
2025-02-27 21:42:43 +01:00
Andreas Kling
8ab61843be LibWeb: Parse CSS fit-content(<length-percentage>) values
Before this change, we only parsed fit-content as a standalone keyword,
but CSS-SIZING-3 added it as a function as well. I don't know of
anything else in CSS that is overloaded like this, so it ends up looking
a little awkward in the implementation.

Note that a lot of code had already been prepped for fit-content values
to have an argument, we just weren't parsing it.
2025-02-27 00:44:14 +01:00
Sam Atkins
c729c3fcee LibWeb/CSS: Add custom-ident blacklists to Properties.json
These excluded values use a similar notation to the ranges for numeric
types: `![foo,bar,baz]` to exclude `foo`, `bar`, and `baz`.
2025-02-26 11:22:47 +00:00
Luke Wilde
198cec481a LibWeb: Allow null for optional, nullable, no default value union types
For these types, it would previously only accept `undefined` for the
`null` state.

Fixes GET requests in the Turbo library always failing:
9e057f284a/src/http/fetch_request.js (L219-L220)
9e057f284a/src/http/fetch_request.js (L51-L64)

This was found on https://www.fangamer.com/.
2025-02-22 18:45:27 +01:00
rmg-x
2b32f94527 CodeGenerators: Fix clang-18 crash by specifying types explicitly
clang 18.1.8 was crashing during the build without this change.

Filed a bug report here:
https://github.com/llvm/llvm-project/issues/128359

Co-authored-by: Tim Flynn <trflynn89@pm.me>
2025-02-22 12:38:11 -05:00
Tim Ledbetter
7ee33529e8 IDLGenerators: Throw TypeError if custom element is already constructed
Throwing a TypeError instead of an InvalidStateError DOMException
follows the current specification steps.
2025-02-22 05:39:23 -05:00
Timothy Flynn
2c03de60da AK+Everywhere: Remove now-unecessary use of ByteString with JSON types
This removes JsonObject::get_byte_string and JsonObject::to_byte_string.
2025-02-20 19:27:51 -05:00
Timothy Flynn
bc54c0cdfb AK+Everywhere: Store JSON strings as String 2025-02-20 19:27:51 -05:00
Timothy Flynn
e591636419 AK+Everywhere: Store JSON object keys as String 2025-02-20 19:27:51 -05:00
Psychpsyo
3b577e6135 Meta: Improve IDL generator for dictionary members
This makes it so that the IDL generator no longer assumed that
dictionary members with a default value are optional, since they
will always, at least, have the default value.
2025-02-18 10:18:40 -07:00
Sam Atkins
71cb04d8cb IPCCompiler: Allow arguments to not be default-constructible
All fields are always initialized, so we don't need to initialize them
by default. This lets us send types over IPC that can't be
default-constructed, such as a Variant without Empty.
2025-02-17 11:37:38 -05:00
Sam Atkins
b3b7e76c10 IPCCompiler: Remove invalid state from IPC message classes
At some point, we stopped ever constructing invalid messages. This makes
that clearer, and will allow us to stop requiring that IPC arguments be
default-constructible.
2025-02-17 11:37:38 -05:00
Andrew Kaster
80c259125c Meta+LibWeb: Pass IDL files to codegen using response file on Windows
It might be a good idea to do this on other platforms as well, but at
least on Windows, the command line for GenerateWindowOrWorkerInterfaces
becomes too large.
2025-02-12 19:13:49 -07:00
Shannon Booth
ba382c454a LibWeb/Bindings: Allow optional string returned in a union
This is not a very pleasant fix, but matches a similar const_cast that
we do to return JS objects returned in a union. Ideally we would
'simply' remove the const from the value being visited in the variant,
but that opens up a whole can of worms where we are currently relying on
temporary lifetime extension so that interfaces can return a Variant of
GC::Ref's to JS::Objects.
2025-02-10 17:05:15 +00:00
Shannon Booth
f3ec727555 LibWeb/Bindings: Support returning nullable types in dictionaries
We were previously assuming that dictionary members were always
required when being returned.

This is a bit of a weird case, because unlike _input_ dictionaries
which the spec marks as required, 'result' dictionaries do not seem to
be marked in spec IDL as required. This is still fine from the POV that
the spec is written as it states that we should only be putting the
values into the dictionary if the value exists.

We could do this through some metaprogramming constexpr type checks.
For example, if the type in our C++ representation was not an
Optional, we can skip the has_value check.

Instead of doing that, change the IDL of the result dictionaries to
annotate these members so that the IDL generator knows this
information up front. While all current cases have every single
member returned or not returned, it is conceivable that the spec
could have a situation that one member is always returned (and
should get marked as required), while the others are optionally
returned. Therefore, this new GenerateAsRequired attribute is
applied for each individual member.
2025-02-10 17:05:15 +00:00
Shannon Booth
64a2c156bb LibWeb/Bindings: Generate dictionary in bindings in a C++ scope
This fixes a compile error of multiple variables of the same name within
the same scope for the URLPattern IDL, which has a dictionary return
type that contains multiple dictionaries of the same type. Conveniently,
this also makes the complicated generated code of the URLPattern
interface easier to read by adding some more structure :^)
2025-02-10 17:05:15 +00:00
Shannon Booth
69f0120833 LibWeb/Bindings: Add support for converting records to javascript 2025-02-10 17:05:15 +00:00
Luke Wilde
958938655d LibWeb/WebGL: Implement WEBGL_compressed_texture_s3tc extension 2025-02-09 01:00:51 +01:00
Luke Wilde
484008d440 LibWeb/WebGL: Implement compressedTex(Sub)Image2D 2025-02-09 01:00:51 +01:00
Luke Wilde
f1b81b1ae2 LibWeb/WebGL2: Implement getActiveUniforms 2025-02-09 01:00:51 +01:00
Luke Wilde
071a445015 LibWeb/WebGL2: Implement drawArraysInstanced 2025-02-09 01:00:51 +01:00
Luke Wilde
f1801fb1d2 LibWeb: Make namespace attributes writable and configurable by default
This matches the prototype attributes.

Used by https://chatgpt.com/, where it runs this code:
```js
CSS.supports('animation-timeline: --works')
```
If this returns false, it will attempt to polyfill Animation Timeline
and override CSS.supports to support Animation Timeline properties.
2025-02-07 15:36:02 +01:00
Sam Atkins
6a4d80b9b6 LibWeb/CSS: Integrate ParsingContext into the Parser
This is not really a context, but more of a set of parameters for
creating a Parser. So, treat it as such: Rename it to ParsingParams,
and store its values and methods directly in the Parser instead of
keeping the ParsingContext around.

This has a nice side-effect of not including DOM/Document.h everywhere
that needs a Parser.
2025-02-06 16:47:25 +00:00
devgianlu
da9eaf8788 LibWeb: Stub for Credential Management API
Stub out basic Credential Management APIs and import IDL tests.

Spec: https://w3c.github.io/webappsec-credential-management/
2025-02-05 13:18:47 -07:00
devgianlu
e14511468f IDLGenerators: Do not generate required dictionary members as Optional 2025-02-05 13:18:47 -07:00
devgianlu
348db1c445 LibIDL+IDLGenerators: Support generation of IDL partial dictionaries 2025-02-05 13:18:47 -07:00
Sam Atkins
c3d61020e7 LibWeb/CSS: Make CalculationNodes ref-counted
Calc simplification (which I'm working towards) involves repeatedly
deriving a new calculation tree from an existing one, and in many
cases, either the whole result or a portion of it will be identical to
that of the original. Using RefPtr lets us avoid making unnecessary
copies. As a bonus it will also make it easier to return either `this`
or a new node.

In future we could also cache commonly-used nodes, similar to how we do
so for 1px and 0px LengthStyleValues and various keywords.
2025-01-30 19:31:54 +01:00
Shannon Booth
d4649db55e LibWeb/URLPattern: Add initial stub for URLPattern interface 2025-01-27 18:07:17 +00:00
Luke Wilde
d915b574ab LibWeb/WebGL: Implement pixel format conversion for TexImageSource
This is done by using the combination of format and type to map to the
appropriate Skia bitmap type. With this, we then read the SkImage of
the TexImageSource into a new SkPixmap with the destination format
information and holding an appropriately sized buffer. Once created,
readPixels is called to convert and write the image into the buffer.
2025-01-21 21:36:05 +01:00