mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 19:59:17 +00:00
LibWeb: Pass old parent's root to Node::removed_from()
This will allow nodes to access the root they've just been removed from.
This commit is contained in:
parent
d465e2aa2b
commit
7269fc3e52
Notes:
github-actions[bot]
2025-01-23 20:40:20 +00:00
Author: https://github.com/awesomekling
Commit: 7269fc3e52
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3345
Reviewed-by: https://github.com/AtkinsSJ
39 changed files with 65 additions and 60 deletions
|
@ -1089,9 +1089,9 @@ void Element::inserted()
|
|||
document().element_with_name_was_added({}, *this);
|
||||
}
|
||||
|
||||
void Element::removed_from(Node* node)
|
||||
void Element::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Base::removed_from(node);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
if (m_id.has_value())
|
||||
document().element_with_id_was_removed({}, *this);
|
||||
|
|
|
@ -403,7 +403,7 @@ protected:
|
|||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
virtual i32 default_tab_index_value() const;
|
||||
|
||||
|
|
|
@ -906,9 +906,11 @@ void Node::remove(bool suppress_observers)
|
|||
if (auto assigned_slot = assigned_slot_for_node(*this))
|
||||
assign_slottables(*assigned_slot);
|
||||
|
||||
auto& parent_root = parent->root();
|
||||
|
||||
// 13. If parent’s root is a shadow root, and parent is a slot whose assigned nodes is the empty list, then run
|
||||
// signal a slot change for parent.
|
||||
if (parent->root().is_shadow_root() && is<HTML::HTMLSlotElement>(parent)) {
|
||||
if (parent_root.is_shadow_root() && is<HTML::HTMLSlotElement>(parent)) {
|
||||
auto& slot = static_cast<HTML::HTMLSlotElement&>(*parent);
|
||||
|
||||
if (slot.assigned_nodes_internal().is_empty())
|
||||
|
@ -925,14 +927,14 @@ void Node::remove(bool suppress_observers)
|
|||
|
||||
if (has_descendent_slot) {
|
||||
// 1. Run assign slottables for a tree with parent’s root.
|
||||
assign_slottables_for_a_tree(parent->root());
|
||||
assign_slottables_for_a_tree(parent_root);
|
||||
|
||||
// 2. Run assign slottables for a tree with node.
|
||||
assign_slottables_for_a_tree(*this);
|
||||
}
|
||||
|
||||
// 15. Run the removing steps with node and parent.
|
||||
removed_from(parent);
|
||||
removed_from(parent, parent_root);
|
||||
|
||||
// 16. Let isParentConnected be parent’s connected.
|
||||
bool is_parent_connected = parent->is_connected();
|
||||
|
@ -953,7 +955,7 @@ void Node::remove(bool suppress_observers)
|
|||
// 18. For each shadow-including descendant descendant of node, in shadow-including tree order, then:
|
||||
for_each_shadow_including_descendant([&](Node& descendant) {
|
||||
// 1. Run the removing steps with descendant
|
||||
descendant.removed_from(nullptr);
|
||||
descendant.removed_from(nullptr, parent_root);
|
||||
|
||||
// 2. If descendant is custom and isParentConnected is true, then enqueue a custom element callback reaction with descendant,
|
||||
// callback name "disconnectedCallback", and an empty argument list.
|
||||
|
@ -1433,7 +1435,7 @@ void Node::inserted()
|
|||
set_needs_style_update(true);
|
||||
}
|
||||
|
||||
void Node::removed_from(Node*)
|
||||
void Node::removed_from(Node*, Node&)
|
||||
{
|
||||
m_layout_node = nullptr;
|
||||
m_paintable = nullptr;
|
||||
|
|
|
@ -261,7 +261,7 @@ public:
|
|||
|
||||
virtual void inserted();
|
||||
virtual void post_connection();
|
||||
virtual void removed_from(Node*);
|
||||
virtual void removed_from(Node* old_parent, Node& old_root);
|
||||
virtual void children_changed() { }
|
||||
virtual void adopted_from(Document&) { }
|
||||
virtual WebIDL::ExceptionOr<void> cloned(Node&, bool) const { return {}; }
|
||||
|
|
|
@ -38,11 +38,11 @@ private:
|
|||
form_associated_element_was_inserted(); \
|
||||
} \
|
||||
\
|
||||
virtual void removed_from(DOM::Node* node) override \
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override \
|
||||
{ \
|
||||
ElementBaseClass::removed_from(node); \
|
||||
ElementBaseClass::removed_from(old_parent, old_root); \
|
||||
form_node_was_removed(); \
|
||||
form_associated_element_was_removed(node); \
|
||||
form_associated_element_was_removed(old_parent); \
|
||||
} \
|
||||
\
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override \
|
||||
|
|
|
@ -40,9 +40,9 @@ void HTMLBaseElement::inserted()
|
|||
set_the_frozen_base_url();
|
||||
}
|
||||
|
||||
void HTMLBaseElement::removed_from(Node* parent)
|
||||
void HTMLBaseElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
HTMLElement::removed_from(parent);
|
||||
HTMLElement::removed_from(old_parent, old_root);
|
||||
document().update_base_element({});
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
URL::URL const& frozen_base_url() const { return m_frozen_base_url; }
|
||||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
|
||||
private:
|
||||
|
|
|
@ -52,8 +52,9 @@ void HTMLDetailsElement::inserted()
|
|||
update_shadow_tree_slots();
|
||||
}
|
||||
|
||||
void HTMLDetailsElement::removed_from(DOM::Node*)
|
||||
void HTMLDetailsElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
Base::removed_from(old_parent, old_root);
|
||||
set_shadow_root(nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ private:
|
|||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(DOM::Node*) override;
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
|
||||
|
|
|
@ -41,9 +41,9 @@ void HTMLDialogElement::visit_edges(JS::Cell::Visitor& visitor)
|
|||
visitor.visit(m_close_watcher);
|
||||
}
|
||||
|
||||
void HTMLDialogElement::removed_from(Node* old_parent)
|
||||
void HTMLDialogElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
HTMLElement::removed_from(old_parent);
|
||||
HTMLElement::removed_from(old_parent, old_root);
|
||||
|
||||
// 1. If removedNode's close watcher is not null, then:
|
||||
if (m_close_watcher) {
|
||||
|
|
|
@ -20,7 +20,7 @@ class HTMLDialogElement final : public HTMLElement {
|
|||
public:
|
||||
virtual ~HTMLDialogElement() override;
|
||||
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
String return_value() const;
|
||||
void set_return_value(String);
|
||||
|
|
|
@ -1286,9 +1286,9 @@ void HTMLElement::did_lose_focus()
|
|||
document().editing_host_manager()->set_active_contenteditable_element(nullptr);
|
||||
}
|
||||
|
||||
void HTMLElement::removed_from(Node* old_parent)
|
||||
void HTMLElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Element::removed_from(old_parent);
|
||||
Element::removed_from(old_parent, old_root);
|
||||
|
||||
// If removedNode's popover attribute is not in the no popover state, then run the hide popover algorithm given removedNode, false, false, and false.
|
||||
if (popover().has_value())
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
WebIDL::ExceptionOr<void> set_popover(Optional<String> value);
|
||||
Optional<String> popover() const;
|
||||
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
enum class PopoverVisibilityState {
|
||||
Hidden,
|
||||
|
|
|
@ -56,9 +56,9 @@ void HTMLFrameElement::inserted()
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/obsolete.html#frames:html-element-removing-steps
|
||||
void HTMLFrameElement::removed_from(DOM::Node* node)
|
||||
void HTMLFrameElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
Base::removed_from(node);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
// The frame HTML element removing steps, given removedNode, are to destroy a child navigable given removedNode.
|
||||
destroy_the_child_navigable();
|
||||
|
|
|
@ -25,7 +25,7 @@ private:
|
|||
|
||||
// ^DOM::Element
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual i32 default_tab_index_value() const override;
|
||||
virtual void adjust_computed_style(CSS::ComputedProperties&) override;
|
||||
|
|
|
@ -173,9 +173,9 @@ void HTMLIFrameElement::process_the_iframe_attributes(bool initial_insertion)
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/iframe-embed-object.html#the-iframe-element:the-iframe-element-7
|
||||
void HTMLIFrameElement::removed_from(DOM::Node* node)
|
||||
void HTMLIFrameElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
HTMLElement::removed_from(node);
|
||||
HTMLElement::removed_from(old_parent, old_root);
|
||||
|
||||
// When an iframe element is removed from a document, the user agent must destroy the nested navigable of the element.
|
||||
destroy_the_child_navigable();
|
||||
|
|
|
@ -45,7 +45,7 @@ private:
|
|||
|
||||
// ^DOM::Element
|
||||
virtual void post_connection() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual i32 default_tab_index_value() const override;
|
||||
|
||||
|
|
|
@ -50,9 +50,9 @@ void HTMLLinkElement::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLLinkElement);
|
||||
}
|
||||
|
||||
void HTMLLinkElement::removed_from(Node* old_parent)
|
||||
void HTMLLinkElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Base::removed_from(old_parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
if (m_loaded_style_sheet) {
|
||||
document_or_shadow_root_style_sheets().remove_a_css_style_sheet(*m_loaded_style_sheet);
|
||||
m_loaded_style_sheet = nullptr;
|
||||
|
|
|
@ -28,7 +28,7 @@ public:
|
|||
virtual ~HTMLLinkElement() override;
|
||||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node* old_parent) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
String rel() const { return get_attribute_value(HTML::AttributeNames::rel); }
|
||||
String type() const { return get_attribute_value(HTML::AttributeNames::type); }
|
||||
|
|
|
@ -112,9 +112,9 @@ void HTMLMediaElement::attribute_changed(FlyString const& name, Optional<String>
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/media.html#playing-the-media-resource:media-element-83
|
||||
void HTMLMediaElement::removed_from(DOM::Node* node)
|
||||
void HTMLMediaElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
Base::removed_from(node);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
// When a media element is removed from a Document, the user agent must run the following steps:
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ protected:
|
|||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual void removed_from(DOM::Node*) override;
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
|
||||
// Override in subclasses to handle implementation-specific behavior when the element state changes
|
||||
|
|
|
@ -151,9 +151,9 @@ void HTMLMetaElement::inserted()
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLMetaElement::removed_from(Node* parent)
|
||||
void HTMLMetaElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Base::removed_from(parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
update_metadata();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ private:
|
|||
|
||||
// ^DOM::Element
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -173,8 +173,9 @@ void HTMLMeterElement::inserted()
|
|||
create_shadow_tree_if_needed();
|
||||
}
|
||||
|
||||
void HTMLMeterElement::removed_from(DOM::Node*)
|
||||
void HTMLMeterElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
Base::removed_from(old_parent, old_root);
|
||||
set_shadow_root(nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ public:
|
|||
|
||||
// ^HTMLElement
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(DOM::Node*) override;
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override;
|
||||
|
||||
virtual void adjust_computed_style(CSS::ComputedProperties&) override;
|
||||
|
||||
|
|
|
@ -36,9 +36,9 @@ void HTMLOptGroupElement::inserted()
|
|||
static_cast<HTMLSelectElement&>(*parent()).update_selectedness();
|
||||
}
|
||||
|
||||
void HTMLOptGroupElement::removed_from(Node* old_parent)
|
||||
void HTMLOptGroupElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Base::removed_from(old_parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
// The optgroup HTML element removing steps, given removedNode and oldParent, are:
|
||||
// 1. If oldParent is a select element and removedNode has an option child, then run oldParent's selectedness setting algorithm.
|
||||
|
|
|
@ -25,7 +25,7 @@ private:
|
|||
HTMLOptGroupElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void inserted() override;
|
||||
};
|
||||
|
||||
|
|
|
@ -232,9 +232,9 @@ void HTMLOptionElement::inserted()
|
|||
static_cast<HTMLSelectElement&>(*parent()->parent()).update_selectedness();
|
||||
}
|
||||
|
||||
void HTMLOptionElement::removed_from(Node* old_parent)
|
||||
void HTMLOptionElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Base::removed_from(old_parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
// The option HTML element removing steps, given removedNode and oldParent, are:
|
||||
// 1. If oldParent is a select element, or oldParent is an optgroup element whose parent is a select element,
|
||||
|
|
|
@ -51,7 +51,7 @@ private:
|
|||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
|
||||
void ask_for_a_reset();
|
||||
|
|
|
@ -95,8 +95,9 @@ void HTMLProgressElement::inserted()
|
|||
create_shadow_tree_if_needed();
|
||||
}
|
||||
|
||||
void HTMLProgressElement::removed_from(DOM::Node*)
|
||||
void HTMLProgressElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
Base::removed_from(old_parent, old_root);
|
||||
set_shadow_root(nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
|
||||
// ^HTMLElement
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(DOM::Node*) override;
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override;
|
||||
|
||||
virtual void adjust_computed_style(CSS::ComputedProperties&) override;
|
||||
|
||||
|
|
|
@ -47,10 +47,10 @@ void HTMLSourceElement::inserted()
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element:the-source-element-16
|
||||
void HTMLSourceElement::removed_from(DOM::Node* old_parent)
|
||||
void HTMLSourceElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
|
||||
{
|
||||
// The source HTML element removing steps, given removedNode and oldParent, are:
|
||||
Base::removed_from(old_parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
// FIXME: 1. If removedNode's next sibling was an img element and oldParent is a picture element, then, count this as a
|
||||
// relevant mutation for the img element.
|
||||
|
|
|
@ -23,7 +23,7 @@ private:
|
|||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(DOM::Node*) override;
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -44,10 +44,10 @@ void HTMLStyleElement::inserted()
|
|||
Base::inserted();
|
||||
}
|
||||
|
||||
void HTMLStyleElement::removed_from(Node* old_parent)
|
||||
void HTMLStyleElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
m_style_element_utils.update_a_style_block(*this);
|
||||
Base::removed_from(old_parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/semantics.html#dom-style-disabled
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
|
||||
virtual void children_changed() override;
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
bool disabled();
|
||||
void set_disabled(bool disabled);
|
||||
|
|
|
@ -128,9 +128,9 @@ void SVGElement::update_use_elements_that_reference_this()
|
|||
});
|
||||
}
|
||||
|
||||
void SVGElement::removed_from(Node* parent)
|
||||
void SVGElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
Base::removed_from(parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
|
||||
remove_from_use_element_that_reference_this();
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ protected:
|
|||
virtual WebIDL::ExceptionOr<void> cloned(DOM::Node&, bool) const override;
|
||||
virtual void children_changed() override;
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
void update_use_elements_that_reference_this();
|
||||
void remove_from_use_element_that_reference_this();
|
||||
|
|
|
@ -42,10 +42,10 @@ void SVGStyleElement::inserted()
|
|||
Base::inserted();
|
||||
}
|
||||
|
||||
void SVGStyleElement::removed_from(Node* old_parent)
|
||||
void SVGStyleElement::removed_from(Node* old_parent, Node& old_root)
|
||||
{
|
||||
m_style_element_utils.update_a_style_block(*this);
|
||||
Base::removed_from(old_parent);
|
||||
Base::removed_from(old_parent, old_root);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/cssom/#dom-linkstyle-sheet
|
||||
|
|
|
@ -20,7 +20,7 @@ public:
|
|||
|
||||
virtual void children_changed() override;
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node*) override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
CSS::CSSStyleSheet* sheet();
|
||||
CSS::CSSStyleSheet const* sheet() const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue