mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 11:49:44 +00:00
LibWeb: Add metadata to children update steps invocation
Currently, this metadata is only provided on the insertion steps, though I believe it would be useful to extend to the other cases as well. This metadata can aid in making optimizations for these steps by providing extra context into the type of change which was made on the child.
This commit is contained in:
parent
6c1470994b
commit
903c8860f8
Notes:
github-actions[bot]
2025-01-30 20:56:50 +00:00
Author: https://github.com/shannonbooth
Commit: 903c8860f8
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3373
Reviewed-by: https://github.com/ADKaster ✅
27 changed files with 52 additions and 40 deletions
|
@ -126,7 +126,7 @@ WebIDL::ExceptionOr<void> CharacterData::replace_data(size_t offset, size_t coun
|
|||
|
||||
// 12. If node’s parent is non-null, then run the children changed steps for node’s parent.
|
||||
if (parent())
|
||||
parent()->children_changed();
|
||||
parent()->children_changed(nullptr);
|
||||
|
||||
// NOTE: Since the text node's data has changed, we need to invalidate the text for rendering.
|
||||
// This ensures that the new text is reflected in layout, even if we don't end up
|
||||
|
|
|
@ -1107,9 +1107,9 @@ void Element::removed_from(Node* old_parent, Node& old_root)
|
|||
document().element_with_name_was_removed({}, *this);
|
||||
}
|
||||
|
||||
void Element::children_changed()
|
||||
void Element::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Node::children_changed();
|
||||
Node::children_changed(metadata);
|
||||
set_needs_style_update(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -420,7 +420,7 @@ protected:
|
|||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
virtual i32 default_tab_index_value() const;
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-element-attributes-change-ext
|
||||
|
|
|
@ -745,7 +745,8 @@ void Node::insert_before(GC::Ref<Node> node, GC::Ptr<Node> child, bool suppress_
|
|||
}
|
||||
|
||||
// 9. Run the children changed steps for parent.
|
||||
children_changed();
|
||||
ChildrenChangedMetadata metadata { ChildrenChangedMetadata::Type::Inserted, node };
|
||||
children_changed(&metadata);
|
||||
|
||||
// 10. Let staticNodeList be a list of nodes, initially « ».
|
||||
// Spec-Note: We collect all nodes before calling the post-connection steps on any one of them, instead of calling
|
||||
|
@ -977,7 +978,7 @@ void Node::remove(bool suppress_observers)
|
|||
}
|
||||
|
||||
// 21. Run the children changed steps for parent.
|
||||
parent->children_changed();
|
||||
parent->children_changed(nullptr);
|
||||
|
||||
document().bump_dom_tree_version();
|
||||
}
|
||||
|
|
|
@ -262,7 +262,18 @@ public:
|
|||
virtual void inserted();
|
||||
virtual void post_connection();
|
||||
virtual void removed_from(Node* old_parent, Node& old_root);
|
||||
virtual void children_changed() { }
|
||||
struct ChildrenChangedMetadata {
|
||||
enum class Type {
|
||||
Inserted,
|
||||
Removal,
|
||||
Mutation,
|
||||
};
|
||||
Type type {};
|
||||
GC::Ref<Node> node;
|
||||
};
|
||||
// FIXME: It would be good if we could always provide this metadata for use in optimizations.
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) { }
|
||||
|
||||
virtual void adopted_from(Document&) { }
|
||||
virtual WebIDL::ExceptionOr<void> cloned(Node&, bool) const { return {}; }
|
||||
|
||||
|
|
|
@ -100,9 +100,9 @@ void HTMLDetailsElement::attribute_changed(FlyString const& local_name, Optional
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLDetailsElement::children_changed()
|
||||
void HTMLDetailsElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
update_shadow_tree_slots();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ private:
|
|||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(DOM::Node* old_parent, DOM::Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
|
||||
void queue_a_details_toggle_event_task(String old_state, String new_state);
|
||||
|
|
|
@ -766,9 +766,9 @@ private:
|
|||
|
||||
GC_DEFINE_ALLOCATOR(SourceElementSelector);
|
||||
|
||||
void HTMLMediaElement::children_changed()
|
||||
void HTMLMediaElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
|
||||
if (m_source_element_selector)
|
||||
m_source_element_selector->process_next_candidate().release_value_but_fixme_should_propagate_errors();
|
||||
|
|
|
@ -158,7 +158,7 @@ protected:
|
|||
|
||||
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* old_parent, DOM::Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const* metadata) override;
|
||||
|
||||
// Override in subclasses to handle implementation-specific behavior when the element state changes
|
||||
// to playing or paused, e.g. to start/stop play timers.
|
||||
|
|
|
@ -253,9 +253,9 @@ void HTMLOptionElement::removed_from(Node* old_parent, Node& old_root)
|
|||
}
|
||||
}
|
||||
|
||||
void HTMLOptionElement::children_changed()
|
||||
void HTMLOptionElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
|
||||
update_selection_label();
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ private:
|
|||
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
|
||||
void ask_for_a_reset();
|
||||
void update_selection_label();
|
||||
|
|
|
@ -572,9 +572,9 @@ void HTMLScriptElement::prepare_script()
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model:html-element-post-connection-steps-4
|
||||
void HTMLScriptElement::children_changed()
|
||||
void HTMLScriptElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
|
||||
// 1. Run the script HTML element post-connection steps, given the script element.
|
||||
post_connection();
|
||||
|
|
|
@ -43,7 +43,7 @@ public:
|
|||
|
||||
bool is_parser_inserted() const { return !!m_parser_document; }
|
||||
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
virtual void post_connection() override;
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/scripting.html#dom-script-supports
|
||||
|
|
|
@ -292,9 +292,9 @@ i32 HTMLSelectElement::default_tab_index_value() const
|
|||
return 0;
|
||||
}
|
||||
|
||||
void HTMLSelectElement::children_changed()
|
||||
void HTMLSelectElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
update_cached_list_of_options();
|
||||
update_selectedness();
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ private:
|
|||
|
||||
virtual void computed_properties_changed() override;
|
||||
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
|
||||
void update_cached_list_of_options() const;
|
||||
void show_the_picker_if_applicable();
|
||||
|
|
|
@ -32,9 +32,9 @@ void HTMLStyleElement::visit_edges(Cell::Visitor& visitor)
|
|||
m_style_element_utils.visit_edges(visitor);
|
||||
}
|
||||
|
||||
void HTMLStyleElement::children_changed()
|
||||
void HTMLStyleElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
m_style_element_utils.update_a_style_block(*this);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ class HTMLStyleElement final : public HTMLElement {
|
|||
public:
|
||||
virtual ~HTMLStyleElement() override;
|
||||
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
|
|
|
@ -429,9 +429,9 @@ void HTMLTextAreaElement::update_placeholder_visibility()
|
|||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element:children-changed-steps
|
||||
void HTMLTextAreaElement::children_changed()
|
||||
void HTMLTextAreaElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
|
||||
// The children changed steps for textarea elements must, if the element's dirty value flag is false,
|
||||
// set the element's raw value to its child text content.
|
||||
|
|
|
@ -70,7 +70,7 @@ public:
|
|||
virtual void form_associated_element_was_removed(DOM::Node*) override;
|
||||
virtual void form_associated_element_attribute_changed(FlyString const&, Optional<String> const&, Optional<FlyString> const&) override;
|
||||
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
|
||||
// https://www.w3.org/TR/html-aria/#el-textarea
|
||||
virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::textbox; }
|
||||
|
|
|
@ -27,9 +27,9 @@ void HTMLTitleElement::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLTitleElement);
|
||||
}
|
||||
|
||||
void HTMLTitleElement::children_changed()
|
||||
void HTMLTitleElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
HTMLElement::children_changed();
|
||||
HTMLElement::children_changed(metadata);
|
||||
auto navigable = this->navigable();
|
||||
if (navigable && navigable->is_traversable()) {
|
||||
navigable->traversable_navigable()->page().client().page_did_change_title(document().title().to_byte_string());
|
||||
|
|
|
@ -24,7 +24,7 @@ private:
|
|||
HTMLTitleElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -98,9 +98,9 @@ void SVGElement::inserted()
|
|||
update_use_elements_that_reference_this();
|
||||
}
|
||||
|
||||
void SVGElement::children_changed()
|
||||
void SVGElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
|
||||
update_use_elements_that_reference_this();
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ protected:
|
|||
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual WebIDL::ExceptionOr<void> cloned(DOM::Node&, bool) const override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@ void SVGStyleElement::visit_edges(Cell::Visitor& visitor)
|
|||
m_style_element_utils.visit_edges(visitor);
|
||||
}
|
||||
|
||||
void SVGStyleElement::children_changed()
|
||||
void SVGStyleElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
m_style_element_utils.update_a_style_block(*this);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class SVGStyleElement final : public SVGElement {
|
|||
public:
|
||||
virtual ~SVGStyleElement() override;
|
||||
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
virtual void inserted() override;
|
||||
virtual void removed_from(Node* old_parent, Node& old_root) override;
|
||||
|
||||
|
|
|
@ -30,9 +30,9 @@ GC::Ptr<Layout::Node> SVGTitleElement::create_layout_node(GC::Ref<CSS::ComputedP
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void SVGTitleElement::children_changed()
|
||||
void SVGTitleElement::children_changed(ChildrenChangedMetadata const* metadata)
|
||||
{
|
||||
Base::children_changed();
|
||||
Base::children_changed(metadata);
|
||||
|
||||
auto& page = document().page();
|
||||
if (document().browsing_context() != &page.top_level_browsing_context())
|
||||
|
|
|
@ -20,7 +20,7 @@ private:
|
|||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
virtual GC::Ptr<Layout::Node> create_layout_node(GC::Ref<CSS::ComputedProperties>) override;
|
||||
virtual void children_changed() override;
|
||||
virtual void children_changed(ChildrenChangedMetadata const*) override;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue