Commit graph

248 commits

Author SHA1 Message Date
Shannon Booth
dc401f49ea LibWeb+LibURL: Move HTML::Origin to URL::Origin
While Origin is defined in the HTML spec - this leaves us with quite an
awkward relationship as the URL spec makes use of AO's from what is
defined in the HTML spec.

To simplify this factoring, relocate Origin into LibURL.
2024-10-05 10:46:30 +02:00
Andreas Kling
cc4b3cbacc Meta: Update my e-mail address everywhere
Some checks are pending
CI / Lagom (false, FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, macos-14, macOS, Clang) (push) Waiting to run
CI / Lagom (false, NO_FUZZ, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (true, NO_FUZZ, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (macos-14, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Push notes / build (push) Waiting to run
2024-10-04 13:19:50 +02:00
Andreas Kling
b8ce34068f LibWeb: Invalidate less style on textContent change and node removal
...unless there are :has() selectors present. Then we have to invalidate
everything for now.
2024-09-22 18:42:40 +02:00
Andreas Kling
7d644ecd50 LibWeb: Distinguish parent/child on style invalidation for DOM insertion 2024-09-22 18:42:40 +02:00
Andreas Kling
f351f75a34 LibWeb: Don't try to invalidate style for character data nodes
Character data nodes like text and HTML comments don't have style,
so let's just exit invalidation immediately for those.
2024-09-22 18:42:40 +02:00
Andreas Kling
df048e10f5 LibWeb: Include siblings+descendants when invalidating style
When an element is invalidated, it's possible for any subsequent sibling
or any of their descendants to also need invalidation. (Due to the CSS
sibling combinators, `+` and `~`)

For DOM node insertion/removal, we must also invalidate preceding
siblings, since they could be affected by :first-child, :last-child or
:nth-child() selectors.

This increases the amount of invalidation we do, but it's more correct.

In the future, we will implement optimizations that drastically reduce
the number of elements invalidated.
2024-09-22 18:42:40 +02:00
Andreas Kling
6f34758947 LibWeb: Don't invalidate layout tree on all DOM node removals
DOM nodes that didn't have a layout node before being removed from the
DOM are not going to change the shape of the layout tree after being
removed.

Observing this, we can avoid a full layout tree rebuild on some DOM node
removals.

This avoids a bunch of tree building work when loading https://x.com/
2024-09-19 10:12:44 +02:00
Andreas Kling
aa8f17aea4 LibWeb: Rename invalidate_layout() => invalidate_layout_tree()
I believe this is slightly less confusing, since what the function does
is trigger a full layout tree *rebuild*, not just a relayout.
2024-09-19 10:12:44 +02:00
Andreas Kling
ddbfac38b0 LibWeb: Note what's causing a style invalidation to happen
You can now build with STYLE_INVALIDATION_DEBUG and get a debug stream
of reasons why style invalidations are happening and where.

I've rewritten this code many times, so instead of throwing it away once
again, I figured we should at least have it behind a flag.
2024-09-08 09:45:31 +02:00
Sam Atkins
173daec9db LibWeb: Show pseudo-elements in DOM whose parent has no other children
If a DOM node is an element with pseudo-elements, but it has no child
DOM nodes and is not a shadow host, then the code that serializes its
pseudo-elements would get skipped, making them not show up in the
inspector.
2024-08-07 16:14:49 +02:00
Andreas Kling
e746b2b133 LibWeb: Cache the Document's node navigable when possible
To avoid expensive lookups, we now cache a weak pointer from document to
the last known node navigable. Before using the cache, we validate that
the document is still the navigable's active document.
2024-08-02 21:59:41 +02:00
Ángel Carias
9624e0d2a2 LibWeb/DOM: Implement Node.lookupPrefix
Adds https://dom.spec.whatwg.org/#dom-node-lookupprefix
2024-07-28 00:51:55 +01:00
Tim Ledbetter
f8b1e96e2b LibWeb: Assert that cloned node is not null before returning
This makes potential issues easier to track down.
2024-07-25 15:57:21 +01:00
Tim Ledbetter
72ed62a560 LibWeb: Don't crash when cloning a CDATASection node 2024-07-25 15:57:21 +01:00
Tim Ledbetter
5a578e8f15 LibWeb: Compare node names case insensitively in Node::is_equal_node() 2024-07-19 09:22:08 +02:00
Tim Ledbetter
7ab7be694d LibWeb: Don't consider nodes in different namespaces to be equal
Previously, `Node::is_equal_node()` would return true for nodes in
different namespaces that were otherwise equal.
2024-07-19 09:22:08 +02:00
Tim Ledbetter
055c902a37 LibWeb: Implement Node.isDefaultNamespace()
This method accepts a namespace URI as an argument and returns true if
the given URI is the default namespace on the given node, false
otherwise.
2024-07-18 12:41:01 +03:00
Tim Ledbetter
27d429a85f LibWeb: Implement Node.lookupNamespaceURI()
This method takes a prefix and returns the namespace URI associated
with it on the given node, or null if no namespace is found.
2024-07-18 12:41:01 +03:00
Maciej
9eb568eacb LibWeb: Make innerHTML for XML nodes actually return inner HTML
The spec says to just call the XML serialization algorithm, but it
returns the "outer serialization", and we need the "inner" one. Let's
just concatenate serializations of children; then the result produced is
similar to one from Blink or Gecko.
2024-07-14 11:49:31 +02:00
Tim Ledbetter
0a0651f34e LibWeb: Implement Node.normalize()
This method puts the given node and all of its sub-tree into a
normalized form. A normalized sub-tree has no empty text nodes and no
adjacent text nodes.
2024-07-13 09:35:54 +02:00
Luke Warlow
ce8d3d17c4 LibWeb: Implement unsafe HTML parsing methods
Both Element's and ShadowRoot's setHTMLUnsafe, and Document's static
parseHTMLUnsafe methods are implemented.
2024-06-26 06:13:29 +02:00
Andreas Kling
f4bdf56212 LibWeb: Rename Element::shadow_root_internal() to shadow_root()
And let the old shadow_root(), which was only supposed to be used by
bindings, be called shadow_root_for_bindings() instead.

This makes it much easier to read DOM code, and we don't have to worry
about when to use shadow_root_internal() or why.
2024-06-25 19:22:35 +02:00
Andreas Kling
c7d9c1c0b2 LibWeb: Update DOM cloning algorithm for declarative shadow DOM 2024-06-25 19:22:35 +02:00
Andreas Kling
e62db9c118 LibWeb: Update HTML fragment serialization for declarative shadow DOM 2024-06-25 19:22:35 +02:00
Tim Ledbetter
398bf10b92 LibWeb: Use TraversalDecision for multi level Node traversal methods
This adds the `SkipChildrenAndContinue` option, where traversal
continues but child nodes are not included.
2024-05-07 16:45:28 -06:00
Tim Ledbetter
c57d395a48 LibWeb: Use IterationDecision in single level Node iteration methods
`Node::for_each_child()` and `Node::for_each_child_of_type()` callbacks
now return an `IterationDecision`, which allows us to break early if
required.
2024-05-07 16:45:28 -06:00
Andreas Kling
a4625e3943 LibWeb: Only react to link element attribute changes when BC connected
Link elements that aren't "browsing-context connected" should not
trigger a resource fetch when their attributes change.

This fixes an issue where we'd waste time by loading every style sheet
twice! :^)
2024-04-26 10:40:43 +02:00
Andreas Kling
193fc7ef98 LibWeb: Allow cloneNode() to clone elements with weird attributes
We can't rely on Element.setAttribute() in cloneNode() since that will
throw on weird attribute names. Instead, just follow the spec and copy
attributes into cloned elements verbatim.

This fixes a crash when loading the "issues" tab on GitHub repos.
They are actually sending us unintentionally broken markup, but we
should still support cloning it. :^)
2024-04-21 19:51:24 +02:00
Andreas Kling
53d0dd4a2e LibJS+LibWeb: Use new Cell::Visitor helpers to avoid manual iteration 2024-04-16 07:40:01 +02:00
Andreas Kling
24157e4d1b LibWeb: Only invalidate style/layout on mutation for connected DOM nodes
If a DOM node isn't connected, there's no need to invalidate, since it's
not going to be visible anyway. The node will be automatically inserted
if/when it becomes connected in the future.
2024-04-15 12:58:27 +02:00
Andreas Kling
870a954e11 LibWeb: Implement Element.outerHTML
This piggybacks on the same fragment serialization code that innerHTML
uses, but instead of constructing an imaginary parent element like the
spec asks us to, we just add a separate serialization mode that includes
the context element in the serialized markup.

This makes the image carousel on https://utah.edu/ show up :^)
2024-04-09 18:17:14 -04:00
Shannon Booth
c3217754f1 LibWeb: Remove a bunch of calls to to_byte_string
A bunch of this is leftover from pre porting over to new AK::String.
For example, for functions which previously took a ByteString const&
now accepting a StringView.
2024-04-05 20:01:37 -04:00
Tim Ledbetter
2227674b91 LibWeb: Don't crash when updating a select with detached option elements
`Node::shadow_including_root()` was missing a null check, which caused
a crash when manipulating a select element, whose option elements were
initially detached.
2024-03-23 20:56:26 +01:00
Andreas Kling
cf60f52a78 LibWeb: Add DOM tree version counter
This patch adds a u64 version counter to DOM::Document that increments
whenever the tree structure changes (via node insertion or removal),
or an element attribute is changed somehow.

This will be used as a crude invalidation mechanism for HTMLCollection
to cache its elements.
2024-03-19 20:59:36 +01:00
Andreas Kling
b40f0415ef LibWeb: Make Node::parent_element() an inline function
Also remove a redundant verify_cast<Element> while we're here.
2024-03-19 16:48:22 +01:00
Andreas Kling
bbb96d65b1 LibWeb: Don't crash on live range offset update during node insertion
When inserting a node into a parent, any live DOM ranges that reference
the parent may need to be updated. The spec does this by increasing or
decreasing the start/end offsets of each live range *before* actually
performing the insertion.

This caused us to crash with a verification failure, since it was
possible to set the range offset to an invalid value (that would go on
to immediately become valid after the insertion was finished).

This patch fixes the issue by adding special badged helpers on Range for
Node to reach into it and increase/decrease the offsets during node
insertion. This skips the offset validity check and actually makes our
code read slightly more like the spec.

Found by Domato :^)
2024-03-12 16:30:39 +01:00
Aliaksandr Kalenik
036cd9b2dd LibWeb: Null layout and paintable pointers of removed DOM::Node
When a node is removed from the DOM tree, its paintable needs to be
removed to ensure that it is not used to obtain sizes that are no
longer valid.

This change enables the ResizeObserver to send a notification if a node
is removed, as it should, because a removed node now has a size of zero

It should be okay to nullify pointers without concerning
parent/sibling/child relationships because the layout and paintable
trees will be rebuilt following any DOM mutation anyway.
2024-02-20 10:55:10 +01:00
Tim Ledbetter
02c2b1e67e LibWeb: Implement document.createCDATASection() 2024-02-19 10:42:56 +01:00
Andreas Kling
413eb19579 LibWeb: Skip UTF-8 validation in Node::descendant_text_content()
Since we're just concatenating a bunch of strings that are already
UTF-8, we don't need to check that the result is also UTF-8.
2024-01-24 07:55:13 +01:00
Bastiaan van der Plaat
a681429dff LibWeb: Remove DOM element deprecated_get_attribute() 2024-01-19 13:12:54 -07:00
Andreas Kling
b0afe8463a LibWeb: Make Node::paintable_box() go directly to the paintable
No need to go via the layout tree here, that's a vestige of an earlier
architecture limitation.
2024-01-13 12:33:53 +01:00
Shannon Booth
0695236408 LibWeb: Use cached element name and id where possible
Instead of looking up in the named node map, we can simply use the
cached name and ID on the element.
2024-01-13 12:05:36 +01:00
Andreas Kling
c3059701b0 LibWeb: Avoid style invalidation when entire document has invalid style
If the entire document is invalidated, we know a full style update is
coming soon, and there's no need to try and invalidate a smaller part.

This avoids a *lot* of work on some pages. As an example, we are able to
skip ~1.5 million style invalidations on https://html.spec.whatwg.org/
2024-01-13 11:49:04 +01:00
Shannon Booth
562e0d710c LibWeb: Port ProcessingInstruction from ByteString 2023-12-24 13:26:50 +01:00
Shannon Booth
d8759d9656 LibWeb: Use UTF-16 code unit offsets and lengths in CharacterData
We were previously assuming that the input offsets and lengths were all
in raw byte offsets into a UTF-8 string. While internally our String
representation may be in UTF-8 from the external world it is seen as
UTF-16, with code unit offsets passed through, and used as the returned
length.

Beforehand, the included test included in this commit would crash
ladybird (and otherwise return wrong values).

The implementation here is very inefficient, I am sure there is a
much smarter way to write it so that we would not need a conversion
from UTF-8 to a UTF-16 string (and then back again).

Fixes: #20971
2023-12-23 20:41:41 +01:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
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')
2023-12-17 18:25:10 +03:30
Shannon Booth
83758d4cdd LibWeb: Wrap PseudoElements stored in SimpleSelector in a class
No functional impact intended. This is just a more complicated way of
writing what we have now.

The goal of this commit is so that we are able to store the 'name' of a
pseudo element for use in serializing 'unknown -webkit-
pseudo-elements', see:

https://www.w3.org/TR/selectors-4/#compat

This is quite awkward, as in pretty much all cases just the selector
type enum is enough, but we will need to cache the name for serializing
these unknown selectors. I can't figure out any reason why we would need
this name anywhere else in the engine, so pretty much everywhere is
still just passing around this raw enum. But this change will allow us
to easily store the name inside of this new struct for when it is needed
for serialization, once those webkit unknown elements are supported by
our engine.
2023-12-11 16:54:59 +01:00
Timothy Flynn
18a4455d43 LibWeb: Do not assume a shadow root has a host
After commit ff48b7333c, we remove shadow
roots from elements that are removed from the DOM. Setting a node's
shadow root to null also sets that shadow root's host to null. Thus, the
comment in Node::is_shadow_including_descendant_of that assumes the host
is always non-null is not true.

The test added here would previously crash when interacting with a node
that is a descendant of a removed shadow root.
2023-12-04 01:33:57 +01:00
Shannon Booth
a8f5ebeddd LibWeb: Port DOM::Node from DeprecatedString 2023-12-02 22:54:53 +01:00
Andreas Kling
cc9de38ea4 LibWeb: Fix null pointer dereference in DOM::Node::remove()
Instead of blindly dereferencing m_registered_observer_list, just use
the add_registered_observer() helper.

Fixes #22005
2023-11-20 20:50:53 +01:00