Fix for style regression caused by strictness checking of the number of prope...
authorhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Jan 2007 22:45:42 +0000 (22:45 +0000)
committerhyatt <hyatt@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 26 Jan 2007 22:45:42 +0000 (22:45 +0000)
        "width: 20 px" to fail, because we interpreted it as two values and rejected it.  Our old code allowed 20 to be
        used like a pixel value and then ignored the orphaned unit.

        This patch actually scans the list of values looking for orphaned units and reattaches them to the numeric
        values that they should correspond to.  This means rules like "width: 5 em" will now work in quirks mdoe and
        the "em" unit type will be honored.

        Reviewed by beth

        * WebCore.xcodeproj/project.pbxproj:
        * css/cssparser.cpp:
        (WebCore::unitFromString):
        (WebCore::CSSParser::checkForOrphanedUnits):
        (WebCore::CSSParser::parseValue):
        * css/cssparser.h:
        (WebCore::ValueList::valueAt):
        (WebCore::ValueList::deleteValueAt):

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

WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/css/cssparser.cpp
WebCore/css/cssparser.h

index b33900b..7bdecb5 100644 (file)
@@ -1,3 +1,24 @@
+2007-01-26  David Hyatt  <hyatt@apple.com>
+
+        Fix for style regression caused by strictness checking of the number of properties.  This caused code like:
+        "width: 20 px" to fail, because we interpreted it as two values and rejected it.  Our old code allowed 20 to be
+        used like a pixel value and then ignored the orphaned unit.
+
+        This patch actually scans the list of values looking for orphaned units and reattaches them to the numeric
+        values that they should correspond to.  This means rules like "width: 5 em" will now work in quirks mdoe and
+        the "em" unit type will be honored.
+
+        Reviewed by beth
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * css/cssparser.cpp:
+        (WebCore::unitFromString):
+        (WebCore::CSSParser::checkForOrphanedUnits):
+        (WebCore::CSSParser::parseValue):
+        * css/cssparser.h:
+        (WebCore::ValueList::valueAt):
+        (WebCore::ValueList::deleteValueAt):
+
 2007-01-26  George Staikos  <staikos@kde.org>
 
         Reviewed by Zack.
 2007-01-26  George Staikos  <staikos@kde.org>
 
         Reviewed by Zack.
index 180eafb..fa24e0e 100644 (file)
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
                0867D690FE84028FC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
