#300 enhancement
fearphage

Fix String#replace to support functions in Safari 2

Reported by fearphage | August 22nd, 2008 @ 11:13 AM

Birthed from #297

Safari 2.x does not support functions as the 2nd param of String#replace. The following code attempts to remedy this:


if ('a'.replace(/a/, function() {return 'b'}) != 'b')
(function(replace){
  String.prototype.replace = function(pattern, replacement) {
    // replacement is not function, use built-in
    if (typeof replacement != 'function')
      return replace.apply(this, arguments);

    var str = '' + this;
    // pattern string is not RegExp
    if (!(pattern instanceof RegExp)) {
      var idx = str.indexOf(pattern);
      return (idx == -1 ?
        str :
        replace.apply(str, [pattern, replacement(pattern, idx, str)]);
      );
    }

    var reg = pattern, result = [], lastidx = reg.lastIndex, re;
    while ((re = reg.exec(str)) != null) {
      var idx  = re.index, args = re.concat(idx, str);
      result.push(str.slice(lastidx, idx), replacement.apply(null, args).toString());
      if (!reg.global) {
        lastidx += RegExp.lastMatch.length;
        break;
      }
      else {
        lastidx = reg.lastIndex;
      }
    }
    result.push(str.slice(lastidx));
    return result.join('');
  }
})(String.prototype.replace);

The exchange is performance (failing quickly with the built-in method) for functionality (working as spec'd).

Comments and changes to this ticket

Please Login or create a free account to add a new comment.

You can update this ticket by sending an email to from your email client. (help)

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

The Prototype JavaScript library.

Shared Ticket Bins

People watching this ticket