[CSS Shapes] Preserve box-shape order when serializing shape values
authorbetravis@adobe.com <betravis@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Jan 2014 22:23:53 +0000 (22:23 +0000)
committerbetravis@adobe.com <betravis@adobe.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Jan 2014 22:23:53 +0000 (22:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=127200

Reviewed by Dirk Schulze.

Source/WebCore:

Convert the parsed shape-box pair to a CSSValueList rather than directly
adding the box value to BasicShape. The CSSValueList preserves the
shape-box ordering, and cleans up a little bit of the code shared between
clip and shape values.

Modifying existing parsing tests.

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::shapePropertyValue): Factor out code common to generating shape
values.
(WebCore::ComputedStyleExtractor::propertyValue): Generate a CSSValueList when
you have both a shape and a box.
* css/CSSParser.cpp:
(WebCore::CSSParser::parseBasicShapeAndOrBox): Factor out code common to clip
paths and shape properties that parses the [basic-shape || box] syntax from
the CSS Shapes spec.
(WebCore::CSSParser::parseShapeProperty): Parse shape-box pairs as a CSSValueList.
* css/DeprecatedStyleBuilder.cpp:
(WebCore::ApplyPropertyShape::applyValue): Use the CSSValueList for shape-box pairs.
* css/CSSValueList.h:
(WebCore::CSSValueList::itemWithoutBoundsCheck): Add a const version.
* page/animation/CSSPropertyAnimation.cpp:
(WebCore::blendFunc): Specify a box when blending.
* rendering/style/ShapeValue.h:
(WebCore::ShapeValue::createShapeValue): Add a box parameter.
(WebCore::ShapeValue::ShapeValue): Ditto.

LayoutTests:

Modify the expectations for box shape pairs, preserving the order of
the arguments in non-computed values. Computed values are still a
shape followed by a box.

* fast/shapes/parsing/parsing-shape-inside-expected.txt:
* fast/shapes/parsing/parsing-shape-outside-expected.txt:
* fast/shapes/parsing/parsing-test-utils.js:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@162475 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/shapes/parsing/parsing-shape-inside-expected.txt
LayoutTests/fast/shapes/parsing/parsing-shape-outside-expected.txt
LayoutTests/fast/shapes/parsing/parsing-test-utils.js
Source/WebCore/ChangeLog
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/css/CSSValueList.h
Source/WebCore/css/DeprecatedStyleBuilder.cpp
Source/WebCore/page/animation/CSSPropertyAnimation.cpp
Source/WebCore/rendering/style/ShapeValue.h

index 10b1425..ebe4fd6 100644 (file)
@@ -1,3 +1,18 @@
+2014-01-21  Bear Travis  <betravis@adobe.com>
+
+        [CSS Shapes] Preserve box-shape order when serializing shape values
+        https://bugs.webkit.org/show_bug.cgi?id=127200
+
+        Reviewed by Dirk Schulze.
+
+        Modify the expectations for box shape pairs, preserving the order of
+        the arguments in non-computed values. Computed values are still a
+        shape followed by a box.
+
+        * fast/shapes/parsing/parsing-shape-inside-expected.txt:
+        * fast/shapes/parsing/parsing-shape-outside-expected.txt:
+        * fast/shapes/parsing/parsing-test-utils.js:
+
 2014-01-21  Alexey Proskuryakov  <ap@apple.com>
 
         platform/mac/accessibility/iframe-aria-hidden.html is flaky
