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 |