Skip to content

Commit

Permalink
Use more resiliant shadowroot checking
Browse files Browse the repository at this point in the history
Fixes #1574 [0.9] Gesture event throws exception when dragged outside document

Move targetfinding to Gestures object for testing
Add tests
  • Loading branch information
dfreedm committed May 20, 2015
1 parent a43eb0f commit ee7c628
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 14 deletions.
30 changes: 16 additions & 14 deletions src/standard/gestures.html
Original file line number Diff line number Diff line change
Expand Up @@ -97,24 +97,26 @@
return ta;
}

function deepTargetFind(x, y) {
var node = document.elementFromPoint(x, y);
// this code path is only taken when native ShadowDOM is used
var next = node.shadowRoot;
while(next) {
next = next.elementFromPoint(x, y);
if (next) {
node = next;
next = next.shadowRoot;
}
}
return node;
}

var Gestures = {
gestures: {},
recognizers: [],

deepTargetFind: function(x, y) {
var node = document.elementFromPoint(x, y);
var next = node;
// this code path is only taken when native ShadowDOM is used
// if there is a shadowroot, it may have a node at x/y
// if there is not a shadowroot, exit the loop
while (next && next.shadowRoot) {
// if there is a node at x/y in the shadowroot, look deeper
next = next.shadowRoot.elementFromPoint(x, y);
if (next) {
node = next;
}
}
return node;
},
handleNative: function(ev) {
var handled;
var type = ev.type;
Expand Down Expand Up @@ -396,7 +398,7 @@
ddx: ddx,
ddy: ddy,
hover: function() {
return deepTargetFind(touch.clientX, touch.clientY);
return Gestures.deepTargetFind(touch.clientX, touch.clientY);
}
});
}
Expand Down
51 changes: 51 additions & 0 deletions test/unit/gestures.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,57 @@
});
});

suite('target finding', function() {
var div, divLocation;

setup(function() {
div = document.createElement('div');
div.style.cssText = 'height: 50px; width: 50px; background: red;';
div.id = 'target';
document.body.appendChild(div);
divLocation = div.getBoundingClientRect();
});

test('target finding returns null outside the window', function() {
var actual = Polymer.Gestures.deepTargetFind(-1, -1);
assert.equal(actual, null);
})

test('find the div in document', function() {
var x = divLocation.left, y = divLocation.top;
var actual = Polymer.Gestures.deepTargetFind(x, y);
assert.equal(actual, div);
});

test('find the div with a shadowroot', function() {
div.createShadowRoot();
var x = divLocation.left, y = divLocation.top;
var actual = Polymer.Gestures.deepTargetFind(x, y);
assert.equal(actual, div);
});

test('find the div inside a shadowroot', function() {
var divOwner = document.createElement('span');
document.body.appendChild(divOwner);
divOwner.createShadowRoot().appendChild(div);
var bcr = divOwner.getBoundingClientRect();
var x = bcr.left, y = bcr.top;
var actual = Polymer.Gestures.deepTargetFind(x, y);
assert.equal(actual, div);
});

test('find the div with a shadowroot inside a shadowroot', function() {
div.createShadowRoot();
var divOwner = document.createElement('span');
document.body.appendChild(divOwner);
divOwner.createShadowRoot().appendChild(div);
var bcr = divOwner.getBoundingClientRect();
var x = bcr.left, y = bcr.top;
var actual = Polymer.Gestures.deepTargetFind(x, y);
assert.equal(actual, div);
});
});

// TODO(dfreedm): Add more gesture tests!

</script>
Expand Down

0 comments on commit ee7c628

Please sign in to comment.