Merge "Change login/createaccount forms to new appearance"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Tue, 19 Mar 2013 18:33:42 +0000 (18:33 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Tue, 19 Mar 2013 18:33:42 +0000 (18:33 +0000)
1  2 
includes/DefaultSettings.php
includes/specials/SpecialUserlogin.php
languages/messages/MessagesEn.php
languages/messages/MessagesQqq.php
resources/Resources.php

@@@ -55,19 -55,13 +55,19 @@@ if ( !defined( 'MEDIAWIKI' ) ) 
  /**
   * wgConf hold the site configuration.
   * Not used for much in a default install.
 + * @since 1.5
   */
  $wgConf = new SiteConfiguration;
  
 -/** MediaWiki version number */
 +/**
 + * MediaWiki version number
 + * @since 1.2
 + */
  $wgVersion = '1.21alpha';
  
 -/** Name of the site. It must be changed in LocalSettings.php */
 +/**
 + * Name of the site. It must be changed in LocalSettings.php
 + */
  $wgSitename = 'MediaWiki';
  
  /**
@@@ -93,7 -87,6 +93,7 @@@ $wgServer = WebRequest::detectServer()
   * Must be fully qualified, even if $wgServer is protocol-relative.
   *
   * Defaults to $wgServer, expanded to a fully qualified http:// URL if needed.
 + * @since 1.18
   */
  $wgCanonicalServer = false;
  
@@@ -128,7 -121,6 +128,7 @@@ $wgScriptPath = '/wiki'
   * The default $wgArticlePath will be set based on this value at runtime, but if
   * you have customized it, having this incorrectly set to true can cause
   * redirect loops when "pretty URLs" are used.
 + * @since 1.2.1
   */
  $wgUsePathInfo = ( strpos( PHP_SAPI, 'cgi' ) === false ) &&
        ( strpos( PHP_SAPI, 'apache2filter' ) === false ) &&
   *
   * Some hosting providers use PHP 4 for *.php files, and PHP 5 for *.php5. This
   * variable is provided to support those providers.
 + * @since 1.11
   */
  $wgScriptExtension = '.php';
  
@@@ -183,14 -174,12 +183,14 @@@ $wgRedirectScript = false
   * The URL path to load.php.
   *
   * Defaults to "{$wgScriptPath}/load{$wgScriptExtension}".
 + * @since 1.17
   */
  $wgLoadScript = false;
  
  /**
   * The URL path of the skins directory.
   * Defaults to "{$wgScriptPath}/skins".
 + * @since 1.3
   */
  $wgStylePath = false;
  $wgStyleSheetPath = &$wgStylePath;
  /**
   * The URL path of the skins directory. Should not point to an external domain.
   * Defaults to "{$wgScriptPath}/skins".
 + * @since 1.17
   */
  $wgLocalStylePath = false;
  
@@@ -212,7 -200,6 +212,7 @@@ $wgExtensionAssetsPath = false
  /**
   * Filesystem stylesheets directory.
   * Defaults to "{$IP}/skins".
 + * @since 1.3
   */
  $wgStyleDirectory = false;
  
@@@ -250,14 -237,12 +250,14 @@@ $wgLogo = false
  
  /**
   * The URL path of the shortcut icon.
 + * @since 1.6
   */
  $wgFavicon = '/favicon.ico';
  
  /**
   * The URL path of the icon for iPhone and iPod Touch web app bookmarks.
   * Defaults to no icon.
 + * @since 1.12
   */
  $wgAppleTouchIcon = false;
  
@@@ -281,7 -266,6 +281,7 @@@ $wgTmpDirectory = false
  /**
   * If set, this URL is added to the start of $wgUploadPath to form a complete
   * upload URL.
 + * @since 1.4
   */
  $wgUploadBaseUrl = '';
  
   * Full thumbnail URL will be like $wgUploadStashScalerBaseUrl/e/e6/Foo.jpg/123px-Foo.jpg
   * where 'e6' are the first two characters of the MD5 hash of the file name.
   * If $wgUploadStashScalerBaseUrl is set to false, thumbs are rendered locally as needed.
 + * @since 1.17
   */
  $wgUploadStashScalerBaseUrl = false;
  
   *
   * There must be an appropriate script or rewrite rule in place to handle these
   * URLs.
 + * @since 1.5
   */
  $wgActionPaths = array();
  
@@@ -877,7 -859,7 +877,7 @@@ $wgSVGConverters = array
        'sodipodi' => '$path/sodipodi -z -w $width -f $input -e $output',
        'inkscape' => '$path/inkscape -z -w $width -f $input -e $output',
        'batik' => 'java -Djava.awt.headless=true -jar $path/batik-rasterizer.jar -w $width -d $output $input',
 -      'rsvg' => '$path/rsvg -w$width -h$height $input $output',
 +      'rsvg' => '$path/rsvg -w $width -h $height $input $output',
        'imgserv' => '$path/imgserv-wrapper -i svg -o png -w$width $input $output',
        'ImagickExt' => array( 'SvgHandler::rasterizeImagickExt' ),
  );
