-
Notifications
You must be signed in to change notification settings - Fork 2
/
split-fix.js
77 lines (68 loc) · 2.65 KB
/
split-fix.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//----------------------------------------------------------------------------------------------
/*
Cross-Browser Split 0.3
By Steven Levithan <http://stevenlevithan.com>
MIT license
Provides a consistent cross-browser, ECMA-262 v3 compliant split method
*/
String.prototype._$$split = String.prototype._$$split || String.prototype.split;
String.prototype.split = function (s /* separator */, limit) {
// if separator is not a regex, use the native split method
if (!(s instanceof RegExp))
return String.prototype._$$split.apply(this, arguments);
var flags = (s.global ? "g" : "") + (s.ignoreCase ? "i" : "") + (s.multiline ? "m" : ""),
s2 = new RegExp("^" + s.source + "$", flags),
output = [],
origLastIndex = s.lastIndex,
lastLastIndex = 0,
i = 0, match, lastLength;
/* behavior for limit: if it's...
- undefined: no limit
- NaN or zero: return an empty array
- a positive number: use limit after dropping any decimal
- a negative number: no limit
- other: type-convert, then use the above rules
*/
if (limit === undefined || +limit < 0) {
limit = false;
} else {
limit = Math.floor(+limit);
if (!limit)
return [];
}
if (s.global)
s.lastIndex = 0;
else
s = new RegExp(s.source, "g" + flags);
while ((!limit || i++ <= limit) && (match = s.exec(this))) {
var emptyMatch = !match[0].length;
// Fix IE's infinite-loop-resistant but incorrect lastIndex
if (emptyMatch && s.lastIndex > match.index)
s.lastIndex--;
if (s.lastIndex > lastLastIndex) {
// Fix browsers whose exec methods don't consistently return undefined for non-participating capturing groups
if (match.length > 1) {
match[0].replace(s2, function () {
for (var j = 1; j < arguments.length - 2; j++) {
if (arguments[j] === undefined)
match[j] = undefined;
}
});
}
output = output.concat(this.slice(lastLastIndex, match.index));
if (1 < match.length && match.index < this.length)
output = output.concat(match.slice(1));
lastLength = match[0].length; // only needed if s.lastIndex === this.length
lastLastIndex = s.lastIndex;
}
if (emptyMatch)
s.lastIndex++; // avoid an infinite loop
}
// since this uses test(), output must be generated before restoring lastIndex
output = lastLastIndex === this.length ?
(s.test("") && !lastLength ? output : output.concat("")) :
(limit ? output : output.concat(this.slice(lastLastIndex)));
s.lastIndex = origLastIndex; // only needed if s.global, else we're working with a copy of the regex
return output;
};
//----------------------------------------------------------------------------------------------