From d8ee73f208f3c48a2c37ec0e1b6170e43fc53e48 Mon Sep 17 00:00:00 2001 From: Alexander Gugel Date: Wed, 3 Jun 2015 17:35:31 +0200 Subject: [PATCH] fix: No longer stopPropagation on events --- dom-renderers/DOMRenderer.js | 6 +++- dom-renderers/test/DOMRenderer.js | 60 +++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/dom-renderers/DOMRenderer.js b/dom-renderers/DOMRenderer.js index 8e17af52..15e8181d 100644 --- a/dom-renderers/DOMRenderer.js +++ b/dom-renderers/DOMRenderer.js @@ -86,6 +86,8 @@ function DOMRenderer (element, selector, compositor) { this._VPtransform = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]); this._size = [null, null]; + + this._lastEv = null; } @@ -132,6 +134,8 @@ DOMRenderer.prototype.subscribe = function subscribe(type, preventDefault) { * @return {undefined} undefined */ DOMRenderer.prototype._triggerEvent = function _triggerEvent(ev) { + if (this._lastEv === ev) return; + // Use ev.path, which is an array of Elements (polyfilled if needed). var evPath = ev.path ? ev.path : _getPath(ev); // First element in the path is the element on which the event has actually @@ -146,7 +150,7 @@ DOMRenderer.prototype._triggerEvent = function _triggerEvent(ev) { // Stop further event propogation and path traversal as soon as the // first ElementCache subscribing for the emitted event has been found. if (this._elements[path] && this._elements[path].subscribe[ev.type]) { - ev.stopPropagation(); + this._lastEv = ev; // Optionally preventDefault. This needs forther consideration and // should be optional. Eventually this should be a separate command/ diff --git a/dom-renderers/test/DOMRenderer.js b/dom-renderers/test/DOMRenderer.js index 2c083fb5..ca1b7ee7 100644 --- a/dom-renderers/test/DOMRenderer.js +++ b/dom-renderers/test/DOMRenderer.js @@ -266,4 +266,64 @@ test('DOMRenderer', function(t) { t.end(); }); + + t.test('_triggerEvent method', function(t) { + var element = document.createElement('div'); + var selector = 'selector'; + var sentEvents = []; + + var compositor = { + sendEvent: function (path, ev, payload) { + sentEvents.push([path, ev, payload]); + } + }; + + var domRenderer = new DOMRenderer(element, selector, compositor); + + domRenderer.loadPath(selector + '/' + 0); + domRenderer.findTarget(); + domRenderer.insertEl('div'); + + domRenderer.loadPath(selector + '/' + 0 + '/' + 1); + domRenderer.findTarget(); + domRenderer.insertEl('div'); + + domRenderer.subscribe('click'); + + domRenderer.loadPath(selector + '/' + 0 + '/' + 1 + '/' + 0); + domRenderer.findTarget(); + domRenderer.insertEl('div'); + + domRenderer.subscribe('click'); + + var ev1 = { + type: 'click', + target: {}, + path: [ + { dataset: { faPath: selector + '/' + 0 + '/' + 1 + '/' + 0 } }, + { dataset: { faPath: selector + '/' + 0 + '/' + 1 } }, + { dataset: { faPath: selector + '/' + 0 } } + ], + stopPropagation: function() { + t.fail('domRenderer._triggerEvent should not stopPropagation of DOM event'); + } + }; + + domRenderer._triggerEvent(ev1); + + t.deepEqual( + sentEvents[0].slice(0, 2), + [ selector + '/' + 0 + '/' + 1 + '/' + 0, ev1.type ], + 'domRenderer._triggerEvent should emit correct event on leaf node' + ); + + sentEvents.length = 0; + + domRenderer._triggerEvent(ev1); + + t.equal(sentEvents.length, 0, 'domRenderer._triggerEvent should not emit same event multiple times in a row'); + + t.end(); + }); + });