Title: [135848] trunk
Revision
135848
Author
apav...@chromium.org
Date
2012-11-27 04:39:56 -0800 (Tue, 27 Nov 2012)

Log Message

Incorrect value of CSSStyleDeclaration#length when a shorthand property is inherit or initial
https://bugs.webkit.org/show_bug.cgi?id=73002

Reviewed by Alexis Menard.

Source/WebCore:

Before the patch, "inherit" and "initial" shorthands would get added to the StylePropertySet as-is, their longhands unspecified.
This patch tackles two aspects of the problem:
- When parsing "initial" and "inherit" shorthands, their longhands are added to the property set with the corresponding values.
- When querying "initial" and "inherit" shorthands, their values are reconstructed from the longhands as usual, but if all of the longhands
  are found to have the same explicit "initial" or "inherit" value, the respective single value is returned as the shorthand value.

When reconstructing shorthands, a "common value" is tracked. If all longhands involved have the same explicit value, it becomes the
"common value", otherwise it is a String(). The "inherit" or "initial" common value ultimately becomes the shorthand value
(except for the "background-position" shorthand, which is a special case).

* css/CSSParser.cpp:
(WebCore::parseKeywordValue): Parse shorthands' "initial" and "inherit" values using the CSSParser.
(WebCore::CSSParser::addExpandedPropertyForValue): Add simple property or all sharthand's longhands with given value and priority.
(WebCore::CSSParser::parseValue): For "initial" and "inherit" shorthands, add their longhands with the respective value, not the shorthands proper.
* css/CSSParser.h: Add addExpandedPropertyForValue().
* css/StylePropertySet.cpp:
(WebCore::isInitialOrInherit): Check if the value is "initial" or "inherit".
(WebCore):
(WebCore::StylePropertySet::appendFontLonghandValueIfExplicit): Modified to track the common value for the "font" shorthand.
(WebCore::StylePropertySet::fontValue): Ditto.
(WebCore::StylePropertySet::get4Values): Return "inherit" or "initial" if all 4 values are explicitly "inherit" or "initial".
(WebCore::StylePropertySet::getLayeredShorthandValue): Use the common value approach for layered shorthands.
(WebCore::StylePropertySet::getShorthandValue): Ditto for ordinary shorthands.
(WebCore::StylePropertySet::borderPropertyValue): Ditto for the "border" shorthand.
* css/StylePropertySet.h: Modify the appendFontLonghandValueIfExplicit() signature.
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::setFont): Now that "inherit" and "initial" shorthands are represented by their longhands,
we need to check the string value of the "font" shorthand for being "inherit" or "initial" instead: getPropertyCSSValue() no longer works,
since the shorthand itself is no longer added to the StylePropertySet.

LayoutTests:

Expectations get fixed in some cases.

* css3/flexbox/flex-property-parsing-expected.txt:
* fast/css/inherit-initial-shorthand-values-expected.txt: Added.
* fast/css/inherit-initial-shorthand-values.html: Added.
* fast/css/parsing-text-emphasis-expected.txt:
* fast/css/parsing-text-emphasis.html:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (135847 => 135848)


--- trunk/LayoutTests/ChangeLog	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/LayoutTests/ChangeLog	2012-11-27 12:39:56 UTC (rev 135848)
@@ -1,3 +1,18 @@
+2012-11-27  Alexander Pavlov  <apav...@chromium.org>
+
+        Incorrect value of CSSStyleDeclaration#length when a shorthand property is inherit or initial
+        https://bugs.webkit.org/show_bug.cgi?id=73002
+
+        Reviewed by Alexis Menard.
+
+        Expectations get fixed in some cases.
+
+        * css3/flexbox/flex-property-parsing-expected.txt:
+        * fast/css/inherit-initial-shorthand-values-expected.txt: Added.
+        * fast/css/inherit-initial-shorthand-values.html: Added.
+        * fast/css/parsing-text-emphasis-expected.txt:
+        * fast/css/parsing-text-emphasis.html:
+
 2012-09-17  Allan Sandfeld Jensen  <allan.jen...@nokia.com>
 
         Incorrect rect-based hit-test result when hit-test region includes culled inlines

