Bartosz Dziewoński has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/394804 )

Change subject: Revert "Special:Preferences: Use OOjs UI" and follow-ups
......................................................................

Revert "Special:Preferences: Use OOjs UI" and follow-ups

The number of issues with the new interface is unacceptable and we
will not be able to fix them reasonably quickly. See subtasks of
T180538 for the list of issues, raised both by the Wikimedia community
and by WMF employees.

I should have pushed back harder against the merging of this half-baked
change with the promise that we'll fix it later. I convinced myself
that the regressions were not so noticeable and that the issues that
were pointed out will in fact be fixed by someone. Predictably,
however, regressions were bad and the only person fixing the issues
was me.

I am not going to work nights to make this page decent again within a
reasonable timeframe; I'm not sure if I'd even be able to since many
issues are problems with the design rather than the implementation. No
one else seems to be working on improving it, therefore I am reverting
the change.

On the bright side, this work has resulted in a number of improvements
to HTMLForm and Preferences code, which are not being reverted here:
<https://gerrit.wikimedia.org/r/#/q/topic:T117781>.

If anyone reattempts this, I recommend gating the new interface behind
a configuration variable and URL parameter, like we did with
$wgOOUIEditPage in the past, and testing thoroughly in production
before enabling it for everyone.

* Revert "Special:Preferences: Use OOjs UI"
  This reverts commit 486e566cfef612de6773df435a74d5fc37e27174.
* Revert "Preferences: Show preview of edit fonts in edit font selector"
  This reverts commit 6634ff729dc7f6d0f541639dbdf3c4d9f786ddf6.
* Revert "Follow-Up Iae63b6994: Add missing editfont dependency"
  This reverts commit ce42fdf151c39f91cf4077673219fa6228a54d7f.
* Revert "Preferences: Improve visual appearance by “unboxing” sections"
  This reverts commit c9415bb0059f4dae4abc5e39a8af844328333120.
* Revert "Remove box-shadow from preference panels for ooui-apex"
  This reverts commit a934b82ca27971e8f0553a7ab7c8ee30fccf3283.
* Revert "Preferences: Don't show the watchlist token; just link to ResetTokens"
  This reverts commit e8c9102fc7b66460c33f643b0dea7190cb89ac83.
* Revert "mw.special.preferences: Make the "Basic information" section more 
compact"
  This reverts commit d48b7260f30c1ec57046a1f8e4c82057aed45e5f.
* Revert "mw.special.preferences: Widen the dropdown of the "Time zone" field"
  This reverts commit afd5f1417efdd463d86186257c4ec77dd4a442ce.

Bug: T117781
Bug: T180538
Change-Id: I44b5daea1828f71881b5bd35218f5ecb7ab7f36e
---
M includes/Preferences.php
M includes/specials/SpecialPasswordReset.php
M includes/specials/SpecialPreferences.php
M includes/specials/SpecialResetTokens.php
M includes/specials/forms/PreferencesForm.php
M languages/i18n/en.json
M languages/i18n/qqq.json
M resources/Resources.php
M resources/src/mediawiki.legacy/oldshared.css
M resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js
D resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js
M resources/src/mediawiki.special/mediawiki.special.preferences.styles.css
M resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js
M resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js
M tests/selenium/pageobjects/preferences.page.js
15 files changed, 216 insertions(+), 295 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/04/394804/1