-                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        knownRegions = (
                                English,
                        hasScannedForEncodings = 1;
                        knownRegions = (
                                English,
                        productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
                        projectDirPath = "";
                        projectRoot = "";
                        productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
                        projectDirPath = "";
                        projectRoot = "";
-                       shouldCheckCompatibility = 1;
                        targets = (
                                93F198A508245E59001E9ABC /* WebCore */,
                                DD041FBE09D9DDBE0010AF2A /* Derived Sources */,
                        targets = (
                                93F198A508245E59001E9ABC /* WebCore */,
                                DD041FBE09D9DDBE0010AF2A /* Derived Sources */,
index a0098c8..9e24e72 100644 (file)
@@ -421,6 +421,76 @@ bool CSSParser::validUnit(Value* value, Units unitflags, bool strict)
     return b;
 }
 
     return b;
 }
 
+static int unitFromString(Value* value)
+{
+    if (value->unit != CSSPrimitiveValue::CSS_IDENT || value->id)
+        return 0;
+
+    String str = domString(value->string);
+    if (str == "em")
+        return CSSPrimitiveValue::CSS_EMS;
+    if (str == "ex")
+        return CSSPrimitiveValue::CSS_EXS;
+    if (str == "px")
+        return CSSPrimitiveValue::CSS_PX;
+    if (str == "cm")
+        return CSSPrimitiveValue::CSS_CM;
+    if (str == "mm")
+        return CSSPrimitiveValue::CSS_MM;
+    if (str == "in")
+        return CSSPrimitiveValue::CSS_IN;
+    if (str == "pt")
+        return CSSPrimitiveValue::CSS_PT;
+    if (str == "pc")
+        return CSSPrimitiveValue::CSS_PC;
+    if (str == "deg")
+        return CSSPrimitiveValue::CSS_DEG;
+    if (str == "rad")
+        return CSSPrimitiveValue::CSS_RAD;
+    if (str == "grad")
+        return CSSPrimitiveValue::CSS_GRAD;
+    if (str == "ms")
+        return CSSPrimitiveValue::CSS_MS;
+    if (str == "s")
+        return CSSPrimitiveValue::CSS_S;
+    if (str == "Hz")
+        return CSSPrimitiveValue::CSS_HZ;
+    if (str == "kHz")
+        return CSSPrimitiveValue::CSS_KHZ;
+    
+    return 0;
+}
+
+void CSSParser::checkForOrphanedUnits()
+{
+    if (strict || inShorthand())
+        return;
+        
+    // The purpose of this code is to implement the WinIE quirk that allows unit types to be separated from their numeric values
+    // by whitespace, so e.g., width: 20 px instead of width:20px.  This is invalid CSS, so we don't do this in strict mode.
+    Value* numericVal = 0;
+    unsigned size = valueList->size();
+    for (unsigned i = 0; i < size; i++) {
+        Value* value = valueList->valueAt(i);
+        if (numericVal) {
+            // Change the unit type of the numeric val to match.
+            int unit = unitFromString(value);
+            if (unit) {
+                numericVal->unit = unit;
+                numericVal = 0;
+
+                // Now delete the bogus unit value.
+                valueList->deleteValueAt(i);
+                i--; // We're safe even though |i| is unsigned, since we only hit this code if we had a previous numeric value (so |i| is always > 0 here).
+                size--;
+                continue;
+            }
+        }
+        
+        numericVal = (value->unit == CSSPrimitiveValue::CSS_NUMBER) ? value : 0;
+    }
+}
+
 bool CSSParser::parseValue(int propId, bool important)
 {
     if (!valueList)
 bool CSSParser::parseValue(int propId, bool important)
 {
     if (!valueList)
@@ -451,6 +521,10 @@ bool CSSParser::parseValue(int propId, bool important)
     bool valid_primitive = false;
     CSSValue *parsedValue = 0;
 
     bool valid_primitive = false;
     CSSValue *parsedValue = 0;
 
+    // In quirks mode, we will look for units that have been incorrectly separated from the number they belong to
+    // by a space.  We go ahead and associate the unit with the number even though it is invalid CSS.
+    checkForOrphanedUnits();
+
     switch(propId) {
         /* The comment to the left defines all valid value of this properties as defined
          * in CSS 2, Appendix F. Property index
     switch(propId) {
         /* The comment to the left defines all valid value of this properties as defined
          * in CSS 2, Appendix F. Property index
index 4596122..e45b910 100644 (file)
@@ -94,6 +94,9 @@ namespace WebCore {
         Value* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
         Value* next() { ++m_current; return current(); }
 
         Value* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
         Value* next() { ++m_current; return current(); }
 
+        Value* valueAt(unsigned i) { return i < m_values.size() ? &m_values[i] : 0; }
+        void deleteValueAt(unsigned i) { m_values.remove(i); }
+
     private:
         Vector<Value, 16> m_values;
         unsigned m_current;
     private:
         Vector<Value, 16> m_values;
         unsigned m_current;
@@ -234,6 +237,8 @@ namespace WebCore {
 
         bool inShorthand() const { return m_inParseShorthand; }
 
 
         bool inShorthand() const { return m_inParseShorthand; }
 
+        void checkForOrphanedUnits();
+        
         UChar* data;
         UChar* yytext;
         UChar* yy_c_buf_p;
         UChar* data;
         UChar* yytext;
         UChar* yy_c_buf_p;