mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-27 11:09:20 +03:00
76 lines
2.9 KiB
JavaScript
76 lines
2.9 KiB
JavaScript
const observableLatestValue = Symbol('_latestValue'),
|
|
length = 'length';
|
|
|
|
ko.observable = initialValue => {
|
|
function observable() {
|
|
if (arguments.length > 0) {
|
|
// Write
|
|
|
|
// Ignore writes if the value hasn't changed
|
|
if (observable.isDifferent(observable[observableLatestValue], arguments[0])) {
|
|
observable.valueWillMutate();
|
|
observable[observableLatestValue] = arguments[0];
|
|
observable.valueHasMutated();
|
|
}
|
|
return this; // Permits chained assignments
|
|
}
|
|
// Read
|
|
ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation
|
|
return observable[observableLatestValue];
|
|
}
|
|
|
|
observable[observableLatestValue] = initialValue;
|
|
|
|
Object.defineProperty(observable, length, {
|
|
get: () => null == observable[observableLatestValue] ? undefined : observable[observableLatestValue][length]
|
|
});
|
|
|
|
// Inherit from 'subscribable'
|
|
ko.subscribable['fn'].init(observable);
|
|
|
|
// Inherit from 'observable'
|
|
Object.setPrototypeOf(observable, observableFn);
|
|
|
|
return observable;
|
|
}
|
|
|
|
// Define prototype for observables
|
|
var observableFn = {
|
|
'toJSON': function() {
|
|
let value = this[observableLatestValue];
|
|
return value?.toJSON?.() || value;
|
|
},
|
|
equalityComparer: valuesArePrimitiveAndEqual,
|
|
peek: function() { return this[observableLatestValue]; },
|
|
valueHasMutated: function () {
|
|
this.notifySubscribers(this[observableLatestValue], 'spectate');
|
|
this.notifySubscribers(this[observableLatestValue]);
|
|
},
|
|
valueWillMutate: function () { this.notifySubscribers(this[observableLatestValue], 'beforeChange'); }
|
|
};
|
|
|
|
// Note that for browsers that don't support proto assignment, the
|
|
// inheritance chain is created manually in the ko.observable constructor
|
|
Object.setPrototypeOf(observableFn, ko.subscribable['fn']);
|
|
|
|
var protoProperty = ko.observable.protoProperty = '__ko_proto__';
|
|
observableFn[protoProperty] = ko.observable;
|
|
|
|
ko.isObservable = instance => {
|
|
var proto = typeof instance == 'function' && instance[protoProperty];
|
|
if (proto && proto !== observableFn[protoProperty] && proto !== ko.computed['fn'][protoProperty]) {
|
|
throw Error("Invalid object that looks like an observable; possibly from another Knockout instance");
|
|
}
|
|
return !!proto;
|
|
};
|
|
|
|
ko.isWriteableObservable = instance => {
|
|
return (typeof instance == 'function' && (
|
|
(instance[protoProperty] === observableFn[protoProperty]) || // Observable
|
|
(instance[protoProperty] === ko.computed['fn'][protoProperty] && instance.hasWriteFunction))); // Writable computed observable
|
|
};
|
|
|
|
ko.exportSymbol('observable', ko.observable);
|
|
ko.exportSymbol('isObservable', ko.isObservable);
|
|
ko.exportSymbol('observable.fn', observableFn);
|
|
ko.exportProperty(observableFn, 'valueHasMutated', observableFn.valueHasMutated);
|