mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 07:58:11 +00:00
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.
This commit is contained in:
parent
41f84deb9f
commit
0695236408
11 changed files with 30 additions and 36 deletions
|
@ -1285,7 +1285,7 @@ JS::NonnullGCPtr<HTMLCollection> Document::anchors()
|
||||||
{
|
{
|
||||||
if (!m_anchors) {
|
if (!m_anchors) {
|
||||||
m_anchors = HTMLCollection::create(*this, HTMLCollection::Scope::Descendants, [](Element const& element) {
|
m_anchors = HTMLCollection::create(*this, HTMLCollection::Scope::Descendants, [](Element const& element) {
|
||||||
return is<HTML::HTMLAnchorElement>(element) && element.has_attribute(HTML::AttributeNames::name);
|
return is<HTML::HTMLAnchorElement>(element) && element.name().has_value();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return *m_anchors;
|
return *m_anchors;
|
||||||
|
@ -1828,7 +1828,7 @@ Element* Document::find_a_potential_indicated_element(FlyString const& fragment)
|
||||||
// whose value is equal to fragment, then return the first such element in tree order.
|
// whose value is equal to fragment, then return the first such element in tree order.
|
||||||
Element* element_with_name = nullptr;
|
Element* element_with_name = nullptr;
|
||||||
root().for_each_in_subtree_of_type<Element>([&](Element const& element) {
|
root().for_each_in_subtree_of_type<Element>([&](Element const& element) {
|
||||||
if (element.attribute(HTML::AttributeNames::name) == fragment) {
|
if (element.name() == fragment) {
|
||||||
element_with_name = const_cast<Element*>(&element);
|
element_with_name = const_cast<Element*>(&element);
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,12 +118,10 @@ Vector<FlyString> HTMLCollection::supported_property_names() const
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. If element is in the HTML namespace and has a name attribute whose value is neither the empty string nor is in result, append element’s name attribute value to result.
|
// 2. If element is in the HTML namespace and has a name attribute whose value is neither the empty string nor is in result, append element’s name attribute value to result.
|
||||||
if (element->namespace_uri() == Namespace::HTML) {
|
if (element->namespace_uri() == Namespace::HTML && element->name().has_value()) {
|
||||||
if (auto maybe_name = element->attribute(HTML::AttributeNames::name); maybe_name.has_value()) {
|
auto name = element->name().value();
|
||||||
auto name = maybe_name.release_value();
|
if (!name.is_empty() && !result.contains_slow(name))
|
||||||
if (!name.is_empty() && !result.contains_slow(name))
|
result.append(move(name));
|
||||||
result.append(name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1481,8 +1481,8 @@ String Node::debug_description() const
|
||||||
builder.append(node_name().to_deprecated_fly_string().to_lowercase());
|
builder.append(node_name().to_deprecated_fly_string().to_lowercase());
|
||||||
if (is_element()) {
|
if (is_element()) {
|
||||||
auto const& element = static_cast<DOM::Element const&>(*this);
|
auto const& element = static_cast<DOM::Element const&>(*this);
|
||||||
if (auto id = element.get_attribute(HTML::AttributeNames::id); id.has_value())
|
if (element.id().has_value())
|
||||||
builder.appendff("#{}", id.value());
|
builder.appendff("#{}", element.id().value());
|
||||||
for (auto const& class_name : element.class_names())
|
for (auto const& class_name : element.class_names())
|
||||||
builder.appendff(".{}", class_name);
|
builder.appendff(".{}", class_name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,10 +150,9 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho
|
||||||
if (layout_node.dom_node() && is<DOM::Element>(*layout_node.dom_node())) {
|
if (layout_node.dom_node() && is<DOM::Element>(*layout_node.dom_node())) {
|
||||||
auto& element = verify_cast<DOM::Element>(*layout_node.dom_node());
|
auto& element = verify_cast<DOM::Element>(*layout_node.dom_node());
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
auto id = element.deprecated_attribute(HTML::AttributeNames::id);
|
if (element.id().has_value() && !element.id()->is_empty()) {
|
||||||
if (!id.is_empty()) {
|
|
||||||
builder.append('#');
|
builder.append('#');
|
||||||
builder.append(id);
|
builder.append(*element.id());
|
||||||
}
|
}
|
||||||
for (auto& class_name : element.class_names()) {
|
for (auto& class_name : element.class_names()) {
|
||||||
builder.append('.');
|
builder.append('.');
|
||||||
|
|
|
@ -104,7 +104,7 @@ void FormAssociatedElement::reset_form_owner()
|
||||||
// 1. If the first element in element's tree, in tree order, to have an ID that is identical to element's form content attribute's value, is a form element, then associate the element with that form element.
|
// 1. If the first element in element's tree, in tree order, to have an ID that is identical to element's form content attribute's value, is a form element, then associate the element with that form element.
|
||||||
auto form_value = html_element.attribute(HTML::AttributeNames::form);
|
auto form_value = html_element.attribute(HTML::AttributeNames::form);
|
||||||
html_element.root().for_each_in_inclusive_subtree_of_type<HTMLFormElement>([this, &form_value](HTMLFormElement& form_element) {
|
html_element.root().for_each_in_inclusive_subtree_of_type<HTMLFormElement>([this, &form_value](HTMLFormElement& form_element) {
|
||||||
if (form_element.attribute(HTML::AttributeNames::id) == form_value) {
|
if (form_element.id() == form_value) {
|
||||||
set_form(&form_element);
|
set_form(&form_element);
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -902,8 +902,8 @@ Vector<FlyString> HTMLFormElement::supported_property_names() const
|
||||||
|
|
||||||
// 2. If candidate has a name attribute, add an entry to sourced names with that name attribute's value as the
|
// 2. If candidate has a name attribute, add an entry to sourced names with that name attribute's value as the
|
||||||
// string, candidate as the element, and name as the source.
|
// string, candidate as the element, and name as the source.
|
||||||
if (auto maybe_name = candidate->attribute(HTML::AttributeNames::name); maybe_name.has_value())
|
if (candidate->name().has_value())
|
||||||
sourced_names.append(SourcedName { maybe_name.value(), candidate, SourcedName::Source::Name, {} });
|
sourced_names.append(SourcedName { candidate->name().value(), candidate, SourcedName::Source::Name, {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. For each img element candidate whose form owner is the form element:
|
// 3. For each img element candidate whose form owner is the form element:
|
||||||
|
@ -920,8 +920,8 @@ Vector<FlyString> HTMLFormElement::supported_property_names() const
|
||||||
|
|
||||||
// 2. If candidate has a name attribute, add an entry to sourced names with that name attribute's value as the
|
// 2. If candidate has a name attribute, add an entry to sourced names with that name attribute's value as the
|
||||||
// string, candidate as the element, and name as the source.
|
// string, candidate as the element, and name as the source.
|
||||||
if (auto maybe_name = candidate->attribute(HTML::AttributeNames::name); maybe_name.has_value())
|
if (candidate->name().has_value())
|
||||||
sourced_names.append(SourcedName { maybe_name.value(), candidate, SourcedName::Source::Name, {} });
|
sourced_names.append(SourcedName { candidate->name().value(), candidate, SourcedName::Source::Name, {} });
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. For each entry past entry in the past names map add an entry to sourced names with the past entry's name as
|
// 4. For each entry past entry in the past names map add an entry to sourced names with the past entry's name as
|
||||||
|
@ -984,8 +984,7 @@ WebIDL::ExceptionOr<JS::Value> HTMLFormElement::named_item_value(FlyString const
|
||||||
if (!is_form_control(element, *this))
|
if (!is_form_control(element, *this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// FIXME: DOM::Element::name() isn't cached
|
return name == element.id() || name == element.name();
|
||||||
return name == element.id() || name == element.attribute(HTML::AttributeNames::name);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. If candidates is empty, let candidates be a live RadioNodeList object containing all the img elements,
|
// 2. If candidates is empty, let candidates be a live RadioNodeList object containing all the img elements,
|
||||||
|
@ -1000,8 +999,7 @@ WebIDL::ExceptionOr<JS::Value> HTMLFormElement::named_item_value(FlyString const
|
||||||
if (element.form() != this)
|
if (element.form() != this)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// FIXME: DOM::Element::name() isn't cached
|
return name == element.id() || name == element.name();
|
||||||
return name == element.id() || name == element.attribute(HTML::AttributeNames::name);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,8 @@ void HTMLMetaElement::inserted()
|
||||||
// * The element is in a document tree
|
// * The element is in a document tree
|
||||||
// * The element has a name attribute, whose value is an ASCII case-insensitive match for theme-color
|
// * The element has a name attribute, whose value is an ASCII case-insensitive match for theme-color
|
||||||
// * The element has a content attribute
|
// * The element has a content attribute
|
||||||
auto name = attribute(AttributeNames::name);
|
|
||||||
auto content = attribute(AttributeNames::content);
|
auto content = attribute(AttributeNames::content);
|
||||||
if (name.has_value() && name->bytes_as_string_view().equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
|
if (name().has_value() && name()->equals_ignoring_ascii_case("theme-color"sv) && content.has_value()) {
|
||||||
auto context = CSS::Parser::ParsingContext { document() };
|
auto context = CSS::Parser::ParsingContext { document() };
|
||||||
|
|
||||||
// 2. For each element in candidate elements:
|
// 2. For each element in candidate elements:
|
||||||
|
|
|
@ -76,8 +76,8 @@ WebIDL::ExceptionOr<void> NavigableContainer::create_new_child_navigable()
|
||||||
Optional<String> target_name;
|
Optional<String> target_name;
|
||||||
|
|
||||||
// 5. If element has a name content attribute, then set targetName to the value of that attribute.
|
// 5. If element has a name content attribute, then set targetName to the value of that attribute.
|
||||||
if (auto value = attribute(HTML::AttributeNames::name); value.has_value())
|
if (name().has_value())
|
||||||
target_name = move(value);
|
target_name = name().value().to_string();
|
||||||
|
|
||||||
// 6. Let documentState be a new document state, with
|
// 6. Let documentState be a new document state, with
|
||||||
// - document: document
|
// - document: document
|
||||||
|
|
|
@ -1587,8 +1587,8 @@ Vector<FlyString> Window::supported_property_names() const
|
||||||
// and are in a document tree with window's associated Document as their root.
|
// and are in a document tree with window's associated Document as their root.
|
||||||
associated_document().for_each_in_subtree_of_type<DOM::Element>([&property_names](auto& element) -> IterationDecision {
|
associated_document().for_each_in_subtree_of_type<DOM::Element>([&property_names](auto& element) -> IterationDecision {
|
||||||
if (is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element)) {
|
if (is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element)) {
|
||||||
if (auto const& name = element.attribute(AttributeNames::name); name.has_value())
|
if (element.name().has_value())
|
||||||
property_names.set(name.value(), AK::HashSetExistingEntryBehavior::Keep);
|
property_names.set(element.name().value(), AK::HashSetExistingEntryBehavior::Keep);
|
||||||
}
|
}
|
||||||
if (auto const& name = element.id(); name.has_value())
|
if (auto const& name = element.id(); name.has_value())
|
||||||
property_names.set(name.value().to_string(), AK::HashSetExistingEntryBehavior::Keep);
|
property_names.set(name.value().to_string(), AK::HashSetExistingEntryBehavior::Keep);
|
||||||
|
@ -1636,9 +1636,9 @@ WebIDL::ExceptionOr<JS::Value> Window::named_item_value(FlyString const& name) c
|
||||||
// whose filter matches only named objects of window with the name name. (By definition, these will all be elements.)
|
// whose filter matches only named objects of window with the name name. (By definition, these will all be elements.)
|
||||||
return DOM::HTMLCollection::create(mutable_this.associated_document(), DOM::HTMLCollection::Scope::Descendants, [name](auto& element) -> bool {
|
return DOM::HTMLCollection::create(mutable_this.associated_document(), DOM::HTMLCollection::Scope::Descendants, [name](auto& element) -> bool {
|
||||||
if ((is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element))
|
if ((is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element))
|
||||||
&& (element.attribute(AttributeNames::name) == name))
|
&& (element.name() == name))
|
||||||
return true;
|
return true;
|
||||||
return element.attribute(AttributeNames::id) == name;
|
return element.id() == name;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1664,9 +1664,9 @@ Window::NamedObjects Window::named_objects(StringView name)
|
||||||
// HTML elements that have an id content attribute whose value is name and are in a document tree with window's associated Document as their root.
|
// HTML elements that have an id content attribute whose value is name and are in a document tree with window's associated Document as their root.
|
||||||
associated_document().for_each_in_subtree_of_type<DOM::Element>([&objects, &name](auto& element) -> IterationDecision {
|
associated_document().for_each_in_subtree_of_type<DOM::Element>([&objects, &name](auto& element) -> IterationDecision {
|
||||||
if ((is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element))
|
if ((is<HTMLEmbedElement>(element) || is<HTMLFormElement>(element) || is<HTMLImageElement>(element) || is<HTMLObjectElement>(element))
|
||||||
&& (element.attribute(AttributeNames::name) == name))
|
&& (element.name() == name))
|
||||||
objects.elements.append(element);
|
objects.elements.append(element);
|
||||||
else if (element.attribute(AttributeNames::id) == name)
|
else if (element.id() == name)
|
||||||
objects.elements.append(element);
|
objects.elements.append(element);
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
|
|
@ -93,7 +93,7 @@ Label const* Label::label_for_control_node(LabelableNode const& control)
|
||||||
// same tree as the label element. If the attribute is specified and there is an element in the tree
|
// same tree as the label element. If the attribute is specified and there is an element in the tree
|
||||||
// whose ID is equal to the value of the for attribute, and the first such element in tree order is
|
// whose ID is equal to the value of the for attribute, and the first such element in tree order is
|
||||||
// a labelable element, then that element is the label element's labeled control.
|
// a labelable element, then that element is the label element's labeled control.
|
||||||
if (auto id = control.dom_node().attribute(HTML::AttributeNames::id); id.has_value() && !id->is_empty()) {
|
if (auto const& id = control.dom_node().id(); id.has_value() && !id->is_empty()) {
|
||||||
Label const* label = nullptr;
|
Label const* label = nullptr;
|
||||||
|
|
||||||
control.document().layout_node()->for_each_in_inclusive_subtree_of_type<Label>([&](auto& node) {
|
control.document().layout_node()->for_each_in_inclusive_subtree_of_type<Label>([&](auto& node) {
|
||||||
|
@ -128,7 +128,7 @@ LabelableNode* Label::labeled_control()
|
||||||
// a labelable element, then that element is the label element's labeled control.
|
// a labelable element, then that element is the label element's labeled control.
|
||||||
if (auto for_ = dom_node().for_(); for_.has_value()) {
|
if (auto for_ = dom_node().for_(); for_.has_value()) {
|
||||||
document().layout_node()->for_each_in_inclusive_subtree_of_type<LabelableNode>([&](auto& node) {
|
document().layout_node()->for_each_in_inclusive_subtree_of_type<LabelableNode>([&](auto& node) {
|
||||||
if (node.dom_node().attribute(HTML::AttributeNames::id) == for_) {
|
if (node.dom_node().id() == for_) {
|
||||||
control = &node;
|
control = &node;
|
||||||
return IterationDecision::Break;
|
return IterationDecision::Break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -899,8 +899,8 @@ ByteString Node::debug_description() const
|
||||||
builder.appendff("<{}>", dom_node()->node_name());
|
builder.appendff("<{}>", dom_node()->node_name());
|
||||||
if (dom_node()->is_element()) {
|
if (dom_node()->is_element()) {
|
||||||
auto& element = static_cast<DOM::Element const&>(*dom_node());
|
auto& element = static_cast<DOM::Element const&>(*dom_node());
|
||||||
if (auto id = element.get_attribute(HTML::AttributeNames::id); id.has_value())
|
if (element.id().has_value())
|
||||||
builder.appendff("#{}", id.value());
|
builder.appendff("#{}", element.id().value());
|
||||||
for (auto const& class_name : element.class_names())
|
for (auto const& class_name : element.class_names())
|
||||||
builder.appendff(".{}", class_name);
|
builder.appendff(".{}", class_name);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue