Add GSS for loop and genkeyframes

Add support of two new feature of GSS:
- for loop
- @gen-webkit-keyframes: generate a @-webkit-keyframes
based on an existing @keyframes

Change-Id: I982443e7b8ead9c04b9e783f2bbe75f010644f8d
diff --git a/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java b/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java
index a789edb..9b9edfc 100644
--- a/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/GssResourceGenerator.java
@@ -84,8 +84,10 @@
 import com.google.gwt.thirdparty.common.css.compiler.passes.CreateConditionalNodes;
 import com.google.gwt.thirdparty.common.css.compiler.passes.CreateConstantReferences;
 import com.google.gwt.thirdparty.common.css.compiler.passes.CreateDefinitionNodes;
+import com.google.gwt.thirdparty.common.css.compiler.passes.CreateForLoopNodes;
 import com.google.gwt.thirdparty.common.css.compiler.passes.CreateMixins;
 import com.google.gwt.thirdparty.common.css.compiler.passes.CreateStandardAtRuleNodes;
+import com.google.gwt.thirdparty.common.css.compiler.passes.CreateVendorPrefixedKeyframes;
 import com.google.gwt.thirdparty.common.css.compiler.passes.CssClassRenaming;
 import com.google.gwt.thirdparty.common.css.compiler.passes.DisallowDuplicateDeclarations;
 import com.google.gwt.thirdparty.common.css.compiler.passes.EliminateEmptyRulesetNodes;
@@ -103,6 +105,8 @@
 import com.google.gwt.thirdparty.common.css.compiler.passes.ReplaceMixins;
 import com.google.gwt.thirdparty.common.css.compiler.passes.ResolveCustomFunctionNodes;
 import com.google.gwt.thirdparty.common.css.compiler.passes.SplitRulesetNodes;
+import com.google.gwt.thirdparty.common.css.compiler.passes.UnrollLoops;
+import com.google.gwt.thirdparty.common.css.compiler.passes.ValidatePropertyValues;
 import com.google.gwt.thirdparty.guava.common.base.CaseFormat;
 import com.google.gwt.thirdparty.guava.common.base.Charsets;
 import com.google.gwt.thirdparty.guava.common.base.Joiner;
@@ -855,11 +859,16 @@
     new CreateConstantReferences(cssTree.getMutatingVisitController()).runPass();
     new CreateConditionalNodes(cssTree.getMutatingVisitController(), errorManager).runPass();
     new CreateRuntimeConditionalNodes(cssTree.getMutatingVisitController()).runPass();
+    new CreateForLoopNodes(cssTree.getMutatingVisitController(), errorManager).runPass();
     new CreateComponentNodes(cssTree.getMutatingVisitController(), errorManager).runPass();
+    new ValidatePropertyValues(cssTree.getVisitController(), errorManager).runPass();
 
     new HandleUnknownAtRuleNodes(cssTree.getMutatingVisitController(), errorManager,
         allowedAtRules, true, false).runPass();
     new ProcessKeyframes(cssTree.getMutatingVisitController(), errorManager, true, true).runPass();
+    new CreateVendorPrefixedKeyframes(cssTree.getMutatingVisitController(),
+            errorManager).runPass();
+    new UnrollLoops(cssTree.getMutatingVisitController(), errorManager).runPass();
     new ProcessRefiners(cssTree.getMutatingVisitController(), errorManager, true).runPass();
     new MarkNonFlippableNodes(cssTree.getMutatingVisitController(), errorManager).runPass();
   }
diff --git a/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java b/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java
index 74f7bd6..e292a6c 100644
--- a/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java
+++ b/user/test/com/google/gwt/resources/client/gss/GssResourceTest.java
@@ -19,6 +19,8 @@
 import com.google.gwt.resources.client.gss.TestResources.Charset;
 import com.google.gwt.resources.client.gss.TestResources.ClassNameAnnotation;
 import com.google.gwt.resources.client.gss.TestResources.EmptyClass;
+import com.google.gwt.resources.client.gss.TestResources.Forloop;
+import com.google.gwt.resources.client.gss.TestResources.GenKeyFrames;
 import com.google.gwt.resources.client.gss.TestResources.NonStandardAtRules;
 import com.google.gwt.resources.client.gss.TestResources.NonStandardFunctions;
 import com.google.gwt.resources.client.gss.TestResources.RuntimeConditional;
@@ -196,6 +198,23 @@
     assertEquals("", res().empty().getText());
   }
 
+  public void testForLoop() {
+    Forloop forloop = res().forloop();
+
+    String expectedCss = "." + forloop.foo0() + "{padding:0}." + forloop.foo2() + "{padding:2px}." + forloop.foo4() + "{padding:4px}";
+
+    assertEquals(expectedCss, forloop.getText());
+  }
+
+  public void testGenKeyFrames() {
+    GenKeyFrames genKeyFrames = res().genKeyFrames();
+
+    String expectedCss = "@keyframes myframe{0%{top:0}to{top:200px}}@-webkit-keyframes myframe{0%{top:0}to{top:200px}}" +
+            "div{animation:myframe 5s infinite}";
+
+    assertEquals(expectedCss, genKeyFrames.getText());
+  }
+
   private String runtimeExpectedCss(String color, String padding, String foo) {
     String s = "." + foo + "{width:100%}" + "." + foo + "{color:" + color + "}";
 
diff --git a/user/test/com/google/gwt/resources/client/gss/TestResources.java b/user/test/com/google/gwt/resources/client/gss/TestResources.java
index a1b89fc..a29a95c 100644
--- a/user/test/com/google/gwt/resources/client/gss/TestResources.java
+++ b/user/test/com/google/gwt/resources/client/gss/TestResources.java
@@ -187,6 +187,26 @@
   interface Empty extends CssResource {
   }
 
+  /**
+   * Used to test For loop feature.
+   */
+  interface Forloop extends CssResource {
+    @ClassName("foo-0")
+    String foo0();
+
+    @ClassName("foo-2")
+    String foo2();
+
+    @ClassName("foo-4")
+    String foo4();
+  }
+
+  /**
+   * Used to test vendor keyframes generation.
+   */
+  interface GenKeyFrames extends CssResource {
+  }
+
   @Source("constants.gss")
   Constants constants();
 
@@ -234,4 +254,8 @@
   Charset charset();
 
   Empty empty();
+
+  Forloop forloop();
+
+  GenKeyFrames genKeyFrames();
 }
diff --git a/user/test/com/google/gwt/resources/client/gss/forloop.gss b/user/test/com/google/gwt/resources/client/gss/forloop.gss
new file mode 100644
index 0000000..6393123
--- /dev/null
+++ b/user/test/com/google/gwt/resources/client/gss/forloop.gss
@@ -0,0 +1,7 @@
+@for $i from 0 to 4 step 2 {
+    @def PADDING mult(1px, $i);
+
+    .foo-$i {
+        padding: PADDING;
+    }
+}
\ No newline at end of file
diff --git a/user/test/com/google/gwt/resources/client/gss/genKeyFrames.gss b/user/test/com/google/gwt/resources/client/gss/genKeyFrames.gss
new file mode 100644
index 0000000..62e1de3
--- /dev/null
+++ b/user/test/com/google/gwt/resources/client/gss/genKeyFrames.gss
@@ -0,0 +1,13 @@
+/* @gen-webkit-keyframes */
+@keyframes myframe {
+    from {
+        top: 0px;
+    }
+    to {
+        top: 200px;
+    }
+}
+
+div {
+    animation: myframe 5s infinite;
+}
\ No newline at end of file