hellojs-xiaotian
Version:
A clientside Javascript library for standardizing requests to OAuth2 web services (and OAuth1 - with a shim)
87 lines (73 loc) • 3.45 kB
JavaScript
var observableLatestValue = ko.utils.createSymbolOrString('_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]); },
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.hasPrototype = function(instance, prototype) {
if ((instance === null) || (instance === undefined) || (instance[protoProperty] === undefined)) return false;
if (instance[protoProperty] === prototype) return true;
return ko.hasPrototype(instance[protoProperty], prototype); // Walk the prototype chain
};
ko.isObservable = function (instance) {
return ko.hasPrototype(instance, ko.observable);
}
ko.isWriteableObservable = function (instance) {
// Observable
if ((typeof instance == 'function') && instance[protoProperty] === ko.observable)
return true;
// Writeable dependent observable
if ((typeof instance == 'function') && (instance[protoProperty] === ko.dependentObservable) && (instance.hasWriteFunction))
return true;
// Anything else
return false;
}
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);