Merge "user: Allow "CAS update failed" exceptions to be normalised"
[lhc/web/wiklou.git] / resources / src / mediawiki.viewport.js
1 ( function () {
2 'use strict';
3
4 /**
5 * Utility library for viewport-related functions
6 *
7 * Notable references:
8 * - https://github.com/tuupola/jquery_lazyload
9 * - https://github.com/luis-almeida/unveil
10 *
11 * @class mw.viewport
12 * @singleton
13 */
14 var viewport = {
15
16 /**
17 * This is a private method pulled inside the module for testing purposes.
18 *
19 * @ignore
20 * @private
21 * @return {Object} Viewport positions
22 */
23 makeViewportFromWindow: function () {
24 var $window = $( window ),
25 scrollTop = $window.scrollTop(),
26 scrollLeft = $window.scrollLeft();
27
28 return {
29 top: scrollTop,
30 left: scrollLeft,
31 right: scrollLeft + $window.width(),
32 bottom: ( window.innerHeight ? window.innerHeight : $window.height() ) + scrollTop
33 };
34 },
35
36 /**
37 * Check if any part of a given element is in a given viewport
38 *
39 * @method
40 * @param {HTMLElement} el Element that's being tested
41 * @param {Object} [rectangle] Viewport to test against; structured as such:
42 *
43 * var rectangle = {
44 * top: topEdge,
45 * left: leftEdge,
46 * right: rightEdge,
47 * bottom: bottomEdge
48 * }
49 * Defaults to viewport made from `window`.
50 *
51 * @return {boolean}
52 */
53 isElementInViewport: function ( el, rectangle ) {
54 var $el = $( el ),
55 offset = $el.offset(),
56 rect = {
57 height: $el.height(),
58 width: $el.width(),
59 top: offset.top,
60 left: offset.left
61 },
62 viewport = rectangle || this.makeViewportFromWindow();
63
64 return (
65 // Top border must be above viewport's bottom
66 ( viewport.bottom >= rect.top ) &&
67 // Left border must be before viewport's right border
68 ( viewport.right >= rect.left ) &&
69 // Bottom border must be below viewport's top
70 ( viewport.top <= rect.top + rect.height ) &&
71 // Right border must be after viewport's left border
72 ( viewport.left <= rect.left + rect.width )
73 );
74 },
75
76 /**
77 * Check if an element is a given threshold away in any direction from a given viewport
78 *
79 * @method
80 * @param {HTMLElement} el Element that's being tested
81 * @param {number} [threshold] Pixel distance considered "close". Must be a positive number.
82 * Defaults to 50.
83 * @param {Object} [rectangle] Viewport to test against.
84 * Defaults to viewport made from `window`.
85 * @return {boolean}
86 */
87 isElementCloseToViewport: function ( el, threshold, rectangle ) {
88 var viewport = rectangle ? $.extend( {}, rectangle ) : this.makeViewportFromWindow();
89 threshold = threshold || 50;
90
91 viewport.top -= threshold;
92 viewport.left -= threshold;
93 viewport.right += threshold;
94 viewport.bottom += threshold;
95 return this.isElementInViewport( el, viewport );
96 }
97
98 };
99
100 mw.viewport = viewport;
101 }() );