Merge "ForeignStructuredUpload: Depend on mediawiki.widgets.DateInputWidget"
[mediawiki.git] / resources / src / mediawiki.special / mediawiki.special.userlogin.signup.js
bloba0c6ee2a63e258442f67d56cc0f8895a2b484284
1 /*!
2  * JavaScript for signup form.
3  */
4 ( function ( mw, $ ) {
5         // When sending password by email, hide the password input fields.
6         $( function () {
7                 // Always required if checked, otherwise it depends, so we use the original
8                 var $emailLabel = $( 'label[for="wpEmail"]' ),
9                         originalText = $emailLabel.text(),
10                         requiredText = mw.message( 'createacct-emailrequired' ).text(),
11                         $createByMailCheckbox = $( '#wpCreateaccountMail' ),
12                         $beforePwds = $( '.mw-row-password:first' ).prev(),
13                         $pwds;
15                 function updateForCheckbox() {
16                         var checked = $createByMailCheckbox.prop( 'checked' );
17                         if ( checked ) {
18                                 $pwds = $( '.mw-row-password' ).detach();
19                                 $emailLabel.text( requiredText );
20                         } else {
21                                 if ( $pwds ) {
22                                         $beforePwds.after( $pwds );
23                                         $pwds = null;
24                                 }
25                                 $emailLabel.text( originalText );
26                         }
27                 }
29                 $createByMailCheckbox.on( 'change', updateForCheckbox );
30                 updateForCheckbox();
31         } );
33         // Check if the username is invalid or already taken
34         $( function () {
35                 var
36                         // We need to hook to all of these events to be sure we are notified of all changes to the
37                         // value of an <input type=text> field.
38                         events = 'keyup keydown change mouseup cut paste focus blur',
39                         $input = $( '#wpName2' ),
40                         $statusContainer = $( '#mw-createacct-status-area' ),
41                         api = new mw.Api(),
42                         currentRequest;
44                 // Hide any present status messages.
45                 function clearStatus() {
46                         $statusContainer.slideUp( function () {
47                                 $statusContainer
48                                         .removeAttr( 'class' )
49                                         .empty();
50                         } );
51                 }
53                 // Returns a promise receiving a { state:, username: } object, where:
54                 // * 'state' is one of 'invalid', 'taken', 'ok'
55                 // * 'username' is the validated username if 'state' is 'ok', null otherwise (if it's not
56                 //   possible to register such an account)
57                 function checkUsername( username ) {
58                         // We could just use .then() if we didn't have to pass on .abort()…
59                         var d, apiPromise;
61                         d = $.Deferred();
62                         apiPromise = api.get( {
63                                 action: 'query',
64                                 list: 'users',
65                                 ususers: username // '|' in usernames is handled below
66                         } )
67                                 .done( function ( resp ) {
68                                         var userinfo = resp.query.users[ 0 ];
70                                         if ( resp.query.users.length !== 1 ) {
71                                                 // Happens if the user types '|' into the field
72                                                 d.resolve( { state: 'invalid', username: null } );
73                                         } else if ( userinfo.invalid !== undefined ) {
74                                                 d.resolve( { state: 'invalid', username: null } );
75                                         } else if ( userinfo.userid !== undefined ) {
76                                                 d.resolve( { state: 'taken', username: null } );
77                                         } else {
78                                                 d.resolve( { state: 'ok', username: username } );
79                                         }
80                                 } )
81                                 .fail( d.reject );
83                         return d.promise( { abort: apiPromise.abort } );
84                 }
86                 function updateUsernameStatus() {
87                         var
88                                 username = $.trim( $input.val() ),
89                                 currentRequestInternal;
91                         // Abort any pending requests.
92                         if ( currentRequest ) {
93                                 currentRequest.abort();
94                         }
96                         if ( username === '' ) {
97                                 clearStatus();
98                                 return;
99                         }
101                         currentRequest = currentRequestInternal = checkUsername( username ).done( function ( info ) {
102                                 var message;
104                                 // Another request was fired in the meantime, the result we got here is no longer current.
105                                 // This shouldn't happen as we abort pending requests, but you never know.
106                                 if ( currentRequest !== currentRequestInternal ) {
107                                         return;
108                                 }
109                                 // If we're here, then the current request has finished, avoid calling .abort() needlessly.
110                                 currentRequest = undefined;
112                                 if ( info.state === 'ok' ) {
113                                         clearStatus();
114                                 } else {
115                                         if ( info.state === 'invalid' ) {
116                                                 message = mw.message( 'noname' ).text();
117                                         } else if ( info.state === 'taken' ) {
118                                                 message = mw.message( 'userexists' ).text();
119                                         }
121                                         $statusContainer
122                                                 .attr( 'class', 'errorbox' )
123                                                 .empty()
124                                                 .append(
125                                                         // Ugh…
126                                                         // @todo Change the HTML structure in includes/templates/Usercreate.php
127                                                         $( '<strong>' ).text( mw.message( 'createacct-error' ).text() ),
128                                                         $( '<br>' ),
129                                                         document.createTextNode( message )
130                                                 )
131                                                 .slideDown();
132                                 }
133                         } ).fail( function () {
134                                 clearStatus();
135                         } );
136                 }
138                 $input.on( events, $.debounce( 1000, updateUsernameStatus ) );
139         } );
140 }( mediaWiki, jQuery ) );