diff --git a/includes/Preferences.php b/includes/Preferences.php
index 924e3ad..2dd3e2d 100644
--- a/includes/Preferences.php
+++ b/includes/Preferences.php
@@ -75,11 +75,6 @@
         * @return array|null
         */
        static function getPreferences( $user, IContextSource $context ) {
-               OutputPage::setupOOUI(
-                       strtolower( $context->getSkin()->getSkinName() ),
-                       $context->getLanguage()->getDir()
-               );
-
                $defaultPreferences = [];
 
                self::profilePreferences( $user, $context, $defaultPreferences 
);
@@ -317,17 +312,14 @@
                if ( $canEditPrivateInfo && 
$authManager->allowsAuthenticationDataChange(
                        new PasswordAuthenticationRequest(), false )->isGood()
                ) {
-                       $link = new OOUI\ButtonWidget( [
-                               'href' => SpecialPage::getTitleFor( 
'ChangePassword' )->getLinkURL( [
-                                       'returnto' => SpecialPage::getTitleFor( 
'Preferences' )->getPrefixedText()
-                               ] ),
-                               'label' => $context->msg( 'prefs-resetpass' 
)->text(),
-                       ] );
+                       $link = $linkRenderer->makeLink( 
SpecialPage::getTitleFor( 'ChangePassword' ),
+                               $context->msg( 'prefs-resetpass' )->text(), [],
+                               [ 'returnto' => SpecialPage::getTitleFor( 
'Preferences' )->getPrefixedText() ] );
 
                        $defaultPreferences['password'] = [
                                'type' => 'info',
                                'raw' => true,
-                               'default' => (string)$link,
+                               'default' => $link,
                                'label-message' => 'yourpassword',
                                'section' => 'personal/info',
                        ];
@@ -471,15 +463,16 @@
 
                                $emailAddress = $user->getEmail() ? 
htmlspecialchars( $user->getEmail() ) : '';
                                if ( $canEditPrivateInfo && 
$authManager->allowsPropertyChange( 'emailaddress' ) ) {
-                                       $link = new OOUI\ButtonWidget( [
-                                               'href' => 
SpecialPage::getTitleFor( 'ChangeEmail' )->getLinkURL( [
-                                                       'returnto' => 
SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText()
-                                               ] ),
-                                               'label' =>
-                                                       $context->msg( 
$user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->text(),
-                                       ] );
+                                       $link = $linkRenderer->makeLink(
+                                               SpecialPage::getTitleFor( 
'ChangeEmail' ),
+                                               $context->msg( 
$user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->text(),
+                                               [],
+                                               [ 'returnto' => 
SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ] );
 
-                                       $emailAddress .= $emailAddress == '' ? 
$link : ( '<br />' . $link );
+                                       $emailAddress .= $emailAddress == '' ? 
$link : (
+                                               $context->msg( 'word-separator' 
)->escaped()
+                                               . $context->msg( 'parentheses' 
)->rawParams( $link )->escaped()
+                                       );
                                }
 
                                $defaultPreferences['emailaddress'] = [
@@ -514,10 +507,10 @@
                                        } else {
                                                $disableEmailPrefs = true;
                                                $emailauthenticated = 
$context->msg( 'emailnotauthenticated' )->parse() . '<br />' .
-                                                       new OOUI\ButtonWidget( [
-                                                               'href' => 
SpecialPage::getTitleFor( 'Confirmemail' )->getLinkURL(),
-                                                               'label' => 
$context->msg( 'emailconfirmlink' )->text(),
-                                                       ] );
+                                                       
$linkRenderer->makeKnownLink(
+                                                               
SpecialPage::getTitleFor( 'Confirmemail' ),
+                                                               $context->msg( 
'emailconfirmlink' )->text()
+                                                       ) . '<br />';
                                                $emailauthenticationclass = 
"mw-email-not-authenticated";
                                        }
                                } else {
@@ -754,7 +747,6 @@
                        'default' => $tzSetting,
                        'size' => 20,
                        'section' => 'rendering/timeoffset',
-                       'id' => 'wpTimeCorrection',
                ];
        }
 
@@ -997,7 +989,7 @@
 
                # # Watchlist #####################################
                if ( $user->isAllowed( 'editmywatchlist' ) ) {
-                       $editWatchlistLinks = '';
+                       $editWatchlistLinks = [];
                        $editWatchlistModes = [
                                'edit' => [ 'EditWatchlist', false ],
                                'raw' => [ 'EditWatchlist', 'raw' ],
@@ -1006,19 +998,16 @@
                        $linkRenderer = 
MediaWikiServices::getInstance()->getLinkRenderer();
                        foreach ( $editWatchlistModes as $editWatchlistMode => 
$mode ) {
                                // Messages: prefs-editwatchlist-edit, 
prefs-editwatchlist-raw, prefs-editwatchlist-clear
-                               $editWatchlistLinks .=
-                                       new OOUI\ButtonWidget( [
-                                               'href' => 
SpecialPage::getTitleFor( $mode[0], $mode[1] )->getLinkURL(),
-                                               'label' => new OOUI\HtmlSnippet(
-                                                       $context->msg( 
"prefs-editwatchlist-{$editWatchlistMode}" )->parse()
-                                               ),
-                                       ] );
+                               $editWatchlistLinks[] = 
$linkRenderer->makeKnownLink(
+                                       SpecialPage::getTitleFor( $mode[0], 
$mode[1] ),
+                                       new HtmlArmor( $context->msg( 
"prefs-editwatchlist-{$editWatchlistMode}" )->parse() )
+                               );
                        }
 
                        $defaultPreferences['editwatchlist'] = [
                                'type' => 'info',
                                'raw' => true,
-                               'default' => $editWatchlistLinks,
+                               'default' => $context->getLanguage()->pipeList( 
$editWatchlistLinks ),
                                'label-message' => 'prefs-editwatchlist-label',
                                'section' => 'watchlist/editwatchlist',
                        ];
@@ -1134,20 +1123,12 @@
                        $defaultPreferences['watchlisttoken'] = [
                                'type' => 'api',
                        ];
-
-                       $tokenButton = new OOUI\ButtonWidget( [
-                               'href' => SpecialPage::getTitleFor( 
'ResetTokens' )->getLinkURL( [
-                                       'returnto' => SpecialPage::getTitleFor( 
'Preferences' )->getPrefixedText()
-                               ] ),
-                               'label' => $context->msg( 
'prefs-watchlist-managetokens' )->text(),
-                       ] );
                        $defaultPreferences['watchlisttoken-info'] = [
                                'type' => 'info',
                                'section' => 'watchlist/tokenwatchlist',
                                'label-message' => 'prefs-watchlist-token',
-                               'help-message' => 'prefs-help-tokenmanagement',
-                               'raw' => true,
-                               'default' => (string)$tokenButton,
+                               'default' => $user->getTokenFromOption( 
'watchlisttoken' ),
+                               'help-message' => 'prefs-help-watchlist-token2',
                        ];
                }
        }
@@ -1369,9 +1350,6 @@
                $formClass = 'PreferencesForm',
                array $remove = []
        ) {
-               // We use ButtonWidgets in some of the getPreferences() 
functions
-               $context->getOutput()->enableOOUI();
-
                $formDescriptor = self::getPreferences( $user, $context );
                if ( count( $remove ) ) {
                        $removeKeys = array_flip( $remove );
diff --git a/includes/specials/SpecialPasswordReset.php 
b/includes/specials/SpecialPasswordReset.php
index bf8dea6..a4f16bd 100644
--- a/includes/specials/SpecialPasswordReset.php
+++ b/includes/specials/SpecialPasswordReset.php
@@ -110,8 +110,6 @@
        public function alterForm( HTMLForm $form ) {
                $resetRoutes = $this->getConfig()->get( 'PasswordResetRoutes' );
 
-               $form->setSubmitDestructive();
-
                $form->addHiddenFields( $this->getRequest()->getValues( 
'returnto', 'returntoquery' ) );
 
                $i = 0;
diff --git a/includes/specials/SpecialPreferences.php 
b/includes/specials/SpecialPreferences.php
index 7fa74af..8ad1630 100644
--- a/includes/specials/SpecialPreferences.php
+++ b/includes/specials/SpecialPreferences.php
@@ -50,8 +50,8 @@
                        return;
                }
 
-               $out->addModules( 'mediawiki.special.preferences.ooui' );
-               $out->addModuleStyles( 
'mediawiki.special.preferences.styles.ooui' );
+               $out->addModules( 'mediawiki.special.preferences' );
+               $out->addModuleStyles( 'mediawiki.special.preferences.styles' );
 
                $session = $this->getRequest()->getSession();
                if ( $session->get( 'specialPreferencesSaveSuccess' ) ) {
@@ -83,19 +83,37 @@
 
                $htmlForm = $this->getFormObject( $user, $this->getContext() );
                $htmlForm->setSubmitCallback( [ 'Preferences', 'tryUISubmit' ] 
);
+               $sectionTitles = $htmlForm->getPreferenceSections();
 
-               $prefTabs = [];
-               foreach ( $htmlForm->getPreferenceSections() as $key ) {
-                       $prefTabs[] = [
-                               'name' => $key,
-                               'label' => $htmlForm->getLegend( $key ),
-                       ];
+               $prefTabs = '';
+               foreach ( $sectionTitles as $key ) {
+                       $prefTabs .= Html::rawElement( 'li',
+                               [
+                                       'role' => 'presentation',
+                                       'class' => ( $key === 'personal' ) ? 
'selected' : null
+                               ],
+                               Html::rawElement( 'a',
+                                       [
+                                               'id' => 'preftab-' . $key,
+                                               'role' => 'tab',
+                                               'href' => '#mw-prefsection-' . 
$key,
+                                               'aria-controls' => 
'mw-prefsection-' . $key,
+                                               'aria-selected' => ( $key === 
'personal' ) ? 'true' : 'false',
+                                               'tabIndex' => ( $key === 
'personal' ) ? 0 : -1,
+                                       ],
+                                       $htmlForm->getLegend( $key )
+                               )
+                       );
                }
-               $out->addJsConfigVars( 'wgPreferencesTabs', $prefTabs );
 
-               // TODO: Render fake tabs here to avoid FOUC.
-               // $out->addHTML( $fakeTabs );
-
+               $out->addHTML(
+                       Html::rawElement( 'ul',
+                               [
+                                       'id' => 'preftoc',
+                                       'role' => 'tablist'
+                               ],
+                               $prefTabs )
+               );
                $htmlForm->show();
        }
 
@@ -118,7 +136,7 @@
 
                $context = new DerivativeContext( $this->getContext() );
                $context->setTitle( $this->getPageTitle( 'reset' ) ); // Reset 
subpage
-               $htmlForm = HTMLForm::factory( 'ooui', [], $context, 
'prefs-restore' );
+               $htmlForm = new HTMLForm( [], $context, 'prefs-restore' );
 
                $htmlForm->setSubmitTextMsg( 'restoreprefs' );
                $htmlForm->setSubmitDestructive();
diff --git a/includes/specials/SpecialResetTokens.php 
b/includes/specials/SpecialResetTokens.php
index d5b0903..964a261 100644
--- a/includes/specials/SpecialResetTokens.php
+++ b/includes/specials/SpecialResetTokens.php
@@ -121,7 +121,6 @@
         * @param HTMLForm $form
         */
        protected function alterForm( HTMLForm $form ) {
-               $form->setSubmitDestructive();
                if ( $this->getTokensList() ) {
                        $form->setSubmitTextMsg( 'resettokens-resetbutton' );
                } else {
diff --git a/includes/specials/forms/PreferencesForm.php 
b/includes/specials/forms/PreferencesForm.php
index 28cfb8b..d4e5ef4 100644
--- a/includes/specials/forms/PreferencesForm.php
+++ b/includes/specials/forms/PreferencesForm.php
@@ -18,10 +18,12 @@
  * @file
  */
 
+use MediaWiki\MediaWikiServices;
+
 /**
  * Form to edit user preferences.
  */
-class PreferencesForm extends OOUIHTMLForm {
+class PreferencesForm extends HTMLForm {
        // Override default value from HTMLForm
        protected $mSubSectionBeforeFields = false;
 
@@ -69,6 +71,8 @@
         * @return string
         */
        function getButtons() {
+               $attrs = [ 'id' => 'mw-prefs-restoreprefs' ];
+
                if ( !$this->getModifiedUser()->isAllowedAny( 
'editmyprivateinfo', 'editmyoptions' ) ) {
                        return '';
                }
@@ -78,14 +82,9 @@
                if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) {
                        $t = $this->getTitle()->getSubpage( 'reset' );
 
-                       $html .= new OOUI\ButtonWidget( [
-                               'infusable' => true,
-                               'id' => 'mw-prefs-restoreprefs',
-                               'label' => $this->msg( 'restoreprefs' )->text(),
-                               'href' => $t->getLinkURL(),
-                               'flags' => [ 'destructive' ],
-                               'framed' => false,
-                       ] );
+                       $linkRenderer = 
MediaWikiServices::getInstance()->getLinkRenderer();
+                       $html .= "\n" . $linkRenderer->makeLink( $t, 
$this->msg( 'restoreprefs' )->text(),
+                               Html::buttonAttributes( $attrs, [ 'mw-ui-quiet' 
] ) );
 
                        $html = Xml::tags( 'div', [ 'class' => 
'mw-prefs-buttons' ], $html );
                }
diff --git a/languages/i18n/en.json b/languages/i18n/en.json
index 5c25de6..87bd13e 100644
--- a/languages/i18n/en.json
+++ b/languages/i18n/en.json
@@ -1027,7 +1027,6 @@
        "prefs-watchlist-edits": "Maximum number of changes to show in 
watchlist:",
        "prefs-watchlist-edits-max": "Maximum number: 1000",
        "prefs-watchlist-token": "Watchlist token:",
-       "prefs-watchlist-managetokens": "Manage tokens",
        "prefs-misc": "Misc",
        "prefs-resetpass": "Change password",
        "prefs-changeemail": "Change or remove email address",
@@ -1045,7 +1044,7 @@
        "recentchangesdays-max": "Maximum $1 {{PLURAL:$1|day|days}}",
        "recentchangescount": "Number of edits to show by default:",
        "prefs-help-recentchangescount": "This includes recent changes, page 
histories, and logs.",
-       "prefs-help-tokenmanagement": "You can see and reset the secret key for 
your account that can access the Web feed of your watchlist. Anyone who knows 
the key will be able to read your watchlist, so do not share it.",
+       "prefs-help-watchlist-token2": "This is the secret key to the web feed 
of your watchlist.\nAnyone who knows it will be able to read your watchlist, so 
do not share it.\nIf you need to, [[Special:ResetTokens|you can reset it]].",
        "savedprefs": "Your preferences have been saved.",
        "savedrights": "The user groups of {{GENDER:$1|$1}} have been saved.",
        "timezonelegend": "Time zone:",
diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json
index 27d8e43..1988a46 100644
--- a/languages/i18n/qqq.json
+++ b/languages/i18n/qqq.json
@@ -1222,7 +1222,6 @@
        "prefs-watchlist-edits": "Used in [[Special:Preferences]], tab 
\"Watchlist\".",
        "prefs-watchlist-edits-max": "Shown as hint in [[Special:Preferences]], 
tab \"Watchlist\"",
        "prefs-watchlist-token": "Used in [[Special:Preferences]], tab 
Watchlist.",
-       "prefs-watchlist-managetokens": "Label for the button to see and reset 
the user's private tokens",
        "prefs-misc": "Tab used on the [[Special:Preferences|user preferences]] 
special page.",
        "prefs-resetpass": "Button on user data tab in user preferences. When 
you click the button you go to the special page 
[[Special:ResetPass]].\n\n{{Identical|Change password}}",
        "prefs-changeemail": "Link on [[Special:Preferences]] to 
[[Special:ChangeEmail]]. [[Special:ChangeEmail]] also allows removing email 
address. \n\nSee also:\n* {{msg-mw|prefs-help-email-required|help}}\n* 
{{msg-mw|prefs-help-email|help}}\n* {{msg-mw|prefs-help-email-others|help}}\n* 
{{msg-mw|prefs-setemail|link title}}",
@@ -1240,7 +1239,7 @@
        "recentchangesdays-max": "Shown as hint in [[Special:Preferences]], tab 
\"Recent changes\". Parameters:\n* $1 - number of days\nSee also:\n* 
{{msg-mw|Prefs-watchlist-days-max}}",
        "recentchangescount": "Used in [[Special:Preferences]], tab \"Recent 
changes\".",
        "prefs-help-recentchangescount": "Used in [[Special:Preferences]], tab 
\"Recent changes\".",
-       "prefs-help-tokenmanagement": "Used in [[Special:Preferences]], 
Watchlist tab.",
+       "prefs-help-watchlist-token2": "Used in [[Special:Preferences]], tab 
Watchlist. (Formerly in {{msg-mw|prefs-help-watchlist-token}}.)",
        "savedprefs": "This message appears after saving changes to your user 
preferences.",
        "savedrights": "This message appears after saving the user groups on 
[[Special:UserRights]].\n* $1 - The user name of the user which groups was 
saved.",
        "timezonelegend": "{{Identical|Time zone}}",
diff --git a/resources/Resources.php b/resources/Resources.php
index 0665a2a..0e6939b 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -2098,11 +2098,10 @@
        'mediawiki.special.pagesWithProp' => [
                'styles' => 
'resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css',
        ],
-       'mediawiki.special.preferences.ooui' => [
+       'mediawiki.special.preferences' => [
                'scripts' => [
                        
'resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js',
                        
'resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js',
-                       
'resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js',
                        
'resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js',
                        
'resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js',
                ],
@@ -2116,12 +2115,9 @@
                        'mediawiki.language',
                        'mediawiki.confirmCloseWindow',
                        'mediawiki.notification.convertmessagebox',
-                       'oojs-ui-widgets',
-                       'mediawiki.widgets.SelectWithInputWidget',
-                       'mediawiki.editfont.styles',
                ],
        ],
-       'mediawiki.special.preferences.styles.ooui' => [
+       'mediawiki.special.preferences.styles' => [
                'styles' => 
'resources/src/mediawiki.special/mediawiki.special.preferences.styles.css',
        ],
        'mediawiki.special.recentchanges' => [
diff --git a/resources/src/mediawiki.legacy/oldshared.css 
b/resources/src/mediawiki.legacy/oldshared.css
index 596b0d6..7b2d711 100644
--- a/resources/src/mediawiki.legacy/oldshared.css
+++ b/resources/src/mediawiki.legacy/oldshared.css
@@ -220,6 +220,28 @@
        font-size: larger;
 }
 
+/* preference page with js-genrated toc */
+#preftoc {
+       float: left;
+       margin: 1em 1em 1em 1em;
+       width: 13em;
+}
+
+#preftoc li {
+       border: 1px solid #fff;
+}
+
+#preftoc li.selected {
+       background-color: #f9f9f9;
+       border: 1px dashed #aaa;
+}
+
+#preftoc a,
+#preftoc a:active {
+       display: block;
+       color: #005189;
+}
+
 .mw-prefs-buttons {
        clear: left;
        float: left;
diff --git 
a/resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js 
b/resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js
index fe127eb..45df37f 100644
--- 
a/resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js
+++ 
b/resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js
@@ -4,11 +4,9 @@
  */
 ( function ( mw, $ ) {
        $( function () {
-               var allowCloseWindow, saveButton, restoreButton;
+               var allowCloseWindow;
 
-               // Check if all of the form values are unchanged.
-               // (This function could be changed to infuse and check OOUI 
widgets, but that would only make it
-               // slower and more complicated. It works fine to treat them as 
HTML elements.)
+               // Check if all of the form values are unchanged
                function isPrefsChanged() {
                        var inputs = $( '#mw-prefs-form :input[name]' ),
                                input, $input, inputType,
@@ -43,15 +41,12 @@
                        return false;
                }
 
-               saveButton = OO.ui.infuse( $( '#prefcontrol' ) );
-               restoreButton = OO.ui.infuse( $( '#mw-prefs-restoreprefs' ) );
-
                // Disable the button to save preferences unless preferences 
have changed
                // Check if preferences have been changed before JS has 
finished loading
                if ( !isPrefsChanged() ) {
-                       saveButton.setDisabled( true );
-                       $( '#preferences .oo-ui-fieldsetLayout' ).one( 'change 
keydown mousedown', function () {
-                               saveButton.setDisabled( false );
+                       $( '#prefcontrol' ).prop( 'disabled', true );
+                       $( '#preferences > fieldset' ).one( 'change keydown 
mousedown', function () {
+                               $( '#prefcontrol' ).prop( 'disabled', false );
                        } );
                }
 
@@ -63,11 +58,6 @@
                        namespace: 'prefswarning'
                } );
                $( '#mw-prefs-form' ).submit( $.proxy( allowCloseWindow, 
'release' ) );
-               restoreButton.on( 'click', function () {
-                       allowCloseWindow.release();
-                       // The default behavior of events in OOUI is always 
prevented. Follow the link manually.
-                       // Note that middle-click etc. still works, as it 
doesn't emit a OOUI 'click' event.
-                       location.href = restoreButton.getHref();
-               } );
+               $( '#mw-prefs-restoreprefs' ).click( $.proxy( allowCloseWindow, 
'release' ) );
        } );
 }( mediaWiki, jQuery ) );
diff --git 
a/resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js 
b/resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js
deleted file mode 100644
index fe48886..0000000
--- a/resources/src/mediawiki.special/mediawiki.special.preferences.editfont.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*!
- * JavaScript for Special:Preferences: editfont field enhancements.
- */
-( function ( mw, $ ) {
-       $( function () {
-               var widget, lastValue;
-
-               try {
-                       widget = OO.ui.infuse( $( '#mw-input-wpeditfont' ) );
-               } catch ( err ) {
-                       // This preference could theoretically be disabled 
($wgHiddenPrefs)
-                       return;
-               }
-
-               // Style options
-               widget.dropdownWidget.menu.items.forEach( function ( item ) {
-                       item.$label.addClass( 'mw-editfont-' + item.getData() );
-               } );
-
-               function updateLabel( value ) {
-                       // Style selected item label
-                       widget.dropdownWidget.$label
-                               .removeClass( 'mw-editfont-' + lastValue )
-                               .addClass( 'mw-editfont-' + value );
-                       lastValue = value;
-               }
-
-               widget.on( 'change', updateLabel );
-               updateLabel( widget.getValue() );
-
-       } );
-}( mediaWiki, jQuery ) );
diff --git 
a/resources/src/mediawiki.special/mediawiki.special.preferences.styles.css 
b/resources/src/mediawiki.special/mediawiki.special.preferences.styles.css
index 0ee4ac2..33b630a 100644
--- a/resources/src/mediawiki.special/mediawiki.special.preferences.styles.css
+++ b/resources/src/mediawiki.special/mediawiki.special.preferences.styles.css
@@ -1,28 +1,27 @@
 /* Reuses colors from mediawiki.legacy/shared.css */
-.mw-email-not-authenticated .oo-ui-labelWidget,
-.mw-email-none .oo-ui-labelWidget {
+.mw-email-not-authenticated .mw-input,
+.mw-email-none .mw-input {
        border: 1px solid #fde29b;
        background-color: #fdf1d1;
        color: #000;
 }
 /* Authenticated email field has its own class too. Unstyled by default */
 /*
-.mw-email-authenticated .oo-ui-labelWidget { }
+.mw-email-authenticated .mw-input { }
 */
-
-/* This is needed because add extra buttons in a weird way */
-.mw-prefs-buttons .mw-htmlform-submit-buttons {
-       margin: 0;
-       display: inline;
+/* This breaks due to nolabel styling */
+#preferences > fieldset td.mw-label {
+       width: 20%;
 }
 
-.mw-prefs-buttons {
-       margin-top: 1em;
+#preferences > fieldset table {
+       width: 100%;
+}
+#preferences > fieldset table.mw-htmlform-matrix {
+       width: auto;
 }
 
-#prefcontrol {
-       margin-right: 0.5em;
-}
+/* The CSS below is also for JS enabled version, because we want to prevent 
FOUC */
 
 /*
  * Hide, but keep accessible for screen-readers.
@@ -34,74 +33,15 @@
        zoom: 1;
 }
 
-/* Override OOUI styles so that dropdowns near the bottom of the form don't 
get clipped,
- * e.g.'Appearance' / 'Threshold for stub link formatting'. This is hacky and 
bad, it would be
- * better solved by setting overlays for the widgets, but we can't do it from 
PHP... */
-#preferences .oo-ui-panelLayout {
-       position: static;
-       overflow: visible;
-       -webkit-transform: none;
-       transform: none;
+.client-nojs #preftoc {
+       display: none;
 }
 
-#preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       border-color: #c8ccd1;
-       border-width: 1px 0 0;
-       border-radius: 0;
-       padding-left: 0;
-       padding-right: 0;
-       box-shadow: none;
+.client-js #preferences > fieldset {
+       display: none;
 }
 
-/* Tweak the margins to reduce the shifting of form contents
- * after JS code loads and rearranges the page */
-.client-js #preferences > .oo-ui-panelLayout {
-       margin: 1em 0;
-}
-
-.client-js #preferences .oo-ui-panelLayout-framed .oo-ui-panelLayout-framed {
-       margin-left: 0.25em;
-}
-
-.client-js #preferences .oo-ui-tabPanelLayout {
-       padding-top: 0.5em;
-       padding-bottom: 0.5em;
-}
-
-.client-js #preferences .oo-ui-tabPanelLayout .oo-ui-panelLayout-framed {
-       margin-left: 0;
-       margin-bottom: 0;
-       border: 0;
-       padding-top: 0;
-}
-
-.client-js #preferences > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > 
.oo-ui-fieldsetLayout-header {
-       margin-bottom: 1em;
-}
-
-/* Make the "Basic information" section more compact */
-/* OOUI's `align: 'left'` for FieldLayouts sucks, so we do our own */
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > 
.oo-ui-fieldLayout-header {
-       width: 20%;
-       display: inline-block;
-       vertical-align: middle;
-       padding: 0;
-}
-
-#mw-htmlform-info > .oo-ui-fieldLayout-align-top > .oo-ui-fieldLayout-body > 
.oo-ui-fieldLayout-field {
-       width: 80%;
-       display: inline-block;
-       vertical-align: middle;
-}
-
-/* Expand the dropdown and textfield of "Time zone" field to the */
-/* usual maximum width and display them on separate lines. */
-#wpTimeCorrection .oo-ui-dropdownInputWidget,
-#wpTimeCorrection .oo-ui-textInputWidget {
+/* Only the 1st tab is shown by default in JS mode */
+.client-js #preferences #mw-prefsection-personal {
        display: block;
