|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 /*global intl_Collator: false, */ |
|
6 |
|
7 /* ES6 Draft September 5, 2013 21.1.3.3 */ |
|
8 function String_codePointAt(pos) { |
|
9 // Steps 1-3. |
|
10 CheckObjectCoercible(this); |
|
11 var S = ToString(this); |
|
12 |
|
13 // Steps 4-5. |
|
14 var position = ToInteger(pos); |
|
15 |
|
16 // Step 6. |
|
17 var size = S.length; |
|
18 |
|
19 // Step 7. |
|
20 if (position < 0 || position >= size) |
|
21 return undefined; |
|
22 |
|
23 // Steps 8-9. |
|
24 var first = callFunction(std_String_charCodeAt, S, position); |
|
25 if (first < 0xD800 || first > 0xDBFF || position + 1 === size) |
|
26 return first; |
|
27 |
|
28 // Steps 10-11. |
|
29 var second = callFunction(std_String_charCodeAt, S, position + 1); |
|
30 if (second < 0xDC00 || second > 0xDFFF) |
|
31 return first; |
|
32 |
|
33 // Step 12. |
|
34 return (first - 0xD800) * 0x400 + (second - 0xDC00) + 0x10000; |
|
35 } |
|
36 |
|
37 var collatorCache = new Record(); |
|
38 |
|
39 /* ES6 20121122 draft 15.5.4.21. */ |
|
40 function String_repeat(count) { |
|
41 // Steps 1-3. |
|
42 CheckObjectCoercible(this); |
|
43 var S = ToString(this); |
|
44 |
|
45 // Steps 4-5. |
|
46 var n = ToInteger(count); |
|
47 |
|
48 // Steps 6-7. |
|
49 if (n < 0) |
|
50 ThrowError(JSMSG_NEGATIVE_REPETITION_COUNT); // a RangeError |
|
51 |
|
52 if (!(n * S.length < (1 << 28))) |
|
53 ThrowError(JSMSG_RESULTING_STRING_TOO_LARGE); // a RangeError |
|
54 |
|
55 // Communicate |n|'s possible range to the compiler. |
|
56 n = n & ((1 << 28) - 1); |
|
57 |
|
58 // Steps 8-9. |
|
59 var T = ""; |
|
60 for (;;) { |
|
61 if (n & 1) |
|
62 T += S; |
|
63 n >>= 1; |
|
64 if (n) |
|
65 S += S; |
|
66 else |
|
67 break; |
|
68 } |
|
69 return T; |
|
70 } |
|
71 |
|
72 #define STRING_ITERATOR_SLOT_ITERATED_OBJECT 0 |
|
73 #define STRING_ITERATOR_SLOT_NEXT_INDEX 1 |
|
74 |
|
75 // ES6 draft specification, section 21.1.3.27, version 2013-09-27. |
|
76 function String_iterator() { |
|
77 CheckObjectCoercible(this); |
|
78 var S = ToString(this); |
|
79 var iterator = NewStringIterator(); |
|
80 UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_ITERATED_OBJECT, S); |
|
81 UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_NEXT_INDEX, 0); |
|
82 return iterator; |
|
83 } |
|
84 |
|
85 function StringIteratorIdentity() { |
|
86 return this; |
|
87 } |
|
88 |
|
89 function StringIteratorNext() { |
|
90 // FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 924059. |
|
91 if (!IsObject(this) || !IsStringIterator(this)) |
|
92 ThrowError(JSMSG_INCOMPATIBLE_METHOD, "StringIterator", "next", ToString(this)); |
|
93 |
|
94 var S = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_ITERATED_OBJECT); |
|
95 var index = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX); |
|
96 var size = S.length; |
|
97 |
|
98 if (index >= size) { |
|
99 return { value: undefined, done: true }; |
|
100 } |
|
101 |
|
102 var charCount = 1; |
|
103 var first = callFunction(std_String_charCodeAt, S, index); |
|
104 if (first >= 0xD800 && first <= 0xDBFF && index + 1 < size) { |
|
105 var second = callFunction(std_String_charCodeAt, S, index + 1); |
|
106 if (second >= 0xDC00 && second <= 0xDFFF) { |
|
107 charCount = 2; |
|
108 } |
|
109 } |
|
110 |
|
111 UnsafeSetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX, index + charCount); |
|
112 var value = callFunction(std_String_substring, S, index, index + charCount); |
|
113 |
|
114 return { value: value, done: false }; |
|
115 } |
|
116 |
|
117 /** |
|
118 * Compare this String against that String, using the locale and collation |
|
119 * options provided. |
|
120 * |
|
121 * Spec: ECMAScript Internationalization API Specification, 13.1.1. |
|
122 */ |
|
123 function String_localeCompare(that) { |
|
124 // Steps 1-3. |
|
125 CheckObjectCoercible(this); |
|
126 var S = ToString(this); |
|
127 var That = ToString(that); |
|
128 |
|
129 // Steps 4-5. |
|
130 var locales = arguments.length > 1 ? arguments[1] : undefined; |
|
131 var options = arguments.length > 2 ? arguments[2] : undefined; |
|
132 |
|
133 // Step 6. |
|
134 var collator; |
|
135 if (locales === undefined && options === undefined) { |
|
136 // This cache only optimizes for the old ES5 localeCompare without |
|
137 // locales and options. |
|
138 if (collatorCache.collator === undefined) |
|
139 collatorCache.collator = intl_Collator(locales, options); |
|
140 collator = collatorCache.collator; |
|
141 } else { |
|
142 collator = intl_Collator(locales, options); |
|
143 } |
|
144 |
|
145 // Step 7. |
|
146 return intl_CompareStrings(collator, S, That); |
|
147 } |
|
148 |
|
149 /* ES6 Draft September 5, 2013 21.1.2.2 */ |
|
150 function String_static_fromCodePoint() { |
|
151 // Step 1. is not relevant |
|
152 // Step 2. |
|
153 var length = arguments.length; |
|
154 |
|
155 // Step 3. |
|
156 var elements = new List(); |
|
157 |
|
158 // Step 4-5., 5g. |
|
159 for (var nextIndex = 0; nextIndex < length; nextIndex++) { |
|
160 // Step 5a. |
|
161 var next = arguments[nextIndex]; |
|
162 // Step 5b-c. |
|
163 var nextCP = ToNumber(next); |
|
164 |
|
165 // Step 5d. |
|
166 if (nextCP !== ToInteger(nextCP) || std_isNaN(nextCP)) |
|
167 ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); |
|
168 |
|
169 // Step 5e. |
|
170 if (nextCP < 0 || nextCP > 0x10FFFF) |
|
171 ThrowError(JSMSG_NOT_A_CODEPOINT, ToString(nextCP)); |
|
172 |
|
173 // Step 5f. |
|
174 // Inlined UTF-16 Encoding |
|
175 if (nextCP <= 0xFFFF) { |
|
176 elements.push(nextCP); |
|
177 continue; |
|
178 } |
|
179 |
|
180 elements.push((((nextCP - 0x10000) / 0x400) | 0) + 0xD800); |
|
181 elements.push((nextCP - 0x10000) % 0x400 + 0xDC00); |
|
182 } |
|
183 |
|
184 // Step 6. |
|
185 return callFunction(std_Function_apply, std_String_fromCharCode, null, elements); |
|
186 } |
|
187 |
|
188 /** |
|
189 * Compare String str1 against String str2, using the locale and collation |
|
190 * options provided. |
|
191 * |
|
192 * Mozilla proprietary. |
|
193 * Spec: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#String_generic_methods |
|
194 */ |
|
195 function String_static_localeCompare(str1, str2) { |
|
196 if (arguments.length < 1) |
|
197 ThrowError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare"); |
|
198 var locales = arguments.length > 2 ? arguments[2] : undefined; |
|
199 var options = arguments.length > 3 ? arguments[3] : undefined; |
|
200 return callFunction(String_localeCompare, str1, str2, locales, options); |
|
201 } |
|
202 |