Modified: trunk/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt (135847 => 135848)


--- trunk/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/LayoutTests/css3/flexbox/flex-property-parsing-expected.txt	2012-11-27 12:39:56 UTC (rev 135848)
@@ -107,7 +107,7 @@
 PASS getComputedStyle(flexitem).webkitFlex is "0 0 auto"
 PASS flexitem.style.webkitFlex is "initial"
 PASS getComputedStyle(flexitem).webkitFlex is "0 1 auto"
-FAIL flexitem.style.webkitFlex should be 0 0 auto. Was initial.
+PASS flexitem.style.webkitFlex is "0 0 auto"
 PASS getComputedStyle(flexitem).webkitFlex is "0 0 auto"
 PASS successfullyParsed is true
 

Added: trunk/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt (0 => 135848)


--- trunk/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/css/inherit-initial-shorthand-values-expected.txt	2012-11-27 12:39:56 UTC (rev 135848)
@@ -0,0 +1,40 @@
+PASS test('background') is "inherit, initial"
+PASS test('background-position') is "inherit, initial"
+PASS test('background-repeat') is "inherit, initial"
+PASS test('border') is "inherit, initial"
+PASS test('border-bottom') is "inherit, initial"
+PASS test('border-color') is "inherit, initial"
+PASS test('border-left') is "inherit, initial"
+PASS test('border-radius') is "inherit, initial"
+PASS test('border-right') is "inherit, initial"
+PASS test('border-spacing') is "inherit, initial"
+PASS test('border-style') is "inherit, initial"
+PASS test('border-top') is "inherit, initial"
+PASS test('border-width') is "inherit, initial"
+PASS test('list-style') is "inherit, initial"
+PASS test('font') is "inherit, initial"
+PASS test('margin') is "inherit, initial"
+PASS test('outline') is "inherit, initial"
+PASS test('overflow') is "inherit, initial"
+PASS test('padding') is "inherit, initial"
+PASS test('webkit-animation') is "inherit, initial"
+PASS test('webkit-border-after') is "inherit, initial"
+PASS test('webkit-border-before') is "inherit, initial"
+PASS test('webkit-border-end') is "inherit, initial"
+PASS test('webkit-border-start') is "inherit, initial"
+PASS test('webkit-columns') is "inherit, initial"
+PASS test('webkit-column-rule') is "inherit, initial"
+PASS test('webkit-flex-flow') is "inherit, initial"
+PASS test('webkit-flex') is "inherit, initial"
+PASS test('webkit-marginCollapse') is "inherit, initial"
+PASS test('webkit-marquee') is "inherit, initial"
+PASS test('webkit-mask') is "inherit, initial"
+PASS test('webkit-mask-position') is "inherit, initial"
+PASS test('webkit-mask-repeat') is "inherit, initial"
+PASS test('webkit-text-emphasis') is "inherit, initial"
+PASS test('webkit-text-stroke') is "inherit, initial"
+PASS test('webkit-transition') is "inherit, initial"
+PASS test('webkit-transform-origin') is "inherit, initial"
+Test that e matched declaration cache handles explicitly inherited properties correctly.
+
+

Added: trunk/LayoutTests/fast/css/inherit-initial-shorthand-values.html (0 => 135848)


--- trunk/LayoutTests/fast/css/inherit-initial-shorthand-values.html	                        (rev 0)
+++ trunk/LayoutTests/fast/css/inherit-initial-shorthand-values.html	2012-11-27 12:39:56 UTC (rev 135848)
@@ -0,0 +1,71 @@
+<script src=""
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+</script>
+<style>
+#test {
+}
+</style>
+<body>
+</body>
+<p>
+Test that e matched declaration cache handles explicitly inherited properties correctly.
+<p>
+<script>
+var shorthandNames = [
+    "background",
+    "background-position",
+    "background-repeat",
+    "border",
+    "border-bottom",
+    "border-color",
+    // getPropertyValue() functionality not supported, see http://webkit.org/b/103245.
+    // "border-image",
+    "border-left",
+    "border-radius",
+    "border-right",
+    "border-spacing",
+    "border-style",
+    "border-top",
+    "border-width",
+    "list-style",
+    "font",
+    "margin",
+    "outline",
+    "overflow",
+    "padding",
+    "webkit-animation",
+    "webkit-border-after",
+    "webkit-border-before",
+    "webkit-border-end",
+    "webkit-border-start",
+    "webkit-columns",
+    "webkit-column-rule",
+    "webkit-flex-flow",
+    "webkit-flex",
+    "webkit-marginCollapse",
+    "webkit-marquee",
+    "webkit-mask",
+    "webkit-mask-position",
+    "webkit-mask-repeat",
+    "webkit-text-emphasis",
+    "webkit-text-stroke",
+    "webkit-transition",
+    "webkit-transform-origin"
+];
+
+var style = document.styleSheets[0].rules[0].style;
+function test(shorthand) {
+    var result = [];
+    style[shorthand] = "inherit";
+    result.push(style[shorthand]);
+    style[shorthand] = "initial";
+    result.push(style[shorthand]);
+    return result.join(", ");
+}
+
+for (var i = 0; i < shorthandNames.length; ++i) {
+    shouldBeEqualToString("test('" + shorthandNames[i] + "')", "inherit, initial");
+}
+</script>

Modified: trunk/LayoutTests/fast/css/parsing-text-emphasis-expected.txt (135847 => 135848)


--- trunk/LayoutTests/fast/css/parsing-text-emphasis-expected.txt	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/LayoutTests/fast/css/parsing-text-emphasis-expected.txt	2012-11-27 12:39:56 UTC (rev 135848)
@@ -36,8 +36,8 @@
 PASS: '-webkit-text-emphasis-style: "cheese" open;' parsed as ['', '', '', '']
 PASS: '-webkit-text-emphasis-style: open "cheese";' parsed as ['', '', '', '']
 
-PASS: '-webkit-text-emphasis: initial' parsed as ['', '', '', 'initial']
-PASS: '-webkit-text-emphasis: inherit' parsed as ['', '', '', 'inherit']
+PASS: '-webkit-text-emphasis: initial' parsed as ['initial', '', 'initial', 'initial']
+PASS: '-webkit-text-emphasis: inherit' parsed as ['inherit', '', 'inherit', 'inherit']
 PASS: '-webkit-text-emphasis: red' parsed as ['red', '', 'initial', 'red']
 PASS: '-webkit-text-emphasis: "cheese"' parsed as ['initial', '', 'cheese', 'cheese']
 PASS: '-webkit-text-emphasis: red "cheese"' parsed as ['red', '', 'cheese', 'cheese red']

Modified: trunk/LayoutTests/fast/css/parsing-text-emphasis.html (135847 => 135848)


--- trunk/LayoutTests/fast/css/parsing-text-emphasis.html	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/LayoutTests/fast/css/parsing-text-emphasis.html	2012-11-27 12:39:56 UTC (rev 135848)
@@ -67,8 +67,8 @@
     test('-webkit-text-emphasis-style: open "cheese";', '', '', '');
 
     log("");
-    test('-webkit-text-emphasis: initial', '', '', '', 'initial');
-    test('-webkit-text-emphasis: inherit', '', '', '', 'inherit');
+    test('-webkit-text-emphasis: initial', 'initial', '', 'initial', 'initial');
+    test('-webkit-text-emphasis: inherit', 'inherit', '', 'inherit', 'inherit');
     test('-webkit-text-emphasis: red', 'red', '', 'initial', 'red');
     test('-webkit-text-emphasis: "cheese"', 'initial', '', 'cheese', 'cheese');
     test('-webkit-text-emphasis: red "cheese"', 'red', '', 'cheese', 'cheese red');

