UNPKG

@danielkalen/simplybind

Version:

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

1,805 lines (1,447 loc) 162 kB
export { _getArrayObserver as getArrayObserver }; export { _getMapObserver as getMapObserver }; export { _getSetObserver as getSetObserver }; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _dec, _dec2, _class, _dec3, _class2, _dec4, _class3, _dec5, _class5, _dec6, _class7, _dec7, _class8, _dec8, _class9, _dec9, _class10, _class11, _temp, _dec10, _class12, _class13, _temp2; function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } import * as LogManager from 'aurelia-logging'; import { PLATFORM, DOM } from 'aurelia-pal'; import { TaskQueue } from 'aurelia-task-queue'; import { metadata } from 'aurelia-metadata'; var map = Object.create(null); export function camelCase(name) { if (name in map) { return map[name]; } var result = name.charAt(0).toLowerCase() + name.slice(1).replace(/[_.-](\w|$)/g, function (_, x) { return x.toUpperCase(); }); map[name] = result; return result; } export function createOverrideContext(bindingContext, parentOverrideContext) { return { bindingContext: bindingContext, parentOverrideContext: parentOverrideContext || null }; } export function getContextFor(name, scope, ancestor) { var oc = scope.overrideContext; if (ancestor) { while (ancestor && oc) { ancestor--; oc = oc.parentOverrideContext; } if (ancestor || !oc) { return undefined; } return name in oc ? oc : oc.bindingContext; } while (oc && !(name in oc) && !(oc.bindingContext && name in oc.bindingContext)) { oc = oc.parentOverrideContext; } if (oc) { return name in oc ? oc : oc.bindingContext; } return scope.bindingContext || scope.overrideContext; } export function createScopeForTest(bindingContext, parentBindingContext) { if (parentBindingContext) { return { bindingContext: bindingContext, overrideContext: createOverrideContext(bindingContext, createOverrideContext(parentBindingContext)) }; } return { bindingContext: bindingContext, overrideContext: createOverrideContext(bindingContext) }; } export var sourceContext = 'Binding:source'; var slotNames = []; var versionSlotNames = []; for (var i = 0; i < 100; i++) { slotNames.push('_observer' + i); versionSlotNames.push('_observerVersion' + i); } function addObserver(observer) { var observerSlots = this._observerSlots === undefined ? 0 : this._observerSlots; var i = observerSlots; while (i-- && this[slotNames[i]] !== observer) {} if (i === -1) { i = 0; while (this[slotNames[i]]) { i++; } this[slotNames[i]] = observer; observer.subscribe(sourceContext, this); if (i === observerSlots) { this._observerSlots = i + 1; } } if (this._version === undefined) { this._version = 0; } this[versionSlotNames[i]] = this._version; } function observeProperty(obj, propertyName) { var observer = this.observerLocator.getObserver(obj, propertyName); addObserver.call(this, observer); } function observeArray(array) { var observer = this.observerLocator.getArrayObserver(array); addObserver.call(this, observer); } function unobserve(all) { var i = this._observerSlots; while (i--) { if (all || this[versionSlotNames[i]] !== this._version) { var observer = this[slotNames[i]]; this[slotNames[i]] = null; if (observer) { observer.unsubscribe(sourceContext, this); } } } } export function connectable() { return function (target) { target.prototype.observeProperty = observeProperty; target.prototype.observeArray = observeArray; target.prototype.unobserve = unobserve; target.prototype.addObserver = addObserver; }; } var bindings = new Map(); var minimumImmediate = 100; var frameBudget = 15; var isFlushRequested = false; var immediate = 0; function flush(animationFrameStart) { var i = 0; var keys = bindings.keys(); var item = void 0; while (item = keys.next()) { if (item.done) { break; } var binding = item.value; bindings.delete(binding); binding.connect(true); i++; if (i % 100 === 0 && PLATFORM.performance.now() - animationFrameStart > frameBudget) { break; } } if (bindings.size) { PLATFORM.requestAnimationFrame(flush); } else { isFlushRequested = false; immediate = 0; } } export function enqueueBindingConnect(binding) { if (immediate < minimumImmediate) { immediate++; binding.connect(false); } else { bindings.set(binding); } if (!isFlushRequested) { isFlushRequested = true; PLATFORM.requestAnimationFrame(flush); } } function addSubscriber(context, callable) { if (this.hasSubscriber(context, callable)) { return false; } if (!this._context0) { this._context0 = context; this._callable0 = callable; return true; } if (!this._context1) { this._context1 = context; this._callable1 = callable; return true; } if (!this._context2) { this._context2 = context; this._callable2 = callable; return true; } if (!this._contextsRest) { this._contextsRest = [context]; this._callablesRest = [callable]; return true; } this._contextsRest.push(context); this._callablesRest.push(callable); return true; } function removeSubscriber(context, callable) { if (this._context0 === context && this._callable0 === callable) { this._context0 = null; this._callable0 = null; return true; } if (this._context1 === context && this._callable1 === callable) { this._context1 = null; this._callable1 = null; return true; } if (this._context2 === context && this._callable2 === callable) { this._context2 = null; this._callable2 = null; return true; } var rest = this._contextsRest; var index = void 0; if (!rest || !rest.length || (index = rest.indexOf(context)) === -1 || this._callablesRest[index] !== callable) { return false; } rest.splice(index, 1); this._callablesRest.splice(index, 1); return true; } var arrayPool1 = []; var arrayPool2 = []; var poolUtilization = []; function callSubscribers(newValue, oldValue) { var context0 = this._context0; var callable0 = this._callable0; var context1 = this._context1; var callable1 = this._callable1; var context2 = this._context2; var callable2 = this._callable2; var length = this._contextsRest ? this._contextsRest.length : 0; var contextsRest = void 0; var callablesRest = void 0; var poolIndex = void 0; var i = void 0; if (length) { poolIndex = poolUtilization.length; while (poolIndex-- && poolUtilization[poolIndex]) {} if (poolIndex < 0) { poolIndex = poolUtilization.length; contextsRest = []; callablesRest = []; poolUtilization.push(true); arrayPool1.push(contextsRest); arrayPool2.push(callablesRest); } else { poolUtilization[poolIndex] = true; contextsRest = arrayPool1[poolIndex]; callablesRest = arrayPool2[poolIndex]; } i = length; while (i--) { contextsRest[i] = this._contextsRest[i]; callablesRest[i] = this._callablesRest[i]; } } if (context0) { if (callable0) { callable0.call(context0, newValue, oldValue); } else { context0(newValue, oldValue); } } if (context1) { if (callable1) { callable1.call(context1, newValue, oldValue); } else { context1(newValue, oldValue); } } if (context2) { if (callable2) { callable2.call(context2, newValue, oldValue); } else { context2(newValue, oldValue); } } if (length) { for (i = 0; i < length; i++) { var callable = callablesRest[i]; var context = contextsRest[i]; if (callable) { callable.call(context, newValue, oldValue); } else { context(newValue, oldValue); } contextsRest[i] = null; callablesRest[i] = null; } poolUtilization[poolIndex] = false; } } function hasSubscribers() { return !!(this._context0 || this._context1 || this._context2 || this._contextsRest && this._contextsRest.length); } function hasSubscriber(context, callable) { var has = this._context0 === context && this._callable0 === callable || this._context1 === context && this._callable1 === callable || this._context2 === context && this._callable2 === callable; if (has) { return true; } var index = void 0; var contexts = this._contextsRest; if (!contexts || (index = contexts.length) === 0) { return false; } var callables = this._callablesRest; while (index--) { if (contexts[index] === context && callables[index] === callable) { return true; } } return false; } export function subscriberCollection() { return function (target) { target.prototype.addSubscriber = addSubscriber; target.prototype.removeSubscriber = removeSubscriber; target.prototype.callSubscribers = callSubscribers; target.prototype.hasSubscribers = hasSubscribers; target.prototype.hasSubscriber = hasSubscriber; }; } export var ExpressionObserver = (_dec = connectable(), _dec2 = subscriberCollection(), _dec(_class = _dec2(_class = function () { function ExpressionObserver(scope, expression, observerLocator, lookupFunctions) { this.scope = scope; this.expression = expression; this.observerLocator = observerLocator; this.lookupFunctions = lookupFunctions; } ExpressionObserver.prototype.getValue = function getValue() { return this.expression.evaluate(this.scope, this.lookupFunctions); }; ExpressionObserver.prototype.setValue = function setValue(newValue) { this.expression.assign(this.scope, newValue); }; ExpressionObserver.prototype.subscribe = function subscribe(context, callable) { var _this = this; if (!this.hasSubscribers()) { this.oldValue = this.expression.evaluate(this.scope, this.lookupFunctions); this.expression.connect(this, this.scope); } this.addSubscriber(context, callable); if (arguments.length === 1 && context instanceof Function) { return { dispose: function dispose() { _this.unsubscribe(context, callable); } }; } }; ExpressionObserver.prototype.unsubscribe = function unsubscribe(context, callable) { if (this.removeSubscriber(context, callable) && !this.hasSubscribers()) { this.unobserve(true); this.oldValue = undefined; } }; ExpressionObserver.prototype.call = function call() { var newValue = this.expression.evaluate(this.scope, this.lookupFunctions); var oldValue = this.oldValue; if (newValue !== oldValue) { this.oldValue = newValue; this.callSubscribers(newValue, oldValue); } this._version++; this.expression.connect(this, this.scope); this.unobserve(false); }; return ExpressionObserver; }()) || _class) || _class); function isIndex(s) { return +s === s >>> 0; } function toNumber(s) { return +s; } function newSplice(index, removed, addedCount) { return { index: index, removed: removed, addedCount: addedCount }; } var EDIT_LEAVE = 0; var EDIT_UPDATE = 1; var EDIT_ADD = 2; var EDIT_DELETE = 3; function ArraySplice() {} ArraySplice.prototype = { calcEditDistances: function calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd) { var rowCount = oldEnd - oldStart + 1; var columnCount = currentEnd - currentStart + 1; var distances = new Array(rowCount); var north = void 0; var west = void 0; for (var _i = 0; _i < rowCount; ++_i) { distances[_i] = new Array(columnCount); distances[_i][0] = _i; } for (var j = 0; j < columnCount; ++j) { distances[0][j] = j; } for (var _i2 = 1; _i2 < rowCount; ++_i2) { for (var _j = 1; _j < columnCount; ++_j) { if (this.equals(current[currentStart + _j - 1], old[oldStart + _i2 - 1])) { distances[_i2][_j] = distances[_i2 - 1][_j - 1]; } else { north = distances[_i2 - 1][_j] + 1; west = distances[_i2][_j - 1] + 1; distances[_i2][_j] = north < west ? north : west; } } } return distances; }, spliceOperationsFromEditDistances: function spliceOperationsFromEditDistances(distances) { var i = distances.length - 1; var j = distances[0].length - 1; var current = distances[i][j]; var edits = []; while (i > 0 || j > 0) { if (i === 0) { edits.push(EDIT_ADD); j--; continue; } if (j === 0) { edits.push(EDIT_DELETE); i--; continue; } var northWest = distances[i - 1][j - 1]; var west = distances[i - 1][j]; var north = distances[i][j - 1]; var min = void 0; if (west < north) { min = west < northWest ? west : northWest; } else { min = north < northWest ? north : northWest; } if (min === northWest) { if (northWest === current) { edits.push(EDIT_LEAVE); } else { edits.push(EDIT_UPDATE); current = northWest; } i--; j--; } else if (min === west) { edits.push(EDIT_DELETE); i--; current = west; } else { edits.push(EDIT_ADD); j--; current = north; } } edits.reverse(); return edits; }, calcSplices: function calcSplices(current, currentStart, currentEnd, old, oldStart, oldEnd) { var prefixCount = 0; var suffixCount = 0; var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart); if (currentStart === 0 && oldStart === 0) { prefixCount = this.sharedPrefix(current, old, minLength); } if (currentEnd === current.length && oldEnd === old.length) { suffixCount = this.sharedSuffix(current, old, minLength - prefixCount); } currentStart += prefixCount; oldStart += prefixCount; currentEnd -= suffixCount; oldEnd -= suffixCount; if (currentEnd - currentStart === 0 && oldEnd - oldStart === 0) { return []; } if (currentStart === currentEnd) { var _splice = newSplice(currentStart, [], 0); while (oldStart < oldEnd) { _splice.removed.push(old[oldStart++]); } return [_splice]; } else if (oldStart === oldEnd) { return [newSplice(currentStart, [], currentEnd - currentStart)]; } var ops = this.spliceOperationsFromEditDistances(this.calcEditDistances(current, currentStart, currentEnd, old, oldStart, oldEnd)); var splice = undefined; var splices = []; var index = currentStart; var oldIndex = oldStart; for (var _i3 = 0; _i3 < ops.length; ++_i3) { switch (ops[_i3]) { case EDIT_LEAVE: if (splice) { splices.push(splice); splice = undefined; } index++; oldIndex++; break; case EDIT_UPDATE: if (!splice) { splice = newSplice(index, [], 0); } splice.addedCount++; index++; splice.removed.push(old[oldIndex]); oldIndex++; break; case EDIT_ADD: if (!splice) { splice = newSplice(index, [], 0); } splice.addedCount++; index++; break; case EDIT_DELETE: if (!splice) { splice = newSplice(index, [], 0); } splice.removed.push(old[oldIndex]); oldIndex++; break; } } if (splice) { splices.push(splice); } return splices; }, sharedPrefix: function sharedPrefix(current, old, searchLength) { for (var _i4 = 0; _i4 < searchLength; ++_i4) { if (!this.equals(current[_i4], old[_i4])) { return _i4; } } return searchLength; }, sharedSuffix: function sharedSuffix(current, old, searchLength) { var index1 = current.length; var index2 = old.length; var count = 0; while (count < searchLength && this.equals(current[--index1], old[--index2])) { count++; } return count; }, calculateSplices: function calculateSplices(current, previous) { return this.calcSplices(current, 0, current.length, previous, 0, previous.length); }, equals: function equals(currentValue, previousValue) { return currentValue === previousValue; } }; var arraySplice = new ArraySplice(); export function calcSplices(current, currentStart, currentEnd, old, oldStart, oldEnd) { return arraySplice.calcSplices(current, currentStart, currentEnd, old, oldStart, oldEnd); } function intersect(start1, end1, start2, end2) { if (end1 < start2 || end2 < start1) { return -1; } if (end1 === start2 || end2 === start1) { return 0; } if (start1 < start2) { if (end1 < end2) { return end1 - start2; } return end2 - start2; } if (end2 < end1) { return end2 - start1; } return end1 - start1; } export function mergeSplice(splices, index, removed, addedCount) { var splice = newSplice(index, removed, addedCount); var inserted = false; var insertionOffset = 0; for (var _i5 = 0; _i5 < splices.length; _i5++) { var current = splices[_i5]; current.index += insertionOffset; if (inserted) { continue; } var intersectCount = intersect(splice.index, splice.index + splice.removed.length, current.index, current.index + current.addedCount); if (intersectCount >= 0) { splices.splice(_i5, 1); _i5--; insertionOffset -= current.addedCount - current.removed.length; splice.addedCount += current.addedCount - intersectCount; var deleteCount = splice.removed.length + current.removed.length - intersectCount; if (!splice.addedCount && !deleteCount) { inserted = true; } else { var currentRemoved = current.removed; if (splice.index < current.index) { var prepend = splice.removed.slice(0, current.index - splice.index); Array.prototype.push.apply(prepend, currentRemoved); currentRemoved = prepend; } if (splice.index + splice.removed.length > current.index + current.addedCount) { var append = splice.removed.slice(current.index + current.addedCount - splice.index); Array.prototype.push.apply(currentRemoved, append); } splice.removed = currentRemoved; if (current.index < splice.index) { splice.index = current.index; } } } else if (splice.index < current.index) { inserted = true; splices.splice(_i5, 0, splice); _i5++; var offset = splice.addedCount - splice.removed.length; current.index += offset; insertionOffset += offset; } } if (!inserted) { splices.push(splice); } } function createInitialSplices(array, changeRecords) { var splices = []; for (var _i6 = 0; _i6 < changeRecords.length; _i6++) { var record = changeRecords[_i6]; switch (record.type) { case 'splice': mergeSplice(splices, record.index, record.removed.slice(), record.addedCount); break; case 'add': case 'update': case 'delete': if (!isIndex(record.name)) { continue; } var index = toNumber(record.name); if (index < 0) { continue; } mergeSplice(splices, index, [record.oldValue], record.type === 'delete' ? 0 : 1); break; default: console.error('Unexpected record type: ' + JSON.stringify(record)); break; } } return splices; } export function projectArraySplices(array, changeRecords) { var splices = []; createInitialSplices(array, changeRecords).forEach(function (splice) { if (splice.addedCount === 1 && splice.removed.length === 1) { if (splice.removed[0] !== array[splice.index]) { splices.push(splice); } return; } splices = splices.concat(calcSplices(array, splice.index, splice.index + splice.addedCount, splice.removed, 0, splice.removed.length)); }); return splices; } function newRecord(type, object, key, oldValue) { return { type: type, object: object, key: key, oldValue: oldValue }; } export function getChangeRecords(map) { var entries = new Array(map.size); var keys = map.keys(); var i = 0; var item = void 0; while (item = keys.next()) { if (item.done) { break; } entries[i] = newRecord('added', map, item.value); i++; } return entries; } export var ModifyCollectionObserver = (_dec3 = subscriberCollection(), _dec3(_class2 = function () { function ModifyCollectionObserver(taskQueue, collection) { this.taskQueue = taskQueue; this.queued = false; this.changeRecords = null; this.oldCollection = null; this.collection = collection; this.lengthPropertyName = collection instanceof Map || collection instanceof Set ? 'size' : 'length'; } ModifyCollectionObserver.prototype.subscribe = function subscribe(context, callable) { this.addSubscriber(context, callable); }; ModifyCollectionObserver.prototype.unsubscribe = function unsubscribe(context, callable) { this.removeSubscriber(context, callable); }; ModifyCollectionObserver.prototype.addChangeRecord = function addChangeRecord(changeRecord) { if (!this.hasSubscribers() && !this.lengthObserver) { return; } if (changeRecord.type === 'splice') { var index = changeRecord.index; var arrayLength = changeRecord.object.length; if (index > arrayLength) { index = arrayLength - changeRecord.addedCount; } else if (index < 0) { index = arrayLength + changeRecord.removed.length + index - changeRecord.addedCount; } if (index < 0) { index = 0; } changeRecord.index = index; } if (this.changeRecords === null) { this.changeRecords = [changeRecord]; } else { this.changeRecords.push(changeRecord); } if (!this.queued) { this.queued = true; this.taskQueue.queueMicroTask(this); } }; ModifyCollectionObserver.prototype.flushChangeRecords = function flushChangeRecords() { if (this.changeRecords && this.changeRecords.length || this.oldCollection) { this.call(); } }; ModifyCollectionObserver.prototype.reset = function reset(oldCollection) { this.oldCollection = oldCollection; if (this.hasSubscribers() && !this.queued) { this.queued = true; this.taskQueue.queueMicroTask(this); } }; ModifyCollectionObserver.prototype.getLengthObserver = function getLengthObserver() { return this.lengthObserver || (this.lengthObserver = new CollectionLengthObserver(this.collection)); }; ModifyCollectionObserver.prototype.call = function call() { var changeRecords = this.changeRecords; var oldCollection = this.oldCollection; var records = void 0; this.queued = false; this.changeRecords = []; this.oldCollection = null; if (this.hasSubscribers()) { if (oldCollection) { if (this.collection instanceof Map || this.collection instanceof Set) { records = getChangeRecords(oldCollection); } else { records = calcSplices(this.collection, 0, this.collection.length, oldCollection, 0, oldCollection.length); } } else { if (this.collection instanceof Map || this.collection instanceof Set) { records = changeRecords; } else { records = projectArraySplices(this.collection, changeRecords); } } this.callSubscribers(records); } if (this.lengthObserver) { this.lengthObserver.call(this.collection[this.lengthPropertyName]); } }; return ModifyCollectionObserver; }()) || _class2); export var CollectionLengthObserver = (_dec4 = subscriberCollection(), _dec4(_class3 = function () { function CollectionLengthObserver(collection) { this.collection = collection; this.lengthPropertyName = collection instanceof Map || collection instanceof Set ? 'size' : 'length'; this.currentValue = collection[this.lengthPropertyName]; } CollectionLengthObserver.prototype.getValue = function getValue() { return this.collection[this.lengthPropertyName]; }; CollectionLengthObserver.prototype.setValue = function setValue(newValue) { this.collection[this.lengthPropertyName] = newValue; }; CollectionLengthObserver.prototype.subscribe = function subscribe(context, callable) { this.addSubscriber(context, callable); }; CollectionLengthObserver.prototype.unsubscribe = function unsubscribe(context, callable) { this.removeSubscriber(context, callable); }; CollectionLengthObserver.prototype.call = function call(newValue) { var oldValue = this.currentValue; this.callSubscribers(newValue, oldValue); this.currentValue = newValue; }; return CollectionLengthObserver; }()) || _class3); var pop = Array.prototype.pop; var push = Array.prototype.push; var reverse = Array.prototype.reverse; var shift = Array.prototype.shift; var sort = Array.prototype.sort; var splice = Array.prototype.splice; var unshift = Array.prototype.unshift; Array.prototype.pop = function () { var notEmpty = this.length > 0; var methodCallResult = pop.apply(this, arguments); if (notEmpty && this.__array_observer__ !== undefined) { this.__array_observer__.addChangeRecord({ type: 'delete', object: this, name: this.length, oldValue: methodCallResult }); } return methodCallResult; }; Array.prototype.push = function () { var methodCallResult = push.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.addChangeRecord({ type: 'splice', object: this, index: this.length - arguments.length, removed: [], addedCount: arguments.length }); } return methodCallResult; }; Array.prototype.reverse = function () { var oldArray = void 0; if (this.__array_observer__ !== undefined) { this.__array_observer__.flushChangeRecords(); oldArray = this.slice(); } var methodCallResult = reverse.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.reset(oldArray); } return methodCallResult; }; Array.prototype.shift = function () { var notEmpty = this.length > 0; var methodCallResult = shift.apply(this, arguments); if (notEmpty && this.__array_observer__ !== undefined) { this.__array_observer__.addChangeRecord({ type: 'delete', object: this, name: 0, oldValue: methodCallResult }); } return methodCallResult; }; Array.prototype.sort = function () { var oldArray = void 0; if (this.__array_observer__ !== undefined) { this.__array_observer__.flushChangeRecords(); oldArray = this.slice(); } var methodCallResult = sort.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.reset(oldArray); } return methodCallResult; }; Array.prototype.splice = function () { var methodCallResult = splice.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.addChangeRecord({ type: 'splice', object: this, index: arguments[0], removed: methodCallResult, addedCount: arguments.length > 2 ? arguments.length - 2 : 0 }); } return methodCallResult; }; Array.prototype.unshift = function () { var methodCallResult = unshift.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.addChangeRecord({ type: 'splice', object: this, index: 0, removed: [], addedCount: arguments.length }); } return methodCallResult; }; function _getArrayObserver(taskQueue, array) { return ModifyArrayObserver.for(taskQueue, array); } var ModifyArrayObserver = function (_ModifyCollectionObse) { _inherits(ModifyArrayObserver, _ModifyCollectionObse); function ModifyArrayObserver(taskQueue, array) { return _possibleConstructorReturn(this, _ModifyCollectionObse.call(this, taskQueue, array)); } ModifyArrayObserver.for = function _for(taskQueue, array) { if (!('__array_observer__' in array)) { Reflect.defineProperty(array, '__array_observer__', { value: ModifyArrayObserver.create(taskQueue, array), enumerable: false, configurable: false }); } return array.__array_observer__; }; ModifyArrayObserver.create = function create(taskQueue, array) { return new ModifyArrayObserver(taskQueue, array); }; return ModifyArrayObserver; }(ModifyCollectionObserver); export var Expression = function () { function Expression() { this.isChain = false; this.isAssignable = false; } Expression.prototype.evaluate = function evaluate(scope, lookupFunctions, args) { throw new Error('Binding expression "' + this + '" cannot be evaluated.'); }; Expression.prototype.assign = function assign(scope, value, lookupFunctions) { throw new Error('Binding expression "' + this + '" cannot be assigned to.'); }; Expression.prototype.toString = function toString() { return Unparser.unparse(this); }; return Expression; }(); export var Chain = function (_Expression) { _inherits(Chain, _Expression); function Chain(expressions) { var _this3 = _possibleConstructorReturn(this, _Expression.call(this)); _this3.expressions = expressions; _this3.isChain = true; return _this3; } Chain.prototype.evaluate = function evaluate(scope, lookupFunctions) { var result = void 0; var expressions = this.expressions; var last = void 0; for (var _i7 = 0, length = expressions.length; _i7 < length; ++_i7) { last = expressions[_i7].evaluate(scope, lookupFunctions); if (last !== null) { result = last; } } return result; }; Chain.prototype.accept = function accept(visitor) { return visitor.visitChain(this); }; return Chain; }(Expression); export var BindingBehavior = function (_Expression2) { _inherits(BindingBehavior, _Expression2); function BindingBehavior(expression, name, args) { var _this4 = _possibleConstructorReturn(this, _Expression2.call(this)); _this4.expression = expression; _this4.name = name; _this4.args = args; return _this4; } BindingBehavior.prototype.evaluate = function evaluate(scope, lookupFunctions) { return this.expression.evaluate(scope, lookupFunctions); }; BindingBehavior.prototype.assign = function assign(scope, value, lookupFunctions) { return this.expression.assign(scope, value, lookupFunctions); }; BindingBehavior.prototype.accept = function accept(visitor) { return visitor.visitBindingBehavior(this); }; BindingBehavior.prototype.connect = function connect(binding, scope) { this.expression.connect(binding, scope); }; BindingBehavior.prototype.bind = function bind(binding, scope, lookupFunctions) { if (this.expression.expression && this.expression.bind) { this.expression.bind(binding, scope, lookupFunctions); } var behavior = lookupFunctions.bindingBehaviors(this.name); if (!behavior) { throw new Error('No BindingBehavior named "' + this.name + '" was found!'); } var behaviorKey = 'behavior-' + this.name; if (binding[behaviorKey]) { throw new Error('A binding behavior named "' + this.name + '" has already been applied to "' + this.expression + '"'); } binding[behaviorKey] = behavior; behavior.bind.apply(behavior, [binding, scope].concat(evalList(scope, this.args, binding.lookupFunctions))); }; BindingBehavior.prototype.unbind = function unbind(binding, scope) { var behaviorKey = 'behavior-' + this.name; binding[behaviorKey].unbind(binding, scope); binding[behaviorKey] = null; if (this.expression.expression && this.expression.unbind) { this.expression.unbind(binding, scope); } }; return BindingBehavior; }(Expression); export var ValueConverter = function (_Expression3) { _inherits(ValueConverter, _Expression3); function ValueConverter(expression, name, args, allArgs) { var _this5 = _possibleConstructorReturn(this, _Expression3.call(this)); _this5.expression = expression; _this5.name = name; _this5.args = args; _this5.allArgs = allArgs; return _this5; } ValueConverter.prototype.evaluate = function evaluate(scope, lookupFunctions) { var converter = lookupFunctions.valueConverters(this.name); if (!converter) { throw new Error('No ValueConverter named "' + this.name + '" was found!'); } if ('toView' in converter) { return converter.toView.apply(converter, evalList(scope, this.allArgs, lookupFunctions)); } return this.allArgs[0].evaluate(scope, lookupFunctions); }; ValueConverter.prototype.assign = function assign(scope, value, lookupFunctions) { var converter = lookupFunctions.valueConverters(this.name); if (!converter) { throw new Error('No ValueConverter named "' + this.name + '" was found!'); } if ('fromView' in converter) { value = converter.fromView.apply(converter, [value].concat(evalList(scope, this.args, lookupFunctions))); } return this.allArgs[0].assign(scope, value, lookupFunctions); }; ValueConverter.prototype.accept = function accept(visitor) { return visitor.visitValueConverter(this); }; ValueConverter.prototype.connect = function connect(binding, scope) { var expressions = this.allArgs; var i = expressions.length; while (i--) { expressions[i].connect(binding, scope); } }; return ValueConverter; }(Expression); export var Assign = function (_Expression4) { _inherits(Assign, _Expression4); function Assign(target, value) { var _this6 = _possibleConstructorReturn(this, _Expression4.call(this)); _this6.target = target; _this6.value = value; return _this6; } Assign.prototype.evaluate = function evaluate(scope, lookupFunctions) { return this.target.assign(scope, this.value.evaluate(scope, lookupFunctions)); }; Assign.prototype.accept = function accept(vistor) { vistor.visitAssign(this); }; Assign.prototype.connect = function connect(binding, scope) {}; return Assign; }(Expression); export var Conditional = function (_Expression5) { _inherits(Conditional, _Expression5); function Conditional(condition, yes, no) { var _this7 = _possibleConstructorReturn(this, _Expression5.call(this)); _this7.condition = condition; _this7.yes = yes; _this7.no = no; return _this7; } Conditional.prototype.evaluate = function evaluate(scope, lookupFunctions) { return !!this.condition.evaluate(scope) ? this.yes.evaluate(scope) : this.no.evaluate(scope); }; Conditional.prototype.accept = function accept(visitor) { return visitor.visitConditional(this); }; Conditional.prototype.connect = function connect(binding, scope) { this.condition.connect(binding, scope); if (this.condition.evaluate(scope)) { this.yes.connect(binding, scope); } else { this.no.connect(binding, scope); } }; return Conditional; }(Expression); export var AccessThis = function (_Expression6) { _inherits(AccessThis, _Expression6); function AccessThis(ancestor) { var _this8 = _possibleConstructorReturn(this, _Expression6.call(this)); _this8.ancestor = ancestor; return _this8; } AccessThis.prototype.evaluate = function evaluate(scope, lookupFunctions) { var oc = scope.overrideContext; var i = this.ancestor; while (i-- && oc) { oc = oc.parentOverrideContext; } return i < 1 && oc ? oc.bindingContext : undefined; }; AccessThis.prototype.accept = function accept(visitor) { return visitor.visitAccessThis(this); }; AccessThis.prototype.connect = function connect(binding, scope) {}; return AccessThis; }(Expression); export var AccessScope = function (_Expression7) { _inherits(AccessScope, _Expression7); function AccessScope(name, ancestor) { var _this9 = _possibleConstructorReturn(this, _Expression7.call(this)); _this9.name = name; _this9.ancestor = ancestor; _this9.isAssignable = true; return _this9; } AccessScope.prototype.evaluate = function evaluate(scope, lookupFunctions) { var context = getContextFor(this.name, scope, this.ancestor); return context[this.name]; }; AccessScope.prototype.assign = function assign(scope, value) { var context = getContextFor(this.name, scope, this.ancestor); return context ? context[this.name] = value : undefined; }; AccessScope.prototype.accept = function accept(visitor) { return visitor.visitAccessScope(this); }; AccessScope.prototype.connect = function connect(binding, scope) { var context = getContextFor(this.name, scope, this.ancestor); binding.observeProperty(context, this.name); }; return AccessScope; }(Expression); export var AccessMember = function (_Expression8) { _inherits(AccessMember, _Expression8); function AccessMember(object, name) { var _this10 = _possibleConstructorReturn(this, _Expression8.call(this)); _this10.object = object; _this10.name = name; _this10.isAssignable = true; return _this10; } AccessMember.prototype.evaluate = function evaluate(scope, lookupFunctions) { var instance = this.object.evaluate(scope, lookupFunctions); return instance === null || instance === undefined ? instance : instance[this.name]; }; AccessMember.prototype.assign = function assign(scope, value) { var instance = this.object.evaluate(scope); if (instance === null || instance === undefined) { instance = {}; this.object.assign(scope, instance); } instance[this.name] = value; return value; }; AccessMember.prototype.accept = function accept(visitor) { return visitor.visitAccessMember(this); }; AccessMember.prototype.connect = function connect(binding, scope) { this.object.connect(binding, scope); var obj = this.object.evaluate(scope); if (obj) { binding.observeProperty(obj, this.name); } }; return AccessMember; }(Expression); export var AccessKeyed = function (_Expression9) { _inherits(AccessKeyed, _Expression9); function AccessKeyed(object, key) { var _this11 = _possibleConstructorReturn(this, _Expression9.call(this)); _this11.object = object; _this11.key = key; _this11.isAssignable = true; return _this11; } AccessKeyed.prototype.evaluate = function evaluate(scope, lookupFunctions) { var instance = this.object.evaluate(scope, lookupFunctions); var lookup = this.key.evaluate(scope, lookupFunctions); return getKeyed(instance, lookup); }; AccessKeyed.prototype.assign = function assign(scope, value) { var instance = this.object.evaluate(scope); var lookup = this.key.evaluate(scope); return setKeyed(instance, lookup, value); }; AccessKeyed.prototype.accept = function accept(visitor) { return visitor.visitAccessKeyed(this); }; AccessKeyed.prototype.connect = function connect(binding, scope) { this.object.connect(binding, scope); var obj = this.object.evaluate(scope); if (obj instanceof Object) { this.key.connect(binding, scope); var key = this.key.evaluate(scope); if (key !== null && key !== undefined && !(Array.isArray(obj) && typeof key === 'number')) { binding.observeProperty(obj, key); } } }; return AccessKeyed; }(Expression); export var CallScope = function (_Expression10) { _inherits(CallScope, _Expression10); function CallScope(name, args, ancestor) { var _this12 = _possibleConstructorReturn(this, _Expression10.call(this)); _this12.name = name; _this12.args = args; _this12.ancestor = ancestor; return _this12; } CallScope.prototype.evaluate = function evaluate(scope, lookupFunctions, mustEvaluate) { var args = evalList(scope, this.args, lookupFunctions); var context = getContextFor(this.name, scope, this.ancestor); var func = getFunction(context, this.name, mustEvaluate); if (func) { return func.apply(context, args); } return undefined; }; CallScope.prototype.accept = function accept(visitor) { return visitor.visitCallScope(this); }; CallScope.prototype.connect = function connect(binding, scope) { var args = this.args; var i = args.length; while (i--) { args[i].connect(binding, scope); } }; return CallScope; }(Expression); export var CallMember = function (_Expression11) { _inherits(CallMember, _Expression11); function CallMember(object, name, args) { var _this13 = _possibleConstructorReturn(this, _Expression11.call(this)); _this13.object = object; _this13.name = name; _this13.args = args; return _this13; } CallMember.prototype.evaluate = function evaluate(scope, lookupFunctions, mustEvaluate) { var instance = this.object.evaluate(scope, lookupFunctions); var args = evalList(scope, this.args, lookupFunctions); var func = getFunction(instance, this.name, mustEvaluate); if (func) { return func.apply(instance, args); } return undefined; }; CallMember.prototype.accept = function accept(visitor) { return visitor.visitCallMember(this); }; CallMember.prototype.connect = function connect(binding, scope) { this.object.connect(binding, scope); var obj = this.object.evaluate(scope); if (getFunction(obj, this.name, false)) { var args = this.args; var _i8 = args.length; while (_i8--) { args[_i8].connect(binding, scope); } } }; return CallMember; }(Expression); export var CallFunction = function (_Expression12) { _inherits(CallFunction, _Expression12); function CallFunction(func, args) { var _this14 = _possibleConstructorReturn(this, _Expression12.call(this)); _this14.func = func; _this14.args = args; return _this14; } CallFunction.prototype.evaluate = function evaluate(scope, lookupFunctions, mustEvaluate) { var func = this.func.evaluate(scope, lookupFunctions); if (typeof func === 'function') { return func.apply(null, evalList(scope, this.args, lookupFunctions)); } if (!mustEvaluate && (func === null || func === undefined)) { return undefined; } throw new Error(this.func + ' is not a function'); }; CallFunction.prototype.accept = function accept(visitor) { return visitor.visitCallFunction(this); }; CallFunction.prototype.connect = function connect(binding, scope) { this.func.connect(binding, scope); var func = this.func.evaluate(scope); if (typeof func === 'function') { var args = this.args; var _i9 = args.length; while (_i9--) { args[_i9].connect(binding, scope); } } }; return CallFunction; }(Expression); export var Binary = function (_Expression13) { _inherits(Binary, _Expression13); function Binary(operation, left, right) { var _this15 = _possibleConstructorReturn(this, _Expression13.call(this)); _this15.operation = operation; _this15.left = left; _this15.right = right; return _this15; } Binary.prototype.evaluate = function evaluate(scope, lookupFunctions) { var left = this.left.evaluate(scope); switch (this.operation) { case '&&': return left && this.right.evaluate(scope); case '||': return left || this.right.evaluate(scope); } var right = this.right.evaluate(scope); switch (this.operation) { case '==': return left == right; case '===': return left === right; case '!=': return left != right; case '!==': return left !== right; } if (left === null || right === null || left === undefined || right === undefined) { switch (this.operation) { case '+': if (left !== null && left !== undefined) return left; if (right !== null && right !== undefined) return right; return 0; case '-': if (left !== null && left !== undefined) return left; if (right !== null && right !== undefined) return 0 - right; return 0; } return null; } switch (this.operation) { case '+': return autoConvertAdd(left, right); case '-': return left - right; case '*': return left * right; case '/': return left / right; case '%': return left % right; case '<': return left < right; case '>': return left > right; case '<=': return left <= right; case '>=': return left >= right; case '^': return left ^ right; } throw new Error('Internal error [' + this.operation + '] not handled'); }; Binary.prototype.accept = function accept(visitor) { return visitor.visitBinary(this); }; Binary.prototype.connect = function connect(binding, scope) { this.left.connect(binding, scope); var left = this.left.evaluate(scope); if (this.operation === '&&' && !left || this.operation === '||' && left) { return; } this.right.connect(binding, scope); }; return Binary; }(Expression); export var PrefixNot = function (_Expression14) { _inherits(PrefixNot, _Expression14); function PrefixNot(operation, expression) { var _this16 = _possibleConstructorReturn(this, _Expression14.call(this)); _this16.operation = operation; _this16.expression = expression; return _this16; } PrefixNot.prototype.evaluate = function evaluate(scope, lookupFunctions) { return !this.expression.evaluate(scope); }; PrefixNot.prototype.accept = function accept(visitor) { return visitor.visitPrefix(this); }; PrefixNot.prototype.connect = function connect(binding, scope) { this.expression.connect(binding, scope); }; return PrefixNot; }(Expression); export var LiteralPrimitive = function (_Expression15) { _inherits(LiteralPrimitive, _Expression15); function LiteralPrimitive(value) { var _this17 = _possibleConstructorReturn(this, _Expression15.call(this)); _this17.value = value; return _this17; } LiteralPrimitive.prototype.evaluate = function evaluate(scope, lookupFunctions) { return this.value; }; LiteralPrimitive.prototype.accept = function accept(visitor) { return visitor.visitLiteralPrimitive(this); }; LiteralPrimitive.prototype.connect = function connect(binding, scope) {}; return LiteralPrimitive; }(Expression); export var LiteralString = function (_Expression16) { _inherits(LiteralString, _Expression16); function LiteralString(value) { var _this18 = _possibleConstructorReturn(this, _Expression16.call(this)); _this18.value = value; return _this18; } LiteralString.prototype.evaluate = function evaluate(scope, lookupFunctions) { return this.value; }; LiteralString.prototype.accept = function accept(visitor) { return visitor.visitLiteralString(this); }; LiteralString.prototype.connect = function connect(binding, scope) {}; return LiteralString; }(Expression); export var LiteralArray = function (_Expression17) { _inherits(LiteralArray, _Expression17); function LiteralArray(elements) { var _this19 = _possibleConstructorReturn(this, _Expression17.call(this)); _this19.elements = elements; return _this19; } LiteralArray.prototype.evaluate = function evaluate(scope, lookupFunctions) { var elements = this.elements; var result = []; for (var _i10 = 0, length = elements.length; _i10 < length; ++_i10) { result[_i10] = elements[_i10].evaluate(scope, lookupFunctions); } return result; }; LiteralArray.prototype.accept = function accept(visitor) { return visitor.visitLiteralArray(this); }; LiteralArray.prototype.connect = function connect(binding, scope) { var length = this.elements.length; for (var _i11 = 0; _i11 < length; _i11++) { this.elements[_i11].connect(binding, scope); } }; return LiteralArray; }(Expression); export var LiteralObject