From e914ffecf8fa2c96c8ec0233f67475ee404f77e1 Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Thu, 27 Nov 2014 13:16:42 +0100 Subject: [PATCH 1/3] Can bind events to ShadowRoots. --- src/browser/ui/ReactDOMComponent.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js index 0a6f60e14acb..8532e50837e4 100644 --- a/src/browser/ui/ReactDOMComponent.js +++ b/src/browser/ui/ReactDOMComponent.js @@ -15,6 +15,7 @@ var CSSPropertyOperations = require('CSSPropertyOperations'); var DOMProperty = require('DOMProperty'); var DOMPropertyOperations = require('DOMPropertyOperations'); +var ExecutionEnvironment = require('ExecutionEnvironment'); var ReactComponent = require('ReactComponent'); var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); var ReactMount = require('ReactMount'); @@ -74,6 +75,25 @@ function assertValidProps(props) { ); } +var ShadowRoot = ExecutionEnvironment.canUseDOM ? window.ShadowRoot : false; + +/** + * @param {object} node + */ +var realContainer = !!ShadowRoot ? + function(node) { // if browser supports shadow DOM + if (node instanceof ShadowRoot || !node.parentNode) { + return node; + } + return realContainer(node.parentNode); // tries to go up in the shadow DOM tree to get the root + } : + function(node) { + if (!node.parentNode) { + return node; + } + return realContainer(node.parentNode); + }; + function putListener(id, registrationName, listener, transaction) { if (__DEV__) { // IE8 has no API for event capturing and the `onScroll` event doesn't From fe5c2afccbed476b4c376d6fabbedc4451bcbd6f Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Thu, 27 Nov 2014 13:20:30 +0100 Subject: [PATCH 2/3] Call realContainer to bind the events. Otherwise they're still bound to the document and not the shadowroot. --- src/browser/ui/ReactDOMComponent.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js index 8532e50837e4..b97b8973308b 100644 --- a/src/browser/ui/ReactDOMComponent.js +++ b/src/browser/ui/ReactDOMComponent.js @@ -107,7 +107,7 @@ function putListener(id, registrationName, listener, transaction) { var container = ReactMount.findReactContainerForID(id); if (container) { var doc = container.nodeType === ELEMENT_NODE_TYPE ? - container.ownerDocument : + realContainer(container) : container; listenTo(registrationName, doc); } From 2db502a50e3f273b5f6573a2303d21b21c69656c Mon Sep 17 00:00:00 2001 From: Nicolas Brugneaux Date: Tue, 2 Dec 2014 00:11:16 +0100 Subject: [PATCH 3/3] Look for the root in an iterative way. Uses a while loop instead of recursivly calling `parentNode`. Reuses node.ownerDocument when shadowRoot isn't supported. --- src/browser/ui/ReactDOMComponent.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/browser/ui/ReactDOMComponent.js b/src/browser/ui/ReactDOMComponent.js index b97b8973308b..c32bd517d05d 100644 --- a/src/browser/ui/ReactDOMComponent.js +++ b/src/browser/ui/ReactDOMComponent.js @@ -82,16 +82,16 @@ var ShadowRoot = ExecutionEnvironment.canUseDOM ? window.ShadowRoot : false; */ var realContainer = !!ShadowRoot ? function(node) { // if browser supports shadow DOM - if (node instanceof ShadowRoot || !node.parentNode) { - return node; + var _node = node; + // iterates until we find the shadow root or until the parent is reached + while (!(_node instanceof ShadowRoot) && _node.parentNode) + { + _node = node.parentNode; } - return realContainer(node.parentNode); // tries to go up in the shadow DOM tree to get the root + return _node; } : function(node) { - if (!node.parentNode) { - return node; - } - return realContainer(node.parentNode); + return node.ownerDocument; }; function putListener(id, registrationName, listener, transaction) {