Quellcode durchsuchen

LibWeb: Generate MathML Elements

We will now generate MathML elements when parsing HTML.
Jonah vor 2 Jahren
Ursprung
Commit
442602bec8

+ 2 - 0
Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp

@@ -36,6 +36,7 @@
 #include <LibWeb/HTML/TagNames.h>
 #include <LibWeb/HTML/Window.h>
 #include <LibWeb/HTML/WindowProxy.h>
+#include <LibWeb/MathML/TagNames.h>
 #include <LibWeb/Namespace.h>
 #include <LibWeb/NavigationTiming/EntryNames.h>
 #include <LibWeb/PerformanceTimeline/EntryTypes.h>
@@ -87,6 +88,7 @@ ErrorOr<void> initialize_main_thread_vm()
     HTML::CustomElementReactionNames::initialize_strings();
     HTML::EventNames::initialize_strings();
     HTML::TagNames::initialize_strings();
+    MathML::TagNames::initialize_strings();
     Namespace::initialize_strings();
     NavigationTiming::EntryNames::initialize_strings();
     PerformanceTimeline::EntryTypes::initialize_strings();

+ 1 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -451,6 +451,7 @@ set(SOURCES
     Loader/Resource.cpp
     Loader/ResourceLoader.cpp
     MathML/MathMLElement.cpp
+    MathML/TagNames.cpp
     MimeSniff/MimeType.cpp
     Namespace.cpp
     NavigationTiming/EntryNames.cpp

+ 20 - 0
Userland/Libraries/LibWeb/DOM/ElementFactory.cpp

@@ -81,6 +81,8 @@
 #include <LibWeb/HTML/HTMLUnknownElement.h>
 #include <LibWeb/HTML/HTMLVideoElement.h>
 #include <LibWeb/HTML/Scripting/ExceptionReporter.h>
+#include <LibWeb/MathML/MathMLElement.h>
+#include <LibWeb/MathML/TagNames.h>
 #include <LibWeb/Namespace.h>
 #include <LibWeb/SVG/SVGCircleElement.h>
 #include <LibWeb/SVG/SVGClipPathElement.h>
@@ -477,6 +479,15 @@ static WebIDL::ExceptionOr<JS::GCPtr<SVG::SVGElement>> create_svg_element(JS::Re
     return nullptr;
 }
 
+static WebIDL::ExceptionOr<JS::GCPtr<MathML::MathMLElement>> create_mathml_element(JS::Realm& realm, Document& document, QualifiedName qualified_name)
+{
+    auto const& local_name = TRY_OR_THROW_OOM(realm.vm(), FlyString::from_deprecated_fly_string(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 MUST_OR_THROW_OOM(realm.heap().allocate<MathML::MathMLElement>(realm, document, move(qualified_name)));
+
+    return nullptr;
+}
 // https://dom.spec.whatwg.org/#concept-create-element
 WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element(Document& document, DeprecatedFlyString local_name, DeprecatedFlyString namespace_, DeprecatedFlyString prefix, Optional<String> is_value, bool synchronous_custom_elements_flag)
 {
@@ -634,6 +645,15 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element(Document& document
         }
     }
 
+    if (namespace_ == Namespace::MathML) {
+        auto element = TRY(create_mathml_element(realm, document, qualified_name));
+        if (element) {
+            element->set_is_value(move(is_value));
+            element->set_custom_element_state(CustomElementState::Uncustomized);
+            return JS::NonnullGCPtr<Element> { *element };
+        }
+    }
+
     // 8. Return result.
     // NOTE: See step 3.
 

+ 7 - 1
Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp

@@ -1430,6 +1430,7 @@ HTMLParser::AdoptionAgencyAlgorithmOutcome HTMLParser::run_the_adoption_agency_a
     }
 }
 
+// https://html.spec.whatwg.org/multipage/parsing.html#special
 bool HTMLParser::is_special_tag(DeprecatedFlyString const& tag_name, DeprecatedFlyString const& namespace_)
 {
     if (namespace_ == Namespace::HTML) {
@@ -1522,7 +1523,12 @@ bool HTMLParser::is_special_tag(DeprecatedFlyString const& tag_name, DeprecatedF
             SVG::TagNames::foreignObject,
             SVG::TagNames::title);
     } else if (namespace_ == Namespace::MathML) {
-        TODO();
+        return tag_name.is_one_of(
+            MathML::TagNames::mi,
+            MathML::TagNames::mo,
+            MathML::TagNames::mn,
+            MathML::TagNames::mtext,
+            MathML::TagNames::annotation_xml);
     }
 
     return false;

+ 9 - 0
Userland/Libraries/LibWeb/MathML/MathMLElement.cpp

@@ -6,6 +6,7 @@
 
 #include <LibWeb/Bindings/ExceptionOrUtils.h>
 #include <LibWeb/MathML/MathMLElement.h>
+#include <LibWeb/MathML/TagNames.h>
 
 namespace Web::MathML {
 
@@ -24,4 +25,12 @@ void MathMLElement::initialize(JS::Realm& realm)
     m_dataset = MUST(HTML::DOMStringMap::create(*this));
 }
 
+Optional<ARIA::Role> MathMLElement::default_role() const
+{
+    // https://www.w3.org/TR/html-aria/#el-math
+    if (local_name() == TagNames::math.to_deprecated_fly_string())
+        return ARIA::Role::math;
+    return {};
+}
+
 }

+ 2 - 0
Userland/Libraries/LibWeb/MathML/MathMLElement.h

@@ -22,6 +22,8 @@ public:
     HTML::DOMStringMap* dataset() { return m_dataset.ptr(); }
     HTML::DOMStringMap const* dataset() const { return m_dataset.ptr(); }
 
+    virtual Optional<ARIA::Role> default_role() const override;
+
 protected:
     virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; }
 

+ 30 - 0
Userland/Libraries/LibWeb/MathML/TagNames.cpp

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, Jonah Shafran <jonahshafran@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/String.h>
+#include <LibWeb/MathML/TagNames.h>
+
+namespace Web::MathML::TagNames {
+
+#define __ENUMERATE_MATHML_TAG(name) FlyString name;
+ENUMERATE_MATHML_TAGS
+#undef __ENUMERATE_MATHML_TAG
+FlyString annotation_xml;
+
+void initialize_strings()
+{
+    static bool s_initialized = false;
+    VERIFY(!s_initialized);
+
+#define __ENUMERATE_MATHML_TAG(name) name = #name##_fly_string;
+    ENUMERATE_MATHML_TAGS
+#undef __ENUMERATE_MATHML_TAG
+    annotation_xml = "annotation-xml"_fly_string;
+
+    s_initialized = true;
+}
+
+}

+ 52 - 0
Userland/Libraries/LibWeb/MathML/TagNames.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2023, Jonah Shafran <jonahshafran@gmail.com>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/FlyString.h>
+
+namespace Web::MathML::TagNames {
+
+#define ENUMERATE_MATHML_TAGS             \
+    __ENUMERATE_MATHML_TAG(annotation)    \
+    __ENUMERATE_MATHML_TAG(maction)       \
+    __ENUMERATE_MATHML_TAG(math)          \
+    __ENUMERATE_MATHML_TAG(merror)        \
+    __ENUMERATE_MATHML_TAG(mfrac)         \
+    __ENUMERATE_MATHML_TAG(mi)            \
+    __ENUMERATE_MATHML_TAG(mmultiscripts) \
+    __ENUMERATE_MATHML_TAG(mn)            \
+    __ENUMERATE_MATHML_TAG(mo)            \
+    __ENUMERATE_MATHML_TAG(mover)         \
+    __ENUMERATE_MATHML_TAG(mpadded)       \
+    __ENUMERATE_MATHML_TAG(mphantom)      \
+    __ENUMERATE_MATHML_TAG(mprescripts)   \
+    __ENUMERATE_MATHML_TAG(mroot)         \
+    __ENUMERATE_MATHML_TAG(mrow)          \
+    __ENUMERATE_MATHML_TAG(ms)            \
+    __ENUMERATE_MATHML_TAG(mspace)        \
+    __ENUMERATE_MATHML_TAG(msqrt)         \
+    __ENUMERATE_MATHML_TAG(mstyle)        \
+    __ENUMERATE_MATHML_TAG(msub)          \
+    __ENUMERATE_MATHML_TAG(msubsup)       \
+    __ENUMERATE_MATHML_TAG(msup)          \
+    __ENUMERATE_MATHML_TAG(mtable)        \
+    __ENUMERATE_MATHML_TAG(mtd)           \
+    __ENUMERATE_MATHML_TAG(mtext)         \
+    __ENUMERATE_MATHML_TAG(mtr)           \
+    __ENUMERATE_MATHML_TAG(munder)        \
+    __ENUMERATE_MATHML_TAG(munderover)    \
+    __ENUMERATE_MATHML_TAG(semantics)
+
+#define __ENUMERATE_MATHML_TAG(name) extern FlyString name;
+ENUMERATE_MATHML_TAGS
+#undef __ENUMERATE_MATHML_TAG
+
+extern FlyString annotation_xml;
+
+void initialize_strings();
+
+}