Modified: trunk/Source/WebCore/ChangeLog (135847 => 135848)


--- trunk/Source/WebCore/ChangeLog	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/Source/WebCore/ChangeLog	2012-11-27 12:39:56 UTC (rev 135848)
@@ -1,3 +1,40 @@
+2012-11-27  Alexander Pavlov  <apav...@chromium.org>
+
+        Incorrect value of CSSStyleDeclaration#length when a shorthand property is inherit or initial
+        https://bugs.webkit.org/show_bug.cgi?id=73002
+
+        Reviewed by Alexis Menard.
+
+        Before the patch, "inherit" and "initial" shorthands would get added to the StylePropertySet as-is, their longhands unspecified.
+        This patch tackles two aspects of the problem:
+        - When parsing "initial" and "inherit" shorthands, their longhands are added to the property set with the corresponding values.
+        - When querying "initial" and "inherit" shorthands, their values are reconstructed from the longhands as usual, but if all of the longhands
+          are found to have the same explicit "initial" or "inherit" value, the respective single value is returned as the shorthand value.
+
+        When reconstructing shorthands, a "common value" is tracked. If all longhands involved have the same explicit value, it becomes the
+        "common value", otherwise it is a String(). The "inherit" or "initial" common value ultimately becomes the shorthand value
+        (except for the "background-position" shorthand, which is a special case).
+
+        * css/CSSParser.cpp:
+        (WebCore::parseKeywordValue): Parse shorthands' "initial" and "inherit" values using the CSSParser.
+        (WebCore::CSSParser::addExpandedPropertyForValue): Add simple property or all sharthand's longhands with given value and priority.
+        (WebCore::CSSParser::parseValue): For "initial" and "inherit" shorthands, add their longhands with the respective value, not the shorthands proper.
+        * css/CSSParser.h: Add addExpandedPropertyForValue().
+        * css/StylePropertySet.cpp:
+        (WebCore::isInitialOrInherit): Check if the value is "initial" or "inherit".
+        (WebCore):
+        (WebCore::StylePropertySet::appendFontLonghandValueIfExplicit): Modified to track the common value for the "font" shorthand.
+        (WebCore::StylePropertySet::fontValue): Ditto.
+        (WebCore::StylePropertySet::get4Values): Return "inherit" or "initial" if all 4 values are explicitly "inherit" or "initial".
+        (WebCore::StylePropertySet::getLayeredShorthandValue): Use the common value approach for layered shorthands.
+        (WebCore::StylePropertySet::getShorthandValue): Ditto for ordinary shorthands.
+        (WebCore::StylePropertySet::borderPropertyValue): Ditto for the "border" shorthand.
+        * css/StylePropertySet.h: Modify the appendFontLonghandValueIfExplicit() signature.
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::setFont): Now that "inherit" and "initial" shorthands are represented by their longhands,
+        we need to check the string value of the "font" shorthand for being "inherit" or "initial" instead: getPropertyCSSValue() no longer works,
+        since the shorthand itself is no longer added to the StylePropertySet.
+
 2012-11-27  Kentaro Hara  <hara...@chromium.org>
 
         Unreviewed. Renamed TRYCATCH => V8TRYCATCH.

Modified: trunk/Source/WebCore/css/CSSParser.cpp (135847 => 135848)


