mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 07:30:19 +00:00
LibWeb: Remove most of the copying of CSS::Parser::ComponentValue
This class was being copied all over the place, however, most of these cases can be easily prevented with `auto const&` or `NonnullRawPtr<>`. It also didn't have a move constructor, causing `Vector` to copy on every resize as well. Removing all these copies results in an almost 15% increase in performance for CSS parsing, as measured with callgrind.
This commit is contained in:
parent
e50b9f5478
commit
0de9818470
Notes:
github-actions[bot]
2024-11-06 09:44:18 +00:00
Author: https://github.com/yyny Commit: https://github.com/LadybirdBrowser/ladybird/commit/0de9818470d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2093 Reviewed-by: https://github.com/AtkinsSJ ✅
5 changed files with 60 additions and 54 deletions
|
@ -17,6 +17,9 @@ namespace Web::CSS::Parser {
|
||||||
|
|
||||||
// https://drafts.csswg.org/css-syntax/#component-value
|
// https://drafts.csswg.org/css-syntax/#component-value
|
||||||
class ComponentValue {
|
class ComponentValue {
|
||||||
|
AK_MAKE_DEFAULT_COPYABLE(ComponentValue);
|
||||||
|
AK_MAKE_DEFAULT_MOVABLE(ComponentValue);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ComponentValue(Token);
|
ComponentValue(Token);
|
||||||
explicit ComponentValue(Function&&);
|
explicit ComponentValue(Function&&);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
|
#include <AK/NonnullRawPtr.h>
|
||||||
#include <LibWeb/CSS/Parser/Parser.h>
|
#include <LibWeb/CSS/Parser/Parser.h>
|
||||||
#include <LibWeb/CSS/StyleValues/ConicGradientStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/ConicGradientStyleValue.h>
|
||||||
#include <LibWeb/CSS/StyleValues/LinearGradientStyleValue.h>
|
#include <LibWeb/CSS/StyleValues/LinearGradientStyleValue.h>
|
||||||
|
@ -297,13 +298,13 @@ RefPtr<CSSStyleValue> Parser::parse_conic_gradient_function(TokenStream<Componen
|
||||||
|
|
||||||
// conic-gradient( [ [ from <angle> ]? [ at <position> ]? ] ||
|
// conic-gradient( [ [ from <angle> ]? [ at <position> ]? ] ||
|
||||||
// <color-interpolation-method> , <angular-color-stop-list> )
|
// <color-interpolation-method> , <angular-color-stop-list> )
|
||||||
auto token = tokens.next_token();
|
NonnullRawPtr<ComponentValue const> token = tokens.next_token();
|
||||||
bool got_from_angle = false;
|
bool got_from_angle = false;
|
||||||
bool got_color_interpolation_method = false;
|
bool got_color_interpolation_method = false;
|
||||||
bool got_at_position = false;
|
bool got_at_position = false;
|
||||||
while (token.is(Token::Type::Ident)) {
|
while (token->is(Token::Type::Ident)) {
|
||||||
auto consume_identifier = [&](auto identifier) {
|
auto consume_identifier = [&](auto identifier) {
|
||||||
auto token_string = token.token().ident();
|
auto token_string = token->token().ident();
|
||||||
if (token_string.equals_ignoring_ascii_case(identifier)) {
|
if (token_string.equals_ignoring_ascii_case(identifier)) {
|
||||||
tokens.discard_a_token();
|
tokens.discard_a_token();
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
|
@ -319,7 +320,7 @@ RefPtr<CSSStyleValue> Parser::parse_conic_gradient_function(TokenStream<Componen
|
||||||
if (!tokens.has_next_token())
|
if (!tokens.has_next_token())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
auto angle_token = tokens.consume_a_token();
|
auto const& angle_token = tokens.consume_a_token();
|
||||||
if (!angle_token.is(Token::Type::Dimension))
|
if (!angle_token.is(Token::Type::Dimension))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto angle = angle_token.token().dimension_value();
|
auto angle = angle_token.token().dimension_value();
|
||||||
|
|
|
@ -121,7 +121,7 @@ NonnullRefPtr<MediaQuery> Parser::parse_media_query(TokenStream<ComponentValue>&
|
||||||
return media_query;
|
return media_query;
|
||||||
|
|
||||||
// `[ and <media-condition-without-or> ]?`
|
// `[ and <media-condition-without-or> ]?`
|
||||||
if (auto maybe_and = tokens.consume_a_token(); maybe_and.is_ident("and"sv)) {
|
if (auto const& maybe_and = tokens.consume_a_token(); maybe_and.is_ident("and"sv)) {
|
||||||
if (auto media_condition = parse_media_condition(tokens, MediaCondition::AllowOr::No)) {
|
if (auto media_condition = parse_media_condition(tokens, MediaCondition::AllowOr::No)) {
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
if (tokens.has_next_token())
|
if (tokens.has_next_token())
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <AK/CharacterTypes.h>
|
#include <AK/CharacterTypes.h>
|
||||||
#include <AK/Debug.h>
|
#include <AK/Debug.h>
|
||||||
#include <AK/GenericLexer.h>
|
#include <AK/GenericLexer.h>
|
||||||
|
#include <AK/NonnullRawPtr.h>
|
||||||
#include <AK/SourceLocation.h>
|
#include <AK/SourceLocation.h>
|
||||||
#include <AK/TemporaryChange.h>
|
#include <AK/TemporaryChange.h>
|
||||||
#include <LibWeb/CSS/CSSStyleDeclaration.h>
|
#include <LibWeb/CSS/CSSStyleDeclaration.h>
|
||||||
|
@ -152,7 +153,7 @@ Vector<Rule> Parser::parse_a_stylesheets_contents(TokenStream<T>& input)
|
||||||
CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<URL::URL> location)
|
CSSStyleSheet* Parser::parse_as_css_stylesheet(Optional<URL::URL> location)
|
||||||
{
|
{
|
||||||
// To parse a CSS stylesheet, first parse a stylesheet.
|
// To parse a CSS stylesheet, first parse a stylesheet.
|
||||||
auto style_sheet = parse_a_stylesheet(m_token_stream, {});
|
auto const& style_sheet = parse_a_stylesheet(m_token_stream, {});
|
||||||
|
|
||||||
// Interpret all of the resulting top-level qualified rules as style rules, defined below.
|
// Interpret all of the resulting top-level qualified rules as style rules, defined below.
|
||||||
JS::MarkedVector<CSSRule*> rules(m_context.realm().heap());
|
JS::MarkedVector<CSSRule*> rules(m_context.realm().heap());
|
||||||
|
@ -672,7 +673,7 @@ Vector<RuleOrListOfDeclarations> Parser::consume_a_blocks_contents(TokenStream<T
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
ComponentValue Parser::consume_a_component_value(TokenStream<ComponentValue>& tokens)
|
ComponentValue Parser::consume_a_component_value<ComponentValue>(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
// Note: This overload is called once tokens have already been converted into component values,
|
// Note: This overload is called once tokens have already been converted into component values,
|
||||||
// so we do not need to do the work in the more general overload.
|
// so we do not need to do the work in the more general overload.
|
||||||
|
@ -791,7 +792,7 @@ SimpleBlock Parser::consume_a_simple_block(TokenStream<T>& input)
|
||||||
// anything else
|
// anything else
|
||||||
{
|
{
|
||||||
// Consume a component value from input and append the result to block’s value.
|
// Consume a component value from input and append the result to block’s value.
|
||||||
block.value.empend(consume_a_component_value(input));
|
block.value.empend(move(consume_a_component_value(input)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1130,7 +1131,7 @@ Optional<ComponentValue> Parser::parse_a_component_value(TokenStream<T>& input)
|
||||||
|
|
||||||
// 6. If input is empty, return value. Otherwise, return a syntax error.
|
// 6. If input is empty, return value. Otherwise, return a syntax error.
|
||||||
if (input.is_empty())
|
if (input.is_empty())
|
||||||
return value;
|
return move(value);
|
||||||
// FIXME: Syntax error
|
// FIXME: Syntax error
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1468,7 +1469,7 @@ RefPtr<CSSStyleValue> Parser::parse_basic_shape_value(TokenStream<ComponentValue
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Optional<Gfx::WindingRule> fill_rule;
|
Optional<Gfx::WindingRule> fill_rule;
|
||||||
auto first_argument = arguments[0];
|
auto const& first_argument = arguments[0];
|
||||||
TokenStream first_argument_tokens { first_argument };
|
TokenStream first_argument_tokens { first_argument };
|
||||||
|
|
||||||
first_argument_tokens.discard_whitespace();
|
first_argument_tokens.discard_whitespace();
|
||||||
|
@ -1536,6 +1537,7 @@ bool Parser::is_valid_in_the_current_context(QualifiedRule&)
|
||||||
// FIXME: Implement this check
|
// FIXME: Implement this check
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::PropertiesAndCustomProperties Parser::extract_properties(Vector<RuleOrListOfDeclarations> const& rules_and_lists_of_declarations)
|
Parser::PropertiesAndCustomProperties Parser::extract_properties(Vector<RuleOrListOfDeclarations> const& rules_and_lists_of_declarations)
|
||||||
{
|
{
|
||||||
PropertiesAndCustomProperties result;
|
PropertiesAndCustomProperties result;
|
||||||
|
@ -1645,7 +1647,7 @@ RefPtr<CustomIdentStyleValue> Parser::parse_custom_ident_value(TokenStream<Compo
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
|
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (!token.is(Token::Type::Ident))
|
if (!token.is(Token::Type::Ident))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
auto custom_ident = token.token().ident();
|
auto custom_ident = token.token().ident();
|
||||||
|
@ -2050,7 +2052,7 @@ Optional<Ratio> Parser::parse_ratio(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto two_value_transaction = tokens.begin_transaction();
|
auto two_value_transaction = tokens.begin_transaction();
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
auto solidus = tokens.consume_a_token();
|
auto const& solidus = tokens.consume_a_token();
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
auto maybe_denominator = read_number_value(tokens.consume_a_token());
|
auto maybe_denominator = read_number_value(tokens.consume_a_token());
|
||||||
|
|
||||||
|
@ -2359,7 +2361,7 @@ RefPtr<CSSStyleValue> Parser::parse_dimension_value(TokenStream<ComponentValue>&
|
||||||
|
|
||||||
RefPtr<CSSStyleValue> Parser::parse_integer_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue> Parser::parse_integer_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto peek_token = tokens.next_token();
|
auto const& peek_token = tokens.next_token();
|
||||||
if (peek_token.is(Token::Type::Number) && peek_token.token().number().is_integer()) {
|
if (peek_token.is(Token::Type::Number) && peek_token.token().number().is_integer()) {
|
||||||
tokens.discard_a_token(); // integer
|
tokens.discard_a_token(); // integer
|
||||||
return IntegerStyleValue::create(peek_token.token().number().integer_value());
|
return IntegerStyleValue::create(peek_token.token().number().integer_value());
|
||||||
|
@ -2374,7 +2376,7 @@ RefPtr<CSSStyleValue> Parser::parse_integer_value(TokenStream<ComponentValue>& t
|
||||||
|
|
||||||
RefPtr<CSSStyleValue> Parser::parse_number_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue> Parser::parse_number_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto peek_token = tokens.next_token();
|
auto const& peek_token = tokens.next_token();
|
||||||
if (peek_token.is(Token::Type::Number)) {
|
if (peek_token.is(Token::Type::Number)) {
|
||||||
tokens.discard_a_token(); // number
|
tokens.discard_a_token(); // number
|
||||||
return NumberStyleValue::create(peek_token.token().number().value());
|
return NumberStyleValue::create(peek_token.token().number().value());
|
||||||
|
@ -2390,7 +2392,7 @@ RefPtr<CSSStyleValue> Parser::parse_number_value(TokenStream<ComponentValue>& to
|
||||||
RefPtr<CSSStyleValue> Parser::parse_number_percentage_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue> Parser::parse_number_percentage_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
// Parses [<percentage> | <number>] (which is equivalent to [<alpha-value>])
|
// Parses [<percentage> | <number>] (which is equivalent to [<alpha-value>])
|
||||||
auto peek_token = tokens.next_token();
|
auto const& peek_token = tokens.next_token();
|
||||||
if (peek_token.is(Token::Type::Number)) {
|
if (peek_token.is(Token::Type::Number)) {
|
||||||
tokens.discard_a_token(); // number
|
tokens.discard_a_token(); // number
|
||||||
return NumberStyleValue::create(peek_token.token().number().value());
|
return NumberStyleValue::create(peek_token.token().number().value());
|
||||||
|
@ -2436,7 +2438,7 @@ RefPtr<CSSStyleValue> Parser::parse_number_percentage_none_value(TokenStream<Com
|
||||||
|
|
||||||
RefPtr<CSSStyleValue> Parser::parse_percentage_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue> Parser::parse_percentage_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto peek_token = tokens.next_token();
|
auto const& peek_token = tokens.next_token();
|
||||||
if (peek_token.is(Token::Type::Percentage)) {
|
if (peek_token.is(Token::Type::Percentage)) {
|
||||||
tokens.discard_a_token(); // percentage
|
tokens.discard_a_token(); // percentage
|
||||||
return PercentageStyleValue::create(Percentage(peek_token.token().percentage()));
|
return PercentageStyleValue::create(Percentage(peek_token.token().percentage()));
|
||||||
|
@ -2581,7 +2583,7 @@ RefPtr<CSSStyleValue> Parser::parse_time_percentage_value(TokenStream<ComponentV
|
||||||
|
|
||||||
RefPtr<CSSStyleValue> Parser::parse_keyword_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue> Parser::parse_keyword_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto peek_token = tokens.next_token();
|
auto const& peek_token = tokens.next_token();
|
||||||
if (peek_token.is(Token::Type::Ident)) {
|
if (peek_token.is(Token::Type::Ident)) {
|
||||||
auto keyword = keyword_from_string(peek_token.token().ident());
|
auto keyword = keyword_from_string(peek_token.token().ident());
|
||||||
if (keyword.has_value()) {
|
if (keyword.has_value()) {
|
||||||
|
@ -2597,7 +2599,7 @@ RefPtr<CSSStyleValue> Parser::parse_keyword_value(TokenStream<ComponentValue>& t
|
||||||
RefPtr<CSSStyleValue> Parser::parse_rect_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<CSSStyleValue> Parser::parse_rect_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto function_token = tokens.consume_a_token();
|
auto const& function_token = tokens.consume_a_token();
|
||||||
if (!function_token.is_function("rect"sv))
|
if (!function_token.is_function("rect"sv))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -3207,7 +3209,7 @@ RefPtr<CSSStyleValue> Parser::parse_color_function(TokenStream<ComponentValue>&
|
||||||
auto inner_tokens = TokenStream { function_token.function().value };
|
auto inner_tokens = TokenStream { function_token.function().value };
|
||||||
inner_tokens.discard_whitespace();
|
inner_tokens.discard_whitespace();
|
||||||
|
|
||||||
auto maybe_color_space = inner_tokens.consume_a_token();
|
auto const& maybe_color_space = inner_tokens.consume_a_token();
|
||||||
inner_tokens.discard_whitespace();
|
inner_tokens.discard_whitespace();
|
||||||
if (!any_of(CSSColor::s_supported_color_space, [&](auto supported) { return maybe_color_space.is_ident(supported); }))
|
if (!any_of(CSSColor::s_supported_color_space, [&](auto supported) { return maybe_color_space.is_ident(supported); }))
|
||||||
return {};
|
return {};
|
||||||
|
@ -3281,7 +3283,7 @@ RefPtr<CSSStyleValue> Parser::parse_color_value(TokenStream<ComponentValue>& tok
|
||||||
|
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
auto component_value = tokens.consume_a_token();
|
auto const& component_value = tokens.consume_a_token();
|
||||||
|
|
||||||
if (component_value.is(Token::Type::Ident)) {
|
if (component_value.is(Token::Type::Ident)) {
|
||||||
auto ident = component_value.token().ident();
|
auto ident = component_value.token().ident();
|
||||||
|
@ -3414,7 +3416,7 @@ RefPtr<CSSStyleValue> Parser::parse_counter_value(TokenStream<ComponentValue>& t
|
||||||
};
|
};
|
||||||
|
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (token.is_function("counter"sv)) {
|
if (token.is_function("counter"sv)) {
|
||||||
// counter() = counter( <counter-name>, <counter-style>? )
|
// counter() = counter( <counter-name>, <counter-style>? )
|
||||||
auto& function = token.function();
|
auto& function = token.function();
|
||||||
|
@ -3547,7 +3549,7 @@ RefPtr<CSSStyleValue> Parser::parse_ratio_value(TokenStream<ComponentValue>& tok
|
||||||
|
|
||||||
RefPtr<StringStyleValue> Parser::parse_string_value(TokenStream<ComponentValue>& tokens)
|
RefPtr<StringStyleValue> Parser::parse_string_value(TokenStream<ComponentValue>& tokens)
|
||||||
{
|
{
|
||||||
auto peek = tokens.next_token();
|
auto const& peek = tokens.next_token();
|
||||||
if (peek.is(Token::Type::String)) {
|
if (peek.is(Token::Type::String)) {
|
||||||
tokens.discard_a_token();
|
tokens.discard_a_token();
|
||||||
return StringStyleValue::create(peek.token().string());
|
return StringStyleValue::create(peek.token().string());
|
||||||
|
@ -4822,9 +4824,9 @@ RefPtr<CSSStyleValue> Parser::parse_rotate_value(TokenStream<ComponentValue>& to
|
||||||
return RotationStyleValue::create(angle.release_nonnull(), NumberStyleValue::create(0), NumberStyleValue::create(0), NumberStyleValue::create(1));
|
return RotationStyleValue::create(angle.release_nonnull(), NumberStyleValue::create(0), NumberStyleValue::create(0), NumberStyleValue::create(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parse_one_of_xyz = [&]() -> Optional<ComponentValue> {
|
auto parse_one_of_xyz = [&]() -> Optional<ComponentValue const&> {
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto axis = tokens.consume_a_token();
|
auto const& axis = tokens.consume_a_token();
|
||||||
|
|
||||||
if (axis.is_ident("x"sv) || axis.is_ident("y"sv) || axis.is_ident("z"sv)) {
|
if (axis.is_ident("x"sv) || axis.is_ident("y"sv) || axis.is_ident("z"sv)) {
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
@ -5180,7 +5182,7 @@ RefPtr<CSSStyleValue> Parser::parse_filter_value_list_value(TokenStream<Componen
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
auto parse_filter_function = [&](auto filter_token, auto function_values) -> Optional<FilterFunction> {
|
auto parse_filter_function = [&](auto filter_token, auto const& function_values) -> Optional<FilterFunction> {
|
||||||
TokenStream tokens { function_values };
|
TokenStream tokens { function_values };
|
||||||
tokens.discard_whitespace();
|
tokens.discard_whitespace();
|
||||||
|
|
||||||
|
@ -5823,7 +5825,7 @@ Vector<ParsedFontFace::Source> Parser::parse_font_face_src(TokenStream<T>& compo
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto maybe_function = source_tokens.consume_a_token();
|
auto const& maybe_function = source_tokens.consume_a_token();
|
||||||
if (!maybe_function.is_function()) {
|
if (!maybe_function.is_function()) {
|
||||||
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-face src invalid (token after `url()` that isn't a function: {}); discarding.", maybe_function.to_debug_string());
|
dbgln_if(CSS_PARSER_DEBUG, "CSSParser: @font-face src invalid (token after `url()` that isn't a function: {}); discarding.", maybe_function.to_debug_string());
|
||||||
return {};
|
return {};
|
||||||
|
@ -5894,7 +5896,7 @@ RefPtr<CSSStyleValue> Parser::parse_list_style_value(TokenStream<ComponentValue>
|
||||||
|
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
while (tokens.has_next_token()) {
|
while (tokens.has_next_token()) {
|
||||||
if (auto peek = tokens.next_token(); peek.is_ident("none"sv)) {
|
if (auto const& peek = tokens.next_token(); peek.is_ident("none"sv)) {
|
||||||
tokens.discard_a_token();
|
tokens.discard_a_token();
|
||||||
found_nones++;
|
found_nones++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -5966,7 +5968,7 @@ RefPtr<CSSStyleValue> Parser::parse_math_depth_value(TokenStream<ComponentValue>
|
||||||
// auto-add | add(<integer>) | <integer>
|
// auto-add | add(<integer>) | <integer>
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
|
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (tokens.has_next_token())
|
if (tokens.has_next_token())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
@ -5977,7 +5979,7 @@ RefPtr<CSSStyleValue> Parser::parse_math_depth_value(TokenStream<ComponentValue>
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Make it easier to parse "thing that might be <bar> or literally anything that resolves to it" and get rid of this
|
// FIXME: Make it easier to parse "thing that might be <bar> or literally anything that resolves to it" and get rid of this
|
||||||
auto parse_something_that_resolves_to_integer = [this](ComponentValue& token) -> RefPtr<CSSStyleValue> {
|
auto parse_something_that_resolves_to_integer = [this](ComponentValue const& token) -> RefPtr<CSSStyleValue> {
|
||||||
if (token.is(Token::Type::Number) && token.token().number().is_integer())
|
if (token.is(Token::Type::Number) && token.token().number().is_integer())
|
||||||
return IntegerStyleValue::create(token.token().to_integer());
|
return IntegerStyleValue::create(token.token().to_integer());
|
||||||
if (auto value = parse_calculated_value(token); value && value->resolves_to_number())
|
if (auto value = parse_calculated_value(token); value && value->resolves_to_number())
|
||||||
|
@ -5989,7 +5991,7 @@ RefPtr<CSSStyleValue> Parser::parse_math_depth_value(TokenStream<ComponentValue>
|
||||||
if (token.is_function("add"sv)) {
|
if (token.is_function("add"sv)) {
|
||||||
auto add_tokens = TokenStream { token.function().value };
|
auto add_tokens = TokenStream { token.function().value };
|
||||||
add_tokens.discard_whitespace();
|
add_tokens.discard_whitespace();
|
||||||
auto integer_token = add_tokens.consume_a_token();
|
auto const& integer_token = add_tokens.consume_a_token();
|
||||||
add_tokens.discard_whitespace();
|
add_tokens.discard_whitespace();
|
||||||
if (add_tokens.has_next_token())
|
if (add_tokens.has_next_token())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -6349,7 +6351,7 @@ RefPtr<CSSStyleValue> Parser::parse_easing_value(TokenStream<ComponentValue>& to
|
||||||
|
|
||||||
EasingStyleValue::Steps steps;
|
EasingStyleValue::Steps steps;
|
||||||
|
|
||||||
auto intervals_argument = comma_separated_arguments[0][0];
|
auto const& intervals_argument = comma_separated_arguments[0][0];
|
||||||
if (!intervals_argument.is(Token::Type::Number))
|
if (!intervals_argument.is(Token::Type::Number))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (!intervals_argument.token().number().is_integer())
|
if (!intervals_argument.token().number().is_integer())
|
||||||
|
@ -6807,7 +6809,7 @@ Optional<CSS::GridMinMax> Parser::parse_min_max(Vector<ComponentValue> const& co
|
||||||
part_one_tokens.discard_whitespace();
|
part_one_tokens.discard_whitespace();
|
||||||
if (!part_one_tokens.has_next_token())
|
if (!part_one_tokens.has_next_token())
|
||||||
return {};
|
return {};
|
||||||
auto current_token = part_one_tokens.consume_a_token();
|
NonnullRawPtr<ComponentValue const> current_token = part_one_tokens.consume_a_token();
|
||||||
auto min_grid_size = parse_grid_size(current_token);
|
auto min_grid_size = parse_grid_size(current_token);
|
||||||
|
|
||||||
TokenStream part_two_tokens { comma_separated_list[1] };
|
TokenStream part_two_tokens { comma_separated_list[1] };
|
||||||
|
@ -6863,7 +6865,7 @@ Optional<CSS::GridRepeat> Parser::parse_repeat(Vector<ComponentValue> const& com
|
||||||
Vector<Variant<ExplicitGridTrack, GridLineNames>> repeat_params;
|
Vector<Variant<ExplicitGridTrack, GridLineNames>> repeat_params;
|
||||||
auto last_object_was_line_names = false;
|
auto last_object_was_line_names = false;
|
||||||
while (part_two_tokens.has_next_token()) {
|
while (part_two_tokens.has_next_token()) {
|
||||||
auto token = part_two_tokens.consume_a_token();
|
auto const& token = part_two_tokens.consume_a_token();
|
||||||
Vector<String> line_names;
|
Vector<String> line_names;
|
||||||
if (token.is_block()) {
|
if (token.is_block()) {
|
||||||
if (last_object_was_line_names)
|
if (last_object_was_line_names)
|
||||||
|
@ -6873,7 +6875,7 @@ Optional<CSS::GridRepeat> Parser::parse_repeat(Vector<ComponentValue> const& com
|
||||||
return {};
|
return {};
|
||||||
TokenStream block_tokens { token.block().value };
|
TokenStream block_tokens { token.block().value };
|
||||||
while (block_tokens.has_next_token()) {
|
while (block_tokens.has_next_token()) {
|
||||||
auto current_block_token = block_tokens.consume_a_token();
|
auto const& current_block_token = block_tokens.consume_a_token();
|
||||||
line_names.append(current_block_token.token().ident().to_string());
|
line_names.append(current_block_token.token().ident().to_string());
|
||||||
block_tokens.discard_whitespace();
|
block_tokens.discard_whitespace();
|
||||||
}
|
}
|
||||||
|
@ -6979,7 +6981,7 @@ RefPtr<CSSStyleValue> Parser::parse_grid_track_size_list(TokenStream<ComponentVa
|
||||||
Vector<Variant<ExplicitGridTrack, GridLineNames>> track_list;
|
Vector<Variant<ExplicitGridTrack, GridLineNames>> track_list;
|
||||||
auto last_object_was_line_names = false;
|
auto last_object_was_line_names = false;
|
||||||
while (tokens.has_next_token()) {
|
while (tokens.has_next_token()) {
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (token.is_block()) {
|
if (token.is_block()) {
|
||||||
if (last_object_was_line_names && !allow_separate_line_name_blocks) {
|
if (last_object_was_line_names && !allow_separate_line_name_blocks) {
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
@ -6994,7 +6996,7 @@ RefPtr<CSSStyleValue> Parser::parse_grid_track_size_list(TokenStream<ComponentVa
|
||||||
TokenStream block_tokens { token.block().value };
|
TokenStream block_tokens { token.block().value };
|
||||||
block_tokens.discard_whitespace();
|
block_tokens.discard_whitespace();
|
||||||
while (block_tokens.has_next_token()) {
|
while (block_tokens.has_next_token()) {
|
||||||
auto current_block_token = block_tokens.consume_a_token();
|
auto const& current_block_token = block_tokens.consume_a_token();
|
||||||
line_names.append(current_block_token.token().ident().to_string());
|
line_names.append(current_block_token.token().ident().to_string());
|
||||||
block_tokens.discard_whitespace();
|
block_tokens.discard_whitespace();
|
||||||
}
|
}
|
||||||
|
@ -7027,7 +7029,7 @@ RefPtr<GridAutoFlowStyleValue> Parser::parse_grid_auto_flow_value(TokenStream<Co
|
||||||
|
|
||||||
auto parse_axis = [&]() -> Optional<GridAutoFlowStyleValue::Axis> {
|
auto parse_axis = [&]() -> Optional<GridAutoFlowStyleValue::Axis> {
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (!token.is(Token::Type::Ident))
|
if (!token.is(Token::Type::Ident))
|
||||||
return {};
|
return {};
|
||||||
auto const& ident = token.token().ident();
|
auto const& ident = token.token().ident();
|
||||||
|
@ -7043,7 +7045,7 @@ RefPtr<GridAutoFlowStyleValue> Parser::parse_grid_auto_flow_value(TokenStream<Co
|
||||||
|
|
||||||
auto parse_dense = [&]() -> Optional<GridAutoFlowStyleValue::Dense> {
|
auto parse_dense = [&]() -> Optional<GridAutoFlowStyleValue::Dense> {
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (!token.is(Token::Type::Ident))
|
if (!token.is(Token::Type::Ident))
|
||||||
return {};
|
return {};
|
||||||
auto const& ident = token.token().ident();
|
auto const& ident = token.token().ident();
|
||||||
|
@ -7080,7 +7082,7 @@ RefPtr<CSSStyleValue> Parser::parse_scrollbar_gutter_value(TokenStream<Component
|
||||||
|
|
||||||
auto parse_stable = [&]() -> Optional<bool> {
|
auto parse_stable = [&]() -> Optional<bool> {
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (!token.is(Token::Type::Ident))
|
if (!token.is(Token::Type::Ident))
|
||||||
return {};
|
return {};
|
||||||
auto const& ident = token.token().ident();
|
auto const& ident = token.token().ident();
|
||||||
|
@ -7096,7 +7098,7 @@ RefPtr<CSSStyleValue> Parser::parse_scrollbar_gutter_value(TokenStream<Component
|
||||||
|
|
||||||
auto parse_both_edges = [&]() -> Optional<bool> {
|
auto parse_both_edges = [&]() -> Optional<bool> {
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (!token.is(Token::Type::Ident))
|
if (!token.is(Token::Type::Ident))
|
||||||
return {};
|
return {};
|
||||||
auto const& ident = token.token().ident();
|
auto const& ident = token.token().ident();
|
||||||
|
@ -7140,7 +7142,7 @@ RefPtr<CSSStyleValue> Parser::parse_grid_auto_track_sizes(TokenStream<ComponentV
|
||||||
Vector<Variant<ExplicitGridTrack, GridLineNames>> track_list;
|
Vector<Variant<ExplicitGridTrack, GridLineNames>> track_list;
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
while (tokens.has_next_token()) {
|
while (tokens.has_next_token()) {
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
auto track_sizing_function = parse_track_sizing_function(token);
|
auto track_sizing_function = parse_track_sizing_function(token);
|
||||||
if (!track_sizing_function.has_value()) {
|
if (!track_sizing_function.has_value()) {
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
|
@ -7187,7 +7189,7 @@ RefPtr<GridTrackPlacementStyleValue> Parser::parse_grid_track_placement(TokenStr
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line({}, custom_ident->custom_ident().to_string()));
|
return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line({}, custom_ident->custom_ident().to_string()));
|
||||||
}
|
}
|
||||||
auto& token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
if (auto maybe_calculated = parse_calculated_value(token); maybe_calculated && maybe_calculated->resolves_to_number()) {
|
if (auto maybe_calculated = parse_calculated_value(token); maybe_calculated && maybe_calculated->resolves_to_number()) {
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line(static_cast<int>(maybe_calculated->resolve_integer().value()), {}));
|
return GridTrackPlacementStyleValue::create(GridTrackPlacement::make_line(static_cast<int>(maybe_calculated->resolve_integer().value()), {}));
|
||||||
|
@ -7211,7 +7213,7 @@ RefPtr<GridTrackPlacementStyleValue> Parser::parse_grid_track_placement(TokenStr
|
||||||
auto span_or_position_value = 0;
|
auto span_or_position_value = 0;
|
||||||
String identifier_value;
|
String identifier_value;
|
||||||
while (tokens.has_next_token()) {
|
while (tokens.has_next_token()) {
|
||||||
auto& token = tokens.next_token();
|
auto const& token = tokens.next_token();
|
||||||
if (token.is_ident("auto"sv))
|
if (token.is_ident("auto"sv))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
if (token.is_ident("span"sv)) {
|
if (token.is_ident("span"sv)) {
|
||||||
|
@ -7256,11 +7258,11 @@ RefPtr<CSSStyleValue> Parser::parse_grid_track_placement_shorthand_value(Propert
|
||||||
auto end_property = (property_id == PropertyID::GridColumn) ? PropertyID::GridColumnEnd : PropertyID::GridRowEnd;
|
auto end_property = (property_id == PropertyID::GridColumn) ? PropertyID::GridColumnEnd : PropertyID::GridRowEnd;
|
||||||
|
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto current_token = tokens.consume_a_token();
|
NonnullRawPtr<ComponentValue const> current_token = tokens.consume_a_token();
|
||||||
|
|
||||||
Vector<ComponentValue> track_start_placement_tokens;
|
Vector<ComponentValue> track_start_placement_tokens;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (current_token.is_delim('/'))
|
if (current_token->is_delim('/'))
|
||||||
break;
|
break;
|
||||||
track_start_placement_tokens.append(current_token);
|
track_start_placement_tokens.append(current_token);
|
||||||
if (!tokens.has_next_token())
|
if (!tokens.has_next_token())
|
||||||
|
@ -8021,7 +8023,7 @@ Optional<Parser::PropertyAndValue> Parser::parse_css_value_for_properties(Readon
|
||||||
if (property_accepts_dimension) {
|
if (property_accepts_dimension) {
|
||||||
if (peek_token.is(Token::Type::Number) && m_context.is_parsing_svg_presentation_attribute()) {
|
if (peek_token.is(Token::Type::Number) && m_context.is_parsing_svg_presentation_attribute()) {
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
auto token = tokens.consume_a_token();
|
auto const& token = tokens.consume_a_token();
|
||||||
// https://svgwg.org/svg2-draft/types.html#presentation-attribute-css-value
|
// https://svgwg.org/svg2-draft/types.html#presentation-attribute-css-value
|
||||||
// We need to allow <number> in any place that expects a <length> or <angle>.
|
// We need to allow <number> in any place that expects a <length> or <angle>.
|
||||||
// FIXME: How should these numbers be interpreted? https://github.com/w3c/svgwg/issues/792
|
// FIXME: How should these numbers be interpreted? https://github.com/w3c/svgwg/issues/792
|
||||||
|
@ -8292,7 +8294,7 @@ OwnPtr<CalculationNode> Parser::parse_a_calculation(Vector<ComponentValue> const
|
||||||
};
|
};
|
||||||
using Value = Variant<NonnullOwnPtr<CalculationNode>, Operator>;
|
using Value = Variant<NonnullOwnPtr<CalculationNode>, Operator>;
|
||||||
Vector<Value> values;
|
Vector<Value> values;
|
||||||
for (auto& value : original_values) {
|
for (auto const& value : original_values) {
|
||||||
if (value.is(Token::Type::Whitespace))
|
if (value.is(Token::Type::Whitespace))
|
||||||
continue;
|
continue;
|
||||||
if (value.is(Token::Type::Delim)) {
|
if (value.is(Token::Type::Delim)) {
|
||||||
|
@ -8422,7 +8424,7 @@ OwnPtr<CalculationNode> Parser::parse_a_calculation(Vector<ComponentValue> const
|
||||||
values.first().visit(
|
values.first().visit(
|
||||||
[&](ComponentValue& component_value) {
|
[&](ComponentValue& component_value) {
|
||||||
if (component_value.is_block() && component_value.block().is_paren())
|
if (component_value.is_block() && component_value.block().is_paren())
|
||||||
single_value = UnparsedCalculationNode::create(component_value);
|
single_value = UnparsedCalculationNode::create(move(component_value));
|
||||||
},
|
},
|
||||||
[&](NonnullOwnPtr<CalculationNode>& node) {
|
[&](NonnullOwnPtr<CalculationNode>& node) {
|
||||||
if (node->type() == CalculationNode::Type::Product)
|
if (node->type() == CalculationNode::Type::Product)
|
||||||
|
@ -8624,7 +8626,7 @@ bool Parser::expand_variables(DOM::Element& element, Optional<Selector::PseudoEl
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!value.is_function()) {
|
if (!value.is_function()) {
|
||||||
dest.empend(value);
|
dest.empend(value.token());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!value.function().name.equals_ignoring_ascii_case("var"sv)) {
|
if (!value.function().name.equals_ignoring_ascii_case("var"sv)) {
|
||||||
|
|
|
@ -184,11 +184,11 @@ Optional<Selector::SimpleSelector::QualifiedName> Parser::parse_selector_qualifi
|
||||||
|
|
||||||
auto transaction = tokens.begin_transaction();
|
auto transaction = tokens.begin_transaction();
|
||||||
|
|
||||||
auto first_token = tokens.consume_a_token();
|
auto const& first_token = tokens.consume_a_token();
|
||||||
if (first_token.is_delim('|')) {
|
if (first_token.is_delim('|')) {
|
||||||
// Case 1: `|<name>`
|
// Case 1: `|<name>`
|
||||||
if (is_name(tokens.next_token())) {
|
if (is_name(tokens.next_token())) {
|
||||||
auto name_token = tokens.consume_a_token();
|
auto const& name_token = tokens.consume_a_token();
|
||||||
|
|
||||||
if (allow_wildcard_name == AllowWildcardName::No && name_token.is_delim('*'))
|
if (allow_wildcard_name == AllowWildcardName::No && name_token.is_delim('*'))
|
||||||
return {};
|
return {};
|
||||||
|
@ -559,7 +559,7 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
|
||||||
case PseudoClassMetadata::ParameterType::Ident: {
|
case PseudoClassMetadata::ParameterType::Ident: {
|
||||||
auto function_token_stream = TokenStream(pseudo_function.value);
|
auto function_token_stream = TokenStream(pseudo_function.value);
|
||||||
function_token_stream.discard_whitespace();
|
function_token_stream.discard_whitespace();
|
||||||
auto maybe_keyword_token = function_token_stream.consume_a_token();
|
auto const& maybe_keyword_token = function_token_stream.consume_a_token();
|
||||||
function_token_stream.discard_whitespace();
|
function_token_stream.discard_whitespace();
|
||||||
if (!maybe_keyword_token.is(Token::Type::Ident) || function_token_stream.has_next_token()) {
|
if (!maybe_keyword_token.is(Token::Type::Ident) || function_token_stream.has_next_token()) {
|
||||||
dbgln_if(CSS_PARSER_DEBUG, "Failed to parse :{}() parameter as a keyword: not an ident", pseudo_function.name);
|
dbgln_if(CSS_PARSER_DEBUG, "Failed to parse :{}() parameter as a keyword: not an ident", pseudo_function.name);
|
||||||
|
@ -584,10 +584,10 @@ Parser::ParseErrorOr<Selector::SimpleSelector> Parser::parse_pseudo_simple_selec
|
||||||
auto function_token_stream = TokenStream(pseudo_function.value);
|
auto function_token_stream = TokenStream(pseudo_function.value);
|
||||||
auto language_token_lists = parse_a_comma_separated_list_of_component_values(function_token_stream);
|
auto language_token_lists = parse_a_comma_separated_list_of_component_values(function_token_stream);
|
||||||
|
|
||||||
for (auto language_token_list : language_token_lists) {
|
for (auto const& language_token_list : language_token_lists) {
|
||||||
auto language_token_stream = TokenStream(language_token_list);
|
auto language_token_stream = TokenStream(language_token_list);
|
||||||
language_token_stream.discard_whitespace();
|
language_token_stream.discard_whitespace();
|
||||||
auto language_token = language_token_stream.consume_a_token();
|
auto const& language_token = language_token_stream.consume_a_token();
|
||||||
if (!(language_token.is(Token::Type::Ident) || language_token.is(Token::Type::String))) {
|
if (!(language_token.is(Token::Type::Ident) || language_token.is(Token::Type::String))) {
|
||||||
dbgln_if(CSS_PARSER_DEBUG, "Invalid language range in :{}() - not a string/ident", pseudo_function.name);
|
dbgln_if(CSS_PARSER_DEBUG, "Invalid language range in :{}() - not a string/ident", pseudo_function.name);
|
||||||
return ParseError::SyntaxError;
|
return ParseError::SyntaxError;
|
||||||
|
|
Loading…
Reference in a new issue