LibWeb/DOM: Update an attribute's node document
Some checks are pending
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, 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
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run

Corresponds to b64559cc08
This commit is contained in:
Sam Atkins 2025-02-21 12:01:20 +00:00
commit 0fcd7f9aea
Notes: github-actions[bot] 2025-02-23 22:37:41 +00:00
7 changed files with 68 additions and 7 deletions

View file

@ -2276,7 +2276,7 @@ void Document::adopt_node(Node& node)
// 1. For each inclusiveDescendant in nodes shadow-including inclusive descendants:
node.for_each_shadow_including_inclusive_descendant([&](DOM::Node& inclusive_descendant) {
// 1. Set inclusiveDescendants node document to document.
inclusive_descendant.set_document({}, *this);
inclusive_descendant.set_document(Badge<Document> {}, *this);
// FIXME: 2. If inclusiveDescendant is an element, then set the node document of each attribute in inclusiveDescendants
// attribute list to document.

View file

@ -237,17 +237,23 @@ void NamedNodeMap::replace_attribute(Attr& old_attribute, Attr& new_attribute, s
{
VERIFY(old_attribute.owner_element());
// 1. Replace oldAttr by newAttr in oldAttrs elements attribute list.
// 1. Let element be oldAttributes element.
auto* element = old_attribute.owner_element();
// 2. Replace oldAttribute by newAttribute in elements attribute list.
m_attributes.remove(old_attribute_index);
m_attributes.insert(old_attribute_index, new_attribute);
// 2. Set newAttrs element to oldAttrs element.
new_attribute.set_owner_element(old_attribute.owner_element());
// 3. Set newAttributes element to element.
new_attribute.set_owner_element(element);
// 3. Set oldAttrs element to null.
// 4. Set newAttributes node document to elements node document.
new_attribute.set_document(Badge<NamedNodeMap> {}, element->document());
// 5. Set oldAttributes element to null.
old_attribute.set_owner_element(nullptr);
// 4. Handle attribute changes for oldAttr with newAttrs element, oldAttrs value, and newAttrs value.
// 6. Handle attribute changes for oldAttribute with element, oldAttributes value, and newAttributes value.
old_attribute.handle_attribute_changes(*new_attribute.owner_element(), old_attribute.value(), new_attribute.value());
}
@ -260,7 +266,10 @@ void NamedNodeMap::append_attribute(Attr& attribute)
// 2. Set attributes element to element.
attribute.set_owner_element(&associated_element());
// 3. Handle attribute changes for attribute with element, null, and attributes value.
// 3. Set attributes node document to elements node document.
attribute.set_document(Badge<NamedNodeMap> {}, associated_element().document());
// 4. Handle attribute changes for attribute with element, null, and attributes value.
attribute.handle_attribute_changes(associated_element(), {}, attribute.value());
}

View file

@ -1281,6 +1281,11 @@ void Node::set_document(Badge<Document>, Document& document)
set_document(document);
}
void Node::set_document(Badge<NamedNodeMap>, Document& document)
{
set_document(document);
}
void Node::set_document(Document& document)
{
if (m_document.ptr() == &document)

View file

@ -302,6 +302,7 @@ public:
void invalidate_style(StyleInvalidationReason, Vector<CSS::InvalidationSet::Property> const&, StyleInvalidationOptions);
void set_document(Badge<Document>, Document&);
void set_document(Badge<NamedNodeMap>, Document&);
virtual EventTarget* get_parent(Event const&) override;

View file

@ -0,0 +1,7 @@
Harness status: OK
Found 2 tests
2 Pass
Pass Moving an attribute between documents
Pass Replacing an attribute across documents

View file

@ -0,0 +1,8 @@
<!doctype html>
<meta charset=utf-8>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
<div id=log></div>
<script src="../../dom/nodes/attributes-namednodemap-cross-document.window.js"></script>

View file

@ -0,0 +1,31 @@
"use strict";
test(() => {
const element = document.createElement("div");
element.setAttribute("x", "first");
const attribute = element.attributes[0];
assert_equals(attribute.ownerDocument, document);
const otherDocument = new Document();
const otherElement = otherDocument.createElement("other");
assert_throws_dom("InUseAttributeError", () => otherElement.attributes.setNamedItem(attribute));
element.removeAttribute("x");
otherElement.attributes.setNamedItem(attribute);
assert_equals(attribute.ownerDocument, otherDocument);
}, "Moving an attribute between documents");
test(() => {
const element = document.createElement("div");
element.setAttribute("x", "first");
const attribute = element.attributes[0];
element.removeAttribute("x");
const otherDocument = new Document();
const otherElement = otherDocument.createElement("other");
otherElement.setAttribute("x", "second");
otherElement.attributes.setNamedItem(attribute);
assert_equals(attribute.ownerDocument, otherDocument);
assert_equals(otherElement.getAttribute("x"), "first");
}, "Replacing an attribute across documents");