868 lines
25 KiB
JavaScript
868 lines
25 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, */
|
|
|
|
function StringProtoHasNoMatch() {
|
|
var ObjectProto = GetBuiltinPrototype("Object");
|
|
var StringProto = GetBuiltinPrototype("String");
|
|
if (!ObjectHasPrototype(StringProto, ObjectProto))
|
|
return false;
|
|
return !(std_match in StringProto);
|
|
}
|
|
|
|
function IsStringMatchOptimizable() {
|
|
var RegExpProto = GetBuiltinPrototype("RegExp");
|
|
// If RegExpPrototypeOptimizable succeeds, `exec` and `@@match` are
|
|
// guaranteed to be data properties.
|
|
return RegExpPrototypeOptimizable(RegExpProto) &&
|
|
RegExpProto.exec === RegExp_prototype_Exec &&
|
|
RegExpProto[std_match] === RegExpMatch;
|
|
}
|
|
|
|
// ES 2016 draft Mar 25, 2016 21.1.3.11.
|
|
function String_match(regexp) {
|
|
// Step 1.
|
|
RequireObjectCoercible(this);
|
|
|
|
// Step 2.
|
|
var isPatternString = (typeof regexp === "string");
|
|
if (!(isPatternString && StringProtoHasNoMatch()) && regexp !== undefined && regexp !== null) {
|
|
// Step 2.a.
|
|
var matcher = GetMethod(regexp, std_match);
|
|
|
|
// Step 2.b.
|
|
if (matcher !== undefined)
|
|
return callContentFunction(matcher, regexp, this);
|
|
}
|
|
|
|
// Step 3.
|
|
var S = ToString(this);
|
|
|
|
if (isPatternString && IsStringMatchOptimizable()) {
|
|
var flatResult = FlatStringMatch(S, regexp);
|
|
if (flatResult !== undefined)
|
|
return flatResult;
|
|
}
|
|
|
|
// Step 4.
|
|
var rx = RegExpCreate(regexp);
|
|
|
|
// Step 5 (optimized case).
|
|
if (IsStringMatchOptimizable())
|
|
return RegExpMatcher(rx, S, 0);
|
|
|
|
// Step 5.
|
|
return callContentFunction(GetMethod(rx, std_match), rx, S);
|
|
}
|
|
|
|
function String_generic_match(thisValue, regexp) {
|
|
if (thisValue === undefined)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.match');
|
|
return callFunction(String_match, thisValue, regexp);
|
|
}
|
|
|
|
/**
|
|
* A helper function implementing the logic for both String.prototype.padStart
|
|
* and String.prototype.padEnd as described in ES7 Draft March 29, 2016
|
|
*/
|
|
function String_pad(maxLength, fillString, padEnd=false) {
|
|
|
|
// Steps 1-2.
|
|
RequireObjectCoercible(this);
|
|
let str = ToString(this);
|
|
|
|
// Steps 3-4.
|
|
let intMaxLength = ToLength(maxLength);
|
|
let strLen = str.length;
|
|
|
|
// Step 5.
|
|
if (intMaxLength <= strLen)
|
|
return str;
|
|
|
|
// Steps 6-7.
|
|
let filler = fillString === undefined ? " " : ToString(fillString);
|
|
|
|
// Step 8.
|
|
if (filler === "")
|
|
return str;
|
|
|
|
// Step 9.
|
|
let fillLen = intMaxLength - strLen;
|
|
|
|
// Step 10.
|
|
let truncatedStringFiller = callFunction(String_repeat, filler,
|
|
fillLen / filler.length);
|
|
|
|
truncatedStringFiller += callFunction(String_substr, filler, 0,
|
|
fillLen % filler.length);
|
|
|
|
// Step 11.
|
|
if (padEnd === true)
|
|
return str + truncatedStringFiller;
|
|
return truncatedStringFiller + str;
|
|
}
|
|
|
|
function String_pad_start(maxLength, fillString=" ") {
|
|
return callFunction(String_pad, this, maxLength, fillString, false);
|
|
}
|
|
|
|
function String_pad_end(maxLength, fillString=" ") {
|
|
return callFunction(String_pad, this, maxLength, fillString, true);
|
|
}
|
|
|
|
function StringProtoHasNoReplace() {
|
|
var ObjectProto = GetBuiltinPrototype("Object");
|
|
var StringProto = GetBuiltinPrototype("String");
|
|
if (!ObjectHasPrototype(StringProto, ObjectProto))
|
|
return false;
|
|
return !(std_replace in StringProto);
|
|
}
|
|
|
|
// A thin wrapper to call SubstringKernel with int32-typed arguments.
|
|
// Caller should check the range of |from| and |length|.
|
|
function Substring(str, from, length) {
|
|
assert(typeof str === "string", "|str| should be a string");
|
|
assert(from | 0 === from, "coercing |from| into int32 should not change the value");
|
|
assert(length | 0 === length, "coercing |length| into int32 should not change the value");
|
|
|
|
return SubstringKernel(str, from | 0, length | 0);
|
|
}
|
|
|
|
// ES 2016 draft Mar 25, 2016 21.1.3.14.
|
|
function String_replace(searchValue, replaceValue) {
|
|
// Step 1.
|
|
RequireObjectCoercible(this);
|
|
|
|
// Step 2.
|
|
if (!(typeof searchValue === "string" && StringProtoHasNoReplace()) &&
|
|
searchValue !== undefined && searchValue !== null)
|
|
{
|
|
// Step 2.a.
|
|
var replacer = GetMethod(searchValue, std_replace);
|
|
|
|
// Step 2.b.
|
|
if (replacer !== undefined)
|
|
return callContentFunction(replacer, searchValue, this, replaceValue);
|
|
}
|
|
|
|
// Step 3.
|
|
var string = ToString(this);
|
|
|
|
// Step 4.
|
|
var searchString = ToString(searchValue);
|
|
|
|
if (typeof replaceValue === "string") {
|
|
// Steps 6-12: Optimized for string case.
|
|
return StringReplaceString(string, searchString, replaceValue);
|
|
}
|
|
|
|
// Step 5.
|
|
if (!IsCallable(replaceValue)) {
|
|
// Steps 6-12.
|
|
return StringReplaceString(string, searchString, ToString(replaceValue));
|
|
}
|
|
|
|
// Step 7.
|
|
var pos = callFunction(std_String_indexOf, string, searchString);
|
|
if (pos === -1)
|
|
return string;
|
|
|
|
// Step 8.
|
|
var replStr = ToString(callContentFunction(replaceValue, undefined, searchString, pos, string));
|
|
|
|
// Step 10.
|
|
var tailPos = pos + searchString.length;
|
|
|
|
// Step 11.
|
|
var newString;
|
|
if (pos === 0)
|
|
newString = "";
|
|
else
|
|
newString = Substring(string, 0, pos);
|
|
|
|
newString += replStr;
|
|
var stringLength = string.length;
|
|
if (tailPos < stringLength)
|
|
newString += Substring(string, tailPos, stringLength - tailPos);
|
|
|
|
// Step 12.
|
|
return newString;
|
|
}
|
|
|
|
function String_generic_replace(thisValue, searchValue, replaceValue) {
|
|
if (thisValue === undefined)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.replace');
|
|
return callFunction(String_replace, thisValue, searchValue, replaceValue);
|
|
}
|
|
|
|
function StringProtoHasNoSearch() {
|
|
var ObjectProto = GetBuiltinPrototype("Object");
|
|
var StringProto = GetBuiltinPrototype("String");
|
|
if (!ObjectHasPrototype(StringProto, ObjectProto))
|
|
return false;
|
|
return !(std_search in StringProto);
|
|
}
|
|
|
|
function IsStringSearchOptimizable() {
|
|
var RegExpProto = GetBuiltinPrototype("RegExp");
|
|
// If RegExpPrototypeOptimizable succeeds, `exec` and `@@search` are
|
|
// guaranteed to be data properties.
|
|
return RegExpPrototypeOptimizable(RegExpProto) &&
|
|
RegExpProto.exec === RegExp_prototype_Exec &&
|
|
RegExpProto[std_search] === RegExpSearch;
|
|
}
|
|
|
|
// ES 2016 draft Mar 25, 2016 21.1.3.15.
|
|
function String_search(regexp) {
|
|
// Step 1.
|
|
RequireObjectCoercible(this);
|
|
|
|
// Step 2.
|
|
var isPatternString = (typeof regexp === "string");
|
|
if (!(isPatternString && StringProtoHasNoSearch()) && regexp !== undefined && regexp !== null) {
|
|
// Step 2.a.
|
|
var searcher = GetMethod(regexp, std_search);
|
|
|
|
// Step 2.b.
|
|
if (searcher !== undefined)
|
|
return callContentFunction(searcher, regexp, this);
|
|
}
|
|
|
|
// Step 3.
|
|
var string = ToString(this);
|
|
|
|
if (isPatternString && IsStringSearchOptimizable()) {
|
|
var flatResult = FlatStringSearch(string, regexp);
|
|
if (flatResult !== -2)
|
|
return flatResult;
|
|
}
|
|
|
|
// Step 4.
|
|
var rx = RegExpCreate(regexp);
|
|
|
|
// Step 5.
|
|
return callContentFunction(GetMethod(rx, std_search), rx, string);
|
|
}
|
|
|
|
function String_generic_search(thisValue, regexp) {
|
|
if (thisValue === undefined)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.search');
|
|
return callFunction(String_search, thisValue, regexp);
|
|
}
|
|
|
|
function StringProtoHasNoSplit() {
|
|
var ObjectProto = GetBuiltinPrototype("Object");
|
|
var StringProto = GetBuiltinPrototype("String");
|
|
if (!ObjectHasPrototype(StringProto, ObjectProto))
|
|
return false;
|
|
return !(std_split in StringProto);
|
|
}
|
|
|
|
// ES 2016 draft Mar 25, 2016 21.1.3.17.
|
|
function String_split(separator, limit) {
|
|
// Step 1.
|
|
RequireObjectCoercible(this);
|
|
|
|
// Optimized path for string.split(string), especially when both strings
|
|
// are constants. Following sequence of if's cannot be put together in
|
|
// order that IonMonkey sees the constant if present (bug 1246141).
|
|
if (typeof this === "string") {
|
|
if (StringProtoHasNoSplit()) {
|
|
if (typeof separator === "string") {
|
|
if (limit === undefined) {
|
|
// inlineConstantStringSplitString needs both arguments to
|
|
// be MConstant, so pass them directly.
|
|
return StringSplitString(this, separator);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Step 2.
|
|
if (!(typeof separator == "string" && StringProtoHasNoSplit()) &&
|
|
separator !== undefined && separator !== null)
|
|
{
|
|
// Step 2.a.
|
|
var splitter = GetMethod(separator, std_split);
|
|
|
|
// Step 2.b.
|
|
if (splitter !== undefined)
|
|
return callContentFunction(splitter, separator, this, limit);
|
|
}
|
|
|
|
// Step 3.
|
|
var S = ToString(this);
|
|
|
|
// Step 6.
|
|
var R;
|
|
if (limit !== undefined) {
|
|
var lim = limit >>> 0;
|
|
|
|
// Step 9.
|
|
R = ToString(separator);
|
|
|
|
// Step 10.
|
|
if (lim === 0)
|
|
return [];
|
|
|
|
// Step 11.
|
|
if (separator === undefined)
|
|
return [S];
|
|
|
|
// Steps 4, 8, 12-18.
|
|
return StringSplitStringLimit(S, R, lim);
|
|
}
|
|
|
|
// Step 9.
|
|
R = ToString(separator);
|
|
|
|
// Step 11.
|
|
if (separator === undefined)
|
|
return [S];
|
|
|
|
// Optimized path.
|
|
// Steps 4, 8, 12-18.
|
|
return StringSplitString(S, R);
|
|
}
|
|
|
|
function String_generic_split(thisValue, separator, limit) {
|
|
if (thisValue === undefined)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.split');
|
|
return callFunction(String_split, thisValue, separator, limit);
|
|
}
|
|
|
|
/* ES6 Draft Oct 14, 2014 21.1.3.19 */
|
|
function String_substring(start, end) {
|
|
// Steps 1-3.
|
|
RequireObjectCoercible(this);
|
|
var str = ToString(this);
|
|
|
|
// Step 4.
|
|
var len = str.length;
|
|
|
|
// Step 5.
|
|
var intStart = ToInteger(start);
|
|
|
|
// Step 6.
|
|
var intEnd = (end === undefined) ? len : ToInteger(end);
|
|
|
|
// Step 7.
|
|
var finalStart = std_Math_min(std_Math_max(intStart, 0), len);
|
|
|
|
// Step 8.
|
|
var finalEnd = std_Math_min(std_Math_max(intEnd, 0), len);
|
|
|
|
// Steps 9-10.
|
|
var from, to;
|
|
if (finalStart < finalEnd) {
|
|
from = finalStart;
|
|
to = finalEnd;
|
|
} else {
|
|
from = finalEnd;
|
|
to = finalStart;
|
|
}
|
|
|
|
// Step 11.
|
|
// While |from| and |to - from| are bounded to the length of |str| and this
|
|
// and thus definitely in the int32 range, they can still be typed as
|
|
// double. Eagerly truncate since SubstringKernel only accepts int32.
|
|
return SubstringKernel(str, from | 0, (to - from) | 0);
|
|
}
|
|
|
|
function String_static_substring(string, start, end) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.substring');
|
|
return callFunction(String_substring, string, start, end);
|
|
}
|
|
|
|
/* ES6 Draft Oct 14, 2014 B.2.3.1 */
|
|
function String_substr(start, length) {
|
|
// Steps 1-2.
|
|
RequireObjectCoercible(this);
|
|
var str = ToString(this);
|
|
|
|
// Steps 3-4.
|
|
var intStart = ToInteger(start);
|
|
|
|
// Steps 5-7.
|
|
var size = str.length;
|
|
// Use |size| instead of +Infinity to avoid performing calculations with
|
|
// doubles. (The result is the same either way.)
|
|
var end = (length === undefined) ? size : ToInteger(length);
|
|
|
|
// Step 8.
|
|
if (intStart < 0)
|
|
intStart = std_Math_max(intStart + size, 0);
|
|
|
|
// Step 9.
|
|
var resultLength = std_Math_min(std_Math_max(end, 0), size - intStart);
|
|
|
|
// Step 10.
|
|
if (resultLength <= 0)
|
|
return "";
|
|
|
|
// Step 11.
|
|
// While |intStart| and |resultLength| are bounded to the length of |str|
|
|
// and thus definitely in the int32 range, they can still be typed as
|
|
// double. Eagerly truncate since SubstringKernel only accepts int32.
|
|
return SubstringKernel(str, intStart | 0, resultLength | 0);
|
|
}
|
|
|
|
function String_static_substr(string, start, length) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.substr');
|
|
return callFunction(String_substr, string, start, length);
|
|
}
|
|
|
|
/* ES6 Draft Oct 14, 2014 21.1.3.16 */
|
|
function String_slice(start, end) {
|
|
// Steps 1-3.
|
|
RequireObjectCoercible(this);
|
|
var str = ToString(this);
|
|
|
|
// Step 4.
|
|
var len = str.length;
|
|
|
|
// Step 5.
|
|
var intStart = ToInteger(start);
|
|
|
|
// Step 6.
|
|
var intEnd = (end === undefined) ? len : ToInteger(end);
|
|
|
|
// Step 7.
|
|
var from = (intStart < 0) ? std_Math_max(len + intStart, 0) : std_Math_min(intStart, len);
|
|
|
|
// Step 8.
|
|
var to = (intEnd < 0) ? std_Math_max(len + intEnd, 0) : std_Math_min(intEnd, len);
|
|
|
|
// Step 9.
|
|
var span = std_Math_max(to - from, 0);
|
|
|
|
// Step 10.
|
|
// While |from| and |span| are bounded to the length of |str|
|
|
// and thus definitely in the int32 range, they can still be typed as
|
|
// double. Eagerly truncate since SubstringKernel only accepts int32.
|
|
return SubstringKernel(str, from | 0, span | 0);
|
|
}
|
|
|
|
function String_static_slice(string, start, end) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.slice');
|
|
return callFunction(String_slice, string, start, end);
|
|
}
|
|
|
|
/* ES6 Draft September 5, 2013 21.1.3.3 */
|
|
function String_codePointAt(pos) {
|
|
// Steps 1-3.
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
|
|
// Steps 4-5.
|
|
var position = ToInteger(pos);
|
|
|
|
// Step 6.
|
|
var size = S.length;
|
|
|
|
// Step 7.
|
|
if (position < 0 || position >= size)
|
|
return undefined;
|
|
|
|
// Steps 8-9.
|
|
var first = callFunction(std_String_charCodeAt, S, position);
|
|
if (first < 0xD800 || first > 0xDBFF || position + 1 === size)
|
|
return first;
|
|
|
|
// Steps 10-11.
|
|
var second = callFunction(std_String_charCodeAt, S, position + 1);
|
|
if (second < 0xDC00 || second > 0xDFFF)
|
|
return first;
|
|
|
|
// Step 12.
|
|
return (first - 0xD800) * 0x400 + (second - 0xDC00) + 0x10000;
|
|
}
|
|
|
|
var collatorCache = new Record();
|
|
|
|
/* ES6 20121122 draft 15.5.4.21. */
|
|
function String_repeat(count) {
|
|
// Steps 1-3.
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
|
|
// Steps 4-5.
|
|
var n = ToInteger(count);
|
|
|
|
// Steps 6-7.
|
|
if (n < 0)
|
|
ThrowRangeError(JSMSG_NEGATIVE_REPETITION_COUNT);
|
|
|
|
if (!(n * S.length < (1 << 28)))
|
|
ThrowRangeError(JSMSG_RESULTING_STRING_TOO_LARGE);
|
|
|
|
// 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;
|
|
}
|
|
|
|
// ES6 draft specification, section 21.1.3.27, version 2013-09-27.
|
|
function String_iterator() {
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
var iterator = NewStringIterator();
|
|
UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_TARGET, S);
|
|
UnsafeSetReservedSlot(iterator, ITERATOR_SLOT_NEXT_INDEX, 0);
|
|
return iterator;
|
|
}
|
|
|
|
function StringIteratorNext() {
|
|
var obj;
|
|
if (!IsObject(this) || (obj = GuardToStringIterator(this)) === null) {
|
|
return callFunction(CallStringIteratorMethodIfWrapped, this,
|
|
"StringIteratorNext");
|
|
}
|
|
|
|
var S = UnsafeGetStringFromReservedSlot(obj, ITERATOR_SLOT_TARGET);
|
|
// We know that JSString::MAX_LENGTH <= INT32_MAX (and assert this in
|
|
// SelfHostring.cpp) so our current index can never be anything other than
|
|
// an Int32Value.
|
|
var index = UnsafeGetInt32FromReservedSlot(obj, ITERATOR_SLOT_NEXT_INDEX);
|
|
var size = S.length;
|
|
var result = { value: undefined, done: false };
|
|
|
|
if (index >= size) {
|
|
result.done = true;
|
|
return result;
|
|
}
|
|
|
|
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(obj, ITERATOR_SLOT_NEXT_INDEX, index + charCount);
|
|
result.value = callFunction(String_substring, S, index, index + charCount);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
RequireObjectCoercible(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);
|
|
}
|
|
|
|
/* ES6 Draft May 22, 2014 21.1.2.4 */
|
|
function String_static_raw(callSite, ...substitutions) {
|
|
// Step 1 (implicit).
|
|
// Step 2.
|
|
var numberOfSubstitutions = substitutions.length;
|
|
|
|
// Steps 3-4.
|
|
var cooked = ToObject(callSite);
|
|
|
|
// Steps 5-7.
|
|
var raw = ToObject(cooked.raw);
|
|
|
|
// Steps 8-10.
|
|
var literalSegments = ToLength(raw.length);
|
|
|
|
// Step 11.
|
|
if (literalSegments <= 0)
|
|
return "";
|
|
|
|
// Step 12.
|
|
var resultString = "";
|
|
|
|
// Step 13.
|
|
var nextIndex = 0;
|
|
|
|
// Step 14.
|
|
while (true) {
|
|
// Steps a-d.
|
|
var nextSeg = ToString(raw[nextIndex]);
|
|
|
|
// Step e.
|
|
resultString = resultString + nextSeg;
|
|
|
|
// Step f.
|
|
if (nextIndex + 1 === literalSegments)
|
|
// Step f.i.
|
|
return resultString;
|
|
|
|
// Steps g-j.
|
|
var nextSub;
|
|
if (nextIndex < numberOfSubstitutions)
|
|
nextSub = ToString(substitutions[nextIndex]);
|
|
else
|
|
nextSub = "";
|
|
|
|
// Step k.
|
|
resultString = resultString + nextSub;
|
|
|
|
// Step l.
|
|
nextIndex++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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)
|
|
ThrowTypeError(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);
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.3
|
|
function String_big() {
|
|
RequireObjectCoercible(this);
|
|
return "<big>" + ToString(this) + "</big>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.4
|
|
function String_blink() {
|
|
RequireObjectCoercible(this);
|
|
return "<blink>" + ToString(this) + "</blink>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.5
|
|
function String_bold() {
|
|
RequireObjectCoercible(this);
|
|
return "<b>" + ToString(this) + "</b>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.6
|
|
function String_fixed() {
|
|
RequireObjectCoercible(this);
|
|
return "<tt>" + ToString(this) + "</tt>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.9
|
|
function String_italics() {
|
|
RequireObjectCoercible(this);
|
|
return "<i>" + ToString(this) + "</i>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.11
|
|
function String_small() {
|
|
RequireObjectCoercible(this);
|
|
return "<small>" + ToString(this) + "</small>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.12
|
|
function String_strike() {
|
|
RequireObjectCoercible(this);
|
|
return "<strike>" + ToString(this) + "</strike>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.13
|
|
function String_sub() {
|
|
RequireObjectCoercible(this);
|
|
return "<sub>" + ToString(this) + "</sub>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.14
|
|
function String_sup() {
|
|
RequireObjectCoercible(this);
|
|
return "<sup>" + ToString(this) + "</sup>";
|
|
}
|
|
|
|
function EscapeAttributeValue(v) {
|
|
var inputStr = ToString(v);
|
|
var inputLen = inputStr.length;
|
|
var outputStr = "";
|
|
var chunkStart = 0;
|
|
for (var i = 0; i < inputLen; i++) {
|
|
if (inputStr[i] === '"') {
|
|
outputStr += callFunction(String_substring, inputStr, chunkStart, i) + '"';
|
|
chunkStart = i + 1;
|
|
}
|
|
}
|
|
if (chunkStart === 0)
|
|
return inputStr;
|
|
if (chunkStart < inputLen)
|
|
outputStr += callFunction(String_substring, inputStr, chunkStart);
|
|
return outputStr;
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.2
|
|
function String_anchor(name) {
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
return '<a name="' + EscapeAttributeValue(name) + '">' + S + "</a>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.7
|
|
function String_fontcolor(color) {
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
return '<font color="' + EscapeAttributeValue(color) + '">' + S + "</font>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.8
|
|
function String_fontsize(size) {
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
return '<font size="' + EscapeAttributeValue(size) + '">' + S + "</font>";
|
|
}
|
|
|
|
// ES6 draft 2014-04-27 B.2.3.10
|
|
function String_link(url) {
|
|
RequireObjectCoercible(this);
|
|
var S = ToString(this);
|
|
return '<a href="' + EscapeAttributeValue(url) + '">' + S + "</a>";
|
|
}
|
|
|
|
function String_static_toLowerCase(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toLowerCase');
|
|
return callFunction(std_String_toLowerCase, string);
|
|
}
|
|
|
|
function String_static_toUpperCase(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toUpperCase');
|
|
return callFunction(std_String_toUpperCase, string);
|
|
}
|
|
|
|
function String_static_charAt(string, pos) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.charAt');
|
|
return callFunction(std_String_charAt, string, pos);
|
|
}
|
|
|
|
function String_static_charCodeAt(string, pos) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.charCodeAt');
|
|
return callFunction(std_String_charCodeAt, string, pos);
|
|
}
|
|
|
|
function String_static_includes(string, searchString) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.includes');
|
|
var position = arguments.length > 2 ? arguments[2] : undefined;
|
|
return callFunction(std_String_includes, string, searchString, position);
|
|
}
|
|
|
|
function String_static_indexOf(string, searchString) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.indexOf');
|
|
var position = arguments.length > 2 ? arguments[2] : undefined;
|
|
return callFunction(std_String_indexOf, string, searchString, position);
|
|
}
|
|
|
|
function String_static_lastIndexOf(string, searchString) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.lastIndexOf');
|
|
var position = arguments.length > 2 ? arguments[2] : undefined;
|
|
return callFunction(std_String_lastIndexOf, string, searchString, position);
|
|
}
|
|
|
|
function String_static_startsWith(string, searchString) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.startsWith');
|
|
var position = arguments.length > 2 ? arguments[2] : undefined;
|
|
return callFunction(std_String_startsWith, string, searchString, position);
|
|
}
|
|
|
|
function String_static_endsWith(string, searchString) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.endsWith');
|
|
var endPosition = arguments.length > 2 ? arguments[2] : undefined;
|
|
return callFunction(std_String_endsWith, string, searchString, endPosition);
|
|
}
|
|
|
|
function String_static_trim(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trim');
|
|
return callFunction(std_String_trim, string);
|
|
}
|
|
|
|
function String_static_trimStart(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimStart');
|
|
return callFunction(std_String_trimStart, string);
|
|
}
|
|
|
|
function String_static_trimEnd(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.trimEnd');
|
|
return callFunction(std_String_trimEnd, string);
|
|
}
|
|
|
|
function String_static_toLocaleLowerCase(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toLocaleLowerCase');
|
|
return callFunction(std_String_toLocaleLowerCase, string);
|
|
}
|
|
|
|
function String_static_toLocaleUpperCase(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.toLocaleUpperCase');
|
|
return callFunction(std_String_toLocaleUpperCase, string);
|
|
}
|
|
|
|
function String_static_normalize(string) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.normalize');
|
|
var form = arguments.length > 1 ? arguments[1] : undefined;
|
|
return callFunction(std_String_normalize, string, form);
|
|
}
|
|
|
|
function String_static_concat(string, arg1) {
|
|
if (arguments.length < 1)
|
|
ThrowTypeError(JSMSG_MISSING_FUN_ARG, 0, 'String.concat');
|
|
var args = callFunction(std_Array_slice, arguments, 1);
|
|
return callFunction(std_Function_apply, std_String_concat, string, args);
|
|
}
|