Split /resources into /resources/lib and /resources/src
[lhc/web/wiklou.git] / resources / src / jquery / jquery.hidpi.js
1 /**
2 * Responsive images based on 'srcset' and 'window.devicePixelRatio' emulation where needed.
3 *
4 * Call $().hidpi() on a document or part of a document to replace image srcs in that section.
5 *
6 * $.devicePixelRatio() can be used to supplement window.devicePixelRatio with support on
7 * some additional browsers.
8 */
9 ( function ( $ ) {
10
11 /**
12 * Detect reported or approximate device pixel ratio.
13 * 1.0 means 1 CSS pixel is 1 hardware pixel
14 * 2.0 means 1 CSS pixel is 2 hardware pixels
15 * etc
16 *
17 * Uses window.devicePixelRatio if available, or CSS media queries on IE.
18 *
19 * @return {number} Device pixel ratio
20 */
21 $.devicePixelRatio = function () {
22 if ( window.devicePixelRatio !== undefined ) {
23 // Most web browsers:
24 // * WebKit (Safari, Chrome, Android browser, etc)
25 // * Opera
26 // * Firefox 18+
27 return window.devicePixelRatio;
28 } else if ( window.msMatchMedia !== undefined ) {
29 // Windows 8 desktops / tablets, probably Windows Phone 8
30 //
31 // IE 10 doesn't report pixel ratio directly, but we can get the
32 // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for
33 // simplicity, but you may get different values depending on zoom
34 // factor, size of screen and orientation in Metro IE.
35 if ( window.msMatchMedia( '(min-resolution: 192dpi)' ).matches ) {
36 return 2;
37 } else if ( window.msMatchMedia( '(min-resolution: 144dpi)' ).matches ) {
38 return 1.5;
39 } else {
40 return 1;
41 }
42 } else {
43 // Legacy browsers...
44 // Assume 1 if unknown.
45 return 1;
46 }
47 };
48
49 /**
50 * Implement responsive images based on srcset attributes, if browser has no
51 * native srcset support.
52 *
53 * @return {jQuery} This selection
54 */
55 $.fn.hidpi = function () {
56 var $target = this,
57 // @todo add support for dpi media query checks on Firefox, IE
58 devicePixelRatio = $.devicePixelRatio(),
59 testImage = new Image();
60
61 if ( devicePixelRatio > 1 && testImage.srcset === undefined ) {
62 // No native srcset support.
63 $target.find( 'img' ).each( function () {
64 var $img = $( this ),
65 srcset = $img.attr( 'srcset' ),
66 match;
67 if ( typeof srcset === 'string' && srcset !== '' ) {
68 match = $.matchSrcSet( devicePixelRatio, srcset );
69 if (match !== null ) {
70 $img.attr( 'src', match );
71 }
72 }
73 });
74 }
75
76 return $target;
77 };
78
79 /**
80 * Match a srcset entry for the given device pixel ratio
81 *
82 * Exposed for testing.
83 *
84 * @param {number} devicePixelRatio
85 * @param {string} srcset
86 * @return {mixed} null or the matching src string
87 */
88 $.matchSrcSet = function ( devicePixelRatio, srcset ) {
89 var candidates,
90 candidate,
91 bits,
92 src,
93 i,
94 ratioStr,
95 ratio,
96 selectedRatio = 1,
97 selectedSrc = null;
98 candidates = srcset.split( / *, */ );
99 for ( i = 0; i < candidates.length; i++ ) {
100 candidate = candidates[i];
101 bits = candidate.split( / +/ );
102 src = bits[0];
103 if ( bits.length > 1 && bits[1].charAt( bits[1].length - 1 ) === 'x' ) {
104 ratioStr = bits[1].substr( 0, bits[1].length - 1 );
105 ratio = parseFloat( ratioStr );
106 if ( ratio <= devicePixelRatio && ratio > selectedRatio ) {
107 selectedRatio = ratio;
108 selectedSrc = src;
109 }
110 }
111 }
112 return selectedSrc;
113 };
114
115 }( jQuery ) );