From a389fbc6f0f3b90cccb7282ef6e88941b84b8d2a Mon Sep 17 00:00:00 2001 From: ericdrowell Date: Fri, 20 Sep 2013 16:45:59 -0700 Subject: [PATCH] implemented stage content mobile events and added functional tests --- src/Stage.js | 50 +++++++++++------ test/functional/Events-test.js | 98 ++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+), 17 deletions(-) diff --git a/src/Stage.js b/src/Stage.js index a55eef74..fab93490 100644 --- a/src/Stage.js +++ b/src/Stage.js @@ -405,9 +405,12 @@ this.targetShape._fireAndBubble(MOUSELEAVE, evt); this.targetShape = null; } - this._fire(CONTENT_MOUSEMOVE, evt); + } + // content event + this._fire(CONTENT_MOUSEMOVE, evt); + if(dd) { dd._drag(evt); } @@ -430,6 +433,7 @@ shape._fireAndBubble(MOUSEDOWN, evt); } + // content event this._fire(CONTENT_MOUSEDOWN); // always call preventDefault for desktop events because some browsers @@ -469,6 +473,7 @@ } } } + // content events this._fire(CONTENT_MOUSEUP); if (Kinetic.listenClickTap) { this._fire(CONTENT_CLICK, evt); @@ -495,12 +500,14 @@ if (shape) { this.tapStartShape = shape; shape._fireAndBubble(TOUCHSTART, evt); - } - // only call preventDefault if the shape is listening for events - if (shape.isListening() && evt.preventDefault) { - evt.preventDefault(); + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } } + // content event + this._fire(CONTENT_TOUCHSTART, evt); }, _touchend: function(evt) { this._setPointerPosition(evt); @@ -532,32 +539,41 @@ shape._fireAndBubble(DBL_TAP, evt); } } + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + // content events + if (Kinetic.listenClickTap) { + this._fire(CONTENT_TOUCHEND, evt); + if(fireDblClick) { + this._fire(CONTENT_DBL_TAP, evt); + } } Kinetic.listenClickTap = false; - - // only call preventDefault if the shape is listening for events - if (shape.isListening() && evt.preventDefault) { - evt.preventDefault(); - } }, _touchmove: function(evt) { this._setPointerPosition(evt); var dd = Kinetic.DD, obj = this.getIntersection(this.getPointerPosition()), - shape = obj && obj.shape ? obj.shape : this; + shape = obj && obj.shape ? obj.shape : undefined; - shape._fireAndBubble(TOUCHMOVE, evt); + if (shape) { + shape._fireAndBubble(TOUCHMOVE, evt); + + // only call preventDefault if the shape is listening for events + if (shape.isListening() && evt.preventDefault) { + evt.preventDefault(); + } + } + this._fire(CONTENT_TOUCHMOVE, evt); // start drag and drop if(dd) { dd._drag(evt); } - - // only call preventDefault if the shape is listening for events - if (shape.isListening() && evt.preventDefault) { - evt.preventDefault(); - } }, _setMousePosition: function(evt) { diff --git a/test/functional/Events-test.js b/test/functional/Events-test.js index a6b18229..fed7b2ae 100644 --- a/test/functional/Events-test.js +++ b/test/functional/Events-test.js @@ -130,4 +130,102 @@ suite('Events', function() { assert.equal(stageContentMouseover, 1); }); + + test('stage content touch events', function() { + var stage = addStage(); + var layer = new Kinetic.Layer(); + var circle = new Kinetic.Circle({ + x: 100, + y: 100, + radius: 70, + fill: 'green', + stroke: 'black', + strokeWidth: 4, + name: 'myCircle' + }); + + layer.add(circle); + stage.add(layer); + + var circleTouchstart = + circleTouchend = + stageContentTouchstart = + stageContentTouchend = + stageContentTouchmove = + stageContentTap = + stageContentDbltap = + 0; + + var top = stage.content.getBoundingClientRect().top; + + + circle.on('touchstart', function() { + circleTouchstart++; + }); + + circle.on('touchend', function() { + circleTouchend++; + }); + + stage.on('contentTouchstart', function() { + stageContentTouchstart++; + }); + + stage.on('contentTouchend', function() { + stageContentTouchend++; + }); + + stage.on('contentTouchmove', function() { + stageContentTouchmove++; + }); + + stage.on('contentTap', function() { + stageContentTap++; + }); + + stage.on('contentDbltap', function() { + stageContentDbltap++; + }); + + stage._touchstart({ + clientX: 100, + clientY: 100 + top + }); + + stage._touchend({ + clientX: 100, + clientY: 100 + top + }); + + assert.equal(circleTouchstart, 1, 1); + assert.equal(circleTouchend, 1, 2); + assert.equal(stageContentTouchstart, 1, 3); + assert.equal(stageContentTouchend, 1, 4); + assert.equal(stageContentDbltap, 1, 5); + + stage._touchstart({ + clientX: 1, + clientY: 1 + top + }); + stage._touchend({ + clientX: 1, + clientY: 1 + top + }); + + assert.equal(stageContentTouchstart, 2, 6); + assert.equal(stageContentTouchend, 2, 6); + + // trigger double tap + stage._touchstart({ + clientX: 1, + clientY: 1 + top + }); + stage._touchend({ + clientX: 1, + clientY: 1 + top + }); + + assert.equal(stageContentTouchstart, 3, 8); + assert.equal(stageContentTouchend, 3, 9); + }); }); \ No newline at end of file