mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 20:49:20 +03:00
83 lines
3.3 KiB
JavaScript
83 lines
3.3 KiB
JavaScript
var observableLatestValue = Symbol('_latestValue');
|
|
|
|
ko.observable = function (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
|
|
}
|
|
else {
|
|
// 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;
|
|
|
|
// Inherit from 'subscribable'
|
|
if (!ko.utils.canSetPrototype) {
|
|
// 'subscribable' won't be on the prototype chain unless we put it there directly
|
|
ko.utils.extend(observable, ko.subscribable['fn']);
|
|
}
|
|
ko.subscribable['fn'].init(observable);
|
|
|
|
// Inherit from 'observable'
|
|
ko.utils.setPrototypeOfOrExtend(observable, observableFn);
|
|
|
|
if (ko.options['deferUpdates']) {
|
|
ko.extenders['deferred'](observable, true);
|
|
}
|
|
|
|
return observable;
|
|
}
|
|
|
|
// Define prototype for observables
|
|
var observableFn = {
|
|
'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
|
|
if (ko.utils.canSetPrototype) {
|
|
ko.utils.setPrototypeOf(observableFn, ko.subscribable['fn']);
|
|
}
|
|
|
|
var protoProperty = ko.observable.protoProperty = '__ko_proto__';
|
|
observableFn[protoProperty] = ko.observable;
|
|
|
|
ko.isObservable = function (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 = function (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('isWriteableObservable', ko.isWriteableObservable);
|
|
ko.exportSymbol('isWritableObservable', ko.isWriteableObservable);
|
|
ko.exportSymbol('observable.fn', observableFn);
|
|
ko.exportProperty(observableFn, 'peek', observableFn.peek);
|
|
ko.exportProperty(observableFn, 'valueHasMutated', observableFn.valueHasMutated);
|
|
ko.exportProperty(observableFn, 'valueWillMutate', observableFn.valueWillMutate);
|