Merge "jquery.tablesorter: Silence an expected "sort-rowspan-error" warning"
[mediawiki.git] / resources / src / mediawiki.special.createaccount / signup.js
blob32e233eeb76f6bcad597518c5eaaf5b97dc6fb23
1 /*!
2 * JavaScript for signup form.
3 */
4 const HtmlformChecker = require( './HtmlformChecker.js' );
6 // When sending password by email, hide the password input fields.
7 $( () => {
8 // Always required if checked, otherwise it depends, so we use the original
9 const $emailLabel = $( 'label[for="wpEmail"] .cdx-label__label__text' ),
10 originalText = $emailLabel.text(),
11 requiredText = mw.msg( 'createacct-emailrequired' ),
12 $createByMailCheckbox = $( '#wpCreateaccountMail' ),
13 $beforePwds = $( '.mw-row-password' ).first().prev();
14 let $pwds;
16 function updateForCheckbox() {
17 const checked = $createByMailCheckbox.prop( 'checked' );
18 if ( checked ) {
19 $pwds = $( '.mw-row-password' ).detach();
20 // TODO when this uses the optional flag, show/hide that instead of changing the text
21 $emailLabel.text( requiredText );
22 } else {
23 if ( $pwds ) {
24 $beforePwds.after( $pwds );
25 $pwds = null;
27 $emailLabel.text( originalText );
31 $createByMailCheckbox.on( 'change', updateForCheckbox );
32 updateForCheckbox();
33 } );
35 // Check if the username is invalid or already taken; show username normalisation warning
36 mw.hook( 'htmlform.enhance' ).add( ( $root ) => {
37 const $usernameInput = $root.find( '#wpName2' ),
38 $passwordInput = $root.find( '#wpPassword2' ),
39 $emailInput = $root.find( '#wpEmail' ),
40 $realNameInput = $root.find( '#wpRealName' ),
41 api = new mw.Api();
43 function checkUsername( username, signal ) {
44 // Leading/trailing/multiple whitespace characters are always stripped in usernames,
45 // this should not require a warning. We do warn about underscores.
46 username = username.replace( / +/g, ' ' ).trim();
48 return api.get( {
49 action: 'query',
50 list: 'users',
51 ususers: username,
52 usprop: 'cancreate',
53 formatversion: 2,
54 errorformat: 'html',
55 errorsuselocal: true,
56 uselang: mw.config.get( 'wgUserLanguage' )
57 }, { signal } )
58 .then( ( resp ) => {
59 const userinfo = resp.query.users[ 0 ];
61 if ( resp.query.users.length !== 1 || userinfo.invalid ) {
62 return { valid: false, messages: [ mw.message( 'noname' ).parseDom() ] };
63 } else if ( userinfo.userid !== undefined ) {
64 return { valid: false, messages: [ mw.message( 'userexists' ).parseDom() ] };
65 } else if ( !userinfo.cancreate ) {
66 return {
67 valid: false,
68 messages: userinfo.cancreateerror ? userinfo.cancreateerror.map( ( m ) => m.html ) : []
70 } else if ( userinfo.name !== username ) {
71 return { valid: true, messages: [
72 mw.message( 'createacct-normalization', username, userinfo.name ).parseDom()
73 ] };
74 } else {
75 return { valid: true, messages: [] };
77 } );
80 function checkPassword( _password, signal ) {
81 if ( $usernameInput.val().trim() === '' ) {
82 return $.Deferred().resolve( { valid: true, messages: [] } );
85 return api.post( {
86 action: 'validatepassword',
87 user: $usernameInput.val(),
88 password: $passwordInput.val(),
89 email: $emailInput.val() || '',
90 realname: $realNameInput.val() || '',
91 formatversion: 2,
92 errorformat: 'html',
93 errorsuselocal: true,
94 uselang: mw.config.get( 'wgUserLanguage' )
95 }, { signal } )
96 .then( ( resp ) => {
97 const pwinfo = resp.validatepassword || {};
99 return {
100 valid: pwinfo.validity === 'Good',
101 messages: pwinfo.validitymessages ? pwinfo.validitymessages.map( ( m ) => m.html ) : []
103 } );
106 const usernameChecker = new HtmlformChecker( $usernameInput, checkUsername );
107 usernameChecker.attach();
109 const passwordChecker = new HtmlformChecker( $passwordInput, checkPassword );
110 passwordChecker.attach( $usernameInput.add( $emailInput ).add( $realNameInput ) );
111 } );