From 0b2da4f8c65c6c4be903ef17a72175f0f6baf43f Mon Sep 17 00:00:00 2001 From: Jonah Date: Sun, 30 Jul 2023 17:35:10 -0500 Subject: [PATCH] LibWeb: Add the default user agent MathML stylesheet We now apply MathML's default user agent style sheet along with other default styles. This sheet is not mixed in with the other styles in CSS/Default.css because it is a namespaced stylesheet and so has to be its own sheet. --- Meta/CMake/libweb_generators.cmake | 13 ++ .../Userland/Libraries/LibWeb/BUILD.gn | 7 ++ .../css-namespace-tag-name-selector.txt | 38 +++--- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + .../Libraries/LibWeb/CSS/StyleComputer.cpp | 11 ++ .../LibWeb/HTML/Parser/HTMLParser.cpp | 1 + Userland/Libraries/LibWeb/MathML/Default.css | 119 ++++++++++++++++++ 7 files changed, 171 insertions(+), 19 deletions(-) create mode 100644 Userland/Libraries/LibWeb/MathML/Default.css diff --git a/Meta/CMake/libweb_generators.cmake b/Meta/CMake/libweb_generators.cmake index 00889c33c5..4d28dea77d 100644 --- a/Meta/CMake/libweb_generators.cmake +++ b/Meta/CMake/libweb_generators.cmake @@ -89,6 +89,19 @@ function (generate_css_implementation) add_custom_target(generate_QuirksModeStyleSheetSource.cpp DEPENDS CSS/QuirksModeStyleSheetSource.cpp) add_dependencies(all_generated generate_QuirksModeStyleSheetSource.cpp) + add_custom_command( + OUTPUT MathML/MathMLStyleSheetSource.cpp + COMMAND "${CMAKE_COMMAND}" -E make_directory CSS + COMMAND "${LIBWEB_INPUT_FOLDER}/Scripts/GenerateStyleSheetSource.sh" mathml_stylesheet_source "${LIBWEB_INPUT_FOLDER}/MathML/Default.css" > MathML/MathMLStyleSheetSource.cpp.tmp + COMMAND "${CMAKE_COMMAND}" -E copy_if_different MathML/MathMLStyleSheetSource.cpp.tmp MathML/MathMLStyleSheetSource.cpp + COMMAND "${CMAKE_COMMAND}" -E remove MathML/MathMLStyleSheetSource.cpp.tmp + VERBATIM + DEPENDS "${LIBWEB_INPUT_FOLDER}/Scripts/GenerateStyleSheetSource.sh" + MAIN_DEPENDENCY "${LIBWEB_INPUT_FOLDER}/MathML/Default.css" + ) + add_custom_target(generate_MathMLStyleSheetSource.cpp DEPENDS MathML/MathMLStyleSheetSource.cpp) + add_dependencies(all_generated generate_MathMLStyleSheetSource.cpp) + set(CSS_GENERATED_TO_INSTALL "CSS/EasingFunctions.h" "CSS/Enums.h" diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn index db3701b2ff..a1335d70d7 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn @@ -213,6 +213,13 @@ embed_as_string_view("generate_quirks_mode_stylesheet_source") { namespace = "Web::CSS" } +embed_as_string_view("generate_mathml_stylesheet_source") { + input = "MathML/Default.css" + output = "$target_gen_dir/MathML/MathMLStyleSheetSource.cpp" + variable_name = "mathml_stylesheet_source" + namespace = "Web::MathML" +} + source_set("all_generated") { generated_deps = [ ":generate_aria_roles", diff --git a/Tests/LibWeb/Layout/expected/css-namespace-tag-name-selector.txt b/Tests/LibWeb/Layout/expected/css-namespace-tag-name-selector.txt index 0c5b96578f..59c954aa7a 100644 --- a/Tests/LibWeb/Layout/expected/css-namespace-tag-name-selector.txt +++ b/Tests/LibWeb/Layout/expected/css-namespace-tag-name-selector.txt @@ -1,41 +1,41 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline - BlockContainer at (8,8) content-size 784x207.3125 children: not-inline - BlockContainer <(anonymous)> at (8,8) content-size 784x161.65625 children: inline - line 0 width: 413.453125, height: 161.65625, bottom: 161.65625, baseline: 152 + BlockContainer at (8,8) content-size 784x299.65625 children: not-inline + BlockContainer <(anonymous)> at (8,8) content-size 784x152 children: inline + line 0 width: 302, height: 152, bottom: 152, baseline: 152 frag 0 from SVGSVGBox start: 0, length: 0, rect: [9,9 300x150] - frag 1 from TextNode start: 0, length: 1, rect: [310,146 8x17.46875] - " " - frag 2 from TextNode start: 0, length: 5, rect: [320,126 99.453125x43.671875] - "Hello" SVGSVGBox at (9,9) content-size 300x150 [SVG] children: inline InlineNode SVGTextBox at (9,9) content-size 0x0 children: inline TextNode <#text> TextNode <#text> InlineNode - InlineNode - TextNode <#text> + BlockContainer at (9,161) content-size 100x100 children: inline + line 0 width: 99.453125, height: 43.671875, bottom: 43.671875, baseline: 33.828125 + frag 0 from TextNode start: 0, length: 5, rect: [9,161 99.453125x43.671875] + "Hello" TextNode <#text> - BlockContainer
at (9,170.65625) content-size 782x43.65625 children: inline + BlockContainer <(anonymous)> at (8,262) content-size 784x0 children: inline + TextNode <#text> + BlockContainer
at (9,263) content-size 782x43.65625 children: inline line 0 width: 101.453125, height: 43.65625, bottom: 43.65625, baseline: 33.828125 - frag 0 from TextNode start: 0, length: 5, rect: [10,170.65625 99.453125x43.671875] + frag 0 from TextNode start: 0, length: 5, rect: [10,263 99.453125x43.671875] "Hello" InlineNode TextNode <#text> - BlockContainer <(anonymous)> at (8,215.3125) content-size 784x0 children: inline + BlockContainer <(anonymous)> at (8,307.65625) content-size 784x0 children: inline TextNode <#text> PaintableWithLines (Viewport<#document>) [0,0 800x600] PaintableWithLines (BlockContainer) [0,0 800x600] - PaintableWithLines (BlockContainer) [8,8 784x207.3125] - PaintableWithLines (BlockContainer(anonymous)) [8,8 784x161.65625] overflow: [8,8 784x161.671875] + PaintableWithLines (BlockContainer) [8,8 784x299.65625] + PaintableWithLines (BlockContainer(anonymous)) [8,8 784x152] SVGSVGPaintable (SVGSVGBox) [8,8 302x152] - TextPaintable (TextNode<#text>) InlinePaintable (InlineNode) - InlinePaintable (InlineNode) - TextPaintable (TextNode<#text>) - PaintableWithLines (BlockContainer
) [8,169.65625 784x45.65625] overflow: [9,170.65625 782x43.671875] + PaintableWithLines (BlockContainer) [8,160 102x102] + TextPaintable (TextNode<#text>) + PaintableWithLines (BlockContainer(anonymous)) [8,262 784x0] + PaintableWithLines (BlockContainer
) [8,262 784x45.65625] overflow: [9,263 782x43.671875] InlinePaintable (InlineNode) TextPaintable (TextNode<#text>) - PaintableWithLines (BlockContainer(anonymous)) [8,215.3125 784x0] + PaintableWithLines (BlockContainer(anonymous)) [8,307.65625 784x0] diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index c7305da6ca..f4d0066e4f 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -633,6 +633,7 @@ set(GENERATED_SOURCES CSS/QuirksModeStyleSheetSource.cpp CSS/TransformFunctions.cpp CSS/ValueID.cpp + MathML/MathMLStyleSheetSource.cpp ) serenity_lib(LibWeb web) diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index ea9955fc1a..b812212777 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -195,6 +195,16 @@ static CSSStyleSheet& quirks_mode_stylesheet(DOM::Document const& document) return *sheet; } +static CSSStyleSheet& mathml_stylesheet(DOM::Document const& document) +{ + static JS::Handle sheet; + if (!sheet.cell()) { + extern StringView mathml_stylesheet_source; + sheet = JS::make_handle(parse_css_stylesheet(CSS::Parser::ParsingContext(document), mathml_stylesheet_source)); + } + return *sheet; +} + template void StyleComputer::for_each_stylesheet(CascadeOrigin cascade_origin, Callback callback) const { @@ -202,6 +212,7 @@ void StyleComputer::for_each_stylesheet(CascadeOrigin cascade_origin, Callback c callback(default_stylesheet(document())); if (document().in_quirks_mode()) callback(quirks_mode_stylesheet(document())); + callback(mathml_stylesheet(document())); } if (cascade_origin == CascadeOrigin::Author) { for (auto const& sheet : document().style_sheets().sheets()) diff --git a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp index 878d2043bd..6578a7c9e4 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/HTMLParser.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include diff --git a/Userland/Libraries/LibWeb/MathML/Default.css b/Userland/Libraries/LibWeb/MathML/Default.css new file mode 100644 index 0000000000..1104b7fb39 --- /dev/null +++ b/Userland/Libraries/LibWeb/MathML/Default.css @@ -0,0 +1,119 @@ +/* https://w3c.github.io/mathml-core/#user-agent-stylesheet */ +@namespace url(http://www.w3.org/1998/Math/MathML); + +/* Universal rules */ +* { + font-size: math; + display: block math; + writing-mode: horizontal-tb !important; +} + +/* The element */ +math { + direction: ltr; + text-indent: 0; + letter-spacing: normal; + line-height: normal; + word-spacing: normal; + font-family: math; + font-size: inherit; + font-style: normal; + font-weight: normal; + display: inline math; + math-shift: normal; + math-style: compact; + math-depth: 0; +} +math[display="block" i] { + display: block math; + math-style: normal; +} +math[display="inline" i] { + display: inline math; + math-style: compact; +} + +/* -like elements */ +semantics > :not(:first-child) { + display: none; +} +maction > :not(:first-child) { + display: none; +} +merror { + border: 1px solid red; + background-color: lightYellow; +} +mphantom { + visibility: hidden; +} + +/* Token elements */ +mi { + text-transform: math-auto; +} + +/* Tables */ +mtable { + display: inline-table; + math-style: compact; +} +mtr { + display: table-row; +} +mtd { + display: table-cell; + /* Centering inside table cells should rely on box alignment properties. + See https://github.com/w3c/mathml-core/issues/156 */ + text-align: center; + padding: 0.5ex 0.4em; +} + +/* Fractions */ +mfrac { + padding-inline-start: 1px; + padding-inline-end: 1px; +} +mfrac > * { + math-depth: auto-add; + math-style: compact; +} +mfrac > :nth-child(2) { + math-shift: compact; +} + +/* Other rules for scriptlevel, displaystyle and math-shift */ +mroot > :not(:first-child) { + math-depth: add(2); + math-style: compact; +} +mroot, msqrt { + math-shift: compact; +} +msub > :not(:first-child), +msup > :not(:first-child), +msubsup > :not(:first-child), +mmultiscripts > :not(:first-child), +munder > :not(:first-child), +mover > :not(:first-child), +munderover > :not(:first-child) { + math-depth: add(1); + math-style: compact; +} +munder[accentunder="true" i] > :nth-child(2), +mover[accent="true" i] > :nth-child(2), +munderover[accentunder="true" i] > :nth-child(2), +munderover[accent="true" i] > :nth-child(3) { + font-size: inherit; +} +msub > :nth-child(2), +msubsup > :nth-child(2), +mmultiscripts > :nth-child(even), +mmultiscripts > mprescripts ~ :nth-child(odd), +mover[accent="true" i] > :first-child, +munderover[accent="true" i] > :first-child { + math-shift: compact; +} +mmultiscripts > mprescripts ~ :nth-child(even) { + math-shift: inherit; +}