diff options
Diffstat (limited to 'www/wiki/extensions/UploadWizard/resources/details/uw.TitleDetailsWidget.js')
-rw-r--r-- | www/wiki/extensions/UploadWizard/resources/details/uw.TitleDetailsWidget.js | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/www/wiki/extensions/UploadWizard/resources/details/uw.TitleDetailsWidget.js b/www/wiki/extensions/UploadWizard/resources/details/uw.TitleDetailsWidget.js new file mode 100644 index 00000000..99a8dc6e --- /dev/null +++ b/www/wiki/extensions/UploadWizard/resources/details/uw.TitleDetailsWidget.js @@ -0,0 +1,231 @@ +( function ( mw, uw, $, OO ) { + + var NS_FILE = mw.config.get( 'wgNamespaceIds' ).file; + + /** + * A title field in UploadWizard's "Details" step form. + * + * @class uw.TitleDetailsWidget + * @extends uw.DetailsWidget + * @constructor + * @param {Object} [config] + */ + uw.TitleDetailsWidget = function UWTitleDetailsWidget( config ) { + config = config || {}; + uw.TitleDetailsWidget.parent.call( this ); + + this.extension = config.extension; + // We wouldn't want or use any of mw.widgets.TitleInputWidget functionality. + this.titleInput = new OO.ui.TextInputWidget( { + classes: [ 'mwe-title', 'mwe-upwiz-titleDetailsWidget-title' ], + maxLength: 250 + } ); + + // Aggregate 'change' event (with delay) + this.titleInput.on( 'change', OO.ui.debounce( this.emit.bind( this, 'change' ), 500 ) ); + + this.$element.addClass( 'mwe-upwiz-titleDetailsWidget' ); + this.$element.append( + this.titleInput.$element + ); + }; + OO.inheritClass( uw.TitleDetailsWidget, uw.DetailsWidget ); + + /** + * Reliably turn input into a MediaWiki title that is located in the 'File:' namespace. + * Also applies file-specific checks ($wgIllegalFileChars). + * + * var title = uw.TitleDetailsWidget.static.makeTitleInFileNS( 'filename.ext' ); + * + * @static + * @param {string} filename Desired file name; optionally with 'File:' namespace prefixed + * @return {mw.Title|null} + */ + uw.TitleDetailsWidget.static.makeTitleInFileNS = function ( filename ) { + var + mwTitle = mw.Title.newFromText( filename, NS_FILE ), + illegalFileChars = new RegExp( '[' + mw.config.get( 'wgIllegalFileChars', '' ) + ']' ); + if ( mwTitle && mwTitle.getNamespaceId() !== NS_FILE ) { + // Force file namespace + mwTitle = mw.Title.makeTitle( NS_FILE, filename ); + } + if ( mwTitle && illegalFileChars.test( mwTitle.getMainText() ) ) { + // Consider the title invalid if it contains characters disallowed in file names + mwTitle = null; + } + return mwTitle; + }; + + /** + * @inheritdoc + */ + uw.TitleDetailsWidget.prototype.pushPending = function () { + this.titleInput.pushPending(); + }; + + /** + * @inheritdoc + */ + uw.TitleDetailsWidget.prototype.popPending = function () { + this.titleInput.popPending(); + }; + + /** + * Get a mw.Title object for current value. + * + * @return {mw.Title|null} + */ + uw.TitleDetailsWidget.prototype.getTitle = function () { + var value, extRegex, cleaned, title; + value = this.titleInput.getValue().trim(); + if ( !value ) { + return null; + } + extRegex = new RegExp( '\\.' + this.extension + '$', 'i' ); + cleaned = value.replace( extRegex, '' ).replace( /\.+$/g, '' ).trim(); + title = uw.TitleDetailsWidget.static.makeTitleInFileNS( cleaned + '.' + this.extension ); + return title; + }; + + /** + * @inheritdoc + */ + uw.TitleDetailsWidget.prototype.getErrors = function () { + var + errors = [], + value = this.titleInput.getValue().trim(), + processDestinationCheck = this.processDestinationCheck, + title = this.getTitle(); + + if ( value === '' ) { + errors.push( mw.message( 'mwe-upwiz-error-blank' ) ); + return $.Deferred().resolve( errors ).promise(); + } + + if ( !title ) { + errors.push( mw.message( 'mwe-upwiz-error-title-invalid' ) ); + return $.Deferred().resolve( errors ).promise(); + } + + return mw.DestinationChecker.checkTitle( title.getPrefixedText() ) + .then( function ( result ) { + var moreErrors = processDestinationCheck( result ); + if ( result.blacklist.unavailable ) { + // We don't have a title blacklist, so just check for some likely undesirable patterns. + moreErrors = moreErrors.concat( + mw.QuickTitleChecker.checkTitle( title.getNameText() ).map( function ( errorCode ) { + // Messages: + // mwe-upwiz-error-title-invalid, mwe-upwiz-error-title-senselessimagename, + // mwe-upwiz-error-title-thumbnail, mwe-upwiz-error-title-extension, + return mw.message( 'mwe-upwiz-error-title-' + errorCode ); + } ) + ); + } + return moreErrors; + } ) + .then( function ( moreErrors ) { + return [].concat( errors, moreErrors ); + }, function () { + return $.Deferred().resolve( errors ); + } ); + }; + + /** + * Process the result of a destination filename check, return array of mw.Messages objects + * representing errors. + * + * @private + * @param {Object} result Result to process, output from mw.DestinationChecker + * @return {mw.Message[]} Error messages + */ + uw.TitleDetailsWidget.prototype.processDestinationCheck = function ( result ) { + var messageParams, errors, titleString; + + if ( result.unique.isUnique && result.blacklist.notBlacklisted && !result.unique.isProtected ) { + return []; + } + + // Something is wrong with this title. + errors = []; + + try { + titleString = result.unique.title || result.title; + titleString = uw.TitleDetailsWidget.static.makeTitleInFileNS( titleString ).getPrefixedText(); + } catch ( e ) { + // Unparseable result? This shouldn't happen, we checked for that earlier... + errors.push( mw.message( 'mwe-upwiz-error-title-invalid' ) ); + return errors; + } + + if ( !result.unique.isUnique ) { + // result is NOT unique + if ( result.unique.href ) { + errors.push( mw.message( + 'mwe-upwiz-fileexists-replace-on-page', + titleString, + $( '<a>' ).attr( { href: result.unique.href, target: '_blank' } ) + ) ); + } else { + errors.push( mw.message( 'mwe-upwiz-fileexists-replace-no-link', titleString ) ); + } + } else if ( result.unique.isProtected ) { + errors.push( mw.message( 'mwe-upwiz-error-title-protected' ) ); + } else { + mw.messages.set( result.blacklist.blacklistMessage, result.blacklist.blacklistReason ); + messageParams = [ + 'mwe-upwiz-blacklisted-details', + titleString, + function () { + mw.errorDialog( $( '<div>' ).msg( result.blacklist.blacklistMessage ) ); + } + ]; + + // feedback request for titleblacklist + if ( mw.UploadWizard.config.blacklistIssuesPage !== undefined && mw.UploadWizard.config.blacklistIssuesPage !== '' ) { + messageParams[ 0 ] = 'mwe-upwiz-blacklisted-details-feedback'; + messageParams.push( function () { + var feedback = new mw.Feedback( { + title: new mw.Title( mw.UploadWizard.config.blacklistIssuesPage ), + dialogTitleMessageKey: 'mwe-upwiz-feedback-title' + } ); + feedback.launch( { + message: mw.message( 'mwe-upwiz-feedback-blacklist-line-intro', result.blacklist.blacklistLine ).text(), + subject: mw.message( 'mwe-upwiz-feedback-blacklist-subject', titleString ).text() + } ); + } ); + } + + errors.push( mw.message.apply( mw, messageParams ) ); + } + + return errors; + }; + + /** + * @inheritdoc + */ + uw.TitleDetailsWidget.prototype.getWikiText = function () { + return this.titleInput.getValue().trim(); + }; + + /** + * @inheritdoc + * @return {Object} See #setSerialized + */ + uw.TitleDetailsWidget.prototype.getSerialized = function () { + return { + title: this.titleInput.getValue() + }; + }; + + /** + * @inheritdoc + * @param {Object} serialized + * @param {string} serialized.language Title language code + * @param {string} serialized.title Title text + */ + uw.TitleDetailsWidget.prototype.setSerialized = function ( serialized ) { + this.titleInput.setValue( serialized.title ); + }; + +}( mediaWiki, mediaWiki.uploadWizard, jQuery, OO ) ); |