@danielkalen/simplybind
Version:
Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.
155 lines (99 loc) • 4.15 kB
text/coffeescript
BindingInterfacePrivate =
selfClone: ()-> new BindingInterface(null, @)
defineMainProps: (binding)->
= binding
Object.defineProperties @,
'value': get: ()-> binding.value
'original': get: ()-> binding.objects or binding.object
'subscribers': get: ()-> binding.subs.slice().map (sub)-> sub.object
createBinding: (subject, newObjectType, bindingInterface, isFunction)->
= subject
cachedBinding = cache.get(subject, isFunction, , )
if cachedBinding # Exit early by returning the subject from cache if is already in there
return
else
newBinding = new Binding(subject, newObjectType, bindingInterface)
cache.set(newBinding, isFunction)
return newBinding
patchCachedBinding: (cachedBinding)->
if cachedBinding.type is 'ObjectProp' and not of # This property was manually deleted and needs its prop to be re-defined as a live one
convertToLive(cachedBinding, )
if
cachedBinding.optionsDefault[option] = value for option,value of
for key,value of cachedBinding.optionsDefault
[key] = if checkIf.isDefined([key]) then [key] else value
return cachedBinding
setProperty: (subject)->
subject = subject.toString() if checkIf.isNumber(subject)
= = subject
unless .simpleSelector
if targetIncludes(subject, ':')
split = subject.split(':')
= split.slice(0, -1).join(':')
= split[split.length-1]
if targetIncludes(subject, '.') # Placeholder extraction
split = .split('.') # We use '@property' instead of 'subject' because it may have been modified by the previous ':' descriptor check
= split[0]
= split.slice(1).join('.')
if targetIncludes(, 'event')
if targetIncludes(subject, '#')
split = .split('#')
= split[0]
= split[1]
else
=
= 0
throwWarning('badEventArg',1) if isNaN parseInt()
return @
setObject: (subject, isFunction)->
= 1
# simplyimport:if BUNDLE_TARGET = 'browser'
import './prototype-private.setObject-parseDOMObject'
# simplyimport:end
switch
when isFunction
newObjectType = 'Func'
when
newObjectType = 'Pholder'
when targetIncludes(, 'array') and checkIf.isArray(subject[])
newObjectType = 'Array'
when targetIncludes(, 'event')
newObjectType = 'Event'
import './prototype-private.setObject-defineEventMethods'
when targetIncludes(, 'func')
newObjectType = 'Proxy'
# simplyimport:if BUNDLE_TARGET = 'browser'
when isDomRadio
newObjectType = 'DOMRadio'
when isDomCheckbox
newObjectType = 'DOMCheckbox'
when targetIncludes(, 'attr')
newObjectType = 'DOMAttr'
# simplyimport:end
else
newObjectType = 'ObjectProp'
if targetIncludes(, 'multi')
throwError('emptyList') if not subject.length
new GroupBinding(@, subject, newObjectType)
else
if targetIncludes(.type, 'Event') or targetIncludes(.type, 'Proxy')
.updateOnBind = false
else if targetIncludes(.type, 'Func')
.updateOnBind = true
if
return
else
return @
addToPublisher: (publisherInterface)->
publisherInterface.stage = 2
publisherInterface.subs.push(@)
alreadyHadSub = publisherInterface._.addSub(, publisherInterface.options, publisherInterface.updateOnce)
if publisherInterface.updateOnce
delete publisherInterface.updateOnce
else if publisherInterface.options.updateOnBind and not alreadyHadSub
if .isMulti
publisherInterface._.updateSub(binding, publisherInterface._) for binding in .bindings
else
publisherInterface._.updateSub(, publisherInterface._)
return