/* * Copyright 2016 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.template.soy.soytree; import javax.annotation.Nullable; /** * The type of HTML (or non-HTML) that contains a Soy node. This is primarily used by the contextual * auto-escaper to add escaping directives. It's also used by incremental DOM's HTML parser to mark * nodes for other passes to consume. */ public enum HtmlContext { /** Outside an HTML tag, directive, or comment. (Parsed character data). */ HTML_PCDATA(EscapingMode.ESCAPE_HTML), /** * Inside an element whose content is RCDATA where text and entities can appear but where nested * elements cannot. The content of {@code <title>} and {@code <textarea>} fall into this category * since they cannot contain nested elements in HTML. */ HTML_RCDATA(EscapingMode.ESCAPE_HTML_RCDATA), /** Just before a tag name on an open tag. */ HTML_BEFORE_OPEN_TAG_NAME(EscapingMode.FILTER_HTML_ELEMENT_NAME), /** Just before a tag name on an close tag. */ HTML_BEFORE_CLOSE_TAG_NAME(EscapingMode.FILTER_HTML_ELEMENT_NAME), /** * Just after a tag name, e.g. in ^ in <script^> or <div^>. * * <p>Note tag names must be printed all at once since we can't otherwise easily handle <s{if * 1}cript{/if}>. */ HTML_TAG_NAME( "Dynamic values are not permitted in the middle of an HTML tag name;" + " try adding a space before."), /** Before an HTML attribute or the end of a tag. */ HTML_TAG(EscapingMode.FILTER_HTML_ATTRIBUTES), // TODO: Do we need to filter out names that look like JS/CSS/URI attribute names. /** Inside an HTML attribute name. */ HTML_ATTRIBUTE_NAME(EscapingMode.FILTER_HTML_ATTRIBUTES), /** Following an equals sign (<tt>=</tt>) after an attribute name in an HTML tag. */ HTML_BEFORE_ATTRIBUTE_VALUE("(unexpected state)"), /** Inside an HTML comment. */ HTML_COMMENT(EscapingMode.ESCAPE_HTML_RCDATA), /** Inside a normal (non-CSS, JS, or URI) HTML attribute value. */ HTML_NORMAL_ATTR_VALUE(EscapingMode.ESCAPE_HTML_ATTRIBUTE), /** In CSS content outside a comment, string, or URI. */ CSS(EscapingMode.FILTER_CSS_VALUE), /** In CSS inside a comment. */ CSS_COMMENT("CSS comments cannot contain dynamic values."), /** In CSS inside a double quoted string. */ CSS_DQ_STRING(EscapingMode.ESCAPE_CSS_STRING), /** In CSS inside a single quoted string. */ CSS_SQ_STRING(EscapingMode.ESCAPE_CSS_STRING), /** In CSS in a URI terminated by the first close parenthesis. */ CSS_URI(EscapingMode.NORMALIZE_URI), /** In CSS in a URI terminated by the first double quote. */ CSS_DQ_URI(EscapingMode.NORMALIZE_URI), /** In CSS in a URI terminated by the first single quote. */ CSS_SQ_URI(EscapingMode.NORMALIZE_URI), /** In JavaScript, outside a comment, string, or Regexp literal. */ JS(EscapingMode.ESCAPE_JS_VALUE), /** In JavaScript inside a line comment. */ JS_LINE_COMMENT("JS comments cannot contain dynamic values."), /** In JavaScript inside a block comment. */ JS_BLOCK_COMMENT("JS comments cannot contain dynamic values."), /** In JavaScript inside a double quoted string. */ JS_DQ_STRING(EscapingMode.ESCAPE_JS_STRING), /** In JavaScript inside a single quoted string. */ JS_SQ_STRING(EscapingMode.ESCAPE_JS_STRING), /** In JavaScript inside a regular expression literal. */ JS_REGEX(EscapingMode.ESCAPE_JS_REGEX), /** In a URI, which may or may not be in an HTML attribute. */ URI(EscapingMode.NORMALIZE_URI), /** Plain text; no escaping. */ TEXT(EscapingMode.TEXT); @Nullable private final EscapingMode escapingMode; @Nullable private final String errorMessage; /** * The escaping mode appropriate for dynamic content inserted at this state. Null if there is no * appropriate escaping convention to use as for comments or plain text which do not have escaping * conventions. */ public EscapingMode getEscapingMode() { return escapingMode; } /** Error message to show when trying to print a dynamic value inside of this state. */ public String getErrorMessage() { return errorMessage; } HtmlContext(EscapingMode escapingMode) { this.escapingMode = escapingMode; this.errorMessage = null; } HtmlContext(String errorMessage) { this.errorMessage = errorMessage; this.escapingMode = null; } }