Merge "SpecialMovepage: Convert form to use OOUI controls"
[lhc/web/wiklou.git] / resources / src / mediawiki.special / mediawiki.special.userlogin.signup.js
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;
14
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 }
28
29 $createByMailCheckbox.on( 'change', updateForCheckbox );
30 updateForCheckbox();
31 } );
32
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;
43
44 // Hide any present status messages.
45 function clearStatus() {
46 $statusContainer.slideUp( function () {
47 $statusContainer
48 .removeAttr( 'class' )
49 .empty();
50 } );
51 }
52
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;
60
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 ];
69
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 );
82
83 return d.promise( { abort: apiPromise.abort } );
84 }
85
86 function updateUsernameStatus() {
87 var
88 username = $.trim( $input.val() ),
89 currentRequestInternal;
90
91 // Abort any pending requests.
92 if ( currentRequest ) {
93 currentRequest.abort();
94 }
95
96 if ( username === '' ) {
97 clearStatus();
98 return;
99 }
100
101 currentRequest = currentRequestInternal = checkUsername( username ).done( function ( info ) {
102 var message;
103
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;
111
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 }
120
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 }
137
138 $input.on( events, $.debounce( 1000, updateUsernameStatus ) );
139 } );
140 }( mediaWiki, jQuery ) );