Move small code snippets into …OutlineParameterSelectWidget

Most notably:
* Move some code snippets from the outer …TemplateWidget to
  the inner …SelectWidget, without introducing new
  dependencies.
* Move all knowledge about the item class
  …OutlineParameterWidget class into …SelectWidget.
* Some more self-documenting method names for event handlers.
* Avoid the somewhat ambiguous variable name "checkbox" in
  favor of "item". That's how it's named in the upstream OOUI
  …SelectWidget.

This is extracted from the following patch Ibd94c39. The
difference is that the following patch adds a new dependency:
The …SelectWidget gets to know the template model. This patch
here contains all changes that are possible without this new
dependency.

Bug: T288827
Change-Id: I187f313c84424b28005d9276cb1356029f9ebb75
This commit is contained in:
Thiemo Kreuz 2021-08-26 16:29:42 +02:00
parent a5718f01c5
commit 7aeff4bfd3
3 changed files with 66 additions and 52 deletions

View file

@ -35,6 +35,22 @@ OO.mixinClass( ve.ui.MWTransclusionOutlineParameterSelectWidget, OO.ui.mixin.Tab
* @param {string} paramName
*/
/* Static Methods */
/**
* @param {Object} config
* @param {string} config.data Parameter name
* @param {string} config.label
* @param {boolean} [config.required] Required parameters can't be unchecked
* @param {boolean} [config.selected] If the parameter is currently used (checked)
* @return {ve.ui.MWTransclusionOutlineParameterWidget}
*/
ve.ui.MWTransclusionOutlineParameterSelectWidget.static.createItem = function ( config ) {
return new ve.ui.MWTransclusionOutlineParameterWidget( config );
};
/* Methods */
/**
* @inheritDoc OO.ui.mixin.GroupElement
* @param {ve.ui.MWTransclusionOutlineParameterWidget[]} items
@ -43,9 +59,9 @@ OO.mixinClass( ve.ui.MWTransclusionOutlineParameterSelectWidget, OO.ui.mixin.Tab
*/
ve.ui.MWTransclusionOutlineParameterSelectWidget.prototype.addItems = function ( items, index ) {
var self = this;
items.forEach( function ( checkbox ) {
checkbox.connect( self, {
change: [ 'onCheckboxChange', checkbox ],
items.forEach( function ( item ) {
item.connect( self, {
change: [ 'onCheckboxChange', item ],
parameterFocused: [ 'emit', 'parameterFocused' ]
} );
} );
@ -53,16 +69,27 @@ ve.ui.MWTransclusionOutlineParameterSelectWidget.prototype.addItems = function (
return ve.ui.MWTransclusionOutlineParameterSelectWidget.super.prototype.addItems.call( this, items, index );
};
/**
* @param {string} paramName
*/
ve.ui.MWTransclusionOutlineParameterSelectWidget.prototype.markParameterAsUnused = function ( paramName ) {
// There is no OO.ui.SelectWidget.unselectItemByData(), we need to do this manually
var item = this.findItemFromData( paramName );
if ( item ) {
item.setSelected( false );
}
};
/**
* @private
* @param {ve.ui.MWTransclusionOutlineParameterWidget} checkbox
* @param {ve.ui.MWTransclusionOutlineParameterWidget} item
* @param {boolean} value
*/
ve.ui.MWTransclusionOutlineParameterSelectWidget.prototype.onCheckboxChange = function ( checkbox, value ) {
ve.ui.MWTransclusionOutlineParameterSelectWidget.prototype.onCheckboxChange = function ( item, value ) {
// This extra check shouldn't be necessary, but better be safe than sorry
if ( checkbox.isSelected() !== value ) {
if ( item.isSelected() !== value ) {
// Note: This should have been named `toggle…` as it toggles the item's selection
this.chooseItem( checkbox );
this.chooseItem( item );
}
};

View file

@ -16,8 +16,8 @@
* @param {Object} config
* @cfg {string} data Parameter name
* @cfg {string} label
* @cfg {boolean} [required]
* @cfg {boolean} [selected]
* @cfg {boolean} [required] Required parameters can't be unchecked
* @cfg {boolean} [selected] If the parameter is currently used (checked)
*/
ve.ui.MWTransclusionOutlineParameterWidget = function VeUiMWTransclusionOutlineParameterWidget( config ) {
this.checkbox = new OO.ui.CheckboxInputWidget( {

View file

@ -22,12 +22,11 @@ ve.ui.MWTransclusionOutlineTemplateWidget = function VeUiMWTransclusionOutlineTe
// Initialization
this.templateModel = template.connect( this, {
add: 'onAddParameter',
remove: 'onRemoveParameter'
add: 'onParameterAddedToTemplateModel',
remove: 'onParameterRemovedFromTemplateModel'
} );
var widget = this;
var checkboxes = this.templateModel
var parameterNames = this.templateModel
.getAllParametersOrdered()
.filter( function ( paramName ) {
if ( spec.isParameterDeprecated( paramName ) && !template.hasParameter( paramName ) ) {
@ -35,9 +34,6 @@ ve.ui.MWTransclusionOutlineTemplateWidget = function VeUiMWTransclusionOutlineTe
}
// Don't create a checkbox for ve.ui.MWParameterPlaceholderPage
return paramName;
} )
.map( function ( paramName ) {
return widget.createCheckbox( paramName );
} );
this.searchWidget = new OO.ui.SearchInputWidget( {
@ -45,19 +41,19 @@ ve.ui.MWTransclusionOutlineTemplateWidget = function VeUiMWTransclusionOutlineTe
classes: [ 've-ui-mwTransclusionOutlineTemplateWidget-searchWidget' ]
} ).connect( this, {
change: 'filterParameters'
} ).toggle( checkboxes.length );
} ).toggle( parameterNames.length );
this.infoWidget = new OO.ui.LabelWidget( {
label: new OO.ui.HtmlSnippet( ve.msg( 'visualeditor-dialog-transclusion-filter-no-match' ) ),
classes: [ 've-ui-mwTransclusionOutlineTemplateWidget-no-match' ]
} ).toggle( false );
this.parameters = new ve.ui.MWTransclusionOutlineParameterSelectWidget( {
items: checkboxes
items: parameterNames.map( this.createCheckbox.bind( this ) )
} )
.connect( this, {
choose: 'onParameterChoose',
parameterFocused: 'onParameterFocused',
change: 'onCheckboxListChange'
change: 'onParameterWidgetListChanged'
} );
this.$element.append(
@ -91,12 +87,11 @@ OO.inheritClass( ve.ui.MWTransclusionOutlineTemplateWidget, ve.ui.MWTransclusion
/**
* @private
* @param {string} paramName
* @return {ve.ui.MWTransclusionOutlineParameterWidget}
* @return {OO.ui.OptionWidget}
*/
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.createCheckbox = function ( paramName ) {
var spec = this.templateModel.getSpec();
return new ve.ui.MWTransclusionOutlineParameterWidget( {
return ve.ui.MWTransclusionOutlineParameterSelectWidget.static.createItem( {
required: spec.isParameterRequired( paramName ),
label: spec.getParameterLabel( paramName ),
data: paramName,
@ -106,11 +101,11 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.createCheckbox = function (
/**
* @private
* @param {ve.ui.MWTransclusionOutlineParameterWidget} checkbox
* @param {string} paramName
* @return {number}
*/
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.insertCheckboxAtCanonicalPosition = function ( checkbox ) {
var paramName = checkbox.getData(),
insertAt = 0,
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.findCanonicalPosition = function ( paramName ) {
var insertAt = 0,
// Note this might include parameters that don't have a checkbox, e.g. deprecated
allParamNames = this.templateModel.getAllParametersOrdered();
for ( var i = 0; i < allParamNames.length; i++ ) {
@ -120,17 +115,14 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.insertCheckboxAtCanonicalPos
insertAt++;
}
}
this.parameters.addItems( [ checkbox ], insertAt );
return insertAt;
};
/**
* Handles a template model add event {@see ve.dm.MWTemplateModel}.
* Triggered when a parameter is added to the template model.
*
* @private
* @param {ve.dm.MWParameterModel} param
*/
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onAddParameter = function ( param ) {
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onParameterAddedToTemplateModel = function ( param ) {
var paramName = param.getName();
// The placeholder (currently) doesn't get a corresponding item in the sidebar
if ( !paramName ) {
@ -138,10 +130,11 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onAddParameter = function (
}
// All parameters known via the spec already have a checkbox
var checkbox = this.parameters.findItemFromData( paramName );
if ( !checkbox ) {
checkbox = this.createCheckbox( paramName );
this.insertCheckboxAtCanonicalPosition( checkbox );
var item = this.parameters.findItemFromData( paramName );
if ( !item ) {
item = this.createCheckbox( paramName );
this.parameters.addItems( [ item ], this.findCanonicalPosition( paramName ) );
// Make sure an active filter is applied to the new checkbox as well
var filter = this.searchWidget.getValue();
if ( filter ) {
@ -149,35 +142,29 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onAddParameter = function (
}
}
checkbox.setSelected( true, true );
item.setSelected( true, true );
// Reset filter, but only if it hides the relevant checkbox
if ( !checkbox.isVisible() ) {
if ( !item.isVisible() ) {
this.searchWidget.setValue( '' );
}
};
/**
* Handles a template model remove event {@see ve.dm.MWTemplateModel}.
* Triggered when a parameter is removed from the template model.
*
* @private
* @param {ve.dm.MWParameterModel} param
*/
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onRemoveParameter = function ( param ) {
var checkbox = this.parameters.findItemFromData( param.getName() );
if ( checkbox ) {
checkbox.setSelected( false, true );
}
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onParameterRemovedFromTemplateModel = function ( param ) {
this.parameters.markParameterAsUnused( param.getName() );
};
/**
* @private
* @param {ve.ui.MWTransclusionOutlineParameterWidget} checkbox
* @param {OO.ui.OptionWidget} item
* @param {boolean} selected
*/
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onParameterChoose = function ( checkbox, selected ) {
var paramName = checkbox.getData(),
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onParameterChoose = function ( item, selected ) {
var paramName = item.getData(),
param = this.templateModel.getParameter( paramName );
if ( !selected ) {
this.templateModel.removeParameter( param );
@ -202,7 +189,7 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onParameterFocused = functio
* @private
* @param {OO.ui.Element[]} items
*/
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onCheckboxListChange = function ( items ) {
ve.ui.MWTransclusionOutlineTemplateWidget.prototype.onParameterWidgetListChanged = function ( items ) {
this.searchWidget.toggle( items.length >= 1 );
};
@ -225,8 +212,8 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.filterParameters = function
query = query.trim().toLowerCase();
// Note: We can't really cache this because the list of know parameters can change any time
this.parameters.items.forEach( function ( checkbox ) {
var paramName = checkbox.getData(),
this.parameters.items.forEach( function ( item ) {
var paramName = item.getData(),
placesToSearch = [
spec.getPrimaryParameterName( paramName ),
spec.getParameterLabel( paramName ),
@ -237,7 +224,7 @@ ve.ui.MWTransclusionOutlineTemplateWidget.prototype.filterParameters = function
return term && term.toLowerCase().indexOf( query ) !== -1;
} );
checkbox.toggle( foundSomeMatch );
item.toggle( foundSomeMatch );
nothingFound = nothingFound && !foundSomeMatch;