border-image should be implemented like a shorthand.
authoralexis.menard@openbossa.org <alexis.menard@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jan 2012 19:11:10 +0000 (19:11 +0000)
committeralexis.menard@openbossa.org <alexis.menard@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jan 2012 19:11:10 +0000 (19:11 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76697

Reviewed by Tony Chang.

Source/WebCore:

Make sure that border-image is implemented like a shorthand : when we parse
it we set the correct value to its longhands. The code was not doing it
previously as we inherited the old implementation of -webkit-border-image which
is not a shorthand but a regular property. It will then increase
style.length for a given element as we now expand the longhands.
The behavior stays the same for -webkit-border-image.

Test: fast/css/border-image-style-length.html

* css/CSSParser.cpp:
(WebCore::CSSParser::parseValue):
(WebCore::BorderImageParseContext::BorderImageParseContext):
(WebCore::BorderImageParseContext::commitWebKitBorderImage):
(WebCore::BorderImageParseContext::commitBorderImage):
(BorderImageParseContext):
(WebCore::BorderImageParseContext::commitBorderImageProperty):
(WebCore::CSSParser::parseBorderImage):
* css/CSSParser.h:
():
* css/CSSPropertyLonghand.cpp:
(WebCore::initShorthandMap):
* css/CSSStyleApplyProperty.cpp:
():
(WebCore::ApplyPropertyExpanding::applyInheritValue):
(WebCore::ApplyPropertyExpanding::applyInitialValue):
(WebCore::ApplyPropertyExpanding::applyValue):
(WebCore::ApplyPropertyBorderImageModifier::applyInitialValue):
(WebCore::CSSStyleApplyProperty::CSSStyleApplyProperty):
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::mapNinePieceImage):
* page/animation/AnimationBase.cpp:
(WebCore::AnimationBase::ensurePropertyMap):
(WebCore::addShorthandProperties):
* rendering/style/RenderStyle.h:
(WebCore::RenderStyleBitfields::borderImageSlices):
(WebCore::RenderStyleBitfields::borderImageWidth):
(WebCore::RenderStyleBitfields::borderImageOutset):
(RenderStyleBitfields):
(WebCore::RenderStyleBitfields::setBorderImageSlices):
(WebCore::RenderStyleBitfields::setBorderImageWidth):
(WebCore::RenderStyleBitfields::setBorderImageOutset):

LayoutTests:

Make sure we cover that border-image correctly expands its longhands.

* fast/css/border-image-style-length-expected.txt: Added.
* fast/css/border-image-style-length.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/fast/css/border-image-style-length-expected.txt [new file with mode: 0644]
LayoutTests/fast/css/border-image-style-length.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/css/CSSPropertyLonghand.cpp
Source/WebCore/css/CSSStyleApplyProperty.cpp
Source/WebCore/css/CSSStyleSelector.cpp
Source/WebCore/page/animation/AnimationBase.cpp
Source/WebCore/rendering/style/RenderStyle.h

index 59f8792..0a8f6c3 100644 (file)
@@ -1,3 +1,15 @@
+2012-01-25  Alexis Menard  <alexis.menard@openbossa.org>
+
+        border-image should be implemented like a shorthand.
+        https://bugs.webkit.org/show_bug.cgi?id=76697
+
+        Reviewed by Tony Chang.
+
+        Make sure we cover that border-image correctly expands its longhands.
+
+        * fast/css/border-image-style-length-expected.txt: Added.
+        * fast/css/border-image-style-length.html: Added.
+
 2012-01-24  MORITA Hajime  <morrita@google.com>
 
         [Refactoring][Internals] Should have InternalSettings
