LibWeb: Port validate_and_extract from DeprecatedFlyString

This commit is contained in:
Shannon Booth 2023-11-05 12:37:49 +13:00 committed by Andreas Kling
parent 2f009d983b
commit b337b4370a
5 changed files with 19 additions and 21 deletions

View file

@ -140,7 +140,7 @@ JS::NonnullGCPtr<Document> DOMImplementation::create_html_document(Optional<Stri
WebIDL::ExceptionOr<JS::NonnullGCPtr<DocumentType>> DOMImplementation::create_document_type(String const& qualified_name, String const& public_id, String const& system_id)
{
// 1. Validate qualifiedName.
TRY(Document::validate_qualified_name(realm(), qualified_name.to_deprecated_string()));
TRY(Document::validate_qualified_name(realm(), qualified_name));
// 2. Return a new doctype, with qualifiedName as its name, publicId as its public ID, and systemId as its system ID, and with its node document set to the associated document of this.
auto document_type = DocumentType::create(document());

View file

@ -1374,7 +1374,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> Document::create_element_ns(Optio
namespace_to_use = namespace_.value();
// 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract.
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_to_use, qualified_name.to_deprecated_string()));
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_to_use, qualified_name));
// 2. Let is be null.
Optional<String> is_value;
@ -2270,14 +2270,12 @@ bool Document::is_valid_name(String const& name)
}
// https://dom.spec.whatwg.org/#validate
WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_name(JS::Realm& realm, DeprecatedString const& qualified_name)
WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_name(JS::Realm& realm, FlyString const& qualified_name)
{
if (qualified_name.is_empty())
return WebIDL::InvalidCharacterError::create(realm, "Empty string is not a valid qualified name."_fly_string);
Utf8View utf8view { qualified_name };
if (!utf8view.validate())
return WebIDL::InvalidCharacterError::create(realm, "Invalid qualified name."_fly_string);
auto utf8view = qualified_name.code_points();
Optional<size_t> colon_offset;
@ -2311,12 +2309,12 @@ WebIDL::ExceptionOr<Document::PrefixAndTagName> Document::validate_qualified_nam
if (*colon_offset == 0)
return WebIDL::InvalidCharacterError::create(realm, "Qualified name can't start with colon (:)."_fly_string);
if (*colon_offset >= (qualified_name.length() - 1))
if (*colon_offset >= (qualified_name.bytes_as_string_view().length() - 1))
return WebIDL::InvalidCharacterError::create(realm, "Qualified name can't end with colon (:)."_fly_string);
return Document::PrefixAndTagName {
.prefix = qualified_name.substring_view(0, *colon_offset),
.tag_name = qualified_name.substring_view(*colon_offset + 1),
.prefix = MUST(FlyString::from_utf8(qualified_name.bytes_as_string_view().substring_view(0, *colon_offset))),
.tag_name = MUST(FlyString::from_utf8(qualified_name.bytes_as_string_view().substring_view(*colon_offset + 1))),
};
}
@ -3010,7 +3008,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Attr>> Document::create_attribute_ns(Option
namespace_to_use = namespace_.value();
// 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract.
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_to_use, qualified_name.to_deprecated_string()));
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_to_use, qualified_name));
// 2. Return a new attribute whose namespace is namespace, namespace prefix is prefix, local name is localName, and node document is this.

View file

@ -1,13 +1,13 @@
/*
* Copyright (c) 2018-2023, Andreas Kling <kling@serenityos.org>
* Copyright (c) 2021-2023, Linus Groh <linusg@serenityos.org>
* Copyright (c) 2023, Shannon Booth <shannon@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/DeprecatedFlyString.h>
#include <AK/DeprecatedString.h>
#include <AK/Function.h>
#include <AK/HashMap.h>
@ -408,10 +408,10 @@ public:
static bool is_valid_name(String const&);
struct PrefixAndTagName {
DeprecatedFlyString prefix;
DeprecatedFlyString tag_name;
FlyString prefix;
FlyString tag_name;
};
static WebIDL::ExceptionOr<PrefixAndTagName> validate_qualified_name(JS::Realm&, DeprecatedString const& qualified_name);
static WebIDL::ExceptionOr<PrefixAndTagName> validate_qualified_name(JS::Realm&, FlyString const& qualified_name);
JS::NonnullGCPtr<NodeIterator> create_node_iterator(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);
JS::NonnullGCPtr<TreeWalker> create_tree_walker(Node& root, unsigned what_to_show, JS::GCPtr<NodeFilter>);

View file

@ -206,7 +206,7 @@ WebIDL::ExceptionOr<void> Element::set_attribute(FlyString const& name, String c
}
// https://dom.spec.whatwg.org/#validate-and-extract
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, Optional<FlyString> namespace_, DeprecatedFlyString qualified_name)
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, Optional<FlyString> namespace_, FlyString const& qualified_name)
{
// 1. If namespace is the empty string, then set it to null.
if (namespace_.has_value() && namespace_.value().is_empty())
@ -222,10 +222,10 @@ WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, Option
auto local_name = qualified_name;
// 5. If qualifiedName contains a U+003A (:), then strictly split the string on it and set prefix to the part before and localName to the part after.
if (qualified_name.view().contains(':')) {
auto parts = qualified_name.view().split_view(':');
if (qualified_name.bytes_as_string_view().contains(':')) {
auto parts = qualified_name.bytes_as_string_view().split_view(':');
prefix = MUST(FlyString::from_utf8(parts[0]));
local_name = parts[1];
local_name = MUST(FlyString::from_utf8(parts[1]));
}
// 6. If prefix is non-null and namespace is null, then throw a "NamespaceError" DOMException.
@ -245,7 +245,7 @@ WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, Option
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 { MUST(FlyString::from_deprecated_fly_string(local_name)), prefix, namespace_ };
return QualifiedName { local_name, prefix, namespace_ };
}
// https://dom.spec.whatwg.org/#dom-element-setattributens
@ -257,7 +257,7 @@ WebIDL::ExceptionOr<void> Element::set_attribute_ns(Optional<String> const& name
namespace_to_use = namespace_.value();
// 1. Let namespace, prefix, and localName be the result of passing namespace and qualifiedName to validate and extract.
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_to_use, qualified_name.to_deprecated_fly_string()));
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_to_use, 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.to_deprecated_fly_string(), extracted_qualified_name.prefix(), extracted_qualified_name.namespace_());

View file

@ -434,6 +434,6 @@ private:
template<>
inline bool Node::fast_is<Element>() const { return is_element(); }
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm&, Optional<FlyString> namespace_, DeprecatedFlyString qualified_name);
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm&, Optional<FlyString> namespace_, FlyString const& qualified_name);
}