Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Side by Side Diff: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp

Issue 1998033003: [css-grid] Simplify grid track sizes parsing (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: New version addressing review comments Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "core/css/parser/CSSPropertyParser.h" 5 #include "core/css/parser/CSSPropertyParser.h"
6 6
7 #include "core/StylePropertyShorthand.h" 7 #include "core/StylePropertyShorthand.h"
8 #include "core/css/CSSBasicShapeValues.h" 8 #include "core/css/CSSBasicShapeValues.h"
9 #include "core/css/CSSBorderImage.h" 9 #include "core/css/CSSBorderImage.h"
10 #include "core/css/CSSContentDistributionValue.h" 10 #include "core/css/CSSContentDistributionValue.h"
(...skipping 3241 matching lines...) Expand 10 before | Expand all | Expand 10 after
3252 if (spanValue) 3252 if (spanValue)
3253 values->append(spanValue); 3253 values->append(spanValue);
3254 if (numericValue) 3254 if (numericValue)
3255 values->append(numericValue); 3255 values->append(numericValue);
3256 if (gridLineName) 3256 if (gridLineName)
3257 values->append(gridLineName); 3257 values->append(gridLineName);
3258 ASSERT(values->length()); 3258 ASSERT(values->length());
3259 return values; 3259 return values;
3260 } 3260 }
3261 3261
3262 static bool allTracksAreFixedSized(CSSValueList& valueList) 3262 static bool isGridTrackFixedSized(const CSSValue& value)
3263 { 3263 {
3264 for (CSSValue* value : valueList) { 3264 const CSSPrimitiveValue& primitiveValue = value.isPrimitiveValue()
3265 if (value->isGridLineNamesValue()) 3265 ? toCSSPrimitiveValue(value)
3266 continue; 3266 : toCSSPrimitiveValue(*toCSSFunctionValue(value).item(0));
3267 // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax ( <fixed-breadth>, <track-breadth> ) 3267 CSSValueID valueID = primitiveValue.getValueID();
3268 if (value->isGridAutoRepeatValue()) { 3268 if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || valueI D == CSSValueAuto || primitiveValue.isFlex())
3269 if (!allTracksAreFixedSized(toCSSValueList(*value))) 3269 return false;
3270 return false; 3270
3271 continue;
3272 }
3273 const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue()
3274 ? toCSSPrimitiveValue(*value)
3275 : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0));
3276 CSSValueID valueID = primitiveValue.getValueID();
3277 if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || va lueID == CSSValueAuto || primitiveValue.isFlex())
3278 return false;
3279 }
3280 return true; 3271 return true;
3281 } 3272 }
3282 3273
3283 static Vector<String> parseGridTemplateAreasColumnNames(const String& gridRowNam es) 3274 static Vector<String> parseGridTemplateAreasColumnNames(const String& gridRowNam es)
3284 { 3275 {
3285 ASSERT(!gridRowNames.isEmpty()); 3276 ASSERT(!gridRowNames.isEmpty());
3286 Vector<String> columnNames; 3277 Vector<String> columnNames;
3287 // Using StringImpl to avoid checks and indirection in every call to String: :operator[]. 3278 // Using StringImpl to avoid checks and indirection in every call to String: :operator[].
3288 StringImpl& text = *gridRowNames.impl(); 3279 StringImpl& text = *gridRowNames.impl();
3289 3280
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
3367 return false; 3358 return false;
3368 3359
3369 gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.s tartLine(), gridArea.rows.endLine() + 1); 3360 gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.s tartLine(), gridArea.rows.endLine() + 1);
3370 } 3361 }
3371 currentColumn = lookAheadColumn - 1; 3362 currentColumn = lookAheadColumn - 1;
3372 } 3363 }
3373 3364
3374 return true; 3365 return true;
3375 } 3366 }
3376 3367
3377 enum TrackSizeRestriction { FixedSizeOnly, InflexibleSizeOnly, AllowAll }; 3368 static CSSPrimitiveValue* consumeGridBreadth(CSSParserTokenRange& range, CSSPars erMode cssParserMode)
3378
3379 static CSSPrimitiveValue* consumeGridBreadth(CSSParserTokenRange& range, CSSPars erMode cssParserMode, TrackSizeRestriction restriction = AllowAll)
3380 { 3369 {
3381 if (restriction != FixedSizeOnly) { 3370 const CSSParserToken& token = range.peek();
3382 const CSSParserToken& token = range.peek(); 3371 if (identMatches<CSSValueMinContent, CSSValueMaxContent, CSSValueAuto>(token .id()))
3383 if (identMatches<CSSValueMinContent, CSSValueMaxContent, CSSValueAuto>(t oken.id())) 3372 return consumeIdent(range);
3384 return consumeIdent(range); 3373 if (token.type() == DimensionToken && token.unitType() == CSSPrimitiveValue: :UnitType::Fraction) {
3385 if (token.type() == DimensionToken && token.unitType() == CSSPrimitiveVa lue::UnitType::Fraction) { 3374 if (range.peek().numericValue() < 0)
3386 if (restriction == InflexibleSizeOnly || range.peek().numericValue() < 0) 3375 return nullptr;
3387 return nullptr; 3376 return cssValuePool().createValue(range.consumeIncludingWhitespace().num ericValue(), CSSPrimitiveValue::UnitType::Fraction);
3388 return cssValuePool().createValue(range.consumeIncludingWhitespace() .numericValue(), CSSPrimitiveValue::UnitType::Fraction);
3389 }
3390 } 3377 }
3391 return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative, U nitlessQuirk::Allow); 3378 return consumeLengthOrPercent(range, cssParserMode, ValueRangeNonNegative, U nitlessQuirk::Allow);
3392 } 3379 }
3393 3380
3394 // TODO(rob.buis): This needs a bool parameter so we can disallow <auto-track-li st> for the grid shorthand. 3381 // TODO(rob.buis): This needs a bool parameter so we can disallow <auto-track-li st> for the grid shorthand.
3395 static CSSValue* consumeGridTrackSize(CSSParserTokenRange& range, CSSParserMode cssParserMode, TrackSizeRestriction restriction = AllowAll) 3382 static CSSValue* consumeGridTrackSize(CSSParserTokenRange& range, CSSParserMode cssParserMode)
3396 { 3383 {
3397 const CSSParserToken& token = range.peek(); 3384 const CSSParserToken& token = range.peek();
3398 if (restriction == AllowAll && identMatches<CSSValueAuto>(token.id())) 3385 if (identMatches<CSSValueAuto>(token.id()))
3399 return consumeIdent(range); 3386 return consumeIdent(range);
3400 3387
3401 if (token.functionId() == CSSValueMinmax) { 3388 if (token.functionId() == CSSValueMinmax) {
3402 CSSParserTokenRange rangeCopy = range; 3389 CSSParserTokenRange rangeCopy = range;
3403 CSSParserTokenRange args = consumeFunction(rangeCopy); 3390 CSSParserTokenRange args = consumeFunction(rangeCopy);
3404 TrackSizeRestriction minTrackBreadthRestriction = restriction == AllowAl l ? InflexibleSizeOnly : restriction; 3391 CSSPrimitiveValue* minTrackBreadth = consumeGridBreadth(args, cssParserM ode);
3405 CSSPrimitiveValue* minTrackBreadth = consumeGridBreadth(args, cssParserM ode, minTrackBreadthRestriction); 3392 if (!minTrackBreadth || minTrackBreadth->isFlex() || !consumeCommaInclud ingWhitespace(args))
3406 if (!minTrackBreadth || !consumeCommaIncludingWhitespace(args))
3407 return nullptr; 3393 return nullptr;
3408 CSSPrimitiveValue* maxTrackBreadth = consumeGridBreadth(args, cssParserM ode); 3394 CSSPrimitiveValue* maxTrackBreadth = consumeGridBreadth(args, cssParserM ode);
3409 if (!maxTrackBreadth || !args.atEnd()) 3395 if (!maxTrackBreadth || !args.atEnd())
3410 return nullptr; 3396 return nullptr;
3411 range = rangeCopy; 3397 range = rangeCopy;
3412 CSSFunctionValue* result = CSSFunctionValue::create(CSSValueMinmax); 3398 CSSFunctionValue* result = CSSFunctionValue::create(CSSValueMinmax);
3413 result->append(minTrackBreadth); 3399 result->append(minTrackBreadth);
3414 result->append(maxTrackBreadth); 3400 result->append(maxTrackBreadth);
3415 return result; 3401 return result;
3416 } 3402 }
3417 return consumeGridBreadth(range, cssParserMode, restriction); 3403 return consumeGridBreadth(range, cssParserMode);
3418 } 3404 }
3419 3405
3420 // Appends to the passed in CSSGridLineNamesValue if any, otherwise creates a ne w one. 3406 // Appends to the passed in CSSGridLineNamesValue if any, otherwise creates a ne w one.
3421 static CSSGridLineNamesValue* consumeGridLineNames(CSSParserTokenRange& range, C SSGridLineNamesValue* lineNames = nullptr) 3407 static CSSGridLineNamesValue* consumeGridLineNames(CSSParserTokenRange& range, C SSGridLineNamesValue* lineNames = nullptr)
3422 { 3408 {
3423 CSSParserTokenRange rangeCopy = range; 3409 CSSParserTokenRange rangeCopy = range;
3424 if (rangeCopy.consumeIncludingWhitespace().type() != LeftBracketToken) 3410 if (rangeCopy.consumeIncludingWhitespace().type() != LeftBracketToken)
3425 return nullptr; 3411 return nullptr;
3426 if (!lineNames) 3412 if (!lineNames)
3427 lineNames = CSSGridLineNamesValue::create(); 3413 lineNames = CSSGridLineNamesValue::create();
3428 while (CSSCustomIdentValue* lineName = consumeCustomIdentForGridLine(rangeCo py)) 3414 while (CSSCustomIdentValue* lineName = consumeCustomIdentForGridLine(rangeCo py))
3429 lineNames->append(lineName); 3415 lineNames->append(lineName);
3430 if (rangeCopy.consumeIncludingWhitespace().type() != RightBracketToken) 3416 if (rangeCopy.consumeIncludingWhitespace().type() != RightBracketToken)
3431 return nullptr; 3417 return nullptr;
3432 range = rangeCopy; 3418 range = rangeCopy;
3433 return lineNames; 3419 return lineNames;
3434 } 3420 }
3435 3421
3436 static bool consumeGridTrackRepeatFunction(CSSParserTokenRange& range, CSSParser Mode cssParserMode, CSSValueList& list, bool& isAutoRepeat) 3422 static bool consumeGridTrackRepeatFunction(CSSParserTokenRange& range, CSSParser Mode cssParserMode, CSSValueList& list, bool& isAutoRepeat, bool& allTracksAreFi xedSized)
3437 { 3423 {
3438 CSSParserTokenRange args = consumeFunction(range); 3424 CSSParserTokenRange args = consumeFunction(range);
3439 // The number of repetitions for <auto-repeat> is not important at parsing l evel 3425 // The number of repetitions for <auto-repeat> is not important at parsing l evel
3440 // because it will be computed later, let's set it to 1. 3426 // because it will be computed later, let's set it to 1.
3441 size_t repetitions = 1; 3427 size_t repetitions = 1;
3442 isAutoRepeat = identMatches<CSSValueAutoFill, CSSValueAutoFit>(args.peek().i d()); 3428 isAutoRepeat = identMatches<CSSValueAutoFill, CSSValueAutoFit>(args.peek().i d());
3443 CSSValueList* repeatedValues; 3429 CSSValueList* repeatedValues;
3444 if (isAutoRepeat) { 3430 if (isAutoRepeat) {
3445 repeatedValues = CSSGridAutoRepeatValue::create(args.consumeIncludingWhi tespace().id()); 3431 repeatedValues = CSSGridAutoRepeatValue::create(args.consumeIncludingWhi tespace().id());
3446 } else { 3432 } else {
3447 // TODO(rob.buis): a consumeIntegerRaw would be more efficient here. 3433 // TODO(rob.buis): a consumeIntegerRaw would be more efficient here.
3448 CSSPrimitiveValue* repetition = consumePositiveInteger(args); 3434 CSSPrimitiveValue* repetition = consumePositiveInteger(args);
3449 if (!repetition) 3435 if (!repetition)
3450 return false; 3436 return false;
3451 repetitions = clampTo<size_t>(repetition->getDoubleValue(), 0, kGridMaxT racks); 3437 repetitions = clampTo<size_t>(repetition->getDoubleValue(), 0, kGridMaxT racks);
3452 repeatedValues = CSSValueList::createSpaceSeparated(); 3438 repeatedValues = CSSValueList::createSpaceSeparated();
3453 } 3439 }
3454 if (!consumeCommaIncludingWhitespace(args)) 3440 if (!consumeCommaIncludingWhitespace(args))
3455 return false; 3441 return false;
3456 CSSGridLineNamesValue* lineNames = consumeGridLineNames(args); 3442 CSSGridLineNamesValue* lineNames = consumeGridLineNames(args);
3457 if (lineNames) 3443 if (lineNames)
3458 repeatedValues->append(lineNames); 3444 repeatedValues->append(lineNames);
3459 3445
3460 size_t numberOfTracks = 0; 3446 size_t numberOfTracks = 0;
3461 TrackSizeRestriction restriction = isAutoRepeat ? FixedSizeOnly : AllowAll;
3462 while (!args.atEnd()) { 3447 while (!args.atEnd()) {
3463 if (isAutoRepeat && numberOfTracks) 3448 if (isAutoRepeat && numberOfTracks)
3464 return false; 3449 return false;
3465 CSSValue* trackSize = consumeGridTrackSize(args, cssParserMode, restrict ion); 3450 CSSValue* trackSize = consumeGridTrackSize(args, cssParserMode);
3466 if (!trackSize) 3451 if (!trackSize)
3467 return false; 3452 return false;
3453 if (allTracksAreFixedSized)
3454 allTracksAreFixedSized = isGridTrackFixedSized(*trackSize);
3468 repeatedValues->append(trackSize); 3455 repeatedValues->append(trackSize);
3469 ++numberOfTracks; 3456 ++numberOfTracks;
3470 lineNames = consumeGridLineNames(args); 3457 lineNames = consumeGridLineNames(args);
3471 if (lineNames) 3458 if (lineNames)
3472 repeatedValues->append(lineNames); 3459 repeatedValues->append(lineNames);
3473 } 3460 }
3474 // We should have found at least one <track-size> or else it is not a valid <track-list>. 3461 // We should have found at least one <track-size> or else it is not a valid <track-list>.
3475 if (!numberOfTracks) 3462 if (!numberOfTracks)
3476 return false; 3463 return false;
3477 3464
(...skipping 11 matching lines...) Expand all
3489 } 3476 }
3490 3477
3491 static CSSValue* consumeGridTrackList(CSSParserTokenRange& range, CSSParserMode cssParserMode) 3478 static CSSValue* consumeGridTrackList(CSSParserTokenRange& range, CSSParserMode cssParserMode)
3492 { 3479 {
3493 CSSValueList* values = CSSValueList::createSpaceSeparated(); 3480 CSSValueList* values = CSSValueList::createSpaceSeparated();
3494 CSSGridLineNamesValue* lineNames = consumeGridLineNames(range); 3481 CSSGridLineNamesValue* lineNames = consumeGridLineNames(range);
3495 if (lineNames) 3482 if (lineNames)
3496 values->append(lineNames); 3483 values->append(lineNames);
3497 3484
3498 bool seenAutoRepeat = false; 3485 bool seenAutoRepeat = false;
3486 bool allTracksAreFixedSized = true;
3499 // TODO(rob.buis): <line-names> should not be able to directly precede <auto -repeat>. 3487 // TODO(rob.buis): <line-names> should not be able to directly precede <auto -repeat>.
3500 do { 3488 do {
3501 bool isAutoRepeat; 3489 bool isAutoRepeat;
3502 if (range.peek().functionId() == CSSValueRepeat) { 3490 if (range.peek().functionId() == CSSValueRepeat) {
3503 if (!consumeGridTrackRepeatFunction(range, cssParserMode, *values, i sAutoRepeat)) 3491 if (!consumeGridTrackRepeatFunction(range, cssParserMode, *values, i sAutoRepeat, allTracksAreFixedSized))
3504 return nullptr; 3492 return nullptr;
3505 if (isAutoRepeat && seenAutoRepeat) 3493 if (isAutoRepeat && seenAutoRepeat)
3506 return nullptr; 3494 return nullptr;
3507 seenAutoRepeat = seenAutoRepeat || isAutoRepeat; 3495 seenAutoRepeat = seenAutoRepeat || isAutoRepeat;
3508 } else if (CSSValue* value = consumeGridTrackSize(range, cssParserMode, seenAutoRepeat ? FixedSizeOnly : AllowAll)) { 3496 } else if (CSSValue* value = consumeGridTrackSize(range, cssParserMode)) {
3497 if (allTracksAreFixedSized)
3498 allTracksAreFixedSized = isGridTrackFixedSized(*value);
3509 values->append(value); 3499 values->append(value);
3510 } else { 3500 } else {
3511 return nullptr; 3501 return nullptr;
3512 } 3502 }
3503 if (seenAutoRepeat && !allTracksAreFixedSized)
3504 return nullptr;
3513 lineNames = consumeGridLineNames(range); 3505 lineNames = consumeGridLineNames(range);
3514 if (lineNames) 3506 if (lineNames)
3515 values->append(lineNames); 3507 values->append(lineNames);
3516 } while (!range.atEnd() && range.peek().type() != DelimiterToken); 3508 } while (!range.atEnd() && range.peek().type() != DelimiterToken);
3517 // <auto-repeat> requires definite minimum track sizes in order to compute t he number of repetitions.
3518 // The above while loop detects those appearances after the <auto-repeat> bu t not the ones before.
3519 if (seenAutoRepeat && !allTracksAreFixedSized(*values))
3520 return nullptr;
3521 return values; 3509 return values;
3522 } 3510 }
3523 3511
3524 static CSSValue* consumeGridTemplatesRowsOrColumns(CSSParserTokenRange& range, C SSParserMode cssParserMode) 3512 static CSSValue* consumeGridTemplatesRowsOrColumns(CSSParserTokenRange& range, C SSParserMode cssParserMode)
3525 { 3513 {
3526 if (range.peek().id() == CSSValueNone) 3514 if (range.peek().id() == CSSValueNone)
3527 return consumeIdent(range); 3515 return consumeIdent(range);
3528 return consumeGridTrackList(range, cssParserMode); 3516 return consumeGridTrackList(range, cssParserMode);
3529 } 3517 }
3530 3518
(...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after
5174 case CSSPropertyGridTemplate: 5162 case CSSPropertyGridTemplate:
5175 return consumeGridTemplateShorthand(CSSPropertyGridTemplate, important); 5163 return consumeGridTemplateShorthand(CSSPropertyGridTemplate, important);
5176 case CSSPropertyGrid: 5164 case CSSPropertyGrid:
5177 return consumeGridShorthand(important); 5165 return consumeGridShorthand(important);
5178 default: 5166 default:
5179 return false; 5167 return false;
5180 } 5168 }
5181 } 5169 }
5182 5170
5183 } // namespace blink 5171 } // namespace blink
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698