neft
Version:
Universal Platform
128 lines (110 loc) • 3.63 kB
text/coffeescript
'use strict'
exports.BINDING_THIS_TO_TARGET_OPTS = BINDING_THIS_TO_TARGET_OPTS = 1
repeatString = (str, amount) ->
r = str
for i in [0...amount - 1] by 1
r += str
r
isArrayElementIndexer = (string, index) ->
if string[index] isnt '['
return false
while index++ < string.length
char = string[index]
if char is ']'
return true
unless /[0-9]/.test(char)
return false
false
exports.isBinding = (code) ->
try
func = new Function 'console', "'use strict'; return #{code};"
func.call null
return false
true
exports.parse = (val, isPublicId, opts = 0, objOpts = {}, isVariableId) ->
isVariableId ?= -> false
binding = ['']
val += ' '
lastBinding = null
isString = false
isArrayIndexer = false
for char, i in val
if isArrayIndexer and char is ']'
isArrayIndexer = false
continue
isCurrentArrayIndexer = not isString and isArrayElementIndexer(val, i)
if (char is '.' or isCurrentArrayIndexer) and lastBinding
isArrayIndexer = isCurrentArrayIndexer
lastBinding.push ''
continue
if lastBinding and (isString or ///[a-zA-Z_0-9$]///.test(char))
lastBinding[lastBinding.length - 1] += char
else if ///[a-zA-Z_$]///.test(char)
lastBinding = [char]
binding.push lastBinding
else
if lastBinding is null
binding[binding.length - 1] += char
else
lastBinding = null
binding.push char
if char in ['\'', '"'] and val[i - 1] isnt '\\'
isString = not isString
for elem, i in binding when typeof elem isnt 'string'
elem = objOpts.modifyBindingPart?(elem) or elem
[] = elem
if id is 'parent' or id is 'nextSibling' or id is 'previousSibling' or id is 'target' or objOpts.globalIdToThis?[id]
elem.unshift "this"
else if opts & BINDING_THIS_TO_TARGET_OPTS and id is 'this'
elem.splice 1, 0, 'target'
else if isPublicId(id) and (i is 0 or binding[i-1][binding[i-1].length - 1] isnt '.')
continue
else
binding[i] = elem.join '.'
i = -1
n = binding.length
while ++i < n
if typeof binding[i] is 'string'
if typeof binding[i - 1] is 'string'
binding[i - 1] += binding[i]
else if binding[i].trim() isnt ''
continue
binding.splice i, 1
n--
text = ''
hash = ''
for elem, i in binding
if typeof elem is 'string'
hash += elem
else if elem.length > 1
if binding[i - 1]? and text
text += ", "
text += repeatString('[', elem.length - 1)
if isVariableId(elem[0])
text += "#{elem[0]}"
else
text += "'#{elem[0]}'"
if elem[0] is "this"
hash += "this"
else
hash += "#{elem[0]}"
elem.shift()
for id, i in elem
text += ", '#{id}']"
if isFinite(id)
hash += "[#{id}]"
else
hash += ".#{id}"
else
if elem[0] is "this"
hash += "this"
else
hash += "#{elem[0]}"
hash = hash.trim()
text = text.trim()
hash: hash
connections: text