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

This commit is contained in:
Eric Rowell
2013-07-24 22:56:21 -07:00
parent 7a1b854a12
commit 57a9313a7b
8 changed files with 88 additions and 39 deletions

View File

@@ -49,7 +49,7 @@
* event by name such as 'click.foobar'. * event by name such as 'click.foobar'.
* @method * @method
* @memberof Kinetic.Node.prototype * @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 * @param {Function} handler The handler function is passed an event object
* @example * @example
* // add click listener<br> * // add click listener<br>
@@ -77,10 +77,10 @@
* console.log('you clicked/touched me!');<br> * console.log('you clicked/touched me!');<br>
* }); * });
*/ */
on: function(typesStr, handler) { on: function(evtStr, handler) {
var types = typesStr.split(SPACE), var events = evtStr.split(SPACE),
len = types.length, len = events.length,
n, type, event, parts, baseEvent, name; n, event, parts, baseEvent, name;
/* /*
* loop through types and attach event listeners to * loop through types and attach event listeners to
@@ -88,12 +88,12 @@
* will create three event bindings * will create three event bindings
*/ */
for(n = 0; n < len; n++) { for(n = 0; n < len; n++) {
type = types[n]; event = events[n];
event = type;
parts = event.split(DOT); parts = event.split(DOT);
baseEvent = parts[0]; 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]) { if(!this.eventListeners[baseEvent]) {
this.eventListeners[baseEvent] = []; this.eventListeners[baseEvent] = [];
} }
@@ -114,7 +114,7 @@
* all events in that namespace will be removed. * all events in that namespace will be removed.
* @method * @method
* @memberof Kinetic.Node.prototype * @memberof Kinetic.Node.prototype
* @param {String} typesStr e.g. 'click', 'mousedown touchstart', '.foobar' * @param {String} evtStr e.g. 'click', 'mousedown touchstart', '.foobar'
* @example * @example
* // remove listener<br> * // remove listener<br>
* node.off('click');<br><br> * node.off('click');<br><br>
@@ -125,31 +125,26 @@
* // remove listener by name<br> * // remove listener by name<br>
* node.off('click.foo'); * node.off('click.foo');
*/ */
off: function(typesStr) { off: function(evtStr) {
var types = typesStr.split(SPACE), var events = evtStr.split(SPACE),
len = types.length, len = events.length,
n, type, t, event, parts, baseEvent; n, i, event, parts, baseEvent, name;
for(n = 0; n < len; n++) { for(n = 0; n < len; n++) {
type = types[n]; event = events[n];
event = type;
parts = event.split(DOT); parts = event.split(DOT);
baseEvent = parts[0]; baseEvent = parts[0];
name = parts[1];
if(parts.length > 1) { if(baseEvent) {
if(baseEvent) { if(this.eventListeners[baseEvent]) {
if(this.eventListeners[baseEvent]) { this._off(baseEvent, name);
this._off(baseEvent, parts[1]);
}
}
else {
for(t in this.eventListeners) {
this._off(t, parts[1]);
}
} }
} }
else { else {
delete this.eventListeners[baseEvent]; for(t in this.eventListeners) {
this._off(t, name);
}
} }
} }
return this; return this;
@@ -964,10 +959,15 @@
}, },
_off: function(type, name) { _off: function(type, name) {
var evtListeners = this.eventListeners[type], var evtListeners = this.eventListeners[type],
i; i, evtName;
for(i = 0; i < evtListeners.length; i++) { 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); evtListeners.splice(i, 1);
if(evtListeners.length === 0) { if(evtListeners.length === 0) {
delete this.eventListeners[type]; delete this.eventListeners[type];

View File

@@ -61,7 +61,7 @@
this.className = LABEL; this.className = LABEL;
Kinetic.Group.call(this, config); Kinetic.Group.call(this, config);
this.on('add', function(evt) { this.on('add.kinetic', function(evt) {
that._addListeners(evt.child); that._addListeners(evt.child);
that._sync(); that._sync();
}); });

View File

@@ -32,7 +32,7 @@
this.className = 'Path'; this.className = 'Path';
this.dataArray = Kinetic.Path.parsePathData(this.getData()); this.dataArray = Kinetic.Path.parsePathData(this.getData());
this.on('dataChange', function() { this.on('dataChange.kinetic', function() {
that.dataArray = Kinetic.Path.parsePathData(this.getData()); that.dataArray = Kinetic.Path.parsePathData(this.getData());
}); });
}, },

View File

@@ -56,15 +56,12 @@
this.className = 'TextPath'; this.className = 'TextPath';
this.dataArray = Kinetic.Path.parsePathData(this.attrs.data); 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); that.dataArray = Kinetic.Path.parsePathData(this.attrs.data);
}); });
// update text data for certain attr changes // update text data for certain attr changes
var attrs = ['text', 'textStroke', 'textStrokeWidth']; this.on('textChange.kinetic textStroke.kinetic textStrokeWidth.kinetic', that._setTextData);
for(var n = 0; n < attrs.length; n++) {
var attr = attrs[n];
this.on(attr + 'Change', that._setTextData);
}
that._setTextData(); that._setTextData();
}, },
drawFunc: function(canvas) { drawFunc: function(canvas) {

View File

@@ -31,7 +31,7 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this.className = 'Blob'; this.className = 'Blob';
this.on('pointsChange tensionChange', function() { this.on('pointsChange.kinetic tensionChange.kinetic', function() {
that._setAllPoints(); that._setAllPoints();
}); });

View File

@@ -31,7 +31,7 @@
Kinetic.Shape.call(this, config); Kinetic.Shape.call(this, config);
this.className = 'Spline'; this.className = 'Spline';
this.on('pointsChange tensionChange', function() { this.on('pointsChange.kinetic tensionChange.kinetic', function() {
that._setAllPoints(); that._setAllPoints();
}); });

View File

@@ -78,7 +78,7 @@
this.anim = new Kinetic.Animation(); this.anim = new Kinetic.Animation();
var that = this; var that = this;
this.on('animationChange', function() { this.on('animationChange.kinetic', function() {
// reset index when animation changes // reset index when animation changes
that.setIndex(0); that.setIndex(0);
}); });

View File

@@ -105,5 +105,57 @@ Test.Modules.BLOB = {
test(stage.get('Blob')[0].getPoints().length === 4, 'created blob should have 4 points'); 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');
} }
}; };