UNPKG

@danielkalen/simplybind

Version:

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

137 lines (124 loc) 3.83 kB
/* eslint-disable no-extend-native */ import {ModifyCollectionObserver} from './collection-observation'; let pop = Array.prototype.pop; let push = Array.prototype.push; let reverse = Array.prototype.reverse; let shift = Array.prototype.shift; let sort = Array.prototype.sort; let splice = Array.prototype.splice; let unshift = Array.prototype.unshift; Array.prototype.pop = function() { let notEmpty = this.length > 0; let 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() { let 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() { let oldArray; if (this.__array_observer__ !== undefined) { this.__array_observer__.flushChangeRecords(); oldArray = this.slice(); } let methodCallResult = reverse.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.reset(oldArray); } return methodCallResult; }; Array.prototype.shift = function() { let notEmpty = this.length > 0; let 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() { let oldArray; if (this.__array_observer__ !== undefined) { this.__array_observer__.flushChangeRecords(); oldArray = this.slice(); } let methodCallResult = sort.apply(this, arguments); if (this.__array_observer__ !== undefined) { this.__array_observer__.reset(oldArray); } return methodCallResult; }; Array.prototype.splice = function() { let 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() { let 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; }; export function getArrayObserver(taskQueue, array) { return ModifyArrayObserver.for(taskQueue, array); } class ModifyArrayObserver extends ModifyCollectionObserver { constructor(taskQueue, array) { super(taskQueue, array); } /** * Searches for observer or creates a new one associated with given array instance * @param taskQueue * @param array instance for which observer is searched * @returns ModifyArrayObserver always the same instance for any given array instance */ static 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__; } static create(taskQueue, array) { return new ModifyArrayObserver(taskQueue, array); } }