--- trunk/Source/WebCore/css/CSSParser.cpp	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/Source/WebCore/css/CSSParser.cpp	2012-11-27 12:39:56 UTC (rev 135848)
@@ -1086,9 +1086,17 @@
 {
     ASSERT(!string.isEmpty());
 
-    if (!isKeywordPropertyID(propertyId))
-        return false;
+    if (!isKeywordPropertyID(propertyId)) {
+        // All properties accept the values of "initial" and "inherit".
+        String lowerCaseString = string.lower();
+        if (lowerCaseString != "initial" && lowerCaseString != "inherit")
+            return false;
 
+        // Parse initial/inherit shorthands using the CSSParser.
+        if (shorthandForProperty(propertyId).length())
+            return false;
+    }
+
     CSSParserString cssString;
     cssString.init(string);
     int valueID = cssValueKeywordID(cssString);
@@ -1689,6 +1697,22 @@
     return 0;
 }
 
+void CSSParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue> prpValue, bool important)
+{
+    const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
+    unsigned shorthandLength = shorthand.length();
+    if (!shorthandLength) {
+        addProperty(propId, prpValue, important);
+        return;
+    }
+
+    RefPtr<CSSValue> value = prpValue;
+    ShorthandScope scope(this, propId);
+    const CSSPropertyID* longhands = shorthand.properties();
+    for (unsigned i = 0; i < shorthandLength; ++i)
+        addProperty(longhands[i], value, important);
+}
+
 bool CSSParser::parseValue(CSSPropertyID propId, bool important)
 {
     if (!m_valueList)
@@ -1710,13 +1734,13 @@
     if (id == CSSValueInherit) {
         if (num != 1)
             return false;
-        addProperty(propId, cssValuePool().createInheritedValue(), important);
+        addExpandedPropertyForValue(propId, cssValuePool().createInheritedValue(), important);
         return true;
     }
     else if (id == CSSValueInitial) {
         if (num != 1)
             return false;
-        addProperty(propId, cssValuePool().createExplicitInitialValue(), important);
+        addExpandedPropertyForValue(propId, cssValuePool().createExplicitInitialValue(), important);
         return true;
     }
 

Modified: trunk/Source/WebCore/css/CSSParser.h (135847 => 135848)


--- trunk/Source/WebCore/css/CSSParser.h	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/Source/WebCore/css/CSSParser.h	2012-11-27 12:39:56 UTC (rev 135848)
@@ -92,6 +92,7 @@
     void addProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
     void rollbackLastProperties(int num);
     bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
+    void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue>, bool);
 
     bool parseValue(CSSPropertyID, bool important);
     bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);

Modified: trunk/Source/WebCore/css/StylePropertySet.cpp (135847 => 135848)


--- trunk/Source/WebCore/css/StylePropertySet.cpp	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/Source/WebCore/css/StylePropertySet.cpp	2012-11-27 12:39:56 UTC (rev 135848)
@@ -60,6 +60,13 @@
     return sizeof(ImmutableStylePropertySet) - sizeof(void*) + sizeof(CSSValue*) * count + sizeof(StylePropertyMetadata) * count;
 }
 
+static bool isInitialOrInherit(const String& value)
+{
+    DEFINE_STATIC_LOCAL(String, initial, ("initial"));
+    DEFINE_STATIC_LOCAL(String, inherit, ("inherit"));
+    return value.length() == 7 && (value == initial || value == inherit);
+}
+
 PassRefPtr<StylePropertySet> StylePropertySet::createImmutable(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
 {
     void* slot = WTF::fastMalloc(sizeForImmutableStylePropertySetWithPropertyCount(count));
@@ -218,14 +225,16 @@
     return horizontalValueCSSText + ' ' + verticalValueCSSText;
 }
 
-bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID, StringBuilder& result) const
+bool StylePropertySet::appendFontLonghandValueIfExplicit(CSSPropertyID propertyID, StringBuilder& result, String& commonValue) const
 {
     int foundPropertyIndex = findPropertyIndex(propertyID);
     if (foundPropertyIndex == -1)
         return false; // All longhands must have at least implicit values if "font" is specified.
 
-    if (propertyAt(foundPropertyIndex).isImplicit())
+    if (propertyAt(foundPropertyIndex).isImplicit()) {
+        commonValue = String();
         return true;
+    }
 
     char prefix = '\0';
     switch (propertyID) {
@@ -245,7 +254,10 @@
 
     if (prefix && !result.isEmpty())
         result.append(prefix);
-    result.append(propertyAt(foundPropertyIndex).value()->cssText());
+    String value = propertyAt(foundPropertyIndex).value()->cssText();
+    result.append(value);
+    if (!commonValue.isNull() && commonValue != value)
+        commonValue = String();
 
     return true;
 }
@@ -260,22 +272,25 @@
     if (fontSizeProperty.isImplicit())
         return emptyString();
 
+    String commonValue = fontSizeProperty.value()->cssText();
     StringBuilder result;
     bool success = true;
-    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result);
-    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result);
-    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result);
+    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontStyle, result, commonValue);
+    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontVariant, result, commonValue);
+    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontWeight, result, commonValue);
     if (!result.isEmpty())
         result.append(' ');
     result.append(fontSizeProperty.value()->cssText());
