2020-01-18 09:38:21 +01:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
2021-09-10 20:23:57 +01:00
|
|
|
* Copyright (c) 2021, Sam Atkins <atkinssj@serenityos.org>
|
2020-01-18 09:38:21 +01:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 09:38:21 +01:00
|
|
|
*/
|
|
|
|
|
2021-05-30 20:22:25 +02:00
|
|
|
#include <AK/TypeCasts.h>
|
2020-02-06 15:04:03 +01:00
|
|
|
#include <LibCore/DirIterator.h>
|
2020-12-14 15:56:01 +01:00
|
|
|
#include <LibGfx/FontDatabase.h>
|
2020-03-07 10:32:51 +01:00
|
|
|
#include <LibWeb/CSS/StyleProperties.h>
|
|
|
|
#include <LibWeb/FontCache.h>
|
2021-10-06 20:02:41 +02:00
|
|
|
#include <LibWeb/Layout/BlockContainer.h>
|
2021-08-12 16:41:09 +01:00
|
|
|
#include <LibWeb/Layout/Node.h>
|
2019-09-21 15:32:17 +03:00
|
|
|
|
2020-07-26 20:01:35 +02:00
|
|
|
namespace Web::CSS {
|
2020-03-07 10:27:02 +01:00
|
|
|
|
2020-01-05 16:54:38 +01:00
|
|
|
StyleProperties::StyleProperties()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
StyleProperties::StyleProperties(const StyleProperties& other)
|
2020-04-08 17:18:47 +02:00
|
|
|
: m_property_values(other.m_property_values)
|
2020-01-05 16:54:38 +01:00
|
|
|
{
|
|
|
|
if (other.m_font) {
|
|
|
|
m_font = other.m_font->clone();
|
|
|
|
} else {
|
|
|
|
m_font = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NonnullRefPtr<StyleProperties> StyleProperties::clone() const
|
|
|
|
{
|
2021-04-23 16:46:57 +02:00
|
|
|
return adopt_ref(*new StyleProperties(*this));
|
2020-01-05 16:54:38 +01:00
|
|
|
}
|
|
|
|
|
2019-10-08 15:34:19 +02:00
|
|
|
void StyleProperties::set_property(CSS::PropertyID id, NonnullRefPtr<StyleValue> value)
|
2019-09-21 15:32:17 +03:00
|
|
|
{
|
2021-09-21 11:38:18 +02:00
|
|
|
m_property_values.set(id, move(value));
|
2019-09-21 15:32:17 +03:00
|
|
|
}
|
|
|
|
|
2020-06-13 15:16:56 +02:00
|
|
|
void StyleProperties::set_property(CSS::PropertyID id, const StringView& value)
|
|
|
|
{
|
2021-09-21 11:38:18 +02:00
|
|
|
m_property_values.set(id, StringStyleValue::create(value));
|
2020-06-13 15:16:56 +02:00
|
|
|
}
|
|
|
|
|
2021-09-21 11:38:18 +02:00
|
|
|
Optional<NonnullRefPtr<StyleValue>> StyleProperties::property(CSS::PropertyID property_id) const
|
2019-09-21 15:32:17 +03:00
|
|
|
{
|
2021-09-21 11:38:18 +02:00
|
|
|
auto it = m_property_values.find(property_id);
|
|
|
|
if (it == m_property_values.end())
|
2021-08-20 12:48:17 +01:00
|
|
|
return {};
|
2021-09-21 11:38:18 +02:00
|
|
|
return it->value;
|
2019-09-21 15:32:17 +03:00
|
|
|
}
|
|
|
|
|
2019-10-08 15:34:19 +02:00
|
|
|
Length StyleProperties::length_or_fallback(CSS::PropertyID id, const Length& fallback) const
|
2019-09-21 15:32:17 +03:00
|
|
|
{
|
2019-10-08 15:34:19 +02:00
|
|
|
auto value = property(id);
|
2019-09-21 15:32:17 +03:00
|
|
|
if (!value.has_value())
|
|
|
|
return fallback;
|
2021-06-12 00:03:15 +02:00
|
|
|
|
|
|
|
if (value.value()->is_calculated()) {
|
|
|
|
Length length = Length(0, Length::Type::Calculated);
|
2021-09-23 21:20:02 +01:00
|
|
|
length.set_calculated_style(&value.value()->as_calculated());
|
2021-06-12 00:03:15 +02:00
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2019-09-21 15:32:17 +03:00
|
|
|
return value.value()->to_length();
|
|
|
|
}
|
2019-09-25 11:55:04 +03:00
|
|
|
|
2020-12-15 20:01:00 +01:00
|
|
|
LengthBox StyleProperties::length_box(CSS::PropertyID left_id, CSS::PropertyID top_id, CSS::PropertyID right_id, CSS::PropertyID bottom_id, const CSS::Length& default_value) const
|
2020-05-11 23:04:59 +02:00
|
|
|
{
|
2020-06-24 17:45:42 +02:00
|
|
|
LengthBox box;
|
2020-12-15 20:01:00 +01:00
|
|
|
box.left = length_or_fallback(left_id, default_value);
|
|
|
|
box.top = length_or_fallback(top_id, default_value);
|
|
|
|
box.right = length_or_fallback(right_id, default_value);
|
|
|
|
box.bottom = length_or_fallback(bottom_id, default_value);
|
2020-06-24 17:45:42 +02:00
|
|
|
return box;
|
2020-05-11 23:04:59 +02:00
|
|
|
}
|
|
|
|
|
2021-09-16 19:20:20 +01:00
|
|
|
Color StyleProperties::color_or_fallback(CSS::PropertyID id, Layout::NodeWithStyle const& node, Color fallback) const
|
2019-09-28 22:18:19 +02:00
|
|
|
{
|
2019-10-08 15:34:19 +02:00
|
|
|
auto value = property(id);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value() || !value.value()->has_color())
|
2019-09-28 22:18:19 +02:00
|
|
|
return fallback;
|
2021-09-16 19:20:20 +01:00
|
|
|
return value.value()->to_color(node);
|
2019-09-28 22:18:19 +02:00
|
|
|
}
|
2019-10-06 11:23:58 +02:00
|
|
|
|
2021-09-23 13:13:51 +02:00
|
|
|
NonnullRefPtr<Gfx::Font> StyleProperties::font_fallback(bool monospace, bool bold)
|
2021-04-22 20:47:47 +02:00
|
|
|
{
|
|
|
|
if (monospace && bold)
|
2021-05-20 18:55:23 +02:00
|
|
|
return Gfx::FontDatabase::default_fixed_width_font().bold_variant();
|
2021-04-22 20:47:47 +02:00
|
|
|
|
|
|
|
if (monospace)
|
|
|
|
return Gfx::FontDatabase::default_fixed_width_font();
|
|
|
|
|
|
|
|
if (bold)
|
2021-05-20 18:40:48 +02:00
|
|
|
return Gfx::FontDatabase::default_font().bold_variant();
|
2021-04-22 20:47:47 +02:00
|
|
|
|
|
|
|
return Gfx::FontDatabase::default_font();
|
|
|
|
}
|
|
|
|
|
2020-11-22 15:53:01 +01:00
|
|
|
float StyleProperties::line_height(const Layout::Node& layout_node) const
|
2019-10-12 13:42:58 +02:00
|
|
|
{
|
2020-06-24 11:08:46 +02:00
|
|
|
auto line_height_length = length_or_fallback(CSS::PropertyID::LineHeight, Length::make_auto());
|
2019-11-18 16:54:20 +01:00
|
|
|
if (line_height_length.is_absolute())
|
2020-06-07 17:55:46 +02:00
|
|
|
return (float)line_height_length.to_px(layout_node);
|
2021-09-23 19:51:45 +02:00
|
|
|
return (float)computed_font().glyph_height() * 1.4f;
|
2019-10-12 13:42:58 +02:00
|
|
|
}
|
2019-10-14 18:32:02 +02:00
|
|
|
|
2020-06-15 17:29:35 +02:00
|
|
|
Optional<int> StyleProperties::z_index() const
|
|
|
|
{
|
2021-09-10 20:37:09 +01:00
|
|
|
auto maybe_value = property(CSS::PropertyID::ZIndex);
|
|
|
|
if (!maybe_value.has_value())
|
2020-06-15 17:29:35 +02:00
|
|
|
return {};
|
2021-09-10 20:37:09 +01:00
|
|
|
auto& value = maybe_value.value();
|
|
|
|
|
2021-09-23 19:54:19 +01:00
|
|
|
if (value->has_auto())
|
2021-09-10 20:37:09 +01:00
|
|
|
return 0;
|
|
|
|
if (value->is_numeric())
|
2021-09-23 21:20:02 +01:00
|
|
|
return value->as_numeric().int_value();
|
2021-09-10 20:37:09 +01:00
|
|
|
return {};
|
2020-06-15 17:29:35 +02:00
|
|
|
}
|
|
|
|
|
2021-07-23 13:18:09 +03:00
|
|
|
Optional<float> StyleProperties::opacity() const
|
|
|
|
{
|
2021-09-10 20:23:57 +01:00
|
|
|
auto maybe_value = property(CSS::PropertyID::Opacity);
|
|
|
|
if (!maybe_value.has_value())
|
2021-07-23 13:18:09 +03:00
|
|
|
return {};
|
2021-09-10 20:23:57 +01:00
|
|
|
auto& value = maybe_value.value();
|
|
|
|
|
2021-09-23 21:20:02 +01:00
|
|
|
if (value->has_number())
|
|
|
|
return clamp(value->to_number(), 0.0f, 1.0f);
|
2021-09-10 20:23:57 +01:00
|
|
|
|
2021-09-23 21:20:02 +01:00
|
|
|
if (value->has_length()) {
|
2021-09-10 20:23:57 +01:00
|
|
|
auto length = value->to_length();
|
|
|
|
if (length.is_percentage())
|
|
|
|
return clamp(length.raw_value() / 100.0f, 0.0f, 1.0f);
|
|
|
|
}
|
2021-07-23 13:18:09 +03:00
|
|
|
|
2021-09-10 20:23:57 +01:00
|
|
|
return {};
|
2021-07-23 13:18:09 +03:00
|
|
|
}
|
|
|
|
|
2021-01-18 17:41:57 +01:00
|
|
|
Optional<CSS::FlexDirection> StyleProperties::flex_direction() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::FlexDirection);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::Row:
|
|
|
|
return CSS::FlexDirection::Row;
|
|
|
|
case CSS::ValueID::RowReverse:
|
|
|
|
return CSS::FlexDirection::RowReverse;
|
|
|
|
case CSS::ValueID::Column:
|
|
|
|
return CSS::FlexDirection::Column;
|
|
|
|
case CSS::ValueID::ColumnReverse:
|
|
|
|
return CSS::FlexDirection::ColumnReverse;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-30 12:11:32 +02:00
|
|
|
Optional<CSS::FlexWrap> StyleProperties::flex_wrap() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::FlexWrap);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::Wrap:
|
|
|
|
return CSS::FlexWrap::Wrap;
|
|
|
|
case CSS::ValueID::Nowrap:
|
|
|
|
return CSS::FlexWrap::Nowrap;
|
|
|
|
case CSS::ValueID::WrapReverse:
|
|
|
|
return CSS::FlexWrap::WrapReverse;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-30 14:23:43 +02:00
|
|
|
Optional<CSS::FlexBasisData> StyleProperties::flex_basis() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::FlexBasis);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
if (value.value()->is_identifier() && value.value()->to_identifier() == CSS::ValueID::Content)
|
|
|
|
return { { CSS::FlexBasis::Content, {} } };
|
|
|
|
|
2021-09-23 19:54:19 +01:00
|
|
|
if (value.value()->has_auto())
|
2021-08-06 22:00:25 +02:00
|
|
|
return { { CSS::FlexBasis::Auto, {} } };
|
|
|
|
|
2021-09-23 21:20:02 +01:00
|
|
|
if (value.value()->has_length())
|
2021-05-30 14:23:43 +02:00
|
|
|
return { { CSS::FlexBasis::Length, value.value()->to_length() } };
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2021-05-30 20:22:25 +02:00
|
|
|
Optional<float> StyleProperties::flex_grow_factor() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::FlexGrow);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
if (value.value()->has_number())
|
|
|
|
return value.value()->to_number();
|
LibWeb: Make '0' always be both a number and a length in CSS
A '0' token can be interpreted both as a Number, and as a Length. This
is problematic as in our CSS parser, we often call parse_css_value()
first, to figure out what something is, and then assign it. So we do not
know in advance whether we want a Length or not. Previously, it always
got parsed as a Length, and then every place that expected a
NumericStyleValue had to also check for a Length(0), which is easy to
forget to do.
In particular, this was causing issues with the `flex` property parsing.
To solve this, we now always parse 0 as a NumericStyleValue, and NSVs of
0 pretend to be a Length(0px) when asked. In two places, we were casting
to a LengthStyleValue* based on is_length(), which no longer works, so
those have been adjusted to use `StyleValue::to_length()` instead. They
also now check for `is_numeric()` first, to avoid the extra conversion
to a Length and back.
Possibly this opens up new issues elsewhere. In my testing it seems
fine, but until we can get CSS test suites running, it's hard to know
for certain.
2021-08-05 15:26:04 +01:00
|
|
|
return {};
|
2021-05-30 20:22:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Optional<float> StyleProperties::flex_shrink_factor() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::FlexShrink);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
if (value.value()->has_number())
|
|
|
|
return value.value()->to_number();
|
LibWeb: Make '0' always be both a number and a length in CSS
A '0' token can be interpreted both as a Number, and as a Length. This
is problematic as in our CSS parser, we often call parse_css_value()
first, to figure out what something is, and then assign it. So we do not
know in advance whether we want a Length or not. Previously, it always
got parsed as a Length, and then every place that expected a
NumericStyleValue had to also check for a Length(0), which is easy to
forget to do.
In particular, this was causing issues with the `flex` property parsing.
To solve this, we now always parse 0 as a NumericStyleValue, and NSVs of
0 pretend to be a Length(0px) when asked. In two places, we were casting
to a LengthStyleValue* based on is_length(), which no longer works, so
those have been adjusted to use `StyleValue::to_length()` instead. They
also now check for `is_numeric()` first, to avoid the extra conversion
to a Length and back.
Possibly this opens up new issues elsewhere. In my testing it seems
fine, but until we can get CSS test suites running, it's hard to know
for certain.
2021-08-05 15:26:04 +01:00
|
|
|
return {};
|
2021-05-30 20:22:25 +02:00
|
|
|
}
|
2021-07-16 18:38:26 +02:00
|
|
|
Optional<CSS::JustifyContent> StyleProperties::justify_content() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::JustifyContent);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::FlexStart:
|
|
|
|
return CSS::JustifyContent::FlexStart;
|
|
|
|
case CSS::ValueID::FlexEnd:
|
|
|
|
return CSS::JustifyContent::FlexEnd;
|
|
|
|
case CSS::ValueID::Center:
|
|
|
|
return CSS::JustifyContent::Center;
|
|
|
|
case CSS::ValueID::SpaceBetween:
|
|
|
|
return CSS::JustifyContent::SpaceBetween;
|
|
|
|
case CSS::ValueID::SpaceAround:
|
|
|
|
return CSS::JustifyContent::SpaceAround;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
2021-05-30 20:22:25 +02:00
|
|
|
|
2021-09-18 17:20:00 +02:00
|
|
|
Vector<CSS::Transformation> StyleProperties::transformations() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::Transform);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
if (value.value()->is_identifier() && value.value()->to_identifier() == CSS::ValueID::None)
|
|
|
|
return {};
|
|
|
|
|
|
|
|
if (!value.value()->is_value_list())
|
|
|
|
return {};
|
|
|
|
|
2021-09-23 21:20:02 +01:00
|
|
|
auto& list = value.value()->as_value_list();
|
2021-09-18 17:20:00 +02:00
|
|
|
|
|
|
|
Vector<CSS::Transformation> transformations;
|
|
|
|
|
|
|
|
for (auto& it : list.values()) {
|
|
|
|
if (!it.is_transformation())
|
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
auto& transformation_style_value = it.as_transformation();
|
2021-09-18 17:20:00 +02:00
|
|
|
CSS::Transformation transformation;
|
|
|
|
transformation.function = transformation_style_value.transform_function();
|
|
|
|
Vector<Variant<CSS::Length, float>> values;
|
|
|
|
for (auto& transformation_value : transformation_style_value.values()) {
|
|
|
|
if (transformation_value.is_length()) {
|
|
|
|
values.append({ transformation_value.to_length() });
|
|
|
|
} else if (transformation_value.is_numeric()) {
|
2021-09-23 21:20:02 +01:00
|
|
|
values.append({ transformation_value.to_number() });
|
2021-09-18 17:20:00 +02:00
|
|
|
} else {
|
|
|
|
dbgln("FIXME: Unsupported value in transform!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
transformation.values = move(values);
|
|
|
|
transformations.append(move(transformation));
|
|
|
|
}
|
|
|
|
return transformations;
|
|
|
|
}
|
|
|
|
|
2021-09-15 18:27:20 +02:00
|
|
|
Optional<CSS::AlignItems> StyleProperties::align_items() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::AlignItems);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::FlexStart:
|
|
|
|
return CSS::AlignItems::FlexStart;
|
|
|
|
case CSS::ValueID::FlexEnd:
|
|
|
|
return CSS::AlignItems::FlexEnd;
|
|
|
|
case CSS::ValueID::Center:
|
|
|
|
return CSS::AlignItems::Center;
|
|
|
|
case CSS::ValueID::Baseline:
|
|
|
|
return CSS::AlignItems::Baseline;
|
|
|
|
case CSS::ValueID::Stretch:
|
|
|
|
return CSS::AlignItems::Stretch;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-14 18:47:00 +01:00
|
|
|
Optional<CSS::Position> StyleProperties::position() const
|
2020-03-23 17:29:15 +01:00
|
|
|
{
|
2020-12-14 18:47:00 +01:00
|
|
|
auto value = property(CSS::PropertyID::Position);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-12-14 18:47:00 +01:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 18:47:00 +01:00
|
|
|
case CSS::ValueID::Static:
|
|
|
|
return CSS::Position::Static;
|
|
|
|
case CSS::ValueID::Relative:
|
|
|
|
return CSS::Position::Relative;
|
|
|
|
case CSS::ValueID::Absolute:
|
|
|
|
return CSS::Position::Absolute;
|
|
|
|
case CSS::ValueID::Fixed:
|
|
|
|
return CSS::Position::Fixed;
|
|
|
|
case CSS::ValueID::Sticky:
|
|
|
|
return CSS::Position::Sticky;
|
|
|
|
default:
|
|
|
|
return {};
|
2020-03-23 17:29:15 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-14 18:32:02 +02:00
|
|
|
bool StyleProperties::operator==(const StyleProperties& other) const
|
|
|
|
{
|
|
|
|
if (m_property_values.size() != other.m_property_values.size())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for (auto& it : m_property_values) {
|
|
|
|
auto jt = other.m_property_values.find(it.key);
|
|
|
|
if (jt == other.m_property_values.end())
|
|
|
|
return false;
|
|
|
|
auto& my_value = *it.value;
|
|
|
|
auto& other_value = *jt->value;
|
|
|
|
if (my_value.type() != other_value.type())
|
|
|
|
return false;
|
2020-12-14 15:56:01 +01:00
|
|
|
if (my_value != other_value)
|
2019-10-14 18:32:02 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2020-03-07 10:27:02 +01:00
|
|
|
|
2020-12-14 18:38:02 +01:00
|
|
|
Optional<CSS::TextAlign> StyleProperties::text_align() const
|
2020-06-13 10:54:58 +02:00
|
|
|
{
|
2020-12-14 18:38:02 +01:00
|
|
|
auto value = property(CSS::PropertyID::TextAlign);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-12-14 18:38:02 +01:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 18:38:02 +01:00
|
|
|
case CSS::ValueID::Left:
|
|
|
|
return CSS::TextAlign::Left;
|
|
|
|
case CSS::ValueID::Center:
|
2020-06-23 23:28:40 +02:00
|
|
|
return CSS::TextAlign::Center;
|
2020-12-14 18:38:02 +01:00
|
|
|
case CSS::ValueID::Right:
|
2020-06-23 23:28:40 +02:00
|
|
|
return CSS::TextAlign::Right;
|
2020-12-14 18:38:02 +01:00
|
|
|
case CSS::ValueID::Justify:
|
2020-06-23 23:28:40 +02:00
|
|
|
return CSS::TextAlign::Justify;
|
2020-12-15 20:39:09 +01:00
|
|
|
case CSS::ValueID::LibwebCenter:
|
|
|
|
return CSS::TextAlign::LibwebCenter;
|
2020-12-14 18:38:02 +01:00
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
2020-06-13 10:54:58 +02:00
|
|
|
}
|
|
|
|
|
2020-06-24 16:37:44 +02:00
|
|
|
Optional<CSS::WhiteSpace> StyleProperties::white_space() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::WhiteSpace);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-06-24 16:37:44 +02:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Normal:
|
2020-06-24 16:37:44 +02:00
|
|
|
return CSS::WhiteSpace::Normal;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Nowrap:
|
2020-06-24 16:37:44 +02:00
|
|
|
return CSS::WhiteSpace::Nowrap;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Pre:
|
2020-06-24 16:37:44 +02:00
|
|
|
return CSS::WhiteSpace::Pre;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::PreLine:
|
2020-06-24 16:37:44 +02:00
|
|
|
return CSS::WhiteSpace::PreLine;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::PreWrap:
|
2020-06-24 16:37:44 +02:00
|
|
|
return CSS::WhiteSpace::PreWrap;
|
2020-12-14 22:22:35 +01:00
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
2020-06-24 16:37:44 +02:00
|
|
|
}
|
|
|
|
|
2020-12-04 16:11:55 +01:00
|
|
|
Optional<CSS::LineStyle> StyleProperties::line_style(CSS::PropertyID property_id) const
|
|
|
|
{
|
|
|
|
auto value = property(property_id);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-12-04 16:11:55 +01:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::None:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::None;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Hidden:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Hidden;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Dotted:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Dotted;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Dashed:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Dashed;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Solid:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Solid;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Double:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Double;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Groove:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Groove;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Ridge:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Ridge;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Inset:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Inset;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Outset:
|
2020-12-04 16:11:55 +01:00
|
|
|
return CSS::LineStyle::Outset;
|
2020-12-14 22:22:35 +01:00
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
2020-12-04 16:11:55 +01:00
|
|
|
}
|
|
|
|
|
2020-06-26 15:08:42 +02:00
|
|
|
Optional<CSS::Float> StyleProperties::float_() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::Float);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-06-26 15:08:42 +02:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::None:
|
2020-06-26 15:08:42 +02:00
|
|
|
return CSS::Float::None;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Left:
|
2020-06-26 15:08:42 +02:00
|
|
|
return CSS::Float::Left;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Right:
|
2020-06-26 15:08:42 +02:00
|
|
|
return CSS::Float::Right;
|
2020-12-14 22:22:35 +01:00
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
2020-06-26 15:08:42 +02:00
|
|
|
}
|
|
|
|
|
2020-12-06 01:45:51 +01:00
|
|
|
Optional<CSS::Clear> StyleProperties::clear() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::Clear);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-12-06 01:45:51 +01:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::None:
|
2020-12-06 01:45:51 +01:00
|
|
|
return CSS::Clear::None;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Left:
|
2020-12-06 01:45:51 +01:00
|
|
|
return CSS::Clear::Left;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Right:
|
2020-12-06 01:45:51 +01:00
|
|
|
return CSS::Clear::Right;
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Both:
|
2020-12-06 01:45:51 +01:00
|
|
|
return CSS::Clear::Both;
|
2020-12-14 22:22:35 +01:00
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
2020-12-06 01:45:51 +01:00
|
|
|
}
|
|
|
|
|
2021-02-21 17:41:00 +00:00
|
|
|
Optional<CSS::Cursor> StyleProperties::cursor() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::Cursor);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2021-02-21 17:41:00 +00:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2021-02-21 17:41:00 +00:00
|
|
|
case CSS::ValueID::Auto:
|
|
|
|
return CSS::Cursor::Auto;
|
|
|
|
case CSS::ValueID::Default:
|
|
|
|
return CSS::Cursor::Default;
|
|
|
|
case CSS::ValueID::None:
|
|
|
|
return CSS::Cursor::None;
|
|
|
|
case CSS::ValueID::ContextMenu:
|
|
|
|
return CSS::Cursor::ContextMenu;
|
|
|
|
case CSS::ValueID::Help:
|
|
|
|
return CSS::Cursor::Help;
|
|
|
|
case CSS::ValueID::Pointer:
|
|
|
|
return CSS::Cursor::Pointer;
|
|
|
|
case CSS::ValueID::Progress:
|
|
|
|
return CSS::Cursor::Progress;
|
|
|
|
case CSS::ValueID::Wait:
|
|
|
|
return CSS::Cursor::Wait;
|
|
|
|
case CSS::ValueID::Cell:
|
|
|
|
return CSS::Cursor::Cell;
|
|
|
|
case CSS::ValueID::Crosshair:
|
|
|
|
return CSS::Cursor::Crosshair;
|
|
|
|
case CSS::ValueID::Text:
|
|
|
|
return CSS::Cursor::Text;
|
|
|
|
case CSS::ValueID::VerticalText:
|
|
|
|
return CSS::Cursor::VerticalText;
|
|
|
|
case CSS::ValueID::Alias:
|
|
|
|
return CSS::Cursor::Alias;
|
|
|
|
case CSS::ValueID::Copy:
|
|
|
|
return CSS::Cursor::Copy;
|
|
|
|
case CSS::ValueID::Move:
|
|
|
|
return CSS::Cursor::Move;
|
|
|
|
case CSS::ValueID::NoDrop:
|
|
|
|
return CSS::Cursor::NoDrop;
|
|
|
|
case CSS::ValueID::NotAllowed:
|
|
|
|
return CSS::Cursor::NotAllowed;
|
|
|
|
case CSS::ValueID::Grab:
|
|
|
|
return CSS::Cursor::Grab;
|
|
|
|
case CSS::ValueID::Grabbing:
|
|
|
|
return CSS::Cursor::Grabbing;
|
|
|
|
case CSS::ValueID::EResize:
|
|
|
|
return CSS::Cursor::EResize;
|
|
|
|
case CSS::ValueID::NResize:
|
|
|
|
return CSS::Cursor::NResize;
|
|
|
|
case CSS::ValueID::NeResize:
|
|
|
|
return CSS::Cursor::NeResize;
|
|
|
|
case CSS::ValueID::NwResize:
|
|
|
|
return CSS::Cursor::NwResize;
|
|
|
|
case CSS::ValueID::SResize:
|
|
|
|
return CSS::Cursor::SResize;
|
|
|
|
case CSS::ValueID::SeResize:
|
|
|
|
return CSS::Cursor::SeResize;
|
|
|
|
case CSS::ValueID::SwResize:
|
|
|
|
return CSS::Cursor::SwResize;
|
|
|
|
case CSS::ValueID::WResize:
|
|
|
|
return CSS::Cursor::WResize;
|
|
|
|
case CSS::ValueID::EwResize:
|
|
|
|
return CSS::Cursor::EwResize;
|
|
|
|
case CSS::ValueID::NsResize:
|
|
|
|
return CSS::Cursor::NsResize;
|
|
|
|
case CSS::ValueID::NeswResize:
|
|
|
|
return CSS::Cursor::NeswResize;
|
|
|
|
case CSS::ValueID::NwseResize:
|
|
|
|
return CSS::Cursor::NwseResize;
|
|
|
|
case CSS::ValueID::ColResize:
|
|
|
|
return CSS::Cursor::ColResize;
|
|
|
|
case CSS::ValueID::RowResize:
|
|
|
|
return CSS::Cursor::RowResize;
|
|
|
|
case CSS::ValueID::AllScroll:
|
|
|
|
return CSS::Cursor::AllScroll;
|
|
|
|
case CSS::ValueID::ZoomIn:
|
|
|
|
return CSS::Cursor::ZoomIn;
|
|
|
|
case CSS::ValueID::ZoomOut:
|
|
|
|
return CSS::Cursor::ZoomOut;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-06-24 16:22:16 +02:00
|
|
|
CSS::Display StyleProperties::display() const
|
|
|
|
{
|
2020-12-14 22:22:35 +01:00
|
|
|
auto value = property(CSS::PropertyID::Display);
|
|
|
|
if (!value.has_value() || !value.value()->is_identifier())
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::Inline);
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::None:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::None);
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Block:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::Block);
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Inline:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::Inline);
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::InlineBlock:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::InlineBlock);
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::ListItem:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::ListItem);
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::Table:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::Table);
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::TableRow:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableRow };
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::TableCell:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableCell };
|
2021-01-07 14:40:02 +01:00
|
|
|
case CSS::ValueID::TableColumn:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableColumn };
|
2021-01-07 14:40:02 +01:00
|
|
|
case CSS::ValueID::TableColumnGroup:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableColumnGroup };
|
2021-01-07 14:40:02 +01:00
|
|
|
case CSS::ValueID::TableCaption:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableCaption };
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::TableRowGroup:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableRowGroup };
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::TableHeaderGroup:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableHeaderGroup };
|
2020-12-14 22:22:35 +01:00
|
|
|
case CSS::ValueID::TableFooterGroup:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display { CSS::Display::Internal::TableFooterGroup };
|
2021-01-18 17:32:34 +01:00
|
|
|
case CSS::ValueID::Flex:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::Flex);
|
2020-12-14 22:22:35 +01:00
|
|
|
default:
|
2021-10-06 17:57:44 +02:00
|
|
|
return CSS::Display::from_short(CSS::Display::Short::Block);
|
2020-12-14 22:22:35 +01:00
|
|
|
}
|
2020-06-24 16:22:16 +02:00
|
|
|
}
|
|
|
|
|
2020-12-15 13:36:27 +01:00
|
|
|
Optional<CSS::TextDecorationLine> StyleProperties::text_decoration_line() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::TextDecorationLine);
|
2021-09-23 21:20:02 +01:00
|
|
|
if (!value.has_value())
|
2020-12-15 13:36:27 +01:00
|
|
|
return {};
|
2021-09-23 21:20:02 +01:00
|
|
|
switch (value.value()->to_identifier()) {
|
2020-12-15 13:36:27 +01:00
|
|
|
case CSS::ValueID::None:
|
|
|
|
return CSS::TextDecorationLine::None;
|
|
|
|
case CSS::ValueID::Underline:
|
|
|
|
return CSS::TextDecorationLine::Underline;
|
|
|
|
case CSS::ValueID::Overline:
|
|
|
|
return CSS::TextDecorationLine::Overline;
|
|
|
|
case CSS::ValueID::LineThrough:
|
|
|
|
return CSS::TextDecorationLine::LineThrough;
|
|
|
|
case CSS::ValueID::Blink:
|
|
|
|
return CSS::TextDecorationLine::Blink;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-15 14:15:49 +01:00
|
|
|
Optional<CSS::TextTransform> StyleProperties::text_transform() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::TextTransform);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::None:
|
|
|
|
return CSS::TextTransform::None;
|
|
|
|
case CSS::ValueID::Lowercase:
|
|
|
|
return CSS::TextTransform::Lowercase;
|
|
|
|
case CSS::ValueID::Uppercase:
|
|
|
|
return CSS::TextTransform::Uppercase;
|
|
|
|
case CSS::ValueID::Capitalize:
|
|
|
|
return CSS::TextTransform::Capitalize;
|
|
|
|
case CSS::ValueID::FullWidth:
|
|
|
|
return CSS::TextTransform::FullWidth;
|
|
|
|
case CSS::ValueID::FullSizeKana:
|
|
|
|
return CSS::TextTransform::FullSizeKana;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-15 16:50:39 +01:00
|
|
|
Optional<CSS::ListStyleType> StyleProperties::list_style_type() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::ListStyleType);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::None:
|
|
|
|
return CSS::ListStyleType::None;
|
|
|
|
case CSS::ValueID::Disc:
|
|
|
|
return CSS::ListStyleType::Disc;
|
|
|
|
case CSS::ValueID::Circle:
|
|
|
|
return CSS::ListStyleType::Circle;
|
|
|
|
case CSS::ValueID::Square:
|
|
|
|
return CSS::ListStyleType::Square;
|
|
|
|
case CSS::ValueID::Decimal:
|
|
|
|
return CSS::ListStyleType::Decimal;
|
2021-04-22 22:14:24 +02:00
|
|
|
case CSS::ValueID::DecimalLeadingZero:
|
|
|
|
return CSS::ListStyleType::DecimalLeadingZero;
|
2021-04-22 23:39:18 +02:00
|
|
|
case CSS::ValueID::LowerAlpha:
|
|
|
|
return CSS::ListStyleType::LowerAlpha;
|
|
|
|
case CSS::ValueID::LowerLatin:
|
|
|
|
return CSS::ListStyleType::LowerLatin;
|
2021-04-22 23:52:15 +02:00
|
|
|
case CSS::ValueID::UpperAlpha:
|
|
|
|
return CSS::ListStyleType::UpperAlpha;
|
|
|
|
case CSS::ValueID::UpperLatin:
|
|
|
|
return CSS::ListStyleType::UpperLatin;
|
2021-07-04 17:17:23 +02:00
|
|
|
case CSS::ValueID::UpperRoman:
|
|
|
|
return CSS::ListStyleType::UpperRoman;
|
|
|
|
case CSS::ValueID::LowerRoman:
|
|
|
|
return CSS::ListStyleType::LowerRoman;
|
2020-12-15 16:50:39 +01:00
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-22 15:20:31 +01:00
|
|
|
Optional<CSS::Overflow> StyleProperties::overflow_x() const
|
|
|
|
{
|
|
|
|
return overflow(CSS::PropertyID::OverflowX);
|
|
|
|
}
|
|
|
|
|
|
|
|
Optional<CSS::Overflow> StyleProperties::overflow_y() const
|
|
|
|
{
|
|
|
|
return overflow(CSS::PropertyID::OverflowY);
|
|
|
|
}
|
|
|
|
|
|
|
|
Optional<CSS::Overflow> StyleProperties::overflow(CSS::PropertyID property_id) const
|
|
|
|
{
|
|
|
|
auto value = property(property_id);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::Auto:
|
|
|
|
return CSS::Overflow::Auto;
|
|
|
|
case CSS::ValueID::Visible:
|
|
|
|
return CSS::Overflow::Visible;
|
|
|
|
case CSS::ValueID::Hidden:
|
|
|
|
return CSS::Overflow::Hidden;
|
|
|
|
case CSS::ValueID::Clip:
|
|
|
|
return CSS::Overflow::Clip;
|
|
|
|
case CSS::ValueID::Scroll:
|
|
|
|
return CSS::Overflow::Scroll;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-05 12:05:35 -04:00
|
|
|
Optional<CSS::Repeat> StyleProperties::background_repeat_x() const
|
2021-04-02 15:41:29 -04:00
|
|
|
{
|
2021-04-05 12:05:35 -04:00
|
|
|
auto value = property(CSS::PropertyID::BackgroundRepeatX);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::NoRepeat:
|
|
|
|
return CSS::Repeat::NoRepeat;
|
|
|
|
case CSS::ValueID::Repeat:
|
|
|
|
return CSS::Repeat::Repeat;
|
|
|
|
case CSS::ValueID::Round:
|
|
|
|
return CSS::Repeat::Round;
|
|
|
|
case CSS::ValueID::Space:
|
|
|
|
return CSS::Repeat::Space;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Optional<CSS::Repeat> StyleProperties::background_repeat_y() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::BackgroundRepeatY);
|
2021-04-02 15:41:29 -04:00
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::NoRepeat:
|
|
|
|
return CSS::Repeat::NoRepeat;
|
|
|
|
case CSS::ValueID::Repeat:
|
|
|
|
return CSS::Repeat::Repeat;
|
|
|
|
case CSS::ValueID::Round:
|
|
|
|
return CSS::Repeat::Round;
|
|
|
|
case CSS::ValueID::Space:
|
|
|
|
return CSS::Repeat::Space;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
2021-07-23 21:22:31 +02:00
|
|
|
|
|
|
|
Optional<CSS::BoxShadowData> StyleProperties::box_shadow() const
|
|
|
|
{
|
|
|
|
auto value_or_error = property(CSS::PropertyID::BoxShadow);
|
|
|
|
if (!value_or_error.has_value())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
auto value = value_or_error.value();
|
|
|
|
if (!value->is_box_shadow())
|
|
|
|
return {};
|
|
|
|
|
2021-09-23 21:20:02 +01:00
|
|
|
auto& box = value->as_box_shadow();
|
|
|
|
return { { box.offset_x(), box.offset_y(), box.blur_radius(), box.color() } };
|
2021-07-23 21:22:31 +02:00
|
|
|
}
|
2021-10-05 16:55:02 +01:00
|
|
|
|
|
|
|
CSS::BoxSizing StyleProperties::box_sizing() const
|
|
|
|
{
|
|
|
|
auto value = property(CSS::PropertyID::BoxSizing);
|
|
|
|
if (!value.has_value())
|
|
|
|
return {};
|
|
|
|
|
|
|
|
switch (value.value()->to_identifier()) {
|
|
|
|
case CSS::ValueID::BorderBox:
|
|
|
|
return CSS::BoxSizing::BorderBox;
|
|
|
|
case CSS::ValueID::ContentBox:
|
|
|
|
return CSS::BoxSizing::ContentBox;
|
|
|
|
default:
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
2020-03-07 10:27:02 +01:00
|
|
|
}
|