/*! * VisualEditor user interface MWParameterPage class. * * @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt * @license The MIT License (MIT); see LICENSE.txt */ /** * MediaWiki transclusion dialog template page. * * @class * @extends OO.ui.PageLayout * * @constructor * @param {ve.dm.MWParameterModel} parameter Template parameter * @param {string} name Unique symbolic name of page * @param {Object} [config] Configuration options * @cfg {jQuery} [$overlay] Overlay to render dropdowns in * @cfg {boolean} [readOnly] Parameter is read-only */ ve.ui.MWParameterPage = function VeUiMWParameterPage( parameter, name, config ) { var paramName = parameter.getName(), veConfig = mw.config.get( 'wgVisualEditorConfig' ); // Configuration initialization config = ve.extendObject( { scrollable: false }, config ); // Parent constructor ve.ui.MWParameterPage.super.call( this, name, config ); // Properties this.edited = false; this.parameter = parameter; this.originalValue = parameter.getValue(); this.spec = parameter.getTemplate().getSpec(); this.defaultValue = parameter.getDefaultValue(); this.exampleValue = parameter.getExampleValue(); this.$info = $( '
' ) .text( this.spec.getParameterDescription( paramName ) || '' ) ); // Note: Calling createValueInput() sets some properties we rely on later in this function this.valueInput = this.createValueInput() .setValue( this.parameter.getValue() ) .connect( this, { change: 'onValueInputChange' } ); this.valueInput.$input.attr( 'aria-describedby', $doc.attr( 'id' ) ); if ( config.readOnly && this.valueInput.setReadOnly ) { this.valueInput.setReadOnly( true ); } var labelElement = new OO.ui.LabelWidget( { input: this.valueInput, label: this.spec.getParameterLabel( paramName ), classes: [ 've-ui-mwParameterPage-label' ] } ); var statusIndicator; if ( this.parameter.isRequired() ) { if ( !this.useNewSidebar ) { statusIndicator = new OO.ui.IndicatorWidget( { classes: [ 've-ui-mwParameterPage-statusIndicator' ], indicator: 'required', title: ve.msg( 'visualeditor-dialog-transclusion-required-parameter' ) } ); } $doc.append( $( '
' ) .addClass( 've-ui-mwParameterPage-doc-required' ) .text( ve.msg( 'visualeditor-dialog-transclusion-required-parameter-description' ) ) ); } else if ( this.parameter.isDeprecated() ) { statusIndicator = new OO.ui.IndicatorWidget( { classes: [ 've-ui-mwParameterPage-statusIndicator' ], indicator: 'alert', title: ve.msg( 'visualeditor-dialog-transclusion-deprecated-parameter' ) } ); $doc.append( $( '
' ) .addClass( 've-ui-mwParameterPage-doc-deprecated' ) .text( ve.msg( 'visualeditor-dialog-transclusion-deprecated-parameter-description', this.spec.getParameterDeprecationDescription( paramName ) ) ) ); } if ( this.defaultValue ) { $doc.append( $( '
' ) .addClass( 've-ui-mwParameterPage-doc-default' ) .text( ve.msg( 'visualeditor-dialog-transclusion-param-default', this.defaultValue ) ) ); } if ( this.exampleValue ) { $doc.append( $( '
' )
.addClass( 've-ui-mwParameterPage-doc-example' )
.text(
ve.msg(
this.useInlineDescriptions ?
'visualeditor-dialog-transclusion-param-example-long' :
'visualeditor-dialog-transclusion-param-example',
this.exampleValue
)
)
);
}
// Construct the action buttons
if ( !this.rawValueInput && !this.useNewSidebar ) {
this.rawFallbackButton = new OO.ui.ButtonWidget( {
framed: false,
icon: 'wikiText',
title: ve.msg( 'visualeditor-dialog-transclusion-raw-fallback' )
} )
.connect( this, { click: 'onRawFallbackButtonClick' } );
this.$actions.append( this.rawFallbackButton.$element );
}
if ( !this.useInlineDescriptions ) {
if ( $doc.text().trim() === '' ) {
this.infoButton = new OO.ui.ButtonWidget( {
disabled: true,
title: ve.msg( 'visualeditor-dialog-transclusion-param-info-missing' ),
framed: false,
icon: 'info',
classes: [ 've-ui-mwParameterPage-infoButton' ]
} );
} else {
this.infoButton = new OO.ui.PopupButtonWidget( {
$overlay: config.$overlay,
popup: {
$content: $doc
},
title: ve.msg( 'visualeditor-dialog-transclusion-param-info' ),
framed: false,
icon: 'info',
classes: [ 've-ui-mwParameterPage-infoButton' ]
} );
}
this.$actions.append( this.infoButton.$element );
}
if ( !this.parameter.isRequired() && !config.readOnly && !this.useNewSidebar ) {
var removeButton = new OO.ui.ButtonWidget( {
framed: false,
icon: 'trash',
title: ve.msg( 'visualeditor-dialog-transclusion-remove-param' ),
flags: [ 'destructive' ],
classes: [ 've-ui-mwParameterPage-removeButton' ]
} )
.connect( this, { click: 'onRemoveButtonClick' } );
this.$actions.append( removeButton.$element );
}
// Initialization
this.$info
.addClass( 've-ui-mwParameterPage-info' )
.append( labelElement.$element );
if ( statusIndicator ) {
this.$info.append( ' ', statusIndicator.$element );
}
this.$actions
.addClass( 've-ui-mwParameterPage-actions' );
this.$field
.addClass( 've-ui-mwParameterPage-field' )
.append(
this.valueInput.$element
);
if ( this.useNewSidebar && !this.parameter.isDocumented() ) {
$( '' )
.addClass( 've-ui-mwParameterPage-undocumentedLabel' )
.text( ve.msg( 'visualeditor-dialog-transclusion-param-undocumented' ) )
.insertAfter( labelElement.$element );
}
if ( this.useSuggestedValues && this.parameter.getSuggestedValues().length ) {
this.warningMessage = new OO.ui.MessageWidget( {
inline: true,
classes: [ 've-ui-mwParameterPage-warning' ]
} ).toggle( false );
this.$field.append( this.warningMessage.$element );
}
this.$element
.addClass( 've-ui-mwParameterPage' )
.append( this.$info, this.$field, this.$actions );
if ( this.useInlineDescriptions ) {
this.$field.addClass( 've-ui-mwParameterPage-inlineDescription' );
this.collapsibleDoc = new ve.ui.MWExpandableContentElement( {
classes: [ 've-ui-mwParameterPage-inlineDescription' ],
$content: $doc
} );
this.$info.after( this.collapsibleDoc.$element );
}
// FIXME this and the addPlaceholderParameter can be remove when the feature flag is gone
if ( !config.readOnly && !this.useNewSidebar ) {
// This button is only shown when this …ParameterPage is neither followed by another
// …TemplatePage (i.e. it's the last template in the transclusion) nor a
// …ParameterPlaceholderPage (i.e. the parameter search widget isn't shown). This state
// should be unreachable, but isn't. Hiding this is done via CSS.
var addButton = new OO.ui.ButtonWidget( {
framed: false,
icon: 'parameter',
label: this.useNewSidebar ?
ve.msg( 'visualeditor-dialog-transclusion-add-undocumented-param' ) :
ve.msg( 'visualeditor-dialog-transclusion-add-param' )
} )
.connect( this, { click: 'addPlaceholderParameter' } );
$( '