| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) | |
| 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | |
| 4 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc.
All rights reserved. | |
| 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> | |
| 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | |
| 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | |
| 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. | |
| 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. | |
| 10 * | |
| 11 * This library is free software; you can redistribute it and/or | |
| 12 * modify it under the terms of the GNU Library General Public | |
| 13 * License as published by the Free Software Foundation; either | |
| 14 * version 2 of the License, or (at your option) any later version. | |
| 15 * | |
| 16 * This library is distributed in the hope that it will be useful, | |
| 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 19 * Library General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU Library General Public License | |
| 22 * along with this library; see the file COPYING.LIB. If not, write to | |
| 23 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | |
| 24 * Boston, MA 02110-1301, USA. | |
| 25 */ | |
| 26 | |
| 27 #include "core/css/parser/CSSPropertyParser.h" | |
| 28 | |
| 29 #include "core/StylePropertyShorthand.h" | |
| 30 #include "core/css/CSSCustomIdentValue.h" | |
| 31 #include "core/css/CSSFunctionValue.h" | |
| 32 #include "core/css/CSSGridAutoRepeatValue.h" | |
| 33 #include "core/css/CSSGridLineNamesValue.h" | |
| 34 #include "core/css/CSSPrimitiveValueMappings.h" | |
| 35 #include "core/css/CSSValuePair.h" | |
| 36 #include "core/css/CSSValuePool.h" | |
| 37 #include "core/css/parser/CSSParserValues.h" | |
| 38 #include "core/css/parser/CSSPropertyParserHelpers.h" | |
| 39 #include "core/style/GridArea.h" | |
| 40 #include "platform/RuntimeEnabledFeatures.h" | |
| 41 | |
| 42 namespace blink { | |
| 43 | |
| 44 using namespace CSSPropertyParserHelpers; | |
| 45 | |
| 46 void CSSPropertyParser::addProperty(CSSPropertyID propId, CSSValue* value, bool
important, bool implicit) | |
| 47 { | |
| 48 ASSERT(!isPropertyAlias(propId)); | |
| 49 | |
| 50 int shorthandIndex = 0; | |
| 51 bool setFromShorthand = false; | |
| 52 | |
| 53 if (m_currentShorthand) { | |
| 54 Vector<StylePropertyShorthand, 4> shorthands; | |
| 55 getMatchingShorthandsForLonghand(propId, &shorthands); | |
| 56 setFromShorthand = true; | |
| 57 if (shorthands.size() > 1) | |
| 58 shorthandIndex = indexOfShorthandForLonghand(m_currentShorthand, sho
rthands); | |
| 59 } | |
| 60 | |
| 61 m_parsedProperties->append(CSSProperty(propId, value, important, setFromShor
thand, shorthandIndex, implicit)); | |
| 62 } | |
| 63 | |
| 64 void CSSPropertyParser::addExpandedPropertyForValue(CSSPropertyID propId, CSSVal
ue* value, bool important) | |
| 65 { | |
| 66 const StylePropertyShorthand& shorthand = shorthandForProperty(propId); | |
| 67 unsigned shorthandLength = shorthand.length(); | |
| 68 if (!shorthandLength) { | |
| 69 addProperty(propId, value, important); | |
| 70 return; | |
| 71 } | |
| 72 | |
| 73 ShorthandScope scope(this, propId); | |
| 74 const CSSPropertyID* longhands = shorthand.properties(); | |
| 75 for (unsigned i = 0; i < shorthandLength; ++i) | |
| 76 addProperty(longhands[i], value, important); | |
| 77 } | |
| 78 | |
| 79 bool CSSPropertyParser::legacyParseShorthand(CSSPropertyID propertyID, bool impo
rtant) | |
| 80 { | |
| 81 switch (propertyID) { | |
| 82 case CSSPropertyGrid: | |
| 83 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | |
| 84 return parseGridShorthand(important); | |
| 85 | |
| 86 // The remaining shorthands are handled in CSSPropertyParser.cpp | |
| 87 default: | |
| 88 return false; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 bool CSSPropertyParser::parseGridShorthand(bool important) | |
| 93 { | |
| 94 ShorthandScope scope(this, CSSPropertyGrid); | |
| 95 ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8); | |
| 96 | |
| 97 CSSParserTokenRange rangeCopy = m_range; | |
| 98 | |
| 99 // 1- <grid-template> | |
| 100 if (consumeGridTemplateShorthand(important)) { | |
| 101 // It can only be specified the explicit or the implicit grid properties
in a single grid declaration. | |
| 102 // The sub-properties not specified are set to their initial value, as n
ormal for shorthands. | |
| 103 addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitia
lValue(), important); | |
| 104 addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitIni
tialValue(), important); | |
| 105 addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitia
lValue(), important); | |
| 106 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitIniti
alValue(), important); | |
| 107 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialV
alue(), important); | |
| 108 return true; | |
| 109 } | |
| 110 | |
| 111 m_range = rangeCopy; | |
| 112 | |
| 113 // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ] | |
| 114 CSSValueList* gridAutoFlow = consumeGridAutoFlow(m_range); | |
| 115 if (!gridAutoFlow) | |
| 116 return false; | |
| 117 | |
| 118 CSSValue* autoColumnsValue = nullptr; | |
| 119 CSSValue* autoRowsValue = nullptr; | |
| 120 | |
| 121 if (!m_range.atEnd()) { | |
| 122 autoRowsValue = consumeGridTrackSize(m_range, m_context.mode()); | |
| 123 if (!autoRowsValue) | |
| 124 return false; | |
| 125 if (consumeSlashIncludingWhitespace(m_range)) { | |
| 126 autoColumnsValue = consumeGridTrackSize(m_range, m_context.mode()); | |
| 127 if (!autoColumnsValue) | |
| 128 return false; | |
| 129 } | |
| 130 if (!m_range.atEnd()) | |
| 131 return false; | |
| 132 } else { | |
| 133 // Other omitted values are set to their initial values. | |
| 134 autoColumnsValue = cssValuePool().createImplicitInitialValue(); | |
| 135 autoRowsValue = cssValuePool().createImplicitInitialValue(); | |
| 136 } | |
| 137 | |
| 138 // if <grid-auto-columns> value is omitted, it is set to the value specified
for grid-auto-rows. | |
| 139 if (!autoColumnsValue) | |
| 140 autoColumnsValue = autoRowsValue; | |
| 141 | |
| 142 addProperty(CSSPropertyGridAutoFlow, gridAutoFlow, important); | |
| 143 addProperty(CSSPropertyGridAutoColumns, autoColumnsValue, important); | |
| 144 addProperty(CSSPropertyGridAutoRows, autoRowsValue, important); | |
| 145 | |
| 146 // It can only be specified the explicit or the implicit grid properties in
a single grid declaration. | |
| 147 // The sub-properties not specified are set to their initial value, as norma
l for shorthands. | |
| 148 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitIni
tialValue(), important); | |
| 149 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitia
lValue(), important); | |
| 150 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitIniti
alValue(), important); | |
| 151 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialVa
lue(), important); | |
| 152 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue
(), important); | |
| 153 | |
| 154 return true; | |
| 155 } | |
| 156 | |
| 157 bool allTracksAreFixedSized(CSSValueList& valueList) | |
| 158 { | |
| 159 for (auto value : valueList) { | |
| 160 if (value->isGridLineNamesValue()) | |
| 161 continue; | |
| 162 // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax
( <fixed-breadth>, <track-breadth> ) | |
| 163 if (value->isGridAutoRepeatValue()) { | |
| 164 if (!allTracksAreFixedSized(toCSSValueList(*value))) | |
| 165 return false; | |
| 166 continue; | |
| 167 } | |
| 168 ASSERT(value->isPrimitiveValue() || (value->isFunctionValue() && toCSSFu
nctionValue(*value).item(0))); | |
| 169 const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue() | |
| 170 ? toCSSPrimitiveValue(*value) | |
| 171 : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0)); | |
| 172 CSSValueID valueID = primitiveValue.getValueID(); | |
| 173 if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || va
lueID == CSSValueAuto || primitiveValue.isFlex()) | |
| 174 return false; | |
| 175 } | |
| 176 return true; | |
| 177 } | |
| 178 | |
| 179 static Vector<String> parseGridTemplateAreasColumnNames(const String& gridRowNam
es) | |
| 180 { | |
| 181 ASSERT(!gridRowNames.isEmpty()); | |
| 182 Vector<String> columnNames; | |
| 183 // Using StringImpl to avoid checks and indirection in every call to String:
:operator[]. | |
| 184 StringImpl& text = *gridRowNames.impl(); | |
| 185 | |
| 186 StringBuilder areaName; | |
| 187 for (unsigned i = 0; i < text.length(); ++i) { | |
| 188 if (text[i] == ' ') { | |
| 189 if (!areaName.isEmpty()) { | |
| 190 columnNames.append(areaName.toString()); | |
| 191 areaName.clear(); | |
| 192 } | |
| 193 continue; | |
| 194 } | |
| 195 if (text[i] == '.') { | |
| 196 if (areaName == ".") | |
| 197 continue; | |
| 198 if (!areaName.isEmpty()) { | |
| 199 columnNames.append(areaName.toString()); | |
| 200 areaName.clear(); | |
| 201 } | |
| 202 } else { | |
| 203 if (areaName == ".") { | |
| 204 columnNames.append(areaName.toString()); | |
| 205 areaName.clear(); | |
| 206 } | |
| 207 } | |
| 208 | |
| 209 areaName.append(text[i]); | |
| 210 } | |
| 211 | |
| 212 if (!areaName.isEmpty()) | |
| 213 columnNames.append(areaName.toString()); | |
| 214 | |
| 215 return columnNames; | |
| 216 } | |
| 217 | |
| 218 bool parseGridTemplateAreasRow(const String& gridRowNames, NamedGridAreaMap& gri
dAreaMap, const size_t rowCount, size_t& columnCount) | |
| 219 { | |
| 220 if (gridRowNames.isEmpty() || gridRowNames.containsOnlyWhitespace()) | |
| 221 return false; | |
| 222 | |
| 223 Vector<String> columnNames = parseGridTemplateAreasColumnNames(gridRowNames)
; | |
| 224 if (!columnCount) { | |
| 225 columnCount = columnNames.size(); | |
| 226 ASSERT(columnCount); | |
| 227 } else if (columnCount != columnNames.size()) { | |
| 228 // The declaration is invalid is all the rows don't have the number of c
olumns. | |
| 229 return false; | |
| 230 } | |
| 231 | |
| 232 for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) { | |
| 233 const String& gridAreaName = columnNames[currentCol]; | |
| 234 | |
| 235 // Unamed areas are always valid (we consider them to be 1x1). | |
| 236 if (gridAreaName == ".") | |
| 237 continue; | |
| 238 | |
| 239 // We handle several grid areas with the same name at once to simplify t
he validation code. | |
| 240 size_t lookAheadCol; | |
| 241 for (lookAheadCol = currentCol + 1; lookAheadCol < columnCount; ++lookAh
eadCol) { | |
| 242 if (columnNames[lookAheadCol] != gridAreaName) | |
| 243 break; | |
| 244 } | |
| 245 | |
| 246 NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName); | |
| 247 if (gridAreaIt == gridAreaMap.end()) { | |
| 248 gridAreaMap.add(gridAreaName, GridArea(GridSpan::translatedDefiniteG
ridSpan(rowCount, rowCount + 1), GridSpan::translatedDefiniteGridSpan(currentCol
, lookAheadCol))); | |
| 249 } else { | |
| 250 GridArea& gridArea = gridAreaIt->value; | |
| 251 | |
| 252 // The following checks test that the grid area is a single filled-i
n rectangle. | |
| 253 // 1. The new row is adjacent to the previously parsed row. | |
| 254 if (rowCount != gridArea.rows.endLine()) | |
| 255 return false; | |
| 256 | |
| 257 // 2. The new area starts at the same position as the previously par
sed area. | |
| 258 if (currentCol != gridArea.columns.startLine()) | |
| 259 return false; | |
| 260 | |
| 261 // 3. The new area ends at the same position as the previously parse
d area. | |
| 262 if (lookAheadCol != gridArea.columns.endLine()) | |
| 263 return false; | |
| 264 | |
| 265 gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.s
tartLine(), gridArea.rows.endLine() + 1); | |
| 266 } | |
| 267 currentCol = lookAheadCol - 1; | |
| 268 } | |
| 269 | |
| 270 return true; | |
| 271 } | |
| 272 | |
| 273 } // namespace blink | |
| OLD | NEW |