# all files / src/mixins/ LabelElement.js

98% Statements 49/50
97.44% Branches 38/39
100% Functions 7/7
98% Lines 49/50

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191

    1×

    35745×

    35745×
    35745×

    35745×
    35745×

    1×

    1×

    1×
    4×

    4×
    1×
    1×
    1×
    10×
    1×

    3×

    4×
    2×

    2×

    4×

    1×
    35745×

    35745×
    35745×

    1×
    36076×
    36076×

    36076×
    6487×
    319×

    6487×
    6487×

    36076×

    36076×

    1×
    4×

    1×
    321×

    1×
    36064×
    5569×

    916×

    4653×

    30495×
    912×
    29583×
    6×

    29577×

     /**
     * LabelElement is often mixed into other classes to generate a label, which
     * helps identify the function of an interface element.
     * See the [OOjs UI documentation on MediaWiki] [1] for more information.
     *
     * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels
     *
     * @abstract
     * @class
     *
     * @constructor
     * @param {Object} [config] Configuration options
     * @cfg {jQuery} [$label] The label element created by the class. If this
     *  configuration is omitted, the label element will use a generated `<span>`.
     * @cfg {jQuery|string|Function|OO.ui.HtmlSnippet} [label] The label text. The label can be specified
     *  as a plaintext string, a jQuery selection of elements, or a function that will produce a string
     *  in the future. See the [OOjs UI documentation on MediaWiki] [2] for examples.
     *  [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Icons,_Indicators,_and_Labels#Labels
     */
    OO.ui.mixin.LabelElement = function OoUiMixinLabelElement( config ) {
    	// Configuration initialization
    	config = config || {};

    	// Properties
    	this.$label = null;
    	this.label = null;

    	// Initialization
    	this.setLabel( config.label || this.constructor.static.label );
    	this.setLabelElement( config.$label || $( '<span>' ) );
    };

    /* Setup */

    OO.initClass( OO.ui.mixin.LabelElement );

    /* Events */

    /**
     * @event labelChange
     * @param {string} value
     */

    /* Static Properties */

    /**
     * The label text. The label can be specified as a plaintext string, a function that will
     * produce a string in the future, or `null` for no label. The static value will
     * be overridden if a label is specified with the #label config option.
     *
     * @static
     * @inheritable
     * @property {string|Function|null}
     */
    OO.ui.mixin.LabelElement.static.label = null;

    /* Static methods */

    /**
     * Highlight the first occurrence of the query in the given text
     *
     * @param {string} text Text
     * @param {string} query Query to find
     * @param {Function} [compare] Optional string comparator, e.g. Intl.Collator().compare
     * @return {jQuery} Text with the first match of the query
     *  sub-string wrapped in highlighted span
     */
    OO.ui.mixin.LabelElement.static.highlightQuery = function ( text, query, compare ) {
    	var i, tLen, qLen,
    		offset = -1,
    		$result = $( '<span>' );

    	if ( compare ) {
    		tLen = text.length;
    		qLen = query.length;
    		for ( i = 0; offset === -1 && i <= tLen - qLen; i++ ) {
    			if ( compare( query, text.slice( i, i + qLen ) ) === 0 ) {
    				offset = i;
    			}
    		}
    	} else {
    		offset = text.toLowerCase().indexOf( query.toLowerCase() );
    	}

    	if ( !query.length || offset === -1 ) {
    		$result.text( text );
    	} else {
    		$result.append(
    			document.createTextNode( text.slice( 0, offset ) ),
    			$( '<span>' )
    				.addClass( 'oo-ui-labelElement-label-highlight' )
    				.text( text.slice( offset, offset + query.length ) ),
    			document.createTextNode( text.slice( offset + query.length ) )
    		);
    	}
    	return $result.contents();
    };

    /* Methods */

    /**
     * Set the label element.
     *
     * If an element is already set, it will be cleaned up before setting up the new element.
     *
     * @param {jQuery} $label Element to use as label
     */
    OO.ui.mixin.LabelElement.prototype.setLabelElement = function ( $label ) {
    	Iif ( this.$label ) {
    		this.$label.removeClass( 'oo-ui-labelElement-label' ).empty();
    	}

    	this.$label = $label.addClass( 'oo-ui-labelElement-label' );
    	this.setLabelContent( this.label );
    };

    /**
     * Set the label.
     *
     * An empty string will result in the label being hidden. A string containing only whitespace will
     * be converted to a single `&nbsp;`.
     *
     * @param {jQuery|string|OO.ui.HtmlSnippet|Function|null} label Label nodes; text; a function that returns nodes or
     *  text; or null for no label
     * @chainable
     */
    OO.ui.mixin.LabelElement.prototype.setLabel = function ( label ) {
    	label = typeof label === 'function' ? OO.ui.resolveMsg( label ) : label;
    	label = ( ( typeof label === 'string' || label instanceof jQuery ) && label.length ) || ( label instanceof OO.ui.HtmlSnippet && label.toString().length ) ? label : null;

    	if ( this.label !== label ) {
    		if ( this.$label ) {
    			this.setLabelContent( label );
    		}
    		this.label = label;
    		this.emit( 'labelChange' );
    	}

    	this.$element.toggleClass( 'oo-ui-labelElement', !!this.label );

    	return this;
    };

    /**
     * Set the label as plain text with a highlighted query
     *
     * @param {string} text Text label to set
     * @param {string} query Substring of text to highlight
     * @param {Function} [compare] Optional string comparator, e.g. Intl.Collator().compare
     * @chainable
     */
    OO.ui.mixin.LabelElement.prototype.setHighlightedQuery = function ( text, query, compare ) {
    	return this.setLabel( this.constructor.static.highlightQuery( text, query, compare ) );
    };

    /**
     * Get the label.
     *
     * @return {jQuery|string|Function|null} Label nodes; text; a function that returns nodes or
     *  text; or null for no label
     */
    OO.ui.mixin.LabelElement.prototype.getLabel = function () {
    	return this.label;
    };

    /**
     * Set the content of the label.
     *
     * Do not call this method until after the label element has been set by #setLabelElement.
     *
     * @private
     * @param {jQuery|string|Function|null} label Label nodes; text; a function that returns nodes or
     *  text; or null for no label
     */
    OO.ui.mixin.LabelElement.prototype.setLabelContent = function ( label ) {
    	if ( typeof label === 'string' ) {
    		if ( label.match( /^\s*$/ ) ) {
    			// Convert whitespace only string to a single non-breaking space
    			this.$label.html( '&nbsp;' );
    		} else {
    			this.$label.text( label );
    		}
    	} else if ( label instanceof OO.ui.HtmlSnippet ) {
    		this.$label.html( label.toString() );
    	} else if ( label instanceof jQuery ) {
    		this.$label.empty().append( label );
    	} else {
    		this.$label.empty();
    	}
    };