From: christian.plesner.hansen@gmail.com Date: Tue, 13 Oct 2009 08:13:45 +0000 (+0000) Subject: Add trim, trimLeft and trimRight methods to String X-Git-Tag: upstream/4.7.83~23161 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f1354a299eb4423cfebd4d8f72a487b1f31658bd;p=platform%2Fupstream%2Fv8.git Add trim, trimLeft and trimRight methods to String Based on a recent patch for Webkit. trim is defined in ES 5 section 15.5.4.20. Author: Jan de Mooij git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3052 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/runtime.cc b/src/runtime.cc index ab4572d..a2a8193 100644 --- a/src/runtime.cc +++ b/src/runtime.cc @@ -3584,6 +3584,36 @@ static Object* Runtime_StringToUpperCase(Arguments args) { return ConvertCase(args, &to_upper_mapping); } +static inline bool IsTrimWhiteSpace(unibrow::uchar c) { + return unibrow::WhiteSpace::Is(c) || c == 0x200b; +} + +static Object* Runtime_StringTrim(Arguments args) { + NoHandleAllocation ha; + ASSERT(args.length() == 3); + + CONVERT_CHECKED(String, s, args[0]); + CONVERT_BOOLEAN_CHECKED(trimLeft, args[1]); + CONVERT_BOOLEAN_CHECKED(trimRight, args[2]); + + s->TryFlattenIfNotFlat(); + int length = s->length(); + + int left = 0; + if (trimLeft) { + while (left < length && IsTrimWhiteSpace(s->Get(left))) { + left++; + } + } + + int right = length; + if (trimRight) { + while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) { + right--; + } + } + return s->Slice(left, right); +} bool Runtime::IsUpperCaseChar(uint16_t ch) { unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; diff --git a/src/runtime.h b/src/runtime.h index afa278b..279181d 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -152,6 +152,7 @@ namespace internal { F(StringSlice, 3, 1) \ F(StringReplaceRegExpWithString, 4, 1) \ F(StringMatch, 3, 1) \ + F(StringTrim, 3, 1) \ \ /* Numbers */ \ F(NumberToRadixString, 2, 1) \ diff --git a/src/string.js b/src/string.js index fbdc307..d2d6e96 100644 --- a/src/string.js +++ b/src/string.js @@ -680,6 +680,18 @@ function StringToLocaleUpperCase() { return %StringToUpperCase(ToString(this)); } +// ES5, 15.5.4.20 +function StringTrim() { + return %StringTrim(ToString(this), true, true); +} + +function StringTrimLeft() { + return %StringTrim(ToString(this), true, false); +} + +function StringTrimRight() { + return %StringTrim(ToString(this), false, true); +} // ECMA-262, section 15.5.3.2 function StringFromCharCode(code) { @@ -855,6 +867,9 @@ function SetupString() { "toLocaleLowerCase", StringToLocaleLowerCase, "toUpperCase", StringToUpperCase, "toLocaleUpperCase", StringToLocaleUpperCase, + "trim", StringTrim, + "trimLeft", StringTrimLeft, + "trimRight", StringTrimRight, "link", StringLink, "anchor", StringAnchor, "fontcolor", StringFontcolor, diff --git a/test/mjsunit/third_party/string-trim.js b/test/mjsunit/third_party/string-trim.js new file mode 100644 index 0000000..1a8d357 --- /dev/null +++ b/test/mjsunit/third_party/string-trim.js @@ -0,0 +1,107 @@ +// Copyright (c) 2009 Apple Computer, Inc. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// 3. Neither the name of the copyright holder(s) nor the names of any +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +// OF THE POSSIBILITY OF SUCH DAMAGE. + +// Based on LayoutTests/fast/js/script-tests/string-trim.js + +// References to trim(), trimLeft() and trimRight() functions for +// testing Function's *.call() and *.apply() methods. + +var trim = String.prototype.trim; +var trimLeft = String.prototype.trimLeft; +var trimRight = String.prototype.trimRight; + +var testString = 'foo bar'; +var trimString = ''; +var leftTrimString = ''; +var rightTrimString = ''; +var wsString = ''; + +var whitespace = [ + {s : '\u0009', t : 'HORIZONTAL TAB'}, + {s : '\u000A', t : 'LINE FEED OR NEW LINE'}, + {s : '\u000B', t : 'VERTICAL TAB'}, + {s : '\u000C', t : 'FORMFEED'}, + {s : '\u000D', t : 'CARRIAGE RETURN'}, + {s : '\u0020', t : 'SPACE'}, + {s : '\u00A0', t : 'NO-BREAK SPACE'}, + {s : '\u2000', t : 'EN QUAD'}, + {s : '\u2001', t : 'EM QUAD'}, + {s : '\u2002', t : 'EN SPACE'}, + {s : '\u2003', t : 'EM SPACE'}, + {s : '\u2004', t : 'THREE-PER-EM SPACE'}, + {s : '\u2005', t : 'FOUR-PER-EM SPACE'}, + {s : '\u2006', t : 'SIX-PER-EM SPACE'}, + {s : '\u2007', t : 'FIGURE SPACE'}, + {s : '\u2008', t : 'PUNCTUATION SPACE'}, + {s : '\u2009', t : 'THIN SPACE'}, + {s : '\u200A', t : 'HAIR SPACE'}, + {s : '\u3000', t : 'IDEOGRAPHIC SPACE'}, + {s : '\u2028', t : 'LINE SEPARATOR'}, + {s : '\u2029', t : 'PARAGRAPH SEPARATOR'}, + {s : '\u200B', t : 'ZERO WIDTH SPACE (category Cf)'} +]; + +for (var i = 0; i < whitespace.length; i++) { + assertEquals(whitespace[i].s.trim(), ''); + assertEquals(whitespace[i].s.trimLeft(), ''); + assertEquals(whitespace[i].s.trimRight(), ''); + wsString += whitespace[i].s; +} + +trimString = wsString + testString + wsString; +leftTrimString = testString + wsString; // Trimmed from the left. +rightTrimString = wsString + testString; // Trimmed from the right. + +assertEquals(wsString.trim(), ''); +assertEquals(wsString.trimLeft(), ''); +assertEquals(wsString.trimRight(), ''); + +assertEquals(trimString.trim(), testString); +assertEquals(trimString.trimLeft(), leftTrimString); +assertEquals(trimString.trimRight(), rightTrimString); + +assertEquals(leftTrimString.trim(), testString); +assertEquals(leftTrimString.trimLeft(), leftTrimString); +assertEquals(leftTrimString.trimRight(), testString); + +assertEquals(rightTrimString.trim(), testString); +assertEquals(rightTrimString.trimLeft(), testString); +assertEquals(rightTrimString.trimRight(), rightTrimString); + +var testValues = [0, Infinity, NaN, true, false, ({}), ['an','array'] + ({toString:function(){return 'wibble'}}) +]; + +for (var i = 0; i < testValues.length; i++) { + assertEquals(trim.call(testValues[i]), String(testValues[i])); + assertEquals(trimLeft.call(testValues[i]), String(testValues[i])); + assertEquals(trimRight.call(testValues[i]), String(testValues[i])); +}