diff -r 490d5cc509ed -r cf61fcea0001 wp/wp-admin/js/color-picker.js --- a/wp/wp-admin/js/color-picker.js Tue Jun 09 11:14:17 2015 +0000 +++ b/wp/wp-admin/js/color-picker.js Mon Oct 14 17:39:30 2019 +0200 @@ -1,14 +1,21 @@ /* global wpColorPickerL10n */ -( function( $, undef ){ +( function( $, undef ) { var ColorPicker, - // html stuff - _before = '', + _before = '', _after = '
', _wrap = '', - _button = ''; + _button = '', + _wrappingLabel = '', + _wrappingLabelText = ''; - // jQuery UI Widget constructor + /** + * @summary Creates a jQuery UI color picker. + * + * Creates a jQuery UI color picker that is used in the theme customizer. + * + * @since 3.5.0 + */ ColorPicker = { options: { defaultColor: false, @@ -17,10 +24,65 @@ hide: true, palettes: true, width: 255, - mode: 'hsv' + mode: 'hsv', + type: 'full', + slider: 'horizontal' }, + /** + * @summary Creates a color picker that only allows you to adjust the hue. + * + * @since 3.5.0 + * + * @access private + * + * @returns {void} + */ + _createHueOnly: function() { + var self = this, + el = self.element, + color; + + el.hide(); + + // Set the saturation to the maximum level. + color = 'hsl(' + el.val() + ', 100, 50)'; + + // Create an instance of the color picker, using the hsl mode. + el.iris( { + mode: 'hsl', + type: 'hue', + hide: false, + color: color, + /** + * @summary Handles the onChange event if one has been defined in the options. + * + * @param {Event} event The event that's being called. + * @param {HTMLElement} ui The HTMLElement containing the color picker. + * + * @returns {void} + */ + change: function( event, ui ) { + if ( $.isFunction( self.options.change ) ) { + self.options.change.call( this, event, ui ); + } + }, + width: self.options.width, + slider: self.options.slider + } ); + }, + /** + * @summary Creates the color picker. + * + * Creates the color picker, sets default values, css classes and wraps it all in HTML. + * + * @since 3.5.0 + * + * @access private + * + * @returns {void} + */ _create: function() { - // bail early for unsupported Iris. + // Return early if Iris support is missing. if ( ! $.support.iris ) { return; } @@ -28,27 +90,80 @@ var self = this, el = self.element; + // Override default options with options bound to the element. $.extend( self.options, el.data() ); - // keep close bound so it can be attached to a body listener + // Create a color picker which only allows adjustments to the hue. + if ( self.options.type === 'hue' ) { + return self._createHueOnly(); + } + + // Bind the close event. self.close = $.proxy( self.close, self ); self.initialValue = el.val(); - // Set up HTML structure, hide things - el.addClass( 'wp-color-picker' ).hide().wrap( _wrap ); - self.wrap = el.parent(); - self.toggler = $( _before ).insertBefore( el ).css( { backgroundColor: self.initialValue } ).attr( 'title', wpColorPickerL10n.pick ).attr( 'data-current', wpColorPickerL10n.current ); - self.pickerContainer = $( _after ).insertAfter( el ); + // Add a CSS class to the input field. + el.addClass( 'wp-color-picker' ); + + /* + * Check if there's already a wrapping label, e.g. in the Customizer. + * If there's no label, add a default one to match the Customizer template. + */ + if ( ! el.parent( 'label' ).length ) { + // Wrap the input field in the default label. + el.wrap( _wrappingLabel ); + // Insert the default label text. + self.wrappingLabelText = $( _wrappingLabelText ) + .insertBefore( el ) + .text( wpColorPickerL10n.defaultLabel ); + } + + /* + * At this point, either it's the standalone version or the Customizer + * one, we have a wrapping label to use as hook in the DOM, let's store it. + */ + self.wrappingLabel = el.parent(); + + // Wrap the label in the main wrapper. + self.wrappingLabel.wrap( _wrap ); + // Store a reference to the main wrapper. + self.wrap = self.wrappingLabel.parent(); + // Set up the toggle button and insert it before the wrapping label. + self.toggler = $( _before ) + .insertBefore( self.wrappingLabel ) + .css( { backgroundColor: self.initialValue } ); + // Set the toggle button span element text. + self.toggler.find( '.wp-color-result-text' ).text( wpColorPickerL10n.pick ); + // Set up the Iris container and insert it after the wrapping label. + self.pickerContainer = $( _after ).insertAfter( self.wrappingLabel ); + // Store a reference to the Clear/Default button. self.button = $( _button ); + // Set up the Clear/Default button. if ( self.options.defaultColor ) { - self.button.addClass( 'wp-picker-default' ).val( wpColorPickerL10n.defaultString ); + self.button + .addClass( 'wp-picker-default' ) + .val( wpColorPickerL10n.defaultString ) + .attr( 'aria-label', wpColorPickerL10n.defaultAriaLabel ); } else { - self.button.addClass( 'wp-picker-clear' ).val( wpColorPickerL10n.clear ); + self.button + .addClass( 'wp-picker-clear' ) + .val( wpColorPickerL10n.clear ) + .attr( 'aria-label', wpColorPickerL10n.clearAriaLabel ); } - el.wrap( '' ).after(self.button); + // Wrap the wrapping label in its wrapper and append the Clear/Default button. + self.wrappingLabel + .wrap( '' ) + .after( self.button ); + + /* + * The input wrapper now contains the label+input+Clear/Default button. + * Store a reference to the input wrapper: we'll use this to toggle + * the controls visibility. + */ + self.inputWrapper = el.closest( '.wp-picker-input-wrap' ); el.iris( { target: self.pickerContainer, @@ -56,9 +171,22 @@ width: self.options.width, mode: self.options.mode, palettes: self.options.palettes, + /** + * @summary Handles the onChange event if one has been defined in the options. + * + * Handles the onChange event if one has been defined in the options and additionally + * sets the background color for the toggler element. + * + * @since 3.5.0 + * + * @param {Event} event The event that's being called. + * @param {HTMLElement} ui The HTMLElement containing the color picker. + * + * @returns {void} + */ change: function( event, ui ) { self.toggler.css( { backgroundColor: ui.color.toString() } ); - // check for a custom cb + if ( $.isFunction( self.options.change ) ) { self.options.change.call( this, event, ui ); } @@ -67,18 +195,42 @@ el.val( self.initialValue ); self._addListeners(); + + // Force the color picker to always be closed on initial load. if ( ! self.options.hide ) { self.toggler.click(); } }, + /** + * @summary Binds event listeners to the color picker. + * + * @since 3.5.0 + * + * @access private + * + * @returns {void} + */ _addListeners: function() { var self = this; - // prevent any clicks inside this widget from leaking to the top and closing it + /** + * @summary Prevent any clicks inside this widget from leaking to the top and closing it. + * + * @since 3.5.0 + * + * @param {Event} event The event that's being called. + * + * @returs {void} + */ self.wrap.on( 'click.wpcolorpicker', function( event ) { event.stopPropagation(); }); + /** + * @summary Open or close the color picker depending on the class. + * + * @since 3.5 + */ self.toggler.click( function(){ if ( self.toggler.hasClass( 'wp-picker-open' ) ) { self.close(); @@ -87,27 +239,42 @@ } }); + /** + * @summary Checks if value is empty when changing the color in the color picker. + * + * Checks if value is empty when changing the color in the color picker. + * If so, the background color is cleared. + * + * @since 3.5.0 + * + * @param {Event} event The event that's being called. + * + * @returns {void} + */ self.element.change( function( event ) { var me = $( this ), val = me.val(); - // Empty = clear + if ( val === '' || val === '#' ) { self.toggler.css( 'backgroundColor', '' ); - // fire clear callback if we have one + // Fire clear callback if we have one. if ( $.isFunction( self.options.clear ) ) { self.options.clear.call( this, event ); } } }); - // open a keyboard-focused closed picker with space or enter - self.toggler.on( 'keyup', function( event ) { - if ( event.keyCode === 13 || event.keyCode === 32 ) { - event.preventDefault(); - self.toggler.trigger( 'click' ).next().focus(); - } - }); - + /** + * @summary Enables the user to clear or revert the color in the color picker. + * + * Enables the user to either clear the color in the color picker or revert back to the default color. + * + * @since 3.5.0 + * + * @param {Event} event The event that's being called. + * + * @returns {void} + */ self.button.click( function( event ) { var me = $( this ); if ( me.hasClass( 'wp-picker-clear' ) ) { @@ -121,29 +288,67 @@ } }); }, + /** + * @summary Opens the color picker dialog. + * + * @since 3.5.0 + * + * @returns {void} + */ open: function() { - this.element.show().iris( 'toggle' ).focus(); - this.button.removeClass( 'hidden' ); - this.toggler.addClass( 'wp-picker-open' ); + this.element.iris( 'toggle' ); + this.inputWrapper.removeClass( 'hidden' ); + this.wrap.addClass( 'wp-picker-active' ); + this.toggler + .addClass( 'wp-picker-open' ) + .attr( 'aria-expanded', 'true' ); $( 'body' ).trigger( 'click.wpcolorpicker' ).on( 'click.wpcolorpicker', this.close ); }, + /** + * @summary Closes the color picker dialog. + * + * @since 3.5.0 + * + * @returns {void} + */ close: function() { - this.element.hide().iris( 'toggle' ); - this.button.addClass( 'hidden' ); - this.toggler.removeClass( 'wp-picker-open' ); + this.element.iris( 'toggle' ); + this.inputWrapper.addClass( 'hidden' ); + this.wrap.removeClass( 'wp-picker-active' ); + this.toggler + .removeClass( 'wp-picker-open' ) + .attr( 'aria-expanded', 'false' ); $( 'body' ).off( 'click.wpcolorpicker', this.close ); }, - // $("#input").wpColorPicker('color') returns the current color - // $("#input").wpColorPicker('color', '#bada55') to set + /** + * @summary Returns iris object or sets new color. + * + * Returns the iris object if no new color is provided. If a new color is provided, it sets the new color. + * + * @param newColor {string|*} The new color to use. Can be undefined. + * + * @since 3.5.0 + * + * @returns {string} The element's color + */ color: function( newColor ) { if ( newColor === undef ) { return this.element.iris( 'option', 'color' ); } - this.element.iris( 'option', 'color', newColor ); }, - //$("#input").wpColorPicker('defaultColor') returns the current default color - //$("#input").wpColorPicker('defaultColor', newDefaultColor) to set + /** + * @summary Returns iris object or sets new default color. + * + * Returns the iris object if no new default color is provided. + * If a new default color is provided, it sets the new default color. + * + * @param newDefaultColor {string|*} The new default color to use. Can be undefined. + * + * @since 3.5.0 + * + * @returns {boolean|string} The element's color. + */ defaultColor: function( newDefaultColor ) { if ( newDefaultColor === undef ) { return this.options.defaultColor; @@ -153,5 +358,6 @@ } }; + // Register the color picker as a widget. $.widget( 'wp.wpColorPicker', ColorPicker ); }( jQuery ) );