summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/UploadWizard/resources/details/uw.DateDetailsWidget.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/UploadWizard/resources/details/uw.DateDetailsWidget.js')
-rw-r--r--www/wiki/extensions/UploadWizard/resources/details/uw.DateDetailsWidget.js214
1 files changed, 214 insertions, 0 deletions
diff --git a/www/wiki/extensions/UploadWizard/resources/details/uw.DateDetailsWidget.js b/www/wiki/extensions/UploadWizard/resources/details/uw.DateDetailsWidget.js
new file mode 100644
index 00000000..077fb517
--- /dev/null
+++ b/www/wiki/extensions/UploadWizard/resources/details/uw.DateDetailsWidget.js
@@ -0,0 +1,214 @@
+( function ( mw, uw, $, OO ) {
+
+ /**
+ * A date field in UploadWizard's "Details" step form.
+ *
+ * @extends uw.DetailsWidget
+ * @constructor
+ * @param {Object} config Configuration options
+ * @cfg {mw.UploadWizardUpload} upload
+ */
+ uw.DateDetailsWidget = function UWDateDetailsWidget( config ) {
+ uw.DateDetailsWidget.parent.call( this );
+
+ this.upload = config.upload;
+ this.dateInputWidgetMode = null; // or: 'calendar', 'arbitrary'
+ this.dateInputWidgetToggler = new OO.ui.ButtonSelectWidget( {
+ classes: [ 'mwe-upwiz-dateDetailsWidget-toggler' ],
+ items: [
+ new OO.ui.ButtonOptionWidget( {
+ data: 'calendar',
+ icon: 'calendar',
+ title: mw.msg( 'mwe-upwiz-calendar-date' )
+ } ),
+ new OO.ui.ButtonOptionWidget( {
+ data: 'arbitrary',
+ icon: 'edit',
+ title: mw.msg( 'mwe-upwiz-custom-date' )
+ } )
+ ]
+ } )
+ .selectItemByData( 'calendar' )
+ .on( 'choose', function ( selectedItem ) {
+ this.setupDateInput( selectedItem.getData() );
+ this.dateInputWidget.focus();
+ }.bind( this ) );
+
+ this.$element.addClass( 'mwe-upwiz-dateDetailsWidget' );
+ this.$element.append(
+ this.dateInputWidgetToggler.$element
+ // this.dateInputWidget.$element goes here after setupDateInput() runs
+ );
+ this.setupDateInput();
+ };
+ OO.inheritClass( uw.DateDetailsWidget, uw.DetailsWidget );
+
+ /**
+ * Set up the date input field, or switch between 'calendar' and 'arbitrary' mode.
+ *
+ * @param {string} [mode] Mode to switch to, 'calendar' or 'arbitrary'
+ * @private
+ */
+ uw.DateDetailsWidget.prototype.setupDateInput = function ( mode ) {
+ var
+ oldDateInputWidget = this.dateInputWidget;
+
+ if ( mode === undefined ) {
+ mode = this.dateInputWidgetMode === 'calendar' ? 'arbitrary' : 'calendar';
+ }
+ this.dateInputWidgetMode = mode;
+ this.dateInputWidgetToggler.selectItemByData( mode );
+
+ if ( mode === 'arbitrary' ) {
+ this.dateInputWidget = new OO.ui.TextInputWidget( {
+ classes: [ 'mwe-date', 'mwe-upwiz-dateDetailsWidget-date' ],
+ placeholder: mw.msg( 'mwe-upwiz-select-date' )
+ } );
+ } else {
+ this.dateInputWidget = new mw.widgets.DateInputWidget( {
+ classes: [ 'mwe-date', 'mwe-upwiz-dateDetailsWidget-date' ],
+ placeholderLabel: mw.msg( 'mwe-upwiz-select-date' )
+ } );
+ // If the user types '{{', assume that they are trying to input template wikitext and switch
+ // to 'arbitrary' mode. This might help confused power-users (T110026#1567714).
+ this.dateInputWidget.textInput.on( 'change', function ( value ) {
+ if ( value === '{{' ) {
+ this.setupDateInput( 'arbitrary' );
+ this.dateInputWidget.setValue( '{{' );
+ this.dateInputWidget.moveCursorToEnd();
+ }
+ }.bind( this ) );
+ }
+
+ if ( oldDateInputWidget ) {
+ this.dateInputWidget.setValue( oldDateInputWidget.getValue() );
+ oldDateInputWidget.$element.replaceWith( this.dateInputWidget.$element );
+ } else {
+ this.dateInputWidgetToggler.$element.after( this.dateInputWidget.$element );
+ }
+
+ // Aggregate 'change' event
+ this.dateInputWidget.connect( this, { change: [ 'emit', 'change' ] } );
+
+ // Also emit if the value was changed to fit the new widget
+ if ( oldDateInputWidget && oldDateInputWidget.getValue() !== this.dateInputWidget.getValue() ) {
+ this.emit( 'change' );
+ }
+ };
+
+ /**
+ * Gets the selected license(s). The returned value will be a license
+ * key => license props map, as defined in UploadWizard.config.php.
+ *
+ * @return {Object}
+ */
+ uw.DateDetailsWidget.prototype.getLicenses = function () {
+ if ( this.upload.deedChooser && this.upload.deedChooser.deed && this.upload.deedChooser.deed.licenseInput ) {
+ return this.upload.deedChooser.deed.licenseInput.getLicenses();
+ }
+
+ // no license has been selected yet
+ // this could happen when uploading multiple files and selecting to
+ // provide copyright information for each file individually
+ return {};
+ };
+
+ /**
+ * @inheritdoc
+ */
+ uw.DateDetailsWidget.prototype.getWarnings = function () {
+ var i,
+ license,
+ licenseMsg,
+ warnings = [],
+ dateVal = Date.parse( this.dateInputWidget.getValue().trim() ),
+ licenses = this.getLicenses(),
+ // licenses that likely mean the image date is some time in the past
+ warnLicenses = [ 'pd-usgov', 'pd-usgov-nasa', 'pd-art' ],
+ now = new Date(),
+ date = new Date( this.dateInputWidget.getValue() );
+
+ // We don't really know what timezone this datetime is in. It could be the user's timezone, or
+ // it could be the camera's timezone for data imported from EXIF, and we don't know what
+ // timezone that is. UTC+14 is the highest timezone that currently exists, so assume that to
+ // avoid giving false warnings.
+ if ( this.dateInputWidgetMode === 'calendar' &&
+ dateVal > now.getTime() + 14 * 60 * 60 ) {
+ warnings.push( mw.message( 'mwe-upwiz-warning-postdate' ) );
+ }
+
+ // doublecheck that we've actually selected a valid date
+ if ( !isNaN( date.getTime() ) ) {
+ // it's unlikely for public domain images to have been published today
+ if ( now.toISOString().slice( 0, 10 ) === date.toISOString().slice( 0, 10 ) ) {
+ for ( i in warnLicenses ) {
+ if ( warnLicenses[ i ] in licenses ) {
+ license = licenses[ warnLicenses[ i ] ];
+ licenseMsg = mw.message( license.msg, 0, license.url ? license.url : '#missing license URL' );
+ warnings.push( mw.message( 'mwe-upwiz-error-date-license-unlikely', licenseMsg.parse() ) );
+ }
+ }
+ }
+ }
+
+ return $.Deferred().resolve( warnings ).promise();
+ };
+
+ /**
+ * @inheritdoc
+ */
+ uw.DateDetailsWidget.prototype.getErrors = function () {
+ var errors = [],
+ licenses = this.getLicenses(),
+ now = new Date(),
+ old = new Date( now.getFullYear() - 70, now.getMonth(), now.getDate() ),
+ old100 = new Date( now.getFullYear() - 100, now.getMonth(), now.getDate() ),
+ date = new Date( this.dateInputWidget.getValue() );
+
+ if ( this.dateInputWidget.getValue().trim() === '' ) {
+ errors.push( mw.message( 'mwe-upwiz-error-blank' ) );
+ } else if ( 'pd-us' in licenses && date.getFullYear() >= 1923 ) {
+ // if the license stated the work is public domain, it must've been
+ // created a really long time ago
+ errors.push( mw.message( 'mwe-upwiz-error-date-license-mismatch', mw.message( licenses[ 'pd-us' ].msg ).parse() ) );
+ } else if ( 'pd-old' in licenses && date > old ) {
+ // if the author died 70 years ago, the timestamp should reflect that
+ errors.push( mw.message( 'mwe-upwiz-error-date-license-mismatch', mw.message( licenses[ 'pd-old' ].msg ).parse() ) );
+ } else if ( 'pd-old-100' in licenses && date > old100 ) {
+ // if the author died 100 years ago, the timestamp should reflect that
+ errors.push( mw.message( 'mwe-upwiz-error-date-license-mismatch', mw.message( licenses[ 'pd-old-100' ].msg ).parse() ) );
+ }
+
+ return $.Deferred().resolve( errors ).promise();
+ };
+
+ /**
+ * @inheritdoc
+ */
+ uw.DateDetailsWidget.prototype.getWikiText = function () {
+ return this.dateInputWidget.getValue().trim();
+ };
+
+ /**
+ * @inheritdoc
+ * @return {Object} See #setSerialized
+ */
+ uw.DateDetailsWidget.prototype.getSerialized = function () {
+ return {
+ mode: this.dateInputWidgetMode,
+ value: this.dateInputWidget.getValue()
+ };
+ };
+
+ /**
+ * @inheritdoc
+ * @param {Object} serialized
+ * @param {string} serialized.mode Date input mode ('calendar' or 'arbitrary')
+ * @param {string} serialized.value Date value for given mode
+ */
+ uw.DateDetailsWidget.prototype.setSerialized = function ( serialized ) {
+ this.setupDateInput( serialized.mode );
+ this.dateInputWidget.setValue( serialized.value );
+ };
+
+}( mediaWiki, mediaWiki.uploadWizard, jQuery, OO ) );