// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library csslib.visitor; import 'package:source_maps/span.dart' show Span; import 'parser.dart'; part 'src/css_printer.dart'; part 'src/tree.dart'; part 'src/tree_base.dart'; part 'src/tree_printer.dart'; abstract class VisitorBase { void visitCssComment(CssComment node); void visitCommentDefinition(CommentDefinition node); void visitStyleSheet(StyleSheet node); void visitTopLevelProduction(TopLevelProduction node); void visitDirective(Directive node); void visitMediaExpression(MediaExpression node); void visitMediaQuery(MediaQuery node); void visitMediaDirective(MediaDirective node); void visitHostDirective(HostDirective node); void visitPageDirective(PageDirective node); void visitCharsetDirective(CharsetDirective node); void visitImportDirective(ImportDirective node); void visitKeyFrameDirective(KeyFrameDirective node); void visitKeyFrameBlock(KeyFrameBlock node); void visitFontFaceDirective(FontFaceDirective node); void visitStyletDirective(StyletDirective node); void visitNamespaceDirective(NamespaceDirective node); void visitVarDefinitionDirective(VarDefinitionDirective node); void visitRuleSet(RuleSet node); void visitDeclarationGroup(DeclarationGroup node); void visitMarginGroup(DeclarationGroup node); void visitDeclaration(Declaration node); void visitVarDefinition(VarDefinition node); void visitSelectorGroup(SelectorGroup node); void visitSelector(Selector node); void visitSimpleSelectorSequence(SimpleSelectorSequence node); void visitSimpleSelector(SimpleSelector node); void visitElementSelector(ElementSelector node); void visitNamespaceSelector(NamespaceSelector node); void visitAttributeSelector(AttributeSelector node); void visitIdSelector(IdSelector node); void visitClassSelector(ClassSelector node); void visitPseudoClassSelector(PseudoClassSelector node); void visitPseudoElementSelector(PseudoElementSelector node); void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node); void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node); void visitNegationSelector(NegationSelector node); void visitSelectorExpression(SelectorExpression node); void visitUnicodeRangeTerm(UnicodeRangeTerm node); void visitLiteralTerm(LiteralTerm node); void visitHexColorTerm(HexColorTerm node); void visitNumberTerm(NumberTerm node); void visitUnitTerm(UnitTerm node); void visitLengthTerm(LengthTerm node); void visitPercentageTerm(PercentageTerm node); void visitEmTerm(EmTerm node); void visitExTerm(ExTerm node); void visitAngleTerm(AngleTerm node); void visitTimeTerm(TimeTerm node); void visitFreqTerm(FreqTerm node); void visitFractionTerm(FractionTerm node); void visitUriTerm(UriTerm node); void visitResolutionTerm(ResolutionTerm node); void visitChTerm(ChTerm node); void visitRemTerm(RemTerm node); void visitViewportTerm(ViewportTerm node); void visitFunctionTerm(FunctionTerm node); void visitGroupTerm(GroupTerm node); void visitItemTerm(ItemTerm node); void visitIE8Term(IE8Term node); void visitOperatorSlash(OperatorSlash node); void visitOperatorComma(OperatorComma node); void visitOperatorPlus(OperatorPlus node); void visitOperatorMinus(OperatorMinus node); void visitVarUsage(VarUsage node); void visitExpressions(Expressions node); void visitBinaryExpression(BinaryExpression node); void visitUnaryExpression(UnaryExpression node); void visitIdentifier(Identifier node); void visitWildcard(Wildcard node); void visitThisOperator(ThisOperator node); void visitNegation(Negation node); void visitDartStyleExpression(DartStyleExpression node); void visitFontExpression(FontExpression node); void visitBoxExpression(BoxExpression node); void visitMarginExpression(MarginExpression node); void visitBorderExpression(BorderExpression node); void visitHeightExpression(HeightExpression node); void visitPaddingExpression(PaddingExpression node); void visitWidthExpression(WidthExpression node); } /** Base vistor class for the style sheet AST. */ class Visitor implements VisitorBase { /** Helper function to walk a list of nodes. */ void _visitNodeList(list) { // Don't use iterable otherwise the list can't grow while using Visitor. // It certainly can't have items deleted before the index being iterated // but items could be added after the index. for (var index = 0; index < list.length; index++) { list[index].visit(this); } } void visitTree(StyleSheet tree) => visitStyleSheet(tree); void visitStyleSheet(StyleSheet ss) { _visitNodeList(ss.topLevels); } void visitTopLevelProduction(TopLevelProduction node) { } void visitDirective(Directive node) { } void visitCssComment(CssComment node) { } void visitCommentDefinition(CommentDefinition node) { } void visitMediaExpression(MediaExpression node) { visitExpressions(node.exprs); } void visitMediaQuery(MediaQuery node) { for (var mediaExpr in node.expressions) { visitMediaExpression(mediaExpr); } } void visitMediaDirective(MediaDirective node) { for (var mediaQuery in node.mediaQueries) { visitMediaQuery(mediaQuery); } for (var ruleset in node.rulesets) { visitRuleSet(ruleset); } } void visitHostDirective(HostDirective node) { for (var ruleset in node.rulesets) { visitRuleSet(ruleset); } } void visitPageDirective(PageDirective node) { for (var declGroup in node._declsMargin) { if (declGroup is MarginGroup) { visitMarginGroup(declGroup); } else { visitDeclarationGroup(declGroup); } } } void visitCharsetDirective(CharsetDirective node) { } void visitImportDirective(ImportDirective node) { for (var mediaQuery in node.mediaQueries) { visitMediaQuery(mediaQuery); } } void visitKeyFrameDirective(KeyFrameDirective node) { visitIdentifier(node._name); _visitNodeList(node._blocks); } void visitKeyFrameBlock(KeyFrameBlock node) { visitExpressions(node._blockSelectors); visitDeclarationGroup(node._declarations); } void visitFontFaceDirective(FontFaceDirective node) { visitDeclarationGroup(node._declarations); } void visitStyletDirective(StyletDirective node) { _visitNodeList(node._rulesets); } void visitNamespaceDirective(NamespaceDirective node) { } void visitVarDefinitionDirective(VarDefinitionDirective node) { visitVarDefinition(node.def); } void visitRuleSet(RuleSet node) { visitSelectorGroup(node._selectorGroup); visitDeclarationGroup(node._declarationGroup); } void visitDeclarationGroup(DeclarationGroup node) { _visitNodeList(node._declarations); } void visitMarginGroup(MarginGroup node) => visitDeclarationGroup(node); void visitDeclaration(Declaration node) { visitIdentifier(node._property); if (node._expression != null) node._expression.visit(this); } void visitVarDefinition(VarDefinition node) { visitIdentifier(node._property); if (node._expression != null) node._expression.visit(this); } void visitSelectorGroup(SelectorGroup node) { _visitNodeList(node.selectors); } void visitSelector(Selector node) { _visitNodeList(node._simpleSelectorSequences); } void visitSimpleSelectorSequence(SimpleSelectorSequence node) { var selector = node._selector; if (selector is NamespaceSelector) { visitNamespaceSelector(selector); } else if (selector is ElementSelector) { visitElementSelector(selector); } else if (selector is IdSelector) { visitIdSelector(selector); } else if (selector is ClassSelector) { visitClassSelector(selector); } else if (selector is PseudoClassFunctionSelector) { visitPseudoClassFunctionSelector(selector); } else if (selector is PseudoElementFunctionSelector) { visitPseudoElementFunctionSelector(selector); } else if (selector is PseudoClassSelector) { visitPseudoClassSelector(selector); } else if (selector is PseudoElementSelector) { visitPseudoElementSelector(selector); } else if (selector is NegationSelector) { visitNegationSelector(selector); } else if (selector is SelectorExpression) { visitSelectorExpression(selector); } else if (selector is AttributeSelector) { visitAttributeSelector(selector); } else { visitSimpleSelector(selector); } } void visitSimpleSelector(SimpleSelector node) => node._name.visit(this); void visitNamespaceSelector(NamespaceSelector node) { var namespace = node._namespace; if (namespace is Identifier) { visitIdentifier(namespace); } else if (namespace is Wildcard) { visitWildcard(namespace); } visitSimpleSelector(node.nameAsSimpleSelector); } void visitElementSelector(ElementSelector node) => visitSimpleSelector(node); void visitAttributeSelector(AttributeSelector node) { visitSimpleSelector(node); } void visitIdSelector(IdSelector node) => visitSimpleSelector(node); void visitClassSelector(ClassSelector node) => visitSimpleSelector(node); void visitPseudoClassSelector(PseudoClassSelector node) => visitSimpleSelector(node); void visitPseudoElementSelector(PseudoElementSelector node) => visitSimpleSelector(node); void visitPseudoClassFunctionSelector(PseudoClassFunctionSelector node) => visitSimpleSelector(node); void visitPseudoElementFunctionSelector(PseudoElementFunctionSelector node) => visitSimpleSelector(node); void visitNegationSelector(NegationSelector node) => visitSimpleSelector(node); void visitSelectorExpression(SelectorExpression node) { _visitNodeList(node._expressions); } void visitUnicodeRangeTerm(UnicodeRangeTerm node) { } void visitLiteralTerm(LiteralTerm node) { } void visitHexColorTerm(HexColorTerm node) { } void visitNumberTerm(NumberTerm node) { } void visitUnitTerm(UnitTerm node) { } void visitLengthTerm(LengthTerm node) { visitUnitTerm(node); } void visitPercentageTerm(PercentageTerm node) { visitLiteralTerm(node); } void visitEmTerm(EmTerm node) { visitLiteralTerm(node); } void visitExTerm(ExTerm node) { visitLiteralTerm(node); } void visitAngleTerm(AngleTerm node) { visitUnitTerm(node); } void visitTimeTerm(TimeTerm node) { visitUnitTerm(node); } void visitFreqTerm(FreqTerm node) { visitUnitTerm(node); } void visitFractionTerm(FractionTerm node) { visitLiteralTerm(node); } void visitUriTerm(UriTerm node) { visitLiteralTerm(node); } void visitResolutionTerm(ResolutionTerm node) { visitUnitTerm(node); } void visitChTerm(ChTerm node) { visitUnitTerm(node); } void visitRemTerm(RemTerm node) { visitUnitTerm(node); } void visitViewportTerm(ViewportTerm node) { visitUnitTerm(node); } void visitFunctionTerm(FunctionTerm node) { visitLiteralTerm(node); visitExpressions(node._params); } void visitGroupTerm(GroupTerm node) { for (var term in node._terms) { term.visit(this); } } void visitItemTerm(ItemTerm node) { visitNumberTerm(node); } void visitIE8Term(IE8Term node) { } void visitOperatorSlash(OperatorSlash node) { } void visitOperatorComma(OperatorComma node) { } void visitOperatorPlus(OperatorPlus node) { } void visitOperatorMinus(OperatorMinus node) { } void visitVarUsage(VarUsage node) { _visitNodeList(node.defaultValues); } void visitExpressions(Expressions node) { _visitNodeList(node.expressions); } void visitBinaryExpression(BinaryExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitUnaryExpression(UnaryExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitIdentifier(Identifier node) { } void visitWildcard(Wildcard node) { } void visitThisOperator(ThisOperator node) { } void visitNegation(Negation node) { } void visitDartStyleExpression(DartStyleExpression node) { } void visitFontExpression(FontExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitBoxExpression(BoxExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitMarginExpression(MarginExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitBorderExpression(BorderExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitHeightExpression(HeightExpression node) { // TODO(terry): TB throw UnimplementedError; } void visitPaddingExpression(PaddingExpression node) { // TODO(terry): TBD throw UnimplementedError; } void visitWidthExpression(WidthExpression node) { // TODO(terry): TBD throw UnimplementedError; } }