Index: packages/csslib/lib/src/tree.dart |
diff --git a/packages/csslib/lib/src/tree.dart b/packages/csslib/lib/src/tree.dart |
index ba8370e96b1b1a65acb8fcca5de95fb3a2d047ac..509e708fb372d752f69b023962c8cd66485ef67c 100644 |
--- a/packages/csslib/lib/src/tree.dart |
+++ b/packages/csslib/lib/src/tree.dart |
@@ -120,12 +120,28 @@ class SimpleSelectorSequence extends TreeNode { |
bool get isCombinatorTilde => combinator == TokenKind.COMBINATOR_TILDE; |
bool get isCombinatorDescendant => |
combinator == TokenKind.COMBINATOR_DESCENDANT; |
- |
- String get _combinatorToString => isCombinatorDescendant |
- ? ' ' |
- : isCombinatorPlus |
- ? ' + ' |
- : isCombinatorGreater ? ' > ' : isCombinatorTilde ? ' ~ ' : ''; |
+ bool get isCombinatorDeep => combinator == TokenKind.COMBINATOR_DEEP; |
+ bool get isCombinatorShadowPiercingDescendant => |
+ combinator == TokenKind.COMBINATOR_SHADOW_PIERCING_DESCENDANT; |
+ |
+ String get _combinatorToString { |
+ switch (combinator) { |
+ case TokenKind.COMBINATOR_SHADOW_PIERCING_DESCENDANT: |
+ return ' >>> '; |
+ case TokenKind.COMBINATOR_DEEP: |
+ return ' /deep/ '; |
+ case TokenKind.COMBINATOR_DESCENDANT: |
+ return ' '; |
+ case TokenKind.COMBINATOR_GREATER: |
+ return ' > '; |
+ case TokenKind.COMBINATOR_PLUS: |
+ return ' + '; |
+ case TokenKind.COMBINATOR_TILDE: |
+ return ' ~ '; |
+ default: |
+ return ''; |
+ } |
+ } |
SimpleSelectorSequence clone() => |
new SimpleSelectorSequence(simpleSelector, span, combinator); |
@@ -283,23 +299,32 @@ class PseudoClassSelector extends SimpleSelector { |
// ::pseudoElement |
class PseudoElementSelector extends SimpleSelector { |
- PseudoElementSelector(Identifier name, SourceSpan span) : super(name, span); |
+ // If true, this is a CSS2.1 pseudo-element with only a single ':'. |
+ final bool isLegacy; |
+ |
+ PseudoElementSelector(Identifier name, SourceSpan span, |
+ {this.isLegacy: false}) |
+ : super(name, span); |
visit(VisitorBase visitor) => visitor.visitPseudoElementSelector(this); |
PseudoElementSelector clone() => new PseudoElementSelector(_name, span); |
- String toString() => "::$name"; |
+ String toString() => "${isLegacy ? ':' : '::'}$name"; |
} |
-// :pseudoClassFunction(expression) |
+// :pseudoClassFunction(argument) |
class PseudoClassFunctionSelector extends PseudoClassSelector { |
- final SelectorExpression expression; |
+ final TreeNode _argument; // Selector, SelectorExpression |
- PseudoClassFunctionSelector(Identifier name, this.expression, SourceSpan span) |
+ PseudoClassFunctionSelector(Identifier name, this._argument, SourceSpan span) |
: super(name, span); |
PseudoClassFunctionSelector clone() => |
- new PseudoClassFunctionSelector(_name, expression, span); |
+ new PseudoClassFunctionSelector(_name, _argument, span); |
+ |
+ TreeNode get argument => _argument; |
+ Selector get selector => _argument as Selector; |
+ SelectorExpression get expression => _argument as SelectorExpression; |
visit(VisitorBase visitor) => visitor.visitPseudoClassFunctionSelector(this); |
} |
@@ -410,6 +435,124 @@ class Directive extends TreeNode { |
visit(VisitorBase visitor) => visitor.visitDirective(this); |
} |
+class DocumentDirective extends Directive { |
+ final List<LiteralTerm> functions; |
+ final List<TreeNode> groupRuleBody; |
+ |
+ DocumentDirective(this.functions, this.groupRuleBody, SourceSpan span) |
+ : super(span); |
+ |
+ DocumentDirective clone() { |
+ var clonedFunctions = <LiteralTerm>[]; |
+ for (var function in functions) { |
+ clonedFunctions.add(function.clone()); |
+ } |
+ var clonedGroupRuleBody = <TreeNode>[]; |
+ for (var rule in groupRuleBody) { |
+ clonedGroupRuleBody.add(rule.clone()); |
+ } |
+ return new DocumentDirective(clonedFunctions, clonedGroupRuleBody, span); |
+ } |
+ |
+ visit(VisitorBase visitor) => visitor.visitDocumentDirective(this); |
+} |
+ |
+class SupportsDirective extends Directive { |
+ final SupportsCondition condition; |
+ final List<TreeNode> groupRuleBody; |
+ |
+ SupportsDirective(this.condition, this.groupRuleBody, SourceSpan span) |
+ : super(span); |
+ |
+ SupportsDirective clone() { |
+ var clonedCondition = condition.clone(); |
+ var clonedGroupRuleBody = <TreeNode>[]; |
+ for (var rule in groupRuleBody) { |
+ clonedGroupRuleBody.add(rule.clone()); |
+ } |
+ return new SupportsDirective(clonedCondition, clonedGroupRuleBody, span); |
+ } |
+ |
+ visit(VisitorBase visitor) => visitor.visitSupportsDirective(this); |
+} |
+ |
+abstract class SupportsCondition extends TreeNode { |
+ SupportsCondition(SourceSpan span) : super(span); |
+} |
+ |
+class SupportsConditionInParens extends SupportsCondition { |
+ /// A [Declaration] or nested [SupportsCondition]. |
+ final TreeNode condition; |
+ |
+ SupportsConditionInParens(Declaration declaration, SourceSpan span) |
+ : condition = declaration, |
+ super(span); |
+ |
+ SupportsConditionInParens.nested(SupportsCondition condition, SourceSpan span) |
+ : condition = condition, |
+ super(span); |
+ |
+ SupportsConditionInParens clone() => |
+ new SupportsConditionInParens(condition.clone(), span); |
+ |
+ visit(VisitorBase visitor) => visitor.visitSupportsConditionInParens(this); |
+} |
+ |
+class SupportsNegation extends SupportsCondition { |
+ final SupportsConditionInParens condition; |
+ |
+ SupportsNegation(this.condition, SourceSpan span) : super(span); |
+ |
+ SupportsNegation clone() => new SupportsNegation(condition.clone(), span); |
+ |
+ visit(VisitorBase visitor) => visitor.visitSupportsNegation(this); |
+} |
+ |
+class SupportsConjunction extends SupportsCondition { |
+ final List<SupportsConditionInParens> conditions; |
+ |
+ SupportsConjunction(this.conditions, SourceSpan span) : super(span); |
+ |
+ SupportsConjunction clone() { |
+ var clonedConditions = <SupportsCondition>[]; |
+ for (var condition in conditions) { |
+ clonedConditions.add(condition.clone()); |
+ } |
+ return new SupportsConjunction(clonedConditions, span); |
+ } |
+ |
+ visit(VisitorBase visitor) => visitor.visitSupportsConjunction(this); |
+} |
+ |
+class SupportsDisjunction extends SupportsCondition { |
+ final List<SupportsConditionInParens> conditions; |
+ |
+ SupportsDisjunction(this.conditions, SourceSpan span) : super(span); |
+ |
+ SupportsDisjunction clone() { |
+ var clonedConditions = <SupportsCondition>[]; |
+ for (var condition in conditions) { |
+ clonedConditions.add(condition.clone()); |
+ } |
+ return new SupportsDisjunction(clonedConditions, span); |
+ } |
+ |
+ visit(VisitorBase visitor) => visitor.visitSupportsDisjunction(this); |
+} |
+ |
+class ViewportDirective extends Directive { |
+ final String name; |
+ final DeclarationGroup declarations; |
+ |
+ ViewportDirective(this.name, this.declarations, SourceSpan span) |
+ : super(span); |
+ |
+ ViewportDirective clone() => |
+ new ViewportDirective(name, declarations.clone(), span); |
+ |
+ visit(VisitorBase visitor) => visitor.visitViewportDirective(this); |
+} |
+ |
class ImportDirective extends Directive { |
/** import name specified. */ |
final String import; |
@@ -421,7 +564,7 @@ class ImportDirective extends Directive { |
: super(span); |
ImportDirective clone() { |
- var cloneMediaQueries = []; |
+ var cloneMediaQueries = <MediaQuery>[]; |
for (var mediaQuery in mediaQueries) { |
cloneMediaQueries.add(mediaQuery.clone()); |
} |
@@ -483,12 +626,13 @@ class MediaQuery extends TreeNode { |
TokenKind.idToValue(TokenKind.MEDIA_OPERATORS, _mediaUnary).toUpperCase(); |
MediaQuery clone() { |
- var cloneExpressions = []; |
+ var cloneExpressions = <MediaExpression>[]; |
for (var expr in expressions) { |
cloneExpressions.add(expr.clone()); |
} |
return new MediaQuery(_mediaUnary, _mediaType, cloneExpressions, span); |
} |
+ |
visit(VisitorBase visitor) => visitor.visitMediaQuery(this); |
} |
@@ -500,11 +644,11 @@ class MediaDirective extends Directive { |
: super(span); |
MediaDirective clone() { |
- var cloneQueries = []; |
+ var cloneQueries = <MediaQuery>[]; |
for (var mediaQuery in mediaQueries) { |
cloneQueries.add(mediaQuery.clone()); |
} |
- var cloneRulesets = []; |
+ var cloneRulesets = <RuleSet>[]; |
for (var ruleset in rulesets) { |
cloneRulesets.add(ruleset.clone()); |
} |
@@ -520,7 +664,7 @@ class HostDirective extends Directive { |
HostDirective(this.rulesets, SourceSpan span) : super(span); |
HostDirective clone() { |
- var cloneRulesets = []; |
+ var cloneRulesets = <RuleSet>[]; |
for (var ruleset in rulesets) { |
cloneRulesets.add(ruleset.clone()); |
} |
@@ -540,7 +684,7 @@ class PageDirective extends Directive { |
: super(span); |
PageDirective clone() { |
- var cloneDeclsMargin = []; |
+ var cloneDeclsMargin = <DeclarationGroup>[]; |
for (var declMargin in _declsMargin) { |
cloneDeclsMargin.add(declMargin.clone()); |
} |
@@ -599,6 +743,7 @@ class KeyFrameDirective extends Directive { |
} |
return new KeyFrameDirective(_keyframeName, cloneBlocks, span); |
} |
+ |
visit(VisitorBase visitor) => visitor.visitKeyFrameDirective(this); |
} |
@@ -635,7 +780,7 @@ class StyletDirective extends Directive { |
bool get isExtension => true; |
StyletDirective clone() { |
- var cloneRulesets = []; |
+ var cloneRulesets = <RuleSet>[]; |
for (var ruleset in rulesets) { |
cloneRulesets.add(ruleset.clone()); |
} |
@@ -675,14 +820,14 @@ class VarDefinitionDirective extends Directive { |
class MixinDefinition extends Directive { |
final String name; |
- final List definedArgs; |
+ final List<TreeNode> definedArgs; |
final bool varArgs; |
MixinDefinition(this.name, this.definedArgs, this.varArgs, SourceSpan span) |
: super(span); |
MixinDefinition clone() { |
- var cloneDefinedArgs = []; |
+ var cloneDefinedArgs = <TreeNode>[]; |
for (var definedArg in definedArgs) { |
cloneDefinedArgs.add(definedArg.clone()); |
} |
@@ -694,18 +839,18 @@ class MixinDefinition extends Directive { |
/** Support a Sass @mixin. See http://sass-lang.com for description. */ |
class MixinRulesetDirective extends MixinDefinition { |
- final List rulesets; |
+ final List<TreeNode> rulesets; |
- MixinRulesetDirective(String name, List<VarDefinitionDirective> args, |
- bool varArgs, this.rulesets, SourceSpan span) |
+ MixinRulesetDirective(String name, List<TreeNode> args, bool varArgs, |
+ this.rulesets, SourceSpan span) |
: super(name, args, varArgs, span); |
MixinRulesetDirective clone() { |
- var clonedArgs = []; |
+ var clonedArgs = <VarDefinition>[]; |
for (var arg in definedArgs) { |
clonedArgs.add(arg.clone()); |
} |
- var clonedRulesets = []; |
+ var clonedRulesets = <TreeNode>[]; |
for (var ruleset in rulesets) { |
clonedRulesets.add(ruleset.clone()); |
} |
@@ -719,12 +864,12 @@ class MixinRulesetDirective extends MixinDefinition { |
class MixinDeclarationDirective extends MixinDefinition { |
final DeclarationGroup declarations; |
- MixinDeclarationDirective(String name, List<VarDefinitionDirective> args, |
- bool varArgs, this.declarations, SourceSpan span) |
+ MixinDeclarationDirective(String name, List<TreeNode> args, bool varArgs, |
+ this.declarations, SourceSpan span) |
: super(name, args, varArgs, span); |
MixinDeclarationDirective clone() { |
- var clonedArgs = []; |
+ var clonedArgs = <TreeNode>[]; |
for (var arg in definedArgs) { |
clonedArgs.add(arg.clone()); |
} |
@@ -738,16 +883,14 @@ class MixinDeclarationDirective extends MixinDefinition { |
/** To support consuming a SASS mixin @include. */ |
class IncludeDirective extends Directive { |
final String name; |
- final List<List<TreeNode>> args; |
+ final List<List<Expression>> args; |
IncludeDirective(this.name, this.args, SourceSpan span) : super(span); |
IncludeDirective clone() { |
- var cloneArgs = []; |
+ var cloneArgs = <List<Expression>>[]; |
for (var arg in args) { |
- for (var term in arg) { |
- cloneArgs.add(term.clone()); |
- } |
+ cloneArgs.add(arg.map((term) => term.clone()).toList()); |
} |
return new IncludeDirective(name, cloneArgs, span); |
} |
@@ -790,9 +933,9 @@ class Declaration extends TreeNode { |
bool get hasDartStyle => dartStyle != null; |
- Declaration clone() => new Declaration( |
- _property.clone(), _expression.clone(), dartStyle, span, |
- important: important); |
+ Declaration clone() => |
+ new Declaration(_property.clone(), _expression.clone(), dartStyle, span, |
+ important: important); |
visit(VisitorBase visitor) => visitor.visitDeclaration(this); |
} |
@@ -852,7 +995,7 @@ class ExtendDeclaration extends Declaration { |
class DeclarationGroup extends TreeNode { |
/** Can be either Declaration or RuleSet (if nested selector). */ |
- final List declarations; |
+ final List<TreeNode> declarations; |
DeclarationGroup(this.declarations, SourceSpan span) : super(span); |
@@ -867,10 +1010,10 @@ class DeclarationGroup extends TreeNode { |
class MarginGroup extends DeclarationGroup { |
final int margin_sym; // TokenType for for @margin sym. |
- MarginGroup(this.margin_sym, List<Declaration> decls, SourceSpan span) |
+ MarginGroup(this.margin_sym, List<TreeNode> decls, SourceSpan span) |
: super(decls, span); |
MarginGroup clone() => |
- new MarginGroup(margin_sym, super.clone() as dynamic, span); |
+ new MarginGroup(margin_sym, super.clone().declarations, span); |
visit(VisitorBase visitor) => visitor.visitMarginGroup(this); |
} |
@@ -881,7 +1024,7 @@ class VarUsage extends Expression { |
VarUsage(this.name, this.defaultValues, SourceSpan span) : super(span); |
VarUsage clone() { |
- var clonedValues = []; |
+ var clonedValues = <Expression>[]; |
for (var expr in defaultValues) { |
clonedValues.add(expr.clone()); |
} |
@@ -1165,6 +1308,7 @@ class Expressions extends Expression { |
} |
return clonedExprs; |
} |
+ |
visit(VisitorBase visitor) => visitor.visitExpressions(this); |
} |
@@ -1231,15 +1375,20 @@ class FontExpression extends DartStyleExpression { |
// font-style font-variant font-weight font-size/line-height font-family |
// TODO(terry): Only px/pt for now need to handle all possible units to |
// support calc expressions on units. |
- FontExpression(SourceSpan span, {dynamic size, List<String> family, |
- int weight, String style, String variant, LineHeight lineHeight}) |
+ FontExpression(SourceSpan span, |
+ {dynamic size, |
+ List<String> family, |
+ int weight, |
+ String style, |
+ String variant, |
+ LineHeight lineHeight}) |
: font = new Font( |
- size: size is LengthTerm ? size.value : size, |
- family: family, |
- weight: weight, |
- style: style, |
- variant: variant, |
- lineHeight: lineHeight), |
+ size: size is LengthTerm ? size.value : size, |
+ family: family, |
+ weight: weight, |
+ style: style, |
+ variant: variant, |
+ lineHeight: lineHeight), |
super(DartStyleExpression.fontStyle, span); |
FontExpression merged(DartStyleExpression newFontExpr) { |
@@ -1297,7 +1446,7 @@ class MarginExpression extends BoxExpression { |
/** Margin expression ripped apart. */ |
MarginExpression(SourceSpan span, {num top, num right, num bottom, num left}) |
: super(DartStyleExpression.marginStyle, span, |
- new BoxEdge(left, top, right, bottom)); |
+ new BoxEdge(left, top, right, bottom)); |
MarginExpression.boxEdge(SourceSpan span, BoxEdge box) |
: super(DartStyleExpression.marginStyle, span, box); |
@@ -1333,7 +1482,7 @@ class BorderExpression extends BoxExpression { |
/** Border expression ripped apart. */ |
BorderExpression(SourceSpan span, {num top, num right, num bottom, num left}) |
: super(DartStyleExpression.borderStyle, span, |
- new BoxEdge(left, top, right, bottom)); |
+ new BoxEdge(left, top, right, bottom)); |
BorderExpression.boxEdge(SourceSpan span, BoxEdge box) |
: super(DartStyleExpression.borderStyle, span, box); |
@@ -1358,7 +1507,7 @@ class BorderExpression extends BoxExpression { |
BorderExpression._merge( |
BorderExpression x, BorderExpression y, SourceSpan span) |
: super(DartStyleExpression.borderStyle, span, |
- new BoxEdge.merge(x.box, y.box)); |
+ new BoxEdge.merge(x.box, y.box)); |
BorderExpression clone() => new BorderExpression(span, |
top: box.top, right: box.right, bottom: box.bottom, left: box.left); |
@@ -1410,7 +1559,7 @@ class PaddingExpression extends BoxExpression { |
/** Padding expression ripped apart. */ |
PaddingExpression(SourceSpan span, {num top, num right, num bottom, num left}) |
: super(DartStyleExpression.paddingStyle, span, |
- new BoxEdge(left, top, right, bottom)); |
+ new BoxEdge(left, top, right, bottom)); |
PaddingExpression.boxEdge(SourceSpan span, BoxEdge box) |
: super(DartStyleExpression.paddingStyle, span, box); |
@@ -1435,7 +1584,7 @@ class PaddingExpression extends BoxExpression { |
PaddingExpression._merge( |
PaddingExpression x, PaddingExpression y, SourceSpan span) |
: super(DartStyleExpression.paddingStyle, span, |
- new BoxEdge.merge(x.box, y.box)); |
+ new BoxEdge.merge(x.box, y.box)); |
PaddingExpression clone() => new PaddingExpression(span, |
top: box.top, right: box.right, bottom: box.bottom, left: box.left); |