/*
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.common.css.compiler.passes;
import com.google.common.css.compiler.ast.CssConstantReferenceNode;
import com.google.common.css.compiler.ast.CssDeclarationNode;
import com.google.common.css.compiler.ast.CssFontFaceNode;
import com.google.common.css.compiler.ast.CssImportRuleNode;
import com.google.common.css.compiler.ast.CssKeyframeRulesetNode;
import com.google.common.css.compiler.ast.CssMediaRuleNode;
import com.google.common.css.compiler.ast.CssPageRuleNode;
import com.google.common.css.compiler.ast.CssRulesetNode;
import com.google.common.css.compiler.ast.CssUnknownAtRuleNode;
import com.google.common.css.compiler.ast.CssValueNode;
import com.google.common.css.compiler.ast.VisitController;
import javax.annotation.Nullable;
/**
* Printer for templates, which outputs GSS with holes to be filled for references. In addition, the
* declaration boundaries are explicitly noted, so that a declaration can be removed if it ends up
* empty.
*
* @param <T> type of chunk id objects
* @author dgajda@google.com (Damian Gajda)
*/
public class TemplateCompactPrintingVisitor<T> extends ChunkCompactPrintingVisitor<T> {
public TemplateCompactPrintingVisitor(
VisitController visitController,
T chunk,
@Nullable CodeBuffer buffer) {
super(visitController, chunk, buffer);
}
@Override
protected void appendValueNode(CssValueNode node) {
if (node instanceof CssConstantReferenceNode) {
buffer.append(TemplateCompactPrinter.REFERENCE_START);
super.appendValueNode(node);
buffer.append(TemplateCompactPrinter.REFERENCE_END);
} else {
super.appendValueNode(node);
}
}
@Override
public boolean enterDeclaration(CssDeclarationNode declaration) {
buffer.append(TemplateCompactPrinter.DECLARATION_START);
return super.enterDeclaration(declaration);
}
@Override
public void leaveDeclaration(CssDeclarationNode declaration) {
super.leaveDeclaration(declaration);
buffer.append(TemplateCompactPrinter.DECLARATION_END);
}
@Override
public boolean enterRuleset(CssRulesetNode ruleset) {
boolean printRuleset = super.enterRuleset(ruleset);
if (printRuleset) {
buffer.append(TemplateCompactPrinter.RULE_START);
}
return printRuleset;
}
@Override
public void leaveRuleset(CssRulesetNode ruleset) {
// only called if enterRuleset returns true
buffer.append(TemplateCompactPrinter.RULE_END);
super.leaveRuleset(ruleset);
}
@Override
public boolean enterMediaRule(CssMediaRuleNode media) {
buffer.append(TemplateCompactPrinter.RULE_START);
boolean printMediaRule = super.enterMediaRule(media);
if (!printMediaRule) {
buffer.deleteLastCharIfCharIs(TemplateCompactPrinter.RULE_START);
}
return printMediaRule;
}
@Override
public void leaveMediaRule(CssMediaRuleNode media) {
// only called if enterMediaRule returns true
super.leaveMediaRule(media);
buffer.append(TemplateCompactPrinter.RULE_END);
}
@Override
public boolean enterFontFace(CssFontFaceNode cssFontFaceNode) {
buffer.append(TemplateCompactPrinter.RULE_START);
boolean printFontFace = super.enterFontFace(cssFontFaceNode);
if (!printFontFace) {
buffer.deleteLastCharIfCharIs(TemplateCompactPrinter.RULE_START);
}
return printFontFace;
}
@Override
public void leaveFontFace(CssFontFaceNode cssFontFaceNode) {
// only called if enterFontFace returns true
super.leaveFontFace(cssFontFaceNode);
buffer.append(TemplateCompactPrinter.RULE_END);
}
@Override
public boolean enterKeyframeRuleset(CssKeyframeRulesetNode ruleset) {
buffer.append(TemplateCompactPrinter.RULE_START);
boolean printKeyframeRuleset = super.enterKeyframeRuleset(ruleset);
if (!printKeyframeRuleset) {
buffer.deleteLastCharIfCharIs(TemplateCompactPrinter.RULE_START);
}
return printKeyframeRuleset;
}
@Override
public void leaveKeyframeRuleset(CssKeyframeRulesetNode ruleset) {
// only called if enterKeyframeRuleset returns true
super.leaveKeyframeRuleset(ruleset);
buffer.append(TemplateCompactPrinter.RULE_END);
}
@Override
public boolean enterPageRule(CssPageRuleNode node) {
buffer.append(TemplateCompactPrinter.RULE_START);
boolean printPageRule = super.enterPageRule(node);
if (!printPageRule) {
buffer.deleteLastCharIfCharIs(TemplateCompactPrinter.RULE_START);
}
return printPageRule;
}
@Override
public void leavePageRule(CssPageRuleNode node) {
// only called if enterPageRule returns true
super.leavePageRule(node);
buffer.append(TemplateCompactPrinter.RULE_END);
}
@Override
public boolean enterUnknownAtRule(CssUnknownAtRuleNode node) {
buffer.append(TemplateCompactPrinter.RULE_START);
boolean printUnknownAtRule = super.enterUnknownAtRule(node);
if (!printUnknownAtRule) {
buffer.deleteLastCharIfCharIs(TemplateCompactPrinter.RULE_START);
}
return printUnknownAtRule;
}
@Override
public void leaveUnknownAtRule(CssUnknownAtRuleNode node) {
// only called if enterUnknownAtRule returns true
super.leaveUnknownAtRule(node);
buffer.append(TemplateCompactPrinter.RULE_END);
}
@Override
public boolean enterImportRule(CssImportRuleNode node) {
buffer.append(TemplateCompactPrinter.RULE_START);
boolean printImportRule = super.enterImportRule(node);
if (!printImportRule) {
buffer.deleteLastCharIfCharIs(TemplateCompactPrinter.RULE_START);
}
return printImportRule;
}
@Override
public void leaveImportRule(CssImportRuleNode node) {
super.leaveImportRule(node);
buffer.append(TemplateCompactPrinter.RULE_END);
}
}