* Defaults to the current date and time (with 0 milliseconds).
*/
mw.widgets.datetime.DateTimeFormatter = function MwWidgetsDatetimeDateTimeFormatter( config ) {
- var statick = this.constructor[ 'static' ];
-
- statick.setupDefaults();
+ this.constructor.static.setupDefaults();
config = $.extend( {
format: '@default',
local: false,
- fullZones: statick.fullZones,
- shortZones: statick.shortZones
+ fullZones: this.constructor.static.fullZones,
+ shortZones: this.constructor.static.shortZones
}, config );
// Mixin constructors
OO.EventEmitter.call( this );
// Properties
- if ( statick.formats[ config.format ] ) {
- this.format = statick.formats[ config.format ];
+ if ( this.constructor.static.formats[ config.format ] ) {
+ this.format = this.constructor.static.formats[ config.format ];
} else {
this.format = config.format;
}
* @inheritable
* @property {Object}
*/
- mw.widgets.datetime.DateTimeFormatter[ 'static' ].formats = {};
+ mw.widgets.datetime.DateTimeFormatter.static.formats = {};
/**
* Default time zone indicators
* @inheritable
* @property {string[]}
*/
- mw.widgets.datetime.DateTimeFormatter[ 'static' ].fullZones = null;
+ mw.widgets.datetime.DateTimeFormatter.static.fullZones = null;
/**
* Default abbreviated time zone indicators
* @inheritable
* @property {string[]}
*/
- mw.widgets.datetime.DateTimeFormatter[ 'static' ].shortZones = null;
+ mw.widgets.datetime.DateTimeFormatter.static.shortZones = null;
- mw.widgets.datetime.DateTimeFormatter[ 'static' ].setupDefaults = function () {
+ mw.widgets.datetime.DateTimeFormatter.static.setupDefaults = function () {
if ( !this.fullZones ) {
this.fullZones = [
mw.msg( 'timezone-utc' ),
return this.local;
};
+ // eslint-disable-next-line valid-jsdoc
/**
* Toggle whether dates are in local time or UTC
*
* - 'boolean': The field is a boolean.
* - 'toggleLocal': The field represents {@link #getLocal this.getLocal()}.
* Editing should directly call {@link #toggleLocal this.toggleLocal()}.
+ * @return {boolean} return.calendarComponent Whether this field is part of a calendar, e.g.
+ * part of the date instead of the time.
* @return {number} return.size Maximum number of characters in the field (when
* the 'intercalary' component is falsey). If 0, the field should be hidden entirely.
* @return {Object.<string,number>} return.intercalarySize Map from
}
spec = {
component: null,
+ calendarComponent: false,
editable: false,
type: 'static',
value: params.slice( 1 ).join( '|' ),
c = params[ 0 ] === '#' ? '' : ':';
return {
component: 'zone',
+ calendarComponent: false,
editable: true,
type: 'toggleLocal',
size: 5 + c.length,
case 'full':
spec = {
component: 'zone',
+ calendarComponent: false,
editable: true,
type: 'toggleLocal',
values: params[ 0 ] === 'short' ? this.shortZones : this.fullZones,
* - 'clip': "Jan 32" => "Jan 31", "Feb 32" => "Feb 28" (or 29), "Feb 0" => "Feb 1", etc.
* @return {Date} Adjusted date
*/
- mw.widgets.datetime.DateTimeFormatter.prototype.adjustComponent = function ( date /*, component, delta, mode */ ) {
+ mw.widgets.datetime.DateTimeFormatter.prototype.adjustComponent = function ( date /* , component, delta, mode */ ) {
// Should be overridden by subclass
return date;
};
calendar: {}
}, config );
+ // See InputWidget#reusePreInfuseDOM about config.$input
+ if ( config.$input ) {
+ config.$input.addClass( 'oo-ui-element-hidden' );
+ }
+
if ( $.isPlainObject( config.formatter ) && config.formatter.format === undefined ) {
config.formatter.format = '@' + config.type;
}
/* Static properties */
- mw.widgets.datetime.DateTimeInputWidget[ 'static' ].supportsSimpleLabel = false;
+ mw.widgets.datetime.DateTimeInputWidget.static.supportsSimpleLabel = false;
/* Events */
$field = $( '<span>' )
.width( sz )
.data( 'mw-widgets-datetime-dateTimeInputWidget-placeholder', placeholder );
+ if ( spec.type !== 'static' ) {
+ $field.prop( 'tabIndex', -1 );
+ $field.on( 'focus', this.onFieldFocus.bind( this, $field ) );
+ }
if ( spec.type === 'static' ) {
$field.text( spec.value );
} else {
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Key down event
+ * @return {boolean} False to cancel the default event
*/
mw.widgets.datetime.DateTimeInputWidget.prototype.onFieldKeyDown = function ( $field, e ) {
var spec = $field.data( 'mw-widgets-datetime-dateTimeInputWidget-fieldSpec' );
* @param {jQuery.Event} e Focus event
*/
mw.widgets.datetime.DateTimeInputWidget.prototype.onFieldFocus = function ( $field ) {
+ var spec = $field.data( 'mw-widgets-datetime-dateTimeInputWidget-fieldSpec' );
+
if ( !this.isDisabled() ) {
if ( this.getValueAsDate() === null ) {
this.setValue( this.formatter.getDefaultDate() );
}
if ( this.calendar ) {
- this.calendar.toggle( true );
+ this.calendar.toggle( !!spec.calendarComponent );
}
}
};
* @private
* @param {jQuery} $field
* @param {jQuery.Event} e Change event
+ * @return {boolean} False to cancel the default event
*/
mw.widgets.datetime.DateTimeInputWidget.prototype.onFieldWheel = function ( $field, e ) {
var delta = 0,
/**
* @inheritdoc
*/
- mw.widgets.datetime.DiscordianDateTimeFormatter[ 'static' ].formats = {
+ mw.widgets.datetime.DiscordianDateTimeFormatter.static.formats = {
'@time': '${hour|0}:${minute|0}:${second|0}',
'@date': '$!{dow|full}${not-intercalary|1|, }${season|full}${not-intercalary|1| }${day|#}, ${year|#}',
'@datetime': '$!{dow|full}${not-intercalary|1|, }${season|full}${not-intercalary|1| }${day|#}, ${year|#} ${hour|0}:${minute|0}:${second|0} $!{zone|short}',
case 'year|#':
spec = {
component: 'Year',
+ calendarComponent: true,
type: 'number',
size: 4,
zeropad: false
case 'season|#':
spec = {
component: 'Season',
+ calendarComponent: true,
type: 'number',
size: 1,
intercalarySize: { 1: 0 },
case 'season|full':
spec = {
component: 'Season',
+ calendarComponent: true,
type: 'string',
intercalarySize: { 1: 0 },
values: {
case 'dow|full':
spec = {
component: 'DOW',
+ calendarComponent: true,
editable: false,
type: 'string',
intercalarySize: { 1: 0 },
case 'day|0':
spec = {
component: 'Day',
+ calendarComponent: true,
type: 'string',
size: 2,
intercalarySize: { 1: 13 },
case 'second|0':
spec = {
component: tag.charAt( 0 ).toUpperCase() + tag.slice( 1 ),
+ calendarComponent: false,
type: 'number',
size: 2,
zeropad: params[ 0 ] === '0'
case 'millisecond|0':
spec = {
component: 'Millisecond',
+ calendarComponent: false,
type: 'number',
size: 3,
zeropad: params[ 0 ] === '0'
/**
* Provides various methods needed for formatting dates and times. This
- * implementation implments the proleptic Gregorian calendar over years
+ * implementation implements the proleptic Gregorian calendar over years
* 0000–9999.
*
* @class
* @cfg {number} [weekStartsOn=0] What day the week starts on: 0 is Sunday, 1 is Monday, 6 is Saturday.
*/
mw.widgets.datetime.ProlepticGregorianDateTimeFormatter = function MwWidgetsDatetimeProlepticGregorianDateTimeFormatter( config ) {
- var statick = this.constructor[ 'static' ];
-
- statick.setupDefaults();
+ this.constructor.static.setupDefaults();
config = $.extend( {
weekStartsOn: 0,
- hour12Periods: statick.hour12Periods
+ hour12Periods: this.constructor.static.hour12Periods
}, config );
if ( config.fullMonthNames && !config.shortMonthNames ) {
}.bind( this ) );
}
config = $.extend( {
- fullMonthNames: statick.fullMonthNames,
- shortMonthNames: statick.shortMonthNames,
- fullDayNames: statick.fullDayNames,
- shortDayNames: statick.shortDayNames,
- dayLetters: statick.dayLetters
+ fullMonthNames: this.constructor.static.fullMonthNames,
+ shortMonthNames: this.constructor.static.shortMonthNames,
+ fullDayNames: this.constructor.static.fullDayNames,
+ shortDayNames: this.constructor.static.shortDayNames,
+ dayLetters: this.constructor.static.dayLetters
}, config );
// Parent constructor
/**
* @inheritdoc
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].formats = {
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.formats = {
'@time': '${hour|0}:${minute|0}:${second|0}',
'@date': '$!{dow|short} ${day|#} ${month|short} ${year|#}',
'@datetime': '$!{dow|short} ${day|#} ${month|short} ${year|#} ${hour|0}:${minute|0}:${second|0} $!{zone|short}',
* @inheritable
* @property {Object}
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].fullMonthNames = null;
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.fullMonthNames = null;
/**
* Default abbreviated month names.
* @inheritable
* @property {Object}
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].shortMonthNames = null;
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.shortMonthNames = null;
/**
* Default full day of week names.
* @inheritable
* @property {Object}
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].fullDayNames = null;
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.fullDayNames = null;
/**
* Default abbreviated day of week names.
* @inheritable
* @property {Object}
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].shortDayNames = null;
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.shortDayNames = null;
/**
* Default day letters.
* @inheritable
* @property {string[]}
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].dayLetters = null;
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.dayLetters = null;
/**
* Default AM/PM indicators
* @inheritable
* @property {string[]}
*/
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].hour12Periods = null;
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.hour12Periods = null;
- mw.widgets.datetime.ProlepticGregorianDateTimeFormatter[ 'static' ].setupDefaults = function () {
- mw.widgets.datetime.DateTimeFormatter[ 'static' ].setupDefaults.call( this );
+ mw.widgets.datetime.ProlepticGregorianDateTimeFormatter.static.setupDefaults = function () {
+ mw.widgets.datetime.DateTimeFormatter.static.setupDefaults.call( this );
if ( this.fullMonthNames && !this.shortMonthNames ) {
this.shortMonthNames = {};
case 'year|0':
spec = {
component: 'year',
+ calendarComponent: true,
type: 'number',
size: 4,
zeropad: params[ 0 ] === '0'
case 'month|full':
spec = {
component: 'month',
+ calendarComponent: true,
type: 'string',
values: params[ 0 ] === 'short' ? this.shortMonthNames : this.fullMonthNames
};
case 'dow|full':
spec = {
component: 'dow',
+ calendarComponent: true,
editable: false,
type: 'string',
values: params[ 0 ] === 'short' ? this.shortDayNames : this.fullDayNames
case 'month|0':
case 'day|#':
case 'day|0':
+ spec = {
+ component: tag,
+ calendarComponent: true,
+ type: 'number',
+ size: 2,
+ zeropad: params[ 0 ] === '0'
+ };
+ break;
+
case 'hour|#':
case 'hour|0':
case 'minute|#':
case 'second|0':
spec = {
component: tag,
+ calendarComponent: false,
type: 'number',
size: 2,
zeropad: params[ 0 ] === '0'
case 'hour|012':
spec = {
component: 'hour12',
+ calendarComponent: false,
type: 'number',
size: 2,
zeropad: params[ 0 ] === '012'
case 'hour|period':
spec = {
component: 'hour12period',
+ calendarComponent: false,
type: 'boolean',
values: this.hour12Periods
};
case 'millisecond|0':
spec = {
component: 'millisecond',
+ calendarComponent: false,
type: 'number',
size: 3,
zeropad: params[ 0 ] === '0'