]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.TagItemWidget.js
1 ( function ( mw, $ ) {
2         /**
3          * Extend OOUI's TagItemWidget to also display a popup on hover.
4          *
5          * @class
6          * @extends OO.ui.TagItemWidget
7          * @mixins OO.ui.mixin.PopupElement
8          *
9          * @constructor
10          * @param {mw.rcfilters.Controller} controller
11          * @param {mw.rcfilters.dm.FilterItem} model Item model
12          * @param {Object} config Configuration object
13          * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
14          */
15         mw.rcfilters.ui.TagItemWidget = function MwRcfiltersUiTagItemWidget( controller, model, config ) {
16                 // Configuration initialization
17                 config = config || {};
18
19                 this.controller = controller;
20                 this.model = model;
21                 this.selected = false;
22
23                 mw.rcfilters.ui.TagItemWidget.parent.call( this, $.extend( {
24                         data: this.model.getName(),
25                         label: $( '<div>' ).html( this.model.getPrefixedLabel() ).contents()
26                 }, config ) );
27
28                 this.$overlay = config.$overlay || this.$element;
29                 this.popupLabel = new OO.ui.LabelWidget();
30
31                 // Mixin constructors
32                 OO.ui.mixin.PopupElement.call( this, $.extend( {
33                         popup: {
34                                 padded: false,
35                                 align: 'center',
36                                 position: 'above',
37                                 $content: $( '<div>' )
38                                         .addClass( 'mw-rcfilters-ui-tagItemWidget-popup-content' )
39                                         .append( this.popupLabel.$element ),
40                                 $floatableContainer: this.$element,
41                                 classes: [ 'mw-rcfilters-ui-tagItemWidget-popup' ]
42                         }
43                 }, config ) );
44
45                 this.popupTimeoutShow = null;
46                 this.popupTimeoutHide = null;
47
48                 this.$highlight = $( '<div>' )
49                         .addClass( 'mw-rcfilters-ui-tagItemWidget-highlight' );
50
51                 // Add title attribute with the item label to 'x' button
52                 this.closeButton.setTitle( mw.msg( 'rcfilters-tag-remove', this.model.getLabel() ) );
53
54                 // Events
55                 this.model.connect( this, { update: 'onModelUpdate' } );
56
57                 // Initialization
58                 this.$overlay.append( this.popup.$element );
59                 this.$element
60                         .addClass( 'mw-rcfilters-ui-tagItemWidget' )
61                         .prepend( this.$highlight )
62                         .attr( 'aria-haspopup', 'true' )
63                         .on( 'mouseenter', this.onMouseEnter.bind( this ) )
64                         .on( 'mouseleave', this.onMouseLeave.bind( this ) );
65
66                 this.setCurrentMuteState();
67                 this.setHighlightColor();
68         };
69
70         /* Initialization */
71
72         OO.inheritClass( mw.rcfilters.ui.TagItemWidget, OO.ui.TagItemWidget );
73         OO.mixinClass( mw.rcfilters.ui.TagItemWidget, OO.ui.mixin.PopupElement );
74
75         /* Methods */
76
77         /**
78          * Respond to model update event
79          */
80         mw.rcfilters.ui.TagItemWidget.prototype.onModelUpdate = function () {
81                 this.setCurrentMuteState();
82
83                 // Update label if needed
84                 this.setLabel( $( '<div>' ).html( this.model.getPrefixedLabel() ).contents() );
85
86                 this.setHighlightColor();
87         };
88
89         mw.rcfilters.ui.TagItemWidget.prototype.setHighlightColor = function () {
90                 var selectedColor = this.model.isHighlightEnabled() ? this.model.getHighlightColor() : null;
91
92                 this.$highlight
93                         .attr( 'data-color', selectedColor )
94                         .toggleClass(
95                                 'mw-rcfilters-ui-tagItemWidget-highlight-highlighted',
96                                 !!selectedColor
97                         );
98         };
99
100         /**
101          * Set the current mute state for this item
102          */
103         mw.rcfilters.ui.TagItemWidget.prototype.setCurrentMuteState = function () {};
104
105         /**
106          * Respond to mouse enter event
107          */
108         mw.rcfilters.ui.TagItemWidget.prototype.onMouseEnter = function () {
109                 var labelText = this.model.getStateMessage();
110
111                 if ( labelText ) {
112                         this.popupLabel.setLabel( labelText );
113
114                         // Set timeout for the popup to show
115                         this.popupTimeoutShow = setTimeout( function () {
116                                 this.popup.toggle( true );
117                         }.bind( this ), 500 );
118
119                         // Cancel the hide timeout
120                         clearTimeout( this.popupTimeoutHide );
121                         this.popupTimeoutHide = null;
122                 }
123         };
124
125         /**
126          * Respond to mouse leave event
127          */
128         mw.rcfilters.ui.TagItemWidget.prototype.onMouseLeave = function () {
129                 this.popupTimeoutHide = setTimeout( function () {
130                         this.popup.toggle( false );
131                 }.bind( this ), 250 );
132
133                 // Clear the show timeout
134                 clearTimeout( this.popupTimeoutShow );
135                 this.popupTimeoutShow = null;
136         };
137
138         /**
139          * Set selected state on this widget
140          *
141          * @param {boolean} [isSelected] Widget is selected
142          */
143         mw.rcfilters.ui.TagItemWidget.prototype.toggleSelected = function ( isSelected ) {
144                 isSelected = isSelected !== undefined ? isSelected : !this.selected;
145
146                 if ( this.selected !== isSelected ) {
147                         this.selected = isSelected;
148
149                         this.$element.toggleClass( 'mw-rcfilters-ui-tagItemWidget-selected', this.selected );
150                 }
151         };
152
153         /**
154          * Get the selected state of this widget
155          *
156          * @return {boolean} Tag is selected
157          */
158         mw.rcfilters.ui.TagItemWidget.prototype.isSelected = function () {
159                 return this.selected;
160         };
161
162         /**
163          * Get item name
164          *
165          * @return {string} Filter name
166          */
167         mw.rcfilters.ui.TagItemWidget.prototype.getName = function () {
168                 return this.model.getName();
169         };
170
171         /**
172          * Get item model
173          *
174          * @return {string} Filter model
175          */
176         mw.rcfilters.ui.TagItemWidget.prototype.getModel = function () {
177                 return this.model;
178         };
179
180         /**
181          * Get item view
182          *
183          * @return {string} Filter view
184          */
185         mw.rcfilters.ui.TagItemWidget.prototype.getView = function () {
186                 return this.model.getGroupModel().getView();
187         };
188
189         /**
190          * Remove and destroy external elements of this widget
191          */
192         mw.rcfilters.ui.TagItemWidget.prototype.destroy = function () {
193                 // Destroy the popup
194                 this.popup.$element.detach();
195
196                 // Disconnect events
197                 this.model.disconnect( this );
198                 this.closeButton.disconnect( this );
199         };
200 }( mediaWiki, jQuery ) );