Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Cross-browser split function for CoffeeScript
# 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
You can’t perform that action at this time.