Title: [208291] trunk/Source/WebCore
Revision
208291
Author
hy...@apple.com
Date
2016-11-02 11:07:32 -0700 (Wed, 02 Nov 2016)

Log Message

[CSS Parser] Support scroll-snap-* properties
https://bugs.webkit.org/show_bug.cgi?id=164321

Reviewed by Simon Fraser.

* css/CSSPrimitiveValue.h:
* css/StyleBuilderConverter.h:
(WebCore::StyleBuilderConverter::convertScrollSnapPoints):
(WebCore::StyleBuilderConverter::convertSnapCoordinatePair):
(WebCore::StyleBuilderConverter::convertScrollSnapCoordinates):
* css/parser/CSSPropertyParser.cpp:
(WebCore::consumePositionLonghand):
(WebCore::consumePositionX):
(WebCore::consumePositionY):
(WebCore::consumePositionList):
(WebCore::consumeScrollSnapDestination):
(WebCore::consumeScrollSnapPoints):
(WebCore::CSSPropertyParser::parseSingleValue):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (208290 => 208291)


--- trunk/Source/WebCore/ChangeLog	2016-11-02 17:48:23 UTC (rev 208290)
+++ trunk/Source/WebCore/ChangeLog	2016-11-02 18:07:32 UTC (rev 208291)
@@ -1,3 +1,24 @@
+2016-11-02  Dave Hyatt  <hy...@apple.com>
+
+        [CSS Parser] Support scroll-snap-* properties
+        https://bugs.webkit.org/show_bug.cgi?id=164321
+
+        Reviewed by Simon Fraser.
+
+        * css/CSSPrimitiveValue.h:
+        * css/StyleBuilderConverter.h:
+        (WebCore::StyleBuilderConverter::convertScrollSnapPoints):
+        (WebCore::StyleBuilderConverter::convertSnapCoordinatePair):
+        (WebCore::StyleBuilderConverter::convertScrollSnapCoordinates):
+        * css/parser/CSSPropertyParser.cpp:
+        (WebCore::consumePositionLonghand):
+        (WebCore::consumePositionX):
+        (WebCore::consumePositionY):
+        (WebCore::consumePositionList):
+        (WebCore::consumeScrollSnapDestination):
+        (WebCore::consumeScrollSnapPoints):
+        (WebCore::CSSPropertyParser::parseSingleValue):
+
 2016-11-02  David Kilzer  <ddkil...@apple.com>
 
         Add logging for "WebKit encountered an internal error" messages

Modified: trunk/Source/WebCore/css/CSSPrimitiveValue.h (208290 => 208291)


--- trunk/Source/WebCore/css/CSSPrimitiveValue.h	2016-11-02 17:48:23 UTC (rev 208290)
+++ trunk/Source/WebCore/css/CSSPrimitiveValue.h	2016-11-02 18:07:32 UTC (rev 208291)
@@ -113,6 +113,7 @@
         CSS_DPCM = 32,
         CSS_FR = 33,
 #if ENABLE(CSS_SCROLL_SNAP)
+        // FIXME-NEWPARSER: Remove once new parser lands.
         CSS_LENGTH_REPEAT = 34,
 #endif
         CSS_PAIR = 100, // We envision this being exposed as a means of getting computed style values for pairs (border-spacing/radius, background-position, etc.)

Modified: trunk/Source/WebCore/css/StyleBuilderConverter.h (208290 => 208291)


--- trunk/Source/WebCore/css/StyleBuilderConverter.h	2016-11-02 17:48:23 UTC (rev 208290)
+++ trunk/Source/WebCore/css/StyleBuilderConverter.h	2016-11-02 18:07:32 UTC (rev 208291)
@@ -807,17 +807,28 @@
 
 inline std::unique_ptr<ScrollSnapPoints> StyleBuilderConverter::convertScrollSnapPoints(StyleResolver& styleResolver, const CSSValue& value)
 {
+    // FIXME-NEWPARSER: Old parser supports an identifier value called "elements" when it seems like
+    // "none" is what others use. For now, support both in the converter.
     auto points = std::make_unique<ScrollSnapPoints>();
-
+    
     if (is<CSSPrimitiveValue>(value)) {
-        ASSERT(downcast<CSSPrimitiveValue>(value).valueID() == CSSValueElements);
+        ASSERT(downcast<CSSPrimitiveValue>(value).valueID() == CSSValueElements || downcast<CSSPrimitiveValue>(value).valueID() == CSSValueNone);
         points->usesElements = true;
         return points;
     }
-
+    
     for (auto& currentValue : downcast<CSSValueList>(value)) {
+        if (is<CSSFunctionValue>(currentValue.get())) {
+            auto& functionValue = downcast<CSSFunctionValue>(currentValue.get());
+            points->repeatOffset = parseSnapCoordinate(styleResolver, *functionValue.arguments()->item(0));
+            points->hasRepeat = true;
+            break;
+        }
+        
         auto& itemValue = downcast<CSSPrimitiveValue>(currentValue.get());
         if (auto* lengthRepeat = itemValue.lengthRepeatValue()) {
+            // FIXME-NEWPARSER: Old parsing code, which uses a special primitive value.
+            // Can remove this once new parser turns on.
             if (auto* interval = lengthRepeat->interval()) {
                 points->repeatOffset = parseSnapCoordinate(styleResolver, *interval);
                 points->hasRepeat = true;
@@ -832,6 +843,16 @@
 
 inline LengthSize StyleBuilderConverter::convertSnapCoordinatePair(StyleResolver& styleResolver, const CSSValue& value, size_t offset)
 {
+    // FIXME-NEWPARSER: Can make this unconditional once old parser is gone. This is just how
+    // we detect that we're dealing with the new parser's pairs.
+    if (value.isPrimitiveValue() && downcast<CSSPrimitiveValue>(value).pairValue()) {
+        Pair* pair = downcast<CSSPrimitiveValue>(value).pairValue();
+        Length lengthX = convertPositionComponent<CSSValueLeft, CSSValueRight>(styleResolver, *pair->first());
+        Length lengthY = convertPositionComponent<CSSValueTop, CSSValueBottom>(styleResolver, *pair->second());
+        return LengthSize(lengthX, lengthY);
+    }
+
+    // FIXME-NEWPARSER: Remove once old parser is gone.
     auto& valueList = downcast<CSSValueList>(value);
     return LengthSize(parseSnapCoordinate(styleResolver, *valueList.item(offset)), parseSnapCoordinate(styleResolver, *valueList.item(offset + 1)));
 }
@@ -838,7 +859,31 @@
 
 inline Vector<LengthSize> StyleBuilderConverter::convertScrollSnapCoordinates(StyleResolver& styleResolver, const CSSValue& value)
 {
+    if (is<CSSPrimitiveValue>(value)) {
+        ASSERT(downcast<CSSPrimitiveValue>(value).valueID() == CSSValueNone);
+        return Vector<LengthSize>();
+    }
+
     auto& valueList = downcast<CSSValueList>(value);
+    if (!valueList.length())
+        return Vector<LengthSize>();
+    
+    // FIXME-NEWPARSER: Can make this unconditional once old parser is gone. This is just how
+    // we detect that we're dealing with the new parser's pairs.
+    if (valueList.item(0)->isPrimitiveValue() && downcast<CSSPrimitiveValue>(*valueList.item(0)).pairValue()) {
+        Vector<LengthSize> coordinates;
+        coordinates.reserveInitialCapacity(valueList.length());
+        for (auto& snapCoordinate : valueList) {
+            Pair* pair = downcast<CSSPrimitiveValue>(*snapCoordinate.ptr()).pairValue();
+            Length lengthX = convertPositionComponent<CSSValueLeft, CSSValueRight>(styleResolver, *pair->first());
+            Length lengthY = convertPositionComponent<CSSValueTop, CSSValueBottom>(styleResolver, *pair->second());
+            coordinates.uncheckedAppend(LengthSize(lengthX, lengthY));
+        }
+        return coordinates;
+    }
+    
+    // FIXME-NEWPARSER: Remove all of this once old parser is gone, including all the functions
+    // it calls.
     ASSERT(!(valueList.length() % 2));
     size_t pointCount = valueList.length() / 2;
     Vector<LengthSize> coordinates;

Modified: trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp (208290 => 208291)


--- trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2016-11-02 17:48:23 UTC (rev 208290)
+++ trunk/Source/WebCore/css/parser/CSSPropertyParser.cpp	2016-11-02 18:07:32 UTC (rev 208291)
@@ -1719,7 +1719,7 @@
 }
 
 template <CSSValueID start, CSSValueID end>
-static RefPtr<CSSValue> consumePositionLonghand(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+static RefPtr<CSSPrimitiveValue> consumePositionLonghand(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
     if (range.peek().type() == IdentToken) {
         CSSValueID id = range.peek().id();
@@ -1738,12 +1738,12 @@
     return consumeLengthOrPercent(range, cssParserMode, ValueRangeAll);
 }
 
-static RefPtr<CSSValue> consumePositionX(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+static RefPtr<CSSPrimitiveValue> consumePositionX(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
     return consumePositionLonghand<CSSValueLeft, CSSValueRight>(range, cssParserMode);
 }
 
-static RefPtr<CSSValue> consumePositionY(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+static RefPtr<CSSPrimitiveValue> consumePositionY(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
     return consumePositionLonghand<CSSValueTop, CSSValueBottom>(range, cssParserMode);
 }
@@ -2006,15 +2006,20 @@
 
 #if ENABLE(CSS_SCROLL_SNAP)
 
-static RefPtr<CSSValueList> consumePositionList(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+static RefPtr<CSSValueList> consumeSnapPointCoordinateList(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
-    RefPtr<CSSValueList> positions = CSSValueList::createCommaSeparated();
+    RefPtr<CSSValueList> positions = CSSValueList::createSpaceSeparated();
     do {
-        RefPtr<CSSValue> position = consumePosition(range, cssParserMode, UnitlessQuirk::Forbid);
-        if (!position)
+        
+        RefPtr<CSSPrimitiveValue> first = consumePositionX(range, cssParserMode);
+        if (!first || range.atEnd())
             return nullptr;
+        RefPtr<CSSPrimitiveValue> second = consumePositionY(range, cssParserMode);
+        if (!second)
+            return nullptr;
+        RefPtr<CSSValue> position = createPrimitiveValuePair(first.releaseNonNull(), second.releaseNonNull(), Pair::IdenticalValueEncoding::DoNotCoalesce);
         positions->append(position.releaseNonNull());
-    } while (consumeCommaIncludingWhitespace(range));
+    } while (!range.atEnd());
     return positions;
 }
 
@@ -2022,23 +2027,45 @@
 {
     if (range.peek().id() == CSSValueNone)
         return consumeIdent(range);
-    return consumePositionList(range, cssParserMode);
+    return consumeSnapPointCoordinateList(range, cssParserMode);
 }
 
+static RefPtr<CSSValue> consumeScrollSnapDestination(CSSParserTokenRange& range, CSSParserMode cssParserMode)
+{
+    RefPtr<CSSPrimitiveValue> first = consumePositionX(range, cssParserMode);
+    if (!first || range.atEnd())
+        return nullptr;
+    RefPtr<CSSPrimitiveValue> second = consumePositionY(range, cssParserMode);
+    if (!second)
+        return nullptr;
+    return createPrimitiveValuePair(first.releaseNonNull(), second.releaseNonNull(), Pair::IdenticalValueEncoding::DoNotCoalesce);
+}
+
 static RefPtr<CSSValue> consumeScrollSnapPoints(CSSParserTokenRange& range, CSSParserMode cssParserMode)
 {
-    if (range.peek().id() == CSSValueNone)
+    if (range.peek().id() == CSSValueNone || range.peek().id() == CSSValueElements)
         return consumeIdent(range);
-    if (range.peek().functionId() == CSSValueRepeat) {
-        CSSParserTokenRange args = consumeFunction(range);
-        RefPtr<CSSPrimitiveValue> parsedValue = consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
-        if (args.atEnd() && parsedValue && (parsedValue->isCalculated() || parsedValue->doubleValue() > 0)) {
-            RefPtr<CSSFunctionValue> result = CSSFunctionValue::create(CSSValueRepeat);
-            result->append(parsedValue.releaseNonNull());
-            return result;
+    
+    RefPtr<CSSValueList> points = CSSValueList::createSpaceSeparated();
+    do {
+        if (range.peek().functionId() == CSSValueRepeat) {
+            CSSParserTokenRange args = consumeFunction(range);
+            RefPtr<CSSPrimitiveValue> parsedValue = consumeLengthOrPercent(args, cssParserMode, ValueRangeNonNegative);
+            if (args.atEnd() && parsedValue && (parsedValue->isCalculated() || parsedValue->doubleValue() > 0)) {
+                Ref<CSSFunctionValue> result = CSSFunctionValue::create(CSSValueRepeat);
+                result->append(parsedValue.releaseNonNull());
+                points->append(WTFMove(result));
+            }
+        } else {
+            RefPtr<CSSValue> length = consumeLengthOrPercent(range, cssParserMode, ValueRangeAll, UnitlessQuirk::Forbid);
+            if (!length)
+                return nullptr;
+            points->append(length.releaseNonNull());
         }
-    }
-    return nullptr;
+    } while (!range.atEnd());
+    
+    
+    return points;
 }
 
 #endif
@@ -3602,6 +3629,8 @@
 #if ENABLE(CSS_SCROLL_SNAP)
     case CSSPropertyWebkitScrollSnapCoordinate:
         return consumeScrollSnapCoordinate(m_range, m_context.mode);
+    case CSSPropertyWebkitScrollSnapDestination:
+        return consumeScrollSnapDestination(m_range, m_context.mode);
     case CSSPropertyWebkitScrollSnapPointsX:
     case CSSPropertyWebkitScrollSnapPointsY:
         return consumeScrollSnapPoints(m_range, m_context.mode);
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to