134 lines
4.0 KiB
JavaScript
134 lines
4.0 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/*global intl_Collator: false, */
|
|
|
|
|
|
var collatorCache = new Record();
|
|
|
|
/* ES6 20121122 draft 15.5.4.21. */
|
|
function String_repeat(count) {
|
|
// Steps 1-3.
|
|
CheckObjectCoercible(this);
|
|
var S = ToString(this);
|
|
|
|
// Steps 4-5.
|
|
var n = ToInteger(count);
|
|
|
|
// Steps 6-7.
|
|
if (n < 0)
|
|
ThrowError(JSMSG_NEGATIVE_REPETITION_COUNT); // a RangeError
|
|
|
|
if (!(n * S.length < (1 << 28)))
|
|
ThrowError(JSMSG_RESULTING_STRING_TOO_LARGE); // a RangeError
|
|
|
|
// Communicate |n|'s possible range to the compiler.
|
|
n = n & ((1 << 28) - 1);
|
|
|
|
// Steps 8-9.
|
|
var T = "";
|
|
for (;;) {
|
|
if (n & 1)
|
|
T += S;
|
|
n >>= 1;
|
|
if (n)
|
|
S += S;
|
|
else
|
|
break;
|
|
}
|
|
return T;
|
|
}
|
|
|
|
#define STRING_ITERATOR_SLOT_ITERATED_OBJECT 0
|
|
#define STRING_ITERATOR_SLOT_NEXT_INDEX 1
|
|
|
|
// ES6 draft specification, section 21.1.3.27, version 2013-09-27.
|
|
function String_iterator() {
|
|
CheckObjectCoercible(this);
|
|
var S = ToString(this);
|
|
var iterator = NewStringIterator();
|
|
UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_ITERATED_OBJECT, S);
|
|
UnsafeSetReservedSlot(iterator, STRING_ITERATOR_SLOT_NEXT_INDEX, 0);
|
|
return iterator;
|
|
}
|
|
|
|
function StringIteratorIdentity() {
|
|
return this;
|
|
}
|
|
|
|
function StringIteratorNext() {
|
|
// FIXME: Cross-compartment wrapper StringIterator objects should pass this test. Bug 924059.
|
|
if (!IsObject(this) || !IsStringIterator(this))
|
|
ThrowError(JSMSG_INCOMPATIBLE_METHOD, "StringIterator", "next", ToString(this));
|
|
|
|
var S = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_ITERATED_OBJECT);
|
|
var index = UnsafeGetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX);
|
|
var size = S.length;
|
|
|
|
if (index >= size) {
|
|
return { value: undefined, done: true };
|
|
}
|
|
|
|
var charCount = 1;
|
|
var first = callFunction(std_String_charCodeAt, S, index);
|
|
if (first >= 0xD800 && first <= 0xDBFF && index + 1 < size) {
|
|
var second = callFunction(std_String_charCodeAt, S, index + 1);
|
|
if (second >= 0xDC00 && second <= 0xDFFF) {
|
|
charCount = 2;
|
|
}
|
|
}
|
|
|
|
UnsafeSetReservedSlot(this, STRING_ITERATOR_SLOT_NEXT_INDEX, index + charCount);
|
|
var value = callFunction(std_String_substring, S, index, index + charCount);
|
|
|
|
return { value: value, done: false };
|
|
}
|
|
|
|
/**
|
|
* Compare this String against that String, using the locale and collation
|
|
* options provided.
|
|
*
|
|
* Spec: ECMAScript Internationalization API Specification, 13.1.1.
|
|
*/
|
|
function String_localeCompare(that) {
|
|
// Steps 1-3.
|
|
CheckObjectCoercible(this);
|
|
var S = ToString(this);
|
|
var That = ToString(that);
|
|
|
|
// Steps 4-5.
|
|
var locales = arguments.length > 1 ? arguments[1] : undefined;
|
|
var options = arguments.length > 2 ? arguments[2] : undefined;
|
|
|
|
// Step 6.
|
|
var collator;
|
|
if (locales === undefined && options === undefined) {
|
|
// This cache only optimizes for the old ES5 localeCompare without
|
|
// locales and options.
|
|
if (collatorCache.collator === undefined)
|
|
collatorCache.collator = intl_Collator(locales, options);
|
|
collator = collatorCache.collator;
|
|
} else {
|
|
collator = intl_Collator(locales, options);
|
|
}
|
|
|
|
// Step 7.
|
|
return intl_CompareStrings(collator, S, That);
|
|
}
|
|
|
|
/**
|
|
* Compare String str1 against String str2, using the locale and collation
|
|
* options provided.
|
|
*
|
|
* Mozilla proprietary.
|
|
* Spec: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/String#String_generic_methods
|
|
*/
|
|
function String_static_localeCompare(str1, str2) {
|
|
if (arguments.length < 1)
|
|
ThrowError(JSMSG_MISSING_FUN_ARG, 0, "String.localeCompare");
|
|
var locales = arguments.length > 2 ? arguments[2] : undefined;
|
|
var options = arguments.length > 3 ? arguments[3] : undefined;
|
|
return callFunction(String_localeCompare, str1, str2, locales, options);
|
|
}
|