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.0 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: 300, 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 } ); 121 122 this._super(); 123 }, 124 /** 125 * Binds event listeners to the Iris. 126 * 127 * @since 3.0.0 128 * @access private 129 * 130 * @return {void} 131 */ 132 _addInputListeners: function ( input ) { 133 var self = this, 134 debounceTimeout = 100, 135 callback = function ( event ) { 136 var val = input.val(), 137 color = new Color( val ), 138 val = val.replace( /^(#|(rgb|hsl)a?)/, '' ), 139 type = self.alphaOptions.alphaColorType; 140 141 input.removeClass( 'iris-error' ); 142 143 if ( ! color.error ) { 144 // let's not do this on keyup for hex shortcodes 145 if ( 146 'hex' !== type || 147 ! ( 148 event.type === 'keyup' && 149 val.match( /^[0-9a-fA-F]{3}$/ ) 150 ) 151 ) { 152 // Compare color ( #AARRGGBB ) 153 if ( 154 color.toIEOctoHex() !== 155 self._color.toIEOctoHex() 156 ) { 157 self._setOption( 158 'color', 159 self._getColor( color ) 160 ); 161 } 162 } 163 } else if ( val !== '' ) { 164 input.addClass( 'iris-error' ); 165 } 166 }; 167 168 input 169 .on( 'change', callback ) 170 .on( 'keyup', self._debounce( callback, debounceTimeout ) ); 171 172 // If we initialized hidden, show on first focus. The rest is up to you. 173 if ( self.options.hide ) { 174 input.one( 'focus', function () { 175 self.show(); 176 } ); 177 } 178 }, 179 /** 180 * Init Controls 181 * 182 * @since 3.0.0 183 * @access private 184 * 185 * @return {void} 186 */ 187 _initControls: function () { 188 this._super(); 189 190 if ( this.alphaOptions.alphaEnabled ) { 191 // Create Alpha controls 192 var self = this,
193 stripAlpha = self.controls.strip.clone( false, false ), 194 stripAlphaSlider = stripAlpha.find( '.iris-slider-offset' ), 195 controls = { 196 stripAlpha: stripAlpha, 197 stripAlphaSlider: stripAlphaSlider, 198 }; 199 200 stripAlpha.addClass( 'iris-strip-alpha' ); 201 stripAlphaSlider.addClass( 'iris-slider-offset-alpha' ); 202 stripAlpha.appendTo( self.picker.find( '.iris-picker-inner' ) ); 203 204 // Push new controls 205 $.each( controls, function ( k, v ) { 206 self.controls[ k ] = v; 207 } ); 208 209 // Create slider 210 self.controls.stripAlphaSlider.slider( { 211 orientation: 'vertical', 212 min: 0, 213 max: 100, 214 step: 1, 215 value: parseInt( self._color._alpha * 100 ), 216 slide: function ( event, ui ) { 217 self.active = 'strip'; 218 // Update alpha value 219 self._color._alpha = parseFloat( ui.value / 100 ); 220 self._change.apply( self, arguments ); 221 }, 222 } ); 223 } 224 }, 225 /** 226 * Create the controls sizes 227 * 228 * @since 3.0.0 229 * @access private 230 * 231 * @param {bool} reset Set to True for recreate the controls sizes. 232 * 233 * @return {void} 234 */ 235 _dimensions: function ( reset ) { 236 this._super( reset ); 237 238 if ( this.alphaOptions.alphaEnabled ) { 239 var self = this, 240 opts = self.options, 241 controls = self.controls, 242 square = controls.square, 243 strip = self.picker.find( '.iris-strip' ), 244 innerWidth, 245 squareWidth, 246 stripWidth, 247 stripMargin, 248 totalWidth; 249 250 /** 251 * I use Math.round() to avoid possible size errors, 252 * this function returns the value of a number rounded 253 * to the nearest integer. 254 * 255 * The width to append all widgets, 256 * if border is enabled, 22 is subtracted. 257 * 20 for css left and right property 258 * 2 for css border 259 */ 260 innerWidth = Math.round( 261 self.picker.outerWidth( true ) - ( opts.border ? 22 : 0 ) 262 ); 263 // The width of the draggable, aka square. 264 squareWidth = Math.round( square.outerWidth() ); 265 // The width for the sliders 266 stripWidth = Math.round( ( innerWidth - squareWidth ) / 2 ); 267 // The margin for the sliders 268 stripMargin = Math.round( stripWidth / 2 ); 269 // The total width of the elements. 270 totalWidth = Math.round( 271 squareWidth + stripWidth * 2 + stripMargin * 2 272 ); 273 274 // Check and change if necessary. 275 while ( totalWidth > innerWidth ) { 276 stripWidth = Math.round( stripWidth - 2 ); 277 stripMargin = Math.round( stripMargin - 1 ); 278 totalWidth = Math.round( 279 squareWidth + stripWidth * 2 + stripMargin * 2 280 ); 281 } 282 283 square.css( 'margin', '0' ); 284 strip 285 .width( stripWidth ) 286 .css( 'margin-left', stripMargin + 'px' ); 287 } 288 }, 289 /** 290 * Callback to update the controls and the current color. 291 * 292 * @since 3.0.0 293 * @access private 294 * 295 * @return {void} 296 */ 297 _change: function () { 298 var self = this, 299 active = self.active; 300 301 self._super(); 302 303 if ( self.alphaOptions.alphaEnabled ) { 304 var controls = self.controls, 305 alpha = parseInt( self._color._alpha * 100 ), 306 color = self._color.toRgb(), 307 gradient = [ 308 'rgb(' + 309 color.r + 310 ',' + 311 color.g + 312 ',' + 313 color.b + 314 ') 0%', 315 'rgba(' + 316 color.r + 317 ',' + 318 color.g + 319 ',' + 320 color.b + 321 ', 0) 100%', 322 ], 323 target = self.picker 324 .closest( '.wp-picker-container' ) 325 .find( '.wp-color-result' ); 326 327 self.options.color = self._getColor(); 328 // Generate background slider alpha, only for CSS3. 329 controls.stripAlpha.css( { 330 background: 331 'linear-gradient(to bottom, ' + 332 gradient.join( ', ' ) + 333 '), url(' + 334 backgroundImage + 335 ')', 336 } ); 337 // Update alpha value 338 if ( active ) { 339 controls.stripAlphaSlider.slider( 'value', alpha ); 340 } 341 342 if ( ! self._color.error ) { 343 self.element 344 .removeClass( 'iris-error' ) 345 .val( self.options.color ); 346 } 347 348 self.picker 349 .find( '.iris-palette-container' ) 350 .on( 'click.palette', '.iris-palette', function () { 351 var color = $( this ).data( 'color' ); 352 if ( self.alphaOptions.alphaReset ) { 353 self._color._alpha = 1; 354 color = self._getColor(); 355 } 356 self._setOption( 'color', color ); 357 } ); 358 } 359 }, 360 /** 361 * Paint dimensions. 362 * 363 * @since 3.0.0 364 * @access private 365 * 366 * @param {string} origin Origin (position). 367 * @param {string} control Type of the control, 368 * 369 * @return {void} 370 */ 371 _paintDimension: function ( origin, control ) { 372 var self = this, 373 color = false;
374 375 // Fix for slider hue opacity. 376 if ( self.alphaOptions.alphaEnabled && 'strip' === control ) { 377 color = self._color; 378 self._color = new Color( color.toString() ); 379 self.hue = self._color.h(); 380 } 381 382 self._super( origin, control ); 383 384 // Restore the color after paint. 385 if ( color ) { 386 self._color = color; 387 } 388 }, 389 /** 390 * To update the options, see original source to view the available options. 391 * 392 * @since 3.0.0 393 * 394 * @param {string} key The Option name. 395 * @param {mixed} value The Option value to update. 396 * 397 * @return {void} 398 */ 399 _setOption: function ( key, value ) { 400 var self = this; 401 if ( 'color' === key && self.alphaOptions.alphaEnabled ) { 402 // cast to string in case we have a number 403 value = '' + value; 404 newColor = new Color( value ).setHSpace( self.options.mode ); 405 // Check if error && Check the color to prevent callbacks with the same color. 406 if ( 407 ! newColor.error && 408 self._getColor( newColor ) !== self._getColor() 409 ) { 410 self._color = newColor; 411 self.options.color = self._getColor(); 412 self.active = 'external'; 413 self._change(); 414 } 415 } else { 416 return self._super( key, value ); 417 } 418 }, 419 /** 420 * Returns the iris object if no new color is provided. If a new color is provided, it sets the new color. 421 * 422 * @param newColor {string|*} The new color to use. Can be undefined. 423 * 424 * @since 3.0.0 425 * 426 * @return {string} The element's color. 427 */ 428 color: function ( newColor ) { 429 if ( newColor === true ) { 430 return this._color.clone(); 431 } 432 if ( newColor === undef ) { 433 return this._getColor(); 434 } 435 this.option( 'color', newColor ); 436 }, 437 } ); 438 439 /** 440 * wpColorPicker 441 */ 442 $.widget( 'wp.wpColorPicker', $.wp.wpColorPicker, { 443 /** 444 * Alpha options 445 * 446 * @since 3.0.0 447 * 448 * @type {Object} 449 */ 450 alphaOptions: { 451 alphaEnabled: false, 452 }, 453 /** 454 * Get the alpha options. 455 * 456 * @since 3.0.0 457 * @access private 458 * 459 * @return {object} The current alpha options. 460 */ 461 _getAlphaOptions: function () { 462 var el = this.element, 463 type = el.data( 'type' ) || this.options.type, 464 color = el.data( 'defaultColor' ) || el.val(), 465 options = { 466 alphaEnabled: el.data( 'alphaEnabled' ) || false, 467 alphaCustomWidth: 130, 468 alphaReset: false, 469 alphaColorType: 'rgb', 470 alphaColorWithSpace: false, 471 }; 472 473 if ( options.alphaEnabled ) { 474 options.alphaEnabled = el.is( 'input' ) && 'full' === type; 475 } 476 477 if ( ! options.alphaEnabled ) { 478 return options; 479 } 480 481 options.alphaColorWithSpace = color && color.match( /\s/ ); 482 483 $.each( options, function ( name, defaultValue ) { 484 var value = el.data( name ) || defaultValue; 485 switch ( name ) { 486 case 'alphaCustomWidth': 487 value = value ? parseInt( value, 10 ) : 0; 488 value = isNaN( value ) ? defaultValue : value; 489 break; 490 case 'alphaColorType': 491 if ( ! value.match( /^(hex|(rgb|hsl)a?)$/ ) ) { 492 if ( color && color.match( /^#/ ) ) { 493 value = 'hex'; 494 } else if ( color && color.match( /^hsla?/ ) ) { 495 value = 'hsl'; 496 } else { 497 value = defaultValue; 498 } 499 } 500 break; 501 default: 502 value = !! value; 503 break; 504 } 505 options[ name ] = value; 506 } ); 507 508 return options; 509 }, 510 /** 511 * Create widget 512 * 513 * @since 3.0.0 514 * @access private 515 * 516 * @return {void} 517 */ 518 _create: function () { 519 // Return early if Iris support is missing. 520 if ( ! $.support.iris ) { 521 return; 522 } 523 524 // Set the alpha options for the current instance. 525 this.alphaOptions = this._getAlphaOptions(); 526 527 // Create widget. 528 this._super(); 529 }, 530 /** 531 * Binds event listeners to the color picker and create options, etc... 532 * 533 * @since 3.0.0 534 * @access private 535 * 536 * @return {void} 537 */ 538 _addListeners: function () { 539 if ( ! this.alphaOptions.alphaEnabled ) { 540 return this._super(); 541 } 542 543 var self = this, 544 el = self.element, 545 isDeprecated = self.toggler.is( 'a' ); 546 547 this.alphaOptions.defaultWidth = el.width(); 548 if ( this.alphaOptions.alphaCustomWidth ) { 549 el.width( 550 parseInt( 551 this.alphaOptions.defaultWidth + 552 this.alphaOptions.alphaCustomWidth, 553 10 554 ) 555 ); 556 } 557 558 self.toggler.css( { 559 position: 'relative',
560 'background-image': 'url(' + backgroundImage + ')', 561 } ); 562 563 if ( isDeprecated ) { 564 self.toggler.html( '<span class="color-alpha" />' ); 565 } else { 566 self.toggler.append( '<span class="color-alpha" />' ); 567 } 568 569 self.colorAlpha = self.toggler.find( 'span.color-alpha' ).css( { 570 width: '30px', 571 height: '100%', 572 position: 'absolute', 573 top: 0, 574 'background-color': el.val(), 575 } ); 576 577 // Define the correct position for ltr or rtl direction. 578 if ( 'ltr' === self.colorAlpha.css( 'direction' ) ) { 579 self.colorAlpha.css( { 580 'border-bottom-left-radius': '2px', 581 'border-top-left-radius': '2px', 582 left: 0, 583 } ); 584 } else { 585 self.colorAlpha.css( { 586 'border-bottom-right-radius': '2px', 587 'border-top-right-radius': '2px', 588 right: 0, 589 } ); 590 } 591 592 el.iris( { 593 /** 594 * @summary Handles the onChange event if one has been defined in the options. 595 * 596 * Handles the onChange event if one has been defined in the options and additionally 597 * sets the background color for the toggler element. 598 * 599 * @since 3.0.0 600 * 601 * @param {Event} event The event that's being called. 602 * @param {HTMLElement} ui The HTMLElement containing the color picker. 603 * 604 * @returns {void} 605 */ 606 change: function ( event, ui ) { 607 self.colorAlpha.css( { 608 'background-color': ui.color.to_s( 609 self.alphaOptions.alphaColorType 610 ), 611 } ); 612 613 // fire change callback if we have one 614 if ( $.isFunction( self.options.change ) ) { 615 self.options.change.call( this, event, ui ); 616 } 617 }, 618 } ); 619 620 /** 621 * Prevent any clicks inside this widget from leaking to the top and closing it. 622 * 623 * @since 3.0.0 624 * 625 * @param {Event} event The event that's being called. 626 * 627 * @return {void} 628 */ 629 self.wrap.on( 'click.wpcolorpicker', function ( event ) { 630 event.stopPropagation(); 631 } ); 632 633 /** 634 * Open or close the color picker depending on the class. 635 * 636 * @since 3.0.0 637 */ 638 self.toggler.click( function () { 639 if ( self.toggler.hasClass( 'wp-picker-open' ) ) { 640 self.close(); 641 } else { 642 self.open(); 643 } 644 } ); 645 646 /** 647 * Checks if value is empty when changing the color in the color picker. 648 * If so, the background color is cleared. 649 * 650 * @since 3.0.0 651 * 652 * @param {Event} event The event that's being called. 653 * 654 * @return {void} 655 */ 656 el.change( function ( event ) { 657 var val = $( this ).val(); 658 659 if ( 660 el.hasClass( 'iris-error' ) || 661 val === '' || 662 val.match( /^(#|(rgb|hsl)a?)$/ ) 663 ) { 664 if ( isDeprecated ) { 665 self.toggler.removeAttr( 'style' ); 666 } 667 668 self.colorAlpha.css( 'background-color', '' ); 669 670 // fire clear callback if we have one 671 if ( $.isFunction( self.options.clear ) ) { 672 self.options.clear.call( this, event ); 673 } 674 } 675 } ); 676 677 /** 678 * Enables the user to either clear the color in the color picker or revert back to the default color. 679 * 680 * @since 3.0.0 681 * 682 * @param {Event} event The event that's being called. 683 * 684 * @return {void} 685 */ 686 self.button.click( function ( event ) { 687 if ( $( this ).hasClass( 'wp-picker-default' ) ) { 688 el.val( self.options.defaultColor ).change(); 689 } else if ( $( this ).hasClass( 'wp-picker-clear' ) ) { 690 el.val( '' ); 691 if ( isDeprecated ) { 692 self.toggler.removeAttr( 'style' ); 693 } 694 695 self.colorAlpha.css( 'background-color', '' ); 696 697 // fire clear callback if we have one 698 if ( $.isFunction( self.options.clear ) ) { 699 self.options.clear.call( this, event ); 700 } 701 702 el.trigger( 'change' ); 703 } 704 } ); 705 }, 706 } ); 707} )( 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.