Chromium Code Reviews| Index: sdk/lib/convert/html_escape.dart |
| diff --git a/sdk/lib/convert/html_escape.dart b/sdk/lib/convert/html_escape.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..dd9f3e710ea2d939e5312f1fae1d1a14b5cf529e |
| --- /dev/null |
| +++ b/sdk/lib/convert/html_escape.dart |
| @@ -0,0 +1,100 @@ |
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +part of dart.convert; |
| + |
| +// TODO(floitsch) - Document - Issue 13097 |
| +const HTML_ESCAPE = const HtmlEscape(); |
| + |
| +class HtmlEscapeMode { |
|
Jennifer Messerly
2013/09/05 20:41:37
nit: I think you could just have one TODO about th
|
| + final String _name; |
| + final bool escapeLtGt; |
| + final bool escapeQuot; |
| + final bool escapeApos; |
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| + static const HtmlEscapeMode UNKNOWN = |
|
Jennifer Messerly
2013/09/05 20:41:37
suggestion: rename UNKNOWN_QUOTED_ATTRIBUTE
(the
|
| + const HtmlEscapeMode._('unknown', true, true, true); |
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| + static const HtmlEscapeMode ATTRIBUTE = |
|
Jennifer Messerly
2013/09/05 20:41:37
DOUBLE_QUOTE_ATTRIBUTE
and add SINGLE_QUOTE_ATTRI
|
| + const HtmlEscapeMode._('attribute', false, true, false); |
|
Jennifer Messerly
2013/09/05 20:41:37
Shouldn't this include less than and greater than
kevmoo-old
2013/09/07 20:34:15
The argument is that they are unneeded. Only in el
|
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| + static const HtmlEscapeMode ELEMENT = |
|
Jennifer Messerly
2013/09/05 20:41:37
ELEMENT_CONTENT
|
| + const HtmlEscapeMode._('element', true, false, false); |
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| + const HtmlEscapeMode._(this._name, this.escapeLtGt, this.escapeQuot, |
|
Jennifer Messerly
2013/09/05 20:41:37
named arguments to make call the definitions more
kevmoo-old
2013/09/07 20:34:15
Agreed.
|
| + this.escapeApos); |
| + |
| + String toString() => _name; |
| +} |
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| +class HtmlEscape extends Converter<String, String> { |
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| + final HtmlEscapeMode mode; |
| + |
| + // TODO(floitsch) - Document - Issue 13097 |
| + const HtmlEscape([this.mode = HtmlEscapeMode.UNKNOWN]); |
| + |
| + String convert(String text) { |
| + var val = _convert(text, 0, text.length); |
| + return val == null ? text : val; |
| + } |
| + |
| + 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; |
| + 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; |
| + } |
| + if (replace != null) { |
| + if (result == null) result = new StringBuffer(text.substring(start, i)); |
| + result.write(replace); |
| + } else if (result != null) { |
| + result.write(ch); |
| + } |
| + } |
| + |
| + return result != null ? result.toString() : null; |
| + } |
| + |
| + StringConversionSink startChunkedConversion( |
| + ChunkedConversionSink<String> sink) { |
| + |
| + if (sink is! StringConversionSink) { |
| + sink = new StringConversionSink.from(sink); |
| + } |
| + return new _HtmlEscapeSink(this, sink); |
| + } |
| +} |
| + |
| +class _HtmlEscapeSink extends StringConversionSinkBase { |
| + final HtmlEscape _escape; |
| + final StringConversionSink _sink; |
| + |
| + _HtmlEscapeSink(this._escape, this._sink); |
| + |
| + void addSlice(String chunk, int start, int end, bool isLast) { |
| + var val = _escape._convert(chunk, start, end); |
| + if(val == null) { |
| + _sink.addSlice(chunk, start, end, isLast); |
| + } else { |
| + _sink.add(val); |
| + if (isLast) _sink.close(); |
| + } |
| + } |
| + |
| + void close() => _sink.close(); |
| +} |