Change login/createaccount forms to new appearance
authorS Page <spage@wikimedia.org>
Tue, 5 Mar 2013 03:13:39 +0000 (19:13 -0800)
committerS Page <spage@wikimedia.org>
Tue, 19 Mar 2013 04:12:03 +0000 (21:12 -0700)
If a global variable is set or if you add ?useAgora=1 to the query
string, Special:Userlogin loads a different login or create account
template (Userlogin-/UsercreateAgora.php) with an Agora look and
different messaging.  Otherwise the current form is unchanged so
that wikis can cut over to the new look when desired.

These new templates apply mw-ui-formlist and mw-ui-button styles defined
in a new 'mediawiki.ui' CSS module in core (copied from Extension:Agora).

In useAgora mode, Special:Userlogin also:
* Adds new modules with some additional CSS for new form features
  ("Join wiki", benefits of creating an account).
* Defines new "userlogin/usercreate-xx" messages, many are the same as
  existing messages but without ':' on the end.
* Uses a distinct title for each mode instead of generic "Log in /
  Create account".
* Uses JavaScript to munge the create account CAPTCHA.
* Outputs checkboxes using UserloginTemplateAgora::labelledCheck()
* Displays a benefits column of wiki edits/users/contributor numbers.

TODO:
- Restyle/reposition language selector
- Munge CAPTCHA in PHP not JavaScript, i18n of new CAPTCHA messages.
- Identify the subset of Agora appropriate for non-Vector skins and
  create mediawiki.ui.default.css from that.

Patch set 18: Agora styles now in core.

Bug: 44628
Change-Id: I859edab4fc4fa9fe35fdef15fc429ae19a95305d

