mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-02 05:59:21 +03:00
Clone 3.5.1 from github
This commit is contained in:
parent
5d281486d0
commit
091c4ec811
65 changed files with 6957 additions and 7 deletions
208
vendors/knockout/src/subscribables/subscribable.js
vendored
Normal file
208
vendors/knockout/src/subscribables/subscribable.js
vendored
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
|
||||
ko.subscription = function (target, callback, disposeCallback) {
|
||||
this._target = target;
|
||||
this._callback = callback;
|
||||
this._disposeCallback = disposeCallback;
|
||||
this._isDisposed = false;
|
||||
this._node = null;
|
||||
this._domNodeDisposalCallback = null;
|
||||
ko.exportProperty(this, 'dispose', this.dispose);
|
||||
ko.exportProperty(this, 'disposeWhenNodeIsRemoved', this.disposeWhenNodeIsRemoved);
|
||||
};
|
||||
ko.subscription.prototype.dispose = function () {
|
||||
var self = this;
|
||||
if (!self._isDisposed) {
|
||||
if (self._domNodeDisposalCallback) {
|
||||
ko.utils.domNodeDisposal.removeDisposeCallback(self._node, self._domNodeDisposalCallback);
|
||||
}
|
||||
self._isDisposed = true;
|
||||
self._disposeCallback();
|
||||
|
||||
self._target = self._callback = self._disposeCallback = self._node = self._domNodeDisposalCallback = null;
|
||||
}
|
||||
};
|
||||
ko.subscription.prototype.disposeWhenNodeIsRemoved = function (node) {
|
||||
this._node = node;
|
||||
ko.utils.domNodeDisposal.addDisposeCallback(node, this._domNodeDisposalCallback = this.dispose.bind(this));
|
||||
};
|
||||
|
||||
ko.subscribable = function () {
|
||||
ko.utils.setPrototypeOfOrExtend(this, ko_subscribable_fn);
|
||||
ko_subscribable_fn.init(this);
|
||||
}
|
||||
|
||||
var defaultEvent = "change";
|
||||
|
||||
// Moved out of "limit" to avoid the extra closure
|
||||
function limitNotifySubscribers(value, event) {
|
||||
if (!event || event === defaultEvent) {
|
||||
this._limitChange(value);
|
||||
} else if (event === 'beforeChange') {
|
||||
this._limitBeforeChange(value);
|
||||
} else {
|
||||
this._origNotifySubscribers(value, event);
|
||||
}
|
||||
}
|
||||
|
||||
var ko_subscribable_fn = {
|
||||
init: function(instance) {
|
||||
instance._subscriptions = { "change": [] };
|
||||
instance._versionNumber = 1;
|
||||
},
|
||||
|
||||
subscribe: function (callback, callbackTarget, event) {
|
||||
var self = this;
|
||||
|
||||
event = event || defaultEvent;
|
||||
var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback;
|
||||
|
||||
var subscription = new ko.subscription(self, boundCallback, function () {
|
||||
ko.utils.arrayRemoveItem(self._subscriptions[event], subscription);
|
||||
if (self.afterSubscriptionRemove)
|
||||
self.afterSubscriptionRemove(event);
|
||||
});
|
||||
|
||||
if (self.beforeSubscriptionAdd)
|
||||
self.beforeSubscriptionAdd(event);
|
||||
|
||||
if (!self._subscriptions[event])
|
||||
self._subscriptions[event] = [];
|
||||
self._subscriptions[event].push(subscription);
|
||||
|
||||
return subscription;
|
||||
},
|
||||
|
||||
"notifySubscribers": function (valueToNotify, event) {
|
||||
event = event || defaultEvent;
|
||||
if (event === defaultEvent) {
|
||||
this.updateVersion();
|
||||
}
|
||||
if (this.hasSubscriptionsForEvent(event)) {
|
||||
var subs = event === defaultEvent && this._changeSubscriptions || this._subscriptions[event].slice(0);
|
||||
try {
|
||||
ko.dependencyDetection.begin(); // Begin suppressing dependency detection (by setting the top frame to undefined)
|
||||
for (var i = 0, subscription; subscription = subs[i]; ++i) {
|
||||
// In case a subscription was disposed during the arrayForEach cycle, check
|
||||
// for isDisposed on each subscription before invoking its callback
|
||||
if (!subscription._isDisposed)
|
||||
subscription._callback(valueToNotify);
|
||||
}
|
||||
} finally {
|
||||
ko.dependencyDetection.end(); // End suppressing dependency detection
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
getVersion: function () {
|
||||
return this._versionNumber;
|
||||
},
|
||||
|
||||
hasChanged: function (versionToCheck) {
|
||||
return this.getVersion() !== versionToCheck;
|
||||
},
|
||||
|
||||
updateVersion: function () {
|
||||
++this._versionNumber;
|
||||
},
|
||||
|
||||
limit: function(limitFunction) {
|
||||
var self = this, selfIsObservable = ko.isObservable(self),
|
||||
ignoreBeforeChange, notifyNextChange, previousValue, pendingValue, didUpdate,
|
||||
beforeChange = 'beforeChange';
|
||||
|
||||
if (!self._origNotifySubscribers) {
|
||||
self._origNotifySubscribers = self["notifySubscribers"];
|
||||
self["notifySubscribers"] = limitNotifySubscribers;
|
||||
}
|
||||
|
||||
var finish = limitFunction(function() {
|
||||
self._notificationIsPending = false;
|
||||
|
||||
// If an observable provided a reference to itself, access it to get the latest value.
|
||||
// This allows computed observables to delay calculating their value until needed.
|
||||
if (selfIsObservable && pendingValue === self) {
|
||||
pendingValue = self._evalIfChanged ? self._evalIfChanged() : self();
|
||||
}
|
||||
var shouldNotify = notifyNextChange || (didUpdate && self.isDifferent(previousValue, pendingValue));
|
||||
|
||||
didUpdate = notifyNextChange = ignoreBeforeChange = false;
|
||||
|
||||
if (shouldNotify) {
|
||||
self._origNotifySubscribers(previousValue = pendingValue);
|
||||
}
|
||||
});
|
||||
|
||||
self._limitChange = function(value, isDirty) {
|
||||
if (!isDirty || !self._notificationIsPending) {
|
||||
didUpdate = !isDirty;
|
||||
}
|
||||
self._changeSubscriptions = self._subscriptions[defaultEvent].slice(0);
|
||||
self._notificationIsPending = ignoreBeforeChange = true;
|
||||
pendingValue = value;
|
||||
finish();
|
||||
};
|
||||
self._limitBeforeChange = function(value) {
|
||||
if (!ignoreBeforeChange) {
|
||||
previousValue = value;
|
||||
self._origNotifySubscribers(value, beforeChange);
|
||||
}
|
||||
};
|
||||
self._recordUpdate = function() {
|
||||
didUpdate = true;
|
||||
};
|
||||
self._notifyNextChangeIfValueIsDifferent = function() {
|
||||
if (self.isDifferent(previousValue, self.peek(true /*evaluate*/))) {
|
||||
notifyNextChange = true;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
hasSubscriptionsForEvent: function(event) {
|
||||
return this._subscriptions[event] && this._subscriptions[event].length;
|
||||
},
|
||||
|
||||
getSubscriptionsCount: function (event) {
|
||||
if (event) {
|
||||
return this._subscriptions[event] && this._subscriptions[event].length || 0;
|
||||
} else {
|
||||
var total = 0;
|
||||
ko.utils.objectForEach(this._subscriptions, function(eventName, subscriptions) {
|
||||
if (eventName !== 'dirty')
|
||||
total += subscriptions.length;
|
||||
});
|
||||
return total;
|
||||
}
|
||||
},
|
||||
|
||||
isDifferent: function(oldValue, newValue) {
|
||||
return !this['equalityComparer'] || !this['equalityComparer'](oldValue, newValue);
|
||||
},
|
||||
|
||||
toString: function() {
|
||||
return '[object Object]'
|
||||
},
|
||||
|
||||
extend: applyExtenders
|
||||
};
|
||||
|
||||
ko.exportProperty(ko_subscribable_fn, 'init', ko_subscribable_fn.init);
|
||||
ko.exportProperty(ko_subscribable_fn, 'subscribe', ko_subscribable_fn.subscribe);
|
||||
ko.exportProperty(ko_subscribable_fn, 'extend', ko_subscribable_fn.extend);
|
||||
ko.exportProperty(ko_subscribable_fn, 'getSubscriptionsCount', ko_subscribable_fn.getSubscriptionsCount);
|
||||
|
||||
// For browsers that support proto assignment, we overwrite the prototype of each
|
||||
// observable instance. Since observables are functions, we need Function.prototype
|
||||
// to still be in the prototype chain.
|
||||
if (ko.utils.canSetPrototype) {
|
||||
ko.utils.setPrototypeOf(ko_subscribable_fn, Function.prototype);
|
||||
}
|
||||
|
||||
ko.subscribable['fn'] = ko_subscribable_fn;
|
||||
|
||||
|
||||
ko.isSubscribable = function (instance) {
|
||||
return instance != null && typeof instance.subscribe == "function" && typeof instance["notifySubscribers"] == "function";
|
||||
};
|
||||
|
||||
ko.exportSymbol('subscribable', ko.subscribable);
|
||||
ko.exportSymbol('isSubscribable', ko.isSubscribable);
|
||||
Loading…
Add table
Add a link
Reference in a new issue