com.google.gwt.safecss.shared.SafeStylesBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gwt.safecss.shared.SafeStylesBuilder.java

Source

/*
 * 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.gwt.safecss.shared;

import com.google.gwt.dom.client.Style.BorderStyle;
import com.google.gwt.dom.client.Style.Cursor;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.FontStyle;
import com.google.gwt.dom.client.Style.FontWeight;
import com.google.gwt.dom.client.Style.ListStyleType;
import com.google.gwt.dom.client.Style.Overflow;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.TableLayout;
import com.google.gwt.dom.client.Style.TextDecoration;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.Style.VerticalAlign;
import com.google.gwt.dom.client.Style.Visibility;
import com.google.gwt.safehtml.shared.SafeUri;

/**
 * A builder that facilitates the building up of XSS-safe CSS attribute strings
 * from {@link SafeStyles}. It is used essentially like a {@link StringBuilder},
 * but access {@link SafeStyles} instead of Strings.
 * 
 * <p>
 * The accumulated XSS-safe {@link SafeStyles} can be obtained in the form of a
 * {@link SafeStyles} via the {@link #toSafeStyles()} method.
 * 
 * <p>
 * This class is not thread-safe.
 */
public final class SafeStylesBuilder {

    private final StringBuilder sb = new StringBuilder();

    /**
     * Constructs an empty {@link SafeStylesBuilder}.
     */
    public SafeStylesBuilder() {
    }

    /**
     * Appends the contents of another {@link SafeStyles} object, without applying
     * any escaping or sanitization to it.
     * 
     * @param styles the {@link SafeStyles} to append
     * @return a reference to this object
     */
    public SafeStylesBuilder append(SafeStyles styles) {
        sb.append(styles.asString());
        return this;
    }

    /**
     * <p>
     * Appends {@link SafeStyles} constructed from a trusted string, i.e., without
     * escaping the string. Only minimal checks are performed. The calling code
     * should be carefully reviewed to ensure the argument meets the
     * {@link SafeStyles} contract.
     * 
     * <p>
     * Generally, {@link SafeStyles} should be of the form
     * {@code cssPropertyName:value;}, where neither the name nor the value
     * contain malicious scripts.
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * 
     * <p>
     * The following example values comply with this type's contract:
     * <ul>
     * <li><code>width: 1em;</code></li>
     * <li><code>height:1em;</code></li>
     * <li><code>width: 1em;height: 1em;</code></li>
     * <li><code>background:url('http://url');</code></li>
     * </ul>
     * In addition, the empty string is safe for use in a CSS attribute.
     * 
     * <p>
     * The following example values do <em>not</em> comply with this type's
     * contract:
     * <ul>
     * <li><code>background: red</code> (missing a trailing semi-colon)</li>
     * <li><code>background:</code> (missing a value and a trailing semi-colon)</li>
     * <li><code>1em</code> (missing an attribute name, which provides context for
     * the value)</li>
     * </ul>
     * 
     * @param styles the input String
     * @return a {@link SafeStyles} instance
     */
    public SafeStylesBuilder appendTrustedString(String styles) {
        SafeStylesUtils.verifySafeStylesConstraints(styles);
        sb.append(styles);
        return this;
    }

    /**
     * Append the background-image CSS property.
     * 
     * @param uri the URI of the background image
     * @see #trustedBackgroundImage(String)
     */
    public SafeStylesBuilder backgroundImage(SafeUri uri) {
        return append(SafeStylesUtils.forBackgroundImage(uri));
    }

    /**
     * Append the border-style CSS property.
     */
    public SafeStylesBuilder borderStyle(BorderStyle value) {
        return append(SafeStylesUtils.forBorderStyle(value));
    }

    /**
     * Append the border-width css property.
     */
    public SafeStylesBuilder borderWidth(double value, Unit unit) {
        return append(SafeStylesUtils.forBorderWidth(value, unit));
    }

    /**
     * Append the bottom css property.
     */
    public SafeStylesBuilder bottom(double value, Unit unit) {
        return append(SafeStylesUtils.forBottom(value, unit));
    }

    /**
     * Append the cursor CSS property.
     */
    public SafeStylesBuilder cursor(Cursor value) {
        return append(SafeStylesUtils.forCursor(value));
    }

    /**
     * Append the display CSS property.
     */
    public SafeStylesBuilder display(Display value) {
        return append(SafeStylesUtils.forDisplay(value));
    }

    /**
     * Append the float css property.
     * 
     * <p>
     * Note: This method has the suffix "prop" to avoid Java compilation errors.
     * The term "float" is a reserved word in Java representing the primitive
     * float.
     * </p>
     */
    public SafeStylesBuilder floatprop(Float value) {
        return append(SafeStylesUtils.forFloat(value));
    }

    /**
     * Append the font-size css property.
     */
    public SafeStylesBuilder fontSize(double value, Unit unit) {
        return append(SafeStylesUtils.forFontSize(value, unit));
    }