@@@ -2846,6 -2828,16 +2846,16 @@@ $wgVectorUseSimpleSearch = true
   */
  $wgVectorUseIconWatch = false;
  
+ /**
+  * Use "Agora" design for Special:Userlogin.
+  */
+ $wgUseAgoraUserLogin = false;
+ /**
+  * Use "Agora" design for account creation (Special:Userlogin?type=signup).
+  */
+ $wgUseAgoraCreateAccount = false;
  /**
   * Display user edit counts in various prominent places.
   */
@@@ -6406,7 -6398,7 +6416,7 @@@ $wgContentHandlerTextFallback = 'ignore
   *
   * @since 1.21
   */
 -$wgContentHandlerUseDB = false;
 +$wgContentHandlerUseDB = true;
  
  /**
   * Determines which types of text are parsed as wikitext. This does not imply that these kinds
@@@ -49,7 -49,9 +49,9 @@@ class LoginForm extends SpecialPage 
        var $mSkipCookieCheck, $mReturnToQuery, $mToken, $mStickHTTPS;
        var $mType, $mReason, $mRealName;
        var $mAbortLoginErrorMsg = 'login-abort-generic';
-       private $mLoaded = false;
+       private $mLoaded = false, $mSecureLoginUrl;
+       // TODO (spage 2013-02-13)  Remove old forms by, say, release 1.22.
+       private $mShowAgora;
  
        /**
         * @var ExternalUser
                        $this->mReturnTo = '';
                        $this->mReturnToQuery = '';
                }
+               $this->mShowAgora = $this->shouldShowAgora();
        }
  
        function getDescription() {
-               return $this->msg( $this->getUser()->isAllowed( 'createaccount' ) ?
-                       'userlogin' : 'userloginnocreate' )->text();
+               if ( !$this->getUser()->isAllowed( 'createaccount' ) ) {
+                       return $this->msg( 'userloginnocreate' )->text();
+               }
+               if ( $this->mShowAgora ) {
+                       return $this->msg( $this->mType === 'signup' ?
+                                       'createaccount' : 'login'
+                               )->text();
+               } else {
+                       return $this->msg( 'userlogin' )->text();
+               }
        }
  
        public function execute( $par ) {
                $this->load();
                $this->setHeaders();
  
+               // If logging in and not on HTTPS, either redirect to it or offer a link.
                global $wgSecureLogin;
                if (
                        $this->mType !== 'signup' &&
-                       $wgSecureLogin &&
                        WebRequest::detectProtocol() !== 'https'
                ) {
                        $title = $this->getFullTitle();
                                'wpStickHTTPS' => $this->mStickHTTPS
                        );
                        $url = $title->getFullURL( $query, false, PROTO_HTTPS );
-                       $this->getOutput()->redirect( $url );
-                       return;
+                       if ( $wgSecureLogin ) {
+                               $this->getOutput()->redirect( $url );
+                               return;
+                       } else {
+                               // A wiki without https login support should set wgServer to
+                               // http://somehost, in which case the secure URL generated
+                               // above actually won't be PROTO_HTTPS.
+                               if ( strncmp($url, PROTO_HTTPS, strlen( PROTO_HTTPS ) ) === 0 ) {
+                                       $this->mSecureLoginUrl = $url;
+                               }
+                       }
                }
  
                if ( $par == 'signup' ) { # Check for [[Special:Userlogin/signup]]
         * @return bool
         */
        function addNewAccount() {
 -              global $wgUser, $wgEmailAuthentication, $wgLoginLanguageSelector;
 +              global $wgContLang, $wgUser, $wgEmailAuthentication, $wgLoginLanguageSelector;
  
                # Create the account and abort if there's a problem doing so
                $status = $this->addNewAccountInternal();
  
                $u = $status->getValue();
  
 -              # If we showed up language selection links, and one was in use, be
 -              # smart (and sensible) and save that language as the user's preference
 -              if( $wgLoginLanguageSelector && $this->mLanguage ) {
 -                      $u->setOption( 'language', $this->mLanguage );
 +              # Only save preferences if the user is not creating an account for someone else.
 +              if ( $this->getUser()->isAnon() ) {
 +                      # If we showed up language selection links, and one was in use, be
 +                      # smart (and sensible) and save that language as the user's preference
 +                      if( $wgLoginLanguageSelector && $this->mLanguage ) {
 +                              $u->setOption( 'language', $this->mLanguage );
 +                      } else {
 +
 +                              # Otherwise the user's language preference defaults to $wgContLang,
 +                              # but it may be better to set it to their preferred $wgContLang variant,
 +                              # based on browser preferences or URL parameters.
 +                              $u->setOption( 'language', $wgContLang->getPreferredVariant() );
 +                      }
 +                      if ( $wgContLang->hasVariants() ) {
 +                              $u->setOption( 'variant', $wgContLang->getPreferredVariant() );
 +                      }
                }
  
                $out = $this->getOutput();
                }
        }
  
