Merge "jquery.makeCollapsible: Don't ignore clicks on fake links without href"
[lhc/web/wiklou.git] / resources / src / mediawiki / mediawiki.viewport.js
1 ( function ( mw, $ ) {
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 */
22 makeViewportFromWindow: function () {
23 var $window = $( window ),
24 scrollTop = $window.scrollTop(),
25 scrollLeft = $window.scrollLeft();
26
27 return {
28 top: scrollTop,
29 left: scrollLeft,
30 right: scrollLeft + $window.width(),
31 bottom: ( window.innerHeight ? window.innerHeight : $window.height() ) + scrollTop
32 };
33 },
34
35 /**
36 * Check if any part of a given element is in a given viewport
37 *
38 * @method
39 * @param {HTMLElement} el Element that's being tested
40 * @param {Object} [rectangle] Viewport to test against; structured as such:
41 *
42 * var rectangle = {
43 * top: topEdge,
44 * left: leftEdge,
45 * right: rightEdge,
46 * bottom: bottomEdge
47 * }
48 * Defaults to viewport made from `window`.
49 *
50 * @return {boolean}
51 */
52 isElementInViewport: function ( el, rectangle ) {
53 var $el = $( el ),
54 offset = $el.offset(),
55 rect = {
56 height: $el.height(),
57 width: $el.width(),
58 top: offset.top,
59 left: offset.left
60 },
61 viewport = rectangle || this.makeViewportFromWindow();
62
63 return (
64 // Top border must be above viewport's bottom
65 ( viewport.bottom >= rect.top ) &&
66 // Left border must be before viewport's right border
67 ( viewport.right >= rect.left ) &&
68 // Bottom border must be below viewport's top
69 ( viewport.top <= rect.top + rect.height ) &&
70 // Right border must be after viewport's left border
71 ( viewport.left <= rect.left + rect.width )
72 );
73 },
74
75 /**
76 * Check if an element is a given threshold away in any direction from a given viewport
77 *
78 * @method
79 * @param {HTMLElement} el Element that's being tested
80 * @param {number} [threshold] Pixel distance considered "close". Must be a positive number.
81 * Defaults to 50.
82 * @param {Object} [rectangle] Viewport to test against.
83 * Defaults to viewport made from `window`.
84 * @return {boolean}
85 */
86 isElementCloseToViewport: function ( el, threshold, rectangle ) {
87 var viewport = rectangle ? $.extend( {}, rectangle ) : this.makeViewportFromWindow();
88 threshold = threshold || 50 ;
89
90 viewport.top -= threshold;
91 viewport.left -= threshold;
92 viewport.right += threshold;
93 viewport.bottom += threshold;
94 return this.isElementInViewport( el, viewport );
95 }
96
97 };
98
99 mw.viewport = viewport;
100 }( mediaWiki, jQuery ) );