    /**
     * Append the font-style CSS property.
     */
    public SafeStylesBuilder fontStyle(FontStyle value) {
        return append(SafeStylesUtils.forFontStyle(value));
    }

    /**
     * Append the font-weight CSS property.
     */
    public SafeStylesBuilder fontWeight(FontWeight value) {
        return append(SafeStylesUtils.forFontWeight(value));
    }

    /**
     * Append the height css property.
     */
    public SafeStylesBuilder height(double value, Unit unit) {
        return append(SafeStylesUtils.forHeight(value, unit));
    }

    /**
     * Append the left css property.
     */
    public SafeStylesBuilder left(double value, Unit unit) {
        return append(SafeStylesUtils.forLeft(value, unit));
    }

    /**
     * Append the list-style-type CSS property.
     */
    public SafeStylesBuilder listStyleType(ListStyleType value) {
        return append(SafeStylesUtils.forListStyleType(value));
    }

    /**
     * Append the margin css property.
     */
    public SafeStylesBuilder margin(double value, Unit unit) {
        return append(SafeStylesUtils.forMargin(value, unit));
    }

    /**
     * Append the margin-bottom css property.
     */
    public SafeStylesBuilder marginBottom(double value, Unit unit) {
        return append(SafeStylesUtils.forMarginBottom(value, unit));
    }

    /**
     * Append the margin-left css property.
     */
    public SafeStylesBuilder marginLeft(double value, Unit unit) {
        return append(SafeStylesUtils.forMarginLeft(value, unit));
    }

    /**
     * Append the margin-right css property.
     */
    public SafeStylesBuilder marginRight(double value, Unit unit) {
        return append(SafeStylesUtils.forMarginRight(value, unit));
    }

    /**
     * Append the margin-top css property.
     */
    public SafeStylesBuilder marginTop(double value, Unit unit) {
        return append(SafeStylesUtils.forMarginTop(value, unit));
    }

    /**
     * Append the opacity css property.
     */
    public SafeStylesBuilder opacity(double value) {
        return append(SafeStylesUtils.forOpacity(value));
    }

    /**
     * Append the overflow CSS property.
     */
    public SafeStylesBuilder overflow(Overflow value) {
        return append(SafeStylesUtils.forOverflow(value));
    }

    /**
     * Append the overflow-x CSS property.
     */
    public SafeStylesBuilder overflowX(Overflow value) {
        return append(SafeStylesUtils.forOverflowX(value));
    }

    /**
     * Append the overflow-y CSS property.
     */
    public SafeStylesBuilder overflowY(Overflow value) {
        return append(SafeStylesUtils.forOverflowY(value));
    }

    /**
     * Append the padding css property.
     */
    public SafeStylesBuilder padding(double value, Unit unit) {
        return append(SafeStylesUtils.forPadding(value, unit));
    }

    /**
     * Append the padding-bottom css property.
     */
    public SafeStylesBuilder paddingBottom(double value, Unit unit) {
        return append(SafeStylesUtils.forPaddingBottom(value, unit));
    }

    /**
     * Append the padding-left css property.
     */
    public SafeStylesBuilder paddingLeft(double value, Unit unit) {
        return append(SafeStylesUtils.forPaddingLeft(value, unit));
    }

    /**
     * Append the padding-right css property.
     */
    public SafeStylesBuilder paddingRight(double value, Unit unit) {
        return append(SafeStylesUtils.forPaddingRight(value, unit));
    }

    /**
     * Append the padding-top css property.
     */
    public SafeStylesBuilder paddingTop(double value, Unit unit) {
        return append(SafeStylesUtils.forPaddingTop(value, unit));
    }

    /**
     * Append the position CSS property.
     */
    public SafeStylesBuilder position(Position value) {
        return append(SafeStylesUtils.forPosition(value));
    }

    /**
     * Append the right css property.
     */
    public SafeStylesBuilder right(double value, Unit unit) {
        return append(SafeStylesUtils.forRight(value, unit));
    }

    /**
     * Append the table-layout CSS property.
     */
    public SafeStylesBuilder tableLayout(TableLayout value) {
        return append(SafeStylesUtils.forTableLayout(value));
    }

    /**
     * Append the text-decoration CSS property.
     */
    public SafeStylesBuilder textDecoration(TextDecoration value) {
        return append(SafeStylesUtils.forTextDecoration(value));
    }

    /**
     * Append the top css property.
     */
    public SafeStylesBuilder top(double value, Unit unit) {
        return append(SafeStylesUtils.forTop(value, unit));
    }

    /**
     * Returns the safe CSS properties accumulated in the builder as a
     * {@link SafeStyles}.
     * 
     * @return a {@link SafeStyles} instance
     */
    public SafeStyles toSafeStyles() {
        return new SafeStylesString(sb.toString());
    }

