123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- 'use strict';
- angular.module('mgcrea.ngStrap.helpers.dimensions', [])
- .factory('dimensions', function () {
- var fn = {};
- /**
- * Test the element nodeName
- * @param element
- * @param name
- */
- var nodeName = fn.nodeName = function (element, name) {
- return element.nodeName && element.nodeName.toLowerCase() === name.toLowerCase();
- };
- /**
- * Returns the element computed style
- * @param element
- * @param prop
- * @param extra
- */
- fn.css = function (element, prop, extra) {
- var value;
- if (element.currentStyle) { // IE
- value = element.currentStyle[prop];
- } else if (window.getComputedStyle) {
- value = window.getComputedStyle(element)[prop];
- } else {
- value = element.style[prop];
- }
- return extra === true ? parseFloat(value) || 0 : value;
- };
- /**
- * Provides read-only equivalent of jQuery's offset function:
- * @required-by bootstrap-tooltip, bootstrap-affix
- * @url http://api.jquery.com/offset/
- * @param element
- */
- fn.offset = function (element) {
- var boxRect = element.getBoundingClientRect();
- var docElement = element.ownerDocument;
- return {
- width: boxRect.width || element.offsetWidth,
- height: boxRect.height || element.offsetHeight,
- top: boxRect.top + (window.pageYOffset || docElement.documentElement.scrollTop) - (docElement.documentElement.clientTop || 0),
- left: boxRect.left + (window.pageXOffset || docElement.documentElement.scrollLeft) - (docElement.documentElement.clientLeft || 0)
- };
- };
- /**
- * Provides set equivalent of jQuery's offset function:
- * @required-by bootstrap-tooltip
- * @url http://api.jquery.com/offset/
- * @param element
- * @param options
- * @param i
- */
- fn.setOffset = function (element, options, i) {
- var curPosition;
- var curLeft;
- var curCSSTop;
- var curTop;
- var curOffset;
- var curCSSLeft;
- var calculatePosition;
- var position = fn.css(element, 'position');
- var curElem = angular.element(element);
- var props = {};
- // Set position first, in-case top/left are set even on static elem
- if (position === 'static') {
- element.style.position = 'relative';
- }
- curOffset = fn.offset(element);
- curCSSTop = fn.css(element, 'top');
- curCSSLeft = fn.css(element, 'left');
- calculatePosition = (position === 'absolute' || position === 'fixed') &&
- (curCSSTop + curCSSLeft).indexOf('auto') > -1;
- // Need to be able to calculate position if either
- // top or left is auto and position is either absolute or fixed
- if (calculatePosition) {
- curPosition = fn.position(element);
- curTop = curPosition.top;
- curLeft = curPosition.left;
- } else {
- curTop = parseFloat(curCSSTop) || 0;
- curLeft = parseFloat(curCSSLeft) || 0;
- }
- if (angular.isFunction(options)) {
- options = options.call(element, i, curOffset);
- }
- if (options.top !== null) {
- props.top = (options.top - curOffset.top) + curTop;
- }
- if (options.left !== null) {
- props.left = (options.left - curOffset.left) + curLeft;
- }
- if ('using' in options) {
- options.using.call(curElem, props);
- } else {
- curElem.css({
- top: props.top + 'px',
- left: props.left + 'px'
- });
- }
- };
- /**
- * Provides read-only equivalent of jQuery's position function
- * @required-by bootstrap-tooltip, bootstrap-affix
- * @url http://api.jquery.com/offset/
- * @param element
- */
- fn.position = function (element) {
- var offsetParentRect = {top: 0, left: 0};
- var offsetParentEl;
- var offset;
- // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
- if (fn.css(element, 'position') === 'fixed') {
- // We assume that getBoundingClientRect is available when computed position is fixed
- offset = element.getBoundingClientRect();
- } else {
- // Get *real* offsetParentEl
- offsetParentEl = offsetParentElement(element);
- // Get correct offsets
- offset = fn.offset(element);
- if (!nodeName(offsetParentEl, 'html')) {
- offsetParentRect = fn.offset(offsetParentEl);
- }
- // Add offsetParent borders
- offsetParentRect.top += fn.css(offsetParentEl, 'borderTopWidth', true);
- offsetParentRect.left += fn.css(offsetParentEl, 'borderLeftWidth', true);
- }
- // Subtract parent offsets and element margins
- return {
- width: element.offsetWidth,
- height: element.offsetHeight,
- top: offset.top - offsetParentRect.top - fn.css(element, 'marginTop', true),
- left: offset.left - offsetParentRect.left - fn.css(element, 'marginLeft', true)
- };
- };
- /**
- * Returns the closest, non-statically positioned offsetParent of a given element
- * @required-by fn.position
- * @param element
- */
- function offsetParentElement (element) {
- var docElement = element.ownerDocument;
- var offsetParent = element.offsetParent || docElement;
- if (nodeName(offsetParent, '#document')) return docElement.documentElement;
- while (offsetParent && !nodeName(offsetParent, 'html') && fn.css(offsetParent, 'position') === 'static') {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent || docElement.documentElement;
- }
- /**
- * Provides equivalent of jQuery's height function
- * @required-by bootstrap-affix
- * @url http://api.jquery.com/height/
- * @param element
- * @param outer
- */
- fn.height = function (element, outer) {
- var value = element.offsetHeight;
- if (outer) {
- value += fn.css(element, 'marginTop', true) + fn.css(element, 'marginBottom', true);
- } else {
- value -= fn.css(element, 'paddingTop', true) + fn.css(element, 'paddingBottom', true) + fn.css(element, 'borderTopWidth', true) + fn.css(element, 'borderBottomWidth', true);
- }
- return value;
- };
- /**
- * Provides equivalent of jQuery's width function
- * @required-by bootstrap-affix
- * @url http://api.jquery.com/width/
- * @param element
- * @param outer
- */
- fn.width = function (element, outer) {
- var value = element.offsetWidth;
- if (outer) {
- value += fn.css(element, 'marginLeft', true) + fn.css(element, 'marginRight', true);
- } else {
- value -= fn.css(element, 'paddingLeft', true) + fn.css(element, 'paddingRight', true) + fn.css(element, 'borderLeftWidth', true) + fn.css(element, 'borderRightWidth', true);
- }
- return value;
- };
- return fn;
- });
|