From 58f8f519bae5315c1ef440770af6608f30e45a63 Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Mon, 4 May 2015 14:31:23 -0700 Subject: [PATCH] Provide $.bracketedDevicePixelRatio convenience function Brackets the detected value from $.devicePixelRatio() to one of the values [1, 1.5, 2] that we use for generating images in default srcset attribute. This is convenient for runtime fetching of images that match our standard rendering sizes on devices/browsers that are slightly off normal, to avoid creating extra thumbs and slowing the fetching. Bug: T97935 Change-Id: Ic9cb16543edee629543fa362f569414567756d79 --- resources/src/jquery/jquery.hidpi.js | 51 ++++++++++++++++++- .../resources/jquery/jquery.hidpi.test.js | 16 ++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/resources/src/jquery/jquery.hidpi.js b/resources/src/jquery/jquery.hidpi.js index 2b9bf7a313..aa6590bf50 100644 --- a/resources/src/jquery/jquery.hidpi.js +++ b/resources/src/jquery/jquery.hidpi.js @@ -27,14 +27,15 @@ $.devicePixelRatio = function () { if ( window.devicePixelRatio !== undefined ) { // Most web browsers: - // * WebKit (Safari, Chrome, Android browser, etc) + // * WebKit/Blink (Safari, Chrome, Android browser, etc) // * Opera // * Firefox 18+ + // * Microsoft Edge (Windows 10) return window.devicePixelRatio; } else if ( window.msMatchMedia !== undefined ) { // Windows 8 desktops / tablets, probably Windows Phone 8 // - // IE 10 doesn't report pixel ratio directly, but we can get the + // IE 10/11 doesn't report pixel ratio directly, but we can get the // screen DPI and divide by 96. We'll bracket to [1, 1.5, 2.0] for // simplicity, but you may get different values depending on zoom // factor, size of screen and orientation in Metro IE. @@ -52,6 +53,52 @@ $.devicePixelRatio = function () { } }; +/** + * Bracket a given device pixel ratio to one of [1, 1.5, 2]. + * + * This is useful for grabbing images on the fly with sizes based on the display + * density, without causing slowdown and extra thumbnail renderings on devices + * that are slightly different from the most common sizes. + * + * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails, + * so will be consistent with default renderings. + * + * @static + * @inheritable + * @return {number} Device pixel ratio + */ +$.bracketDevicePixelRatio = function ( baseRatio ) { + if ( baseRatio > 1.5 ) { + return 2; + } else if ( baseRatio > 1 ) { + return 1.5; + } else { + return 1; + } +}; + +/** + * Get reported or approximate device pixel ratio, bracketed to [1, 1.5, 2]. + * + * This is useful for grabbing images on the fly with sizes based on the display + * density, without causing slowdown and extra thumbnail renderings on devices + * that are slightly different from the most common sizes. + * + * The bracketed ratios match the default 'srcset' output on MediaWiki thumbnails, + * so will be consistent with default renderings. + * + * - 1.0 means 1 CSS pixel is 1 hardware pixel + * - 1.5 means 1 CSS pixel is 1.5 hardware pixels + * - 2.0 means 1 CSS pixel is 2 hardware pixels + * + * @static + * @inheritable + * @return {number} Device pixel ratio + */ +$.bracketedDevicePixelRatio = function () { + return $.bracketDevicePixelRatio( $.devicePixelRatio() ); +}; + /** * Implement responsive images based on srcset attributes, if browser has no * native srcset support. diff --git a/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js b/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js index 906369eec0..8c6287658e 100644 --- a/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js +++ b/tests/qunit/suites/resources/jquery/jquery.hidpi.test.js @@ -6,6 +6,22 @@ assert.equal( typeof devicePixelRatio, 'number', '$.devicePixelRatio() returns a number' ); } ); + QUnit.test( 'bracketedDevicePixelRatio', 1, function ( assert ) { + var devicePixelRatio = $.devicePixelRatio(); + assert.equal( typeof devicePixelRatio, 'number', '$.bracketedDevicePixelRatio() returns a number' ); + } ); + + QUnit.test( 'bracketDevicePixelRatio', 8, function ( assert ) { + assert.equal( $.bracketDevicePixelRatio( 0.75 ), 1, '0.75 gives 1' ); + assert.equal( $.bracketDevicePixelRatio( 1 ), 1, '1 gives 1' ); + assert.equal( $.bracketDevicePixelRatio( 1.25 ), 1.5, '1.25 gives 1.5' ); + assert.equal( $.bracketDevicePixelRatio( 1.5 ), 1.5, '1.5 gives 1.5' ); + assert.equal( $.bracketDevicePixelRatio( 1.75 ), 2, '1.75 gives 2' ); + assert.equal( $.bracketDevicePixelRatio( 2 ), 2, '2 gives 2' ); + assert.equal( $.bracketDevicePixelRatio( 2.5 ), 2, '2.5 gives 2' ); + assert.equal( $.bracketDevicePixelRatio( 3 ), 2, '3 gives 2' ); + } ); + QUnit.test( 'matchSrcSet', 6, function ( assert ) { var srcset = 'onefive.png 1.5x, two.png 2x'; -- 2.20.1