From 5226e2d6d0a7abc91d41bea9e922f5f7cb9acc48 Mon Sep 17 00:00:00 2001 From: Ryan Seddon Date: Mon, 10 Sep 2018 16:28:54 +1000 Subject: [PATCH] fix(menus): Change handleOutsideMouseDown to handle when clicking on iframes --- .../menus/src/containers/MenuContainer.js | 38 ++++++++++++++----- .../src/containers/MenuContainer.spec.js | 4 +- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/menus/src/containers/MenuContainer.js b/packages/menus/src/containers/MenuContainer.js index 8ba3f721d3c..d849bcfd83e 100644 --- a/packages/menus/src/containers/MenuContainer.js +++ b/packages/menus/src/containers/MenuContainer.js @@ -151,15 +151,15 @@ class MenuContainer extends ControlledComponent { } componentDidMount() { - const doc = getDocument ? getDocument(this.props) : document; - - doc.addEventListener('mousedown', this.handleOutsideMouseDown); + this.getDocuments().forEach(doc => { + doc.addEventListener('mousedown', this.handleOutsideMouseDown); + }); } componentWillUnmount() { - const doc = getDocument ? getDocument(this.props) : document; - - doc.removeEventListener('mousedown', this.handleOutsideMouseDown); + this.getDocuments().forEach(doc => { + doc.removeEventListener('mousedown', this.handleOutsideMouseDown); + }); } componentDidUpdate(prevProps, prevState) { @@ -195,18 +195,38 @@ class MenuContainer extends ControlledComponent { } } + getDocuments = () => { + const doc = getDocument ? getDocument(this.props) : document; + const iframes = doc.querySelectorAll('iframe'); + + return [...iframes].reduce( + (documents, iframe) => { + try { + if (iframe.contentDocument) { + return [...documents, iframe.contentDocument]; + } + } catch (e) {} // eslint-disable-line no-empty + + return documents; + }, + [doc] + ); + }; + /** * Used to know when a Menu is blured by mouse */ handleOutsideMouseDown = event => { const { isOpen } = this.getControlledState(); + const { target, which } = event; + const isLeftClick = which === 1; - if (!isOpen) { + if (!isOpen || !isLeftClick) { return; } - if (this.menuReference && !this.menuReference.contains(event.target)) { - if (this.triggerReference && !this.triggerReference.contains(event.target)) { + if (this.menuReference && !this.menuReference.contains(target)) { + if (this.triggerReference && !this.triggerReference.contains(target)) { this.toggleMenuVisibility({ closedByBlur: true }); } } diff --git a/packages/menus/src/containers/MenuContainer.spec.js b/packages/menus/src/containers/MenuContainer.spec.js index bd9dd3131de..b5d4a63827c 100644 --- a/packages/menus/src/containers/MenuContainer.spec.js +++ b/packages/menus/src/containers/MenuContainer.spec.js @@ -237,7 +237,7 @@ describe('MenuContainer', () => { }); }); - it('closes menu if blured by click', () => { + it('closes menu if blurred by click', () => { /** * Enzyme doesn't attach mount/shallow wrapper to the document by default. * This allows us to test the blur events correctly. @@ -247,7 +247,7 @@ describe('MenuContainer', () => { }); findTrigger(wrapper).simulate('click'); jest.runOnlyPendingTimers(); - document.dispatchEvent(new Event('mousedown')); + document.dispatchEvent(new MouseEvent('mousedown', { which: 1 })); wrapper.update(); expect(findMenu(wrapper)).not.toExist();