Validate CSS Device Adaptation properties and resolve shorthands
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Nov 2012 12:47:46 +0000 (12:47 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Nov 2012 12:47:46 +0000 (12:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=95962

Patch by Thiago Marcos P. Santos <thiago.santos@intel.com> on 2012-11-05
Reviewed by Alexis Menard.

Source/WebCore:

Add the missing keywords and properties for the viewport at-rule.
Note that we have to mark that we are inside a viewport scope because
some properties are not validated as they would be inside a style
rule. As an example, the semantics of CSSPropertyWidth are completely
different: on a viewport rule, it stands for a shorthand for the
minimum and maximum width.

Test: css3/device-adapt/viewport-properties-validation.html

* css/CSSComputedStyleDeclaration.cpp:
(WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
* css/CSSParser.cpp:
(WebCore::CSSParser::parseValue):
(WebCore):
(WebCore::CSSParser::parseViewportProperty):
(WebCore::CSSParser::parseViewportShorthand):
* css/CSSParser.h:
* css/CSSProperty.cpp:
(WebCore::CSSProperty::isInheritedProperty):
* css/CSSPropertyNames.in:
* css/CSSValueKeywords.in:

LayoutTests:

Added a test for CSS Device Adaptation property parsing validation.

* css3/device-adapt/viewport-properties-validation-expected.txt: Added.
* css3/device-adapt/viewport-properties-validation.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/css3/device-adapt/viewport-properties-validation-expected.txt [new file with mode: 0644]
LayoutTests/css3/device-adapt/viewport-properties-validation.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSComputedStyleDeclaration.cpp
Source/WebCore/css/CSSParser.cpp
Source/WebCore/css/CSSParser.h
Source/WebCore/css/CSSProperty.cpp
Source/WebCore/css/CSSPropertyNames.in
Source/WebCore/css/CSSValueKeywords.in

index f9e9753..affe3dd 100644 (file)
@@ -1,3 +1,15 @@
+2012-11-05  Thiago Marcos P. Santos  <thiago.santos@intel.com>
+
+        Validate CSS Device Adaptation properties and resolve shorthands
+        https://bugs.webkit.org/show_bug.cgi?id=95962
+
+        Reviewed by Alexis Menard.
+
+        Added a test for CSS Device Adaptation property parsing validation.
+
+        * css3/device-adapt/viewport-properties-validation-expected.txt: Added.
+        * css3/device-adapt/viewport-properties-validation.html: Added.
+
 2012-11-05  Raphael Kubo da Costa  <raphael.kubo.da.costa@intel.com>
 
         [EFL] Unreviewed gardening.
diff --git a/LayoutTests/css3/device-adapt/viewport-properties-validation-expected.txt b/LayoutTests/css3/device-adapt/viewport-properties-validation-expected.txt
new file mode 100644 (file)
index 0000000..945e5c7
--- /dev/null
@@ -0,0 +1,12 @@
+
+PASS Rule with no attributes 
+PASS Shorthands with double value 
+PASS Shorthands with single value 
+PASS Shorthands should override properties if defined later 
+PASS All valid properties with valid intial values 
+PASS All valid properties with valid values 
+PASS All valid properties with invalid intial values 
+PASS Negative numbers should be dropped on zoom attribute 
+PASS Viewport attributes inside selectors should be dropped 
+PASS Invalid attributes among valid should be dropped 
+
diff --git a/LayoutTests/css3/device-adapt/viewport-properties-validation.html b/LayoutTests/css3/device-adapt/viewport-properties-validation.html
new file mode 100644 (file)
index 0000000..3490cbf
--- /dev/null
@@ -0,0 +1,200 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style type="text/css">
+        /* Valid viewport syntax with no properties. */
+        @-webkit-viewport {
+        }
+
+        /* Shorthands should be evaluated to the respective attributes. */
+        @-webkit-viewport {
+            width: 400px 500px;
+            height: 200px 300px;
+        }
+
+        /* Shorthands with single value should assume this value for min and max. */
+        @-webkit-viewport {
+            width: 500px;
+            height: 300px;
+        }
+
+        /* Shorthands should override properties if defined later. */
+        @-webkit-viewport {
+            min-width: 100px;
+            min-width: 100px;
+            max-height: 100px;
+            max-height: 100px;
+            width: 500px;
+            height: 300px;
+        }
+
+        /* All valid properties with valid initial values. */
+        @-webkit-viewport {
+            min-width: auto;
+            max-width: auto;
+            min-height: auto;
+            max-height: auto;
+            min-zoom: auto;
+            max-zoom: auto;
+            orientation: auto;
+            user-zoom: zoom;
+            zoom: auto;
+        }
+
+        /* All valid properties with valid values. */
+        @-webkit-viewport {
+            min-width: 50%;
+            max-width: 100px;
+            min-height: device-width;
+            max-height: device-height;
+            min-zoom: 50%;
+            max-zoom: 0.5;
+            orientation: landscape;
+            user-zoom: fixed;
+            zoom: 0.6;
+        }
+
+        /* All valid properties with invalid initial values. Should be empty. */
+        @-webkit-viewport {
+            min-width: zoom;
+            max-width: fixed;
+            min-height: landscape;
+            max-height: portrait;
+            min-zoom: 10px;
+            max-zoom: 50px;
+            orientation: 50%;
+            user-zoom: auto;
+            zoom: device-height;
+        }
+
+        /* Negative numbers should be dropped on zoom. */
+        @-webkit-viewport {
+            min-zoom: -1;
+            max-zoom: -0.5;
+            zoom: -0.6;
+        }
+
+        /* Viewport attributes inside selectors should be dropped. */
+        .foo {
+            min-zoom: auto;
+            max-zoom: auto;
+            orientation: auto;
+            user-zoom: zoom;
+            zoom: auto;
+        }
+
+        /* Invalid attributes among valid should be dropped. */
+        @-webkit-viewport {
+            font-family: sans-serif;
+            min-width: device-width;
+            max-width: device-height;
+            foo: auto;
+            min-height: 500px;
+            max-height: 50%;
+            text-indent: 0;
+            min-zoom: 0.5;
+            max-zoom: 50%;
+            orientation: portrait;
+            color: red;
+            user-zoom: zoom;
+            zoom: 60%;
+            letter-spacing: 0.5em;
+        }
+    </style>
+    <meta charset="utf-8" />
+    <link rel="help" href="http://www.w3.org/TR/css-device-adapt/#syntax" />
+    <script src="../../resources/testharness.js"></script>
+    <script src="../../resources/testharnessreport.js"></script>
+    <script type="text/javascript">
+        var rules = document.styleSheets[0].cssRules;
+
+        test(function() {
+            assert_equals(rules.item(0).cssText, "@-webkit-viewport { }");
+        }, "Rule with no attributes");
+
+        test(function() {
+            assert_equals(rules.item(1).cssText,
+                "@-webkit-viewport {" +
+                " min-width: 400px;" +
+                " max-width: 500px;" +
+                " min-height: 200px;" +
+                " max-height: 300px; }");
+        }, "Shorthands with double value");
+
+        test(function() {
+            assert_equals(rules.item(2).cssText,
+                "@-webkit-viewport {" +
+                " min-width: 500px;" +
+                " max-width: 500px;" +
+                " min-height: 300px;" +
+                " max-height: 300px; }");
+        }, "Shorthands with single value");
+
+        test(function() {
+            assert_equals(rules.item(3).cssText,
+                "@-webkit-viewport {" +
+                " min-width: 500px;" +
+                " max-width: 500px;" +
+                " min-height: 300px;" +
+                " max-height: 300px; }");
+        }, "Shorthands should override properties if defined later");
+
+        test(function() {
+            assert_equals(rules.item(4).cssText,
+                "@-webkit-viewport {" +
+                " min-width: auto;" +
+                " max-width: auto;" +
+                " min-height: auto;" +
+                " max-height: auto;" +
+                " min-zoom: auto;" +
+                " max-zoom: auto;" +
+                " orientation: auto;" +
+                " user-zoom: zoom;" +
+                " zoom: auto; }");
+        }, "All valid properties with valid intial values");
+
+        test(function() {
+            assert_equals(rules.item(5).cssText,
+                "@-webkit-viewport {" +
+                " min-width: 50%;" +
+                " max-width: 100px;" +
+                " min-height: device-width;" +
+                " max-height: device-height;" +
+                " min-zoom: 50%;" +
+                " max-zoom: 0.5;" +
+                " orientation: landscape;" +
+                " user-zoom: fixed;" +
+                " zoom: 0.6; }");
+        }, "All valid properties with valid values");
+
+        test(function() {
+            assert_equals(rules.item(6).cssText, "@-webkit-viewport { }");
+        }, "All valid properties with invalid intial values");
+
+        test(function() {
+            assert_equals(rules.item(7).cssText, "@-webkit-viewport { }");
+        }, "Negative numbers should be dropped on zoom attribute");
+
+        test(function() {
+            assert_equals(rules.item(8).cssText, ".foo { }");
+        }, "Viewport attributes inside selectors should be dropped");
+
+        test(function() {
+            assert_equals(rules.item(9).cssText,
+                "@-webkit-viewport {" +
+                " min-width: device-width;" +
+                " max-width: device-height;" +
+                " min-height: 500px;" +
+                " max-height: 50%;" +
+                " min-zoom: 0.5;" +
+                " max-zoom: 50%;" +
+                " orientation: portrait;" +
+                " user-zoom: zoom;" +
+                " zoom: 60%; }");
+        }, "Invalid attributes among valid should be dropped");
+    </script>
+</head>
+<body>
+    <div id="log"></div>
+</body>
+</html>
index 479bdeb..fa7d0f0 100644 (file)
@@ -1,3 +1,32 @@
+2012-11-05  Thiago Marcos P. Santos  <thiago.santos@intel.com>
+
+        Validate CSS Device Adaptation properties and resolve shorthands
+        https://bugs.webkit.org/show_bug.cgi?id=95962
+
+        Reviewed by Alexis Menard.
+
+        Add the missing keywords and properties for the viewport at-rule.
+        Note that we have to mark that we are inside a viewport scope because
+        some properties are not validated as they would be inside a style
+        rule. As an example, the semantics of CSSPropertyWidth are completely
+        different: on a viewport rule, it stands for a shorthand for the
+        minimum and maximum width.
+
+        Test: css3/device-adapt/viewport-properties-validation.html
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue):
+        * css/CSSParser.cpp:
+        (WebCore::CSSParser::parseValue):
+        (WebCore):
+        (WebCore::CSSParser::parseViewportProperty):
+        (WebCore::CSSParser::parseViewportShorthand):
+        * css/CSSParser.h:
+        * css/CSSProperty.cpp:
+        (WebCore::CSSProperty::isInheritedProperty):
+        * css/CSSPropertyNames.in:
+        * css/CSSValueKeywords.in:
+
 2012-11-05  Sheriff Bot  <webkit.review.bot@gmail.com>
 
         Unreviewed, rolling out r133286, r133385, and r133394.
index 3af8785..1e6d207 100644 (file)
@@ -2649,6 +2649,14 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropert
 #endif
             break;
 
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+        case CSSPropertyMaxZoom:
+        case CSSPropertyMinZoom:
+        case CSSPropertyOrientation:
+        case CSSPropertyUserZoom:
+            break;
+#endif
+
 #if ENABLE(SVG)
         case CSSPropertyClipPath:
         case CSSPropertyClipRule:
index 5a29d2f..b161aec 100644 (file)
@@ -6,6 +6,7 @@
  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
  * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
  * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -1729,6 +1730,11 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
         return true;
     }
 
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    if (inViewport())
+        return parseViewportProperty(propId, important);
+#endif
+
     bool validPrimitive = false;
     RefPtr<CSSValue> parsedValue;
 
@@ -2856,6 +2862,17 @@ bool CSSParser::parseValue(CSSPropertyID propId, bool important)
         // These properties should be handled before in isValidKeywordPropertyAndValue().
         ASSERT_NOT_REACHED();
         return false;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    // Properties bellow are validated inside parseViewportProperty, because we
+    // check for parser state inViewportScope. We need to invalidate if someone
+    // adds them outside a @viewport rule.
+    case CSSPropertyMaxZoom:
+    case CSSPropertyMinZoom:
+    case CSSPropertyOrientation:
+    case CSSPropertyUserZoom:
+        validPrimitive = false;
+        break;
+#endif
 #if ENABLE(SVG)
     default:
         return parseSVGValue(propId, important);
@@ -10417,6 +10434,84 @@ StyleRuleBase* CSSParser::createViewportRule()
 
     return result;
 }
