From: Krinkle Date: Tue, 2 Aug 2011 03:11:08 +0000 (+0000) Subject: mediawiki.Title: Removing public setter functions. Title object should be immutable. X-Git-Tag: 1.31.0-rc.0~28501 X-Git-Url: http://git.cyclocoop.org/%7D%7Cconcat%7B?a=commitdiff_plain;h=27152e4da7014fd8457a567d0aaf37fe49f253a2;p=lhc%2Fweb%2Fwiklou.git mediawiki.Title: Removing public setter functions. Title object should be immutable. - To avoid repetition, instead of substituting, changed them to private helper functions - Updated test suite to create new objects for different titles, rather than modifying the existing one. - Adding missing unit tests, now 100% complete according to QUnit CompletnessTest + Test for Title.prototype.getNamespaceId + Test forTitle.prototype.getPrefixedText + Test forTitle.prototype.getExtension Follows-up r90331 CR --- diff --git a/resources/mediawiki/mediawiki.Title.js b/resources/mediawiki/mediawiki.Title.js index 3978d66f31..96292d2241 100644 --- a/resources/mediawiki/mediawiki.Title.js +++ b/resources/mediawiki/mediawiki.Title.js @@ -7,7 +7,7 @@ * * Relies on: mw.config (wgFormattedNamespaces, wgNamespaceIds, wgCaseSensitiveNamespaces), mw.util.wikiGetlink */ -(function( $ ) { +( function( $ ) { /* Local space */ @@ -26,15 +26,10 @@ var Title = function( title, namespace ) { this._ext = null; // extension if ( arguments.length === 2 ) { - this.setNameAndExtension( title ).setNamespaceById( namespace ); + setNameAndExtension( this, title ); + this._ns = fixNsId( namespace ); } else if ( arguments.length === 1 ) { - // If title is like "Blabla: Hello" ignore exception by setNamespace(), - // and instead assume NS_MAIN and keep prefix - try { - this.setAll( title ); - } catch(e) { - this.setNameAndExtension( title ); - } + setAll( this, title ); } return this; }, @@ -63,7 +58,100 @@ var Title = function( title, namespace ) { } else { return ''; } + }, + + /** + * Sanatize name. + */ + fixName = function( s ) { + return clean( $.trim( s ) ); + }, + + /** + * Sanatize name. + */ + fixExt = function( s ) { + return clean( s.toLowerCase() ); + }, + + /** + * Sanatize namespace id. + * @param id {Number} Namespace id. + * @return {Number|Boolean} The id as-is or boolean false if invalid. + */ + fixNsId = function( id ) { + // wgFormattedNamespaces is an object of *string* key-vals (ie. arr["0"] not arr[0] ) + var ns = mw.config.get( 'wgFormattedNamespaces' )[id.toString()]; + + // Check only undefined (may be false-y, such as '' (main namespace) ). + if ( ns === undefined ) { + return false; + } else { + return Number( id ); + } + }, + + /** + * Get namespace id from namespace name by any known namespace/id pair (localized, canonical or alias). + * + * @example On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or even 'Bild'. + * @param ns {String} Namespace name (case insensitive, leading/trailing space ignored). + * @return {Number|Boolean} Namespace id or boolean false if unrecognized. + */ + getNsIdByName = function( ns ) { + // toLowerCase throws exception on null/undefined. Return early. + if ( ns == null ) { + return false; + } + ns = clean( $.trim( ns.toLowerCase() ) ); // Normalize + var id = mw.config.get( 'wgNamespaceIds' )[ns]; + if ( id === undefined ) { + mw.log( 'mw.Title: Unrecognized namespace: ' + ns ); + return false; + } + return fixNsId( id ); + }, + + /** + * Helper to extract namespace, name and extension from a string. + * + * @param title {mw.Title} + * @param raw {String} + * @return {mw.Title} + */ + setAll = function( title, s ) { + var matches = s.match( /^(?:([^:]+):)?(.*?)(?:\.(\w{1,5}))?$/ ); + ns_match = getNsIdByName( matches[1] ); + if ( matches.length && ns_match ) { + if ( matches[1] ) { title._ns = ns_match; } + if ( matches[2] ) { title._name = fixName( matches[2] ); } + if ( matches[3] ) { title._ext = fixExt( matches[3] ); } + } else { + // Consistency with MediaWiki: Unknown namespace > fallback to main namespace. + title._ns = 0; + setNameAndExtension( title, s ); + } + return title; + }, + + /** + * Helper to extract name and extension from a string. + * + * @param title {mw.Title} + * @param raw {String} + * @return {mw.Title} + */ + setNameAndExtension = function( title, raw ) { + var matches = raw.match( /^(?:)?(.*?)(?:\.(\w{1,5}))?$/ ); + if ( matches.length ) { + if ( matches[1] ) { title._name = fixName( matches[1] ); } + if ( matches[2] ) { title._ext = fixExt( matches[2] ); } + } else { + throw new Error( 'mw.Title: Could not parse title "' + raw + '"' ); + } + return title; }; + /* Static space */ @@ -118,37 +206,6 @@ var Title = function( title, namespace ) { var fn = { constructor: Title, - /** - * @param id {Number} Canonical namespace id. - * @return {mw.Title} this - */ - setNamespaceById: function( id ) { - // wgFormattedNamespaces is an object of *string* key-vals, - var ns = mw.config.get( 'wgFormattedNamespaces' )[id.toString()]; - - // Cannot cast to boolean, ns may be '' (main namespace) - if ( ns === undefined ) { - this._ns = false; - } else { - this._ns = Number( id ); - } - return this; - }, - - /** - * Set namespace by any known namespace/id pair (localized, canonical or alias) - * On a German wiki this could be 'File', 'Datei', 'Image' or even 'Bild' for NS_FILE. - * @param ns {String} A namespace name (case insensitive, space insensitive) - * @return {mw.Title} this - */ - setNamespace: function( ns ) { - ns = clean( $.trim( ns.toLowerCase() ) ); // Normalize - var id = mw.config.get( 'wgNamespaceIds' )[ns]; - if ( id === undefined ) { - throw new Error( 'mw.Title: Unrecognized canonical namespace: ' + ns ); - } - return this.setNamespaceById( id ); - }, /** * Get the namespace number. @@ -167,16 +224,6 @@ var Title = function( title, namespace ) { return mw.config.get( 'wgFormattedNamespaces' )[this._ns].replace( / /g, '_' ) + (this._ns === 0 ? '' : ':'); }, - /** - * Set the "name" portion, removing illegal characters. - * @param s {String} Page name (without namespace prefix) - * @return {mw.Title} this - */ - setName: function( s ) { - this._name = clean( $.trim( s ) ); - return this; - }, - /** * The name, like "Foo_bar" * @return {String} @@ -229,16 +276,6 @@ var Title = function( title, namespace ) { return text( this.getMain() ); }, - /** - * Set the "extension" portion, removing illegal characters. - * @param s {String} - * @return {mw.Title} this - */ - setExtension: function( s ) { - this._ext = clean( s.toLowerCase() ); - return this; - }, - /** * Get the extension (returns null if there was none) * @return {String|null} extension @@ -255,37 +292,6 @@ var Title = function( title, namespace ) { return this._ext === null ? '' : '.' + this._ext; }, - /** - * @param s {String} - * @return {mw.Title} this - */ - setAll: function( s ) { - var matches = s.match( /^(?:([^:]+):)?(.*?)(?:\.(\w{1,5}))?$/ ); - if ( matches.length ) { - if ( matches[1] ) { this.setNamespace( matches[1] ); } - if ( matches[2] ) { this.setName( matches[2] ); } - if ( matches[3] ) { this.setExtension( matches[3] ); } - } else { - throw new Error( 'mw.Title: Could not parse title "' + s + '"' ); - } - return this; - }, - - /** - * @param s {String} - * @return {mw.Title} this - */ - setNameAndExtension: function( s ) { - var matches = s.match( /^(?:)?(.*?)(?:\.(\w{1,5}))?$/ ); - if ( matches.length ) { - if ( matches[1] ) { this.setName( matches[1] ); } - if ( matches[2] ) { this.setExtension( matches[2] ); } - } else { - throw new Error( 'mw.Title: Could not parse title "' + s + '"' ); - } - return this; - }, - /** * Return the URL to this title * @return {String} diff --git a/tests/qunit/suites/resources/mediawiki/mediawiki.Title.js b/tests/qunit/suites/resources/mediawiki/mediawiki.Title.js index b873e7f278..82a1ebc398 100644 --- a/tests/qunit/suites/resources/mediawiki/mediawiki.Title.js +++ b/tests/qunit/suites/resources/mediawiki/mediawiki.Title.js @@ -63,76 +63,56 @@ test( '-- Initial check', function() { ok( mw.Title, 'mw.Title defined' ); }); -test( 'Filename', function() { - expect(4); +test( 'Transform between Text and Db', function() { + expect(2); _titleConfig(); - var title = new mw.Title( 'File:foo_bar.JPG' ); + var title; - equal( title.getMain(), 'Foo_bar.jpg' ); - equal( title.getMainText(), 'Foo bar.jpg' ); - equal( title.getNameText(), 'Foo bar' ); - equal( title.toString(), 'File:Foo_bar.jpg' ); + title = new mw.Title( 'File:quux pif.jpg' ); + equal( title.getName(), 'Quux_pif' ); + + title = new mw.Title( 'File:Glarg_foo_glang.jpg' ); + equal( title.getNameText(), 'Glarg foo glang' ); }); -test( 'Transform between Text to Db', function() { - expect(6); +test( 'Main text for filename', function() { + expect(8); _titleConfig(); var title = new mw.Title( 'File:foo_bar.JPG' ); - title.setName( 'quux pif' ); - - equal( title.getMain(), 'Quux_pif.jpg' ); - equal( title.getMainText(), 'Quux pif.jpg' ); - equal( title.getNameText(), 'Quux pif' ); - equal( title.toString(), 'File:Quux_pif.jpg' ); - title.setName( 'glarg_foo_glang' ); - - equal( title.toString(), 'File:Glarg_foo_glang.jpg' ); - equal( title.getMainText(), 'Glarg foo glang.jpg' ); -}); - -test( 'Initiate from name and set namespace', function() { - expect(1); - _titleConfig(); - - var title = new mw.Title( 'catalonian_penguins.PNG' ); - title.setNamespace( 'file' ); - equal( title.toString(), 'File:Catalonian_penguins.png' ); + equal( title.getNamespaceId(), 6 ); + equal( title.getNamespacePrefix(), 'File:' ); + equal( title.getName(), 'Foo_bar' ); + equal( title.getNameText(), 'Foo bar' ); + equal( title.getMain(), 'Foo_bar.jpg' ); + equal( title.getMainText(), 'Foo bar.jpg' ); + equal( title.getExtension(), 'jpg' ); + equal( title.getDotExtension(), '.jpg' ); }); test( 'Namespace detection and conversion', function() { - expect(7); + expect(6); _titleConfig(); var title; - title = new mw.Title( 'something.PDF' ); - title.setNamespace( 'file' ); + title = new mw.Title( 'something.PDF', 6 ); equal( title.toString(), 'File:Something.pdf' ); - title = new mw.Title( 'NeilK' ); - title.setNamespace( 'user_talk' ); + title = new mw.Title( 'NeilK', 3 ); equal( title.toString(), 'User_talk:NeilK' ); equal( title.toText(), 'User talk:NeilK' ); - title = new mw.Title( 'Frobisher' ); - title.setNamespaceById( 100 ); + title = new mw.Title( 'Frobisher', 100 ); equal( title.toString(), 'Penguins:Frobisher' ); - title = new mw.Title( 'flightless_yet_cute.jpg' ); - title.setNamespace( 'antarctic_waterfowl' ); + title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' ); equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' ); - title = new mw.Title( 'flightless_yet_cute.jpg' ); - title.setNamespace( 'Penguins' ); + title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' ); equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' ); - - title = new mw.Title( 'flightless_yet_cute.jpg' ); - raises( function() { - title.setNamespace( 'Entirely Unknown' ); - }); }); test( 'Case-sensivity', function() { @@ -157,6 +137,16 @@ test( 'Case-sensivity', function() { equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' ); }); +test( 'toString / toText', function() { + expect(2); + _titleConfig(); + + var title = new mw.Title( 'Some random page' ); + + equal( title.toString(), title.getPrefixedDb() ); + equal( title.toText(), title.getPrefixedText() ); +}); + test( 'Exists', function() { expect(3); _titleConfig();