-       max-width: 50em;
-}
-
-#wpTimeCorrection .oo-ui-textInputWidget {
-       margin-top: 0.5em;
 }
diff --git 
a/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js 
b/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js
index 9f1691c..dcfad27 100644
--- a/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js
+++ b/resources/src/mediawiki.special/mediawiki.special.preferences.tabs.js
@@ -3,9 +3,28 @@
  */
 ( function ( mw, $ ) {
        $( function () {
-               var $preferences, tabs, wrapper, previousTab;
+               var $preftoc, $preferences, $fieldsets, labelFunc, previousTab;
 
+               labelFunc = function () {
+                       return this.id.replace( /^mw-prefsection/g, 'preftab' );
+               };
+
+               $preftoc = $( '#preftoc' );
                $preferences = $( '#preferences' );
+
+               $fieldsets = $preferences.children( 'fieldset' )
+                       .attr( {
+                               role: 'tabpanel',
+                               'aria-labelledby': labelFunc
+                       } );
+               $fieldsets.not( '#mw-prefsection-personal' )
+                       .hide()
+                       .attr( 'aria-hidden', 'true' );
+
+               // T115692: The following is kept for backwards compatibility 
with older skins
+               $preferences.addClass( 'jsprefs' );
+               $fieldsets.addClass( 'prefsection' );
+               $fieldsets.children( 'legend' ).addClass( 'mainLegend' );
 
                // Make sure the accessibility tip is selectable so that screen 
reader users take notice,
                // but hide it per default to reduce interface clutter. Also 
make sure it becomes visible
@@ -19,76 +38,62 @@
                                } else {
                                        $( this ).css( 'height', 'auto' );
                                }
-                       } ).prependTo( '#mw-content-text' );
-
-               tabs = new OO.ui.IndexLayout( {
-                       expanded: false,
-                       // Do not remove focus from the tabs menu after 
choosing a tab
-                       autoFocus: false
-               } );
-
-               mw.config.get( 'wgPreferencesTabs' ).forEach( function ( 
tabConfig ) {
-                       var panel, $panelContents;
-
-                       panel = new OO.ui.TabPanelLayout( tabConfig.name, {
-                               expanded: false,
-                               label: tabConfig.label
-                       } );
-                       $panelContents = $( '#mw-prefsection-' + tabConfig.name 
);
-
-                       // Hide the unnecessary PHP PanelLayouts
-                       // (Do not use .remove(), as that would remove event 
handlers for everything inside them)
-                       $panelContents.parent().detach();
-
-                       panel.$element.append( $panelContents );
-                       tabs.addTabPanels( [ panel ] );
-
-                       // Remove duplicate labels
-                       // (This must be after .addTabPanels(), otherwise the 
tab item doesn't exist yet)
-                       $panelContents.children( 'legend' ).remove();
-                       $panelContents.attr( 'aria-labelledby', 
panel.getTabItem().getElementId() );
-               } );
-
-               wrapper = new OO.ui.PanelLayout( {
-                       expanded: false,
-                       padded: false,
-                       framed: true
-               } );
-               wrapper.$element.append( tabs.$element );
-               $preferences.prepend( wrapper.$element );
-
-               function updateHash( panel ) {
-                       var scrollTop, active;
-                       // Handle hash manually to prevent jumping,
-                       // therefore save and restore scrollTop to prevent 
jumping.
-                       scrollTop = $( window ).scrollTop();
-                       // Changing the hash apparently causes keyboard focus 
to be lost?
-                       // Save and restore it. This makes no sense though.
-                       active = document.activeElement;
-                       location.hash = '#mw-prefsection-' + panel.getName();
-                       if ( active ) {
-                               active.focus();
-                       }
-                       $( window ).scrollTop( scrollTop );
-               }
-
-               tabs.on( 'set', updateHash );
+                       } ).insertBefore( $preftoc );
 
                /**
+                * It uses document.getElementById for security reasons (HTML 
injections in $()).
+                *
                 * @ignore
                 * @param {string} name the name of a tab without the prefix 
("mw-prefsection-")
                 * @param {string} [mode] A hash will be set according to the 
current
-                *  open section. Set mode 'noHash' to supress this.
+                *  open section. Set mode 'noHash' to surpress this.
                 */
                function switchPrefTab( name, mode ) {
-                       if ( mode === 'noHash' ) {
-                               tabs.off( 'set', updateHash );
+                       var $tab, scrollTop;
+                       // Handle hash manually to prevent jumping,
+                       // therefore save and restore scrollTop to prevent 
jumping.
+                       scrollTop = $( window ).scrollTop();
+                       if ( mode !== 'noHash' ) {
+                               location.hash = '#mw-prefsection-' + name;
                        }
-                       tabs.setTabPanel( name );
-                       if ( mode === 'noHash' ) {
-                               tabs.on( 'set', updateHash );
+                       $( window ).scrollTop( scrollTop );
+
+                       $preftoc.find( 'li' ).removeClass( 'selected' )
+                               .find( 'a' ).attr( {
+                                       tabIndex: -1,
+                                       'aria-selected': 'false'
+                               } );
+
+                       $tab = $( document.getElementById( 'preftab-' + name ) 
);
+                       if ( $tab.length ) {
+                               $tab.attr( {
+                                       tabIndex: 0,
+                                       'aria-selected': 'true'
+                               } ).focus()
+                                       .parent().addClass( 'selected' );
+
+                               $preferences.children( 'fieldset' 
).hide().attr( 'aria-hidden', 'true' );
+                               $( document.getElementById( 'mw-prefsection-' + 
name ) ).show().attr( 'aria-hidden', 'false' );
                        }
                }
+
+               // Enable keyboard users to use left and right keys to switch 
tabs
+               $preftoc.on( 'keydown', function ( event ) {
+                       var keyLeft = 37,
+                               keyRight = 39,
+                               $el;
+
+                       if ( event.keyCode === keyLeft ) {
+                               $el = $( '#preftoc li.selected' ).prev().find( 
'a' );
+                       } else if ( event.keyCode === keyRight ) {
+                               $el = $( '#preftoc li.selected' ).next().find( 
'a' );
+                       } else {
+                               return;
+                       }
+                       if ( $el.length > 0 ) {
+                               switchPrefTab( $el.attr( 'href' ).replace( 
'#mw-prefsection-', '' ) );
+                       }
+               } );
 
                // Jump to correct section as indicated by the hash.
                // This function is called onload and onhashchange.
@@ -110,9 +115,15 @@
                        }
                }
 
