Merge "Prepare for REL1_33 cut, labelling master as 1.34-alpha"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / ItemMenuOptionWidget.js
1 var FilterItemHighlightButton = require( './FilterItemHighlightButton.js' ),
2 CheckboxInputWidget = require( './CheckboxInputWidget.js' ),
3 ItemMenuOptionWidget;
4
5 /**
6 * A widget representing a base toggle item
7 *
8 * @class mw.rcfilters.ui.ItemMenuOptionWidget
9 * @extends OO.ui.MenuOptionWidget
10 *
11 * @constructor
12 * @param {mw.rcfilters.Controller} controller RCFilters controller
13 * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
14 * @param {mw.rcfilters.dm.ItemModel} invertModel
15 * @param {mw.rcfilters.dm.ItemModel} itemModel Item model
16 * @param {mw.rcfilters.ui.HighlightPopupWidget} highlightPopup Shared highlight color picker
17 * @param {Object} config Configuration object
18 */
19 ItemMenuOptionWidget = function MwRcfiltersUiItemMenuOptionWidget(
20 controller, filtersViewModel, invertModel, itemModel, highlightPopup, config
21 ) {
22 var layout,
23 classes = [],
24 $label = $( '<div>' )
25 .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label' );
26
27 config = config || {};
28
29 this.controller = controller;
30 this.filtersViewModel = filtersViewModel;
31 this.invertModel = invertModel;
32 this.itemModel = itemModel;
33
34 // Parent
35 ItemMenuOptionWidget.parent.call( this, $.extend( {
36 // Override the 'check' icon that OOUI defines
37 icon: '',
38 data: this.itemModel.getName(),
39 label: this.itemModel.getLabel()
40 }, config ) );
41
42 this.checkboxWidget = new CheckboxInputWidget( {
43 value: this.itemModel.getName(),
44 selected: this.itemModel.isSelected()
45 } );
46
47 $label.append(
48 $( '<div>' )
49 .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label-title' )
50 .append( $( '<bdi>' ).append( this.$label ) )
51 );
52 if ( this.itemModel.getDescription() ) {
53 $label.append(
54 $( '<div>' )
55 .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-label-desc' )
56 .append( $( '<bdi>' ).text( this.itemModel.getDescription() ) )
57 );
58 }
59
60 this.highlightButton = new FilterItemHighlightButton(
61 this.controller,
62 this.itemModel,
63 highlightPopup,
64 {
65 $overlay: config.$overlay || this.$element,
66 title: mw.msg( 'rcfilters-highlightmenu-help' )
67 }
68 );
69 this.highlightButton.toggle( this.filtersViewModel.isHighlightEnabled() );
70
71 this.excludeLabel = new OO.ui.LabelWidget( {
72 label: mw.msg( 'rcfilters-filter-excluded' )
73 } );
74 this.excludeLabel.toggle(
75 this.itemModel.getGroupModel().getView() === 'namespaces' &&
76 this.itemModel.isSelected() &&
77 this.invertModel.isSelected()
78 );
79
80 layout = new OO.ui.FieldLayout( this.checkboxWidget, {
81 label: $label,
82 align: 'inline'
83 } );
84
85 // Events
86 this.filtersViewModel.connect( this, { highlightChange: 'updateUiBasedOnState' } );
87 this.invertModel.connect( this, { update: 'updateUiBasedOnState' } );
88 this.itemModel.connect( this, { update: 'updateUiBasedOnState' } );
89 // HACK: Prevent defaults on 'click' for the label so it
90 // doesn't steal the focus away from the input. This means
91 // we can continue arrow-movement after we click the label
92 // and is consistent with the checkbox *itself* also preventing
93 // defaults on 'click' as well.
94 layout.$label.on( 'click', false );
95
96 this.$element
97 .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget' )
98 .addClass( 'mw-rcfilters-ui-itemMenuOptionWidget-view-' + this.itemModel.getGroupModel().getView() )
99 .append(
100 $( '<div>' )
101 .addClass( 'mw-rcfilters-ui-table' )
102 .append(
103 $( '<div>' )
104 .addClass( 'mw-rcfilters-ui-row' )
105 .append(
106 $( '<div>' )
107 .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-itemCheckbox' )
108 .append( layout.$element ),
109 $( '<div>' )
110 .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-excludeLabel' )
111 .append( this.excludeLabel.$element ),
112 $( '<div>' )
113 .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-itemMenuOptionWidget-highlightButton' )
114 .append( this.highlightButton.$element )
115 )
116 )
117 );
118
119 if ( this.itemModel.getIdentifiers() ) {
120 this.itemModel.getIdentifiers().forEach( function ( ident ) {
121 classes.push( 'mw-rcfilters-ui-itemMenuOptionWidget-identifier-' + ident );
122 } );
123
124 this.$element.addClass( classes );
125 }
126
127 this.updateUiBasedOnState();
128 };
129
130 /* Initialization */
131
132 OO.inheritClass( ItemMenuOptionWidget, OO.ui.MenuOptionWidget );
133
134 /* Static properties */
135
136 // We do our own scrolling to top
137 ItemMenuOptionWidget.static.scrollIntoViewOnSelect = false;
138
139 /* Methods */
140
141 /**
142 * Respond to item model update event
143 */
144 ItemMenuOptionWidget.prototype.updateUiBasedOnState = function () {
145 this.checkboxWidget.setSelected( this.itemModel.isSelected() );
146
147 this.highlightButton.toggle( this.filtersViewModel.isHighlightEnabled() );
148 this.excludeLabel.toggle(
149 this.itemModel.getGroupModel().getView() === 'namespaces' &&
150 this.itemModel.isSelected() &&
151 this.invertModel.isSelected()
152 );
153 this.toggle( this.itemModel.isVisible() );
154 };
155
156 /**
157 * Get the name of this filter
158 *
159 * @return {string} Filter name
160 */
161 ItemMenuOptionWidget.prototype.getName = function () {
162 return this.itemModel.getName();
163 };
164
165 ItemMenuOptionWidget.prototype.getModel = function () {
166 return this.itemModel;
167 };
168
169 module.exports = ItemMenuOptionWidget;