From 19731fc14cb04da7f795b901a722d95e8d33ea43 Mon Sep 17 00:00:00 2001 From: Luke Date: Tue, 4 May 2021 22:25:43 +0100 Subject: [PATCH] LibWeb: Use HTML-uppercased qualified name for the Element node name For regular elements, this is just the qualified name. However, for HTML elements in HTML documents, it is the qualified name uppercased. This is used by jQuery to determine the document is an HTML document. Not having this made jQuery assume the document was XML, causing weird behaviour. To do this, an internal string of qualified name is created. This is to prevent constantly regenerating it. This is allowed by the spec. This is the same for the HTML-uppercased qualified name. --- Userland/Libraries/LibWeb/DOM/Element.cpp | 11 +++++++++++ Userland/Libraries/LibWeb/DOM/Element.h | 7 ++++++- Userland/Libraries/LibWeb/QualifiedName.h | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp index 37cff6ec5f..dae0af495b 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.cpp +++ b/Userland/Libraries/LibWeb/DOM/Element.cpp @@ -34,6 +34,7 @@ Element::Element(Document& document, QualifiedName qualified_name) : ParentNode(document, NodeType::ELEMENT_NODE) , m_qualified_name(move(qualified_name)) { + make_html_uppercased_qualified_name(); } Element::~Element() @@ -359,4 +360,14 @@ NonnullRefPtr Element::style_for_bindings() return *m_inline_style; } +// https://dom.spec.whatwg.org/#element-html-uppercased-qualified-name +void Element::make_html_uppercased_qualified_name() +{ + // This is allowed by the spec: "User agents could optimize qualified name and HTML-uppercased qualified name by storing them in internal slots." + if (namespace_() == Namespace::HTML /* FIXME: and its node document is an HTML document */) + m_html_uppercased_qualified_name = qualified_name().to_uppercase(); + else + m_html_uppercased_qualified_name = qualified_name(); +} + } diff --git a/Userland/Libraries/LibWeb/DOM/Element.h b/Userland/Libraries/LibWeb/DOM/Element.h index 189363a99f..bcf693e6d7 100644 --- a/Userland/Libraries/LibWeb/DOM/Element.h +++ b/Userland/Libraries/LibWeb/DOM/Element.h @@ -29,7 +29,9 @@ public: Element(Document&, QualifiedName); virtual ~Element() override; - virtual FlyString node_name() const final { return m_qualified_name.local_name(); } + const String& qualified_name() const { return m_qualified_name.as_string(); } + String html_uppercased_qualified_name() const { return m_html_uppercased_qualified_name; } + virtual FlyString node_name() const final { return html_uppercased_qualified_name(); } const FlyString& local_name() const { return m_qualified_name.local_name(); } // NOTE: This is for the JS bindings @@ -96,7 +98,10 @@ private: Attribute* find_attribute(const FlyString& name); const Attribute* find_attribute(const FlyString& name) const; + void make_html_uppercased_qualified_name(); + QualifiedName m_qualified_name; + String m_html_uppercased_qualified_name; Vector m_attributes; RefPtr m_inline_style; diff --git a/Userland/Libraries/LibWeb/QualifiedName.h b/Userland/Libraries/LibWeb/QualifiedName.h index c956bc804c..c7c429d2d3 100644 --- a/Userland/Libraries/LibWeb/QualifiedName.h +++ b/Userland/Libraries/LibWeb/QualifiedName.h @@ -17,16 +17,33 @@ public: , m_prefix(prefix) , m_namespace(namespace_) { + make_internal_string(); } const FlyString& local_name() const { return m_local_name; } const FlyString& prefix() const { return m_prefix; } const FlyString& namespace_() const { return m_namespace; } + const String& as_string() const { return m_as_string; } + private: FlyString m_local_name; FlyString m_prefix; FlyString m_namespace; + String m_as_string; + + // https://dom.spec.whatwg.org/#concept-attribute-qualified-name + // https://dom.spec.whatwg.org/#concept-element-qualified-name + void 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 (m_prefix.is_null()) { + m_as_string = m_local_name; + return; + } + + m_as_string = String::formatted("{}:{}", m_prefix, m_local_name); + } }; }