ed3124049f99d88092a346bea3126b39c710b85b
2 * Responsive images based on `srcset` and `window.devicePixelRatio` emulation where needed.
4 * Call `.hidpi()` on a document or part of a document to proces image srcsets within that section.
6 * `$.devicePixelRatio()` can be used as a substitute for `window.devicePixelRatio`.
7 * It provides a familiar interface to retrieve the pixel ratio for browsers that don't
8 * implement `window.devicePixelRatio` but do have a different way of getting it.
10 * @class jQuery.plugin.hidpi
15 * Get reported or approximate device pixel ratio.
17 * - 1.0 means 1 CSS pixel is 1 hardware pixel
18 * - 2.0 means 1 CSS pixel is 2 hardware pixels
21 * Uses `window.devicePixelRatio` if available, or CSS media queries on IE.
25 * @return {number} Device pixel ratio
27 $.devicePixelRatio = function () {
28 if ( window
.devicePixelRatio
!== undefined ) {
30 // * WebKit/Blink (Safari, Chrome, Android browser, etc)
33 // * Microsoft Edge (Windows 10)
34 return window
.devicePixelRatio
;
35 } else if ( window
.msMatchMedia
!== undefined ) {
36 // Windows 8 desktops / tablets, probably Windows Phone 8
38 // IE 10/11 doesn't report pixel ratio directly, but we can get the
39 // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for
40 // simplicity, but you may get different values depending on zoom
41 // factor, size of screen and orientation in Metro IE.
42 if ( window
.msMatchMedia( '(min-resolution: 192dpi)' ).matches
) {
44 } else if ( window
.msMatchMedia( '(min-resolution: 144dpi)' ).matches
) {
51 // Assume 1 if unknown.
57 * Bracket a given device pixel ratio to one of [1, 1.5, 2].
59 * This is useful for grabbing images on the fly with sizes based on the display
60 * density, without causing slowdown and extra thumbnail renderings on devices
61 * that are slightly different from the most common sizes.
63 * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
64 * so will be consistent with default renderings.
68 * @return {number} Device pixel ratio
70 $.bracketDevicePixelRatio = function ( baseRatio
) {
71 if ( baseRatio
> 1.5 ) {
73 } else if ( baseRatio
> 1 ) {
81 * Get reported or approximate device pixel ratio, bracketed to [1, 1.5, 2].
83 * This is useful for grabbing images on the fly with sizes based on the display
84 * density, without causing slowdown and extra thumbnail renderings on devices
85 * that are slightly different from the most common sizes.
87 * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails,
88 * so will be consistent with default renderings.
90 * - 1.0 means 1 CSS pixel is 1 hardware pixel
91 * - 1.5 means 1 CSS pixel is 1.5 hardware pixels
92 * - 2.0 means 1 CSS pixel is 2 hardware pixels
96 * @return {number} Device pixel ratio
98 $.bracketedDevicePixelRatio = function () {
99 return $.bracketDevicePixelRatio( $.devicePixelRatio() );
103 * Implement responsive images based on srcset attributes, if browser has no
104 * native srcset support.
106 * @return {jQuery} This selection
109 $.fn
.hidpi = function () {
111 // TODO add support for dpi media query checks on Firefox, IE
112 devicePixelRatio
= $.devicePixelRatio(),
113 testImage
= new Image();
115 if ( devicePixelRatio
> 1 && testImage
.srcset
=== undefined ) {
116 // No native srcset support.
117 $target
.find( 'img' ).each( function () {
118 var $img
= $( this ),
119 srcset
= $img
.attr( 'srcset' ),
121 if ( typeof srcset
=== 'string' && srcset
!== '' ) {
122 match
= $.matchSrcSet( devicePixelRatio
, srcset
);
123 if ( match
!== null ) {
124 $img
.attr( 'src', match
);
134 * Match a srcset entry for the given device pixel ratio
136 * Exposed for testing.
140 * @param {number} devicePixelRatio
141 * @param {string} srcset
142 * @return {Mixed} null or the matching src string
144 $.matchSrcSet = function ( devicePixelRatio
, srcset
) {
154 candidates
= srcset
.split( / *, */
);
155 for ( i
= 0; i
< candidates
.length
; i
++ ) {
156 candidate
= candidates
[ i
];
157 bits
= candidate
.split( / +/ );
159 if ( bits
.length
> 1 && bits
[ 1 ].charAt( bits
[ 1 ].length
- 1 ) === 'x' ) {
160 ratioStr
= bits
[ 1 ].slice( 0, -1 );
161 ratio
= parseFloat( ratioStr
);
162 if ( ratio
<= devicePixelRatio
&& ratio
> selectedRatio
) {
163 selectedRatio
= ratio
;
173 * @mixins jQuery.plugin.hidpi