2011-04-10 Mike Lawther <mikelawther@chromium.org>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Apr 2011 02:31:42 +0000 (02:31 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Apr 2011 02:31:42 +0000 (02:31 +0000)
        Reviewed by Ojan Vafai.

        flex/bison tokens and grammar for CSS calc
        https://bugs.webkit.org/show_bug.cgi?id=54412

        Only the 'errors' and 'regression' tests pass as intended right now. As of this
        patch, none of the actual calculations are expected to work, since only
        the lexing/grammar stage is present.

        * css3/calc/calc-errors-expected.txt: Added.
        * css3/calc/calc-errors.html: Added.
        * css3/calc/lexer-regression-57581-2-expected.txt: Added.
        * css3/calc/lexer-regression-57581-2.html: Added.
        * css3/calc/lexer-regression-57581-3-expected.txt: Added.
        * css3/calc/lexer-regression-57581-3.html: Added.
        * css3/calc/lexer-regression-57581-expected.txt: Added.
        * css3/calc/lexer-regression-57581.html: Added.
        * css3/calc/minmax-errors-expected.txt: Added.
        * css3/calc/minmax-errors.html: Added.
        * css3/calc/simple-calcs-expected.txt: Added.
        * css3/calc/simple-calcs.html: Added.
        * css3/calc/simple-minmax-expected.txt: Added.
        * css3/calc/simple-minmax.html: Added.
2011-04-10  Mike Lawther  <mikelawther@chromium.org>

        Reviewed by Ojan Vafai.

        flex/bison tokens and grammar for CSS calc
        https://bugs.webkit.org/show_bug.cgi?id=54412

        Tests: css3/calc/calc-errors.html
               css3/calc/lexer-regression-57581-2.html
               css3/calc/lexer-regression-57581-3.html
               css3/calc/lexer-regression-57581.html
               css3/calc/minmax-errors.html
               css3/calc/nested-rounded-corners.html
               css3/calc/simple-calcs.html
               css3/calc/simple-minmax.html

        * css/CSSGrammar.y:
        * css/CSSParserValues.cpp:
        (WebCore::CSSParserValueList::insertValueAt):
        (WebCore::CSSParserValueList::extend):
        * css/CSSParserValues.h:
        * css/tokenizer.flex:

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

20 files changed:
LayoutTests/ChangeLog
LayoutTests/css3/calc/calc-errors-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/calc-errors.html [new file with mode: 0644]
LayoutTests/css3/calc/lexer-regression-57581-2-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/lexer-regression-57581-2.html [new file with mode: 0644]
LayoutTests/css3/calc/lexer-regression-57581-3-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/lexer-regression-57581-3.html [new file with mode: 0644]
LayoutTests/css3/calc/lexer-regression-57581-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/lexer-regression-57581.html [new file with mode: 0644]
LayoutTests/css3/calc/minmax-errors-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/minmax-errors.html [new file with mode: 0644]
LayoutTests/css3/calc/simple-calcs-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/simple-calcs.html [new file with mode: 0644]
LayoutTests/css3/calc/simple-minmax-expected.txt [new file with mode: 0644]
LayoutTests/css3/calc/simple-minmax.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/CSSGrammar.y
Source/WebCore/css/CSSParserValues.cpp
Source/WebCore/css/CSSParserValues.h
Source/WebCore/css/tokenizer.flex

index 91980b1..df0b4c5 100644 (file)
@@ -1,3 +1,29 @@
+2011-04-10  Mike Lawther  <mikelawther@chromium.org>
+
+        Reviewed by Ojan Vafai.
+
+        flex/bison tokens and grammar for CSS calc
+        https://bugs.webkit.org/show_bug.cgi?id=54412
+
+        Only the 'errors' and 'regression' tests pass as intended right now. As of this
+        patch, none of the actual calculations are expected to work, since only
+        the lexing/grammar stage is present.
+
+        * css3/calc/calc-errors-expected.txt: Added.
+        * css3/calc/calc-errors.html: Added.
+        * css3/calc/lexer-regression-57581-2-expected.txt: Added.
+        * css3/calc/lexer-regression-57581-2.html: Added.
+        * css3/calc/lexer-regression-57581-3-expected.txt: Added.
+        * css3/calc/lexer-regression-57581-3.html: Added.
+        * css3/calc/lexer-regression-57581-expected.txt: Added.
+        * css3/calc/lexer-regression-57581.html: Added.
+        * css3/calc/minmax-errors-expected.txt: Added.
+        * css3/calc/minmax-errors.html: Added.
+        * css3/calc/simple-calcs-expected.txt: Added.
+        * css3/calc/simple-calcs.html: Added.
+        * css3/calc/simple-minmax-expected.txt: Added.
+        * css3/calc/simple-minmax.html: Added.
+
 2011-04-10  Kent Tamura  <tkent@chromium.org>
 
         [Chromium] Update expectations for r83360.
diff --git a/LayoutTests/css3/calc/calc-errors-expected.txt b/LayoutTests/css3/calc/calc-errors-expected.txt
new file mode 100644 (file)
index 0000000..ec814f4
--- /dev/null
@@ -0,0 +1,53 @@
+All boxes below should be 100px * 100px and green.
+
+unclosed calc => PASS
+unclosed calc with garbage => PASS
+garbage => PASS
+zero division => PASS
+non length => PASS
+number + length => PASS
+length + number => PASS
+percent + number => PASS
+number + percent => PASS
+length - number => PASS
+number - length => PASS
+percent - number => PASS
+number - percent => PASS
+length * length => PASS
+length * percent => PASS
+percent * length => PASS
+percent * percent => PASS
+number / length => PASS
+number / percent => PASS
+length / length => PASS
+length / percent => PASS
+percent / length => PASS
+percent / percent => PASS
+number mod length => PASS
+number mod percent => PASS
+length mod length => PASS
+length mod percent => PASS
+percent mod length => PASS
+percent mod percent => PASS
+mod10 => PASS
+1mod => PASS
+70px+40px no whitespace around + => PASS
+70px +40px no whitespace on right of + => PASS
+70px+ 40px no whitespace on left of + => PASS
+70px+-40px no whitespace around + => PASS
+70px-40px no whitespace around - => PASS
+70px -40px no whitespace on right of - => PASS
+70px- 40px no whitespace on left of - => PASS
+70px-+40px no whitespace around - => PASS
+too many nests => PASS
+end with operator => PASS
+start with operator => PASS
+no expressions => PASS
+too many pluses => PASS
+no binary operator => PASS
+two binary operators => PASS
+invalid operator '@' => PASS
+invalid operator 'flim' => PASS
+invalid operator '@' => PASS
+invalid operator 'flim' => PASS
+invalid operator 'flim' with parens => PASS
diff --git a/LayoutTests/css3/calc/calc-errors.html b/LayoutTests/css3/calc/calc-errors.html
new file mode 100644 (file)
index 0000000..590c4e2
--- /dev/null
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML>
+<style>
+#test div {
+    height: 100px;
+    background-color: red;
+}
+</style>
+
+<p>
+  All boxes below should be 100px * 100px and green.
+</p>
+
+<div id="test">
+
+<!-- just plain bad -->
+<div style="width: 100px; width: -webkit-calc(;">unclosed calc</div>
+<div style="width: 100px; width: -webkit-calc( flim;">unclosed calc with garbage</div>
+<div style="width: 100px; width: -webkit-calc( flim );">garbage</div>
+
+
+<!-- zero division -->
+<div style="width: 100px; width: -webkit-calc(1ex / 0);">zero division</div>
+
+<!-- wrong combination -->
+<div style="width: 100px; width: -webkit-calc(200);">non length</div>
+<div style="width: 100px; width: -webkit-calc(10 + 10px);">number + length</div>
+<div style="width: 100px; width: -webkit-calc(10px + 10);">length + number</div>
+<div style="width: 100px; width: -webkit-calc(10% + 100);">percent + number</div>
+<div style="width: 100px; width: -webkit-calc(100 + 10%);">number + percent</div>
+
+<div style="width: 100px; width: -webkit-calc(300px - 100);">length - number</div>
+<div style="width: 100px; width: -webkit-calc(300 - 100px);">number - length</div>
+<div style="width: 100px; width: -webkit-calc(100% - 10);">percent - number</div>
+<div style="width: 100px; width: -webkit-calc(100 - 10%);">number - percent</div>
+
+<div style="width: 100px; width: -webkit-calc(10px*100px);">length * length</div>
+<div style="width: 100px; width: -webkit-calc(10px*100%);">length * percent</div>
+<div style="width: 100px; width: -webkit-calc(10%*100px);">percent * length</div>
+<div style="width: 100px; width: -webkit-calc(10%*100%);">percent * percent</div>
+
+<div style="width: 100px; width: -webkit-calc(100/10px);">number / length</div>
+<div style="width: 100px; width: -webkit-calc(100/10%);">number / percent</div>
+<div style="width: 100px; width: -webkit-calc(100px/10px);">length / length</div>
+<div style="width: 100px; width: -webkit-calc(100px/10%);">length / percent</div>
+<div style="width: 100px; width: -webkit-calc(100%/10px);">percent / length</div>
+<div style="width: 100px; width: -webkit-calc(100%/10%);">percent / percent</div>
+
+<div style="width: 100px; width: -webkit-calc(100 mod 10px);">number mod length</div>
+<div style="width: 100px; width: -webkit-calc(100 mod 10%);">number mod percent</div>
+<div style="width: 100px; width: -webkit-calc(100px mod 10px);">length mod length</div>
+<div style="width: 100px; width: -webkit-calc(100px mod 10%);">length mod percent</div>
+<div style="width: 100px; width: -webkit-calc(100% mod 10px);">percent mod length</div>
+<div style="width: 100px; width: -webkit-calc(100% mod 10%);">percent mod percent</div>
+
+<!-- mod, +, - require whitespaces around the operator -->
+<div style="width: 100px; width: -webkit-calc(1 mod10 * 200px);">mod10 </div>
+<div style="width: 100px; width: -webkit-calc(1mod 10 * 200px);">1mod</div>
+<div style="width: 100px; width: -webkit-calc(70px+40px);">70px+40px no whitespace around + </div>
+<div style="width: 100px; width: -webkit-calc(70px +40px);">70px +40px no whitespace on right of +</div>
+<div style="width: 100px; width: -webkit-calc(70px+ 40px);">70px+ 40px no whitespace on left of +</div>
+<div style="width: 100px; width: -webkit-calc(70px+-40px);">70px+-40px no whitespace around + </div>
+<div style="width: 100px; width: -webkit-calc(70px-40px);">70px-40px no whitespace around - </div>
+<div style="width: 100px; width: -webkit-calc(70px -40px);">70px -40px no whitespace on right of -</div>
+<div style="width: 100px; width: -webkit-calc(70px- 40px);">70px- 40px no whitespace on left of -</div>
+<div style="width: 100px; width: -webkit-calc(70px-+40px);">70px-+40px no whitespace around - </div>
+
+<!-- too many nests should be rejected to avoid stack overflow -->
+<div style="width: 100px; width: -webkit-calc(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((200px)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))));">too many nests</div>
+<!-- invalid formulas -->
+<div style="width: 100px; width: -webkit-calc(200px*);">end with operator</div>
+<div style="width: 100px; width: -webkit-calc(+ +200px);">start with operator</div>
+<div style="width: 100px; width: -webkit-calc();">no expressions</div>
+<div style="width: 100px; width: -webkit-calc(100px + + +100px);">too many pluses</div>
+<div style="width: 100px; width: -webkit-calc(200px 200px);">no binary operator</div>
+<div style="width: 100px; width: -webkit-calc(100px * * 2);">two binary operators</div>
+<div style="width: 100px; width: -webkit-calc(100px @ 2);">invalid operator '@'</div>
+<div style="width: 100px; width: -webkit-calc(1 flim 2);">invalid operator 'flim'</div>
+<div style="width: 100px; width: -webkit-calc(100px @ 2);">invalid operator '@'</div>
+<div style="width: 100px; width: -webkit-calc(1 flim 2);">invalid operator 'flim'</div>
+<div style="width: 100px; width: -webkit-calc(1 flim (2));">invalid operator 'flim' with parens</div>
+</div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var test = document.getElementById("test");
+for (var element = test.firstChild; element; element = element.nextSibling) {
+    var width = element.offsetWidth;
+    var error = [];
+    if (width != 100)
+        error.push("expected width of 100, but was " + width);
+    var height = element.offsetHeight;
+    if (height != 100)
+        error.push("expected height of 100, but was " + width);
+
+    if (error == "") {
+        element.style.backgroundColor = "green";
+        element.innerHTML += " => PASS";
+    } else {
+        element.innerHTML += " => FAIL: " + error.join(", ");
+    }
+}
+</script>
diff --git a/LayoutTests/css3/calc/lexer-regression-57581-2-expected.txt b/LayoutTests/css3/calc/lexer-regression-57581-2-expected.txt
new file mode 100644 (file)
index 0000000..53a4edc
--- /dev/null
@@ -0,0 +1,5 @@
+This test comes from a regression filed in https://bugs.webkit.org/show_bug.cgi?id=57581.
+
+The test passes if it does not crash
+
+
diff --git a/LayoutTests/css3/calc/lexer-regression-57581-2.html b/LayoutTests/css3/calc/lexer-regression-57581-2.html
new file mode 100644 (file)
index 0000000..9d0f23a
--- /dev/null
@@ -0,0 +1,9 @@
+<p>This test comes from a regression filed in <a href="https://bugs.webkit.org/show_bug.cgi?id=57581">https://bugs.webkit.org/show_bug.cgi?id=57581</a>.</p>
+<p>The test passes if it does not crash</p>
+
+<div style="width: -webkit-calc(((1px)\e))"></div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
diff --git a/LayoutTests/css3/calc/lexer-regression-57581-3-expected.txt b/LayoutTests/css3/calc/lexer-regression-57581-3-expected.txt
new file mode 100644 (file)
index 0000000..53a4edc
--- /dev/null
@@ -0,0 +1,5 @@
+This test comes from a regression filed in https://bugs.webkit.org/show_bug.cgi?id=57581.
+
+The test passes if it does not crash
+
+
diff --git a/LayoutTests/css3/calc/lexer-regression-57581-3.html b/LayoutTests/css3/calc/lexer-regression-57581-3.html
new file mode 100644 (file)
index 0000000..e121e4c
--- /dev/null
@@ -0,0 +1,9 @@
+<p>This test comes from a regression filed in <a href="https://bugs.webkit.org/show_bug.cgi?id=57581">https://bugs.webkit.org/show_bug.cgi?id=57581</a>.</p>
+<p>The test passes if it does not crash</p>
+
+<div style="width: -webkit-calc((((1px)\e))"></div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
diff --git a/LayoutTests/css3/calc/lexer-regression-57581-expected.txt b/LayoutTests/css3/calc/lexer-regression-57581-expected.txt
new file mode 100644 (file)
index 0000000..53a4edc
--- /dev/null
@@ -0,0 +1,5 @@
+This test comes from a regression filed in https://bugs.webkit.org/show_bug.cgi?id=57581.
+
+The test passes if it does not crash
+
+
diff --git a/LayoutTests/css3/calc/lexer-regression-57581.html b/LayoutTests/css3/calc/lexer-regression-57581.html
new file mode 100644 (file)
index 0000000..9c0e3a2
--- /dev/null
@@ -0,0 +1,9 @@
+<p>This test comes from a regression filed in <a href="https://bugs.webkit.org/show_bug.cgi?id=57581">https://bugs.webkit.org/show_bug.cgi?id=57581</a>.</p>
+<p>The test passes if it does not crash</p>
+
+<div style="A:-webkit-calc(((1)\e))"></div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+</script>
diff --git a/LayoutTests/css3/calc/minmax-errors-expected.txt b/LayoutTests/css3/calc/minmax-errors-expected.txt
new file mode 100644 (file)
index 0000000..5d5707f
--- /dev/null
@@ -0,0 +1,21 @@
+All boxes below should be 100px * 100px and green.
+
+MIN
+unclosed min => PASS
+unclosed min with garbage => PASS
+garbage => PASS
+extra trailing comma => PASS
+leading comma => PASS
+trailing garbage => PASS
+bad expression => PASS
+mix length and number => PASS
+mix number and length => PASS
+mix percent and number => PASS
+mix number and percent => PASS
+MAX
+unclosed max => PASS
+unclosed max with garbage => PASS
+mix length and number => PASS
+mix number and length => PASS
+mix percent and number => PASS
+mix number and percent => PASS
diff --git a/LayoutTests/css3/calc/minmax-errors.html b/LayoutTests/css3/calc/minmax-errors.html
new file mode 100644 (file)
index 0000000..3f5d919
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE HTML>
+<style>
+#test div {
+    height: 100px;
+    background-color: red;
+}
+</style>
+
+<p>
+  All boxes below should be 100px * 100px and green.
+</p>
+
+<div id="test">
+
+MIN
+<div style="width: 100px; width: -webkit-min(">unclosed min</div>
+<div style="width: 100px; width: -webkit-min( bob">unclosed min with garbage</div>
+<div style="width: 100px; width: -webkit-min( bob );">garbage</div>
+<div style="width: 100px; width: -webkit-min(20px,);">extra trailing comma</div>
+<div style="width: 100px; width: -webkit-min(,20px);">leading comma</div>
+<div style="width: 100px; width: -webkit-min(20px, bob);">trailing garbage</div>
+<div style="width: 100px; width: -webmit-min(20px, 10px + flim);">bad expression</div>
+<div style="width: 100px; width: -webkit-min(256px, 120);">mix length and number</div>
+<div style="width: 100px; width: -webkit-min(256, 120px);">mix number and length</div>
+<div style="width: 100px; width: -webkit-min(50%, 150);">mix percent and number</div>
+<div style="width: 100px; width: -webkit-min(150, 50%);">mix number and percent</div>
+
+MAX
+<div style="width: 100px; width: -webkit-max(">unclosed max</div>
+<div style="width: 100px; width: -webkit-max( bob">unclosed max with garbage</div>
+<div style="width: 100px; width: -webkit-max(256px, 120);">mix length and number</div>
+<div style="width: 100px; width: -webkit-max(256, 120px);">mix number and length</div>
+<div style="width: 100px; width: -webkit-max(50%, 150);">mix percent and number</div>
+<div style="width: 100px; width: -webkit-max(150, 50%);">mix number and percent</div>
+
+</div>
+
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var test = document.getElementById("test");
+for (var element = test.firstChild; element; element = element.nextSibling) {
+    var width = element.offsetWidth;
+    var error = [];
+    if (width != 100)
+        error.push("expected width of 100, but was " + width);
+    var height = element.offsetHeight;
+    if (height != 100)
+        error.push("expected height of 100, but was " + width);
+
+    if (error == "") {
+        element.style.backgroundColor = "green";
+        element.innerHTML += " => PASS";
+    } else {
+        element.innerHTML += " => FAIL: " + error.join(", ");
+    }
+}
+</script>
diff --git a/LayoutTests/css3/calc/simple-calcs-expected.txt b/LayoutTests/css3/calc/simple-calcs-expected.txt
new file mode 100644 (file)
index 0000000..450f9cf
--- /dev/null
@@ -0,0 +1,49 @@
+All boxes below should be 100px * 100px and green.
+
+control => PASS
+50px + 50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+150px - 50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px + 50px (2 spaces around operator) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+150px - 50px (2 spaces around operator) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px*2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px *2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px* 2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+200px/2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+200px /2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+200px/ 2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px*(2) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px *(2) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px* (2) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px*(1 + 1) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px*(12 - 10) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px*(10 / 5) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+10px* (5 * 2) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px* (12 mod 10) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px + 10px * 5 (operation order) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+1100px mod 1000 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+100%/2 (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+100% + -100px (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+80% - 60px (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+300px - 100% (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+-100px + 100% (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+20% + 30% (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+80% - 30% (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+10% * 5 (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+5 * 10% (where 100% is 200px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+(100px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+(50px + 50px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+(50px) + 50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px + (50px) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px + 50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px + 25px * 2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+(25px + 25px) * 2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+2 * 50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+2 * 100px / 2 => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+12 mod 10 * 50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+(1em - 1em) + 100px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+50px + +50px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+-50px + 150px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+-50px - -150px => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+(((((((100px))))))) => FAIL: @zoom=1 expected width of 100, but was 256; @zoom=1.2 expected width of 100, but was 256; @zoom=2 expected width of 100, but was 256
+100px => FAIL: @zoom=1 expected height of 100, but was 50; @zoom=1.2 expected height of 100, but was 50; @zoom=2 expected height of 100, but was 50
+100% * 2 => FAIL: @zoom=1 expected height of 100, but was 50; @zoom=1.2 expected height of 100, but was 50; @zoom=2 expected height of 100, but was 50
diff --git a/LayoutTests/css3/calc/simple-calcs.html b/LayoutTests/css3/calc/simple-calcs.html
new file mode 100644 (file)
index 0000000..dfb2ee2
--- /dev/null
@@ -0,0 +1,127 @@
+<!DOCTYPE HTML>\r
+<style>\r
+.width-test {\r
+    height: 100px;\r
+    width: 256px;\r
+    background-color: red;\r
+}\r
+\r
+.height-test {\r
+    width: 100px;\r
+    height: 50px;\r
+    background-color: red;\r
+}\r
+</style>\r
+\r
+<p>\r
+  All boxes below should be 100px * 100px and green.\r
+</p>\r
+\r
+<div id="test">\r
+<div style="width:100px; height:100px;">control</div>\r
+<div class="width-test" style="width: -webkit-calc(50px + 50px);">50px + 50px</div>\r
+<div class="width-test" style="width: -webkit-calc(150px - 50px);">150px - 50px</div>\r
+<div class="width-test" style="width: -webkit-calc(50px  +  50px);">50px  +  50px (2 spaces around operator)</div>\r
+<div class="width-test" style="width: -webkit-calc(150px  -  50px);">150px  - 50px (2 spaces around operator)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px*2);">50px*2</div>\r
+<div class="width-test" style="width: -webkit-calc(50px *2);">50px *2</div>\r
+<div class="width-test" style="width: -webkit-calc(50px* 2);">50px* 2</div>\r
+<div class="width-test" style="width: -webkit-calc(200px/2);">200px/2</div>\r
+<div class="width-test" style="width: -webkit-calc(200px /2);">200px /2</div>\r
+<div class="width-test" style="width: -webkit-calc(200px/ 2);">200px/ 2</div>\r
+<div class="width-test" style="width: -webkit-calc(50px*(2));">50px*(2)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px *(2));">50px *(2)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px* (2));">50px* (2)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px*(1 + 1));">50px*(1 + 1)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px*(12 - 10));">50px*(12 - 10)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px*(10 / 5));">50px*(10 / 5)</div>\r
+<div class="width-test" style="width: -webkit-calc(10px* (5 * 2));">10px* (5 * 2)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px* (12 mod 10));">50px* (12 mod 10)</div>\r
+<div class="width-test" style="width: -webkit-calc(50px + 10px * 5);">50px + 10px * 5 (operation order)</div>\r
+<div class="width-test" style="width: -webkit-calc(1100px mod 1000);">1100px mod 1000</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(100%/2);">100%/2 (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(100% + -100px);">100% + -100px (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(80% - 60px);">80% - 60px (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(300px - 100%);">300px - 100% (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(-100px + 100%);">-100px + 100% (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(20% + 30%);">20% + 30% (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(80% - 30%);">80% - 30% (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(10% * 5);">10% * 5 (where 100% is 200px)</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(5 * 10%);">5 * 10% (where 100% is 200px)</div>\r
+</div>\r
+<!--\r
+ FIXME: what do we do with mod of percent?\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+    <div class="width-test" style="width: -webkit-calc(75% mod 100);">150% mod 100 (where 100% is 200px)</div>\r
+</div>\r
+-->\r
+<div class="width-test" style="width: -webkit-calc((100px));">(100px)</div>\r
+<div class="width-test" style="width: -webkit-calc((50px + 50px));">(50px + 50px)</div>\r
+<div class="width-test" style="width: -webkit-calc((50px) + 50px);">(50px) + 50px</div>\r
+<div class="width-test" style="width: -webkit-calc(50px + (50px));">50px + (50px)</div>\r
+<div class="width-test" style="width: -webkit-calc( 50px +  50px );"> 50px +  50px </div>\r
+<div class="width-test" style="width: -webkit-calc( 50px + 25px * 2 );"> 50px + 25px * 2 </div>\r
+<div class="width-test" style="width: -webkit-calc( (25px + 25px) * 2 );"> (25px + 25px) * 2 </div>\r
+<div class="width-test" style="width: -webkit-calc(2 * 50px);">2 * 50px</div>\r
+<div class="width-test" style="width: -webkit-calc(2 * 100px / 2);">2 * 100px / 2</div>\r
+<div class="width-test" style="width: -webkit-calc(12 mod 10 * 50px);">12 mod 10 * 50px</div>\r
+<div class="width-test" style="width: -webkit-calc((1em - 1em) + 100px);">(1em - 1em) + 100px</div>\r
+<div class="width-test" style="width: -webkit-calc(50px +  +50px);">50px +  +50px</div>\r
+<div class="width-test" style="width: -webkit-calc(-50px + 150px);">-50px + 150px</div>\r
+<div class="width-test" style="width: -webkit-calc(-50px - -150px);">-50px - -150px</div>\r
+<div class="width-test" style="width: -webkit-calc((((((((100px))))))));">(((((((100px)))))))</div>\r
+<div class="height-test" style="height: -webkit-calc(100px);">100px</div>\r
+<div style="height: 50px; background-color: white;" class="wrapper">\r
+  <div class="height-test" style="height: -webkit-calc(100% * 2);">100% * 2</div>\r
+</div>\r
+</div>\r
+\r
+<script>\r
+if (window.layoutTestController)\r
+    layoutTestController.dumpAsText();\r
+\r
+zoomLevels = [1, 1.2, 2];\r
+var test = document.getElementById("test");\r
+for (var child = test.firstChild; child; child = child.nextSibling) {\r
+    var element = child;\r
+    if (element.className == "wrapper") {\r
+        element = element.firstChild;\r
+        while (element.tagName != "DIV") element = element.nextSibling;\r
+    }\r
+\r
+    var error = [];\r
+    for (var z = 0; z < zoomLevels.length; z++) {\r
+        var zoom = zoomLevels[z];\r
+        document.body.style.zoom = zoom;\r
+        var width = element.offsetWidth;\r
+        if (width != 100)\r
+            error.push("@zoom=" + zoom + " expected width of 100, but was " + width);\r
+        var height = element.offsetHeight;\r
+        if (height != 100)\r
+            error.push("@zoom=" + zoom + " expected height of 100, but was " + height);\r
+    }\r
+    if (error == "") {\r
+        element.style.backgroundColor = "green";\r
+        element.innerHTML += " => PASS";\r
+    } else\r
+        element.innerHTML += " => FAIL: " + error.join("; ");\r
+}\r
+document.body.style.zoom = 1;\r
+</script>\r
diff --git a/LayoutTests/css3/calc/simple-minmax-expected.txt b/LayoutTests/css3/calc/simple-minmax-expected.txt
new file mode 100644 (file)
index 0000000..7596690
--- /dev/null
@@ -0,0 +1,18 @@
+All boxes below should be 100px * 100px and green.
+
+min(100px) => FAIL: expected width of 100, but was 256
+min( 100px ) => FAIL: expected width of 100, but was 256
+min((((100px)))) => FAIL: expected width of 100, but was 256
+min(150px,100px) => FAIL: expected width of 100, but was 256
+min(150px,100px,200px) => FAIL: expected width of 100, but was 256
+min( 150px , 100px ,200px) => FAIL: expected width of 100, but was 256
+min(90px + 50px ,100px) => FAIL: expected width of 100, but was 256
+min(100%,100px) - where 100% is 200px => FAIL: expected width of 100, but was 256
+min(100px,100%) - where 100% is 200px => FAIL: expected width of 100, but was 256
+max(100px) => FAIL: expected width of 100, but was 256
+max(50px,100px) => FAIL: expected width of 100, but was 256
+max(50px,100px,20px) => FAIL: expected width of 100, but was 256
+max(120px - 50px,100px) => FAIL: expected width of 100, but was 256
+max(100%,100px) - where 100% is 50px => FAIL: expected width of 100, but was 256
+max(100px,100%) - where 100% is 50px => FAIL: expected width of 100, but was 256
+min(200px,100px) => FAIL: expected height of 100, but was 50
diff --git a/LayoutTests/css3/calc/simple-minmax.html b/LayoutTests/css3/calc/simple-minmax.html
new file mode 100644 (file)
index 0000000..a017316
--- /dev/null
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>\r
+<style>\r
+.width-test {\r
+    height: 100px;\r
+    width: 256px;\r
+    background-color: red;\r
+}\r
+\r
+.height-test {\r
+    width: 100px;\r
+    height: 50px;\r
+    background-color: red;\r
+}\r
+</style>\r
+\r
+<p>\r
+  All boxes below should be 100px * 100px and green.\r
+</p>\r
+\r
+<div id="test">\r
+\r
+<div class="width-test" style="width: -webkit-min(100px);">min(100px)</div>\r
+<div class="width-test" style="width: -webkit-min( 100px );">min( 100px )</div>\r
+<div class="width-test" style="width: -webkit-min((((100px))));">min((((100px))))</div>\r
+<div class="width-test" style="width: -webkit-min(150px,100px);">min(150px,100px)</div>\r
+<div class="width-test" style="width: -webkit-min(150px,100px,200px);">min(150px,100px,200px)</div>\r
+<div class="width-test" style="width: -webkit-min(  150px ,  100px  ,200px);">min(  150px  ,  100px  ,200px)</div>\r
+<div class="width-test" style="width: -webkit-min(90px + 50px ,100px);">min(90px + 50px ,100px)</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+  <div class="width-test" style="width: -webkit-min(100%,100px);">min(100%,100px) - where 100% is 200px</div>\r
+</div>\r
+<div style="width: 200px; background-color: white;" class="wrapper">\r
+  <div class="width-test" style="width: -webkit-min(100px,100%);">min(100px,100%) - where 100% is 200px</div>\r
+</div>\r
+\r
+<div class="width-test" style="width: -webkit-max(100px);">max(100px)</div>\r
+<div class="width-test" style="width: -webkit-max(50px,100px);">max(50px,100px)</div>\r
+<div class="width-test" style="width: -webkit-max(50px,100px,20px);">max(50px,100px,20px)</div>\r
+<div class="width-test" style="width: -webkit-max(120px - 50px,100px);">max(120px - 50px,100px)</div>\r
+<div style="width: 50px; background-color: white;" class="wrapper">\r
+  <div class="width-test" style="width: -webkit-max(100%,100px);">max(100%,100px) - where 100% is 50px</div>\r
+</div>\r
+<div style="width: 50px; background-color: white;" class="wrapper">\r
+  <div class="width-test" style="width: -webkit-max(100px,100%);">max(100px,100%) - where 100% is 50px</div>\r
+</div>\r
+\r
+<div class="height-test" style="height: -webkit-min(200px, 100px);">min(200px,100px)</div>\r
+\r
+</div>\r
+\r
+<script>\r
+if (window.layoutTestController)\r
+    layoutTestController.dumpAsText();\r
+\r
+var test = document.getElementById("test");\r
+for (var child = test.firstChild; child; child = child.nextSibling) {\r
+    var element = child;\r
+    if (element.className == "wrapper") {\r
+        element = element.firstChild;\r
+        while (element.tagName != "DIV") element = element.nextSibling;\r
+    }\r
+\r
+    var width = element.offsetWidth;\r
+    var error = [];\r
+    if (width != 100)\r
+        error.push("expected width of 100, but was " + width);\r
+    var height = element.offsetHeight;\r
+    if (height != 100)\r
+        error.push("expected height of 100, but was " + height);\r
+\r
+    if (error == "") {\r
+        element.style.backgroundColor = "green";\r
+        element.innerHTML += " => PASS";\r
+    } else\r
+        element.innerHTML += " => FAIL: " + error.join(", ");\r
+}\r
+</script>\r
index d91035b..9d2074f 100644 (file)
@@ -1,3 +1,26 @@
+2011-04-10  Mike Lawther  <mikelawther@chromium.org>
+
+        Reviewed by Ojan Vafai.
+
+        flex/bison tokens and grammar for CSS calc
+        https://bugs.webkit.org/show_bug.cgi?id=54412
+
+        Tests: css3/calc/calc-errors.html
+               css3/calc/lexer-regression-57581-2.html
+               css3/calc/lexer-regression-57581-3.html
+               css3/calc/lexer-regression-57581.html
+               css3/calc/minmax-errors.html
+               css3/calc/nested-rounded-corners.html
+               css3/calc/simple-calcs.html
+               css3/calc/simple-minmax.html
+
+        * css/CSSGrammar.y:
+        * css/CSSParserValues.cpp:
+        (WebCore::CSSParserValueList::insertValueAt):
+        (WebCore::CSSParserValueList::extend):
+        * css/CSSParserValues.h:
+        * css/tokenizer.flex:
+
 2011-04-10  Alice Boxhall  <aboxhall@chromium.org>
 
         Reviewed by Ryosuke Niwa.
index b3cccdb..269eaf0 100644 (file)
@@ -99,7 +99,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 
 %}
 
-%expect 50
+%expect 54
 
 %nonassoc LOWEST_PREC
 
@@ -183,6 +183,7 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %token <number> HERTZ
 %token <number> KHERTZ
 %token <string> DIMEN
+%token <string> INVALIDDIMEN
 %token <number> PERCENTAGE
 %token <number> FLOATTOKEN
 %token <number> INTEGER
@@ -191,6 +192,9 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %token <string> FUNCTION
 %token <string> ANYFUNCTION
 %token <string> NOTFUNCTION
+%token <string> CALCFUNCTION
+%token <string> MINFUNCTION
+%token <string> MAXFUNCTION
 
 %token <string> UNICODERANGE
 
@@ -271,6 +275,14 @@ static int cssyylex(YYSTYPE* yylval, void* parser)
 %type <value> term
 %type <value> unary_term
 %type <value> function
+%type <value> calc_func_term
+%type <character> calc_func_operator
+%type <valueList> calc_func_expr
+%type <valueList> calc_func_expr_list
+%type <valueList> calc_func_paren_expr
+%type <value> calc_function
+%type <string> min_or_max
+%type <value> min_or_max_function
 
 %type <string> element_name
 %type <string> attr_name
@@ -1407,6 +1419,12 @@ term:
   | function {
       $$ = $1;
   }
+  | calc_function {
+      $$ = $1;
+  }
+  | min_or_max_function {
+      $$ = $1;
+  }
   | '%' maybe_space { /* Handle width: %; */
       $$.id = 0; $$.unit = 0;
   }
@@ -1463,6 +1481,143 @@ function:
         $$.function = f;
   }
   ;
+calc_func_term:
+  unary_term { $$ = $1; }
+  | unary_operator unary_term { $$ = $2; $$.fValue *= $1; }
+  ;
+
+calc_func_operator:
+    '+' WHITESPACE {
+        $$ = '+';
+    }
+    | '-' WHITESPACE {
+        $$ = '-';
+    }
+    | '*' maybe_space {
+        $$ = '*';
+    }
+    | '/' maybe_space {
+        $$ = '/';
+    }
+    | IDENT maybe_space {
+        if (equalIgnoringCase("mod", $1.characters, $1.length))
+            $$ = '%';
+        else
+            $$ = 0;
+    }
+  ;
+
+calc_func_paren_expr:
+    '(' maybe_space calc_func_expr maybe_space ')' maybe_space {
+        if ($3) {
+            $$ = $3;
+            CSSParserValue v;
+            v.id = 0;
+            v.unit = CSSParserValue::Operator;
+            v.iValue = '(';
+            $$->insertValueAt(0, v);
+            v.iValue = ')';
+            $$->addValue(v);
+        } else
+            $$ = 0;
+    }
+
+calc_func_expr:
+    calc_func_term maybe_space {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        $$ = p->createFloatingValueList();
+        $$->addValue(p->sinkFloatingValue($1));
+    }
+    | calc_func_expr calc_func_operator calc_func_term {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        if ($1 && $2) {
+            $$ = $1;
+            CSSParserValue v;
+            v.id = 0;
+            v.unit = CSSParserValue::Operator;
+            v.iValue = $2;
+            $$->addValue(v);
+            $$->addValue(p->sinkFloatingValue($3));
+        } else
+            $$ = 0;
+
+    }
+    | calc_func_expr calc_func_operator calc_func_paren_expr {
+        if ($1 && $2 && $3) {
+            $$ = $1;
+            CSSParserValue v;
+            v.id = 0;
+            v.unit = CSSParserValue::Operator;
+            v.iValue = $2;
+            $$->addValue(v);
+            $$->extend(*($3));
+        } else 
+            $$ = 0;
+    }
+    | calc_func_paren_expr
+    | calc_func_expr error {
+        $$ = 0;
+    }
+  ;
+
+calc_func_expr_list:
+    calc_func_expr  {
+        $$ = $1;
+    }    
+    | calc_func_expr_list ',' maybe_space calc_func_expr {
+        if ($1 && $4) {
+            $$ = $1;
+            CSSParserValue v;
+            v.id = 0;
+            v.unit = CSSParserValue::Operator;
+            v.iValue = ',';
+            $$->addValue(v);
+            $$->extend(*($4));
+        } else
+            $$ = 0;
+    }
+    
+
+calc_function:
+    CALCFUNCTION maybe_space calc_func_expr ')' maybe_space {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        CSSParserFunction* f = p->createFloatingFunction();
+        f->name = $1;
+        f->args = p->sinkFloatingValueList($3);
+        $$.id = 0;
+        $$.unit = CSSParserValue::Function;
+        $$.function = f;
+    }
+    | CALCFUNCTION maybe_space error {
+        YYERROR;
+    }
+    ;
+
+
+min_or_max:
+    MINFUNCTION {
+        $$ = $1;
+    }
+    | MAXFUNCTION {
+        $$ = $1;
+    }
+    ;
+
+min_or_max_function:
+    min_or_max maybe_space calc_func_expr_list ')' maybe_space {
+        CSSParser* p = static_cast<CSSParser*>(parser);
+        CSSParserFunction* f = p->createFloatingFunction();
+        f->name = $1;
+        f->args = p->sinkFloatingValueList($3);
+        $$.id = 0;
+        $$.unit = CSSParserValue::Function;
+        $$.function = f;
+    } 
+    | min_or_max maybe_space error {
+        YYERROR;
+    }
+    ;
 
 /* error handling rules */
 
index 9ecb96d..94dcd3c 100644 (file)
@@ -44,12 +44,23 @@ void CSSParserValueList::addValue(const CSSParserValue& v)
 {
     m_values.append(v);
 }
-    
+
+void CSSParserValueList::insertValueAt(unsigned i, const CSSParserValue& v)
+{
+    m_values.insert(i, v);
+}
+
 void CSSParserValueList::deleteValueAt(unsigned i)
 { 
     m_values.remove(i);
 }
 
+void CSSParserValueList::extend(CSSParserValueList& valueList)
+{
+    for (unsigned int i = 0; i < valueList.size(); ++i)
+        m_values.append(*(valueList.valueAt(i)));
+}
+
 PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
 {
     RefPtr<CSSValue> parsedValue;
index 0f43b8c..81ecbc3 100644 (file)
@@ -71,7 +71,9 @@ public:
     ~CSSParserValueList();
     
     void addValue(const CSSParserValue&);
+    void insertValueAt(unsigned, const CSSParserValue&);
     void deleteValueAt(unsigned);
+    void extend(CSSParserValueList&);
 
     unsigned size() const { return m_values.size(); }
     CSSParserValue* current() { return m_current < m_values.size() ? &m_values[m_current] : 0; }
index f72144a..3285d2f 100644 (file)
@@ -101,6 +101,7 @@ nth             [\+-]?{intnum}*n([\t\r\n ]*[\+-][\t\r\n ]*{intnum})?
 {num}Hz                 {yyTok = HERTZ; return yyTok;}
 {num}kHz                {yyTok = KHERTZ; return yyTok;}
 {num}{ident}            {yyTok = DIMEN; return yyTok;}
+{num}{ident}\+          {yyTok = INVALIDDIMEN; return yyTok;}
 {num}%+                 {yyTok = PERCENTAGE; return yyTok;}
 {intnum}                {yyTok = INTEGER; return yyTok;}
 {num}                   {yyTok = FLOATTOKEN; return yyTok;}
@@ -109,6 +110,9 @@ nth             [\+-]?{intnum}*n([\t\r\n ]*[\+-][\t\r\n ]*{intnum})?
 "not("                  {yyTok = NOTFUNCTION; return yyTok;}
 "url("{w}{string}{w}")" {yyTok = URI; return yyTok;}
 "url("{w}{url}{w}")"    {yyTok = URI; return yyTok;}
+"-webkit-calc("         {yyTok = CALCFUNCTION; return yyTok;}
+"-webkit-min("          {yyTok = MINFUNCTION; return yyTok;}
+"-webkit-max("          {yyTok = MAXFUNCTION; return yyTok;}
 {ident}"("              {yyTok = FUNCTION; return yyTok;}
 
 U\+{range}              {yyTok = UNICODERANGE; return yyTok;}