src/offset.js

Maintainability

61.80

Lines of code

167

Created with Raphaël 2.1.002550751002013-2-252013-1-262012-12-272012-11-272012-10-282012-9-282012-8-292013-3-27Maintainability: 61.8

Created with Raphaël 2.1.0046931391852013-2-252013-1-262012-12-272012-11-272012-10-282012-9-282012-8-292013-3-27Lines of Code: 167

Difficulty

52.11

Estimated Errors

1.40

Function weight

By Complexity

Created with Raphaël 2.1.0setOffset10

By SLOC

Created with Raphaël 2.1.0setOffset45
1
jQuery.fn.offset = function( options ) {
2
    if ( arguments.length ) {
3
        return options === undefined ?
4
            this :
5
            this.each(function( i ) {
6
                jQuery.offset.setOffset( this, options, i );
7
            });
8
    }
9
 
10
    var docElem, win,
11
        elem = this[ 0 ],
12
        box = { top: 0, left: 0 },
13
        doc = elem && elem.ownerDocument;
14
 
15
    if ( !doc ) {
16
        return;
17
    }
18
 
19
    docElem = doc.documentElement;
20
 
21
    // Make sure it's not a disconnected DOM node
22
    if ( !jQuery.contains( docElem, elem ) ) {
23
        return box;
24
    }
25
 
26
    // If we don't have gBCR, just use 0,0 rather than error
27
    // BlackBerry 5, iOS 3 (original iPhone)
28
    if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
29
        box = elem.getBoundingClientRect();
30
    }
31
    win = getWindow( doc );
32
    return {
33
        top: box.top + win.pageYOffset - docElem.clientTop,
34
        left: box.left + win.pageXOffset - docElem.clientLeft
35
    };
36
};
37
 
38
jQuery.offset = {
39
 
40
    setOffset: function( elem, options, i ) {
41
        var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
42
            position = jQuery.css( elem, "position" ),
43
            curElem = jQuery( elem ),
44
            props = {};
45
 
46
        // Set position first, in-case top/left are set even on static elem
47
        if ( position === "static" ) {
48
            elem.style.position = "relative";
49
        }
50
 
51
        curOffset = curElem.offset();
52
        curCSSTop = jQuery.css( elem, "top" );
53
        curCSSLeft = jQuery.css( elem, "left" );
54
        calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
55
 
56
        // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
57
        if ( calculatePosition ) {
58
            curPosition = curElem.position();
59
            curTop = curPosition.top;
60
            curLeft = curPosition.left;
61
 
62
        } else {
63
            curTop = parseFloat( curCSSTop ) || 0;
64
            curLeft = parseFloat( curCSSLeft ) || 0;
65
        }
66
 
67
        if ( jQuery.isFunction( options ) ) {
68
            options = options.call( elem, i, curOffset );
69
        }
70
 
71
        if ( options.top != null ) {
Column: 26 "Use '!==' to compare with 'null'."
72
            props.top = ( options.top - curOffset.top ) + curTop;
73
        }
74
        if ( options.left != null ) {
Column: 27 "Use '!==' to compare with 'null'."
75
            props.left = ( options.left - curOffset.left ) + curLeft;
76
        }
77
 
78
        if ( "using" in options ) {
79
            options.using.call( elem, props );
80
 
81
        } else {
82
            curElem.css( props );
83
        }
84
    }
85
};
86
 
87
 
88
jQuery.fn.extend({
89
 
90
    position: function() {
91
        if ( !this[ 0 ] ) {
92
            return;
93
        }
94
 
95
        var offsetParent, offset,
96
            elem = this[ 0 ],
97
            parentOffset = { top: 0, left: 0 };
98
 
99
        // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
100
        if ( jQuery.css( elem, "position" ) === "fixed" ) {
101
            // We assume that getBoundingClientRect is available when computed position is fixed
102
            offset = elem.getBoundingClientRect();
103
 
104
        } else {
105
            // Get *real* offsetParent
106
            offsetParent = this.offsetParent();
107
 
108
            // Get correct offsets
109
            offset = this.offset();
110
            if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
111
                parentOffset = offsetParent.offset();
112
            }
113
 
114
            // Add offsetParent borders
115
            parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
116
            parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
117
        }
118
 
119
        // Subtract parent offsets and element margins
120
        return {
121
            top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
122
            left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
123
        };
124
    },
125
 
126
    offsetParent: function() {
127
        return this.map(function() {
128
            var offsetParent = this.offsetParent || docElem;
129
 
130
            while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
131
                offsetParent = offsetParent.offsetParent;
132
            }
133
 
134
            return offsetParent || docElem;
135
        });
136
    }
137
});
138
 
139
 
140
// Create scrollLeft and scrollTop methods
141
jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
142
    var top = "pageYOffset" === prop;
143
 
144
    jQuery.fn[ method ] = function( val ) {
145
        return jQuery.access( this, function( elem, method, val ) {
146
            var win = getWindow( elem );
147
 
148
            if ( val === undefined ) {
149
                return win ? win[ prop ] : elem[ method ];
150
            }
151
 
152
            if ( win ) {
153
                win.scrollTo(
154
                    !top ? val : window.pageXOffset,
155
                    top ? val : window.pageYOffset
156
                );
157
 
158
            } else {
159
                elem[ method ] = val;
160
            }
161
        }, method, val, arguments.length, null );
162
    };
163
});
164
 
165
function getWindow( elem ) {
166
    return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
167
}