This patch also does:
* Fix the behavior for filenames that have a dot, but no file
extension after the dot.
* Add missing test cases.
It seems like this method is barely used anywhere:
https://codesearch.wmflabs.org/search/?q=newFromUserInput&i=1
So we might as well remove it, and inline simplified versions that
only do exactly the normalizations that are needed. For example,
silently stripping leading colons is a somewhat suprising thing to
do. Shouldn't such a title be invalid, instead of silently being
converted to something else? But this is unrelated to what this
patch does.
Change-Id: I1596fb0d9d02ca230a37f3d70d65296d6ce4ddb4
* @return {mw.Title|null} A valid Title object or null if the input cannot be turned into a valid title
*/
Title.newFromUserInput = function ( title, defaultNamespaceOrOptions, options ) {
* @return {mw.Title|null} A valid Title object or null if the input cannot be turned into a valid title
*/
Title.newFromUserInput = function ( title, defaultNamespaceOrOptions, options ) {
- var namespace, m, id, ext, parts,
+ var namespace, m, id, ext, lastDot,
defaultNamespace;
// defaultNamespace is optional; check whether options moves up
defaultNamespace;
// defaultNamespace is optional; check whether options moves up
namespace === NS_MEDIA ||
( options.forUploading && ( namespace === NS_FILE ) )
) {
namespace === NS_MEDIA ||
( options.forUploading && ( namespace === NS_FILE ) )
) {
title = sanitize( title, [ 'generalRule', 'fileRule' ] );
// Operate on the file extension
// Although it is possible having spaces between the name and the ".ext" this isn't nice for
// operating systems hiding file extensions -> strip them later on
title = sanitize( title, [ 'generalRule', 'fileRule' ] );
// Operate on the file extension
// Although it is possible having spaces between the name and the ".ext" this isn't nice for
// operating systems hiding file extensions -> strip them later on
- parts = title.split( '.' );
-
- if ( parts.length > 1 ) {
-
- // Get the last part, which is supposed to be the file extension
- ext = parts.pop();
+ lastDot = title.lastIndexOf( '.' );
- // Remove whitespace of the name part (that W/O extension)
- title = parts.join( '.' ).trim();
-
- // Cut, if too long and append file extension
- title = trimFileNameToByteLength( title, ext );
+ // No or empty file extension
+ if ( lastDot === -1 || lastDot >= title.length - 1 ) {
+ return null;
+ }
+ // Get the last part, which is supposed to be the file extension
+ ext = title.slice( lastDot + 1 );
- // Missing file extension
- title = parts.join( '.' ).trim();
+ // Remove whitespace of the name part (that without extension)
+ title = title.slice( 0, lastDot ).trim();
- // Name has no file extension and a fallback wasn't provided either
- return null;
- }
+ // Cut, if too long and append file extension
+ title = trimFileNameToByteLength( title, ext );
title = sanitize( title, [ 'generalRule' ] );
// Cut titles exceeding the TITLE_MAX_BYTES byte size limit
title = sanitize( title, [ 'generalRule' ] );
// Cut titles exceeding the TITLE_MAX_BYTES byte size limit
title: 'File:Foo.JPEG ',
expected: 'File:Foo.JPEG',
description: 'Page in File-namespace with trailing whitespace'
title: 'File:Foo.JPEG ',
expected: 'File:Foo.JPEG',
description: 'Page in File-namespace with trailing whitespace'
+ },
+ {
+ title: 'File:Foo',
+ description: 'File name without file extension'
+ },
+ {
+ title: 'File:Foo.',
+ description: 'File name with empty file extension'