ericdrowell/KineticJS — pull request #626 by kzhdev (2013-10-04 19:31:11+00:00)
Title: Don't use cached event listener length in node._fire because changing shape attribute could remove kinetic event handler from the array which will cause 'hander of undefined' error

Steps to reproduce the issue:

var rect = new Kinetic.Rect({
x: 100,
y: 150,
width: 100,
height: 100,
stroke: 'red',
strokeWidth: 1
});
rect.on('mousedown', function(e) {
var node = e.targetNode;
node.setDraggable(false);
});
rect.on('mouseup', function(e) {
var node = e.targetNode;
node.setDraggable(true);
});
layer.add(rect);
layer.draw();

open browser's debugger tool (I'm using chrome) and run above code. It works fine the first time clicked on the rectangle. The second time clicked on the rectangle, 'Uncaught TypeError: Cannot read property 'handler' of undefined' occurred.

'mousedown.kinetic' handler will be removed when calling node.setDraggable(false) in the mousedown event. When clicked on the rectangle the first time, it worked because the 'mousedown.kinetic' handler was the first handler. When clicked on the rectangle again, the 'mousedown.kinetic' handler was behind the rectangle's mousedown handler (it was added back to the event listeners array in mouseup event). After executing the rectangles's mousedown handler, the for loop threw exception because it tried to use the dangling event handler.