Create an HTMLForm field for selecting a timezone
This patch introduces HTMLTimezoneField, an HTMLForm field type that allows the user to select a timezone, either from a geographic zone, by manually entering an offset, or using the wiki/browser default. This logic is extracted from DefaultPreferencesFactory so that it can be reused elsewhere. The widget itself is really just an HTMLSelectOrOtherField, it's just the list of options and the JS logic that is special. Bug: T309629 Change-Id: I99a00dff7e3319ce45883191daee16bec1ed68ba
This commit is contained in:
parent
090599c048
commit
ec09c19fba
9 changed files with 241 additions and 161 deletions
|
|
@ -601,6 +601,7 @@ $wgAutoloadLocalClasses = [
|
|||
'HTMLTextAreaField' => __DIR__ . '/includes/htmlform/fields/HTMLTextAreaField.php',
|
||||
'HTMLTextField' => __DIR__ . '/includes/htmlform/fields/HTMLTextField.php',
|
||||
'HTMLTextFieldWithButton' => __DIR__ . '/includes/htmlform/fields/HTMLTextFieldWithButton.php',
|
||||
'HTMLTimezoneField' => __DIR__ . '/includes/htmlform/fields/HTMLTimezoneField.php',
|
||||
'HTMLTitleTextField' => __DIR__ . '/includes/htmlform/fields/HTMLTitleTextField.php',
|
||||
'HTMLTitlesMultiselectField' => __DIR__ . '/includes/htmlform/fields/HTMLTitlesMultiselectField.php',
|
||||
'HTMLUserTextField' => __DIR__ . '/includes/htmlform/fields/HTMLUserTextField.php',
|
||||
|
|
|
|||
|
|
@ -184,6 +184,7 @@ class HTMLForm extends ContextSource {
|
|||
'time' => HTMLDateTimeField::class,
|
||||
'datetime' => HTMLDateTimeField::class,
|
||||
'expiry' => HTMLExpiryField::class,
|
||||
'timezone' => HTMLTimezoneField::class,
|
||||
// HTMLTextField will output the correct type="" attribute automagically.
|
||||
// There are about four zillion other HTML5 input types, like range, but
|
||||
// we don't use those at the moment, so no point in adding all of them.
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ class HTMLSelectOrOtherField extends HTMLTextField {
|
|||
|
||||
$wrapperAttribs = [
|
||||
'id' => $this->mID,
|
||||
'class' => self::FIELD_CLASS
|
||||
'class' => $this->getFieldClasses()
|
||||
];
|
||||
if ( $this->mClass !== '' ) {
|
||||
$wrapperAttribs['class'] .= ' ' . $this->mClass;
|
||||
$wrapperAttribs['class'][] = $this->mClass;
|
||||
}
|
||||
return Html::rawElement(
|
||||
'div',
|
||||
|
|
@ -139,7 +139,7 @@ class HTMLSelectOrOtherField extends HTMLTextField {
|
|||
$disabled = true;
|
||||
}
|
||||
|
||||
$inputClasses = [ self::FIELD_CLASS ];
|
||||
$inputClasses = $this->getFieldClasses();
|
||||
if ( $this->mClass !== '' ) {
|
||||
$inputClasses = array_merge( $inputClasses, explode( ' ', $this->mClass ) );
|
||||
}
|
||||
|
|
@ -176,4 +176,16 @@ class HTMLSelectOrOtherField extends HTMLTextField {
|
|||
return $this->getDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of classes that should be applied to the widget itself. Unfortunately, we can't use
|
||||
* $this->mClass or the 'cssclass' config option, because they're also added to the outer field wrapper
|
||||
* (which includes the label). This method exists a temporary workaround until HTMLFormField will have
|
||||
* a stable way for subclasses to specify additional classes for the widget itself.
|
||||
* @internal Should only be used in HTMLTimezoneField
|
||||
* @return string[]
|
||||
*/
|
||||
protected function getFieldClasses(): array {
|
||||
return [ self::FIELD_CLASS ];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
151
includes/htmlform/fields/HTMLTimezoneField.php
Normal file
151
includes/htmlform/fields/HTMLTimezoneField.php
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
<?php
|
||||
|
||||
use MediaWiki\MainConfigNames;
|
||||
use MediaWiki\MediaWikiServices;
|
||||
use Wikimedia\Message\ITextFormatter;
|
||||
use Wikimedia\Message\MessageValue;
|
||||
|
||||
/**
|
||||
* Dropdown widget that allows the user to select a timezone, either by choosing a geographic zone, by using the wiki
|
||||
* default, or by manually specifying an offset. It also has an option to fill the value from the browser settings.
|
||||
* The value of this field is in a format accepted by UserTimeCorrection.
|
||||
*/
|
||||
class HTMLTimezoneField extends HTMLSelectOrOtherField {
|
||||
private const FIELD_CLASS = 'mw-htmlform-timezone-field';
|
||||
|
||||
/** @var ITextFormatter */
|
||||
private $msgFormatter;
|
||||
|
||||
/**
|
||||
* @stable to call
|
||||
* @inheritDoc
|
||||
* Note that no options should be specified.
|
||||
*/
|
||||
public function __construct( $params ) {
|
||||
if ( isset( $params['options'] ) ) {
|
||||
throw new InvalidArgumentException( "Options should not be provided to " . __CLASS__ );
|
||||
}
|
||||
$params['placeholder-message'] = $params['placeholder-message'] ?? 'timezone-useoffset-placeholder';
|
||||
$params['options'] = [];
|
||||
parent::__construct( $params );
|
||||
$lang = $this->mParent ? $this->mParent->getLanguage() : RequestContext::getMain()->getLanguage();
|
||||
$langCode = $lang->getCode();
|
||||
$this->msgFormatter = MediaWikiServices::getInstance()->getMessageFormatterFactory()
|
||||
->getTextFormatter( $langCode );
|
||||
$this->mOptions = $this->getTimezoneOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string|string[]>
|
||||
*/
|
||||
private function getTimezoneOptions(): array {
|
||||
$opt = [];
|
||||
|
||||
$localTZoffset = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LocalTZoffset );
|
||||
$timeZoneList = $this->getTimeZoneList();
|
||||
|
||||
$timestamp = MWTimestamp::getLocalInstance();
|
||||
// Check that the LocalTZoffset is the same as the local time zone offset
|
||||
if ( $localTZoffset === (int)$timestamp->format( 'Z' ) / 60 ) {
|
||||
$timezoneName = $timestamp->getTimezone()->getName();
|
||||
// Localize timezone
|
||||
if ( isset( $timeZoneList[$timezoneName] ) ) {
|
||||
$timezoneName = $timeZoneList[$timezoneName]['name'];
|
||||
}
|
||||
$server_tz_msg = $this->msgFormatter->format(
|
||||
MessageValue::new( 'timezoneuseserverdefault', [ $timezoneName ] )
|
||||
);
|
||||
} else {
|
||||
$tzstring = sprintf(
|
||||
'%+03d:%02d',
|
||||
floor( $localTZoffset / 60 ),
|
||||
abs( $localTZoffset ) % 60
|
||||
);
|
||||
$server_tz_msg = $this->msgFormatter->format(
|
||||
MessageValue::new( 'timezoneuseserverdefault', [ $tzstring ] )
|
||||
);
|
||||
}
|
||||
$opt[$server_tz_msg] = "System|$localTZoffset";
|
||||
$opt[$this->msgFormatter->format( MessageValue::new( 'timezoneuseoffset' ) )] = 'other';
|
||||
$opt[$this->msgFormatter->format( MessageValue::new( 'guesstimezone' ) )] = 'guess';
|
||||
|
||||
foreach ( $timeZoneList as $timeZoneInfo ) {
|
||||
$region = $timeZoneInfo['region'];
|
||||
if ( !isset( $opt[$region] ) ) {
|
||||
$opt[$region] = [];
|
||||
}
|
||||
$opt[$region][$timeZoneInfo['name']] = $timeZoneInfo['timecorrection'];
|
||||
}
|
||||
return $opt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all time zones
|
||||
* @return string[][] A list of all time zones. The system name of the time zone is used as key and
|
||||
* the value is an array which contains localized name, the timecorrection value used for
|
||||
* preferences and the region
|
||||
*/
|
||||
private function getTimeZoneList(): array {
|
||||
$identifiers = DateTimeZone::listIdentifiers();
|
||||
// @phan-suppress-next-line PhanTypeComparisonFromArray See phan issue #3162
|
||||
if ( $identifiers === false ) {
|
||||
return [];
|
||||
}
|
||||
sort( $identifiers );
|
||||
|
||||
$tzRegions = [
|
||||
'Africa' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-africa' ) ),
|
||||
'America' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-america' ) ),
|
||||
'Antarctica' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-antarctica' ) ),
|
||||
'Arctic' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-arctic' ) ),
|
||||
'Asia' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-asia' ) ),
|
||||
'Atlantic' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-atlantic' ) ),
|
||||
'Australia' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-australia' ) ),
|
||||
'Europe' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-europe' ) ),
|
||||
'Indian' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-indian' ) ),
|
||||
'Pacific' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-pacific' ) ),
|
||||
];
|
||||
asort( $tzRegions );
|
||||
|
||||
$timeZoneList = [];
|
||||
|
||||
$now = new DateTime();
|
||||
|
||||
foreach ( $identifiers as $identifier ) {
|
||||
$parts = explode( '/', $identifier, 2 );
|
||||
|
||||
// DateTimeZone::listIdentifiers() returns a number of
|
||||
// backwards-compatibility entries. This filters them out of the
|
||||
// list presented to the user.
|
||||
if ( count( $parts ) !== 2 || !array_key_exists( $parts[0], $tzRegions ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Localize region
|
||||
$parts[0] = $tzRegions[$parts[0]];
|
||||
|
||||
$dateTimeZone = new DateTimeZone( $identifier );
|
||||
$minDiff = floor( $dateTimeZone->getOffset( $now ) / 60 );
|
||||
|
||||
$display = str_replace( '_', ' ', $parts[0] . '/' . $parts[1] );
|
||||
$value = "ZoneInfo|$minDiff|$identifier";
|
||||
|
||||
$timeZoneList[$identifier] = [
|
||||
'name' => $display,
|
||||
'timecorrection' => $value,
|
||||
'region' => $parts[0],
|
||||
];
|
||||
}
|
||||
|
||||
return $timeZoneList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function getFieldClasses(): array {
|
||||
$classes = parent::getFieldClasses();
|
||||
$classes[] = self::FIELD_CLASS;
|
||||
return $classes;
|
||||
}
|
||||
}
|
||||
|
|
@ -20,11 +20,10 @@
|
|||
|
||||
namespace MediaWiki\Preferences;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Html;
|
||||
use HTMLForm;
|
||||
use HTMLFormField;
|
||||
use HTMLTimezoneField;
|
||||
use IContextSource;
|
||||
use ILanguageConverter;
|
||||
use Language;
|
||||
|
|
@ -48,7 +47,6 @@ use MediaWiki\User\UserTimeCorrection;
|
|||
use Message;
|
||||
use MessageLocalizer;
|
||||
use MWException;
|
||||
use MWTimestamp;
|
||||
use NamespaceInfo;
|
||||
use OutputPage;
|
||||
use Parser;
|
||||
|
|
@ -63,8 +61,6 @@ use Title;
|
|||
use UnexpectedValueException;
|
||||
use User;
|
||||
use UserGroupMembership;
|
||||
use Wikimedia\Message\ITextFormatter;
|
||||
use Wikimedia\Message\MessageValue;
|
||||
use Xml;
|
||||
|
||||
/**
|
||||
|
|
@ -1041,20 +1037,14 @@ class DefaultPreferencesFactory implements PreferencesFactory {
|
|||
$tzDefault = $userTimeCorrectionObj->toString();
|
||||
}
|
||||
|
||||
$msgFormatter = MediaWikiServices::getInstance()->getMessageFormatterFactory()
|
||||
->getTextFormatter( $context->getLanguage()->getCode() );
|
||||
$tzOptions = $this->getTimezoneOptions( $msgFormatter );
|
||||
|
||||
$defaultPreferences['timecorrection'] = [
|
||||
'class' => \HTMLSelectOrOtherField::class,
|
||||
'class' => HTMLTimezoneField::class,
|
||||
'label-message' => 'timezonelegend',
|
||||
'options' => $tzOptions,
|
||||
'default' => $tzDefault,
|
||||
'size' => 20,
|
||||
'section' => 'rendering/timeoffset',
|
||||
'id' => 'wpTimeCorrection',
|
||||
'filter' => TimezoneFilter::class,
|
||||
'placeholder-message' => 'timezone-useoffset-placeholder',
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -1836,49 +1826,6 @@ class DefaultPreferencesFactory implements PreferencesFactory {
|
|||
return $htmlForm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ITextFormatter $msgFormatter
|
||||
* @return array
|
||||
*/
|
||||
protected function getTimezoneOptions( ITextFormatter $msgFormatter ) {
|
||||
$opt = [];
|
||||
|
||||
$localTZoffset = $this->options->get( MainConfigNames::LocalTZoffset );
|
||||
$timeZoneList = $this->getTimeZoneList( $msgFormatter );
|
||||
|
||||
$timestamp = MWTimestamp::getLocalInstance();
|
||||
// Check that the LocalTZoffset is the same as the local time zone offset
|
||||
if ( $localTZoffset === (int)$timestamp->format( 'Z' ) / 60 ) {
|
||||
$timezoneName = $timestamp->getTimezone()->getName();
|
||||
// Localize timezone
|
||||
if ( isset( $timeZoneList[$timezoneName] ) ) {
|
||||
$timezoneName = $timeZoneList[$timezoneName]['name'];
|
||||
}
|
||||
$server_tz_msg = $msgFormatter->format(
|
||||
MessageValue::new( 'timezoneuseserverdefault', [ $timezoneName ] )
|
||||
);
|
||||
} else {
|
||||
$tzstring = sprintf(
|
||||
'%+03d:%02d',
|
||||
floor( $localTZoffset / 60 ),
|
||||
abs( $localTZoffset ) % 60
|
||||
);
|
||||
$server_tz_msg = $msgFormatter->format( MessageValue::new( 'timezoneuseserverdefault', [ $tzstring ] ) );
|
||||
}
|
||||
$opt[$server_tz_msg] = "System|$localTZoffset";
|
||||
$opt[$msgFormatter->format( MessageValue::new( 'timezoneuseoffset' ) )] = 'other';
|
||||
$opt[$msgFormatter->format( MessageValue::new( 'guesstimezone' ) )] = 'guess';
|
||||
|
||||
foreach ( $timeZoneList as $timeZoneInfo ) {
|
||||
$region = $timeZoneInfo['region'];
|
||||
if ( !isset( $opt[$region] ) ) {
|
||||
$opt[$region] = [];
|
||||
}
|
||||
$opt[$region][$timeZoneInfo['name']] = $timeZoneInfo['timecorrection'];
|
||||
}
|
||||
return $opt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the form submission if everything validated properly
|
||||
*
|
||||
|
|
@ -2011,67 +1958,4 @@ class DefaultPreferencesFactory implements PreferencesFactory {
|
|||
|
||||
return ( $res === true ? Status::newGood() : $res );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of all time zones
|
||||
* @param ITextFormatter $msgFormatter
|
||||
* @return array[] A list of all time zones. The system name of the time zone is used as key and
|
||||
* the value is an array which contains localized name, the timecorrection value used for
|
||||
* preferences and the region
|
||||
* @since 1.26
|
||||
*/
|
||||
protected function getTimeZoneList( ITextFormatter $msgFormatter ) {
|
||||
$identifiers = DateTimeZone::listIdentifiers();
|
||||
// @phan-suppress-next-line PhanTypeComparisonFromArray See phan issue #3162
|
||||
if ( $identifiers === false ) {
|
||||
return [];
|
||||
}
|
||||
sort( $identifiers );
|
||||
|
||||
$tzRegions = [
|
||||
'Africa' => $msgFormatter->format( MessageValue::new( 'timezoneregion-africa' ) ),
|
||||
'America' => $msgFormatter->format( MessageValue::new( 'timezoneregion-america' ) ),
|
||||
'Antarctica' => $msgFormatter->format( MessageValue::new( 'timezoneregion-antarctica' ) ),
|
||||
'Arctic' => $msgFormatter->format( MessageValue::new( 'timezoneregion-arctic' ) ),
|
||||
'Asia' => $msgFormatter->format( MessageValue::new( 'timezoneregion-asia' ) ),
|
||||
'Atlantic' => $msgFormatter->format( MessageValue::new( 'timezoneregion-atlantic' ) ),
|
||||
'Australia' => $msgFormatter->format( MessageValue::new( 'timezoneregion-australia' ) ),
|
||||
'Europe' => $msgFormatter->format( MessageValue::new( 'timezoneregion-europe' ) ),
|
||||
'Indian' => $msgFormatter->format( MessageValue::new( 'timezoneregion-indian' ) ),
|
||||
'Pacific' => $msgFormatter->format( MessageValue::new( 'timezoneregion-pacific' ) ),
|
||||
];
|
||||
asort( $tzRegions );
|
||||
|
||||
$timeZoneList = [];
|
||||
|
||||
$now = new DateTime();
|
||||
|
||||
foreach ( $identifiers as $identifier ) {
|
||||
$parts = explode( '/', $identifier, 2 );
|
||||
|
||||
// DateTimeZone::listIdentifiers() returns a number of
|
||||
// backwards-compatibility entries. This filters them out of the
|
||||
// list presented to the user.
|
||||
if ( count( $parts ) !== 2 || !array_key_exists( $parts[0], $tzRegions ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Localize region
|
||||
$parts[0] = $tzRegions[$parts[0]];
|
||||
|
||||
$dateTimeZone = new DateTimeZone( $identifier );
|
||||
$minDiff = floor( $dateTimeZone->getOffset( $now ) / 60 );
|
||||
|
||||
$display = str_replace( '_', ' ', $parts[0] . '/' . $parts[1] );
|
||||
$value = "ZoneInfo|$minDiff|$identifier";
|
||||
|
||||
$timeZoneList[$identifier] = [
|
||||
'name' => $display,
|
||||
'timecorrection' => $value,
|
||||
'region' => $parts[0],
|
||||
];
|
||||
}
|
||||
|
||||
return $timeZoneList;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1358,21 +1358,21 @@
|
|||
"savedrights": "This message appears after saving the user groups on [[Special:UserRights]].\n* $1 - The username of the user which groups was saved.",
|
||||
"timezonelegend": "{{Identical|Time zone}}",
|
||||
"localtime": "Used as label in [[Special:Preferences#mw-prefsection-datetime|preferences]].",
|
||||
"timezoneuseserverdefault": "[[Special:Preferences]] > Date and time > Time zone\n\nThis option lets your time zone setting use the one that is used on the wiki (often UTC).\n\nParameters:\n* $1 - timezone name, or timezone offset (in \"%+03d:%02d\" format)",
|
||||
"timezoneuseoffset": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.",
|
||||
"timezone-useoffset-placeholder": "Used in \"Time zone\" text input field as placeholder in [[Special:Preferences#mw-prefsection-datetime|preferences]]",
|
||||
"timezoneuseserverdefault": "Option in timezone selector form fields.\n\nThis option lets your time zone setting use the one that is used on the wiki (often UTC).\n\nParameters:\n* $1 - timezone name, or timezone offset (in \"%+03d:%02d\" format)",
|
||||
"timezoneuseoffset": "Option in timezone selector form fields that lets the user manually enter an offset from UTC.",
|
||||
"timezone-useoffset-placeholder": "Placeholder of the text input in timezone selector form fields.",
|
||||
"servertime": "Used as label in [[Special:Preferences#mw-prefsection-datetime|preferences]].",
|
||||
"guesstimezone": "Option to fill in the timezone from the browser setting",
|
||||
"timezoneregion-africa": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-america": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-antarctica": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-arctic": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-asia": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-atlantic": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-australia": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}\n{{Identical|Australia}}",
|
||||
"timezoneregion-europe": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-indian": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-pacific": "Used in \"Time zone\" listbox in [[Special:Preferences#mw-prefsection-datetime|preferences]], \"date and time\" tab.\n{{Related|Timezoneregion}}",
|
||||
"guesstimezone": "Option in timezone selector form fields to fill in the timezone from the browser setting",
|
||||
"timezoneregion-africa": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-america": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-antarctica": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-arctic": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-asia": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-atlantic": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-australia": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}\n{{Identical|Australia}}",
|
||||
"timezoneregion-europe": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-indian": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"timezoneregion-pacific": "Used in timezone selector form fields.\n{{Related|Timezoneregion}}",
|
||||
"allowemail": "Used in [[Special:Preferences]] > {{int:prefs-personal}} > {{int:email}}.",
|
||||
"email-allow-new-users-label": "Used in [[Special:Preferences]] > {{int:prefs-prohibit}} > {{int:email}}.",
|
||||
"email-mutelist-label": "Used in [[Special:Preferences]] > {{int:prefs-prohibit}} > {{int:email}}.",
|
||||
|
|
|
|||
|
|
@ -910,6 +910,7 @@ return [
|
|||
'resources/src/mediawiki.htmlform/multiselect.js',
|
||||
'resources/src/mediawiki.htmlform/selectandother.js',
|
||||
'resources/src/mediawiki.htmlform/selectorother.js',
|
||||
'resources/src/mediawiki.htmlform/timezone.js',
|
||||
],
|
||||
'dependencies' => [
|
||||
'mediawiki.util',
|
||||
|
|
|
|||
56
resources/src/mediawiki.htmlform/timezone.js
Normal file
56
resources/src/mediawiki.htmlform/timezone.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* HTMLForm enhancements:
|
||||
* Enable the "Fill in from browser" option for the timezone selector
|
||||
*/
|
||||
( function () {
|
||||
function minutesToHours( min ) {
|
||||
var tzHour = Math.floor( Math.abs( min ) / 60 ),
|
||||
tzMin = Math.abs( min ) % 60,
|
||||
tzString = ( ( min >= 0 ) ? '' : '-' ) + ( ( tzHour < 10 ) ? '0' : '' ) + tzHour +
|
||||
':' + ( ( tzMin < 10 ) ? '0' : '' ) + tzMin;
|
||||
return tzString;
|
||||
}
|
||||
|
||||
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
|
||||
mw.loader.using( 'mediawiki.widgets.SelectWithInputWidget', function () {
|
||||
$root.find( '.mw-htmlform-timezone-field' ).each( function () {
|
||||
// This is identical to OO.ui.infuse( ... ), but it makes the class name of the result known.
|
||||
var timezoneWidget = mw.widgets.SelectWithInputWidget.static.infuse( $( this ) );
|
||||
|
||||
function maybeGuessTimezone() {
|
||||
if ( timezoneWidget.dropdowninput.getValue() !== 'guess' ) {
|
||||
return;
|
||||
}
|
||||
// If available, get the named time zone from the browser.
|
||||
// (We also support older browsers where this API is not available.)
|
||||
var timeZone;
|
||||
try {
|
||||
// This may return undefined
|
||||
// eslint-disable-next-line compat/compat
|
||||
timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
} catch ( err ) {
|
||||
timeZone = null;
|
||||
}
|
||||
|
||||
// Get the time offset
|
||||
var minuteDiff = -( new Date().getTimezoneOffset() );
|
||||
|
||||
var newValue;
|
||||
if ( timeZone ) {
|
||||
// Try to save both time zone and offset
|
||||
newValue = 'ZoneInfo|' + minuteDiff + '|' + timeZone;
|
||||
timezoneWidget.dropdowninput.setValue( newValue );
|
||||
}
|
||||
if ( !timeZone || timezoneWidget.dropdowninput.getValue() !== newValue ) {
|
||||
// No time zone, or it's unknown to MediaWiki. Save only offset
|
||||
timezoneWidget.dropdowninput.setValue( 'other' );
|
||||
timezoneWidget.textinput.setValue( minutesToHours( minuteDiff ) );
|
||||
}
|
||||
}
|
||||
|
||||
timezoneWidget.dropdowninput.on( 'change', maybeGuessTimezone );
|
||||
maybeGuessTimezone();
|
||||
} );
|
||||
} );
|
||||
} );
|
||||
}() );
|
||||
|
|
@ -13,9 +13,6 @@
|
|||
return;
|
||||
}
|
||||
|
||||
// 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.
|
||||
var timezoneWidget = mw.widgets.SelectWithInputWidget.static.infuse( $target );
|
||||
|
||||
|
|
@ -65,31 +62,8 @@
|
|||
} else {
|
||||
// Time zone not manually specified by user
|
||||
if ( type === 'guess' ) {
|
||||
// If available, get the named time zone from the browser.
|
||||
// (We also support older browsers where this API is not available.)
|
||||
var timeZone;
|
||||
try {
|
||||
// This may return undefined
|
||||
timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
} catch ( err ) {
|
||||
timeZone = null;
|
||||
}
|
||||
|
||||
// Get the time offset
|
||||
minuteDiff = -( new Date().getTimezoneOffset() );
|
||||
|
||||
var newValue;
|
||||
if ( timeZone ) {
|
||||
// Try to save both time zone and offset
|
||||
newValue = 'ZoneInfo|' + minuteDiff + '|' + timeZone;
|
||||
timezoneWidget.dropdowninput.setValue( newValue );
|
||||
}
|
||||
if ( !timeZone || timezoneWidget.dropdowninput.getValue() !== newValue ) {
|
||||
// No time zone, or it's unknown to MediaWiki. Save only offset
|
||||
timezoneWidget.dropdowninput.setValue( 'other' );
|
||||
timezoneWidget.textinput.setValue( minutesToHours( minuteDiff ) );
|
||||
}
|
||||
|
||||
} else {
|
||||
// Grab data from the dropdown value
|
||||
minuteDiff = parseInt( type.split( '|' )[ 1 ], 10 ) || 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue