636 lines
16 KiB
JavaScript
636 lines
16 KiB
JavaScript
/**!
|
|
* wp-color-picker-alpha
|
|
*
|
|
* Overwrite Automattic Iris for enabled Alpha Channel in wpColorPicker
|
|
* Only run in input and is defined data alpha in true
|
|
*
|
|
* Version: 3.0.0
|
|
* https://github.com/kallookoo/wp-color-picker-alpha
|
|
* Licensed under the GPLv2 license or later.
|
|
*/
|
|
|
|
( function( $, undef ) {
|
|
|
|
var wpColorPickerAlpha = {
|
|
'version' : 300
|
|
};
|
|
|
|
// Always try to use the last version of this script.
|
|
if ( 'wpColorPickerAlpha' in window && 'version' in window.wpColorPickerAlpha ) {
|
|
var version = parseInt( window.wpColorPickerAlpha.version, 10 );
|
|
if ( ! isNaN( version ) && version >= wpColorPickerAlpha.version ) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Prevent multiple initiations
|
|
if ( Color.fn.hasOwnProperty( 'to_s' ) ) {
|
|
return;
|
|
}
|
|
|
|
// Create new method to replace the `Color.toString()` inside the scripts.
|
|
Color.fn.to_s = function( type ) {
|
|
type = ( type || 'hex' );
|
|
// Change hex to rgba to return the correct color.
|
|
if ( 'hex' === type && this._alpha < 1 ) {
|
|
type = 'rgba';
|
|
}
|
|
|
|
var color = '';
|
|
if ( 'hex' === type ) {
|
|
color = this.toString();
|
|
} else if ( ! this.error ) {
|
|
color = this.toCSS( type ).replace( /\(\s+/, '(' ).replace( /\s+\)/, ')' );
|
|
}
|
|
return color;
|
|
}
|
|
|
|
// Register the global variable.
|
|
window.wpColorPickerAlpha = wpColorPickerAlpha;
|
|
|
|
// Background image encoded
|
|
var backgroundImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==';
|
|
|
|
/**
|
|
* Iris
|
|
*/
|
|
$.widget( 'a8c.iris', $.a8c.iris, {
|
|
/**
|
|
* Alpha options
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
alphaOptions: {
|
|
alphaEnabled: false,
|
|
},
|
|
/**
|
|
* Get the current color or the new color.
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @param {Object|*} The color instance if not defined return the cuurent color.
|
|
*
|
|
* @return {string} The element's color.
|
|
*/
|
|
_getColor: function( color ) {
|
|
if ( color === undef ) {
|
|
color = this._color;
|
|
}
|
|
|
|
if ( this.alphaOptions.alphaEnabled ) {
|
|
color = color.to_s( this.alphaOptions.alphaColorType );
|
|
if ( ! this.alphaOptions.alphaColorWithSpace ) {
|
|
color = color.replace( /\s+/g, '' );
|
|
}
|
|
return color;
|
|
}
|
|
return color.toString();
|
|
},
|
|
/**
|
|
* Create widget
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_create: function() {
|
|
try {
|
|
// Try to get the wpColorPicker alpha options.
|
|
this.alphaOptions = this.element.wpColorPicker( 'instance' ).alphaOptions;
|
|
} catch( e ) {}
|
|
|
|
// We make sure there are all options
|
|
$.extend( {}, this.alphaOptions, {
|
|
alphaEnabled: false,
|
|
alphaCustomWidth: 130,
|
|
alphaReset: false,
|
|
alphaColorType: 'hex',
|
|
alphaColorWithSpace: false,
|
|
} );
|
|
|
|
this._super();
|
|
},
|
|
/**
|
|
* Binds event listeners to the Iris.
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_addInputListeners: function( input ) {
|
|
var self = this,
|
|
debounceTimeout = 100,
|
|
callback = function( event ){
|
|
var val = input.val(),
|
|
color = new Color( val ),
|
|
val = val.replace( /^(#|(rgb|hsl)a?)/, '' ),
|
|
type = self.alphaOptions.alphaColorType;
|
|
|
|
input.removeClass( 'iris-error' );
|
|
|
|
if ( ! color.error ) {
|
|
// let's not do this on keyup for hex shortcodes
|
|
if ( 'hex' !== type || ! ( event.type === 'keyup' && val.match( /^[0-9a-fA-F]{3}$/ ) ) ) {
|
|
// Compare color ( #AARRGGBB )
|
|
if ( color.toIEOctoHex() !== self._color.toIEOctoHex() ) {
|
|
self._setOption( 'color', self._getColor( color ) );
|
|
}
|
|
}
|
|
} else if ( val !== '' ) {
|
|
input.addClass( 'iris-error' );
|
|
}
|
|
};
|
|
|
|
input.on( 'change', callback ).on( 'keyup', self._debounce( callback, debounceTimeout ) );
|
|
|
|
// If we initialized hidden, show on first focus. The rest is up to you.
|
|
if ( self.options.hide ) {
|
|
input.one( 'focus', function() {
|
|
self.show();
|
|
});
|
|
}
|
|
},
|
|
/**
|
|
* Init Controls
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_initControls: function() {
|
|
this._super();
|
|
|
|
if ( this.alphaOptions.alphaEnabled ) {
|
|
// Create Alpha controls
|
|
var self = this,
|
|
stripAlpha = self.controls.strip.clone(false, false),
|
|
stripAlphaSlider = stripAlpha.find( '.iris-slider-offset' ),
|
|
controls = {
|
|
stripAlpha : stripAlpha,
|
|
stripAlphaSlider : stripAlphaSlider
|
|
};
|
|
|
|
stripAlpha.addClass( 'iris-strip-alpha' );
|
|
stripAlphaSlider.addClass( 'iris-slider-offset-alpha' );
|
|
stripAlpha.appendTo( self.picker.find( '.iris-picker-inner' ) );
|
|
|
|
// Push new controls
|
|
$.each( controls, function( k, v ) {
|
|
self.controls[k] = v;
|
|
} );
|
|
|
|
// Create slider
|
|
self.controls.stripAlphaSlider.slider( {
|
|
orientation : 'vertical',
|
|
min : 0,
|
|
max : 100,
|
|
step : 1,
|
|
value : parseInt( self._color._alpha * 100 ),
|
|
slide : function( event, ui ) {
|
|
self.active = 'strip';
|
|
// Update alpha value
|
|
self._color._alpha = parseFloat( ui.value / 100 );
|
|
self._change.apply( self, arguments );
|
|
}
|
|
} );
|
|
}
|
|
},
|
|
/**
|
|
* Create the controls sizes
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @param {bool} reset Set to True for recreate the controls sizes.
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_dimensions: function( reset ) {
|
|
this._super( reset );
|
|
|
|
if ( this.alphaOptions.alphaEnabled ) {
|
|
var self = this,
|
|
opts = self.options,
|
|
controls = self.controls,
|
|
square = controls.square,
|
|
strip = self.picker.find( '.iris-strip' ),
|
|
innerWidth, squareWidth, stripWidth, stripMargin, totalWidth;
|
|
|
|
/**
|
|
* I use Math.round() to avoid possible size errors,
|
|
* this function returns the value of a number rounded
|
|
* to the nearest integer.
|
|
*
|
|
* The width to append all widgets,
|
|
* if border is enabled, 22 is subtracted.
|
|
* 20 for css left and right property
|
|
* 2 for css border
|
|
*/
|
|
innerWidth = Math.round( self.picker.outerWidth( true ) - ( opts.border ? 22 : 0 ) );
|
|
// The width of the draggable, aka square.
|
|
squareWidth = Math.round( square.outerWidth() );
|
|
// The width for the sliders
|
|
stripWidth = Math.round( ( innerWidth - squareWidth ) / 2 );
|
|
// The margin for the sliders
|
|
stripMargin = Math.round( stripWidth / 2 );
|
|
// The total width of the elements.
|
|
totalWidth = Math.round( squareWidth + ( stripWidth * 2 ) + ( stripMargin * 2 ) );
|
|
|
|
// Check and change if necessary.
|
|
while ( totalWidth > innerWidth ) {
|
|
stripWidth = Math.round( stripWidth - 2 );
|
|
stripMargin = Math.round( stripMargin - 1 );
|
|
totalWidth = Math.round( squareWidth + ( stripWidth * 2 ) + ( stripMargin * 2 ) );
|
|
}
|
|
|
|
|
|
square.css( 'margin', '0' );
|
|
strip.width( stripWidth ).css( 'margin-left', stripMargin + 'px' );
|
|
}
|
|
},
|
|
/**
|
|
* Callback to update the controls and the current color.
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_change: function() {
|
|
var self = this,
|
|
active = self.active;
|
|
|
|
self._super();
|
|
|
|
if ( self.alphaOptions.alphaEnabled ) {
|
|
var controls = self.controls,
|
|
alpha = parseInt( self._color._alpha * 100 ),
|
|
color = self._color.toRgb(),
|
|
gradient = [
|
|
'rgb(' + color.r + ',' + color.g + ',' + color.b + ') 0%',
|
|
'rgba(' + color.r + ',' + color.g + ',' + color.b + ', 0) 100%'
|
|
],
|
|
target = self.picker.closest( '.wp-picker-container' ).find( '.wp-color-result' );
|
|
|
|
self.options.color = self._getColor();
|
|
// Generate background slider alpha, only for CSS3.
|
|
controls.stripAlpha.css( { 'background' : 'linear-gradient(to bottom, ' + gradient.join( ', ' ) + '), url(' + backgroundImage + ')' } );
|
|
// Update alpha value
|
|
if ( active ) {
|
|
controls.stripAlphaSlider.slider( 'value', alpha );
|
|
}
|
|
|
|
if ( ! self._color.error ) {
|
|
self.element.removeClass( 'iris-error' ).val( self.options.color );
|
|
}
|
|
|
|
self.picker.find( '.iris-palette-container' ).on( 'click.palette', '.iris-palette', function() {
|
|
var color = $( this ).data( 'color' );
|
|
if ( self.alphaOptions.alphaReset ) {
|
|
self._color._alpha = 1;
|
|
color = self._getColor();
|
|
}
|
|
self._setOption( 'color', color );
|
|
} );
|
|
}
|
|
},
|
|
/**
|
|
* Paint dimensions.
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @param {string} origin Origin (position).
|
|
* @param {string} control Type of the control,
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_paintDimension: function( origin, control ) {
|
|
var self = this,
|
|
color = false;
|
|
|
|
// Fix for slider hue opacity.
|
|
if ( self.alphaOptions.alphaEnabled && 'strip' === control ) {
|
|
color = self._color;
|
|
self._color = new Color( color.toString() );
|
|
self.hue = self._color.h();
|
|
}
|
|
|
|
self._super( origin, control );
|
|
|
|
// Restore the color after paint.
|
|
if ( color ) {
|
|
self._color = color;
|
|
}
|
|
},
|
|
/**
|
|
* To update the options, see original source to view the available options.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param {string} key The Option name.
|
|
* @param {mixed} value The Option value to update.
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_setOption: function( key, value ) {
|
|
var self = this;
|
|
if ( 'color' === key && self.alphaOptions.alphaEnabled ) {
|
|
// cast to string in case we have a number
|
|
value = '' + value;
|
|
newColor = new Color( value ).setHSpace( self.options.mode );
|
|
// Check if error && Check the color to prevent callbacks with the same color.
|
|
if ( ! newColor.error && self._getColor( newColor ) !== self._getColor() ) {
|
|
self._color = newColor;
|
|
self.options.color = self._getColor();
|
|
self.active = 'external';
|
|
self._change();
|
|
}
|
|
} else {
|
|
return self._super( key, value );
|
|
}
|
|
},
|
|
/**
|
|
* 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.0.0
|
|
*
|
|
* @return {string} The element's color.
|
|
*/
|
|
color: function( newColor ) {
|
|
if ( newColor === true ) {
|
|
return this._color.clone();
|
|
}
|
|
if ( newColor === undef ) {
|
|
return this._getColor();
|
|
}
|
|
this.option( 'color', newColor );
|
|
},
|
|
} );
|
|
|
|
/**
|
|
* wpColorPicker
|
|
*/
|
|
$.widget( 'wp.wpColorPicker', $.wp.wpColorPicker, {
|
|
/**
|
|
* Alpha options
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @type {Object}
|
|
*/
|
|
alphaOptions: {
|
|
alphaEnabled: false,
|
|
},
|
|
/**
|
|
* Get the alpha options.
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {object} The current alpha options.
|
|
*/
|
|
_getAlphaOptions: function() {
|
|
var el = this.element,
|
|
type = ( el.data( 'type' ) || this.options.type ),
|
|
color = ( el.data( 'defaultColor' ) || el.val() ),
|
|
options = {
|
|
alphaEnabled: ( el.data( 'alphaEnabled' ) || false ),
|
|
alphaCustomWidth: 130,
|
|
alphaReset: false,
|
|
alphaColorType: 'rgb',
|
|
alphaColorWithSpace: false,
|
|
};
|
|
|
|
if ( options.alphaEnabled ) {
|
|
options.alphaEnabled = ( el.is( 'input' ) && 'full' === type );
|
|
}
|
|
|
|
if ( ! options.alphaEnabled ) {
|
|
return options;
|
|
}
|
|
|
|
options.alphaColorWithSpace = ( color && color.match( /\s/ ) );
|
|
|
|
$.each( options, function( name, defaultValue ) {
|
|
var value = ( el.data( name ) || defaultValue );
|
|
switch ( name ) {
|
|
case 'alphaCustomWidth':
|
|
value = ( value ? parseInt( value, 10 ) : 0 );
|
|
value = ( isNaN( value ) ? defaultValue : value );
|
|
break;
|
|
case 'alphaColorType':
|
|
if ( ! value.match( /^(hex|(rgb|hsl)a?)$/ ) ) {
|
|
if ( color && color.match( /^#/ ) ) {
|
|
value = 'hex';
|
|
} else if ( color && color.match( /^hsla?/ ) ) {
|
|
value = 'hsl';
|
|
} else {
|
|
value = defaultValue;
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
value = !!value;
|
|
break;
|
|
}
|
|
options[name] = value;
|
|
} );
|
|
|
|
return options;
|
|
},
|
|
/**
|
|
* Create widget
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_create: function() {
|
|
// Return early if Iris support is missing.
|
|
if ( ! $.support.iris ) {
|
|
return;
|
|
}
|
|
|
|
// Set the alpha options for the current instance.
|
|
this.alphaOptions = this._getAlphaOptions();
|
|
|
|
// Create widget.
|
|
this._super();
|
|
},
|
|
/**
|
|
* Binds event listeners to the color picker and create options, etc...
|
|
*
|
|
* @since 3.0.0
|
|
* @access private
|
|
*
|
|
* @return {void}
|
|
*/
|
|
_addListeners: function() {
|
|
if ( ! this.alphaOptions.alphaEnabled ) {
|
|
return this._super();
|
|
}
|
|
|
|
var self = this,
|
|
el = self.element,
|
|
isDeprecated = self.toggler.is( 'a' );
|
|
|
|
this.alphaOptions.defaultWidth = el.width();
|
|
if ( this.alphaOptions.alphaCustomWidth ) {
|
|
el.width( parseInt( this.alphaOptions.defaultWidth + this.alphaOptions.alphaCustomWidth, 10 ) );
|
|
}
|
|
|
|
self.toggler.css( {
|
|
'position': 'relative',
|
|
'background-image' : 'url(' + backgroundImage + ')'
|
|
} );
|
|
|
|
if ( isDeprecated ) {
|
|
self.toggler.html( '<span class="color-alpha" />' );
|
|
} else {
|
|
self.toggler.append( '<span class="color-alpha" />' );
|
|
}
|
|
|
|
self.colorAlpha = self.toggler.find( 'span.color-alpha' ).css( {
|
|
'width' : '30px',
|
|
'height' : '100%',
|
|
'position' : 'absolute',
|
|
'top' : 0,
|
|
'background-color' : el.val(),
|
|
} );
|
|
|
|
// Define the correct position for ltr or rtl direction.
|
|
if ( 'ltr' === self.colorAlpha.css( 'direction' ) ) {
|
|
self.colorAlpha.css( {
|
|
'border-bottom-left-radius' : '2px',
|
|
'border-top-left-radius' : '2px',
|
|
'left' : 0
|
|
} );
|
|
} else {
|
|
self.colorAlpha.css( {
|
|
'border-bottom-right-radius' : '2px',
|
|
'border-top-right-radius' : '2px',
|
|
'right' : 0
|
|
} );
|
|
}
|
|
|
|
|
|
el.iris( {
|
|
/**
|
|
* @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.0.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.colorAlpha.css( { 'background-color': ui.color.to_s( self.alphaOptions.alphaColorType ) } );
|
|
|
|
// fire change callback if we have one
|
|
if ( $.isFunction( self.options.change ) ) {
|
|
self.options.change.call( this, event, ui );
|
|
}
|
|
}
|
|
} );
|
|
|
|
|
|
/**
|
|
* Prevent any clicks inside this widget from leaking to the top and closing it.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Event} event The event that's being called.
|
|
*
|
|
* @return {void}
|
|
*/
|
|
self.wrap.on( 'click.wpcolorpicker', function( event ) {
|
|
event.stopPropagation();
|
|
});
|
|
|
|
/**
|
|
* Open or close the color picker depending on the class.
|
|
*
|
|
* @since 3.0.0
|
|
*/
|
|
self.toggler.click( function() {
|
|
if ( self.toggler.hasClass( 'wp-picker-open' ) ) {
|
|
self.close();
|
|
} else {
|
|
self.open();
|
|
}
|
|
});
|
|
|
|
/**
|
|
* Checks if value is empty when changing the color in the color picker.
|
|
* If so, the background color is cleared.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Event} event The event that's being called.
|
|
*
|
|
* @return {void}
|
|
*/
|
|
el.change( function( event ) {
|
|
var val = $( this ).val();
|
|
|
|
if ( el.hasClass( 'iris-error' ) || val === '' || val.match( /^(#|(rgb|hsl)a?)$/ ) ) {
|
|
if ( isDeprecated ) {
|
|
self.toggler.removeAttr( 'style' );
|
|
}
|
|
|
|
self.colorAlpha.css( 'background-color', '' );
|
|
|
|
// fire clear callback if we have one
|
|
if ( $.isFunction( self.options.clear ) ) {
|
|
self.options.clear.call( this, event );
|
|
}
|
|
}
|
|
} );
|
|
|
|
/**
|
|
* Enables the user to either clear the color in the color picker or revert back to the default color.
|
|
*
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Event} event The event that's being called.
|
|
*
|
|
* @return {void}
|
|
*/
|
|
self.button.click( function( event ) {
|
|
if ( $( this ).hasClass( 'wp-picker-default' ) ) {
|
|
el.val( self.options.defaultColor ).change();
|
|
} else if ( $( this ).hasClass( 'wp-picker-clear' ) ) {
|
|
el.val( '' );
|
|
if ( isDeprecated ) {
|
|
self.toggler.removeAttr( 'style' );
|
|
}
|
|
|
|
self.colorAlpha.css( 'background-color', '' );
|
|
|
|
// fire clear callback if we have one
|
|
if ( $.isFunction( self.options.clear ) ) {
|
|
self.options.clear.call( this, event );
|
|
}
|
|
|
|
el.trigger( 'change' );
|
|
}
|
|
} );
|
|
},
|
|
} );
|
|
} ( jQuery ) );
|