From 57a9313a7b4465f6a340f3401dd93bd64b62bc28 Mon Sep 17 00:00:00 2001 From: Eric Rowell Date: Wed, 24 Jul 2013 22:56:21 -0700 Subject: [PATCH] all kinetic specific listeners now have the kinetic namespace. off no longer removes listeners with a kinetic namespace, unless you force remove it via .kinetic --- src/Node.js | 56 +++++++++++++++---------------- src/plugins/Label.js | 2 +- src/plugins/Path.js | 2 +- src/plugins/TextPath.js | 9 ++--- src/shapes/Blob.js | 2 +- src/shapes/Spline.js | 2 +- src/shapes/Sprite.js | 2 +- tests/js/unit/shapes/blobTests.js | 52 ++++++++++++++++++++++++++++ 8 files changed, 88 insertions(+), 39 deletions(-) diff --git a/src/Node.js b/src/Node.js index d8ab3b91..46d1e0ef 100644 --- a/src/Node.js +++ b/src/Node.js @@ -49,7 +49,7 @@ * event by name such as 'click.foobar'. * @method * @memberof Kinetic.Node.prototype - * @param {String} typesStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo' + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo' * @param {Function} handler The handler function is passed an event object * @example * // add click listener
@@ -77,10 +77,10 @@ * console.log('you clicked/touched me!');
* }); */ - on: function(typesStr, handler) { - var types = typesStr.split(SPACE), - len = types.length, - n, type, event, parts, baseEvent, name; + on: function(evtStr, handler) { + var events = evtStr.split(SPACE), + len = events.length, + n, event, parts, baseEvent, name; /* * loop through types and attach event listeners to @@ -88,12 +88,12 @@ * will create three event bindings */ for(n = 0; n < len; n++) { - type = types[n]; - event = type; + event = events[n]; parts = event.split(DOT); baseEvent = parts[0]; - name = parts.length > 1 ? parts[1] : EMPTY_STRING; + name = parts[1] || EMPTY_STRING; + // create events array if it doesn't exist if(!this.eventListeners[baseEvent]) { this.eventListeners[baseEvent] = []; } @@ -114,7 +114,7 @@ * all events in that namespace will be removed. * @method * @memberof Kinetic.Node.prototype - * @param {String} typesStr e.g. 'click', 'mousedown touchstart', '.foobar' + * @param {String} evtStr e.g. 'click', 'mousedown touchstart', '.foobar' * @example * // remove listener
* node.off('click');

@@ -125,31 +125,26 @@ * // remove listener by name
* node.off('click.foo'); */ - off: function(typesStr) { - var types = typesStr.split(SPACE), - len = types.length, - n, type, t, event, parts, baseEvent; + off: function(evtStr) { + var events = evtStr.split(SPACE), + len = events.length, + n, i, event, parts, baseEvent, name; for(n = 0; n < len; n++) { - type = types[n]; - event = type; + event = events[n]; parts = event.split(DOT); baseEvent = parts[0]; + name = parts[1]; - if(parts.length > 1) { - if(baseEvent) { - if(this.eventListeners[baseEvent]) { - this._off(baseEvent, parts[1]); - } - } - else { - for(t in this.eventListeners) { - this._off(t, parts[1]); - } + if(baseEvent) { + if(this.eventListeners[baseEvent]) { + this._off(baseEvent, name); } } else { - delete this.eventListeners[baseEvent]; + for(t in this.eventListeners) { + this._off(t, name); + } } } return this; @@ -964,10 +959,15 @@ }, _off: function(type, name) { var evtListeners = this.eventListeners[type], - i; + i, evtName; for(i = 0; i < evtListeners.length; i++) { - if(evtListeners[i].name === name) { + evtName = evtListeners[i].name; + // the following two conditions must be true in order to remove a handler: + // 1) the current event name cannot be kinetic unless the event name is kinetic + // this enables developers to force remove a kinetic specific listener for whatever reason + // 2) an event name is not specified, or if one is specified, it matches the current event name + if((evtName !== 'kinetic' || name === 'kinetic') && (!name || evtName === name)) { evtListeners.splice(i, 1); if(evtListeners.length === 0) { delete this.eventListeners[type]; diff --git a/src/plugins/Label.js b/src/plugins/Label.js index 4278925f..0cb52404 100644 --- a/src/plugins/Label.js +++ b/src/plugins/Label.js @@ -61,7 +61,7 @@ this.className = LABEL; Kinetic.Group.call(this, config); - this.on('add', function(evt) { + this.on('add.kinetic', function(evt) { that._addListeners(evt.child); that._sync(); }); diff --git a/src/plugins/Path.js b/src/plugins/Path.js index 37652eee..fc80a822 100644 --- a/src/plugins/Path.js +++ b/src/plugins/Path.js @@ -32,7 +32,7 @@ this.className = 'Path'; this.dataArray = Kinetic.Path.parsePathData(this.getData()); - this.on('dataChange', function() { + this.on('dataChange.kinetic', function() { that.dataArray = Kinetic.Path.parsePathData(this.getData()); }); }, diff --git a/src/plugins/TextPath.js b/src/plugins/TextPath.js index 61e9c0e6..65fdf142 100644 --- a/src/plugins/TextPath.js +++ b/src/plugins/TextPath.js @@ -56,15 +56,12 @@ this.className = 'TextPath'; this.dataArray = Kinetic.Path.parsePathData(this.attrs.data); - this.on('dataChange', function() { + this.on('dataChange.kinetic', function() { that.dataArray = Kinetic.Path.parsePathData(this.attrs.data); }); + // update text data for certain attr changes - var attrs = ['text', 'textStroke', 'textStrokeWidth']; - for(var n = 0; n < attrs.length; n++) { - var attr = attrs[n]; - this.on(attr + 'Change', that._setTextData); - } + this.on('textChange.kinetic textStroke.kinetic textStrokeWidth.kinetic', that._setTextData); that._setTextData(); }, drawFunc: function(canvas) { diff --git a/src/shapes/Blob.js b/src/shapes/Blob.js index cac774f2..5aed5c40 100644 --- a/src/shapes/Blob.js +++ b/src/shapes/Blob.js @@ -31,7 +31,7 @@ Kinetic.Shape.call(this, config); this.className = 'Blob'; - this.on('pointsChange tensionChange', function() { + this.on('pointsChange.kinetic tensionChange.kinetic', function() { that._setAllPoints(); }); diff --git a/src/shapes/Spline.js b/src/shapes/Spline.js index f2ea92d8..3451af6c 100644 --- a/src/shapes/Spline.js +++ b/src/shapes/Spline.js @@ -31,7 +31,7 @@ Kinetic.Shape.call(this, config); this.className = 'Spline'; - this.on('pointsChange tensionChange', function() { + this.on('pointsChange.kinetic tensionChange.kinetic', function() { that._setAllPoints(); }); diff --git a/src/shapes/Sprite.js b/src/shapes/Sprite.js index cdae004e..687f449d 100644 --- a/src/shapes/Sprite.js +++ b/src/shapes/Sprite.js @@ -78,7 +78,7 @@ this.anim = new Kinetic.Animation(); var that = this; - this.on('animationChange', function() { + this.on('animationChange.kinetic', function() { // reset index when animation changes that.setIndex(0); }); diff --git a/tests/js/unit/shapes/blobTests.js b/tests/js/unit/shapes/blobTests.js index e486ca43..e8fd37ce 100644 --- a/tests/js/unit/shapes/blobTests.js +++ b/tests/js/unit/shapes/blobTests.js @@ -105,5 +105,57 @@ Test.Modules.BLOB = { test(stage.get('Blob')[0].getPoints().length === 4, 'created blob should have 4 points'); + }, + 'add blobs': function(containerId) { + var stage = new Kinetic.Stage({ + container: containerId, + width: 578, + height: 200 + }); + var layer = new Kinetic.Layer(); + + var blob = new Kinetic.Blob({ + points: [{ + x: 73, + y: 140 + }, { + x: 340, + y: 23 + }, { + x: 500, + y: 109 + }, { + x: 300, + y: 170 + }], + stroke: 'blue', + strokeWidth: 10, + draggable: true, + fill: '#aaf', + tension: 0.8 + }); + + layer.add(blob); + + stage.add(layer); + + test(blob.eventListeners.pointsChange[0].name === 'kinetic', 'blob should have kinetic specific pointsChange event handler'); + test(blob.eventListeners.tensionChange[0].name === 'kinetic', 'blob should have kinetic specific tensionChange event handler'); + + // removing handlers should not remove kinetic specific handlers + blob.off('pointsChange'); + blob.off('tensionChange'); + + test(blob.eventListeners.pointsChange[0].name === 'kinetic', 'blob should have kinetic specific pointsChange event handler'); + test(blob.eventListeners.tensionChange[0].name === 'kinetic', 'blob should have kinetic specific tensionChange event handler'); + + // you can force remove an event by adding the name + blob.off('pointsChange.kinetic'); + blob.off('tensionChange.kinetic'); + + test(!blob.eventListeners.pointsChange, 'blob should have no pointsChange handlers'); + test(!blob.eventListeners.tensionChange, 'blob should have no tensionChange handlers'); + + } };