Created
March 11, 2012 07:37
-
-
Save cognitom/2015450 to your computer and use it in GitHub Desktop.
Cross-browser split function for CoffeeScript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Cross-Browser Split 1.0.1 for CoffeeScript | |
# (c) Tsutomu Kawamura @OSSCafe; just converting to CoffeeScript | |
# (c) Steven Levithan <stevenlevithan.com>; MIT License | |
# An ECMA-compliant, uniform cross-browser split method */ | |
if !cbSplit | |
cbSplit = (str, separator, limit) -> | |
# if `separator` is not a regex, use the native `split` | |
return cbSplit._nativeSplit.call str, separator, limit if Object::toString.call(separator) isnt "[object RegExp]" | |
output = [] | |
lastLastIndex = 0 | |
flags = (if separator.ignoreCase then "i" else "") + (if separator.multiline then "m" else "") + (if separator.sticky then "y" else "") | |
separator = RegExp separator.source, flags + "g" # make `global` and avoid `lastIndex` issues by working with a copy | |
str = str + "" # type conversion | |
separator2 = RegExp "^" + separator.source + "$(?!\\s)", flags if !cbSplit._compliantExecNpcg # doesn't need /g or /y, but they don't hurt | |
# behavior for `limit`: if it's... | |
# - `undefined`: no limit. | |
# - `NaN` or zero: return an empty array. | |
# - a positive number: use `Math.floor(limit)`. | |
# - a negative number: no limit. | |
# - other: type-convert, then use the above rules. | |
if !limit? || +limit < 0 | |
limit = Infinity | |
else | |
limit = Math.floor(+limit) | |
return [] if !limit | |
while match = separator.exec str | |
lastIndex = match.index + match[0].length # `separator.lastIndex` is not reliable cross-browser | |
if lastIndex > lastLastIndex | |
output.push str.slice(lastLastIndex, match.index) | |
# fix browsers whose `exec` methods don't consistently return `undefined` for nonparticipating capturing groups | |
if !cbSplit._compliantExecNpcg && match.length > 1 | |
match[0].replace separator2, () -> | |
match[i] = undefined for i in [1..(arguments.length-2)] when !arguments[i]? | |
Array::push.apply output, match.slice(1) if match.length > 1 && match.index < str.length | |
lastLength = match[0].length | |
lastLastIndex = lastIndex | |
break if output.length >= limit | |
separator.lastIndex++ if separator.lastIndex == match.index # avoid an infinite loop | |
if lastLastIndex == str.length | |
output.push "" if lastLength || !separator.test "" | |
else | |
output.push str.slice(lastLastIndex) | |
if output.length > limit then output.slice 0, limit else output | |
cbSplit._compliantExecNpcg = /()??/.exec("")[1]? # NPCG: nonparticipating capturing group | |
cbSplit._nativeSplit = String::split | |
# for convenience... | |
String::split = (separator, limit) -> cbSplit @, separator, limit |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment