From 451880d04dd33aeeb08c002a2e8134622e2415e3 Mon Sep 17 00:00:00 2001 From: Ryan Niemeyer Date: Mon, 16 Jun 2014 09:36:18 -0500 Subject: [PATCH] make extra removeNode call to ensure that moved nodes are disposed properly in KO 3+ fixes #104 --- bower.json | 2 +- build/knockout-sortable.js | 7 ++- build/knockout-sortable.min.js | 4 +- examples/connectedLists.html | 2 +- examples/draggable.html | 2 +- examples/seatingChart.html | 2 +- examples/singleList.html | 2 +- ext/knockout-3.0.0.js | 94 --------------------------------- ext/knockout-3.1.0.js | 96 ++++++++++++++++++++++++++++++++++ package.json | 2 +- spec/runner.html | 2 +- src/knockout-sortable.js | 5 +- 12 files changed, 114 insertions(+), 106 deletions(-) delete mode 100644 ext/knockout-3.0.0.js create mode 100644 ext/knockout-3.1.0.js diff --git a/bower.json b/bower.json index c90688c..c035573 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "knockout-sortable", - "version": "0.8.6", + "version": "0.8.7", "main": "./build/knockout-sortable.min.js", "ignore": [ "examples", diff --git a/build/knockout-sortable.js b/build/knockout-sortable.js index bf6387b..d729bb4 100644 --- a/build/knockout-sortable.js +++ b/build/knockout-sortable.js @@ -1,4 +1,4 @@ -// knockout-sortable 0.8.6 | (c) 2014 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license +// knockout-sortable 0.8.7 | (c) 2014 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license ;(function(factory) { if (typeof define === "function" && define.amd) { // AMD anonymous module @@ -191,7 +191,7 @@ if (arg.cancelDrop) { //call cancel on the correct list if (arg.sourceParent) { - $(arg.sourceParent === arg.targetParent ? this : ui.sender).sortable('cancel'); + $(arg.sourceParent === arg.targetParent ? this : ui.sender).sortable("cancel"); } //for a draggable item just remove the element else { @@ -206,6 +206,9 @@ if (sourceParent) { sourceParent.splice(sourceIndex, 1); + //in KO 3+, nodes outside of the original parent aren't found when trying to dispose, need to do this manually + ko.removeNode(el); + //if using deferred updates plugin, force updates if (ko.processAllDeferredBindingUpdates) { ko.processAllDeferredBindingUpdates(); diff --git a/build/knockout-sortable.min.js b/build/knockout-sortable.min.js index 51e140f..e828ad0 100644 --- a/build/knockout-sortable.min.js +++ b/build/knockout-sortable.min.js @@ -1,2 +1,2 @@ -// knockout-sortable 0.8.6 | (c) 2014 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license -!function(a){"function"==typeof define&&define.amd?define(["knockout","jquery","jquery.ui.sortable"],a):a(window.ko,jQuery)}(function(a,b){var c="ko_sortItem",d="ko_sourceIndex",e="ko_sortList",f="ko_parentList",g="ko_dragItem",h=a.utils.unwrapObservable,i=a.utils.domData.get,j=a.utils.domData.set,k=function(b,d){a.utils.arrayForEach(b,function(a){1===a.nodeType&&(j(a,c,d),j(a,f,i(a.parentNode,e)))})},l=function(b,c){var d,e={},f=h(b())||{};return f.data?(e[c]=f.data,e.name=f.template):e[c]=b(),a.utils.arrayForEach(["afterAdd","afterRender","as","beforeRemove","includeDestroyed","templateEngine","templateOptions"],function(b){e[b]=f[b]||a.bindingHandlers.sortable[b]}),"foreach"===c&&(e.afterRender?(d=e.afterRender,e.afterRender=function(a,b){k.call(b,a,b),d.call(b,a,b)}):e.afterRender=k),e},m=function(a,b){var c=h(b);if(c)for(var d=0;a>d;d++)c[d]&&h(c[d]._destroy)&&a++;return a};a.bindingHandlers.sortable={init:function(k,n,o,p,q){var r,s,t=b(k),u=h(n())||{},v=l(n,"foreach"),w={};t.contents().each(function(){this&&1!==this.nodeType&&k.removeChild(this)}),b.extend(!0,w,a.bindingHandlers.sortable),u.options&&w.options&&(a.utils.extend(w.options,u.options),delete u.options),a.utils.extend(w,u),w.connectClass&&(a.isObservable(w.allowDrop)||"function"==typeof w.allowDrop)?a.computed({read:function(){var b=h(w.allowDrop),c="function"==typeof b?b.call(this,v.foreach):b;a.utils.toggleDomNodeCssClass(k,w.connectClass,c)},disposeWhenNodeIsRemoved:k},this):a.utils.toggleDomNodeCssClass(k,w.connectClass,w.allowDrop),a.bindingHandlers.template.init(k,function(){return v},o,p,q),r=w.options.start,s=w.options.update;var x=setTimeout(function(){var l;t.sortable(a.utils.extend(w.options,{start:function(b,c){var e=c.item[0];j(e,d,a.utils.arrayIndexOf(c.item.parent().children(),e)),c.item.find("input:focus").change(),r&&r.apply(this,arguments)},receive:function(a,b){l=i(b.item[0],g),l&&(l.clone&&(l=l.clone()),w.dragged&&(l=w.dragged.call(this,l,a,b)||l))},update:function(g,h){var k,n,o,p,q,r=h.item[0],t=h.item.parent()[0],u=i(r,c)||l;if(l=null,u&&(this===t||b.contains(this,t))){if(k=i(r,f),o=i(r,d),n=i(r.parentNode,e),p=a.utils.arrayIndexOf(h.item.parent().children(),r),v.includeDestroyed||(o=m(o,k),p=m(p,n)),(w.beforeMove||w.afterMove)&&(q={item:u,sourceParent:k,sourceParentNode:k&&h.sender||r.parentNode,sourceIndex:o,targetParent:n,targetIndex:p,cancelDrop:!1}),w.beforeMove&&(w.beforeMove.call(this,q,g,h),q.cancelDrop))return q.sourceParent?b(q.sourceParent===q.targetParent?this:h.sender).sortable("cancel"):b(r).remove(),void 0;p>=0&&(k&&(k.splice(o,1),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates()),n.splice(p,0,u)),j(r,c,null),h.item.remove(),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates(),w.afterMove&&w.afterMove.call(this,q,g,h)}s&&s.apply(this,arguments)},connectWith:w.connectClass?"."+w.connectClass:!1})),void 0!==w.isEnabled&&a.computed({read:function(){t.sortable(h(w.isEnabled)?"enable":"disable")},disposeWhenNodeIsRemoved:k})},0);return a.utils.domNodeDisposal.addDisposeCallback(k,function(){(t.data("ui-sortable")||t.data("sortable"))&&t.sortable("destroy"),clearTimeout(x)}),{controlsDescendantBindings:!0}},update:function(b,c,d,f,g){var h=l(c,"foreach");j(b,e,h.foreach),a.bindingHandlers.template.update(b,function(){return h},d,f,g)},connectClass:"ko_container",allowDrop:!0,afterMove:null,beforeMove:null,options:{}},a.bindingHandlers.draggable={init:function(c,d,e,f,i){var k=h(d())||{},m=k.options||{},n=a.utils.extend({},a.bindingHandlers.draggable.options),o=l(d,"data"),p=k.connectClass||a.bindingHandlers.draggable.connectClass,q=void 0!==k.isEnabled?k.isEnabled:a.bindingHandlers.draggable.isEnabled;return k=k.data||k,j(c,g,k),a.utils.extend(n,m),n.connectToSortable=p?"."+p:!1,b(c).draggable(n),void 0!==q&&a.computed({read:function(){b(c).draggable(h(q)?"enable":"disable")},disposeWhenNodeIsRemoved:c}),a.bindingHandlers.template.init(c,function(){return o},e,f,i)},update:function(b,c,d,e,f){var g=l(c,"data");return a.bindingHandlers.template.update(b,function(){return g},d,e,f)},connectClass:a.bindingHandlers.sortable.connectClass,options:{helper:"clone"}}}); \ No newline at end of file +// knockout-sortable 0.8.7 | (c) 2014 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license +!function(a){"function"==typeof define&&define.amd?define(["knockout","jquery","jquery.ui.sortable"],a):a(window.ko,jQuery)}(function(a,b){var c="ko_sortItem",d="ko_sourceIndex",e="ko_sortList",f="ko_parentList",g="ko_dragItem",h=a.utils.unwrapObservable,i=a.utils.domData.get,j=a.utils.domData.set,k=function(b,d){a.utils.arrayForEach(b,function(a){1===a.nodeType&&(j(a,c,d),j(a,f,i(a.parentNode,e)))})},l=function(b,c){var d,e={},f=h(b())||{};return f.data?(e[c]=f.data,e.name=f.template):e[c]=b(),a.utils.arrayForEach(["afterAdd","afterRender","as","beforeRemove","includeDestroyed","templateEngine","templateOptions"],function(b){e[b]=f[b]||a.bindingHandlers.sortable[b]}),"foreach"===c&&(e.afterRender?(d=e.afterRender,e.afterRender=function(a,b){k.call(b,a,b),d.call(b,a,b)}):e.afterRender=k),e},m=function(a,b){var c=h(b);if(c)for(var d=0;a>d;d++)c[d]&&h(c[d]._destroy)&&a++;return a};a.bindingHandlers.sortable={init:function(k,n,o,p,q){var r,s,t=b(k),u=h(n())||{},v=l(n,"foreach"),w={};t.contents().each(function(){this&&1!==this.nodeType&&k.removeChild(this)}),b.extend(!0,w,a.bindingHandlers.sortable),u.options&&w.options&&(a.utils.extend(w.options,u.options),delete u.options),a.utils.extend(w,u),w.connectClass&&(a.isObservable(w.allowDrop)||"function"==typeof w.allowDrop)?a.computed({read:function(){var b=h(w.allowDrop),c="function"==typeof b?b.call(this,v.foreach):b;a.utils.toggleDomNodeCssClass(k,w.connectClass,c)},disposeWhenNodeIsRemoved:k},this):a.utils.toggleDomNodeCssClass(k,w.connectClass,w.allowDrop),a.bindingHandlers.template.init(k,function(){return v},o,p,q),r=w.options.start,s=w.options.update;var x=setTimeout(function(){var l;t.sortable(a.utils.extend(w.options,{start:function(b,c){var e=c.item[0];j(e,d,a.utils.arrayIndexOf(c.item.parent().children(),e)),c.item.find("input:focus").change(),r&&r.apply(this,arguments)},receive:function(a,b){l=i(b.item[0],g),l&&(l.clone&&(l=l.clone()),w.dragged&&(l=w.dragged.call(this,l,a,b)||l))},update:function(g,h){var k,n,o,p,q,r=h.item[0],t=h.item.parent()[0],u=i(r,c)||l;if(l=null,u&&(this===t||b.contains(this,t))){if(k=i(r,f),o=i(r,d),n=i(r.parentNode,e),p=a.utils.arrayIndexOf(h.item.parent().children(),r),v.includeDestroyed||(o=m(o,k),p=m(p,n)),(w.beforeMove||w.afterMove)&&(q={item:u,sourceParent:k,sourceParentNode:k&&h.sender||r.parentNode,sourceIndex:o,targetParent:n,targetIndex:p,cancelDrop:!1}),w.beforeMove&&(w.beforeMove.call(this,q,g,h),q.cancelDrop))return q.sourceParent?b(q.sourceParent===q.targetParent?this:h.sender).sortable("cancel"):b(r).remove(),void 0;p>=0&&(k&&(k.splice(o,1),a.removeNode(r),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates()),n.splice(p,0,u)),j(r,c,null),h.item.remove(),a.processAllDeferredBindingUpdates&&a.processAllDeferredBindingUpdates(),w.afterMove&&w.afterMove.call(this,q,g,h)}s&&s.apply(this,arguments)},connectWith:w.connectClass?"."+w.connectClass:!1})),void 0!==w.isEnabled&&a.computed({read:function(){t.sortable(h(w.isEnabled)?"enable":"disable")},disposeWhenNodeIsRemoved:k})},0);return a.utils.domNodeDisposal.addDisposeCallback(k,function(){(t.data("ui-sortable")||t.data("sortable"))&&t.sortable("destroy"),clearTimeout(x)}),{controlsDescendantBindings:!0}},update:function(b,c,d,f,g){var h=l(c,"foreach");j(b,e,h.foreach),a.bindingHandlers.template.update(b,function(){return h},d,f,g)},connectClass:"ko_container",allowDrop:!0,afterMove:null,beforeMove:null,options:{}},a.bindingHandlers.draggable={init:function(c,d,e,f,i){var k=h(d())||{},m=k.options||{},n=a.utils.extend({},a.bindingHandlers.draggable.options),o=l(d,"data"),p=k.connectClass||a.bindingHandlers.draggable.connectClass,q=void 0!==k.isEnabled?k.isEnabled:a.bindingHandlers.draggable.isEnabled;return k=k.data||k,j(c,g,k),a.utils.extend(n,m),n.connectToSortable=p?"."+p:!1,b(c).draggable(n),void 0!==q&&a.computed({read:function(){b(c).draggable(h(q)?"enable":"disable")},disposeWhenNodeIsRemoved:c}),a.bindingHandlers.template.init(c,function(){return o},e,f,i)},update:function(b,c,d,e,f){var g=l(c,"data");return a.bindingHandlers.template.update(b,function(){return g},d,e,f)},connectClass:a.bindingHandlers.sortable.connectClass,options:{helper:"clone"}}}); \ No newline at end of file diff --git a/examples/connectedLists.html b/examples/connectedLists.html index 3e7c5c3..29bfd28 100644 --- a/examples/connectedLists.html +++ b/examples/connectedLists.html @@ -7,7 +7,7 @@ - +