/* * Copyright 2011 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.base.Preconditions; import com.google.common.css.Vendor; import com.google.common.css.compiler.ast.CssCompilerPass; import com.google.common.css.compiler.ast.CssDeclarationNode; import com.google.common.css.compiler.ast.CssPropertyNode; import com.google.common.css.compiler.ast.DefaultTreeVisitor; import com.google.common.css.compiler.ast.MutatingVisitController; import com.google.common.css.compiler.ast.Property; import javax.annotation.Nonnull; /** * A {@link CssCompilerPass} that removes all vendor-specific properties, except * for one {@link Vendor} that is specified in the constructor. This is * designed to facilitate creating a vendor-specific stylesheet. For example, * suppose you have the following CSS: * <pre> * .button { * border-radius: 2px; * -moz-border-radius: 2px; * -webkit-border-radius: 2px; * } * </pre> * <p>If {@link Vendor#WEBKIT} were specified as the "vendor to keep" when running * this pass, then the resulting CSS would be: * <pre> * .button { * border-radius: 2px; * -webkit-border-radius: 2px; * } * </pre> * {@code border-radius} would not be removed because it is not a * vendor-specific property, and {@code -webkit-border-radius} would not be * removed because {@link Vendor#WEBKIT} was specified as the "vendor to keep." * Only {@code -moz-border-radius} is removed because it is vendor-specific, but * it is not the whitelisted vendor. If there were properties prefixed with * "-o-" for Opera or "-ms-" for Microsoft, then those would have been removed, * as well. * * @author bolinfest@google.com (Michael Bolin) */ public class RemoveVendorSpecificProperties extends DefaultTreeVisitor implements CssCompilerPass { private final Vendor vendorToKeep; private final MutatingVisitController visitController; /** * @param vendorToKeep determines the vendor for whose vendor-specific * properties will not be stripped. This parameter may not be null: if * there is no such venor, then this pass should not be used. * @param visitController to facilitate traversing the AST */ public RemoveVendorSpecificProperties(@Nonnull Vendor vendorToKeep, MutatingVisitController visitController) { Preconditions.checkNotNull(vendorToKeep); this.vendorToKeep = vendorToKeep; this.visitController = visitController; } /** * Checks whether the {@code Property} of {@code declarationNode} is a * vendor-specific property that does not match {@code vendorToKeep}. If so, * then the declaration is removed. */ @Override public boolean enterDeclaration(CssDeclarationNode declarationNode) { CssPropertyNode propertyNode = declarationNode.getPropertyName(); Property property = propertyNode.getProperty(); Vendor vendor = property.getVendor(); if (vendor != null && !vendor.equals(vendorToKeep)) { visitController.removeCurrentNode(); return false; } else { return true; } } @Override public void runPass() { visitController.startVisit(this); } }