summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@gmail.com>2021-07-28 14:10:03 +0100
committerAndreas Kling <kling@serenityos.org>2021-07-31 00:18:11 +0200
commit697bffa3bd988e94fe10659dfeaf604c48071d4b (patch)
tree189d5e5e40365fe6bb532b21a6ba53c86635de73 /Userland/Libraries/LibWeb
parent1b72766e4eeffa6d19b77e9c7c7bd6cff2951bb8 (diff)
downloadserenity-697bffa3bd988e94fe10659dfeaf604c48071d4b.zip
LibWeb: Convert CSS parse_{color,length}() lambdas into methods
This lets us get the Length and Color values directly, without having to create a StyleValue object and then throw it away again, when parsing the box-shadow property in the next commit.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp428
-rw-r--r--Userland/Libraries/LibWeb/CSS/Parser/Parser.h2
2 files changed, 217 insertions, 213 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
index 0a00a88a7b..4641a5b7a0 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.cpp
@@ -1414,74 +1414,75 @@ RefPtr<StyleValue> Parser::parse_keyword_or_custom_value(ParsingContext const&,
return {};
}
-RefPtr<StyleValue> Parser::parse_length_value(ParsingContext const& context, StyleComponentValueRule const& component_value)
+Optional<Length> Parser::parse_length(ParsingContext const& context, StyleComponentValueRule const& component_value)
{
- auto parse_length = [&]() -> Optional<Length> {
- Length::Type type = Length::Type::Undefined;
- Optional<float> numeric_value;
-
- if (component_value.is(Token::Type::Dimension)) {
- auto length_string = component_value.token().m_value.string_view();
- auto unit_string = component_value.token().m_unit.string_view();
-
- if (unit_string.equals_ignoring_case("%")) {
- type = Length::Type::Percentage;
- } else if (unit_string.equals_ignoring_case("px")) {
- type = Length::Type::Px;
- } else if (unit_string.equals_ignoring_case("pt")) {
- type = Length::Type::Pt;
- } else if (unit_string.equals_ignoring_case("pc")) {
- type = Length::Type::Pc;
- } else if (unit_string.equals_ignoring_case("mm")) {
- type = Length::Type::Mm;
- } else if (unit_string.equals_ignoring_case("rem")) {
- type = Length::Type::Rem;
- } else if (unit_string.equals_ignoring_case("em")) {
- type = Length::Type::Em;
- } else if (unit_string.equals_ignoring_case("ex")) {
- type = Length::Type::Ex;
- } else if (unit_string.equals_ignoring_case("vw")) {
- type = Length::Type::Vw;
- } else if (unit_string.equals_ignoring_case("vh")) {
- type = Length::Type::Vh;
- } else if (unit_string.equals_ignoring_case("vmax")) {
- type = Length::Type::Vmax;
- } else if (unit_string.equals_ignoring_case("vmin")) {
- type = Length::Type::Vmin;
- } else if (unit_string.equals_ignoring_case("cm")) {
- type = Length::Type::Cm;
- } else if (unit_string.equals_ignoring_case("in")) {
- type = Length::Type::In;
- } else if (unit_string.equals_ignoring_case("Q")) {
- type = Length::Type::Q;
- } else if (context.in_quirks_mode()) {
- type = Length::Type::Px;
- }
+ Length::Type type = Length::Type::Undefined;
+ Optional<float> numeric_value;
- numeric_value = try_parse_float(length_string);
- } else if (component_value.is(Token::Type::Number)) {
- auto value_string = component_value.token().m_value.string_view();
- if (value_string == "0") {
- type = Length::Type::Px;
- numeric_value = 0;
- } else if (context.in_quirks_mode()) {
- type = Length::Type::Px;
- numeric_value = try_parse_float(value_string);
- }
- } else if (component_value.is(Token::Type::Percentage)) {
+ if (component_value.is(Token::Type::Dimension)) {
+ auto length_string = component_value.token().m_value.string_view();
+ auto unit_string = component_value.token().m_unit.string_view();
+
+ if (unit_string.equals_ignoring_case("%")) {
type = Length::Type::Percentage;
- auto value_string = component_value.token().m_value.string_view();
+ } else if (unit_string.equals_ignoring_case("px")) {
+ type = Length::Type::Px;
+ } else if (unit_string.equals_ignoring_case("pt")) {
+ type = Length::Type::Pt;
+ } else if (unit_string.equals_ignoring_case("pc")) {
+ type = Length::Type::Pc;
+ } else if (unit_string.equals_ignoring_case("mm")) {
+ type = Length::Type::Mm;
+ } else if (unit_string.equals_ignoring_case("rem")) {
+ type = Length::Type::Rem;
+ } else if (unit_string.equals_ignoring_case("em")) {
+ type = Length::Type::Em;
+ } else if (unit_string.equals_ignoring_case("ex")) {
+ type = Length::Type::Ex;
+ } else if (unit_string.equals_ignoring_case("vw")) {
+ type = Length::Type::Vw;
+ } else if (unit_string.equals_ignoring_case("vh")) {
+ type = Length::Type::Vh;
+ } else if (unit_string.equals_ignoring_case("vmax")) {
+ type = Length::Type::Vmax;
+ } else if (unit_string.equals_ignoring_case("vmin")) {
+ type = Length::Type::Vmin;
+ } else if (unit_string.equals_ignoring_case("cm")) {
+ type = Length::Type::Cm;
+ } else if (unit_string.equals_ignoring_case("in")) {
+ type = Length::Type::In;
+ } else if (unit_string.equals_ignoring_case("Q")) {
+ type = Length::Type::Q;
+ } else if (context.in_quirks_mode()) {
+ type = Length::Type::Px;
+ }
+
+ numeric_value = try_parse_float(length_string);
+ } else if (component_value.is(Token::Type::Number)) {
+ auto value_string = component_value.token().m_value.string_view();
+ if (value_string == "0") {
+ type = Length::Type::Px;
+ numeric_value = 0;
+ } else if (context.in_quirks_mode()) {
+ type = Length::Type::Px;
numeric_value = try_parse_float(value_string);
}
+ } else if (component_value.is(Token::Type::Percentage)) {
+ type = Length::Type::Percentage;
+ auto value_string = component_value.token().m_value.string_view();
+ numeric_value = try_parse_float(value_string);
+ }
- if (!numeric_value.has_value())
- return {};
+ if (!numeric_value.has_value())
+ return {};
- return Length(numeric_value.value(), type);
- };
+ return Length(numeric_value.value(), type);
+}
+RefPtr<StyleValue> Parser::parse_length_value(ParsingContext const& context, StyleComponentValueRule const& component_value)
+{
if (component_value.is(Token::Type::Dimension) || component_value.is(Token::Type::Number) || component_value.is(Token::Type::Percentage)) {
- auto length = parse_length();
+ auto length = parse_length(context, component_value);
if (length.has_value())
return LengthStyleValue::create(length.value());
}
@@ -1516,178 +1517,179 @@ RefPtr<StyleValue> Parser::parse_identifier_value(ParsingContext const&, StyleCo
return {};
}
-RefPtr<StyleValue> Parser::parse_color_value(ParsingContext const&, StyleComponentValueRule const& component_value)
+Optional<Color> Parser::parse_color(ParsingContext const&, StyleComponentValueRule const& component_value)
{
// https://www.w3.org/TR/css-color-3/
- auto parse_css_color = [&]() -> Optional<Color> {
- if (component_value.is(Token::Type::Ident)) {
- auto ident = component_value.token().ident();
- if (ident.equals_ignoring_case("transparent"))
- return Color::from_rgba(0x00000000);
-
- auto color = Color::from_string(ident.to_string().to_lowercase());
- if (color.has_value())
- return color;
-
- } else if (component_value.is(Token::Type::Hash)) {
- // FIXME: Read it directly
- auto color = Color::from_string(String::formatted("#{}", component_value.token().m_value.to_string().to_lowercase()));
- if (color.has_value())
- return color;
-
- } else if (component_value.is_function()) {
- auto& function = component_value.function();
- auto& values = function.values();
-
- Vector<Token> params;
- for (size_t i = 0; i < values.size(); ++i) {
- auto& value = values.at(i);
- if (value.is(Token::Type::Whitespace))
- continue;
+ if (component_value.is(Token::Type::Ident)) {
+ auto ident = component_value.token().ident();
+ if (ident.equals_ignoring_case("transparent"))
+ return Color::from_rgba(0x00000000);
+
+ auto color = Color::from_string(ident.to_string().to_lowercase());
+ if (color.has_value())
+ return color;
+
+ } else if (component_value.is(Token::Type::Hash)) {
+ // FIXME: Read it directly
+ auto color = Color::from_string(String::formatted("#{}", component_value.token().m_value.to_string().to_lowercase()));
+ if (color.has_value())
+ return color;
+
+ } else if (component_value.is_function()) {
+ auto& function = component_value.function();
+ auto& values = function.values();
+
+ Vector<Token> params;
+ for (size_t i = 0; i < values.size(); ++i) {
+ auto& value = values.at(i);
+ if (value.is(Token::Type::Whitespace))
+ continue;
+
+ if (value.is(Token::Type::Percentage) || value.is(Token::Type::Number)) {
+ params.append(value.token());
+ // Eat following comma and whitespace
+ while ((i + 1) < values.size()) {
+ auto& next = values.at(i + 1);
+ if (next.is(Token::Type::Whitespace))
+ i++;
+ else if (next.is(Token::Type::Comma))
+ break;
- if (value.is(Token::Type::Percentage) || value.is(Token::Type::Number)) {
- params.append(value.token());
- // Eat following comma and whitespace
- while ((i + 1) < values.size()) {
- auto& next = values.at(i + 1);
- if (next.is(Token::Type::Whitespace))
- i++;
- else if (next.is(Token::Type::Comma))
- break;
-
- return {};
- }
+ return {};
}
}
+ }
- if (function.name().equals_ignoring_case("rgb")) {
- if (params.size() != 3)
- return {};
+ if (function.name().equals_ignoring_case("rgb")) {
+ if (params.size() != 3)
+ return {};
- auto r_val = params[0];
- auto g_val = params[1];
- auto b_val = params[2];
-
- if (r_val.is(Token::NumberType::Integer)
- && g_val.is(Token::NumberType::Integer)
- && b_val.is(Token::NumberType::Integer)) {
-
- auto maybe_r = r_val.m_value.string_view().to_uint<u8>();
- auto maybe_g = g_val.m_value.string_view().to_uint<u8>();
- auto maybe_b = b_val.m_value.string_view().to_uint<u8>();
- if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value())
- return Color(maybe_r.value(), maybe_g.value(), maybe_b.value());
-
- } else if (r_val.is(Token::Type::Percentage)
- && g_val.is(Token::Type::Percentage)
- && b_val.is(Token::Type::Percentage)) {
-
- auto maybe_r = try_parse_float(r_val.m_value.string_view());
- auto maybe_g = try_parse_float(g_val.m_value.string_view());
- auto maybe_b = try_parse_float(b_val.m_value.string_view());
- if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) {
- u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255);
- u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255);
- u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255);
- return Color(r, g, b);
- }
+ auto r_val = params[0];
+ auto g_val = params[1];
+ auto b_val = params[2];
+
+ if (r_val.is(Token::NumberType::Integer)
+ && g_val.is(Token::NumberType::Integer)
+ && b_val.is(Token::NumberType::Integer)) {
+
+ auto maybe_r = r_val.m_value.string_view().to_uint<u8>();
+ auto maybe_g = g_val.m_value.string_view().to_uint<u8>();
+ auto maybe_b = b_val.m_value.string_view().to_uint<u8>();
+ if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value())
+ return Color(maybe_r.value(), maybe_g.value(), maybe_b.value());
+
+ } else if (r_val.is(Token::Type::Percentage)
+ && g_val.is(Token::Type::Percentage)
+ && b_val.is(Token::Type::Percentage)) {
+
+ auto maybe_r = try_parse_float(r_val.m_value.string_view());
+ auto maybe_g = try_parse_float(g_val.m_value.string_view());
+ auto maybe_b = try_parse_float(b_val.m_value.string_view());
+ if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value()) {
+ u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255);
+ u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255);
+ u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255);
+ return Color(r, g, b);
}
- } else if (function.name().equals_ignoring_case("rgba")) {
- if (params.size() != 4)
- return {};
+ }
+ } else if (function.name().equals_ignoring_case("rgba")) {
+ if (params.size() != 4)
+ return {};
- auto r_val = params[0];
- auto g_val = params[1];
- auto b_val = params[2];
- auto a_val = params[3];
-
- if (r_val.is(Token::NumberType::Integer)
- && g_val.is(Token::NumberType::Integer)
- && b_val.is(Token::NumberType::Integer)
- && a_val.is(Token::Type::Number)) {
-
- auto maybe_r = r_val.m_value.string_view().to_uint<u8>();
- auto maybe_g = g_val.m_value.string_view().to_uint<u8>();
- auto maybe_b = b_val.m_value.string_view().to_uint<u8>();
- auto maybe_a = try_parse_float(a_val.m_value.string_view());
- if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) {
- u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255);
- return Color(maybe_r.value(), maybe_g.value(), maybe_b.value(), a);
- }
-
- } else if (r_val.is(Token::Type::Percentage)
- && g_val.is(Token::Type::Percentage)
- && b_val.is(Token::Type::Percentage)
- && a_val.is(Token::Type::Number)) {
-
- auto maybe_r = try_parse_float(r_val.m_value.string_view());
- auto maybe_g = try_parse_float(g_val.m_value.string_view());
- auto maybe_b = try_parse_float(b_val.m_value.string_view());
- auto maybe_a = try_parse_float(a_val.m_value.string_view());
- if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) {
- u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255);
- u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255);
- u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255);
- u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255);
- return Color(r, g, b, a);
- }
+ auto r_val = params[0];
+ auto g_val = params[1];
+ auto b_val = params[2];
+ auto a_val = params[3];
+
+ if (r_val.is(Token::NumberType::Integer)
+ && g_val.is(Token::NumberType::Integer)
+ && b_val.is(Token::NumberType::Integer)
+ && a_val.is(Token::Type::Number)) {
+
+ auto maybe_r = r_val.m_value.string_view().to_uint<u8>();
+ auto maybe_g = g_val.m_value.string_view().to_uint<u8>();
+ auto maybe_b = b_val.m_value.string_view().to_uint<u8>();
+ auto maybe_a = try_parse_float(a_val.m_value.string_view());
+ if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) {
+ u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255);
+ return Color(maybe_r.value(), maybe_g.value(), maybe_b.value(), a);
}
- } else if (function.name().equals_ignoring_case("hsl")) {
- if (params.size() != 3)
- return {};
- auto h_val = params[0];
- auto s_val = params[1];
- auto l_val = params[2];
-
- if (h_val.is(Token::Type::Number)
- && s_val.is(Token::Type::Percentage)
- && l_val.is(Token::Type::Percentage)) {
-
- auto maybe_h = try_parse_float(h_val.m_value.string_view());
- auto maybe_s = try_parse_float(s_val.m_value.string_view());
- auto maybe_l = try_parse_float(l_val.m_value.string_view());
- if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value()) {
- float h = maybe_h.value();
- float s = maybe_s.value() / 100.0f;
- float l = maybe_l.value() / 100.0f;
- return Color::from_hsl(h, s, l);
- }
+ } else if (r_val.is(Token::Type::Percentage)
+ && g_val.is(Token::Type::Percentage)
+ && b_val.is(Token::Type::Percentage)
+ && a_val.is(Token::Type::Number)) {
+
+ auto maybe_r = try_parse_float(r_val.m_value.string_view());
+ auto maybe_g = try_parse_float(g_val.m_value.string_view());
+ auto maybe_b = try_parse_float(b_val.m_value.string_view());
+ auto maybe_a = try_parse_float(a_val.m_value.string_view());
+ if (maybe_r.has_value() && maybe_g.has_value() && maybe_b.has_value() && maybe_a.has_value()) {
+ u8 r = clamp(lroundf(maybe_r.value() * 2.55f), 0, 255);
+ u8 g = clamp(lroundf(maybe_g.value() * 2.55f), 0, 255);
+ u8 b = clamp(lroundf(maybe_b.value() * 2.55f), 0, 255);
+ u8 a = clamp(lroundf(maybe_a.value() * 255.0f), 0, 255);
+ return Color(r, g, b, a);
}
- } else if (function.name().equals_ignoring_case("hsla")) {
- if (params.size() != 4)
- return {};
+ }
+ } else if (function.name().equals_ignoring_case("hsl")) {
+ if (params.size() != 3)
+ return {};
- auto h_val = params[0];
- auto s_val = params[1];
- auto l_val = params[2];
- auto a_val = params[3];
-
- if (h_val.is(Token::Type::Number)
- && s_val.is(Token::Type::Percentage)
- && l_val.is(Token::Type::Percentage)
- && a_val.is(Token::Type::Number)) {
-
- auto maybe_h = try_parse_float(h_val.m_value.string_view());
- auto maybe_s = try_parse_float(s_val.m_value.string_view());
- auto maybe_l = try_parse_float(l_val.m_value.string_view());
- auto maybe_a = try_parse_float(a_val.m_value.string_view());
- if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value() && maybe_a.has_value()) {
- float h = maybe_h.value();
- float s = maybe_s.value() / 100.0f;
- float l = maybe_l.value() / 100.0f;
- float a = maybe_a.value();
- return Color::from_hsla(h, s, l, a);
- }
+ auto h_val = params[0];
+ auto s_val = params[1];
+ auto l_val = params[2];
+
+ if (h_val.is(Token::Type::Number)
+ && s_val.is(Token::Type::Percentage)
+ && l_val.is(Token::Type::Percentage)) {
+
+ auto maybe_h = try_parse_float(h_val.m_value.string_view());
+ auto maybe_s = try_parse_float(s_val.m_value.string_view());
+ auto maybe_l = try_parse_float(l_val.m_value.string_view());
+ if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value()) {
+ float h = maybe_h.value();
+ float s = maybe_s.value() / 100.0f;
+ float l = maybe_l.value() / 100.0f;
+ return Color::from_hsl(h, s, l);
}
}
- return {};
- }
+ } else if (function.name().equals_ignoring_case("hsla")) {
+ if (params.size() != 4)
+ return {};
+ auto h_val = params[0];
+ auto s_val = params[1];
+ auto l_val = params[2];
+ auto a_val = params[3];
+
+ if (h_val.is(Token::Type::Number)
+ && s_val.is(Token::Type::Percentage)
+ && l_val.is(Token::Type::Percentage)
+ && a_val.is(Token::Type::Number)) {
+
+ auto maybe_h = try_parse_float(h_val.m_value.string_view());
+ auto maybe_s = try_parse_float(s_val.m_value.string_view());
+ auto maybe_l = try_parse_float(l_val.m_value.string_view());
+ auto maybe_a = try_parse_float(a_val.m_value.string_view());
+ if (maybe_h.has_value() && maybe_s.has_value() && maybe_l.has_value() && maybe_a.has_value()) {
+ float h = maybe_h.value();
+ float s = maybe_s.value() / 100.0f;
+ float l = maybe_l.value() / 100.0f;
+ float a = maybe_a.value();
+ return Color::from_hsla(h, s, l, a);
+ }
+ }
+ }
return {};
- };
+ }
- auto color = parse_css_color();
+ return {};
+}
+
+RefPtr<StyleValue> Parser::parse_color_value(ParsingContext const& context, StyleComponentValueRule const& component_value)
+{
+ auto color = parse_color(context, component_value);
if (color.has_value())
return ColorStyleValue::create(color.value());
diff --git a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
index 165da97c5e..cbbb236c08 100644
--- a/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
+++ b/Userland/Libraries/LibWeb/CSS/Parser/Parser.h
@@ -165,6 +165,8 @@ private:
[[nodiscard]] Optional<StyleProperty> convert_to_style_property(StyleDeclarationRule&);
static Optional<float> try_parse_float(StringView string);
+ static Optional<Color> parse_color(ParsingContext const&, StyleComponentValueRule const&);
+ static Optional<Length> parse_length(ParsingContext const&, StyleComponentValueRule const&);
static Optional<URL> parse_url_function(ParsingContext const&, StyleComponentValueRule const&);
static RefPtr<StyleValue> parse_keyword_or_custom_value(ParsingContext const&, StyleComponentValueRule const&);