+
+bool CSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
+{
+    CSSParserValue* value = m_valueList->current();
+    if (!value)
+        return false;
+
+    int id = value->id;
+    bool validPrimitive = false;
+
+    switch (propId) {
+    case CSSPropertyMinWidth: // auto | device-width | device-height | <length> | <percentage>
+    case CSSPropertyMaxWidth:
+    case CSSPropertyMinHeight:
+    case CSSPropertyMaxHeight:
+        if (id == CSSValueAuto || id == CSSValueDeviceWidth || id == CSSValueDeviceHeight)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+        break;
+    case CSSPropertyWidth: // shorthand
+        return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
+    case CSSPropertyHeight:
+        return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
+    case CSSPropertyMinZoom: // auto | <number> | <percentage>
+    case CSSPropertyMaxZoom:
+    case CSSPropertyZoom:
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
+        break;
+    case CSSPropertyUserZoom: // zoom | fixed
+        if (id == CSSValueZoom || id == CSSValueFixed)
+            validPrimitive = true;
+        break;
+    case CSSPropertyOrientation: // auto | portrait | landscape
+        if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
+            validPrimitive = true;
+    default:
+        break;
+    }
+
+    RefPtr<CSSValue> parsedValue;
+    if (validPrimitive) {
+        parsedValue = parseValidPrimitive(id, value);
+        m_valueList->next();
+    }
+
+    if (parsedValue) {
+        if (!m_valueList->current() || inShorthand()) {
+            addProperty(propId, parsedValue.release(), important);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool CSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
+{
+    unsigned numValues = m_valueList->size();
+
+    if (numValues > 2)
+        return false;
+
+    ShorthandScope scope(this, propId);
+
+    if (!parseViewportProperty(first, important))
+        return false;
+
+    // If just one value is supplied, the second value
+    // is implicitly initialized with the first value.
+    if (numValues == 1)
+        m_valueList->previous();
+
+    return parseViewportProperty(second, important);
+}
 #endif
 
 template <typename CharacterType>
index 635648b..2c31794 100644 (file)
@@ -524,6 +524,9 @@ private:
     bool m_allowNamespaceDeclarations;
 
 #if ENABLE(CSS_DEVICE_ADAPTATION)
+    bool parseViewportProperty(CSSPropertyID propId, bool important);
+    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
+
     bool inViewport() const { return m_inViewport; }
     bool m_inViewport;
 #endif
index 02aa5ba..79be67b 100644 (file)
@@ -681,6 +681,12 @@ bool CSSProperty::isInheritedProperty(CSSPropertyID propertyID)
 #if ENABLE(DRAGGABLE_REGION)
     case CSSPropertyWebkitAppRegion:
 #endif
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+    case CSSPropertyMaxZoom:
+    case CSSPropertyMinZoom:
+    case CSSPropertyOrientation:
+    case CSSPropertyUserZoom:
+#endif
         return false;
     case CSSPropertyInvalid:
         ASSERT_NOT_REACHED();
index 8776e04..7f699e3 100644 (file)
@@ -402,6 +402,12 @@ z-index
 -webkit-wrap-through
 -webkit-wrap
 #endif
+#if defined(ENABLE_CSS_DEVICE_ADAPTATION) && ENABLE_CSS_DEVICE_ADAPTATION
+max-zoom
+min-zoom
+orientation
+user-zoom
+#endif
 #if defined(ENABLE_TOUCH_EVENTS) && ENABLE_TOUCH_EVENTS
 -webkit-tap-highlight-color
 #endif
index 2c1702a..4b9cc6e 100644 (file)
@@ -775,6 +775,24 @@ step-end
 document
 reset
 
+#if defined(ENABLE_CSS_DEVICE_ADAPTATION) && ENABLE_CSS_DEVICE_ADAPTATION
+//
+// CSS_PROP_USER_ZOOM
+//
+// fixed
+zoom
+
+//
+// CSS_PROP_MIN_WIDTH
+// CSS_PROP_MAX_WIDTH
+// CSS_PROP_MIN_HEIGHT
+// CSS_PROP_MAX_HEIGHT
+//
+// auto
+device-width
+device-height
+#endif
+
 //
 // CSS_PROP_POINTER_EVENTS
 //