| Index: sky/engine/core/css/parser/CSSPropertyParser.cpp
|
| diff --git a/sky/engine/core/css/parser/CSSPropertyParser.cpp b/sky/engine/core/css/parser/CSSPropertyParser.cpp
|
| index d10c78f9668f16010dbe224b073694d558520ef4..d4f307e03e4d0a97db9152c7aee4499348d55075 100644
|
| --- a/sky/engine/core/css/parser/CSSPropertyParser.cpp
|
| +++ b/sky/engine/core/css/parser/CSSPropertyParser.cpp
|
| @@ -40,8 +40,6 @@
|
| #include "core/css/CSSFontFeatureValue.h"
|
| #include "core/css/CSSFunctionValue.h"
|
| #include "core/css/CSSGradientValue.h"
|
| -#include "core/css/CSSGridLineNamesValue.h"
|
| -#include "core/css/CSSGridTemplateAreasValue.h"
|
| #include "core/css/CSSImageSetValue.h"
|
| #include "core/css/CSSImageValue.h"
|
| #include "core/css/CSSInheritedValue.h"
|
| @@ -1139,60 +1137,6 @@ bool CSSPropertyParser::parseValue(CSSPropertyID propId, bool important)
|
| return false;
|
| }
|
|
|
| - case CSSPropertyJustifySelf:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseItemPositionOverflowPosition(propId, important);
|
| - case CSSPropertyJustifyItems:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - m_valueList->setCurrentIndex(0);
|
| - return parseItemPositionOverflowPosition(propId, important);
|
| - case CSSPropertyGridAutoFlow:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - parsedValue = parseGridAutoFlow(*m_valueList);
|
| - break;
|
| - case CSSPropertyGridAutoColumns:
|
| - case CSSPropertyGridAutoRows:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - parsedValue = parseGridTrackSize(*m_valueList);
|
| - break;
|
| -
|
| - case CSSPropertyGridTemplateColumns:
|
| - case CSSPropertyGridTemplateRows:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - parsedValue = parseGridTrackList();
|
| - break;
|
| -
|
| - case CSSPropertyGridColumnEnd:
|
| - case CSSPropertyGridColumnStart:
|
| - case CSSPropertyGridRowEnd:
|
| - case CSSPropertyGridRowStart:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - parsedValue = parseGridPosition();
|
| - break;
|
| -
|
| - case CSSPropertyGridColumn:
|
| - case CSSPropertyGridRow:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseGridItemPositionShorthand(propId, important);
|
| -
|
| - case CSSPropertyGridArea:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseGridAreaShorthand(important);
|
| -
|
| - case CSSPropertyGridTemplateAreas:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - parsedValue = parseGridTemplateAreas();
|
| - break;
|
| -
|
| - case CSSPropertyGridTemplate:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseGridTemplateShorthand(important);
|
| -
|
| - case CSSPropertyGrid:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseGridShorthand(important);
|
| -
|
| case CSSPropertyWebkitMarginCollapse: {
|
| if (num == 1) {
|
| ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
|
| @@ -1391,14 +1335,6 @@ bool CSSPropertyParser::parseValue(CSSPropertyID propId, bool important)
|
| parsedValue = parseTouchAction();
|
| break;
|
|
|
| - case CSSPropertyAlignSelf:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseItemPositionOverflowPosition(propId, important);
|
| -
|
| - case CSSPropertyAlignItems:
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| - return parseItemPositionOverflowPosition(propId, important);
|
| -
|
| // Properties below are validated inside parseViewportProperty, because we
|
| // check for parser state. We need to invalidate if someone adds them outside
|
| // a @viewport rule.
|
| @@ -2977,667 +2913,6 @@ static inline bool isCSSWideKeyword(CSSParserValue& value)
|
| return value.id == CSSValueInitial || value.id == CSSValueInherit || value.id == CSSValueDefault;
|
| }
|
|
|
| -static inline bool isValidCustomIdentForGridPositions(CSSParserValue& value)
|
| -{
|
| - // FIXME: we need a more general solution for <custom-ident> in all properties.
|
| - return value.unit == CSSPrimitiveValue::CSS_IDENT && value.id != CSSValueSpan && value.id != CSSValueAuto && !isCSSWideKeyword(value);
|
| -}
|
| -
|
| -// The function parses [ <integer> || <custom-ident> ] in <grid-line> (which can be stand alone or with 'span').
|
| -bool CSSPropertyParser::parseIntegerOrCustomIdentFromGridPosition(RefPtr<CSSPrimitiveValue>& numericValue, RefPtr<CSSPrimitiveValue>& gridLineName)
|
| -{
|
| - CSSParserValue* value = m_valueList->current();
|
| - if (validUnit(value, FInteger) && value->fValue) {
|
| - numericValue = createPrimitiveNumericValue(value);
|
| - value = m_valueList->next();
|
| - if (value && isValidCustomIdentForGridPositions(*value)) {
|
| - gridLineName = createPrimitiveStringValue(m_valueList->current());
|
| - m_valueList->next();
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - if (isValidCustomIdentForGridPositions(*value)) {
|
| - gridLineName = createPrimitiveStringValue(m_valueList->current());
|
| - value = m_valueList->next();
|
| - if (value && validUnit(value, FInteger) && value->fValue) {
|
| - numericValue = createPrimitiveNumericValue(value);
|
| - m_valueList->next();
|
| - }
|
| - return true;
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -PassRefPtr<CSSValue> CSSPropertyParser::parseGridPosition()
|
| -{
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - CSSParserValue* value = m_valueList->current();
|
| - if (value->id == CSSValueAuto) {
|
| - m_valueList->next();
|
| - return cssValuePool().createIdentifierValue(CSSValueAuto);
|
| - }
|
| -
|
| - RefPtr<CSSPrimitiveValue> numericValue = nullptr;
|
| - RefPtr<CSSPrimitiveValue> gridLineName = nullptr;
|
| - bool hasSeenSpanKeyword = false;
|
| -
|
| - if (parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName)) {
|
| - value = m_valueList->current();
|
| - if (value && value->id == CSSValueSpan) {
|
| - hasSeenSpanKeyword = true;
|
| - m_valueList->next();
|
| - }
|
| - } else if (value->id == CSSValueSpan) {
|
| - hasSeenSpanKeyword = true;
|
| - if (CSSParserValue* nextValue = m_valueList->next()) {
|
| - if (!isForwardSlashOperator(nextValue) && !parseIntegerOrCustomIdentFromGridPosition(numericValue, gridLineName))
|
| - return nullptr;
|
| - }
|
| - }
|
| -
|
| - // Check that we have consumed all the value list. For shorthands, the parser will pass
|
| - // the whole value list (including the opposite position).
|
| - if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current()))
|
| - return nullptr;
|
| -
|
| - // If we didn't parse anything, this is not a valid grid position.
|
| - if (!hasSeenSpanKeyword && !gridLineName && !numericValue)
|
| - return nullptr;
|
| -
|
| - // Negative numbers are not allowed for span (but are for <integer>).
|
| - if (hasSeenSpanKeyword && numericValue && numericValue->getIntValue() < 0)
|
| - return nullptr;
|
| -
|
| - // For the <custom-ident> case.
|
| - if (gridLineName && !numericValue && !hasSeenSpanKeyword)
|
| - return cssValuePool().createValue(gridLineName->getStringValue(), CSSPrimitiveValue::CSS_STRING);
|
| -
|
| - RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
|
| - if (hasSeenSpanKeyword)
|
| - values->append(cssValuePool().createIdentifierValue(CSSValueSpan));
|
| - if (numericValue)
|
| - values->append(numericValue.release());
|
| - if (gridLineName)
|
| - values->append(gridLineName.release());
|
| - ASSERT(values->length());
|
| - return values.release();
|
| -}
|
| -
|
| -static PassRefPtr<CSSValue> gridMissingGridPositionValue(CSSValue* value)
|
| -{
|
| - if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->isString())
|
| - return value;
|
| -
|
| - return cssValuePool().createIdentifierValue(CSSValueAuto);
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
|
| -{
|
| - ShorthandScope scope(this, shorthandId);
|
| - const StylePropertyShorthand& shorthand = shorthandForProperty(shorthandId);
|
| - ASSERT(shorthand.length() == 2);
|
| -
|
| - RefPtr<CSSValue> startValue = parseGridPosition();
|
| - if (!startValue)
|
| - return false;
|
| -
|
| - RefPtr<CSSValue> endValue = nullptr;
|
| - if (m_valueList->current()) {
|
| - if (!isForwardSlashOperator(m_valueList->current()))
|
| - return false;
|
| -
|
| - if (!m_valueList->next())
|
| - return false;
|
| -
|
| - endValue = parseGridPosition();
|
| - if (!endValue || m_valueList->current())
|
| - return false;
|
| - } else {
|
| - endValue = gridMissingGridPositionValue(startValue.get());
|
| - }
|
| -
|
| - addProperty(shorthand.properties()[0], startValue, important);
|
| - addProperty(shorthand.properties()[1], endValue, important);
|
| - return true;
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseGridTemplateRowsAndAreas(PassRefPtr<CSSValue> templateColumns, bool important)
|
| -{
|
| - NamedGridAreaMap gridAreaMap;
|
| - size_t rowCount = 0;
|
| - size_t columnCount = 0;
|
| - bool trailingIdentWasAdded = false;
|
| - RefPtr<CSSValueList> templateRows = CSSValueList::createSpaceSeparated();
|
| -
|
| - // At least template-areas strings must be defined.
|
| - if (!m_valueList->current())
|
| - return false;
|
| -
|
| - while (m_valueList->current()) {
|
| - // Handle leading <custom-ident>*.
|
| - if (m_valueList->current()->unit == CSSParserValue::ValueList) {
|
| - if (trailingIdentWasAdded) {
|
| - // A row's trailing ident must be concatenated with the next row's leading one.
|
| - parseGridLineNames(*m_valueList, *templateRows, toCSSGridLineNamesValue(templateRows->item(templateRows->length() - 1)));
|
| - } else {
|
| - parseGridLineNames(*m_valueList, *templateRows);
|
| - }
|
| - }
|
| -
|
| - // Handle a template-area's row.
|
| - if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
|
| - return false;
|
| - ++rowCount;
|
| -
|
| - // Handle template-rows's track-size.
|
| - if (m_valueList->current() && m_valueList->current()->unit != CSSParserValue::ValueList && m_valueList->current()->unit != CSSPrimitiveValue::CSS_STRING) {
|
| - RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
|
| - if (!value)
|
| - return false;
|
| - templateRows->append(value);
|
| - } else {
|
| - templateRows->append(cssValuePool().createIdentifierValue(CSSValueAuto));
|
| - }
|
| -
|
| - // This will handle the trailing/leading <custom-ident>* in the grammar.
|
| - trailingIdentWasAdded = false;
|
| - if (m_valueList->current() && m_valueList->current()->unit == CSSParserValue::ValueList) {
|
| - parseGridLineNames(*m_valueList, *templateRows);
|
| - trailingIdentWasAdded = true;
|
| - }
|
| - }
|
| -
|
| - // [<track-list> /]?
|
| - if (templateColumns)
|
| - addProperty(CSSPropertyGridTemplateColumns, templateColumns, important);
|
| - else
|
| - addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentifierValue(CSSValueNone), important);
|
| -
|
| - // [<line-names>? <string> [<track-size> <line-names>]? ]+
|
| - RefPtr<CSSValue> templateAreas = CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
|
| - addProperty(CSSPropertyGridTemplateAreas, templateAreas.release(), important);
|
| - addProperty(CSSPropertyGridTemplateRows, templateRows.release(), important);
|
| -
|
| -
|
| - return true;
|
| -}
|
| -
|
| -
|
| -bool CSSPropertyParser::parseGridTemplateShorthand(bool important)
|
| -{
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - ShorthandScope scope(this, CSSPropertyGridTemplate);
|
| - ASSERT(gridTemplateShorthand().length() == 3);
|
| -
|
| - // At least "none" must be defined.
|
| - if (!m_valueList->current())
|
| - return false;
|
| -
|
| - bool firstValueIsNone = m_valueList->current()->id == CSSValueNone;
|
| -
|
| - // 1- 'none' case.
|
| - if (firstValueIsNone && !m_valueList->next()) {
|
| - addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentifierValue(CSSValueNone), important);
|
| - addProperty(CSSPropertyGridTemplateRows, cssValuePool().createIdentifierValue(CSSValueNone), important);
|
| - addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifierValue(CSSValueNone), important);
|
| - return true;
|
| - }
|
| -
|
| - unsigned index = 0;
|
| - RefPtr<CSSValue> columnsValue = nullptr;
|
| - if (firstValueIsNone) {
|
| - columnsValue = cssValuePool().createIdentifierValue(CSSValueNone);
|
| - } else {
|
| - columnsValue = parseGridTrackList();
|
| - }
|
| -
|
| - // 2- <grid-template-columns> / <grid-template-columns> syntax.
|
| - if (columnsValue) {
|
| - if (!(m_valueList->current() && isForwardSlashOperator(m_valueList->current()) && m_valueList->next()))
|
| - return false;
|
| - index = m_valueList->currentIndex();
|
| - if (RefPtr<CSSValue> rowsValue = parseGridTrackList()) {
|
| - if (m_valueList->current())
|
| - return false;
|
| - addProperty(CSSPropertyGridTemplateColumns, columnsValue, important);
|
| - addProperty(CSSPropertyGridTemplateRows, rowsValue, important);
|
| - addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifierValue(CSSValueNone), important);
|
| - return true;
|
| - }
|
| - }
|
| -
|
| -
|
| - // 3- [<track-list> /]? [<line-names>? <string> [<track-size> <line-names>]? ]+ syntax.
|
| - // The template-columns <track-list> can't be 'none'.
|
| - if (firstValueIsNone)
|
| - return false;
|
| - // It requires to rewind parsing due to previous syntax failures.
|
| - m_valueList->setCurrentIndex(index);
|
| - return parseGridTemplateRowsAndAreas(columnsValue, important);
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseGridShorthand(bool important)
|
| -{
|
| - ShorthandScope scope(this, CSSPropertyGrid);
|
| - ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 4);
|
| -
|
| - // 1- <grid-template>
|
| - if (parseGridTemplateShorthand(important)) {
|
| - // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
|
| - // The sub-properties not specified are set to their initial value, as normal for shorthands.
|
| - addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitialValue(), important);
|
| - addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitInitialValue(), important);
|
| - addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitialValue(), important);
|
| - return true;
|
| - }
|
| -
|
| - // Need to rewind parsing to explore the alternative syntax of this shorthand.
|
| - m_valueList->setCurrentIndex(0);
|
| -
|
| - // 2- <grid-auto-flow> [ <grid-auto-columns> [ / <grid-auto-rows> ]? ]
|
| - if (!parseValue(CSSPropertyGridAutoFlow, important))
|
| - return false;
|
| -
|
| - RefPtr<CSSValue> autoColumnsValue = nullptr;
|
| - RefPtr<CSSValue> autoRowsValue = nullptr;
|
| -
|
| - if (m_valueList->current()) {
|
| - autoColumnsValue = parseGridTrackSize(*m_valueList);
|
| - if (!autoColumnsValue)
|
| - return false;
|
| - if (m_valueList->current()) {
|
| - if (!isForwardSlashOperator(m_valueList->current()) || !m_valueList->next())
|
| - return false;
|
| - autoRowsValue = parseGridTrackSize(*m_valueList);
|
| - if (!autoRowsValue)
|
| - return false;
|
| - }
|
| - if (m_valueList->current())
|
| - return false;
|
| - } else {
|
| - // Other omitted values are set to their initial values.
|
| - autoColumnsValue = cssValuePool().createImplicitInitialValue();
|
| - autoRowsValue = cssValuePool().createImplicitInitialValue();
|
| - }
|
| -
|
| - // if <grid-auto-rows> value is omitted, it is set to the value specified for grid-auto-columns.
|
| - if (!autoRowsValue)
|
| - autoRowsValue = autoColumnsValue;
|
| -
|
| - addProperty(CSSPropertyGridAutoColumns, autoColumnsValue, important);
|
| - addProperty(CSSPropertyGridAutoRows, autoRowsValue, important);
|
| -
|
| - // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
|
| - // The sub-properties not specified are set to their initial value, as normal for shorthands.
|
| - addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitInitialValue(), important);
|
| - addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitialValue(), important);
|
| - addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitInitialValue(), important);
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseGridAreaShorthand(bool important)
|
| -{
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - ShorthandScope scope(this, CSSPropertyGridArea);
|
| - const StylePropertyShorthand& shorthand = gridAreaShorthand();
|
| - ASSERT_UNUSED(shorthand, shorthand.length() == 4);
|
| -
|
| - RefPtr<CSSValue> rowStartValue = parseGridPosition();
|
| - if (!rowStartValue)
|
| - return false;
|
| -
|
| - RefPtr<CSSValue> columnStartValue = nullptr;
|
| - if (!parseSingleGridAreaLonghand(columnStartValue))
|
| - return false;
|
| -
|
| - RefPtr<CSSValue> rowEndValue = nullptr;
|
| - if (!parseSingleGridAreaLonghand(rowEndValue))
|
| - return false;
|
| -
|
| - RefPtr<CSSValue> columnEndValue = nullptr;
|
| - if (!parseSingleGridAreaLonghand(columnEndValue))
|
| - return false;
|
| -
|
| - if (!columnStartValue)
|
| - columnStartValue = gridMissingGridPositionValue(rowStartValue.get());
|
| -
|
| - if (!rowEndValue)
|
| - rowEndValue = gridMissingGridPositionValue(rowStartValue.get());
|
| -
|
| - if (!columnEndValue)
|
| - columnEndValue = gridMissingGridPositionValue(columnStartValue.get());
|
| -
|
| - addProperty(CSSPropertyGridRowStart, rowStartValue, important);
|
| - addProperty(CSSPropertyGridColumnStart, columnStartValue, important);
|
| - addProperty(CSSPropertyGridRowEnd, rowEndValue, important);
|
| - addProperty(CSSPropertyGridColumnEnd, columnEndValue, important);
|
| - return true;
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseSingleGridAreaLonghand(RefPtr<CSSValue>& property)
|
| -{
|
| - if (!m_valueList->current())
|
| - return true;
|
| -
|
| - if (!isForwardSlashOperator(m_valueList->current()))
|
| - return false;
|
| -
|
| - if (!m_valueList->next())
|
| - return false;
|
| -
|
| - property = parseGridPosition();
|
| - return true;
|
| -}
|
| -
|
| -void CSSPropertyParser::parseGridLineNames(CSSParserValueList& inputList, CSSValueList& valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames)
|
| -{
|
| - ASSERT(inputList.current() && inputList.current()->unit == CSSParserValue::ValueList);
|
| -
|
| - CSSParserValueList* identList = inputList.current()->valueList;
|
| - if (!identList->size()) {
|
| - inputList.next();
|
| - return;
|
| - }
|
| -
|
| - // Need to ensure the identList is at the heading index, since the parserList might have been rewound.
|
| - identList->setCurrentIndex(0);
|
| -
|
| - RefPtr<CSSGridLineNamesValue> lineNames = previousNamedAreaTrailingLineNames;
|
| - if (!lineNames)
|
| - lineNames = CSSGridLineNamesValue::create();
|
| - while (CSSParserValue* identValue = identList->current()) {
|
| - ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
|
| - RefPtr<CSSPrimitiveValue> lineName = createPrimitiveStringValue(identValue);
|
| - lineNames->append(lineName.release());
|
| - identList->next();
|
| - }
|
| - if (!previousNamedAreaTrailingLineNames)
|
| - valueList.append(lineNames.release());
|
| -
|
| - inputList.next();
|
| -}
|
| -
|
| -PassRefPtr<CSSValue> CSSPropertyParser::parseGridTrackList()
|
| -{
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - CSSParserValue* value = m_valueList->current();
|
| - if (value->id == CSSValueNone) {
|
| - m_valueList->next();
|
| - return cssValuePool().createIdentifierValue(CSSValueNone);
|
| - }
|
| -
|
| - RefPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
|
| - // Handle leading <ident>*.
|
| - value = m_valueList->current();
|
| - if (value && value->unit == CSSParserValue::ValueList)
|
| - parseGridLineNames(*m_valueList, *values);
|
| -
|
| - bool seenTrackSizeOrRepeatFunction = false;
|
| - while (CSSParserValue* currentValue = m_valueList->current()) {
|
| - if (isForwardSlashOperator(currentValue))
|
| - break;
|
| - if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) {
|
| - if (!parseGridTrackRepeatFunction(*values))
|
| - return nullptr;
|
| - seenTrackSizeOrRepeatFunction = true;
|
| - } else {
|
| - RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
|
| - if (!value)
|
| - return nullptr;
|
| - values->append(value);
|
| - seenTrackSizeOrRepeatFunction = true;
|
| - }
|
| - // This will handle the trailing <ident>* in the grammar.
|
| - value = m_valueList->current();
|
| - if (value && value->unit == CSSParserValue::ValueList)
|
| - parseGridLineNames(*m_valueList, *values);
|
| - }
|
| -
|
| - // We should have found a <track-size> or else it is not a valid <track-list>
|
| - if (!seenTrackSizeOrRepeatFunction)
|
| - return nullptr;
|
| -
|
| - return values;
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseGridTrackRepeatFunction(CSSValueList& list)
|
| -{
|
| - CSSParserValueList* arguments = m_valueList->current()->function->args.get();
|
| - if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
|
| - return false;
|
| -
|
| - ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
|
| - size_t repetitions = arguments->valueAt(0)->fValue;
|
| -
|
| - // The spec allows us to clamp the number of repetitions: http://www.w3.org/TR/css-grid-1/#repeat-notation
|
| - const size_t maxRepetitions = 10000;
|
| - repetitions = std::min(repetitions, maxRepetitions);
|
| -
|
| - RefPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
|
| - arguments->next(); // Skip the repetition count.
|
| - arguments->next(); // Skip the comma.
|
| -
|
| - // Handle leading <ident>*.
|
| - CSSParserValue* currentValue = arguments->current();
|
| - if (currentValue && currentValue->unit == CSSParserValue::ValueList)
|
| - parseGridLineNames(*arguments, *repeatedValues);
|
| -
|
| - bool seenTrackSize = false;
|
| - while (arguments->current()) {
|
| - RefPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
|
| - if (!trackSize)
|
| - return false;
|
| -
|
| - repeatedValues->append(trackSize);
|
| - seenTrackSize = true;
|
| -
|
| - // This takes care of any trailing <ident>* in the grammar.
|
| - currentValue = arguments->current();
|
| - if (currentValue && currentValue->unit == CSSParserValue::ValueList)
|
| - parseGridLineNames(*arguments, *repeatedValues);
|
| - }
|
| -
|
| - // We should have found at least one <track-size> or else it is not a valid <track-list>.
|
| - if (!seenTrackSize)
|
| - return false;
|
| -
|
| - for (size_t i = 0; i < repetitions; ++i) {
|
| - for (size_t j = 0; j < repeatedValues->length(); ++j)
|
| - list.append(repeatedValues->item(j));
|
| - }
|
| -
|
| - // parseGridTrackSize iterated over the repeat arguments, move to the next value.
|
| - m_valueList->next();
|
| - return true;
|
| -}
|
| -
|
| -
|
| -PassRefPtr<CSSValue> CSSPropertyParser::parseGridTrackSize(CSSParserValueList& inputList)
|
| -{
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - CSSParserValue* currentValue = inputList.current();
|
| - inputList.next();
|
| -
|
| - if (currentValue->id == CSSValueAuto)
|
| - return cssValuePool().createIdentifierValue(CSSValueAuto);
|
| -
|
| - if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "minmax(")) {
|
| - // The spec defines the following grammar: minmax( <track-breadth> , <track-breadth> )
|
| - CSSParserValueList* arguments = currentValue->function->args.get();
|
| - if (!arguments || arguments->size() != 3 || !isComma(arguments->valueAt(1)))
|
| - return nullptr;
|
| -
|
| - RefPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(arguments->valueAt(0));
|
| - if (!minTrackBreadth)
|
| - return nullptr;
|
| -
|
| - RefPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(arguments->valueAt(2));
|
| - if (!maxTrackBreadth)
|
| - return nullptr;
|
| -
|
| - RefPtr<CSSValueList> parsedArguments = CSSValueList::createCommaSeparated();
|
| - parsedArguments->append(minTrackBreadth);
|
| - parsedArguments->append(maxTrackBreadth);
|
| - return CSSFunctionValue::create("minmax(", parsedArguments);
|
| - }
|
| -
|
| - return parseGridBreadth(currentValue);
|
| -}
|
| -
|
| -PassRefPtr<CSSPrimitiveValue> CSSPropertyParser::parseGridBreadth(CSSParserValue* currentValue)
|
| -{
|
| - if (currentValue->id == CSSValueMinContent || currentValue->id == CSSValueMaxContent)
|
| - return cssValuePool().createIdentifierValue(currentValue->id);
|
| -
|
| - if (currentValue->unit == CSSPrimitiveValue::CSS_FR) {
|
| - double flexValue = currentValue->fValue;
|
| -
|
| - // Fractional unit is a non-negative dimension.
|
| - if (flexValue <= 0)
|
| - return nullptr;
|
| -
|
| - return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
|
| - }
|
| -
|
| - if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
|
| - return nullptr;
|
| -
|
| - return createPrimitiveNumericValue(currentValue);
|
| -}
|
| -
|
| -bool CSSPropertyParser::parseGridTemplateAreasRow(NamedGridAreaMap& gridAreaMap, const size_t rowCount, size_t& columnCount)
|
| -{
|
| - CSSParserValue* currentValue = m_valueList->current();
|
| - if (!currentValue || currentValue->unit != CSSPrimitiveValue::CSS_STRING)
|
| - return false;
|
| -
|
| - String gridRowNames = currentValue->string;
|
| - if (!gridRowNames.length())
|
| - return false;
|
| -
|
| - Vector<String> columnNames;
|
| - gridRowNames.split(' ', columnNames);
|
| -
|
| - if (!columnCount) {
|
| - columnCount = columnNames.size();
|
| - ASSERT(columnCount);
|
| - } else if (columnCount != columnNames.size()) {
|
| - // The declaration is invalid is all the rows don't have the number of columns.
|
| - return false;
|
| - }
|
| -
|
| - for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
|
| - const String& gridAreaName = columnNames[currentCol];
|
| -
|
| - // Unamed areas are always valid (we consider them to be 1x1).
|
| - if (gridAreaName == ".")
|
| - continue;
|
| -
|
| - // We handle several grid areas with the same name at once to simplify the validation code.
|
| - size_t lookAheadCol;
|
| - for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
|
| - if (columnNames[lookAheadCol + 1] != gridAreaName)
|
| - break;
|
| - }
|
| -
|
| - NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
|
| - if (gridAreaIt == gridAreaMap.end()) {
|
| - gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
|
| - } else {
|
| - GridCoordinate& gridCoordinate = gridAreaIt->value;
|
| -
|
| - // The following checks test that the grid area is a single filled-in rectangle.
|
| - // 1. The new row is adjacent to the previously parsed row.
|
| - if (rowCount != gridCoordinate.rows.resolvedFinalPosition.next().toInt())
|
| - return false;
|
| -
|
| - // 2. The new area starts at the same position as the previously parsed area.
|
| - if (currentCol != gridCoordinate.columns.resolvedInitialPosition.toInt())
|
| - return false;
|
| -
|
| - // 3. The new area ends at the same position as the previously parsed area.
|
| - if (lookAheadCol != gridCoordinate.columns.resolvedFinalPosition.toInt())
|
| - return false;
|
| -
|
| - ++gridCoordinate.rows.resolvedFinalPosition;
|
| - }
|
| - currentCol = lookAheadCol;
|
| - }
|
| -
|
| - m_valueList->next();
|
| - return true;
|
| -}
|
| -
|
| -PassRefPtr<CSSValue> CSSPropertyParser::parseGridTemplateAreas()
|
| -{
|
| - NamedGridAreaMap gridAreaMap;
|
| - size_t rowCount = 0;
|
| - size_t columnCount = 0;
|
| -
|
| - while (m_valueList->current()) {
|
| - if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
|
| - return nullptr;
|
| - ++rowCount;
|
| - }
|
| -
|
| - if (!rowCount || !columnCount)
|
| - return nullptr;
|
| -
|
| - return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
|
| -}
|
| -
|
| -PassRefPtr<CSSValue> CSSPropertyParser::parseGridAutoFlow(CSSParserValueList& list)
|
| -{
|
| - // [ row | column ] && dense? | stack && [ row | column ]?
|
| - ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
|
| -
|
| - CSSParserValue* value = list.current();
|
| - if (!value)
|
| - return nullptr;
|
| -
|
| - RefPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
|
| -
|
| - // First parameter.
|
| - CSSValueID firstId = value->id;
|
| - if (firstId != CSSValueRow && firstId != CSSValueColumn && firstId != CSSValueDense && firstId != CSSValueStack)
|
| - return nullptr;
|
| - parsedValues->append(cssValuePool().createIdentifierValue(firstId));
|
| -
|
| - // Second parameter, if any.
|
| - value = list.next();
|
| - if (!value && firstId == CSSValueDense)
|
| - return nullptr;
|
| -
|
| - if (value) {
|
| - switch (firstId) {
|
| - case CSSValueRow:
|
| - case CSSValueColumn:
|
| - if (value->id != CSSValueDense && value->id != CSSValueStack)
|
| - return parsedValues;
|
| - break;
|
| - case CSSValueDense:
|
| - case CSSValueStack:
|
| - if (value->id != CSSValueRow && value->id != CSSValueColumn)
|
| - return parsedValues;
|
| - break;
|
| - default:
|
| - return parsedValues;
|
| - }
|
| - parsedValues->append(cssValuePool().createIdentifierValue(value->id));
|
| - list.next();
|
| - }
|
| -
|
| - return parsedValues;
|
| -}
|
| -
|
| bool CSSPropertyParser::parseClipShape(CSSPropertyID propId, bool important)
|
| {
|
| CSSParserValue* value = m_valueList->current();
|
|
|