20 files changed:
includes/AutoLoader.php
includes/DefaultSettings.php
includes/specials/SpecialUserlogin.php
includes/templates/UsercreateAgora.php [new file with mode: 0644]
includes/templates/UserloginAgora.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/glyph-people-large.png [new file with mode: 0644]
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-lock.png [new file with mode: 0644]
resources/mediawiki.special/images/icon-pages.png [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.createaccount.agora.css [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.createaccount.agora.js [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.forms.agora.css [new file with mode: 0644]
resources/mediawiki.special/mediawiki.special.userlogin.agora.css [new file with mode: 0644]
resources/mediawiki.ui/mediawiki.ui.default.css [new file with mode: 0644]
resources/mediawiki.ui/mediawiki.ui.vector.css [new file with mode: 0644]

index 7136232..1f56b12 100644 (file)
@@ -1011,7 +1011,10 @@ $wgAutoloadLocalClasses = array(
 
        # includes/templates
        'UserloginTemplate' => 'includes/templates/Userlogin.php',
+       'AgoraTemplate' => 'includes/templates/UserloginAgora.php',
+       'UserloginTemplateAgora' => 'includes/templates/UserloginAgora.php',
        'UsercreateTemplate' => 'includes/templates/Usercreate.php',
+       'UsercreateTemplateAgora' => 'includes/templates/UsercreateAgora.php',
 
        # includes/upload
        'UploadBase' => 'includes/upload/UploadBase.php',
index 5d051d7..18ddb9c 100644 (file)
@@ -2828,6 +2828,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.
  */
index dc350bf..9ec0235 100644 (file)
@@ -49,7 +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
@@ -134,11 +136,21 @@ class LoginForm extends SpecialPage {
                        $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 ) {
@@ -149,10 +161,10 @@ class LoginForm extends SpecialPage {
                $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();
@@ -162,8 +174,17 @@ class LoginForm extends SpecialPage {
                                '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]]
@@ -1011,6 +1032,32 @@ class LoginForm extends SpecialPage {
                }
        }
 
+       /**
+        * 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
         */
@@ -1022,6 +1069,7 @@ class LoginForm extends SpecialPage {
 
                $titleObj = $this->getTitle();
                $user = $this->getUser();
+               $out = $this->getOutput();
 
                if ( $this->mType == 'signup' ) {
                        // Block signup here if in readonly. Keeps user from
@@ -1048,17 +1096,28 @@ class LoginForm extends SpecialPage {
                }
 
                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 );
@@ -1070,16 +1129,23 @@ class LoginForm extends SpecialPage {
                        $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', '' );
                }
@@ -1139,8 +1205,9 @@ class LoginForm extends SpecialPage {
                        }
                }
 
+               $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' );
@@ -1163,7 +1230,6 @@ class LoginForm extends SpecialPage {
                        wfRunHooks( 'UserLoginForm', array( &$template ) );
                }
 
-               $out = $this->getOutput();
                $out->disallowUserJs(); // just in case...
                $out->addTemplate( $template );
        }
diff --git a/includes/templates/UsercreateAgora.php b/includes/templates/UsercreateAgora.php
new file mode 100644 (file)
index 0000000..44ea9c8
--- /dev/null
@@ -0,0 +1,281 @@
+<?php
+/**
+ * Html form for account creation with new Agora 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
+ */
+
+/**
+ * @defgroup Templates Templates
+ */
+
+if( !defined( 'MEDIAWIKI' ) ) die( -1 );
+
+/**
+ * @ingroup Templates
+ */
+class UsercreateTemplateAgora extends AgoraTemplate {
+       function addInputItem( $name, $value, $type, $msg, $helptext = false ) {
+               $this->data['extraInput'][] = array(
+                       'name' => $name,
+                       'value' => $value,
+                       'type' => $type,
+                       'msg' => $msg,
+                       'helptext' => $helptext,
+               );
+       }
+
+       function execute() {
+?>
+<div class="mw-ui-container">
+<div id="userloginForm">
+<h2 class="createaccount-join"><?php $this->msg('createacct-join') ?></h2>
+<form name="userlogin2" id="userlogin2" method="post" action="<?php $this->text('action') ?>">
+       <?php $this->html('header'); /* pre-table point for form plugins... */ ?>
+       <?php if( $this->haveData( 'languages' ) ) { ?><div id="languagelinks"><p><?php $this->html( 'languages' ); ?></p></div><?php } ?>
+       <ul class="mw-ui-formlist">
+       <?php
+       if( $this->data['message'] ) {
+?>
+               <li>
+                       <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>
+                       <div class="visualClear"></div>
+               </li>
+       <?php } ?>
+               <li>
+                       <label for='wpName2'>
+                               <?php $this->msg('userlogin-yourname') ?>
+
+                               <span class="mw-ui-flush-right"><?php echo wfMessage( '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' => wfMessage( 'userlogin-yourname-ph' )->text(),
+                               'autofocus'
+                       ) ); ?>
+               </li>
+               <li>
+               <?php if( $this->data['createemail'] ) {
+                       echo UserloginTemplateAgora::labelledCheck(
+                               wfMessage( 'createaccountmail' )->text(),
+                               'wpCreateaccountMail',
+                               'wpCreateaccountMail',
+                               $this->data['createemailset'],
+                               array( 'tabindex' => '2' )
+                       );
+               } ?>
+               </li>
+               <li 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' => wfMessage( 'createacct-yourpassword-ph' )->text()
+                       ) + User::passwordChangeInputAttribs() ); ?>
+               </li>
+       <?php if( $this->data['usedomain'] ) {
+               $doms = "";
+               foreach( $this->data['domainnames'] as $dom ) {
+                       $doms .= "<option>" . htmlspecialchars( $dom ) . "</option>";
+               }
+       ?>
+               <li>
+                       <!-- TODO (spage 2013-02-13) what replaces td class="mw-label" ? -->
+                       <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>
+               </li>
+       <?php } ?>
+               <li 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' => wfMessage( 'createacct-yourpasswordagain-ph' )->text()
+                               ) + User::passwordChangeInputAttribs() );
+                       ?>
+               </li>
+               <li>
+               <?php if( $this->data['useemail'] ) { ?>
+                       <label for='wpEmail'><?php $this->msg('createacct-emailoptional') // FIXME required/optional message
+                               // FIXME        $this->data['emailrequired'] ? createacct-emailrequired / optional.
+               ?></label>
+                       <?php
+                               echo Html::input( 'wpEmail', $this->data['email'], 'email', array(
+                                       'class' => 'mw-input loginText',
+                                       'id' => 'wpEmail',
+                                       'tabindex' => '6',
+                                       'size' => '20',
+                                       'placeholder' => wfMessage( 'createacct-email-ph' )->text()
+                                       # Can't do + array( 'autofocus' ) because + for arrays in PHP
+                                       # only works right for associative arrays!  Thanks, PHP.
+                               ) + ( $this->data['emailrequired'] ? array() : array( 'required' => '' ) ) );
+                       ?>
+                       <?php
+                       // Agora eliminate 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 } ?>
+               </li>
+               <?php if( $this->data['userealname'] ) { ?>
+                       <li>
+                               <label for='wpRealName'><?php $this->msg('yourrealname') ?></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>
+                       </li>
+               <?php } ?>
+               <?php if( $this->data['usereason'] ) { ?>
+                       <li>
+                               <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' />
+                       </li>
+               <?php } ?>
+               <?php if( $this->data['canremember'] ) { ?>
+                       <li>
+                               <?php
+                               global $wgCookieExpiration;
+                               $expirationDays = ceil( $wgCookieExpiration / ( 3600 * 24 ) );
+                               echo UserloginTemplateAgora::labelledCheck(
+                                       wfMessage( 'remembermypassword' )->numParams( $expirationDays )->text(),
+                                       'wpRemember',
+                                       'wpRemember',
+                                       $this->data['remember'],
+                                       array( 'tabindex' => '9' )
+                               )
+                               ?>
+                       </li>
+               <?php }
+
+               $tabIndex = 10;
+               if ( isset( $this->data['extraInput'] ) && is_array( $this->data['extraInput'] ) ) {
+                       foreach ( $this->data['extraInput'] as $inputItem ) { ?>
+                       <li>
+                               <?php
+                                       // Output the message label, unless it's a checkbox.
+                                       if ( !empty( $inputItem['msg'] ) && $inputItem['type'] != 'checkbox' ) {
+                                               ?><label for="<?php
+                                               echo htmlspecialchars( $inputItem['name'] ); ?>"><?php
+                                               $this->msgWiki( $inputItem['msg'] ) ?></label><?php
+                                       } else {
+                                               ## Lost in table rows here...
+                                               ?><!-- do I need to output a label to v-align these optional checkboxes? --><?php
+                                       }
+                               ?>
+                               <input type="<?php echo htmlspecialchars( $inputItem['type'] ) ?>" class="mw-input" name="<?php
+                                       echo htmlspecialchars( $inputItem['name'] ); ?>"
+                                               tabindex="<?php echo $tabIndex++; ?>"
+                                               value="<?php
+                                       if ( $inputItem['type'] != 'checkbox' ) {
+                                               echo htmlspecialchars( $inputItem['value'] );
+                                       } else {
+                                               echo '1';
+                                       }
+                                       ?>" id="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"
+                                               <?php
+                                       if ( $inputItem['type'] == 'checkbox' && !empty( $inputItem['value'] ) )
+                                               echo 'checked="checked"';
+                                               ?> /> <?php
+                                               if ( $inputItem['type'] == 'checkbox' && !empty( $inputItem['msg'] ) ) {
+                                                       ?>
+                                       <label for="<?php echo htmlspecialchars( $inputItem['name'] ); ?>"><?php
+                                               $this->msgHtml( $inputItem['msg'] ) ?></label><?php
+                                               }
+                                       if( $inputItem['helptext'] !== false ) {
+                                       ?>
+                                       <div class="prefsectiontip">
+                                               <?php $this->msgWiki( $inputItem['helptext'] ); ?>
+                                       </div>
+                                       <?php } ?>
+                       </li>
+<?php
+                       }
+               }
+?>
+               <li>
+                       <div class="mw-submit">
+                               <input type='submit' class="mw-ui-button big block primary" name="wpCreateaccount" id="wpCreateaccount"
+                                       tabindex="<?php echo $tabIndex++; ?>"
+                                       value="<?php $this->msg('createaccount') ?>" />
+                       </div>
+               </li>
+       </ul>
+       <input type="hidden" id="useAgora" name="useAgora" 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="createacct-benefits-container hidden-phone visible-desktop visible-tablet">
+       <h2><?php echo wfMessage( 'createacct-benefit-heading' )->text() ?></h2>
+       <ul class="createacct-benefits-list">
+               <li>
+                       <div class="benefits-icon <?php echo wfMessage( 'createacct-benefit-icon1' )->text() ?>"></div>
+                       <div class="number-text">
+                               <h3><?php echo wfMessage( 'createacct-benefit-head1' )->text() ?></h3>
+                               <p><?php echo wfMessage( 'createacct-benefit-body1' )->text() ?></p>
+                       </div>
+               </li>
+               <li>
+                       <div class="benefits-icon <?php echo wfMessage( 'createacct-benefit-icon2' )->text() ?>"></div>
+                       <div class="number-text">
+                               <h3><?php echo wfMessage( 'createacct-benefit-head2' )->text() ?></h3>
+                               <p><?php echo wfMessage( 'createacct-benefit-body2' )->text() ?></p>
+                       </div>
+               </li>
+               <li>
+                       <div class="benefits-icon <?php echo wfMessage( 'createacct-benefit-icon3' )->text() ?>"></div>
+                       <div class="number-text">
+                               <h3><?php echo wfMessage( 'createacct-benefit-head3' )->text() ?></h3>
+                               <p><?php echo wfMessage( 'createacct-benefit-body3' )->text() ?></p>
+                       </div>
+               </li>
+  </ul>
+</div>
+</div>
+<?php
+
+       }
+}
diff --git a/includes/templates/UserloginAgora.php b/includes/templates/UserloginAgora.php
new file mode 100644 (file)
index 0000000..58bed78
--- /dev/null
@@ -0,0 +1,225 @@
+<?php
+/**
+ * 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
+ */
+
+/**
+ * @defgroup Templates Templates
+ */
+
+/**
+ * New base template for Agora-look templates that provides helper methods for
+ * some Agora-specific layouts.
+ */
+abstract class AgoraTemplate extends QuickTemplate {
+
+       /**
+        * Convenience function to build an Agora HTML checkbox nested inside a
+        * label.  This arguably belongs in class Html, but then Agora clients
+        * would have to apply an Agora class to the label as well as attrs for the
+        * checkbox.
+        *
+        * @param $label string text for label
+        * @param $name string form element name
+        * @param $id
+        * @param $checked bool (default: false)
+        * @param $attribs array additional attributes for the input checkbox
+        *
+        * @return string HTML
+        * @see Xml:checkLabel
+        */
+       public static function labelledCheck( $label, $name, $id, $checked = false, $attribs = array() ) {
+               return Html::rawElement(
+                               'label',
+                               array(
+                                       'for' => $id,
+                                       'class' => 'mw-ui-checkbox-label'
+                               ),
+                               Xml::check(
+                                       $id,
+                                       $checked,
+                                       array( 'id' => $id ) + $attribs
+                               ) .
+                               $label
+                       );
+       }
+
+}
+
+/**
+ * Html form for user login with new Agora appearance.
+ */
+
+class UserloginTemplateAgora extends AgoraTemplate {
+
+       function execute() {
+?>
+<div class="mw-ui-container">
+<div id="userloginForm">
+<form name="userlogin" method="post" action="<?php $this->text('action') ?>">
+       <?php $this->html('header'); /* pre-table point for form plugins... */ ?>
+       <?php if( $this->haveData( 'languages' ) ) { ?><div id="languagelinks"><p><?php $this->html('languages' ); ?></p></div><?php } ?>
+       <ul class="mw-ui-formlist">
+       <?php
+       // TODO is inside the form the right place for this?
+       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>
+               <div class="visualClear"></div>
+<?php } ?>
+
+               <li>
+                       <label for='wpName1'>
+                               <?php
+                               $this->msg('userlogin-yourname');
+                               if ( $this->data['secureLoginUrl'] ) {
+                                       echo Html::element( 'a', array(
+                                                       'href' => $this->data['secureLoginUrl'],
+                                                       'class' => 'mw-ui-flush-right mw-secure',
+                                               ), wfMessage( 'userlogin-signwithsecure' )->text() );
+                               } ?>
+                       </label>
+                       <?php
+                       echo Html::input( 'wpName', $this->data['name'], 'text', array(
+                               'class' => 'loginText',
+                               'id' => 'wpName1',
+                               'tabindex' => '1',
+                               'size' => '20',
+                               'required',
+                               'placeholder' => wfMessage( 'userlogin-yourname-ph' )->text()
+                               # Can't do + array( 'autofocus' ) because + for arrays in PHP
+                               # only works right for associative arrays!  Thanks, PHP.
+                       ) + ( $this->data['name'] ? array() : array( 'autofocus' => '' ) ) );
+                       ?>
+               </li>
+               <li>
+                       <label for='wpPassword1'>
+                       <?php
+                       $this->msg('userlogin-yourpassword');
+
+                       if ( $this->data['useemail'] && $this->data['canreset'] ) {
+                               if( $this->data['resetlink'] === true ){
+                                       echo Linker::link(
+                                               SpecialPage::getTitleFor( 'PasswordReset' ),
+                                               wfMessage( 'userlogin-resetlink' )->parse(),
+                                               array( 'class' => 'mw-ui-flush-right' )
+                                       );
+                               } elseif( $this->data['resetlink'] === null ) {
+                                       /* TODO (spage 2013-02-26) no idea what class to use for this,
+                                        * it doesn't belong in the label.
+                                        */
+                                       echo Html::input(
+                                               'wpMailmypassword',
+                                               wfMessage( 'mailmypassword' )->text(),
+                                               'submit', array(
+                                                       'id' => 'wpMailmypassword',
+                                                       'tabindex' => '10'
+                                               )
+                                       );
+                               }
+                       } ?>
+                       </label>
+                       <?php
+                       echo Html::input( 'wpPassword', null, 'password', array(
+                               'class' => 'loginPassword',
+                               'id' => 'wpPassword1',
+                               'tabindex' => '2',
+                               'size' => '20',
+                               'placeholder' => wfMessage( 'userlogin-yourpassword-ph' )->text()
+                       ) + ( $this->data['name'] ? array( 'autofocus' ) : array() ) ); ?>
+               </li>
+       <?php if( isset( $this->data['usedomain'] ) && $this->data['usedomain'] ) {
+               $doms = "";
+               foreach( $this->data['domainnames'] as $dom ) {
+                       $doms .= "<option>" . htmlspecialchars( $dom ) . "</option>";
+               }
+       ?>
+               <li id="mw-user-domain-section">
+                       <label for='wpDomain' class="pos-above"><?php $this->msg( 'yourdomain' ) ?></label>
+                               <select name="wpDomain" value="<?php $this->text( 'domain' ) ?>"
+                                       tabindex="3">
+                                       <?php echo $doms ?>
+                               </select>
+               </li>
+       <?php }
+
+       if( $this->haveData( 'extrafields' ) ) {
+               echo $this->data['extrafields'];
+       } ?>
+
+               <li>
+                       <?php if( $this->data['canremember'] ) {
+                               global $wgCookieExpiration;
+                               $expirationDays = ceil( $wgCookieExpiration / ( 3600 * 24 ) );
+                               echo $this->labelledCheck(
+                                       wfMessage( 'userlogin-remembermypassword' )->numParams( $expirationDays )->text(),
+                                       'wpRemember',
+                                       'wpRemember',
+                                       $this->data['remember']
+                               );
+                       } ?>
+               </li>
+<?php if( $this->data['cansecurelogin'] ) { ?>
+               <li>
+                       <?php
+                       echo Xml::checkLabel(
+                               wfMessage( 'securelogin-stick-https' )->text(),
+                               'wpStickHTTPS',
+                               'wpStickHTTPS',
+                               $this->data['stickHTTPS'],
+                               array( 'tabindex' => '9' )
+                       );
+                       ?>
+               </li>
+<?php } ?>
+               <li>
+                       <?php
+                       echo Html::input( 'wpLoginAttempt', wfMessage( 'login' )->text(), 'submit', array(
+                               'id' => 'wpLoginAttempt',
+                               'tabindex' => '9',
+                               'class' => 'mw-ui-button big block primary'
+                       ) );
+                       ?>
+               </li>
+               <li style="text-align: center;">
+                       <?php echo wfMessage( 'userlogin-helplink' )->parse() ?>
+               </li>
+               <li>
+               <?php if( $this->haveData( 'createOrLoginHref' ) ) { ?>
+               <div id="createaccount-cta">
+                       <h3 id="userloginlink"><?php $this->msg( 'userlogin-noaccount' ) ?><a href="<?php $this->text( 'createOrLoginHref' ) ?>" id="mw-joinproject" class="mw-ui-button constructive" style="width: auto; display: inline-block;"><?php $this->msg( 'userlogin-joinproject' ) ?></a></h3>
+               </div>
+               <?php } ?>
+               </li>
+       </ul>
+       <input type="hidden" id="useAgora" name="useAgora" 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="wpLoginToken" value="<?php $this->text( 'token' ); ?>" /><?php } ?>
+</form>
+</div>
+</div>
+<?php
+
+} // end execute()
+}
index e07da4f..0bba637 100644 (file)
@@ -1075,9 +1075,20 @@ Note that some pages may continue to be displayed as if you were still logged in
 '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.',
