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

Side by Side Diff: Source/core/css/parser/BisonCSSParser-in.cpp

Issue 149373004: [CSS Grid Layout] Implementation of the grid-template shorthand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@grid-template-working
Patch Set: New approach: simpler code, reusing track-list parsing and allow rewinding. Created 6 years, 10 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 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 case CSSPropertyGridAutoRows: 2377 case CSSPropertyGridAutoRows:
2378 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled()) 2378 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2379 return false; 2379 return false;
2380 parsedValue = parseGridTrackSize(*m_valueList); 2380 parsedValue = parseGridTrackSize(*m_valueList);
2381 break; 2381 break;
2382 2382
2383 case CSSPropertyGridTemplateColumns: 2383 case CSSPropertyGridTemplateColumns:
2384 case CSSPropertyGridTemplateRows: 2384 case CSSPropertyGridTemplateRows:
2385 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled()) 2385 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2386 return false; 2386 return false;
2387 return parseGridTrackList(propId, important); 2387 parsedValue = parseGridTrackList(important);
2388 break;
2388 2389
2389 case CSSPropertyGridColumnEnd: 2390 case CSSPropertyGridColumnEnd:
2390 case CSSPropertyGridColumnStart: 2391 case CSSPropertyGridColumnStart:
2391 case CSSPropertyGridRowEnd: 2392 case CSSPropertyGridRowEnd:
2392 case CSSPropertyGridRowStart: 2393 case CSSPropertyGridRowStart:
2393 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled()) 2394 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2394 return false; 2395 return false;
2395 parsedValue = parseGridPosition(); 2396 parsedValue = parseGridPosition();
2396 break; 2397 break;
2397 2398
2398 case CSSPropertyGridColumn: 2399 case CSSPropertyGridColumn:
2399 case CSSPropertyGridRow: 2400 case CSSPropertyGridRow:
2400 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled()) 2401 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2401 return false; 2402 return false;
2402 return parseGridItemPositionShorthand(propId, important); 2403 return parseGridItemPositionShorthand(propId, important);
2403 2404
2404 case CSSPropertyGridArea: 2405 case CSSPropertyGridArea:
2405 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled()) 2406 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2406 return false; 2407 return false;
2407 return parseGridAreaShorthand(important); 2408 return parseGridAreaShorthand(important);
2408 2409
2409 case CSSPropertyGridTemplateAreas: 2410 case CSSPropertyGridTemplateAreas:
2410 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled()) 2411 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2411 return false; 2412 return false;
2412 parsedValue = parseGridTemplateAreas(); 2413 parsedValue = parseGridTemplateAreas();
2413 break; 2414 break;
2414 2415
2416 case CSSPropertyGridTemplate:
2417 if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
2418 return false;
2419 return parseGridTemplateShorthand(important);
2420
2415 case CSSPropertyWebkitMarginCollapse: { 2421 case CSSPropertyWebkitMarginCollapse: {
2416 if (num == 1) { 2422 if (num == 1) {
2417 ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse); 2423 ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
2418 if (!parseValue(webkitMarginCollapseShorthand().properties()[0], imp ortant)) 2424 if (!parseValue(webkitMarginCollapseShorthand().properties()[0], imp ortant))
2419 return false; 2425 return false;
2420 CSSValue* value = m_parsedProperties.last().value(); 2426 CSSValue* value = m_parsedProperties.last().value();
2421 addProperty(webkitMarginCollapseShorthand().properties()[1], value, important); 2427 addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
2422 return true; 2428 return true;
2423 } 2429 }
2424 else if (num == 2) { 2430 else if (num == 2) {
(...skipping 2168 matching lines...) Expand 10 before | Expand all | Expand 10 after
4593 return false; 4599 return false;
4594 } else { 4600 } else {
4595 endValue = gridMissingGridPositionValue(startValue.get()); 4601 endValue = gridMissingGridPositionValue(startValue.get());
4596 } 4602 }
4597 4603
4598 addProperty(shorthand.properties()[0], startValue, important); 4604 addProperty(shorthand.properties()[0], startValue, important);
4599 addProperty(shorthand.properties()[1], endValue, important); 4605 addProperty(shorthand.properties()[1], endValue, important);
4600 return true; 4606 return true;
4601 } 4607 }
4602 4608
4609
4610 bool BisonCSSParser::parseGridTemplateRowsAndAreas(bool important)
4611 {
4612 NamedGridAreaMap gridAreaMap;
4613 size_t rowCount = 0;
4614 size_t columnCount = 0;
4615 bool traillingIdentAdded = false;
4616 RefPtr<CSSValueList> templateRows = CSSValueList::createSpaceSeparated();
4617
4618 // At least template-areas strings must be defined.
4619 if (!m_valueList->current())
4620 return false;
4621
4622 while (m_valueList->current()) {
4623 // Handle leading <custom-ident>*.
4624 if (m_valueList->current()->unit == CSSParserValue::ValueList) {
4625 if (traillingIdentAdded)
4626 parseGridLineNames(m_valueList.get(), *templateRows, static_cast <CSSGridLineNamesValue*>(templateRows->item(templateRows->length() - 1)));
4627 else
4628 parseGridLineNames(m_valueList.get(), *templateRows);
4629 }
4630
4631 // Handle a template-area's row.
4632 if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
4633 return false;
4634 ++rowCount;
4635
4636 // Handle template-rows's track-size.
4637 if (m_valueList->current() && m_valueList->current()->unit != CSSParserV alue::ValueList && m_valueList->current()->unit != CSSPrimitiveValue::CSS_STRING ) {
4638 RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
4639 if (!value)
4640 return false;
4641 templateRows->append(value);
4642 } else {
4643 templateRows->append(cssValuePool().createIdentifierValue(CSSValueAu to));
4644 }
4645
4646 // This will handle the trailing/leading <custom-ident>* in the grammar.
4647 traillingIdentAdded = false;
4648 if (m_valueList->current() && m_valueList->current()->unit == CSSParserV alue::ValueList) {
4649 parseGridLineNames(m_valueList.get(), *templateRows);
4650 traillingIdentAdded = true;
4651 }
4652 }
4653
4654 RefPtr<CSSValue> templateAreas = CSSGridTemplateAreasValue::create(gridAreaM ap, rowCount, columnCount);
4655 addProperty(CSSPropertyGridTemplateAreas, templateAreas.release(), important );
4656 addProperty(CSSPropertyGridTemplateRows, templateRows.release(), important);
Julien - ping for review 2014/02/26 21:53:38 This is confusing as we set CSSPropertyGridTemplat
jfernandez 2014/02/27 11:18:15 Done.
4657
4658 return true;
4659 }
4660
4661
4662 bool BisonCSSParser::parseGridTemplateShorthand(bool important)
4663 {
4664 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
4665
4666 ShorthandScope scope(this, CSSPropertyGridTemplate);
4667 ASSERT(gridTemplateShorthand().length() == 3);
4668 unsigned index = 0;
4669
4670 if (!m_valueList->current())
4671 return false;
4672
4673 // none or <grid-template-columns> or [<track-list> / ] ?
4674 if (parseValue(CSSPropertyGridTemplateColumns, important)) {
Julien - ping for review 2014/02/26 21:53:38 Based on the comment below about not handling the
jfernandez 2014/02/27 11:18:15 Done.
4675 if (!m_valueList->current()) {
4676 if (m_valueList->previous()->id != CSSValueNone)
Julien - ping for review 2014/02/26 21:53:38 This check seems unneeded as the grid-template-col
jfernandez 2014/02/27 11:18:15 After the change related to the parserValue recurs
4677 return false;
4678 addProperty(CSSPropertyGridTemplateRows, cssValuePool().createIdenti fierValue(CSSValueNone), important);
4679 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdent ifierValue(CSSValueNone), important);
4680 return true;
4681 }
4682 if (!isForwardSlashOperator(m_valueList->current()))
4683 return false;
4684 if (!m_valueList->next())
4685 return false;
4686 // <grid-template-rows>
4687 index = m_valueList->currentIndex();
4688 if (parseValue(CSSPropertyGridTemplateRows, important)) {
4689 addProperty(CSSPropertyGridTemplateAreas, cssValuePool().createIdent ifierValue(CSSValueNone), important);
4690 if (m_valueList->next())
4691 return false;
4692 return true;
4693 }
4694 } else {
4695 index = 0;
4696 addProperty(CSSPropertyGridTemplateColumns, cssValuePool().createIdentif ierValue(CSSValueNone), important);
4697 }
4698
4699 // Need to rewind parsing to explore the complex syntax of this shorthand.
4700 while (m_valueList->currentIndex() > index)
4701 m_valueList->previous();
Julien - ping for review 2014/02/26 21:53:38 This is fairly inefficient, I would rather add the
4702
4703 // [ <line-names>? <string> [ <track-size> <line-names> ]? ]+
4704 if (!parseGridTemplateRowsAndAreas(important))
Julien - ping for review 2014/02/26 21:53:38 return parseGridTemplateRowsAndAreas(important);
jfernandez 2014/02/27 11:18:15 Done.
4705 return false;
4706
4707
4708 return true;
4709 }
4710
4711
4603 bool BisonCSSParser::parseGridAreaShorthand(bool important) 4712 bool BisonCSSParser::parseGridAreaShorthand(bool important)
4604 { 4713 {
4605 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); 4714 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
4606 4715
4607 ShorthandScope scope(this, CSSPropertyGridArea); 4716 ShorthandScope scope(this, CSSPropertyGridArea);
4608 const StylePropertyShorthand& shorthand = gridAreaShorthand(); 4717 const StylePropertyShorthand& shorthand = gridAreaShorthand();
4609 ASSERT_UNUSED(shorthand, shorthand.length() == 4); 4718 ASSERT_UNUSED(shorthand, shorthand.length() == 4);
4610 4719
4611 RefPtr<CSSValue> rowStartValue = parseGridPosition(); 4720 RefPtr<CSSValue> rowStartValue = parseGridPosition();
4612 if (!rowStartValue) 4721 if (!rowStartValue)
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
4648 if (!isForwardSlashOperator(m_valueList->current())) 4757 if (!isForwardSlashOperator(m_valueList->current()))
4649 return false; 4758 return false;
4650 4759
4651 if (!m_valueList->next()) 4760 if (!m_valueList->next())
4652 return false; 4761 return false;
4653 4762
4654 property = parseGridPosition(); 4763 property = parseGridPosition();
4655 return true; 4764 return true;
4656 } 4765 }
4657 4766
4658 void BisonCSSParser::parseGridLineNames(CSSParserValueList* parserValueList, CSS ValueList& valueList) 4767 void BisonCSSParser::parseGridLineNames(CSSParserValueList* parserValueList, CSS ValueList& valueList, CSSGridLineNamesValue* lineNamesToConcat)
4659 { 4768 {
4660 ASSERT(parserValueList->current() && parserValueList->current()->unit == CSS ParserValue::ValueList); 4769 ASSERT(parserValueList->current() && parserValueList->current()->unit == CSS ParserValue::ValueList);
4661 4770
4662 CSSParserValueList* identList = parserValueList->current()->valueList; 4771 CSSParserValueList* identList = parserValueList->current()->valueList;
4663 if (!identList->size()) { 4772 if (!identList->size()) {
4664 parserValueList->next(); 4773 parserValueList->next();
4665 return; 4774 return;
4666 } 4775 }
4667 4776
4668 RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue: :create(); 4777 // Need to ensure the identList is at the heading index, since the parserLis t might have been rewound.
4778 while (identList->currentIndex() > 0)
4779 identList->previous();
4780
4781 RefPtr<CSSGridLineNamesValue> lineNames = lineNamesToConcat ? lineNamesToCon cat : CSSGridLineNamesValue::create();
4669 while (CSSParserValue* identValue = identList->current()) { 4782 while (CSSParserValue* identValue = identList->current()) {
4670 ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT); 4783 ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
4671 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineName = createPrimitiveStringVa lue(identValue); 4784 RefPtrWillBeRawPtr<CSSPrimitiveValue> lineName = createPrimitiveStringVa lue(identValue);
4672 lineNames->append(lineName.release()); 4785 lineNames->append(lineName.release());
4673 identList->next(); 4786 identList->next();
4674 } 4787 }
4675 valueList.append(lineNames.release()); 4788 if (!lineNamesToConcat)
4789 valueList.append(lineNames.release());
4676 4790
4677 parserValueList->next(); 4791 parserValueList->next();
4678 } 4792 }
4679 4793
4680 bool BisonCSSParser::parseGridTrackList(CSSPropertyID propId, bool important) 4794 PassRefPtr<CSSValue> BisonCSSParser::parseGridTrackList(bool important)
4681 { 4795 {
4682 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled()); 4796 ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
4683 4797
4684 CSSParserValue* value = m_valueList->current(); 4798 CSSParserValue* value = m_valueList->current();
4685 if (value->id == CSSValueNone) { 4799 if (value->id == CSSValueNone) {
4686 if (m_valueList->next()) 4800 if (m_valueList->next() && (!isForwardSlashOperator(m_valueList->current ())))
Julien - ping for review 2014/02/26 21:53:38 I would remove this check and push it to the calle
jfernandez 2014/02/27 11:18:15 Done.
4687 return false; 4801 return 0;
4688 4802
4689 addProperty(propId, cssValuePool().createIdentifierValue(value->id), imp ortant); 4803 return cssValuePool().createIdentifierValue(value->id);
4690 return true;
4691 } 4804 }
4692 4805
4693 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated (); 4806 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated ();
4694 // Handle leading <ident>*. 4807 // Handle leading <ident>*.
4695 value = m_valueList->current(); 4808 value = m_valueList->current();
4696 if (value && value->unit == CSSParserValue::ValueList) 4809 if (value && value->unit == CSSParserValue::ValueList)
4697 parseGridLineNames(m_valueList.get(), *values); 4810 parseGridLineNames(m_valueList.get(), *values);
4698 4811
4699 bool seenTrackSizeOrRepeatFunction = false; 4812 bool seenTrackSizeOrRepeatFunction = false;
4700 while (CSSParserValue* currentValue = m_valueList->current()) { 4813 while (CSSParserValue* currentValue = m_valueList->current()) {
4814 if (isForwardSlashOperator(currentValue))
4815 break;
4701 if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase( currentValue->function->name, "repeat(")) { 4816 if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase( currentValue->function->name, "repeat(")) {
4702 if (!parseGridTrackRepeatFunction(*values)) 4817 if (!parseGridTrackRepeatFunction(*values))
4703 return false; 4818 return 0;
4704 seenTrackSizeOrRepeatFunction = true; 4819 seenTrackSizeOrRepeatFunction = true;
4705 } else { 4820 } else {
4706 RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList); 4821 RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
4707 if (!value) 4822 if (!value)
4708 return false; 4823 return 0;
4709 values->append(value); 4824 values->append(value);
4710 seenTrackSizeOrRepeatFunction = true; 4825 seenTrackSizeOrRepeatFunction = true;
4711 } 4826 }
4712 // This will handle the trailing <ident>* in the grammar. 4827 // This will handle the trailing <ident>* in the grammar.
4713 value = m_valueList->current(); 4828 value = m_valueList->current();
4714 if (value && value->unit == CSSParserValue::ValueList) 4829 if (value && value->unit == CSSParserValue::ValueList)
4715 parseGridLineNames(m_valueList.get(), *values); 4830 parseGridLineNames(m_valueList.get(), *values);
4716 } 4831 }
4717 4832
4718 // We should have found a <track-size> or else it is not a valid <track-list > 4833 // We should have found a <track-size> or else it is not a valid <track-list >
4719 if (!seenTrackSizeOrRepeatFunction) 4834 if (!seenTrackSizeOrRepeatFunction)
4720 return false; 4835 return 0;
4721 4836
4722 addProperty(propId, values.release(), important); 4837 return values;
4723 return true;
4724 } 4838 }
4725 4839
4726 bool BisonCSSParser::parseGridTrackRepeatFunction(CSSValueList& list) 4840 bool BisonCSSParser::parseGridTrackRepeatFunction(CSSValueList& list)
4727 { 4841 {
4728 CSSParserValueList* arguments = m_valueList->current()->function->args.get() ; 4842 CSSParserValueList* arguments = m_valueList->current()->function->args.get() ;
4729 if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1))) 4843 if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
4730 return false; 4844 return false;
4731 4845
4732 ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0); 4846 ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
4733 size_t repetitions = arguments->valueAt(0)->fValue; 4847 size_t repetitions = arguments->valueAt(0)->fValue;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
4810 4924
4811 return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR); 4925 return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
4812 } 4926 }
4813 4927
4814 if (!validUnit(currentValue, FNonNeg | FLength | FPercent)) 4928 if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
4815 return 0; 4929 return 0;
4816 4930
4817 return createPrimitiveNumericValue(currentValue); 4931 return createPrimitiveNumericValue(currentValue);
4818 } 4932 }
4819 4933
4934 bool BisonCSSParser::parseGridTemplateAreasRow(NamedGridAreaMap& gridAreaMap, co nst size_t rowCount, size_t& columnCount)
4935 {
4936 CSSParserValue* currentValue = m_valueList->current();
4937 if (!currentValue || currentValue->unit != CSSPrimitiveValue::CSS_STRING)
4938 return false;
4939
4940 String gridRowNames = currentValue->string;
4941 if (!gridRowNames.length())
4942 return false;
4943
4944 Vector<String> columnNames;
4945 gridRowNames.split(' ', columnNames);
4946
4947 if (!columnCount) {
4948 columnCount = columnNames.size();
4949 ASSERT(columnCount);
4950 } else if (columnCount != columnNames.size()) {
4951 // The declaration is invalid is all the rows don't have the number of c olumns.
4952 return false;
4953 }
4954
4955 for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
4956 const String& gridAreaName = columnNames[currentCol];
4957
4958 // Unamed areas are always valid (we consider them to be 1x1).
4959 if (gridAreaName == ".")
4960 continue;
4961
4962 // We handle several grid areas with the same name at once to simplify t he validation code.
4963 size_t lookAheadCol;
4964 for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++look AheadCol) {
4965 if (columnNames[lookAheadCol + 1] != gridAreaName)
4966 break;
4967 }
4968
4969 NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
4970 if (gridAreaIt == gridAreaMap.end()) {
4971 gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowC ount), GridSpan(currentCol, lookAheadCol)));
4972 } else {
4973 GridCoordinate& gridCoordinate = gridAreaIt->value;
4974
4975 // The following checks test that the grid area is a single filled-i n rectangle.
4976 // 1. The new row is adjacent to the previously parsed row.
4977 if (rowCount != gridCoordinate.rows.initialPositionIndex + 1)
4978 return false;
4979
4980 // 2. The new area starts at the same position as the previously par sed area.
4981 if (currentCol != gridCoordinate.columns.initialPositionIndex)
4982 return false;
4983
4984 // 3. The new area ends at the same position as the previously parse d area.
4985 if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
4986 return false;
4987
4988 ++gridCoordinate.rows.finalPositionIndex;
4989 }
4990 currentCol = lookAheadCol;
4991 }
4992
4993 m_valueList->next();
4994 return true;
4995 }
4996
4820 PassRefPtr<CSSValue> BisonCSSParser::parseGridTemplateAreas() 4997 PassRefPtr<CSSValue> BisonCSSParser::parseGridTemplateAreas()
4821 { 4998 {
4822 NamedGridAreaMap gridAreaMap; 4999 NamedGridAreaMap gridAreaMap;
4823 size_t rowCount = 0; 5000 size_t rowCount = 0;
4824 size_t columnCount = 0; 5001 size_t columnCount = 0;
4825 5002
4826 while (CSSParserValue* currentValue = m_valueList->current()) { 5003 while (m_valueList->current()) {
4827 if (currentValue->unit != CSSPrimitiveValue::CSS_STRING) 5004 if (!parseGridTemplateAreasRow(gridAreaMap, rowCount, columnCount))
4828 return 0; 5005 return 0;
4829
4830 String gridRowNames = currentValue->string;
4831 if (!gridRowNames.length())
4832 return 0;
4833
4834 Vector<String> columnNames;
4835 gridRowNames.split(' ', columnNames);
4836
4837 if (!columnCount) {
4838 columnCount = columnNames.size();
4839 ASSERT(columnCount);
4840 } else if (columnCount != columnNames.size()) {
4841 // The declaration is invalid is all the rows don't have the number of columns.
4842 return 0;
4843 }
4844
4845 for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
4846 const String& gridAreaName = columnNames[currentCol];
4847
4848 // Unamed areas are always valid (we consider them to be 1x1).
4849 if (gridAreaName == ".")
4850 continue;
4851
4852 // We handle several grid areas with the same name at once to simpli fy the validation code.
4853 size_t lookAheadCol;
4854 for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++ lookAheadCol) {
4855 if (columnNames[lookAheadCol + 1] != gridAreaName)
4856 break;
4857 }
4858
4859 NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaNam e);
4860 if (gridAreaIt == gridAreaMap.end()) {
4861 gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
4862 } else {
4863 GridCoordinate& gridCoordinate = gridAreaIt->value;
4864
4865 // The following checks test that the grid area is a single fill ed-in rectangle.
4866 // 1. The new row is adjacent to the previously parsed row.
4867 if (rowCount != gridCoordinate.rows.initialPositionIndex + 1)
4868 return 0;
4869
4870 // 2. The new area starts at the same position as the previously parsed area.
4871 if (currentCol != gridCoordinate.columns.initialPositionIndex)
4872 return 0;
4873
4874 // 3. The new area ends at the same position as the previously p arsed area.
4875 if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
4876 return 0;
4877
4878 ++gridCoordinate.rows.finalPositionIndex;
4879 }
4880 currentCol = lookAheadCol;
4881 }
4882
4883 ++rowCount; 5006 ++rowCount;
4884 m_valueList->next();
4885 } 5007 }
4886 5008
4887 if (!rowCount || !columnCount) 5009 if (!rowCount || !columnCount)
4888 return 0; 5010 return 0;
4889 5011
4890 return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount) ; 5012 return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount) ;
4891 } 5013 }
4892 5014
4893 PassRefPtr<CSSValue> BisonCSSParser::parseCounterContent(CSSParserValueList* arg s, bool counters) 5015 PassRefPtr<CSSValue> BisonCSSParser::parseCounterContent(CSSParserValueList* arg s, bool counters)
4894 { 5016 {
(...skipping 5201 matching lines...) Expand 10 before | Expand all | Expand 10 after
10096 { 10218 {
10097 // The tokenizer checks for the construct of an+b. 10219 // The tokenizer checks for the construct of an+b.
10098 // However, since the {ident} rule precedes the {nth} rule, some of those 10220 // However, since the {ident} rule precedes the {nth} rule, some of those
10099 // tokens are identified as string literal. Furthermore we need to accept 10221 // tokens are identified as string literal. Furthermore we need to accept
10100 // "odd" and "even" which does not match to an+b. 10222 // "odd" and "even" which does not match to an+b.
10101 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even") 10223 return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
10102 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n"); 10224 || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
10103 } 10225 }
10104 10226
10105 } 10227 }
OLDNEW
« no previous file with comments | « Source/core/css/parser/BisonCSSParser.h ('k') | Source/core/css/resolver/StyleBuilderCustom.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698