3 * Quick links menu option widget
6 * @extends OO.ui.Widget
7 * @mixins OO.ui.mixin.LabelElement
8 * @mixins OO.ui.mixin.IconElement
9 * @mixins OO.ui.mixin.TitledElement
12 * @param {mw.rcfilters.dm.SavedQueryItemModel} model View model
13 * @param {Object} [config] Configuration object
14 * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
16 mw
.rcfilters
.ui
.SavedLinksListItemWidget
= function MwRcfiltersUiSavedLinksListWidget( model
, config
) {
17 config
= config
|| {};
22 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.parent
.call( this, $.extend( {
23 data
: this.model
.getID()
27 OO
.ui
.mixin
.LabelElement
.call( this, $.extend( {
28 label
: this.model
.getLabel()
30 OO
.ui
.mixin
.IconElement
.call( this, $.extend( {
33 OO
.ui
.mixin
.TitledElement
.call( this, $.extend( {
34 title
: this.model
.getLabel()
38 this.$overlay
= config
.$overlay
|| this.$element
;
40 this.popupButton
= new OO
.ui
.ButtonWidget( {
41 classes
: [ 'mw-rcfilters-ui-savedLinksListItemWidget-button' ],
45 this.menu
= new OO
.ui
.MenuSelectWidget( {
46 classes
: [ 'mw-rcfilters-ui-savedLinksListItemWidget-menu' ],
47 widget
: this.popupButton
,
49 horizontalPosition
: 'end',
50 $floatableContainer
: this.popupButton
.$element
,
52 new OO
.ui
.MenuOptionWidget( {
55 label
: mw
.msg( 'rcfilters-savedqueries-rename' )
57 new OO
.ui
.MenuOptionWidget( {
60 label
: mw
.msg( 'rcfilters-savedqueries-remove' )
62 new OO
.ui
.MenuOptionWidget( {
65 label
: mw
.msg( 'rcfilters-savedqueries-setdefault' )
70 this.editInput
= new OO
.ui
.TextInputWidget( {
71 classes
: [ 'mw-rcfilters-ui-savedLinksListItemWidget-input' ]
73 this.saveButton
= new OO
.ui
.ButtonWidget( {
75 flags
: [ 'primary', 'progressive' ]
77 this.toggleEdit( false );
80 this.model
.connect( this, { update
: 'onModelUpdate' } );
81 this.popupButton
.connect( this, { click
: 'onPopupButtonClick' } );
82 this.menu
.connect( this, {
83 choose
: 'onMenuChoose'
85 this.saveButton
.connect( this, { click
: 'save' } );
86 this.editInput
.connect( this, {
87 change
: 'onInputChange',
90 this.editInput
.$input
.on( {
91 blur
: this.onInputBlur
.bind( this ),
92 keyup
: this.onInputKeyup
.bind( this )
94 this.$element
.on( { click
: this.onClick
.bind( this ) } );
95 this.$label
.on( { click
: this.onClick
.bind( this ) } );
96 this.$icon
.on( { click
: this.onDefaultIconClick
.bind( this ) } );
97 // Prevent propagation on mousedown for the save button
98 // so the menu doesn't close
99 this.saveButton
.$element
.on( { mousedown: function () { return false; } } );
102 this.toggleDefault( !!this.model
.isDefault() );
103 this.$overlay
.append( this.menu
.$element
);
105 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget' )
106 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-query-' + this.model
.getID() )
109 .addClass( 'mw-rcfilters-ui-table' )
112 .addClass( 'mw-rcfilters-ui-row' )
115 .addClass( 'mw-rcfilters-ui-cell' )
116 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-content' )
119 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-label' ),
120 this.editInput
.$element
,
121 this.saveButton
.$element
124 .addClass( 'mw-rcfilters-ui-cell' )
125 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-icon' )
126 .append( this.$icon
),
127 this.popupButton
.$element
128 .addClass( 'mw-rcfilters-ui-cell' )
135 OO
.inheritClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.Widget
);
136 OO
.mixinClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.mixin
.LabelElement
);
137 OO
.mixinClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.mixin
.IconElement
);
138 OO
.mixinClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.mixin
.TitledElement
);
145 * The delete option was selected for this item
150 * @param {boolean} default Item is default
152 * The 'make default' option was selected for this item
157 * @param {string} newLabel New label for the query
159 * The label has been edited
165 * Respond to model update event
167 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onModelUpdate = function () {
168 this.setLabel( this.model
.getLabel() );
169 this.toggleDefault( this.model
.isDefault() );
173 * Respond to click on the element or label
177 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onClick = function () {
178 if ( !this.editing
) {
179 this.emit( 'click' );
184 * Respond to click on the 'default' icon. Open the submenu where the
185 * default state can be changed.
187 * @return {boolean} false
189 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onDefaultIconClick = function () {
195 * Respond to popup button click event
197 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onPopupButtonClick = function () {
202 * Respond to menu choose event
204 * @param {OO.ui.MenuOptionWidget} item Chosen item
208 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onMenuChoose = function ( item
) {
209 var action
= item
.getData();
211 if ( action
=== 'edit' ) {
212 this.toggleEdit( true );
213 } else if ( action
=== 'delete' ) {
214 this.emit( 'delete' );
215 } else if ( action
=== 'default' ) {
216 this.emit( 'default', !this.default );
219 this.menu
.selectItem( null );
221 this.menu
.toggle( false );
225 * Respond to input keyup event, this is the way to intercept 'escape' key
227 * @param {jQuery.Event} e Event data
228 * @return {boolean} false
230 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onInputKeyup = function ( e
) {
231 if ( e
.which
=== OO
.ui
.Keys
.ESCAPE
) {
232 // Return the input to the original label
233 this.editInput
.setValue( this.getLabel() );
234 this.toggleEdit( false );
240 * Respond to blur event on the input
242 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onInputBlur = function () {
245 // Whether the save succeeded or not, the input-blur event
246 // means we need to cancel editing mode
247 this.toggleEdit( false );
251 * Respond to input change event
253 * @param {string} value Input value
255 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onInputChange = function ( value
) {
256 value
= value
.trim();
258 this.saveButton
.setDisabled( !value
);
262 * Save the name of the query
264 * @param {string} [value] The value to save
267 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.save = function () {
268 var value
= this.editInput
.getValue().trim();
271 this.emit( 'edit', value
);
272 this.toggleEdit( false );
277 * Toggle edit mode on this widget
279 * @param {boolean} isEdit Widget is in edit mode
281 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.toggleEdit = function ( isEdit
) {
282 isEdit
= isEdit
=== undefined ? !this.editing
: isEdit
;
284 if ( this.editing
!== isEdit
) {
285 this.$element
.toggleClass( 'mw-rcfilters-ui-savedLinksListItemWidget-edit', isEdit
);
286 this.editInput
.setValue( this.getLabel() );
288 this.editInput
.toggle( isEdit
);
289 this.$label
.toggleClass( 'oo-ui-element-hidden', isEdit
);
290 this.$icon
.toggleClass( 'oo-ui-element-hidden', isEdit
);
291 this.popupButton
.toggle( !isEdit
);
292 this.saveButton
.toggle( isEdit
);
295 this.editInput
.$input
.focus();
297 this.editing
= isEdit
;
302 * Toggle default this widget
304 * @param {boolean} isDefault This item is default
306 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.toggleDefault = function ( isDefault
) {
307 isDefault
= isDefault
=== undefined ? !this.default : isDefault
;
309 if ( this.default !== isDefault
) {
310 this.default = isDefault
;
311 this.setIcon( this.default ? 'pushPin' : '' );
312 this.menu
.getItemFromData( 'default' ).setLabel(
314 mw
.msg( 'rcfilters-savedqueries-unsetdefault' ) :
315 mw
.msg( 'rcfilters-savedqueries-setdefault' )
323 * @return {string} Query identifier
325 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.getID = function () {
326 return this.model
.getID();