OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "core/css/parser/CSSPropertyParser.h" | 6 #include "core/css/parser/CSSPropertyParser.h" |
7 | 7 |
8 #include "core/StylePropertyShorthand.h" | 8 #include "core/StylePropertyShorthand.h" |
9 #include "core/css/CSSCalculationValue.h" | 9 #include "core/css/CSSCalculationValue.h" |
10 #include "core/css/CSSCustomIdentValue.h" | 10 #include "core/css/CSSCustomIdentValue.h" |
(...skipping 1397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1408 RefPtrWillBeRawPtr<CSSValueList> shadowValueList = CSSValueList::createComma Separated(); | 1408 RefPtrWillBeRawPtr<CSSValueList> shadowValueList = CSSValueList::createComma Separated(); |
1409 do { | 1409 do { |
1410 if (RefPtrWillBeRawPtr<CSSShadowValue> shadowValue = parseSingleShadow(r ange, context, isBoxShadowProperty, isBoxShadowProperty)) | 1410 if (RefPtrWillBeRawPtr<CSSShadowValue> shadowValue = parseSingleShadow(r ange, context, isBoxShadowProperty, isBoxShadowProperty)) |
1411 shadowValueList->append(shadowValue.release()); | 1411 shadowValueList->append(shadowValue.release()); |
1412 else | 1412 else |
1413 return nullptr; | 1413 return nullptr; |
1414 } while (consumeCommaIncludingWhitespace(range)); | 1414 } while (consumeCommaIncludingWhitespace(range)); |
1415 return shadowValueList; | 1415 return shadowValueList; |
1416 } | 1416 } |
1417 | 1417 |
1418 static PassRefPtrWillBeRawPtr<CSSValue> consumeTextDecorationLine(CSSParserToken Range& range) | |
1419 { | |
1420 CSSValueID id = range.peek().id(); | |
1421 if (id == CSSValueNone) | |
1422 return consumeIdent(range); | |
1423 | |
1424 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated() ; | |
1425 ListHashSet<int> ids; | |
1426 RefPtrWillBeRawPtr<CSSPrimitiveValue> ident; | |
1427 CSSParserTokenRange textDecorationRange = range; | |
1428 while ((ident = consumeIdent<CSSValueBlink, CSSValueUnderline, CSSValueOverl ine, CSSValueLineThrough>(textDecorationRange))) { | |
1429 ListHashSet<int>::AddResult result = ids.add(ident->getValueID()); | |
Timothy Loh
2015/11/02 03:36:28
I guess we can just use list->hasValue(ident.get()
rwlbuis
2015/11/03 20:53:15
Good idea, however I think HashSet solution is bet
| |
1430 if (!result.isNewEntry) | |
1431 return nullptr; | |
1432 list->append(ident.release()); | |
1433 } | |
1434 | |
1435 // Values are either valid or in shorthand scope. | |
Timothy Loh
2015/11/02 03:36:28
I don't understand this comment :\
rwlbuis
2015/11/03 20:53:15
Probably outdated, I removed it.
| |
1436 if (!list->length()) | |
1437 return nullptr; | |
1438 range = textDecorationRange; | |
1439 return list.release(); | |
1440 } | |
1441 | |
1418 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID unresolvedProperty) | 1442 PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty ID unresolvedProperty) |
1419 { | 1443 { |
1420 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); | 1444 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
1421 m_range.consumeWhitespace(); | 1445 m_range.consumeWhitespace(); |
1422 switch (property) { | 1446 switch (property) { |
1423 case CSSPropertyWillChange: | 1447 case CSSPropertyWillChange: |
1424 return consumeWillChange(m_range); | 1448 return consumeWillChange(m_range); |
1425 case CSSPropertyPage: | 1449 case CSSPropertyPage: |
1426 return consumePage(m_range); | 1450 return consumePage(m_range); |
1427 case CSSPropertyQuotes: | 1451 case CSSPropertyQuotes: |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1507 case CSSPropertyAnimationPlayState: | 1531 case CSSPropertyAnimationPlayState: |
1508 case CSSPropertyTransitionProperty: | 1532 case CSSPropertyTransitionProperty: |
1509 case CSSPropertyAnimationTimingFunction: | 1533 case CSSPropertyAnimationTimingFunction: |
1510 case CSSPropertyTransitionTimingFunction: | 1534 case CSSPropertyTransitionTimingFunction: |
1511 return consumeAnimationPropertyList(property, m_range, m_context, unreso lvedProperty == CSSPropertyAliasWebkitAnimationName); | 1535 return consumeAnimationPropertyList(property, m_range, m_context, unreso lvedProperty == CSSPropertyAliasWebkitAnimationName); |
1512 case CSSPropertyOrphans: | 1536 case CSSPropertyOrphans: |
1513 case CSSPropertyWidows: | 1537 case CSSPropertyWidows: |
1514 return consumeWidowsOrOrphans(m_range); | 1538 return consumeWidowsOrOrphans(m_range); |
1515 case CSSPropertyWebkitTextFillColor: | 1539 case CSSPropertyWebkitTextFillColor: |
1516 case CSSPropertyWebkitTapHighlightColor: | 1540 case CSSPropertyWebkitTapHighlightColor: |
1541 case CSSPropertyTextDecorationColor: | |
1542 ASSERT(property != CSSPropertyTextDecorationColor || RuntimeEnabledFeatu res::css3TextDecorationsEnabled()); | |
Timothy Loh
2015/11/02 03:36:28
Might as well just put the text-decoration-color c
rwlbuis
2015/11/03 20:53:15
Done.
| |
1517 return consumeColor(m_range, m_context); | 1543 return consumeColor(m_range, m_context); |
1518 case CSSPropertyColor: | 1544 case CSSPropertyColor: |
1519 return consumeColor(m_range, m_context, inQuirksMode()); | 1545 return consumeColor(m_range, m_context, inQuirksMode()); |
1520 case CSSPropertyZIndex: | 1546 case CSSPropertyZIndex: |
1521 return consumeZIndex(m_range); | 1547 return consumeZIndex(m_range); |
1522 case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS 3, so treat as CSS3 | 1548 case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS 3, so treat as CSS3 |
1523 case CSSPropertyBoxShadow: | 1549 case CSSPropertyBoxShadow: |
1524 return consumeShadow(m_range, m_context, property == CSSPropertyBoxShado w); | 1550 return consumeShadow(m_range, m_context, property == CSSPropertyBoxShado w); |
1551 case CSSPropertyWebkitTextDecorationsInEffect: | |
1552 case CSSPropertyTextDecorationLine: | |
1553 return consumeTextDecorationLine(m_range); | |
1525 default: | 1554 default: |
1526 return nullptr; | 1555 return nullptr; |
1527 } | 1556 } |
1528 } | 1557 } |
1529 | 1558 |
1530 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) | 1559 static PassRefPtrWillBeRawPtr<CSSValueList> consumeFontFaceUnicodeRange(CSSParse rTokenRange& range) |
1531 { | 1560 { |
1532 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); | 1561 RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated (); |
1533 | 1562 |
1534 do { | 1563 do { |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1877 return false; | 1906 return false; |
1878 if (!columnWidth) | 1907 if (!columnWidth) |
1879 columnWidth = cssValuePool().createIdentifierValue(CSSValueAuto); | 1908 columnWidth = cssValuePool().createIdentifierValue(CSSValueAuto); |
1880 if (!columnCount) | 1909 if (!columnCount) |
1881 columnCount = cssValuePool().createIdentifierValue(CSSValueAuto); | 1910 columnCount = cssValuePool().createIdentifierValue(CSSValueAuto); |
1882 addProperty(CSSPropertyWebkitColumnWidth, columnWidth.release(), important); | 1911 addProperty(CSSPropertyWebkitColumnWidth, columnWidth.release(), important); |
1883 addProperty(CSSPropertyWebkitColumnCount, columnCount.release(), important); | 1912 addProperty(CSSPropertyWebkitColumnCount, columnCount.release(), important); |
1884 return true; | 1913 return true; |
1885 } | 1914 } |
1886 | 1915 |
1916 bool CSSPropertyParser::consumeShorthand(CSSPropertyID propId, const StyleProper tyShorthand& shorthand, bool important) | |
1917 { | |
1918 // We try to greedily match as many properties as possible. | |
1919 RefPtrWillBeRawPtr<CSSValue> propertyFound[6] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; // 6 is enough size. | |
1920 while (!m_range.atEnd()) { | |
1921 bool found = false; | |
1922 for (unsigned propertyIndex = 0; !found && propertyIndex < shorthand.len gth(); ++propertyIndex) { | |
1923 if (!propertyFound[propertyIndex]) { | |
1924 if (CSSParserFastPaths::isKeywordPropertyID(shorthand.properties ()[propertyIndex])) { | |
1925 if (CSSParserFastPaths::isValidKeywordPropertyAndValue(short hand.properties()[propertyIndex], m_range.peek().id())) | |
1926 propertyFound[propertyIndex] = consumeIdent(m_range); | |
1927 } else { | |
1928 propertyFound[propertyIndex] = parseSingleValue(shorthand.pr operties()[propertyIndex]); | |
1929 } | |
1930 if (propertyFound[propertyIndex]) | |
1931 found = true; | |
1932 } | |
1933 } | |
1934 | |
1935 // If we didn't find at least one match, this is an invalid shorthand an d we have to ignore it. | |
1936 if (!found) | |
1937 return false; | |
1938 } | |
1939 | |
1940 // Fill in any remaining properties with the initial value. | |
1941 ImplicitScope implicitScope(this); | |
1942 const StylePropertyShorthand* const* const propertiesForInitialization = sho rthand.propertiesForInitialization(); | |
1943 for (unsigned i = 0; i < shorthand.length(); ++i) { | |
1944 if (propertyFound[i]) { | |
1945 addProperty(shorthand.properties()[i], propertyFound[i].release(), i mportant); | |
1946 } else { | |
1947 if (propertiesForInitialization) { | |
1948 const StylePropertyShorthand& initProperties = *(propertiesForIn itialization[i]); | |
1949 for (unsigned propIndex = 0; propIndex < initProperties.length() ; ++propIndex) | |
1950 addProperty(initProperties.properties()[propIndex], cssValue Pool().createImplicitInitialValue(), important); | |
1951 } else { | |
1952 addProperty(shorthand.properties()[i], cssValuePool().createImpl icitInitialValue(), important); | |
1953 } | |
1954 } | |
1955 } | |
1956 return true; | |
1957 } | |
1958 | |
1887 bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im portant) | 1959 bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im portant) |
1888 { | 1960 { |
1889 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); | 1961 CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty); |
1890 | 1962 |
1891 m_range.consumeWhitespace(); | 1963 m_range.consumeWhitespace(); |
1892 CSSPropertyID oldShorthand = m_currentShorthand; | 1964 CSSPropertyID oldShorthand = m_currentShorthand; |
1893 // TODO(rob.buis): Remove this when the legacy property parser is gone | 1965 // TODO(rob.buis): Remove this when the legacy property parser is gone |
1894 m_currentShorthand = property; | 1966 m_currentShorthand = property; |
1895 switch (property) { | 1967 switch (property) { |
1896 case CSSPropertyWebkitMarginCollapse: { | 1968 case CSSPropertyWebkitMarginCollapse: { |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1941 return consumeBorderSpacing(important); | 2013 return consumeBorderSpacing(important); |
1942 case CSSPropertyWebkitColumns: { | 2014 case CSSPropertyWebkitColumns: { |
1943 // TODO(rwlbuis): investigate if this shorthand hack can be removed. | 2015 // TODO(rwlbuis): investigate if this shorthand hack can be removed. |
1944 m_currentShorthand = oldShorthand; | 2016 m_currentShorthand = oldShorthand; |
1945 return consumeColumns(important); | 2017 return consumeColumns(important); |
1946 } | 2018 } |
1947 case CSSPropertyAnimation: | 2019 case CSSPropertyAnimation: |
1948 return consumeAnimationShorthand(animationShorthandForParsing(), unresol vedProperty == CSSPropertyAliasWebkitAnimation, important); | 2020 return consumeAnimationShorthand(animationShorthandForParsing(), unresol vedProperty == CSSPropertyAliasWebkitAnimation, important); |
1949 case CSSPropertyTransition: | 2021 case CSSPropertyTransition: |
1950 return consumeAnimationShorthand(transitionShorthandForParsing(), false, important); | 2022 return consumeAnimationShorthand(transitionShorthandForParsing(), false, important); |
2023 case CSSPropertyTextDecoration: { | |
2024 // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration | |
2025 // is disabled to match CSS 2.1 rules for parsing 'text-decoration'. | |
2026 if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) | |
2027 return consumeShorthand(CSSPropertyTextDecoration, textDecorationSho rthand(), important); | |
2028 RefPtrWillBeRawPtr<CSSValue> textDecoration = consumeTextDecorationLine( m_range); | |
2029 if (!textDecoration || !m_range.atEnd()) | |
2030 return false; | |
2031 addProperty(CSSPropertyTextDecoration, textDecoration.release(), importa nt); | |
2032 return true; | |
2033 } | |
1951 default: | 2034 default: |
1952 m_currentShorthand = oldShorthand; | 2035 m_currentShorthand = oldShorthand; |
1953 return false; | 2036 return false; |
1954 } | 2037 } |
1955 } | 2038 } |
1956 | 2039 |
1957 } // namespace blink | 2040 } // namespace blink |
OLD | NEW |