Create account form with vertical form appearance
authorMatthew Flaschen <mflaschen@wikimedia.org>
Sat, 6 Apr 2013 01:57:03 +0000 (21:57 -0400)
committerS Page <spage@wikimedia.org>
Tue, 23 Apr 2013 22:56:02 +0000 (15:56 -0700)
Similar to the login form (change 55847), this presents a compact
vertically-stacked form, if a global variable is set or if you add
?useNew=1 to the query string.

The redesigned create account form also:

* Removes the remember me checkbox (see bugzilla 47267)
* Displays some wiki statistics in a benefits column.
* Repositions the FancyCaptcha image if present using JavaScript (see
  bugzilla 47372).
* Sets the template skin as in change 59577.

Bug: 44628
Bug: 47267
Change-Id: I9b03d519af43de147bff0ac509a1154f67cd3a0a

15 files changed:
RELEASE-NOTES-1.22
includes/AutoLoader.php
includes/DefaultSettings.php
includes/specials/SpecialUserlogin.php
includes/templates/UsercreateVForm.php [new file with mode: 0644]
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php
maintenance/language/messages.inc
resources/Resources.php
resources/mediawiki.special/images/icon-contributors.png [new file with mode: 0644]
resources/mediawiki.special/images/icon-edits.png [new file with mode: 0644]
resources/mediawiki.special/images/icon-pages.png [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.createAccount.vform.css [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.createAccount.vform.js [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.vforms.css

index 0e2f1da..2dea3b5 100644 (file)
@@ -12,7 +12,8 @@ production.
 * $wgRedirectScript was removed. It was unused.
 * Removed $wgLocalMessageCacheSerialized, it is now always true.
 * When $wgUseVFormUserLogin is true, the redesign of Special:UserLogin is
-  activated.
+  activated; when $wgUseVFormCreateAccount is true, the redesign of
+  Special:UserLogin/signup is activated.
 * $wgVectorUseIconWatch is now enabled by default.
 
 === New features in 1.22 ===
@@ -24,8 +25,12 @@ production.
   preference). This feature was moved from the Vector extension, and is now part
   of core for all skins. Take care when upgrading that you don't use an older
   version of the Vector extension as this feature may conflict.
-* New version of Special:UserLogin form. It is opt-in for now, controlled by
-  the $wgUseVFormUserLogin setting or a 'useNew' URL parameter trigger.
+* New 'mediawiki.ui' CSS module providing mw-ui-* styles for buttons and a
+  compact vertical form layout.
+* New versions of login (Special:UserLogin) and create account
+  (Special:UserLogin/signup) forms. They are opt-in for now, controlled by
+  the $wgUseVFormUserLogin and $wgUseVFormCreateAccount settings or a 'useNew'
+  URL parameter trigger.
 * (bug 23343) Implemented ability to apply IP blocks to the contents of X-Forwarded-For headers
   by adding a new configuration variable $wgApplyIpBlocksToXff (disabled by default).
 * The new hook 'APIGetPossibleErrors' to modify the list of possible errors was
index daa5fcb..4813d45 100644 (file)
@@ -1008,6 +1008,7 @@ $wgAutoloadLocalClasses = array(
        'UserloginTemplate' => 'includes/templates/Userlogin.php',
        'UserloginTemplateVForm' => 'includes/templates/UserloginVForm.php',
        'UsercreateTemplate' => 'includes/templates/Usercreate.php',
+       'UsercreateTemplateVForm' => 'includes/templates/UsercreateVForm.php',
 
        # includes/upload
        'UploadBase' => 'includes/upload/UploadBase.php',
index da2f321..c198081 100644 (file)
@@ -2829,12 +2829,22 @@ $wgVectorUseSimpleSearch = true;
 $wgVectorUseIconWatch = true;
 
 /**
- * Use VForm design for Special:Userlogin.  This can be overridden by
- * a useNew bool in the query string.  For instance, if it is globally
- * false, you can try it with useNew=1.
+ * Use compact vertical form ("VForm") design for Special:Userlogin.  This can
+ * be overridden by a useNew bool in the query string.  For instance, if it is
+ * globally false, you can try it with useNew=1.
+ *
+ * @since 1.22
  */
 $wgUseVFormUserLogin = false;
 
+/**
+ * Use compact vertical form ("VForm") design for account creation
+ * (Special:Userlogin?type=signup).
+ *
+ * @since 1.22
+ */
+$wgUseVFormCreateAccount = false;
+
 /**
  * Display user edit counts in various prominent places.
  */
index f7e4d0a..624975e 100644 (file)
@@ -1023,10 +1023,10 @@ class LoginForm extends SpecialPage {
         * @return Boolean
         */
        private function shouldShowVForm() {
-               global $wgUseVFormUserLogin;
+               global $wgUseVFormCreateAccount, $wgUseVFormUserLogin;
 
                if ( $this->mType == 'signup' ) {
-                       return false;
+                       return $this->mRequest->getBool( 'useNew', $wgUseVFormCreateAccount );
                } else {
                        return $this->mRequest->getBool( 'useNew', $wgUseVFormUserLogin );
                }
@@ -1070,11 +1070,24 @@ class LoginForm extends SpecialPage {
                }
 
                if ( $this->mType == 'signup' ) {
-                       $template = new UsercreateTemplate();
+                       $out->addModules( 'mediawiki.special.userlogin.signup' );
+                       if ( $this->mShowVForm ) {
+                               $template = new UsercreateTemplateVForm();
+                               $out->addModuleStyles( array(
+                                       'mediawiki.ui',
+                                       'mediawiki.special.createaccount.vform'
+                               ) );
+                               // XXX hack pending RL or JS parse() support for complex content messages
+                               // https://bugzilla.wikimedia.org/show_bug.cgi?id=25349
+                               $out->addJsConfigVars( 'wgCreateacctImgcaptchaHelp',
+                                       $this->msg( 'createacct-imgcaptcha-help' )->parse() );
+                               $out->addModules( 'mediawiki.special.createaccount.vform.js' );
+                       } else {
+                               $template = new UsercreateTemplate();
+                       }
                        $q = 'action=submitlogin&type=signup';
                        $linkq = 'type=login';
                        $linkmsg = 'gotaccount';
-                       $out->addModules( 'mediawiki.special.userlogin.signup' );
                } else {
                        if ( $this->mShowVForm ) {
                                $template = new UserloginTemplateVForm();
diff --git a/includes/templates/UsercreateVForm.php b/includes/templates/UsercreateVForm.php
new file mode 100644 (file)
index 0000000..0472b8d
--- /dev/null
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Html form for account creation with new VForm appearance.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup Templates
+ */
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+       die( -1 );
+}
+
+/**
+ * Html form for create account with new VForm appearance.
+ *
+ * @since 1.22
+ */
+class UsercreateTemplateVForm extends BaseTemplate {
+
+       /**
+        * Extensions (AntiSpoof and TitleBlacklist) call this in response to
+        * UserCreateForm hook to add checkboxes to the create account form.
+        */
+       function addInputItem( $name, $value, $type, $msg, $helptext = false ) {
+               $this->data['extraInput'][] = array(
+                       'name' => $name,
+                       'value' => $value,
+                       'type' => $type,
+                       'msg' => $msg,
+                       'helptext' => $helptext,
+               );
+       }
+
+       function execute() {
+               global $wgCookieExpiration;
+               $expirationDays = ceil( $wgCookieExpiration / ( 3600 * 24 ) );
+?>
+<div class="mw-ui-container">
+       <?php
+       if ( $this->haveData( 'languages' ) ) {
+       ?>
+               <div id="languagelinks">
+                       <p><?php $this->html( 'languages' ); ?></p>
+               </div>
+       <?php
+       }
+       ?>
+<div id="userloginForm">
+<h2 class="createaccount-join"><?php $this->msg( 'createacct-join' ); ?></h2>
+<form name="userlogin2" id="userlogin2" class="mw-ui-vform" method="post" action="<?php $this->text( 'action' ); ?>">
+       <section class="mw-form-header">
+               <?php $this->html( 'header' ); /* extensions such as ConfirmEdit add form HTML here */ ?>
+       </section>
+       <?php
+       if ( $this->data['message'] ) {
+?>
+               <div class="<?php $this->text( 'messagetype' ); ?>box">
+               <?php if ( $this->data['messagetype'] == 'error' ) { ?>
+                       <strong><?php $this->msg( 'loginerror' )?></strong><br />
+               <?php } ?>
+               <?php $this->html( 'message' ); ?>
+               </div>
+       <?php } ?>
+               <div>
+                       <label for='wpName2'>
+                               <?php $this->msg( 'userlogin-yourname' ); ?>
+
+                               <span class="mw-ui-flush-right"><?php echo $this->getMsg( 'createacct-helpusername-link' )->parse(); ?></span>
+                       </label>
+                       <?php echo Html::input( 'wpName', $this->data['name'], 'text', array(
+                               'class' => 'mw-input loginText',
+                               'id' => 'wpName2',
+                               'tabindex' => '1',
+                               'size' => '20',
+                               'required',
+                               'placeholder' => $this->getMsg( 'userlogin-yourname-ph' )->text(),
+                               'autofocus'
+                       ) ); ?>
+               </div>
+               <div>
+               <?php if ( $this->data['createemail'] ) { ?>
+                       <label class="mw-ui-checkbox-label">
+                               <input name="wpCreateaccountMail" type="checkbox" value="1" id="wpCreateaccountMail" tabindex="2"
+                                       <?php if ( $this->data['createemailset'] ) {
+                                               echo 'checked="checked"';
+                                       } ?>
+                               >
+                               <?php $this->msg( 'createaccountmail' ); ?>
+                       </label>
+               <?php } ?>
+               </div>
+               <div class="mw-row-password">
+                       <label for='wpPassword2'><?php $this->msg( 'userlogin-yourpassword' ); ?></label>
+                       <?php echo Html::input( 'wpPassword', null, 'password', array(
+                               'class' => 'mw-input loginPassword',
+                               'id' => 'wpPassword2',
+                               'tabindex' => '3',
+                               'size' => '20',
+                               'required',
+                               'placeholder' => $this->getMsg( 'createacct-yourpassword-ph' )->text()
+                       ) + User::passwordChangeInputAttribs() ); ?>
+               </div>
+       <?php if ( $this->data['usedomain'] ) {
+               $doms = "";
+               foreach ( $this->data['domainnames'] as $dom ) {
+                       $doms .= "<option>" . htmlspecialchars( $dom ) . "</option>";
+               }
+       ?>
+               <div>
+                       <label><?php $this->msg( 'yourdomainname' ); ?></label>
+                       <div class="mw-input">
+                               <select name="wpDomain" value="<?php $this->text( 'domain' ); ?>"
+                                       tabindex="4">
+                                       <?php echo $doms ?>
+                               </select>
+                       </div>
+               </div>
+       <?php } ?>
+               <div class="mw-row-password">
+                       <label for='wpRetype'><?php $this->msg( 'createacct-yourpasswordagain' ); ?></label>
+                       <?php
+                       echo Html::input( 'wpRetype', null, 'password', array(
+                               'class' => 'mw-input loginPassword',
+                               'id' => 'wpRetype',
+                               'tabindex' => '5',
+                               'size' => '20',
+                               'required',
+                               'placeholder' => $this->getMsg( 'createacct-yourpasswordagain-ph' )->text()
+                               ) + User::passwordChangeInputAttribs() );
+                       ?>
+               </div>
+               <div>
+               <?php if ( $this->data['useemail'] ) { ?>
+                       <label for='wpEmail'>
+                               <?php
+                                       $this->msg( $this->data['emailrequired'] ?
+                                               'createacct-emailrequired' :
+                                               'createacct-emailoptional'
+                                       );
+                               ?>
+                       </label>
+                       <?php
+                               echo Html::input( 'wpEmail', $this->data['email'], 'email', array(
+                                       'class' => 'mw-input loginText',
+                                       'id' => 'wpEmail',
+                                       'tabindex' => '6',
+                                       'size' => '20',
+                                       'placeholder' => $this->getMsg( 'createacct-email-ph' )->text()
+                               ) + ( $this->data['emailrequired'] ? array() : array( 'required' => '' ) ) );
+                       ?>
+                       <?php
+                       // VForm eliminates the prefsectiontip div tip:
+                       // prefs-help-email-required is redundant with the placeholder text
+                       // Doesn't show the wordy prefs-help-email
+                       // Doesn't show the wordy prefs-help-email-others
+                       ?>
+               <?php } ?>
+               </div>
+               <?php if ( $this->data['userealname'] ) { ?>
+                       <div>
+                               <label for='wpRealName'><?php $this->msg( 'createacct-realname' ); ?></label>
+                               <input type='text' class='mw-input loginText' name="wpRealName" id="wpRealName"
+                                       tabindex="7"
+                                       value="<?php $this->text( 'realname' ); ?>" size='20' />
+                               <div class="prefsectiontip">
+                                       <?php $this->msgWiki( 'prefs-help-realname' ); ?>
+                               </div>
+                       </div>
+               <?php }
+               if ( $this->data['usereason'] ) { ?>
+                       <div>
+                               <label for='wpReason'><?php $this->msg( 'createacct-reason' ); ?></label>
+                               <input type='text' class='mw-input loginText' name="wpReason" id="wpReason"
+                                               tabindex="8"
+                                               value="<?php $this->text( 'reason' ); ?>" size='20' />
+                       </div>
+               <?php }
+               $tabIndex = 9;
+               if ( isset( $this->data['extraInput'] ) && is_array( $this->data['extraInput'] ) ) {
+                       foreach ( $this->data['extraInput'] as $inputItem ) { ?>
+                       <div>
+                               <?php
+                               // If it's a checkbox, output the whole thing (assume it has a msg).
+                               if ( $inputItem['type'] == 'checkbox' ) {
+                               ?>
+                                       <label class="mw-ui-checkbox-label">
+                                               <input
+                                                       name="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+                                                       id="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+                                                       type="checkbox" value="1"
+                                                       tabindex="<?php echo $tabIndex++; ?>"
+                                                       <?php if ( !empty( $inputItem['value'] ) )  {
+                                                               echo 'checked="checked"';
+                                                       } ?>
+                                               >
+                                               <?php $this->msg( $inputItem['msg'] ); ?>
+                                       </label>
+                               <?php
+                               } else {
+                                       // Not a checkbox.
+                                       if ( !empty( $inputItem['msg'] ) ) {
+                                               // Output the message label
+                                       ?>
+                                               <label for="<?php echo htmlspecialchars( $inputItem['name'] ); ?>">
+                                                       <?php $this->msgWiki( $inputItem['msg'] ); ?>
+                                               </label>
+                                       <?php
+                                       }
+                                       ?>
+                                       <input
+                                               type="<?php echo htmlspecialchars( $inputItem['type'] ); ?>"
+                                               class="mw-input"
+                                               name="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+                                               tabindex="<?php echo $tabIndex++; ?>"
+                                               value="<?php echo htmlspecialchars( $inputItem['value'] ); ?>"
+                                               id="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+                                       />
+                               <?php
+                               }
+                               if ( $inputItem['helptext'] !== false ) {
+                               ?>
+                                       <div class="prefsectiontip">
+                                               <?php $this->msgWiki( $inputItem['helptext'] ); ?>
+                                       </div>
+                               <?php
+                               }
+                               ?>
+                               </div>
+                       <?php
+                       }
+               }
+               // JS attempts to move the image CAPTCHA below this part of the form,
+               // so skip one index.
+               $tabIndex++;
+               ?>
+               <div class="mw-submit">
+                       <input type='submit' class="mw-ui-button mw-ui-big mw-ui-block mw-ui-primary" name="wpCreateaccount" id="wpCreateaccount"
+                               tabindex="<?php echo $tabIndex++; ?>"
+                               value="<?php $this->msg( 'createaccount' ); ?>" />
+               </div>
+       <input type="hidden" id="useNew" name="useNew" value="1" />
+<?php if ( $this->haveData( 'uselang' ) ) { ?><input type="hidden" name="uselang" value="<?php $this->text( 'uselang' ); ?>" /><?php } ?>
+<?php if ( $this->haveData( 'token' ) ) { ?><input type="hidden" name="wpCreateaccountToken" value="<?php $this->text( 'token' ); ?>" /><?php } ?>
+</form>
+</div>
+<div class="mw-createacct-benefits-container">
+       <h2><?php $this->msg( 'createacct-benefit-heading' ); ?></h2>
+       <div class="mw-createacct-benefits-list">
+               <div>
+                       <div class="mw-benefits-icon <?php $this->msg( 'createacct-benefit-icon1' ); ?>"></div>
+                       <div class="mw-number-text">
+                               <h3><?php $this->msg( 'createacct-benefit-head1' ); ?></h3>
+                               <p><?php $this->msg( 'createacct-benefit-body1' ); ?></p>
+                       </div>
+               </div>
+               <div>
+                       <div class="mw-benefits-icon <?php $this->msg( 'createacct-benefit-icon2' ); ?>"></div>
+                       <div class="mw-number-text">
+                               <h3><?php $this->msg( 'createacct-benefit-head2' ); ?></h3>
+                               <p><?php $this->msg( 'createacct-benefit-body2' ); ?></p>
+                       </div>
+               </div>
+               <div>
+                       <div class="mw-benefits-icon <?php $this->msg( 'createacct-benefit-icon3' ); ?>"></div>
+                       <div class="mw-number-text">
+                               <h3><?php $this->msg( 'createacct-benefit-head3' ); ?></h3>
+                               <p><?php $this->msg( 'createacct-benefit-body3' ); ?></p>
+                       </div>
+               </div>
+       </div>
+</div>
+</div>
+<?php
+
+       }
+}
index 9d09fe8..00bf2ba 100644 (file)
@@ -1081,10 +1081,15 @@ Do not forget to change your [[Special:Preferences|{{SITENAME}} preferences]].',
 'yourname'                     => 'Username:',
 'userlogin-yourname'           => 'Username',
 'userlogin-yourname-ph'        => 'Enter your username',
+'createacct-helpusername-url'     => '{{ns:Project}}:Username_policy',
+'createacct-helpusername-link'    => '[[{{MediaWiki:createacct-helpusername-url}}|(help me choose)]]',
 'yourpassword'                 => 'Password:',
 'userlogin-yourpassword'       => 'Password',
 'userlogin-yourpassword-ph'    => 'Enter your password',
+'createacct-yourpassword-ph'      => 'Enter a password',
 'yourpasswordagain'            => 'Retype password:',
+'createacct-yourpasswordagain'    => 'Confirm password',
+'createacct-yourpasswordagain-ph' => 'Enter password again',
 'remembermypassword'           => 'Remember my login on this browser (for a maximum of $1 {{PLURAL:$1|day|days}})',
 'userlogin-remembermypassword' => 'Remember me',
 'userlogin-signwithsecure'     => 'Sign in with secure server',
@@ -1111,8 +1116,28 @@ Do not forget to change your [[Special:Preferences|{{SITENAME}} preferences]].',
 'userlogin-resetlink'          => 'Forgotten your login details?',
 'helplogin-url'                => 'Help:Logging in',
 'userlogin-helplink'           => '[[{{MediaWiki:helplogin-url}}|Help with logging in]]',
+'createacct-join'                 => 'Enter your information below.',
+'createacct-emailrequired'        => 'Email address',
+'createacct-emailoptional'        => 'Email address (optional)',
+'createacct-email-ph'             => 'Enter your email address',
 'createaccountmail'            => 'Use a temporary random password and send it to the email address specified below',
+'createacct-realname'             => 'Real name (optional)',
 'createaccountreason'          => 'Reason:',
+'createacct-reason'               => 'Reason',
+'createacct-captcha'              => 'Security check',
+'createacct-captcha-help-url'     => '{{ns:Project}}:Request an account',
+'createacct-imgcaptcha-help'      => 'Can\'t see the image? [[{{MediaWiki:createacct-captcha-help-url}}|Request an account]]',
+'createacct-imgcaptcha-ph'        => 'Enter the text you see above',
+'createacct-benefit-heading'      => '{{SITENAME}} is made by people like you.',
+'createacct-benefit-icon1'        => 'icon-edits',
+'createacct-benefit-head1'        => '{{NUMBEROFEDITS}}',
+'createacct-benefit-body1'        => 'edits',
+'createacct-benefit-icon2'        => 'icon-pages',
+'createacct-benefit-head2'        => '{{NUMBEROFARTICLES}}',
+'createacct-benefit-body2'        => 'pages',
+'createacct-benefit-icon3'        => 'icon-contributors',
+'createacct-benefit-head3'        => '{{NUMBEROFUSERS}}',
+'createacct-benefit-body3'        => 'contributors this month',
 'badretype'                    => 'The passwords you entered do not match.',
 'userexists'                   => 'Username entered already in use.
 Please choose a different name.',
index 6084ba2..1478f35 100644 (file)
@@ -1061,7 +1061,12 @@ In user preferences.
 'userlogin-yourpassword' => 'In new vertical user login & create account forms, label for password field.
 {{Identical|Password}}',
 'userlogin-yourpassword-ph' => 'Placeholder text in new userlogin form for password field.',
+'createacct-helpusername-url' => 'The URL of a page providing username guidance for the wiki.',
+'createacct-helpusername-link' => 'Message in new create account form providing guidance for username.',
+'createacct-yourpassword-ph' => 'Placeholder text in new create account form for password field.',
 'yourpasswordagain' => 'In user preferences',
+'createacct-yourpasswordagain' => 'In new create account form, label for field to re-enter password',
+'createacct-yourpasswordagain-ph' => 'Placeholder text in new create account form for re-enter password field.',
 'remembermypassword' => 'A check box in [[Special:UserLogin]]
 
 {{Identical|Remember my login on this computer}}',
@@ -1129,8 +1134,28 @@ Wikitext linking to login help.
 
 See also:
 * {{msg-mw|Helplogin-url}}',
+'createacct-join' => 'Subheading of vertical-layout create account form encouraging user to join the wiki.',
+'createacct-emailrequired'  => 'Label in vertical-layout create account form for email field when it is required.',
+'createacct-emailoptional' => 'Label in vertical-layout create account form for email field when it is optional.',
+'createacct-email-ph'  => 'Placeholder in vertical-layout create account form for email field.',
 'createaccountmail' => 'Button text for creating a new account and sending the new password to the specified e-mail address directly, as used on [[Special:UserLogin/signup]] if creating accounts by e-mail is allowed.',
+'createacct-realname' => 'In vertical-layout create account form, label for field to enter optional real name.',
 'createaccountreason' => '{{Identical|Reason}}',
+'createacct-reason' => 'In vertical-layout create account form, label for field to enter reason to create an account when already logged-in.',
+'createacct-captcha' => 'Label in vertical-layout create account form for CAPTCHA input field when repositioned by JavaScript.',
+'createacct-captcha-help-url' => 'The URL of a page providing CAPTCHA assistance for the wiki.',
+'createacct-imgcaptcha-help' => 'Help text in vertical-layout create account form for image CAPTCHA input field when repositioned by JavaScript.',
+'createacct-imgcaptcha-ph' => 'Placehodler text in vertical-layout create account form for image CAPTCHA input field when repositioned by JavaScript.',
+'createacct-benefit-heading' => 'In vertical-layout create account form, the heading for the section describing the benefits of creating an account.',
+'createacct-benefit-icon1' => 'In vertical-layout create account form, the CSS style for the div next to the first benefit. If you replace this you will need probably need to adjust CSS.',
+'createacct-benefit-head1' => 'In vertical-layout create account form, the text in the heading for the first benefit. Do not edit the magic word; if you replace it you will probably need to adjust CSS.',
+'createacct-benefit-body1' => 'In vertical-layout create account form, the text for the first benefit.',
+'createacct-benefit-icon2' => 'In vertical-layout create account form, the CSS style for the div next to the second benefit. If you replace this you will need probably need to adjust CSS.',
+'createacct-benefit-head2' => 'In vertical-layout create account form, the text in the heading for the second benefit. Do not edit the magic word; if you replace it you will probably need to adjust CSS.',
+'createacct-benefit-body2' => 'In vertical-layout create account form, the text for the second benefit.',
+'createacct-benefit-icon3' => 'In vertical-layout create account form, the CSS style for the div next to the third benefit. If you replace this you will need probably need to adjust CSS.',
+'createacct-benefit-head3' => 'In vertical-layout create account form, the text in the heading for the third benefit. Do not edit the magic word; if you replace it you will probably need to adjust CSS.',
+'createacct-benefit-body3' => 'In vertical-layout create account form, the text for the third benefit.',
 'badretype' => 'Used as error message when the new password and its retype do not match.',
 'userexists' => 'Used as error message in creating a user account.',
 'loginerror' => 'Used as title of error message.
@@ -1180,7 +1205,7 @@ $1 is the minimum number of characters in the password.',
 
 Parameters:
 * $1 is a user name. This parameter can be used with GENDER.',
-'noemailcreate' => 'Used as error message in [[Special:UserLogin]].',
+'noemailcreate' => 'Used as error message when one user creates an account for another and there is no email.',
 'passwordsent' => '* $1 - username',
 'blocked-mailpassword' => 'Used as error message in password recovery.',
 'eauthentsent' => "This message appears after entering an e-mail address in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}, then clicking on '{{int:saveprefs}}'.",
index cc5b9d3..4410187 100644 (file)
@@ -442,10 +442,15 @@ $wgMessageStructure = array(
                'yourname',
                'userlogin-yourname',
                'userlogin-yourname-ph',
+               'createacct-helpusername-url',
+               'createacct-helpusername-link',
                'yourpassword',
                'userlogin-yourpassword',
                'userlogin-yourpassword-ph',
+               'createacct-yourpassword-ph',
                'yourpasswordagain',
+               'createacct-yourpasswordagain',
+               'createacct-yourpasswordagain-ph',
                'remembermypassword',
                'userlogin-remembermypassword',
                'userlogin-signwithsecure',
@@ -472,8 +477,28 @@ $wgMessageStructure = array(
                'userlogin-resetlink',
                'helplogin-url',
                'userlogin-helplink',
+               'createacct-join',
+               'createacct-emailrequired',
+               'createacct-emailoptional',
+               'createacct-email-ph',
                'createaccountmail',
+               'createacct-realname',
                'createaccountreason',
+               'createacct-reason',
+               'createacct-captcha',
+               'createacct-captcha-help-url',
+               'createacct-imgcaptcha-help',
+               'createacct-imgcaptcha-ph',
+               'createacct-benefit-heading',
+               'createacct-benefit-icon1',
+               'createacct-benefit-head1',
+               'createacct-benefit-body1',
+               'createacct-benefit-icon2',
+               'createacct-benefit-head2',
+               'createacct-benefit-body2',
+               'createacct-benefit-icon3',
+               'createacct-benefit-head3',
+               'createacct-benefit-body3',
                'badretype',
                'userexists',
                'loginerror',
index c96184e..538ee01 100644 (file)
@@ -944,6 +944,22 @@ return array(
                ),
                'position' => 'top',
        ),
+       'mediawiki.special.createaccount.vform' => array(
+               'styles' => array(
+                       'resources/mediawiki.special/mediawiki.special.vforms.css',
+                       'resources/mediawiki.special/mediawiki.special.createAccount.vform.css',
+               ),
+               'position' => 'top',
+       ),
+       'mediawiki.special.createaccount.vform.js' => array(
+               'scripts' => 'resources/mediawiki.special/mediawiki.special.createAccount.vform.js',
+               'messages' => array(
+                       'createacct-captcha',
+                       'createacct-imgcaptcha-ph'
+               ),
+               'dependencies' => 'mediawiki.jqueryMsg',
+               'position' => 'top',
+       ),
        'mediawiki.special.javaScriptTest' => array(
                'scripts' => 'resources/mediawiki.special/mediawiki.special.javaScriptTest.js',
                'messages' => array_merge( Skin::getSkinNameMessages(), array(
diff --git a/resources/mediawiki.special/images/icon-contributors.png b/resources/mediawiki.special/images/icon-contributors.png
new file mode 100644 (file)
index 0000000..62b37f9
Binary files /dev/null and b/resources/mediawiki.special/images/icon-contributors.png differ
diff --git a/resources/mediawiki.special/images/icon-edits.png b/resources/mediawiki.special/images/icon-edits.png
new file mode 100644 (file)
index 0000000..263832b
Binary files /dev/null and b/resources/mediawiki.special/images/icon-edits.png differ
diff --git a/resources/mediawiki.special/images/icon-pages.png b/resources/mediawiki.special/images/icon-pages.png
new file mode 100644 (file)
index 0000000..0389c84
Binary files /dev/null and b/resources/mediawiki.special/images/icon-pages.png differ
diff --git a/resources/mediawiki.special/mediawiki.special.createAccount.vform.css b/resources/mediawiki.special/mediawiki.special.createAccount.vform.css
new file mode 100644 (file)
index 0000000..a1d78a2
--- /dev/null
@@ -0,0 +1,98 @@
+/* Disable the underline that Vector puts on h2 headings, and bold them. */
+.mw-ui-container h2 {
+       border: 0;
+       font-weight: bold;
+}
+
+/* shuffled CAPTCHA */
+#wpCaptchaWord {
+       margin-top: 6px;
+}
+
+.mw-createacct-captcha-container {
+       background-color: #f8f8f8;
+       border: 1px solid #c9c9c9;
+       padding: 10px;
+       text-align: center;
+}
+
+.mw-createacct-captcha-image-container {
+       background-color: #fff;
+       min-height: 95px;
+}
+
+.mw-createacct-captcha-assisted {
+       display: block;
+       margin-top: 0.5em;
+}
+
+.mw-createacct-captcha-and-reload {
+       border: 1px solid #c9c9c9;
+       display: table-cell;
+       width: 270px;
+       background-color: #FFF;
+}
+
+.mw-createacct-captcha-and-reload .confirmedit-captcha-reload {
+       display: block;
+       float: right;
+}
+
+/* Benefits column CSS to the right (if it fits) of the form. */
+.mw-ui-container #userloginForm {
+       float: left;
+}
+
+div.mw-createacct-benefits-container {
+       float: left
+}
+
+div.mw-createacct-benefits-container h2 {
+       margin-bottom: 30px;
+}
+
+div.mw-benefits-icon {
+       display: inline-block;
+       padding: 0;
+       float: left;
+       width: 80px;
+       height: 75px;
+       margin-right: 15px;
+       border: 0;
+}
+
+.mw-benefits-icon.icon-edits {
+       /* @embed */
+       background: url(images/icon-edits.png) no-repeat right;
+}
+
+.mw-benefits-icon.icon-pages {
+       /* @embed */
+       background: url(images/icon-pages.png) no-repeat right;
+}
+
+.mw-benefits-icon.icon-contributors {
+       /* @embed */
+       background: url(images/icon-contributors.png) no-repeat right;
+}
+
+/* Special font for numbers in benefits*/
+div.mw-number-text h3 {
+       top: 0;
+       margin: 0;
+       padding: 0;
+       color: #252525;
+       font-family: 'Georgia', serif;
+       font-weight: normal;
+       font-size: 2.2em;
+       line-height: 1.2;
+       text-align: center;
+}
+
+div.mw-number-text {
+       display: block;
+       font-size: 1.2em;
+       color: #444;
+       margin-top: 1em;
+       text-align: center;
+}
diff --git a/resources/mediawiki.special/mediawiki.special.createAccount.vform.js b/resources/mediawiki.special/mediawiki.special.createAccount.vform.js
new file mode 100644 (file)
index 0000000..11084fe
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * JavaScript for Create account form (Special:UserLogin?type=signup).
+ */
+( function ( mw, $ ) {
+
+       $( document ).ready( function( $ ) {
+               var $content = $( '#mw-content-text' ),
+                       $submit = $content.find( '#wpCreateaccount' ),
+                       tabIndex,
+                       $captchaStuff,
+                       helpMsg = mw.config.get( 'wgCreateacctImgcaptchaHelp' ),
+                       captchaImage;
+
+               /*
+                * CAPTCHA
+                * The CAPTCHA is in a div style="captcha" at the top of the form.
+                * If it's a FancyCaptcha, then we remove it and insert it lower down,
+                * in a customized div with just what we need (e.g. no
+                * fancycaptcha-createaccount message).
+                */
+               if ( !$submit.length) {
+                       return;
+               }
+               tabIndex = $submit.prop( 'tabindex' ) - 1;
+               $captchaStuff = $content.find ( '.captcha' );
+
+               if ( $captchaStuff.length ) {
+
+                       // The FancyCaptcha image has this class in the ConfirmEdit extension
+                       // after 2013-04-18.
+                       captchaImage = $captchaStuff.find( 'img.fancycaptcha-image' );
+                       if ( captchaImage.length !== 1 ) {
+                               return;
+                       }
+
+                       $captchaStuff.remove();
+
+                       // Insert another div before the submit button.
+                       $submit.closest( 'div' )
+                               .before( [
+                       '<div>',
+                               '<label for="wpCaptchaWord">' + mw.message( 'createacct-captcha' ).escaped() + '</label>',
+                               '<div class="mw-createacct-captcha-container">',
+                                       '<div class="mw-createacct-captcha-and-reload">',
+                                               '<div class="mw-createacct-captcha-image-container">',
+                                                       '<img id="mw-createacct-captcha" alt="PLACEHOLDER">',
+                                               '</div>',
+                                       '</div>',
+                                       '<input id="wpCaptchaWord" name="wpCaptchaWord" type="text" placeholder="' +
+                                               mw.message( 'createacct-imgcaptcha-ph' ).escaped() +
+                                               '" tabindex="' + tabIndex + '" autocapitalize="off" autocorrect="off">',
+                                       '<small class="mw-createacct-captcha-assisted">' + helpMsg + '</small>',
+                               '</div>',
+                       '</div>'
+                                       ].join( '' )
+                               );
+
+                       // Replace the placeholder img with the img from the old CAPTCHA.
+                       captchaImage.replaceAll( $content.find( '#mw-createacct-captcha' ) );
+
+                       // Append CAPTCHA reload, if any.
+                       $( '.mw-createacct-captcha-and-reload' ).append( $captchaStuff.find( '.confirmedit-captcha-reload' ) );
+
+                       // Find the input field, add the text (if any) of the existing CAPTCHA
+                       // field (although usually it's blanked out on every redisplay),
+                       // and after it move over the hidden field that tells the CAPTCHA
+                       // what to do.
+                       $content.find( '#wpCaptchaWord' )
+                               .val( $captchaStuff.find( '#wpCaptchaWord' ).val() )
+                               .after( $captchaStuff.find( '#wpCaptchaId' ) );
+               }
+
+       });
+
+}( mediaWiki, jQuery ) );
index ca9fc91..2d948ea 100644 (file)
@@ -41,3 +41,12 @@ section.mw-form-header {
        text-shadow: 0 1px #fae3e3;
        word-wrap: break-word;
 }
+
+/*
+ * Override the right margin of the form to give space in case a benefits
+ * column appears to the side.
+ *
+ */
+.mw-ui-container #userloginForm {
+       margin-right: 100px;
+}