mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:28:12 +00:00
LibWeb: Port Element::name to a cached FlyString
Also removing some handling of OOM while we are in the area.
This commit is contained in:
parent
cb9118efe3
commit
41f84deb9f
6 changed files with 22 additions and 24 deletions
|
@ -1252,9 +1252,8 @@ void Document::set_hovered_node(Node* node)
|
||||||
|
|
||||||
JS::NonnullGCPtr<HTMLCollection> Document::get_elements_by_name(String const& name)
|
JS::NonnullGCPtr<HTMLCollection> Document::get_elements_by_name(String const& name)
|
||||||
{
|
{
|
||||||
auto deprecated_name = name.to_byte_string();
|
return HTMLCollection::create(*this, HTMLCollection::Scope::Descendants, [name](Element const& element) {
|
||||||
return HTMLCollection::create(*this, HTMLCollection::Scope::Descendants, [deprecated_name](Element const& element) {
|
return element.name() == name;
|
||||||
return element.name() == deprecated_name;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -459,6 +459,11 @@ void Element::attribute_changed(FlyString const& name, Optional<String> const& v
|
||||||
m_id = {};
|
m_id = {};
|
||||||
else
|
else
|
||||||
m_id = value_or_empty;
|
m_id = value_or_empty;
|
||||||
|
} else if (name == HTML::AttributeNames::name) {
|
||||||
|
if (!value.has_value())
|
||||||
|
m_name = {};
|
||||||
|
else
|
||||||
|
m_name = value_or_empty;
|
||||||
} else if (name == HTML::AttributeNames::class_) {
|
} else if (name == HTML::AttributeNames::class_) {
|
||||||
auto new_classes = value_or_empty.bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace);
|
auto new_classes = value_or_empty.bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace);
|
||||||
m_classes.clear();
|
m_classes.clear();
|
||||||
|
|
|
@ -174,8 +174,6 @@ public:
|
||||||
Layout::NodeWithStyle* layout_node();
|
Layout::NodeWithStyle* layout_node();
|
||||||
Layout::NodeWithStyle const* layout_node() const;
|
Layout::NodeWithStyle const* layout_node() const;
|
||||||
|
|
||||||
ByteString name() const { return deprecated_attribute(HTML::AttributeNames::name); }
|
|
||||||
|
|
||||||
CSS::StyleProperties* computed_css_values() { return m_computed_css_values.ptr(); }
|
CSS::StyleProperties* computed_css_values() { return m_computed_css_values.ptr(); }
|
||||||
CSS::StyleProperties const* computed_css_values() const { return m_computed_css_values.ptr(); }
|
CSS::StyleProperties const* computed_css_values() const { return m_computed_css_values.ptr(); }
|
||||||
void set_computed_css_values(RefPtr<CSS::StyleProperties>);
|
void set_computed_css_values(RefPtr<CSS::StyleProperties>);
|
||||||
|
@ -368,6 +366,7 @@ public:
|
||||||
Directionality directionality() const;
|
Directionality directionality() const;
|
||||||
|
|
||||||
Optional<FlyString> const& id() const { return m_id; }
|
Optional<FlyString> const& id() const { return m_id; }
|
||||||
|
Optional<FlyString> const& name() const { return m_name; }
|
||||||
|
|
||||||
virtual JS::GCPtr<JS::HeapFunction<void()>> take_lazy_load_resumption_steps(Badge<DOM::Document>)
|
virtual JS::GCPtr<JS::HeapFunction<void()>> take_lazy_load_resumption_steps(Badge<DOM::Document>)
|
||||||
{
|
{
|
||||||
|
@ -417,6 +416,7 @@ private:
|
||||||
Optional<Dir> m_dir;
|
Optional<Dir> m_dir;
|
||||||
|
|
||||||
Optional<FlyString> m_id;
|
Optional<FlyString> m_id;
|
||||||
|
Optional<FlyString> m_name;
|
||||||
|
|
||||||
using PseudoElementLayoutNodes = Array<JS::GCPtr<Layout::Node>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)>;
|
using PseudoElementLayoutNodes = Array<JS::GCPtr<Layout::Node>, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)>;
|
||||||
OwnPtr<PseudoElementLayoutNodes> m_pseudo_element_nodes;
|
OwnPtr<PseudoElementLayoutNodes> m_pseudo_element_nodes;
|
||||||
|
|
|
@ -84,17 +84,15 @@ Element* HTMLCollection::item(size_t index) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem-key
|
// https://dom.spec.whatwg.org/#dom-htmlcollection-nameditem-key
|
||||||
Element* HTMLCollection::named_item(FlyString const& name_) const
|
Element* HTMLCollection::named_item(FlyString const& name) const
|
||||||
{
|
{
|
||||||
auto name = name_.to_deprecated_fly_string();
|
|
||||||
|
|
||||||
// 1. If key is the empty string, return null.
|
// 1. If key is the empty string, return null.
|
||||||
if (name.is_empty())
|
if (name.is_empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto elements = collect_matching_elements();
|
auto elements = collect_matching_elements();
|
||||||
// 2. Return the first element in the collection for which at least one of the following is true:
|
// 2. Return the first element in the collection for which at least one of the following is true:
|
||||||
// - it has an ID which is key;
|
// - it has an ID which is key;
|
||||||
if (auto it = elements.find_if([&](auto& entry) { return entry->id().has_value() && entry->id().value() == name_; }); it != elements.end())
|
if (auto it = elements.find_if([&](auto& entry) { return entry->id().has_value() && entry->id().value() == name; }); it != elements.end())
|
||||||
return *it;
|
return *it;
|
||||||
// - it is in the HTML namespace and has a name attribute whose value is key;
|
// - it is in the HTML namespace and has a name attribute whose value is key;
|
||||||
if (auto it = elements.find_if([&](auto& entry) { return entry->namespace_uri() == Namespace::HTML && entry->name() == name; }); it != elements.end())
|
if (auto it = elements.find_if([&](auto& entry) { return entry->namespace_uri() == Namespace::HTML && entry->name() == name; }); it != elements.end())
|
||||||
|
|
|
@ -39,8 +39,6 @@ Variant<Empty, Element*, JS::Handle<RadioNodeList>> HTMLFormControlsCollection::
|
||||||
if (name.is_empty())
|
if (name.is_empty())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
auto const deprecated_name = name.to_deprecated_fly_string();
|
|
||||||
|
|
||||||
// 2. If, at the time the method is called, there is exactly one node in the collection that has either an id attribute or a name attribute equal to name, then return that node and stop the algorithm.
|
// 2. If, at the time the method is called, there is exactly one node in the collection that has either an id attribute or a name attribute equal to name, then return that node and stop the algorithm.
|
||||||
// 3. Otherwise, if there are no nodes in the collection that have either an id attribute or a name attribute equal to name, then return null and stop the algorithm.
|
// 3. Otherwise, if there are no nodes in the collection that have either an id attribute or a name attribute equal to name, then return null and stop the algorithm.
|
||||||
Element* matching_element = nullptr;
|
Element* matching_element = nullptr;
|
||||||
|
@ -48,7 +46,7 @@ Variant<Empty, Element*, JS::Handle<RadioNodeList>> HTMLFormControlsCollection::
|
||||||
|
|
||||||
auto collection = collect_matching_elements();
|
auto collection = collect_matching_elements();
|
||||||
for (auto const& element : collection) {
|
for (auto const& element : collection) {
|
||||||
if (element->id() != name && element->name() != deprecated_name)
|
if (element->id() != name && element->name() != name)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (matching_element) {
|
if (matching_element) {
|
||||||
|
@ -68,12 +66,12 @@ Variant<Empty, Element*, JS::Handle<RadioNodeList>> HTMLFormControlsCollection::
|
||||||
// 4. Otherwise, create a new RadioNodeList object representing a live view of the HTMLFormControlsCollection object, further filtered so that the only nodes in the
|
// 4. Otherwise, create a new RadioNodeList object representing a live view of the HTMLFormControlsCollection object, further filtered so that the only nodes in the
|
||||||
// RadioNodeList object are those that have either an id attribute or a name attribute equal to name. The nodes in the RadioNodeList object must be sorted in tree
|
// RadioNodeList object are those that have either an id attribute or a name attribute equal to name. The nodes in the RadioNodeList object must be sorted in tree
|
||||||
// order. Return that RadioNodeList object.
|
// order. Return that RadioNodeList object.
|
||||||
return JS::make_handle(RadioNodeList::create(realm(), root(), LiveNodeList::Scope::Descendants, [name, deprecated_name](Node const& node) {
|
return JS::make_handle(RadioNodeList::create(realm(), root(), LiveNodeList::Scope::Descendants, [name](Node const& node) {
|
||||||
if (!is<Element>(node))
|
if (!is<Element>(node))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto const& element = verify_cast<Element>(node);
|
auto const& element = verify_cast<Element>(node);
|
||||||
return element.id() == name || element.name() == deprecated_name;
|
return element.id() == name || element.name() == name;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,19 +103,17 @@ WebIDL::ExceptionOr<Optional<Vector<XHR::FormDataEntry>>> construct_entry_list(J
|
||||||
// FIXME: 3. If the field is a form-associated custom element, then perform the entry construction algorithm given field and entry list, then continue.
|
// FIXME: 3. If the field is a form-associated custom element, then perform the entry construction algorithm given field and entry list, then continue.
|
||||||
|
|
||||||
// 4. If either the field element does not have a name attribute specified, or its name attribute's value is the empty string, then continue.
|
// 4. If either the field element does not have a name attribute specified, or its name attribute's value is the empty string, then continue.
|
||||||
if (control->name().is_empty())
|
if (!control->name().has_value() || control->name()->is_empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// 5. Let name be the value of the field element's name attribute.
|
// 5. Let name be the value of the field element's name attribute.
|
||||||
auto name = TRY_OR_THROW_OOM(vm, String::from_byte_string(control->name()));
|
auto name = control->name().value();
|
||||||
|
|
||||||
// 6. If the field element is a select element, then for each option element in the select element's list of options whose selectedness is true and that is not disabled, create an entry with name and the value of the option element, and append it to entry list.
|
// 6. If the field element is a select element, then for each option element in the select element's list of options whose selectedness is true and that is not disabled, create an entry with name and the value of the option element, and append it to entry list.
|
||||||
if (auto* select_element = dynamic_cast<HTML::HTMLSelectElement*>(control.ptr())) {
|
if (auto* select_element = dynamic_cast<HTML::HTMLSelectElement*>(control.ptr())) {
|
||||||
for (auto const& option_element : select_element->list_of_options()) {
|
for (auto const& option_element : select_element->list_of_options()) {
|
||||||
if (option_element->selected() && !option_element->disabled()) {
|
if (option_element->selected() && !option_element->disabled()) {
|
||||||
auto option_name = TRY_OR_THROW_OOM(vm, String::from_byte_string(option_element->name()));
|
entry_list.append(XHR::FormDataEntry { .name = name.to_string(), .value = option_element->value() });
|
||||||
auto option_value = option_element->value();
|
|
||||||
TRY_OR_THROW_OOM(vm, entry_list.try_append(XHR::FormDataEntry { .name = move(option_name), .value = move(option_value) }));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +126,7 @@ WebIDL::ExceptionOr<Optional<Vector<XHR::FormDataEntry>>> construct_entry_list(J
|
||||||
|
|
||||||
// 2. Create an entry with name and value, and append it to entry list.
|
// 2. Create an entry with name and value, and append it to entry list.
|
||||||
auto checkbox_or_radio_element_name = TRY_OR_THROW_OOM(vm, String::from_byte_string(checkbox_or_radio_element->name()));
|
auto checkbox_or_radio_element_name = TRY_OR_THROW_OOM(vm, String::from_byte_string(checkbox_or_radio_element->name()));
|
||||||
TRY_OR_THROW_OOM(vm, entry_list.try_append(XHR::FormDataEntry { .name = move(checkbox_or_radio_element_name), .value = move(value) }));
|
entry_list.append(XHR::FormDataEntry { .name = move(checkbox_or_radio_element_name), .value = move(value) });
|
||||||
}
|
}
|
||||||
// 8. Otherwise, if the field element is an input element whose type attribute is in the File Upload state, then:
|
// 8. Otherwise, if the field element is an input element whose type attribute is in the File Upload state, then:
|
||||||
else if (auto* file_element = dynamic_cast<HTML::HTMLInputElement*>(control.ptr()); file_element && file_element->type_state() == HTMLInputElement::TypeAttributeState::FileUpload) {
|
else if (auto* file_element = dynamic_cast<HTML::HTMLInputElement*>(control.ptr()); file_element && file_element->type_state() == HTMLInputElement::TypeAttributeState::FileUpload) {
|
||||||
|
@ -137,13 +135,13 @@ WebIDL::ExceptionOr<Optional<Vector<XHR::FormDataEntry>>> construct_entry_list(J
|
||||||
FileAPI::FilePropertyBag options {};
|
FileAPI::FilePropertyBag options {};
|
||||||
options.type = "application/octet-stream"_string;
|
options.type = "application/octet-stream"_string;
|
||||||
auto file = TRY(FileAPI::File::create(realm, {}, String {}, options));
|
auto file = TRY(FileAPI::File::create(realm, {}, String {}, options));
|
||||||
TRY_OR_THROW_OOM(vm, entry_list.try_append(XHR::FormDataEntry { .name = move(name), .value = JS::make_handle(file) }));
|
entry_list.append(XHR::FormDataEntry { .name = name.to_string(), .value = JS::make_handle(file) });
|
||||||
}
|
}
|
||||||
// 2. Otherwise, for each file in selected files, create an entry with name and a File object representing the file, and append it to entry list.
|
// 2. Otherwise, for each file in selected files, create an entry with name and a File object representing the file, and append it to entry list.
|
||||||
else {
|
else {
|
||||||
for (size_t i = 0; i < file_element->files()->length(); i++) {
|
for (size_t i = 0; i < file_element->files()->length(); i++) {
|
||||||
auto file = JS::NonnullGCPtr { *file_element->files()->item(i) };
|
auto file = JS::NonnullGCPtr { *file_element->files()->item(i) };
|
||||||
TRY_OR_THROW_OOM(vm, entry_list.try_append(XHR::FormDataEntry { .name = move(name), .value = JS::make_handle(file) }));
|
entry_list.append(XHR::FormDataEntry { .name = name.to_string(), .value = JS::make_handle(file) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,11 +151,11 @@ WebIDL::ExceptionOr<Optional<Vector<XHR::FormDataEntry>>> construct_entry_list(J
|
||||||
auto charset = encoding.has_value() ? encoding.value() : "UTF-8"_string;
|
auto charset = encoding.has_value() ? encoding.value() : "UTF-8"_string;
|
||||||
|
|
||||||
// 2. Create an entry with name and charset, and append it to entry list.
|
// 2. Create an entry with name and charset, and append it to entry list.
|
||||||
TRY_OR_THROW_OOM(vm, entry_list.try_append(XHR::FormDataEntry { .name = move(name), .value = move(charset) }));
|
entry_list.append(XHR::FormDataEntry { .name = name.to_string(), .value = move(charset) });
|
||||||
}
|
}
|
||||||
// 10. Otherwise, create an entry with name and the value of the field element, and append it to entry list.
|
// 10. Otherwise, create an entry with name and the value of the field element, and append it to entry list.
|
||||||
else {
|
else {
|
||||||
TRY_OR_THROW_OOM(vm, entry_list.try_append(XHR::FormDataEntry { .name = move(name), .value = control_as_form_associated_element->value() }));
|
entry_list.append(XHR::FormDataEntry { .name = name.to_string(), .value = control_as_form_associated_element->value() });
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: 11. If the element has a dirname attribute, and that attribute's value is not the empty string, then:
|
// FIXME: 11. If the element has a dirname attribute, and that attribute's value is not the empty string, then:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue