mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-28 19:59:17 +00:00
LibWeb: Update DOMImplementation.createDocumentType()
name validation
This now follows the latest specification steps.
This commit is contained in:
parent
f98312d022
commit
16dbb44de2
Notes:
github-actions[bot]
2025-06-19 11:57:08 +00:00
Author: https://github.com/tcl3
Commit: 16dbb44de2
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5141
Reviewed-by: https://github.com/gmta ✅
Reviewed-by: https://github.com/trflynn89 ✅
6 changed files with 228 additions and 6 deletions
|
@ -137,14 +137,16 @@ GC::Ref<Document> DOMImplementation::create_html_document(Optional<String> const
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype
|
||||
WebIDL::ExceptionOr<GC::Ref<DocumentType>> DOMImplementation::create_document_type(String const& qualified_name, String const& public_id, String const& system_id)
|
||||
WebIDL::ExceptionOr<GC::Ref<DocumentType>> DOMImplementation::create_document_type(String const& name, String const& public_id, String const& system_id)
|
||||
{
|
||||
// 1. Validate qualifiedName.
|
||||
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.
|
||||
// 1. If name is not a valid doctype name, then throw an "InvalidCharacterError" DOMException.
|
||||
if (!is_valid_doctype_name(name))
|
||||
return WebIDL::InvalidCharacterError::create(realm(), "Invalid doctype name"_string);
|
||||
|
||||
// 2. Return a new doctype, with name 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());
|
||||
document_type->set_name(qualified_name);
|
||||
document_type->set_name(name);
|
||||
document_type->set_public_id(public_id);
|
||||
document_type->set_system_id(system_id);
|
||||
return document_type;
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
|
||||
WebIDL::ExceptionOr<GC::Ref<XMLDocument>> create_document(Optional<FlyString> const&, String const&, GC::Ptr<DocumentType>) const;
|
||||
GC::Ref<Document> create_html_document(Optional<String> const& title) const;
|
||||
WebIDL::ExceptionOr<GC::Ref<DocumentType>> create_document_type(String const& qualified_name, String const& public_id, String const& system_id);
|
||||
WebIDL::ExceptionOr<GC::Ref<DocumentType>> create_document_type(String const& name, String const& public_id, String const& system_id);
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-domimplementation-hasfeature
|
||||
bool has_feature() const
|
||||
|
|
|
@ -28,4 +28,12 @@ void DocumentType::initialize(JS::Realm& realm)
|
|||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#valid-doctype-name
|
||||
bool is_valid_doctype_name(String const& name)
|
||||
{
|
||||
// A string is a valid doctype name if it does not contain ASCII whitespace, U+0000 NULL, or U+003E (>).
|
||||
constexpr Array<u32, 7> INVALID_DOCTYPE_CHARACTERS { '\t', '\n', '\f', '\r', ' ', '\0', '>' };
|
||||
return !name.code_points().contains_any_of(INVALID_DOCTYPE_CHARACTERS);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -44,6 +44,8 @@ private:
|
|||
String m_system_id;
|
||||
};
|
||||
|
||||
bool is_valid_doctype_name(String const&);
|
||||
|
||||
template<>
|
||||
inline bool Node::fast_is<DocumentType>() const { return is_document_type(); }
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
Harness status: OK
|
||||
|
||||
Found 82 tests
|
||||
|
||||
82 Pass
|
||||
Pass DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)
|
||||
Pass createDocumentType("", "", "") should work
|
||||
Pass createDocumentType("test:root", "1234", "") should work
|
||||
Pass createDocumentType("test:root", "1234", "test") should work
|
||||
Pass createDocumentType("test:root", "test", "") should work
|
||||
Pass createDocumentType("test:root", "test", "test") should work
|
||||
Pass createDocumentType("_:_", "", "") should work
|
||||
Pass createDocumentType("_:h0", "", "") should work
|
||||
Pass createDocumentType("_:test", "", "") should work
|
||||
Pass createDocumentType("_:_.", "", "") should work
|
||||
Pass createDocumentType("_:a-", "", "") should work
|
||||
Pass createDocumentType("l_:_", "", "") should work
|
||||
Pass createDocumentType("ns:_0", "", "") should work
|
||||
Pass createDocumentType("ns:a0", "", "") should work
|
||||
Pass createDocumentType("ns0:test", "", "") should work
|
||||
Pass createDocumentType("ns:EEE.", "", "") should work
|
||||
Pass createDocumentType("ns:_-", "", "") should work
|
||||
Pass createDocumentType("a.b:c", "", "") should work
|
||||
Pass createDocumentType("a-b:c.j", "", "") should work
|
||||
Pass createDocumentType("a-b:c", "", "") should work
|
||||
Pass createDocumentType("foo", "", "") should work
|
||||
Pass createDocumentType("1foo", "", "") should work
|
||||
Pass createDocumentType("foo1", "", "") should work
|
||||
Pass createDocumentType("f1oo", "", "") should work
|
||||
Pass createDocumentType("@foo", "", "") should work
|
||||
Pass createDocumentType("foo@", "", "") should work
|
||||
Pass createDocumentType("f@oo", "", "") should work
|
||||
Pass createDocumentType("edi:{", "", "") should work
|
||||
Pass createDocumentType("edi:}", "", "") should work
|
||||
Pass createDocumentType("edi:~", "", "") should work
|
||||
Pass createDocumentType("edi:'", "", "") should work
|
||||
Pass createDocumentType("edi:!", "", "") should work
|
||||
Pass createDocumentType("edi:@", "", "") should work
|
||||
Pass createDocumentType("edi:#", "", "") should work
|
||||
Pass createDocumentType("edi:$", "", "") should work
|
||||
Pass createDocumentType("edi:%", "", "") should work
|
||||
Pass createDocumentType("edi:^", "", "") should work
|
||||
Pass createDocumentType("edi:&", "", "") should work
|
||||
Pass createDocumentType("edi:*", "", "") should work
|
||||
Pass createDocumentType("edi:(", "", "") should work
|
||||
Pass createDocumentType("edi:)", "", "") should work
|
||||
Pass createDocumentType("edi:+", "", "") should work
|
||||
Pass createDocumentType("edi:=", "", "") should work
|
||||
Pass createDocumentType("edi:[", "", "") should work
|
||||
Pass createDocumentType("edi:]", "", "") should work
|
||||
Pass createDocumentType("edi:\\", "", "") should work
|
||||
Pass createDocumentType("edi:/", "", "") should work
|
||||
Pass createDocumentType("edi:;", "", "") should work
|
||||
Pass createDocumentType("edi:`", "", "") should work
|
||||
Pass createDocumentType("edi:<", "", "") should work
|
||||
Pass createDocumentType("edi:>", "", "") should throw INVALID_CHARACTER_ERR
|
||||
Pass createDocumentType("edi:,", "", "") should work
|
||||
Pass createDocumentType("edi:a ", "", "") should throw INVALID_CHARACTER_ERR
|
||||
Pass createDocumentType("edi:\"", "", "") should work
|
||||
Pass createDocumentType("{", "", "") should work
|
||||
Pass createDocumentType("}", "", "") should work
|
||||
Pass createDocumentType("'", "", "") should work
|
||||
Pass createDocumentType("~", "", "") should work
|
||||
Pass createDocumentType("`", "", "") should work
|
||||
Pass createDocumentType("@", "", "") should work
|
||||
Pass createDocumentType("#", "", "") should work
|
||||
Pass createDocumentType("$", "", "") should work
|
||||
Pass createDocumentType("%", "", "") should work
|
||||
Pass createDocumentType("^", "", "") should work
|
||||
Pass createDocumentType("&", "", "") should work
|
||||
Pass createDocumentType("*", "", "") should work
|
||||
Pass createDocumentType("(", "", "") should work
|
||||
Pass createDocumentType(")", "", "") should work
|
||||
Pass createDocumentType("f:oo", "", "") should work
|
||||
Pass createDocumentType(":foo", "", "") should work
|
||||
Pass createDocumentType("foo:", "", "") should work
|
||||
Pass createDocumentType("prefix::local", "", "") should work
|
||||
Pass createDocumentType("foo", "foo", "") should work
|
||||
Pass createDocumentType("foo", "", "foo") should work
|
||||
Pass createDocumentType("foo", "f'oo", "") should work
|
||||
Pass createDocumentType("foo", "", "f'oo") should work
|
||||
Pass createDocumentType("foo", "f\"oo", "") should work
|
||||
Pass createDocumentType("foo", "", "f\"oo") should work
|
||||
Pass createDocumentType("foo", "f'o\"o", "") should work
|
||||
Pass createDocumentType("foo", "", "f'o\"o") should work
|
||||
Pass createDocumentType("foo", "foo>", "") should work
|
||||
Pass createDocumentType("foo", "", "foo>") should work
|
|
@ -0,0 +1,123 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>DOMImplementation.createDocumentType(qualifiedName, publicId, systemId)</title>
|
||||
<link rel=help href="https://dom.spec.whatwg.org/#dom-domimplementation-createdocumenttype">
|
||||
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-name">
|
||||
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-publicid">
|
||||
<link rel=help href="https://dom.spec.whatwg.org/#dom-documenttype-systemid">
|
||||
<link rel=help href="https://dom.spec.whatwg.org/#dom-node-ownerdocument">
|
||||
<script src="../../resources/testharness.js"></script>
|
||||
<script src="../../resources/testharnessreport.js"></script>
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
test(function() {
|
||||
var tests = [
|
||||
["", "", "", null],
|
||||
["test:root", "1234", "", null],
|
||||
["test:root", "1234", "test", null],
|
||||
["test:root", "test", "", null],
|
||||
["test:root", "test", "test", null],
|
||||
["_:_", "", "", null],
|
||||
["_:h0", "", "", null],
|
||||
["_:test", "", "", null],
|
||||
["_:_.", "", "", null],
|
||||
["_:a-", "", "", null],
|
||||
["l_:_", "", "", null],
|
||||
["ns:_0", "", "", null],
|
||||
["ns:a0", "", "", null],
|
||||
["ns0:test", "", "", null],
|
||||
["ns:EEE.", "", "", null],
|
||||
["ns:_-", "", "", null],
|
||||
["a.b:c", "", "", null],
|
||||
["a-b:c.j", "", "", null],
|
||||
["a-b:c", "", "", null],
|
||||
["foo", "", "", null],
|
||||
["1foo", "", "", null],
|
||||
["foo1", "", "", null],
|
||||
["f1oo", "", "", null],
|
||||
["@foo", "", "", null],
|
||||
["foo@", "", "", null],
|
||||
["f@oo", "", "", null],
|
||||
["edi:{", "", "", null],
|
||||
["edi:}", "", "", null],
|
||||
["edi:~", "", "", null],
|
||||
["edi:'", "", "", null],
|
||||
["edi:!", "", "", null],
|
||||
["edi:@", "", "", null],
|
||||
["edi:#", "", "", null],
|
||||
["edi:$", "", "", null],
|
||||
["edi:%", "", "", null],
|
||||
["edi:^", "", "", null],
|
||||
["edi:&", "", "", null],
|
||||
["edi:*", "", "", null],
|
||||
["edi:(", "", "", null],
|
||||
["edi:)", "", "", null],
|
||||
["edi:+", "", "", null],
|
||||
["edi:=", "", "", null],
|
||||
["edi:[", "", "", null],
|
||||
["edi:]", "", "", null],
|
||||
["edi:\\", "", "", null],
|
||||
["edi:/", "", "", null],
|
||||
["edi:;", "", "", null],
|
||||
["edi:`", "", "", null],
|
||||
["edi:<", "", "", null],
|
||||
["edi:>", "", "", "INVALID_CHARACTER_ERR"],
|
||||
["edi:,", "", "", null],
|
||||
["edi:a ", "", "", "INVALID_CHARACTER_ERR"],
|
||||
["edi:\"", "", "", null],
|
||||
["{", "", "", null],
|
||||
["}", "", "", null],
|
||||
["'", "", "", null],
|
||||
["~", "", "", null],
|
||||
["`", "", "", null],
|
||||
["@", "", "", null],
|
||||
["#", "", "", null],
|
||||
["$", "", "", null],
|
||||
["%", "", "", null],
|
||||
["^", "", "", null],
|
||||
["&", "", "", null],
|
||||
["*", "", "", null],
|
||||
["(", "", "", null],
|
||||
[")", "", "", null],
|
||||
["f:oo", "", "", null],
|
||||
[":foo", "", "", null],
|
||||
["foo:", "", "", null],
|
||||
["prefix::local", "", "", null],
|
||||
["foo", "foo", "", null],
|
||||
["foo", "", "foo", null],
|
||||
["foo", "f'oo", "", null],
|
||||
["foo", "", "f'oo", null],
|
||||
["foo", 'f"oo', "", null],
|
||||
["foo", "", 'f"oo', null],
|
||||
["foo", "f'o\"o", "", null],
|
||||
["foo", "", "f'o\"o", null],
|
||||
["foo", "foo>", "", null],
|
||||
["foo", "", "foo>", null]
|
||||
]
|
||||
|
||||
var doc = document.implementation.createHTMLDocument("title");
|
||||
var doTest = function(aDocument, aQualifiedName, aPublicId, aSystemId) {
|
||||
var doctype = aDocument.implementation.createDocumentType(aQualifiedName, aPublicId, aSystemId);
|
||||
assert_equals(doctype.name, aQualifiedName, "name")
|
||||
assert_equals(doctype.nodeName, aQualifiedName, "nodeName")
|
||||
assert_equals(doctype.publicId, aPublicId, "publicId")
|
||||
assert_equals(doctype.systemId, aSystemId, "systemId")
|
||||
assert_equals(doctype.ownerDocument, aDocument, "ownerDocument")
|
||||
assert_equals(doctype.nodeValue, null, "nodeValue")
|
||||
}
|
||||
tests.forEach(function(t) {
|
||||
var qualifiedName = t[0], publicId = t[1], systemId = t[2], expected = t[3]
|
||||
test(function() {
|
||||
if (expected) {
|
||||
assert_throws_dom(expected, function() {
|
||||
document.implementation.createDocumentType(qualifiedName, publicId, systemId)
|
||||
})
|
||||
} else {
|
||||
doTest(document, qualifiedName, publicId, systemId);
|
||||
doTest(doc, qualifiedName, publicId, systemId);
|
||||
}
|
||||
}, "createDocumentType(" + format_value(qualifiedName) + ", " + format_value(publicId) + ", " + format_value(systemId) + ") should " +
|
||||
(expected ? "throw " + expected : "work"));
|
||||
});
|
||||
})
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue