Merge "Allow wikilinks in "Powersearch-ns""
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.FilterCapsuleMultiselectWidget.js
1 ( function ( mw, $ ) {
2 /**
3 * Filter-specific CapsuleMultiselectWidget
4 *
5 * @extends OO.ui.CapsuleMultiselectWidget
6 *
7 * @constructor
8 * @param {mw.rcfilters.Controller} controller RCFilters controller
9 * @param {mw.rcfilters.dm.FiltersViewModel} model RCFilters view model
10 * @param {OO.ui.InputWidget} filterInput A filter input that focuses the capsule widget
11 * @param {Object} config Configuration object
12 */
13 mw.rcfilters.ui.FilterCapsuleMultiselectWidget = function MwRcfiltersUiFilterCapsuleMultiselectWidget( controller, model, filterInput, config ) {
14 // Parent
15 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.call( this, $.extend( {
16 $autoCloseIgnore: filterInput.$element
17 }, config ) );
18
19 this.controller = controller;
20 this.model = model;
21 this.filterInput = filterInput;
22
23 this.$content.prepend(
24 $( '<div>' )
25 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content-title' )
26 .text( mw.msg( 'rcfilters-activefilters' ) )
27 );
28
29 this.resetButton = new OO.ui.ButtonWidget( {
30 icon: 'trash',
31 framed: false,
32 title: mw.msg( 'rcfilters-clear-all-filters' ),
33 classes: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-resetButton' ]
34 } );
35
36 this.emptyFilterMessage = new OO.ui.LabelWidget( {
37 label: mw.msg( 'rcfilters-empty-filter' ),
38 classes: [ 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-emptyFilters' ]
39 } );
40
41 // Events
42 this.resetButton.connect( this, { click: 'onResetButtonClick' } );
43 this.model.connect( this, { itemUpdate: 'onModelItemUpdate' } );
44 // Add the filterInput as trigger
45 this.filterInput.$input
46 .on( 'focus', this.focus.bind( this ) );
47
48 // Initialize
49 this.$content.append( this.emptyFilterMessage.$element );
50 this.$handle
51 .append(
52 // The content and button should appear side by side regardless of how
53 // wide the button is; the button also changes its width depending
54 // on language and its state, so the safest way to present both side
55 // by side is with a table layout
56 $( '<div>' )
57 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-table' )
58 .append(
59 $( '<div>' )
60 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-row' )
61 .append(
62 $( '<div>' )
63 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-content' )
64 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
65 .append( this.$content ),
66 $( '<div>' )
67 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget-cell' )
68 .append( this.resetButton.$element )
69 )
70 )
71 );
72
73 this.$element
74 .addClass( 'mw-rcfilters-ui-filterCapsuleMultiselectWidget' );
75
76 this.reevaluateResetRestoreState();
77 };
78
79 /* Initialization */
80
81 OO.inheritClass( mw.rcfilters.ui.FilterCapsuleMultiselectWidget, OO.ui.CapsuleMultiselectWidget );
82
83 /* Events */
84
85 /**
86 * @event remove
87 * @param {string[]} filters Array of names of removed filters
88 *
89 * Filters were removed
90 */
91
92 /* Methods */
93
94 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onModelItemUpdate = function () {
95 // Re-evaluate reset state
96 this.reevaluateResetRestoreState();
97 };
98
99 /**
100 * Respond to click event on the reset button
101 */
102 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onResetButtonClick = function () {
103 if ( this.model.areCurrentFiltersEmpty() ) {
104 // Reset to default filters
105 this.controller.resetToDefaults();
106 } else {
107 // Reset to have no filters
108 this.controller.emptyFilters();
109 }
110 };
111
112 /**
113 * Reevaluate the restore state for the widget between setting to defaults and clearing all filters
114 */
115 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.reevaluateResetRestoreState = function () {
116 var defaultsAreEmpty = this.model.areDefaultFiltersEmpty(),
117 currFiltersAreEmpty = this.model.areCurrentFiltersEmpty(),
118 hideResetButton = currFiltersAreEmpty && defaultsAreEmpty;
119
120 this.resetButton.setIcon(
121 currFiltersAreEmpty ? 'history' : 'trash'
122 );
123
124 this.resetButton.setLabel(
125 currFiltersAreEmpty ? mw.msg( 'rcfilters-restore-default-filters' ) : ''
126 );
127
128 this.resetButton.toggle( !hideResetButton );
129 this.emptyFilterMessage.toggle( currFiltersAreEmpty );
130 };
131
132 /**
133 * @inheritdoc
134 */
135 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.focus = function () {
136 // Override this method; we don't want to focus on the popup, and we
137 // don't want to bind the size to the handle.
138 if ( !this.isDisabled() ) {
139 this.popup.toggle( true );
140 this.filterInput.$input.get( 0 ).focus();
141 }
142 return this;
143 };
144
145 /**
146 * @inheritdoc
147 */
148 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onFocusForPopup = function () {
149 // HACK can be removed once I21b8cff4048 is merged in oojs-ui
150 this.focus();
151 };
152
153 /**
154 * @inheritdoc
155 */
156 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.removeItems = function ( items ) {
157 // Parent
158 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.parent.prototype.removeItems.call( this, items );
159
160 this.emit( 'remove', items.map( function ( item ) { return item.getData(); } ) );
161 };
162
163 /**
164 * @inheritdoc
165 */
166 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onKeyDown = function () {};
167
168 /**
169 * @inheritdoc
170 */
171 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.onPopupFocusOut = function () {};
172
173 /**
174 * @inheritdoc
175 */
176 mw.rcfilters.ui.FilterCapsuleMultiselectWidget.prototype.clearInput = function () {
177 if ( this.filterInput ) {
178 this.filterInput.setValue( '' );
179 }
180 this.menu.toggle( false );
181 this.menu.selectItem();
182 this.menu.highlightItem();
183 };
184 }( mediaWiki, jQuery ) );