diff --git a/LayoutTests/fast/css/border-image-style-length-expected.txt b/LayoutTests/fast/css/border-image-style-length-expected.txt
new file mode 100644 (file)
index 0000000..626ebfb
--- /dev/null
@@ -0,0 +1,12 @@
+Test the style.length of an element with a border-image.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS e.style.length is 5
+PASS e.style.length is 0
+PASS e.style.length is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/css/border-image-style-length.html b/LayoutTests/fast/css/border-image-style-length.html
new file mode 100644 (file)
index 0000000..d7c743b
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src="../js/resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+
+description("Test the style.length of an element with a border-image.")
+
+var testContainer = document.createElement("div");
+document.body.appendChild(testContainer);
+
+testContainer.innerHTML = '<div id="test">hello</div>';
+
+e = document.getElementById('test');
+e.style.borderImage = "url(dummy://test.png) 10 / 13px 1.5em 1em 10px";
+shouldBe("e.style.length", "5");
+e.style.borderImage = "";
+shouldBe("e.style.length", "0");
+e.style.webkitBorderImage = "url(dummy://test.png) 0 7 0 13 / 0 7 0 13 stretch stretch";
+shouldBe("e.style.length", "1");
+document.body.removeChild(testContainer);
+
+</script>
+<script src="../js/resources/js-test-post.js"></script>
+</body>
+</html>
index 35056bb..e01a329 100644 (file)
@@ -1,3 +1,52 @@
+2012-01-25  Alexis Menard  <alexis.menard@openbossa.org>
+
+        border-image should be implemented like a shorthand.
+        https://bugs.webkit.org/show_bug.cgi?id=76697
+
+        Reviewed by Tony Chang.
+
+        Make sure that border-image is implemented like a shorthand : when we parse
+        it we set the correct value to its longhands. The code was not doing it
+        previously as we inherited the old implementation of -webkit-border-image which
+        is not a shorthand but a regular property. It will then increase
+        style.length for a given element as we now expand the longhands.
+        The behavior stays the same for -webkit-border-image.
+
+        Test: fast/css/border-image-style-length.html
+
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseValue):
+        (WebCore::BorderImageParseContext::BorderImageParseContext):
+        (WebCore::BorderImageParseContext::commitWebKitBorderImage):
+        (WebCore::BorderImageParseContext::commitBorderImage):
+        (BorderImageParseContext):
+        (WebCore::BorderImageParseContext::commitBorderImageProperty):
+        (WebCore::CSSParser::parseBorderImage):
+        * css/CSSParser.h:
+        ():
+        * css/CSSPropertyLonghand.cpp:
+        (WebCore::initShorthandMap):
+        * css/CSSStyleApplyProperty.cpp:
+        ():
+        (WebCore::ApplyPropertyExpanding::applyInheritValue):
+        (WebCore::ApplyPropertyExpanding::applyInitialValue):
+        (WebCore::ApplyPropertyExpanding::applyValue):
+        (WebCore::ApplyPropertyBorderImageModifier::applyInitialValue):
+        (WebCore::CSSStyleApplyProperty::CSSStyleApplyProperty):
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::mapNinePieceImage):
+        * page/animation/AnimationBase.cpp:
+        (WebCore::AnimationBase::ensurePropertyMap):
+        (WebCore::addShorthandProperties):
+        * rendering/style/RenderStyle.h:
+        (WebCore::RenderStyleBitfields::borderImageSlices):
+        (WebCore::RenderStyleBitfields::borderImageWidth):
+        (WebCore::RenderStyleBitfields::borderImageOutset):
+        (RenderStyleBitfields):
+        (WebCore::RenderStyleBitfields::setBorderImageSlices):
+        (WebCore::RenderStyleBitfields::setBorderImageWidth):
+        (WebCore::RenderStyleBitfields::setBorderImageOutset):
+
 2012-01-23  MORITA Hajime  <morrita@google.com>
 
         [Refactoring][Internals] Should have InternalSettings
index 3be734d..eaf6703 100644 (file)
@@ -1474,7 +1474,10 @@ bool CSSParser::parseValue(int propId, bool important)
             validPrimitive = true;
         break;
 
-    case CSSPropertyBorderImage:
+    case CSSPropertyBorderImage: {
+        RefPtr<CSSValue> result;
+        return parseBorderImage(propId, result, important);
+    }
     case CSSPropertyWebkitBorderImage:
     case CSSPropertyWebkitMaskBoxImage: {
         RefPtr<CSSValue> result;
@@ -5299,9 +5302,8 @@ bool CSSParser::parseFlex(int propId, bool important)
 }
 
 struct BorderImageParseContext {
-    BorderImageParseContext(CSSValuePool* cssValuePool)
-    : m_cssValuePool(cssValuePool)
-    , m_canAdvance(false)
+    BorderImageParseContext()
+    : m_canAdvance(false)
     , m_allowCommit(true)
     , m_allowImage(true)
     , m_allowImageSlice(true)
@@ -5381,12 +5383,27 @@ struct BorderImageParseContext {
         m_allowImage = !m_image;
     }
 
-    PassRefPtr<CSSValue> commitBorderImage()
+    PassRefPtr<CSSValue> commitWebKitBorderImage()
     {
         return createBorderImageValue(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat);
     }
 
-    CSSValuePool* m_cssValuePool;
+    void commitBorderImage(CSSParser* parser, bool important)
+    {
+        commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important);
+        commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
+        commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
+        commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
+        commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important);
+    }
+
+    void commitBorderImageProperty(int propId, CSSParser* parser, PassRefPtr<CSSValue> value, bool important)
+    {
+        if (value)
+            parser->addProperty(propId, value, important);
+        else
+            parser->addProperty(propId, parser->cssValuePool()->createImplicitInitialValue(), important, true);
+    }
 
     bool m_canAdvance;
 
