]> source.dussan.org Git - vaadin-framework.git/commitdiff
Support nested SASS imports (#11909)
authorHenri Sara <hesara@vaadin.com>
Thu, 23 May 2013 09:42:14 +0000 (12:42 +0300)
committerVaadin Code Review <review@vaadin.com>
Tue, 28 May 2013 14:07:51 +0000 (14:07 +0000)
Change-Id: I05f88e398e7e28f476d8c0d50b7f9ac54a7cba0b

theme-compiler/src/com/vaadin/sass/internal/parser/Parser.java
theme-compiler/src/com/vaadin/sass/internal/parser/Parser.jj
theme-compiler/src/com/vaadin/sass/internal/tree/ImportNode.java
theme-compiler/src/com/vaadin/sass/internal/visitor/ImportNodeHandler.java
theme-compiler/tests/resources/automatic/css/nested-import.css [new file with mode: 0644]
theme-compiler/tests/resources/automatic/scss/nested-import.scss [new file with mode: 0644]

index d938dfefe860a2cb874ad49652692cc1369810f7..382e8e67110d6b89f3d10f80ec06a73e692a0bd9 100755 (executable)
@@ -136,6 +136,7 @@ public class Parser implements org.w3c.css.sac.Parser, ParserConstants {
      * @exception IOException the source can't be parsed.
      * @exception CSSException the source is not CSS valid.
      */
+    // TODO required by original parser but not used by Vaadin?
     public void parseRule(InputSource source)
             throws CSSException, IOException {
         this.source = source;
@@ -1870,6 +1871,7 @@ char connector = ' ';
         case IDENT:
         case VARIABLE:
         case HASH:
+        case IMPORT_SYM:
         case MEDIA_SYM:
         case KEY_FRAME_SYM:
           ;
@@ -1907,6 +1909,9 @@ char connector = ' ';
         case MICROSOFT_RULE:
           microsoftExtension();
           break;
+        case IMPORT_SYM:
+          importDeclaration();
+          break;
         default:
           jj_la1[69] = jj_gen;
           jj_consume_token(-1);
@@ -6080,6 +6085,7 @@ LexicalUnitImpl result = null;
  * The following functions are useful for a DOM CSS implementation only and are
  * not part of the general CSS2 parser.
  */
+// TODO required by original parser but not used by Vaadin?
   final public void _parseRule() throws ParseException {
  String ret = null;
     label_168:
@@ -7364,13 +7370,13 @@ LexicalUnitImpl result = null;
     return false;
   }
 
-  private boolean jj_3R_261() {
-    if (jj_scan_token(INTERPOLATION)) return true;
+  private boolean jj_3_9() {
+    if (jj_3R_184()) return true;
     return false;
   }
 
-  private boolean jj_3_9() {
-    if (jj_3R_184()) return true;
+  private boolean jj_3R_261() {
+    if (jj_scan_token(INTERPOLATION)) return true;
     return false;
   }
 
@@ -7529,7 +7535,7 @@ LexicalUnitImpl result = null;
       jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x401,0x4000,0x0,0x0,0x0,0x0,0x2200,0x0,0x0,0x0,0x400,0x400,0x0,0x0,0x8000,0x0,0x8000,0x0,0x0,0x4465,0x4465,0x0,0x0,0x0,0xae00,0xae00,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0xaa00,0x0,0x0,0x0,0x0,0x0,0xe00,0xe00,0x0,0x400,0x400,0x0,0x0,0x0,0x0,0x4465,0x4465,0x0,0x0,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x400,0x400,0x400,0x400,0x400,0x0,0x0,0x0,0x0,0x600,0x0,0x0,0x0,0x0,0x400,0x0,0x100,0x0,0x0,0x1,0x424,0x4000,0x4c00,0x0,0x4424,0x0,0x2,0x0,0x4c00,0x80,0x0,0x4424,0x0,0x4c00,0x0,0x0,0x0,0x4400,0x0,0x4424,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x0,0x4425,0x4425,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x4000,0xffffee00,0x0,0x0,0x0,0x0,0xffffee00,0x0,0x0,0x0,0x4400,0x0,0x0,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,0xffffee00,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xffffee00,0x0,0xffff8800,0x0,0x400,0x2600,0xffffae00,0x0,0x0,0xffffee00,0x0,0x400,0x0,0x0,0x0,0x400,0x0,0x0,0x400,0x0,};
    }
    private static void jj_la1_init_3() {
-      jj_la1_3 = new int[] {0x20,0x200,0x200,0x8,0x200,0x0,0x0,0x0,0x1d4,0x0,0x200,0x0,0x200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x114,0x0,0x0,0x0,0x31006fc,0x31006fc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x31006f8,0x0,0x0,0x0,0x0,0x0,0x1000000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x114,0x0,0x0,0x0,0x4,0x0,0x4,0x4,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x800000,0x0,0x114,0x0,0x0,0x0,0x800000,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x1d4,0x1d4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x1000003,0x0,0x0,0x100004,0x1100007,0x0,0x0,0x1100007,0x0,0xdc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
+      jj_la1_3 = new int[] {0x20,0x200,0x200,0x8,0x200,0x0,0x0,0x0,0x1d4,0x0,0x200,0x0,0x200,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x114,0x0,0x0,0x0,0x31006fc,0x31006fc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x31006f8,0x0,0x0,0x0,0x0,0x0,0x1000000,0x1000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x11c,0x11c,0x0,0x0,0x0,0x4,0x0,0x4,0x4,0x0,0x0,0x4,0x4,0x4,0x4,0x4,0x4,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x800000,0x0,0x114,0x0,0x0,0x0,0x800000,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x114,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1000000,0x0,0x1d4,0x1d4,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x0,0x1100007,0x0,0x0,0x0,0x1000000,0x0,0x0,0x0,0x4,0x0,0x0,0x0,0x0,0xe00000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x400,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1100007,0x0,0x1000003,0x0,0x0,0x100004,0x1100007,0x0,0x0,0x1100007,0x0,0xdc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
    }
   final private JJCalls[] jj_2_rtns = new JJCalls[9];
   private boolean jj_rescan = false;
index 7f86527015f90ffd9ddc0713eb92194a34e34f89..daf20423d6a105ef3cf5fa785774d0a78765a805 100644 (file)
@@ -169,6 +169,7 @@ public class Parser implements org.w3c.css.sac.Parser {
      * @exception IOException the source can't be parsed.
      * @exception CSSException the source is not CSS valid.
      */    
+    // TODO required by original parser but not used by Vaadin?
     public void parseRule(InputSource source) 
            throws CSSException, IOException {
        this.source = source;
@@ -1188,7 +1189,8 @@ void styleRule() :
         start = true;
         documentHandler.startSelector(l);
      }
-     ( ifContentStatement() | controlDirective() | microsoftExtension() )*
+     // a CSS import here will not work
+     ( ifContentStatement() | controlDirective() | microsoftExtension() | importDeclaration() )*
      <RBRACE> (<S>)*
  } catch (ThrowedParseException e) {
      if (errorHandler != null) {
@@ -2947,7 +2949,7 @@ String skipAfterExpression() {
  * The following functions are useful for a DOM CSS implementation only and are
  * not part of the general CSS2 parser.
  */
-
+// TODO required by original parser but not used by Vaadin?
 void _parseRule() :
 {String ret = null;
 }
index f7d664d54defd0b98330b8b2cab23edf151a2ec9..6dc95db5c21d4c89cc2d4986bf343575c99210b0 100644 (file)
@@ -18,7 +18,6 @@ package com.vaadin.sass.internal.tree;
 
 import org.w3c.css.sac.SACMediaList;
 
-import com.vaadin.sass.internal.ScssStylesheet;
 import com.vaadin.sass.internal.visitor.ImportNodeHandler;
 
 public class ImportNode extends Node {
@@ -74,7 +73,7 @@ public class ImportNode extends Node {
 
     @Override
     public void traverse() {
-        // TODO shouldn't be reached with current setup, try anyway?
-        ImportNodeHandler.traverse((ScssStylesheet) getParentNode());
+        // nested imports
+        ImportNodeHandler.traverse(getParentNode());
     }
 }
index e356ed3525a6341d02137442a610a66398504c17..cb9896967ad47c3456580d9de18ca12b2bfa9be7 100644 (file)
@@ -26,6 +26,7 @@ import org.w3c.css.sac.LexicalUnit;
 
 import com.vaadin.sass.internal.ScssStylesheet;
 import com.vaadin.sass.internal.parser.LexicalUnitImpl;
+import com.vaadin.sass.internal.parser.ParseException;
 import com.vaadin.sass.internal.tree.ImportNode;
 import com.vaadin.sass.internal.tree.Node;
 import com.vaadin.sass.internal.tree.RuleNode;
@@ -33,7 +34,23 @@ import com.vaadin.sass.internal.util.StringUtil;
 
 public class ImportNodeHandler {
 
-    public static void traverse(ScssStylesheet node) {
+    public static void traverse(Node node) {
+        ScssStylesheet styleSheet = null;
+        if (node instanceof ScssStylesheet) {
+            styleSheet = (ScssStylesheet) node;
+        } else {
+            // iterate to parents of node, find ScssStylesheet
+            Node parent = node.getParentNode();
+            while (parent != null && !(parent instanceof ScssStylesheet)) {
+                parent = parent.getParentNode();
+            }
+            if (parent instanceof ScssStylesheet) {
+                styleSheet = (ScssStylesheet) parent;
+            }
+        }
+        if (styleSheet == null) {
+            throw new ParseException("Nested import in an invalid context");
+        }
         ArrayList<Node> c = new ArrayList<Node>(node.getChildren());
         for (Node n : c) {
             if (n instanceof ImportNode) {
@@ -41,7 +58,7 @@ public class ImportNodeHandler {
                 if (!importNode.isPureCssImport()) {
                     try {
                         StringBuilder filePathBuilder = new StringBuilder(
-                                node.getFileName());
+                                styleSheet.getFileName());
                         filePathBuilder.append(File.separatorChar).append(
                                 importNode.getUri());
                         if (!filePathBuilder.toString().endsWith(".scss")) {
@@ -50,7 +67,8 @@ public class ImportNodeHandler {
 
                         // set parent's charset to imported node.
                         ScssStylesheet imported = ScssStylesheet.get(
-                                filePathBuilder.toString(), node.getCharset());
+                                filePathBuilder.toString(),
+                                styleSheet.getCharset());
                         if (imported == null) {
                             imported = ScssStylesheet.get(importNode.getUri());
                         }
@@ -76,6 +94,11 @@ public class ImportNodeHandler {
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
+                } else {
+                    if (styleSheet != node) {
+                        throw new ParseException(
+                                "CSS imports can only be used at the top level, not as nested imports. Within style rules, use SCSS imports.");
+                    }
                 }
             }
         }
diff --git a/theme-compiler/tests/resources/automatic/css/nested-import.css b/theme-compiler/tests/resources/automatic/css/nested-import.css
new file mode 100644 (file)
index 0000000..7c6793f
--- /dev/null
@@ -0,0 +1,5 @@
+.foo .bar {
+    background: url(foo/lorem.png);
+    background: url(foo/lorem.png);
+    background: url(foo/lorem.png);
+}
\ No newline at end of file
diff --git a/theme-compiler/tests/resources/automatic/scss/nested-import.scss b/theme-compiler/tests/resources/automatic/scss/nested-import.scss
new file mode 100644 (file)
index 0000000..605d64a
--- /dev/null
@@ -0,0 +1,3 @@
+.foo {
+    @import "foo/bar.scss";
+}
\ No newline at end of file