index ecbeb4b..38a6be8 100644 (file)
@@ -107,13 +107,13 @@ PASS getCSSText("-webkit-shape-inside", "polygon(nonzero, 0px 0px, 10px 10px, 10
 PASS getComputedStyleValue("-webkit-shape-inside", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"
 PASS getCSSText("-webkit-shape-inside", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
 PASS getComputedStyleValue("-webkit-shape-inside", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
-PASS getCSSText("-webkit-shape-inside", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) content-box"
+PASS getCSSText("-webkit-shape-inside", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-inside", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) content-box"
-PASS getCSSText("-webkit-shape-inside", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) padding-box"
+PASS getCSSText("-webkit-shape-inside", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-inside", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) padding-box"
-PASS getCSSText("-webkit-shape-inside", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"
+PASS getCSSText("-webkit-shape-inside", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-inside", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"
-PASS getCSSText("-webkit-shape-inside", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
+PASS getCSSText("-webkit-shape-inside", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-inside", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
 PASS getCSSText("-webkit-shape-inside", "outside-shape") is "outside-shape"
 PASS getComputedStyleValue("-webkit-shape-inside", "outside-shape") is "outside-shape"
index 64fef1b..c89560d 100644 (file)
@@ -107,13 +107,13 @@ PASS getCSSText("-webkit-shape-outside", "polygon(nonzero, 0px 0px, 10px 10px, 1
 PASS getComputedStyleValue("-webkit-shape-outside", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"
 PASS getCSSText("-webkit-shape-outside", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
 PASS getComputedStyleValue("-webkit-shape-outside", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
-PASS getCSSText("-webkit-shape-outside", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) content-box"
+PASS getCSSText("-webkit-shape-outside", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-outside", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) content-box"
-PASS getCSSText("-webkit-shape-outside", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) padding-box"
+PASS getCSSText("-webkit-shape-outside", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-outside", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) padding-box"
-PASS getCSSText("-webkit-shape-outside", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"
+PASS getCSSText("-webkit-shape-outside", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-outside", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"
-PASS getCSSText("-webkit-shape-outside", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
+PASS getCSSText("-webkit-shape-outside", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)"
 PASS getComputedStyleValue("-webkit-shape-outside", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)") is "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"
 PASS removeBaseURL(getCSSText("-webkit-shape-outside", "url('image')")) is "url(image)"
 PASS removeBaseURL(getComputedStyleValue("-webkit-shape-outside", "url('image')")) is "url(image)"
index d94535d..d23fad2 100644 (file)
@@ -67,10 +67,10 @@ var validShapeValues = [
     "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box",
     "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box",
 
-    ["content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) content-box"],
-    ["padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) padding-box"],
-    ["border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"],
-    ["margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"]
+    ["content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "content-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) content-box"],
+    ["padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "padding-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) padding-box"],
+    ["border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "border-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) border-box"],
+    ["margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "margin-box polygon(nonzero, 0px 0px, 10px 10px, 10px 0px)", "polygon(nonzero, 0px 0px, 10px 10px, 10px 0px) margin-box"]
 ];
 
 // Invalid values for both shape-inside and shape-outside. When an invalid shape value is specified, the 
index 0bfc956..e9fad05 100644 (file)
@@ -1,3 +1,37 @@
+2014-01-21  Bear Travis  <betravis@adobe.com>
+
+        [CSS Shapes] Preserve box-shape order when serializing shape values
+        https://bugs.webkit.org/show_bug.cgi?id=127200
+
+        Reviewed by Dirk Schulze.
+
+        Convert the parsed shape-box pair to a CSSValueList rather than directly
+        adding the box value to BasicShape. The CSSValueList preserves the
+        shape-box ordering, and cleans up a little bit of the code shared between
+        clip and shape values.
+
+        Modifying existing parsing tests.
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::shapePropertyValue): Factor out code common to generating shape
+        values.
+        (WebCore::ComputedStyleExtractor::propertyValue): Generate a CSSValueList when
+        you have both a shape and a box.
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseBasicShapeAndOrBox): Factor out code common to clip
+        paths and shape properties that parses the [basic-shape || box] syntax from
+        the CSS Shapes spec.
+        (WebCore::CSSParser::parseShapeProperty): Parse shape-box pairs as a CSSValueList.
+        * css/DeprecatedStyleBuilder.cpp:
+        (WebCore::ApplyPropertyShape::applyValue): Use the CSSValueList for shape-box pairs.
+        * css/CSSValueList.h:
+        (WebCore::CSSValueList::itemWithoutBoundsCheck): Add a const version.
+        * page/animation/CSSPropertyAnimation.cpp:
+        (WebCore::blendFunc): Specify a box when blending.
+        * rendering/style/ShapeValue.h:
+        (WebCore::ShapeValue::createShapeValue): Add a box parameter.
+        (WebCore::ShapeValue::ShapeValue): Ditto.
+
 2014-01-21  Daniel Bates  <dabates@apple.com>
 
         Fix the iOS Simulator release build
index 5f3f2ef..cf16db3 100644 (file)
@@ -1763,6 +1763,31 @@ static inline PassRefPtr<RenderStyle> computeRenderStyleForProperty(Node* styled
     return styledNode->computedStyle(styledNode->isPseudoElement() ? NOPSEUDO : pseudoElementSpecifier);
 }
 
+#if ENABLE(CSS_SHAPES)
+static PassRefPtr<CSSValue> shapePropertyValue(const RenderStyle* style, const ShapeValue* shapeValue)
+{
+    if (!shapeValue)
+        return cssValuePool().createIdentifierValue(CSSValueNone);
+
+    if (shapeValue->type() == ShapeValue::Outside)
+        return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
+
+    if (shapeValue->type() == ShapeValue::Box)
+        return cssValuePool().createValue(shapeValue->layoutBox());
+
+    if (shapeValue->type() == ShapeValue::Image)
+        return shapeValue->image() ? shapeValue->image()->cssValue() : cssValuePool().createIdentifierValue(CSSValueNone);
+
+    ASSERT(shapeValue->type() == ShapeValue::Shape);
+
+    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    list->append(valueForBasicShape(style, shapeValue->shape()));
+    if (shapeValue->layoutBox() != BoxMissing)
+        list->append(cssValuePool().createValue(shapeValue->layoutBox()));
+    return list.release();
+}
+#endif
+
 PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
 {
     Node* styledNode = this->styledNode();
@@ -2938,31 +2963,9 @@ PassRefPtr<CSSValue> ComputedStyleExtractor::propertyValue(CSSPropertyID propert
         case CSSPropertyWebkitShapeImageThreshold:
             return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyWebkitShapeInside:
-            if (!style->shapeInside())
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            if (style->shapeInside()->type() == ShapeValue::Box)
-                return cssValuePool().createValue(style->shapeInside()->layoutBox());
-            if (style->shapeInside()->type() == ShapeValue::Outside)
-                return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
-            if (style->shapeInside()->type() == ShapeValue::Image) {
-                if (style->shapeInside()->image())
-                    return style->shapeInside()->image()->cssValue();
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            }
-            ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
-            return valueForBasicShape(style.get(), style->shapeInside()->shape());
+            return shapePropertyValue(style.get(), style->shapeInside());
         case CSSPropertyWebkitShapeOutside:
-            if (!style->shapeOutside())
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            if (style->shapeOutside()->type() == ShapeValue::Box)
-                return cssValuePool().createValue(style->shapeOutside()->layoutBox());
-            if (style->shapeOutside()->type() == ShapeValue::Image) {
-                if (style->shapeOutside()->image())
-                    return style->shapeOutside()->image()->cssValue();
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            }
-            ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
-            return valueForBasicShape(style.get(), style->shapeOutside()->shape());
+            return shapePropertyValue(style.get(), style->shapeOutside());
 #endif
 #if ENABLE(CSS_FILTERS)
         case CSSPropertyWebkitFilter:
index 0a3fa0e..5c1c054 100644 (file)
@@ -5843,7 +5843,7 @@ PassRefPtr<CSSBasicShape> CSSParser::parseBasicShapePolygon(CSSParserValueList*
     return shape;
 }
 
-static bool isBoxValue(CSSValueID valueId)
+static bool isBoxValue(CSSValueID valueId, CSSPropertyID propId)
 {
     switch (valueId) {
     case CSSValueContentBox:
@@ -5851,12 +5851,48 @@ static bool isBoxValue(CSSValueID valueId)
     case CSSValueBorderBox:
     case CSSValueMarginBox:
         return true;
+    case CSSValueBoundingBox:
+        return propId == CSSPropertyWebkitClipPath;
     default: break;
     }
 
     return false;
 }
 
+PassRefPtr<CSSValue> CSSParser::parseBasicShapeAndOrBox(CSSPropertyID propId)
+{
+    CSSParserValue* value = m_valueList->current();
+
+    bool shapeFound = false;
+    bool boxFound = false;
+    CSSValueID valueId;
+
+    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    for (unsigned i = 0; i < 2; ++i) {
+        if (!value)
+            break;
+        valueId = value->id;
+        if (value->unit == CSSParserValue::Function && !shapeFound) {
+            // parseBasicShape already asks for the next value list item.
+            RefPtr<CSSPrimitiveValue> shapeValue = parseBasicShape();
+            if (!shapeValue)
+                return nullptr;
+            list->append(shapeValue.release());
+            shapeFound = true;
+        } else if (isBoxValue(valueId, propId) && !boxFound) {
+            list->append(parseValidPrimitive(valueId, value));
+            boxFound = true;
+            m_valueList->next();
+        } else
+            return nullptr;
+        value = m_valueList->current();
+    }
+
+    if (m_valueList->current())
+        return nullptr;
+    return list.release();
+}
+
 #if ENABLE(CSS_SHAPES)
 PassRefPtr<CSSValue> CSSParser::parseShapeProperty(CSSPropertyID propId)
 {
@@ -5881,33 +5917,7 @@ PassRefPtr<CSSValue> CSSParser::parseShapeProperty(CSSPropertyID propId)
         return imageValue.release();
     }
 
-    if (value->unit == CSSParserValue::Function) {
-        shapeValue = parseBasicShape();
-    } else if (isBoxValue(valueId)) {
-        keywordValue = parseValidPrimitive(valueId, value);
-        m_valueList->next();
-    } else
-        return nullptr;
-
-    value = m_valueList->current();
-
-    if (value) {
-        valueId = value->id;
-        if (keywordValue && value->unit == CSSParserValue::Function) {
-            shapeValue = parseBasicShape();
-        } else if (shapeValue && isBoxValue(valueId)) {
-            keywordValue = parseValidPrimitive(valueId, value);
-            m_valueList->next();
-        } else
-            return nullptr;
-    }
-
-    ASSERT(!shapeValue || shapeValue->isShape());
-
-    if (shapeValue && keywordValue)
-        shapeValue->getShapeValue()->setLayoutBox(keywordValue.release());
-
-    return shapeValue ? shapeValue.release() : keywordValue.release();
+    return parseBasicShapeAndOrBox(propId);
 }
 #endif
 
@@ -5927,31 +5937,7 @@ PassRefPtr<CSSValue> CSSParser::parseClipPath()
     }
 #endif
 
-    bool shapeFound = false;
-    bool boxFound = false;
-    RefPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    for (unsigned i = 0; i < 2; ++i) {
-        if (!value)
-            break;
-        valueId = value->id;
-        if (value->unit == CSSParserValue::Function && !shapeFound) {
-            // parseBasicShape already asks for the next value list item.
-            RefPtr<CSSPrimitiveValue> shapeValue = parseBasicShape();
-            if (!shapeValue)
-                return nullptr;
-            list->append(shapeValue.release());
-            shapeFound = true;
-        } else if ((isBoxValue(valueId) || valueId == CSSValueBoundingBox) && !boxFound) {
-            list->append(parseValidPrimitive(valueId, value));
-            boxFound = true;
-            m_valueList->next();
-        } else
-            return nullptr;
-        value = m_valueList->current();
-    }
-    if (value)
-        return nullptr;
-    return list.release();
+    return parseBasicShapeAndOrBox(CSSPropertyWebkitClipPath);
 }
 
 // FIXME This function is temporary to allow for an orderly transition between
index cf0e57a..47b05e6 100644 (file)
@@ -179,6 +179,7 @@ public:
     PassRefPtr<CSSValue> parseShapeProperty(CSSPropertyID);
 #endif
 
+    PassRefPtr<CSSValue> parseBasicShapeAndOrBox(CSSPropertyID propId);
     PassRefPtr<CSSPrimitiveValue> parseBasicShape();
     PassRefPtr<CSSPrimitiveValue> parseShapeRadius(CSSParserValue*);
     PassRefPtr<CSSBasicShape> parseBasicShapeRectangle(CSSParserValueList*);
index 94e2603..fa82a9a 100644 (file)
@@ -52,6 +52,7 @@ public:
     CSSValue* item(size_t index) { return index < m_values.size() ? m_values[index].get() : 0; }
     const CSSValue* item(size_t index) const { return index < m_values.size() ? m_values[index].get() : 0; }
     CSSValue* itemWithoutBoundsCheck(size_t index) { return m_values[index].get(); }
+    const CSSValue* itemWithoutBoundsCheck(size_t index) const { ASSERT(index < m_values.size()); return m_values[index].get(); }
 
     void append(PassRefPtr<CSSValue> value) { m_values.append(value); }
     void prepend(PassRefPtr<CSSValue> value) { m_values.insert(0, value); }
index 6a8a355..31f2387 100644 (file)
@@ -2182,23 +2182,36 @@ public:
             CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
             if (primitiveValue->getValueID() == CSSValueAuto)
                 setValue(styleResolver->style(), 0);
-            else if (primitiveValue->getValueID() == CSSValueContentBox
-                || primitiveValue->getValueID() == CSSValueBorderBox
-                || primitiveValue->getValueID() == CSSValuePaddingBox
-                || primitiveValue->getValueID() == CSSValueMarginBox)
-                setValue(styleResolver->style(), ShapeValue::createLayoutBoxValue(LayoutBox(*primitiveValue)));
             else if (primitiveValue->getValueID() == CSSValueOutsideShape)
                 setValue(styleResolver->style(), ShapeValue::createOutsideValue());
-            else if (primitiveValue->isShape()) {
-                RefPtr<ShapeValue> shape = ShapeValue::createShapeValue(basicShapeForValue(styleResolver->style(), styleResolver->rootElementStyle(), primitiveValue->getShapeValue()));
-                setValue(styleResolver->style(), shape.release());
-            }
         } else if (value->isImageValue() || value->isImageSetValue()) {
             RefPtr<ShapeValue> shape = ShapeValue::createImageValue(styleResolver->styleImage(property, value));
             setValue(styleResolver->style(), shape.release());
-        }
+        } else if (value->isValueList()) {
+            RefPtr<BasicShape> shape;
+            LayoutBox layoutBox = BoxMissing;
+            CSSValueList* valueList = toCSSValueList(value);
+            for (unsigned i = 0; i < valueList->length(); ++i) {
+                CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(valueList->itemWithoutBoundsCheck(i));
+                if (primitiveValue->isShape())
+                    shape = basicShapeForValue(styleResolver->style(), styleResolver->rootElementStyle(), primitiveValue->getShapeValue());
+                else if (primitiveValue->getValueID() == CSSValueContentBox
+                    || primitiveValue->getValueID() == CSSValueBorderBox
+                    || primitiveValue->getValueID() == CSSValuePaddingBox
+                    || primitiveValue->getValueID() == CSSValueMarginBox)
+                    layoutBox = LayoutBox(*primitiveValue);
+                else
+                    return;
+            }
+
+            if (shape)
+                setValue(styleResolver->style(), ShapeValue::createShapeValue(shape.release(), layoutBox));
+            else if (layoutBox != BoxMissing)
+                setValue(styleResolver->style(), ShapeValue::createLayoutBoxValue(layoutBox));
 
+        }
     }
+
     static PropertyHandler createHandler()
     {
         PropertyHandler handler = ApplyPropertyDefaultBase<ShapeValue*, getterFunction, PassRefPtr<ShapeValue>, setterFunction, ShapeValue*, initialFunction>::createHandler();
index 72c78fe..a398a7a 100644 (file)
@@ -153,13 +153,16 @@ static inline PassRefPtr<ShapeValue> blendFunc(const AnimationBase*, ShapeValue*
     if (from->type() != ShapeValue::Shape || to->type() != ShapeValue::Shape)
         return to;
 
+    if (from->layoutBox() != to->layoutBox())
+        return to;
+
     const BasicShape* fromShape = from->shape();
     const BasicShape* toShape = to->shape();
 
     if (!fromShape->canBlend(toShape))
         return to;
 
-    return ShapeValue::createShapeValue(toShape->blend(fromShape, progress));
+    return ShapeValue::createShapeValue(toShape->blend(fromShape, progress), to->layoutBox());
 }
 #endif
 
index 0cc22c4..53c11a7 100644 (file)
@@ -48,9 +48,9 @@ public:
         Image
     };
 
-    static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape)
+    static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape, LayoutBox layoutBox)
     {
-        return adoptRef(new ShapeValue(shape));
+        return adoptRef(new ShapeValue(shape, layoutBox));
     }
 
     static PassRefPtr<ShapeValue> createLayoutBoxValue(LayoutBox layoutBox)
@@ -84,10 +84,10 @@ public:
     bool operator==(const ShapeValue& other) const { return type() == other.type(); }
 
 private:
-    ShapeValue(PassRefPtr<BasicShape> shape)
+    ShapeValue(PassRefPtr<BasicShape> shape, LayoutBox layoutBox)
         : m_type(Shape)
         , m_shape(shape)
-        , m_layoutBox(m_shape->layoutBox())
+        , m_layoutBox(layoutBox)
     {
     }
     ShapeValue(ShapeValueType type)