UNPKG

@danielkalen/simplybind

Version:

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

162 lines (85 loc) 3.81 kB
import [browserOnly] helpers-changeEvent.coffee noop = ()-> genID = ()-> ''+(++currentID) genObj = ()-> Object.create(null) genProxiedInterface = (publisher, isSibling)-> (subject, specificOptions, saveOptions)-> SimplyBind(subject, specificOptions, saveOptions, publisher, isSibling) genProxiedEventInterface = (publisher, isSibling)-> (eventName, customOutMethod, customInMethod)-> SimplyBind(0, null, false, publisher, isSibling).ofEvent(eventName, customInMethod, customOutMethod) # ==== Checks ================================================================================= targetIncludes = (target, item)-> target.indexOf(item) isnt -1 checkIf = isDefined: (subject)-> subject isnt undefined isArray: (subject)-> subject instanceof Array isObject: (subject)-> typeof subject is 'object' and subject # 2nd check is to test against 'null' values isString: (subject)-> typeof subject is 'string' isNumber: (subject)-> typeof subject is 'number' isFunction: (subject)-> typeof subject is 'function' isBindingInterface: (subject)-> subject instanceof BindingInterface isSimpleObject: (subject)-> checkIf.isFunction(subject) or checkIf.isArray(subject) import [browserOnly] helpers-checkIf.DOM.coffee # ==== Object cloning ================================================================================= cloneObject = (object)-> clone = genObj() clone[key] = object[key] for key of object return clone extendState = (base, stateToInherit)-> stateMapping = Object.keys(stateToInherit) base[key] = stateToInherit[key] for key in stateMapping return # ==== Binding Cache ================================================================================= cache = get: (object, isSimpleObject, selector, isMultiChoice)-> if isSimpleObject return boundInstances[object._sb_ID] else import [browserOnly] helpers-cache.get.DOMChoice_group.coffee if object._sb_map and object._sb_map[selector] return boundInstances[ object._sb_map[selector] ] set: (B, isSimpleObject)-> # B ==== Binding Object if isSimpleObject Object.defineProperty B.object, '_sb_ID', {'configurable':true, 'value':B.ID} else selector = B.selector if B.object._sb_map B.object._sb_map[selector] = B.ID else propsMap = {} propsMap[selector] = B.ID Object.defineProperty B.object, '_sb_map', {'configurable':true, 'value':propsMap} return # ==== Placeholders ================================================================================= escapeRegEx = /[.*+?^${}()|[\]\\]/g pholderRegEx = pholderRegExSplit = null setPholderRegEx = ()-> start = settings.placeholder[0].replace(escapeRegEx, '\\$&') end = settings.placeholder[1].replace(escapeRegEx, '\\$&') middle = "[^#{end}]+" pholderRegEx = new RegExp("#{start}(#{middle})#{end}", 'g') pholderRegExSplit = new RegExp("#{start}#{middle}#{end}", 'g') return setPholderRegEx() # Create the regEx on init applyPlaceholders = (contexts, values, indexMap)-> output = '' for contextPart,index in contexts output += contextPart output += values[indexMap[index]] if indexMap[index] return output import [browserOnly] helpers-scanTextNodesPlaceholders.coffee # ==== Errors + Warnings ================================================================================= throwError = (errorName)-> throw new Error 'SimplyBind: '+(errors[errorName] or errorName) throwWarning = (warningName, depth)-> unless settings.silent errSource = getErrSource(depth) warn = errors[warningName] warn += "\n\n"+errSource console.warn('SimplyBind: '+warn) return throwErrorBadArg = (arg)-> throwError "Invalid argument/s (#{arg})", true return getErrSource = (depth)-> ((new Error).stack or '') .split('\n') .slice(depth+3) .join('\n')