react-bootstrap
Version:
Bootstrap 3 components build with React
211 lines (179 loc) • 5.49 kB
JavaScript
;
var _interopRequireDefault = require('babel-runtime/helpers/interop-require-default')['default'];
exports.__esModule = true;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var canUseDom = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
/**
* Get elements owner document
*
* @param {ReactComponent|HTMLElement} componentOrElement
* @returns {HTMLElement}
*/
function ownerDocument(componentOrElement) {
var elem = _react2['default'].findDOMNode(componentOrElement);
return elem && elem.ownerDocument || document;
}
function ownerWindow(componentOrElement) {
var doc = ownerDocument(componentOrElement);
return doc.defaultView ? doc.defaultView : doc.parentWindow;
}
/**
* get the active element, safe in IE
* @return {HTMLElement}
*/
function getActiveElement(componentOrElement) {
var doc = ownerDocument(componentOrElement);
try {
return doc.activeElement || doc.body;
} catch (e) {
return doc.body;
}
}
/**
* Shortcut to compute element style
*
* @param {HTMLElement} elem
* @returns {CssStyle}
*/
function getComputedStyles(elem) {
return ownerDocument(elem).defaultView.getComputedStyle(elem, null);
}
/**
* Get elements offset
*
* TODO: REMOVE JQUERY!
*
* @param {HTMLElement} DOMNode
* @returns {{top: number, left: number}}
*/
function getOffset(DOMNode) {
if (window.jQuery) {
return window.jQuery(DOMNode).offset();
}
var docElem = ownerDocument(DOMNode).documentElement;
var box = { top: 0, left: 0 };
// If we don't have gBCR, just use 0,0 rather than error
// BlackBerry 5, iOS 3 (original iPhone)
if (typeof DOMNode.getBoundingClientRect !== 'undefined') {
box = DOMNode.getBoundingClientRect();
}
return {
top: box.top + window.pageYOffset - docElem.clientTop,
left: box.left + window.pageXOffset - docElem.clientLeft
};
}
/**
* Get elements position
*
* TODO: REMOVE JQUERY!
*
* @param {HTMLElement} elem
* @param {HTMLElement?} offsetParent
* @returns {{top: number, left: number}}
*/
function getPosition(elem, offsetParent) {
var offset = undefined,
parentOffset = undefined;
if (window.jQuery) {
if (!offsetParent) {
return window.jQuery(elem).position();
}
offset = window.jQuery(elem).offset();
parentOffset = window.jQuery(offsetParent).offset();
// Get element offset relative to offsetParent
return {
top: offset.top - parentOffset.top,
left: offset.left - parentOffset.left
};
}
parentOffset = { top: 0, left: 0 };
// Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
if (getComputedStyles(elem).position === 'fixed') {
// We assume that getBoundingClientRect is available when computed position is fixed
offset = elem.getBoundingClientRect();
} else {
if (!offsetParent) {
// Get *real* offsetParent
offsetParent = offsetParentFunc(elem);
}
// Get correct offsets
offset = getOffset(elem);
if (offsetParent.nodeName !== 'HTML') {
parentOffset = getOffset(offsetParent);
}
// Add offsetParent borders
parentOffset.top += parseInt(getComputedStyles(offsetParent).borderTopWidth, 10);
parentOffset.left += parseInt(getComputedStyles(offsetParent).borderLeftWidth, 10);
}
// Subtract parent offsets and element margins
return {
top: offset.top - parentOffset.top - parseInt(getComputedStyles(elem).marginTop, 10),
left: offset.left - parentOffset.left - parseInt(getComputedStyles(elem).marginLeft, 10)
};
}
/**
* Get an element's size
*
* @param {HTMLElement} elem
* @returns {{width: number, height: number}}
*/
function getSize(elem) {
var rect = {
width: elem.offsetWidth || 0,
height: elem.offsetHeight || 0
};
if (typeof elem.getBoundingClientRect !== 'undefined') {
var _elem$getBoundingClientRect = elem.getBoundingClientRect();
var width = _elem$getBoundingClientRect.width;
var height = _elem$getBoundingClientRect.height;
rect.width = width || rect.width;
rect.height = height || rect.height;
}
return rect;
}
/**
* Get parent element
*
* @param {HTMLElement?} elem
* @returns {HTMLElement}
*/
function offsetParentFunc(elem) {
var docElem = ownerDocument(elem).documentElement;
var offsetParent = elem.offsetParent || docElem;
while (offsetParent && (offsetParent.nodeName !== 'HTML' && getComputedStyles(offsetParent).position === 'static')) {
offsetParent = offsetParent.offsetParent;
}
return offsetParent || docElem;
}
/**
* Cross browser .contains() polyfill
* @param {HTMLElement} elem
* @param {HTMLElement} inner
* @return {bool}
*/
function contains(elem, inner) {
function ie8Contains(root, node) {
while (node) {
if (node === root) {
return true;
}
node = node.parentNode;
}
return false;
}
return elem && elem.contains ? elem.contains(inner) : elem && elem.compareDocumentPosition ? elem === inner || !!(elem.compareDocumentPosition(inner) & 16) : ie8Contains(elem, inner);
}
exports['default'] = {
canUseDom: canUseDom,
contains: contains,
ownerWindow: ownerWindow,
ownerDocument: ownerDocument,
getComputedStyles: getComputedStyles,
getOffset: getOffset,
getPosition: getPosition,
getSize: getSize,
activeElement: getActiveElement,
offsetParent: offsetParentFunc
};
module.exports = exports['default'];