master
Raw Download raw file
 1/***
 2 * @method split([separator], [limit])
 3 * @author andrewplummer
 4 * @returns Array
 5 * @dependencies None
 6 * @short Split a string into an array. This method is native to Javascript, but this plugin patches it to provide cross-browser reliability when splitting on a regex.
 7 * @example
 8 *
 9 *   'comma,separated,values'.split(',') -> ['comma','separated','values']
10 *   'a,b|c>d'.split(/[,|>]/)            -> ['multi','separated','values']
11 *
12 ***/
13
14// Many thanks to Steve Levithan here for a ton of inspiration and work dealing with
15// cross browser Regex splitting.  http://blog.stevenlevithan.com/archives/cross-browser-split
16
17String.extend({
18
19  'split': function(separator, limit) {
20    var output = [];
21    var lastLastIndex = 0;
22    var flags;
23    var getRegExpFlags = function(reg, add) {
24      var flags = reg.toString().match(/[^/]*$/)[0];
25      if(add) {
26        flags = (flags + add).split('').sort().join('').replace(/([gimy])\1+/g, '$1');
27      }
28      return flags;
29    }
30    var flags = getRegExpFlags(separator, 'g');
31    // make `global` and avoid `lastIndex` issues by working with a copy
32    var separator = new RegExp(separator.source, flags);
33    var separator2, match, lastIndex, lastLength;
34    if(!RegExp.NPCGSupport) {
35      // doesn't need /g or /y, but they don't hurt
36      separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
37    }
38    if(limit === undefined || limit < 0) {
39      limit = Infinity;
40    } else {
41      limit = Math.floor(limit);
42      if(!limit) return [];
43    }
44
45    while (match = separator.exec(this)) {
46      lastIndex = match.index + match[0].length; // `separator.lastIndex` is not reliable cross-browser
47      if(lastIndex > lastLastIndex) {
48        output.push(this.slice(lastLastIndex, match.index));
49        // fix browsers whose `exec` methods don't consistently return `undefined` for nonparticipating capturing groups
50        if(!RegExp.NPCGSupport && match.length > 1) {
51          match[0].replace(separator2, function () {
52            for (var i = 1; i < arguments.length - 2; i++) {
53              if(arguments[i] === undefined) {
54                match[i] = undefined;
55              }
56            }
57          });
58        }
59        if(match.length > 1 && match.index < this.length) {
60          array.prototype.push.apply(output, match.slice(1));
61        }
62        lastLength = match[0].length;
63        lastLastIndex = lastIndex;
64        if(output.length >= limit) {
65          break;
66        }
67      }
68      if(separator.lastIndex === match.index) {
69        separator.lastIndex++; // avoid an infinite loop
70      }
71    }
72    if(lastLastIndex === this.length) {
73      if(lastLength || !separator.test('')) output.push('');
74    } else {
75      output.push(this.slice(lastLastIndex));
76    }
77    return output.length > limit ? output.slice(0, limit) : output;
78  }
79
80}, function(s) {
81  return Object.prototype.toString.call(s) === '[object RegExp]';
82});
83
84