2 * Responsive images based on 'srcset' and 'window.devicePixelRatio' emulation where needed.
4 * Call $().hidpi() on a document or part of a document to replace image srcs in that section.
6 * $.devicePixelRatio() can be used to supplement window.devicePixelRatio with support on
7 * some additional browsers.
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
17 * Uses window.devicePixelRatio if available, or CSS media queries on IE.
19 * @return {number} Device pixel ratio
21 $.devicePixelRatio = function () {
22 if ( window
.devicePixelRatio
!== undefined ) {
24 // * WebKit (Safari, Chrome, Android browser, etc)
27 return window
.devicePixelRatio
;
28 } else if ( window
.msMatchMedia
!== undefined ) {
29 // Windows 8 desktops / tablets, probably Windows Phone 8
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
) {
37 } else if ( window
.msMatchMedia( '(min-resolution: 144dpi)' ).matches
) {
44 // Assume 1 if unknown.
50 * Implement responsive images based on srcset attributes, if browser has no
51 * native srcset support.
53 * @return {jQuery} This selection
55 $.fn
.hidpi = function () {
57 // @todo add support for dpi media query checks on Firefox, IE
58 devicePixelRatio
= $.devicePixelRatio(),
59 testImage
= new Image();
61 if ( devicePixelRatio
> 1 && testImage
.srcset
=== undefined ) {
62 // No native srcset support.
63 $target
.find( 'img' ).each( function () {
65 srcset
= $img
.attr( 'srcset' ),
67 if ( typeof srcset
=== 'string' && srcset
!== '' ) {
68 match
= $.matchSrcSet( devicePixelRatio
, srcset
);
69 if (match
!== null ) {
70 $img
.attr( 'src', match
);
80 * Match a srcset entry for the given device pixel ratio
82 * Exposed for testing.
84 * @param {number} devicePixelRatio
85 * @param {string} srcset
86 * @return {mixed} null or the matching src string
88 $.matchSrcSet = function ( devicePixelRatio
, srcset
) {
98 candidates
= srcset
.split( / *, */
);
99 for ( i
= 0; i
< candidates
.length
; i
++ ) {
100 candidate
= candidates
[i
];
101 bits
= candidate
.split( / +/ );
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
;