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

Unified Diff: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp

Issue 1412803007: Parse text-decoration shorthand in CSSPropertyParser with CSSParserTokens (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Alternative fix Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index e5286c36554fdd73b7078ca7bb4ff55115c2e03c..6b1e6437bf8e1d31db47ade3a2562086ef6134e2 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -1415,6 +1415,30 @@ static PassRefPtrWillBeRawPtr<CSSValue> consumeShadow(CSSParserTokenRange& range
return shadowValueList;
}
+static PassRefPtrWillBeRawPtr<CSSValue> consumeTextDecorationLine(CSSParserTokenRange& range)
+{
+ CSSValueID id = range.peek().id();
+ if (id == CSSValueNone)
+ return consumeIdent(range);
+
+ RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+ ListHashSet<int> ids;
+ RefPtrWillBeRawPtr<CSSPrimitiveValue> ident;
+ CSSParserTokenRange textDecorationRange = range;
+ while ((ident = consumeIdent<CSSValueBlink, CSSValueUnderline, CSSValueOverline, CSSValueLineThrough>(textDecorationRange))) {
+ 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
+ if (!result.isNewEntry)
+ return nullptr;
+ list->append(ident.release());
+ }
+
+ // 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.
+ if (!list->length())
+ return nullptr;
+ range = textDecorationRange;
+ return list.release();
+}
+
PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSPropertyID unresolvedProperty)
{
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -1514,6 +1538,8 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
return consumeWidowsOrOrphans(m_range);
case CSSPropertyWebkitTextFillColor:
case CSSPropertyWebkitTapHighlightColor:
+ case CSSPropertyTextDecorationColor:
+ ASSERT(property != CSSPropertyTextDecorationColor || RuntimeEnabledFeatures::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.
return consumeColor(m_range, m_context);
case CSSPropertyColor:
return consumeColor(m_range, m_context, inQuirksMode());
@@ -1522,6 +1548,9 @@ PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSingleValue(CSSProperty
case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
case CSSPropertyBoxShadow:
return consumeShadow(m_range, m_context, property == CSSPropertyBoxShadow);
+ case CSSPropertyWebkitTextDecorationsInEffect:
+ case CSSPropertyTextDecorationLine:
+ return consumeTextDecorationLine(m_range);
default:
return nullptr;
}
@@ -1884,6 +1913,49 @@ bool CSSPropertyParser::consumeColumns(bool important)
return true;
}
+bool CSSPropertyParser::consumeShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important)
+{
+ // We try to greedily match as many properties as possible.
+ RefPtrWillBeRawPtr<CSSValue> propertyFound[6] = { nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }; // 6 is enough size.
+ while (!m_range.atEnd()) {
+ bool found = false;
+ for (unsigned propertyIndex = 0; !found && propertyIndex < shorthand.length(); ++propertyIndex) {
+ if (!propertyFound[propertyIndex]) {
+ if (CSSParserFastPaths::isKeywordPropertyID(shorthand.properties()[propertyIndex])) {
+ if (CSSParserFastPaths::isValidKeywordPropertyAndValue(shorthand.properties()[propertyIndex], m_range.peek().id()))
+ propertyFound[propertyIndex] = consumeIdent(m_range);
+ } else {
+ propertyFound[propertyIndex] = parseSingleValue(shorthand.properties()[propertyIndex]);
+ }
+ if (propertyFound[propertyIndex])
+ found = true;
+ }
+ }
+
+ // If we didn't find at least one match, this is an invalid shorthand and we have to ignore it.
+ if (!found)
+ return false;
+ }
+
+ // Fill in any remaining properties with the initial value.
+ ImplicitScope implicitScope(this);
+ const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization();
+ for (unsigned i = 0; i < shorthand.length(); ++i) {
+ if (propertyFound[i]) {
+ addProperty(shorthand.properties()[i], propertyFound[i].release(), important);
+ } else {
+ if (propertiesForInitialization) {
+ const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]);
+ for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex)
+ addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important);
+ } else {
+ addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important);
+ }
+ }
+ }
+ return true;
+}
+
bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool important)
{
CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
@@ -1948,6 +2020,17 @@ bool CSSPropertyParser::parseShorthand(CSSPropertyID unresolvedProperty, bool im
return consumeAnimationShorthand(animationShorthandForParsing(), unresolvedProperty == CSSPropertyAliasWebkitAnimation, important);
case CSSPropertyTransition:
return consumeAnimationShorthand(transitionShorthandForParsing(), false, important);
+ case CSSPropertyTextDecoration: {
+ // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration
+ // is disabled to match CSS 2.1 rules for parsing 'text-decoration'.
+ if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+ return consumeShorthand(CSSPropertyTextDecoration, textDecorationShorthand(), important);
+ RefPtrWillBeRawPtr<CSSValue> textDecoration = consumeTextDecorationLine(m_range);
+ if (!textDecoration || !m_range.atEnd())
+ return false;
+ addProperty(CSSPropertyTextDecoration, textDecoration.release(), important);
+ return true;
+ }
default:
m_currentShorthand = oldShorthand;
return false;

Powered by Google App Engine
This is Rietveld 408576698