ffffng/app/bower_components/jquery/src/offset.js

234 lines
6.7 KiB
JavaScript
Raw Normal View History

2017-05-13 13:25:33 +02:00
define( [
2014-05-12 20:08:19 +02:00
"./core",
"./core/access",
2017-05-13 13:25:33 +02:00
"./var/document",
"./var/documentElement",
2019-03-29 22:00:08 +01:00
"./var/isFunction",
2014-05-12 20:08:19 +02:00
"./css/var/rnumnonpx",
"./css/curCSS",
"./css/addGetHookIf",
"./css/support",
2019-03-29 22:00:08 +01:00
"./var/isWindow",
2014-05-12 20:08:19 +02:00
"./core/init",
"./css",
"./selector" // contains
2019-03-29 22:00:08 +01:00
], function( jQuery, access, document, documentElement, isFunction, rnumnonpx,
curCSS, addGetHookIf, support, isWindow ) {
2014-05-12 20:08:19 +02:00
2017-05-13 13:25:33 +02:00
"use strict";
2014-05-12 20:08:19 +02:00
jQuery.offset = {
setOffset: function( elem, options, i ) {
var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
position = jQuery.css( elem, "position" ),
curElem = jQuery( elem ),
props = {};
// Set position first, in-case top/left are set even on static elem
if ( position === "static" ) {
elem.style.position = "relative";
}
curOffset = curElem.offset();
curCSSTop = jQuery.css( elem, "top" );
curCSSLeft = jQuery.css( elem, "left" );
calculatePosition = ( position === "absolute" || position === "fixed" ) &&
2017-05-13 13:25:33 +02:00
( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
2014-05-12 20:08:19 +02:00
2016-05-16 13:33:49 +02:00
// Need to be able to calculate position if either
// top or left is auto and position is either absolute or fixed
2014-05-12 20:08:19 +02:00
if ( calculatePosition ) {
curPosition = curElem.position();
curTop = curPosition.top;
curLeft = curPosition.left;
} else {
curTop = parseFloat( curCSSTop ) || 0;
curLeft = parseFloat( curCSSLeft ) || 0;
}
2019-03-29 22:00:08 +01:00
if ( isFunction( options ) ) {
2017-05-13 13:25:33 +02:00
// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
2014-05-12 20:08:19 +02:00
}
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( elem, props );
} else {
curElem.css( props );
}
}
};
2017-05-13 13:25:33 +02:00
jQuery.fn.extend( {
2019-03-29 22:00:08 +01:00
// offset() relates an element's border box to the document origin
2014-05-12 20:08:19 +02:00
offset: function( options ) {
2017-05-13 13:25:33 +02:00
// Preserve chaining for setter
2014-05-12 20:08:19 +02:00
if ( arguments.length ) {
return options === undefined ?
this :
2017-05-13 13:25:33 +02:00
this.each( function( i ) {
2014-05-12 20:08:19 +02:00
jQuery.offset.setOffset( this, options, i );
2017-05-13 13:25:33 +02:00
} );
2014-05-12 20:08:19 +02:00
}
2019-03-29 22:00:08 +01:00
var rect, win,
2017-05-13 13:25:33 +02:00
elem = this[ 0 ];
2014-05-12 20:08:19 +02:00
2017-05-13 13:25:33 +02:00
if ( !elem ) {
2014-05-12 20:08:19 +02:00
return;
}
2017-05-13 13:25:33 +02:00
// Return zeros for disconnected and hidden (display: none) elements (gh-2310)
// Support: IE <=11 only
// Running getBoundingClientRect on a
// disconnected node in IE throws an error
if ( !elem.getClientRects().length ) {
return { top: 0, left: 0 };
2014-05-12 20:08:19 +02:00
}
2019-03-29 22:00:08 +01:00
// Get document-relative position by adding viewport scroll to viewport-relative gBCR
2017-05-13 13:25:33 +02:00
rect = elem.getBoundingClientRect();
2019-03-29 22:00:08 +01:00
win = elem.ownerDocument.defaultView;
2014-05-12 20:08:19 +02:00
return {
2019-03-29 22:00:08 +01:00
top: rect.top + win.pageYOffset,
left: rect.left + win.pageXOffset
2014-05-12 20:08:19 +02:00
};
},
2019-03-29 22:00:08 +01:00
// position() relates an element's margin box to its offset parent's padding box
// This corresponds to the behavior of CSS absolute positioning
2014-05-12 20:08:19 +02:00
position: function() {
if ( !this[ 0 ] ) {
return;
}
2019-03-29 22:00:08 +01:00
var offsetParent, offset, doc,
2014-05-12 20:08:19 +02:00
elem = this[ 0 ],
parentOffset = { top: 0, left: 0 };
2019-03-29 22:00:08 +01:00
// position:fixed elements are offset from the viewport, which itself always has zero offset
2014-05-12 20:08:19 +02:00
if ( jQuery.css( elem, "position" ) === "fixed" ) {
2017-05-13 13:25:33 +02:00
2019-03-29 22:00:08 +01:00
// Assume position:fixed implies availability of getBoundingClientRect
2014-05-12 20:08:19 +02:00
offset = elem.getBoundingClientRect();
} else {
2019-03-29 22:00:08 +01:00
offset = this.offset();
2017-05-13 13:25:33 +02:00
2019-03-29 22:00:08 +01:00
// Account for the *real* offset parent, which can be the document or its root element
// when a statically positioned element is identified
doc = elem.ownerDocument;
offsetParent = elem.offsetParent || doc.documentElement;
while ( offsetParent &&
( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
jQuery.css( offsetParent, "position" ) === "static" ) {
2014-05-12 20:08:19 +02:00
2019-03-29 22:00:08 +01:00
offsetParent = offsetParent.parentNode;
2014-05-12 20:08:19 +02:00
}
2019-03-29 22:00:08 +01:00
if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
2014-05-12 20:08:19 +02:00
2019-03-29 22:00:08 +01:00
// Incorporate borders into its offset, since they are outside its content origin
parentOffset = jQuery( offsetParent ).offset();
parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
}
2014-05-12 20:08:19 +02:00
}
// Subtract parent offsets and element margins
return {
top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
};
},
2017-05-13 13:25:33 +02:00
// This method will return documentElement in the following cases:
// 1) For the element inside the iframe without offsetParent, this method will return
// documentElement of the parent window
// 2) For the hidden or detached element
// 3) For body or html element, i.e. in case of the html node - it will return itself
//
// but those exceptions were never presented as a real life use-cases
// and might be considered as more preferable results.
//
// This logic, however, is not guaranteed and can change at any point in the future
2014-05-12 20:08:19 +02:00
offsetParent: function() {
2017-05-13 13:25:33 +02:00
return this.map( function() {
var offsetParent = this.offsetParent;
2014-05-12 20:08:19 +02:00
2017-05-13 13:25:33 +02:00
while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
2014-05-12 20:08:19 +02:00
offsetParent = offsetParent.offsetParent;
}
2017-05-13 13:25:33 +02:00
return offsetParent || documentElement;
} );
2014-05-12 20:08:19 +02:00
}
2017-05-13 13:25:33 +02:00
} );
2014-05-12 20:08:19 +02:00
// Create scrollLeft and scrollTop methods
jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
var top = "pageYOffset" === prop;
jQuery.fn[ method ] = function( val ) {
return access( this, function( elem, method, val ) {
2017-05-13 13:25:33 +02:00
// Coalesce documents and windows
var win;
2019-03-29 22:00:08 +01:00
if ( isWindow( elem ) ) {
2017-05-13 13:25:33 +02:00
win = elem;
} else if ( elem.nodeType === 9 ) {
win = elem.defaultView;
}
2014-05-12 20:08:19 +02:00
if ( val === undefined ) {
return win ? win[ prop ] : elem[ method ];
}
if ( win ) {
win.scrollTo(
2017-05-13 13:25:33 +02:00
!top ? val : win.pageXOffset,
top ? val : win.pageYOffset
2014-05-12 20:08:19 +02:00
);
} else {
elem[ method ] = val;
}
2017-05-13 13:25:33 +02:00
}, method, val, arguments.length );
2014-05-12 20:08:19 +02:00
};
2017-05-13 13:25:33 +02:00
} );
2014-05-12 20:08:19 +02:00
2017-05-13 13:25:33 +02:00
// Support: Safari <=7 - 9.1, Chrome <=37 - 49
2014-05-12 20:08:19 +02:00
// Add the top/left cssHooks using jQuery.fn.position
// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
2017-05-13 13:25:33 +02:00
// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
2016-05-16 13:33:49 +02:00
// getComputedStyle returns percent when specified for top/left/bottom/right;
// rather than make the css module depend on the offset module, just check for it here
2014-05-12 20:08:19 +02:00
jQuery.each( [ "top", "left" ], function( i, prop ) {
jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
function( elem, computed ) {
if ( computed ) {
computed = curCSS( elem, prop );
2017-05-13 13:25:33 +02:00
2016-05-16 13:33:49 +02:00
// If curCSS returns percentage, fallback to offset
2014-05-12 20:08:19 +02:00
return rnumnonpx.test( computed ) ?
jQuery( elem ).position()[ prop ] + "px" :
computed;
}
}
);
2017-05-13 13:25:33 +02:00
} );
2014-05-12 20:08:19 +02:00
return jQuery;
2017-05-13 13:25:33 +02:00
} );