@@ -5407,10 +5424,10 @@ struct BorderImageParseContext {
     RefPtr<CSSValue> m_repeat;
 };
 
-bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result)
+bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result, bool important)
 {
     ShorthandScope scope(this, propId);
-    BorderImageParseContext context(cssValuePool());
+    BorderImageParseContext context;
     while (CSSParserValue* val = m_valueList->current()) {
         context.setCanAdvance(false);
 
@@ -5463,8 +5480,11 @@ bool CSSParser::parseBorderImage(int propId, RefPtr<CSSValue>& result)
     }
 
     if (context.allowCommit()) {
-        // Need to fully commit as a single value.
-        result = context.commitBorderImage();
+        if (propId == CSSPropertyBorderImage)
+            context.commitBorderImage(this, important);
+        else
+            // Need to fully commit as a single value.
+            result = context.commitWebKitBorderImage();
         return true;
     }
 
index a0df696..3bf045e 100644 (file)
@@ -173,7 +173,7 @@ public:
 
     // CSS3 Parsing Routines (for properties specific to CSS3)
     PassRefPtr<CSSValueList> parseShadow(CSSParserValueList*, int propId);
-    bool parseBorderImage(int propId, RefPtr<CSSValue>&);
+    bool parseBorderImage(int propId, RefPtr<CSSValue>&, bool important = false);
     bool parseBorderImageRepeat(RefPtr<CSSValue>&);
     bool parseBorderImageSlice(int propId, RefPtr<CSSBorderImageSliceValue>&);
     bool parseBorderImageWidth(RefPtr<CSSPrimitiveValue>&);
index bdd128c..0d03b20 100644 (file)
@@ -66,6 +66,15 @@ static void initShorthandMap(ShorthandMap& shorthandMap)
     };
     SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderColor, borderColorProperties);
 
+    static const int borderImageProperties[] = {
+        CSSPropertyBorderImageSource,
+        CSSPropertyBorderImageSlice,
+        CSSPropertyBorderImageWidth,
+        CSSPropertyBorderImageOutset,
+        CSSPropertyBorderImageRepeat
+    };
+    SET_SHORTHAND_MAP_ENTRY(shorthandMap, CSSPropertyBorderImage, borderImageProperties);
+
     static const int borderStyleProperties[] = {
         CSSPropertyBorderTopStyle,
         CSSPropertyBorderRightStyle,
index b8211bf..629470b 100644 (file)
@@ -47,7 +47,7 @@ using namespace std;
 namespace WebCore {
 
 enum ExpandValueBehavior {SuppressValue = 0, ExpandValue};
-template <ExpandValueBehavior expandValue, CSSPropertyID one = CSSPropertyInvalid, CSSPropertyID two = CSSPropertyInvalid, CSSPropertyID three = CSSPropertyInvalid, CSSPropertyID four = CSSPropertyInvalid>
+template <ExpandValueBehavior expandValue, CSSPropertyID one = CSSPropertyInvalid, CSSPropertyID two = CSSPropertyInvalid, CSSPropertyID three = CSSPropertyInvalid, CSSPropertyID four = CSSPropertyInvalid, CSSPropertyID five = CSSPropertyInvalid>
 class ApplyPropertyExpanding {
 public:
 
@@ -69,6 +69,7 @@ public:
         applyInheritValue<two>(selector);
         applyInheritValue<three>(selector);
         applyInheritValue<four>(selector);
+        applyInheritValue<five>(selector);
     }
 
     template <CSSPropertyID id>
@@ -89,6 +90,7 @@ public:
         applyInitialValue<two>(selector);
         applyInitialValue<three>(selector);
         applyInitialValue<four>(selector);
+        applyInitialValue<five>(selector);
     }
 
     template <CSSPropertyID id>
@@ -112,6 +114,7 @@ public:
         applyValue<two>(selector, value);
         applyValue<three>(selector, value);
         applyValue<four>(selector, value);
+        applyValue<five>(selector, value);
     }
     static PropertyHandler createHandler() { return PropertyHandler(&applyInheritValue, &applyInitialValue, &applyValue); }
 };
