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 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 3.0.0 77 * @access private 78 * 79 * @param {Object|*} The color instance if not defined return the cuurent 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 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 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 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 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 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 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 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 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 3.0.0 425 * 426 * @type {Object} 427 */ 428 alphaOptions: { 429 alphaEnabled: false, 430 }, 431 /** 432 * Get the alpha options. 433 * 434 * @since 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 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 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 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 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 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 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 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 );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.