Chromium Code Reviews| Index: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| index c0049bd1d317bebfea3b367c02af5217b56fc15f..d10e483db8cf6c81fed99fa337489d2ca3da8e3c 100644 |
| --- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| +++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp |
| @@ -16,6 +16,8 @@ |
| #include "core/css/CSSFontFeatureValue.h" |
| #include "core/css/CSSFunctionValue.h" |
| #include "core/css/CSSGradientValue.h" |
| +#include "core/css/CSSGridAutoRepeatValue.h" |
| +#include "core/css/CSSGridLineNamesValue.h" |
| #include "core/css/CSSImageSetValue.h" |
| #include "core/css/CSSPaintValue.h" |
| #include "core/css/CSSPathValue.h" |
| @@ -3102,6 +3104,113 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeGridTrackSize(CSSParserTokenRange |
| return consumeGridBreadth(range, cssParserMode, restriction); |
| } |
| +static bool consumeGridLineNames(CSSParserTokenRange& range, CSSValueList& valueList) |
|
Timothy Loh
2016/03/24 04:29:31
I think this would be clearer it returned a CSSGri
rwlbuis
2016/03/24 20:40:32
Done.
|
| +{ |
| + if (range.peek().type() != LeftBracketToken) |
| + return true; |
| + range.consumeIncludingWhitespace(); // Skip '['. |
| + RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create(); |
| + while (RefPtrWillBeRawPtr<CSSCustomIdentValue> lineName = consumeCustomIdentForGridLine(range)) |
| + lineNames->append(lineName.release()); |
| + if (range.peek().type() != RightBracketToken) |
| + return false; |
| + range.consumeIncludingWhitespace(); // Consume ']'. |
| + valueList.append(lineNames.release()); |
| + return true; |
| +} |
| + |
| +static bool consumeGridTrackRepeatFunction(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSValueList& list, bool& isAutoRepeat) |
|
Timothy Loh
2016/03/24 04:29:31
Maybe better / more consistent with everything els
rwlbuis
2016/03/24 20:40:32
Done.
|
| +{ |
| + if (range.peek().functionId() != CSSValueRepeat) |
| + return false; |
| + |
| + CSSParserTokenRange args = consumeFunction(range); |
| + // The number of repetitions for <auto-repeat> is not important at parsing level |
| + // because it will be computed later, let's set it to 1. |
| + size_t repetitions = 1; |
| + isAutoRepeat = identMatches<CSSValueAutoFill, CSSValueAutoFit>(args.peek().id()); |
| + RefPtrWillBeRawPtr<CSSValueList> repeatedValues; |
| + if (!isAutoRepeat) { |
|
Timothy Loh
2016/03/24 04:29:31
clearer to not negate here and swap the blocks aro
rwlbuis
2016/03/24 20:40:32
Done.
|
| + if (args.peek().type() != NumberToken || args.peek().numericValueType() != IntegerValueType) |
|
Timothy Loh
2016/03/24 04:29:31
consumePositiveInteger??
rwlbuis
2016/03/24 20:40:32
That would work, but it will create a CSSValue for
Timothy Loh
2016/03/29 02:47:39
We need to use it to handle calc() correctly. Mayb
|
| + return false; |
| + double repetition = args.consumeIncludingWhitespace().numericValue(); |
| + if (repetition < 1) |
| + return false; |
| + repetitions = clampTo<size_t>(repetition, 0, kGridMaxTracks); |
| + repeatedValues = CSSValueList::createSpaceSeparated(); |
| + } else { |
| + repeatedValues = CSSGridAutoRepeatValue::create(args.consumeIncludingWhitespace().id()); |
| + } |
| + if (!consumeCommaIncludingWhitespace(args) || !consumeGridLineNames(args, *repeatedValues)) |
| + return false; |
| + |
| + size_t numberOfTracks = 0; |
| + TrackSizeRestriction restriction = isAutoRepeat ? FixedSizeOnly : AllowAll; |
| + while (!args.atEnd()) { |
|
Timothy Loh
2016/03/24 04:29:31
I think you can do:
do {
..
} while (!args.at
rwlbuis
2016/03/24 20:40:32
I don't think this will work since then it would i
Timothy Loh
2016/03/29 02:47:39
Not sure what you mean exactly :/
rwlbuis
2016/03/29 21:15:50
Sorry, I meant I think we still need numberOfTrack
|
| + if (isAutoRepeat && numberOfTracks) |
| + return false; |
| + RefPtrWillBeRawPtr<CSSValue> trackSize = consumeGridTrackSize(args, cssParserMode, restriction); |
| + if (!trackSize) |
| + return false; |
| + repeatedValues->append(trackSize.release()); |
| + ++numberOfTracks; |
| + if (!consumeGridLineNames(args, *repeatedValues)) |
| + return false; |
| + } |
| + // We should have found at least one <track-size> or else it is not a valid <track-list>. |
| + if (!numberOfTracks) |
| + return false; |
| + |
| + if (isAutoRepeat) { |
| + list.append(repeatedValues.release()); |
| + } else { |
| + // We clamp the repetitions to a multiple of the repeat() track list's size, while staying below the max grid size. |
| + repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks); |
| + for (size_t i = 0; i < repetitions; ++i) { |
| + for (size_t j = 0; j < repeatedValues->length(); ++j) |
| + list.append(repeatedValues->item(j)); |
| + } |
| + } |
| + return true; |
| +} |
| + |
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeGridTrackList(CSSParserTokenRange& range, CSSParserMode cssParserMode) |
| +{ |
| + if (range.peek().id() == CSSValueNone) |
|
Timothy Loh
2016/03/24 04:29:31
I think consumeGridTrackList (or just consumeTrack
rwlbuis
2016/03/24 20:40:32
Agreed, good point, done.
|
| + return consumeIdent(range); |
| + RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); |
| + if (!consumeGridLineNames(range, *values)) |
| + return nullptr; |
| + |
| + bool seenTrackSizeOrRepeatFunction = false; |
| + bool seenAutoRepeat = false; |
| + while (!range.atEnd()) { |
|
Timothy Loh
2016/03/24 04:29:31
Maybe like this, and then you don't need seenTrack
rwlbuis
2016/03/24 20:40:32
Done.
|
| + if (range.peek().type() == DelimiterToken && range.peek().delimiter() == '/') |
| + break; |
| + bool isAutoRepeat; |
| + if (consumeGridTrackRepeatFunction(range, cssParserMode, *values, isAutoRepeat)) { |
| + if (isAutoRepeat && seenAutoRepeat) |
| + return nullptr; |
| + seenAutoRepeat = seenAutoRepeat || isAutoRepeat; |
| + } else if (RefPtrWillBeRawPtr<CSSValue> value = consumeGridTrackSize(range, cssParserMode, seenAutoRepeat ? FixedSizeOnly : AllowAll)) { |
| + values->append(value.release()); |
| + } else { |
| + return nullptr; |
| + } |
| + seenTrackSizeOrRepeatFunction = true; |
| + if (!consumeGridLineNames(range, *values)) |
| + return nullptr; |
| + } |
| + // We should have found a <track-size> or else it is not a valid <track-list>. |
| + if (!seenTrackSizeOrRepeatFunction) |
| + return nullptr; |
| + // <auto-repeat> requires definite minimum track sizes in order to compute the number of repetitions. |
| + // The above while loop detects those appearances after the <auto-repeat> but not the ones before. |
| + if (seenAutoRepeat && !allTracksAreFixedSized(*values)) |
| + return nullptr; |
| + return values.release(); |
| +} |
| + |
| PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty) |
| { |
| CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
| @@ -3474,6 +3583,10 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty |
| case CSSPropertyGridAutoRows: |
| ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); |
| return consumeGridTrackSize(m_range, m_context.mode()); |
| + case CSSPropertyGridTemplateColumns: |
| + case CSSPropertyGridTemplateRows: |
| + ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); |
| + return consumeGridTrackList(m_range, m_context.mode()); |
| default: |
| CSSParserValueList valueList(m_range); |
| if (valueList.size()) { |