Chromium Code Reviews| Index: sdk/lib/_internal/lib/js_string.dart |
| diff --git a/sdk/lib/_internal/lib/js_string.dart b/sdk/lib/_internal/lib/js_string.dart |
| index 4055647e46b5407a8260eac22f03a0469332feb3..b6d54876c9d7e2e742b4c84b45d17e12a4d47abe 100644 |
| --- a/sdk/lib/_internal/lib/js_string.dart |
| +++ b/sdk/lib/_internal/lib/js_string.dart |
| @@ -175,6 +175,37 @@ class JSString extends Interceptor implements String, JSIndexable { |
| } |
| } |
| + /// Finds the index of the first non-whitespace character, or the |
| + /// end of the string. |
| + static int _skipLeadingWhitespace(String string, int index) { |
| + while (index < string.length) { |
| + int codeUnit = string.codeUnitAt(index); |
| + if (codeUnit == SPACE || |
| + codeUnit == CARRIAGE_RETURN || |
| + _isWhitespace(codeUnit)) { |
| + index++; |
| + } else { |
| + break; |
| + } |
| + } |
| + return index; |
| + } |
| + |
| + /// Finds the index after the the last non-whitespace character, or 0. |
| + static int _skipTrailingWhitespace(String string, int index) { |
| + while (index > 0) { |
| + int codeUnit = string.codeUnitAt(index - 1); |
| + if (codeUnit == SPACE || |
| + codeUnit == CARRIAGE_RETURN || |
| + _isWhitespace(codeUnit)) { |
| + index--; |
| + } else { |
| + break; |
| + } |
| + } |
| + return index; |
| + } |
| + |
| // Dart2js can't use JavaScript trim, because JavaScript does not trim |
| // the NEXT LINE character (0x85) and BOMs (0xFEFF). |
| String trim() { |
| @@ -191,17 +222,7 @@ class JSString extends Interceptor implements String, JSIndexable { |
| int firstCode = result.codeUnitAt(0); |
| int startIndex = 0; |
| if (firstCode == NEL || firstCode == BOM) { |
|
Søren Gjesse
2014/03/10 16:50:03
What if there are several BOM/NEL characters? Shou
Lasse Reichstein Nielsen
2014/03/11 10:36:29
Those are handled by _skipLeadingWhitespace. They
|
| - startIndex++; |
| - while (startIndex < result.length) { |
| - int codeUnit = result.codeUnitAt(startIndex); |
| - if (codeUnit == SPACE || |
| - codeUnit == CARRIAGE_RETURN || |
| - _isWhitespace(codeUnit)) { |
| - startIndex++; |
| - } else { |
| - break; |
| - } |
| - } |
| + startIndex = _skipLeadingWhitespace(this, 1); |
| if (startIndex == result.length) return ""; |
| } |
| @@ -210,22 +231,62 @@ class JSString extends Interceptor implements String, JSIndexable { |
| // Therefore we don't need to verify that endIndex > startIndex. |
| int lastCode = result.codeUnitAt(endIndex - 1); |
| if (lastCode == NEL || lastCode == BOM) { |
| - endIndex--; |
| - while (true) { |
| - int codeUnit = result.codeUnitAt(endIndex - 1); |
| - if (codeUnit == SPACE || |
| - codeUnit == CARRIAGE_RETURN || |
| - _isWhitespace(codeUnit)) { |
| - endIndex--; |
| - } else { |
| - break; |
| - } |
| - } |
| + endIndex = _skipTrailingWhitespace(this, endIndex - 1); |
| } |
| if (startIndex == 0 && endIndex == result.length) return result; |
| return JS('String', r'#.substring(#, #)', result, startIndex, endIndex); |
| } |
| + // Dart2js can't use JavaScript trim, because JavaScript does not trim |
| + // the NEXT LINE character (0x85) and BOMs (0xFEFF). |
| + String trimLeft() { |
| + const int CARRIAGE_RETURN = 0x0D; |
| + const int SPACE = 0x20; |
| + const int NEL = 0x85; |
| + const int BOM = 0xFEFF; |
| + |
| + // Start by doing JS trim. Then check if it leaves a NEL or BOM at |
| + // either end of the string. |
| + String result = JS('String', '#.trimLeft()', this); |
|
Lasse Reichstein Nielsen
2014/03/10 13:27:50
Just checked. "trimLeft" and "trimRight" are not i
Søren Gjesse
2014/03/10 16:50:03
Are we even doing that for trim?
Lasse Reichstein Nielsen
2014/03/11 10:36:29
Plain trim is in ES5.
My simple rewrite here would
|
| + |
| + if (result.length == 0) return result; |
| + int firstCode = result.codeUnitAt(0); |
| + int startIndex = 0; |
| + if (firstCode == NEL || firstCode == BOM) { |
| + startIndex = _skipLeadingWhitespace(this, 1); |
| + if (startIndex == result.length) return ""; |
| + } |
| + |
| + if (startIndex == 0) return result; |
| + return JS('String', r'#.substring(#, #)', |
| + result, startIndex, result.length); |
| + } |
| + |
| + // Dart2js can't use JavaScript trim, because JavaScript does not trim |
| + // the NEXT LINE character (0x85) and BOMs (0xFEFF). |
| + String trimRight() { |
| + const int CARRIAGE_RETURN = 0x0D; |
| + const int SPACE = 0x20; |
| + const int NEL = 0x85; |
| + const int BOM = 0xFEFF; |
| + |
| + // Start by doing JS trim. Then check if it leaves a NEL or BOM at |
| + // either end of the string. |
| + String result = JS('String', '#.trimRight()', this); |
| + |
| + if (result.length == 0) return result; |
| + |
| + int endIndex = result.length; |
| + // We know that there is at least one character that is non-whitespace. |
| + // Therefore we don't need to verify that endIndex > startIndex. |
| + int lastCode = result.codeUnitAt(endIndex - 1); |
| + if (lastCode == NEL || lastCode == BOM) { |
| + endIndex = _skipTrailingWhitespace(this, endIndex - 1); |
| + } |
| + if (endIndex == result.length) return result; |
| + return JS('String', r'#.substring(#, #)', result, 0, endIndex); |
| + } |
| + |
| String operator*(int times) { |
| if (0 >= times) return ''; // Unnecessary but hoists argument type check. |
| if (times == 1 || this.length == 0) return this; |