-               // Handle other things that change the hash (e.g. using
+               // In browsers that support the onhashchange event we will not 
bind click
+               // handlers and instead let the browser do the default behavior 
(clicking the
+               // <a href="#.."> will naturally set the hash, handled by 
onhashchange.
+               // But other things that change the hash will also be caught 
(e.g. using
                // the Back and Forward browser navigation).
-               if ( 'onhashchange' in window ) {
+               // Note the special check for IE "compatibility" mode.
+               if ( 'onhashchange' in window &&
+                       ( document.documentMode === undefined || 
document.documentMode >= 8 )
+               ) {
                        $( window ).on( 'hashchange', function () {
                                var hash = location.hash;
                                if ( hash.match( /^#mw-[\w-]+/ ) ) {
@@ -120,12 +131,22 @@
                                } else if ( hash === '' ) {
                                        switchPrefTab( 'personal', 'noHash' );
                                }
+                       } )
+                               // Run the function immediately to select the 
proper tab on startup.
+                               .trigger( 'hashchange' );
+               // In older browsers we'll bind a click handler as fallback.
+               // We must not have onhashchange *and* the click handlers, 
otherwise
+               // the click handler calls switchPrefTab() which sets the hash 
value,
+               // which triggers onhashchange and calls switchPrefTab() again.
+               } else {
+                       $preftoc.on( 'click', 'li a', function ( e ) {
+                               switchPrefTab( $( this ).attr( 'href' 
).replace( '#mw-prefsection-', '' ) );
+                               e.preventDefault();
                        } );
+                       // If we've reloaded the page or followed an 
open-in-new-window,
+                       // make the selected tab visible.
+                       detectHash();
                }
-
-               // If we've reloaded the page or followed an open-in-new-window,
-               // make the selected tab visible.
-               detectHash();
 
                // Restore the active tab after saving the preferences
                previousTab = mw.storage.session.get( 'mwpreferences-prevTab' );
@@ -136,7 +157,7 @@
                }
 
                $( '#mw-prefs-form' ).on( 'submit', function () {
-                       var value = tabs.getCurrentTabPanelName();
+                       var value = $( $preftoc ).find( 'li.selected a' ).attr( 
'id' ).replace( 'preftab-', '' );
                        mw.storage.session.set( 'mwpreferences-prevTab', value 
);
                } );
 
diff --git 
a/resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js 
b/resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js
index 7fbcc77..03656ee 100644
--- a/resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js
+++ b/resources/src/mediawiki.special/mediawiki.special.preferences.timezone.js
@@ -4,19 +4,13 @@
 ( function ( mw, $ ) {
        $( function () {
                var
-                       timezoneWidget, $localtimeHolder, servertime;
+                       $tzSelect, $tzTextbox, $localtimeHolder, servertime;
 
                // Timezone functions.
                // Guesses Timezone from browser and updates fields onchange.
 
-               // This is identical to OO.ui.infuse( ... ), but it makes the 
class name of the result known.
-               try {
-                       timezoneWidget = 
mw.widgets.SelectWithInputWidget.static.infuse( $( '#wpTimeCorrection' ) );
-               } catch ( err ) {
-                       // This preference could theoretically be disabled 
($wgHiddenPrefs)
-                       timezoneWidget = null;
-               }
-
+               $tzSelect = $( '#mw-input-wptimecorrection' );
+               $tzTextbox = $( '#mw-input-wptimecorrection-other' );
                $localtimeHolder = $( '#wpLocalTime' );
                servertime = parseInt( $( 'input[name="wpServerTime"]' ).val(), 
10 );
 
@@ -54,21 +48,21 @@
 
                function updateTimezoneSelection() {
                        var minuteDiff, localTime,
-                               type = timezoneWidget.dropdowninput.getValue();
+                               type = $tzSelect.val();
 
                        if ( type === 'other' ) {
                                // User specified time zone manually in <input>
                                // Grab data from the textbox, parse it.
-                               minuteDiff = hoursToMinutes( 
timezoneWidget.textinput.getValue() );
+                               minuteDiff = hoursToMinutes( $tzTextbox.val() );
                        } else {
                                // Time zone not manually specified by user
                                if ( type === 'guess' ) {
                                        // Get browser timezone & fill it in
                                        minuteDiff = -( new 
Date().getTimezoneOffset() );
-                                       timezoneWidget.textinput.setValue( 
minutesToHours( minuteDiff ) );
-                                       timezoneWidget.dropdowninput.setValue( 
'other' );
+                                       $tzTextbox.val( minutesToHours( 
minuteDiff ) );
+                                       $tzSelect.val( 'other' );
                                } else {
-                                       // Grab data from the dropdown value
+                                       // Grab data from the $tzSelect value
                                        minuteDiff = parseInt( type.split( '|' 
)[ 1 ], 10 ) || 0;
                                }
                        }
@@ -82,9 +76,9 @@
                        $localtimeHolder.text( mw.language.convertNumber( 
minutesToHours( localTime ) ) );
                }
 
-               if ( timezoneWidget ) {
-                       timezoneWidget.dropdowninput.on( 'change', 
updateTimezoneSelection );
-                       timezoneWidget.textinput.on( 'change', 
updateTimezoneSelection );
+               if ( $tzSelect.length && $tzTextbox.length ) {
+                       $tzSelect.change( updateTimezoneSelection );
+                       $tzTextbox.blur( updateTimezoneSelection );
                        updateTimezoneSelection();
                }
 
diff --git a/tests/selenium/pageobjects/preferences.page.js 
b/tests/selenium/pageobjects/preferences.page.js
index 890fe5b..98b87fe 100644
--- a/tests/selenium/pageobjects/preferences.page.js
+++ b/tests/selenium/pageobjects/preferences.page.js
@@ -3,8 +3,8 @@
 
 class PreferencesPage extends Page {
 
-       get realName() { return browser.element( '#mw-input-wprealname 
.oo-ui-inputWidget-input' ); }
-       get save() { return browser.element( '#prefcontrol 
.oo-ui-buttonElement-button' ); }
+       get realName() { return browser.element( '#mw-input-wprealname' ); }
+       get save() { return browser.element( '#prefcontrol' ); }
 
        open() {
                super.open( 'Special:Preferences' );

-- 
To view, visit https://gerrit.wikimedia.org/r/394804
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I44b5daea1828f71881b5bd35218f5ecb7ab7f36e
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Bartosz Dziewoński <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to