~holger-seelig/cobweb.js/trunk

« back to all changes in this revision

Viewing changes to cobweb.js/lib/jquery-contextMenu/src/jquery.ui.position.js

  • Committer: Holger Seelig
  • Date: 2017-08-22 04:53:24 UTC
  • Revision ID: holger.seelig@yahoo.de-20170822045324-4of4xxgt79669gbt
Switched to npm.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*!
2
 
 * jQuery UI Position 1.11.4
3
 
 * http://jqueryui.com
4
 
 *
5
 
 * Copyright jQuery Foundation and other contributors
6
 
 * Released under the MIT license.
7
 
 * http://jquery.org/license
8
 
 *
9
 
 * http://api.jqueryui.com/position/
10
 
 */
11
 
(function( factory ) {
12
 
        if ( typeof define === "function" && define.amd ) {
13
 
 
14
 
                // AMD. Register as an anonymous module.
15
 
                define( [ "jquery" ], factory );
16
 
        } else {
17
 
 
18
 
                // Browser globals
19
 
                factory( jQuery );
20
 
        }
21
 
}(function( $ ) {
22
 
(function() {
23
 
 
24
 
$.ui = $.ui || {};
25
 
 
26
 
var cachedScrollbarWidth, supportsOffsetFractions,
27
 
        max = Math.max,
28
 
        abs = Math.abs,
29
 
        round = Math.round,
30
 
        rhorizontal = /left|center|right/,
31
 
        rvertical = /top|center|bottom/,
32
 
        roffset = /[\+\-]\d+(\.[\d]+)?%?/,
33
 
        rposition = /^\w+/,
34
 
        rpercent = /%$/,
35
 
        _position = $.fn.position;
36
 
 
37
 
function getOffsets( offsets, width, height ) {
38
 
        return [
39
 
                parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
40
 
                parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
41
 
        ];
42
 
}
43
 
 
44
 
function parseCss( element, property ) {
45
 
        return parseInt( $.css( element, property ), 10 ) || 0;
46
 
}
47
 
 
48
 
function getDimensions( elem ) {
49
 
        var raw = elem[0];
50
 
        if ( raw.nodeType === 9 ) {
51
 
                return {
52
 
                        width: elem.width(),
53
 
                        height: elem.height(),
54
 
                        offset: { top: 0, left: 0 }
55
 
                };
56
 
        }
57
 
        if ( $.isWindow( raw ) ) {
58
 
                return {
59
 
                        width: elem.width(),
60
 
                        height: elem.height(),
61
 
                        offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
62
 
                };
63
 
        }
64
 
        if ( raw.preventDefault ) {
65
 
                return {
66
 
                        width: 0,
67
 
                        height: 0,
68
 
                        offset: { top: raw.pageY, left: raw.pageX }
69
 
                };
70
 
        }
71
 
        return {
72
 
                width: elem.outerWidth(),
73
 
                height: elem.outerHeight(),
74
 
                offset: elem.offset()
75
 
        };
76
 
}
77
 
 
78
 
$.position = {
79
 
        scrollbarWidth: function() {
80
 
                if ( cachedScrollbarWidth !== undefined ) {
81
 
                        return cachedScrollbarWidth;
82
 
                }
83
 
                var w1, w2,
84
 
                        div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
85
 
                        innerDiv = div.children()[0];
86
 
 
87
 
                $( "body" ).append( div );
88
 
                w1 = innerDiv.offsetWidth;
89
 
                div.css( "overflow", "scroll" );
90
 
 
91
 
                w2 = innerDiv.offsetWidth;
92
 
 
93
 
                if ( w1 === w2 ) {
94
 
                        w2 = div[0].clientWidth;
95
 
                }
96
 
 
97
 
                div.remove();
98
 
 
99
 
                return (cachedScrollbarWidth = w1 - w2);
100
 
        },
101
 
        getScrollInfo: function( within ) {
102
 
                var overflowX = within.isWindow || within.isDocument ? "" :
103
 
                                within.element.css( "overflow-x" ),
104
 
                        overflowY = within.isWindow || within.isDocument ? "" :
105
 
                                within.element.css( "overflow-y" ),
106
 
                        hasOverflowX = overflowX === "scroll" ||
107
 
                                ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
108
 
                        hasOverflowY = overflowY === "scroll" ||
109
 
                                ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
110
 
                return {
111
 
                        width: hasOverflowY ? $.position.scrollbarWidth() : 0,
112
 
                        height: hasOverflowX ? $.position.scrollbarWidth() : 0
113
 
                };
114
 
        },
115
 
        getWithinInfo: function( element ) {
116
 
                var withinElement = $( element || window ),
117
 
                        isWindow = $.isWindow( withinElement[0] ),
118
 
                        isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
119
 
                return {
120
 
                        element: withinElement,
121
 
                        isWindow: isWindow,
122
 
                        isDocument: isDocument,
123
 
                        offset: withinElement.offset() || { left: 0, top: 0 },
124
 
                        scrollLeft: withinElement.scrollLeft(),
125
 
                        scrollTop: withinElement.scrollTop(),
126
 
 
127
 
                        // support: jQuery 1.6.x
128
 
                        // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows
129
 
                        width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),
130
 
                        height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()
131
 
                };
132
 
        }
133
 
};
134
 
 
135
 
$.fn.position = function( options ) {
136
 
        if ( !options || !options.of ) {
137
 
                return _position.apply( this, arguments );
138
 
        }
139
 
 
140
 
        // make a copy, we don't want to modify arguments
141
 
        options = $.extend( {}, options );
142
 
 
143
 
        var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
144
 
                target = $( options.of ),
145
 
                within = $.position.getWithinInfo( options.within ),
146
 
                scrollInfo = $.position.getScrollInfo( within ),
147
 
                collision = ( options.collision || "flip" ).split( " " ),
148
 
                offsets = {};
149
 
 
150
 
        dimensions = getDimensions( target );
151
 
        if ( target[0].preventDefault ) {
152
 
                // force left top to allow flipping
153
 
                options.at = "left top";
154
 
        }
155
 
        targetWidth = dimensions.width;
156
 
        targetHeight = dimensions.height;
157
 
        targetOffset = dimensions.offset;
158
 
        // clone to reuse original targetOffset later
159
 
        basePosition = $.extend( {}, targetOffset );
160
 
 
161
 
        // force my and at to have valid horizontal and vertical positions
162
 
        // if a value is missing or invalid, it will be converted to center
163
 
        $.each( [ "my", "at" ], function() {
164
 
                var pos = ( options[ this ] || "" ).split( " " ),
165
 
                        horizontalOffset,
166
 
                        verticalOffset;
167
 
 
168
 
                if ( pos.length === 1) {
169
 
                        pos = rhorizontal.test( pos[ 0 ] ) ?
170
 
                                pos.concat( [ "center" ] ) :
171
 
                                rvertical.test( pos[ 0 ] ) ?
172
 
                                        [ "center" ].concat( pos ) :
173
 
                                        [ "center", "center" ];
174
 
                }
175
 
                pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
176
 
                pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
177
 
 
178
 
                // calculate offsets
179
 
                horizontalOffset = roffset.exec( pos[ 0 ] );
180
 
                verticalOffset = roffset.exec( pos[ 1 ] );
181
 
                offsets[ this ] = [
182
 
                        horizontalOffset ? horizontalOffset[ 0 ] : 0,
183
 
                        verticalOffset ? verticalOffset[ 0 ] : 0
184
 
                ];
185
 
 
186
 
                // reduce to just the positions without the offsets
187
 
                options[ this ] = [
188
 
                        rposition.exec( pos[ 0 ] )[ 0 ],
189
 
                        rposition.exec( pos[ 1 ] )[ 0 ]
190
 
                ];
191
 
        });
192
 
 
193
 
        // normalize collision option
194
 
        if ( collision.length === 1 ) {
195
 
                collision[ 1 ] = collision[ 0 ];
196
 
        }
197
 
 
198
 
        if ( options.at[ 0 ] === "right" ) {
199
 
                basePosition.left += targetWidth;
200
 
        } else if ( options.at[ 0 ] === "center" ) {
201
 
                basePosition.left += targetWidth / 2;
202
 
        }
203
 
 
204
 
        if ( options.at[ 1 ] === "bottom" ) {
205
 
                basePosition.top += targetHeight;
206
 
        } else if ( options.at[ 1 ] === "center" ) {
207
 
                basePosition.top += targetHeight / 2;
208
 
        }
209
 
 
210
 
        atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
211
 
        basePosition.left += atOffset[ 0 ];
212
 
        basePosition.top += atOffset[ 1 ];
213
 
 
214
 
        return this.each(function() {
215
 
                var collisionPosition, using,
216
 
                        elem = $( this ),
217
 
                        elemWidth = elem.outerWidth(),
218
 
                        elemHeight = elem.outerHeight(),
219
 
                        marginLeft = parseCss( this, "marginLeft" ),
220
 
                        marginTop = parseCss( this, "marginTop" ),
221
 
                        collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
222
 
                        collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
223
 
                        position = $.extend( {}, basePosition ),
224
 
                        myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
225
 
 
226
 
                if ( options.my[ 0 ] === "right" ) {
227
 
                        position.left -= elemWidth;
228
 
                } else if ( options.my[ 0 ] === "center" ) {
229
 
                        position.left -= elemWidth / 2;
230
 
                }
231
 
 
232
 
                if ( options.my[ 1 ] === "bottom" ) {
233
 
                        position.top -= elemHeight;
234
 
                } else if ( options.my[ 1 ] === "center" ) {
235
 
                        position.top -= elemHeight / 2;
236
 
                }
237
 
 
238
 
                position.left += myOffset[ 0 ];
239
 
                position.top += myOffset[ 1 ];
240
 
 
241
 
                // if the browser doesn't support fractions, then round for consistent results
242
 
                if ( !supportsOffsetFractions ) {
243
 
                        position.left = round( position.left );
244
 
                        position.top = round( position.top );
245
 
                }
246
 
 
247
 
                collisionPosition = {
248
 
                        marginLeft: marginLeft,
249
 
                        marginTop: marginTop
250
 
                };
251
 
 
252
 
                $.each( [ "left", "top" ], function( i, dir ) {
253
 
                        if ( $.ui.position[ collision[ i ] ] ) {
254
 
                                $.ui.position[ collision[ i ] ][ dir ]( position, {
255
 
                                        targetWidth: targetWidth,
256
 
                                        targetHeight: targetHeight,
257
 
                                        elemWidth: elemWidth,
258
 
                                        elemHeight: elemHeight,
259
 
                                        collisionPosition: collisionPosition,
260
 
                                        collisionWidth: collisionWidth,
261
 
                                        collisionHeight: collisionHeight,
262
 
                                        offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
263
 
                                        my: options.my,
264
 
                                        at: options.at,
265
 
                                        within: within,
266
 
                                        elem: elem
267
 
                                });
268
 
                        }
269
 
                });
270
 
 
271
 
                if ( options.using ) {
272
 
                        // adds feedback as second argument to using callback, if present
273
 
                        using = function( props ) {
274
 
                                var left = targetOffset.left - position.left,
275
 
                                        right = left + targetWidth - elemWidth,
276
 
                                        top = targetOffset.top - position.top,
277
 
                                        bottom = top + targetHeight - elemHeight,
278
 
                                        feedback = {
279
 
                                                target: {
280
 
                                                        element: target,
281
 
                                                        left: targetOffset.left,
282
 
                                                        top: targetOffset.top,
283
 
                                                        width: targetWidth,
284
 
                                                        height: targetHeight
285
 
                                                },
286
 
                                                element: {
287
 
                                                        element: elem,
288
 
                                                        left: position.left,
289
 
                                                        top: position.top,
290
 
                                                        width: elemWidth,
291
 
                                                        height: elemHeight
292
 
                                                },
293
 
                                                horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
294
 
                                                vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
295
 
                                        };
296
 
                                if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
297
 
                                        feedback.horizontal = "center";
298
 
                                }
299
 
                                if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
300
 
                                        feedback.vertical = "middle";
301
 
                                }
302
 
                                if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
303
 
                                        feedback.important = "horizontal";
304
 
                                } else {
305
 
                                        feedback.important = "vertical";
306
 
                                }
307
 
                                options.using.call( this, props, feedback );
308
 
                        };
309
 
                }
310
 
 
311
 
                elem.offset( $.extend( position, { using: using } ) );
312
 
        });
313
 
};
314
 
 
315
 
$.ui.position = {
316
 
        fit: {
317
 
                left: function( position, data ) {
318
 
                        var within = data.within,
319
 
                                withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
320
 
                                outerWidth = within.width,
321
 
                                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
322
 
                                overLeft = withinOffset - collisionPosLeft,
323
 
                                overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
324
 
                                newOverRight;
325
 
 
326
 
                        // element is wider than within
327
 
                        if ( data.collisionWidth > outerWidth ) {
328
 
                                // element is initially over the left side of within
329
 
                                if ( overLeft > 0 && overRight <= 0 ) {
330
 
                                        newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
331
 
                                        position.left += overLeft - newOverRight;
332
 
                                // element is initially over right side of within
333
 
                                } else if ( overRight > 0 && overLeft <= 0 ) {
334
 
                                        position.left = withinOffset;
335
 
                                // element is initially over both left and right sides of within
336
 
                                } else {
337
 
                                        if ( overLeft > overRight ) {
338
 
                                                position.left = withinOffset + outerWidth - data.collisionWidth;
339
 
                                        } else {
340
 
                                                position.left = withinOffset;
341
 
                                        }
342
 
                                }
343
 
                        // too far left -> align with left edge
344
 
                        } else if ( overLeft > 0 ) {
345
 
                                position.left += overLeft;
346
 
                        // too far right -> align with right edge
347
 
                        } else if ( overRight > 0 ) {
348
 
                                position.left -= overRight;
349
 
                        // adjust based on position and margin
350
 
                        } else {
351
 
                                position.left = max( position.left - collisionPosLeft, position.left );
352
 
                        }
353
 
                },
354
 
                top: function( position, data ) {
355
 
                        var within = data.within,
356
 
                                withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
357
 
                                outerHeight = data.within.height,
358
 
                                collisionPosTop = position.top - data.collisionPosition.marginTop,
359
 
                                overTop = withinOffset - collisionPosTop,
360
 
                                overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
361
 
                                newOverBottom;
362
 
 
363
 
                        // element is taller than within
364
 
                        if ( data.collisionHeight > outerHeight ) {
365
 
                                // element is initially over the top of within
366
 
                                if ( overTop > 0 && overBottom <= 0 ) {
367
 
                                        newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
368
 
                                        position.top += overTop - newOverBottom;
369
 
                                // element is initially over bottom of within
370
 
                                } else if ( overBottom > 0 && overTop <= 0 ) {
371
 
                                        position.top = withinOffset;
372
 
                                // element is initially over both top and bottom of within
373
 
                                } else {
374
 
                                        if ( overTop > overBottom ) {
375
 
                                                position.top = withinOffset + outerHeight - data.collisionHeight;
376
 
                                        } else {
377
 
                                                position.top = withinOffset;
378
 
                                        }
379
 
                                }
380
 
                        // too far up -> align with top
381
 
                        } else if ( overTop > 0 ) {
382
 
                                position.top += overTop;
383
 
                        // too far down -> align with bottom edge
384
 
                        } else if ( overBottom > 0 ) {
385
 
                                position.top -= overBottom;
386
 
                        // adjust based on position and margin
387
 
                        } else {
388
 
                                position.top = max( position.top - collisionPosTop, position.top );
389
 
                        }
390
 
                }
391
 
        },
392
 
        flip: {
393
 
                left: function( position, data ) {
394
 
                        var within = data.within,
395
 
                                withinOffset = within.offset.left + within.scrollLeft,
396
 
                                outerWidth = within.width,
397
 
                                offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
398
 
                                collisionPosLeft = position.left - data.collisionPosition.marginLeft,
399
 
                                overLeft = collisionPosLeft - offsetLeft,
400
 
                                overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
401
 
                                myOffset = data.my[ 0 ] === "left" ?
402
 
                                        -data.elemWidth :
403
 
                                        data.my[ 0 ] === "right" ?
404
 
                                                data.elemWidth :
405
 
                                                0,
406
 
                                atOffset = data.at[ 0 ] === "left" ?
407
 
                                        data.targetWidth :
408
 
                                        data.at[ 0 ] === "right" ?
409
 
                                                -data.targetWidth :
410
 
                                                0,
411
 
                                offset = -2 * data.offset[ 0 ],
412
 
                                newOverRight,
413
 
                                newOverLeft;
414
 
 
415
 
                        if ( overLeft < 0 ) {
416
 
                                newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
417
 
                                if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
418
 
                                        position.left += myOffset + atOffset + offset;
419
 
                                }
420
 
                        } else if ( overRight > 0 ) {
421
 
                                newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
422
 
                                if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
423
 
                                        position.left += myOffset + atOffset + offset;
424
 
                                }
425
 
                        }
426
 
                },
427
 
                top: function( position, data ) {
428
 
                        var within = data.within,
429
 
                                withinOffset = within.offset.top + within.scrollTop,
430
 
                                outerHeight = within.height,
431
 
                                offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
432
 
                                collisionPosTop = position.top - data.collisionPosition.marginTop,
433
 
                                overTop = collisionPosTop - offsetTop,
434
 
                                overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
435
 
                                top = data.my[ 1 ] === "top",
436
 
                                myOffset = top ?
437
 
                                        -data.elemHeight :
438
 
                                        data.my[ 1 ] === "bottom" ?
439
 
                                                data.elemHeight :
440
 
                                                0,
441
 
                                atOffset = data.at[ 1 ] === "top" ?
442
 
                                        data.targetHeight :
443
 
                                        data.at[ 1 ] === "bottom" ?
444
 
                                                -data.targetHeight :
445
 
                                                0,
446
 
                                offset = -2 * data.offset[ 1 ],
447
 
                                newOverTop,
448
 
                                newOverBottom;
449
 
                        if ( overTop < 0 ) {
450
 
                                newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
451
 
                                if ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {
452
 
                                        position.top += myOffset + atOffset + offset;
453
 
                                }
454
 
                        } else if ( overBottom > 0 ) {
455
 
                                newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
456
 
                                if ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {
457
 
                                        position.top += myOffset + atOffset + offset;
458
 
                                }
459
 
                        }
460
 
                }
461
 
        },
