UNPKG

@danielkalen/simplybind

Version:

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

444 lines (166 loc) 6.84 kB
BindingInterfacePublic = of: (object)-> if @stage isnt 0 and @stage isnt 2 throwErrorUnavail methodNames[0] unless checkIf.isObject(object) or checkIf.isFunction(object) throwErrorBadArg methodNames[0], object if checkIf.isBindingInterface(object) object = object.object if @stage is 2 # Indicates this binding is currently acting as a proxy for the another (proxied) binding @proxies[@proxies.length-1] = proxied = @lastProxied.of(object) @state.hasInitialBinding = true @state.hasTransform = false @_.addDep(proxied._) maybeUpdateDep(@_, proxied._) return @new(@stage+1, object) ofEvent: (eventName, customInMethod, customOutMethod)-> if @stage isnt 0 or @state.hasEventName throwErrorUnavail methodNames[1] else if not eventName or not checkIf.isString(eventName) throwErrorBadArg methodNames[1], eventName else if isNaN parseInt(@property) throwWarning('badEventArg',1) @state.hasEventName = true @eventName = eventName @selector = @property+'#'+@eventName @customEventMethod = 'in': customInMethod 'out': customOutMethod return @ to: (subject, specificOptions)-> if @stage isnt 1 or @state.hasInitialBinding throwErrorUnavail methodNames[2] @proxies.push proxied = computeProxied(@, subject, specificOptions) if proxied.stage is 0 newStage = 2 else newStage = 3 @state.hasInitialBinding = true return @new(newStage) and: (subject, specificOptions)-> if @stage isnt 3 or not @state.hasInitialBinding or @state.hasMultiTransform throwErrorUnavail methodNames[3] @proxies.push proxied = computeProxied(@, subject, specificOptions) if proxied.stage is 0 newStage = 2 else newStage = 3 @state.hasTransform = false return @new(newStage) toEvent: (eventName, customOutMethod, customInMethod, specificOptions)-> # Bad argument error handling will occur in .ofEvent if @stage isnt 1 throwErrorUnavail methodNames[4] @proxies.push SimplyBind(0, specificOptions).ofEvent(eventName, customInMethod, customOutMethod) return @new(2) chainTo: (subject, specificOptions)-> if @stage isnt 3 throwErrorUnavail methodNames[5] return SimplyBind(@lastProxied).to(subject, specificOptions) set: (newValue)-> if @stage is 0 or @stage is 2 throwErrorUnavail methodNames[6] @_.setValue(newValue, @placeholder) return @ get: ()-> if @stage is 0 or @stage is 2 throwErrorUnavail methodNames[7] return if @placeholder then @_.pholderValues[@placeholder] else @_.value transformSelf: (transformFn)-> # Applied only to the last proxy if @stage isnt 1 or @stage is 1 and @_.type is 'Array' throwErrorUnavail methodNames[8] if not checkIf.isFunction(transformFn) throwWarning('fnOnly',1) else @_.selfTransform = transformFn if @_.options.updateOnBind currentValue = if @_.isMulti then @value[0] else @value @_.setValue(currentValue) return @ transform: (transformFn)-> # Applied only to the last proxy if @stage isnt 3 or @state.hasTransform or @state.hasMultiTransform throwErrorUnavail methodNames[9] @state.hasTransform = @_.processTransform(transformFn, @proxies.slice(-1)) or false return @new(3) transformAll: (transformFn)-> # Applied to entrie proxies set if @stage isnt 3 or @state.hasTransform or @state.hasMultiTransform throwErrorUnavail methodNames[10] @state.hasMultiTransform = @_.processTransform(transformFn, @proxies) or false return @new(3) condition: (conditionFn)-> # Applied only to the last proxy if @stage isnt 3 throwErrorUnavail methodNames[11] @_.processCondition(conditionFn, @proxies.slice(-1)) return @new(3) conditionAll: (conditionFn)-> # Applied to entrie proxies set if @stage isnt 3 throwErrorUnavail methodNames[12] @_.processCondition(conditionFn, @proxies) return @new(3) bothWays: (dontOrAltTransform)-> # Applied only to the last proxy if @stage isnt 3 or @state.hasMultiTransform throwErrorUnavail methodNames[13] proxied = @lastProxied proxiedBinding = proxied._.addDep(@_, true) originTransform = @_.transforms[proxied.ID] originCondition = @_.conditions[proxied.ID] if originTransform or dontOrAltTransform transformToUse = if checkIf.isFunction(dontOrAltTransform) then dontOrAltTransform else originTransform proxiedBinding.addTransform(@ID, transformToUse) if transformToUse and dontOrAltTransform isnt false if originCondition proxiedBinding.addCondition(@ID, originCondition) @_.addDep(proxied._, true) return @ unBind: (bothWays)-> # Applied to all proxies if @stage isnt 3 throwErrorUnavail methodNames[14] @_.removeDep(proxied._, bothWays) for proxied in @proxies return @ pollEvery: (time)-> if @stage isnt 3 or @_.type is 'Event' throwErrorUnavail methodNames[15] @_.addPollInterval(time) return @ stopPolling: ()-> if @stage isnt 3 throwErrorUnavail methodNames[16] @_.removePollInterval() return @ updateDepsOnEvent: (eventName, customMethod)-> if @stage isnt 3 throwErrorUnavail methodNames[17] @_.registerEvent(eventName, customMethod) return @ removeEvent: (eventName, customMethod)-> if @stage isnt 3 throwErrorUnavail methodNames[18] @_.unRegisterEvent(eventName, customMethod) return @ throttle: (delay)-> if @stage isnt 1 and @stage isnt 3 throwErrorUnavail methodNames[19] if delay and checkIf.isNumber(delay) @_.throttleRate = delay else if delay is false delete @_.throttleRate return @ setOption: (optionName, newValue)-> newOptions = "#{optionName}":newValue setOptionsForBinding(@_, newOptions) setOptionsForBinding(proxied._, newOptions) for proxied in @proxies return @ # Aliases BindingInterfacePublic.update = BindingInterfacePublic.set BindingInterfacePublic.twoWay = BindingInterfacePublic.bothWays BindingInterfacePublic.pipe = BindingInterfacePublic.chainTo methodNames = Object.keys(BindingInterfacePublic) BindingInterface::[methodName] = BindingInterfacePublic[methodName] for methodName in methodNames # ==== Helpers ================================================================================= computeProxied = (instance, subject, specificOptions={})-> proxied = SimplyBind(subject, specificOptions, true) if proxied.stage isnt 0 instance._.addDep(proxied._, instance) maybeUpdateDep instance._, proxied._ return proxied maybeUpdateDep = (instance, proxied)-> # Both arguments refer to the private Binding instances if instance.options.updateOnBind or instance.type is 'Func' instance.updateDep(proxied, instance)