mirror of
https://github.com/zebrajr/ladybird.git
synced 2025-12-06 00:19:53 +01:00
LibWeb: Add MathML Element presentational hints
This commit is contained in:
parent
f1571c4217
commit
96b34ea744
|
|
@ -758,7 +758,10 @@ set(SOURCES
|
|||
Loader/ProxyMappings.cpp
|
||||
Loader/Resource.cpp
|
||||
Loader/ResourceLoader.cpp
|
||||
MathML/AttributeNames.cpp
|
||||
MathML/MathMLElement.cpp
|
||||
MathML/MathMLMiElement.cpp
|
||||
MathML/MathMLMspaceElement.cpp
|
||||
MathML/TagNames.cpp
|
||||
MediaCapabilitiesAPI/MediaCapabilities.cpp
|
||||
MediaSourceExtensions/BufferedChangeEvent.cpp
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@
|
|||
#include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
|
||||
#include <LibWeb/Infra/Strings.h>
|
||||
#include <LibWeb/MathML/MathMLElement.h>
|
||||
#include <LibWeb/MathML/MathMLMiElement.h>
|
||||
#include <LibWeb/MathML/MathMLMspaceElement.h>
|
||||
#include <LibWeb/MathML/TagNames.h>
|
||||
#include <LibWeb/Namespace.h>
|
||||
#include <LibWeb/SVG/SVGAElement.h>
|
||||
|
|
@ -543,6 +545,12 @@ static GC::Ref<SVG::SVGElement> create_svg_element(JS::Realm& realm, Document& d
|
|||
|
||||
static GC::Ref<MathML::MathMLElement> create_mathml_element(JS::Realm& realm, Document& document, QualifiedName qualified_name)
|
||||
{
|
||||
auto const& local_name = qualified_name.local_name();
|
||||
if (local_name == MathML::TagNames::mi)
|
||||
return realm.create<MathML::MathMLMiElement>(document, move(qualified_name));
|
||||
if (local_name == MathML::TagNames::mspace)
|
||||
return realm.create<MathML::MathMLMspaceElement>(document, move(qualified_name));
|
||||
|
||||
// https://w3c.github.io/mathml-core/#dom-and-javascript
|
||||
// All the nodes representing MathML elements in the DOM must implement, and expose to scripts,
|
||||
// the following MathMLElement interface.
|
||||
|
|
|
|||
|
|
@ -885,6 +885,8 @@ struct LayoutState;
|
|||
namespace Web::MathML {
|
||||
|
||||
class MathMLElement;
|
||||
class MathMLMiElement;
|
||||
class MathMLMspaceElement;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
16
Libraries/LibWeb/MathML/AttributeNames.cpp
Normal file
16
Libraries/LibWeb/MathML/AttributeNames.cpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Lorenz Ackermann, <me@lorenzackermann.xyz>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/MathML/AttributeNames.h>
|
||||
|
||||
namespace Web::MathML::AttributeNames {
|
||||
|
||||
#define __ENUMERATE_MATHML_ATTRIBUTE(name, attribute) \
|
||||
FlyString name = attribute##_fly_string;
|
||||
ENUMERATE_MATHML_ATTRIBUTES
|
||||
#undef __ENUMERATE_MATHML_ATTRIBUTE
|
||||
|
||||
}
|
||||
31
Libraries/LibWeb/MathML/AttributeNames.h
Normal file
31
Libraries/LibWeb/MathML/AttributeNames.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Lorenz Ackermann, <me@lorenzackermann.xyz>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/FlyString.h>
|
||||
#include <LibWeb/Export.h>
|
||||
|
||||
namespace Web::MathML::AttributeNames {
|
||||
|
||||
#define ENUMERATE_MATHML_ATTRIBUTES \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(autofocus, "autofocus") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(depth, "depth") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(dir, "dir") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(displaystyle, "displaystyle") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(height, "height") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(mathbackground, "mathbackground") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(mathcolor, "mathcolor") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(mathsize, "mathsize") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(mathvariant, "mathvariant") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(scriptlevel, "scriptlevel") \
|
||||
__ENUMERATE_MATHML_ATTRIBUTE(width, "width")
|
||||
|
||||
#define __ENUMERATE_MATHML_ATTRIBUTE(name, attribute) extern WEB_API FlyString name;
|
||||
ENUMERATE_MATHML_ATTRIBUTES
|
||||
#undef __ENUMERATE_MATHML_ATTRIBUTE
|
||||
|
||||
}
|
||||
|
|
@ -6,6 +6,13 @@
|
|||
|
||||
#include <LibWeb/Bindings/ExceptionOrUtils.h>
|
||||
#include <LibWeb/Bindings/MathMLElementPrototype.h>
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/StyleValues/IntegerStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
|
||||
#include <LibWeb/CSS/StyleValues/MathDepthStyleValue.h>
|
||||
#include <LibWeb/HTML/Numbers.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
#include <LibWeb/MathML/AttributeNames.h>
|
||||
#include <LibWeb/MathML/MathMLElement.h>
|
||||
#include <LibWeb/MathML/TagNames.h>
|
||||
|
||||
|
|
@ -59,4 +66,68 @@ void MathMLElement::visit_edges(JS::Cell::Visitor& visitor)
|
|||
HTMLOrSVGElement::visit_edges(visitor);
|
||||
}
|
||||
|
||||
bool MathMLElement::is_presentational_hint(FlyString const& name) const
|
||||
{
|
||||
return first_is_one_of(name, AttributeNames::dir, AttributeNames::mathcolor, AttributeNames::mathbackground,
|
||||
AttributeNames::mathsize, AttributeNames::displaystyle, AttributeNames::scriptlevel);
|
||||
}
|
||||
|
||||
void MathMLElement::apply_presentational_hints(GC::Ref<CSS::CascadedProperties> cascaded_properties) const
|
||||
{
|
||||
for_each_attribute([&](auto& name, auto& value) {
|
||||
if (name == AttributeNames::dir) {
|
||||
// https://w3c.github.io/mathml-core/#attributes-common-to-html-and-mathml-elements
|
||||
// The dir attribute, if present, must be an ASCII case-insensitive match to ltr or rtl. In that case, the
|
||||
// user agent is expected to treat the attribute as a presentational hint setting the element's direction
|
||||
// property to the corresponding value. More precisely, an ASCII case-insensitive match to rtl is mapped to
|
||||
// rtl while an ASCII case-insensitive match to ltr is mapped to ltr.
|
||||
if (value.equals_ignoring_ascii_case("ltr"sv))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Direction, CSS::KeywordStyleValue::create(CSS::Keyword::Ltr));
|
||||
else if (value.equals_ignoring_ascii_case("rtl"sv))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Direction, CSS::KeywordStyleValue::create(CSS::Keyword::Rtl));
|
||||
} else if (name == AttributeNames::mathcolor) {
|
||||
// https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes
|
||||
// The mathcolor and mathbackground attributes, if present, must have a value that is a <color>. In that case,
|
||||
// the user agent is expected to treat these attributes as a presentational hint setting the element's color
|
||||
// and background-color properties to the corresponding values.
|
||||
if (auto parsed_value = parse_css_value(CSS::Parser::ParsingParams { document() }, value, CSS::PropertyID::Color))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Color, parsed_value.release_nonnull());
|
||||
} else if (name == AttributeNames::mathbackground) {
|
||||
if (auto parsed_value = parse_css_value(CSS::Parser::ParsingParams { document() }, value, CSS::PropertyID::BackgroundColor))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, parsed_value.release_nonnull());
|
||||
} else if (name == AttributeNames::mathsize) {
|
||||
// https://w3c.github.io/mathml-core/#dfn-mathsize
|
||||
// The mathsize attribute, if present, must have a value that is a valid <length-percentage>.
|
||||
// In that case, the user agent is expected to treat the attribute as a presentational hint setting the
|
||||
// element's font-size property to the corresponding value.
|
||||
if (auto parsed_value = HTML::parse_dimension_value(value))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::FontSize, parsed_value.release_nonnull());
|
||||
} else if (name == AttributeNames::displaystyle) {
|
||||
// https://w3c.github.io/mathml-core/#dfn-displaystyle
|
||||
// The displaystyle attribute, if present, must have a value that is a boolean. In that case, the user agent
|
||||
// is expected to treat the attribute as a presentational hint setting the element's math-style property to
|
||||
// the corresponding value. More precisely, an ASCII case-insensitive match to true is mapped to normal while
|
||||
// an ASCII case-insensitive match to false is mapped to compact.
|
||||
if (value.equals_ignoring_ascii_case("true"sv))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MathStyle, CSS::KeywordStyleValue::create(CSS::Keyword::Normal));
|
||||
else if (value.equals_ignoring_ascii_case("false"sv))
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MathStyle, CSS::KeywordStyleValue::create(CSS::Keyword::Compact));
|
||||
} else if (name == AttributeNames::scriptlevel) {
|
||||
// https://w3c.github.io/mathml-core/#dfn-scriptlevel
|
||||
// The scriptlevel attribute, if present, must have value +<U>, -<U> or <U> where <U> is an unsigned-integer.
|
||||
// In that case the user agent is expected to treat the scriptlevel attribute as a presentational hint
|
||||
// setting the element's math-depth property to the corresponding value. More precisely, +<U>, -<U> and <U>
|
||||
// are respectively mapped to add(<U>) add(<-U>) and <U>.
|
||||
if (Optional<StringView> parsed_value = HTML::parse_integer_digits(value); parsed_value.has_value()) {
|
||||
auto string_value = parsed_value.value();
|
||||
if (auto value = parsed_value->to_number<i32>(TrimWhitespace::No); value.has_value()) {
|
||||
auto style_value = string_value[0] == '+' || string_value[0] == '-' ? CSS::MathDepthStyleValue::create_add(CSS::IntegerStyleValue::create(value.release_value()))
|
||||
: CSS::MathDepthStyleValue::create_integer(CSS::IntegerStyleValue::create(value.release_value()));
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MathDepth, style_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,14 +24,15 @@ public:
|
|||
virtual Optional<ARIA::Role> default_role() const override;
|
||||
|
||||
protected:
|
||||
MathMLElement(DOM::Document&, DOM::QualifiedName);
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
virtual WebIDL::ExceptionOr<void> cloned(DOM::Node&, bool) const override;
|
||||
virtual void inserted() override;
|
||||
virtual GC::Ptr<DOM::EventTarget> global_event_handlers_to_event_target(FlyString const&) override { return *this; }
|
||||
virtual bool is_presentational_hint(FlyString const&) const override;
|
||||
virtual void apply_presentational_hints(GC::Ref<CSS::CascadedProperties>) const override;
|
||||
|
||||
private:
|
||||
MathMLElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
|
|
|||
41
Libraries/LibWeb/MathML/MathMLMiElement.cpp
Normal file
41
Libraries/LibWeb/MathML/MathMLMiElement.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Lorenz Ackermann, <me@lorenzackermann.xyz>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
#include <LibWeb/MathML/AttributeNames.h>
|
||||
#include <LibWeb/MathML/MathMLMiElement.h>
|
||||
|
||||
namespace Web::MathML {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(MathMLMiElement);
|
||||
|
||||
MathMLMiElement::MathMLMiElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
||||
: MathMLElement(document, move(qualified_name))
|
||||
{
|
||||
}
|
||||
|
||||
bool MathMLMiElement::is_presentational_hint(FlyString const& name) const
|
||||
{
|
||||
if (Base::is_presentational_hint(name))
|
||||
return true;
|
||||
return first_is_one_of(name, AttributeNames::mathvariant);
|
||||
}
|
||||
|
||||
void MathMLMiElement::apply_presentational_hints(GC::Ref<CSS::CascadedProperties> cascaded_properties) const
|
||||
{
|
||||
Base::apply_presentational_hints(cascaded_properties);
|
||||
// https://w3c.github.io/mathml-core/#dfn-mathvariant
|
||||
// The mathvariant attribute, if present, must be an ASCII case-insensitive match of normal. In that case, the user
|
||||
// agent is expected to treat the attribute as a presentational hint setting the element's text-transform property
|
||||
// to none. Otherwise it has no effects.
|
||||
if (auto mathvariant = attribute(AttributeNames::mathvariant); mathvariant.has_value() && mathvariant.value().equals_ignoring_ascii_case("normal"sv)) {
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextTransform, CSS::KeywordStyleValue::create(CSS::Keyword::None));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
27
Libraries/LibWeb/MathML/MathMLMiElement.h
Normal file
27
Libraries/LibWeb/MathML/MathMLMiElement.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Lorenz Ackermann, <me@lorenzackermann.xyz>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/MathML/MathMLElement.h>
|
||||
|
||||
namespace Web::MathML {
|
||||
|
||||
class MathMLMiElement final : public MathMLElement {
|
||||
WEB_PLATFORM_OBJECT(MathMLMiElement, MathMLElement);
|
||||
GC_DECLARE_ALLOCATOR(MathMLMiElement);
|
||||
|
||||
public:
|
||||
virtual ~MathMLMiElement() override = default;
|
||||
|
||||
private:
|
||||
MathMLMiElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual bool is_presentational_hint(FlyString const&) const override;
|
||||
virtual void apply_presentational_hints(GC::Ref<CSS::CascadedProperties>) const override;
|
||||
};
|
||||
|
||||
}
|
||||
70
Libraries/LibWeb/MathML/MathMLMspaceElement.cpp
Normal file
70
Libraries/LibWeb/MathML/MathMLMspaceElement.cpp
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Lorenz Ackermann, <me@lorenzackermann.xyz>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/CSS/Parser/Parser.h>
|
||||
#include <LibWeb/HTML/Parser/HTMLParser.h>
|
||||
#include <LibWeb/MathML/AttributeNames.h>
|
||||
#include <LibWeb/MathML/MathMLMspaceElement.h>
|
||||
|
||||
namespace Web::MathML {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(MathMLMspaceElement);
|
||||
|
||||
MathMLMspaceElement::MathMLMspaceElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
||||
: MathMLElement(document, move(qualified_name))
|
||||
{
|
||||
}
|
||||
|
||||
bool MathMLMspaceElement::is_presentational_hint(FlyString const& name) const
|
||||
{
|
||||
if (Base::is_presentational_hint(name))
|
||||
return true;
|
||||
return first_is_one_of(name, AttributeNames::width, AttributeNames::height, AttributeNames::depth);
|
||||
}
|
||||
|
||||
void MathMLMspaceElement::apply_presentational_hints(GC::Ref<CSS::CascadedProperties> cascaded_properties) const
|
||||
{
|
||||
Base::apply_presentational_hints(cascaded_properties);
|
||||
// https://w3c.github.io/mathml-core/#attribute-mspace-width
|
||||
// The width, height, depth, if present, must have a value that is a valid <length-percentage>.
|
||||
auto parse_non_percentage_value = [&](FlyString const& attribute_name) -> RefPtr<CSS::StyleValue const> {
|
||||
if (auto attribute = this->attribute(attribute_name); attribute.has_value()) {
|
||||
if (auto value = HTML::parse_dimension_value(attribute.value()); value && !value->is_percentage()) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
};
|
||||
|
||||
// If the width attribute is present, valid and not a percentage then that attribute is used as a presentational hint
|
||||
// setting the element's width property to the corresponding value.
|
||||
if (auto width_value = parse_non_percentage_value(AttributeNames::width)) {
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, width_value.release_nonnull());
|
||||
}
|
||||
|
||||
// https://w3c.github.io/mathml-core/#attribute-mspace-height
|
||||
// If the height attribute is absent, invalid or a percentage then the requested line-ascent is 0. Otherwise the
|
||||
// requested line-ascent is the resolved value of the height attribute, clamping negative values to 0.
|
||||
auto height_value = parse_non_percentage_value(AttributeNames::height);
|
||||
// FIXME set the line-ascent
|
||||
|
||||
// If both the height and depth attributes are present, valid and not a percentage then they are used as a
|
||||
// presentational hint setting the element's height property to the concatenation of the
|
||||
// strings "calc(", the height attribute value, " + ", the depth attribute value, and ")". If only one of these
|
||||
// attributes is present, valid and not a percentage then it is treated as a presentational hint setting the
|
||||
// element's height property to the corresponding value.
|
||||
auto depth_value = parse_non_percentage_value(AttributeNames::depth);
|
||||
|
||||
if (height_value && depth_value) {
|
||||
// FIXME set the presentational hint to calculate height + depth
|
||||
} else if (height_value) {
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, height_value.release_nonnull());
|
||||
} else if (depth_value) {
|
||||
cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, depth_value.release_nonnull());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
27
Libraries/LibWeb/MathML/MathMLMspaceElement.h
Normal file
27
Libraries/LibWeb/MathML/MathMLMspaceElement.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Lorenz Ackermann, <me@lorenzackermann.xyz>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/MathML/MathMLElement.h>
|
||||
|
||||
namespace Web::MathML {
|
||||
|
||||
class MathMLMspaceElement final : public MathMLElement {
|
||||
WEB_PLATFORM_OBJECT(MathMLMspaceElement, MathMLElement);
|
||||
GC_DECLARE_ALLOCATOR(MathMLMspaceElement);
|
||||
|
||||
public:
|
||||
virtual ~MathMLMspaceElement() override = default;
|
||||
|
||||
private:
|
||||
MathMLMspaceElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual bool is_presentational_hint(FlyString const&) const override;
|
||||
virtual void apply_presentational_hints(GC::Ref<CSS::CascadedProperties>) const override;
|
||||
};
|
||||
|
||||
}
|
||||
24
Tests/LibWeb/Text/expected/MathML/presentational_hints.txt
Normal file
24
Tests/LibWeb/Text/expected/MathML/presentational_hints.txt
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
direction: ltr
|
||||
direction: ltr
|
||||
direction: rtl
|
||||
color: red
|
||||
color: rgb(255, 0, 0)
|
||||
background-color: blue
|
||||
background-color: rgb(0, 0, 255)
|
||||
font-size: 10px
|
||||
math-style: compact
|
||||
math-style: normal
|
||||
math-style: normal
|
||||
math-style: compact
|
||||
math-style: compact
|
||||
math-depth: 1
|
||||
math-depth: 2
|
||||
math-depth: 3
|
||||
math-depth: -2
|
||||
text-transform: math-auto
|
||||
text-transform: none
|
||||
width: 10px
|
||||
width: auto
|
||||
height: 20px
|
||||
height: 30px
|
||||
height: auto
|
||||
57
Tests/LibWeb/Text/input/MathML/presentational_hints.html
Normal file
57
Tests/LibWeb/Text/input/MathML/presentational_hints.html
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="../include.js"></script>
|
||||
|
||||
<body>
|
||||
<math data-prop="direction">
|
||||
<mi></mi>
|
||||
<mi dir="LTR"></mi>
|
||||
<mi dir="rtl"></mi>
|
||||
</math>
|
||||
<math data-prop="color">
|
||||
<mi mathcolor="red"></mi>
|
||||
<mi mathcolor="#f00"></mi>
|
||||
</math>
|
||||
<math data-prop="background-color">
|
||||
<mi mathbackground="blue"></mi>
|
||||
<mi mathbackground="#0000ff"></mi>
|
||||
</math>
|
||||
<math data-prop="font-size">
|
||||
<mi mathsize="10px"></mi>
|
||||
</math>
|
||||
<math data-prop="math-style">
|
||||
<mi displaystyle=""></mi>
|
||||
<mi displaystyle="true"></mi>
|
||||
<mi displaystyle="TRuE"></mi>
|
||||
<mi displaystyle="false"></mi>
|
||||
<mi displaystyle="faLse"></mi>
|
||||
</math>
|
||||
<math data-prop="math-depth" style="math-depth:1">
|
||||
<mi></mi>
|
||||
<mi scriptlevel="2"></mi>
|
||||
<mi scriptlevel="+2"></mi>
|
||||
<mi scriptlevel="-3"></mi>
|
||||
</math>
|
||||
<math data-prop="text-transform">
|
||||
<mi></mi>
|
||||
<mi mathvariant="normal"></mi>
|
||||
</math>
|
||||
<math data-prop="width">
|
||||
<mspace width="10px"></mspace>
|
||||
<mspace width="10%"></mspace>
|
||||
</math>
|
||||
<math data-prop="height">
|
||||
<mspace height="20px"></mspace>
|
||||
<mspace depth="30px"></mspace>
|
||||
<mspace height="10%"></mspace>
|
||||
</math>
|
||||
</body>
|
||||
<script>
|
||||
test(() => {
|
||||
[...document.querySelectorAll('[data-prop]')].forEach(propItem => {
|
||||
const prop = propItem.dataset['prop'];
|
||||
[...propItem.querySelectorAll('& > *')].forEach(item =>
|
||||
println(`${prop}: ${item.computedStyleMap().get(prop).toString()}`)
|
||||
);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user