RCFilters UI: Prevent label from stealing focus on click
[lhc/web/wiklou.git] / resources / src / mediawiki.rcfilters / ui / mw.rcfilters.ui.FilterMenuOptionWidget.js
1 ( function ( mw ) {
2 /**
3 * A widget representing a single toggle filter
4 *
5 * @extends OO.ui.MenuOptionWidget
6 *
7 * @constructor
8 * @param {mw.rcfilters.Controller} controller RCFilters controller
9 * @param {mw.rcfilters.dm.FilterItem} model Filter item model
10 * @param {Object} config Configuration object
11 */
12 mw.rcfilters.ui.FilterMenuOptionWidget = function MwRcfiltersUiFilterMenuOptionWidget( controller, model, config ) {
13 var layout,
14 $label = $( '<div>' )
15 .addClass( 'mw-rcfilters-ui-filterMenuOptionWidget-label' );
16
17 config = config || {};
18
19 this.controller = controller;
20 this.model = model;
21
22 // Parent
23 mw.rcfilters.ui.FilterMenuOptionWidget.parent.call( this, $.extend( {
24 // Override the 'check' icon that OOUI defines
25 icon: '',
26 data: this.model.getName(),
27 label: this.model.getLabel()
28 }, config ) );
29
30 this.checkboxWidget = new mw.rcfilters.ui.CheckboxInputWidget( {
31 value: this.model.getName(),
32 selected: this.model.isSelected()
33 } );
34
35 $label.append(
36 $( '<div>' )
37 .addClass( 'mw-rcfilters-ui-filterMenuOptionWidget-label-title' )
38 .append( this.$label )
39 );
40 if ( this.model.getDescription() ) {
41 $label.append(
42 $( '<div>' )
43 .addClass( 'mw-rcfilters-ui-filterMenuOptionWidget-label-desc' )
44 .text( this.model.getDescription() )
45 );
46 }
47
48 this.highlightButton = new mw.rcfilters.ui.FilterItemHighlightButton(
49 this.controller,
50 this.model,
51 {
52 $overlay: config.$overlay || this.$element,
53 title: mw.msg( 'rcfilters-highlightmenu-help' )
54 }
55 );
56 this.highlightButton.toggle( this.model.isHighlightEnabled() );
57
58 layout = new OO.ui.FieldLayout( this.checkboxWidget, {
59 label: $label,
60 align: 'inline'
61 } );
62 // Event
63 this.model.connect( this, { update: 'onModelUpdate' } );
64 this.model.getGroupModel().connect( this, { update: 'onGroupModelUpdate' } );
65 // HACK: Prevent defaults on 'click' for the label so it
66 // doesn't steal the focus away from the input. This means
67 // we can continue arrow-movement after we click the label
68 // and is consistent with the checkbox *itself* also preventing
69 // defaults on 'click' as well.
70 layout.$label.on( 'click', false );
71
72 this.$element
73 .addClass( 'mw-rcfilters-ui-filterMenuOptionWidget' )
74 .append(
75 $( '<div>' )
76 .addClass( 'mw-rcfilters-ui-table' )
77 .append(
78 $( '<div>' )
79 .addClass( 'mw-rcfilters-ui-row' )
80 .append(
81 $( '<div>' )
82 .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-filterMenuOptionWidget-filterCheckbox' )
83 .append( layout.$element ),
84 $( '<div>' )
85 .addClass( 'mw-rcfilters-ui-cell mw-rcfilters-ui-filterMenuOptionWidget-highlightButton' )
86 .append( this.highlightButton.$element )
87 )
88 )
89 );
90 };
91
92 /* Initialization */
93
94 OO.inheritClass( mw.rcfilters.ui.FilterMenuOptionWidget, OO.ui.MenuOptionWidget );
95
96 /* Static properties */
97
98 // We do our own scrolling to top
99 mw.rcfilters.ui.FilterMenuOptionWidget.static.scrollIntoViewOnSelect = false;
100
101 /* Methods */
102
103 /**
104 * Respond to item model update event
105 */
106 mw.rcfilters.ui.FilterMenuOptionWidget.prototype.onModelUpdate = function () {
107 this.checkboxWidget.setSelected( this.model.isSelected() );
108
109 this.setCurrentMuteState();
110 };
111
112 /**
113 * Respond to item group model update event
114 */
115 mw.rcfilters.ui.FilterMenuOptionWidget.prototype.onGroupModelUpdate = function () {
116 this.setCurrentMuteState();
117 };
118
119 /**
120 * Set the current mute state for this item
121 */
122 mw.rcfilters.ui.FilterMenuOptionWidget.prototype.setCurrentMuteState = function () {
123 this.$element.toggleClass(
124 'mw-rcfilters-ui-filterMenuOptionWidget-muted',
125 this.model.isConflicted() ||
126 (
127 // Item is also muted when any of the items in its group is active
128 this.model.getGroupModel().isActive() &&
129 // But it isn't selected
130 !this.model.isSelected() &&
131 // And also not included
132 !this.model.isIncluded()
133 )
134 );
135
136 this.highlightButton.toggle( this.model.isHighlightEnabled() );
137 };
138
139 /**
140 * Get the name of this filter
141 *
142 * @return {string} Filter name
143 */
144 mw.rcfilters.ui.FilterMenuOptionWidget.prototype.getName = function () {
145 return this.model.getName();
146 };
147
148 mw.rcfilters.ui.FilterMenuOptionWidget.prototype.getModel = function () {
149 return this.model;
150 };
151
152 }( mediaWiki ) );