com.google.common.css.compiler.ast.CssFunctionNode.java Source code

Java tutorial

Introduction

Here is the source code for com.google.common.css.compiler.ast.CssFunctionNode.java

Source

/*
 * Copyright 2008 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.ast;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.css.SourceCodeLocation;

import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

/**
 * A node representing a function.
 *
 * @author oana@google.com (Oana Florescu)
 */
public class CssFunctionNode extends CssValueNode implements ChunkAware {

    /**
     * Contains the list of recognized CSS functions.
     */
    public abstract static class Function {

        /** A map of function names to function objects. */
        private static final Map<String, Function> NAME_TO_FUNCTION_MAP;

        static {
            List<String> recognizedCssFunctions = ImmutableList.of(
                    // CSS 2.1
                    "attr", "counter", "rect", "rgb", "url",

                    // Per-site user stylesheet rules
                    // http://lists.w3.org/Archives/Public/www-style/2004Aug/0135
                    "domain", "url-prefix",

                    // IE8 and earlier:
                    // .fiftyPercentOpacity { filter: alpha(opacity=50); }
                    "alpha",

                    // CSS 3
                    "cubic-bezier", "format", // used with @font-face
                    "from", "hsl", "hsla", "local", // used with @font-face
                    "perspective", "rgba", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "scale", "scaleX",
                    "scaleY", "scaleZ", "scale3d", "steps", "to", "translate", "translateX", "translateY",
                    "translateZ", "translate3d",

                    // Filter
                    // w3.org/TR/filter-effects-1/#FilterProperty
                    // "url" already in list
                    "blur", "brightness", "contrast", "drop-shadow", "grayscale", "hue-rotate", "invert", "opacity",
                    "saturate", "sepia",

                    // Image-Set
                    "image-set", "-moz-image-set", "-ms-image-set", "-o-image-set", "-webkit-image-set",

                    // These take the type of gradient (linear or radial) as a parameter.
                    "-khtml-gradient", "-webkit-gradient", // Prefer -webkit-(linear|radial)-gradient

                    // Linear gradients
                    "linear-gradient", "-moz-linear-gradient", "-ms-linear-gradient", "-o-linear-gradient",
                    "-webkit-linear-gradient", "repeating-linear-gradient", "-moz-repeating-linear-gradient",
                    "-ms-repeating-linear-gradient", "-o-repeating-linear-gradient",
                    "-webkit-repeating-linear-gradient",

                    // Radial gradients
                    "radial-gradient", "-moz-radial-gradient", "-ms-radial-gradient", "-o-radial-gradient",
                    "-webkit-radial-gradient", "repeating-radial-gradient", "-moz-repeating-radial-gradient",
                    "-ms-repeating-radial-gradient", "-o-repeating-radial-gradient",
                    "-webkit-repeating-radial-gradient",

                    // Calc
                    "calc", "-webkit-calc", "-moz-calc",

                    // CSS Shapes
                    "inset", "circle", "ellipse", "polygon");
            ImmutableMap.Builder<String, Function> builder = ImmutableMap.builder();
            for (String functionName : recognizedCssFunctions) {
                builder.put(functionName, new Function(functionName) {
                    @Override
                    public boolean isRecognized() {
                        return true;
                    }
                });
            }
            NAME_TO_FUNCTION_MAP = builder.build();
        }

        /**
         * Serves as a placeholder for custom functions.
         */
        public static final Function CUSTOM = new Function(null /* functionName */) {
            @Override
            public boolean isRecognized() {
                return false;
            }
        };

        /** The name of the function, as it appears in a CSS stylesheet. */
        private final String functionName;

        private Function(String functionName) {
            this.functionName = functionName;
        }

        /**
         * Returns the CSS {@link Function} with the specified name, or {@code null}
         * if the name is not in the list of recognized names. Multiple invocations
         * of this method with the same parameter will return the same object. For a
         * function that is not in the list of recognized names but should be
         * considered valid, use {@link Function#CUSTOM}.
         */
        public static Function byName(String name) {
            return NAME_TO_FUNCTION_MAP.get(name);
        }

        /**
         * Returns {@code true} when this function is in the list of
         * recognized names.
         */
        public abstract boolean isRecognized();

        /**
         * @return the name of the CSS function, such as "rgb" or "url"
         */
        public String getFunctionName() {
            return functionName;
        }

        /**
         * For debugging only.
         */
        @Override
        public String toString() {
            return getFunctionName();
        }
    }

    private final Function function;
    private CssFunctionArgumentsNode arguments;
    private Object chunk;

    /**
     * Constructor of the class.
     *
     * TODO(oana): Deal with the situation that we have an unrecognized
     * function.
     *
     * @param function
     * @param sourceCodeLocation
     */
    public CssFunctionNode(@Nullable Function function, @Nullable SourceCodeLocation sourceCodeLocation) {
        super(null, sourceCodeLocation);
        this.function = function;
        this.arguments = new CssFunctionArgumentsNode();
        becomeParentForNode(this.arguments);
    }

    /**
     * Copy constructor.
     *
     * @param function
     */
    public CssFunctionNode(CssFunctionNode function) {
        super(function);
        this.function = function.getFunction();
        this.arguments = new CssFunctionArgumentsNode(function.getArguments());
        becomeParentForNode(this.arguments);
        this.chunk = function.getChunk();
    }

    /**
     * Constructor used by the proxy mechanism, avoids unnecessary arguments node
     * initialization.
     *
     * <p>NOTE(dgajda): The signature of this constructor only differs in argument
     * order from the main constructor of this class.
     *
     * @param function implementation of the function which is "called" by this
     *     node
     * @param sourceCodeLocation location of this node
     */
    protected CssFunctionNode(@Nullable SourceCodeLocation sourceCodeLocation, @Nullable Function function) {
        super(null, sourceCodeLocation);
        this.function = function;
    }

    @Override
    public CssFunctionNode deepCopy() {
        return new CssFunctionNode(this);
    }

    public Function getFunction() {
        return function;
    }

    public String getFunctionName() {
        return function.toString();
    }

    public CssFunctionArgumentsNode getArguments() {
        return arguments;
    }

    public void setArguments(CssFunctionArgumentsNode arguments) {
        removeAsParentOfNode(this.arguments);
        this.arguments = arguments;
        becomeParentForNode(this.arguments);
    }

    @Override
    public String toString() {
        StringBuffer output = new StringBuffer();
        if (function.getFunctionName() != null) {
            output.append(function.getFunctionName());
        }
        output.append("(");
        for (CssNode node : getArguments().childIterable()) {
            output.append(node.toString());
        }
        output.append(")");
        return output.toString();
    }

    @Override
    public Object getChunk() {
        return chunk;
    }

    @Override
    public void setChunk(Object chunk) {
        this.chunk = chunk;
    }

    /**
     * Print the node instead of null when this node is a parameter.
     */
    @Override
    public String getValue() {
        return toString();
    }
}