LibWeb: Implement dominant-baseline for SVG text

This property determines the default baseline used to align content
within the given box.
This commit is contained in:
Tim Ledbetter
2026-02-25 20:46:37 +00:00
committed by Jelle Raaijmakers
parent 90a211bf47
commit f05bc7c0cd
Notes: github-actions[bot] 2026-02-26 08:24:27 +00:00
25 changed files with 311 additions and 10 deletions

View File

@@ -971,6 +971,12 @@ TextAnchor ComputedProperties::text_anchor() const
return keyword_to_text_anchor(value.to_keyword()).release_value(); return keyword_to_text_anchor(value.to_keyword()).release_value();
} }
Optional<BaselineMetric> ComputedProperties::dominant_baseline() const
{
auto const& value = property(PropertyID::DominantBaseline);
return keyword_to_baseline_metric(value.to_keyword());
}
TextAlign ComputedProperties::text_align() const TextAlign ComputedProperties::text_align() const
{ {
auto const& value = property(PropertyID::TextAlign); auto const& value = property(PropertyID::TextAlign);

View File

@@ -95,6 +95,7 @@ public:
ColorInterpolation color_interpolation() const; ColorInterpolation color_interpolation() const;
PreferredColorScheme color_scheme(PreferredColorScheme, Optional<Vector<String> const&> document_supported_schemes) const; PreferredColorScheme color_scheme(PreferredColorScheme, Optional<Vector<String> const&> document_supported_schemes) const;
TextAnchor text_anchor() const; TextAnchor text_anchor() const;
Optional<BaselineMetric> dominant_baseline() const;
TextAlign text_align() const; TextAlign text_align() const;
TextJustify text_justify() const; TextJustify text_justify() const;
TextOverflow text_overflow() const; TextOverflow text_overflow() const;

View File

@@ -260,6 +260,7 @@ public:
static TransformBox transform_box() { return TransformBox::ViewBox; } static TransformBox transform_box() { return TransformBox::ViewBox; }
static TransformStyle transform_style() { return TransformStyle::Flat; } static TransformStyle transform_style() { return TransformStyle::Flat; }
static Direction direction() { return Direction::Ltr; } static Direction direction() { return Direction::Ltr; }
static Optional<BaselineMetric> dominant_baseline() { return {}; }
static UnicodeBidi unicode_bidi() { return UnicodeBidi::Normal; } static UnicodeBidi unicode_bidi() { return UnicodeBidi::Normal; }
static WritingMode writing_mode() { return WritingMode::HorizontalTb; } static WritingMode writing_mode() { return WritingMode::HorizontalTb; }
static UserSelect user_select() { return UserSelect::Auto; } static UserSelect user_select() { return UserSelect::Auto; }
@@ -594,6 +595,7 @@ public:
ObjectFit object_fit() const { return m_noninherited.object_fit; } ObjectFit object_fit() const { return m_noninherited.object_fit; }
Position object_position() const { return m_noninherited.object_position; } Position object_position() const { return m_noninherited.object_position; }
Direction direction() const { return m_inherited.direction; } Direction direction() const { return m_inherited.direction; }
Optional<BaselineMetric> dominant_baseline() const { return m_inherited.dominant_baseline; }
UnicodeBidi unicode_bidi() const { return m_noninherited.unicode_bidi; } UnicodeBidi unicode_bidi() const { return m_noninherited.unicode_bidi; }
WritingMode writing_mode() const { return m_inherited.writing_mode; } WritingMode writing_mode() const { return m_inherited.writing_mode; }
UserSelect user_select() const { return m_noninherited.user_select; } UserSelect user_select() const { return m_noninherited.user_select; }
@@ -749,6 +751,7 @@ protected:
ListStyleType list_style_type { InitialValues::list_style_type() }; ListStyleType list_style_type { InitialValues::list_style_type() };
QuotesData quotes { InitialValues::quotes() }; QuotesData quotes { InitialValues::quotes() };
Direction direction { InitialValues::direction() }; Direction direction { InitialValues::direction() };
Optional<BaselineMetric> dominant_baseline { InitialValues::dominant_baseline() };
WritingMode writing_mode { InitialValues::writing_mode() }; WritingMode writing_mode { InitialValues::writing_mode() };
FillRule fill_rule { InitialValues::fill_rule() }; FillRule fill_rule { InitialValues::fill_rule() };
StrokeLinecap stroke_linecap { InitialValues::stroke_linecap() }; StrokeLinecap stroke_linecap { InitialValues::stroke_linecap() };
@@ -1078,6 +1081,7 @@ public:
void set_object_fit(ObjectFit value) { m_noninherited.object_fit = value; } void set_object_fit(ObjectFit value) { m_noninherited.object_fit = value; }
void set_object_position(Position value) { m_noninherited.object_position = move(value); } void set_object_position(Position value) { m_noninherited.object_position = move(value); }
void set_direction(Direction value) { m_inherited.direction = value; } void set_direction(Direction value) { m_inherited.direction = value; }
void set_dominant_baseline(Optional<BaselineMetric> value) { m_inherited.dominant_baseline = value; }
void set_unicode_bidi(UnicodeBidi value) { m_noninherited.unicode_bidi = value; } void set_unicode_bidi(UnicodeBidi value) { m_noninherited.unicode_bidi = value; }
void set_writing_mode(WritingMode value) { m_inherited.writing_mode = value; } void set_writing_mode(WritingMode value) { m_inherited.writing_mode = value; }
void set_user_select(UserSelect value) { m_noninherited.user_select = value; } void set_user_select(UserSelect value) { m_noninherited.user_select = value; }

View File

@@ -127,6 +127,16 @@
"padding-box", "padding-box",
"text" "text"
], ],
"baseline-metric": [
"text-bottom",
"alphabetic",
"ideographic",
"middle",
"central",
"mathematical",
"hanging",
"text-top"
],
"border-collapse": [ "border-collapse": [
"separate", "separate",
"collapse" "collapse"

View File

@@ -130,6 +130,7 @@
"captiontext", "captiontext",
"cell", "cell",
"center", "center",
"central",
"checkbox", "checkbox",
"circle", "circle",
"clip", "clip",
@@ -269,6 +270,7 @@
"inactivecaption", "inactivecaption",
"inactivecaptiontext", "inactivecaptiontext",
"increasing", "increasing",
"ideographic",
"incremental", "incremental",
"infinite", "infinite",
"infinity", "infinity",
@@ -348,6 +350,7 @@
"match-source", "match-source",
"math", "math",
"math-auto", "math-auto",
"mathematical",
"max-content", "max-content",
"medium", "medium",
"menu", "menu",

View File

@@ -1820,6 +1820,18 @@
"display-legacy" "display-legacy"
] ]
}, },
"dominant-baseline": {
"animation-type": "discrete",
"inherited": true,
"initial": "auto",
"requires-computation": "never",
"valid-types": [
"baseline-metric"
],
"valid-identifiers": [
"auto"
]
},
"empty-cells": { "empty-cells": {
"animation-type": "discrete", "animation-type": "discrete",
"inherited": true, "inherited": true,

View File

@@ -0,0 +1,62 @@
/*
* Copyright (c) 2026, Tim Ledbetter <tim.ledbetter@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibGfx/Font/Font.h>
#include <LibWeb/CSS/ComputedValues.h>
namespace Web::Layout {
// https://drafts.csswg.org/css-inline/#dominant-baseline-property
static float dominant_baseline_offset(CSS::BaselineMetric metric, Gfx::FontPixelMetrics const& font_metrics)
{
switch (metric) {
case CSS::BaselineMetric::Central:
return (font_metrics.ascent - font_metrics.descent) / 2;
case CSS::BaselineMetric::Middle:
return font_metrics.x_height / 2;
case CSS::BaselineMetric::Hanging:
// FIXME: Read the hanging baseline from the font's BASE table.
return font_metrics.ascent * 0.8f;
case CSS::BaselineMetric::Ideographic:
// FIXME: Read the ideographic baseline from the font's BASE table.
return -font_metrics.descent;
case CSS::BaselineMetric::Mathematical:
// FIXME: Read the math baseline from the font's BASE table.
return font_metrics.ascent * 0.5f;
case CSS::BaselineMetric::TextTop:
case CSS::BaselineMetric::TextBottom:
// FIXME: Support text-top and text-bottom.
case CSS::BaselineMetric::Alphabetic:
return 0;
}
VERIFY_NOT_REACHED();
}
static CSS::BaselineMetric resolve_dominant_baseline_metric(CSS::ComputedValues const& computed_values)
{
auto dominant_baseline = computed_values.dominant_baseline();
if (dominant_baseline.has_value())
return *dominant_baseline;
// https://drafts.csswg.org/css-inline/#valdef-dominant-baseline-auto
// Equivalent to alphabetic in horizontal writing modes and in vertical writing modes when text-orientation is
// sideways. Equivalent to central in vertical writing modes when text-orientation is mixed or upright.
// FIXME: Take text-orientation into account once it is implemented.
switch (computed_values.writing_mode()) {
case CSS::WritingMode::HorizontalTb:
case CSS::WritingMode::SidewaysRl:
case CSS::WritingMode::SidewaysLr:
return CSS::BaselineMetric::Alphabetic;
case CSS::WritingMode::VerticalRl:
case CSS::WritingMode::VerticalLr:
return CSS::BaselineMetric::Central;
}
VERIFY_NOT_REACHED();
}
}

View File

@@ -893,6 +893,7 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
computed_values.set_stop_opacity(computed_style.stop_opacity()); computed_values.set_stop_opacity(computed_style.stop_opacity());
computed_values.set_text_anchor(computed_style.text_anchor()); computed_values.set_text_anchor(computed_style.text_anchor());
computed_values.set_dominant_baseline(computed_style.dominant_baseline());
// FIXME: Support calc() // FIXME: Support calc()
if (auto const& column_count = computed_style.property(CSS::PropertyID::ColumnCount); column_count.is_integer()) if (auto const& column_count = computed_style.property(CSS::PropertyID::ColumnCount); column_count.is_integer())

View File

@@ -15,6 +15,7 @@
#include <LibGfx/TextLayout.h> #include <LibGfx/TextLayout.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/Layout/BlockFormattingContext.h> #include <LibWeb/Layout/BlockFormattingContext.h>
#include <LibWeb/Layout/DominantBaseline.h>
#include <LibWeb/Layout/SVGClipBox.h> #include <LibWeb/Layout/SVGClipBox.h>
#include <LibWeb/Layout/SVGFormattingContext.h> #include <LibWeb/Layout/SVGFormattingContext.h>
#include <LibWeb/Layout/SVGGeometryBox.h> #include <LibWeb/Layout/SVGGeometryBox.h>
@@ -381,6 +382,9 @@ Gfx::Path SVGFormattingContext::compute_path_for_text(SVGTextBox const& text_box
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
auto baseline_metric = resolve_dominant_baseline_metric(text_box.computed_values());
text_offset.translate_by(0, dominant_baseline_offset(baseline_metric, font.pixel_metrics()));
Gfx::Path path; Gfx::Path path;
path.move_to(text_offset); path.move_to(text_offset);
path.text(text_contents, font); path.text(text_contents, font);

View File

@@ -71,6 +71,7 @@ static ReadonlySpan<NamedPropertyID> attribute_style_properties()
NamedPropertyID(CSS::PropertyID::Cy, { SVG::TagNames::circle, SVG::TagNames::ellipse }), NamedPropertyID(CSS::PropertyID::Cy, { SVG::TagNames::circle, SVG::TagNames::ellipse }),
NamedPropertyID(CSS::PropertyID::Direction), NamedPropertyID(CSS::PropertyID::Direction),
NamedPropertyID(CSS::PropertyID::Display), NamedPropertyID(CSS::PropertyID::Display),
NamedPropertyID(CSS::PropertyID::DominantBaseline),
NamedPropertyID(CSS::PropertyID::FillOpacity), NamedPropertyID(CSS::PropertyID::FillOpacity),
NamedPropertyID(CSS::PropertyID::FillRule), NamedPropertyID(CSS::PropertyID::FillRule),
NamedPropertyID(CSS::PropertyID::Filter), NamedPropertyID(CSS::PropertyID::Filter),

View File

@@ -0,0 +1,64 @@
Viewport <#document> at [0,0] [0+0+0 800 0+0+0] [0+0+0 600 0+0+0] [BFC] children: not-inline
BlockContainer <html> at [0,0] [0+0+0 800 0+0+0] [0+0+0 416 0+0+0] [BFC] children: not-inline
BlockContainer <body> at [8,8] [8+0+0 784 0+0+8] [8+0+0 400 0+0+8] children: inline
frag 0 from SVGSVGBox start: 0, length: 0, rect: [8,8 400x400] baseline: 400
SVGSVGBox <svg> at [8,8] [0+0+0 400 0+0+0] [0+0+0 400 0+0+0] [SVG] children: inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,57.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,107.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,157.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,207.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,257.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,307.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGGeometryBox <line> at [7.75,357.75] [0+0+0 400.5 0+0+0] [0+0+0 0.5 0+0+0] children: not-inline
TextNode <#text> (not painted)
SVGTextBox <text> at [18.171875,44.90625] [0+0+0 44.4375 0+0+0] [0+0+0 14 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
SVGTextBox <text> at [18.171875,92.96875] [0+0+0 100.59375 0+0+0] [0+0+0 15.703125 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
SVGTextBox <text> at [19.015625,150.90625] [0+0+0 68.890625 0+0+0] [0+0+0 14.03125 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
SVGTextBox <text> at [19.3125,198.328125] [0+0+0 54.46875 0+0+0] [0+0+0 15.46875 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
SVGTextBox <text> at [18.859375,255.75] [0+0+0 70.625 0+0+0] [0+0+0 17.515625 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
SVGTextBox <text> at [19.265625,288.953125] [0+0+0 110.5 0+0+0] [0+0+0 17.515625 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
SVGTextBox <text> at [19.3125,350.953125] [0+0+0 126.59375 0+0+0] [0+0+0 15.46875 0+0+0] children: inline
TextNode <#text> (not painted)
TextNode <#text> (not painted)
TextNode <#text> (not painted)
ViewportPaintable (Viewport<#document>) [0,0 800x600]
PaintableWithLines (BlockContainer<HTML>) [0,0 800x416]
PaintableWithLines (BlockContainer<BODY>) [8,8 784x400]
SVGSVGPaintable (SVGSVGBox<svg>) [8,8 400x400] overflow: [8,8 400.25x400]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,57.75 400.5x0.5]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,107.75 400.5x0.5]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,157.75 400.5x0.5]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,207.75 400.5x0.5]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,257.75 400.5x0.5]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,307.75 400.5x0.5]
SVGPathPaintable (SVGGeometryBox<line>) [7.75,357.75 400.5x0.5]
SVGPathPaintable (SVGTextBox<text>) [18.171875,44.90625 44.4375x14]
SVGPathPaintable (SVGTextBox<text>) [18.171875,92.96875 100.59375x15.703125]
SVGPathPaintable (SVGTextBox<text>) [19.015625,150.90625 68.890625x14.03125]
SVGPathPaintable (SVGTextBox<text>) [19.3125,198.328125 54.46875x15.46875]
SVGPathPaintable (SVGTextBox<text>) [18.859375,255.75 70.625x17.515625]
SVGPathPaintable (SVGTextBox<text>) [19.265625,288.953125 110.5x17.515625]
SVGPathPaintable (SVGTextBox<text>) [19.3125,350.953125 126.59375x15.46875]
SC for Viewport<#document> [0,0 800x600] [children: 1] (z-index: auto)
SC for BlockContainer<HTML> [0,0 800x416] [children: 0] (z-index: auto)

View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<svg viewBox="0 0 400 400" width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<line x1="0" y1="50" x2="400" y2="50" stroke="gray" stroke-width="0.5"/>
<line x1="0" y1="100" x2="400" y2="100" stroke="gray" stroke-width="0.5"/>
<line x1="0" y1="150" x2="400" y2="150" stroke="gray" stroke-width="0.5"/>
<line x1="0" y1="200" x2="400" y2="200" stroke="gray" stroke-width="0.5"/>
<line x1="0" y1="250" x2="400" y2="250" stroke="gray" stroke-width="0.5"/>
<line x1="0" y1="300" x2="400" y2="300" stroke="gray" stroke-width="0.5"/>
<line x1="0" y1="350" x2="400" y2="350" stroke="gray" stroke-width="0.5"/>
<text x="10" y="50" font-size="20" font-family="SerenitySans" dominant-baseline="auto">auto</text>
<text x="10" y="100" font-size="20" font-family="SerenitySans" dominant-baseline="alphabetic">alphabetic</text>
<text x="10" y="150" font-size="20" font-family="SerenitySans" dominant-baseline="central">central</text>
<text x="10" y="200" font-size="20" font-family="SerenitySans" dominant-baseline="middle">middle</text>
<text x="10" y="250" font-size="20" font-family="SerenitySans" dominant-baseline="hanging">hanging</text>
<text x="10" y="300" font-size="20" font-family="SerenitySans" dominant-baseline="ideographic">ideographic</text>
<text x="10" y="350" font-size="20" font-family="SerenitySans" dominant-baseline="mathematical">mathematical</text>
</svg>

View File

@@ -12,6 +12,7 @@ All properties associated with getComputedStyle(document.body):
"color-scheme", "color-scheme",
"cursor", "cursor",
"direction", "direction",
"dominant-baseline",
"empty-cells", "empty-cells",
"fill", "fill",
"fill-opacity", "fill-opacity",

View File

@@ -443,6 +443,8 @@ All supported properties and their default values exposed from CSSStylePropertie
'cy': '0px' 'cy': '0px'
'direction': 'ltr' 'direction': 'ltr'
'display': 'block' 'display': 'block'
'dominantBaseline': 'auto'
'dominant-baseline': 'auto'
'emptyCells': 'show' 'emptyCells': 'show'
'empty-cells': 'show' 'empty-cells': 'show'
'fill': 'rgb(0, 0, 0)' 'fill': 'rgb(0, 0, 0)'

View File

@@ -10,6 +10,7 @@ color-interpolation: srgb
color-scheme: normal color-scheme: normal
cursor: auto cursor: auto
direction: ltr direction: ltr
dominant-baseline: auto
empty-cells: show empty-cells: show
fill: rgb(0, 0, 0) fill: rgb(0, 0, 0)
fill-opacity: 1 fill-opacity: 1
@@ -102,7 +103,7 @@ background-position-x: 0%
background-position-y: 0% background-position-y: 0%
background-repeat: repeat background-repeat: repeat
background-size: auto background-size: auto
block-size: 1560px block-size: 1575px
border-block-end-color: rgb(0, 0, 0) border-block-end-color: rgb(0, 0, 0)
border-block-end-style: none border-block-end-style: none
border-block-end-width: 0px border-block-end-width: 0px
@@ -188,7 +189,7 @@ grid-row-start: auto
grid-template-areas: none grid-template-areas: none
grid-template-columns: none grid-template-columns: none
grid-template-rows: none grid-template-rows: none
height: 2850px height: 2865px
inline-size: 784px inline-size: 784px
inset-block-end: auto inset-block-end: auto
inset-block-start: auto inset-block-start: auto

View File

@@ -1,8 +1,8 @@
Harness status: OK Harness status: OK
Found 285 tests Found 286 tests
281 Pass 282 Pass
4 Fail 4 Fail
Pass accent-color Pass accent-color
Pass border-collapse Pass border-collapse
@@ -15,6 +15,7 @@ Pass color-interpolation
Pass color-scheme Pass color-scheme
Pass cursor Pass cursor
Pass direction Pass direction
Pass dominant-baseline
Pass empty-cells Pass empty-cells
Pass fill Pass fill
Pass fill-opacity Pass fill-opacity

View File

@@ -0,0 +1,14 @@
Harness status: OK
Found 9 tests
9 Pass
Pass Property dominant-baseline value 'auto'
Pass Property dominant-baseline value 'text-bottom'
Pass Property dominant-baseline value 'alphabetic'
Pass Property dominant-baseline value 'ideographic'
Pass Property dominant-baseline value 'middle'
Pass Property dominant-baseline value 'central'
Pass Property dominant-baseline value 'mathematical'
Pass Property dominant-baseline value 'hanging'
Pass Property dominant-baseline value 'text-top'

View File

@@ -0,0 +1,9 @@
Harness status: OK
Found 4 tests
4 Pass
Pass e.style['dominant-baseline'] = "normal" should not set the property value
Pass e.style['dominant-baseline'] = "none" should not set the property value
Pass e.style['dominant-baseline'] = "alphabetic, ideographic" should not set the property value
Pass e.style['dominant-baseline'] = "middle central" should not set the property value

View File

@@ -0,0 +1,14 @@
Harness status: OK
Found 9 tests
9 Pass
Pass e.style['dominant-baseline'] = "auto" should set the property value
Pass e.style['dominant-baseline'] = "text-bottom" should set the property value
Pass e.style['dominant-baseline'] = "alphabetic" should set the property value
Pass e.style['dominant-baseline'] = "ideographic" should set the property value
Pass e.style['dominant-baseline'] = "middle" should set the property value
Pass e.style['dominant-baseline'] = "central" should set the property value
Pass e.style['dominant-baseline'] = "mathematical" should set the property value
Pass e.style['dominant-baseline'] = "hanging" should set the property value
Pass e.style['dominant-baseline'] = "text-top" should set the property value

View File

@@ -1,8 +1,8 @@
Harness status: OK Harness status: OK
Found 48 tests Found 49 tests
48 Pass 49 Pass
Pass clip-path presentation attribute supported on an irrelevant element Pass clip-path presentation attribute supported on an irrelevant element
Pass clip-rule presentation attribute supported on an irrelevant element Pass clip-rule presentation attribute supported on an irrelevant element
Pass color presentation attribute supported on an irrelevant element Pass color presentation attribute supported on an irrelevant element
@@ -10,6 +10,7 @@ Pass color-interpolation presentation attribute supported on an irrelevant eleme
Pass cursor presentation attribute supported on an irrelevant element Pass cursor presentation attribute supported on an irrelevant element
Pass direction presentation attribute supported on an irrelevant element Pass direction presentation attribute supported on an irrelevant element
Pass display presentation attribute supported on an irrelevant element Pass display presentation attribute supported on an irrelevant element
Pass dominant-baseline presentation attribute supported on an irrelevant element
Pass fill presentation attribute supported on an irrelevant element Pass fill presentation attribute supported on an irrelevant element
Pass fill-opacity presentation attribute supported on an irrelevant element Pass fill-opacity presentation attribute supported on an irrelevant element
Pass fill-rule presentation attribute supported on an irrelevant element Pass fill-rule presentation attribute supported on an irrelevant element

View File

@@ -1,8 +1,8 @@
Harness status: OK Harness status: OK
Found 58 tests Found 59 tests
57 Pass 58 Pass
1 Fail 1 Fail
Pass clip-path presentation attribute supported on a relevant element Pass clip-path presentation attribute supported on a relevant element
Pass clip-rule presentation attribute supported on a relevant element Pass clip-rule presentation attribute supported on a relevant element
@@ -13,6 +13,7 @@ Pass cx presentation attribute supported on a relevant element
Pass cy presentation attribute supported on a relevant element Pass cy presentation attribute supported on a relevant element
Pass direction presentation attribute supported on a relevant element Pass direction presentation attribute supported on a relevant element
Pass display presentation attribute supported on a relevant element Pass display presentation attribute supported on a relevant element
Pass dominant-baseline presentation attribute supported on a relevant element
Pass fill presentation attribute supported on a relevant element Pass fill presentation attribute supported on a relevant element
Pass fill-opacity presentation attribute supported on a relevant element Pass fill-opacity presentation attribute supported on a relevant element
Pass fill-rule presentation attribute supported on a relevant element Pass fill-rule presentation attribute supported on a relevant element

View File

@@ -1,8 +1,8 @@
Harness status: OK Harness status: OK
Found 48 tests Found 49 tests
48 Pass 49 Pass
Pass clip-path presentation attribute supported on an unknown SVG element Pass clip-path presentation attribute supported on an unknown SVG element
Pass clip-rule presentation attribute supported on an unknown SVG element Pass clip-rule presentation attribute supported on an unknown SVG element
Pass color presentation attribute supported on an unknown SVG element Pass color presentation attribute supported on an unknown SVG element
@@ -10,6 +10,7 @@ Pass color-interpolation presentation attribute supported on an unknown SVG elem
Pass cursor presentation attribute supported on an unknown SVG element Pass cursor presentation attribute supported on an unknown SVG element
Pass direction presentation attribute supported on an unknown SVG element Pass direction presentation attribute supported on an unknown SVG element
Pass display presentation attribute supported on an unknown SVG element Pass display presentation attribute supported on an unknown SVG element
Pass dominant-baseline presentation attribute supported on an unknown SVG element
Pass fill presentation attribute supported on an unknown SVG element Pass fill presentation attribute supported on an unknown SVG element
Pass fill-opacity presentation attribute supported on an unknown SVG element Pass fill-opacity presentation attribute supported on an unknown SVG element
Pass fill-rule presentation attribute supported on an unknown SVG element Pass fill-rule presentation attribute supported on an unknown SVG element

View File

@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Inline Layout: getComputedStyle().dominantBaseline</title>
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#dominant-baseline-property">
<meta name="assert" content="dominant-baseline computed value is as specified.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/computed-testcommon.js"></script>
</head>
<body>
<div id="target"></div>
<script>
test_computed_value("dominant-baseline", "auto");
test_computed_value("dominant-baseline", "text-bottom");
test_computed_value("dominant-baseline", "alphabetic");
test_computed_value("dominant-baseline", "ideographic");
test_computed_value("dominant-baseline", "middle");
test_computed_value("dominant-baseline", "central");
test_computed_value("dominant-baseline", "mathematical");
test_computed_value("dominant-baseline", "hanging");
test_computed_value("dominant-baseline", "text-top");
</script>
</body>
</html>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Inline Layout: parsing dominant-baseline with invalid values</title>
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#dominant-baseline-property">
<meta name="assert" content="dominant-baseline supports only the grammar 'auto | text-bottom | alphabetic | ideographic | middle | central | mathematical | hanging | text-top'.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_invalid_value("dominant-baseline", "normal");
test_invalid_value("dominant-baseline", "none");
test_invalid_value("dominant-baseline", "alphabetic, ideographic");
test_invalid_value("dominant-baseline", "middle central");
</script>
</body>
</html>

View File

@@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>CSS Inline Layout: parsing dominant-baseline with valid values</title>
<link rel="help" href="https://drafts.csswg.org/css-inline-3/#dominant-baseline-property">
<meta name="assert" content="dominant-baseline supports the full grammar 'auto | text-bottom | alphabetic | ideographic | middle | central | mathematical | hanging | text-top'.">
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>
<script src="../../../css/support/parsing-testcommon.js"></script>
</head>
<body>
<script>
test_valid_value("dominant-baseline", "auto");
test_valid_value("dominant-baseline", "text-bottom");
test_valid_value("dominant-baseline", "alphabetic");
test_valid_value("dominant-baseline", "ideographic");
test_valid_value("dominant-baseline", "middle");
test_valid_value("dominant-baseline", "central");
test_valid_value("dominant-baseline", "mathematical");
test_valid_value("dominant-baseline", "hanging");
test_valid_value("dominant-baseline", "text-top");
</script>
</body>
</html>