Add file-link "parser" to mw.Title from commons
authorMark Holmquist <mtraceur@member.fsf.org>
Fri, 4 Oct 2013 00:06:53 +0000 (17:06 -0700)
committerMark Holmquist <mtraceur@member.fsf.org>
Tue, 8 Oct 2013 18:55:07 +0000 (11:55 -0700)
Rillke has been amazing and provided us with a first pass at a file URL
parser for MediaWiki:

https://commons.wikimedia.org/wiki/MediaWiki:Gadget-libUtil.js

Hoping to use this for Extension:MultimediaViewer and others in the near
future - potentially replacing patchset Ib69d1ffdfd3b58c2e8e3314940a2cad311b85533

Also tests.

Change-Id: Ie31e6df376bda087e92ec889d54df3374ba96b5e

resources/mediawiki/mediawiki.Title.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js

index 98277fc..92023a5 100644 (file)
                return t;
        };
 
+       /**
+        * Get the file title from an image element
+        *
+        *     var title = mw.Title.newFromImg( $( 'img:first' ) );
+        *
+        * @static
+        * @param {HTMLImageElement|jQuery} img The image to use as a base.
+        * @return {mw.Title|null} The file title - null if unsuccessful.
+        */
+       Title.newFromImg = function ( img ) {
+               var matches, i, regex, src, decodedSrc,
+
+                       // thumb.php-generated thumbnails
+                       thumbPhpRegex = /thumb\.php/,
+
+                       regexes = [
+                               // Thumbnails
+                               /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s\/]+)\/[0-9]+px-\1[^\s\/]*$/,
+
+                               // Thumbnails in non-hashed upload directories
+                               /\/([^\s\/]+)\/[0-9]+px-\1[^\s\/]*$/,
+
+                               // Full size images
+                               /\/[a-f0-9]\/[a-f0-9]{2}\/([^\s\/]+)$/,
+
+                               // Full-size images in non-hashed upload directories
+                               /\/([^\s\/]+)$/
+                       ],
+
+                       recount = regexes.length;
+
+               img = img.jquery ? img.get( 0 ) : img;
+
+               src = img.src;
+
+               matches = src.match( thumbPhpRegex );
+
+               if ( matches ) {
+                       return mw.Title.newFromText( 'File:' + mw.util.getParamValue( 'f', src ) );
+               }
+
+               decodedSrc = decodeURIComponent( src );
+
+               for ( i = 0; i < recount; i++ ) {
+                       regex = regexes[i];
+                       matches = decodedSrc.match( regex );
+
+                       if ( matches && matches[1] ) {
+                               return mw.Title.newFromText( 'File:' + matches[1] );
+                       }
+               }
+
+               return null;
+       };
+
        /**
         * Whether this title exists on the wiki.
         *
index e6bbe1e..ba15fba 100644 (file)
                assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
        } );
 
+       QUnit.test( 'newFromImg', 28, function ( assert ) {
+               var title, i, thisCase, prefix,
+                       cases = [
+                               {
+                                       url: '/wiki/images/thumb/9/91/Anticlockwise_heliotrope%27s.jpg/99px-Anticlockwise_heliotrope%27s.jpg',
+                                       typeOfUrl: 'Normal hashed directory thumbnail',
+                                       nameText: 'Anticlockwise heliotrope\'s',
+                                       prefixedText: 'File:Anticlockwise heliotrope\'s.jpg'
+                               },
+
+                               {
+                                       url: '//upload.wikimedia.org/wikipedia/commons/thumb/8/80/Wikipedia-logo-v2.svg/150px-Wikipedia-logo-v2.svg.png',
+                                       typeOfUrl: 'Commons thumbnail',
+                                       nameText: 'Wikipedia-logo-v2',
+                                       prefixedText: 'File:Wikipedia-logo-v2.svg'
+                               },
+
+                               {
+                                       url: '/wiki/images/9/91/Anticlockwise_heliotrope%27s.jpg',
+                                       typeOfUrl: 'Full image',
+                                       nameText: 'Anticlockwise heliotrope\'s',
+                                       prefixedText: 'File:Anticlockwise heliotrope\'s.jpg'
+                               },
+
+                               {
+                                       url: 'http://localhost/thumb.php?f=Stuffless_Figaro%27s.jpg&width=180',
+                                       typeOfUrl: 'thumb.php-based thumbnail',
+                                       nameText: 'Stuffless Figaro\'s',
+                                       prefixedText: 'File:Stuffless Figaro\'s.jpg'
+                               },
+
+                               {
+                                       url: '/wikipedia/commons/thumb/Wikipedia-logo-v2.svg/150px-Wikipedia-logo-v2.svg.png',
+                                       typeOfUrl: 'Commons unhashed thumbnail',
+                                       nameText: 'Wikipedia-logo-v2',
+                                       prefixedText: 'File:Wikipedia-logo-v2.svg'
+                               },
+
+                               {
+                                       url: '/wiki/images/Anticlockwise_heliotrope%27s.jpg',
+                                       typeOfUrl: 'Unhashed local file',
+                                       nameText: 'Anticlockwise heliotrope\'s',
+                                       prefixedText: 'File:Anticlockwise heliotrope\'s.jpg'
+                               },
+
+                               {
+                                       url: '',
+                                       typeOfUrl: 'Empty string'
+                               },
+
+                               {
+                                       url: 'foo',
+                                       typeOfUrl: 'String with only alphabet characters'
+                               },
+
+                               {
+                                       url: 'foobar.foobar',
+                                       typeOfUrl: 'Not a file path'
+                               },
+
+                               {
+                                       url: '/a/a0/blah blah blah',
+                                       typeOfUrl: 'Space characters'
+                               }
+                       ];
+
+               for ( i = 0; i < cases.length; i++ ) {
+                       thisCase = cases[i];
+                       title = mw.Title.newFromImg( { src: thisCase.url } );
+
+                       if ( thisCase.nameText !== undefined ) {
+                               prefix = '[' + thisCase.typeOfUrl + ' URL' + '] ';
+
+                               assert.notStrictEqual( title, null, prefix + 'Parses successfully' );
+                               assert.equal( title.getNameText(), thisCase.nameText, prefix + 'Filename matches original' );
+                               assert.equal( title.getPrefixedText(), thisCase.prefixedText, prefix + 'File page title matches original' );
+                               assert.equal( title.getNamespaceId(), 6, prefix + 'Namespace ID matches File namespace' );
+                       } else {
+                               assert.strictEqual( title, null, thisCase.typeOfUrl + ', should not produce an mw.Title object' );
+                       }
+               }
+       } );
+
 }( mediaWiki, jQuery ) );