Merge "Amend $namespaces in core for Javanese (jv)"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.FilterWrapperWidget.js
1 ( function ( mw ) {
2 /**
3 * List displaying all filter groups
4 *
5 * @extends OO.ui.Widget
6 * @mixins OO.ui.mixin.PendingElement
7 *
8 * @constructor
9 * @param {mw.rcfilters.Controller} controller Controller
10 * @param {mw.rcfilters.dm.FiltersViewModel} model View model
11 * @param {Object} config Configuration object
12 * @cfg {Object} [filters] A definition of the filter groups in this list
13 */
14 mw.rcfilters.ui.FilterWrapperWidget = function MwRcfiltersUiFilterWrapperWidget( controller, model, config ) {
15 config = config || {};
16
17 // Parent
18 mw.rcfilters.ui.FilterWrapperWidget.parent.call( this, config );
19 // Mixin constructors
20 OO.ui.mixin.PendingElement.call( this, config );
21
22 this.controller = controller;
23 this.model = model;
24 this.filtersInCapsule = [];
25
26 this.filterPopup = new mw.rcfilters.ui.FiltersListWidget(
27 this.controller,
28 this.model,
29 {
30 label: mw.msg( 'rcfilters-filterlist-title' )
31 }
32 );
33
34 this.textInput = new OO.ui.TextInputWidget( {
35 classes: [ 'mw-rcfilters-ui-filterWrapperWidget-search' ],
36 icon: 'search',
37 placeholder: mw.msg( 'rcfilters-search-placeholder' )
38 } );
39
40 this.capsule = new mw.rcfilters.ui.FilterCapsuleMultiselectWidget( controller, this.model, this.textInput, {
41 popup: {
42 $content: this.filterPopup.$element,
43 classes: [ 'mw-rcfilters-ui-filterWrapperWidget-popup' ]
44 }
45 } );
46
47 // Events
48 this.model.connect( this, {
49 initialize: 'onModelInitialize',
50 itemUpdate: 'onModelItemUpdate'
51 } );
52 this.textInput.connect( this, {
53 change: 'onTextInputChange'
54 } );
55 this.capsule.connect( this, {
56 remove: 'onCapsuleRemoveItem'
57 } );
58
59 this.$element
60 .addClass( 'mw-rcfilters-ui-filterWrapperWidget' )
61 .append( this.capsule.$element, this.textInput.$element );
62 };
63
64 /* Initialization */
65
66 OO.inheritClass( mw.rcfilters.ui.FilterWrapperWidget, OO.ui.Widget );
67 OO.mixinClass( mw.rcfilters.ui.FilterWrapperWidget, OO.ui.mixin.PendingElement );
68
69 /**
70 * Respond to text input change
71 *
72 * @param {string} newValue Current value
73 */
74 mw.rcfilters.ui.FilterWrapperWidget.prototype.onTextInputChange = function ( newValue ) {
75 // Filter the results
76 this.filterPopup.filter( this.model.findMatches( newValue ) );
77 };
78
79 /**
80 * Respond to an event where an item is removed from the capsule.
81 * This is the case where a user actively removes a filter box from the capsule widget.
82 *
83 * @param {string[]} filterNames An array of filter names that were removed
84 */
85 mw.rcfilters.ui.FilterWrapperWidget.prototype.onCapsuleRemoveItem = function ( filterNames ) {
86 var filterItem,
87 widget = this;
88
89 filterNames.forEach( function ( filterName ) {
90 // Go over filters
91 filterItem = widget.model.getItemByName( filterName );
92 filterItem.toggleSelected( false );
93 } );
94 };
95
96 /**
97 * Respond to model update event and set up the available filters to choose
98 * from.
99 */
100 mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelInitialize = function () {
101 var items,
102 wrapper = this,
103 filters = this.model.getItems();
104
105 // Reset
106 this.capsule.getMenu().clearItems();
107
108 // Insert hidden options for the capsule to get its item data from
109 items = filters.map( function ( filterItem ) {
110 return new OO.ui.MenuOptionWidget( {
111 data: filterItem.getName(),
112 label: filterItem.getLabel()
113 } );
114 } );
115
116 this.capsule.getMenu().addItems( items );
117
118 // Add defaults to capsule. We have to do this
119 // after we added to the capsule menu, since that's
120 // how the capsule multiselect widget knows which
121 // object to add
122 filters.forEach( function ( filterItem ) {
123 if ( filterItem.isSelected() ) {
124 wrapper.addCapsuleItemFromName( filterItem.getName() );
125 }
126 } );
127 };
128
129 /**
130 * Respond to model item update
131 *
132 * @param {mw.rcfilters.dm.FilterItem} item Filter item that was updated
133 */
134 mw.rcfilters.ui.FilterWrapperWidget.prototype.onModelItemUpdate = function ( item ) {
135 var widget = this;
136
137 if ( item.isSelected() ) {
138 this.addCapsuleItemFromName( item.getName() );
139 } else {
140 this.capsule.removeItemsFromData( [ item.getName() ] );
141 }
142
143 // Toggle the active state of the group
144 this.filterPopup.getItems().forEach( function ( groupWidget ) {
145 if ( groupWidget.getName() === item.getGroup() ) {
146 groupWidget.toggleActiveState( widget.model.isFilterGroupActive( groupWidget.getName() ) );
147 }
148 } );
149 };
150
151 /**
152 * Add a capsule item by its filter name
153 *
154 * @param {string} itemName Filter name
155 */
156 mw.rcfilters.ui.FilterWrapperWidget.prototype.addCapsuleItemFromName = function ( itemName ) {
157 var item = this.model.getItemByName( itemName );
158
159 this.capsule.addItemsFromData( [ itemName ] );
160
161 // Deal with active/inactive capsule filter items
162 this.capsule.getItemFromData( itemName ).$element
163 .toggleClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-item-inactive', !item.isActive() );
164 };
165 }( mediaWiki ) );