@@ -1091,14 +1102,33 @@ Do not forget to change your [[Special:Preferences|{{SITENAME}} preferences]].',
 '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.',
index c39e9eb..ca42ab3 100644 (file)
@@ -1038,18 +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 @@ 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,8 +1102,25 @@ It is also used on the top of the page for logged out users, where it appears ne
 '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.',
@@ -2450,6 +2480,8 @@ This option lets your time zone setting use the one that is used on the wiki (of
 '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).
 
index 7c16df6..db30ff7 100644 (file)
@@ -430,9 +430,20 @@ $wgMessageStructure = array(
                'welcomeuser',
                'welcomecreation-msg',
                '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',
                'securelogin-stick-https',
                'yourdomainname',
                'password-change-forbidden',
@@ -446,14 +457,33 @@ $wgMessageStructure = array(
                'userlogout',
                'userlogout-summary',
                'notloggedin',
+               'userlogin-noaccount',
+               'userlogin-joinproject',
                'nologin',
                'nologinlink',
                'createaccount',
                'gotaccount',
                'gotaccountlink',
                'userlogin-resetlink',
+               'helplogin-url',
+               'userlogin-helplink',
+               'createacct-join',
+               'createacct-emailrequired',
+               'createacct-emailoptional',
+               'createacct-email-ph',
                'createaccountmail',
                'createaccountreason',
+               'createacct-reason',
+               '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 f5a31fd..83fcb72 100644 (file)
@@ -943,6 +943,21 @@ return array(
        '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(
@@ -1040,4 +1055,11 @@ return array(
                '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',
+       ),
 );
diff --git a/resources/mediawiki.special/images/glyph-people-large.png b/resources/mediawiki.special/images/glyph-people-large.png
new file mode 100644 (file)
index 0000000..2c251d7
Binary files /dev/null and b/resources/mediawiki.special/images/glyph-people-large.png differ
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-lock.png b/resources/mediawiki.special/images/icon-lock.png
new file mode 100644 (file)
index 0000000..306f1f1
Binary files /dev/null and b/resources/mediawiki.special/images/icon-lock.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.agora.css b/resources/mediawiki.special/mediawiki.special.createaccount.agora.css
new file mode 100644 (file)
index 0000000..fc6dec8
--- /dev/null
@@ -0,0 +1,74 @@
+/* Benefits column CSS */
+div.createacct-benefits-container {
+       margin-left: 100px;
+       float: left }
+
+div.createacct-benefits-container h2 {
+       margin-bottom: 30px;
+}
+
+ul.createacct-benefits-list {
+       list-style: none;
+       margin-left: 0;
+}
+
+ul.createacct-benefits-list li {
+       display: block;
+       padding: 0;
+       margin-bottom: 40px; }
+
+div.benefits-icon {
+       display: inline-block;
+       padding: 0;
+       float: left;
+       width: 80px;
+       height: 75px;
+       margin-right: 15px;
+       border: 0; }
+
+.benefits-icon.icon-edits {
+       /* @embed */
+       background: url(images/icon-edits.png) no-repeat right;
+}
+
+.benefits-icon.icon-pages {
+       /* @embed */
+       background: url(images/icon-pages.png) no-repeat right;
+}
+
+.benefits-icon.icon-contributors {
+       /* @embed */
+       background: url(images/icon-contributors.png) no-repeat right;
+}
+
+/* General alignment of benefits */
+.benefits-text {
+       display: inline-block;
+       min-width: 200px;
+       height: 75px;
+       vertical-align: middle;
+       max-width: 450px;
+       padding: 0;
+}
+
+/* Special font for numbers in benefits*/
+div.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.number-text {
+       display: block;
+       font-size: 1.2em;
+       font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
+       color: #444;
+       margin-top: 1em;
+       text-align: center;
+}
diff --git a/resources/mediawiki.special/mediawiki.special.createaccount.agora.js b/resources/mediawiki.special/mediawiki.special.createaccount.agora.js
new file mode 100644 (file)
index 0000000..c14a53a
--- /dev/null
@@ -0,0 +1,47 @@
+/* JavaScript for Special:Userlogin */
+
+jQuery( function( $ ) {
+       var $content = $( '#mw-content-text' ),
+               $captchaStuff;
+
+       /**
+        * CAPTCHA
+        * The CAPTCHA is in a div style="captcha" along with a ton of
+        * irrelevant text from MediaWiki:fancycaptcha-create-account
+        * Strategy: remove it, then repopulate just what we need.
+        * Adds an empty Security check if there's no CAPTCHA.
+        */
+       $captchaStuff = $content.find ( '.captcha' ).remove();
+       if ( $captchaStuff.length ) {
+               // insert another li before the submit button.
+               $content.find( '#wpCreateaccount' ).closest( 'li' )
+                       .before( [
+               '<li>',
+                       '<label class="acux-label" for="wpCaptchaWord">Security check</label>',
+                       '<div class="acux-captcha-container">',
+                               '<img id="acux-captcha" alt="PLACEHOLDER">',
+                               // arguably mw.util.wikiGetLink() here...
+                               '<small>Can\'t see the image? <a href="/wiki/Wikipedia:Request_an_account" title="Wikipedia:Request an account" tabindex="-1">We can create an account for you!</a></small>',
+                               // Same tabindex as Remember me checkbox , but we removed that.
+                               '<input id="wpCaptchaWord" name="wpCaptchaWord" type="text" placeholder="Enter the text you see above" name="captcha-text" tabindex="8" autocapitalize="off" autocorrect="off">',
+                       '</div>',
+               '</li>'
+                               ].join('') );
+
+               // There are only a few only things we want from the old CAPTCHA.
+               // Get the img (we hope only one!) out of the old CAPTCHA,
+               // and replace the placeholder img with it, and style it.
+               $captchaStuff.find( 'img' )
+                       .replaceAll( $content.find( '#acux-captcha' ) )
+                       .addClass( 'acux-captcha');
+
+               // 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' ) );
+       }
+
+});
diff --git a/resources/mediawiki.special/mediawiki.special.forms.agora.css b/resources/mediawiki.special/mediawiki.special.forms.agora.css
new file mode 100644 (file)
index 0000000..4ebc817
--- /dev/null
@@ -0,0 +1,51 @@
+/***************** some of this stuff should move to Agora core CSS *****************/
+/* Style elements in a mw-ui-container.
+DISABLED
+div.mw-ui-container {
+    font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+    font-size: 1.0em;
+    border: 0;
+}
+*/
+
+.mw-ui-container h2 {
+       border: 0;
+       font-weight: bold;
+}
+
+/*
+ * When inside the Agora style, disable the border that Vector puts on the div
+ * surrounding a form.
+ */
+.mw-ui-container #userloginForm, .mw-ui-container #userlogin {
+    border: 0;
+       margin: 0;
+    padding: 0;
+}
+
+/* Note MediaWiki HTML::input drops default type="text" if $wgHtml5 */
+
+/* Similar to .acux-errorbox */
+/*
+ * In theory besides errorbox there could be warningbox, successbox, msgbox,
+ * spage has never seen these in practice.
+ * Vector has styles coloring warningbox cream and successbox green.
+ */
+.mw-ui-formlist .errorbox, .mw-ui-formlist .warningbox, .mw-ui-formlist .successbox {
+       -webkit-box-sizing: border-box;
+       -moz-box-sizing: border-box;
+       box-sizing: border-box;
+       width: 100%;
+       /* munaf, need some font-size to disable vector's font-size: larger for errorbox
+        * munaf, this leaves error text bigger than label text which has
+        * .mw-ui-formlist li label shrinking an addition 0.9em on top of Vector's
+        * #bodyContent 0.8em
+        */
+       font-size: 0.9em;
+       margin: 0 0 1em 0;
+       padding: 0.5em;
+       color: #cc0000;
+       border: 1px solid #fac5c5;
+       background-color: #fae3e3;
+       text-shadow: 0 1px #fae3e3;
+}
diff --git a/resources/mediawiki.special/mediawiki.special.userlogin.agora.css b/resources/mediawiki.special/mediawiki.special.userlogin.agora.css
new file mode 100644 (file)
index 0000000..e8e4453
--- /dev/null
@@ -0,0 +1,34 @@
+/***************** stuff just for userlogin Agora *****************/
+.mw-ui-formlist .mw-secure {
+       /* @embed */
+       background: url(images/icon-lock.png) no-repeat scroll left center transparent;
+       margin: 0 0 0 1px;
+       padding: 0 0 0 11px;
+}
+
+#createaccount-cta {
+    width: 20em;
+    height: 10em;
+    text-align: center;
+       /* @embed */
+    background: url(images/glyph-people-large.png) no-repeat 50%;
+    font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+}
+
+#createaccount-cta h3 {
+    width: 100%;
+    font-size: 0.9em;
+    font-weight: normal;
+    text-align: center;
+    padding-top: 4em;
+}
+
+#mw-joinproject {
+    display: inline-block;
+    font-size: 1em;
+    margin-left: 0.75em;
+
+    -webkit-box-shadow: 4px 4px 4px 4px rgba(255, 255, 255, 1);
+    -moz-box-shadow: 4px 4px 4px 4px rgba(255, 255, 255, 1);
+    box-shadow: 4px 4px 4px 4px rgba(255, 255, 255, 1);
+}
diff --git a/resources/mediawiki.ui/mediawiki.ui.default.css b/resources/mediawiki.ui/mediawiki.ui.default.css
new file mode 100644 (file)
index 0000000..57ba10f
--- /dev/null
@@ -0,0 +1,50 @@
+/* Agora styles, default with vector stuff removed. */
+/* _effects.scss */
+/* Mixins for visual effects in CSS3 */
+/* line 7, ../scss/components/_utilities.scss */
+.mw-ui-flush-left {
+  float: left;
+  margin-left: 0;
+  padding-left: 0;
+}
+
+/* line 11, ../scss/components/_utilities.scss */
+.mw-ui-flush-right {
+  float: right;
+  margin-right: 0;
+  padding-right: 0;
+}
+
+/* line 15, ../scss/components/_utilities.scss */
+.mw-ui-center-block {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+/* no buttons?
+button.mw-ui-button, input[type="submit"].mw-ui-button, a.mw-ui-button 
+button.mw-ui-button:hover, button.mw-ui-button.hover, input[type="submit"].mw-ui-button:hover, input[type="submit"].mw-ui-button.hover, a.mw-ui-button:hover, a.mw-ui-button.hover 
+*/
+
+/* line 7, ../scss/components/_forms.scss */
+ul.mw-ui-formlist {
+  list-style: none;
+  list-style-image: none;
+}
+/* line 16, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li {
+  display: block;
+  width: 100%;
+}
+/* line 25, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li input,
+ul.mw-ui-formlist li label,
+ul.mw-ui-formlist li .mw-ui-button {
+  margin: 0;
+  width: 100%;
+}
+/* nothing about labels or checkboxes
+ul.mw-ui-formlist li label
+ul.mw-ui-formlist li label.mw-ui-checkbox-label > input[type="checkbox"], ul.mw-ui-formlist li label.mw-ui-checkbox-label > input[type="radio"], ul.mw-ui-formlist li label.mw-ui-radio-label > input[type="checkbox"], ul.mw-ui-formlist li label.mw-ui-radio-label > input[type="radio"] 
+*/
diff --git a/resources/mediawiki.ui/mediawiki.ui.vector.css b/resources/mediawiki.ui/mediawiki.ui.vector.css
new file mode 100644 (file)
index 0000000..704ce1b
--- /dev/null
@@ -0,0 +1,335 @@
+/* Agora styles */
+/* _effects.scss */
+/* Mixins for visual effects in CSS3 */
+/* line 7, ../scss/components/_utilities.scss */
+.mw-ui-flush-left {
+  float: left;
+  margin-left: 0;
+  padding-left: 0;
+}
+
+/* line 11, ../scss/components/_utilities.scss */
+.mw-ui-flush-right {
+  float: right;
+  margin-right: 0;
+  padding-right: 0;
+}
+
+/* line 15, ../scss/components/_utilities.scss */
+.mw-ui-center-block {
+  display: block;
+  margin-left: auto;
+  margin-right: auto;
+}
+
+/* line 8, ../scss/components/_buttons.scss */
+button.mw-ui-button, input[type="submit"].mw-ui-button, a.mw-ui-button {
+  display: -moz-inline-stack;
+  display: inline-block;
+  vertical-align: middle;
+  *vertical-align: auto;
+  zoom: 1;
+  *display: inline;
+  padding: 0.4em 1em 0.4em 1em;
+  margin: 0;
+  background-color: #c9c9c9;
+  *background-color: #c9c9c9;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFDCDCDC', endColorstr='#FFC9C9C9');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #dcdcdc), color-stop(100%, #c9c9c9));
+  background-image: -webkit-linear-gradient(top, #dcdcdc, #c9c9c9);
+  background-image: -moz-linear-gradient(top, #dcdcdc, #c9c9c9);
+  background-image: -o-linear-gradient(top, #dcdcdc, #c9c9c9);
+  background-image: linear-gradient(top, #dcdcdc, #c9c9c9);
+  color: #4a4a4a;
+  text-shadow: 0 1px 1px rgba(201, 201, 201, 0.3);
+  border: 1px solid #c4c4c4;
+  -webkit-border-radius: 3px;
+  -moz-border-radius: 3px;
+  -ms-border-radius: 3px;
+  -o-border-radius: 3px;
+  border-radius: 3px;
+  line-height: 1.4em;
+  vertical-align: middle;
+  text-align: center;
+  text-decoration: none;
+  font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+  font-size: 1em;
+  font-weight: bold;
+  cursor: pointer;
+}
+/* line 38, ../scss/mixins/_effects.scss */
+button.mw-ui-button:hover, button.mw-ui-button.hover, input[type="submit"].mw-ui-button:hover, input[type="submit"].mw-ui-button.hover, a.mw-ui-button:hover, a.mw-ui-button.hover {
+  background-color: gainsboro;
+  *background-color: gainsboro;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFE9E9E9', endColorstr='#FFDCDCDC');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #e9e9e9), color-stop(100%, #dcdcdc));
+  background-image: -webkit-linear-gradient(top, #e9e9e9, #dcdcdc);
+  background-image: -moz-linear-gradient(top, #e9e9e9, #dcdcdc);
+  background-image: -o-linear-gradient(top, #e9e9e9, #dcdcdc);
+  background-image: linear-gradient(top, #e9e9e9, #dcdcdc);
+}
+/* line 43, ../scss/mixins/_effects.scss */
+button.mw-ui-button:active, button.mw-ui-button.active, input[type="submit"].mw-ui-button:active, input[type="submit"].mw-ui-button.active, a.mw-ui-button:active, a.mw-ui-button.active {
+  background-image: none;
+  background-color: #c1c1c1;
+  text-shadow: none;
+}
+/* line 53, ../scss/mixins/_effects.scss */
+button.mw-ui-button:disabled, button.mw-ui-button.disabled, input[type="submit"].mw-ui-button:disabled, input[type="submit"].mw-ui-button.disabled, a.mw-ui-button:disabled, a.mw-ui-button.disabled {
+  background-image: none;
+  background-color: #c9c9c9;
+  opacity: 0.5;
+  text-shadow: none;
+}
+/* line 37, ../scss/components/_buttons.scss */
+button.mw-ui-button:disabled, button.mw-ui-button.disabled, input[type="submit"].mw-ui-button:disabled, input[type="submit"].mw-ui-button.disabled, a.mw-ui-button:disabled, a.mw-ui-button.disabled {
+  cursor: default;
+}
+/* line 44, ../scss/components/_buttons.scss */
+button.mw-ui-button.blue, button.mw-ui-button.primary, input[type="submit"].mw-ui-button.blue, input[type="submit"].mw-ui-button.primary, a.mw-ui-button.blue, a.mw-ui-button.primary {
+  background-color: #3366bb;
+  *background-color: #3366bb;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FF4779CD', endColorstr='#FF3366BB');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #4779cd), color-stop(100%, #3366bb));
+  background-image: -webkit-linear-gradient(top, #4779cd, #3366bb);
+  background-image: -moz-linear-gradient(top, #4779cd, #3366bb);
+  background-image: -o-linear-gradient(top, #4779cd, #3366bb);
+  background-image: linear-gradient(top, #4779cd, #3366bb);
+  color: white;
+  text-shadow: 0 1px 1px rgba(51, 102, 187, 0.75);
+  border: 1px solid #3162b3;
+}
+/* line 38, ../scss/mixins/_effects.scss */
+button.mw-ui-button.blue:hover, button.mw-ui-button.blue.hover, button.mw-ui-button.primary:hover, button.mw-ui-button.primary.hover, input[type="submit"].mw-ui-button.blue:hover, input[type="submit"].mw-ui-button.blue.hover, input[type="submit"].mw-ui-button.primary:hover, input[type="submit"].mw-ui-button.primary.hover, a.mw-ui-button.blue:hover, a.mw-ui-button.blue.hover, a.mw-ui-button.primary:hover, a.mw-ui-button.primary.hover {
+  background-color: #4779cd;
+  *background-color: #4779cd;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FF5B88D2', endColorstr='#FF4779CD');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #5b88d2), color-stop(100%, #4779cd));
+  background-image: -webkit-linear-gradient(top, #5b88d2, #4779cd);
+  background-image: -moz-linear-gradient(top, #5b88d2, #4779cd);
+  background-image: -o-linear-gradient(top, #5b88d2, #4779cd);
+  background-image: linear-gradient(top, #5b88d2, #4779cd);
+}
+/* line 43, ../scss/mixins/_effects.scss */
+button.mw-ui-button.blue:active, button.mw-ui-button.blue.active, button.mw-ui-button.primary:active, button.mw-ui-button.primary.active, input[type="submit"].mw-ui-button.blue:active, input[type="submit"].mw-ui-button.blue.active, input[type="submit"].mw-ui-button.primary:active, input[type="submit"].mw-ui-button.primary.active, a.mw-ui-button.blue:active, a.mw-ui-button.blue.active, a.mw-ui-button.primary:active, a.mw-ui-button.primary.active {
+  background-image: none;
+  background-color: #305faf;
+  text-shadow: none;
+}
+/* line 53, ../scss/mixins/_effects.scss */
+button.mw-ui-button.blue:disabled, button.mw-ui-button.blue.disabled, button.mw-ui-button.primary:disabled, button.mw-ui-button.primary.disabled, input[type="submit"].mw-ui-button.blue:disabled, input[type="submit"].mw-ui-button.blue.disabled, input[type="submit"].mw-ui-button.primary:disabled, input[type="submit"].mw-ui-button.primary.disabled, a.mw-ui-button.blue:disabled, a.mw-ui-button.blue.disabled, a.mw-ui-button.primary:disabled, a.mw-ui-button.primary.disabled {
+  background-image: none;
+  background-color: #3366bb;
+  opacity: 0.5;
+  text-shadow: none;
+}
+/* line 49, ../scss/components/_buttons.scss */
+button.mw-ui-button.green, button.mw-ui-button.constructive, input[type="submit"].mw-ui-button.green, input[type="submit"].mw-ui-button.constructive, a.mw-ui-button.green, a.mw-ui-button.constructive {
+  background-color: #27aa65;
+  *background-color: #27aa65;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FF2EC977', endColorstr='#FF27AA65');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #2ec977), color-stop(100%, #27aa65));
+  background-image: -webkit-linear-gradient(top, #2ec977, #27aa65);
+  background-image: -moz-linear-gradient(top, #2ec977, #27aa65);
+  background-image: -o-linear-gradient(top, #2ec977, #27aa65);
+  background-image: linear-gradient(top, #2ec977, #27aa65);
+  color: white;
+  text-shadow: 0 1px 1px rgba(39, 170, 101, 0.75);
+  border: 1px solid #25a260;
+}
+/* line 38, ../scss/mixins/_effects.scss */
+button.mw-ui-button.green:hover, button.mw-ui-button.green.hover, button.mw-ui-button.constructive:hover, button.mw-ui-button.constructive.hover, input[type="submit"].mw-ui-button.green:hover, input[type="submit"].mw-ui-button.green.hover, input[type="submit"].mw-ui-button.constructive:hover, input[type="submit"].mw-ui-button.constructive.hover, a.mw-ui-button.green:hover, a.mw-ui-button.green.hover, a.mw-ui-button.constructive:hover, a.mw-ui-button.constructive.hover {
+  background-color: #2ec977;
+  *background-color: #2ec977;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FF3ED384', endColorstr='#FF2EC977');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #3ed384), color-stop(100%, #2ec977));
+  background-image: -webkit-linear-gradient(top, #3ed384, #2ec977);
+  background-image: -moz-linear-gradient(top, #3ed384, #2ec977);
+  background-image: -o-linear-gradient(top, #3ed384, #2ec977);
+  background-image: linear-gradient(top, #3ed384, #2ec977);
+}
+/* line 43, ../scss/mixins/_effects.scss */
+button.mw-ui-button.green:active, button.mw-ui-button.green.active, button.mw-ui-button.constructive:active, button.mw-ui-button.constructive.active, input[type="submit"].mw-ui-button.green:active, input[type="submit"].mw-ui-button.green.active, input[type="submit"].mw-ui-button.constructive:active, input[type="submit"].mw-ui-button.constructive.active, a.mw-ui-button.green:active, a.mw-ui-button.green.active, a.mw-ui-button.constructive:active, a.mw-ui-button.constructive.active {
+  background-image: none;
+  background-color: #249e5e;
+  text-shadow: none;
+}
+/* line 53, ../scss/mixins/_effects.scss */
+button.mw-ui-button.green:disabled, button.mw-ui-button.green.disabled, button.mw-ui-button.constructive:disabled, button.mw-ui-button.constructive.disabled, input[type="submit"].mw-ui-button.green:disabled, input[type="submit"].mw-ui-button.green.disabled, input[type="submit"].mw-ui-button.constructive:disabled, input[type="submit"].mw-ui-button.constructive.disabled, a.mw-ui-button.green:disabled, a.mw-ui-button.green.disabled, a.mw-ui-button.constructive:disabled, a.mw-ui-button.constructive.disabled {
+  background-image: none;
+  background-color: #27aa65;
+  opacity: 0.5;
+  text-shadow: none;
+}
+/* line 54, ../scss/components/_buttons.scss */
+button.mw-ui-button.red, button.mw-ui-button.destructive, input[type="submit"].mw-ui-button.red, input[type="submit"].mw-ui-button.destructive, a.mw-ui-button.red, a.mw-ui-button.destructive {
+  background-color: #cc0000;
+  *background-color: #cc0000;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFF20000', endColorstr='#FFCC0000');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #f20000), color-stop(100%, #cc0000));
+  background-image: -webkit-linear-gradient(top, #f20000, #cc0000);
+  background-image: -moz-linear-gradient(top, #f20000, #cc0000);
+  background-image: -o-linear-gradient(top, #f20000, #cc0000);
+  background-image: linear-gradient(top, #f20000, #cc0000);
+  color: white;
+  text-shadow: 0 1px 1px rgba(204, 0, 0, 0.75);
+  border: 1px solid #c20000;
+}
+/* line 38, ../scss/mixins/_effects.scss */
+button.mw-ui-button.red:hover, button.mw-ui-button.red.hover, button.mw-ui-button.destructive:hover, button.mw-ui-button.destructive.hover, input[type="submit"].mw-ui-button.red:hover, input[type="submit"].mw-ui-button.red.hover, input[type="submit"].mw-ui-button.destructive:hover, input[type="submit"].mw-ui-button.destructive.hover, a.mw-ui-button.red:hover, a.mw-ui-button.red.hover, a.mw-ui-button.destructive:hover, a.mw-ui-button.destructive.hover {
+  background-color: #f20000;
+  *background-color: #f20000;
+  *zoom: 1;
+  filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#FFFF0D0D', endColorstr='#FFF20000');
+  background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ff0d0d), color-stop(100%, #f20000));
+  background-image: -webkit-linear-gradient(top, #ff0d0d, #f20000);
+  background-image: -moz-linear-gradient(top, #ff0d0d, #f20000);
+  background-image: -o-linear-gradient(top, #ff0d0d, #f20000);
+  background-image: linear-gradient(top, #ff0d0d, #f20000);
+}
+/* line 43, ../scss/mixins/_effects.scss */
+button.mw-ui-button.red:active, button.mw-ui-button.red.active, button.mw-ui-button.destructive:active, button.mw-ui-button.destructive.active, input[type="submit"].mw-ui-button.red:active, input[type="submit"].mw-ui-button.red.active, input[type="submit"].mw-ui-button.destructive:active, input[type="submit"].mw-ui-button.destructive.active, a.mw-ui-button.red:active, a.mw-ui-button.red.active, a.mw-ui-button.destructive:active, a.mw-ui-button.destructive.active {
+  background-image: none;
+  background-color: #bd0000;
+  text-shadow: none;
+}
+/* line 53, ../scss/mixins/_effects.scss */
+button.mw-ui-button.red:disabled, button.mw-ui-button.red.disabled, button.mw-ui-button.destructive:disabled, button.mw-ui-button.destructive.disabled, input[type="submit"].mw-ui-button.red:disabled, input[type="submit"].mw-ui-button.red.disabled, input[type="submit"].mw-ui-button.destructive:disabled, input[type="submit"].mw-ui-button.destructive.disabled, a.mw-ui-button.red:disabled, a.mw-ui-button.red.disabled, a.mw-ui-button.destructive:disabled, a.mw-ui-button.destructive.disabled {
+  background-image: none;
+  background-color: #cc0000;
+  opacity: 0.5;
+  text-shadow: none;
+}
+/* line 60, ../scss/components/_buttons.scss */
+button.mw-ui-button.big, input[type="submit"].mw-ui-button.big, a.mw-ui-button.big {
+  font-size: 1.3em;
+}
+/* line 65, ../scss/components/_buttons.scss */
+button.mw-ui-button.block, input[type="submit"].mw-ui-button.block, a.mw-ui-button.block {
+  display: block;
+  width: 100%;
+}
+
+/* line 7, ../scss/components/_forms.scss */
+ul.mw-ui-formlist {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+  font-size: 1em;
+  line-height: 1.4em;
+  list-style: none;
+  list-style-image: none;
+  width: 20em;
+}
+/* line 16, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li {
+  display: block;
+  margin: 0 0 15px 0;
+  padding: 0;
+  width: 100%;
+}
+/* line 25, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li input,
+ul.mw-ui-formlist li label,
+ul.mw-ui-formlist li .mw-ui-button {
+  display: block;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  margin: 0;
+  width: 100%;
+}
+/* line 32, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li label {
+  width: auto;
+  margin: 0 0 0.2em 0;
+  padding: 0;
+}
+/* line 38, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li label.mw-ui-checkbox-label, ul.mw-ui-formlist li label.mw-ui-radio-label {
+  cursor: pointer;
+  vertical-align: bottom;
+  line-height: normal;
+  height: 1em;
+  font-weight: normal;
+}
+/* line 50, ../scss/mixins/_forms.scss */
+ul.mw-ui-formlist li label.mw-ui-checkbox-label > input[type="checkbox"], ul.mw-ui-formlist li label.mw-ui-checkbox-label > input[type="radio"], ul.mw-ui-formlist li label.mw-ui-radio-label > input[type="checkbox"], ul.mw-ui-formlist li label.mw-ui-radio-label > input[type="radio"] {
+  width: auto;
+  height: auto;
+  margin: 0 0.3em 0 0;
+  padding: 0;
+  border-style: solid;
+  border-width: 1px;
+  border-color: #c9c9c9;
+  cursor: pointer;
+}
+/* line 45, ../scss/components/_forms.scss */
+ul.mw-ui-formlist li input[type="checkbox"],
+ul.mw-ui-formlist li input[type="radio"] {
+  display: inline;
+  -webkit-box-sizing: content-box;
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+  width: auto;
+}
+
+/* line 60, ../scss/components/_forms.scss */
+.mw-ui-input, .mw-ui-formlist li input {
+  outline: 0;
+  font-family: "Helvetica Neue", "Helvetica", "Arial", sans-serif;
+  font-size: 1em;
+  line-height: 1.4em;
+  font-size: 1em;
+  border-style: solid;
+  border-width: 1px;
+  border-color: #c9c9c9;
+  color: #252525;
+  padding: 0.25em 0 0.2em 0.5em;
+}
+/* line 15, ../scss/mixins/_forms.scss */
+.mw-ui-input:focus, .mw-ui-formlist li input:focus {
+  -webkit-box-shadow: #4091ed 0px 0px 5px;
+  -moz-box-shadow: #4091ed 0px 0px 5px;
+  box-shadow: #4091ed 0px 0px 5px;
+  border-color: #4091ed;
+}
+
+/* line 65, ../scss/components/_forms.scss */
+.mw-ui-block-label, .mw-ui-formlist li label {
+  font-weight: bold;
+  font-size: 0.9em;
+  color: #7d7d7d;
+}
+/* line 34, ../scss/mixins/_forms.scss */
+.mw-ui-block-label *, .mw-ui-formlist li label * {
+  font-weight: normal;
+}
+
+/* line 74, ../scss/components/_forms.scss */
+.mw-ui-checkbox-label, .mw-ui-radio-label {
+  cursor: pointer;
+  vertical-align: bottom;
+  line-height: normal;
+  height: 1em;
+  font-weight: normal;
+}
+/* line 50, ../scss/mixins/_forms.scss */
+.mw-ui-checkbox-label > input[type="checkbox"], .mw-ui-checkbox-label > input[type="radio"], .mw-ui-radio-label > input[type="checkbox"], .mw-ui-radio-label > input[type="radio"] {
+  width: auto;
+  height: auto;
+  margin: 0 0.3em 0 0;
+  padding: 0;
+  border-style: solid;
+  border-width: 1px;
+  border-color: #c9c9c9;
+  cursor: pointer;
+}