-    success &= appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result);
-    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontFamily, result);
+    success &= appendFontLonghandValueIfExplicit(CSSPropertyLineHeight, result, commonValue);
+    success &= appendFontLonghandValueIfExplicit(CSSPropertyFontFamily, result, commonValue);
     if (!success) {
         // An invalid "font" value has been built (should never happen, as at least implicit values
         // for mandatory longhands are always found in the style), report empty value instead.
         ASSERT_NOT_REACHED();
         return emptyString();
     }
+    if (isInitialOrInherit(commonValue))
+        return commonValue;
     return result.toString();
 }
 
@@ -298,8 +313,17 @@
     // All 4 properties must be specified.
     if (!top.value() || !right.value() || !bottom.value() || !left.value())
         return String();
-    if (top.value()->isInitialValue() || right.value()->isInitialValue() || bottom.value()->isInitialValue() || left.value()->isInitialValue())
+
+    if (top.isInherited() && right.isInherited() && bottom.isInherited() && left.isInherited())
+        return getValueName(CSSValueInherit);
+
+    if (top.value()->isInitialValue() || right.value()->isInitialValue() || bottom.value()->isInitialValue() || left.value()->isInitialValue()) {
+        if (top.value()->isInitialValue() && right.value()->isInitialValue() && bottom.value()->isInitialValue() && left.value()->isInitialValue() && !top.isImplicit()) {
+            // All components are "initial" and "top" is not implicit.
+            return getValueName(CSSValueInitial);
+        }
         return String();
+    }
     if (top.isImportant() != right.isImportant() || right.isImportant() != bottom.isImportant() || bottom.isImportant() != left.isImportant())
         return String();
 
@@ -344,6 +368,9 @@
         }
     }
 
+    String commonValue;
+    bool commonValueInitialized = false;
+
     // Now stitch the properties together.  Implicit initial values are flagged as such and
     // can safely be omitted.
     for (size_t i = 0; i < numLayers; i++) {
@@ -400,6 +427,7 @@
                 }
             }
 
+            String valueText;
             if (value && !value->isImplicitInitialValue()) {
                 if (!layerResult.isEmpty())
                     layerResult.append(' ');
@@ -414,15 +442,28 @@
                 } else if (useRepeatYShorthand) {
                     useRepeatYShorthand = false;
                     layerResult.append(getValueName(CSSValueRepeatY));
-                } else if (useSingleWordShorthand) {
-                    useSingleWordShorthand = false;
-                    layerResult.append(value->cssText());
-                } else
-                    layerResult.append(value->cssText());
+                } else {
+                    if (useSingleWordShorthand)
+                        useSingleWordShorthand = false;
+                    valueText = value->cssText();
+                    layerResult.append(valueText);
+                }
 
-                if (shorthand.properties()[j] == CSSPropertyBackgroundPositionY)
+                if (shorthand.properties()[j] == CSSPropertyBackgroundPositionY) {
                     foundBackgroundPositionYCSSProperty = true;
+
+                    // background-position is a special case: if only the first offset is specified,
+                    // the second one defaults to "center", not the same value.
+                    if (commonValueInitialized && commonValue != "initial" && commonValue != "inherit")
+                        commonValue = String();
+                }
             }