+       /**
+        * Whether to show "Agora"-style forms.
+        * ?useAgora=1 forces Agora style, ?useAgora=0 forces old-style,
+        * otherwise consult $wgAgoraUserLogin or $wgAgoraCreateAccount.
+        * @return Boolean
+        */
+       private function shouldShowAgora() {
+               global $wgRequest, $wgAgoraUserLogin, $wgAgoraCreateAccount;
+               $override = $wgRequest->getBool( 'useAgora' );
+               if ( $override !== null ) {
+                       return $override;
+               }
+               if ( $this->mType == 'signup' ) {
+                       return (boolean) $wgAgoraCreateAccount;
+               } else {
+                       return (boolean) $wgAgoraUserLogin;
+               }
+       }
+       /**
+        */
+       private function isAgoraExtensionCSSAvailable() {
+               global $wgResourceModules;
+               return array_key_exists( 'ext.agora.base', $wgResourceModules );
+       }
        /**
         * @private
         */
  
                $titleObj = $this->getTitle();
                $user = $this->getUser();
+               $out = $this->getOutput();
  
                if ( $this->mType == 'signup' ) {
                        // Block signup here if in readonly. Keeps user from
                }
  
                if ( $this->mType == 'signup' ) {
-                       $template = new UsercreateTemplate();
+                       $template = $this->mShowAgora
+                               ? new UsercreateTemplateAgora() : new UsercreateTemplate();
                        $q = 'action=submitlogin&type=signup';
                        $linkq = 'type=login';
                        $linkmsg = 'gotaccount';
-                       $this->getOutput()->addModules( 'mediawiki.special.userlogin.signup' );
+                       $out->addModules( 'mediawiki.special.userlogin.signup' );
                } else {
-                       $template = new UserloginTemplate();
+                       $template = $this->mShowAgora
+                               ? new UserloginTemplateAgora() : new UserloginTemplate();
                        $q = 'action=submitlogin&type=login';
                        $linkq = 'type=signup';
                        $linkmsg = 'nologin';
                }
+               if ( $this->mShowAgora ) {
+                       $out->addModules( array(
+                               // core Agora look, what gets loaded is dependent on skin.
+                               'mediawiki.ui',
+                               $this->mType === 'signup' ? 
+                                       'mediawiki.special.createaccount.agora' :
+                                       'mediawiki.special.userlogin.agora'
+                       ) );
+               }
  
                if ( $this->mReturnTo !== '' ) {
                        $returnto = '&returnto=' . wfUrlencode( $this->mReturnTo );
                        $linkq .= $returnto;
                }
  
-               # Don't show a "create account" link if the user can't
+               # Don't show a "create account" link if the user can't.
                if( $this->showCreateOrLoginLink( $user ) ) {
                        # Pass any language selection on to the mode switch link
                        if( $wgLoginLanguageSelector && $this->mLanguage ) {
                                $linkq .= '&uselang=' . $this->mLanguage;
                        }
-                       $link = Html::element( 'a', array( 'href' => $titleObj->getLocalURL( $linkq ) ),
-                               $this->msg( $linkmsg . 'link' )->text() ); # Calling either 'gotaccountlink' or 'nologinlink'
+                       if ( !$this->mShowAgora ) {
+                               $link = Html::element( 'a', array( 'href' => $titleObj->getLocalURL( $linkq ) ),
+                                       $this->msg( $linkmsg . 'link' )->text() ); # Calling either 'gotaccountlink' or 'nologinlink'
+                                       $template->set( 'link', $this->msg( $linkmsg )->rawParams( $link )->parse() );
  
-                       $template->set( 'link', $this->msg( $linkmsg )->rawParams( $link )->parse() );
+                       } else {
+                               // Supply hyperlink, login template creates the button.
+                               // (The template 'link' key is obsolete in the Agora design.)
+                               $template->set( 'createOrLoginHref', $titleObj->getLocalURL( $linkq ) );
+                       }
                } else {
                        $template->set( 'link', '' );
                }
                        }
                }
  
