diff --git a/packages/fbjs/src/__forks__/Style.js b/packages/fbjs/src/__forks__/Style.js index 5374226f..afb22d70 100644 --- a/packages/fbjs/src/__forks__/Style.js +++ b/packages/fbjs/src/__forks__/Style.js @@ -48,7 +48,8 @@ var Style = { if (!node) { return null; } - while (node && node !== document.body) { + var ownerDocument = node.ownerDocument; + while (node && node !== ownerDocument.body) { if (_isNodeScrollable(node, 'overflow') || _isNodeScrollable(node, 'overflowY') || _isNodeScrollable(node, 'overflowX')) { @@ -56,7 +57,7 @@ var Style = { } node = node.parentNode; } - return window; + return ownerDocument.defaultView || ownerDocument.parentWindow; }, }; diff --git a/packages/fbjs/src/__forks__/getUnboundedScrollPosition.js b/packages/fbjs/src/__forks__/getUnboundedScrollPosition.js index 996416cf..98227b0e 100644 --- a/packages/fbjs/src/__forks__/getUnboundedScrollPosition.js +++ b/packages/fbjs/src/__forks__/getUnboundedScrollPosition.js @@ -23,10 +23,10 @@ * @return {object} Map with `x` and `y` keys. */ function getUnboundedScrollPosition(scrollable) { - if (scrollable === window) { + if (scrollable.Window && scrollable instanceof scrollable.Window) { return { - x: window.pageXOffset || document.documentElement.scrollLeft, - y: window.pageYOffset || document.documentElement.scrollTop + x: scrollable.pageXOffset || scrollable.document.documentElement.scrollLeft, + y: scrollable.pageYOffset || scrollable.document.documentElement.scrollTop }; } return { diff --git a/packages/fbjs/src/core/dom/__tests__/getActiveElement-test.js b/packages/fbjs/src/core/dom/__tests__/getActiveElement-test.js index 99b8cc78..8601810f 100644 --- a/packages/fbjs/src/core/dom/__tests__/getActiveElement-test.js +++ b/packages/fbjs/src/core/dom/__tests__/getActiveElement-test.js @@ -19,4 +19,17 @@ describe('getActiveElement', () => { var element = getActiveElement(); expect(element.tagName).toEqual('BODY'); }); + + it('uses optional document parameter when provided', () => { + var iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + var iframeDocument = iframe.contentDocument; + var element = getActiveElement(iframeDocument); + try { + expect(element.ownerDocument).toBe(iframeDocument); + expect(element.ownerDocument).not.toBe(document); + } finally { + document.body.removeChild(iframe); + } + }); }); diff --git a/packages/fbjs/src/core/dom/getActiveElement.js b/packages/fbjs/src/core/dom/getActiveElement.js index 97d56983..c5d404e8 100644 --- a/packages/fbjs/src/core/dom/getActiveElement.js +++ b/packages/fbjs/src/core/dom/getActiveElement.js @@ -18,15 +18,19 @@ * * The activeElement will be null only if the document or document body is not * yet defined. + * + * @param {?DOMDocument} doc Defaults to current document. + * @return {?DOMElement} */ -function getActiveElement() /*?DOMElement*/ { - if (typeof document === 'undefined') { +function getActiveElement(doc) /*?DOMElement*/ { + doc = doc || document; + if (typeof doc === 'undefined') { return null; } try { - return document.activeElement || document.body; + return doc.activeElement || doc.body; } catch (e) { - return document.body; + return doc.body; } } diff --git a/packages/fbjs/src/core/dom/getElementRect.js b/packages/fbjs/src/core/dom/getElementRect.js index a9fec9be..a42071a5 100644 --- a/packages/fbjs/src/core/dom/getElementRect.js +++ b/packages/fbjs/src/core/dom/getElementRect.js @@ -19,7 +19,7 @@ const containsNode = require('containsNode'); * @return {object} */ function getElementRect(elem) { - const docElem = document.documentElement; + const docElem = elem.ownerDocument.documentElement; // FF 2, Safari 3 and Opera 9.5- do not support getBoundingClientRect(). // IE9- will throw if the element is not in the document. diff --git a/packages/fbjs/src/core/dom/getScrollPosition.js b/packages/fbjs/src/core/dom/getScrollPosition.js index 1bd9308f..a3016d38 100644 --- a/packages/fbjs/src/core/dom/getScrollPosition.js +++ b/packages/fbjs/src/core/dom/getScrollPosition.js @@ -28,15 +28,15 @@ const getUnboundedScrollPosition = require('getUnboundedScrollPosition'); * @return {object} Map with `x` and `y` keys. */ function getScrollPosition(scrollable) { - const documentScrollElement = getDocumentScrollElement(); - if (scrollable === window) { + const documentScrollElement = getDocumentScrollElement(scrollable.ownerDocument || scrollable.document); + if (scrollable.Window && scrollable instanceof scrollable.Window) { scrollable = documentScrollElement; } const scrollPosition = getUnboundedScrollPosition(scrollable); const viewport = scrollable === documentScrollElement ? - document.documentElement : + scrollable.ownerDocument.documentElement : scrollable; const xMax = scrollable.scrollWidth - viewport.clientWidth; diff --git a/packages/fbjs/src/core/dom/isNode.js b/packages/fbjs/src/core/dom/isNode.js index 00c94d11..722c87c6 100644 --- a/packages/fbjs/src/core/dom/isNode.js +++ b/packages/fbjs/src/core/dom/isNode.js @@ -15,8 +15,10 @@ * @return {boolean} Whether or not the object is a DOM node. */ function isNode(object) { + var doc = object ? (object.ownerDocument || object) : document; + var defaultView = doc.defaultView || window; return !!(object && ( - typeof Node === 'function' ? object instanceof Node : + typeof defaultView.Node === 'function' ? object instanceof defaultView.Node : typeof object === 'object' && typeof object.nodeType === 'number' && typeof object.nodeName === 'string'