mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-26 17:40:27 +00:00
LibWeb: Implement helpers for parsing CSS numeric types
Frequently we want to parse "anything that's a `<length-percentage>`" or similar, which could be a constant value or a calculation, but didn't have a nice way of doing so. That meant repeating the same "try and parse a dimension, see if it's the right type, then maybe try and parse a calculation and see if that's the right type" boilerplate code. Or more often, forgetting about calculations entirely. These helpers should make that a lot more convenient to do. And they also use TokenStream, so we can eventually drop the old `parse_length()` method.
This commit is contained in:
parent
30dcbc306c
commit
e62d692205
Notes:
sideshowbarker
2024-07-17 06:33:00 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/e62d692205 Pull-request: https://github.com/SerenityOS/serenity/pull/22476 Reviewed-by: https://github.com/Lubrsi
2 changed files with 259 additions and 0 deletions
|
@ -1586,6 +1586,252 @@ Optional<Dimension> Parser::parse_dimension(ComponentValue const& component_valu
|
|||
return {};
|
||||
}
|
||||
|
||||
Optional<AngleOrCalculated> Parser::parse_angle(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_angle()) {
|
||||
transaction.commit();
|
||||
return dimension->angle();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_angle()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<AnglePercentage> Parser::parse_angle_percentage(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_angle_percentage()) {
|
||||
transaction.commit();
|
||||
return dimension->angle_percentage();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_angle_percentage()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<FlexOrCalculated> Parser::parse_flex(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_flex()) {
|
||||
transaction.commit();
|
||||
return dimension->flex();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_flex()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<FrequencyOrCalculated> Parser::parse_frequency(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_frequency()) {
|
||||
transaction.commit();
|
||||
return dimension->frequency();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_frequency()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<FrequencyPercentage> Parser::parse_frequency_percentage(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_frequency_percentage()) {
|
||||
transaction.commit();
|
||||
return dimension->frequency_percentage();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_frequency_percentage()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<IntegerOrCalculated> Parser::parse_integer(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (token.is(Token::Type::Number) && token.token().number().is_integer()) {
|
||||
transaction.commit();
|
||||
return token.token().to_integer();
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_number()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<LengthOrCalculated> Parser::parse_length(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_length()) {
|
||||
transaction.commit();
|
||||
return dimension->length();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_length()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<LengthPercentage> Parser::parse_length_percentage(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_length_percentage()) {
|
||||
transaction.commit();
|
||||
return dimension->length_percentage();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_length_percentage()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<NumberOrCalculated> Parser::parse_number(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (token.is(Token::Type::Number)) {
|
||||
transaction.commit();
|
||||
return token.token().number_value();
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_number()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<ResolutionOrCalculated> Parser::parse_resolution(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_resolution()) {
|
||||
transaction.commit();
|
||||
return dimension->resolution();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_resolution()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<TimeOrCalculated> Parser::parse_time(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_time()) {
|
||||
transaction.commit();
|
||||
return dimension->time();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_time()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<TimePercentage> Parser::parse_time_percentage(TokenStream<ComponentValue>& tokens)
|
||||
{
|
||||
auto transaction = tokens.begin_transaction();
|
||||
auto& token = tokens.next_token();
|
||||
|
||||
if (auto dimension = parse_dimension(token); dimension.has_value()) {
|
||||
if (dimension->is_time_percentage()) {
|
||||
transaction.commit();
|
||||
return dimension->time_percentage();
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (auto calc = parse_calculated_value(token); calc && calc->resolves_to_time_percentage()) {
|
||||
transaction.commit();
|
||||
return calc.release_nonnull();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
Optional<LengthOrCalculated> Parser::parse_source_size_value(ComponentValue const& component_value)
|
||||
{
|
||||
if (component_value.is_ident("auto"sv)) {
|
||||
|
|
|
@ -171,6 +171,19 @@ private:
|
|||
Optional<StyleProperty> convert_to_style_property(Declaration const&);
|
||||
|
||||
Optional<Dimension> parse_dimension(ComponentValue const&);
|
||||
Optional<AngleOrCalculated> parse_angle(TokenStream<ComponentValue>&);
|
||||
Optional<AnglePercentage> parse_angle_percentage(TokenStream<ComponentValue>&);
|
||||
Optional<FlexOrCalculated> parse_flex(TokenStream<ComponentValue>&);
|
||||
Optional<FrequencyOrCalculated> parse_frequency(TokenStream<ComponentValue>&);
|
||||
Optional<FrequencyPercentage> parse_frequency_percentage(TokenStream<ComponentValue>&);
|
||||
Optional<IntegerOrCalculated> parse_integer(TokenStream<ComponentValue>&);
|
||||
Optional<LengthOrCalculated> parse_length(TokenStream<ComponentValue>&);
|
||||
Optional<LengthPercentage> parse_length_percentage(TokenStream<ComponentValue>&);
|
||||
Optional<NumberOrCalculated> parse_number(TokenStream<ComponentValue>&);
|
||||
Optional<ResolutionOrCalculated> parse_resolution(TokenStream<ComponentValue>&);
|
||||
Optional<TimeOrCalculated> parse_time(TokenStream<ComponentValue>&);
|
||||
Optional<TimePercentage> parse_time_percentage(TokenStream<ComponentValue>&);
|
||||
|
||||
Optional<Color> parse_rgb_or_hsl_color(StringView function_name, Vector<ComponentValue> const&);
|
||||
Optional<Color> parse_color(ComponentValue const&);
|
||||
Optional<Length> parse_length(ComponentValue const&);
|
||||
|
|
Loading…
Reference in a new issue