@@ -3169,66 +3169,86 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule
3169
3169
return ident;
3170
3170
}
3171
3171
3172
- // FIXME: Also support multiple comma-separated box-shadows
3172
+ return parse_comma_separated_value_list (component_values, [this ](auto & tokens) {
3173
+ return parse_single_box_shadow_value (tokens);
3174
+ });
3175
+ }
3176
+
3177
+ RefPtr<StyleValue> Parser::parse_single_box_shadow_value (TokenStream<StyleComponentValueRule>& tokens)
3178
+ {
3179
+ auto start_position = tokens.position ();
3180
+ auto error = [&]() {
3181
+ tokens.rewind_to_position (start_position);
3182
+ return nullptr ;
3183
+ };
3184
+
3173
3185
Optional<Color> color;
3174
3186
Optional<Length> offset_x;
3175
3187
Optional<Length> offset_y;
3176
3188
Optional<Length> blur_radius;
3177
3189
Optional<Length> spread_distance;
3178
3190
Optional<BoxShadowPlacement> placement;
3179
3191
3180
- for (size_t i = 0 ; i < component_values.size (); ++i) {
3181
- if (auto maybe_color = parse_color (component_values[i]); maybe_color.has_value ()) {
3192
+ while (tokens.has_next_token ()) {
3193
+ auto & token = tokens.peek_token ();
3194
+
3195
+ if (auto maybe_color = parse_color (token); maybe_color.has_value ()) {
3182
3196
if (color.has_value ())
3183
- return nullptr ;
3197
+ return error () ;
3184
3198
color = maybe_color.release_value ();
3199
+ tokens.next_token ();
3185
3200
continue ;
3186
3201
}
3187
3202
3188
- if (auto maybe_offset_x = parse_length (component_values[i] ); maybe_offset_x.has_value ()) {
3203
+ if (auto maybe_offset_x = parse_length (token ); maybe_offset_x.has_value ()) {
3189
3204
// horizontal offset
3190
3205
if (offset_x.has_value ())
3191
- return nullptr ;
3206
+ return error () ;
3192
3207
offset_x = maybe_offset_x.release_value ();
3208
+ tokens.next_token ();
3193
3209
3194
3210
// vertical offset
3195
- if (++i >= component_values. size ())
3196
- return nullptr ;
3197
- auto maybe_offset_y = parse_length (component_values[i] );
3211
+ if (!tokens. has_next_token ())
3212
+ return error () ;
3213
+ auto maybe_offset_y = parse_length (tokens. peek_token () );
3198
3214
if (!maybe_offset_y.has_value ())
3199
- return nullptr ;
3215
+ return error () ;
3200
3216
offset_y = maybe_offset_y.release_value ();
3217
+ tokens.next_token ();
3201
3218
3202
3219
// blur radius (optional)
3203
- if (i + 1 >= component_values. size ())
3220
+ if (!tokens. has_next_token ())
3204
3221
break ;
3205
- auto maybe_blur_radius = parse_length (component_values[i + 1 ] );
3222
+ auto maybe_blur_radius = parse_length (tokens. peek_token () );
3206
3223
if (!maybe_blur_radius.has_value ())
3207
3224
continue ;
3208
- ++i;
3209
3225
blur_radius = maybe_blur_radius.release_value ();
3226
+ tokens.next_token ();
3210
3227
3211
3228
// spread distance (optional)
3212
- if (i + 1 >= component_values. size ())
3229
+ if (!tokens. has_next_token ())
3213
3230
break ;
3214
- auto maybe_spread_distance = parse_length (component_values[i + 1 ] );
3231
+ auto maybe_spread_distance = parse_length (tokens. peek_token () );
3215
3232
if (!maybe_spread_distance.has_value ())
3216
3233
continue ;
3217
- ++i;
3218
3234
spread_distance = maybe_spread_distance.release_value ();
3235
+ tokens.next_token ();
3219
3236
3220
3237
continue ;
3221
3238
}
3222
3239
3223
- if (component_values[i] .is (Token::Type::Ident) && component_values[i] .token ().ident ().equals_ignoring_case (" inset" sv)) {
3240
+ if (token .is (Token::Type::Ident) && token .token ().ident ().equals_ignoring_case (" inset" sv)) {
3224
3241
if (placement.has_value ())
3225
- return nullptr ;
3242
+ return error () ;
3226
3243
placement = BoxShadowPlacement::Inner;
3244
+ tokens.next_token ();
3227
3245
continue ;
3228
3246
}
3229
3247
3230
- // Unrecognized value
3231
- return nullptr ;
3248
+ if (token.is (Token::Type::Comma))
3249
+ break ;
3250
+
3251
+ return error ();
3232
3252
}
3233
3253
3234
3254
// FIXME: If color is absent, default to `currentColor`
@@ -3237,7 +3257,7 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule
3237
3257
3238
3258
// x/y offsets are required
3239
3259
if (!offset_x.has_value () || !offset_y.has_value ())
3240
- return nullptr ;
3260
+ return error () ;
3241
3261
3242
3262
// Other lengths default to 0
3243
3263
if (!blur_radius.has_value ())
0 commit comments