@@ -904,7 +907,7 @@ public:
         NinePieceImage image(getValue(selector->style()));
         switch (modifier) {
         case Outset:
-            image.setOutset(LengthBox());
+            image.setOutset(LengthBox(0));
             break;
         case Repeat:
             image.setHorizontalRule(StretchImageRule);
@@ -1761,7 +1764,7 @@ CSSStyleApplyProperty::CSSStyleApplyProperty()
     setPropertyHandler(CSSPropertyBorderColor, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderTopColor, CSSPropertyBorderRightColor, CSSPropertyBorderBottomColor, CSSPropertyBorderLeftColor>::createHandler());
     setPropertyHandler(CSSPropertyBorder, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderStyle, CSSPropertyBorderWidth, CSSPropertyBorderColor>::createHandler());
 
-    setPropertyHandler(CSSPropertyBorderImage, ApplyPropertyBorderImage<Image, CSSPropertyBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage>::createHandler());
+    setPropertyHandler(CSSPropertyBorderImage, ApplyPropertyExpanding<SuppressValue, CSSPropertyBorderImageSource, CSSPropertyBorderImageSlice, CSSPropertyBorderImageWidth, CSSPropertyBorderImageOutset, CSSPropertyBorderImageRepeat>::createHandler());
     setPropertyHandler(CSSPropertyWebkitBorderImage, ApplyPropertyBorderImage<Image, CSSPropertyWebkitBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage>::createHandler());
     setPropertyHandler(CSSPropertyWebkitMaskBoxImage, ApplyPropertyBorderImage<Mask, CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage>::createHandler());
 
index 6034073..f143423 100644 (file)
@@ -4288,7 +4288,7 @@ void CSSStyleSelector::mapNinePieceImage(CSSPropertyID property, CSSValue* value
 
     // Set the image (this kicks off the load).
     CSSPropertyID imageProperty;
-    if (property == CSSPropertyWebkitBorderImage || property == CSSPropertyBorderImage)
+    if (property == CSSPropertyWebkitBorderImage)
         imageProperty = CSSPropertyBorderImageSource;
     else if (property == CSSPropertyWebkitMaskBoxImage)
         imageProperty = CSSPropertyWebkitMaskBoxImageSource;
index 2cade34..e3ad92f 100644 (file)
@@ -976,7 +976,9 @@ void AnimationBase::ensurePropertyMap()
         gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage, &RenderStyle::setMaskImage));
 
         gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource, &RenderStyle::setBorderImageSource));
-        gPropertyWrappers->append(new PropertyWrapper<const NinePieceImage&>(CSSPropertyBorderImage, &RenderStyle::borderImage, &RenderStyle::setBorderImage));
+        gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices, &RenderStyle::setBorderImageSlices));
+        gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth, &RenderStyle::setBorderImageWidth));
+        gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset, &RenderStyle::setBorderImageOutset));
 
         gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource, &RenderStyle::setMaskBoxImageSource));
         gPropertyWrappers->append(new PropertyWrapper<const NinePieceImage&>(CSSPropertyWebkitMaskBoxImage, &RenderStyle::maskBoxImage, &RenderStyle::setMaskBoxImage));
@@ -1117,6 +1119,7 @@ static void addShorthandProperties()
         CSSPropertyBorderRadius,
         CSSPropertyBorderWidth,
         CSSPropertyBorder,
+        CSSPropertyBorderImage,
         CSSPropertyBorderSpacing,
         CSSPropertyListStyle, // for list-style-image
         CSSPropertyMargin,
index 5f0559b..2b057d3 100644 (file)
@@ -538,7 +538,10 @@ public:
 
     const NinePieceImage& borderImage() const { return surround->border.image(); }
     StyleImage* borderImageSource() const { return surround->border.image().image(); }
+    LengthBox borderImageSlices() const { return surround->border.image().imageSlices(); }
+    LengthBox borderImageWidth() const { return surround->border.image().borderSlices(); }
+    LengthBox borderImageOutset() const { return surround->border.image().outset(); }
+
     LengthSize borderTopLeftRadius() const { return surround->border.topLeft(); }
     LengthSize borderTopRightRadius() const { return surround->border.topRight(); }
     LengthSize borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
@@ -1019,6 +1022,9 @@ public:
     
     void setBorderImage(const NinePieceImage& b) { SET_VAR(surround, border.m_image, b) }
     void setBorderImageSource(PassRefPtr<StyleImage> v) { surround.access()->border.m_image.setImage(v); }
+    void setBorderImageSlices(LengthBox slices) { surround.access()->border.m_image.setImageSlices(slices); }
+    void setBorderImageWidth(LengthBox slices) { surround.access()->border.m_image.setBorderSlices(slices); }
+    void setBorderImageOutset(LengthBox outset) { surround.access()->border.m_image.setOutset(outset); }
 
     void setBorderTopLeftRadius(LengthSize s) { SET_VAR(surround, border.m_topLeft, s) }
     void setBorderTopRightRadius(LengthSize s) { SET_VAR(surround, border.m_topRight, s) }