src/third_party/mozjs/extract/js/src/builtin/String.js
// String.prototype.replaceAll ( searchValue, replaceValue )
String.prototype.replaceAll ( searchValue, replaceValue )
String . prototype . replaceAll ( searchValue replaceValue )
function String_replaceAll(searchValue, replaceValue) {
    if (this === undefined || this === null)
        ThrowIncompatibleMethod("replaceAll", this);
    if (searchValue !== undefined && searchValue !== null) {
        if (IsRegExp(searchValue)) {
            b.i.
            var flags = searchValue.flags;
            b.ii.
            if (flags === undefined || flags === null) {
                ThrowTypeError(JSMSG_FLAGS_UNDEFINED_OR_NULL);
            }
            b.iii.
            if (!callFunction(std_String_includes, ToString(flags), "g")) {
                ThrowTypeError(JSMSG_REQUIRES_GLOBAL_REGEXP, "replaceAll");
            }
        }
        c.
        var replacer = GetMethod(searchValue, GetBuiltinSymbol("replace"));
        b.
        if (replacer !== undefined) {
            return callContentFunction(replacer, searchValue, this, replaceValue);
        }
    }
    var string = ToString(this);
    var searchString = ToString(searchValue);
    if (!IsCallable(replaceValue)) {
        return StringReplaceAllString(string, searchString, ToString(replaceValue));
    }
    var searchLength = searchString.length;
    var advanceBy = std_Math_max(1, searchLength);
    var endOfLastMatch = 0;
    var result = "";
    var position = 0;
    while (true) {
         StringIndexOf doesn't clamp the |position| argument to the input
         string length, i.e. |StringIndexOf("abc", "", 4)| returns -1,
         whereas |"abc".indexOf("", 4)| returns 3. That means we need to
         exit the loop when |nextPosition| is smaller than |position| and
         not just when |nextPosition| is -1.
        var nextPosition = callFunction(std_String_indexOf, string, searchString, position);
        if (nextPosition < position) {
            break;
        }
        position = nextPosition;
         Step 14.a.
        var replacement = ToString(callContentFunction(replaceValue, undefined, searchString,
                                                       position, string));
         Step 14.b (not applicable).
         Step 14.c.
        var stringSlice = Substring(string, endOfLastMatch, position - endOfLastMatch);
         Step 14.d.
        result += stringSlice + replacement;
         Step 14.e.
        endOfLastMatch = position + searchLength;
         Step 11.b.
        position += advanceBy;
    }
     Step 15.
    if (endOfLastMatch < string.length) {
         Step 15.a.
        result += Substring(string, endOfLastMatch, string.length - endOfLastMatch);
    }
     Step 16.
    return result;
}
function String_replaceAll ( searchValue , replaceValue ) { if ( this === undefined || this === null ) ThrowIncompatibleMethod ( "replaceAll" , this ) ; if ( searchValue !== undefined && searchValue !== null ) { if ( IsRegExp ( searchValue ) ) { var flags = searchValue . flags ; if ( flags === undefined || flags === null ) { ThrowTypeError ( JSMSG_FLAGS_UNDEFINED_OR_NULL ) ; } if ( ! callFunction ( std_String_includes , ToString ( flags ) , "g" ) ) { ThrowTypeError ( JSMSG_REQUIRES_GLOBAL_REGEXP , "replaceAll" ) ; } } var replacer = GetMethod ( searchValue , GetBuiltinSymbol ( "replace" ) ) ; if ( replacer !== undefined ) { return callContentFunction ( replacer , searchValue , this , replaceValue ) ; } } var string = ToString ( this ) ; var searchString = ToString ( searchValue ) ; if ( ! IsCallable ( replaceValue ) ) { return StringReplaceAllString ( string , searchString , ToString ( replaceValue ) ) ; } var searchLength = searchString . length ; var advanceBy = std_Math_max ( 1 , searchLength ) ; var endOfLastMatch = 0 ; var result = "" ; var position = 0 ; while ( true ) { var nextPosition = callFunction ( std_String_indexOf , string , searchString , position ) ; if ( nextPosition < position ) { break ; } position = nextPosition ; var replacement = ToString ( callContentFunction ( replaceValue , undefined , searchString , position , string ) ) ; var stringSlice = Substring ( string , endOfLastMatch , position - endOfLastMatch ) ; result += stringSlice + replacement ; endOfLastMatch = position + searchLength ; position += advanceBy ; } if ( endOfLastMatch < string . length ) { result += Substring ( string , endOfLastMatch , string . length - endOfLastMatch ) ; } return result ; }
String.prototype.replaceAll ( searchValue, replaceValue )
String . prototype . replaceAll ( searchValue replaceValue )
// Step 1. // Step 2. // Steps 2.a-b. // Step 2.b.i. // Step 2.b.ii. // Step 2.b.iii. // Step 2.c. // Step 2.b. // Step 3. // Step 4. // Steps 5-6. // Steps 7-16. // Step 7. // Step 8. // Step 9 (not needed in this implementation). // Step 12. // Step 13. // Steps 10-11, 14. // Steps 10-11. // // StringIndexOf doesn't clamp the |position| argument to the input // string length, i.e. |StringIndexOf("abc", "", 4)| returns -1, // whereas |"abc".indexOf("", 4)| returns 3. That means we need to // exit the loop when |nextPosition| is smaller than |position| and // not just when |nextPosition| is -1. // Step 14.a. // Step 14.b (not applicable). // Step 14.c. // Step 14.d. // Step 14.e. // Step 11.b. // Step 15. // Step 15.a. // Step 16.