Index: trunk/phase3/tests/qunit/suites/resources/mediawiki/mediawiki.Title.js |
— | — | @@ -63,76 +63,56 @@ |
64 | 64 | ok( mw.Title, 'mw.Title defined' ); |
65 | 65 | }); |
66 | 66 | |
67 | | -test( 'Filename', function() { |
68 | | - expect(4); |
| 67 | +test( 'Transform between Text and Db', function() { |
| 68 | + expect(2); |
69 | 69 | _titleConfig(); |
70 | 70 | |
71 | | - var title = new mw.Title( 'File:foo_bar.JPG' ); |
| 71 | + var title; |
72 | 72 | |
73 | | - equal( title.getMain(), 'Foo_bar.jpg' ); |
74 | | - equal( title.getMainText(), 'Foo bar.jpg' ); |
75 | | - equal( title.getNameText(), 'Foo bar' ); |
76 | | - equal( title.toString(), 'File:Foo_bar.jpg' ); |
| 73 | + title = new mw.Title( 'File:quux pif.jpg' ); |
| 74 | + equal( title.getName(), 'Quux_pif' ); |
| 75 | + |
| 76 | + title = new mw.Title( 'File:Glarg_foo_glang.jpg' ); |
| 77 | + equal( title.getNameText(), 'Glarg foo glang' ); |
77 | 78 | }); |
78 | 79 | |
79 | | -test( 'Transform between Text to Db', function() { |
80 | | - expect(6); |
| 80 | +test( 'Main text for filename', function() { |
| 81 | + expect(8); |
81 | 82 | _titleConfig(); |
82 | 83 | |
83 | 84 | var title = new mw.Title( 'File:foo_bar.JPG' ); |
84 | | - title.setName( 'quux pif' ); |
85 | 85 | |
86 | | - equal( title.getMain(), 'Quux_pif.jpg' ); |
87 | | - equal( title.getMainText(), 'Quux pif.jpg' ); |
88 | | - equal( title.getNameText(), 'Quux pif' ); |
89 | | - equal( title.toString(), 'File:Quux_pif.jpg' ); |
90 | | - |
91 | | - title.setName( 'glarg_foo_glang' ); |
92 | | - |
93 | | - equal( title.toString(), 'File:Glarg_foo_glang.jpg' ); |
94 | | - equal( title.getMainText(), 'Glarg foo glang.jpg' ); |
| 86 | + equal( title.getNamespaceId(), 6 ); |
| 87 | + equal( title.getNamespacePrefix(), 'File:' ); |
| 88 | + equal( title.getName(), 'Foo_bar' ); |
| 89 | + equal( title.getNameText(), 'Foo bar' ); |
| 90 | + equal( title.getMain(), 'Foo_bar.jpg' ); |
| 91 | + equal( title.getMainText(), 'Foo bar.jpg' ); |
| 92 | + equal( title.getExtension(), 'jpg' ); |
| 93 | + equal( title.getDotExtension(), '.jpg' ); |
95 | 94 | }); |
96 | 95 | |
97 | | -test( 'Initiate from name and set namespace', function() { |
98 | | - expect(1); |
99 | | - _titleConfig(); |
100 | | - |
101 | | - var title = new mw.Title( 'catalonian_penguins.PNG' ); |
102 | | - title.setNamespace( 'file' ); |
103 | | - equal( title.toString(), 'File:Catalonian_penguins.png' ); |
104 | | -}); |
105 | | - |
106 | 96 | test( 'Namespace detection and conversion', function() { |
107 | | - expect(7); |
| 97 | + expect(6); |
108 | 98 | _titleConfig(); |
109 | 99 | |
110 | 100 | var title; |
111 | 101 | |
112 | | - title = new mw.Title( 'something.PDF' ); |
113 | | - title.setNamespace( 'file' ); |
| 102 | + title = new mw.Title( 'something.PDF', 6 ); |
114 | 103 | equal( title.toString(), 'File:Something.pdf' ); |
115 | 104 | |
116 | | - title = new mw.Title( 'NeilK' ); |
117 | | - title.setNamespace( 'user_talk' ); |
| 105 | + title = new mw.Title( 'NeilK', 3 ); |
118 | 106 | equal( title.toString(), 'User_talk:NeilK' ); |
119 | 107 | equal( title.toText(), 'User talk:NeilK' ); |
120 | 108 | |
121 | | - title = new mw.Title( 'Frobisher' ); |
122 | | - title.setNamespaceById( 100 ); |
| 109 | + title = new mw.Title( 'Frobisher', 100 ); |
123 | 110 | equal( title.toString(), 'Penguins:Frobisher' ); |
124 | 111 | |
125 | | - title = new mw.Title( 'flightless_yet_cute.jpg' ); |
126 | | - title.setNamespace( 'antarctic_waterfowl' ); |
| 112 | + title = new mw.Title( 'antarctic_waterfowl:flightless_yet_cute.jpg' ); |
127 | 113 | equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' ); |
128 | 114 | |
129 | | - title = new mw.Title( 'flightless_yet_cute.jpg' ); |
130 | | - title.setNamespace( 'Penguins' ); |
| 115 | + title = new mw.Title( 'Penguins:flightless_yet_cute.jpg' ); |
131 | 116 | equal( title.toString(), 'Penguins:Flightless_yet_cute.jpg' ); |
132 | | - |
133 | | - title = new mw.Title( 'flightless_yet_cute.jpg' ); |
134 | | - raises( function() { |
135 | | - title.setNamespace( 'Entirely Unknown' ); |
136 | | - }); |
137 | 117 | }); |
138 | 118 | |
139 | 119 | test( 'Case-sensivity', function() { |
— | — | @@ -157,6 +137,16 @@ |
158 | 138 | equal( title.toString(), 'User:John', '$wgCapitalLinks=false: User namespace is insensitive, first-letter becomes uppercase' ); |
159 | 139 | }); |
160 | 140 | |
| 141 | +test( 'toString / toText', function() { |
| 142 | + expect(2); |
| 143 | + _titleConfig(); |
| 144 | + |
| 145 | + var title = new mw.Title( 'Some random page' ); |
| 146 | + |
| 147 | + equal( title.toString(), title.getPrefixedDb() ); |
| 148 | + equal( title.toText(), title.getPrefixedText() ); |
| 149 | +}); |
| 150 | + |
161 | 151 | test( 'Exists', function() { |
162 | 152 | expect(3); |
163 | 153 | _titleConfig(); |
Index: trunk/phase3/resources/mediawiki/mediawiki.Title.js |
— | — | @@ -7,7 +7,7 @@ |
8 | 8 | * |
9 | 9 | * Relies on: mw.config (wgFormattedNamespaces, wgNamespaceIds, wgCaseSensitiveNamespaces), mw.util.wikiGetlink |
10 | 10 | */ |
11 | | -(function( $ ) { |
| 11 | +( function( $ ) { |
12 | 12 | |
13 | 13 | /* Local space */ |
14 | 14 | |
— | — | @@ -26,15 +26,10 @@ |
27 | 27 | this._ext = null; // extension |
28 | 28 | |
29 | 29 | if ( arguments.length === 2 ) { |
30 | | - this.setNameAndExtension( title ).setNamespaceById( namespace ); |
| 30 | + setNameAndExtension( this, title ); |
| 31 | + this._ns = fixNsId( namespace ); |
31 | 32 | } else if ( arguments.length === 1 ) { |
32 | | - // If title is like "Blabla: Hello" ignore exception by setNamespace(), |
33 | | - // and instead assume NS_MAIN and keep prefix |
34 | | - try { |
35 | | - this.setAll( title ); |
36 | | - } catch(e) { |
37 | | - this.setNameAndExtension( title ); |
38 | | - } |
| 33 | + setAll( this, title ); |
39 | 34 | } |
40 | 35 | return this; |
41 | 36 | }, |
— | — | @@ -63,7 +58,100 @@ |
64 | 59 | } else { |
65 | 60 | return ''; |
66 | 61 | } |
| 62 | + }, |
| 63 | + |
| 64 | + /** |
| 65 | + * Sanatize name. |
| 66 | + */ |
| 67 | + fixName = function( s ) { |
| 68 | + return clean( $.trim( s ) ); |
| 69 | + }, |
| 70 | + |
| 71 | + /** |
| 72 | + * Sanatize name. |
| 73 | + */ |
| 74 | + fixExt = function( s ) { |
| 75 | + return clean( s.toLowerCase() ); |
| 76 | + }, |
| 77 | + |
| 78 | + /** |
| 79 | + * Sanatize namespace id. |
| 80 | + * @param id {Number} Namespace id. |
| 81 | + * @return {Number|Boolean} The id as-is or boolean false if invalid. |
| 82 | + */ |
| 83 | + fixNsId = function( id ) { |
| 84 | + // wgFormattedNamespaces is an object of *string* key-vals (ie. arr["0"] not arr[0] ) |
| 85 | + var ns = mw.config.get( 'wgFormattedNamespaces' )[id.toString()]; |
| 86 | + |
| 87 | + // Check only undefined (may be false-y, such as '' (main namespace) ). |
| 88 | + if ( ns === undefined ) { |
| 89 | + return false; |
| 90 | + } else { |
| 91 | + return Number( id ); |
| 92 | + } |
| 93 | + }, |
| 94 | + |
| 95 | + /** |
| 96 | + * Get namespace id from namespace name by any known namespace/id pair (localized, canonical or alias). |
| 97 | + * |
| 98 | + * @example On a German wiki this would return 6 for any of 'File', 'Datei', 'Image' or even 'Bild'. |
| 99 | + * @param ns {String} Namespace name (case insensitive, leading/trailing space ignored). |
| 100 | + * @return {Number|Boolean} Namespace id or boolean false if unrecognized. |
| 101 | + */ |
| 102 | + getNsIdByName = function( ns ) { |
| 103 | + // toLowerCase throws exception on null/undefined. Return early. |
| 104 | + if ( ns == null ) { |
| 105 | + return false; |
| 106 | + } |
| 107 | + ns = clean( $.trim( ns.toLowerCase() ) ); // Normalize |
| 108 | + var id = mw.config.get( 'wgNamespaceIds' )[ns]; |
| 109 | + if ( id === undefined ) { |
| 110 | + mw.log( 'mw.Title: Unrecognized namespace: ' + ns ); |
| 111 | + return false; |
| 112 | + } |
| 113 | + return fixNsId( id ); |
| 114 | + }, |
| 115 | + |
| 116 | + /** |
| 117 | + * Helper to extract namespace, name and extension from a string. |
| 118 | + * |
| 119 | + * @param title {mw.Title} |
| 120 | + * @param raw {String} |
| 121 | + * @return {mw.Title} |
| 122 | + */ |
| 123 | + setAll = function( title, s ) { |
| 124 | + var matches = s.match( /^(?:([^:]+):)?(.*?)(?:\.(\w{1,5}))?$/ ); |
| 125 | + ns_match = getNsIdByName( matches[1] ); |
| 126 | + if ( matches.length && ns_match ) { |
| 127 | + if ( matches[1] ) { title._ns = ns_match; } |
| 128 | + if ( matches[2] ) { title._name = fixName( matches[2] ); } |
| 129 | + if ( matches[3] ) { title._ext = fixExt( matches[3] ); } |
| 130 | + } else { |
| 131 | + // Consistency with MediaWiki: Unknown namespace > fallback to main namespace. |
| 132 | + title._ns = 0; |
| 133 | + setNameAndExtension( title, s ); |
| 134 | + } |
| 135 | + return title; |
| 136 | + }, |
| 137 | + |
| 138 | + /** |
| 139 | + * Helper to extract name and extension from a string. |
| 140 | + * |
| 141 | + * @param title {mw.Title} |
| 142 | + * @param raw {String} |
| 143 | + * @return {mw.Title} |
| 144 | + */ |
| 145 | + setNameAndExtension = function( title, raw ) { |
| 146 | + var matches = raw.match( /^(?:)?(.*?)(?:\.(\w{1,5}))?$/ ); |
| 147 | + if ( matches.length ) { |
| 148 | + if ( matches[1] ) { title._name = fixName( matches[1] ); } |
| 149 | + if ( matches[2] ) { title._ext = fixExt( matches[2] ); } |
| 150 | + } else { |
| 151 | + throw new Error( 'mw.Title: Could not parse title "' + raw + '"' ); |
| 152 | + } |
| 153 | + return title; |
67 | 154 | }; |
| 155 | + |
68 | 156 | |
69 | 157 | /* Static space */ |
70 | 158 | |
— | — | @@ -118,39 +206,8 @@ |
119 | 207 | |
120 | 208 | var fn = { |
121 | 209 | constructor: Title, |
122 | | - /** |
123 | | - * @param id {Number} Canonical namespace id. |
124 | | - * @return {mw.Title} this |
125 | | - */ |
126 | | - setNamespaceById: function( id ) { |
127 | | - // wgFormattedNamespaces is an object of *string* key-vals, |
128 | | - var ns = mw.config.get( 'wgFormattedNamespaces' )[id.toString()]; |
129 | 210 | |
130 | | - // Cannot cast to boolean, ns may be '' (main namespace) |
131 | | - if ( ns === undefined ) { |
132 | | - this._ns = false; |
133 | | - } else { |
134 | | - this._ns = Number( id ); |
135 | | - } |
136 | | - return this; |
137 | | - }, |
138 | | - |
139 | 211 | /** |
140 | | - * Set namespace by any known namespace/id pair (localized, canonical or alias) |
141 | | - * On a German wiki this could be 'File', 'Datei', 'Image' or even 'Bild' for NS_FILE. |
142 | | - * @param ns {String} A namespace name (case insensitive, space insensitive) |
143 | | - * @return {mw.Title} this |
144 | | - */ |
145 | | - setNamespace: function( ns ) { |
146 | | - ns = clean( $.trim( ns.toLowerCase() ) ); // Normalize |
147 | | - var id = mw.config.get( 'wgNamespaceIds' )[ns]; |
148 | | - if ( id === undefined ) { |
149 | | - throw new Error( 'mw.Title: Unrecognized canonical namespace: ' + ns ); |
150 | | - } |
151 | | - return this.setNamespaceById( id ); |
152 | | - }, |
153 | | - |
154 | | - /** |
155 | 212 | * Get the namespace number. |
156 | 213 | * @return {Number} |
157 | 214 | */ |
— | — | @@ -168,16 +225,6 @@ |
169 | 226 | }, |
170 | 227 | |
171 | 228 | /** |
172 | | - * Set the "name" portion, removing illegal characters. |
173 | | - * @param s {String} Page name (without namespace prefix) |
174 | | - * @return {mw.Title} this |
175 | | - */ |
176 | | - setName: function( s ) { |
177 | | - this._name = clean( $.trim( s ) ); |
178 | | - return this; |
179 | | - }, |
180 | | - |
181 | | - /** |
182 | 229 | * The name, like "Foo_bar" |
183 | 230 | * @return {String} |
184 | 231 | */ |
— | — | @@ -230,16 +277,6 @@ |
231 | 278 | }, |
232 | 279 | |
233 | 280 | /** |
234 | | - * Set the "extension" portion, removing illegal characters. |
235 | | - * @param s {String} |
236 | | - * @return {mw.Title} this |
237 | | - */ |
238 | | - setExtension: function( s ) { |
239 | | - this._ext = clean( s.toLowerCase() ); |
240 | | - return this; |
241 | | - }, |
242 | | - |
243 | | - /** |
244 | 281 | * Get the extension (returns null if there was none) |
245 | 282 | * @return {String|null} extension |
246 | 283 | */ |
— | — | @@ -256,37 +293,6 @@ |
257 | 294 | }, |
258 | 295 | |
259 | 296 | /** |
260 | | - * @param s {String} |
261 | | - * @return {mw.Title} this |
262 | | - */ |
263 | | - setAll: function( s ) { |
264 | | - var matches = s.match( /^(?:([^:]+):)?(.*?)(?:\.(\w{1,5}))?$/ ); |
265 | | - if ( matches.length ) { |
266 | | - if ( matches[1] ) { this.setNamespace( matches[1] ); } |
267 | | - if ( matches[2] ) { this.setName( matches[2] ); } |
268 | | - if ( matches[3] ) { this.setExtension( matches[3] ); } |
269 | | - } else { |
270 | | - throw new Error( 'mw.Title: Could not parse title "' + s + '"' ); |
271 | | - } |
272 | | - return this; |
273 | | - }, |
274 | | - |
275 | | - /** |
276 | | - * @param s {String} |
277 | | - * @return {mw.Title} this |
278 | | - */ |
279 | | - setNameAndExtension: function( s ) { |
280 | | - var matches = s.match( /^(?:)?(.*?)(?:\.(\w{1,5}))?$/ ); |
281 | | - if ( matches.length ) { |
282 | | - if ( matches[1] ) { this.setName( matches[1] ); } |
283 | | - if ( matches[2] ) { this.setExtension( matches[2] ); } |
284 | | - } else { |
285 | | - throw new Error( 'mw.Title: Could not parse title "' + s + '"' ); |
286 | | - } |
287 | | - return this; |
288 | | - }, |
289 | | - |
290 | | - /** |
291 | 297 | * Return the URL to this title |
292 | 298 | * @return {String} |
293 | 299 | */ |