From 340b48941bdb97655b5c375b0347bcf4d92fb49c Mon Sep 17 00:00:00 2001 From: fcamblor Date: Wed, 24 Oct 2018 11:49:52 +0200 Subject: [PATCH 1/3] Provided test case reproducing getManagerForEl() case returning undefined when root element is provided --- spec/SpecRunner.html | 1 + .../CollectionBinder/getManagerForEl.spec.js | 60 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 spec/javascripts/CollectionBinder/getManagerForEl.spec.js diff --git a/spec/SpecRunner.html b/spec/SpecRunner.html index 24effd0..b1d69d6 100644 --- a/spec/SpecRunner.html +++ b/spec/SpecRunner.html @@ -74,6 +74,7 @@ + diff --git a/spec/javascripts/CollectionBinder/getManagerForEl.spec.js b/spec/javascripts/CollectionBinder/getManagerForEl.spec.js new file mode 100644 index 0000000..ed97064 --- /dev/null +++ b/spec/javascripts/CollectionBinder/getManagerForEl.spec.js @@ -0,0 +1,60 @@ +describe("CollectionBinder: sorting", function(){ + + function createViewWithClickCallback(clickCallback) { + var View = Backbone.View.extend({ + events: function(){ + return { + 'click .clickable-div': this.onElementClicked, + 'click .clickable-span': this.onElementClicked + }; + }, + + initialize: function () { + var elManagerFactory = new Backbone.CollectionBinder.ElManagerFactory("
Hello !
"); + this.collectionBinder = new Backbone.CollectionBinder(elManagerFactory); + + this.collection = new Backbone.Collection([1,2,3]); + }, + + render: function(){ + this.collectionBinder.bind(this.collection, this.$el); + return this; + }, + + onElementClicked: function(event) { + var targetManager = this.collectionBinder.getManagerForEl($(event.currentTarget)); + clickCallback(targetManager); + + // Stopping propagation (in order to avoid bubbling from span to parent div) + event.stopPropagation(); + } + }); + return new View(); + } + + var createViewThenClickAndExpectManagerResolved = function(selectorElementToClick) { + var resolvedManager = undefined; + var clickCallbackCalled = false; + var view = createViewWithClickCallback(function(manager) { + clickCallbackCalled = true; + resolvedManager = manager; + }); + + view.render(); + view.$(selectorElementToClick).click(); + + expect(clickCallbackCalled).toBe(true); + expect(resolvedManager).toBeTruthy(); + + view.remove(); + }; + + it('should resolve el manager when span inner element is clicked', function () { + createViewThenClickAndExpectManagerResolved('span.clickable-span:eq(0)'); + }); + + it('should resolve el manager when div root element is clicked', function () { + createViewThenClickAndExpectManagerResolved('div.clickable-div:eq(0)'); + }); + +}); From 9faeda9c2431f23684247b06b5b2bd8cd0ee2f15 Mon Sep 17 00:00:00 2001 From: fcamblor Date: Wed, 24 Oct 2018 11:09:14 +0200 Subject: [PATCH 2/3] Allowing to consider isElContained(findEl) will return true when findEl is the same node than this._el in collection binder managers --- Backbone.CollectionBinder.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Backbone.CollectionBinder.js b/Backbone.CollectionBinder.js index 41482c7..4e808c4 100644 --- a/Backbone.CollectionBinder.js +++ b/Backbone.CollectionBinder.js @@ -232,7 +232,12 @@ }, isElContained: function(findEl){ - return this._el === findEl || $(this._el).has(findEl).length > 0; + if(this._el === findEl){ + return true; + } + + var $el = $(this._el); + return $el.has(findEl).length > 0 || $el.is(findEl); }, getModel: function(){ @@ -295,7 +300,7 @@ }, isElContained: function(findEl){ - return this._view.el === findEl || this._view.$el.has(findEl).length > 0; + return this._view.el === findEl || this._view.$el.has(findEl).length > 0 || this._view.$el.is(findEl); }, getModel: function(){ From 22bd129ea85de66d477a1cdd89beb3152d0bc8dc Mon Sep 17 00:00:00 2001 From: fcamblor Date: Wed, 24 Oct 2018 11:11:36 +0200 Subject: [PATCH 3/3] manually minified Backbone.CollectionBinder.js using https://jscompress.com/ --- Backbone.CollectionBinder.min.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Backbone.CollectionBinder.min.js b/Backbone.CollectionBinder.min.js index 8911b14..beb260b 100644 --- a/Backbone.CollectionBinder.min.js +++ b/Backbone.CollectionBinder.min.js @@ -2,4 +2,4 @@ // (c) 2015 Bart Wood // Distributed Under MIT License -!function(e){"function"==typeof define&&define.amd?define(["underscore","jquery","backbone","Backbone.ModelBinder"],e):"undefined"!=typeof module&&module.exports?module.exports=e(require("underscore"),require("jquery"),require("backbone")):e(_,$,Backbone)}(function(e,t,i){if(!i)throw"Please include Backbone.js before Backbone.ModelBinder.js";if(!i.ModelBinder)throw"Please include Backbone.ModelBinder.js before Backbone.CollectionBinder.js";i.CollectionBinder=function(t,n){if(e.bindAll.apply(e,[this].concat(e.functions(this))),this._elManagers={},this._elManagerFactory=t,!this._elManagerFactory)throw"elManagerFactory must be defined.";this._elManagerFactory.trigger=this.trigger,this._options=e.extend({},i.CollectionBinder.options,n)},i.CollectionBinder.SetOptions=function(e){i.CollectionBinder.options=e},i.CollectionBinder.VERSION="1.1.0",e.extend(i.CollectionBinder.prototype,i.Events,{bind:function(e,t){if(this.unbind(),!e)throw"collection must be defined";if(!t)throw"parentEl must be defined";this._collection=e,this._elManagerFactory._setParentEl(t),this._onCollectionReset(),this._collection.on("add",this._onCollectionAdd,this),this._collection.on("remove",this._onCollectionRemove,this),this._collection.on("reset",this._onCollectionReset,this),this._collection.on("sort",this._onCollectionSort,this)},unbind:function(){void 0!==this._collection&&(this._collection.off("add",this._onCollectionAdd),this._collection.off("remove",this._onCollectionRemove),this._collection.off("reset",this._onCollectionReset),this._collection.off("sort",this._onCollectionSort)),this._removeAllElManagers()},getManagerForEl:function(t){var i,n,o=e.values(this._elManagers);for(i=0;i0},getModel:function(){return this._model},getEl:function(){return this._el}};return e.extend(o,this),o}}),i.CollectionBinder.ViewManagerFactory=function(t){if(e.bindAll.apply(e,[this].concat(e.functions(this))),this._viewCreator=t,!e.isFunction(this._viewCreator))throw"viewCreator must be a valid function that accepts a model and returns a backbone view"},e.extend(i.CollectionBinder.ViewManagerFactory.prototype,{_setParentEl:function(e){this._parentEl=e},_getParentEl:function(){return this._parentEl},makeElManager:function(i){var n={_model:i,createEl:function(){this._view=this._viewCreator(i),this._view.render(this._model),t(this._parentEl).append(this._view.el),this.trigger("elCreated",this._model,this._view)},removeEl:function(){void 0!==this._view.close?this._view.close():(this._view.$el.remove(),console&&console.log&&console.log("warning, you should implement a close() function for your view, you might end up with zombies")),this.trigger("elRemoved",this._model,this._view)},isElContained:function(e){return this._view.el===e||this._view.$el.has(e).length>0},getModel:function(){return this._model},getView:function(){return this._view},getEl:function(){return this._view.$el}};return e.extend(n,this),n}})}); \ No newline at end of file +!function(e){"function"==typeof define&&define.amd?define(["underscore","jquery","backbone","Backbone.ModelBinder"],e):"undefined"!=typeof module&&module.exports?module.exports=e(require("underscore"),require("jquery"),require("backbone")):e(_,$,Backbone)}(function(o,l,i){if(!i)throw"Please include Backbone.js before Backbone.ModelBinder.js";if(!i.ModelBinder)throw"Please include Backbone.ModelBinder.js before Backbone.CollectionBinder.js";i.CollectionBinder=function(e,t){if(o.bindAll.apply(o,[this].concat(o.functions(this))),this._elManagers={},this._elManagerFactory=e,!this._elManagerFactory)throw"elManagerFactory must be defined.";this._elManagerFactory.trigger=this.trigger,this._options=o.extend({},i.CollectionBinder.options,t)},i.CollectionBinder.SetOptions=function(e){i.CollectionBinder.options=e},i.CollectionBinder.VERSION="1.1.0",o.extend(i.CollectionBinder.prototype,i.Events,{bind:function(e,t){if(this.unbind(),!e)throw"collection must be defined";if(!t)throw"parentEl must be defined";this._collection=e,this._elManagerFactory._setParentEl(t),this._onCollectionReset(),this._collection.on("add",this._onCollectionAdd,this),this._collection.on("remove",this._onCollectionRemove,this),this._collection.on("reset",this._onCollectionReset,this),this._collection.on("sort",this._onCollectionSort,this)},unbind:function(){void 0!==this._collection&&(this._collection.off("add",this._onCollectionAdd),this._collection.off("remove",this._onCollectionRemove),this._collection.off("reset",this._onCollectionReset),this._collection.off("sort",this._onCollectionSort)),this._removeAllElManagers()},getManagerForEl:function(e){var t,i,n=o.values(this._elManagers);for(t=0;t