Merge "Align "What's this" vertically"
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.SaveFiltersPopupButtonWidget.js
1 ( function ( mw ) {
2 /**
3 * Save filters widget. This widget is displayed in the tag area
4 * and allows the user to save the current state of the system
5 * as a new saved filter query they can later load or set as
6 * default.
7 *
8 * @extends OO.ui.PopupButtonWidget
9 *
10 * @constructor
11 * @param {mw.rcfilters.Controller} controller Controller
12 * @param {mw.rcfilters.dm.SavedQueriesModel} model View model
13 * @param {Object} [config] Configuration object
14 */
15 mw.rcfilters.ui.SaveFiltersPopupButtonWidget = function MwRcfiltersUiSaveFiltersPopupButtonWidget( controller, model, config ) {
16 var layout,
17 checkBoxLayout,
18 $popupContent = $( '<div>' );
19
20 config = config || {};
21
22 this.controller = controller;
23 this.model = model;
24
25 // Parent
26 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.parent.call( this, $.extend( {
27 framed: false,
28 icon: 'unClip',
29 $overlay: this.$overlay,
30 title: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
31 popup: {
32 classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup' ],
33 padded: true,
34 head: true,
35 label: mw.msg( 'rcfilters-savedqueries-add-new-title' ),
36 $content: $popupContent
37 }
38 }, config ) );
39 // // HACK: Add an icon to the popup head label
40 this.popup.$head.prepend( ( new OO.ui.IconWidget( { icon: 'unClip' } ) ).$element );
41
42 this.input = new OO.ui.TextInputWidget( {
43 placeholder: mw.msg( 'rcfilters-savedqueries-new-name-placeholder' )
44 } );
45 layout = new OO.ui.FieldLayout( this.input, {
46 label: mw.msg( 'rcfilters-savedqueries-new-name-label' ),
47 align: 'top'
48 } );
49
50 this.setAsDefaultCheckbox = new OO.ui.CheckboxInputWidget();
51 checkBoxLayout = new OO.ui.FieldLayout( this.setAsDefaultCheckbox, {
52 label: mw.msg( 'rcfilters-savedqueries-setdefault' ),
53 align: 'inline'
54 } );
55
56 this.applyButton = new OO.ui.ButtonWidget( {
57 label: mw.msg( 'rcfilters-savedqueries-apply-label' ),
58 classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-apply' ],
59 flags: [ 'primary', 'progressive' ]
60 } );
61 this.cancelButton = new OO.ui.ButtonWidget( {
62 label: mw.msg( 'rcfilters-savedqueries-cancel-label' ),
63 classes: [ 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons-cancel' ]
64 } );
65
66 $popupContent
67 .append(
68 $( '<div>' )
69 .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-layout' )
70 .append( layout.$element ),
71 $( '<div>' )
72 .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-options' )
73 .append( checkBoxLayout.$element ),
74 $( '<div>' )
75 .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget-popup-buttons' )
76 .append(
77 this.cancelButton.$element,
78 this.applyButton.$element
79 )
80 );
81
82 // Events
83 this.popup.connect( this, {
84 ready: 'onPopupReady'
85 } );
86 this.input.connect( this, {
87 change: 'onInputChange',
88 enter: 'onInputEnter'
89 } );
90 this.input.$input.on( {
91 keyup: this.onInputKeyup.bind( this )
92 } );
93 this.setAsDefaultCheckbox.connect( this, { change: 'onSetAsDefaultChange' } );
94 this.cancelButton.connect( this, { click: 'onCancelButtonClick' } );
95 this.applyButton.connect( this, { click: 'onApplyButtonClick' } );
96
97 // Initialize
98 this.applyButton.setDisabled( !this.input.getValue() );
99 this.$element
100 .addClass( 'mw-rcfilters-ui-saveFiltersPopupButtonWidget' );
101 };
102
103 /* Initialization */
104 OO.inheritClass( mw.rcfilters.ui.SaveFiltersPopupButtonWidget, OO.ui.PopupButtonWidget );
105
106 /**
107 * Respond to input enter event
108 */
109 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onInputEnter = function () {
110 this.apply();
111 };
112
113 /**
114 * Respond to input change event
115 *
116 * @param {string} value Input value
117 */
118 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onInputChange = function ( value ) {
119 value = value.trim();
120
121 this.applyButton.setDisabled( !value );
122 };
123
124 /**
125 * Respond to input keyup event, this is the way to intercept 'escape' key
126 *
127 * @param {jQuery.Event} e Event data
128 * @return {boolean} false
129 */
130 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onInputKeyup = function ( e ) {
131 if ( e.which === OO.ui.Keys.ESCAPE ) {
132 this.popup.toggle( false );
133 return false;
134 }
135 };
136
137 /**
138 * Respond to popup ready event
139 */
140 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onPopupReady = function () {
141 this.input.focus();
142 };
143
144 /**
145 * Respond to "set as default" checkbox change
146 * @param {boolean} checked State of the checkbox
147 */
148 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onSetAsDefaultChange = function ( checked ) {
149 var messageKey = checked ?
150 'rcfilters-savedqueries-apply-and-setdefault-label' :
151 'rcfilters-savedqueries-apply-label';
152
153 this.applyButton
154 .setIcon( checked ? 'pushPin' : null )
155 .setLabel( mw.msg( messageKey ) );
156 };
157
158 /**
159 * Respond to cancel button click event
160 */
161 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onCancelButtonClick = function () {
162 this.popup.toggle( false );
163 };
164
165 /**
166 * Respond to apply button click event
167 */
168 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.onApplyButtonClick = function () {
169 this.apply();
170 };
171
172 /**
173 * Apply and add the new quick link
174 */
175 mw.rcfilters.ui.SaveFiltersPopupButtonWidget.prototype.apply = function () {
176 var label = this.input.getValue().trim();
177
178 // This condition is more for sanity-check, since the
179 // apply button should be disabled if the label is empty
180 if ( label ) {
181 this.controller.saveCurrentQuery( label, this.setAsDefaultCheckbox.isSelected() );
182 this.input.setValue( '' );
183 this.setAsDefaultCheckbox.setSelected( false );
184 this.popup.toggle( false );
185
186 this.emit( 'saveCurrent' );
187 }
188 };
189 }( mediaWiki ) );