diff --git a/vendors/knockout/src/binding/defaultBindings/foreach.js b/vendors/knockout/src/binding/defaultBindings/foreach.js index c542ade65..961132fc9 100644 --- a/vendors/knockout/src/binding/defaultBindings/foreach.js +++ b/vendors/knockout/src/binding/defaultBindings/foreach.js @@ -17,8 +17,7 @@ ko.bindingHandlers['foreach'] = { ko.utils.unwrapObservable(modelValue); return { 'foreach': unwrappedValue['data'], - 'as': unwrappedValue['as'], - 'beforeRemove': unwrappedValue['beforeRemove'] + 'as': unwrappedValue['as'] }; }, 'init': (element, valueAccessor) => diff --git a/vendors/knockout/src/binding/defaultBindings/options.js b/vendors/knockout/src/binding/defaultBindings/options.js index d4d478b73..08d2e516f 100644 --- a/vendors/knockout/src/binding/defaultBindings/options.js +++ b/vendors/knockout/src/binding/defaultBindings/options.js @@ -107,10 +107,6 @@ ko.bindingHandlers['options'] = { return [option]; }; - // By using a beforeRemove callback, we delay the removal until after new items are added. This fixes a selection - // problem in IE<=8 and Firefox. See https://github.com/knockout/knockout/issues/1208 - arrayToDomNodeChildrenOptions['beforeRemove'] = option => element.removeChild(option); - var callback = setSelectionCallback; if (allBindings['has']('optionsAfterRender') && typeof allBindings.get('optionsAfterRender') == "function") { callback = (arrayEntry, newOptions) => { diff --git a/vendors/knockout/src/binding/editDetection/arrayToDomNodeChildren.js b/vendors/knockout/src/binding/editDetection/arrayToDomNodeChildren.js index 9057feee2..37af3ce61 100644 --- a/vendors/knockout/src/binding/editDetection/arrayToDomNodeChildren.js +++ b/vendors/knockout/src/binding/editDetection/arrayToDomNodeChildren.js @@ -32,8 +32,14 @@ // of which nodes would be deleted if valueToMap was itself later removed mappedNodes.length = 0; mappedNodes.push(...newMappedNodes); - }, { disposeWhenNodeIsRemoved: containerNode, disposeWhen: ()=>!!mappedNodes.find(ko.utils.domNodeIsAttachedToDocument) }); - return { mappedNodes : mappedNodes, dependentObservable : (dependentObservable.isActive() ? dependentObservable : undefined) }; + }, { + disposeWhenNodeIsRemoved: containerNode, + disposeWhen: ()=>!!mappedNodes.find(ko.utils.domNodeIsAttachedToDocument) + }); + return { + mappedNodes : mappedNodes, + dependentObservable : (dependentObservable.isActive() ? dependentObservable : undefined) + }; } var lastMappingResultDomDataKey = ko.utils.domData.nextKey(), @@ -70,12 +76,6 @@ mapData.indexObservable(currentArrayIndex++); ko.utils.fixUpContinuousNodeArray(mapData.mappedNodes, domNode); newMappingResult.push(mapData); - }, - - callCallback = (callback, items) => { - if (callback) { - items.forEach(item => item?.mappedNodes.forEach(node => callback(node, i, item.arrayEntry))); - } }; if (isFirstExecution) { @@ -112,15 +112,6 @@ // Queue these nodes for later removal if (ko.utils.fixUpContinuousNodeArray(mapData.mappedNodes, domNode).length) { - if (options['beforeRemove']) { - newMappingResult.push(mapData); - countWaitingForRemove++; - if (mapData.arrayEntry === deletedItemDummyValue) { - mapData = null; - } else { - itemsForBeforeRemoveCallbacks[mapData.indexObservable.peek()] = mapData; - } - } if (mapData) { nodesToDelete.push.apply(nodesToDelete, mapData.mappedNodes); } @@ -155,8 +146,8 @@ // Store a copy of the array items we just considered so we can difference it next time ko.utils.domData.set(domNode, lastMappingResultDomDataKey, newMappingResult); - // Next remove nodes for deleted items (or just clean if there's a beforeRemove callback) - nodesToDelete.forEach(options['beforeRemove'] ? ko.cleanNode : ko.removeNode); + // Next remove nodes for deleted items + nodesToDelete.forEach(ko.removeNode); var i, lastNode, mappedNodes, activeElement, insertNode = nodeToInsert => { @@ -183,7 +174,7 @@ } } - // Next add/reorder the remaining items (will include deleted items if there's a beforeRemove callback) + // Next add/reorder the remaining items newMappingResult.forEach(mapData => { // Get nodes for newly added items mapData.mappedNodes @@ -205,15 +196,8 @@ activeElement?.focus(); } - // If there's a beforeRemove callback, call it after reordering. - // Note that we assume that the beforeRemove callback will usually be used to remove the nodes using - // some sort of animation, which is why we first reorder the nodes that will be removed. If the - // callback instead removes the nodes right away, it would be more efficient to skip reordering them. - // Perhaps we'll make that change in the future if this scenario becomes more common. - callCallback(options['beforeRemove'], itemsForBeforeRemoveCallbacks); - // Replace the stored values of deleted items with a dummy value. This provides two benefits: it marks this item - // as already "removed" so we won't call beforeRemove for it again, and it ensures that the item won't match up + // as already "removed", and it ensures that the item won't match up // with an actual item in the array and appear as "retained" or "moved". itemsForBeforeRemoveCallbacks.forEach(callback => callback && (callback.arrayEntry = deletedItemDummyValue)); } diff --git a/vendors/knockout/src/templating/templating.js b/vendors/knockout/src/templating/templating.js index 68d98504a..ba4637be4 100644 --- a/vendors/knockout/src/templating/templating.js +++ b/vendors/knockout/src/templating/templating.js @@ -165,7 +165,7 @@ ko.bindingEvent.notify(targetNode, ko.bindingEvent.childrenComplete); }; - if (!options['beforeRemove'] && ko['isObservableArray'](arrayOrObservableArray)) { + if (ko['isObservableArray'](arrayOrObservableArray)) { setDomNodeChildrenFromArrayMapping(arrayOrObservableArray.peek()); var subscription = arrayOrObservableArray['subscribe'](changeList => {