    /**
     * <p>
     * Append the trusted background color, i.e., without escaping the value. No
     * checks are performed. The calling code should be carefully reviewed to
     * ensure the argument will satisfy the {@link SafeStyles} contract when they
     * are composed into the form: "&lt;name&gt;:&lt;value&gt;;".
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * 
     * @param value the property value
     * @return a {@link SafeStyles} instance
     */
    public SafeStylesBuilder trustedBackgroundColor(String value) {
        return append(SafeStylesUtils.forTrustedBackgroundColor(value));
    }

    /**
     * <p>
     * Append the trusted background image, i.e., without escaping the value. No
     * checks are performed. The calling code should be carefully reviewed to
     * ensure the argument will satisfy the {@link SafeStyles} contract when they
     * are composed into the form: "&lt;name&gt;:&lt;value&gt;;".
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * 
     * @param value the property value
     * @return a {@link SafeStyles} instance
     * @see #backgroundImage(SafeUri)
     */
    public SafeStylesBuilder trustedBackgroundImage(String value) {
        return append(SafeStylesUtils.forTrustedBackgroundImage(value));
    }

    /**
     * <p>
     * Append the trusted border color, i.e., without escaping the value. No
     * checks are performed. The calling code should be carefully reviewed to
     * ensure the argument will satisfy the {@link SafeStyles} contract when they
     * are composed into the form: "&lt;name&gt;:&lt;value&gt;;".
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * 
     * @param value the property value
     * @return a {@link SafeStyles} instance
     */
    public SafeStylesBuilder trustedBorderColor(String value) {
        return append(SafeStylesUtils.forTrustedBorderColor(value));
    }

    /**
     * <p>
     * Append the trusted font color, i.e., without escaping the value. No checks
     * are performed. The calling code should be carefully reviewed to ensure the
     * argument will satisfy the {@link SafeStyles} contract when they are
     * composed into the form: "&lt;name&gt;:&lt;value&gt;;".
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * 
     * @param value the property value
     * @return a {@link SafeStyles} instance
     */
    public SafeStylesBuilder trustedColor(String value) {
        return append(SafeStylesUtils.forTrustedColor(value));
    }

    /**
     * <p>
     * Append a {@link SafeStyles} constructed from a trusted name and a trusted
     * value, i.e., without escaping the name and value. No checks are performed.
     * The calling code should be carefully reviewed to ensure the argument will
     * satisfy the {@link SafeStyles} contract when they are composed into the
     * form: "&lt;name&gt;:&lt;value&gt;;".
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * </p>
     * 
     * <p>
     * The name should be in hyphenated format, not camelCase format.
     * </p>
     * 
     * @param name the property name
     * @param value the property value
     * @return a {@link SafeStyles} instance
     */
    public SafeStylesBuilder trustedNameAndValue(String name, double value, Unit unit) {
        return append(SafeStylesUtils.fromTrustedNameAndValue(name, value, unit));
    }

    /**
     * <p>
     * Append a {@link SafeStyles} constructed from a trusted name and a trusted
     * value, i.e., without escaping the name and value. No checks are performed.
     * The calling code should be carefully reviewed to ensure the argument will
     * satisfy the {@link SafeStyles} contract when they are composed into the
     * form: "&lt;name&gt;:&lt;value&gt;;".
     * 
     * <p>
     * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it
     * could be unsafe to place a {@link SafeStyles} into a &lt;style&gt; tag
     * (where it can't be HTML escaped). For example, if the {@link SafeStyles}
     * containing "
     * <code>font: 'foo &lt;style&gt;&lt;script&gt;evil&lt;/script&gt;</code>'" is
     * used in a style sheet in a &lt;style&gt; tag, this could then break out of
     * the style context into HTML.
     * </p>
     * 
     * <p>
     * The name should be in hyphenated format, not camelCase format.
     * </p>
     * 
     * @param name the property name
     * @param value the property value
     * @return a {@link SafeStyles} instance
     */
    public SafeStylesBuilder trustedNameAndValue(String name, String value) {
        return append(SafeStylesUtils.fromTrustedNameAndValue(name, value));
    }

    /**
     * Append the vertical-align CSS property.
     */
    public SafeStylesBuilder verticalAlign(double value, Unit unit) {
        return append(SafeStylesUtils.forVerticalAlign(value, unit));
    }

    /**
     * Append the vertical-align CSS property.
     */
    public SafeStylesBuilder verticalAlign(VerticalAlign value) {
        return append(SafeStylesUtils.forVerticalAlign(value));
    }

    /**
     * Append the visibility CSS property.
     */
    public SafeStylesBuilder visibility(Visibility value) {
        return append(SafeStylesUtils.forVisibility(value));
    }

    /**
     * Append the width css property.
     */
    public SafeStylesBuilder width(double value, Unit unit) {
        return append(SafeStylesUtils.forWidth(value, unit));
    }

    /**
     * Append the z-index css property.
     */
    public SafeStylesBuilder zIndex(int value) {
        return append(SafeStylesUtils.forZIndex(value));
    }
}