summaryrefslogtreecommitdiff
path: root/www/wiki/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js')
-rw-r--r--www/wiki/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js223
1 files changed, 223 insertions, 0 deletions
diff --git a/www/wiki/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js b/www/wiki/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js
new file mode 100644
index 00000000..188650a9
--- /dev/null
+++ b/www/wiki/resources/src/mediawiki.rcfilters/ui/mw.rcfilters.ui.TagItemWidget.js
@@ -0,0 +1,223 @@
+( function ( mw, $ ) {
+ /**
+ * Extend OOUI's TagItemWidget to also display a popup on hover.
+ *
+ * @class
+ * @extends OO.ui.TagItemWidget
+ * @mixins OO.ui.mixin.PopupElement
+ *
+ * @constructor
+ * @param {mw.rcfilters.Controller} controller
+ * @param {mw.rcfilters.dm.FiltersViewModel} filtersViewModel
+ * @param {mw.rcfilters.dm.FilterItem} invertModel
+ * @param {mw.rcfilters.dm.FilterItem} itemModel Item model
+ * @param {Object} config Configuration object
+ * @cfg {jQuery} [$overlay] A jQuery object serving as overlay for popups
+ */
+ mw.rcfilters.ui.TagItemWidget = function MwRcfiltersUiTagItemWidget(
+ controller, filtersViewModel, invertModel, itemModel, config
+ ) {
+ // Configuration initialization
+ config = config || {};
+
+ this.controller = controller;
+ this.invertModel = invertModel;
+ this.filtersViewModel = filtersViewModel;
+ this.itemModel = itemModel;
+ this.selected = false;
+
+ mw.rcfilters.ui.TagItemWidget.parent.call( this, $.extend( {
+ data: this.itemModel.getName()
+ }, config ) );
+
+ this.$overlay = config.$overlay || this.$element;
+ this.popupLabel = new OO.ui.LabelWidget();
+
+ // Mixin constructors
+ OO.ui.mixin.PopupElement.call( this, $.extend( {
+ popup: {
+ padded: false,
+ align: 'center',
+ position: 'above',
+ $content: $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-tagItemWidget-popup-content' )
+ .append( this.popupLabel.$element ),
+ $floatableContainer: this.$element,
+ classes: [ 'mw-rcfilters-ui-tagItemWidget-popup' ]
+ }
+ }, config ) );
+
+ this.popupTimeoutShow = null;
+ this.popupTimeoutHide = null;
+
+ this.$highlight = $( '<div>' )
+ .addClass( 'mw-rcfilters-ui-tagItemWidget-highlight' );
+
+ // Add title attribute with the item label to 'x' button
+ this.closeButton.setTitle( mw.msg( 'rcfilters-tag-remove', this.itemModel.getLabel() ) );
+
+ // Events
+ this.filtersViewModel.connect( this, { highlightChange: 'updateUiBasedOnState' } );
+ this.invertModel.connect( this, { update: 'updateUiBasedOnState' } );
+ this.itemModel.connect( this, { update: 'updateUiBasedOnState' } );
+
+ // Initialization
+ this.$overlay.append( this.popup.$element );
+ this.$element
+ .addClass( 'mw-rcfilters-ui-tagItemWidget' )
+ .prepend( this.$highlight )
+ .attr( 'aria-haspopup', 'true' )
+ .on( 'mouseenter', this.onMouseEnter.bind( this ) )
+ .on( 'mouseleave', this.onMouseLeave.bind( this ) );
+
+ this.updateUiBasedOnState();
+ };
+
+ /* Initialization */
+
+ OO.inheritClass( mw.rcfilters.ui.TagItemWidget, OO.ui.TagItemWidget );
+ OO.mixinClass( mw.rcfilters.ui.TagItemWidget, OO.ui.mixin.PopupElement );
+
+ /* Methods */
+
+ /**
+ * Respond to model update event
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.updateUiBasedOnState = function () {
+ // Update label if needed
+ var labelMsg = this.itemModel.getLabelMessageKey( this.invertModel.isSelected() );
+ if ( labelMsg ) {
+ this.setLabel( $( '<div>' ).append(
+ $( '<bdi>' ).html(
+ mw.message( labelMsg, mw.html.escape( this.itemModel.getLabel() ) ).parse()
+ )
+ ).contents() );
+ } else {
+ this.setLabel(
+ $( '<bdi>' ).append(
+ this.itemModel.getLabel()
+ )
+ );
+ }
+
+ this.setCurrentMuteState();
+ this.setHighlightColor();
+ };
+
+ /**
+ * Set the current highlight color for this item
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.setHighlightColor = function () {
+ var selectedColor = this.filtersViewModel.isHighlightEnabled() && this.itemModel.isHighlighted ?
+ this.itemModel.getHighlightColor() :
+ null;
+
+ this.$highlight
+ .attr( 'data-color', selectedColor )
+ .toggleClass(
+ 'mw-rcfilters-ui-tagItemWidget-highlight-highlighted',
+ !!selectedColor
+ );
+ };
+
+ /**
+ * Set the current mute state for this item
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.setCurrentMuteState = function () {};
+
+ /**
+ * Respond to mouse enter event
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.onMouseEnter = function () {
+ var labelText = this.itemModel.getStateMessage();
+
+ if ( labelText ) {
+ this.popupLabel.setLabel( labelText );
+
+ // Set timeout for the popup to show
+ this.popupTimeoutShow = setTimeout( function () {
+ this.popup.toggle( true );
+ }.bind( this ), 500 );
+
+ // Cancel the hide timeout
+ clearTimeout( this.popupTimeoutHide );
+ this.popupTimeoutHide = null;
+ }
+ };
+
+ /**
+ * Respond to mouse leave event
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.onMouseLeave = function () {
+ this.popupTimeoutHide = setTimeout( function () {
+ this.popup.toggle( false );
+ }.bind( this ), 250 );
+
+ // Clear the show timeout
+ clearTimeout( this.popupTimeoutShow );
+ this.popupTimeoutShow = null;
+ };
+
+ /**
+ * Set selected state on this widget
+ *
+ * @param {boolean} [isSelected] Widget is selected
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.toggleSelected = function ( isSelected ) {
+ isSelected = isSelected !== undefined ? isSelected : !this.selected;
+
+ if ( this.selected !== isSelected ) {
+ this.selected = isSelected;
+
+ this.$element.toggleClass( 'mw-rcfilters-ui-tagItemWidget-selected', this.selected );
+ }
+ };
+
+ /**
+ * Get the selected state of this widget
+ *
+ * @return {boolean} Tag is selected
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.isSelected = function () {
+ return this.selected;
+ };
+
+ /**
+ * Get item name
+ *
+ * @return {string} Filter name
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.getName = function () {
+ return this.itemModel.getName();
+ };
+
+ /**
+ * Get item model
+ *
+ * @return {string} Filter model
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.getModel = function () {
+ return this.itemModel;
+ };
+
+ /**
+ * Get item view
+ *
+ * @return {string} Filter view
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.getView = function () {
+ return this.itemModel.getGroupModel().getView();
+ };
+
+ /**
+ * Remove and destroy external elements of this widget
+ */
+ mw.rcfilters.ui.TagItemWidget.prototype.destroy = function () {
+ // Destroy the popup
+ this.popup.$element.detach();
+
+ // Disconnect events
+ this.itemModel.disconnect( this );
+ this.closeButton.disconnect( this );
+ };
+}( mediaWiki, jQuery ) );