From 6014a78a887bdd8c113df98dfbc8b4f476fd4863 Mon Sep 17 00:00:00 2001 From: meri Date: Thu, 10 Jan 2013 11:26:37 +0100 Subject: [PATCH] Basic support for import: place import declarations on top of input file and print it as it is. #83 and #19 --- .../github/sommeri/less4j/core/parser/Less.g | 13 +- .../less4j/core/ast/ASTCssNodeType.java | 2 +- .../sommeri/less4j/core/ast/Import.java | 76 ++++++++++++ .../core/compiler/LessToCssCompiler.java | 29 ++++- .../less4j/core/parser/ASTBuilderSwitch.java | 112 ++++++++++++------ .../less4j/core/parser/SuperLessParser.java | 2 + .../less4j/core/parser/TokenTypeSwitch.java | 5 + .../sommeri/less4j/utils/CssPrinter.java | 13 ++ .../sommeri/less4j/compiler/ImportsTest.java | 23 ++++ .../import/import-css-files.css | 27 +++++ .../import/import-css-files.less | 33 ++++++ .../CSS Paged Media Module Level 3/debug.css | 8 -- .../CSS Paged Media Module Level 3/debug.less | 8 -- 13 files changed, 287 insertions(+), 64 deletions(-) create mode 100644 src/main/java/com/github/sommeri/less4j/core/ast/Import.java create mode 100644 src/test/java/com/github/sommeri/less4j/compiler/ImportsTest.java create mode 100644 src/test/resources/compile-basic-features/import/import-css-files.css create mode 100644 src/test/resources/compile-basic-features/import/import-css-files.less delete mode 100644 src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.css delete mode 100644 src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.less diff --git a/src/main/antlr3/com/github/sommeri/less4j/core/parser/Less.g b/src/main/antlr3/com/github/sommeri/less4j/core/parser/Less.g index 14014879..45717bab 100644 --- a/src/main/antlr3/com/github/sommeri/less4j/core/parser/Less.g +++ b/src/main/antlr3/com/github/sommeri/less4j/core/parser/Less.g @@ -165,7 +165,6 @@ tokens { styleSheet @init {enterRule(retval, RULE_STYLESHEET);} : ( a+=charSet* //the original ? was replaced by *, because it is possible (even if it makes no sense) and less.js is able to handle such situation - a+=imports* a+=bodylist EOF ) -> ^(STYLE_SHEET ($a)*) ; @@ -186,7 +185,7 @@ finally { leaveRule(); } // imports @init {enterRule(retval, RULE_IMPORTS);} - : IMPORT_SYM (STRING|URI) (mediaQuery (COMMA mediaQuery)*)? SEMI + : (IMPORT_SYM | IMPORT_ONCE_SYM | IMPORT_MULTIPLE_SYM)^ (term) (mediaQuery (COMMA mediaQuery)*)? SEMI! ; finally { leaveRule(); } @@ -256,6 +255,7 @@ bodyset | keyframes | page | fontface + | imports ; variabledeclaration @@ -377,6 +377,7 @@ general_body | (reusableStructure)=>a+=reusableStructure | a+=pageMarginBox | a+=variabledeclaration + | a+=imports )* ( ( (declaration)=>a+=declaration RBRACE) @@ -1106,7 +1107,9 @@ IDENT : '-'? NMSTART NMCHAR* ; fragment HASH_FRAGMENT : '#' NAME ; HASH : HASH_FRAGMENT ; -IMPORT_SYM : '@' I M P O R T ; +IMPORT_SYM : '@' I M P O R T; +IMPORT_ONCE_SYM : '@' I M P O R T MINUS O N C E; +IMPORT_MULTIPLE_SYM : '@' I M P O R T MINUS M U L T I P L E; PAGE_SYM : '@' P A G E ; MEDIA_SYM : '@' M E D I A ; FONT_FACE_SYM : '@' F O N T MINUS F A C E ; @@ -1195,10 +1198,10 @@ NUMBER // url and uri. URI : (U R L '(' - ((WS)=>WS)? (URL|STRING) WS? + ((WS)=>WS)? (URL) WS? ')') => (U R L '(' - ((WS)=>WS)? (URL|STRING) WS? + ((WS)=>WS)? (URL) WS? ')') | U R L { $type=IDENT; } ; diff --git a/src/main/java/com/github/sommeri/less4j/core/ast/ASTCssNodeType.java b/src/main/java/com/github/sommeri/less4j/core/ast/ASTCssNodeType.java index b09b265c..29e1280b 100644 --- a/src/main/java/com/github/sommeri/less4j/core/ast/ASTCssNodeType.java +++ b/src/main/java/com/github/sommeri/less4j/core/ast/ASTCssNodeType.java @@ -1,5 +1,5 @@ package com.github.sommeri.less4j.core.ast; public enum ASTCssNodeType { - UNKNOWN, CSS_CLASS, DECLARATION, STYLE_SHEET, RULE_SET, SELECTOR, SIMPLE_SELECTOR, PSEUDO_CLASS, PSEUDO_ELEMENT, SELECTOR_ATTRIBUTE, ID_SELECTOR, CHARSET_DECLARATION, FONT_FACE, IDENTIFIER_EXPRESSION, COMPOSED_EXPRESSION, STRING_EXPRESSION, NUMBER, COLOR_EXPRESSION, FUNCTION, MEDIA, COMMENT, DECLARATIONS_BODY, SELECTOR_OPERATOR, SELECTOR_COMBINATOR, EXPRESSION_OPERATOR, NTH, NAMED_EXPRESSION, MEDIA_QUERY, MEDIA_EXPRESSION, MEDIUM, MEDIUM_MODIFIER, MEDIUM_TYPE, MEDIUM_EX_FEATURE, VARIABLE_DECLARATION, VARIABLE, INDIRECT_VARIABLE, PARENTHESES_EXPRESSION, SIGNED_EXPRESSION, ARGUMENT_DECLARATION, MIXIN_REFERENCE, GUARD_CONDITION, COMPARISON_EXPRESSION, GUARD, NESTED_SELECTOR_APPENDER, REUSABLE_STRUCTURE, FAULTY_EXPRESSION, ESCAPED_SELECTOR, ESCAPED_VALUE, INTERPOLABLE_NAME, FIXED_NAME_PART, VARIABLE_NAME_PART, KEYFRAMES, KEYFRAMES_NAME, KEYFRAMES_BODY, REUSABLE_STRUCTURE_NAME, VIEWPORT, GENERAL_BODY, PAGE, NAME, PAGE_MA, PAGE_MARGIN_BOX + UNKNOWN, CSS_CLASS, DECLARATION, STYLE_SHEET, RULE_SET, SELECTOR, SIMPLE_SELECTOR, PSEUDO_CLASS, PSEUDO_ELEMENT, SELECTOR_ATTRIBUTE, ID_SELECTOR, CHARSET_DECLARATION, FONT_FACE, IDENTIFIER_EXPRESSION, COMPOSED_EXPRESSION, STRING_EXPRESSION, NUMBER, COLOR_EXPRESSION, FUNCTION, MEDIA, COMMENT, DECLARATIONS_BODY, SELECTOR_OPERATOR, SELECTOR_COMBINATOR, EXPRESSION_OPERATOR, NTH, NAMED_EXPRESSION, MEDIA_QUERY, MEDIA_EXPRESSION, MEDIUM, MEDIUM_MODIFIER, MEDIUM_TYPE, MEDIUM_EX_FEATURE, VARIABLE_DECLARATION, VARIABLE, INDIRECT_VARIABLE, PARENTHESES_EXPRESSION, SIGNED_EXPRESSION, ARGUMENT_DECLARATION, MIXIN_REFERENCE, GUARD_CONDITION, COMPARISON_EXPRESSION, GUARD, NESTED_SELECTOR_APPENDER, REUSABLE_STRUCTURE, FAULTY_EXPRESSION, ESCAPED_SELECTOR, ESCAPED_VALUE, INTERPOLABLE_NAME, FIXED_NAME_PART, VARIABLE_NAME_PART, KEYFRAMES, KEYFRAMES_NAME, KEYFRAMES_BODY, REUSABLE_STRUCTURE_NAME, VIEWPORT, GENERAL_BODY, PAGE, NAME, PAGE_MA, PAGE_MARGIN_BOX, IMPORT } diff --git a/src/main/java/com/github/sommeri/less4j/core/ast/Import.java b/src/main/java/com/github/sommeri/less4j/core/ast/Import.java new file mode 100644 index 00000000..f502b294 --- /dev/null +++ b/src/main/java/com/github/sommeri/less4j/core/ast/Import.java @@ -0,0 +1,76 @@ +package com.github.sommeri.less4j.core.ast; + +import java.util.ArrayList; +import java.util.List; + +import com.github.sommeri.less4j.core.parser.HiddenTokenAwareTree; +import com.github.sommeri.less4j.utils.ArraysUtils; + +public class Import extends ASTCssNode { + + private ImportKind kind = ImportKind.IMPORT; + private Expression urlExpression; + private List mediums = new ArrayList(); + + public Import(HiddenTokenAwareTree underlyingStructure) { + super(underlyingStructure); + } + + public ImportKind getKind() { + return kind; + } + + public void setKind(ImportKind kind) { + this.kind = kind; + } + + public Expression getUrlExpression() { + return urlExpression; + } + + public void setUrlExpression(Expression urlExpression) { + this.urlExpression = urlExpression; + } + + public List getMediums() { + return mediums; + } + + public void setMediums(List mediums) { + this.mediums = mediums; + } + + public void add(MediaQuery medium) { + mediums.add(medium); + } + + @Override + public List getChilds() { + List result = ArraysUtils.asNonNullList((ASTCssNode)urlExpression); + result.addAll(mediums); + return result; + } + + @Override + public Import clone() { + Import result = (Import) super.clone(); + result.urlExpression = urlExpression==null? null : urlExpression.clone(); + result.mediums = ArraysUtils.deeplyClonedList(mediums); + result.configureParentToAllChilds(); + return result; + } + +//@Override +//public String toString() { +//} + + @Override + public ASTCssNodeType getType() { + return ASTCssNodeType.IMPORT; + } + + public enum ImportKind { + IMPORT, IMPORT_ONCE, IMPORT_MULTIPLE + } + +} diff --git a/src/main/java/com/github/sommeri/less4j/core/compiler/LessToCssCompiler.java b/src/main/java/com/github/sommeri/less4j/core/compiler/LessToCssCompiler.java index 2c77915c..0157411f 100644 --- a/src/main/java/com/github/sommeri/less4j/core/compiler/LessToCssCompiler.java +++ b/src/main/java/com/github/sommeri/less4j/core/compiler/LessToCssCompiler.java @@ -1,9 +1,12 @@ package com.github.sommeri.less4j.core.compiler; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import com.github.sommeri.less4j.core.ast.ASTCssNode; +import com.github.sommeri.less4j.core.ast.ASTCssNodeType; import com.github.sommeri.less4j.core.ast.Body; import com.github.sommeri.less4j.core.ast.Declaration; import com.github.sommeri.less4j.core.ast.Expression; @@ -34,20 +37,40 @@ public LessToCssCompiler(ProblemsHandler problemsHandler) { public ASTCssNode compileToCss(StyleSheet less) { ScopeExtractor scopeBuilder = new ScopeExtractor(); Scope scope = scopeBuilder.extractScope(less); - + ReferencesSolver referencesSolver = new ReferencesSolver(problemsHandler); referencesSolver.solveReferences(less, scope); - + //just a safety measure evaluateExpressions(less); freeNestedRuleSets(less); + sortTopLevelElements(less); return less; } + private void sortTopLevelElements(StyleSheet less) { + Collections.sort(less.getChilds(), new Comparator() { + + @Override + public int compare(ASTCssNode first, ASTCssNode second) { + return code(first) - code(second); + } + + private int code(ASTCssNode node) { + if (node.getType() == ASTCssNodeType.CHARSET_DECLARATION) + return 0; + if (node.getType() == ASTCssNodeType.IMPORT) + return 1; + + return 2; + } + }); + } + private void freeNestedRuleSets(Body body) { NestedRulesCollector nestedRulesCollector = new NestedRulesCollector(); - + List childs = new ArrayList(body.getChilds()); for (ASTCssNode kid : childs) { switch (kid.getType()) { diff --git a/src/main/java/com/github/sommeri/less4j/core/parser/ASTBuilderSwitch.java b/src/main/java/com/github/sommeri/less4j/core/parser/ASTBuilderSwitch.java index 92f88df6..34a1c2b7 100644 --- a/src/main/java/com/github/sommeri/less4j/core/parser/ASTBuilderSwitch.java +++ b/src/main/java/com/github/sommeri/less4j/core/parser/ASTBuilderSwitch.java @@ -26,6 +26,7 @@ import com.github.sommeri.less4j.core.ast.GuardCondition; import com.github.sommeri.less4j.core.ast.IdSelector; import com.github.sommeri.less4j.core.ast.IdentifierExpression; +import com.github.sommeri.less4j.core.ast.Import; import com.github.sommeri.less4j.core.ast.IndirectVariable; import com.github.sommeri.less4j.core.ast.InterpolableName; import com.github.sommeri.less4j.core.ast.Keyframes; @@ -180,9 +181,9 @@ public IndirectVariable handleIndirectVariable(HiddenTokenAwareTree token) { public Declaration handleDeclaration(HiddenTokenAwareTree token) { Iterator iterator = token.getChildren().iterator(); HiddenTokenAwareTree nameToken = iterator.next(); - + String name = nameToken.getText(); - if (nameToken.getType()==LessLexer.STAR) { + if (nameToken.getType() == LessLexer.STAR) { // handling star prefix browser hack nameToken = iterator.next(); name += nameToken.getText(); @@ -287,7 +288,7 @@ public ReusableStructureName handleReusableStructureName(HiddenTokenAwareTree to } return result; } - + public MixinReference handleMixinReference(HiddenTokenAwareTree token) { MixinReference result = new MixinReference(token); List children = token.getChildren(); @@ -311,7 +312,7 @@ public MixinReference handleMixinReference(HiddenTokenAwareTree token) { public MixinReference handleNamespaceReference(HiddenTokenAwareTree token) { MixinReference reference = null; List nameChain = new ArrayList(); - + List children = token.getChildren(); for (HiddenTokenAwareTree kid : children) { ASTCssNode buildKid = switchOn(kid); @@ -323,7 +324,7 @@ public MixinReference handleNamespaceReference(HiddenTokenAwareTree token) { throw new BugHappened(GRAMMAR_MISMATCH, token); } } - + reference.setUnderlyingStructure(token); reference.addNames(nameChain); return reference; @@ -427,7 +428,7 @@ private List handleBodyMembers(HiddenTokenAwareTree token) { } else { token.addOrphans(lbrace.getFollowing()); } - + while (iterator.hasNext()) { members.add(switchOn(iterator.next())); } @@ -442,15 +443,15 @@ public Selector handleSelector(HiddenTokenAwareTree token) { public CssClass handleCssClass(HiddenTokenAwareTree token) { List children = token.getChildren(); return new CssClass(token, toInterpolableName(token, children)); -// HiddenTokenAwareTree nameToken = children.get(0); -// -// String name = nameToken.getText(); -// if (nameToken.getType() != LessLexer.IDENT && name.length() > 1) { -// name = name.substring(1, name.length()); -// } -// -// CssClass result = new CssClass(token, name); -// return result; + // HiddenTokenAwareTree nameToken = children.get(0); + // + // String name = nameToken.getText(); + // if (nameToken.getType() != LessLexer.IDENT && name.length() > 1) { + // name = name.substring(1, name.length()); + // } + // + // CssClass result = new CssClass(token, name); + // return result; } public SelectorAttribute handleSelectorAttribute(HiddenTokenAwareTree token) { @@ -583,10 +584,10 @@ private InterpolableName toInterpolableName(HiddenTokenAwareTree token, List elementNameParts) { - if (elementNameParts.size()!=1) + if (elementNameParts.size() != 1) return false; - - return elementNameParts.get(0).getType()==LessLexer.STAR; + + return elementNameParts.get(0).getType() == LessLexer.STAR; } public EscapedSelector handleEscapedSelector(HiddenTokenAwareTree token) { token.pushHiddenToKids(); HiddenTokenAwareTree valueToken = token.getChild(0); String quotedText = valueToken.getText(); - return new EscapedSelector(valueToken, quotedText.substring(2, quotedText.length() - 1), ""+quotedText.charAt(1)); + return new EscapedSelector(valueToken, quotedText.substring(2, quotedText.length() - 1), "" + quotedText.charAt(1)); } private boolean isMeaningfullWhitespace(HiddenTokenAwareTree kid) { @@ -813,7 +815,7 @@ public Keyframes handleKeyframes(HiddenTokenAwareTree token) { Keyframes result = new Keyframes(token, children.next().getText()); result.addNames(handleKeyframesDeclaration(children.next())); result.setBody(handleKeyframesBody(children.next())); - + return result; } @@ -831,33 +833,33 @@ private List handleKeyframesDeclaration(HiddenTokenAwareTree decl Iterator iterator = declaration.getChildren().iterator(); while (iterator.hasNext()) { HiddenTokenAwareTree token = iterator.next(); - if (token.getType()==LessLexer.COMMA) { + if (token.getType() == LessLexer.COMMA) { token.pushHiddenToSiblings(); - } else if (token.getType()==LessLexer.IDENT) { + } else if (token.getType() == LessLexer.IDENT) { result.add(new KeyframesName(token, token.getText())); } else { throw new BugHappened(GRAMMAR_MISMATCH, token); } - + } - + return result; } - + public Page handlePage(HiddenTokenAwareTree token) { Page result = new Page(token); List children = token.getChildren(); for (HiddenTokenAwareTree kid : children) { - if (kid.getType()==LessLexer.IDENT) { + if (kid.getType() == LessLexer.IDENT) { result.setName(new Name(kid, kid.getText())); - } else if (kid.getType()==LessLexer.PSEUDO_PAGE) { + } else if (kid.getType() == LessLexer.PSEUDO_PAGE) { int pseudoPageIndex = 1; - if (kid.getChild(0).getType()==LessLexer.MEANINGFULL_WHITESPACE) { + if (kid.getChild(0).getType() == LessLexer.MEANINGFULL_WHITESPACE) { pseudoPageIndex = 2; result.setDockedPseudopage(false); } result.setPseudopage(new Name(kid, ":" + kid.getChild(pseudoPageIndex).getText())); - } else if (kid.getType()==LessLexer.BODY) { + } else if (kid.getType() == LessLexer.BODY) { result.setBody(new GeneralBody(kid, handleBodyMembers(kid))); } else { throw new BugHappened(GRAMMAR_MISMATCH, kid); @@ -870,9 +872,9 @@ public PageMarginBox handlePageMarginBox(HiddenTokenAwareTree token) { PageMarginBox result = new PageMarginBox(token); List children = token.getChildren(); for (HiddenTokenAwareTree kid : children) { - if (kid.getType()==LessLexer.AT_NAME) { + if (kid.getType() == LessLexer.AT_NAME) { result.setName(new Name(kid, kid.getText())); - } else if (kid.getType()==LessLexer.BODY) { + } else if (kid.getType() == LessLexer.BODY) { result.setBody(new GeneralBody(kid, handleBodyMembers(kid))); } else { throw new BugHappened(GRAMMAR_MISMATCH, kid); @@ -881,4 +883,36 @@ public PageMarginBox handlePageMarginBox(HiddenTokenAwareTree token) { return result; } + public Import handleImport(HiddenTokenAwareTree token) { + Import result = new Import(token); + switch (token.getType()) { + case LessLexer.IMPORT_SYM: + result.setKind(Import.ImportKind.IMPORT); + break; + case LessLexer.IMPORT_ONCE_SYM: + result.setKind(Import.ImportKind.IMPORT_ONCE); + break; + case LessLexer.IMPORT_MULTIPLE_SYM: + result.setKind(Import.ImportKind.IMPORT_MULTIPLE); + break; + default: + throw new BugHappened(GRAMMAR_MISMATCH, token); + } + + Iterator children = token.getChildren().iterator(); + result.setUrlExpression(handleTerm(children.next())); + while (children.hasNext()) { + HiddenTokenAwareTree kid = children.next(); + if (kid.getType()==LessLexer.COMMA) { + kid.pushHiddenToSiblings(); + } else if (kid.getType()==LessLexer.MEDIA_QUERY) { + result.add(handleMediaQuery(kid)); + } else { + throw new BugHappened(GRAMMAR_MISMATCH, token); + } + } + + return result; + } + } \ No newline at end of file diff --git a/src/main/java/com/github/sommeri/less4j/core/parser/SuperLessParser.java b/src/main/java/com/github/sommeri/less4j/core/parser/SuperLessParser.java index dde519a3..a416118a 100644 --- a/src/main/java/com/github/sommeri/less4j/core/parser/SuperLessParser.java +++ b/src/main/java/com/github/sommeri/less4j/core/parser/SuperLessParser.java @@ -99,6 +99,8 @@ public class SuperLessParser extends Parser { ALTERNATIVE_NAMES_FOR_ERROR_REPORTING.put("PURE_NUMBER", "number"); ALTERNATIVE_NAMES_FOR_ERROR_REPORTING.put("PSEUDO_PAGE", "pseudo page"); ALTERNATIVE_NAMES_FOR_ERROR_REPORTING.put("PAGE_MARGIN_BOX", "page margin box"); + ALTERNATIVE_NAMES_FOR_ERROR_REPORTING.put("IMPORT_ONCE_SYM", "@import-once"); + ALTERNATIVE_NAMES_FOR_ERROR_REPORTING.put("IMPORT_MULTIPLE_SYM", "@import-multiple"); } protected static final String RULE_STYLESHEET = "stylesheet"; diff --git a/src/main/java/com/github/sommeri/less4j/core/parser/TokenTypeSwitch.java b/src/main/java/com/github/sommeri/less4j/core/parser/TokenTypeSwitch.java index ac5c6c16..92b9f699 100644 --- a/src/main/java/com/github/sommeri/less4j/core/parser/TokenTypeSwitch.java +++ b/src/main/java/com/github/sommeri/less4j/core/parser/TokenTypeSwitch.java @@ -138,9 +138,14 @@ public T switchOn(HiddenTokenAwareTree token) { if (type == LessLexer.PAGE_MARGIN_BOX) return handlePageMarginBox(token); + if (type == LessLexer.IMPORT_SYM | type == LessLexer.IMPORT_ONCE_SYM |type == LessLexer.IMPORT_MULTIPLE_SYM) + return handleImport(token); + throw new BugHappened("Unexpected token type: " + type +"("+PrintUtils.toName(type)+ ") for " + token.getText(), token); } + public abstract T handleImport(HiddenTokenAwareTree token); + public abstract T handlePageMarginBox(HiddenTokenAwareTree token); public abstract T handlePage(HiddenTokenAwareTree token); diff --git a/src/main/java/com/github/sommeri/less4j/utils/CssPrinter.java b/src/main/java/com/github/sommeri/less4j/utils/CssPrinter.java index a87c3bfc..052dc7b0 100644 --- a/src/main/java/com/github/sommeri/less4j/utils/CssPrinter.java +++ b/src/main/java/com/github/sommeri/less4j/utils/CssPrinter.java @@ -25,6 +25,7 @@ import com.github.sommeri.less4j.core.ast.FunctionExpression; import com.github.sommeri.less4j.core.ast.IdSelector; import com.github.sommeri.less4j.core.ast.IdentifierExpression; +import com.github.sommeri.less4j.core.ast.Import; import com.github.sommeri.less4j.core.ast.Keyframes; import com.github.sommeri.less4j.core.ast.KeyframesBody; import com.github.sommeri.less4j.core.ast.KeyframesName; @@ -211,6 +212,9 @@ public boolean switchOnType(ASTCssNode node) { case NAME: return appendName((Name) node); + case IMPORT: + return appendImport((Import) node); + case PARENTHESES_EXPRESSION: case SIGNED_EXPRESSION: case VARIABLE: @@ -223,6 +227,15 @@ public boolean switchOnType(ASTCssNode node) { } } + private boolean appendImport(Import node) { + builder.append("@import").ensureSeparator(); + append(node.getUrlExpression()); + appendMediums(node.getMediums()); + builder.append(";"); + + return true; + } + private boolean appendName(Name node) { builder.append(node.getName()); return true; diff --git a/src/test/java/com/github/sommeri/less4j/compiler/ImportsTest.java b/src/test/java/com/github/sommeri/less4j/compiler/ImportsTest.java new file mode 100644 index 00000000..98718d28 --- /dev/null +++ b/src/test/java/com/github/sommeri/less4j/compiler/ImportsTest.java @@ -0,0 +1,23 @@ +package com.github.sommeri.less4j.compiler; + +import java.io.File; +import java.util.Collection; + +import org.junit.runners.Parameterized.Parameters; + +import com.github.sommeri.less4j.utils.TestFileUtils; + +public class ImportsTest extends BasicFeaturesTest { + + private static final String standardCases = "src/test/resources/compile-basic-features/import/"; + + public ImportsTest(File inputFile, File outputFile, String testName) { + super(inputFile, outputFile, testName); + } + + @Parameters() + public static Collection allTestsParameters() { + return (new TestFileUtils()).loadTestFiles(standardCases); + } + +} diff --git a/src/test/resources/compile-basic-features/import/import-css-files.css b/src/test/resources/compile-basic-features/import/import-css-files.css new file mode 100644 index 00000000..b18744b4 --- /dev/null +++ b/src/test/resources/compile-basic-features/import/import-css-files.css @@ -0,0 +1,27 @@ +@import "import\some-file-1.css" screen and (max-width: 400px); +@import 'import\some-file-2.css' handheld; +@import url("import\some-file-3.css?id=123"); +@import url('import\some-file-4.css'); +@import url(import\some-file-5.css); +@import "import\some-file-once-1.css" screen and (max-width: 400px); +@import 'import\some-file-once-2.css' handheld; +@import url("import\some-file-once-3.css?id=123"); +@import url('import\some-file-once-4.css'); +@import url(import\some-file-once-5.css); +@import "import\some-file-multiple-1.css" screen and (max-width: 400px); +@import 'import\some-file-multiple-2.css' handheld; +@import url("import\some-file-multiple-3.css?id=123"); +@import url('import\some-file-multiple-4.css'); +@import url(import\some-file-multiple-5.css); +h1 { + color: red; +} +#namespace { + @import "import\some-file-6.css"; +} +#namespace { + @import "import\some-file-once-6.css"; +} +#namespace { + @import "import\some-file-multiple-6.css"; +} \ No newline at end of file diff --git a/src/test/resources/compile-basic-features/import/import-css-files.less b/src/test/resources/compile-basic-features/import/import-css-files.less new file mode 100644 index 00000000..3f628667 --- /dev/null +++ b/src/test/resources/compile-basic-features/import/import-css-files.less @@ -0,0 +1,33 @@ +h1 { + color: red; +} + +@import "import\some-file-1.css" screen and (max-width: 400px); +@import 'import\some-file-2.css' handheld; +@import url("import\some-file-3.css?id=123"); +@import url('import\some-file-4.css'); +@import url(import\some-file-5.css); + +#namespace { + @import "import\some-file-6.css"; +} + +@import-once "import\some-file-once-1.css" screen and (max-width: 400px); +@import-once 'import\some-file-once-2.css' handheld; +@import-once url("import\some-file-once-3.css?id=123"); +@import-once url('import\some-file-once-4.css'); +@import-once url(import\some-file-once-5.css); + +#namespace { + @import-once "import\some-file-once-6.css"; +} + +@import-multiple "import\some-file-multiple-1.css" screen and (max-width: 400px); +@import-multiple 'import\some-file-multiple-2.css' handheld; +@import-multiple url("import\some-file-multiple-3.css?id=123"); +@import-multiple url('import\some-file-multiple-4.css'); +@import-multiple url(import\some-file-multiple-5.css); + +#namespace { + @import-multiple "import\some-file-multiple-6.css"; +} diff --git a/src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.css b/src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.css deleted file mode 100644 index 1de6b53d..00000000 --- a/src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.css +++ /dev/null @@ -1,8 +0,0 @@ -@page { - @top-left { - margin-left: 3cm; - } - @bottom-center { - margin-left: 3cm; - } -} diff --git a/src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.less b/src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.less deleted file mode 100644 index 1de6b53d..00000000 --- a/src/test/resources/w3c-specifications/CSS Paged Media Module Level 3/debug.less +++ /dev/null @@ -1,8 +0,0 @@ -@page { - @top-left { - margin-left: 3cm; - } - @bottom-center { - margin-left: 3cm; - } -}