From 442602bec861d69d6b4bad64e59247e8b1b94dfd Mon Sep 17 00:00:00 2001 From: Jonah Date: Wed, 5 Jul 2023 20:25:52 -0500 Subject: [PATCH] LibWeb: Generate MathML Elements We will now generate MathML elements when parsing HTML. --- .../LibWeb/Bindings/MainThreadVM.cpp | 2 + Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Libraries/LibWeb/DOM/ElementFactory.cpp | 20 +++++++ .../LibWeb/HTML/Parser/HTMLParser.cpp | 8 ++- .../Libraries/LibWeb/MathML/MathMLElement.cpp | 9 ++++ .../Libraries/LibWeb/MathML/MathMLElement.h | 2 + Userland/Libraries/LibWeb/MathML/TagNames.cpp | 30 +++++++++++ Userland/Libraries/LibWeb/MathML/TagNames.h | 52 +++++++++++++++++++ 8 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 Userland/Libraries/LibWeb/MathML/TagNames.cpp create mode 100644 Userland/Libraries/LibWeb/MathML/TagNames.h diff --git a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp index 0b9c1ce813..bb7895612c 100644 --- a/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp +++ b/Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,7 @@ ErrorOr 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(); diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 26d13ad672..c7305da6ca 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/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 diff --git a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp index 9f522e95d1..017233f915 100644 --- a/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp +++ b/Userland/Libraries/LibWeb/DOM/ElementFactory.cpp @@ -81,6 +81,8 @@ #include #include #include +#include +#include #include #include #include @@ -477,6 +479,15 @@ static WebIDL::ExceptionOr> create_svg_element(JS::Re return nullptr; } +static WebIDL::ExceptionOr> 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(realm, document, move(qualified_name))); + + return nullptr; +} // https://dom.spec.whatwg.org/#concept-create-element WebIDL::ExceptionOr> create_element(Document& document, DeprecatedFlyString local_name, DeprecatedFlyString namespace_, DeprecatedFlyString prefix, Optional is_value, bool synchronous_custom_elements_flag) { @@ -634,6 +645,15 @@ WebIDL::ExceptionOr> 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 }; + } + } + // 8. Return result. // NOTE: See step 3. diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 876a40c881..878d2043bd 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/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; diff --git a/Userland/Libraries/LibWeb/MathML/MathMLElement.cpp b/Userland/Libraries/LibWeb/MathML/MathMLElement.cpp index 039341a0d7..cafa20d34e 100644 --- a/Userland/Libraries/LibWeb/MathML/MathMLElement.cpp +++ b/Userland/Libraries/LibWeb/MathML/MathMLElement.cpp @@ -6,6 +6,7 @@ #include #include +#include namespace Web::MathML { @@ -24,4 +25,12 @@ void MathMLElement::initialize(JS::Realm& realm) m_dataset = MUST(HTML::DOMStringMap::create(*this)); } +Optional 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 {}; +} + } diff --git a/Userland/Libraries/LibWeb/MathML/MathMLElement.h b/Userland/Libraries/LibWeb/MathML/MathMLElement.h index fb076f42ea..d9466a3d04 100644 --- a/Userland/Libraries/LibWeb/MathML/MathMLElement.h +++ b/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 default_role() const override; + protected: virtual DOM::EventTarget& global_event_handlers_to_event_target(FlyString const&) override { return *this; } diff --git a/Userland/Libraries/LibWeb/MathML/TagNames.cpp b/Userland/Libraries/LibWeb/MathML/TagNames.cpp new file mode 100644 index 0000000000..ea15fe326e --- /dev/null +++ b/Userland/Libraries/LibWeb/MathML/TagNames.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023, Jonah Shafran + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +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; +} + +} diff --git a/Userland/Libraries/LibWeb/MathML/TagNames.h b/Userland/Libraries/LibWeb/MathML/TagNames.h new file mode 100644 index 0000000000..771851eaa0 --- /dev/null +++ b/Userland/Libraries/LibWeb/MathML/TagNames.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023, Jonah Shafran + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +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(); + +}