3 * Quick links menu option widget
5 * @extends OO.ui.Widget
6 * @mixins OO.ui.mixin.LabelElement
7 * @mixins OO.ui.mixin.IconElement
8 * @mixins OO.ui.mixin.TitledElement
11 * @param {mw.rcfilters.dm.SavedQueryItemModel} model View model
12 * @param {Object} [config] Configuration object
13 * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
15 mw
.rcfilters
.ui
.SavedLinksListItemWidget
= function MwRcfiltersUiSavedLinksListWidget( model
, config
) {
16 config
= config
|| {};
21 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.parent
.call( this, $.extend( {
22 data
: this.model
.getID()
26 OO
.ui
.mixin
.LabelElement
.call( this, $.extend( {
27 label
: this.model
.getLabel()
29 OO
.ui
.mixin
.IconElement
.call( this, $.extend( {
32 OO
.ui
.mixin
.TitledElement
.call( this, $.extend( {
33 title
: this.model
.getLabel()
37 this.$overlay
= config
.$overlay
|| this.$element
;
39 this.popupButton
= new OO
.ui
.ButtonWidget( {
40 classes
: [ 'mw-rcfilters-ui-savedLinksListItemWidget-button' ],
44 this.menu
= new OO
.ui
.MenuSelectWidget( {
45 classes
: [ 'mw-rcfilters-ui-savedLinksListItemWidget-menu' ],
46 widget
: this.popupButton
,
48 horizontalPosition
: 'end',
49 $floatableContainer
: this.popupButton
.$element
,
51 new OO
.ui
.MenuOptionWidget( {
54 label
: mw
.msg( 'rcfilters-savedqueries-rename' )
56 new OO
.ui
.MenuOptionWidget( {
59 label
: mw
.msg( 'rcfilters-savedqueries-remove' )
61 new OO
.ui
.MenuOptionWidget( {
64 label
: mw
.msg( 'rcfilters-savedqueries-setdefault' )
69 this.editInput
= new OO
.ui
.TextInputWidget( {
70 classes
: [ 'mw-rcfilters-ui-savedLinksListItemWidget-input' ]
72 this.saveButton
= new OO
.ui
.ButtonWidget( {
74 flags
: [ 'primary', 'progressive' ]
76 this.toggleEdit( false );
79 this.model
.connect( this, { update
: 'onModelUpdate' } );
80 this.popupButton
.connect( this, { click
: 'onPopupButtonClick' } );
81 this.menu
.connect( this, {
82 choose
: 'onMenuChoose'
84 this.saveButton
.connect( this, { click
: 'save' } );
85 this.editInput
.connect( this, {
86 change
: 'onInputChange',
89 this.editInput
.$input
.on( {
90 blur
: this.onInputBlur
.bind( this ),
91 keyup
: this.onInputKeyup
.bind( this )
93 this.$element
.on( { click
: this.onClick
.bind( this ) } );
94 this.$label
.on( { click
: this.onClick
.bind( this ) } );
95 // Prevent propagation on mousedown for the save button
96 // so the menu doesn't close
97 this.saveButton
.$element
.on( { mousedown: function () { return false; } } );
100 this.toggleDefault( !!this.model
.isDefault() );
101 this.$overlay
.append( this.menu
.$element
);
103 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget' )
104 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-query-' + this.model
.getID() )
107 .addClass( 'mw-rcfilters-ui-table' )
110 .addClass( 'mw-rcfilters-ui-row' )
113 .addClass( 'mw-rcfilters-ui-cell' )
114 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-content' )
117 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-label' ),
118 this.editInput
.$element
,
119 this.saveButton
.$element
122 .addClass( 'mw-rcfilters-ui-cell' )
123 .addClass( 'mw-rcfilters-ui-savedLinksListItemWidget-icon' )
124 .append( this.$icon
),
125 this.popupButton
.$element
126 .addClass( 'mw-rcfilters-ui-cell' )
133 OO
.inheritClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.Widget
);
134 OO
.mixinClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.mixin
.LabelElement
);
135 OO
.mixinClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.mixin
.IconElement
);
136 OO
.mixinClass( mw
.rcfilters
.ui
.SavedLinksListItemWidget
, OO
.ui
.mixin
.TitledElement
);
143 * The delete option was selected for this item
148 * @param {boolean} default Item is default
150 * The 'make default' option was selected for this item
155 * @param {string} newLabel New label for the query
157 * The label has been edited
163 * Respond to model update event
165 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onModelUpdate = function () {
166 this.setLabel( this.model
.getLabel() );
167 this.toggleDefault( this.model
.isDefault() );
171 * Respond to click on the element or label
175 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onClick = function () {
176 if ( !this.editing
) {
177 this.emit( 'click' );
181 * Respond to popup button click event
183 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onPopupButtonClick = function () {
188 * Respond to menu choose event
190 * @param {OO.ui.MenuOptionWidget} item Chosen item
194 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onMenuChoose = function ( item
) {
195 var action
= item
.getData();
197 if ( action
=== 'edit' ) {
198 this.toggleEdit( true );
199 } else if ( action
=== 'delete' ) {
200 this.emit( 'delete' );
201 } else if ( action
=== 'default' ) {
202 this.emit( 'default', !this.default );
205 this.menu
.selectItem( null );
207 this.menu
.toggle( false );
211 * Respond to input keyup event, this is the way to intercept 'escape' key
213 * @param {jQuery.Event} e Event data
214 * @returns {boolean} false
216 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onInputKeyup = function ( e
) {
217 if ( e
.which
=== OO
.ui
.Keys
.ESCAPE
) {
218 // Return the input to the original label
219 this.editInput
.setValue( this.getLabel() );
220 this.toggleEdit( false );
226 * Respond to blur event on the input
228 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onInputBlur = function () {
231 // Whether the save succeeded or not, the input-blur event
232 // means we need to cancel editing mode
233 this.toggleEdit( false );
237 * Respond to input change event
239 * @param {string} value Input value
241 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.onInputChange = function ( value
) {
242 value
= value
.trim();
244 this.saveButton
.setDisabled( !value
);
248 * Save the name of the query
250 * @param {string} [value] The value to save
253 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.save = function () {
254 var value
= this.editInput
.getValue().trim();
257 this.emit( 'edit', value
);
258 this.toggleEdit( false );
263 * Toggle edit mode on this widget
265 * @param {boolean} isEdit Widget is in edit mode
267 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.toggleEdit = function ( isEdit
) {
268 isEdit
= isEdit
=== undefined ? !this.editing
: isEdit
;
270 if ( this.editing
!== isEdit
) {
271 this.$element
.toggleClass( 'mw-rcfilters-ui-savedLinksListItemWidget-edit', isEdit
);
272 this.editInput
.setValue( this.getLabel() );
274 this.editInput
.toggle( isEdit
);
275 this.$label
.toggleClass( 'oo-ui-element-hidden', isEdit
);
276 this.$icon
.toggleClass( 'oo-ui-element-hidden', isEdit
);
277 this.popupButton
.toggle( !isEdit
);
278 this.saveButton
.toggle( isEdit
);
281 this.editInput
.$input
.focus();
283 this.editing
= isEdit
;
288 * Toggle default this widget
290 * @param {boolean} isDefault This item is default
292 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.toggleDefault = function ( isDefault
) {
293 isDefault
= isDefault
=== undefined ? !this.default : isDefault
;
295 if ( this.default !== isDefault
) {
296 this.default = isDefault
;
297 this.setIcon( this.default ? 'pushPin' : '' );
298 this.menu
.getItemFromData( 'default' ).setLabel(
300 mw
.msg( 'rcfilters-savedqueries-unsetdefault' ) :
301 mw
.msg( 'rcfilters-savedqueries-setdefault' )
309 * @returns {string} Query identifier
311 mw
.rcfilters
.ui
.SavedLinksListItemWidget
.prototype.getID = function () {
312 return this.model
.getID();