Skip to content

Commit

Permalink
fix(doesNodeContainClick): only use x/y if !e.target (Semantic-Org#2494)
Browse files Browse the repository at this point in the history
  • Loading branch information
levithomason authored and Brandon Lawrence committed Mar 14, 2018
1 parent 947767c commit 4598a93
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
15 changes: 13 additions & 2 deletions src/lib/doesNodeContainClick.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions test/specs/lib/doesNodeContainClick-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
4 changes: 3 additions & 1 deletion test/specs/modules/Dimmer/Dimmer-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ describe('Dimmer', () => {

it('omitted when click on children', () => {
const spy = sandbox.spy()
const wrapper = mount(<Dimmer onClickOutside={spy}><div>{faker.hacker.phrase()}</div></Dimmer>)
const wrapper = mount(<Dimmer onClickOutside={spy}><div>{faker.hacker.phrase()}</div></Dimmer>, {
attachTo: document.body,
})

wrapper.find('div.center').childAt(0).simulate('click')
spy.should.have.been.callCount(0)
Expand Down

0 comments on commit 4598a93

Please sign in to comment.