UNPKG

@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
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)-> @object = subject cachedBinding = cache.get(subject, isFunction, @selector, @isMultiChoice) if cachedBinding # Exit early by returning the subject from cache if is already in there return @patchCachedBinding(cachedBinding) else newBinding = new Binding(subject, newObjectType, bindingInterface) cache.set(newBinding, isFunction) return newBinding patchCachedBinding: (cachedBinding)-> if cachedBinding.type is 'ObjectProp' and @property not of @object # This property was manually deleted and needs its prop to be re-defined as a live one convertToLive(cachedBinding, @object) if @saveOptions cachedBinding.optionsDefault[option] = value for option,value of @optionsPassed for key,value of cachedBinding.optionsDefault @options[key] = if checkIf.isDefined(@optionsPassed[key]) then @optionsPassed[key] else value return cachedBinding setProperty: (subject)-> subject = subject.toString() if checkIf.isNumber(subject) @selector = @property = subject unless @options.simpleSelector if targetIncludes(subject, ':') split = subject.split(':') @descriptor = split.slice(0, -1).join(':') @property = split[split.length-1] if targetIncludes(subject, '.') # Placeholder extraction split = @property.split('.') # We use '@property' instead of 'subject' because it may have been modified by the previous ':' descriptor check @property = split[0] @pholder = split.slice(1).join('.') if targetIncludes(@descriptor, 'event') if targetIncludes(subject, '#') split = @property.split('#') @eventName = split[0] @property = split[1] else @eventName = @property @property = 0 throwWarning('badEventArg',1) if isNaN parseInt(@property) return @ setObject: (subject, isFunction)-> @stage = 1 # simplyimport:if BUNDLE_TARGET = 'browser' import './prototype-private.setObject-parseDOMObject' # simplyimport:end switch when isFunction newObjectType = 'Func' when @pholder newObjectType = 'Pholder' when targetIncludes(@descriptor, 'array') and checkIf.isArray(subject[@property]) newObjectType = 'Array' when targetIncludes(@descriptor, 'event') newObjectType = 'Event' import './prototype-private.setObject-defineEventMethods' when targetIncludes(@descriptor, 'func') newObjectType = 'Proxy' # simplyimport:if BUNDLE_TARGET = 'browser' when isDomRadio newObjectType = 'DOMRadio' when isDomCheckbox newObjectType = 'DOMCheckbox' when targetIncludes(@descriptor, 'attr') newObjectType = 'DOMAttr' # simplyimport:end else newObjectType = 'ObjectProp' if targetIncludes(@descriptor, 'multi') throwError('emptyList') if not subject.length @defineMainProps new GroupBinding(@, subject, newObjectType) else @defineMainProps @createBinding(subject, newObjectType, @, isFunction) if targetIncludes(@_.type, 'Event') or targetIncludes(@_.type, 'Proxy') @options.updateOnBind = false else if targetIncludes(@_.type, 'Func') @options.updateOnBind = true if @completeCallback return @completeCallback(@) 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