Skip to content

Commit

Permalink
Make DOM utilities work in nested browsing contexts (#188) (#222)
Browse files Browse the repository at this point in the history
* [fbjs] Use relative document and window (#156)

* [fbjs] Support nested browsing contexts (#156)

* [fbjs] Test getActiveElement api change (#156)
  • Loading branch information
acusti authored and zpao committed Mar 21, 2017
1 parent d7b0358 commit c8c794d
Show file tree
Hide file tree
Showing 7 changed files with 34 additions and 14 deletions.
5 changes: 3 additions & 2 deletions src/__forks__/Style.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,16 @@ 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')) {
return node;
}
node = node.parentNode;
}
return window;
return ownerDocument.defaultView || ownerDocument.parentWindow;
},

};
Expand Down
6 changes: 3 additions & 3 deletions src/__forks__/getUnboundedScrollPosition.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 13 additions & 0 deletions src/core/dom/__tests__/getActiveElement-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
});
});
12 changes: 8 additions & 4 deletions src/core/dom/getActiveElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/dom/getElementRect.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions src/core/dom/getScrollPosition.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 3 additions & 1 deletion src/core/dom/isNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down

0 comments on commit c8c794d

Please sign in to comment.