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..1f6a0f091a9958acecf263a8138eda7502206cde |
| --- /dev/null |
| +++ b/sdk/lib/convert/html_escape.dart |
| @@ -0,0 +1,81 @@ |
| +// 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; |
| + |
| +const HTML_ESCAPE = const HtmlEscape(); |
| + |
| +class HtmlEscapeMode { |
| + final String _name; |
| + final bool escapeLtGt; |
| + final bool escapeQuot; |
| + final bool escapeApos; |
| + |
| + static const HtmlEscapeMode UNKNOWN = |
| + const HtmlEscapeMode._('unknown', true, true, true); |
| + |
| + static const HtmlEscapeMode ATTRIBUTE = |
| + const HtmlEscapeMode._('attribute', false, true, false); |
| + |
| + static const HtmlEscapeMode ELEMENT = |
| + const HtmlEscapeMode._('element', true, false, false); |
| + |
| + const HtmlEscapeMode._(this._name, this.escapeLtGt, this.escapeQuot, |
| + this.escapeApos); |
| + |
| + String toString() => _name; |
| +} |
| + |
| +class HtmlEscape extends Converter<String, String> { |
| + final HtmlEscapeMode mode; |
| + |
| + const HtmlEscape([this.mode = HtmlEscapeMode.UNKNOWN]); |
| + |
| + String convert(String text) { |
| + StringBuffer result = null; |
| + for (int i = 0; i < text.length; i++) { |
| + var ch = text[i]; |
|
floitsch
2013/08/30 15:52:00
Nit: we usually type everything in the dart: libra
Jennifer Messerly
2013/08/30 18:13:59
it is a shame styles in different parts of the cod
|
| + 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(0, i)); |
| + result.write(replace); |
| + } else if (result != null) { |
| + result.write(ch); |
| + } |
| + } |
| + |
| + return result != null ? result.toString() : text; |
| + } |
| + |
| + 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) { |
| + _sink.add(_escape.convert(chunk.substring(start, end))); |
|
floitsch
2013/08/30 15:52:00
Add:
TODO(floitsch): Optimize.
kevmoo-old
2013/09/05 20:30:06
Does the last change handle your request to optimi
|
| + if (isLast) _sink.close(); |
| + } |
| + |
| + void close() => _sink.close(); |
| +} |