mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 12:39:20 +03:00
Changed Knockout a bit
This commit is contained in:
parent
a352ebff25
commit
f105ed3f9d
15 changed files with 205 additions and 194 deletions
|
|
@ -1,6 +1,6 @@
|
|||
(() => {
|
||||
|
||||
var outerFrames = [],
|
||||
let outerFrames = [],
|
||||
currentFrame,
|
||||
lastId = 0,
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ ko.dependencyDetection = {
|
|||
}
|
||||
},
|
||||
|
||||
ignore: (callback, callbackTarget, callbackArgs) => {
|
||||
ignore(callback, callbackTarget, callbackArgs) {
|
||||
try {
|
||||
begin();
|
||||
return callback.apply(callbackTarget, callbackArgs || []);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ ko.computed = (evaluatorFunctionOrOptions, options) => {
|
|||
computedObservable.hasWriteFunction = typeof writeFunction === "function";
|
||||
|
||||
// Inherit from 'subscribable'
|
||||
ko.subscribable['fn'].init(computedObservable);
|
||||
ko.subscribable['fn']['init'](computedObservable);
|
||||
|
||||
// Inherit from 'computed'
|
||||
Object.setPrototypeOf(computedObservable, computedFn);
|
||||
|
|
@ -143,10 +143,10 @@ function evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyD
|
|||
|
||||
var computedFn = {
|
||||
equalityComparer: valuesArePrimitiveAndEqual,
|
||||
getDependenciesCount: function () {
|
||||
getDependenciesCount() {
|
||||
return this[computedState].dependenciesCount;
|
||||
},
|
||||
getDependencies: function () {
|
||||
getDependencies() {
|
||||
var dependencyTracking = this[computedState].dependencyTracking, dependentObservables = [];
|
||||
|
||||
ko.utils.objectForEach(dependencyTracking, (id, dependency) =>
|
||||
|
|
@ -155,7 +155,7 @@ var computedFn = {
|
|||
|
||||
return dependentObservables;
|
||||
},
|
||||
hasAncestorDependency: function (obs) {
|
||||
hasAncestorDependency(obs) {
|
||||
if (!this[computedState].dependenciesCount) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -163,7 +163,7 @@ var computedFn = {
|
|||
return dependencies.includes(obs)
|
||||
|| !!dependencies.find(dep => dep.hasAncestorDependency && dep.hasAncestorDependency(obs));
|
||||
},
|
||||
addDependencyTracking: function (id, target, trackingObj) {
|
||||
addDependencyTracking(id, target, trackingObj) {
|
||||
if (this[computedState].pure && target === this) {
|
||||
throw Error("A 'pure' computed must not be called recursively");
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ var computedFn = {
|
|||
trackingObj._order = this[computedState].dependenciesCount++;
|
||||
trackingObj._version = target.getVersion();
|
||||
},
|
||||
haveDependenciesChanged: function () {
|
||||
haveDependenciesChanged() {
|
||||
var id, dependency, dependencyTracking = this[computedState].dependencyTracking;
|
||||
for (id in dependencyTracking) {
|
||||
if (Object.prototype.hasOwnProperty.call(dependencyTracking, id)) {
|
||||
|
|
@ -183,17 +183,17 @@ var computedFn = {
|
|||
}
|
||||
}
|
||||
},
|
||||
markDirty: function () {
|
||||
markDirty() {
|
||||
// Process "dirty" events if we can handle delayed notifications
|
||||
if (!this[computedState].isBeingEvaluated) {
|
||||
this._evalDelayed?.(false /*isChange*/);
|
||||
}
|
||||
},
|
||||
isActive: function () {
|
||||
isActive() {
|
||||
var state = this[computedState];
|
||||
return state.isDirty || state.dependenciesCount > 0;
|
||||
},
|
||||
respondToChange: function () {
|
||||
respondToChange() {
|
||||
// Ignore "change" events if we've already scheduled a delayed notification
|
||||
if (!this._notificationIsPending) {
|
||||
this.evaluatePossiblyAsync();
|
||||
|
|
@ -201,10 +201,10 @@ var computedFn = {
|
|||
this[computedState].isStale = true;
|
||||
}
|
||||
},
|
||||
subscribeToDependency: function (target) {
|
||||
return target.subscribe(this.evaluatePossiblyAsync, this);
|
||||
subscribeToDependency(target) {
|
||||
return target['subscribe'](this.evaluatePossiblyAsync, this);
|
||||
},
|
||||
evaluatePossiblyAsync: function () {
|
||||
evaluatePossiblyAsync() {
|
||||
var computedObservable = this,
|
||||
throttleEvaluationTimeout = computedObservable['throttleEvaluation'];
|
||||
if (throttleEvaluationTimeout >= 0) {
|
||||
|
|
@ -218,7 +218,7 @@ var computedFn = {
|
|||
computedObservable.evaluateImmediate(true /*notifyChange*/);
|
||||
}
|
||||
},
|
||||
evaluateImmediate: function (notifyChange) {
|
||||
evaluateImmediate(notifyChange) {
|
||||
var computedObservable = this,
|
||||
state = computedObservable[computedState],
|
||||
disposeWhen = state.disposeWhen,
|
||||
|
|
@ -254,7 +254,7 @@ var computedFn = {
|
|||
|
||||
return changed;
|
||||
},
|
||||
evaluateImmediate_CallReadWithDependencyDetection: function (notifyChange) {
|
||||
evaluateImmediate_CallReadWithDependencyDetection(notifyChange) {
|
||||
// This function is really just part of the evaluateImmediate logic. You would never call it from anywhere else.
|
||||
// Factoring it out into a separate function means it can be independent of the try/catch block in evaluateImmediate,
|
||||
// which contributes to saving about 40% off the CPU overhead of computed evaluation (on V8 at least).
|
||||
|
|
@ -316,7 +316,7 @@ var computedFn = {
|
|||
|
||||
return changed;
|
||||
},
|
||||
peek: function (evaluate) {
|
||||
peek(evaluate) {
|
||||
// By default, peek won't re-evaluate, except while the computed is sleeping.
|
||||
// Pass in true to evaluate if needed.
|
||||
var state = this[computedState];
|
||||
|
|
@ -325,7 +325,7 @@ var computedFn = {
|
|||
}
|
||||
return state.latestValue;
|
||||
},
|
||||
limit: function (limitFunction) {
|
||||
limit(limitFunction) {
|
||||
var self = this;
|
||||
// Override the limit function with one that delays evaluation as well
|
||||
ko.subscribable['fn'].limit.call(self, limitFunction);
|
||||
|
|
@ -353,7 +353,7 @@ var computedFn = {
|
|||
self._limitChange(self, !isChange /* isDirty */);
|
||||
};
|
||||
},
|
||||
dispose: function () {
|
||||
dispose() {
|
||||
var state = this[computedState];
|
||||
if (!state.isSleeping && state.dependencyTracking) {
|
||||
ko.utils.objectForEach(state.dependencyTracking, (id, dependency) =>
|
||||
|
|
@ -376,7 +376,7 @@ var computedFn = {
|
|||
};
|
||||
|
||||
var pureComputedOverrides = {
|
||||
beforeSubscriptionAdd: function (event) {
|
||||
beforeSubscriptionAdd(event) {
|
||||
// If asleep, wake up the computed by subscribing to any dependencies.
|
||||
var computedObservable = this,
|
||||
state = computedObservable[computedState];
|
||||
|
|
@ -415,7 +415,7 @@ var pureComputedOverrides = {
|
|||
}
|
||||
}
|
||||
},
|
||||
afterSubscriptionRemove: function (event) {
|
||||
afterSubscriptionRemove(event) {
|
||||
var state = this[computedState];
|
||||
if (!state.isDisposed && event == 'change' && !this.hasSubscriptionsForEvent('change')) {
|
||||
ko.utils.objectForEach(state.dependencyTracking, (id, dependency) => {
|
||||
|
|
@ -432,7 +432,7 @@ var pureComputedOverrides = {
|
|||
this.notifySubscribers(undefined, "asleep");
|
||||
}
|
||||
},
|
||||
getVersion: function () {
|
||||
getVersion() {
|
||||
// Because a pure computed is not automatically updated while it is sleeping, we can't
|
||||
// simply return the version number. Instead, we check if any of the dependencies have
|
||||
// changed and conditionally re-evaluate the computed observable.
|
||||
|
|
|
|||
16
vendors/knockout/src/subscribables/observable.js
vendored
16
vendors/knockout/src/subscribables/observable.js
vendored
|
|
@ -1,5 +1,6 @@
|
|||
const observableLatestValue = Symbol('_latestValue'),
|
||||
length = 'length';
|
||||
//const IS_OBSERVABLE = Symbol('IS_OBSERVABLE');
|
||||
|
||||
ko.observable = initialValue => {
|
||||
function observable() {
|
||||
|
|
@ -10,7 +11,7 @@ ko.observable = initialValue => {
|
|||
if (observable.isDifferent(observable[observableLatestValue], arguments[0])) {
|
||||
observable.valueWillMutate();
|
||||
observable[observableLatestValue] = arguments[0];
|
||||
observable.valueHasMutated();
|
||||
observable['valueHasMutated']();
|
||||
}
|
||||
return this; // Permits chained assignments
|
||||
}
|
||||
|
|
@ -26,7 +27,7 @@ ko.observable = initialValue => {
|
|||
});
|
||||
|
||||
// Inherit from 'subscribable'
|
||||
ko.subscribable['fn'].init(observable);
|
||||
ko.subscribable['fn']['init'](observable);
|
||||
|
||||
// Inherit from 'observable'
|
||||
return Object.setPrototypeOf(observable, observableFn);
|
||||
|
|
@ -34,17 +35,18 @@ ko.observable = initialValue => {
|
|||
|
||||
// Define prototype for observables
|
||||
var observableFn = {
|
||||
'toJSON': function() {
|
||||
// [IS_OBSERVABLE]: 1,
|
||||
'toJSON'() {
|
||||
let value = this[observableLatestValue];
|
||||
return value?.toJSON?.() || value;
|
||||
},
|
||||
equalityComparer: valuesArePrimitiveAndEqual,
|
||||
peek: function() { return this[observableLatestValue]; },
|
||||
valueHasMutated: function () {
|
||||
peek() { return this[observableLatestValue]; },
|
||||
'valueHasMutated'() {
|
||||
this.notifySubscribers(this[observableLatestValue], 'spectate');
|
||||
this.notifySubscribers(this[observableLatestValue]);
|
||||
},
|
||||
valueWillMutate: function () { this.notifySubscribers(this[observableLatestValue], 'beforeChange'); }
|
||||
valueWillMutate() { this.notifySubscribers(this[observableLatestValue], 'beforeChange'); }
|
||||
};
|
||||
|
||||
// Note that for browsers that don't support proto assignment, the
|
||||
|
|
@ -54,6 +56,7 @@ Object.setPrototypeOf(observableFn, ko.subscribable['fn']);
|
|||
var protoProperty = ko.observable.protoProperty = '__ko_proto__';
|
||||
observableFn[protoProperty] = ko.observable;
|
||||
|
||||
//ko.isObservable = obj => !!(obj && obj[IS_OBSERVABLE]);
|
||||
ko.isObservable = instance => {
|
||||
var proto = typeof instance == 'function' && instance[protoProperty];
|
||||
if (proto && proto !== observableFn[protoProperty] && proto !== ko.computed['fn'][protoProperty]) {
|
||||
|
|
@ -71,4 +74,3 @@ ko.isWriteableObservable = instance => {
|
|||
ko.exportSymbol('observable', ko.observable);
|
||||
ko.exportSymbol('isObservable', ko.isObservable);
|
||||
ko.exportSymbol('observable.fn', observableFn);
|
||||
ko.exportProperty(observableFn, 'valueHasMutated', observableFn.valueHasMutated);
|
||||
|
|
|
|||
|
|
@ -72,13 +72,13 @@ ko.extenders['trackArrayChanges'] = (target, options) => {
|
|||
trackingChanges = true;
|
||||
|
||||
// Track how many times the array actually changed value
|
||||
spectateSubscription = target.subscribe(() => ++pendingChanges, null, "spectate");
|
||||
spectateSubscription = target['subscribe'](() => ++pendingChanges, null, "spectate");
|
||||
|
||||
// Each time the array changes value, capture a clone so that on the next
|
||||
// change it's possible to produce a diff
|
||||
previousContents = [].concat(target.peek() || []);
|
||||
cachedDiff = null;
|
||||
changeSubscription = target.subscribe(notifyChanges);
|
||||
changeSubscription = target['subscribe'](notifyChanges);
|
||||
}
|
||||
|
||||
function getChanges(previousContents, currentContents) {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,13 @@ ko.observableArray = initialValues => {
|
|||
return Object.setPrototypeOf(ko.observable(initialValues), ko.observableArray['fn']).extend({'trackArrayChanges':true});
|
||||
};
|
||||
|
||||
//const IS_OBSERVABLE_ARRAY = Symbol('IS_OBSERVABLE_ARRAY');
|
||||
|
||||
// Note that for browsers that don't support proto assignment, the
|
||||
// inheritance chain is created manually in the ko.observableArray constructor
|
||||
ko.observableArray['fn'] = Object.setPrototypeOf({
|
||||
'remove': function (valueOrPredicate) {
|
||||
// [IS_OBSERVABLE_ARRAY]: 1,
|
||||
'remove'(valueOrPredicate) {
|
||||
var underlyingArray = this.peek();
|
||||
var removed = false;
|
||||
var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate)
|
||||
|
|
@ -27,7 +30,7 @@ ko.observableArray['fn'] = Object.setPrototypeOf({
|
|||
underlyingArray.splice(i, 1);
|
||||
}
|
||||
}
|
||||
removed && this.valueHasMutated();
|
||||
removed && this['valueHasMutated']();
|
||||
}
|
||||
}, ko.observable['fn']);
|
||||
|
||||
|
|
@ -47,7 +50,7 @@ Object.getOwnPropertyNames(Array.prototype).forEach(methodName => {
|
|||
this.valueWillMutate();
|
||||
this.cacheDiffForKnownOperation(underlyingArray, methodName, args);
|
||||
var methodCallResult = underlyingArray[methodName](...args);
|
||||
this.valueHasMutated();
|
||||
this['valueHasMutated']();
|
||||
// The native sort and reverse methods return a reference to the array, but it makes more sense to return the observable array instead.
|
||||
return methodCallResult === underlyingArray ? this : methodCallResult;
|
||||
};
|
||||
|
|
@ -60,11 +63,11 @@ Object.getOwnPropertyNames(Array.prototype).forEach(methodName => {
|
|||
}
|
||||
});
|
||||
|
||||
ko.isObservableArray = instance => {
|
||||
return ko.isObservable(instance)
|
||||
//ko.isObservableArray = obj => !!(obj && obj[IS_OBSERVABLE_ARRAY]);
|
||||
ko.isObservableArray = instance =>
|
||||
ko.isObservable(instance)
|
||||
&& typeof instance["remove"] == "function"
|
||||
&& typeof instance["push"] == "function";
|
||||
};
|
||||
|
||||
ko.exportSymbol('observableArray', ko.observableArray);
|
||||
ko.exportSymbol('isObservableArray', ko.isObservableArray);
|
||||
|
|
|
|||
|
|
@ -32,19 +32,23 @@ class koSubscription
|
|||
|
||||
ko.subscribable = function () {
|
||||
Object.setPrototypeOf(this, ko_subscribable_fn);
|
||||
ko_subscribable_fn.init(this);
|
||||
ko_subscribable_fn['init'](this);
|
||||
}
|
||||
|
||||
var defaultEvent = "change";
|
||||
|
||||
//const IS_SUBSCRIBABLE = Symbol('IS_SUBSCRIBABLE');
|
||||
|
||||
var ko_subscribable_fn = {
|
||||
init: instance => {
|
||||
// [IS_SUBSCRIBABLE]: 1,
|
||||
|
||||
'init': instance => {
|
||||
instance._subscriptions = new Map();
|
||||
instance._subscriptions.set("change", new Set);
|
||||
instance._versionNumber = 1;
|
||||
},
|
||||
|
||||
subscribe: function (callback, callbackTarget, event) {
|
||||
'subscribe'(callback, callbackTarget, event) {
|
||||
var self = this;
|
||||
|
||||
event = event || defaultEvent;
|
||||
|
|
@ -63,7 +67,7 @@ var ko_subscribable_fn = {
|
|||
return subscription;
|
||||
},
|
||||
|
||||
notifySubscribers: function (valueToNotify, event) {
|
||||
notifySubscribers(valueToNotify, event) {
|
||||
event = event || defaultEvent;
|
||||
if (event === defaultEvent) {
|
||||
this.updateVersion();
|
||||
|
|
@ -83,19 +87,19 @@ var ko_subscribable_fn = {
|
|||
}
|
||||
},
|
||||
|
||||
getVersion: function () {
|
||||
getVersion() {
|
||||
return this._versionNumber;
|
||||
},
|
||||
|
||||
hasChanged: function (versionToCheck) {
|
||||
hasChanged(versionToCheck) {
|
||||
return this.getVersion() !== versionToCheck;
|
||||
},
|
||||
|
||||
updateVersion: function () {
|
||||
updateVersion() {
|
||||
++this._versionNumber;
|
||||
},
|
||||
|
||||
limit: function(limitFunction) {
|
||||
limit(limitFunction) {
|
||||
var self = this, selfIsObservable = ko.isObservable(self),
|
||||
ignoreBeforeChange, notifyNextChange, previousValue, pendingValue, didUpdate,
|
||||
beforeChange = 'beforeChange';
|
||||
|
|
@ -156,17 +160,17 @@ var ko_subscribable_fn = {
|
|||
};
|
||||
},
|
||||
|
||||
hasSubscriptionsForEvent: function(event) {
|
||||
hasSubscriptionsForEvent(event) {
|
||||
return (this._subscriptions.get(event) || []).size;
|
||||
},
|
||||
|
||||
isDifferent: function(oldValue, newValue) {
|
||||
isDifferent(oldValue, newValue) {
|
||||
return !this.equalityComparer || !this.equalityComparer(oldValue, newValue);
|
||||
},
|
||||
|
||||
toString: () => '[object Object]',
|
||||
|
||||
extend: function(requestedExtenders) {
|
||||
'extend'(requestedExtenders) {
|
||||
var target = this;
|
||||
if (requestedExtenders) {
|
||||
ko.utils.objectForEach(requestedExtenders, (key, value) => {
|
||||
|
|
@ -180,14 +184,11 @@ var ko_subscribable_fn = {
|
|||
}
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
// 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.
|
||||
ko.subscribable['fn'] = Object.setPrototypeOf(ko_subscribable_fn, Function.prototype);
|
||||
|
||||
//ko.isSubscribable = obj => !!(obj && obj[IS_SUBSCRIBABLE]);
|
||||
ko.isSubscribable = instance =>
|
||||
typeof instance?.subscribe == "function" && typeof instance.notifySubscribers == "function";
|
||||
typeof instance?.['subscribe'] == "function" && typeof instance.notifySubscribers == "function";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue