Sumit has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/228785

Change subject: WikidataPageBanner implement srcset polyfill
......................................................................

WikidataPageBanner implement srcset polyfill

Implement a polyfill for srcset attribute which presently has limited support.
Set default banner image as an image of size 640px to avoid unnecessary loading
of a large image.

Change-Id: Ic8f2bbdabe69b9da32acbdf1e13e03c912eae82a
---
M extension.json
M includes/WikidataPageBanner.hooks.php
A 
resources/ext.WikidataPageBanner.srcsetPolyfill/ext.WikidataPageBanner.srcsetPolyfill.js
3 files changed, 140 insertions(+), 1 deletion(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/WikidataPageBanner 
refs/changes/85/228785/1

diff --git a/extension.json b/extension.json
index ab4ff9d..2f6e2c8 100644
--- a/extension.json
+++ b/extension.json
@@ -48,6 +48,16 @@
                                "mobile"
                        ],
                        "position": "top"
+               },
+               "ext.WikidataPageBanner.srcsetPolyfill": {
+                       "scripts": [
+                               
"ext.WikidataPageBanner.srcsetPolyfill/ext.WikidataPageBanner.srcsetPolyfill.js"
+                       ],
+                       "targets": [
+                               "desktop",
+                               "mobile"
+                       ],
+                       "position": "bottom"
                }
        },
        "ResourceFileModulePaths": {
diff --git a/includes/WikidataPageBanner.hooks.php 
b/includes/WikidataPageBanner.hooks.php
index 6465701..0fd5dff 100644
--- a/includes/WikidataPageBanner.hooks.php
+++ b/includes/WikidataPageBanner.hooks.php
@@ -26,6 +26,7 @@
                        // only add banner and styling if valid banner generated
                        if ( $banner !== null ) {
                                $out->addModuleStyles( 'ext.WikidataPageBanner' 
);
+                               $out->addModules( 
'ext.WikidataPageBanner.srcsetPolyfill' );
                                if ( isset( $params['toc'] ) ) {
                                        $out->addModuleStyles( 
'ext.WikidataPageBanner.toc.styles' );
                                }
@@ -211,7 +212,7 @@
                        // create full src set from individual urls, separated 
by comma
                        $srcset = implode( ',', $srcset );
                        // use largest image url as src attribute
-                       $bannerurl = $urls[count( $urls ) - 1];
+                       $bannerurl = $urls[1];
                        $bannerfile = Title::newFromText( "File:$bannername" );
                        $templateParser = new TemplateParser( __DIR__ . 
'/../templates' );
                        $options['bannerfile'] = $bannerfile->getLocalUrl();
diff --git 
a/resources/ext.WikidataPageBanner.srcsetPolyfill/ext.WikidataPageBanner.srcsetPolyfill.js
 
b/resources/ext.WikidataPageBanner.srcsetPolyfill/ext.WikidataPageBanner.srcsetPolyfill.js
new file mode 100644
index 0000000..b309c6a
--- /dev/null
+++ 
b/resources/ext.WikidataPageBanner.srcsetPolyfill/ext.WikidataPageBanner.srcsetPolyfill.js
@@ -0,0 +1,128 @@
+( function( mw, $ ) {
+       /**
+        * Returns whether or not srcset attribute is supported by this browser
+        * @return bool true if srcset is supported, otherwise false
+        */
+       function isSrcsetSupported() {
+               return 'srcset' in new Image();
+       }
+
+       /**
+        * Parses the srcset="" attribute and forms an array of type 
[{url:"",descriptor:""}]
+        * @return {array} Array of objects each of which contains a url of 
image and its corresponding
+        * size
+        */
+       function parseSrcset( srcset ) {
+               var srcSet = [],
+                       url,
+                       desc,
+                       separator,
+                       position;
+               // remove any whitespaces from the end
+               srcset = srcset.trim();
+               while ( srcset.indexOf( ',' ) !== -1 ) {
+                       // get index of space which marks end of url part
+                       position = srcset.indexOf( ' ' );
+                       // url will be the part of string till first whitespace
+                       url = srcset.slice(0, position);
+                       while ( srcset.charAt( position ) === ' ' ) {
+                               position++;
+                       }
+                       desc = '';
+                       // get position of next COMMA ','
+                       separator = srcset.indexOf( ',' );
+                       // get the descriptor which is only 'w' in the 
extension currently
+                       desc = srcset.slice( position, separator );
+                       srcset = srcset.slice( separator + 1 );
+                       srcSet.push( {
+                               url: url,
+                               descriptor: desc
+                       } );
+               }
+               // parse last url
+               position = srcset.indexOf( ' ' );
+               // url will be the part of string till first whitespace
+               url = srcset.slice(0, position);
+               while ( srcset.charAt( position ) === ' ' ) {
+                       position++;
+               }
+               desc = '';
+               desc = srcset.slice( position, separator );
+               srcset = srcset.slice( separator + 1 );
+               srcSet.push( {
+                       url: url,
+                       descriptor: desc
+               } );
+               return srcSet;
+       }
+
+       /**
+        * Parses descriptor string and returns an object of {x:_,w:_,h:_} 
values
+        * @param  {string} desc Descriptor string
+        * @return {object} Object containing keys out of x,w,h and their 
corresponding values
+        */
+       function parseDesc( desc ) {
+               var descriptors = desc.split(/\s/),
+                       result = {},
+                       descriptor,
+                       qualifier,
+                       val,
+                       INT_REGEXP = /^[0-9]+$/;
+               // traverse descriptor string
+               for (var i = 0; i < descriptors.length; i++) {
+                       descriptor = descriptors[i];
+                       if ( descriptor.length > 0 ) {
+                               // get qualifier which is x,w or h
+                               qualifier = descriptor[ descriptor.length - 1 ];
+                               //get value part
+                               val = descriptor.substring( 0, 
descriptor.length-1 );
+                               // value might be int or float depending on 
qualifier
+                               var intVal = parseInt( val, 10 );
+                               var floatVal = parseFloat( val );
+                               if ( val.match( INT_REGEXP ) && qualifier === 
'w' ) {
+                                       result[qualifier] = intVal;
+                               } else if ( val.match( INT_REGEXP ) && 
qualifier === 'h' ) {
+                                       result[qualifier] = intVal;
+                               } else if ( !isNaN( floatVal ) && qualifier === 
'x') {
+                                       result[qualifier] = floatVal;
+                               }
+                       }
+               }
+               return result;
+       }
+
+       /**
+        * Returns the url of the best size image out of those present in 
srcset, taking into
+        * consideration screen size and device pixel ratio
+        * @return {string} Url of image of best size
+        */
+       function getBestImage() {
+               var srcset = $( '.wpb-banner-image' ).attr( 'srcset' ),
+                       srcSet,
+                       imageSizeMultiplier,
+                       apparentWidth,
+                       bestImage = null;
+               imageSizeMultiplier = ( window.devicePixelRatio && 
window.devicePixelRatio > 1 ) ?
+                       window.devicePixelRatio : 1;
+               apparentWidth = $( '.ext-wpb-pagebanner' ).width() * 
imageSizeMultiplier;
+               srcSet = parseSrcset( srcset );
+               // split the descriptor string into an object having 'x', 'w', 
'h' as its keys and look for
+               // best image size
+               for ( var index in srcSet ) {
+                       var descriptor = srcSet[index].descriptor;
+                       descriptor = parseDesc( descriptor );
+                       srcSet[index].descriptor = descriptor;
+                       // set best image as image of size immediately larger 
than apparentWidth
+                       // WikidataPageBanner only parses 'w' descriptor and 
sets image size
+                       if ( descriptor.w && descriptor.w > apparentWidth && 
!bestImage ) {
+                               bestImage = srcSet[index].url;
+                       }
+               }
+               return bestImage;
+       }
+
+       if ( !isSrcsetSupported() ) {
+               var bestImage = getBestImage();
+               $( '.wpb-banner-image' ).attr( 'src', bestImage );
+       }
+}( mediaWiki, jQuery ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/228785
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic8f2bbdabe69b9da32acbdf1e13e03c912eae82a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/WikidataPageBanner
Gerrit-Branch: master
Gerrit-Owner: Sumit <asthana.sumi...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to