Skip to content

Commit 6025805

Browse files
Calme1709AtkinsSJ
authored andcommitted
LibWeb/Meta: Compute the accepted value range for CalculationContexts
This currently only applies to property-level calculation contexts, more work to be done to generate accepted ranges for other calculation contexts (e.g. within transformation functions, color functions, etc)
1 parent 2af7016 commit 6025805

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

Libraries/LibWeb/CSS/Parser/ValueParsing.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4076,6 +4076,7 @@ RefPtr<StyleValue const> Parser::parse_calculated_value(ComponentValue const& co
40764076
return CalculationContext {
40774077
.percentages_resolve_as = property_resolves_percentages_relative_to(property_id),
40784078
.resolve_numbers_as_integers = property_accepts_type(property_id, ValueType::Integer),
4079+
.accepted_type_ranges = property_accepted_type_ranges(property_id),
40794080
};
40804081
},
40814082
[](FunctionContext const& function) -> Optional<CalculationContext> {

Libraries/LibWeb/CSS/StyleValues/CalculatedStyleValue.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class CalculationNode;
3030
struct CalculationContext {
3131
Optional<ValueType> percentages_resolve_as {};
3232
bool resolve_numbers_as_integers = false;
33+
AcceptedTypeRangeMap accepted_type_ranges {};
3334
};
3435

3536
class CalculatedStyleValue : public StyleValue {

Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateCSSPropertyID.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@ bool is_inherited_property(PropertyID);
257257
NonnullRefPtr<StyleValue const> property_initial_value(PropertyID);
258258
259259
bool property_accepts_type(PropertyID, ValueType);
260+
struct AcceptedTypeRange {
261+
float min;
262+
float max;
263+
};
264+
using AcceptedTypeRangeMap = HashMap<ValueType, AcceptedTypeRange>;
265+
AcceptedTypeRangeMap property_accepted_type_ranges(PropertyID);
260266
bool property_accepts_keyword(PropertyID, Keyword);
261267
Optional<Keyword> resolve_legacy_value_alias(PropertyID, Keyword);
262268
Optional<ValueType> property_resolves_percentages_relative_to(PropertyID);
@@ -852,6 +858,71 @@ bool property_accepts_type(PropertyID property_id, ValueType value_type)
852858
}
853859
}
854860
861+
AcceptedTypeRangeMap property_accepted_type_ranges(PropertyID property_id)
862+
{
863+
switch (property_id) {
864+
)~~~");
865+
866+
properties.for_each_member([&](auto& name, auto& value) {
867+
VERIFY(value.is_object());
868+
auto& object = value.as_object();
869+
if (is_legacy_alias(object))
870+
return;
871+
872+
if (auto maybe_valid_types = object.get_array("valid-types"sv); maybe_valid_types.has_value() && !maybe_valid_types->is_empty()) {
873+
auto& valid_types = maybe_valid_types.value();
874+
auto property_generator = generator.fork();
875+
property_generator.set("name:titlecase", title_casify(name));
876+
877+
StringBuilder ranges_builder;
878+
879+
for (auto& type : valid_types.values()) {
880+
VERIFY(type.is_string());
881+
882+
Vector<String> type_parts = MUST(type.as_string().split(' '));
883+
884+
if (type_parts.size() < 2)
885+
continue;
886+
887+
auto type_name = type_parts.first();
888+
889+
if (type_name == "custom-ident")
890+
continue;
891+
892+
// Drop the brackets on the range e.g. "[-∞,∞]" -> "-∞,∞"
893+
auto type_range = MUST(type_parts.get(1)->substring_from_byte_offset(1, type_parts.get(1)->byte_count() - 2));
894+
895+
auto limits = MUST(type_range.split(','));
896+
897+
if (limits.size() != 2)
898+
VERIFY_NOT_REACHED();
899+
900+
// FIXME: Use min and max values for i32 instead of float where applicable (e.g. for "integer")
901+
auto min = limits.get(0) == "-∞" ? "AK::NumericLimits<float>::lowest()"_string : *limits.get(0);
902+
auto max = limits.get(1) == "" ? "AK::NumericLimits<float>::max()"_string : *limits.get(1);
903+
904+
if (!ranges_builder.is_empty())
905+
ranges_builder.appendff(", ");
906+
907+
ranges_builder.appendff("{{ ValueType::{}, {{ {}, {} }} }}", title_casify(type_name), min, max);
908+
}
909+
910+
property_generator.set("ranges", ranges_builder.to_string_without_validation());
911+
912+
property_generator.append(R"~~~(
913+
case PropertyID::@name:titlecase@: {
914+
return { @ranges@ };
915+
})~~~");
916+
}
917+
});
918+
919+
generator.append(R"~~~(
920+
default: {
921+
return { };
922+
}
923+
}
924+
}
925+
855926
bool property_accepts_keyword(PropertyID property_id, Keyword keyword)
856927
{
857928
switch (property_id) {

0 commit comments

Comments
 (0)