From: Bartosz DziewoƄski Date: Tue, 22 Dec 2015 17:56:07 +0000 (+0100) Subject: mw.Title: Implement #makeTitle for titles with predefined namespace X-Git-Tag: 1.31.0-rc.0~8275^2 X-Git-Url: https://git.cyclocoop.org/%28%28?a=commitdiff_plain;h=3d14628237800d4e6b6a7f1322a5a756fb86ce8b;p=lhc%2Fweb%2Fwiklou.git mw.Title: Implement #makeTitle for titles with predefined namespace Unlike #newFromText or the constructor, this function doesn't allow the given `namespace` to be overridden by a namespace prefix in `title`. Name was chosen to match the PHP function Title::makeTitle(). (There's no need for a #makeTitleSafe variant, because #makeTitle is already "safe" and checks title validity.) Change-Id: Ib78dbcb0910bf1458b842b4d9ece6d204761b202 --- diff --git a/resources/src/mediawiki/mediawiki.Title.js b/resources/src/mediawiki/mediawiki.Title.js index 47250eea0a..a727a78d13 100644 --- a/resources/src/mediawiki/mediawiki.Title.js +++ b/resources/src/mediawiki/mediawiki.Title.js @@ -6,6 +6,7 @@ ( function ( mw, $ ) { /*jshint latedef:false */ + // jscs:disable jsDoc /** * @class mw.Title * @@ -14,6 +15,23 @@ * 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 @@ return this; } + // jscs:enable jsDoc /* Private members */ @@ -116,6 +135,18 @@ 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 = /^(.+?)_*:_*(.*)$/, @@ -212,7 +243,7 @@ ], /** - * Internal helper for #constructor and #newFromtext. + * Internal helper for #constructor and #newFromText. * * Based on Title.php#secureAndSplit * @@ -452,6 +483,10 @@ /** * 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 @@ -472,6 +507,24 @@ 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 @@ -761,9 +814,7 @@ * @return {string} */ getNamespacePrefix: function () { - return this.namespace === NS_MAIN ? - '' : - ( mw.config.get( 'wgFormattedNamespaces' )[ this.namespace ].replace( / /g, '_' ) + ':' ); + return getNamespacePrefix( this.namespace ); }, /** diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js b/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js index 4bcb12e6ae..e650ea2946 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.Title.test.js @@ -165,6 +165,32 @@ } } ); + 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' );