| /* |
| * 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.core.shared.GWT; |
| import com.google.gwt.dom.client.Style.BorderStyle; |
| import com.google.gwt.dom.client.Style.Clear; |
| 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.OutlineStyle; |
| 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.TextAlign; |
| import com.google.gwt.dom.client.Style.TextDecoration; |
| import com.google.gwt.dom.client.Style.TextJustify; |
| import com.google.gwt.dom.client.Style.TextOverflow; |
| import com.google.gwt.dom.client.Style.TextTransform; |
| 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.dom.client.Style.WhiteSpace; |
| import com.google.gwt.safehtml.shared.SafeUri; |
| |
| /** |
| * Utility class containing static methods for creating {@link SafeStyles}. |
| */ |
| public final class SafeStylesUtils { |
| |
| /** |
| * Standard implementation of this class. |
| */ |
| static class Impl { |
| public SafeStyles forOpacity(double value) { |
| return new SafeStylesString("opacity: " + value + ";"); |
| } |
| } |
| |
| /** |
| * Server implementation of this class. |
| * |
| * <p> |
| * The server doesn't necessarily know the user agent of the client, so we |
| * combine the results of all other implementations. |
| * </p> |
| */ |
| static class ImplServer extends Impl { |
| |
| private ImplIE8 implIE = new ImplIE8(); |
| |
| @Override |
| public SafeStyles forOpacity(double value) { |
| SafeStylesBuilder sb = new SafeStylesBuilder(); |
| sb.append(super.forOpacity(value)); |
| sb.append(implIE.forOpacity(value)); |
| return sb.toSafeStyles(); |
| } |
| } |
| |
| /** |
| * IE8 implementation of this class. |
| */ |
| static class ImplIE8 extends Impl { |
| @Override |
| public SafeStyles forOpacity(double value) { |
| // IE8 uses an alpha filter instead of opacity. |
| return new SafeStylesString("filter: alpha(opacity=" + (value * 100) + ");"); |
| } |
| } |
| |
| private static Impl impl; |
| |
| /** |
| * Sets the background-image CSS property. |
| * |
| * @param uri the URI of the background image |
| * @return a {@link SafeStyles} instance |
| * @see #forTrustedBackgroundImage(String) |
| */ |
| public static SafeStyles forBackgroundImage(SafeUri uri) { |
| return fromTrustedNameAndValue("background-image", "url(\"" + uri.asString() + "\")"); |
| } |
| |
| /** |
| * Sets the border-style CSS property. |
| */ |
| public static SafeStyles forBorderStyle(BorderStyle value) { |
| return fromTrustedNameAndValue("border-style", value.getCssName()); |
| } |
| |
| /** |
| * Set the border-width css property. |
| */ |
| public static SafeStyles forBorderWidth(double value, Unit unit) { |
| return fromTrustedNameAndValue("border-width", value, unit); |
| } |
| |
| /** |
| * Set the bottom css property. |
| */ |
| public static SafeStyles forBottom(double value, Unit unit) { |
| return fromTrustedNameAndValue("bottom", value, unit); |
| } |
| |
| /** |
| * Sets the 'clear' CSS property. |
| */ |
| public static SafeStyles forClear(Clear value) { |
| return fromTrustedNameAndValue("clear", value.getCssName()); |
| } |
| |
| /** |
| * Sets the cursor CSS property. |
| */ |
| public static SafeStyles forCursor(Cursor value) { |
| return fromTrustedNameAndValue("cursor", value.getCssName()); |
| } |
| |
| /** |
| * Sets the display CSS property. |
| */ |
| public static SafeStyles forDisplay(Display value) { |
| return fromTrustedNameAndValue("display", value.getCssName()); |
| } |
| |
| /** |
| * Set the float css property. |
| */ |
| public static SafeStyles forFloat(Float value) { |
| return fromTrustedNameAndValue("float", value.getCssName()); |
| } |
| |
| /** |
| * Set the font-size css property. |
| */ |
| public static SafeStyles forFontSize(double value, Unit unit) { |
| return fromTrustedNameAndValue("font-size", value, unit); |
| } |
| |
| /** |
| * Sets the font-style CSS property. |
| */ |
| public static SafeStyles forFontStyle(FontStyle value) { |
| return fromTrustedNameAndValue("font-style", value.getCssName()); |
| } |
| |
| /** |
| * Sets the font-weight CSS property. |
| */ |
| public static SafeStyles forFontWeight(FontWeight value) { |
| return fromTrustedNameAndValue("font-weight", value.getCssName()); |
| } |
| |
| /** |
| * Set the height css property. |
| */ |
| public static SafeStyles forHeight(double value, Unit unit) { |
| return fromTrustedNameAndValue("height", value, unit); |
| } |
| |
| /** |
| * Set the left css property. |
| */ |
| public static SafeStyles forLeft(double value, Unit unit) { |
| return fromTrustedNameAndValue("left", value, unit); |
| } |
| |
| /** |
| * Set the line-height css property. |
| */ |
| public static SafeStyles forLineHeight(double value, Unit unit) { |
| return fromTrustedNameAndValue("line-height", value, unit); |
| } |
| |
| /** |
| * Sets the list-style-type CSS property. |
| */ |
| public static SafeStyles forListStyleType(ListStyleType value) { |
| return fromTrustedNameAndValue("list-style-type", value.getCssName()); |
| } |
| |
| /** |
| * Set the margin css property. |
| */ |
| public static SafeStyles forMargin(double value, Unit unit) { |
| return fromTrustedNameAndValue("margin", value, unit); |
| } |
| |
| /** |
| * Set the margin-bottom css property. |
| */ |
| public static SafeStyles forMarginBottom(double value, Unit unit) { |
| return fromTrustedNameAndValue("margin-bottom", value, unit); |
| } |
| |
| /** |
| * Set the margin-left css property. |
| */ |
| public static SafeStyles forMarginLeft(double value, Unit unit) { |
| return fromTrustedNameAndValue("margin-left", value, unit); |
| } |
| |
| /** |
| * Set the margin-right css property. |
| */ |
| public static SafeStyles forMarginRight(double value, Unit unit) { |
| return fromTrustedNameAndValue("margin-right", value, unit); |
| } |
| |
| /** |
| * Set the margin-top css property. |
| */ |
| public static SafeStyles forMarginTop(double value, Unit unit) { |
| return fromTrustedNameAndValue("margin-top", value, unit); |
| } |
| |
| /** |
| * Set the opacity css property. |
| */ |
| public static SafeStyles forOpacity(double value) { |
| return impl().forOpacity(value); |
| } |
| |
| /** |
| * Sets the outline-style CSS property. |
| */ |
| public static SafeStyles forOutlineStyle(OutlineStyle value) { |
| return fromTrustedNameAndValue("outline-style", value.getCssName()); |
| } |
| |
| /** |
| * Set the outline-width css property. |
| */ |
| public static SafeStyles forOutlineWidth(double value, Unit unit) { |
| return fromTrustedNameAndValue("outline-width", value, unit); |
| } |
| |
| /** |
| * Sets the overflow CSS property. |
| */ |
| public static SafeStyles forOverflow(Overflow value) { |
| return fromTrustedNameAndValue("overflow", value.getCssName()); |
| } |
| |
| /** |
| * Sets the overflow-x CSS property. |
| */ |
| public static SafeStyles forOverflowX(Overflow value) { |
| return fromTrustedNameAndValue("overflow-x", value.getCssName()); |
| } |
| |
| /** |
| * Sets the overflow-y CSS property. |
| */ |
| public static SafeStyles forOverflowY(Overflow value) { |
| return fromTrustedNameAndValue("overflow-y", value.getCssName()); |
| } |
| |
| /** |
| * Set the padding css property. |
| */ |
| public static SafeStyles forPadding(double value, Unit unit) { |
| return fromTrustedNameAndValue("padding", value, unit); |
| } |
| |
| /** |
| * Set the padding-bottom css property. |
| */ |
| public static SafeStyles forPaddingBottom(double value, Unit unit) { |
| return fromTrustedNameAndValue("padding-bottom", value, unit); |
| } |
| |
| /** |
| * Set the padding-left css property. |
| */ |
| public static SafeStyles forPaddingLeft(double value, Unit unit) { |
| return fromTrustedNameAndValue("padding-left", value, unit); |
| } |
| |
| /** |
| * Set the padding-right css property. |
| */ |
| public static SafeStyles forPaddingRight(double value, Unit unit) { |
| return fromTrustedNameAndValue("padding-right", value, unit); |
| } |
| |
| /** |
| * Set the padding-top css property. |
| */ |
| public static SafeStyles forPaddingTop(double value, Unit unit) { |
| return fromTrustedNameAndValue("padding-top", value, unit); |
| } |
| |
| /** |
| * Sets the position CSS property. |
| */ |
| public static SafeStyles forPosition(Position value) { |
| return fromTrustedNameAndValue("position", value.getCssName()); |
| } |
| |
| /** |
| * Set the right css property. |
| */ |
| public static SafeStyles forRight(double value, Unit unit) { |
| return fromTrustedNameAndValue("right", value, unit); |
| } |
| |
| /** |
| * Set the table-layout CSS property. |
| */ |
| public static SafeStyles forTableLayout(TableLayout value) { |
| return fromTrustedNameAndValue("table-layout", value.getCssName()); |
| } |
| |
| /** |
| * Sets the 'text-align' CSS property. |
| */ |
| public static SafeStyles forTextAlign(TextAlign value) { |
| return fromTrustedNameAndValue("text-align", value.getCssName()); |
| } |
| |
| /** |
| * Sets the 'text-decoration' CSS property. |
| */ |
| public static SafeStyles forTextDecoration(TextDecoration value) { |
| return fromTrustedNameAndValue("text-decoration", value.getCssName()); |
| } |
| |
| /** |
| * Set the 'text-indent' CSS property. |
| */ |
| public static SafeStyles forTextIndent(double value, Unit unit) { |
| return fromTrustedNameAndValue("text-indent", value + unit.getType()); |
| } |
| |
| /** |
| * Set the 'text-justify' CSS3 property. |
| */ |
| public static SafeStyles forTextJustify(TextJustify value) { |
| return fromTrustedNameAndValue("text-justify", value.getCssName()); |
| } |
| |
| /** |
| * Set the 'text-overflow' CSS3 property. |
| */ |
| public static SafeStyles forTextOverflow(TextOverflow value) { |
| return fromTrustedNameAndValue("text-overflow", value.getCssName()); |
| } |
| |
| /** |
| * Set the 'text-transform' CSS property. |
| */ |
| public static SafeStyles forTextTransform(TextTransform value) { |
| return fromTrustedNameAndValue("text-transform", value.getCssName()); |
| } |
| |
| /** |
| * Set the top css property. |
| */ |
| public static SafeStyles forTop(double value, Unit unit) { |
| return fromTrustedNameAndValue("top", value, unit); |
| } |
| |
| /** |
| * <p> |
| * Returns a {@link SafeStyles} constructed from a 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: |
| * "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> tag, this could then break out of |
| * the style context into HTML. |
| * </p> |
| * |
| * @param value the property value |
| * @return a {@link SafeStyles} instance |
| */ |
| public static SafeStyles forTrustedBackgroundColor(String value) { |
| return fromTrustedNameAndValue("background-color", value); |
| } |
| |
| /** |
| * <p> |
| * Returns a {@link SafeStyles} constructed from a 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: |
| * "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> tag, this could then break out of |
| * the style context into HTML. |
| * </p> |
| * |
| * @param value the property value |
| * @return a {@link SafeStyles} instance |
| * @see #forBackgroundImage(SafeUri) |
| */ |
| public static SafeStyles forTrustedBackgroundImage(String value) { |
| return fromTrustedNameAndValue("background-image", value); |
| } |
| |
| /** |
| * <p> |
| * Returns a {@link SafeStyles} constructed from a 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: |
| * "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> tag, this could then break out of |
| * the style context into HTML. |
| * </p> |
| * |
| * @param value the property value |
| * @return a {@link SafeStyles} instance |
| */ |
| public static SafeStyles forTrustedBorderColor(String value) { |
| return fromTrustedNameAndValue("border-color", value); |
| } |
| |
| /** |
| * <p> |
| * Returns a {@link SafeStyles} constructed from a 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: |
| * "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> tag, this could then break out of |
| * the style context into HTML. |
| * </p> |
| * |
| * @param value the property value |
| * @return a {@link SafeStyles} instance |
| */ |
| public static SafeStyles forTrustedColor(String value) { |
| return fromTrustedNameAndValue("color", value); |
| } |
| |
| /** |
| * <p> |
| * Returns a {@link SafeStyles} constructed from a trusted outline 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: |
| * "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> tag, this could then break out of |
| * the style context into HTML. |
| * </p> |
| * |
| * @param value the property value |
| * @return a {@link SafeStyles} instance |
| */ |
| public static SafeStyles forTrustedOutlineColor(String value) { |
| return fromTrustedNameAndValue("outline-color", value); |
| } |
| |
| /** |
| * Sets the vertical-align CSS property. |
| */ |
| public static SafeStyles forVerticalAlign(double value, Unit unit) { |
| return fromTrustedNameAndValue("vertical-align", value, unit); |
| } |
| |
| /** |
| * Sets the vertical-align CSS property. |
| */ |
| public static SafeStyles forVerticalAlign(VerticalAlign value) { |
| return fromTrustedNameAndValue("vertical-align", value.getCssName()); |
| } |
| |
| /** |
| * Sets the visibility CSS property. |
| */ |
| public static SafeStyles forVisibility(Visibility value) { |
| return fromTrustedNameAndValue("visibility", value.getCssName()); |
| } |
| |
| /** |
| * Set the 'white-space' CSS property. |
| */ |
| public static SafeStyles forWhiteSpace(WhiteSpace value) { |
| return fromTrustedNameAndValue("white-space", value.getCssName()); |
| } |
| |
| /** |
| * Set the width css property. |
| */ |
| public static SafeStyles forWidth(double value, Unit unit) { |
| return fromTrustedNameAndValue("width", value, unit); |
| } |
| |
| /** |
| * Set the z-index css property. |
| */ |
| public static SafeStyles forZIndex(int value) { |
| return new SafeStylesString("z-index: " + value + ";"); |
| } |
| |
| /** |
| * <p> |
| * Returns 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: "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> 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 value |
| * @param unit the units of the value |
| * @return a {@link SafeStyles} instance |
| */ |
| public static SafeStyles fromTrustedNameAndValue(String name, double value, Unit unit) { |
| SafeStylesHostedModeUtils.maybeCheckValidStyleName(name); |
| return new SafeStylesString(name + ":" + value + unit.getType() + ";"); |
| } |
| |
| /** |
| * <p> |
| * Returns 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: "<name>:<value>;". |
| * |
| * <p> |
| * {@link SafeStyles} may never contain literal angle brackets. Otherwise, it |
| * could be unsafe to place a {@link SafeStyles} into a <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> 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 static SafeStyles fromTrustedNameAndValue(String name, String value) { |
| SafeStylesHostedModeUtils.maybeCheckValidStyleName(name); |
| SafeStylesHostedModeUtils.maybeCheckValidStyleValue(value); |
| return fromTrustedString(name + ":" + value + ";"); |
| } |
| |
| /** |
| * <p> |
| * Returns a {@link SafeStyles} constructed from a trusted string, i.e., |
| * without escaping the string. No 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 <style> tag |
| * (where it can't be HTML escaped). For example, if the {@link SafeStyles} |
| * containing " |
| * <code>font: 'foo <style><script>evil</script></code>'" is |
| * used in a style sheet in a <style> 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 s the input String |
| * @return a {@link SafeStyles} instance |
| */ |
| public static SafeStyles fromTrustedString(String s) { |
| return new SafeStylesString(s); |
| } |
| |
| /** |
| * Verify that the basic constraints of a {@link SafeStyles} are met. This |
| * method is not a guarantee that the specified css is safe for use in a CSS |
| * style attribute. It is a minimal set of assertions to check for common |
| * errors. |
| * |
| * @param styles the CSS properties string |
| * @throws NullPointerException if the css is null |
| * @throws AssertionError if the css does not meet the constraints |
| */ |
| static void verifySafeStylesConstraints(String styles) { |
| if (styles == null) { |
| throw new NullPointerException("css is null"); |
| } |
| |
| // CSS properties must end in a semi-colon or they cannot be safely |
| // composed with other properties. |
| assert ((styles.trim().length() == 0) || styles.endsWith(";")) : "Invalid CSS Property: '" |
| + styles + "'. CSS properties must be an empty string or end with a semi-colon (;)."; |
| assert !styles.contains("<") && !styles.contains(">") : "Invalid CSS Property: '" + styles |
| + "'. CSS should not contain brackets (< or >)."; |
| } |
| |
| private static Impl impl() { |
| if (impl == null) { |
| if (GWT.isClient()) { |
| impl = GWT.create(Impl.class); |
| } else { |
| impl = new ImplServer(); |
| } |
| } |
| return impl; |
| } |
| |
| // prevent instantiation |
| private SafeStylesUtils() { |
| } |
| } |