UNPKG

@danielkalen/simplybind

Version:

Magically simple, framework-less one-way/two-way data binding for frontend/backend in ~5kb.

103 lines (75 loc) 3.16 kB
fetchDescriptor = (object, property, isProto)-> descriptor = getDescriptor(object, property) if descriptor descriptor.configurable = true if isProto return descriptor else if objectProto=Object.getPrototypeOf(object) return fetchDescriptor(objectProto, property, true) convertToLive = (bindingInstance, object, onlyArrayMethods)-> _ = bindingInstance _.origDescriptor = fetchDescriptor(object, _.property) if not _.origDescriptor if onlyArrayMethods arrayMutatorMethods.forEach (method)-> # Using forEach because we need a closure here defineProperty object, method, configurable: true value: ()-> result = Array::[method].apply object, arguments _.updateAllSubs(_) return result else if _.type is 'Proxy' origFn = _.origFn = _.value context = object _.value = result:null, args:null if checkIf.isFunction(origFn) slice = [].slice getterValue = proxyFn = ()-> args = slice.call(arguments) _.value.args = args = if _.selfTransform then _.selfTransform(args) else args _.value.result = result = origFn.apply(context, args) _.updateAllSubs(_) return result defineProperty object, _.property, configurable: _.isLiveProp = true get: ()-> getterValue set: (newValue)-> if not checkIf.isFunction(newValue) getterValue = newValue else if newValue isnt origFn origFn = _.origFn = newValue if newValue isnt proxyFn getterValue = proxyFn if getterValue isnt proxyFn return # simplyimport:if BUNDLE_TARGET = 'browser' else if not targetIncludes(_.type, 'DOM') and not (_.object is window and targetIncludes(windowPropsToIgnore, _.property)) # simplyimport:end # simplyimport:if BUNDLE_TARGET = 'node' else # simplyimport:end # 'ObjectProp' or 'Array' type bindings propertyDescriptor = _.origDescriptor or dummyPropertyDescriptor _.origGetter = propertyDescriptor.get.bind(object) if propertyDescriptor.get _.origSetter = propertyDescriptor.set.bind(object) if propertyDescriptor.set shouldWriteLiveProp = propertyDescriptor.configurable # simplyimport:if BUNDLE_TARGET = 'browser' shouldWriteLiveProp = shouldWriteLiveProp and object.constructor isnt CSSStyleDeclaration import './webkitDomDescriptorFix' # simplyimport:end if shouldWriteLiveProp typeIsArray = _.type is 'Array' shouldIndicateUpdateIsFromSelf = not _.origSetter and not typeIsArray defineProperty object, _.property, configurable: _.isLiveProp = true enumerable: propertyDescriptor.enumerable get: _.origGetter or ()-> _.value set: (newValue)-> _.setValue(newValue, _, shouldIndicateUpdateIsFromSelf); return if typeIsArray convertToLive(_, object[_.property], true) return convertToReg = (bindingInstance, object, onlyArrayMethods)-> if onlyArrayMethods delete object[method] for method in arrayMutatorMethods else _ = bindingInstance newDescriptor = _.origDescriptor newDescriptor.value = (_.origFn or _.value) unless newDescriptor.set or newDescriptor.get defineProperty object, _.property, newDescriptor