+               $template->set( 'secureLoginUrl', $this->mSecureLoginUrl );
                // Use loginend-https for HTTPS requests if it's not blank, loginend otherwise
-               // Ditto for signupend
+               // Ditto for signupend.  Agora forms use neither.
                $usingHTTPS = WebRequest::detectProtocol() == 'https';
                $loginendHTTPS = $this->msg( 'loginend-https' );
                $signupendHTTPS = $this->msg( 'signupend-https' );
                        wfRunHooks( 'UserLoginForm', array( &$template ) );
                }
  
-               $out = $this->getOutput();
                $out->disallowUserJs(); // just in case...
                $out->addTemplate( $template );
        }
@@@ -1075,9 -1075,20 +1075,20 @@@ Note that some pages may continue to b
  'welcomecreation-msg'        => 'Your account has been created.
  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',
  'securelogin-stick-https'    => 'Stay connected to HTTPS after login',
  'yourdomainname'             => 'Your domain:',
  'password-change-forbidden'  => 'You cannot change passwords on this wiki.',
  'userlogout'                 => 'Log out',
  'userlogout-summary'         => '', # do not translate or duplicate this message to other languages
  'notloggedin'                => 'Not logged in',
+ 'userlogin-noaccount' => "Don't have an account?",
+ 'userlogin-joinproject'      => 'Join {{SITENAME}}',
  'nologin'                    => "Don't have an account? $1.",
  'nologinlink'                => 'Create an account',
  'createaccount'              => 'Create account',
  'gotaccount'                 => 'Already have an account? $1.',
  'gotaccountlink'             => 'Log in',
  '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',
  'createaccountreason'        => 'Reason:',
+ 'createacct-reason'          => 'Reason',
+ '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.',
@@@ -1149,8 -1179,8 +1179,8 @@@ Please log in again after you receive i
  'blocked-mailpassword'       => 'Your IP address is blocked from editing, and so is not allowed to use the password recovery function to prevent abuse.',
  'eauthentsent'               => 'A confirmation email has been sent to the nominated email address.
  Before any other email is sent to the account, you will have to follow the instructions in the email, to confirm that the account is actually yours.',
 -'throttled-mailpassword'     => 'A password reminder has already been sent, within the last {{PLURAL:$1|hour|$1 hours}}.
 -To prevent abuse, only one password reminder will be sent per {{PLURAL:$1|hour|$1 hours}}.',
 +'throttled-mailpassword'     => 'A password reset email has already been sent, within the last {{PLURAL:$1|hour|$1 hours}}.
 +To prevent abuse, only one password reset email will be sent per {{PLURAL:$1|hour|$1 hours}}.',
  'loginstart'                 => '', # do not translate or duplicate this message to other languages
  'loginend'                   => '', # do not translate or duplicate this message to other languages
  'loginend-https'             => '', # do not translate or duplicate this message to other languages
@@@ -1219,7 -1249,7 +1249,7 @@@ You may have already successfully chang
  
  # Special:PasswordReset
  'passwordreset'                    => 'Reset password',
 -'passwordreset-text'               => 'Complete this form to receive an email reminder of your account details.',
 +'passwordreset-text'               => 'Complete this form to reset your password.',
  'passwordreset-legend'             => 'Reset password',
  'passwordreset-disabled'           => 'Password resets have been disabled on this wiki.',
  'passwordreset-pretext'            => '{{PLURAL:$1||Enter one of the pieces of data below}}',
  'passwordreset-capture-help'       => 'If you check this box, the email (with the temporary password) will be shown to you as well as being sent to the user.',
  'passwordreset-email'              => 'Email address:',
  'passwordreset-emailtitle'         => 'Account details on {{SITENAME}}',
 -'passwordreset-emailtext-ip'       => 'Someone (probably you, from IP address $1) requested a reminder of your
 -account details for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}
 +'passwordreset-emailtext-ip'       => 'Someone (probably you, from IP address $1) requested a reset of your
 +password for {{SITENAME}} ($4). The following user {{PLURAL:$3|account is|accounts are}}
  associated with this email address:
  
  $2
@@@ -1240,7 -1270,7 +1270,7 @@@ You should log in and choose a new pass
  request, or if you have remembered your original password, and you no longer
  wish to change it, you may ignore this message and continue using your old
  password.',
 -'passwordreset-emailtext-user'     => 'User $1 on {{SITENAME}} requested a reminder of your account details for {{SITENAME}}
 +'passwordreset-emailtext-user'     => 'User $1 on {{SITENAME}} requested a reset of your password for {{SITENAME}}
  ($4). The following user {{PLURAL:$3|account is|accounts are}} associated with this email address:
  
  $2