+
+            if (!commonValueInitialized) {
+                commonValue = valueText;
+                commonValueInitialized = true;
+            } else if (!commonValue.isNull() && commonValue != valueText)
+                commonValue = String();
         }
 
         if (!layerResult.isEmpty()) {
@@ -431,6 +472,10 @@
             result.append(layerResult);
         }
     }
+
+    if (isInitialOrInherit(commonValue))
+        return commonValue;
+
     if (result.isEmpty())
         return String();
     return result.toString();
@@ -438,19 +483,28 @@
 
 String StylePropertySet::getShorthandValue(const StylePropertyShorthand& shorthand) const
 {
+    String commonValue;
     StringBuilder result;
     for (unsigned i = 0; i < shorthand.length(); ++i) {
         if (!isPropertyImplicit(shorthand.properties()[i])) {
             RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i]);
             if (!value)
                 return String();
+            String valueText = value->cssText();
+            if (!i)
+                commonValue = valueText;
+            else if (!commonValue.isNull() && commonValue != valueText)
+                commonValue = String();
             if (value->isInitialValue())
                 continue;
             if (!result.isEmpty())
                 result.append(' ');
-            result.append(value->cssText());
-        }
+            result.append(valueText);
+        } else
+            commonValue = String();
     }
+    if (isInitialOrInherit(commonValue))
+        return commonValue;
     if (result.isEmpty())
         return String();
     return result.toString();
@@ -485,6 +539,7 @@
 String StylePropertySet::borderPropertyValue(CommonValueMode valueMode) const
 {
     const StylePropertyShorthand properties[3] = { borderWidthShorthand(), borderStyleShorthand(), borderColorShorthand() };
+    String commonValue;
     StringBuilder result;
     for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
         String value = getCommonValue(properties[i]);
@@ -494,12 +549,18 @@
             ASSERT(valueMode == OmitUncommonValues);
             continue;
         }
+        if (!i)
+            commonValue = value;
+        else if (!commonValue.isNull() && commonValue != value)
+            commonValue = String();
         if (value == "initial")
             continue;
         if (!result.isEmpty())
             result.append(' ');
         result.append(value);
     }
+    if (isInitialOrInherit(commonValue))
+        return commonValue;
     return result.isEmpty() ? String() : result.toString();
 }
 

Modified: trunk/Source/WebCore/css/StylePropertySet.h (135847 => 135848)


--- trunk/Source/WebCore/css/StylePropertySet.h	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/Source/WebCore/css/StylePropertySet.h	2012-11-27 12:39:56 UTC (rev 135848)
@@ -197,7 +197,7 @@
     String get4Values(const StylePropertyShorthand&) const;
     String borderSpacingValue(const StylePropertyShorthand&) const;
     String fontValue() const;
-    bool appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result) const;
+    bool appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const;
 
     bool removeShorthandProperty(CSSPropertyID);
     bool propertyMatches(const PropertyReference&) const;

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (135847 => 135848)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2012-11-27 12:18:48 UTC (rev 135847)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2012-11-27 12:39:56 UTC (rev 135848)
@@ -2070,8 +2070,11 @@
     if (parsedStyle->isEmpty())
         return;
 
-    RefPtr<CSSValue> fontValue = parsedStyle->getPropertyCSSValue(CSSPropertyFont);
-    if (fontValue && fontValue->isInheritedValue())
+    String fontValue = parsedStyle->getPropertyValue(CSSPropertyFont);
+
+    // According to http://lists.w3.org/Archives/Public/public-html/2009Jul/0947.html,
+    // the "inherit" and "initial" values must be ignored.
+    if (fontValue == "inherit" || fontValue == "initial")
         return;
 
     // The parse succeeded.
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to