| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 2003 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) | 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. | 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> | 5 * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com> |
| 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> | 6 * Copyright (C) 2008 Eric Seidel <eric@webkit.org> |
| 7 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmo
bile.com/) | 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. | 8 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved. |
| 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. | 9 * Copyright (C) 2012 Intel Corporation. All rights reserved. |
| 10 * | 10 * |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 199 return CSSPrimitiveValue::create(m_parsedCalculation.release()); | 199 return CSSPrimitiveValue::create(m_parsedCalculation.release()); |
| 200 } | 200 } |
| 201 | 201 |
| 202 ASSERT((value->unit() >= CSSPrimitiveValue::UnitType::Number && value->unit(
) <= CSSPrimitiveValue::UnitType::Kilohertz) | 202 ASSERT((value->unit() >= CSSPrimitiveValue::UnitType::Number && value->unit(
) <= CSSPrimitiveValue::UnitType::Kilohertz) |
| 203 || (value->unit() >= CSSPrimitiveValue::UnitType::Turns && value->unit()
<= CSSPrimitiveValue::UnitType::Chs) | 203 || (value->unit() >= CSSPrimitiveValue::UnitType::Turns && value->unit()
<= CSSPrimitiveValue::UnitType::Chs) |
| 204 || (value->unit() >= CSSPrimitiveValue::UnitType::ViewportWidth && value
->unit() <= CSSPrimitiveValue::UnitType::ViewportMax) | 204 || (value->unit() >= CSSPrimitiveValue::UnitType::ViewportWidth && value
->unit() <= CSSPrimitiveValue::UnitType::ViewportMax) |
| 205 || (value->unit() >= CSSPrimitiveValue::UnitType::DotsPerPixel && value-
>unit() <= CSSPrimitiveValue::UnitType::DotsPerCentimeter)); | 205 || (value->unit() >= CSSPrimitiveValue::UnitType::DotsPerPixel && value-
>unit() <= CSSPrimitiveValue::UnitType::DotsPerCentimeter)); |
| 206 return cssValuePool().createValue(value->fValue, value->unit()); | 206 return cssValuePool().createValue(value->fValue, value->unit()); |
| 207 } | 207 } |
| 208 | 208 |
| 209 inline CSSCustomIdentValue* CSSPropertyParser::createPrimitiveCustomIdentValue(C
SSParserValue* value) | |
| 210 { | |
| 211 ASSERT(value->m_unit == CSSParserValue::String || value->m_unit == CSSParser
Value::Identifier); | |
| 212 return CSSCustomIdentValue::create(value->string); | |
| 213 } | |
| 214 | |
| 215 static inline bool isComma(CSSParserValue* value) | 209 static inline bool isComma(CSSParserValue* value) |
| 216 { | 210 { |
| 217 ASSERT(value); | 211 ASSERT(value); |
| 218 return value->m_unit == CSSParserValue::Operator && value->iValue == ','; | 212 return value->m_unit == CSSParserValue::Operator && value->iValue == ','; |
| 219 } | 213 } |
| 220 | 214 |
| 221 static inline bool isForwardSlashOperator(CSSParserValue* value) | 215 static inline bool isForwardSlashOperator(CSSParserValue* value) |
| 222 { | 216 { |
| 223 ASSERT(value); | 217 ASSERT(value); |
| 224 return value->m_unit == CSSParserValue::Operator && value->iValue == '/'; | 218 return value->m_unit == CSSParserValue::Operator && value->iValue == '/'; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 if (parsedValue) { | 267 if (parsedValue) { |
| 274 if (!m_valueList->current() || inShorthand()) | 268 if (!m_valueList->current() || inShorthand()) |
| 275 return parsedValue; | 269 return parsedValue; |
| 276 } | 270 } |
| 277 return nullptr; | 271 return nullptr; |
| 278 } | 272 } |
| 279 | 273 |
| 280 bool CSSPropertyParser::legacyParseShorthand(CSSPropertyID propertyID, bool impo
rtant) | 274 bool CSSPropertyParser::legacyParseShorthand(CSSPropertyID propertyID, bool impo
rtant) |
| 281 { | 275 { |
| 282 switch (propertyID) { | 276 switch (propertyID) { |
| 283 case CSSPropertyGridTemplate: | |
| 284 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | |
| 285 return parseGridTemplateShorthand(important); | |
| 286 | |
| 287 case CSSPropertyGrid: | 277 case CSSPropertyGrid: |
| 288 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | 278 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); |
| 289 return parseGridShorthand(important); | 279 return parseGridShorthand(important); |
| 290 | 280 |
| 291 // The remaining shorthands are handled in CSSPropertyParser.cpp | 281 // The remaining shorthands are handled in CSSPropertyParser.cpp |
| 292 default: | 282 default: |
| 293 return false; | 283 return false; |
| 294 } | 284 } |
| 295 } | 285 } |
| 296 | 286 |
| 297 static inline bool isCSSWideKeyword(const CSSParserValue& value) | |
| 298 { | |
| 299 return value.id == CSSValueInitial || value.id == CSSValueInherit || value.i
d == CSSValueUnset || value.id == CSSValueDefault; | |
| 300 } | |
| 301 | |
| 302 static inline bool isValidCustomIdentForGridPositions(const CSSParserValue& valu
e) | |
| 303 { | |
| 304 // FIXME: we need a more general solution for <custom-ident> in all properti
es. | |
| 305 return value.m_unit == CSSParserValue::Identifier && value.id != CSSValueSpa
n && value.id != CSSValueAuto && !isCSSWideKeyword(value); | |
| 306 } | |
| 307 | |
| 308 CSSValue* CSSPropertyParser::parseGridTemplateColumns(bool important) | |
| 309 { | |
| 310 if (!(m_valueList->current() && isForwardSlashOperator(m_valueList->current(
)) && m_valueList->next())) | |
| 311 return nullptr; | |
| 312 if (CSSValue* columnsValue = parseGridTrackList()) { | |
| 313 if (m_valueList->current()) | |
| 314 return nullptr; | |
| 315 return columnsValue; | |
| 316 } | |
| 317 | |
| 318 return nullptr; | |
| 319 } | |
| 320 | |
| 321 bool CSSPropertyParser::parseGridTemplateRowsAndAreasAndColumns(bool important) | |
| 322 { | |
| 323 NamedGridAreaMap gridAreaMap; | |
| 324 size_t rowCount = 0; | |
| 325 size_t columnCount = 0; | |
| 326 bool trailingIdentWasAdded = false; | |
| 327 CSSValueList* templateRows = CSSValueList::createSpaceSeparated(); | |
| 328 | |
| 329 // At least template-areas strings must be defined. | |
| 330 if (!m_valueList->current() || isForwardSlashOperator(m_valueList->current()
)) | |
| 331 return false; | |
| 332 | |
| 333 while (m_valueList->current() && !isForwardSlashOperator(m_valueList->curren
t())) { | |
| 334 // Handle leading <custom-ident>*. | |
| 335 if (!parseGridLineNames(*m_valueList, *templateRows, trailingIdentWasAdd
ed ? toCSSGridLineNamesValue(templateRows->item(templateRows->length() - 1)) : n
ullptr)) | |
| 336 return false; | |
| 337 | |
| 338 // Handle a template-area's row. | |
| 339 CSSParserValue* currentValue = m_valueList->current(); | |
| 340 if (!currentValue || currentValue->m_unit != CSSParserValue::String) | |
| 341 return false; | |
| 342 if (!parseGridTemplateAreasRow(currentValue->string, gridAreaMap, rowCou
nt, columnCount)) | |
| 343 return false; | |
| 344 m_valueList->next(); | |
| 345 ++rowCount; | |
| 346 | |
| 347 // Handle template-rows's track-size. | |
| 348 if (m_valueList->current() && m_valueList->current()->m_unit != CSSParse
rValue::Operator && m_valueList->current()->m_unit != CSSParserValue::String) { | |
| 349 CSSValue* value = parseGridTrackSize(*m_valueList); | |
| 350 if (!value) | |
| 351 return false; | |
| 352 templateRows->append(value); | |
| 353 } else { | |
| 354 templateRows->append(cssValuePool().createIdentifierValue(CSSValueAu
to)); | |
| 355 } | |
| 356 | |
| 357 // This will handle the trailing/leading <custom-ident>* in the grammar. | |
| 358 if (!parseGridLineNames(*m_valueList, *templateRows)) | |
| 359 return false; | |
| 360 trailingIdentWasAdded = templateRows->item(templateRows->length() - 1)->
isGridLineNamesValue(); | |
| 361 } | |
| 362 | |
| 363 CSSValue* columnsValue = nullptr; | |
| 364 if (m_valueList->current()) { | |
| 365 ASSERT(isForwardSlashOperator(m_valueList->current())); | |
| 366 columnsValue = parseGridTemplateColumns(important); | |
| 367 if (!columnsValue) | |
| 368 return false; | |
| 369 // The template-columns <track-list> can't be 'none'. | |
| 370 if (columnsValue->isPrimitiveValue() && toCSSPrimitiveValue(*columnsValu
e).getValueID() == CSSValueNone) | |
| 371 return false; | |
| 372 } | |
| 373 | |
| 374 addProperty(CSSPropertyGridTemplateRows, templateRows, important); | |
| 375 addProperty(CSSPropertyGridTemplateColumns, columnsValue ? columnsValue : cs
sValuePool().createIdentifierValue(CSSValueNone), important); | |
| 376 | |
| 377 CSSValue* templateAreas = CSSGridTemplateAreasValue::create(gridAreaMap, row
Count, columnCount); | |
| 378 addProperty(CSSPropertyGridTemplateAreas, templateAreas, important); | |
| 379 | |
| 380 return true; | |
| 381 } | |
| 382 | |
| 383 | |
| 384 bool CSSPropertyParser::parseGridTemplateShorthand(bool important) | |
| 385 { | |
| 386 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | |
| 387 | |
| 388 ShorthandScope scope(this, CSSPropertyGridTemplate); | |
| 389 ASSERT(gridTemplateShorthand().length() == 3); | |
| 390 | |
| 391 // At least "none" must be defined. | |
| 392 if (!m_valueList->current()) | |
| 393 return false; | |
| 394 | |
| 395 bool firstValueIsNone = m_valueList->current()->id == CSSValueNone; | |
| 396 | |
| 397 // 1- 'none' case. | |
| 398 if (firstValueIsNone && !m_valueList->next()) { | |
| 399 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentif
ierValue(CSSValueNone), important); | |
| 400 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createIdentifier
Value(CSSValueNone), important); | |
| 401 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifie
rValue(CSSValueNone), important); | |
| 402 return true; | |
| 403 } | |
| 404 | |
| 405 // 2- <grid-template-rows> / <grid-template-columns> | |
| 406 CSSValue* rowsValue = nullptr; | |
| 407 if (firstValueIsNone) { | |
| 408 rowsValue = cssValuePool().createIdentifierValue(CSSValueNone); | |
| 409 } else { | |
| 410 rowsValue = parseGridTrackList(); | |
| 411 } | |
| 412 | |
| 413 if (rowsValue) { | |
| 414 CSSValue* columnsValue = parseGridTemplateColumns(important); | |
| 415 if (!columnsValue) | |
| 416 return false; | |
| 417 | |
| 418 addProperty(CSSPropertyGridTemplateRows, rowsValue, important); | |
| 419 addProperty(CSSPropertyGridTemplateColumns, columnsValue, important); | |
| 420 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifie
rValue(CSSValueNone), important); | |
| 421 return true; | |
| 422 } | |
| 423 | |
| 424 // 3- [<line-names>? <string> <track-size>? <line-names>? ]+ syntax. | |
| 425 // It requires to rewind parsing due to previous syntax failures. | |
| 426 m_valueList->setCurrentIndex(0); | |
| 427 return parseGridTemplateRowsAndAreasAndColumns(important); | |
| 428 } | |
| 429 | |
| 430 bool CSSPropertyParser::parseGridShorthand(bool important) | 287 bool CSSPropertyParser::parseGridShorthand(bool important) |
| 431 { | 288 { |
| 432 ShorthandScope scope(this, CSSPropertyGrid); | 289 ShorthandScope scope(this, CSSPropertyGrid); |
| 433 ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8); | 290 ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8); |
| 434 | 291 |
| 435 // 1- <grid-template> | 292 // 1- <grid-template> |
| 436 if (parseGridTemplateShorthand(important)) { | 293 if (consumeGridTemplateShorthand(important)) { |
| 437 // It can only be specified the explicit or the implicit grid properties
in a single grid declaration. | 294 // It can only be specified the explicit or the implicit grid properties
in a single grid declaration. |
| 438 // The sub-properties not specified are set to their initial value, as n
ormal for shorthands. | 295 // The sub-properties not specified are set to their initial value, as n
ormal for shorthands. |
| 439 addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitia
lValue(), important); | 296 addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitia
lValue(), important); |
| 440 addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitIni
tialValue(), important); | 297 addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitIni
tialValue(), important); |
| 441 addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitia
lValue(), important); | 298 addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitia
lValue(), important); |
| 442 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitIniti
alValue(), important); | 299 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitIniti
alValue(), important); |
| 443 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialV
alue(), important); | 300 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialV
alue(), important); |
| 444 return true; | 301 return true; |
| 445 } | 302 } |
| 446 | 303 |
| 447 // Need to rewind parsing to explore the alternative syntax of this shorthan
d. | |
| 448 m_valueList->setCurrentIndex(0); | |
| 449 | |
| 450 // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ] | 304 // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ] |
| 451 if (!legacyParseAndApplyValue(CSSPropertyGridAutoFlow, important)) | 305 if (!legacyParseAndApplyValue(CSSPropertyGridAutoFlow, important)) |
| 452 return false; | 306 return false; |
| 453 | 307 |
| 454 CSSValue* autoColumnsValue = nullptr; | 308 CSSValue* autoColumnsValue = nullptr; |
| 455 CSSValue* autoRowsValue = nullptr; | 309 CSSValue* autoRowsValue = nullptr; |
| 456 | 310 |
| 457 if (m_valueList->current()) { | 311 if (m_valueList->current()) { |
| 458 autoRowsValue = parseGridTrackSize(*m_valueList); | 312 autoRowsValue = parseGridTrackSize(*m_valueList); |
| 459 if (!autoRowsValue) | 313 if (!autoRowsValue) |
| (...skipping 24 matching lines...) Expand all Loading... |
| 484 // The sub-properties not specified are set to their initial value, as norma
l for shorthands. | 338 // The sub-properties not specified are set to their initial value, as norma
l for shorthands. |
| 485 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitIni
tialValue(), important); | 339 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitIni
tialValue(), important); |
| 486 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitia
lValue(), important); | 340 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitia
lValue(), important); |
| 487 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitIniti
alValue(), important); | 341 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitIniti
alValue(), important); |
| 488 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialVa
lue(), important); | 342 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialVa
lue(), important); |
| 489 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue
(), important); | 343 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue
(), important); |
| 490 | 344 |
| 491 return true; | 345 return true; |
| 492 } | 346 } |
| 493 | 347 |
| 494 static inline bool isClosingBracket(const CSSParserValue& value) | |
| 495 { | |
| 496 return value.m_unit == CSSParserValue::Operator && value.iValue == ']'; | |
| 497 } | |
| 498 | |
| 499 bool CSSPropertyParser::parseGridLineNames(CSSParserValueList& inputList, CSSVal
ueList& valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames) | |
| 500 { | |
| 501 if (!inputList.current() || inputList.current()->m_unit != CSSParserValue::O
perator || inputList.current()->iValue != '[') | |
| 502 return true; | |
| 503 | |
| 504 // Skip '[' | |
| 505 inputList.next(); | |
| 506 | |
| 507 CSSGridLineNamesValue* lineNames = previousNamedAreaTrailingLineNames; | |
| 508 if (!lineNames) | |
| 509 lineNames = CSSGridLineNamesValue::create(); | |
| 510 | |
| 511 while (CSSParserValue* identValue = inputList.current()) { | |
| 512 if (isClosingBracket(*identValue)) | |
| 513 break; | |
| 514 | |
| 515 if (!isValidCustomIdentForGridPositions(*identValue)) | |
| 516 return false; | |
| 517 | |
| 518 CSSCustomIdentValue* lineName = createPrimitiveCustomIdentValue(identVal
ue); | |
| 519 lineNames->append(lineName); | |
| 520 inputList.next(); | |
| 521 } | |
| 522 | |
| 523 if (!inputList.current() || !isClosingBracket(*inputList.current())) | |
| 524 return false; | |
| 525 | |
| 526 if (!previousNamedAreaTrailingLineNames) | |
| 527 valueList.append(lineNames); | |
| 528 | |
| 529 // Consume ']' | |
| 530 inputList.next(); | |
| 531 return true; | |
| 532 } | |
| 533 | |
| 534 bool allTracksAreFixedSized(CSSValueList& valueList) | 348 bool allTracksAreFixedSized(CSSValueList& valueList) |
| 535 { | 349 { |
| 536 for (auto value : valueList) { | 350 for (auto value : valueList) { |
| 537 if (value->isGridLineNamesValue()) | 351 if (value->isGridLineNamesValue()) |
| 538 continue; | 352 continue; |
| 539 // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax
( <fixed-breadth>, <track-breadth> ) | 353 // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax
( <fixed-breadth>, <track-breadth> ) |
| 540 if (value->isGridAutoRepeatValue()) { | 354 if (value->isGridAutoRepeatValue()) { |
| 541 if (!allTracksAreFixedSized(toCSSValueList(*value))) | 355 if (!allTracksAreFixedSized(toCSSValueList(*value))) |
| 542 return false; | 356 return false; |
| 543 continue; | 357 continue; |
| 544 } | 358 } |
| 545 ASSERT(value->isPrimitiveValue() || (value->isFunctionValue() && toCSSFu
nctionValue(*value).item(0))); | 359 ASSERT(value->isPrimitiveValue() || (value->isFunctionValue() && toCSSFu
nctionValue(*value).item(0))); |
| 546 const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue() | 360 const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue() |
| 547 ? toCSSPrimitiveValue(*value) | 361 ? toCSSPrimitiveValue(*value) |
| 548 : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0)); | 362 : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0)); |
| 549 CSSValueID valueID = primitiveValue.getValueID(); | 363 CSSValueID valueID = primitiveValue.getValueID(); |
| 550 if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || va
lueID == CSSValueAuto || primitiveValue.isFlex()) | 364 if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || va
lueID == CSSValueAuto || primitiveValue.isFlex()) |
| 551 return false; | 365 return false; |
| 552 } | 366 } |
| 553 return true; | 367 return true; |
| 554 } | 368 } |
| 555 | 369 |
| 556 CSSValue* CSSPropertyParser::parseGridTrackList() | |
| 557 { | |
| 558 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | |
| 559 | |
| 560 CSSParserValue* value = m_valueList->current(); | |
| 561 if (value->id == CSSValueNone) { | |
| 562 m_valueList->next(); | |
| 563 return cssValuePool().createIdentifierValue(CSSValueNone); | |
| 564 } | |
| 565 | |
| 566 CSSValueList* values = CSSValueList::createSpaceSeparated(); | |
| 567 // Handle leading <custom-ident>*. | |
| 568 if (!parseGridLineNames(*m_valueList, *values)) | |
| 569 return nullptr; | |
| 570 | |
| 571 bool seenTrackSizeOrRepeatFunction = false; | |
| 572 bool seenAutoRepeat = false; | |
| 573 while (CSSParserValue* currentValue = m_valueList->current()) { | |
| 574 if (isForwardSlashOperator(currentValue)) | |
| 575 break; | |
| 576 if (currentValue->m_unit == CSSParserValue::Function && currentValue->fu
nction->id == CSSValueRepeat) { | |
| 577 bool isAutoRepeat; | |
| 578 if (!parseGridTrackRepeatFunction(*values, isAutoRepeat)) | |
| 579 return nullptr; | |
| 580 if (isAutoRepeat && seenAutoRepeat) | |
| 581 return nullptr; | |
| 582 seenTrackSizeOrRepeatFunction = true; | |
| 583 seenAutoRepeat = seenAutoRepeat || isAutoRepeat; | |
| 584 } else { | |
| 585 CSSValue* value = parseGridTrackSize(*m_valueList, seenAutoRepeat ?
FixedSizeOnly : AllowAll); | |
| 586 if (!value) | |
| 587 return nullptr; | |
| 588 values->append(value); | |
| 589 seenTrackSizeOrRepeatFunction = true; | |
| 590 } | |
| 591 // This will handle the trailing <custom-ident>* in the grammar. | |
| 592 if (!parseGridLineNames(*m_valueList, *values)) | |
| 593 return nullptr; | |
| 594 } | |
| 595 | |
| 596 // We should have found a <track-size> or else it is not a valid <track-list
> | |
| 597 if (!seenTrackSizeOrRepeatFunction) | |
| 598 return nullptr; | |
| 599 | |
| 600 // <auto-repeat> requires definite minimum track sizes in order to compute t
he number of repetitions. | |
| 601 // The above while loop detects those appearances after the <auto-repeat> bu
t not the ones before. | |
| 602 if (seenAutoRepeat && !allTracksAreFixedSized(*values)) | |
| 603 return nullptr; | |
| 604 | |
| 605 return values; | |
| 606 } | |
| 607 | |
| 608 bool CSSPropertyParser::parseGridTrackRepeatFunction(CSSValueList& list, bool& i
sAutoRepeat) | |
| 609 { | |
| 610 CSSParserValueList* arguments = m_valueList->current()->function->args.get()
; | |
| 611 if (!arguments || arguments->size() < 3 || !isComma(arguments->valueAt(1))) | |
| 612 return false; | |
| 613 | |
| 614 CSSParserValue* currentValue = arguments->valueAt(0); | |
| 615 isAutoRepeat = currentValue->id == CSSValueAutoFill || currentValue->id == C
SSValueAutoFit; | |
| 616 if (!isAutoRepeat && !validUnit(currentValue, FPositiveInteger)) | |
| 617 return false; | |
| 618 | |
| 619 // The number of repetitions for <auto-repeat> is not important at parsing l
evel | |
| 620 // because it will be computed later, let's set it to 1. | |
| 621 size_t repetitions = isAutoRepeat ? 1 : clampTo<size_t>(currentValue->fValue
, 0, kGridMaxTracks); | |
| 622 | |
| 623 CSSValueList* repeatedValues = isAutoRepeat ? CSSGridAutoRepeatValue::create
(currentValue->id) : CSSValueList::createSpaceSeparated(); | |
| 624 arguments->next(); // Skip the repetition count. | |
| 625 arguments->next(); // Skip the comma. | |
| 626 | |
| 627 // Handle leading <custom-ident>*. | |
| 628 if (!parseGridLineNames(*arguments, *repeatedValues)) | |
| 629 return false; | |
| 630 | |
| 631 size_t numberOfTracks = 0; | |
| 632 TrackSizeRestriction restriction = isAutoRepeat ? FixedSizeOnly : AllowAll; | |
| 633 while (arguments->current()) { | |
| 634 if (isAutoRepeat && numberOfTracks) | |
| 635 return false; | |
| 636 | |
| 637 CSSValue* trackSize = parseGridTrackSize(*arguments, restriction); | |
| 638 if (!trackSize) | |
| 639 return false; | |
| 640 | |
| 641 repeatedValues->append(trackSize); | |
| 642 ++numberOfTracks; | |
| 643 | |
| 644 // This takes care of any trailing <custom-ident>* in the grammar. | |
| 645 if (!parseGridLineNames(*arguments, *repeatedValues)) | |
| 646 return false; | |
| 647 } | |
| 648 | |
| 649 // We should have found at least one <track-size> or else it is not a valid
<track-list>. | |
| 650 if (!numberOfTracks) | |
| 651 return false; | |
| 652 | |
| 653 if (isAutoRepeat) { | |
| 654 list.append(repeatedValues); | |
| 655 } else { | |
| 656 // We clamp the number of repetitions to a multiple of the repeat() trac
k list's size, while staying below the max | |
| 657 // grid size. | |
| 658 repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks); | |
| 659 | |
| 660 for (size_t i = 0; i < repetitions; ++i) { | |
| 661 for (size_t j = 0; j < repeatedValues->length(); ++j) | |
| 662 list.append(repeatedValues->item(j)); | |
| 663 } | |
| 664 } | |
| 665 | |
| 666 // parseGridTrackSize iterated over the repeat arguments, move to the next v
alue. | |
| 667 m_valueList->next(); | |
| 668 return true; | |
| 669 } | |
| 670 | |
| 671 | 370 |
| 672 CSSValue* CSSPropertyParser::parseGridTrackSize(CSSParserValueList& inputList, T
rackSizeRestriction restriction) | 371 CSSValue* CSSPropertyParser::parseGridTrackSize(CSSParserValueList& inputList, T
rackSizeRestriction restriction) |
| 673 { | 372 { |
| 674 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); | 373 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); |
| 675 | 374 |
| 676 CSSParserValue* currentValue = inputList.current(); | 375 CSSParserValue* currentValue = inputList.current(); |
| 677 inputList.next(); | 376 inputList.next(); |
| 678 | 377 |
| 679 if (currentValue->id == CSSValueAuto) | 378 if (currentValue->id == CSSValueAuto) |
| 680 return restriction == AllowAll ? cssValuePool().createIdentifierValue(CS
SValueAuto) : nullptr; | 379 return restriction == AllowAll ? cssValuePool().createIdentifierValue(CS
SValueAuto) : nullptr; |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 ASSERT(!m_parsedCalculation); | 568 ASSERT(!m_parsedCalculation); |
| 870 m_parsedCalculation = CSSCalcValue::create(args, range); | 569 m_parsedCalculation = CSSCalcValue::create(args, range); |
| 871 | 570 |
| 872 if (!m_parsedCalculation) | 571 if (!m_parsedCalculation) |
| 873 return false; | 572 return false; |
| 874 | 573 |
| 875 return true; | 574 return true; |
| 876 } | 575 } |
| 877 | 576 |
| 878 } // namespace blink | 577 } // namespace blink |
| OLD | NEW |