| Index: sdk/lib/convert/html_escape.dart
|
| diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart
|
| index 512d9c31f2bf4da229779f9a6dba2d21d6869946..f4be4c6595c70f37ec15771b07db21c73bd7bda9 100644
|
| --- a/sdk/lib/convert/html_escape.dart
|
| +++ b/sdk/lib/convert/html_escape.dart
|
| @@ -7,39 +7,125 @@ part of dart.convert;
|
| // TODO(floitsch) - Document - Issue 13097
|
| const HtmlEscape HTML_ESCAPE = const HtmlEscape();
|
|
|
| +/**
|
| + * HTML escape modes.
|
| + *
|
| + * Allows specifying a mode for HTML escaping that depend on the context
|
| + * where the escaped result is going to be used.
|
| + * The relevant contexts are:
|
| + *
|
| + * * as text content of an HTML element.
|
| + * * as value of a (single- or double-) quoted attribute value.
|
| + *
|
| + * All modes require escaping of `&` (ampersand) characters, and may
|
| + * enable escaping of more characters.
|
| + */
|
| class HtmlEscapeMode {
|
| final String _name;
|
| + /** Whether to escape '<' and '>'. */
|
| final bool escapeLtGt;
|
| + /** Whether to escape '"' (quote). */
|
| final bool escapeQuot;
|
| + /** Whether to escape "'" (apostrophe). */
|
| final bool escapeApos;
|
| - final bool escapeSlash;
|
|
|
| - // TODO(floitsch) - Document - Issue 13097
|
| + /**
|
| + * Default escaping mode which escape all characters.
|
| + *
|
| + * The result of such an escaping is usable both in element content and
|
| + * in any attribute value.
|
| + *
|
| + * The escaping only works for elements with normal HTML content,
|
| + * and not for, for example, script or style element content,
|
| + * which require escapes matching their particular content syntax.
|
| + */
|
| static const HtmlEscapeMode UNKNOWN =
|
| - const HtmlEscapeMode._('unknown', true, true, true, true);
|
| -
|
| - // TODO(floitsch) - Document - Issue 13097
|
| + const HtmlEscapeMode._('unknown', true, true, true);
|
| +
|
| + /**
|
| + * Escaping mode for text going into double-quoted HTML attribute values.
|
| + *
|
| + * The result should not be used as the content of an unquoted
|
| + * or single-quoted attribute value.
|
| + *
|
| + * Escapes only double quotes (`"`) but not single quotes (`'`).
|
| + */
|
| static const HtmlEscapeMode ATTRIBUTE =
|
| - const HtmlEscapeMode._('attribute', false, true, false, false);
|
| -
|
| - // TODO(floitsch) - Document - Issue 13097
|
| + const HtmlEscapeMode._('attribute', false, true, false);
|
| +
|
| + /**
|
| + * Escaping mode for text going into single-quoted HTML attribute values.
|
| + *
|
| + * The result should not be used as the content of an unquoted
|
| + * or double-quoted attribute value.
|
| + *
|
| + * Escapes only single quotes (`'`) but not double quotes (`"`).
|
| + */
|
| + static const HtmlEscapeMode SQ_ATTRIBUTE =
|
| + const HtmlEscapeMode._('attribute', false, false, true);
|
| +
|
| + /**
|
| + * Escaping mode for text going into HTML element content.
|
| + *
|
| + * The escaping only works for elements with normal HTML content,
|
| + * and not for, for example, script or style element content,
|
| + * which require escapes matching their particular content syntax.
|
| + *
|
| + * Escapes `<` and `>` characters.
|
| + */
|
| static const HtmlEscapeMode ELEMENT =
|
| - const HtmlEscapeMode._('element', true, false, false, true);
|
| -
|
| - // TODO(floitsch) - Document - Issue 13097
|
| - const HtmlEscapeMode._(this._name, this.escapeLtGt, this.escapeQuot,
|
| - this.escapeApos, this.escapeSlash);
|
| + const HtmlEscapeMode._('element', true, false, false);
|
| +
|
| + const HtmlEscapeMode._(
|
| + this._name, this.escapeLtGt, this.escapeQuot, this.escapeApos);
|
| +
|
| + /**
|
| + * Create a custom escaping mode.
|
| + *
|
| + * All modes escape `&`.
|
| + * The mode can further be set to escape `<` and `>` ([escapeLtGt]),
|
| + * `"` ([escapeQuot]) and/or `'` ([escapeApos]).
|
| + */
|
| + const HtmlEscapeMode({String name: "custom",
|
| + this.escapeLtGt: false,
|
| + this.escapeQuot: false,
|
| + this.escapeApos: false}) : _name = name;
|
|
|
| String toString() => _name;
|
| }
|
|
|
| - // TODO(floitsch) - Document - Issue 13097
|
| +/**
|
| + * Converter which escapes characters with special meaning in HTML.
|
| + *
|
| + * The converter finds characters that are siginificant in HTML source and
|
| + * replaces them with corresponding HTML entities.
|
| + *
|
| + * The characters that need escaping in HTML are:
|
| + *
|
| + * * `&` (ampersand) always need to be escaped.
|
| + * * `<` (less than) and '>' (greater than) when inside an element.
|
| + * * `"` (quote) when inside a double-quoted attribute value.
|
| + * * `'` (apostrophe) when inside a single-quoted attribute value.
|
| + * Apostrophe is escaped as `'` instead of `'` since
|
| + * not all browsers understand `'`.
|
| + *
|
| + * Escaping `>` (greater than) isn't necessary, but the result is often
|
| + * found to be easier to read if greater-than is also escaped whenever
|
| + * less-than is.
|
| + */
|
| class HtmlEscape extends Converter<String, String> {
|
|
|
| - // TODO(floitsch) - Document - Issue 13097
|
| + /** The [HtmlEscapeMode] used by the converter. */
|
| final HtmlEscapeMode mode;
|
|
|
| - // TODO(floitsch) - Document - Issue 13097
|
| + /**
|
| + * Create converter that escapes HTML characters.
|
| + *
|
| + * If [mode] is provided as either [HtmlEscapeMode.ATTRIBUTE] or
|
| + * [HtmlEscapeMode.ELEMENT], only the corresponding subset of HTML
|
| + * characters are escaped.
|
| + * The default is to escape all HTML characters.
|
| + */
|
| const HtmlEscape([this.mode = HtmlEscapeMode.UNKNOWN]);
|
|
|
| String convert(String text) {
|
| @@ -47,29 +133,34 @@ class HtmlEscape extends Converter<String, String> {
|
| return val == null ? text : val;
|
| }
|
|
|
| + /**
|
| + * Converts the substring of text from start to end.
|
| + *
|
| + * Returns `null` if no changes were necessary, otherwise returns
|
| + * the converted string.
|
| + */
|
| String _convert(String text, int start, int end) {
|
| StringBuffer result = null;
|
| for (int i = start; i < end; i++) {
|
| var ch = text[i];
|
| - String replace = null;
|
| + String replacement = null;
|
| switch (ch) {
|
| - case '&': replace = '&'; break;
|
| - case '\u00A0'/*NO-BREAK SPACE*/: replace = ' '; break;
|
| - case '"': if (mode.escapeQuot) replace = '"'; break;
|
| - case "'": if (mode.escapeApos) replace = '''; break;
|
| - case '<': if (mode.escapeLtGt) replace = '<'; break;
|
| - case '>': if (mode.escapeLtGt) replace = '>'; break;
|
| - case '/': if (mode.escapeSlash) replace = '/'; break;
|
| + case '&': replacement = '&'; break;
|
| + case '"': if (mode.escapeQuot) replacement = '"'; break;
|
| + case "'": if (mode.escapeApos) replacement = '''; break;
|
| + case '<': if (mode.escapeLtGt) replacement = '<'; break;
|
| + case '>': if (mode.escapeLtGt) replacement = '>'; break;
|
| }
|
| - if (replace != null) {
|
| - if (result == null) result = new StringBuffer(text.substring(start, i));
|
| - result.write(replace);
|
| - } else if (result != null) {
|
| - result.write(ch);
|
| + if (replacement != null) {
|
| + if (result == null) result = new StringBuffer();
|
| + if (i > start) result.write(text.substring(start, i));
|
| + result.write(replacement);
|
| + start = i + 1;
|
| }
|
| }
|
| -
|
| - return result != null ? result.toString() : null;
|
| + if (result == null) return null;
|
| + if (end > start) result.write(text.substring(start, end));
|
| + return result.toString();
|
| }
|
|
|
| StringConversionSink startChunkedConversion(Sink<String> sink) {
|
|
|