return self::$defaultPreferences;
}
+ OutputPage::setupOOUI(
+ strtolower( $context->getSkin()->getSkinName() ),
+ $context->getLanguage()->getDir()
+ );
+
$defaultPreferences = [];
self::profilePreferences( $user, $context, $defaultPreferences );
if ( $canEditPrivateInfo && $authManager->allowsAuthenticationDataChange(
new PasswordAuthenticationRequest(), false )->isGood()
) {
- $link = $linkRenderer->makeLink( SpecialPage::getTitleFor( 'ChangePassword' ),
- $context->msg( 'prefs-resetpass' )->text(), [],
- [ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ] );
+ $link = new OOUI\ButtonWidget( [
+ 'href' => SpecialPage::getTitleFor( 'ChangePassword' )->getLinkURL( [
+ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText()
+ ] ),
+ 'label' => $context->msg( 'prefs-resetpass' )->text(),
+ ] );
$defaultPreferences['password'] = [
'type' => 'info',
'raw' => true,
- 'default' => $link,
+ 'default' => (string)$link,
'label-message' => 'yourpassword',
'section' => 'personal/info',
];
$emailAddress = $user->getEmail() ? htmlspecialchars( $user->getEmail() ) : '';
if ( $canEditPrivateInfo && $authManager->allowsPropertyChange( 'emailaddress' ) ) {
- $link = $linkRenderer->makeLink(
- SpecialPage::getTitleFor( 'ChangeEmail' ),
- $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->text(),
- [],
- [ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText() ] );
-
- $emailAddress .= $emailAddress == '' ? $link : (
- $context->msg( 'word-separator' )->escaped()
- . $context->msg( 'parentheses' )->rawParams( $link )->escaped()
- );
+ $link = new OOUI\ButtonWidget( [
+ 'href' => SpecialPage::getTitleFor( 'ChangeEmail' )->getLinkURL( [
+ 'returnto' => SpecialPage::getTitleFor( 'Preferences' )->getPrefixedText()
+ ] ),
+ 'label' =>
+ $context->msg( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->text(),
+ ] );
+
+ $emailAddress .= $emailAddress == '' ? $link : ( '<br />' . $link );
}
$defaultPreferences['emailaddress'] = [
} else {
$disableEmailPrefs = true;
$emailauthenticated = $context->msg( 'emailnotauthenticated' )->parse() . '<br />' .
- $linkRenderer->makeKnownLink(
- SpecialPage::getTitleFor( 'Confirmemail' ),
- $context->msg( 'emailconfirmlink' )->text()
- ) . '<br />';
+ new OOUI\ButtonWidget( [
+ 'href' => SpecialPage::getTitleFor( 'Confirmemail' )->getLinkURL(),
+ 'label' => $context->msg( 'emailconfirmlink' )->text(),
+ ] );
$emailauthenticationclass = "mw-email-not-authenticated";
}
} else {
'default' => $tzSetting,
'size' => 20,
'section' => 'rendering/timeoffset',
+ 'id' => 'wpTimeCorrection',
];
}
# # Watchlist #####################################
if ( $user->isAllowed( 'editmywatchlist' ) ) {
- $editWatchlistLinks = [];
+ $editWatchlistLinks = '';
$editWatchlistModes = [
'edit' => [ 'EditWatchlist', false ],
'raw' => [ 'EditWatchlist', 'raw' ],
$linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
foreach ( $editWatchlistModes as $editWatchlistMode => $mode ) {
// Messages: prefs-editwatchlist-edit, prefs-editwatchlist-raw, prefs-editwatchlist-clear
- $editWatchlistLinks[] = $linkRenderer->makeKnownLink(
- SpecialPage::getTitleFor( $mode[0], $mode[1] ),
- new HtmlArmor( $context->msg( "prefs-editwatchlist-{$editWatchlistMode}" )->parse() )
- );
+ $editWatchlistLinks .=
+ new OOUI\ButtonWidget( [
+ 'href' => SpecialPage::getTitleFor( $mode[0], $mode[1] )->getLinkURL(),
+ 'label' => new OOUI\HtmlSnippet(
+ $context->msg( "prefs-editwatchlist-{$editWatchlistMode}" )->parse()
+ ),
+ ] );
}
$defaultPreferences['editwatchlist'] = [
'type' => 'info',
'raw' => true,
- 'default' => $context->getLanguage()->pipeList( $editWatchlistLinks ),
+ 'default' => $editWatchlistLinks,
'label-message' => 'prefs-editwatchlist-label',
'section' => 'watchlist/editwatchlist',
];
'default' => $user->getTokenFromOption( 'watchlisttoken' ),
'help-message' => 'prefs-help-watchlist-token2',
];
+ $defaultPreferences['watchlisttoken-info2'] = [
+ 'type' => 'info',
+ 'section' => 'watchlist/tokenwatchlist',
+ 'raw' => true,
+ 'default' => $context->msg( 'prefs-help-watchlist-token2' )->parse(),
+ ];
}
}
$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 );
return;
}
- $out->addModules( 'mediawiki.special.preferences' );
- $out->addModuleStyles( 'mediawiki.special.preferences.styles' );
+ $out->addModules( 'mediawiki.special.preferences.ooui' );
+ $out->addModuleStyles( 'mediawiki.special.preferences.styles.ooui' );
$session = $this->getRequest()->getSession();
if ( $session->get( 'specialPreferencesSaveSuccess' ) ) {
$htmlForm = $this->getFormObject( $user, $this->getContext() );
$htmlForm->setSubmitCallback( [ 'Preferences', 'tryUISubmit' ] );
- $sectionTitles = $htmlForm->getPreferenceSections();
-
- $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 )
- )
- );
+
+ $prefTabs = [];
+ foreach ( $htmlForm->getPreferenceSections() as $key ) {
+ $prefTabs[] = [
+ 'name' => $key,
+ 'label' => $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();
}
$context = new DerivativeContext( $this->getContext() );
$context->setTitle( $this->getPageTitle( 'reset' ) ); // Reset subpage
- $htmlForm = new HTMLForm( [], $context, 'prefs-restore' );
+ $htmlForm = HTMLForm::factory( 'ooui', [], $context, 'prefs-restore' );
$htmlForm->setSubmitTextMsg( 'restoreprefs' );
$htmlForm->setSubmitDestructive();
* @file
*/
-use MediaWiki\MediaWikiServices;
-
/**
* Form to edit user preferences.
*/
-class PreferencesForm extends HTMLForm {
+class PreferencesForm extends OOUIHTMLForm {
// Override default value from HTMLForm
protected $mSubSectionBeforeFields = false;
* @return string
*/
function getButtons() {
- $attrs = [ 'id' => 'mw-prefs-restoreprefs' ];
-
if ( !$this->getModifiedUser()->isAllowedAny( 'editmyprivateinfo', 'editmyoptions' ) ) {
return '';
}
if ( $this->getModifiedUser()->isAllowed( 'editmyoptions' ) ) {
$t = $this->getTitle()->getSubpage( 'reset' );
- $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
- $html .= "\n" . $linkRenderer->makeLink( $t, $this->msg( 'restoreprefs' )->text(),
- Html::buttonAttributes( $attrs, [ 'mw-ui-quiet' ] ) );
+ $html .= new OOUI\ButtonWidget( [
+ 'infusable' => true,
+ 'id' => 'mw-prefs-restoreprefs',
+ 'label' => $this->msg( 'restoreprefs' )->text(),
+ 'href' => $t->getLinkURL(),
+ 'flags' => [ 'destructive' ],
+ 'framed' => false,
+ ] );
$html = Xml::tags( 'div', [ 'class' => 'mw-prefs-buttons' ], $html );
}
'mediawiki.special.pagesWithProp' => [
'styles' => 'resources/src/mediawiki.special/mediawiki.special.pagesWithProp.css',
],
- 'mediawiki.special.preferences' => [
+ 'mediawiki.special.preferences.ooui' => [
'scripts' => [
'resources/src/mediawiki.special/mediawiki.special.preferences.confirmClose.js',
'resources/src/mediawiki.special/mediawiki.special.preferences.convertmessagebox.js',
'mediawiki.language',
'mediawiki.confirmCloseWindow',
'mediawiki.notification.convertmessagebox',
+ 'oojs-ui-widgets',
+ 'mediawiki.widgets.SelectWithInputWidget',
],
],
- 'mediawiki.special.preferences.styles' => [
+ 'mediawiki.special.preferences.styles.ooui' => [
'styles' => 'resources/src/mediawiki.special/mediawiki.special.preferences.styles.css',
],
'mediawiki.special.recentchanges' => [
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;
*/
( function ( mw, $ ) {
$( function () {
- var allowCloseWindow;
+ var allowCloseWindow, saveButton, restoreButton;
- // Check if all of the form values are unchanged
+ // 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.)
function isPrefsChanged() {
var inputs = $( '#mw-prefs-form :input[name]' ),
input, $input, inputType,
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() ) {
- $( '#prefcontrol' ).prop( 'disabled', true );
- $( '#preferences > fieldset' ).one( 'change keydown mousedown', function () {
- $( '#prefcontrol' ).prop( 'disabled', false );
+ saveButton.setDisabled( true );
+ $( '#preferences .oo-ui-fieldsetLayout' ).one( 'change keydown mousedown', function () {
+ saveButton.setDisabled( false );
} );
}
namespace: 'prefswarning'
} );
$( '#mw-prefs-form' ).submit( $.proxy( allowCloseWindow, 'release' ) );
- $( '#mw-prefs-restoreprefs' ).click( $.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();
+ } );
} );
}( mediaWiki, jQuery ) );
/* Reuses colors from mediawiki.legacy/shared.css */
-.mw-email-not-authenticated .mw-input,
-.mw-email-none .mw-input {
+.mw-email-not-authenticated .oo-ui-labelWidget,
+.mw-email-none .oo-ui-labelWidget {
border: 1px solid #fde29b;
background-color: #fdf1d1;
color: #000;
}
/* Authenticated email field has its own class too. Unstyled by default */
/*
-.mw-email-authenticated .mw-input { }
+.mw-email-authenticated .oo-ui-labelWidget { }
*/
-/* This breaks due to nolabel styling */
-#preferences > fieldset td.mw-label {
- width: 20%;
-}
-#preferences > fieldset table {
- width: 100%;
+/* This is needed because add extra buttons in a weird way */
+.mw-prefs-buttons .mw-htmlform-submit-buttons {
+ margin: 0;
+ display: inline;
}
-#preferences > fieldset table.mw-htmlform-matrix {
- width: auto;
+
+.mw-prefs-buttons {
+ margin-top: 1em;
}
-/* The CSS below is also for JS enabled version, because we want to prevent FOUC */
+#prefcontrol {
+ margin-right: 0.5em;
+}
/*
* Hide, but keep accessible for screen-readers.
zoom: 1;
}
-.client-nojs #preftoc {
- display: none;
+/* 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;
+}
+
+/* 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-panelLayout-framed .oo-ui-tabPanelLayout .oo-ui-panelLayout-framed {
+ margin-left: 0;
}
-.client-js #preferences > fieldset {
- display: none;
+.client-js #preferences .oo-ui-panelLayout-framed .oo-ui-tabPanelLayout {
+ padding-top: 0.5em;
+ padding-bottom: 0.5em;
}
-/* Only the 1st tab is shown by default in JS mode */
-.client-js #preferences #mw-prefsection-personal {
- display: block;
+.client-js #preferences > .oo-ui-panelLayout > .oo-ui-fieldsetLayout > .oo-ui-fieldsetLayout-header {
+ margin-bottom: 1em;
}
*/
( function ( mw, $ ) {
$( function () {
- var $preftoc, $preferences, $fieldsets, labelFunc, previousTab;
+ var $preferences, tabs, wrapper, 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
// when selected. Similar to jquery.mw-jump
} else {
$( this ).css( 'height', 'auto' );
}
- } ).insertBefore( $preftoc );
+ } ).prependTo( '#mw-content-text' );
- /**
- * 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 surpress this.
- */
- function switchPrefTab( name, mode ) {
- var $tab, scrollTop;
+ 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();
- if ( mode !== 'noHash' ) {
- location.hash = '#mw-prefsection-' + name;
+ // 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 );
-
- $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;
+ tabs.on( 'set', updateHash );
+
+ /**
+ * @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.
+ */
+ function switchPrefTab( name, mode ) {
+ if ( mode === 'noHash' ) {
+ tabs.off( 'set', updateHash );
}
- if ( $el.length > 0 ) {
- switchPrefTab( $el.attr( 'href' ).replace( '#mw-prefsection-', '' ) );
+ tabs.setTabPanel( name );
+ if ( mode === 'noHash' ) {
+ tabs.on( 'set', updateHash );
}
- } );
+ }
// Jump to correct section as indicated by the hash.
// This function is called onload and onhashchange.
}
}
- // 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
+ // Handle other things that change the hash (e.g. using
// the Back and Forward browser navigation).
- // Note the special check for IE "compatibility" mode.
- if ( 'onhashchange' in window &&
- ( document.documentMode === undefined || document.documentMode >= 8 )
- ) {
+ if ( 'onhashchange' in window ) {
$( window ).on( 'hashchange', function () {
var hash = location.hash;
if ( hash.match( /^#mw-[\w-]+/ ) ) {
} 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' );
if ( previousTab ) {
}
$( '#mw-prefs-form' ).on( 'submit', function () {
- var value = $( $preftoc ).find( 'li.selected a' ).attr( 'id' ).replace( 'preftab-', '' );
+ var value = tabs.getCurrentTabPanelName();
mw.storage.session.set( 'mwpreferences-prevTab', value );
} );
( function ( mw, $ ) {
$( function () {
var
- $tzSelect, $tzTextbox, $localtimeHolder, servertime;
+ timezoneWidget, $localtimeHolder, servertime;
// Timezone functions.
// Guesses Timezone from browser and updates fields onchange.
- $tzSelect = $( '#mw-input-wptimecorrection' );
- $tzTextbox = $( '#mw-input-wptimecorrection-other' );
+ // 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;
+ }
+
$localtimeHolder = $( '#wpLocalTime' );
servertime = parseInt( $( 'input[name="wpServerTime"]' ).val(), 10 );
function updateTimezoneSelection() {
var minuteDiff, localTime,
- type = $tzSelect.val();
+ type = timezoneWidget.dropdowninput.getValue();
if ( type === 'other' ) {
// User specified time zone manually in <input>
// Grab data from the textbox, parse it.
- minuteDiff = hoursToMinutes( $tzTextbox.val() );
+ minuteDiff = hoursToMinutes( timezoneWidget.textinput.getValue() );
} else {
// Time zone not manually specified by user
if ( type === 'guess' ) {
// Get browser timezone & fill it in
minuteDiff = -( new Date().getTimezoneOffset() );
- $tzTextbox.val( minutesToHours( minuteDiff ) );
- $tzSelect.val( 'other' );
+ timezoneWidget.textinput.setValue( minutesToHours( minuteDiff ) );
+ timezoneWidget.dropdowninput.setValue( 'other' );
} else {
- // Grab data from the $tzSelect value
+ // Grab data from the dropdown value
minuteDiff = parseInt( type.split( '|' )[ 1 ], 10 ) || 0;
}
}
$localtimeHolder.text( mw.language.convertNumber( minutesToHours( localTime ) ) );
}
- if ( $tzSelect.length && $tzTextbox.length ) {
- $tzSelect.change( updateTimezoneSelection );
- $tzTextbox.blur( updateTimezoneSelection );
+ if ( timezoneWidget ) {
+ timezoneWidget.dropdowninput.on( 'change', updateTimezoneSelection );
+ timezoneWidget.textinput.on( 'change', updateTimezoneSelection );
updateTimezoneSelection();
}
/** Helper */
protected function prefsFor( $user_key ) {
+ // TODO This should use Preferences::getPreferences() instead of calling internal methods.
+ // Unfortunately that currently ignores the $user parameter if it has cached data, even for
+ // a different user...
+ OutputPage::setupOOUI(
+ strtolower( $this->context->getSkin()->getSkinName() ),
+ $this->context->getLanguage()->getDir()
+ );
$preferences = [];
Preferences::profilePreferences(
$this->prefUsers[$user_key],
class PreferencesPage extends Page {
- get realName() { return browser.element( '#mw-input-wprealname' ); }
- get save() { return browser.element( '#prefcontrol' ); }
+ get realName() { return browser.element( '#mw-input-wprealname .oo-ui-inputWidget-input' ); }
+ get save() { return browser.element( '#prefcontrol .oo-ui-buttonElement-button' ); }
open() {
super.open( 'Special:Preferences' );