@@@ -1252,9 -1282,9 +1282,9 @@@ wish to change it, you may ignore this 
  password.',
  'passwordreset-emailelement'       => 'Username: $1
  Temporary password: $2',
 -'passwordreset-emailsent'          => 'A reminder email has been sent.',
 -'passwordreset-emailsent-capture'  => 'A reminder email has been sent, which is shown below.',
 -'passwordreset-emailerror-capture' => 'A reminder email was generated, which is shown below, but sending it to the user failed: $1',
 +'passwordreset-emailsent'          => 'A password reset email has been sent.',
 +'passwordreset-emailsent-capture'  => 'A password reset email has been sent, which is shown below.',
 +'passwordreset-emailerror-capture' => 'A password reset email was generated, which is shown below, but sending it to the user failed: $1',
  
  # Special:ChangeEmail
  'changeemail'          => 'Change email address',
@@@ -4869,17 -4899,17 +4899,17 @@@ This site is experiencing technical dif
  'sqlite-no-fts'  => '$1 without full-text search support',
  
  # New logging system
 -'logentry-delete-delete'              => '$1 deleted page $3',
 -'logentry-delete-restore'             => '$1 restored page $3',
 -'logentry-delete-event'               => '$1 changed visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4',
 -'logentry-delete-revision'            => '$1 changed visibility of {{PLURAL:$5|a revision|$5 revisions}} on page $3: $4',
 -'logentry-delete-event-legacy'        => '$1 changed visibility of log events on $3',
 -'logentry-delete-revision-legacy'     => '$1 changed visibility of revisions on page $3',
 -'logentry-suppress-delete'            => '$1 suppressed page $3',
 -'logentry-suppress-event'             => '$1 secretly changed visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4',
 -'logentry-suppress-revision'          => '$1 secretly changed visibility of {{PLURAL:$5|a revision|$5 revisions}} on page $3: $4',
 -'logentry-suppress-event-legacy'      => '$1 secretly changed visibility of log events on $3',
 -'logentry-suppress-revision-legacy'   => '$1 secretly changed visibility of revisions on page $3',
 +'logentry-delete-delete'              => '$1 {{GENDER:$2|deleted}} page $3',
 +'logentry-delete-restore'             => '$1 {{GENDER:$2|restored}} page $3',
 +'logentry-delete-event'               => '$1 {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4',
 +'logentry-delete-revision'            => '$1 {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a revision|$5 revisions}} on page $3: $4',
 +'logentry-delete-event-legacy'        => '$1 {{GENDER:$2|changed}} visibility of log events on $3',
 +'logentry-delete-revision-legacy'     => '$1 {{GENDER:$2|changed}} visibility of revisions on page $3',
 +'logentry-suppress-delete'            => '$1 {{GENDER:$2|suppressed}} page $3',
 +'logentry-suppress-event'             => '$1 secretly {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a log event|$5 log events}} on $3: $4',
 +'logentry-suppress-revision'          => '$1 secretly {{GENDER:$2|changed}} visibility of {{PLURAL:$5|a revision|$5 revisions}} on page $3: $4',
 +'logentry-suppress-event-legacy'      => '$1 secretly {{GENDER:$2|changed}} visibility of log events on $3',
 +'logentry-suppress-revision-legacy'   => '$1 secretly {{GENDER:$2|changed}} visibility of revisions on page $3',
  'revdelete-content-hid'               => 'content hidden',
  'revdelete-summary-hid'               => 'edit summary hidden',
  'revdelete-uname-hid'                 => 'username hidden',
  'revdelete-uname-unhid'               => 'username unhidden',
  'revdelete-restricted'                => 'applied restrictions to administrators',
  'revdelete-unrestricted'              => 'removed restrictions for administrators',
 -'logentry-move-move'                  => '$1 moved page $3 to $4',
 -'logentry-move-move-noredirect'       => '$1 moved page $3 to $4 without leaving a redirect',
 -'logentry-move-move_redir'            => '$1 moved page $3 to $4 over redirect',
 -'logentry-move-move_redir-noredirect' => '$1 moved page $3 to $4 over a redirect without leaving a redirect',
 -'logentry-patrol-patrol'              => '$1 marked revision $4 of page $3 patrolled',
 -'logentry-patrol-patrol-auto'         => '$1 automatically marked revision $4 of page $3 patrolled',
 -'logentry-newusers-newusers'          => 'User account $1 was created',
 -'logentry-newusers-create'            => 'User account $1 was created',
 -'logentry-newusers-create2'           => 'User account $3 was created by $1',
 -'logentry-newusers-byemail'           => 'User account $3 was created by $1 and password was sent by email',
 -'logentry-newusers-autocreate'        => 'User account $1 was created automatically',
 -'logentry-rights-rights'              => '$1 changed group membership for $3 from $4 to $5',
 -'logentry-rights-rights-legacy'       => '$1 changed group membership for $3',
 -'logentry-rights-autopromote'         => '$1 was automatically promoted from $4 to $5',
 +'logentry-move-move'                  => '$1 {{GENDER:$2|moved}} page $3 to $4',
 +'logentry-move-move-noredirect'       => '$1 {{GENDER:$2|moved}} page $3 to $4 without leaving a redirect',
 +'logentry-move-move_redir'            => '$1 {{GENDER:$2|moved}} page $3 to $4 over redirect',
 +'logentry-move-move_redir-noredirect' => '$1 {{GENDER:$2|moved}} page $3 to $4 over a redirect without leaving a redirect',
 +'logentry-patrol-patrol'              => '$1 {{GENDER:$2|marked}} revision $4 of page $3 patrolled',
 +'logentry-patrol-patrol-auto'         => '$1 automatically {{GENDER:$2|marked}} revision $4 of page $3 patrolled',
 +'logentry-newusers-newusers'          => 'User account $1 was {{GENDER:$2|created}}',
 +'logentry-newusers-create'            => 'User account $1 was {{GENDER:$2|created}}',
 +'logentry-newusers-create2'           => 'User account $3 was {{GENDER:$2|created}} by $1',
 +'logentry-newusers-byemail'           => 'User account $3 was {{GENDER:$2|created}} by $1 and password was sent by email',
 +'logentry-newusers-autocreate'        => 'User account $1 was {{GENDER:$2|created}} automatically',
 +'logentry-rights-rights'              => '$1 {{GENDER:$2|changed}} group membership for $3 from $4 to $5',
 +'logentry-rights-rights-legacy'       => '$1 {{GENDER:$2|changed}} group membership for $3',
 +'logentry-rights-autopromote'         => '$1 was automatically {{GENDER:$2|promoted}} from $4 to $5',
  'rightsnone'                          => '(none)',
  
  # For IRC, see bug 34508. Do not change
