Merge "mw.Title: Implement #makeTitle for titles with predefined namespace"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Wed, 20 Jan 2016 19:38:46 +0000 (19:38 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Wed, 20 Jan 2016 19:38:46 +0000 (19:38 +0000)
1  2 
resources/src/mediawiki/mediawiki.Title.js
tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js

@@@ -6,6 -6,7 +6,7 @@@
  ( function ( mw, $ ) {
        /*jshint latedef:false */
  
+       // jscs:disable jsDoc
        /**
         * @class mw.Title
         *
         * logic directly and get null for invalid titles which is easier to work with.
         *
         * @constructor
+        *
+        * Note that in the constructor amd #newFromText method, `namespace` is the **default** namespace
+        * only, and can be overridden by a namespace prefix in `title`. If you do not want this behavior,
+        * use #makeTitle. Compare:
+        *
+        *     new mw.Title( 'Foo', NS_TEMPLATE ).getPrefixedText();                  // => 'Template:Foo'
+        *     mw.Title.newFromText( 'Foo', NS_TEMPLATE ).getPrefixedText();          // => 'Template:Foo'
+        *     mw.Title.makeTitle( NS_TEMPLATE, 'Foo' ).getPrefixedText();            // => 'Template:Foo'
+        *
+        *     new mw.Title( 'Category:Foo', NS_TEMPLATE ).getPrefixedText();         // => 'Category:Foo'
+        *     mw.Title.newFromText( 'Category:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Category:Foo'
+        *     mw.Title.makeTitle( NS_TEMPLATE, 'Category:Foo' ).getPrefixedText();   // => 'Template:Category:Foo'
+        *
+        *     new mw.Title( 'Template:Foo', NS_TEMPLATE ).getPrefixedText();         // => 'Template:Foo'
+        *     mw.Title.newFromText( 'Template:Foo', NS_TEMPLATE ).getPrefixedText(); // => 'Template:Foo'
+        *     mw.Title.makeTitle( NS_TEMPLATE, 'Template:Foo' ).getPrefixedText();   // => 'Template:Template:Foo'
+        *
         * @param {string} title Title of the page. If no second argument given,
         *  this will be searched for a namespace
         * @param {number} [namespace=NS_MAIN] If given, will used as default namespace for the given title
@@@ -32,6 -50,7 +50,7 @@@
  
                return this;
        }
+       // jscs:enable jsDoc
  
        /* Private members */
  
                return id;
        },
  
+       /**
+        * @private
+        * @method getNamespacePrefix_
+        * @param {number} namespace
+        * @return {string}
+        */
+       getNamespacePrefix = function ( namespace ) {
+               return namespace === NS_MAIN ?
+                       '' :
+                       ( mw.config.get( 'wgFormattedNamespaces' )[ namespace ].replace( / /g, '_' ) + ':' );
+       },
        rUnderscoreTrim = /^_+|_+$/g,
  
        rSplit = /^(.+?)_*:_*(.*)$/,
        ],
  
        /**
-        * Internal helper for #constructor and #newFromtext.
+        * Internal helper for #constructor and #newFromText.
         *
         * Based on Title.php#secureAndSplit
         *
        /**
         * Constructor for Title objects with a null return instead of an exception for invalid titles.
         *
+        * Note that `namespace` is the **default** namespace only, and can be overridden by a namespace
+        * prefix in `title`. If you do not want this behavior, use #makeTitle. See #constructor for
+        * details.
+        *
         * @static
         * @param {string} title
         * @param {number} [namespace=NS_MAIN] Default namespace
                return t;
        };
  
+       /**
+        * Constructor for Title objects with predefined namespace.
+        *
+        * Unlike #newFromText or #constructor, this function doesn't allow the given `namespace` to be
+        * overridden by a namespace prefix in `title`. See #constructor for details about this behavior.
+        *
+        * The single exception to this is when `namespace` is 0, indicating the main namespace. The
+        * function behaves like #newFromText in that case.
+        *
+        * @static
+        * @param {number} namespace Namespace to use for the title
+        * @param {string} title
+        * @return {mw.Title|null} A valid Title object or null if the title is invalid
+        */
+       Title.makeTitle = function ( namespace, title ) {
+               return mw.Title.newFromText( getNamespacePrefix( namespace ) + title );
+       };
        /**
         * Constructor for Title objects from user input altering that input to
         * produce a title that MediaWiki will accept as legal
                 * @return {string}
                 */
                getNamespacePrefix: function () {
-                       return this.namespace === NS_MAIN ?
-                               '' :
-                               ( mw.config.get( 'wgFormattedNamespaces' )[ this.namespace ].replace( / /g, '_' ) + ':' );
+                       return getNamespacePrefix( this.namespace );
                },
  
                /**
                 * @return {string}
                 */
                getUrl: function ( params ) {
 -                      return mw.util.getUrl( this.toString(), params );
 +                      var fragment = this.getFragment();
 +                      if ( fragment ) {
 +                              return mw.util.getUrl( this.toString() + '#' + this.getFragment(), params );
 +                      } else {
 +                              return mw.util.getUrl( this.toString(), params );
 +                      }
                },
  
                /**
                }
        } );
  
+       QUnit.test( 'makeTitle', 6, function ( assert ) {
+               var cases, i, title, expected,
+                       NS_MAIN = 0,
+                       NS_TALK = 1,
+                       NS_TEMPLATE = 10;
+               cases = [
+                       [ NS_TEMPLATE, 'Foo', 'Template:Foo' ],
+                       [ NS_TEMPLATE, 'Category:Foo', 'Template:Category:Foo' ],
+                       [ NS_TEMPLATE, 'Template:Foo', 'Template:Template:Foo' ],
+                       [ NS_TALK, 'Help:Foo', null ],
+                       [ NS_TEMPLATE, '<', null ],
+                       [ NS_MAIN, 'Help:Foo', 'Help:Foo' ]
+               ];
+               for ( i = 0; i < cases.length; i++ ) {
+                       title = mw.Title.makeTitle( cases[ i ][ 0 ], cases[ i ][ 1 ] );
+                       expected = cases[ i ][ 2 ];
+                       if ( expected === null ) {
+                               assert.strictEqual( title, expected );
+                       } else {
+                               assert.strictEqual( title.getPrefixedText(), expected );
+                       }
+               }
+       } );
        QUnit.test( 'Basic parsing', 21, function ( assert ) {
                var title;
                title = new mw.Title( 'File:Foo_bar.JPG' );
  
        } );
  
 -      QUnit.test( 'getUrl', 3, function ( assert ) {
 +      QUnit.test( 'getUrl', 4, function ( assert ) {
                var title;
  
                // Config
  
                title = new mw.Title( 'John Doe', 3 );
                assert.equal( title.getUrl(), '/wiki/User_talk:John_Doe', 'Escaping in title and namespace for urls' );
 +
 +              title = new mw.Title( 'John Cena#And_His_Name_Is', 3 );
 +              assert.equal( title.getUrl( { meme: true } ), '/wiki/User_talk:John_Cena?meme=true#And_His_Name_Is', 'title with fragment and query parameter' );
        } );
  
        QUnit.test( 'newFromImg', 44, function ( assert ) {