1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 04:27:45 +00:00

LibWeb: Port Attr interface from DeprecatedString to String

There are an unfortunate number of DeprecatedString conversions required
here, but these should all fall away and look much more pretty again
when other places are also ported away from DeprecatedString.

Leaves only the Element IDL interface left :^)
This commit is contained in:
Shannon Booth 2023-09-10 16:06:58 +12:00 committed by Andreas Kling
parent a41f23a0fc
commit 3bd04d2c58
15 changed files with 172 additions and 117 deletions

View file

@ -15,12 +15,12 @@
namespace Web::DOM {
JS::NonnullGCPtr<Attr> Attr::create(Document& document, DeprecatedFlyString local_name, DeprecatedString value, Element* owner_element)
JS::NonnullGCPtr<Attr> Attr::create(Document& document, FlyString local_name, String value, Element* owner_element)
{
return document.heap().allocate<Attr>(document.realm(), document, QualifiedName(move(local_name), {}, {}), move(value), owner_element);
return document.heap().allocate<Attr>(document.realm(), document, QualifiedName(move(local_name), Optional<FlyString> {}, Optional<FlyString> {}), move(value), owner_element);
}
JS::NonnullGCPtr<Attr> Attr::create(Document& document, QualifiedName qualified_name, DeprecatedString value, Element* owner_element)
JS::NonnullGCPtr<Attr> Attr::create(Document& document, QualifiedName qualified_name, String value, Element* owner_element)
{
return document.heap().allocate<Attr>(document.realm(), document, move(qualified_name), move(value), owner_element);
}
@ -30,7 +30,7 @@ JS::NonnullGCPtr<Attr> Attr::clone(Document& document)
return *heap().allocate<Attr>(realm(), document, m_qualified_name, m_value, nullptr);
}
Attr::Attr(Document& document, QualifiedName qualified_name, DeprecatedString value, Element* owner_element)
Attr::Attr(Document& document, QualifiedName qualified_name, String value, Element* owner_element)
: Node(document, NodeType::ATTRIBUTE_NODE)
, m_qualified_name(move(qualified_name))
, m_value(move(value))
@ -66,7 +66,7 @@ void Attr::set_owner_element(Element* owner_element)
}
// https://dom.spec.whatwg.org/#set-an-existing-attribute-value
void Attr::set_value(DeprecatedString value)
void Attr::set_value(String value)
{
// 1. If attributes element is null, then set attributes value to value.
if (!owner_element()) {
@ -79,7 +79,7 @@ void Attr::set_value(DeprecatedString value)
}
// https://dom.spec.whatwg.org/#concept-element-attributes-change
void Attr::change_attribute(DeprecatedString value)
void Attr::change_attribute(String value)
{
// 1. Let oldValue be attributes value.
auto old_value = move(m_value);
@ -88,14 +88,18 @@ void Attr::change_attribute(DeprecatedString value)
m_value = move(value);
// 3. Handle attribute changes for attribute with attributes element, oldValue, and value.
handle_attribute_changes(*owner_element(), old_value, m_value);
handle_attribute_changes(*owner_element(), old_value.to_deprecated_string(), m_value.to_deprecated_string());
}
// https://dom.spec.whatwg.org/#handle-attribute-changes
void Attr::handle_attribute_changes(Element& element, DeprecatedString const& old_value, DeprecatedString const& new_value)
{
DeprecatedString deprecated_namespace_uri;
if (namespace_uri().has_value())
deprecated_namespace_uri = namespace_uri().value().to_deprecated_fly_string();
// 1. Queue a mutation record of "attributes" for element with attributes local name, attributes namespace, oldValue, « », « », null, and null.
element.queue_mutation_record(MutationType::attributes, local_name(), namespace_uri(), old_value, {}, {}, nullptr, nullptr);
element.queue_mutation_record(MutationType::attributes, local_name().to_deprecated_fly_string(), deprecated_namespace_uri, old_value, {}, {}, nullptr, nullptr);
// 2. If element is custom, then enqueue a custom element callback reaction with element, callback name "attributeChangedCallback", and an argument list containing attributes local name, oldValue, newValue, and attributes namespace.
if (element.is_custom()) {
@ -105,13 +109,13 @@ void Attr::handle_attribute_changes(Element& element, DeprecatedString const& ol
arguments.append(JS::PrimitiveString::create(vm, local_name()));
arguments.append(old_value.is_null() ? JS::js_null() : JS::PrimitiveString::create(vm, old_value));
arguments.append(new_value.is_null() ? JS::js_null() : JS::PrimitiveString::create(vm, new_value));
arguments.append(namespace_uri().is_null() ? JS::js_null() : JS::PrimitiveString::create(vm, namespace_uri()));
arguments.append(!namespace_uri().has_value() ? JS::js_null() : JS::PrimitiveString::create(vm, namespace_uri().value()));
element.enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::attributeChangedCallback, move(arguments));
}
// 3. Run the attribute change steps with element, attributes local name, oldValue, newValue, and attributes namespace.
element.run_attribute_change_steps(local_name(), old_value, new_value, namespace_uri());
element.run_attribute_change_steps(local_name().to_deprecated_fly_string(), old_value, new_value, deprecated_namespace_uri);
}
}

View file

@ -18,22 +18,22 @@ class Attr final : public Node {
WEB_PLATFORM_OBJECT(Attr, Node);
public:
[[nodiscard]] static JS::NonnullGCPtr<Attr> create(Document&, QualifiedName, DeprecatedString value = "", Element* = nullptr);
[[nodiscard]] static JS::NonnullGCPtr<Attr> create(Document&, DeprecatedFlyString local_name, DeprecatedString value = "", Element* = nullptr);
[[nodiscard]] static JS::NonnullGCPtr<Attr> create(Document&, QualifiedName, String value = {}, Element* = nullptr);
[[nodiscard]] static JS::NonnullGCPtr<Attr> create(Document&, FlyString local_name, String value = {}, Element* = nullptr);
JS::NonnullGCPtr<Attr> clone(Document&);
virtual ~Attr() override = default;
virtual FlyString node_name() const override { return MUST(FlyString::from_deprecated_fly_string(name())); }
virtual FlyString node_name() const override { return name(); }
DeprecatedFlyString const& namespace_uri() const { return m_qualified_name.namespace_(); }
DeprecatedFlyString const& prefix() const { return m_qualified_name.prefix(); }
DeprecatedFlyString const& local_name() const { return m_qualified_name.local_name(); }
DeprecatedFlyString const& name() const { return m_qualified_name.as_string(); }
Optional<FlyString> const& namespace_uri() const { return m_qualified_name.namespace_(); }
Optional<FlyString> const& prefix() const { return m_qualified_name.prefix(); }
FlyString const& local_name() const { return m_qualified_name.local_name(); }
FlyString const& name() const { return m_qualified_name.as_string(); }
DeprecatedString const& value() const { return m_value; }
void set_value(DeprecatedString value);
void change_attribute(DeprecatedString value);
String const& value() const { return m_value; }
void set_value(String value);
void change_attribute(String value);
Element* owner_element();
Element const* owner_element() const;
@ -45,13 +45,13 @@ public:
void handle_attribute_changes(Element&, DeprecatedString const& old_value, DeprecatedString const& new_value);
private:
Attr(Document&, QualifiedName, DeprecatedString value, Element*);
Attr(Document&, QualifiedName, String value, Element*);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
QualifiedName m_qualified_name;
DeprecatedString m_value;
String m_value;
JS::GCPtr<Element> m_owner_element;
};

View file

@ -1,7 +1,7 @@
#import <DOM/Node.idl>
#import <DOM/Element.idl>
[Exposed=Window, UseDeprecatedAKString]
[Exposed=Window]
interface Attr : Node {
readonly attribute DOMString? namespaceURI;
readonly attribute DOMString? prefix;

View file

@ -1387,7 +1387,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> Document::create_element_ns(Optio
}
// 4. Return the result of creating an element given document, localName, namespace, prefix, is, and with the synchronous custom elements flag set.
return TRY(DOM::create_element(*this, extracted_qualified_name.local_name(), extracted_qualified_name.namespace_(), extracted_qualified_name.prefix(), move(is_value), true));
return TRY(DOM::create_element(*this, extracted_qualified_name.local_name().to_deprecated_fly_string(), extracted_qualified_name.deprecated_namespace_(), extracted_qualified_name.deprecated_prefix(), move(is_value), true));
}
JS::NonnullGCPtr<DocumentFragment> Document::create_document_fragment()
@ -2963,7 +2963,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Attr>> Document::create_attribute(String co
// 2. If this is an HTML document, then set localName to localName in ASCII lowercase.
// 3. Return a new attribute whose local name is localName and node document is this.
auto deprecated_local_name = local_name.to_deprecated_string();
return Attr::create(*this, is_html_document() ? deprecated_local_name.to_lowercase() : deprecated_local_name);
return Attr::create(*this, MUST(FlyString::from_deprecated_fly_string(is_html_document() ? deprecated_local_name.to_lowercase() : deprecated_local_name)));
}
// https://dom.spec.whatwg.org/#dom-document-createattributens

View file

@ -141,7 +141,7 @@ DeprecatedString Element::get_attribute(DeprecatedFlyString const& name) const
return {};
// 3. Return attrs value.
return attribute->value();
return attribute->value().to_deprecated_string();
}
// https://dom.spec.whatwg.org/#concept-element-attributes-get-value
@ -155,7 +155,7 @@ DeprecatedString Element::get_attribute_value(DeprecatedFlyString const& local_n
return DeprecatedString::empty();
// 3. Return attrs value.
return attribute->value();
return attribute->value().to_deprecated_string();
}
// https://dom.spec.whatwg.org/#dom-element-getattributenode
@ -183,14 +183,14 @@ WebIDL::ExceptionOr<void> Element::set_attribute(DeprecatedFlyString const& name
// 4. If attribute is null, create an attribute whose local name is qualifiedName, value is value, and node document
// is thiss node document, then append this attribute to this, and then return.
if (!attribute) {
auto new_attribute = Attr::create(document(), insert_as_lowercase ? name.to_lowercase() : name, value);
auto new_attribute = Attr::create(document(), MUST(String::from_deprecated_string(insert_as_lowercase ? name.to_lowercase() : name)), MUST(String::from_deprecated_string(value)));
m_attributes->append_attribute(new_attribute);
return {};
}
// 5. Change attribute to value.
attribute->change_attribute(value);
attribute->change_attribute(MUST(String::from_deprecated_string(value)));
return {};
}
@ -243,7 +243,7 @@ WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, Deprec
return WebIDL::NamespaceError::create(realm, "Namespace is the XMLNS namespace and neither qualifiedName nor prefix is 'xmlns'."_fly_string);
// 10. Return namespace, prefix, and localName.
return QualifiedName { local_name, prefix, namespace_ };
return QualifiedName { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, namespace_ };
}
// https://dom.spec.whatwg.org/#dom-element-setattributens
@ -253,7 +253,7 @@ WebIDL::ExceptionOr<void> Element::set_attribute_ns(DeprecatedFlyString const& n
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_, qualified_name));
// 2. Set an attribute value for this using localName, value, and also prefix and namespace.
set_attribute_value(extracted_qualified_name.local_name(), value, extracted_qualified_name.prefix(), extracted_qualified_name.namespace_());
set_attribute_value(extracted_qualified_name.local_name().to_deprecated_fly_string(), value, extracted_qualified_name.deprecated_prefix(), extracted_qualified_name.deprecated_namespace_());
return {};
}
@ -268,16 +268,16 @@ void Element::set_attribute_value(DeprecatedFlyString const& local_name, Depreca
// is localName, value is value, and node document is elements node document, then append this attribute to element,
// and then return.
if (!attribute) {
QualifiedName name { local_name, prefix, namespace_ };
QualifiedName name { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, namespace_ };
auto new_attribute = Attr::create(document(), move(name), value);
auto new_attribute = Attr::create(document(), move(name), MUST(String::from_deprecated_string(value)));
m_attributes->append_attribute(new_attribute);
return;
}
// 3. Change attribute to value.
attribute->change_attribute(value);
attribute->change_attribute(MUST(String::from_deprecated_string(value)));
}
// https://dom.spec.whatwg.org/#dom-element-setattributenode
@ -338,7 +338,7 @@ WebIDL::ExceptionOr<bool> Element::toggle_attribute(DeprecatedFlyString const& n
// 1. If force is not given or is true, create an attribute whose local name is qualifiedName, value is the empty
// string, and node document is thiss node document, then append this attribute to this, and then return true.
if (!force.has_value() || force.value()) {
auto new_attribute = Attr::create(document(), insert_as_lowercase ? name.to_lowercase() : name, "");
auto new_attribute = Attr::create(document(), MUST(String::from_deprecated_string(insert_as_lowercase ? name.to_lowercase() : name)), String {});
m_attributes->append_attribute(new_attribute);
return true;
@ -365,7 +365,7 @@ Vector<DeprecatedString> Element::get_attribute_names() const
Vector<DeprecatedString> names;
for (size_t i = 0; i < m_attributes->length(); ++i) {
auto const* attribute = m_attributes->item(i);
names.append(attribute->name());
names.append(attribute->name().to_deprecated_fly_string());
}
return names;
}
@ -1744,7 +1744,7 @@ JS::ThrowCompletionOr<void> Element::upgrade_element(JS::NonnullGCPtr<HTML::Cust
arguments.append(JS::PrimitiveString::create(vm, attribute->local_name()));
arguments.append(JS::js_null());
arguments.append(JS::PrimitiveString::create(vm, attribute->value()));
arguments.append(JS::PrimitiveString::create(vm, attribute->namespace_uri()));
arguments.append(attribute->namespace_uri().has_value() ? JS::PrimitiveString::create(vm, attribute->namespace_uri().value()) : JS::js_null());
enqueue_a_custom_element_callback_reaction(HTML::CustomElementReactionNames::attributeChangedCallback, move(arguments));
}
@ -1850,14 +1850,14 @@ void Element::setup_custom_element_from_constructor(HTML::CustomElementDefinitio
void Element::set_prefix(DeprecatedFlyString const& value)
{
m_qualified_name.set_prefix(value);
m_qualified_name.set_prefix(MUST(FlyString::from_deprecated_fly_string(value)));
}
void Element::for_each_attribute(Function<void(DeprecatedFlyString const&, DeprecatedString const&)> callback) const
{
for (size_t i = 0; i < m_attributes->length(); ++i) {
auto const* attribute = m_attributes->item(i);
callback(attribute->name(), attribute->value());
callback(attribute->name().to_deprecated_fly_string(), attribute->value().to_deprecated_string());
}
}

View file

@ -74,21 +74,22 @@ class Element
public:
virtual ~Element() override;
DeprecatedFlyString const& qualified_name() const { return m_qualified_name.as_string(); }
DeprecatedFlyString qualified_name() const { return m_qualified_name.as_string().to_deprecated_fly_string(); }
DeprecatedString const& html_uppercased_qualified_name() const { return m_html_uppercased_qualified_name; }
virtual FlyString node_name() const final { return MUST(FlyString::from_deprecated_fly_string(html_uppercased_qualified_name())); }
DeprecatedFlyString const& local_name() const { return m_qualified_name.local_name(); }
DeprecatedFlyString local_name() const { return m_qualified_name.local_name().to_deprecated_fly_string(); }
// NOTE: This is for the JS bindings
DeprecatedString const& tag_name() const { return html_uppercased_qualified_name(); }
DeprecatedFlyString const& prefix() const { return m_qualified_name.prefix(); }
DeprecatedFlyString prefix() const { return m_qualified_name.deprecated_prefix(); }
void set_prefix(DeprecatedFlyString const& value);
DeprecatedFlyString const& namespace_() const { return m_qualified_name.namespace_(); }
DeprecatedFlyString namespace_() const { return m_qualified_name.deprecated_namespace_(); }
// NOTE: This is for the JS bindings
DeprecatedFlyString const& namespace_uri() const { return namespace_(); }
DeprecatedFlyString namespace_uri() const { return namespace_(); }
bool has_attribute(DeprecatedFlyString const& name) const;
bool has_attribute_ns(DeprecatedFlyString namespace_, DeprecatedFlyString const& name) const;

View file

@ -272,7 +272,7 @@ bool is_unknown_html_element(DeprecatedFlyString const& tag_name)
// https://html.spec.whatwg.org/#elements-in-the-dom:element-interface
static JS::NonnullGCPtr<Element> create_html_element(JS::Realm& realm, Document& document, QualifiedName qualified_name)
{
auto lowercase_tag_name = qualified_name.local_name().to_lowercase();
auto lowercase_tag_name = qualified_name.local_name().to_deprecated_fly_string().to_lowercase();
if (lowercase_tag_name == HTML::TagNames::a)
return realm.heap().allocate<HTML::HTMLAnchorElement>(realm, document, move(qualified_name));
@ -426,7 +426,7 @@ static JS::NonnullGCPtr<Element> create_html_element(JS::Realm& realm, Document&
static JS::GCPtr<SVG::SVGElement> create_svg_element(JS::Realm& realm, Document& document, QualifiedName qualified_name)
{
auto const& local_name = qualified_name.local_name();
auto const& local_name = qualified_name.local_name().to_deprecated_fly_string();
if (local_name == SVG::TagNames::svg)
return realm.heap().allocate<SVG::SVGSVGElement>(realm, document, move(qualified_name));
@ -481,7 +481,7 @@ static JS::GCPtr<SVG::SVGElement> create_svg_element(JS::Realm& realm, Document&
static JS::GCPtr<MathML::MathMLElement> create_mathml_element(JS::Realm& realm, Document& document, QualifiedName qualified_name)
{
auto const& local_name = MUST(FlyString::from_deprecated_fly_string(qualified_name.local_name()));
auto const& local_name = qualified_name.local_name();
if (local_name.is_one_of(MathML::TagNames::annotation, MathML::TagNames::annotation_xml, MathML::TagNames::maction, MathML::TagNames::math, MathML::TagNames::merror, MathML::TagNames::mfrac, MathML::TagNames::mi, MathML::TagNames::mmultiscripts, MathML::TagNames::mn, MathML::TagNames::mo, MathML::TagNames::mover, MathML::TagNames::mpadded, MathML::TagNames::mphantom, MathML::TagNames::mprescripts, MathML::TagNames::mroot, MathML::TagNames::mrow, MathML::TagNames::ms, MathML::TagNames::mspace, MathML::TagNames::msqrt, MathML::TagNames::mstyle, MathML::TagNames::msub, MathML::TagNames::msubsup, MathML::TagNames::msup, MathML::TagNames::mtable, MathML::TagNames::mtd, MathML::TagNames::mtext, MathML::TagNames::mtr, MathML::TagNames::munder, MathML::TagNames::munderover, MathML::TagNames::semantics))
return realm.heap().allocate<MathML::MathMLElement>(realm, document, move(qualified_name));
@ -511,7 +511,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element(Document& document
// 2. Set result to a new element that implements interface, with no attributes, namespace set to the HTML namespace,
// namespace prefix set to prefix, local name set to localName, custom element state set to "undefined", custom element definition set to null,
// is value set to is, and node document set to document.
auto element = create_html_element(realm, document, QualifiedName { local_name, prefix, Namespace::HTML });
auto element = create_html_element(realm, document, QualifiedName { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, Namespace::HTML });
// 3. If the synchronous custom elements flag is set, then run this step while catching any exceptions:
if (synchronous_custom_elements_flag) {
@ -596,7 +596,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element(Document& document
// 2. Set result to a new element that implements the HTMLUnknownElement interface, with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix,
// local name set to localName, custom element state set to "failed", custom element definition set to null, is value set to null, and node document set to document.
JS::NonnullGCPtr<Element> element = realm.heap().allocate<HTML::HTMLUnknownElement>(realm, document, QualifiedName { local_name, prefix, Namespace::HTML });
JS::NonnullGCPtr<Element> element = realm.heap().allocate<HTML::HTMLUnknownElement>(realm, document, QualifiedName { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, Namespace::HTML });
element->set_custom_element_state(CustomElementState::Failed);
return element;
}
@ -607,7 +607,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element(Document& document
// 2. Otherwise:
// 1. Set result to a new element that implements the HTMLElement interface, with no attributes, namespace set to the HTML namespace, namespace prefix set to prefix,
// local name set to localName, custom element state set to "undefined", custom element definition set to null, is value set to null, and node document set to document.
auto element = realm.heap().allocate<HTML::HTMLElement>(realm, document, QualifiedName { local_name, prefix, Namespace::HTML });
auto element = realm.heap().allocate<HTML::HTMLElement>(realm, document, QualifiedName { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, Namespace::HTML });
element->set_custom_element_state(CustomElementState::Undefined);
// 2. Enqueue a custom element upgrade reaction given result and definition.
@ -621,7 +621,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element(Document& document
// local name set to localName, custom element state set to "uncustomized", custom element definition set to null, is value set to is,
// and node document set to document.
auto qualified_name = QualifiedName { local_name, prefix, namespace_ };
auto qualified_name = QualifiedName { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, namespace_ };
if (namespace_ == Namespace::HTML) {
auto element = create_html_element(realm, document, move(qualified_name));

View file

@ -53,8 +53,9 @@ Vector<DeprecatedString> NamedNodeMap::supported_property_names() const
names.ensure_capacity(m_attributes.size());
for (auto const& attribute : m_attributes) {
if (!names.contains_slow(attribute->name()))
names.append(attribute->name());
auto const attribute_name = attribute->name().to_deprecated_fly_string();
if (!names.contains_slow(attribute_name))
names.append(attribute_name);
}
// 2. If this NamedNodeMap objects element is in the HTML namespace and its node document is an HTML document, then for each name in names:
@ -193,7 +194,8 @@ Attr const* NamedNodeMap::get_attribute_ns(StringView namespace_, StringView loc
// 2. Return the attribute in elements attribute list whose namespace is namespace and local name is localName, if any; otherwise null.
for (auto const& attribute : m_attributes) {
if (attribute->namespace_uri() == namespace_ && attribute->local_name() == local_name)
// FIXME: This is quite awkard. We should probably be taking an Optional<FlyString> for namespace here.
if ((!attribute->namespace_uri().has_value() == namespace_.is_null() || attribute->namespace_uri() == namespace_) && attribute->local_name() == local_name)
return attribute.ptr();
if (item_index)
++(*item_index);
@ -211,7 +213,11 @@ WebIDL::ExceptionOr<JS::GCPtr<Attr>> NamedNodeMap::set_attribute(Attr& attribute
// 2. Let oldAttr be the result of getting an attribute given attrs namespace, attrs local name, and element.
size_t old_attribute_index = 0;
auto* old_attribute = get_attribute_ns(attribute.namespace_uri(), attribute.local_name(), &old_attribute_index);
DeprecatedString deprecated_namespace_uri;
if (attribute.namespace_uri().has_value())
deprecated_namespace_uri = attribute.namespace_uri().value().to_deprecated_fly_string();
auto* old_attribute = get_attribute_ns(deprecated_namespace_uri, attribute.local_name(), &old_attribute_index);
// 3. If oldAttr is attr, return attr.
if (old_attribute == &attribute)
@ -246,7 +252,7 @@ void NamedNodeMap::replace_attribute(Attr& old_attribute, Attr& new_attribute, s
old_attribute.set_owner_element(nullptr);
// 4. Handle attribute changes for oldAttr with newAttrs element, oldAttrs value, and newAttrs value.
old_attribute.handle_attribute_changes(*new_attribute.owner_element(), old_attribute.value(), new_attribute.value());
old_attribute.handle_attribute_changes(*new_attribute.owner_element(), old_attribute.value().to_deprecated_string(), new_attribute.value().to_deprecated_string());
}
// https://dom.spec.whatwg.org/#concept-element-attributes-append
@ -259,7 +265,7 @@ void NamedNodeMap::append_attribute(Attr& attribute)
attribute.set_owner_element(&associated_element());
// 3. Handle attribute changes for attribute with element, null, and attributes value.
attribute.handle_attribute_changes(associated_element(), {}, attribute.value());
attribute.handle_attribute_changes(associated_element(), {}, attribute.value().to_deprecated_string());
}
// https://dom.spec.whatwg.org/#concept-element-attributes-remove
@ -278,7 +284,7 @@ void NamedNodeMap::remove_attribute_at_index(size_t attribute_index)
attribute->set_owner_element(nullptr);
// 4. Handle attribute changes for attribute with element, attributes value, and null.
attribute->handle_attribute_changes(*element, attribute->value(), {});
attribute->handle_attribute_changes(*element, attribute->value().to_deprecated_string(), {});
}
// https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name

View file

@ -166,7 +166,7 @@ Optional<String> Node::text_content() const
// If Attr node, return this's value.
if (is<Attr>(*this))
return MUST(String::from_deprecated_string(static_cast<Attr const&>(*this).value()));
return static_cast<Attr const&>(*this).value();
// Otherwise, return null
return {};
@ -196,7 +196,7 @@ void Node::set_text_content(Optional<String> const& maybe_content)
// If Attr, set an existing attribute value with this and the given value.
if (is<Attr>(*this)) {
static_cast<Attr&>(*this).set_value(content);
static_cast<Attr&>(*this).set_value(MUST(String::from_deprecated_string(content)));
}
// Otherwise, do nothing.
@ -212,7 +212,7 @@ Optional<String> Node::node_value() const
// If Attr, return thiss value.
if (is<Attr>(this)) {
return MUST(String::from_deprecated_string(verify_cast<Attr>(this)->value()));
return verify_cast<Attr>(this)->value();
}
// If CharacterData, return thiss data.
@ -233,7 +233,7 @@ void Node::set_node_value(Optional<String> const& maybe_value)
// If Attr, set an existing attribute value with this and the given value.
if (is<Attr>(this)) {
verify_cast<Attr>(this)->set_value(value.to_deprecated_string());
verify_cast<Attr>(this)->set_value(move(value));
} else if (is<CharacterData>(this)) {
// If CharacterData, replace data with node this, offset 0, count thiss length, and data the given value.
verify_cast<CharacterData>(this)->set_data(value);

View file

@ -9,10 +9,20 @@
namespace Web::DOM {
static unsigned hash_impl(FlyString const& local_name, Optional<FlyString> const& prefix, Optional<FlyString> const& namespace_)
{
unsigned hash = local_name.hash();
if (prefix.has_value())
hash = pair_int_hash(hash, prefix->hash());
if (namespace_.has_value())
hash = pair_int_hash(hash, namespace_->hash());
return hash;
}
struct ImplTraits : public Traits<QualifiedName::Impl*> {
static unsigned hash(QualifiedName::Impl* impl)
{
return pair_int_hash(impl->local_name.hash(), pair_int_hash(impl->prefix.hash(), impl->namespace_.hash()));
return hash_impl(impl->local_name, impl->prefix, impl->namespace_);
}
static bool equals(QualifiedName::Impl* a, QualifiedName::Impl* b)
@ -25,9 +35,10 @@ struct ImplTraits : public Traits<QualifiedName::Impl*> {
static HashTable<QualifiedName::Impl*, ImplTraits> impls;
static NonnullRefPtr<QualifiedName::Impl> ensure_impl(DeprecatedFlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_)
static NonnullRefPtr<QualifiedName::Impl> ensure_impl(FlyString const& local_name, Optional<FlyString> const& prefix, Optional<FlyString> const& namespace_)
{
auto hash = pair_int_hash(local_name.hash(), pair_int_hash(prefix.hash(), namespace_.hash()));
unsigned hash = hash_impl(local_name, prefix, namespace_);
auto it = impls.find(hash, [&](QualifiedName::Impl* entry) {
return entry->local_name == local_name
&& entry->prefix == prefix
@ -38,12 +49,17 @@ static NonnullRefPtr<QualifiedName::Impl> ensure_impl(DeprecatedFlyString const&
return adopt_ref(*new QualifiedName::Impl(local_name, prefix, namespace_));
}
QualifiedName::QualifiedName(DeprecatedFlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_)
QualifiedName::QualifiedName(FlyString const& local_name, Optional<FlyString> const& prefix, Optional<FlyString> const& namespace_)
: m_impl(ensure_impl(local_name, prefix, namespace_))
{
}
QualifiedName::Impl::Impl(DeprecatedFlyString const& a_local_name, DeprecatedFlyString const& a_prefix, DeprecatedFlyString const& a_namespace)
QualifiedName::QualifiedName(FlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_)
: QualifiedName(local_name, prefix.is_null() ? Optional<FlyString> {} : MUST(FlyString::from_deprecated_fly_string(prefix)), namespace_.is_null() ? Optional<FlyString> {} : MUST(FlyString::from_deprecated_fly_string(namespace_)))
{
}
QualifiedName::Impl::Impl(FlyString const& a_local_name, Optional<FlyString> const& a_prefix, Optional<FlyString> const& a_namespace)
: local_name(a_local_name)
, prefix(a_prefix)
, namespace_(a_namespace)
@ -62,17 +78,17 @@ QualifiedName::Impl::~Impl()
void QualifiedName::Impl::make_internal_string()
{
// This is possible to do according to the spec: "User agents could have this as an internal slot as an optimization."
if (prefix.is_null()) {
if (!prefix.has_value()) {
as_string = local_name;
return;
}
as_string = DeprecatedString::formatted("{}:{}", prefix, local_name);
as_string = MUST(String::formatted("{}:{}", prefix.value(), local_name));
}
void QualifiedName::set_prefix(DeprecatedFlyString const& value)
void QualifiedName::set_prefix(Optional<FlyString> value)
{
m_impl->prefix = value;
m_impl->prefix = move(value);
}
}

View file

@ -8,31 +8,48 @@
#pragma once
#include <AK/DeprecatedFlyString.h>
#include <AK/FlyString.h>
#include <AK/Optional.h>
namespace Web::DOM {
class QualifiedName {
public:
QualifiedName(DeprecatedFlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_);
QualifiedName(FlyString const& local_name, Optional<FlyString> const& prefix, Optional<FlyString> const& namespace_);
QualifiedName(FlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_);
DeprecatedFlyString const& local_name() const { return m_impl->local_name; }
DeprecatedFlyString const& prefix() const { return m_impl->prefix; }
DeprecatedFlyString const& namespace_() const { return m_impl->namespace_; }
FlyString const& local_name() const { return m_impl->local_name; }
Optional<FlyString> const& prefix() const { return m_impl->prefix; }
Optional<FlyString> const& namespace_() const { return m_impl->namespace_; }
DeprecatedFlyString const& as_string() const { return m_impl->as_string; }
DeprecatedFlyString deprecated_prefix() const
{
if (!m_impl->prefix.has_value())
return {};
return m_impl->prefix->to_deprecated_fly_string();
}
DeprecatedFlyString deprecated_namespace_() const
{
if (!m_impl->namespace_.has_value())
return {};
return m_impl->namespace_->to_deprecated_fly_string();
}
FlyString const& as_string() const { return m_impl->as_string; }
struct Impl : public RefCounted<Impl> {
Impl(DeprecatedFlyString const& local_name, DeprecatedFlyString const& prefix, DeprecatedFlyString const& namespace_);
Impl(FlyString const& local_name, Optional<FlyString> const& prefix, Optional<FlyString> const& namespace_);
~Impl();
void make_internal_string();
DeprecatedFlyString local_name;
DeprecatedFlyString prefix;
DeprecatedFlyString namespace_;
DeprecatedFlyString as_string;
FlyString local_name;
Optional<FlyString> prefix;
Optional<FlyString> namespace_;
FlyString as_string;
};
void set_prefix(DeprecatedFlyString const& value);
void set_prefix(Optional<FlyString> value);
private:
NonnullRefPtr<Impl> m_impl;