diff --git a/src/lib/doesNodeContainClick.js b/src/lib/doesNodeContainClick.js index fda38348c8..d1ae271216 100644 --- a/src/lib/doesNodeContainClick.js +++ b/src/lib/doesNodeContainClick.js @@ -12,8 +12,19 @@ import _ from 'lodash' const doesNodeContainClick = (node, e) => { if (_.some([e, node], _.isNil)) return false - // first check if the node contains the e.target, simplest use case - if (node.contains(e.target)) return true + // if there is an e.target and it is in the document, use a simple node.contains() check + if (e.target) { + _.invoke(e.target, 'setAttribute', 'data-suir-click-target', true) + + if (document.querySelector('[data-suir-click-target=true]')) { + _.invoke(e.target, 'removeAttribute', 'data-suir-click-target') + return node.contains(e.target) + } + } + + // Below logic handles cases where the e.target is no longer in the document. + // The result of the click likely has removed the e.target node. + // Instead of node.contains(), we'll identify the click by X/Y position. // return early if the event properties aren't available // prevent measuring the node and repainting if we don't need to diff --git a/test/specs/lib/doesNodeContainClick-test.js b/test/specs/lib/doesNodeContainClick-test.js index a4c81bb6de..8435624500 100644 --- a/test/specs/lib/doesNodeContainClick-test.js +++ b/test/specs/lib/doesNodeContainClick-test.js @@ -26,6 +26,35 @@ describe('doesNodeContainClick', () => { }) }) + describe('e.target', () => { + it('returns node.contains(e.target) if exists', () => { + const node = makeNode() + const target = document.createElement('div') + document.body.appendChild(target) + const event = makeEvent({ target }) + + node.contains.should.not.have.been.called() + + doesNodeContainClick(node, event) + + node.contains.should.have.been.calledOnce() + node.contains.should.have.been.calledWithExactly(event.target) + document.body.removeChild(target) + }) + + it("does not call node.contains(e.target) if doesn't exist", () => { + const node = makeNode() + const target = null + const event = makeEvent({ target }) + + node.contains.should.not.have.been.called() + + doesNodeContainClick(node, event) + + node.contains.should.not.have.been.called() + }) + }) + describe('nil event properties', () => { it('returns false if the e.clientX is nil', () => { doesNodeContainClick(makeNode(), { clientX: null }).should.equal(false) diff --git a/test/specs/modules/Dimmer/Dimmer-test.js b/test/specs/modules/Dimmer/Dimmer-test.js index 3325e8c104..851aa92f7b 100644 --- a/test/specs/modules/Dimmer/Dimmer-test.js +++ b/test/specs/modules/Dimmer/Dimmer-test.js @@ -40,7 +40,9 @@ describe('Dimmer', () => { it('omitted when click on children', () => { const spy = sandbox.spy() - const wrapper = mount(
{faker.hacker.phrase()}
) + const wrapper = mount(
{faker.hacker.phrase()}
, { + attachTo: document.body, + }) wrapper.find('div.center').childAt(0).simulate('click') spy.should.have.been.callCount(0)