2021-07-09 13:48:08 +00:00
|
|
|
/**
|
|
|
|
* Common base class for top-level items (a.k.a. "parts") in the template editor sidebar. Subclasses
|
|
|
|
* should exist for all subclasses of {@see ve.dm.MWTransclusionPartModel}:
|
|
|
|
* - {@see ve.dm.MWTemplateModel}
|
|
|
|
* - {@see ve.dm.MWTemplatePlaceholderModel}
|
|
|
|
* - {@see ve.dm.MWTransclusionContentModel}
|
|
|
|
*
|
2021-07-09 14:47:01 +00:00
|
|
|
* This is inspired by and meant to replace {@see OO.ui.DecoratedOptionWidget} in the context of the
|
|
|
|
* template dialog. Also see {@see OO.ui.ButtonWidget} for inspiration.
|
|
|
|
*
|
2021-07-09 13:48:08 +00:00
|
|
|
* @abstract
|
|
|
|
* @class
|
|
|
|
* @extends OO.ui.Widget
|
|
|
|
*
|
|
|
|
* @constructor
|
2021-07-13 07:27:22 +00:00
|
|
|
* @param {ve.dm.MWTransclusionPartModel} part
|
2021-07-13 09:00:57 +00:00
|
|
|
* @param {Object} config
|
2021-09-11 08:05:31 +00:00
|
|
|
* @cfg {string} [icon=''] Symbolic name of an icon, e.g. "puzzle" or "wikiText"
|
2021-07-13 09:00:57 +00:00
|
|
|
* @cfg {string} label
|
2021-11-15 10:01:52 +00:00
|
|
|
* @cfg {string} ariaDescriptionUnselected
|
|
|
|
* @cfg {string} ariaDescriptionSelected
|
|
|
|
* @cfg {string} ariaDescriptionSelectedSingle
|
2021-07-09 13:48:08 +00:00
|
|
|
*/
|
2021-07-13 07:27:22 +00:00
|
|
|
ve.ui.MWTransclusionOutlinePartWidget = function VeUiMWTransclusionOutlinePartWidget( part, config ) {
|
2021-09-22 09:49:44 +00:00
|
|
|
this.part = part;
|
|
|
|
|
2021-07-09 13:48:08 +00:00
|
|
|
// Parent constructor
|
2021-08-10 15:01:49 +00:00
|
|
|
ve.ui.MWTransclusionOutlinePartWidget.super.call( this, ve.extendObject( config, {
|
2021-09-10 19:18:59 +00:00
|
|
|
classes: [ 've-ui-mwTransclusionOutlinePartWidget' ],
|
2021-08-10 15:01:49 +00:00
|
|
|
data: part.getId()
|
|
|
|
} ) );
|
2021-07-09 14:47:01 +00:00
|
|
|
|
2021-08-27 16:22:37 +00:00
|
|
|
this.header = new ve.ui.MWTransclusionOutlineButtonWidget( config )
|
2021-09-02 16:09:30 +00:00
|
|
|
.connect( this, {
|
2021-09-22 09:49:44 +00:00
|
|
|
keyPressed: 'onHeaderKeyPressed',
|
2022-07-12 09:51:25 +00:00
|
|
|
// The array syntax is a way to call `this.emit( 'transclusionPartSelected', … )`.
|
|
|
|
click: [ 'emit', 'transclusionPartSelected', part.getId() ]
|
2021-09-02 16:09:30 +00:00
|
|
|
} );
|
2021-07-13 09:00:57 +00:00
|
|
|
|
2022-05-04 10:00:47 +00:00
|
|
|
if ( config.ariaDescriptionUnselected ) {
|
2021-11-15 10:01:52 +00:00
|
|
|
this.$ariaDescriptionUnselected = $( '<span>' )
|
2021-11-16 11:00:12 +00:00
|
|
|
.text( config.ariaDescriptionUnselected )
|
2021-11-15 10:01:52 +00:00
|
|
|
.addClass( 've-ui-mwTransclusionOutline-ariaHidden' );
|
|
|
|
|
|
|
|
this.$ariaDescriptionSelected = $( '<span>' )
|
2021-11-16 11:00:12 +00:00
|
|
|
.text( config.ariaDescriptionSelected )
|
2021-11-15 10:01:52 +00:00
|
|
|
.addClass( 've-ui-mwTransclusionOutline-ariaHidden' );
|
|
|
|
|
|
|
|
this.$ariaDescriptionSelectedSingle = $( '<span>' )
|
2021-11-16 11:00:12 +00:00
|
|
|
.text( config.ariaDescriptionSelectedSingle )
|
2021-11-15 10:01:52 +00:00
|
|
|
.addClass( 've-ui-mwTransclusionOutline-ariaHidden' );
|
|
|
|
|
2022-05-04 10:00:47 +00:00
|
|
|
this.header
|
|
|
|
.setAriaDescribedBy( this.$ariaDescriptionUnselected )
|
|
|
|
.$element.prepend(
|
|
|
|
this.$ariaDescriptionUnselected,
|
|
|
|
this.$ariaDescriptionSelected,
|
|
|
|
this.$ariaDescriptionSelectedSingle
|
|
|
|
);
|
2021-11-15 10:01:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.transclusionModel = this.part.getTransclusion().connect( this, {
|
|
|
|
replace: 'updateButtonAriaDescription'
|
|
|
|
} );
|
|
|
|
|
2022-01-14 16:18:00 +00:00
|
|
|
this.$element.append( this.header.$element );
|
2021-07-09 13:48:08 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* Inheritance */
|
|
|
|
|
2021-07-09 15:04:14 +00:00
|
|
|
OO.inheritClass( ve.ui.MWTransclusionOutlinePartWidget, OO.ui.Widget );
|
2021-07-13 07:27:22 +00:00
|
|
|
|
2021-07-13 11:02:26 +00:00
|
|
|
/* Events */
|
|
|
|
|
|
|
|
/**
|
2021-09-02 16:09:30 +00:00
|
|
|
* "Soft" selection with space.
|
|
|
|
*
|
|
|
|
* @event transclusionPartSoftSelected
|
|
|
|
* @param {string} partId Unique id of the {@see ve.dm.MWTransclusionPartModel}, e.g. something like
|
|
|
|
* "part_1".
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* "Hard" selection with enter or mouse click.
|
|
|
|
*
|
2021-08-31 08:05:25 +00:00
|
|
|
* @event transclusionPartSelected
|
2021-09-16 08:42:13 +00:00
|
|
|
* @param {string} pageName Unique id of the {@see OO.ui.BookletLayout} page, e.g. something like
|
|
|
|
* "part_1" or "part_1/param1".
|
2021-07-13 11:02:26 +00:00
|
|
|
*/
|
2021-08-27 16:22:37 +00:00
|
|
|
|
|
|
|
/* Methods */
|
|
|
|
|
2021-09-22 09:49:44 +00:00
|
|
|
/**
|
|
|
|
* @private
|
2022-02-08 13:30:54 +00:00
|
|
|
* @param {number} key
|
2021-09-22 09:49:44 +00:00
|
|
|
* @fires transclusionPartSoftSelected
|
|
|
|
*/
|
|
|
|
ve.ui.MWTransclusionOutlinePartWidget.prototype.onHeaderKeyPressed = function ( key ) {
|
2022-02-08 13:30:54 +00:00
|
|
|
if ( key === OO.ui.Keys.SPACE ) {
|
|
|
|
this.emit( 'transclusionPartSoftSelected', this.getData() );
|
2021-09-22 09:49:44 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-08-27 16:22:37 +00:00
|
|
|
/**
|
|
|
|
* Convenience method, modelled after {@see OO.ui.OptionWidget}, but this isn't one.
|
|
|
|
*
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
ve.ui.MWTransclusionOutlinePartWidget.prototype.isSelected = function () {
|
|
|
|
return this.header.isSelected();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convenience method, modelled after {@see OO.ui.OptionWidget}, but this isn't one.
|
|
|
|
*
|
|
|
|
* @param {boolean} state
|
|
|
|
*/
|
|
|
|
ve.ui.MWTransclusionOutlinePartWidget.prototype.setSelected = function ( state ) {
|
2021-11-15 10:01:52 +00:00
|
|
|
this.updateButtonAriaDescription( state );
|
2021-08-27 16:22:37 +00:00
|
|
|
this.header
|
|
|
|
.setSelected( state )
|
|
|
|
.setFlags( { progressive: state } );
|
|
|
|
};
|
2021-11-15 10:01:52 +00:00
|
|
|
|
|
|
|
/**
|
2022-02-14 15:18:57 +00:00
|
|
|
* @private
|
2021-11-15 10:01:52 +00:00
|
|
|
* @param {boolean} state
|
|
|
|
*/
|
|
|
|
ve.ui.MWTransclusionOutlinePartWidget.prototype.updateButtonAriaDescription = function ( state ) {
|
|
|
|
this.header.setAriaDescribedBy( !state ? this.$ariaDescriptionUnselected :
|
|
|
|
( this.transclusionModel.isSingleTemplate() ? this.$ariaDescriptionSelectedSingle : this.$ariaDescriptionSelected )
|
|
|
|
);
|
|
|
|
};
|