Multiple bug fixes and improvements. Shift, Unshift, and Splice are now supported to do inline array modifications without losing the original array reference across elements.

This commit is contained in:
2020-10-07 08:30:03 -07:00
parent b49a513831
commit 08f4f9006f
2 changed files with 241 additions and 43 deletions

View File

@ -8,6 +8,10 @@ class IgniteProperty {
this.onChangeCallbacks = [];
this.onPushCallbacks = [];
this.onPopCallbacks = [];
this.onShiftCallbacks = [];
this.onUnshiftCallbacks = [];
this.onSpliceCallbacks = [];
this.arrayCallbacks = [];
this.reflected = [];
this._value = val;
@ -64,31 +68,70 @@ class IgniteProperty {
if (Array.isArray(this._value) && this._value.onPushCallbacks == undefined) {
this._value.onPushCallbacks = [];
this._value.onPopCallbacks = [];
this._value.onShiftCallbacks = [];
this._value.onUnshiftCallbacks = [];
this._value.onSpliceCallbacks = [];
this._value.push = function () {
var len = Array.prototype.push.apply(this, arguments);
this.onPushCallbacks.forEach((callback) => callback.invoke(arguments[0]));
this.onPushCallbacks.forEach(callback => callback.invoke(Array.from(arguments)));
return len;
};
this._value.pop = function () {
var len = Array.prototype.pop.apply(this, arguments);
this.onPopCallbacks.forEach((callback) => callback.invoke());
this.onPopCallbacks.forEach(callback => callback.invoke());
return len;
}
this._value.unshift = function () {
var len = Array.prototype.unshift.apply(this, arguments);
this.onUnshiftCallbacks.forEach(callback => callback.invoke(Array.from(arguments)));
return len;
}
this._value.shift = function () {
var len = Array.prototype.shift.apply(this, arguments);
this.onShiftCallbacks.forEach(callback => callback.invoke());
return len;
};
this._value.splice = function (start, deleteCount = 0, ...items) {
var removed = Array.prototype.splice.apply(this, arguments);
this.onSpliceCallbacks.forEach(callback => callback.invoke(start, deleteCount, items));
return removed;
}
this._value.attachOnPush = function (func) {
var callback = new IgniteCallback(func, (detach) => this.detachOnPush(detach));
var callback = new IgniteCallback(func, detach => this.detachOnPush(detach));
this.onPushCallbacks.push(callback);
return callback;
}
this._value.attachOnPop = function (func) {
var callback = new IgniteCallback(func, (detach) => this.detachOnPop(detach));
var callback = new IgniteCallback(func, detach => this.detachOnPop(detach));
this.onPopCallbacks.push(callback);
return callback;
}
this._value.attachOnUnshift = function (func) {
var callback = new IgniteCallback(func, detach => this.detachOnUnshift(detach));
this.onUnshiftCallbacks.push(callback);
return callback;
}
this._value.attachOnShift = function (func) {
var callback = new IgniteCallback(func, detach => this.detachOnShift(detach));
this.onShiftCallbacks.push(callback);
return callback;
}
this._value.attachonSplice = function (func) {
var callback = new IgniteCallback(func, detach => this.detachonSplice(detach));
this.onSpliceCallbacks.push(callback);
return callback;
}
this._value.detachOnPush = function (callback) {
this.onPushCallbacks = this.onPushCallbacks.filter(push => push != callback);
}
@ -97,51 +140,89 @@ class IgniteProperty {
this.onPopCallbacks = this.onPopCallbacks.filter(pop => pop != callback);
}
this.arrayCallbacks.push(this._value.attachOnPush(() => this.invokeOnPush()));
this.arrayCallbacks.push(this._value.attachOnPop(() => this.invokeOnPop()));
} else if (Array.isArray(this._value) && this._value.onPushCallbacks) {
this._value.detachOnUnshift = function (callback) {
this.onUnshiftCallbacks = this.onUnshiftCallbacks.filter(unshift => unshift != callback);
}
this._value.detachOnShift = function (callback) {
this.onShiftCallbacks = this.onShiftCallbacks.filter(shift => shift != callback);
}
this._value.detachonSplice = function (callback) {
this.onSpliceCallbacks = this.onSpliceCallbacks.filter(slice => slice != callback);
}
}
if (Array.isArray(this._value) && this._value.onPushCallbacks) {
//This array has already been patched but attach to it so we get callbacks.
this.arrayCallbacks.push(this._value.attachOnPush(() => this.invokeOnPush()));
this.arrayCallbacks.push(this._value.attachOnPush((items) => this.invokeOnPush(items)));
this.arrayCallbacks.push(this._value.attachOnPop(() => this.invokeOnPop()));
this.arrayCallbacks.push(this._value.attachOnShift(() => this.invokeOnShift()));
this.arrayCallbacks.push(this._value.attachOnUnshift((items) => this.invokeOnUnshift(items)));
this.arrayCallbacks.push(this._value.attachonSplice((start, deleteCount, items) => this.invokeonSplice(start, deleteCount, items)));
}
}
invokeOnChange(oldValue, newValue) {
for (var i = 0; i < this.onChangeCallbacks.length; i++) {
this.onChangeCallbacks[i].invoke(oldValue, newValue);
}
this.onChangeCallbacks.forEach(callback => callback.invoke(oldValue, newValue));
}
invokeOnPush() {
for (var i = 0; i < this.onPushCallbacks.length; i++) {
this.onPushCallbacks[i].invoke(null, this._value);
}
invokeOnPush(items) {
this.onPushCallbacks.forEach(callback => callback.invoke(this._value, items));
}
invokeOnPop() {
for (var i = 0; i < this.onPopCallbacks.length; i++) {
this.onPopCallbacks[i].invoke(null, this._value);
}
this.onPopCallbacks.forEach(callback => callback.invoke(this._value));
}
invokeOnShift() {
this.onShiftCallbacks.forEach(callback => callback.invoke(this._value));
}
invokeOnUnshift(items) {
this.onUnshiftCallbacks.forEach(callback => callback.invoke(this._value, items));
}
invokeonSplice(start, deleteCount, items) {
this.onSpliceCallbacks.forEach(callback => callback.invoke(this._value, start, deleteCount, items));
}
attachOnChange(onChange) {
var callback = new IgniteCallback(onChange, (detach) => this.detachOnChange(detach));
var callback = new IgniteCallback(onChange, detach => this.detachOnChange(detach));
this.onChangeCallbacks.push(callback);
return callback;
}
attachOnPush(onPush) {
var callback = new IgniteCallback(onPush, (detach) => this.detachOnPush(detach));
var callback = new IgniteCallback(onPush, detach => this.detachOnPush(detach));
this.onPushCallbacks.push(callback);
return callback;
}
attachOnPop(onPop) {
var callback = new IgniteCallback(onPop, (detach) => this.detachOnPop(detach));
var callback = new IgniteCallback(onPop, detach => this.detachOnPop(detach));
this.onPopCallbacks.push(callback);
return callback;
}
attachOnShift(onShift) {
var callback = new IgniteCallback(onShift, detach => this.detachOnShift(detach));
this.onShiftCallbacks.push(callback);
return callback;
}
attachOnUnshift(onUnshift) {
var callback = new IgniteCallback(onUnshift, detach => this.detachOnUnshift(detach));
this.onUnshiftCallbacks.push(callback);
return callback;
}
attachOnSplice(onSplice) {
var callback = new IgniteCallback(onSplice, detach => this.detachonSplice(detach));
this.onSpliceCallbacks.push(callback);
return callback;
}
detachOnChange(callback) {
this.onChangeCallbacks = this.onChangeCallbacks.filter(change => change != callback);
}
@ -153,6 +234,18 @@ class IgniteProperty {
detachOnPop(callback) {
this.onPopCallbacks = this.onPopCallbacks.filter(pop => pop != callback);
}
detachOnShift(callback) {
this.onShiftCallbacks = this.onShiftCallbacks.filter(shift => shift != callback);
}
detachOnUnshift(callback) {
this.onUnshiftCallbacks = this.onUnshiftCallbacks.filter(unshift => unshift != callback);
}
detachonSplice(callback) {
this.onSpliceCallbacks = this.onSpliceCallbacks.filter(slice => slice != callback);
}
}
/**