PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.9.5
Secure Custom Fields v6.9.5
6.9.5 6.9.4 6.9.3 6.9.2 6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / assets / inc / color-picker-alpha / wp-color-picker-alpha.js
secure-custom-fields / assets / inc / color-picker-alpha Last commit date
index.php 1 year ago wp-color-picker-alpha.js 1 year ago wp-color-picker-alpha.min.js 1 year ago
wp-color-picker-alpha.js
686 lines
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: 3.0.3
8 * https://github.com/kallookoo/wp-color-picker-alpha
9 * Licensed under the GPLv2 license or later.
10 */
11
12 ( function ( $, undef ) {
13 var wpColorPickerAlpha = {
14 'version': 302,
15 };
16
17 // Always try to use the last version of this script.
18 if (
19 'wpColorPickerAlpha' in window &&
20 'version' in window.wpColorPickerAlpha
21 ) {
22 var version = parseInt( window.wpColorPickerAlpha.version, 10 );
23 if ( ! isNaN( version ) && version >= wpColorPickerAlpha.version ) {
24 return;
25 }
26 }
27
28 // Prevent multiple initiations
29 if ( Color.fn.hasOwnProperty( 'to_s' ) ) {
30 return;
31 }
32
33 // Create new method to replace the `Color.toString()` inside the scripts.
34 Color.fn.to_s = function ( type ) {
35 type = ( type || 'hex' );
36 // Change hex to rgba to return the correct color.
37 if ( 'hex' === type && this._alpha < 1 ) {
38 type = 'rgba';
39 }
40
41 var color = '';
42 if ( 'hex' === type ) {
43 color = this.toString();
44 } else if ( ! this.error ) {
45 color = this.toCSS( type )
46 .replace( /\(\s+/, '(' )
47 .replace( /\s+\)/, ')' );
48 }
49 return color;
50 };
51
52 // Register the global variable.
53 window.wpColorPickerAlpha = wpColorPickerAlpha;
54
55 // Background image encoded
56 var backgroundImage =
57 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAAHnlligAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHJJREFUeNpi+P///4EDBxiAGMgCCCAGFB5AADGCRBgYDh48CCRZIJS9vT2QBAggFBkmBiSAogxFBiCAoHogAKIKAlBUYTELAiAmEtABEECk20G6BOmuIl0CIMBQ/IEMkO0myiSSraaaBhZcbkUOs0HuBwDplz5uFJ3Z4gAAAABJRU5ErkJggg==';
58
59 /**
60 * Iris
61 */
62 $.widget( 'a8c.iris', $.a8c.iris, {
63 /**
64 * Alpha options
65 *
66 * @since ACF 3.0.0
67 *
68 * @type {Object}
69 */
70 alphaOptions: {
71 alphaEnabled: false,
72 },
73 /**
74 * Get the current color or the new color.
75 *
76 * @since ACF 3.0.0
77 * @access private
78 *
79 * @param {Object|*} The color instance if not defined return the current color.
80 *
81 * @return {string} The element's color.
82 */
83 _getColor: function ( color ) {
84 if ( color === undef ) {
85 color = this._color;
86 }
87
88 if ( this.alphaOptions.alphaEnabled ) {
89 color = color.to_s( this.alphaOptions.alphaColorType );
90 if ( ! this.alphaOptions.alphaColorWithSpace ) {
91 color = color.replace( /\s+/g, '' );
92 }
93 return color;
94 }
95 return color.toString();
96 },
97 /**
98 * Create widget
99 *
100 * @since ACF 3.0.0
101 * @access private
102 *
103 * @return {void}
104 */
105 _create: function () {
106 try {
107 // Try to get the wpColorPicker alpha options.
108 this.alphaOptions = this.element.wpColorPicker(
109 'instance'
110 ).alphaOptions;
111 } catch ( e ) {}
112
113 // We make sure there are all options
114 $.extend( {}, this.alphaOptions, {
115 alphaEnabled: false,
116 alphaCustomWidth: 130,
117 alphaReset: false,
118 alphaColorType: 'hex',
119 alphaColorWithSpace: false,
120 alphaSkipDebounce: false,
121 alphaDebounceTimeout: 100,
122 } );
123
124 this._super();
125 },
126 /**
127 * Binds event listeners to the Iris.
128 *
129 * @since ACF 3.0.0
130 * @access private
131 *
132 * @return {void}
133 */
134 _addInputListeners: function ( input ) {
135 var self = this,
136 callback = function ( event ) {
137 var val = input.val(),
138 color = new Color( val ),
139 val = val.replace( /^(#|(rgb|hsl)a?)/, '' ),
140 type = self.alphaOptions.alphaColorType;
141
142 input.removeClass( 'iris-error' );
143
144 if ( ! color.error ) {
145 // let's not do this on keyup for hex shortcodes
146 if (
147 'hex' !== type ||
148 ! (
149 event.type === 'keyup' &&
150 val.match( /^[0-9a-fA-F]{3}$/ )
151 )
152 ) {
153 // Compare color ( #AARRGGBB )
154 if (
155 color.toIEOctoHex() !==
156 self._color.toIEOctoHex()
157 ) {
158 self._setOption(
159 'color',
160 self._getColor( color )
161 );
162 }
163 }
164 } else if ( val !== '' ) {
165 input.addClass( 'iris-error' );
166 }
167 };
168
169 input.on( 'change', callback );
170
171 if( ! self.alphaOptions.alphaSkipDebounce ) {
172 input.on( 'keyup', self._debounce( callback, self.alphaOptions.alphaDebounceTimeout ) );
173 }
174
175 // If we initialized hidden, show on first focus. The rest is up to you.
176 if ( self.options.hide ) {
177 input.one( 'focus', function () {
178 self.show();
179 } );
180 }
181 },
182 /**
183 * Init Controls
184 *
185 * @since ACF 3.0.0
186 * @access private
187 *
188 * @return {void}
189 */
190 _initControls: function () {
191 this._super();
192
193 if ( this.alphaOptions.alphaEnabled ) {
194 // Create Alpha controls
195 var self = this,
196 stripAlpha = self.controls.strip.clone( false, false ),
197 stripAlphaSlider = stripAlpha.find( '.iris-slider-offset' ),
198 controls = {
199 stripAlpha: stripAlpha,
200 stripAlphaSlider: stripAlphaSlider,
201 };
202
203 stripAlpha.addClass( 'iris-strip-alpha' );
204 stripAlphaSlider.addClass( 'iris-slider-offset-alpha' );
205 stripAlpha.appendTo( self.picker.find( '.iris-picker-inner' ) );
206
207 // Push new controls
208 $.each( controls, function ( k, v ) {
209 self.controls[ k ] = v;
210 } );
211
212 // Create slider
213 self.controls.stripAlphaSlider.slider( {
214 orientation: 'vertical',
215 min: 0,
216 max: 100,
217 step: 1,
218 value: parseInt( self._color._alpha * 100 ),
219 slide: function ( event, ui ) {
220 self.active = 'strip';
221 // Update alpha value
222 self._color._alpha = parseFloat( ui.value / 100 );
223 self._change.apply( self, arguments );
224 },
225 } );
226 }
227 },
228 /**
229 * Create the controls sizes
230 *
231 * @since ACF 3.0.0
232 * @access private
233 *
234 * @param {bool} reset Set to True for recreate the controls sizes.
235 *
236 * @return {void}
237 */
238 _dimensions: function ( reset ) {
239 this._super( reset );
240
241 if ( this.alphaOptions.alphaEnabled ) {
242 var self = this,
243 opts = self.options,
244 controls = self.controls,
245 square = controls.square,
246 strip = self.picker.find( '.iris-strip' ),
247 innerWidth,
248 squareWidth,
249 stripWidth,
250 stripMargin,
251 totalWidth;
252
253 /**
254 * I use Math.round() to avoid possible size errors,
255 * this function returns the value of a number rounded
256 * to the nearest integer.
257 *
258 * The width to append all widgets,
259 * if border is enabled, 22 is subtracted.
260 * 20 for css left and right property
261 * 2 for css border
262 */
263 innerWidth = Math.round(
264 self.picker.outerWidth( true ) - ( opts.border ? 22 : 0 )
265 );
266 // The width of the draggable, aka square.
267 squareWidth = Math.round( square.outerWidth() );
268 // The width for the sliders
269 stripWidth = Math.round( ( innerWidth - squareWidth ) / 2 );
270 // The margin for the sliders
271 stripMargin = Math.round( stripWidth / 2 );
272 // The total width of the elements.
273 totalWidth = Math.round(squareWidth + ( stripWidth * 2 ) + ( stripMargin * 2 ) );
274
275 // Check and change if necessary.
276 while ( totalWidth > innerWidth ) {
277 stripWidth = Math.round( stripWidth - 2 );
278 stripMargin = Math.round( stripMargin - 1 );
279 totalWidth = Math.round( squareWidth + ( stripWidth * 2 ) + ( stripMargin * 2 ) );
280 }
281
282 square.css( 'margin', '0' );
283 strip
284 .width( stripWidth )
285 .css( 'margin-left', stripMargin + 'px' );
286 }
287 },
288 /**
289 * Callback to update the controls and the current color.
290 *
291 * @since ACF 3.0.0
292 * @access private
293 *
294 * @return {void}
295 */
296 _change: function () {
297 var self = this,
298 active = self.active;
299
300 self._super();
301
302 if ( self.alphaOptions.alphaEnabled ) {
303 var controls = self.controls,
304 alpha = parseInt( self._color._alpha * 100 ),
305 color = self._color.toRgb(),
306 gradient = [
307 'rgb(' + color.r + ',' + color.g + ',' + color.b + ') 0%',
308 'rgba(' + color.r + ',' + color.g + ',' + color.b + ', 0) 100%'
309 ],
310 target = self.picker
311 .closest( '.wp-picker-container' )
312 .find( '.wp-color-result' );
313
314 self.options.color = self._getColor();
315 // Generate background slider alpha, only for CSS3.
316 controls.stripAlpha.css( {'background' : 'linear-gradient(to bottom, ' + gradient.join( ', ' ) + '), url(' + backgroundImage + ')' } );
317 // Update alpha value
318 if ( active ) {
319 controls.stripAlphaSlider.slider( 'value', alpha );
320 }
321
322 if ( ! self._color.error ) {
323 self.element.removeClass( 'iris-error' ).val( self.options.color );
324 }
325
326 self.picker
327 .find( '.iris-palette-container' )
328 .on( 'click.palette', '.iris-palette', function () {
329 var color = $( this ).data( 'color' );
330 if ( self.alphaOptions.alphaReset ) {
331 self._color._alpha = 1;
332 color = self._getColor();
333 }
334 self._setOption( 'color', color );
335 } );
336 }
337 },
338 /**
339 * Paint dimensions.
340 *
341 * @since ACF 3.0.0
342 * @access private
343 *
344 * @param {string} origin Origin (position).
345 * @param {string} control Type of the control,
346 *
347 * @return {void}
348 */
349 _paintDimension: function ( origin, control ) {
350 var self = this,
351 color = false;
352
353 // Fix for slider hue opacity.
354 if ( self.alphaOptions.alphaEnabled && 'strip' === control ) {
355 color = self._color;
356 self._color = new Color( color.toString() );
357 self.hue = self._color.h();
358 }
359
360 self._super( origin, control );
361
362 // Restore the color after paint.
363 if ( color ) {
364 self._color = color;
365 }
366 },
367 /**
368 * To update the options, see original source to view the available options.
369 *
370 * @since ACF 3.0.0
371 *
372 * @param {string} key The Option name.
373 * @param {mixed} value The Option value to update.
374 *
375 * @return {void}
376 */
377 _setOption: function ( key, value ) {
378 var self = this;
379 if ( 'color' === key && self.alphaOptions.alphaEnabled ) {
380 // cast to string in case we have a number
381 value = '' + value;
382 newColor = new Color( value ).setHSpace( self.options.mode );
383 // Check if error && Check the color to prevent callbacks with the same color.
384 if (
385 ! newColor.error &&
386 self._getColor( newColor ) !== self._getColor()
387 ) {
388 self._color = newColor;
389 self.options.color = self._getColor();
390 self.active = 'external';
391 self._change();
392 }
393 } else {
394 return self._super( key, value );
395 }
396 },
397 /**
398 * Returns the iris object if no new color is provided. If a new color is provided, it sets the new color.
399 *
400 * @param newColor {string|*} The new color to use. Can be undefined.
401 *
402 * @since ACF 3.0.0
403 *
404 * @return {string} The element's color.
405 */
406 color: function ( newColor ) {
407 if ( newColor === true ) {
408 return this._color.clone();
409 }
410 if ( newColor === undef ) {
411 return this._getColor();
412 }
413 this.option( 'color', newColor );
414 },
415 } );
416
417 /**
418 * wpColorPicker
419 */
420 $.widget( 'wp.wpColorPicker', $.wp.wpColorPicker, {
421 /**
422 * Alpha options
423 *
424 * @since ACF 3.0.0
425 *
426 * @type {Object}
427 */
428 alphaOptions: {
429 alphaEnabled: false,
430 },
431 /**
432 * Get the alpha options.
433 *
434 * @since ACF 3.0.0
435 * @access private
436 *
437 * @return {object} The current alpha options.
438 */
439 _getAlphaOptions: function () {
440 var el = this.element,
441 type = ( el.data( 'type' ) || this.options.type ),
442 color = ( el.data( 'defaultColor' ) || el.val() ),
443 options = {
444 alphaEnabled: ( el.data( 'alphaEnabled' ) || false ),
445 alphaCustomWidth: 130,
446 alphaReset: false,
447 alphaColorType: 'rgb',
448 alphaColorWithSpace: false,
449 alphaSkipDebounce: ( !!el.data( 'alphaSkipDebounce' ) || false ),
450 };
451
452 if ( options.alphaEnabled ) {
453 options.alphaEnabled = ( el.is( 'input' ) && 'full' === type );
454 }
455
456 if ( ! options.alphaEnabled ) {
457 return options;
458 }
459
460 options.alphaColorWithSpace = ( color && color.match( /\s/ ) );
461
462 $.each( options, function ( name, defaultValue ) {
463 var value = ( el.data( name ) || defaultValue );
464 switch ( name ) {
465 case 'alphaCustomWidth':
466 value = ( value ? parseInt( value, 10 ) : 0 );
467 value = ( isNaN( value ) ? defaultValue : value );
468 break;
469 case 'alphaColorType':
470 if ( ! value.match( /^(hex|(rgb|hsl)a?)$/ ) ) {
471 if ( color && color.match( /^#/ ) ) {
472 value = 'hex';
473 } else if ( color && color.match( /^hsla?/ ) ) {
474 value = 'hsl';
475 } else {
476 value = defaultValue;
477 }
478 }
479 break;
480 default:
481 value = !! value;
482 break;
483 }
484 options[ name ] = value;
485 } );
486
487 return options;
488 },
489 /**
490 * Create widget
491 *
492 * @since ACF 3.0.0
493 * @access private
494 *
495 * @return {void}
496 */
497 _create: function () {
498 // Return early if Iris support is missing.
499 if ( ! $.support.iris ) {
500 return;
501 }
502
503 // Set the alpha options for the current instance.
504 this.alphaOptions = this._getAlphaOptions();
505
506 // Create widget.
507 this._super();
508 },
509 /**
510 * Binds event listeners to the color picker and create options, etc...
511 *
512 * @since ACF 3.0.0
513 * @access private
514 *
515 * @return {void}
516 */
517 _addListeners: function () {
518 if ( ! this.alphaOptions.alphaEnabled ) {
519 return this._super();
520 }
521
522 var self = this,
523 el = self.element,
524 isDeprecated = self.toggler.is( 'a' );
525
526 this.alphaOptions.defaultWidth = el.width();
527 if ( this.alphaOptions.alphaCustomWidth ) {
528 el.width(
529 parseInt(
530 this.alphaOptions.defaultWidth +
531 this.alphaOptions.alphaCustomWidth,
532 10
533 )
534 );
535 }
536
537 self.toggler.css( {
538 'position': 'relative',
539 'background-image': 'url(' + backgroundImage + ')',
540 } );
541
542 if ( isDeprecated ) {
543 self.toggler.html( '<span class="color-alpha" />' );
544 } else {
545 self.toggler.append( '<span class="color-alpha" />' );
546 }
547
548 self.colorAlpha = self.toggler.find( 'span.color-alpha' ).css( {
549 'width': '30px',
550 'height': '100%',
551 'position': 'absolute',
552 'top': 0,
553 'background-color': el.val(),
554 } );
555
556 // Define the correct position for ltr or rtl direction.
557 if ( 'ltr' === self.colorAlpha.css( 'direction' ) ) {
558 self.colorAlpha.css( {
559 'border-bottom-left-radius': '2px',
560 'border-top-left-radius': '2px',
561 'left': 0,
562 } );
563 } else {
564 self.colorAlpha.css( {
565 'border-bottom-right-radius': '2px',
566 'border-top-right-radius': '2px',
567 'right': 0,
568 } );
569 }
570
571 el.iris( {
572 /**
573 * @summary Handles the onChange event if one has been defined in the options.
574 *
575 * Handles the onChange event if one has been defined in the options and additionally
576 * sets the background color for the toggler element.
577 *
578 * @since ACF 3.0.0
579 *
580 * @param {Event} event The event that's being called.
581 * @param {HTMLElement} ui The HTMLElement containing the color picker.
582 *
583 * @returns {void}
584 */
585 change: function ( event, ui ) {
586 self.colorAlpha.css( {
587 'background-color': ui.color.to_s(
588 self.alphaOptions.alphaColorType
589 ),
590 } );
591
592 // fire change callback if we have one
593 if ( typeof self.options.change === 'function' ) {
594 self.options.change.call( this, event, ui );
595 }
596 },
597 } );
598
599 /**
600 * Prevent any clicks inside this widget from leaking to the top and closing it.
601 *
602 * @since ACF 3.0.0
603 *
604 * @param {Event} event The event that's being called.
605 *
606 * @return {void}
607 */
608 self.wrap.on( 'click.wpcolorpicker', function ( event ) {
609 event.stopPropagation();
610 } );
611
612 /**
613 * Open or close the color picker depending on the class.
614 *
615 * @since ACF 3.0.0
616 */
617 self.toggler.on( 'click', function () {
618 if ( self.toggler.hasClass( 'wp-picker-open' ) ) {
619 self.close();
620 } else {
621 self.open();
622 }
623 } );
624
625 /**
626 * Checks if value is empty when changing the color in the color picker.
627 * If so, the background color is cleared.
628 *
629 * @since ACF 3.0.0
630 *
631 * @param {Event} event The event that's being called.
632 *
633 * @return {void}
634 */
635 el.on( 'change', function ( event ) {
636 var val = $( this ).val();
637
638 if (
639 el.hasClass( 'iris-error' ) ||
640 val === '' ||
641 val.match( /^(#|(rgb|hsl)a?)$/ )
642 ) {
643 if ( isDeprecated ) {
644 self.toggler.removeAttr( 'style' );
645 }
646
647 self.colorAlpha.css( 'background-color', '' );
648
649 // fire clear callback if we have one
650 if ( typeof self.options.clear === 'function' ) {
651 self.options.clear.call( this, event );
652 }
653 }
654 } );
655
656 /**
657 * Enables the user to either clear the color in the color picker or revert back to the default color.
658 *
659 * @since ACF 3.0.0
660 *
661 * @param {Event} event The event that's being called.
662 *
663 * @return {void}
664 */
665 self.button.on( 'click', function ( event ) {
666 if ( $( this ).hasClass( 'wp-picker-default' ) ) {
667 el.val( self.options.defaultColor ).change();
668 } else if ( $( this ).hasClass( 'wp-picker-clear' ) ) {
669 el.val( '' );
670 if ( isDeprecated ) {
671 self.toggler.removeAttr( 'style' );
672 }
673
674 self.colorAlpha.css( 'background-color', '' );
675
676 // fire clear callback if we have one
677 if ( typeof self.options.clear === 'function' ) {
678 self.options.clear.call( this, event );
679 }
680
681 el.trigger( 'change' );
682 }
683 } );
684 },
685 } );
686 } )( jQuery );