462
 
        flipfit: {
463
 
                left: function() {
464
 
                        $.ui.position.flip.left.apply( this, arguments );
465
 
                        $.ui.position.fit.left.apply( this, arguments );
466
 
                },
467
 
                top: function() {
468
 
                        $.ui.position.flip.top.apply( this, arguments );
469
 
                        $.ui.position.fit.top.apply( this, arguments );
470
 
                }
471
 
        }
472
 
};
473
 
 
474
 
// fraction support test
475
 
(function() {
476
 
        var testElement, testElementParent, testElementStyle, offsetLeft, i,
477
 
                body = document.getElementsByTagName( "body" )[ 0 ],
478
 
                div = document.createElement( "div" );
479
 
 
480
 
        //Create a "fake body" for testing based on method used in jQuery.support
481
 
        testElement = document.createElement( body ? "div" : "body" );
482
 
        testElementStyle = {
483
 
                visibility: "hidden",
484
 
                width: 0,
485
 
                height: 0,
486
 
                border: 0,
487
 
                margin: 0,
488
 
                background: "none"
489
 
        };
490
 
        if ( body ) {
491
 
                $.extend( testElementStyle, {
492
 
                        position: "absolute",
493
 
                        left: "-1000px",
494
 
                        top: "-1000px"
495
 
                });
496
 
        }
497
 
        for ( i in testElementStyle ) {
498
 
                testElement.style[ i ] = testElementStyle[ i ];
499
 
        }
500
 
        testElement.appendChild( div );
501
 
        testElementParent = body || document.documentElement;
502
 
        testElementParent.insertBefore( testElement, testElementParent.firstChild );
503
 
 
504
 
        div.style.cssText = "position: absolute; left: 10.7432222px;";
505
 
 
506
 
        offsetLeft = $( div ).offset().left;
507
 
        supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;
508
 
 
509
 
        testElement.innerHTML = "";
510
 
        testElementParent.removeChild( testElement );
511
 
})();
512
 
 
513
 
})();
514
 
 
515
 
return $.ui.position;
516
 
 
517
 
}));