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

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

Issue 1877073004: Move the grid shorthand into CSSPropertyParser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Patch for landing Created 4 years, 8 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 side-by-side diff with in-line comments
Download patch
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 419adc0c8689172fb5591fedd15974a368a99914..365a88dee4ca2ec5c7e41bd993ab6401e2962c64 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -18,6 +18,7 @@
#include "core/css/CSSGradientValue.h"
#include "core/css/CSSGridAutoRepeatValue.h"
#include "core/css/CSSGridLineNamesValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
#include "core/css/CSSImageSetValue.h"
#include "core/css/CSSPaintValue.h"
#include "core/css/CSSPathValue.h"
@@ -59,6 +60,39 @@ CSSPropertyParser::CSSPropertyParser(const CSSParserTokenRange& range,
m_range.consumeWhitespace();
}
+void CSSPropertyParser::addProperty(CSSPropertyID property, CSSValue* value, bool important, bool implicit)
+{
+ ASSERT(!isPropertyAlias(property));
+
+ int shorthandIndex = 0;
+ bool setFromShorthand = false;
+
+ if (m_currentShorthand) {
+ Vector<StylePropertyShorthand, 4> shorthands;
+ getMatchingShorthandsForLonghand(property, &shorthands);
+ setFromShorthand = true;
+ if (shorthands.size() > 1)
+ shorthandIndex = indexOfShorthandForLonghand(m_currentShorthand, shorthands);
+ }
+
+ m_parsedProperties->append(CSSProperty(property, value, important, setFromShorthand, shorthandIndex, implicit));
+}
+
+void CSSPropertyParser::addExpandedPropertyForValue(CSSPropertyID property, CSSValue* value, bool important)
+{
+ const StylePropertyShorthand& shorthand = shorthandForProperty(property);
+ unsigned shorthandLength = shorthand.length();
+ if (!shorthandLength) {
+ addProperty(property, value, important);
+ return;
+ }
+
+ ShorthandScope scope(this, property);
+ const CSSPropertyID* longhands = shorthand.properties();
+ for (unsigned i = 0; i < shorthandLength; ++i)
+ addProperty(longhands[i], value, important);
+}
+
static bool hasInvalidNumericValues(const CSSParserTokenRange& range)
{
for (const CSSParserToken& token : range) {
@@ -2923,7 +2957,7 @@ static CSSValue* consumeBackgroundSize(CSSPropertyID unresolvedProperty, CSSPars
return CSSValuePair::create(horizontal, vertical, CSSValuePair::KeepIdenticalValues);
}
-CSSValueList* consumeGridAutoFlow(CSSParserTokenRange& range)
+static CSSValueList* consumeGridAutoFlow(CSSParserTokenRange& range)
{
CSSPrimitiveValue* rowOrColumnValue = consumeIdent<CSSValueRow, CSSValueColumn>(range);
CSSPrimitiveValue* denseAlgorithm = consumeIdent<CSSValueDense>(range);
@@ -3102,6 +3136,124 @@ static CSSValue* consumeGridLine(CSSParserTokenRange& range)
return values;
}
+static bool allTracksAreFixedSized(CSSValueList& valueList)
+{
+ for (CSSValue* value : valueList) {
+ if (value->isGridLineNamesValue())
+ continue;
+ // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax( <fixed-breadth>, <track-breadth> )
+ if (value->isGridAutoRepeatValue()) {
+ if (!allTracksAreFixedSized(toCSSValueList(*value)))
+ return false;
+ continue;
+ }
+ const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue()
+ ? toCSSPrimitiveValue(*value)
+ : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0));
+ CSSValueID valueID = primitiveValue.getValueID();
+ if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || valueID == CSSValueAuto || primitiveValue.isFlex())
+ return false;
+ }
+ return true;
+}
+
+static Vector<String> parseGridTemplateAreasColumnNames(const String& gridRowNames)
+{
+ ASSERT(!gridRowNames.isEmpty());
+ Vector<String> columnNames;
+ // Using StringImpl to avoid checks and indirection in every call to String::operator[].
+ StringImpl& text = *gridRowNames.impl();
+
+ StringBuilder areaName;
+ for (unsigned i = 0; i < text.length(); ++i) {
+ // TODO(rob.buis): this whitespace check misses \n and \t.
+ // https://drafts.csswg.org/css-grid/#valdef-grid-template-areas-string
+ // https://drafts.csswg.org/css-syntax-3/#whitespace
+ if (text[i] == ' ') {
+ if (!areaName.isEmpty()) {
+ columnNames.append(areaName.toString());
+ areaName.clear();
+ }
+ continue;
+ }
+ if (text[i] == '.') {
+ if (areaName == ".")
+ continue;
+ if (!areaName.isEmpty()) {
+ columnNames.append(areaName.toString());
+ areaName.clear();
+ }
+ } else {
+ // TODO(rob.buis): only allow name code points here.
+ if (areaName == ".") {
+ columnNames.append(areaName.toString());
+ areaName.clear();
+ }
+ }
+
+ areaName.append(text[i]);
+ }
+
+ if (!areaName.isEmpty())
+ columnNames.append(areaName.toString());
+
+ return columnNames;
+}
+
+static bool parseGridTemplateAreasRow(const String& gridRowNames, NamedGridAreaMap& gridAreaMap, const size_t rowCount, size_t& columnCount)
+{
+ if (gridRowNames.isEmpty() || gridRowNames.containsOnlyWhitespace())
+ return false;
+
+ Vector<String> columnNames = parseGridTemplateAreasColumnNames(gridRowNames);
+ if (rowCount == 0) {
+ columnCount = columnNames.size();
+ ASSERT(columnCount);
+ } else if (columnCount != columnNames.size()) {
+ // The declaration is invalid if all the rows don't have the number of columns.
+ return false;
+ }
+
+ for (size_t currentColumn = 0; currentColumn < columnCount; ++currentColumn) {
+ const String& gridAreaName = columnNames[currentColumn];
+
+ // Unamed areas are always valid (we consider them to be 1x1).
+ if (gridAreaName == ".")
+ continue;
+
+ size_t lookAheadColumn = currentColumn + 1;
+ while (lookAheadColumn < columnCount && columnNames[lookAheadColumn] == gridAreaName)
+ lookAheadColumn++;
+
+ NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
+ if (gridAreaIt == gridAreaMap.end()) {
+ gridAreaMap.add(gridAreaName, GridArea(GridSpan::translatedDefiniteGridSpan(rowCount, rowCount + 1), GridSpan::translatedDefiniteGridSpan(currentColumn, lookAheadColumn)));
+ } else {
+ GridArea& gridArea = 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 != gridArea.rows.endLine())
+ return false;
+
+ // 2. The new area starts at the same position as the previously parsed area.
+ if (currentColumn != gridArea.columns.startLine())
+ return false;
+
+ // 3. The new area ends at the same position as the previously parsed area.
+ if (lookAheadColumn != gridArea.columns.endLine())
+ return false;
+
+ gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.startLine(), gridArea.rows.endLine() + 1);
+ }
+ currentColumn = lookAheadColumn - 1;
+ }
+
+ return true;
+}
+
+enum TrackSizeRestriction { FixedSizeOnly, AllowAll };
+
static CSSPrimitiveValue* consumeGridBreadth(CSSParserTokenRange& range, CSSParserMode cssParserMode, TrackSizeRestriction restriction = AllowAll)
{
if (restriction == AllowAll) {
@@ -3118,7 +3270,7 @@ static CSSPrimitiveValue* consumeGridBreadth(CSSParserTokenRange& range, CSSPars
}
// TODO(rob.buis): This needs a bool parameter so we can disallow <auto-track-list> for the grid shorthand.
-CSSValue* consumeGridTrackSize(CSSParserTokenRange& range, CSSParserMode cssParserMode, TrackSizeRestriction restriction)
+static CSSValue* consumeGridTrackSize(CSSParserTokenRange& range, CSSParserMode cssParserMode, TrackSizeRestriction restriction = AllowAll)
{
const CSSParserToken& token = range.peek();
if (restriction == AllowAll && identMatches<CSSValueAuto>(token.id()))
@@ -4563,6 +4715,70 @@ bool CSSPropertyParser::consumeGridTemplateShorthand(bool important)
return consumeGridTemplateRowsAndAreasAndColumns(important);
}
+bool CSSPropertyParser::consumeGridShorthand(bool important)
+{
+ ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+ ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8);
+
+ CSSParserTokenRange rangeCopy = m_range;
+
+ // 1- <grid-template>
+ if (consumeGridTemplateShorthand(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);
+ addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialValue(), important);
+ addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue(), important);
+ return true;
+ }
+
+ m_range = rangeCopy;
+
+ // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ]
+ CSSValueList* gridAutoFlow = consumeGridAutoFlow(m_range);
+ if (!gridAutoFlow)
+ return false;
+
+ CSSValue* autoColumnsValue = nullptr;
+ CSSValue* autoRowsValue = nullptr;
+
+ if (!m_range.atEnd()) {
+ autoRowsValue = consumeGridTrackSize(m_range, m_context.mode());
+ if (!autoRowsValue)
+ return false;
+ if (consumeSlashIncludingWhitespace(m_range)) {
+ autoColumnsValue = consumeGridTrackSize(m_range, m_context.mode());
+ if (!autoColumnsValue)
+ return false;
+ }
+ if (!m_range.atEnd())
+ return false;
+ } else {
+ // Other omitted values are set to their initial values.
+ autoColumnsValue = cssValuePool().createImplicitInitialValue();
+ autoRowsValue = cssValuePool().createImplicitInitialValue();
+ }
+
+ // if <grid-auto-columns> value is omitted, it is set to the value specified for grid-auto-rows.
+ if (!autoColumnsValue)
+ autoColumnsValue = autoRowsValue;
+
+ // 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);
+ addProperty(CSSPropertyGridAutoFlow, gridAutoFlow, important);
+ addProperty(CSSPropertyGridAutoColumns, autoColumnsValue, important);
+ addProperty(CSSPropertyGridAutoRows, autoRowsValue, important);
+ addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialValue(), important);
+ addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue(), important);
+
+ return true;
+}
+
bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important)
{
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -4747,13 +4963,11 @@ bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im
return consumeGridAreaShorthand(important);
case CSSPropertyGridTemplate:
return consumeGridTemplateShorthand(important);
+ case CSSPropertyGrid:
+ return consumeGridShorthand(important);
default:
m_currentShorthand = oldShorthand;
- CSSParserValueList valueList(m_range);
- if (!valueList.size())
- return false;
- m_valueList = &valueList;
- return legacyParseShorthand(unresolvedProperty, important);
+ return false;
}
}

Powered by Google App Engine
This is Rietveld 408576698