From 5a796629c61221261c1856e19dd829973e6158f0 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Wed, 24 Jul 2024 23:55:15 +0100 Subject: [PATCH] LibWeb: Make `document.createElementNS()` case-sensitive Previously, when creating a HTML element with `document.createElementNS()` we would convert the given local name to lowercase before deciding which element type to return. We now no longer perform this lower case conversion, so if an uppercase local name is provided, an element of type `HTMLUnknownElement` will be returned. This aligns our implementation with the specification. --- .../Document-createElementNS-uppercase.txt | 4 + .../Document-createElementNS-uppercase.html | 16 ++ .../Libraries/LibWeb/DOM/ElementFactory.cpp | 142 +++++++++--------- 3 files changed, 91 insertions(+), 71 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/DOM/Document-createElementNS-uppercase.txt create mode 100644 Tests/LibWeb/Text/input/DOM/Document-createElementNS-uppercase.html diff --git a/Tests/LibWeb/Text/expected/DOM/Document-createElementNS-uppercase.txt b/Tests/LibWeb/Text/expected/DOM/Document-createElementNS-uppercase.txt new file mode 100644 index 00000000000..2f847259e37 --- /dev/null +++ b/Tests/LibWeb/Text/expected/DOM/Document-createElementNS-uppercase.txt @@ -0,0 +1,4 @@ +document.createElementNS(HTMLNS, "DIV") is instance of HTMLUnknownElement: true +document.createElementNS(HTMLNS, "div") is instance of HTMLDivElement: true +document.createElement("DIV") is instance of HTMLDivElement: true +document.createElement("div") is instance of HTMLDivElement: true diff --git a/Tests/LibWeb/Text/input/DOM/Document-createElementNS-uppercase.html b/Tests/LibWeb/Text/input/DOM/Document-createElementNS-uppercase.html new file mode 100644 index 00000000000..a9b5cb1ff10 --- /dev/null +++ b/Tests/LibWeb/Text/input/DOM/Document-createElementNS-uppercase.html @@ -0,0 +1,16 @@ + + + diff --git a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp index e10cc9c4ca2..aed7fd79a66 100644 --- a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp +++ b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp @@ -276,148 +276,148 @@ bool is_unknown_html_element(FlyString const& tag_name) // https://html.spec.whatwg.org/#elements-in-the-dom:element-interface static JS::NonnullGCPtr create_html_element(JS::Realm& realm, Document& document, QualifiedName qualified_name) { - FlyString lowercase_tag_name = MUST(Infra::to_ascii_lowercase(qualified_name.local_name())); + FlyString tag_name = qualified_name.local_name(); - if (lowercase_tag_name == HTML::TagNames::a) + if (tag_name == HTML::TagNames::a) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::area) + if (tag_name == HTML::TagNames::area) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::audio) + if (tag_name == HTML::TagNames::audio) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::base) + if (tag_name == HTML::TagNames::base) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::body) + if (tag_name == HTML::TagNames::body) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::br) + if (tag_name == HTML::TagNames::br) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::button) + if (tag_name == HTML::TagNames::button) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::canvas) + if (tag_name == HTML::TagNames::canvas) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::data) + if (tag_name == HTML::TagNames::data) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::datalist) + if (tag_name == HTML::TagNames::datalist) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::details) + if (tag_name == HTML::TagNames::details) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::dialog) + if (tag_name == HTML::TagNames::dialog) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::dir) + if (tag_name == HTML::TagNames::dir) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::div) + if (tag_name == HTML::TagNames::div) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::dl) + if (tag_name == HTML::TagNames::dl) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::embed) + if (tag_name == HTML::TagNames::embed) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::fieldset) + if (tag_name == HTML::TagNames::fieldset) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::font) + if (tag_name == HTML::TagNames::font) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::form) + if (tag_name == HTML::TagNames::form) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::frame) + if (tag_name == HTML::TagNames::frame) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::frameset) + if (tag_name == HTML::TagNames::frameset) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::head) + if (tag_name == HTML::TagNames::head) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of(HTML::TagNames::h1, HTML::TagNames::h2, HTML::TagNames::h3, HTML::TagNames::h4, HTML::TagNames::h5, HTML::TagNames::h6)) + if (tag_name.is_one_of(HTML::TagNames::h1, HTML::TagNames::h2, HTML::TagNames::h3, HTML::TagNames::h4, HTML::TagNames::h5, HTML::TagNames::h6)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::hr) + if (tag_name == HTML::TagNames::hr) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::html) + if (tag_name == HTML::TagNames::html) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::iframe) + if (tag_name == HTML::TagNames::iframe) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::img) + if (tag_name == HTML::TagNames::img) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::input) + if (tag_name == HTML::TagNames::input) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::label) + if (tag_name == HTML::TagNames::label) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::legend) + if (tag_name == HTML::TagNames::legend) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::li) + if (tag_name == HTML::TagNames::li) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::link) + if (tag_name == HTML::TagNames::link) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::map) + if (tag_name == HTML::TagNames::map) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::marquee) + if (tag_name == HTML::TagNames::marquee) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::menu) + if (tag_name == HTML::TagNames::menu) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::meta) + if (tag_name == HTML::TagNames::meta) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::meter) + if (tag_name == HTML::TagNames::meter) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of(HTML::TagNames::ins, HTML::TagNames::del)) + if (tag_name.is_one_of(HTML::TagNames::ins, HTML::TagNames::del)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::object) + if (tag_name == HTML::TagNames::object) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::ol) + if (tag_name == HTML::TagNames::ol) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::optgroup) + if (tag_name == HTML::TagNames::optgroup) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::option) + if (tag_name == HTML::TagNames::option) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::output) + if (tag_name == HTML::TagNames::output) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::p) + if (tag_name == HTML::TagNames::p) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::param) + if (tag_name == HTML::TagNames::param) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::picture) + if (tag_name == HTML::TagNames::picture) return realm.heap().allocate(realm, document, move(qualified_name)); // NOTE: The obsolete elements "listing" and "xmp" are explicitly mapped to HTMLPreElement in the specification. - if (lowercase_tag_name.is_one_of(HTML::TagNames::pre, HTML::TagNames::listing, HTML::TagNames::xmp)) + if (tag_name.is_one_of(HTML::TagNames::pre, HTML::TagNames::listing, HTML::TagNames::xmp)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::progress) + if (tag_name == HTML::TagNames::progress) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of(HTML::TagNames::blockquote, HTML::TagNames::q)) + if (tag_name.is_one_of(HTML::TagNames::blockquote, HTML::TagNames::q)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::script) + if (tag_name == HTML::TagNames::script) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::select) + if (tag_name == HTML::TagNames::select) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::slot) + if (tag_name == HTML::TagNames::slot) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::source) + if (tag_name == HTML::TagNames::source) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::span) + if (tag_name == HTML::TagNames::span) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::style) + if (tag_name == HTML::TagNames::style) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::summary) + if (tag_name == HTML::TagNames::summary) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::caption) + if (tag_name == HTML::TagNames::caption) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of(Web::HTML::TagNames::td, Web::HTML::TagNames::th)) + if (tag_name.is_one_of(Web::HTML::TagNames::td, Web::HTML::TagNames::th)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of(HTML::TagNames::colgroup, HTML::TagNames::col)) + if (tag_name.is_one_of(HTML::TagNames::colgroup, HTML::TagNames::col)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::table) + if (tag_name == HTML::TagNames::table) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::tr) + if (tag_name == HTML::TagNames::tr) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of(HTML::TagNames::tbody, HTML::TagNames::thead, HTML::TagNames::tfoot)) + if (tag_name.is_one_of(HTML::TagNames::tbody, HTML::TagNames::thead, HTML::TagNames::tfoot)) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::template_) + if (tag_name == HTML::TagNames::template_) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::textarea) + if (tag_name == HTML::TagNames::textarea) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::time) + if (tag_name == HTML::TagNames::time) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::title) + if (tag_name == HTML::TagNames::title) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::track) + if (tag_name == HTML::TagNames::track) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::ul) + if (tag_name == HTML::TagNames::ul) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name == HTML::TagNames::video) + if (tag_name == HTML::TagNames::video) return realm.heap().allocate(realm, document, move(qualified_name)); - if (lowercase_tag_name.is_one_of( + if (tag_name.is_one_of( HTML::TagNames::article, HTML::TagNames::section, HTML::TagNames::nav, HTML::TagNames::aside, HTML::TagNames::hgroup, HTML::TagNames::header, HTML::TagNames::footer, HTML::TagNames::address, HTML::TagNames::dt, HTML::TagNames::dd, HTML::TagNames::figure, HTML::TagNames::figcaption, HTML::TagNames::main, HTML::TagNames::em, HTML::TagNames::strong, HTML::TagNames::small, HTML::TagNames::s, HTML::TagNames::cite, HTML::TagNames::dfn, HTML::TagNames::abbr, HTML::TagNames::ruby, HTML::TagNames::rt, HTML::TagNames::rp, HTML::TagNames::code, HTML::TagNames::var, HTML::TagNames::samp, HTML::TagNames::kbd, HTML::TagNames::sub, HTML::TagNames::sup, HTML::TagNames::i, HTML::TagNames::b, HTML::TagNames::u, HTML::TagNames::mark, HTML::TagNames::bdi, HTML::TagNames::bdo, HTML::TagNames::wbr, HTML::TagNames::noscript, // Obsolete HTML::TagNames::acronym, HTML::TagNames::basefont, HTML::TagNames::big, HTML::TagNames::center, HTML::TagNames::nobr, HTML::TagNames::noembed, HTML::TagNames::noframes, HTML::TagNames::plaintext, HTML::TagNames::rb, HTML::TagNames::rtc, HTML::TagNames::strike, HTML::TagNames::tt))