diff --git a/Libraries/LibWeb/CSS/Keywords.json b/Libraries/LibWeb/CSS/Keywords.json index eff596994d6..5c6267ed0b9 100644 --- a/Libraries/LibWeb/CSS/Keywords.json +++ b/Libraries/LibWeb/CSS/Keywords.json @@ -1,4 +1,5 @@ [ + "-infinity", "-libweb-center", "-libweb-left", "-libweb-link", @@ -151,6 +152,7 @@ "dotted", "double", "down", + "e", "e-resize", "ease", "ease-in", @@ -207,6 +209,7 @@ "inactivecaption", "inactivecaptiontext", "infinite", + "infinity", "infobackground", "infotext", "inherit", @@ -285,6 +288,7 @@ "move", "multiply", "n-resize", + "nan", "ne-resize", "nearest", "nesw-resize", @@ -325,6 +329,7 @@ "paint", "paused", "petite-caps", + "pi", "pixelated", "plaintext", "plus-darker", diff --git a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp index 576aa24e8e2..0867caa0afe 100644 --- a/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp +++ b/Libraries/LibWeb/CSS/Parser/ValueParsing.cpp @@ -3340,10 +3340,10 @@ RefPtr Parser::convert_to_calculation_node(CalcParsing::Node co // AD-HOC: We also need to convert tokens into their numeric types. if (component_value->is(Token::Type::Ident)) { - auto maybe_constant = CalculationNode::constant_type_from_string(component_value->token().ident()); - if (!maybe_constant.has_value()) + auto maybe_keyword = keyword_from_string(component_value->token().ident()); + if (!maybe_keyword.has_value()) return nullptr; - return ConstantCalculationNode::create(*maybe_constant); + return NumericCalculationNode::from_keyword(*maybe_keyword, context); } if (component_value->is(Token::Type::Number)) diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp index f9884a30328..dab84206db0 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.cpp @@ -129,26 +129,6 @@ static NonnullRefPtr simplify_2_children(T const& original, Non return original; } -Optional CalculationNode::constant_type_from_string(StringView string) -{ - if (string.equals_ignoring_ascii_case("e"sv)) - return CalculationNode::ConstantType::E; - - if (string.equals_ignoring_ascii_case("pi"sv)) - return CalculationNode::ConstantType::Pi; - - if (string.equals_ignoring_ascii_case("infinity"sv)) - return CalculationNode::ConstantType::Infinity; - - if (string.equals_ignoring_ascii_case("-infinity"sv)) - return CalculationNode::ConstantType::MinusInfinity; - - if (string.equals_ignoring_ascii_case("NaN"sv)) - return CalculationNode::ConstantType::NaN; - - return {}; -} - CalculationNode::CalculationNode(Type type, Optional numeric_type) : m_type(type) , m_numeric_type(move(numeric_type)) @@ -228,6 +208,29 @@ NonnullRefPtr NumericCalculationNode::create(NumericValu return adopt_ref(*new (nothrow) NumericCalculationNode(move(value), numeric_type)); } +RefPtr NumericCalculationNode::from_keyword(Keyword keyword, CalculationContext const& context) +{ + switch (keyword) { + case Keyword::E: + // https://drafts.csswg.org/css-values-4/#valdef-calc-e + return create(Number { Number::Type::Number, AK::E }, context); + case Keyword::Pi: + // https://drafts.csswg.org/css-values-4/#valdef-calc-pi + return create(Number { Number::Type::Number, AK::Pi }, context); + case Keyword::Infinity: + // https://drafts.csswg.org/css-values-4/#valdef-calc-infinity + return create(Number { Number::Type::Number, AK::Infinity }, context); + case Keyword::NegativeInfinity: + // https://drafts.csswg.org/css-values-4/#valdef-calc--infinity + return create(Number { Number::Type::Number, -AK::Infinity }, context); + case Keyword::Nan: + // https://drafts.csswg.org/css-values-4/#valdef-calc-nan + return create(Number { Number::Type::Number, AK::NaN }, context); + default: + return nullptr; + } +} + NumericCalculationNode::NumericCalculationNode(NumericValue value, CSSNumericType numeric_type) : CalculationNode(Type::Numeric, move(numeric_type)) , m_value(move(value)) @@ -1114,73 +1117,6 @@ bool SignCalculationNode::equals(CalculationNode const& other) const return m_value->equals(*static_cast(other).m_value); } -NonnullRefPtr ConstantCalculationNode::create(ConstantType constant) -{ - return adopt_ref(*new (nothrow) ConstantCalculationNode(constant)); -} - -ConstantCalculationNode::ConstantCalculationNode(ConstantType constant) - // https://www.w3.org/TR/css-values-4/#determine-the-type-of-a-calculation - // Anything else is a terminal value, whose type is determined based on its CSS type: - // -> - // the type is «[ ]» (empty map) - : CalculationNode(Type::Constant, CSSNumericType {}) - , m_constant(constant) -{ -} - -ConstantCalculationNode::~ConstantCalculationNode() = default; - -String ConstantCalculationNode::to_string() const -{ - switch (m_constant) { - case CalculationNode::ConstantType::E: - return "e"_string; - case CalculationNode::ConstantType::Pi: - return "pi"_string; - case CalculationNode::ConstantType::Infinity: - return "infinity"_string; - case CalculationNode::ConstantType::MinusInfinity: - return "-infinity"_string; - case CalculationNode::ConstantType::NaN: - return "NaN"_string; - } - - VERIFY_NOT_REACHED(); -} - -CalculatedStyleValue::CalculationResult ConstantCalculationNode::resolve(CalculationResolutionContext const&) const -{ - switch (m_constant) { - case ConstantType::E: - return { AK::E, CSSNumericType {} }; - case ConstantType::Pi: - return { AK::Pi, CSSNumericType {} }; - case ConstantType::Infinity: - return { AK::Infinity, CSSNumericType {} }; - case ConstantType::MinusInfinity: - return { -AK::Infinity, CSSNumericType {} }; - case ConstantType::NaN: - return { AK::NaN, CSSNumericType {} }; - } - - VERIFY_NOT_REACHED(); -} - -void ConstantCalculationNode::dump(StringBuilder& builder, int indent) const -{ - builder.appendff("{: >{}}CONSTANT: {}\n", "", indent, to_string()); -} - -bool ConstantCalculationNode::equals(CalculationNode const& other) const -{ - if (this == &other) - return true; - if (type() != other.type()) - return false; - return m_constant == static_cast(other).m_constant; -} - NonnullRefPtr SinCalculationNode::create(NonnullRefPtr value) { return adopt_ref(*new (nothrow) SinCalculationNode(move(value))); @@ -2795,24 +2731,13 @@ NonnullRefPtr simplify_a_calculation_tree(CalculationNode const } // 3. If root is a that can be resolved, return what it resolves to, simplified. - // NOTE: This is handled below. + // NOTE: We already resolve our ``s at parse-time. + // FIXME: Revisit this once we support any keywords that need resolving later. // 4. Otherwise, return root. return root; } - // AD-HOC: Step 1.3 is done here as we have a separate node type for them. - if (root->type() == CalculationNode::Type::Constant) { - auto const& root_constant = as(*root); - - // 3. If root is a that can be resolved, return what it resolves to, simplified. - // FIXME: At the moment these are all constant numbers. Revisit this once that's not the case. - // (Notably, relative-color syntax allows some other keywords that are relative to the color.) - auto resolved = root_constant.resolve(resolution_context); - VERIFY(resolved.type()->matches_number({})); - return NumericCalculationNode::create(Number { Number::Type::Number, resolved.value() }, context); - } - // 2. If root is any other leaf node (not an operator node): // FIXME: We don't yet allow any of these inside a calculation tree. Revisit once we do. diff --git a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h index 4848510e11b..9a2ab01c7bc 100644 --- a/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h +++ b/Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h @@ -128,17 +128,6 @@ private: // https://www.w3.org/TR/css-values-4/#calculation-tree class CalculationNode : public RefCounted { public: - // https://drafts.csswg.org/css-values-4/#calc-constants - // https://drafts.csswg.org/css-values-4/#calc-error-constants - enum class ConstantType { - E, - Pi, - NaN, - Infinity, - MinusInfinity, - }; - static Optional constant_type_from_string(StringView); - enum class Type { Numeric, // NOTE: Currently, any value with a `var()` or `attr()` function in it is always an @@ -162,10 +151,6 @@ public: Abs, Sign, - // Constant Nodes - // https://drafts.csswg.org/css-values-4/#calc-constants - Constant, - // Trigonometric functions, a sub-type of operator node // https://drafts.csswg.org/css-values-4/#trig-funcs Sin, @@ -260,6 +245,7 @@ private: class NumericCalculationNode final : public CalculationNode { public: static NonnullRefPtr create(NumericValue, CalculationContext const&); + static RefPtr from_keyword(Keyword, CalculationContext const&); ~NumericCalculationNode(); virtual String to_string() const override; @@ -461,24 +447,6 @@ private: NonnullRefPtr m_value; }; -class ConstantCalculationNode final : public CalculationNode { -public: - static NonnullRefPtr create(CalculationNode::ConstantType); - ~ConstantCalculationNode(); - - virtual String to_string() const override; - virtual bool contains_percentage() const override { return false; } - virtual CalculatedStyleValue::CalculationResult resolve(CalculationResolutionContext const&) const override; - virtual NonnullRefPtr with_simplified_children(CalculationContext const&, CalculationResolutionContext const&) const override { return *this; } - - virtual void dump(StringBuilder&, int indent) const override; - virtual bool equals(CalculationNode const&) const override; - -private: - ConstantCalculationNode(ConstantType); - CalculationNode::ConstantType m_constant; -}; - class SinCalculationNode final : public CalculationNode { public: static NonnullRefPtr create(NonnullRefPtr); diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSKeyword.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSKeyword.cpp index e0eade677dd..b183cec3981 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSKeyword.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSKeyword.cpp @@ -39,6 +39,13 @@ ErrorOr serenity_main(Main::Arguments arguments) return 0; } +static String keyword_name(String const& dashy_name) +{ + if (dashy_name == "-infinity"sv) + return "NegativeInfinity"_string; + return title_casify(dashy_name); +} + ErrorOr generate_header_file(JsonArray& keyword_data, Core::File& file) { StringBuilder builder; @@ -57,7 +64,7 @@ enum class Keyword { keyword_data.for_each([&](auto& name) { auto member_generator = generator.fork(); - member_generator.set("name:titlecase", title_casify(name.as_string())); + member_generator.set("name:titlecase", keyword_name(name.as_string())); member_generator.append(R"~~~( @name:titlecase@, @@ -107,7 +114,7 @@ HashMap g_stringv keyword_data.for_each([&](auto& name) { auto member_generator = generator.fork(); member_generator.set("name", name.as_string()); - member_generator.set("name:titlecase", title_casify(name.as_string())); + member_generator.set("name:titlecase", keyword_name(name.as_string())); member_generator.append(R"~~~( {"@name@"sv, Keyword::@name:titlecase@}, )~~~"); @@ -128,7 +135,7 @@ StringView string_from_keyword(Keyword keyword) { keyword_data.for_each([&](auto& name) { auto member_generator = generator.fork(); member_generator.set("name", name.as_string()); - member_generator.set("name:titlecase", title_casify(name.as_string())); + member_generator.set("name:titlecase", keyword_name(name.as_string())); member_generator.append(R"~~~( case Keyword::@name:titlecase@: return "@name@"sv; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSMathFunctions.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSMathFunctions.cpp index 512fc56d5f9..a92b1d488b4 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSMathFunctions.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSMathFunctions.cpp @@ -251,7 +251,7 @@ RefPtr Parser::parse_math_function(Function const& function, Ca // NOTE: We have exactly one default value in the data right now, and it's a ``, // so that's all we handle. if (auto default_value = parameter.get_string("default"sv); default_value.has_value()) { - parameter_generator.set("parameter_default", MUST(String::formatted(" = ConstantCalculationNode::create(CalculationNode::constant_type_from_string(\"{}\"sv).value())", default_value.value()))); + parameter_generator.set("parameter_default", MUST(String::formatted(" = NumericCalculationNode::from_keyword(Keyword::{}, context)", title_casify(default_value.value())))); } else { parameter_generator.set("parameter_default", ""_string); }