diff --git a/dist/knockout-fast-foreach.js b/dist/knockout-fast-foreach.js index f6d6df7..7bfbd2f 100644 --- a/dist/knockout-fast-foreach.js +++ b/dist/knockout-fast-foreach.js @@ -1,5 +1,5 @@ /*! - Knockout Fast Foreach v0.6.0 (2015-12-17T02:29:56.923Z) + Knockout Fast Foreach v0.6.0 (2015-12-24T03:08:52.576Z) By: Brian M Hunt (C) 2015 | License: MIT Adds `fastForEach` to `ko.bindingHandlers`. @@ -367,12 +367,14 @@ FastForEach.prototype.deleted = function (changeItem) { // removes a set of nodes from the DOM FastForEach.prototype.removeNodes = function (nodes) { - if (!nodes.length) { - return; - } + if (!nodes.length) { return; } var removeFn = function () { - ko.utils.arrayForEach(nodes, function (n) { ko.removeNode(n); }); + var parent = nodes[0].parentNode; + for (var i = nodes.length - 1; i >= 0; --i) { + ko.cleanNode(nodes[i]); + parent.removeChild(nodes[i]); + } }; if (this.beforeRemove) { diff --git a/dist/knockout-fast-foreach.min.js b/dist/knockout-fast-foreach.min.js index 59495a2..72fb94f 100644 --- a/dist/knockout-fast-foreach.min.js +++ b/dist/knockout-fast-foreach.min.js @@ -1 +1 @@ -!function(e,t){"function"==typeof define&&define.amd?define(["knockout"],t):"object"==typeof exports?module.exports=t(require("knockout")):e.KnockoutFastForeach=t(e.ko)}(this,function(e){"use strict";function t(e){return!!e&&"object"==typeof e&&e.constructor===Object}function n(e){return 8===e.nodeType&&h.test(u?e.text:e.nodeValue)}function s(t){var n,s=document.createElement("div");return t.content?n=t.content:"SCRIPT"===t.tagName?(n=document.createElement("div"),n.innerHTML=t.text):n=t,e.utils.arrayForEach(e.virtualElements.childNodes(n),function(e){e&&s.insertBefore(e.cloneNode(!0),null)}),s}function i(e,t){return{status:"added",value:e,index:t}}function o(e){return"function"==typeof Symbol?Symbol(e):e}function r(t){this.element=t.element,this.container=n(this.element)?this.element.parentNode:this.element,this.$context=t.$context,this.data=t.data,this.as=t.as,this.noContext=t.noContext,this.noIndex=t.noIndex,this.afterAdd=t.afterAdd,this.beforeRemove=t.beforeRemove,this.templateNode=s(t.templateNode||(t.name?document.getElementById(t.name).cloneNode(!0):t.element)),this.afterQueueFlush=t.afterQueueFlush,this.beforeQueueFlush=t.beforeQueueFlush,this.changeQueue=[],this.firstLastNodesList=[],this.indexesToDelete=[],this.rendering_queued=!1,this.pendingDeletes=[],e.virtualElements.emptyNode(this.element);var o=e.unwrap(this.data);o.map&&this.onArrayChange(o.map(i)),e.isObservable(this.data)&&(this.data.indexOf||(this.data=this.data.extend({trackArrayChanges:!0})),this.changeSubs=this.data.subscribe(this.onArrayChange,this,"arrayChange"))}function a(t){t.$index=e.observable()}var d=9007199254740991,u=document&&""===document.createComment("test").text,h=u?/^$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,l=document&&"function"==typeof document.createDocumentFragment,c=o("_ko_ffe_pending_delete_index");r.PENDING_DELETE_INDEX_KEY=c,r.animateFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){return window.setTimeout(e,1e3/60)},r.prototype.dispose=function(){this.changeSubs&&this.changeSubs.dispose(),this.flushPendingDeletes()},r.prototype.onArrayChange=function(e){for(var t=this,n={added:[],deleted:[]},s=0,i=e.length;i>s;s++){if(n.added.length&&"added"==e[s].status){var o=n.added[n.added.length-1],a=o.isBatch?o.index+o.values.length-1:o.index;if(a+1==e[s].index){o.isBatch||(o={isBatch:!0,status:"added",index:o.index,values:[o.value]},n.added.splice(n.added.length-1,1,o)),o.values.push(e[s].value);continue}}n[e[s].status].push(e[s])}n.deleted.length>0&&(this.changeQueue.push.apply(this.changeQueue,n.deleted),this.changeQueue.push({status:"clearDeletedIndexes"})),this.changeQueue.push.apply(this.changeQueue,n.added),this.changeQueue.length>0&&!this.rendering_queued&&(this.rendering_queued=!0,r.animateFrame.call(window,function(){t.processQueue()}))},r.prototype.processQueue=function(){var t=this,n=d;"function"==typeof this.beforeQueueFlush&&this.beforeQueueFlush(this.changeQueue),e.utils.arrayForEach(this.changeQueue,function(e){"number"==typeof e.index&&(n=Math.min(n,e.index)),t[e.status](e)}),this.flushPendingDeletes(),this.rendering_queued=!1,this.noIndex||this.updateIndexes(n),"function"==typeof this.afterQueueFlush&&this.afterQueueFlush(this.changeQueue),this.changeQueue=[]},r.prototype.added=function(t){for(var n=t.index,s=t.isBatch?t.values:[t.value],i=this.getLastNodeBeforeIndex(n),o=[],r=0,d=s.length;d>r;++r){var u,h=this.getPendingDeleteFor(s[r]);if(h&&h.nodesets.length)u=h.nodesets.pop();else{var l,c=this.templateNode.cloneNode(!0);l=this.noContext?this.$context.extend({$item:s[r],$index:this.noIndex?void 0:e.observable()}):this.$context.createChildContext(s[r],this.as||null,this.noIndex?void 0:a),e.applyBindingsToDescendants(l,c),u=e.virtualElements.childNodes(c)}o.push.apply(o,Array.prototype.slice.call(u)),this.firstLastNodesList.splice(n+r,0,{first:u[0],last:u[u.length-1]})}"function"==typeof this.afterAdd?this.afterAdd({nodeOrArrayInserted:this.insertAllAfter(o,i),foreachInstance:this}):this.insertAllAfter(o,i)},r.prototype.getNodesForIndex=function(e){var t=[],n=this.firstLastNodesList[e].first,s=this.firstLastNodesList[e].last;for(t.push(n);n&&n!==s;)n=n.nextSibling,t.push(n);return t},r.prototype.getLastNodeBeforeIndex=function(e){return 1>e||e-1>=this.firstLastNodesList.length?null:this.firstLastNodesList[e-1].last},r.prototype.insertAllAfter=function(t,n){var s,i,o,r=this.element;if(void 0===t.nodeType&&void 0===t.length)throw new Error("Expected a single node or a node array");if(void 0!==t.nodeType)return e.virtualElements.insertAfter(r,t,n),[t];if(1===t.length)e.virtualElements.insertAfter(r,t[0],n);else if(l){for(s=document.createDocumentFragment(),o=0,i=t.length;o!==i;++o)s.appendChild(t[o]);e.virtualElements.insertAfter(r,s,n)}else for(o=t.length-1;o>=0;--o){var a=t[o];if(!a)break;e.virtualElements.insertAfter(r,a,n)}return t},r.prototype.shouldDelayDeletion=function(e){return e&&("object"==typeof e||"function"==typeof e)},r.prototype.getPendingDeleteFor=function(e){var t=e&&e[c];return void 0===t?null:this.pendingDeletes[t]},r.prototype.getOrCreatePendingDeleteFor=function(e){var t=this.getPendingDeleteFor(e);return t?t:(t={data:e,nodesets:[]},e[c]=this.pendingDeletes.length,this.pendingDeletes.push(t),t)},r.prototype.deleted=function(e){if(this.shouldDelayDeletion(e.value)){var t=this.getOrCreatePendingDeleteFor(e.value);t.nodesets.push(this.getNodesForIndex(e.index))}else this.removeNodes(this.getNodesForIndex(e.index));this.indexesToDelete.push(e.index)},r.prototype.removeNodes=function(t){if(t.length){var n=function(){e.utils.arrayForEach(t,function(t){e.removeNode(t)})};if(this.beforeRemove){var s=this.beforeRemove({nodesToRemove:t,foreachInstance:this})||{};"function"==typeof s.then&&s.then(n,e.onError?e.onError:void 0)}else n()}},r.prototype.flushPendingDeletes=function(){for(var e=0,t=this.pendingDeletes.length;e!=t;++e){for(var n=this.pendingDeletes[e];n.nodesets.length;)this.removeNodes(n.nodesets.pop());n.data&&void 0!==n.data[c]&&delete n.data[c]}this.pendingDeletes=[]},r.prototype.clearDeletedIndexes=function(){for(var e=this.indexesToDelete.length-1;e>=0;--e)this.firstLastNodesList.splice(this.indexesToDelete[e],1);this.indexesToDelete=[]},r.prototype.getContextStartingFrom=function(t){for(var n;t;){if(n=e.contextFor(t))return n;t=t.nextSibling}},r.prototype.updateIndexes=function(e){for(var t,n=e,s=this.firstLastNodesList.length;s>n;++n)t=this.getContextStartingFrom(this.firstLastNodesList[n].first),t&&t.$index(n)},e.bindingHandlers.fastForEach={init:function(n,s,i,o,a){var d,u=s();return t(u)?(u.element=u.element||n,u.$context=a,d=new r(u)):d=new r({element:n,data:e.unwrap(a.$rawData)===u?a.$rawData:u,$context:a}),e.utils.domNodeDisposal.addDisposeCallback(n,function(){d.dispose()}),{controlsDescendantBindings:!0}},FastForEach:r},e.virtualElements.allowedBindings.fastForEach=!0}); \ No newline at end of file +!function(e,t){"function"==typeof define&&define.amd?define(["knockout"],t):"object"==typeof exports?module.exports=t(require("knockout")):e.KnockoutFastForeach=t(e.ko)}(this,function(e){"use strict";function t(e){return!!e&&"object"==typeof e&&e.constructor===Object}function n(e){return 8===e.nodeType&&h.test(u?e.text:e.nodeValue)}function s(t){var n,s=document.createElement("div");return t.content?n=t.content:"SCRIPT"===t.tagName?(n=document.createElement("div"),n.innerHTML=t.text):n=t,e.utils.arrayForEach(e.virtualElements.childNodes(n),function(e){e&&s.insertBefore(e.cloneNode(!0),null)}),s}function i(e,t){return{status:"added",value:e,index:t}}function o(e){return"function"==typeof Symbol?Symbol(e):e}function r(t){this.element=t.element,this.container=n(this.element)?this.element.parentNode:this.element,this.$context=t.$context,this.data=t.data,this.as=t.as,this.noContext=t.noContext,this.noIndex=t.noIndex,this.afterAdd=t.afterAdd,this.beforeRemove=t.beforeRemove,this.templateNode=s(t.templateNode||(t.name?document.getElementById(t.name).cloneNode(!0):t.element)),this.afterQueueFlush=t.afterQueueFlush,this.beforeQueueFlush=t.beforeQueueFlush,this.changeQueue=[],this.firstLastNodesList=[],this.indexesToDelete=[],this.rendering_queued=!1,this.pendingDeletes=[],e.virtualElements.emptyNode(this.element);var o=e.unwrap(this.data);o.map&&this.onArrayChange(o.map(i)),e.isObservable(this.data)&&(this.data.indexOf||(this.data=this.data.extend({trackArrayChanges:!0})),this.changeSubs=this.data.subscribe(this.onArrayChange,this,"arrayChange"))}function a(t){t.$index=e.observable()}var d=9007199254740991,u=document&&""===document.createComment("test").text,h=u?/^$/:/^\s*ko(?:\s+([\s\S]+))?\s*$/,l=document&&"function"==typeof document.createDocumentFragment,c=o("_ko_ffe_pending_delete_index");r.PENDING_DELETE_INDEX_KEY=c,r.animateFrame=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){return window.setTimeout(e,1e3/60)},r.prototype.dispose=function(){this.changeSubs&&this.changeSubs.dispose(),this.flushPendingDeletes()},r.prototype.onArrayChange=function(e){for(var t=this,n={added:[],deleted:[]},s=0,i=e.length;i>s;s++){if(n.added.length&&"added"==e[s].status){var o=n.added[n.added.length-1],a=o.isBatch?o.index+o.values.length-1:o.index;if(a+1==e[s].index){o.isBatch||(o={isBatch:!0,status:"added",index:o.index,values:[o.value]},n.added.splice(n.added.length-1,1,o)),o.values.push(e[s].value);continue}}n[e[s].status].push(e[s])}n.deleted.length>0&&(this.changeQueue.push.apply(this.changeQueue,n.deleted),this.changeQueue.push({status:"clearDeletedIndexes"})),this.changeQueue.push.apply(this.changeQueue,n.added),this.changeQueue.length>0&&!this.rendering_queued&&(this.rendering_queued=!0,r.animateFrame.call(window,function(){t.processQueue()}))},r.prototype.processQueue=function(){var t=this,n=d;"function"==typeof this.beforeQueueFlush&&this.beforeQueueFlush(this.changeQueue),e.utils.arrayForEach(this.changeQueue,function(e){"number"==typeof e.index&&(n=Math.min(n,e.index)),t[e.status](e)}),this.flushPendingDeletes(),this.rendering_queued=!1,this.noIndex||this.updateIndexes(n),"function"==typeof this.afterQueueFlush&&this.afterQueueFlush(this.changeQueue),this.changeQueue=[]},r.prototype.added=function(t){for(var n=t.index,s=t.isBatch?t.values:[t.value],i=this.getLastNodeBeforeIndex(n),o=[],r=0,d=s.length;d>r;++r){var u,h=this.getPendingDeleteFor(s[r]);if(h&&h.nodesets.length)u=h.nodesets.pop();else{var l,c=this.templateNode.cloneNode(!0);l=this.noContext?this.$context.extend({$item:s[r],$index:this.noIndex?void 0:e.observable()}):this.$context.createChildContext(s[r],this.as||null,this.noIndex?void 0:a),e.applyBindingsToDescendants(l,c),u=e.virtualElements.childNodes(c)}o.push.apply(o,Array.prototype.slice.call(u)),this.firstLastNodesList.splice(n+r,0,{first:u[0],last:u[u.length-1]})}"function"==typeof this.afterAdd?this.afterAdd({nodeOrArrayInserted:this.insertAllAfter(o,i),foreachInstance:this}):this.insertAllAfter(o,i)},r.prototype.getNodesForIndex=function(e){var t=[],n=this.firstLastNodesList[e].first,s=this.firstLastNodesList[e].last;for(t.push(n);n&&n!==s;)n=n.nextSibling,t.push(n);return t},r.prototype.getLastNodeBeforeIndex=function(e){return 1>e||e-1>=this.firstLastNodesList.length?null:this.firstLastNodesList[e-1].last},r.prototype.insertAllAfter=function(t,n){var s,i,o,r=this.element;if(void 0===t.nodeType&&void 0===t.length)throw new Error("Expected a single node or a node array");if(void 0!==t.nodeType)return e.virtualElements.insertAfter(r,t,n),[t];if(1===t.length)e.virtualElements.insertAfter(r,t[0],n);else if(l){for(s=document.createDocumentFragment(),o=0,i=t.length;o!==i;++o)s.appendChild(t[o]);e.virtualElements.insertAfter(r,s,n)}else for(o=t.length-1;o>=0;--o){var a=t[o];if(!a)break;e.virtualElements.insertAfter(r,a,n)}return t},r.prototype.shouldDelayDeletion=function(e){return e&&("object"==typeof e||"function"==typeof e)},r.prototype.getPendingDeleteFor=function(e){var t=e&&e[c];return void 0===t?null:this.pendingDeletes[t]},r.prototype.getOrCreatePendingDeleteFor=function(e){var t=this.getPendingDeleteFor(e);return t?t:(t={data:e,nodesets:[]},e[c]=this.pendingDeletes.length,this.pendingDeletes.push(t),t)},r.prototype.deleted=function(e){if(this.shouldDelayDeletion(e.value)){var t=this.getOrCreatePendingDeleteFor(e.value);t.nodesets.push(this.getNodesForIndex(e.index))}else this.removeNodes(this.getNodesForIndex(e.index));this.indexesToDelete.push(e.index)},r.prototype.removeNodes=function(t){if(t.length){var n=function(){for(var n=t[0].parentNode,s=t.length-1;s>=0;--s)e.cleanNode(t[s]),n.removeChild(t[s])};if(this.beforeRemove){var s=this.beforeRemove({nodesToRemove:t,foreachInstance:this})||{};"function"==typeof s.then&&s.then(n,e.onError?e.onError:void 0)}else n()}},r.prototype.flushPendingDeletes=function(){for(var e=0,t=this.pendingDeletes.length;e!=t;++e){for(var n=this.pendingDeletes[e];n.nodesets.length;)this.removeNodes(n.nodesets.pop());n.data&&void 0!==n.data[c]&&delete n.data[c]}this.pendingDeletes=[]},r.prototype.clearDeletedIndexes=function(){for(var e=this.indexesToDelete.length-1;e>=0;--e)this.firstLastNodesList.splice(this.indexesToDelete[e],1);this.indexesToDelete=[]},r.prototype.getContextStartingFrom=function(t){for(var n;t;){if(n=e.contextFor(t))return n;t=t.nextSibling}},r.prototype.updateIndexes=function(e){for(var t,n=e,s=this.firstLastNodesList.length;s>n;++n)t=this.getContextStartingFrom(this.firstLastNodesList[n].first),t&&t.$index(n)},e.bindingHandlers.fastForEach={init:function(n,s,i,o,a){var d,u=s();return t(u)?(u.element=u.element||n,u.$context=a,d=new r(u)):d=new r({element:n,data:e.unwrap(a.$rawData)===u?a.$rawData:u,$context:a}),e.utils.domNodeDisposal.addDisposeCallback(n,function(){d.dispose()}),{controlsDescendantBindings:!0}},FastForEach:r},e.virtualElements.allowedBindings.fastForEach=!0}); \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index 940f027..435889c 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -7,10 +7,10 @@ */ var gulp = require('gulp'), - yaml = require('js-yaml'), - fs = require('fs'), - config = yaml.safeLoad(fs.readFileSync('./config.yaml', 'utf8')), - plugins = require('gulp-load-plugins')(); + yaml = require('js-yaml'), + fs = require('fs'), + config = yaml.safeLoad(fs.readFileSync('./config.yaml', 'utf8')), + plugins = require('gulp-load-plugins')(); // from https://github.com/ikari-pl/gulp-tag-version // function inc(importance) { @@ -41,4 +41,8 @@ gulp.task('js', function () { .pipe(gulp.dest('./dist')); }); +gulp.task('watch', function () { + gulp.watch('./index.js', ['js']) +}) + gulp.task('default', ['js']) diff --git a/index.js b/index.js index a7e2b53..850d7e5 100644 --- a/index.js +++ b/index.js @@ -351,12 +351,14 @@ FastForEach.prototype.deleted = function (changeItem) { // removes a set of nodes from the DOM FastForEach.prototype.removeNodes = function (nodes) { - if (!nodes.length) { - return; - } + if (!nodes.length) { return; } var removeFn = function () { - ko.utils.arrayForEach(nodes, function (n) { ko.removeNode(n); }); + var parent = nodes[0].parentNode; + for (var i = nodes.length - 1; i >= 0; --i) { + ko.cleanNode(nodes[i]); + parent.removeChild(nodes[i]); + } }; if (this.beforeRemove) {