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

Side by Side Diff: third_party/WebKit/Source/core/css/parser/LegacyCSSPropertyParser.cpp

Issue 1843773003: Move the grid-template shorthand into CSSPropertyParser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address another issue 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 unified diff | Download patch
OLDNEW
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
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 RawPtr<CSSCustomIdentValue> CSSPropertyParser::createPrimitiveCustomIdent Value(CSSParserValue* 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 if (parsedValue) { 268 if (parsedValue) {
275 if (!m_valueList->current() || inShorthand()) 269 if (!m_valueList->current() || inShorthand())
276 return parsedValue.release(); 270 return parsedValue.release();
277 } 271 }
278 return nullptr; 272 return nullptr;
279 } 273 }
280 274
281 bool CSSPropertyParser::legacyParseShorthand(CSSPropertyID propertyID, bool impo rtant) 275 bool CSSPropertyParser::legacyParseShorthand(CSSPropertyID propertyID, bool impo rtant)
282 { 276 {
283 switch (propertyID) { 277 switch (propertyID) {
284 case CSSPropertyGridTemplate:
285 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
286 return parseGridTemplateShorthand(important);
287
288 case CSSPropertyGrid: 278 case CSSPropertyGrid:
289 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); 279 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
290 return parseGridShorthand(important); 280 return parseGridShorthand(important);
291 281
292 // The remaining shorthands are handled in CSSPropertyParser.cpp 282 // The remaining shorthands are handled in CSSPropertyParser.cpp
293 default: 283 default:
294 return false; 284 return false;
295 } 285 }
296 } 286 }
297 287
298 static inline bool isCSSWideKeyword(const CSSParserValue& value)
299 {
300 return value.id == CSSValueInitial || value.id == CSSValueInherit || value.i d == CSSValueUnset || value.id == CSSValueDefault;
301 }
302
303 static inline bool isValidCustomIdentForGridPositions(const CSSParserValue& valu e)
304 {
305 // FIXME: we need a more general solution for <custom-ident> in all properti es.
306 return value.m_unit == CSSParserValue::Identifier && value.id != CSSValueSpa n && value.id != CSSValueAuto && !isCSSWideKeyword(value);
307 }
308
309 RawPtr<CSSValue> CSSPropertyParser::parseGridTemplateColumns(bool important)
310 {
311 if (!(m_valueList->current() && isForwardSlashOperator(m_valueList->current( )) && m_valueList->next()))
312 return nullptr;
313 if (RawPtr<CSSValue> columnsValue = parseGridTrackList()) {
314 if (m_valueList->current())
315 return nullptr;
316 return columnsValue;
317 }
318
319 return nullptr;
320 }
321
322 bool CSSPropertyParser::parseGridTemplateRowsAndAreasAndColumns(bool important)
323 {
324 NamedGridAreaMap gridAreaMap;
325 size_t rowCount = 0;
326 size_t columnCount = 0;
327 bool trailingIdentWasAdded = false;
328 RawPtr<CSSValueList> templateRows = CSSValueList::createSpaceSeparated();
329
330 // At least template-areas strings must be defined.
331 if (!m_valueList->current() || isForwardSlashOperator(m_valueList->current() ))
332 return false;
333
334 while (m_valueList->current() && !isForwardSlashOperator(m_valueList->curren t())) {
335 // Handle leading <custom-ident>*.
336 if (!parseGridLineNames(*m_valueList, *templateRows, trailingIdentWasAdd ed ? toCSSGridLineNamesValue(templateRows->item(templateRows->length() - 1)) : n ullptr))
337 return false;
338
339 // Handle a template-area's row.
340 CSSParserValue* currentValue = m_valueList->current();
341 if (!currentValue || currentValue->m_unit != CSSParserValue::String)
342 return false;
343 if (!parseGridTemplateAreasRow(currentValue->string, gridAreaMap, rowCou nt, columnCount))
344 return false;
345 m_valueList->next();
346 ++rowCount;
347
348 // Handle template-rows's track-size.
349 if (m_valueList->current() && m_valueList->current()->m_unit != CSSParse rValue::Operator && m_valueList->current()->m_unit != CSSParserValue::String) {
350 RawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
351 if (!value)
352 return false;
353 templateRows->append(value);
354 } else {
355 templateRows->append(cssValuePool().createIdentifierValue(CSSValueAu to));
356 }
357
358 // This will handle the trailing/leading <custom-ident>* in the grammar.
359 if (!parseGridLineNames(*m_valueList, *templateRows))
360 return false;
361 trailingIdentWasAdded = templateRows->item(templateRows->length() - 1)-> isGridLineNamesValue();
362 }
363
364 RawPtr<CSSValue> columnsValue = nullptr;
365 if (m_valueList->current()) {
366 ASSERT(isForwardSlashOperator(m_valueList->current()));
367 columnsValue = parseGridTemplateColumns(important);
368 if (!columnsValue)
369 return false;
370 // The template-columns <track-list> can't be 'none'.
371 if (columnsValue->isPrimitiveValue() && toCSSPrimitiveValue(*columnsValu e).getValueID() == CSSValueNone)
372 return false;
373 }
374
375 addProperty(CSSPropertyGridTemplateRows, templateRows.release(), important);
376 addProperty(CSSPropertyGridTemplateColumns, columnsValue ? columnsValue.rele ase() : cssValuePool().createIdentifierValue(CSSValueNone), important);
377
378 RawPtr<CSSValue> templateAreas = CSSGridTemplateAreasValue::create(gridAreaM ap, rowCount, columnCount);
379 addProperty(CSSPropertyGridTemplateAreas, templateAreas.release(), important );
380
381 return true;
382 }
383
384
385 bool CSSPropertyParser::parseGridTemplateShorthand(bool important)
386 {
387 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
388
389 ShorthandScope scope(this, CSSPropertyGridTemplate);
390 ASSERT(gridTemplateShorthand().length() == 3);
391
392 // At least "none" must be defined.
393 if (!m_valueList->current())
394 return false;
395
396 bool firstValueIsNone = m_valueList->current()->id == CSSValueNone;
397
398 // 1- 'none' case.
399 if (firstValueIsNone && !m_valueList->next()) {
400 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentif ierValue(CSSValueNone), important);
401 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createIdentifier Value(CSSValueNone), important);
402 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifie rValue(CSSValueNone), important);
403 return true;
404 }
405
406 // 2- <grid-template-rows> / <grid-template-columns>
407 RawPtr<CSSValue> rowsValue = nullptr;
408 if (firstValueIsNone) {
409 rowsValue = cssValuePool().createIdentifierValue(CSSValueNone);
410 } else {
411 rowsValue = parseGridTrackList();
412 }
413
414 if (rowsValue) {
415 RawPtr<CSSValue> columnsValue = parseGridTemplateColumns(important);
416 if (!columnsValue)
417 return false;
418
419 addProperty(CSSPropertyGridTemplateRows, rowsValue.release(), important) ;
420 addProperty(CSSPropertyGridTemplateColumns, columnsValue.release(), impo rtant);
421 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdentifie rValue(CSSValueNone), important);
422 return true;
423 }
424
425 // 3- [<line-names>? <string> <track-size>? <line-names>? ]+ syntax.
426 // It requires to rewind parsing due to previous syntax failures.
427 m_valueList->setCurrentIndex(0);
428 return parseGridTemplateRowsAndAreasAndColumns(important);
429 }
430
431 bool CSSPropertyParser::parseGridShorthand(bool important) 288 bool CSSPropertyParser::parseGridShorthand(bool important)
432 { 289 {
433 ShorthandScope scope(this, CSSPropertyGrid); 290 ShorthandScope scope(this, CSSPropertyGrid);
434 ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8); 291 ASSERT(shorthandForProperty(CSSPropertyGrid).length() == 8);
435 292
436 // 1- <grid-template> 293 // 1- <grid-template>
437 if (parseGridTemplateShorthand(important)) { 294 if (consumeGridTemplateShorthand(important)) {
438 // It can only be specified the explicit or the implicit grid properties in a single grid declaration. 295 // It can only be specified the explicit or the implicit grid properties in a single grid declaration.
439 // The sub-properties not specified are set to their initial value, as n ormal for shorthands. 296 // The sub-properties not specified are set to their initial value, as n ormal for shorthands.
440 addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitia lValue(), important); 297 addProperty(CSSPropertyGridAutoFlow, cssValuePool().createImplicitInitia lValue(), important);
441 addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitIni tialValue(), important); 298 addProperty(CSSPropertyGridAutoColumns, cssValuePool().createImplicitIni tialValue(), important);
442 addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitia lValue(), important); 299 addProperty(CSSPropertyGridAutoRows, cssValuePool().createImplicitInitia lValue(), important);
443 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitIniti alValue(), important); 300 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitIniti alValue(), important);
444 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialV alue(), important); 301 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialV alue(), important);
445 return true; 302 return true;
446 } 303 }
447 304
448 // Need to rewind parsing to explore the alternative syntax of this shorthan d.
449 m_valueList->setCurrentIndex(0);
450
451 // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ] 305 // 2- <grid-auto-flow> [ <grid-auto-rows> [ / <grid-auto-columns> ]? ]
452 if (!legacyParseAndApplyValue(CSSPropertyGridAutoFlow, important)) 306 if (!legacyParseAndApplyValue(CSSPropertyGridAutoFlow, important))
453 return false; 307 return false;
454 308
455 RawPtr<CSSValue> autoColumnsValue = nullptr; 309 RawPtr<CSSValue> autoColumnsValue = nullptr;
456 RawPtr<CSSValue> autoRowsValue = nullptr; 310 RawPtr<CSSValue> autoRowsValue = nullptr;
457 311
458 if (m_valueList->current()) { 312 if (m_valueList->current()) {
459 autoRowsValue = parseGridTrackSize(*m_valueList); 313 autoRowsValue = parseGridTrackSize(*m_valueList);
460 if (!autoRowsValue) 314 if (!autoRowsValue)
(...skipping 24 matching lines...) Expand all
485 // The sub-properties not specified are set to their initial value, as norma l for shorthands. 339 // The sub-properties not specified are set to their initial value, as norma l for shorthands.
486 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitIni tialValue(), important); 340 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createImplicitIni tialValue(), important);
487 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitia lValue(), important); 341 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createImplicitInitia lValue(), important);
488 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitIniti alValue(), important); 342 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createImplicitIniti alValue(), important);
489 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialVa lue(), important); 343 addProperty(CSSPropertyGridColumnGap, cssValuePool().createImplicitInitialVa lue(), important);
490 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue (), important); 344 addProperty(CSSPropertyGridRowGap, cssValuePool().createImplicitInitialValue (), important);
491 345
492 return true; 346 return true;
493 } 347 }
494 348
495 static inline bool isClosingBracket(const CSSParserValue& value)
496 {
497 return value.m_unit == CSSParserValue::Operator && value.iValue == ']';
498 }
499
500 bool CSSPropertyParser::parseGridLineNames(CSSParserValueList& inputList, CSSVal ueList& valueList, CSSGridLineNamesValue* previousNamedAreaTrailingLineNames)
501 {
502 if (!inputList.current() || inputList.current()->m_unit != CSSParserValue::O perator || inputList.current()->iValue != '[')
503 return true;
504
505 // Skip '['
506 inputList.next();
507
508 RawPtr<CSSGridLineNamesValue> lineNames = previousNamedAreaTrailingLineNames ;
509 if (!lineNames)
510 lineNames = CSSGridLineNamesValue::create();
511
512 while (CSSParserValue* identValue = inputList.current()) {
513 if (isClosingBracket(*identValue))
514 break;
515
516 if (!isValidCustomIdentForGridPositions(*identValue))
517 return false;
518
519 RawPtr<CSSCustomIdentValue> lineName = createPrimitiveCustomIdentValue(i dentValue);
520 lineNames->append(lineName.release());
521 inputList.next();
522 }
523
524 if (!inputList.current() || !isClosingBracket(*inputList.current()))
525 return false;
526
527 if (!previousNamedAreaTrailingLineNames)
528 valueList.append(lineNames.release());
529
530 // Consume ']'
531 inputList.next();
532 return true;
533 }
534
535 bool allTracksAreFixedSized(CSSValueList& valueList)
536 {
537 for (auto value : valueList) {
538 if (value->isGridLineNamesValue())
539 continue;
540 // The auto-repeat value holds a <fixed-size> = <fixed-breadth> | minmax ( <fixed-breadth>, <track-breadth> )
541 if (value->isGridAutoRepeatValue()) {
542 if (!allTracksAreFixedSized(toCSSValueList(*value)))
543 return false;
544 continue;
545 }
546 ASSERT(value->isPrimitiveValue() || (value->isFunctionValue() && toCSSFu nctionValue(*value).item(0)));
547 const CSSPrimitiveValue& primitiveValue = value->isPrimitiveValue()
548 ? toCSSPrimitiveValue(*value)
549 : toCSSPrimitiveValue(*toCSSFunctionValue(*value).item(0));
550 CSSValueID valueID = primitiveValue.getValueID();
551 if (valueID == CSSValueMinContent || valueID == CSSValueMaxContent || va lueID == CSSValueAuto || primitiveValue.isFlex())
552 return false;
553 }
554 return true;
555 }
556
557 RawPtr<CSSValue> CSSPropertyParser::parseGridTrackList()
558 {
559 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
560
561 CSSParserValue* value = m_valueList->current();
562 if (value->id == CSSValueNone) {
563 m_valueList->next();
564 return cssValuePool().createIdentifierValue(CSSValueNone);
565 }
566
567 RawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
568 // Handle leading <custom-ident>*.
569 if (!parseGridLineNames(*m_valueList, *values))
570 return nullptr;
571
572 bool seenTrackSizeOrRepeatFunction = false;
573 bool seenAutoRepeat = false;
574 while (CSSParserValue* currentValue = m_valueList->current()) {
575 if (isForwardSlashOperator(currentValue))
576 break;
577 if (currentValue->m_unit == CSSParserValue::Function && currentValue->fu nction->id == CSSValueRepeat) {
578 bool isAutoRepeat;
579 if (!parseGridTrackRepeatFunction(*values, isAutoRepeat))
580 return nullptr;
581 if (isAutoRepeat && seenAutoRepeat)
582 return nullptr;
583 seenTrackSizeOrRepeatFunction = true;
584 seenAutoRepeat = seenAutoRepeat || isAutoRepeat;
585 } else {
586 RawPtr<CSSValue> value = parseGridTrackSize(*m_valueList, seenAutoRe peat ? FixedSizeOnly : AllowAll);
587 if (!value)
588 return nullptr;
589 values->append(value);
590 seenTrackSizeOrRepeatFunction = true;
591 }
592 // This will handle the trailing <custom-ident>* in the grammar.
593 if (!parseGridLineNames(*m_valueList, *values))
594 return nullptr;
595 }
596
597 // We should have found a <track-size> or else it is not a valid <track-list >
598 if (!seenTrackSizeOrRepeatFunction)
599 return nullptr;
600
601 // <auto-repeat> requires definite minimum track sizes in order to compute t he number of repetitions.
602 // The above while loop detects those appearances after the <auto-repeat> bu t not the ones before.
603 if (seenAutoRepeat && !allTracksAreFixedSized(*values))
604 return nullptr;
605
606 return values;
607 }
608
609 bool CSSPropertyParser::parseGridTrackRepeatFunction(CSSValueList& list, bool& i sAutoRepeat)
610 {
611 CSSParserValueList* arguments = m_valueList->current()->function->args.get() ;
612 if (!arguments || arguments->size() < 3 || !isComma(arguments->valueAt(1)))
613 return false;
614
615 CSSParserValue* currentValue = arguments->valueAt(0);
616 isAutoRepeat = currentValue->id == CSSValueAutoFill || currentValue->id == C SSValueAutoFit;
617 if (!isAutoRepeat && !validUnit(currentValue, FPositiveInteger))
618 return false;
619
620 // The number of repetitions for <auto-repeat> is not important at parsing l evel
621 // because it will be computed later, let's set it to 1.
622 size_t repetitions = isAutoRepeat ? 1 : clampTo<size_t>(currentValue->fValue , 0, kGridMaxTracks);
623
624 RawPtr<CSSValueList> repeatedValues = isAutoRepeat ? CSSGridAutoRepeatValue: :create(currentValue->id) : CSSValueList::createSpaceSeparated();
625 arguments->next(); // Skip the repetition count.
626 arguments->next(); // Skip the comma.
627
628 // Handle leading <custom-ident>*.
629 if (!parseGridLineNames(*arguments, *repeatedValues))
630 return false;
631
632 size_t numberOfTracks = 0;
633 TrackSizeRestriction restriction = isAutoRepeat ? FixedSizeOnly : AllowAll;
634 while (arguments->current()) {
635 if (isAutoRepeat && numberOfTracks)
636 return false;
637
638 RawPtr<CSSValue> trackSize = parseGridTrackSize(*arguments, restriction) ;
639 if (!trackSize)
640 return false;
641
642 repeatedValues->append(trackSize);
643 ++numberOfTracks;
644
645 // This takes care of any trailing <custom-ident>* in the grammar.
646 if (!parseGridLineNames(*arguments, *repeatedValues))
647 return false;
648 }
649
650 // We should have found at least one <track-size> or else it is not a valid <track-list>.
651 if (!numberOfTracks)
652 return false;
653
654 if (isAutoRepeat) {
655 list.append(repeatedValues.release());
656 } else {
657 // We clamp the number of repetitions to a multiple of the repeat() trac k list's size, while staying below the max
658 // grid size.
659 repetitions = std::min(repetitions, kGridMaxTracks / numberOfTracks);
660
661 for (size_t i = 0; i < repetitions; ++i) {
662 for (size_t j = 0; j < repeatedValues->length(); ++j)
663 list.append(repeatedValues->item(j));
664 }
665 }
666
667 // parseGridTrackSize iterated over the repeat arguments, move to the next v alue.
668 m_valueList->next();
669 return true;
670 }
671
672
673 RawPtr<CSSValue> CSSPropertyParser::parseGridTrackSize(CSSParserValueList& input List, TrackSizeRestriction restriction) 349 RawPtr<CSSValue> CSSPropertyParser::parseGridTrackSize(CSSParserValueList& input List, TrackSizeRestriction restriction)
674 { 350 {
675 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); 351 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
676 352
677 CSSParserValue* currentValue = inputList.current(); 353 CSSParserValue* currentValue = inputList.current();
678 inputList.next(); 354 inputList.next();
679 355
680 if (currentValue->id == CSSValueAuto) 356 if (currentValue->id == CSSValueAuto)
681 return restriction == AllowAll ? cssValuePool().createIdentifierValue(CS SValueAuto) : nullptr; 357 return restriction == AllowAll ? cssValuePool().createIdentifierValue(CS SValueAuto) : nullptr;
682 358
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
720 396
721 return cssValuePool().createValue(flexValue, CSSPrimitiveValue::UnitType ::Fraction); 397 return cssValuePool().createValue(flexValue, CSSPrimitiveValue::UnitType ::Fraction);
722 } 398 }
723 399
724 if (!validUnit(currentValue, FNonNeg | FLength | FPercent)) 400 if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
725 return nullptr; 401 return nullptr;
726 402
727 return createPrimitiveNumericValue(currentValue); 403 return createPrimitiveNumericValue(currentValue);
728 } 404 }
729 405
730 static Vector<String> parseGridTemplateAreasColumnNames(const String& gridRowNam es)
731 {
732 ASSERT(!gridRowNames.isEmpty());
733 Vector<String> columnNames;
734 // Using StringImpl to avoid checks and indirection in every call to String: :operator[].
735 StringImpl& text = *gridRowNames.impl();
736
737 StringBuilder areaName;
738 for (unsigned i = 0; i < text.length(); ++i) {
739 if (text[i] == ' ') {
740 if (!areaName.isEmpty()) {
741 columnNames.append(areaName.toString());
742 areaName.clear();
743 }
744 continue;
745 }
746 if (text[i] == '.') {
747 if (areaName == ".")
748 continue;
749 if (!areaName.isEmpty()) {
750 columnNames.append(areaName.toString());
751 areaName.clear();
752 }
753 } else {
754 if (areaName == ".") {
755 columnNames.append(areaName.toString());
756 areaName.clear();
757 }
758 }
759
760 areaName.append(text[i]);
761 }
762
763 if (!areaName.isEmpty())
764 columnNames.append(areaName.toString());
765
766 return columnNames;
767 }
768
769 bool parseGridTemplateAreasRow(const String& gridRowNames, NamedGridAreaMap& gri dAreaMap, const size_t rowCount, size_t& columnCount)
770 {
771 if (gridRowNames.isEmpty() || gridRowNames.containsOnlyWhitespace())
772 return false;
773
774 Vector<String> columnNames = parseGridTemplateAreasColumnNames(gridRowNames) ;
775 if (!columnCount) {
776 columnCount = columnNames.size();
777 ASSERT(columnCount);
778 } else if (columnCount != columnNames.size()) {
779 // The declaration is invalid is all the rows don't have the number of c olumns.
780 return false;
781 }
782
783 for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
784 const String& gridAreaName = columnNames[currentCol];
785
786 // Unamed areas are always valid (we consider them to be 1x1).
787 if (gridAreaName == ".")
788 continue;
789
790 // We handle several grid areas with the same name at once to simplify t he validation code.
791 size_t lookAheadCol;
792 for (lookAheadCol = currentCol + 1; lookAheadCol < columnCount; ++lookAh eadCol) {
793 if (columnNames[lookAheadCol] != gridAreaName)
794 break;
795 }
796
797 NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
798 if (gridAreaIt == gridAreaMap.end()) {
799 gridAreaMap.add(gridAreaName, GridArea(GridSpan::translatedDefiniteG ridSpan(rowCount, rowCount + 1), GridSpan::translatedDefiniteGridSpan(currentCol , lookAheadCol)));
800 } else {
801 GridArea& gridArea = gridAreaIt->value;
802
803 // The following checks test that the grid area is a single filled-i n rectangle.
804 // 1. The new row is adjacent to the previously parsed row.
805 if (rowCount != gridArea.rows.endLine())
806 return false;
807
808 // 2. The new area starts at the same position as the previously par sed area.
809 if (currentCol != gridArea.columns.startLine())
810 return false;
811
812 // 3. The new area ends at the same position as the previously parse d area.
813 if (lookAheadCol != gridArea.columns.endLine())
814 return false;
815
816 gridArea.rows = GridSpan::translatedDefiniteGridSpan(gridArea.rows.s tartLine(), gridArea.rows.endLine() + 1);
817 }
818 currentCol = lookAheadCol - 1;
819 }
820
821 return true;
822 }
823
824 RawPtr<CSSValue> CSSPropertyParser::parseGridAutoFlow(CSSParserValueList& list) 406 RawPtr<CSSValue> CSSPropertyParser::parseGridAutoFlow(CSSParserValueList& list)
825 { 407 {
826 // [ row | column ] || dense 408 // [ row | column ] || dense
827 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); 409 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
828 410
829 CSSParserValue* value = list.current(); 411 CSSParserValue* value = list.current();
830 if (!value) 412 if (!value)
831 return nullptr; 413 return nullptr;
832 414
833 RawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated(); 415 RawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 ASSERT(!m_parsedCalculation); 452 ASSERT(!m_parsedCalculation);
871 m_parsedCalculation = CSSCalcValue::create(args, range); 453 m_parsedCalculation = CSSCalcValue::create(args, range);
872 454
873 if (!m_parsedCalculation) 455 if (!m_parsedCalculation)
874 return false; 456 return false;
875 457
876 return true; 458 return true;
877 } 459 }
878 460
879 } // namespace blink 461 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698