| 1 |
/**! |
| 2 |
* wp-color-picker-alpha |
| 3 |
* |
| 4 |
* Overwrite Automattic Iris for enabled Alpha Channel in wpColorPicker |
| 5 |
* Only run in input and is defined data alpha in true |
| 6 |
* |
| 7 |
* Version: 2.1.3 |
| 8 |
* https://github.com/kallookoo/wp-color-picker-alpha |
| 9 |
* Licensed under the GPLv2 license. |
| 10 |
*/ |
| 11 |
( function( $ ) { |
| 12 |
// Prevent double-init. |
| 13 |
if ( $.wp.wpColorPicker.prototype._hasAlpha ) { |
| 14 |
return; |
| 15 |
} |
| 16 |
|
| 17 |
// Variable for some backgrounds ( grid ) |
| 18 |
var image = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==', |
| 19 |
// html stuff for wpColorPicker copy of the original color-picker.js |
| 20 |
_after = '<div class="wp-picker-holder" />', |
| 21 |
_wrap = '<div class="wp-picker-container" />', |
| 22 |
_button = '<input type="button" class="button button-small" />', |
| 23 |
// Prevent CSS issues in < WordPress 4.9 |
| 24 |
_deprecated = ( wpColorPickerL10n.current !== undefined ); |
| 25 |
// Declare some global variables when is deprecated or not |
| 26 |
if ( _deprecated ) { |
| 27 |
var _before = '<a tabindex="0" class="wp-color-result" />'; |
| 28 |
} else { |
| 29 |
var _before = '<button type="button" class="button wp-color-result" aria-expanded="false"><span class="wp-color-result-text"></span></button>', |
| 30 |
_wrappingLabel = '<label></label>', |
| 31 |
_wrappingLabelText = '<span class="screen-reader-text"></span>'; |
| 32 |
} |
| 33 |
/** |
| 34 |
* Overwrite Color |
| 35 |
* for enable support rbga |
| 36 |
*/ |
| 37 |
Color.fn.toString = function() { |
| 38 |
if ( this._alpha < 1 ) |
| 39 |
return this.toCSS( 'rgba', this._alpha ).replace( /\s+/g, '' ); |
| 40 |
|
| 41 |
var hex = parseInt( this._color, 10 ).toString( 16 ); |
| 42 |
|
| 43 |
if ( this.error ) |
| 44 |
return ''; |
| 45 |
|
| 46 |
if ( hex.length < 6 ) |
| 47 |
hex = ( '00000' + hex ).substr( -6 ); |
| 48 |
|
| 49 |
return '#' + hex; |
| 50 |
}; |
| 51 |
|
| 52 |
/** |
| 53 |
* Overwrite wpColorPicker |
| 54 |
*/ |
| 55 |
$.widget( 'wp.wpColorPicker', $.wp.wpColorPicker, { |
| 56 |
_hasAlpha: true, |
| 57 |
/** |
| 58 |
* @summary Creates the color picker. |
| 59 |
* |
| 60 |
* Creates the color picker, sets default values, css classes and wraps it all in HTML. |
| 61 |
* |
| 62 |
* @since 3.5.0 |
| 63 |
* |
| 64 |
* @access private |
| 65 |
* |
| 66 |
* @returns {void} |
| 67 |
*/ |
| 68 |
_create: function() { |
| 69 |
// Return early if Iris support is missing. |
| 70 |
if ( ! $.support.iris ) { |
| 71 |
return; |
| 72 |
} |
| 73 |
|
| 74 |
var self = this, |
| 75 |
el = self.element; |
| 76 |
|
| 77 |
// Override default options with options bound to the element. |
| 78 |
$.extend( self.options, el.data() ); |
| 79 |
|
| 80 |
// Create a color picker which only allows adjustments to the hue. |
| 81 |
if ( self.options.type === 'hue' ) { |
| 82 |
return self._createHueOnly(); |
| 83 |
} |
| 84 |
|
| 85 |
// Bind the close event. |
| 86 |
self.close = $.proxy( self.close, self ); |
| 87 |
|
| 88 |
self.initialValue = el.val(); |
| 89 |
|
| 90 |
// Add a CSS class to the input field. |
| 91 |
el.addClass( 'wp-color-picker' ); |
| 92 |
|
| 93 |
if ( _deprecated ) { |
| 94 |
el.hide().wrap( _wrap ); |
| 95 |
self.wrap = el.parent(); |
| 96 |
self.toggler = $( _before ) |
| 97 |
.insertBefore( el ) |
| 98 |
.css( { backgroundColor : self.initialValue } ) |
| 99 |
.attr( 'title', wpColorPickerL10n.pick ) |
| 100 |
.attr( 'data-current', wpColorPickerL10n.current ); |
| 101 |
self.pickerContainer = $( _after ).insertAfter( el ); |
| 102 |
self.button = $( _button ).addClass('hidden'); |
| 103 |
} else { |
| 104 |
/* |
| 105 |
* Check if there's already a wrapping label, e.g. in the Customizer. |
| 106 |
* If there's no label, add a default one to match the Customizer template. |
| 107 |
*/ |
| 108 |
if ( ! el.parent( 'label' ).length ) { |
| 109 |
// Wrap the input field in the default label. |
| 110 |
el.wrap( _wrappingLabel ); |
| 111 |
// Insert the default label text. |
| 112 |
self.wrappingLabelText = $( _wrappingLabelText ) |
| 113 |
.insertBefore( el ) |
| 114 |
.text( wpColorPickerL10n.defaultLabel ); |
| 115 |
} |
| 116 |
|
| 117 |
/* |
| 118 |
* At this point, either it's the standalone version or the Customizer |
| 119 |
* one, we have a wrapping label to use as hook in the DOM, let's store it. |
| 120 |
*/ |
| 121 |
self.wrappingLabel = el.parent(); |
| 122 |
|
| 123 |
// Wrap the label in the main wrapper. |
| 124 |
self.wrappingLabel.wrap( _wrap ); |
| 125 |
// Store a reference to the main wrapper. |
| 126 |
self.wrap = self.wrappingLabel.parent(); |
| 127 |
// Set up the toggle button and insert it before the wrapping label. |
| 128 |
self.toggler = $( _before ) |
| 129 |
.insertBefore( self.wrappingLabel ) |
| 130 |
.css( { backgroundColor: self.initialValue } ); |
| 131 |
// Set the toggle button span element text. |
| 132 |
self.toggler.find( '.wp-color-result-text' ).text( wpColorPickerL10n.pick ); |
| 133 |
// Set up the Iris container and insert it after the wrapping label. |
| 134 |
self.pickerContainer = $( _after ).insertAfter( self.wrappingLabel ); |
| 135 |
// Store a reference to the Clear/Default button. |
| 136 |
self.button = $( _button ); |
| 137 |
} |
| 138 |
|
| 139 |
// Set up the Clear/Default button. |
| 140 |
if ( self.options.defaultColor ) { |
| 141 |
self.button.addClass( 'wp-picker-default' ).val( wpColorPickerL10n.defaultString ); |
| 142 |
if ( ! _deprecated ) { |
| 143 |
self.button.attr( 'aria-label', wpColorPickerL10n.defaultAriaLabel ); |
| 144 |
} |
| 145 |
} else { |
| 146 |
self.button.addClass( 'wp-picker-clear' ).val( wpColorPickerL10n.clear ); |
| 147 |
if ( ! _deprecated ) { |
| 148 |
self.button.attr( 'aria-label', wpColorPickerL10n.clearAriaLabel ); |
| 149 |
} |
| 150 |
} |
| 151 |
|
| 152 |
if ( _deprecated ) { |
| 153 |
el.wrap( '<span class="wp-picker-input-wrap" />' ).after( self.button ); |
| 154 |
} else { |
| 155 |
// Wrap the wrapping label in its wrapper and append the Clear/Default button. |
| 156 |
self.wrappingLabel |
| 157 |
.wrap( '<span class="wp-picker-input-wrap hidden" />' ) |
| 158 |
.after( self.button ); |
| 159 |
|
| 160 |
/* |
| 161 |
* The input wrapper now contains the label+input+Clear/Default button. |
| 162 |
* Store a reference to the input wrapper: we'll use this to toggle |
| 163 |
* the controls visibility. |
| 164 |
*/ |
| 165 |
self.inputWrapper = el.closest( '.wp-picker-input-wrap' ); |
| 166 |
} |
| 167 |
|
| 168 |
el.iris( { |
| 169 |
target: self.pickerContainer, |
| 170 |
hide: self.options.hide, |
| 171 |
width: self.options.width, |
| 172 |
mode: self.options.mode, |
| 173 |
palettes: self.options.palettes, |
| 174 |
/** |
| 175 |
* @summary Handles the onChange event if one has been defined in the options. |
| 176 |
* |
| 177 |
* Handles the onChange event if one has been defined in the options and additionally |
| 178 |
* sets the background color for the toggler element. |
| 179 |
* |
| 180 |
* @since 3.5.0 |
| 181 |
* |
| 182 |
* @param {Event} event The event that's being called. |
| 183 |
* @param {HTMLElement} ui The HTMLElement containing the color picker. |
| 184 |
* |
| 185 |
* @returns {void} |
| 186 |
*/ |
| 187 |
change: function( event, ui ) { |
| 188 |
if ( self.options.alpha ) { |
| 189 |
self.toggler.css( { 'background-image' : 'url(' + image + ')' } ); |
| 190 |
if ( _deprecated ) { |
| 191 |
self.toggler.html( '<span class="color-alpha" />' ); |
| 192 |
} else { |
| 193 |
self.toggler.css( { |
| 194 |
'position' : 'relative' |
| 195 |
} ); |
| 196 |
if ( self.toggler.find('span.color-alpha').length == 0 ) { |
| 197 |
self.toggler.append('<span class="color-alpha" />'); |
| 198 |
} |
| 199 |
} |
| 200 |
|
| 201 |
self.toggler.find( 'span.color-alpha' ).css( { |
| 202 |
'width' : '30px', |
| 203 |
'position' : 'absolute', |
| 204 |
'top' : 0, |
| 205 |
'bottom' : 0, |
| 206 |
'left' : 0, |
| 207 |
'border-top-left-radius' : '2px', |
| 208 |
'border-bottom-left-radius' : '2px', |
| 209 |
'background' : ui.color.toString() |
| 210 |
} ); |
| 211 |
} else { |
| 212 |
self.toggler.css( { backgroundColor : ui.color.toString() } ); |
| 213 |
} |
| 214 |
|
| 215 |
if ( $.isFunction( self.options.change ) ) { |
| 216 |
self.options.change.call( this, event, ui ); |
| 217 |
} |
| 218 |
} |
| 219 |
} ); |
| 220 |
|
| 221 |
el.val( self.initialValue ); |
| 222 |
self._addListeners(); |
| 223 |
|
| 224 |
// Force the color picker to always be closed on initial load. |
| 225 |
if ( ! self.options.hide ) { |
| 226 |
self.toggler.click(); |
| 227 |
} |
| 228 |
}, |
| 229 |
/** |
| 230 |
* @summary Binds event listeners to the color picker. |
| 231 |
* |
| 232 |
* @since 3.5.0 |
| 233 |
* |
| 234 |
* @access private |
| 235 |
* |
| 236 |
* @returns {void} |
| 237 |
*/ |
| 238 |
_addListeners: function() { |
| 239 |
var self = this; |
| 240 |
|
| 241 |
/** |
| 242 |
* @summary Prevent any clicks inside this widget from leaking to the top and closing it. |
| 243 |
* |
| 244 |
* @since 3.5.0 |
| 245 |
* |
| 246 |
* @param {Event} event The event that's being called. |
| 247 |
* |
| 248 |
* @returs {void} |
| 249 |
*/ |
| 250 |
self.wrap.on( 'click.wpcolorpicker', function( event ) { |
| 251 |
event.stopPropagation(); |
| 252 |
}); |
| 253 |
|
| 254 |
/** |
| 255 |
* @summary Open or close the color picker depending on the class. |
| 256 |
* |
| 257 |
* @since 3.5 |
| 258 |
*/ |
| 259 |
self.toggler.click( function(){ |
| 260 |
if ( self.toggler.hasClass( 'wp-picker-open' ) ) { |
| 261 |
self.close(); |
| 262 |
} else { |
| 263 |
self.open(); |
| 264 |
} |
| 265 |
}); |
| 266 |
|
| 267 |
/** |
| 268 |
* @summary Checks if value is empty when changing the color in the color picker. |
| 269 |
* |
| 270 |
* Checks if value is empty when changing the color in the color picker. |
| 271 |
* If so, the background color is cleared. |
| 272 |
* |
| 273 |
* @since 3.5.0 |
| 274 |
* |
| 275 |
* @param {Event} event The event that's being called. |
| 276 |
* |
| 277 |
* @returns {void} |
| 278 |
*/ |
| 279 |
self.element.on( 'change', function( event ) { |
| 280 |
// Empty or Error = clear |
| 281 |
if ( $( this ).val() === '' || self.element.hasClass( 'iris-error' ) ) { |
| 282 |
if ( self.options.alpha ) { |
| 283 |
if ( _deprecated ) { |
| 284 |
self.toggler.removeAttr( 'style' ); |
| 285 |
} |
| 286 |
self.toggler.find( 'span.color-alpha' ).css( 'backgroundColor', '' ); |
| 287 |
} else { |
| 288 |
self.toggler.css( 'backgroundColor', '' ); |
| 289 |
} |
| 290 |
|
| 291 |
// fire clear callback if we have one |
| 292 |
if ( $.isFunction( self.options.clear ) ) |
| 293 |
self.options.clear.call( this, event ); |
| 294 |
} |
| 295 |
} ); |
| 296 |
|
| 297 |
/** |
| 298 |
* @summary Enables the user to clear or revert the color in the color picker. |
| 299 |
* |
| 300 |
* Enables the user to either clear the color in the color picker or revert back to the default color. |
| 301 |
* |
| 302 |
* @since 3.5.0 |
| 303 |
* |
| 304 |
* @param {Event} event The event that's being called. |
| 305 |
* |
| 306 |
* @returns {void} |
| 307 |
*/ |
| 308 |
self.button.on( 'click', function( event ) { |
| 309 |
if ( $( this ).hasClass( 'wp-picker-clear' ) ) { |
| 310 |
self.element.val( '' ); |
| 311 |
if ( self.options.alpha ) { |
| 312 |
if ( _deprecated ) { |
| 313 |
self.toggler.removeAttr( 'style' ); |
| 314 |
} |
| 315 |
self.toggler.find( 'span.color-alpha' ).css( 'backgroundColor', '' ); |
| 316 |
} else { |
| 317 |
self.toggler.css( 'backgroundColor', '' ); |
| 318 |
} |
| 319 |
|
| 320 |
if ( $.isFunction( self.options.clear ) ) |
| 321 |
self.options.clear.call( this, event ); |
| 322 |
|
| 323 |
} else if ( $( this ).hasClass( 'wp-picker-default' ) ) { |
| 324 |
self.element.val( self.options.defaultColor ).change(); |
| 325 |
} |
| 326 |
}); |
| 327 |
}, |
| 328 |
}); |
| 329 |
|
| 330 |
/** |
| 331 |
* Overwrite iris |
| 332 |
*/ |
| 333 |
$.widget( 'a8c.iris', $.a8c.iris, { |
| 334 |
_create: function() { |
| 335 |
this._super(); |
| 336 |
|
| 337 |
// Global option for check is mode rbga is enabled |
| 338 |
this.options.alpha = this.element.data( 'alpha' ) || false; |
| 339 |
|
| 340 |
// Is not input disabled |
| 341 |
if ( ! this.element.is( ':input' ) ) |
| 342 |
this.options.alpha = false; |
| 343 |
|
| 344 |
if ( typeof this.options.alpha !== 'undefined' && this.options.alpha ) { |
| 345 |
var self = this, |
| 346 |
el = self.element, |
| 347 |
_html = '<div class="iris-strip iris-slider iris-alpha-slider"><div class="iris-slider-offset iris-slider-offset-alpha"></div></div>', |
| 348 |
aContainer = $( _html ).appendTo( self.picker.find( '.iris-picker-inner' ) ), |
| 349 |
aSlider = aContainer.find( '.iris-slider-offset-alpha' ), |
| 350 |
controls = { |
| 351 |
aContainer : aContainer, |
| 352 |
aSlider : aSlider |
| 353 |
}; |
| 354 |
|
| 355 |
if ( typeof el.data( 'custom-width' ) !== 'undefined' ) { |
| 356 |
self.options.customWidth = parseInt( el.data( 'custom-width' ) ) || 0; |
| 357 |
} else { |
| 358 |
self.options.customWidth = 100; |
| 359 |
} |
| 360 |
|
| 361 |
// Set default width for input reset |
| 362 |
self.options.defaultWidth = el.width(); |
| 363 |
|
| 364 |
// Update width for input |
| 365 |
if ( self._color._alpha < 1 || self._color.toString().indexOf('rgb') != -1 ) |
| 366 |
el.width( parseInt( self.options.defaultWidth + self.options.customWidth ) ); |
| 367 |
|
| 368 |
// Push new controls |
| 369 |
$.each( controls, function( k, v ) { |
| 370 |
self.controls[k] = v; |
| 371 |
} ); |
| 372 |
|
| 373 |
// Change size strip and add margin for sliders |
| 374 |
self.controls.square.css( { 'margin-right': '0' } ); |
| 375 |
var emptyWidth = ( self.picker.width() - self.controls.square.width() - 20 ), |
| 376 |
stripsMargin = ( emptyWidth / 6 ), |
| 377 |
stripsWidth = ( ( emptyWidth / 2 ) - stripsMargin ); |
| 378 |
|
| 379 |
$.each( [ 'aContainer', 'strip' ], function( k, v ) { |
| 380 |
self.controls[v].width( stripsWidth ).css( { 'margin-left' : stripsMargin + 'px' } ); |
| 381 |
} ); |
| 382 |
|
| 383 |
// Add new slider |
| 384 |
self._initControls(); |
| 385 |
|
| 386 |
// For updated widget |
| 387 |
self._change(); |
| 388 |
} |
| 389 |
}, |
| 390 |
_initControls: function() { |
| 391 |
this._super(); |
| 392 |
|
| 393 |
if ( this.options.alpha ) { |
| 394 |
var self = this, |
| 395 |
controls = self.controls; |
| 396 |
|
| 397 |
controls.aSlider.slider({ |
| 398 |
orientation : 'vertical', |
| 399 |
min : 0, |
| 400 |
max : 100, |
| 401 |
step : 1, |
| 402 |
value : parseInt( self._color._alpha * 100 ), |
| 403 |
slide : function( event, ui ) { |
| 404 |
// Update alpha value |
| 405 |
self._color._alpha = parseFloat( ui.value / 100 ); |
| 406 |
self._change.apply( self, arguments ); |
| 407 |
} |
| 408 |
}); |
| 409 |
} |
| 410 |
}, |
| 411 |
_change: function() { |
| 412 |
this._super(); |
| 413 |
|
| 414 |
var self = this, |
| 415 |
el = self.element; |
| 416 |
|
| 417 |
if ( this.options.alpha ) { |
| 418 |
var controls = self.controls, |
| 419 |
alpha = parseInt( self._color._alpha * 100 ), |
| 420 |
color = self._color.toRgb(), |
| 421 |
gradient = [ |
| 422 |
'rgb(' + color.r + ',' + color.g + ',' + color.b + ') 0%', |
| 423 |
'rgba(' + color.r + ',' + color.g + ',' + color.b + ', 0) 100%' |
| 424 |
], |
| 425 |
defaultWidth = self.options.defaultWidth, |
| 426 |
customWidth = self.options.customWidth, |
| 427 |
target = self.picker.closest( '.wp-picker-container' ).find( '.wp-color-result' ); |
| 428 |
|
| 429 |
// Generate background slider alpha, only for CSS3 old browser fuck!! :) |
| 430 |
controls.aContainer.css( { 'background' : 'linear-gradient(to bottom, ' + gradient.join( ', ' ) + '), url(' + image + ')' } ); |
| 431 |
|
| 432 |
if ( target.hasClass( 'wp-picker-open' ) ) { |
| 433 |
// Update alpha value |
| 434 |
controls.aSlider.slider( 'value', alpha ); |
| 435 |
|
| 436 |
/** |
| 437 |
* Disabled change opacity in default slider Saturation ( only is alpha enabled ) |
| 438 |
* and change input width for view all value |
| 439 |
*/ |
| 440 |
if ( self._color._alpha < 1 ) { |
| 441 |
controls.strip.attr( 'style', controls.strip.attr( 'style' ).replace( /rgba\(([0-9]+,)(\s+)?([0-9]+,)(\s+)?([0-9]+)(,(\s+)?[0-9\.]+)\)/g, 'rgb($1$3$5)' ) ); |
| 442 |
el.width( parseInt( defaultWidth + customWidth ) ); |
| 443 |
} else { |
| 444 |
el.width( defaultWidth ); |
| 445 |
} |
| 446 |
} |
| 447 |
} |
| 448 |
|
| 449 |
var reset = el.data( 'reset-alpha' ) || false; |
| 450 |
|
| 451 |
if ( reset ) { |
| 452 |
self.picker.find( '.iris-palette-container' ).on( 'click.palette', '.iris-palette', function() { |
| 453 |
self._color._alpha = 1; |
| 454 |
self.active = 'external'; |
| 455 |
self._change(); |
| 456 |
} ); |
| 457 |
} |
| 458 |
}, |
| 459 |
_addInputListeners: function( input ) { |
| 460 |
var self = this, |
| 461 |
debounceTimeout = 100, |
| 462 |
callback = function( event ) { |
| 463 |
var color = new Color( input.val() ), |
| 464 |
val = input.val(); |
| 465 |
|
| 466 |
input.removeClass( 'iris-error' ); |
| 467 |
// we gave a bad color |
| 468 |
if ( color.error ) { |
| 469 |
// don't error on an empty input |
| 470 |
if ( val !== '' ) |
| 471 |
input.addClass( 'iris-error' ); |
| 472 |
} else { |
| 473 |
if ( color.toString() !== self._color.toString() ) { |
| 474 |
// let's not do this on keyup for hex shortcodes |
| 475 |
if ( ! ( event.type === 'keyup' && val.match( /^[0-9a-fA-F]{3}$/ ) ) ) |
| 476 |
self._setOption( 'color', color.toString() ); |
| 477 |
} |
| 478 |
} |
| 479 |
}; |
| 480 |
|
| 481 |
input.on( 'change', callback ).on( 'keyup', self._debounce( callback, debounceTimeout ) ); |
| 482 |
|
| 483 |
// If we initialized hidden, show on first focus. The rest is up to you. |
| 484 |
if ( self.options.hide ) { |
| 485 |
input.on( 'focus', function() { |
| 486 |
self.show(); |
| 487 |
} ); |
| 488 |
} |
| 489 |
} |
| 490 |
} ); |
| 491 |
|
| 492 |
// Auto Call plugin is class is color-picker |
| 493 |
$(function() { |
| 494 |
$( '.color-picker' ).wpColorPicker(); |
| 495 |
}); |
| 496 |
|
| 497 |
}( jQuery ) ); |
| 498 |
|