More Knockout code to ES6

This commit is contained in:
djmaze 2021-07-29 11:43:47 +02:00
parent b7cb990b00
commit cbecdd93a0
22 changed files with 733 additions and 865 deletions

View file

@ -1,49 +1,44 @@
(() => {
ko.dependencyDetection = (() => {
var outerFrames = [],
currentFrame,
lastId = 0,
var outerFrames = [],
currentFrame,
lastId = 0,
begin = options => {
outerFrames.push(currentFrame);
currentFrame = options;
},
begin = options => {
outerFrames.push(currentFrame);
currentFrame = options;
},
end = () => currentFrame = outerFrames.pop();
end = () => currentFrame = outerFrames.pop();
return {
begin: begin,
ko.dependencyDetection = {
begin: begin,
end: end,
end: end,
registerDependency: subscribable => {
if (currentFrame) {
if (!ko.isSubscribable(subscribable))
throw new Error("Only subscribable things can act as dependencies");
currentFrame.callback.call(currentFrame.callbackTarget, subscribable,
subscribable._id || (subscribable._id = ++lastId));
}
},
ignore: (callback, callbackTarget, callbackArgs) => {
try {
begin();
return callback.apply(callbackTarget, callbackArgs || []);
} finally {
end();
}
},
getDependenciesCount: () => {
return currentFrame && currentFrame.computed.getDependenciesCount();
},
isInitial: () => {
return currentFrame && currentFrame.isInitial;
},
computed: () => {
return currentFrame && currentFrame.computed;
registerDependency: subscribable => {
if (currentFrame) {
if (!ko.isSubscribable(subscribable))
throw new Error("Only subscribable things can act as dependencies");
currentFrame.callback.call(currentFrame.callbackTarget, subscribable,
subscribable._id || (subscribable._id = ++lastId));
}
};
},
ignore: (callback, callbackTarget, callbackArgs) => {
try {
begin();
return callback.apply(callbackTarget, callbackArgs || []);
} finally {
end();
}
},
getDependenciesCount: () => currentFrame && currentFrame.computed.getDependenciesCount(),
isInitial: () => currentFrame && currentFrame.isInitial,
computed: () => currentFrame && currentFrame.computed
};
})();

View file

@ -35,18 +35,15 @@ ko.computed = (evaluatorFunctionOrOptions, options) => {
function computedObservable() {
if (arguments.length > 0) {
if (typeof writeFunction === "function") {
// Writing a value
writeFunction(...arguments);
} else {
if (typeof writeFunction !== "function") {
throw new Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
}
// Writing a value
writeFunction(...arguments);
return this; // Permits chained assignments
} else {
// Reading the value
if (!state.isDisposed) {
ko.dependencyDetection.registerDependency(computedObservable);
}
state.isDisposed || ko.dependencyDetection.registerDependency(computedObservable);
if (state.isDirty || (state.isSleeping && computedObservable.haveDependenciesChanged())) {
computedObservable.evaluateImmediate();
}
@ -132,23 +129,23 @@ function computedBeginDependencyDetectionCallback(subscribable, id) {
}
function evaluateImmediate_CallReadThenEndDependencyDetection(state, dependencyDetectionContext) {
// This function is really part of the evaluateImmediate_CallReadWithDependencyDetection logic.
// You'd never call it from anywhere else. Factoring it out means that evaluateImmediate_CallReadWithDependencyDetection
// can be independent of try/finally blocks, which contributes to saving about 40% off the CPU
// overhead of computed evaluation (on V8 at least).
// This function is really part of the evaluateImmediate_CallReadWithDependencyDetection logic.
// You'd never call it from anywhere else. Factoring it out means that evaluateImmediate_CallReadWithDependencyDetection
// can be independent of try/finally blocks, which contributes to saving about 40% off the CPU
// overhead of computed evaluation (on V8 at least).
try {
return state.readFunction();
} finally {
ko.dependencyDetection.end();
try {
return state.readFunction();
} finally {
ko.dependencyDetection.end();
// For each subscription no longer being used, remove it from the active subscriptions list and dispose it
if (dependencyDetectionContext.disposalCount && !state.isSleeping) {
ko.utils.objectForEach(dependencyDetectionContext.disposalCandidates, computedDisposeDependencyCallback);
}
// For each subscription no longer being used, remove it from the active subscriptions list and dispose it
if (dependencyDetectionContext.disposalCount && !state.isSleeping) {
ko.utils.objectForEach(dependencyDetectionContext.disposalCandidates, computedDisposeDependencyCallback);
}
state.isStale = state.isDirty = false;
}
state.isStale = state.isDirty = false;
}
}
var computedFn = {
@ -170,12 +167,8 @@ var computedFn = {
return false;
}
var dependencies = this.getDependencies();
if (dependencies.includes(obs)) {
return true;
}
return !!dependencies.find(dep =>
dep.hasAncestorDependency && dep.hasAncestorDependency(obs)
);
return dependencies.includes(obs)
|| !!dependencies.find(dep => dep.hasAncestorDependency && dep.hasAncestorDependency(obs));
},
addDependencyTracking: function (id, target, trackingObj) {
if (this[computedState].pure && target === this) {

View file

@ -1,5 +1,5 @@
const observableLatestValue = Symbol('_latestValue'),
length = 'length';
length = 'length';
ko.observable = initialValue => {
function observable() {

View file

@ -12,26 +12,22 @@ ko.observableArray = initialValues => {
ko.observableArray['fn'] = {
'remove': function (valueOrPredicate) {
var underlyingArray = this.peek();
var removedValues = [];
var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate) ? valueOrPredicate : function (value) { return value === valueOrPredicate; };
var removed = false;
var predicate = typeof valueOrPredicate == "function" && !ko.isObservable(valueOrPredicate)
? valueOrPredicate : value => value === valueOrPredicate;
var i = underlyingArray.length;
while (i--) {
var value = underlyingArray[i];
if (predicate(value)) {
if (removedValues.length === 0) {
this.valueWillMutate();
}
if (underlyingArray[i] !== value) {
throw Error("Array modified during remove; cannot remove item");
}
removedValues.push(value);
removed || this.valueWillMutate();
removed = true;
underlyingArray.splice(i, 1);
}
}
if (removedValues.length) {
this.valueHasMutated();
}
return removedValues;
removed && this.valueHasMutated();
}
};

View file

@ -41,7 +41,8 @@ var defaultEvent = "change";
var ko_subscribable_fn = {
init: instance => {
instance._subscriptions = { "change": [] };
instance._subscriptions = new Map();
instance._subscriptions.set("change", new Set);
instance._versionNumber = 1;
},
@ -52,7 +53,7 @@ var ko_subscribable_fn = {
var boundCallback = callbackTarget ? callback.bind(callbackTarget) : callback;
var subscription = new koSubscription(self, boundCallback, () => {
ko.utils.arrayRemoveItem(self._subscriptions[event], subscription);
self._subscriptions.get(event).delete(subscription);
if (self.afterSubscriptionRemove)
self.afterSubscriptionRemove(event);
});
@ -60,9 +61,9 @@ var ko_subscribable_fn = {
if (self.beforeSubscriptionAdd)
self.beforeSubscriptionAdd(event);
if (!self._subscriptions[event])
self._subscriptions[event] = [];
self._subscriptions[event].push(subscription);
if (!self._subscriptions.has(event))
self._subscriptions.set(event, new Set);
self._subscriptions.get(event).add(subscription);
return subscription;
},
@ -73,16 +74,14 @@ var ko_subscribable_fn = {
this.updateVersion();
}
if (this.hasSubscriptionsForEvent(event)) {
var subs = event === defaultEvent && this._changeSubscriptions || this._subscriptions[event].slice(0);
var subs = event === defaultEvent && this._changeSubscriptions || new Set(this._subscriptions.get(event));
try {
ko.dependencyDetection.begin(); // Begin suppressing dependency detection (by setting the top frame to undefined)
var i = 0, subscription;
while ((subscription = subs[i++])) {
subs.forEach(subscription => {
// 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);
}
subscription._isDisposed || subscription._callback(valueToNotify);
});
} finally {
ko.dependencyDetection.end(); // End suppressing dependency detection
}
@ -141,7 +140,7 @@ var ko_subscribable_fn = {
if (!isDirty || !self._notificationIsPending) {
didUpdate = !isDirty;
}
self._changeSubscriptions = self._subscriptions[defaultEvent].slice(0);
self._changeSubscriptions = new Set(self._subscriptions.get(defaultEvent));
self._notificationIsPending = ignoreBeforeChange = true;
pendingValue = value;
finish();
@ -163,7 +162,7 @@ var ko_subscribable_fn = {
},
hasSubscriptionsForEvent: function(event) {
return this._subscriptions[event] && this._subscriptions[event].length;
return (this._subscriptions.get(event) || []).size;
},
isDifferent: function(oldValue, newValue) {