@@@ -1038,18 -1038,29 +1038,29 @@@ Parameters
  'yourname' => "{{doc-important|<nowiki>{{</nowiki>[[Gender|GENDER]]<nowiki>}}</nowiki> is '''NOT''' supported.}}
  In user preferences.
  {{Identical|Username}}",
+ 'userlogin-yourname' => "In Agora user login & create account forms, label for username field",
+ 'userlogin-yourname-ph' => "Placeholder text in Agora userlogin/create account form field.",
  'yourpassword' => 'In user preferences
  
  {{Identical|Password}}',
+ 'createacct-helpusername-url' => 'The URL of a page providing username guidance for the wiki.',
+ 'createacct-helpusername-link' => 'Message in Agora create account form providing guidance for username.',
+ 'userlogin-yourpassword' => "In Agora user login & create account forms, label for password field",
+ 'userlogin-yourpassword-ph' => "Placeholder text in Agora userlogin form for password field.",
+ 'createacct-yourpassword-ph' => "Placeholder text in Agora create account form for password field.",
  'yourpasswordagain' => 'In user preferences',
+ 'createacct-yourpasswordagain' => 'In Agora create account form, label for field to re-enter password',
+ 'createacct-yourpasswordagain-ph' => 'Placeholder text in Agora create account form for re-enter password field.',
  'remembermypassword' => 'A check box in [[Special:UserLogin]]
  
  {{Identical|Remember my login on this computer}}',
+ 'userlogin-remembermypassword' => 'The text for a check box in the Agora-style [[Special:UserLogin]]',
+ 'userlogin-signwithsecure'   => 'Text of link to HTTPS login form',
  'securelogin-stick-https' => 'Used as label for checkbox.',
  'yourdomainname' => 'Used as label for listbox.',
  'password-change-forbidden' => 'Error message shown when an external authentication source does not allow the password to be changed.',
  'externaldberror' => 'This message is thrown when a valid attempt to change the wiki password for a user fails because of a database error or an error from an external system.',
- 'login' => "Shown as the caption of the button at [[Special:UserLogin]], and also to anonymous users in the upper right corner of the page when they can't create an account (otherwise the message {{msg-mw|nav-login-createaccount}} is shown there).
+ 'login' => "Shown as the caption of the button at [[Special:UserLogin]], and also to anonymous users in the upper right corner of the page when they can't create an account (otherwise the message {{msg-mw|nav-login-createaccount}} is shown there). Also the title of the Agora login special page, which does not combine Log in & Create account.
  
  See also:
  * {{msg-mw|Login}}
@@@ -1076,6 -1087,8 +1087,8 @@@ See also
  'notloggedin' => 'This message is displayed in the standard skin when not logged in. The message is placed above the login link in the top right corner of pages.
  
  {{Identical|Not logged in}}',
+ 'userlogin-noaccount' => 'In the Agora-style [[Special:Userlogin]] form, this is the text prior to button inviting user to join project',
+ 'userlogin-joinproject' => 'Text of button inviting user to create an account',
  'nologin' => 'A message shown in the log in form. Parameters:
  * $1 - a link to the account creation form, and the text of it is {{msg-mw|Nologinlink}}',
  'nologinlink' => 'Text of the link to the account creation form. Before that link, the message {{msg-mw|Nologin}} appears.
@@@ -1089,12 -1102,28 +1102,29 @@@ It is also used on the top of the page 
  'gotaccountlink' => 'Text of the link to the log in form. Before that link, the message {{msg-mw|Gotaccount}} appears.
  {{Identical|Log in}}',
  'userlogin-resetlink' => 'Used on the login page.',
+ 'helplogin-url' => 'Description: The URL the provides information on logging in to the wiki.',
+ 'userlogin-helplink' => 'Wiki text linking to login help',
+ 'createacct-join' => 'Subheading of create account form encouraging user to join the wiki.',
+ 'createacct-emailrequired'  => 'Label in Agora create account form for email field when it is required.',
+ 'createacct-emailoptional' => 'Label in Agora create account form for email field when it is optional.',
+ 'createacct-email-ph'  => 'Placeholder in Agora 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.',
  'createaccountreason' => '{{Identical|Reason}}',
+ 'createacct-reason' => 'In Agora create account form, label for field to enter reason to create an account when already logged-in.',
+ 'createacct-benefit-heading' => 'In Agora create account form, the heading for the section describing the benefits of creating an account.',
+ 'createacct-benefit-icon1' => 'In Agora 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 Agora 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 Agora create account form, the text for the first benefit.',
+ 'createacct-benefit-icon2' => 'In Agora 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 Agora 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 Agora create account form, the text for the second benefit.',
+ 'createacct-benefit-icon3' => 'In Agora 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 Agora 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 Agora 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.',
 +'loginerror' => 'Used as title of error message.
 +{{Identical|Login error}}',
  'createaccounterror' => 'Parameters:
  * $1 is an error message',
  'nocookiesnew' => "This message is displayed when a new account was successfully created, but the browser doesn't accept cookies.",
@@@ -1143,7 -1172,7 +1173,7 @@@ Parameters
  '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}}'.",
  'throttled-mailpassword' => 'Used in [[Special:PasswordReset]].
 -* $1 - password reminder resend time (in hours)',
 +* $1 - password reset email resend time (in hours)',
  'mailerror' => 'Used as error message in sending confirmation mail to user. Parameters:
  * $1 - new mail address',
  'acct_creation_throttle_hit' => 'Error message at [[Special:CreateAccount]].
@@@ -1241,7 -1270,7 +1271,7 @@@ Parameters
  * $2 - message {{msg-mw|passwordreset-emailelement|notext=1}} repeated $3 times
  * $3 - the number of repetitions in $2
  * $4 - base URL of the wiki',
 -'passwordreset-emailelement' => "This is a body of a reminder email to allow them into the system with a new password. Parameters:
 +'passwordreset-emailelement' => "This is a body of a password reset email to allow them into the system with a new password. Parameters:
  * $1 - the user's login name. This parameter can be used for GENDER.
  * $2 - the temporary password given by the system",
  'passwordreset-emailsent' => 'Used in [[Special:PasswordReset]].
@@@ -2451,6 -2480,8 +2481,8 @@@ This option lets your time zone settin
  'prefs-emailconfirm-label' => 'Sub-heading in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}.',
  'prefs-textboxsize' => "Header for the box specifying the size of the editing window, displayed on the 'editing' tab of the [[Special:Preferences|user preferences]] special page.",
  'youremail' => 'Label of the e-mail text box of the "E-mail options" section of [[Special:Preferences]].
+ Also used on create account form.
  {{Identical|E-mail}}',
  'username' => 'Username field in [[Special:Preferences]]. $1 is the current user name for GENDER distinction (depends on sex setting).
  
@@@ -6828,11 -6859,12 +6860,11 @@@ Parameters
  'svg-long-desc' => 'Displayed under an SVG image at the image description page. Note that argument 3 is a string that includes the file size unit symbol. See for example [[:File:Yes check.svg]].
  
  Start with a lowercase letter, unless the first word is "SVG".',
 -'svg-long-desc-animated' => 'Displayed under an SVG image at the image description page if the image is animated. Non-animated images use {{msg-mw|svg-long-desc}}.
 +'svg-long-desc-animated' => 'Displayed under an SVG image at the image description page if the image is animated.
  * $1 - the width in pixels
  * $2 - the height in pixels
  * $3 - the file size including a unit (for example "10 KB")
 -
 -Start with a lowercase letter, unless the first word is "SVG".',
 +Non-animated images use {{msg-mw|svg-long-desc}}.',
  'svg-long-error' => 'Displayed for invalid SVG file metadata. Parameters:
  * $1 - the error message
  See also:
diff --combined resources/Resources.php
@@@ -160,7 -160,6 +160,7 @@@ return array
        ),
        'jquery.checkboxShiftClick' => array(
                'scripts' => 'resources/jquery/jquery.checkboxShiftClick.js',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.client' => array(
                'scripts' => 'resources/jquery/jquery.client.js',
                'scripts' => 'resources/jquery/jquery.makeCollapsible.js',
                'styles' => 'resources/jquery/jquery.makeCollapsible.css',
                'messages' => array( 'collapsible-expand', 'collapsible-collapse' ),
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.mockjax' => array(
                'scripts' => 'resources/jquery/jquery.mockjax.js',
        ),
        'jquery.mw-jump' => array(
                'scripts' => 'resources/jquery/jquery.mw-jump.js',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.mwExtension' => array(
                'scripts' => 'resources/jquery/jquery.mwExtension.js',
        ),
        'jquery.placeholder' => array(
                'scripts' => 'resources/jquery/jquery.placeholder.js',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.qunit' => array(
                'scripts' => 'resources/jquery/jquery.qunit.js',
                'styles' => 'resources/jquery/jquery.qunit.css',
                'position' => 'top',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.qunit.completenessTest' => array(
                'scripts' => 'resources/jquery/jquery.qunit.completenessTest.js',
                'dependencies' => 'jquery.qunit',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'jquery.spinner' => array(
                'scripts' => 'resources/jquery/jquery.spinner.js',
                        'jquery.mw-jump',
                        'mediawiki.util',
                ),
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'mediawiki.page.startup' => array(
                'scripts' => 'resources/mediawiki.page/mediawiki.page.startup.js',
                        'mediawiki.util',
                ),
                'position' => 'top',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
        'mediawiki.page.patrol.ajax' => array(
                'scripts' => 'resources/mediawiki.page/mediawiki.page.patrol.ajax.js',
        'mediawiki.special.userlogin.signup' => array(
                'scripts' => 'resources/mediawiki.special/mediawiki.special.userLogin.signup.js',
        ),
+       'mediawiki.special.userlogin.agora' => array(
+               'styles' => array(
+                       'resources/mediawiki.special/mediawiki.special.forms.agora.css',
+                       'resources/mediawiki.special/mediawiki.special.userlogin.agora.css',
+               ),
+               'position' => 'top',
+       ),
+       'mediawiki.special.createaccount.agora' => array(
+               'scripts' => 'resources/mediawiki.special/mediawiki.special.createaccount.agora.js',
+               'styles' => array(
+                       'resources/mediawiki.special/mediawiki.special.forms.agora.css',
+                       'resources/mediawiki.special/mediawiki.special.createaccount.agora.css',
+               ),
+               'position' => 'top',
+       ),
        'mediawiki.special.javaScriptTest' => array(
                'scripts' => 'resources/mediawiki.special/mediawiki.special.javaScriptTest.js',
                'messages' => array_merge( Skin::getSkinNameMessages(), array(
                ) ),
                'dependencies' => array( 'jquery.qunit' ),
                'position' => 'top',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
  
        /* MediaWiki Tests */
                        'mediawiki.page.ready',
                ),
                'position' => 'top',
 +              'targets' => array( 'desktop', 'mobile' ),
        ),
  
        /* MediaWiki Legacy */
                'remoteBasePath' => $GLOBALS['wgStylePath'],
                'localBasePath' => $GLOBALS['wgStyleDirectory'],
        ),
+       'mediawiki.ui' => array(
+               'skinStyles' => array(
+                       'default' => 'resources/mediawiki.ui/mediawiki.ui.default.css',
+                       'vector' => 'resources/mediawiki.ui/mediawiki.ui.vector.css',
+               ),
+               'position' => 'top',
+       ),
  );