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..7091a33609add0c23fa5eb9844db8599f1c533d9 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,117 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeGridTrackSize(CSSParserTokenRange |
| return consumeGridBreadth(range, cssParserMode, restriction); |
| } |
| +static PassRefPtrWillBeRawPtr<CSSGridLineNamesValue> consumeGridLineNames(CSSParserTokenRange& range) |
| +{ |
| + if (range.peek().type() != LeftBracketToken) |
| + return nullptr; |
| + CSSParserTokenRange rangeCopy = range; |
| + rangeCopy.consumeIncludingWhitespace(); // Skip '['. |
|
Timothy Loh
2016/03/29 02:47:39
Not a fan of the two comments here, at least becau
rwlbuis
2016/03/29 21:15:51
Done.
|
| + RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create(); |
| + while (RefPtrWillBeRawPtr<CSSCustomIdentValue> lineName = consumeCustomIdentForGridLine(rangeCopy)) |
| + lineNames->append(lineName.release()); |
| + if (rangeCopy.peek().type() != RightBracketToken) |
| + return nullptr; |
| + rangeCopy.consumeIncludingWhitespace(); // Consume ']'. |
| + range = rangeCopy; |
| + return lineNames.release(); |
| +} |
| + |
| +static bool consumeGridTrackRepeatFunction(CSSParserTokenRange& range, CSSParserMode cssParserMode, CSSValueList& list, bool& isAutoRepeat) |
| +{ |
| + 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) { |
| + repeatedValues = CSSGridAutoRepeatValue::create(args.consumeIncludingWhitespace().id()); |
| + } else { |
| + if (args.peek().type() != NumberToken || args.peek().numericValueType() != IntegerValueType) |
| + return false; |
| + double repetition = args.consumeIncludingWhitespace().numericValue(); |
| + if (repetition < 1) |
| + return false; |
| + repetitions = clampTo<size_t>(repetition, 0, kGridMaxTracks); |
| + repeatedValues = CSSValueList::createSpaceSeparated(); |
| + } |
| + if (!consumeCommaIncludingWhitespace(args)) |
| + return false; |
| + RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = consumeGridLineNames(args); |
| + if (lineNames) |
| + repeatedValues->append(lineNames.release()); |
| + |
| + size_t numberOfTracks = 0; |
| + TrackSizeRestriction restriction = isAutoRepeat ? FixedSizeOnly : AllowAll; |
| + while (!args.atEnd()) { |
| + if (isAutoRepeat && numberOfTracks) |
| + return false; |
| + RefPtrWillBeRawPtr<CSSValue> trackSize = consumeGridTrackSize(args, cssParserMode, restriction); |
| + if (!trackSize) |
| + return false; |
| + repeatedValues->append(trackSize.release()); |
| + ++numberOfTracks; |
| + lineNames = consumeGridLineNames(args); |
| + if (lineNames) |
| + repeatedValues->append(lineNames.release()); |
| + } |
| + // 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/29 02:47:39
I think you forgot to remove this from here since
rwlbuis
2016/03/29 21:15:50
Done.
|
| + return consumeIdent(range); |
| + RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated(); |
| + RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = consumeGridLineNames(range); |
| + if (lineNames) |
| + values->append(lineNames.release()); |
| + |
| + bool seenAutoRepeat = false; |
| + do { |
|
Timothy Loh
2016/03/29 02:47:39
This allows <line-names> directly before <auto-rep
svillar
2016/03/29 08:27:36
That's right. If we specify <line-names> then ther
rwlbuis
2016/03/29 21:15:51
Done.
Timothy Loh
2016/03/30 00:15:39
Not sure the TODO is accurate, or I'm misunderstan
|
| + bool isAutoRepeat; |
| + if (range.peek().functionId() == CSSValueRepeat) { |
| + if (!consumeGridTrackRepeatFunction(range, cssParserMode, *values, isAutoRepeat) || (isAutoRepeat && seenAutoRepeat)) |
|
svillar
2016/03/29 08:27:36
I would prefer this to be in two different conditi
rwlbuis
2016/03/29 21:15:50
Done.
|
| + return nullptr; |
| + seenAutoRepeat = seenAutoRepeat || isAutoRepeat; |
| + } else if (RefPtrWillBeRawPtr<CSSValue> value = consumeGridTrackSize(range, cssParserMode, seenAutoRepeat ? FixedSizeOnly : AllowAll)) { |
| + values->append(value.release()); |
| + } else { |
| + return nullptr; |
| + } |
| + lineNames = consumeGridLineNames(range); |
| + if (lineNames) |
| + values->append(lineNames.release()); |
| + } while (!range.atEnd() && range.peek().type() != DelimiterToken); |
| + // <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(); |
| +} |
| + |
| +static PassRefPtrWillBeRawPtr<CSSValue> consumeGridTemplatesRowsOrColumns(CSSParserTokenRange& range, CSSParserMode cssParserMode) |
| +{ |
| + if (range.peek().id() == CSSValueNone) |
| + return consumeIdent(range); |
| + return consumeGridTrackList(range, cssParserMode); |
| +} |
| + |
| PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty) |
| { |
| CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
| @@ -3474,6 +3587,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 consumeGridTemplatesRowsOrColumns(m_range, m_context.mode()); |
| default: |
| CSSParserValueList valueList(m_range); |
| if (valueList.size()) { |