com.google.gwt.resources.client.CssResource.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.resources.client.CssResource.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.gwt.resources.client;

import com.google.gwt.resources.ext.DefaultExtensions;
import com.google.gwt.resources.ext.ResourceGeneratorType;
import com.google.gwt.resources.rg.CssResourceGenerator;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Aggregates and minifies CSS stylesheets. A CssResource represents a regular
 * CSS file with GWT-specific at-rules.
 * <p>
 * Currently-supported accessor functions:
 * 
 * <ul>
 * <li>{@code String someClassName();} will allow the css class
 * <code>.someClassName</code> to be obfuscated at runtime. The function will
 * return the obfuscated class name.</li>
 * <li>{@code <primitive numeric type or String> someDefName();} will allow
 * access to the values defined by {@literal @def} rules within the CSS file.
 * The defined value must be a raw number, a CSS length, or a percentage value
 * if it is to be returned as a numeric type.
 * </ul>
 * 
 * <p>
 * Currently-supported rules:
 * 
 * <ul>
 * <li>{@code @def NAME replacement-expression; .myClass background: NAME;}
 * Define a static constant. The replacement expression may be any CSS that
 * would be valid in a property value context. A {@code @def} may refer to
 * previously-defined rules, but no forward-references will be honored.</li>
 * <li>{@code @eval NAME Java-expression; .myClass background: NAME;} Define a
 * constant based on a Java expression.</li>
 * <li>{@code @external class-name, class-name, ...;} Disable obfuscation for
 * specific class selectors and exclude those class selectors from strictness
 * requirements.</li>
 * <li><code>{@literal @if} [!]property list of values {ruleBlock}</code> Include or
 * exclude CSS rules based on the value of a deferred-binding property. Also
 * {@code @elif} and {@code @else} follow the same pattern.<br/>
 * This might look like {@code @if user.agent ie6 safari ...}.</li>
 * <li><code>{@literal @if} (Java-expression) {ruleBlock}</code> Include or exclude
 * CSS rules based on a boolean Java expression.</li>
 * <li><code>{@literal @noflip} { rules }</code> will suppress the automatic
 * right-to-left transformation applied to the CSS when the module is compiled
 * for an RTL language.</li>
 * <li>
 * <code>{@literal @}sprite .any .selector {gwt-image: "imageResourceFunction";}</code>
 * . The appearance, size, and height of the sprite will be affected by any
 * {@link ImageResource.ImageOptions} annotations present on the related
 * {@link ImageResource} accessor function. Additional properties may be
 * specified in the rule block.</li>
 * <li>{@code @url NAME siblingDataResource; .myClass background: NAME
 * repeat-x;} Use a {@link DataResource} to generate a <code>url('...'}</code> value.</li>
 * </ul>
 * 
 * <p>
 * Currently-supported CSS functions:
 * 
 * <ul>
 * <li>{@code literal("expression")} substitutes a property value that does not
 * conform to CSS2 parsing rules. The escape sequences {@code \"} and {@code \\}
 * will be replaced with {@code "} and {@code \} respectively.
 * <li>{@code value("bundleFunction.someFunction[.other[...]]" [, "suffix"])}
 * substitute the value of a sequence of named zero-arg function invocations. An
 * optional suffix will be appended to the return value of the function. The
 * first name is resolved relative to the bundle interface passed to
 * {@link com.google.gwt.core.client.GWT#create(Class)}. An example:
 * 
 * <pre>
 * .bordersTheSizeOfAnImage {
 *   border-left: value('leftBorderImageResource.getWidth', 'px') solid blue;
 * }
 * </pre>
 * </li>
 * </ul>
 * 
 * <p>
 * Any class selectors that do not correspond with a String accessor method in
 * the return type will trigger a compilation error. This ensures that the
 * CssResource does not contribute any unobfuscated class selectors into the
 * global CSS namespace. Strict mode can be disabled by annotating the
 * ClientBundle method declaration with {@link NotStrict}, however this is only
 * recommended for interacting with legacy CSS.
 * 
 * <p>
 * Given these interfaces:
 * 
 * <pre>
 * interface MyCss extends CssResource {
 *   String someClass();
 * }
 * 
 * interface MyBundle extends ClientBundle {
 *  {@literal @Source("my.css")}
 *   MyCss css();
 * }
 * </pre>
 * 
 * the source CSS will fail to compile if it does not contain exactly the one
 * class selector defined in the MyCss type.
 * <p>
 * The {@code @external} at-rule can be used in strict mode to indicate that
 * certain class selectors are exempt from the strict semantics. Class selectors
 * marked as external will not be obfuscated and are not required to have string
 * accessor functions. Consider the following example in conjunction with the
 * above <code>MyCss</code> interface:
 * 
 * <pre>
   * {@literal @external} .foo, .bar;
   * .foo .someClass .bar { .... }
   * </pre>
 * 
 * The resulting CSS would look like:
 * 
 * <pre>
   * .foo .A1234 .bar { .... }
   * </pre>
 * 
 * If a <code>String foo()</code> method were defined in <code>MyCss</code>, it
 * would return the string value "<code>foo</code>".
 * <p>
 * The utility tool <code>com.google.gwt.resources.css.InterfaceGenerator</code>
 * can be used to automatically generate a Java interface from a
 * CssResource-compatible CSS file.
 * 
 * @see <a href="http://code.google.com/p/google-web-toolkit/wiki/CssResource"
 *      >CssResource design doc</a>
 */
@DefaultExtensions(value = { ".css" })
@ResourceGeneratorType(CssResourceGenerator.class)
public interface CssResource extends CssResourceBase {
    /**
     * The original CSS class name specified in the resource. This allows CSS
     * classes that do not correspond to Java identifiers to be mapped onto
     * obfuscated class accessors.
     * 
     * <pre>
     * .some-non-java-ident { background: blue; }
     * 
     * interface MyCssResource extends CssResource {
     *   {@literal @}ClassName("some-non-java-ident")
     *   String classAccessor();
     * }
     * </pre>
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface ClassName {
        String value();
    }

    /**
     * Makes class selectors from other CssResource types available in the raw
     * source of a CssResource. String accessor methods can be referred to using
     * the value of the imported type's {@link ImportedWithPrefix} value.
     * <p>
     * This is an example of creating a descendant selector with two unrelated
     * types:
     * 
     * <pre>
     *{@literal @ImportedWithPrefix}("some-prefix")
     * interface ToImport extends CssResource {
     *   String widget();
     * }
     * 
     *{@literal @ImportedWithPrefix}("other-import")
     * interface OtherImport extends CssResource {
     *   String widget();
     * }
     * 
     * interface Resources extends ClientBundle {
     *  {@literal @Import}(value = {ToImport.class, OtherImport.class})
     *  {@literal @Source}("my.css")
     *   CssResource usesImports();
     * }
     * 
     * my.css:
     * // Now I can refer to these classes defined elsewhere with no 
     * // fear of name collisions
     * .some-prefix-widget .other-import-widget {...}
     * </pre>
     * 
     * If the imported CssResource type is lacking an {@link ImportedWithPrefix}
     * annotation, the simple name of the type will be used instead. In the above
     * example, without the annotation on <code>ToImport</code>, the class
     * selector would have been <code>.ToImport-widget</code>. Notice also that
     * both interfaces defined a method called <code>widget()</code>, which would
     * prevent meaningful composition of the original interfaces.
     * <p>
     * It is an error to import multiple classes with the same prefix into one
     * CssResource.
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Import {
        Class<? extends CssResource>[] value();
    }

    /**
     * Specifies the string prefix to use when one CssResource is imported into
     * the scope of another CssResource.
     * 
     * @see Import
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface ImportedWithPrefix {
        String value();
    }

    /**
     * The presence of this annotation on a CssResource accessor method indicates
     * that any class selectors that do not correspond with a String accessor
     * method in the return type or an {@code @external} declaration should not
     * trigger a compilation error. This annotation is not recommended for new
     * code.
     * 
     * <pre>
     * interface Resources extends ClientBundle {
     *  {@literal @NotStrict}
     *  {@literal @Source}("legacy.css")
     *   CssResource css();
     * }
     * </pre>
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface NotStrict {
    }

    /**
     * Indicates that the String accessor methods defined in a CssResource will
     * return the same values across all implementations of that type.
     * <p>
     * This is an example of "stateful" class selectors being used:
     * 
     * <pre>
     *{@literal @Shared}
     * interface FocusCss extends CssResource {
     *   String focused();
     *   String unfocused();
     * }
     * 
     * interface PanelCss extends CssResource, FocusCss {
     *   String widget();
     * }
     * 
     * interface InputCss extends CssResource, FocusCss {
     *   String widget();
     * }
     * 
     * input.css:
     * *.focused .widget {border: thin solid blue;}
     * 
     * Application.java:
     * myPanel.add(myInputWidget);
     * myPanel.addStyleName(instanceOfPanelCss.focused());
     * </pre>
     * 
     * Because the <code>FocusCss</code> interface is tagged with {@code @Shared},
     * the <code>focused()</code> method on the instance of <code>PanelCss</code>
     * will match the <code>.focused</code> parent selector in
     * <code>input.css</code>.
     * <p>
     * The effect of inheriting an {@code Shared} interface can be replicated by
     * use use of the {@link Import} annotation (e.g. {@code .FocusCss-focused
     * .widget}), however the use of state-bearing descendant selectors is common
     * enough to warrant an easier use-case.
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Shared {
    }

    /**
     * This annotation is a no-op.
     * 
     * @deprecated Strict mode is now the default behavior for CssResource
     */
    @Deprecated
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Strict {
    }

    /**
     * Calls
     * {@link com.google.gwt.dom.client.StyleInjector#injectStylesheet(String)} to
     * inject the contents of the CssResource into the DOM. Repeated calls to this
     * method on an instance of a CssResources will have no effect.
     * 
     * @return <code>true</code> if this method mutated the DOM.
     */
    boolean ensureInjected();

    /**
     * Provides the contents of the CssResource.
     */
    String getText();
}