From 809985087e670e0f91358703f28e9727489a2f95 Mon Sep 17 00:00:00 2001 From: Meiko Udras Date: Thu, 1 Oct 2015 13:16:18 +0300 Subject: [PATCH 1/4] Add compatibility with IE (Still needed for IE11) http://stackoverflow.com/questions/16618785/ie8-alternative-to-window-scrolly --- modules/menu-container.js | 6 +++--- src/menu-container.js | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/menu-container.js b/modules/menu-container.js index bb9ac92b..73dd3530 100644 --- a/modules/menu-container.js +++ b/modules/menu-container.js @@ -47,8 +47,8 @@ var MenuContainer = _react2["default"].createClass({ getMenuPosition: function getMenuPosition(x, y) { var menu = _react2["default"].findDOMNode(this.refs.menu); var screen = window.screen; - var scrollX = window.scrollX; - var scrollY = window.scrollY; + var scrollX = document.documentElement.scrollTop; + var scrollY = document.documentElement.scrollLeft; var AvailWidth = screen.AvailWidth; var AvailHeight = screen.AvailHeight; var offsetWidth = menu.offsetWidth; @@ -132,4 +132,4 @@ var MenuContainer = _react2["default"].createClass({ }); exports["default"] = MenuContainer; -module.exports = exports["default"]; \ No newline at end of file +module.exports = exports["default"]; diff --git a/src/menu-container.js b/src/menu-container.js index a54bff7f..9d60f2a7 100644 --- a/src/menu-container.js +++ b/src/menu-container.js @@ -35,7 +35,9 @@ const MenuContainer = React.createClass({ }, getMenuPosition(x, y) { let menu = React.findDOMNode(this.refs.menu); - let { screen, scrollX, scrollY } = window, + let scrollX = document.documentElement.scrollTop; + let scrollY = document.documentElement.scrollLeft; + let { screen } = window, { AvailWidth, AvailHeight } = screen, { offsetWidth, offsetHeight } = menu, menuStyles = {}; From a5325c567ee7982b67212277afa0fbb673ce2a73 Mon Sep 17 00:00:00 2001 From: Meiko Udras Date: Mon, 5 Oct 2015 11:04:04 +0300 Subject: [PATCH 2/4] better event handling for contextmenu --- modules/contextmenu-layer.js | 34 +++++++++++++++++++------------- src/contextmenu-layer.js | 38 ++++++++++++++++++++---------------- 2 files changed, 41 insertions(+), 31 deletions(-) diff --git a/modules/contextmenu-layer.js b/modules/contextmenu-layer.js index c6c10bb7..d943a57e 100644 --- a/modules/contextmenu-layer.js +++ b/modules/contextmenu-layer.js @@ -33,14 +33,18 @@ exports["default"] = function (identifier, configure) { (0, _invariant2["default"])(typeof configure === "function", "Expected configure to be a function. See %s", displayName); return _react2["default"].createClass({ - displayName: displayName + "ContextMenuLayer", - componentDidMount: function componentDidMount() { - _react2["default"].findDOMNode(this).addEventListener("contextmenu", this.handleContextClick); - }, - componentWillUnmount: function componentWillUnmount() { - _react2["default"].findDOMNode(this).removeEventListener("contextmenu", this.handleContextClick); - }, - handleContextClick: function handleContextClick(event) { + displayName: displayName + "ContextMenuLayer", + componentDidMount: function componentDidMount() { + document.addEventListener("contextmenu", this.handleContextClick); + }, + componentWillUnmount: function componentWillUnmount() { + document.addEventListener("contextmenu", this.handleContextClick); + }, + handleContextClick: function handleContextClick(event) { + var target = event.target; + var domNode = _react2["default"].findDOMNode(this); + + if(target == domNode || domNode.contains(target)) { var currentItem = configure(this.props); (0, _invariant2["default"])((0, _lodashIsobject2["default"])(currentItem), "Expected configure to return an object. See %s", displayName); @@ -53,12 +57,14 @@ exports["default"] = function (identifier, configure) { currentItem: currentItem, isVisible: typeof identifier === "function" ? identifier(this.props) : identifier }); - }, - render: function render() { - return _react2["default"].createElement(Component, _extends({}, this.props, { identifier: identifier })); - } - }); + } + + }, + render: function render() { + return _react2["default"].createElement(Component, _extends({}, this.props, { identifier: identifier })); + } + }); }; }; -module.exports = exports["default"]; \ No newline at end of file +module.exports = exports["default"]; diff --git a/src/contextmenu-layer.js b/src/contextmenu-layer.js index 451ec16c..84e655e1 100644 --- a/src/contextmenu-layer.js +++ b/src/contextmenu-layer.js @@ -28,30 +28,34 @@ export default function (identifier, configure) { return React.createClass({ displayName: `${displayName}ContextMenuLayer`, componentDidMount() { - React.findDOMNode(this) + document .addEventListener("contextmenu", this.handleContextClick); }, componentWillUnmount() { - React.findDOMNode(this) + document .removeEventListener("contextmenu", this.handleContextClick); }, handleContextClick(event) { - let currentItem = configure(this.props); + let target = event.target; + let domNode = React.findDOMNode(this); + if(target == domNode || domNode.contains(target)) { + let currentItem = configure(this.props); + + invariant( + _isObject(currentItem), + "Expected configure to return an object. See %s", + displayName + ); - invariant( - _isObject(currentItem), - "Expected configure to return an object. See %s", - displayName - ); - - event.preventDefault(); - const actions = flux.getActions("menu"); - actions.setParams({ - x: event.clientX, - y: event.clientY, - currentItem, - isVisible: typeof identifier === "function" ? identifier(this.props) : identifier - }); + event.preventDefault(); + const actions = flux.getActions("menu"); + actions.setParams({ + x: event.clientX, + y: event.clientY, + currentItem, + isVisible: typeof identifier === "function" ? identifier(this.props) : identifier + }); + } }, render() { return ( From 4be296d9c6640b147ae122d20e5ebff2c00d3c16 Mon Sep 17 00:00:00 2001 From: Meiko Udras Date: Mon, 5 Oct 2015 11:48:40 +0300 Subject: [PATCH 3/4] Only hide the currently visible context menu. This fixes a bug on touch screens where the menu closes before the event to click is triggered. This only happens when using multiple contex menus. --- modules/menu-container.js | 27 ++++++++++++++++----------- src/menu-container.js | 21 ++++++++++++--------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/modules/menu-container.js b/modules/menu-container.js index 73dd3530..2129131b 100644 --- a/modules/menu-container.js +++ b/modules/menu-container.js @@ -70,21 +70,26 @@ var MenuContainer = _react2["default"].createClass({ return menuStyles; }, _outsideClickHandler: function _outsideClickHandler(event) { - var localNode = this.localNode, - source = event.target, - found = false; + var _props = this.props; + var isVisible = _props.isVisible; + var identifier = _props.identifier; + if(isVisible === identifier) { + var localNode = this.localNode, + source = event.target, + found = false; - while (source.parentNode) { - found = source === localNode; + while (source.parentNode) { + found = source === localNode; - if (found) { - return; - } + if (found) { + return; + } - source = source.parentNode; - } + source = source.parentNode; + } - this._hideMenu(); + this._hideMenu(); + } }, _hideMenu: function _hideMenu() { this.props.flux.getActions("menu").setParams({ diff --git a/src/menu-container.js b/src/menu-container.js index 9d60f2a7..b5e322d3 100644 --- a/src/menu-container.js +++ b/src/menu-container.js @@ -57,19 +57,22 @@ const MenuContainer = React.createClass({ return menuStyles; }, _outsideClickHandler(event) { - let localNode = this.localNode, - source = event.target, - found = false; + let { isVisible, identifier } = this.props; + if(isVisible === identifier) { + let localNode = this.localNode, + source = event.target, + found = false; - while (source.parentNode) { - found = (source === localNode); + while (source.parentNode) { + found = (source === localNode); - if (found) { return; } + if (found) { return; } - source = source.parentNode; - } + source = source.parentNode; + } - this._hideMenu(); + this._hideMenu(); + } }, _hideMenu() { this.props.flux.getActions("menu").setParams({ From 0ad6fcc44efcab9434b655e3fd1080162f99ef69 Mon Sep 17 00:00:00 2001 From: Meiko Udras Date: Mon, 5 Oct 2015 11:51:55 +0300 Subject: [PATCH 4/4] Remove event listener when unmounting --- modules/contextmenu-layer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/contextmenu-layer.js b/modules/contextmenu-layer.js index d943a57e..cd0af0b1 100644 --- a/modules/contextmenu-layer.js +++ b/modules/contextmenu-layer.js @@ -38,7 +38,7 @@ exports["default"] = function (identifier, configure) { document.addEventListener("contextmenu", this.handleContextClick); }, componentWillUnmount: function componentWillUnmount() { - document.addEventListener("contextmenu", this.handleContextClick); + document.removeEventListener("contextmenu", this.handleContextClick); }, handleContextClick: function handleContextClick(event) { var target = event.target;