1/** 2* This is jQuery MiniColors file. A tiny color picker built on jQuery. Don't edit the file if you want to update module in future. 3* 4* @author A Beautiful Site <http://www.abeautifulsite.net> 5* @copyright 2015 A Beautiful Site 6* @link https://github.com/claviska/jquery-minicolors 7* @license http://opensource.org/licenses/MIT 8*/ 9 10(function (factory) { 11 /* jshint ignore:start */ 12 if (typeof define === 'function' && define.amd) { 13 // AMD. Register as an anonymous module. 14 define(['jquery'], factory); 15 } else if (typeof exports === 'object') { 16 // Node/CommonJS 17 module.exports = factory(require('jquery')); 18 } else { 19 // Browser globals 20 factory(jQuery); 21 } 22 /* jshint ignore:end */ 23}(function ($) { 24 25 'use strict'; 26 27 // Defaults 28 $.minicolors = { 29 defaults: { 30 animationSpeed: 50, 31 animationEasing: 'swing', 32 change: null, 33 changeDelay: 0, 34 control: 'hue', 35 dataUris: true, 36 defaultValue: '', 37 format: 'hex', 38 hide: null, 39 hideSpeed: 100, 40 inline: false, 41 keywords: '', 42 letterCase: 'lowercase', 43 opacity: false, 44 position: 'bottom left', 45 show: null, 46 showSpeed: 100, 47 theme: 'default', 48 swatches: [] 49 } 50 }; 51 52 // Public methods 53 $.extend($.fn, { 54 minicolors: function(method, data) { 55 56 switch(method) { 57 58 // Destroy the control 59 case 'destroy': 60 $(this).each( function() { 61 destroy($(this)); 62 }); 63 return $(this); 64 65 // Hide the color picker 66 case 'hide': 67 hide(); 68 return $(this); 69 70 // Get/set opacity 71 case 'opacity': 72 // Getter 73 if( data === undefined ) { 74 // Getter 75 return $(this).attr('data-opacity'); 76 } else { 77 // Setter 78 $(this).each( function() { 79 updateFromInput($(this).attr('data-opacity', data)); 80 }); 81 } 82 return $(this); 83 84 // Get an RGB(A) object based on the current color/opacity 85 case 'rgbObject': 86 return rgbObject($(this), method === 'rgbaObject'); 87 88 // Get an RGB(A) string based on the current color/opacity 89 case 'rgbString': 90 case 'rgbaString': 91 return rgbString($(this), method === 'rgbaString'); 92 93 // Get/set settings on the fly 94 case 'settings': 95 if( data === undefined ) { 96 return $(this).data('minicolors-settings'); 97 } else { 98 // Setter 99 $(this).each( function() { 100 var settings = $(this).data('minicolors-settings') || {}; 101 destroy($(this)); 102 $(this).minicolors($.extend(true, settings, data)); 103 }); 104 } 105 return $(this); 106 107 // Show the color picker 108 case 'show': 109 show( $(this).eq(0) ); 110 return $(this); 111 112 // Get/set the hex color value 113 case 'value': 114 if( data === undefined ) { 115 // Getter 116 return $(this).val(); 117 } else { 118 // Setter 119 $(this).each( function() { 120 if( typeof(data) === 'object' ) { 121 if( data.opacity ) { 122 $(this).attr('data-opacity', keepWithin(data.opacity, 0, 1)); 123 } 124 if( data.color ) { 125 $(this).val(data.color); 126 } 127 } else { 128 $(this).val(data); 129 } 130 updateFromInput($(this)); 131 }); 132 } 133 return $(this); 134 135 // Initializes the control 136 default: 137 if( method !== 'create' ) data = method; 138 $(this).each( function() { 139 init($(this), data); 140 }); 141 return $(this); 142 143 } 144 145 } 146 }); 147 148 // Initialize input elements 149 function init(input, settings) { 150 151 var minicolors = $('<div class="minicolors" />'), 152 defaults = $.minicolors.defaults, 153 size, 154 swatches, 155 swatch, 156 panel, 157 i; 158
159 // Do nothing if already initialized 160 if( input.data('minicolors-initialized') ) return; 161 162 // Handle settings 163 settings = $.extend(true, {}, defaults, settings); 164 165 // The wrapper 166 minicolors 167 .addClass('minicolors-theme-' + settings.theme) 168 .toggleClass('minicolors-with-opacity', settings.opacity) 169 .toggleClass('minicolors-no-data-uris', settings.dataUris !== true); 170 171 // Custom positioning 172 if( settings.position !== undefined ) { 173 $.each(settings.position.split(' '), function() { 174 minicolors.addClass('minicolors-position-' + this); 175 }); 176 } 177 178 // Input size 179 if( settings.format === 'rgb' ) { 180 size = settings.opacity ? '25' : '20'; 181 } else { 182 size = settings.keywords ? '11' : '7'; 183 } 184 185 // The input 186 input 187 .addClass('minicolors-input') 188 .data('minicolors-initialized', false) 189 .data('minicolors-settings', settings) 190 .prop('size', size) 191 .wrap(minicolors) 192 .after( 193 '<div class="minicolors-panel minicolors-slider-' + settings.control + '">' + 194 '<div class="minicolors-slider minicolors-sprite">' + 195 '<div class="minicolors-picker"></div>' + 196 '</div>' + 197 '<div class="minicolors-opacity-slider minicolors-sprite">' + 198 '<div class="minicolors-picker"></div>' + 199 '</div>' + 200 '<div class="minicolors-grid minicolors-sprite">' + 201 '<div class="minicolors-grid-inner"></div>' + 202 '<div class="minicolors-picker"><div></div></div>' + 203 '</div>' + 204 '</div>' 205 ); 206 207 // The swatch 208 if( !settings.inline ) { 209 input.after('<span class="minicolors-swatch minicolors-sprite minicolors-input-swatch"><span class="minicolors-swatch-color"></span></span>'); 210 input.next('.minicolors-input-swatch').on('click', function(event) { 211 event.preventDefault(); 212 input.focus(); 213 }); 214 } 215 216 // Prevent text selection in IE 217 panel = input.parent().find('.minicolors-panel'); 218 panel.on('selectstart', function() { return false; }).end(); 219 220 // Swatches 221 if (settings.swatches && settings.swatches.length !== 0) { 222 if (settings.swatches.length > 7) { 223 settings.swatches.length = 7; 224 } 225 panel.addClass('minicolors-with-swatches'); 226 swatches = $('<ul class="minicolors-swatches"></ul>') 227 .appendTo(panel); 228 for(i = 0; i < settings.swatches.length; ++i) { 229 swatch = settings.swatches[i]; 230 swatch = isRgb(swatch) ? parseRgb(swatch, true) : hex2rgb(parseHex(swatch, true)); 231 $('<li class="minicolors-swatch minicolors-sprite"><span class="minicolors-swatch-color"></span></li>') 232 .appendTo(swatches) 233 .data('swatch-color', settings.swatches[i]) 234 .find('.minicolors-swatch-color') 235 .css({ 236 backgroundColor: rgb2hex(swatch), 237 opacity: swatch.a 238 }); 239 settings.swatches[i] = swatch; 240 } 241 242 } 243 244 // Inline controls 245 if( settings.inline ) input.parent().addClass('minicolors-inline'); 246 247 updateFromInput(input, false); 248 249 input.data('minicolors-initialized', true); 250 251 } 252 253 // Returns the input back to its original state 254 function destroy(input) { 255 256 var minicolors = input.parent(); 257 258 // Revert the input element 259 input 260 .removeData('minicolors-initialized') 261 .removeData('minicolors-settings') 262 .removeProp('size') 263 .removeClass('minicolors-input'); 264 265 // Remove the wrap and destroy whatever remains 266 minicolors.before(input).remove(); 267 268 } 269 270 // Shows the specified dropdown panel 271 function show(input) { 272 273 var minicolors = input.parent(), 274 panel = minicolors.find('.minicolors-panel'), 275 settings = input.data('minicolors-settings'); 276
277 // Do nothing if uninitialized, disabled, inline, or already open 278 if( !input.data('minicolors-initialized') || 279 input.prop('disabled') || 280 minicolors.hasClass('minicolors-inline') || 281 minicolors.hasClass('minicolors-focus') 282 ) return; 283 284 hide(); 285 286 minicolors.addClass('minicolors-focus'); 287 panel 288 .stop(true, true) 289 .fadeIn(settings.showSpeed, function() { 290 if( settings.show ) settings.show.call(input.get(0)); 291 }); 292 293 } 294 295 // Hides all dropdown panels 296 function hide() { 297 298 $('.minicolors-focus').each( function() { 299 300 var minicolors = $(this), 301 input = minicolors.find('.minicolors-input'), 302 panel = minicolors.find('.minicolors-panel'), 303 settings = input.data('minicolors-settings'); 304 305 panel.fadeOut(settings.hideSpeed, function() { 306 if( settings.hide ) settings.hide.call(input.get(0)); 307 minicolors.removeClass('minicolors-focus'); 308 }); 309 310 }); 311 } 312 313 // Moves the selected picker 314 function move(target, event, animate) { 315 316 var input = target.parents('.minicolors').find('.minicolors-input'), 317 settings = input.data('minicolors-settings'), 318 picker = target.find('[class$=-picker]'), 319 offsetX = target.offset().left, 320 offsetY = target.offset().top, 321 x = Math.round(event.pageX - offsetX), 322 y = Math.round(event.pageY - offsetY), 323 duration = animate ? settings.animationSpeed : 0, 324 wx, wy, r, phi; 325 326 // Touch support 327 if( event.originalEvent.changedTouches ) { 328 x = event.originalEvent.changedTouches[0].pageX - offsetX; 329 y = event.originalEvent.changedTouches[0].pageY - offsetY; 330 } 331 332 // Constrain picker to its container 333 if( x < 0 ) x = 0; 334 if( y < 0 ) y = 0; 335 if( x > target.width() ) x = target.width(); 336 if( y > target.height() ) y = target.height(); 337 338 // Constrain color wheel values to the wheel 339 if( target.parent().is('.minicolors-slider-wheel') && picker.parent().is('.minicolors-grid') ) { 340 wx = 75 - x; 341 wy = 75 - y; 342 r = Math.sqrt(wx * wx + wy * wy); 343 phi = Math.atan2(wy, wx); 344 if( phi < 0 ) phi += Math.PI * 2; 345 if( r > 75 ) { 346 r = 75; 347 x = 75 - (75 * Math.cos(phi)); 348 y = 75 - (75 * Math.sin(phi)); 349 } 350 x = Math.round(x); 351 y = Math.round(y); 352 } 353 354 // Move the picker 355 if( target.is('.minicolors-grid') ) { 356 picker 357 .stop(true) 358 .animate({ 359 top: y + 'px', 360 left: x + 'px' 361 }, duration, settings.animationEasing, function() { 362 updateFromControl(input, target); 363 }); 364 } else { 365 picker 366 .stop(true) 367 .animate({ 368 top: y + 'px' 369 }, duration, settings.animationEasing, function() { 370 updateFromControl(input, target); 371 }); 372 } 373 374 } 375 376 // Sets the input based on the color picker values 377 function updateFromControl(input, target) { 378 379 function getCoords(picker, container) { 380 381 var left, top; 382 if( !picker.length || !container ) return null; 383 left = picker.offset().left; 384 top = picker.offset().top; 385 386 return { 387 x: left - container.offset().left + (picker.outerWidth() / 2), 388 y: top - container.offset().top + (picker.outerHeight() / 2) 389 }; 390 391 } 392 393 var hue, saturation, brightness, x, y, r, phi, 394 395 hex = input.val(), 396 opacity = input.attr('data-opacity'), 397 398 // Helpful references 399 minicolors = input.parent(), 400 settings = input.data('minicolors-settings'), 401 swatch = minicolors.find('.minicolors-input-swatch'), 402 403 // Panel objects 404 grid = minicolors.find('.minicolors-grid'), 405 slider = minicolors.find('.minicolors-slider'), 406 opacitySlider = minicolors.find('.minicolors-opacity-slider'), 407 408 // Picker objects 409 gridPicker = grid.find('[class$=-picker]'), 410 sliderPicker = slider.find('[class$=-picker]'), 411 opacityPicker = opacitySlider.find('[class$=-picker]'), 412 413 // Picker positions 414 gridPos = getCoords(gridPicker, grid), 415 sliderPos = getCoords(sliderPicker, slider), 416 opacityPos = getCoords(opacityPicker, opacitySlider); 417 418 // Handle colors 419 if( target.is('.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider') ) { 420 421 // Determine HSB values 422 switch(settings.control) { 423 424 case 'wheel': 425 // Calculate hue, saturation, and brightness 426 x = (grid.width() / 2) - gridPos.x; 427 y = (grid.height() / 2) - gridPos.y; 428 r = Math.sqrt(x * x + y * y); 429 phi = Math.atan2(y, x); 430 if( phi < 0 ) phi += Math.PI * 2; 431 if( r > 75 ) { 432 r = 75; 433 gridPos.x = 69 - (75 * Math.cos(phi)); 434 gridPos.y = 69 - (75 * Math.sin(phi)); 435 } 436 saturation = keepWithin(r / 0.75, 0, 100); 437 hue = keepWithin(phi * 180 / Math.PI, 0, 360); 438 brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100); 439 hex = hsb2hex({ 440 h: hue, 441 s: saturation, 442 b: brightness 443 }); 444 445 // Update UI 446 slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 })); 447 break; 448 449 case 'saturation': 450 // Calculate hue, saturation, and brightness 451 hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360); 452 saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100); 453 brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100); 454 hex = hsb2hex({ 455 h: hue, 456 s: saturation, 457 b: brightness 458 }); 459 460 // Update UI 461 slider.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: brightness })); 462 minicolors.find('.minicolors-grid-inner').css('opacity', saturation / 100); 463 break; 464 465 case 'brightness': 466 // Calculate hue, saturation, and brightness 467 hue = keepWithin(parseInt(gridPos.x * (360 / grid.width()), 10), 0, 360); 468 saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100); 469 brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100); 470 hex = hsb2hex({ 471 h: hue, 472 s: saturation, 473 b: brightness 474 }); 475 476 // Update UI 477 slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 })); 478 minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (brightness / 100)); 479 break; 480 481 default: 482 // Calculate hue, saturation, and brightness 483 hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height()), 10), 0, 360); 484 saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100); 485 brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100); 486 hex = hsb2hex({ 487 h: hue, 488 s: saturation, 489 b: brightness 490 }); 491 492 // Update UI 493 grid.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: 100 })); 494 break; 495 496 } 497 498 // Handle opacity 499 if( settings.opacity ) { 500 opacity = parseFloat(1 - (opacityPos.y / opacitySlider.height())).toFixed(2); 501 } else { 502 opacity = 1; 503 } 504 505 updateInput(input, hex, opacity); 506 } 507 else { 508 // Set swatch color 509 swatch.find('span').css({ 510 backgroundColor: hex, 511 opacity: opacity 512 }); 513 514 // Handle change event 515 doChange(input, hex, opacity); 516 } 517 } 518 519 // Sets the value of the input and does the appropriate conversions 520 // to respect settings, also updates the swatch 521 function updateInput(input, value, opacity) { 522 var rgb, 523 524 // Helpful references 525 minicolors = input.parent(), 526 settings = input.data('minicolors-settings'), 527 swatch = minicolors.find('.minicolors-input-swatch'); 528 529 if( settings.opacity ) input.attr('data-opacity', opacity); 530 531 // Set color string 532 if( settings.format === 'rgb' ) { 533 // Returns RGB(A) string 534 535 // Checks for input format and does the conversion 536 if ( isRgb(value) ) { 537 rgb = parseRgb(value, true); 538 } 539 else { 540 rgb = hex2rgb(parseHex(value, true)); 541 } 542 543 opacity = input.attr('data-opacity') === '' ? 1 : keepWithin( parseFloat( input.attr('data-opacity') ).toFixed(2), 0, 1 );
544 if( isNaN( opacity ) || !settings.opacity ) opacity = 1; 545 546 if( input.minicolors('rgbObject').a <= 1 && rgb && settings.opacity) { 547 // Set RGBA string if alpha 548 value = 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat( opacity ) + ')'; 549 } else { 550 // Set RGB string (alpha = 1) 551 value = 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')'; 552 } 553 } else { 554 // Returns hex color 555 556 // Checks for input format and does the conversion 557 if ( isRgb(value) ) { 558 value = rgbString2hex(value); 559 } 560 561 value = convertCase( value, settings.letterCase ); 562 } 563 564 // Update value from picker 565 input.val( value ); 566 567 // Set swatch color 568 swatch.find('span').css({ 569 backgroundColor: value, 570 opacity: opacity 571 }); 572 573 // Handle change event 574 doChange(input, value, opacity); 575 } 576 577 // Sets the color picker values from the input 578 function updateFromInput(input, preserveInputValue) { 579 580 var hex, 581 hsb, 582 opacity, 583 keywords, 584 alpha, 585 value, 586 x, y, r, phi, 587 588 // Helpful references 589 minicolors = input.parent(), 590 settings = input.data('minicolors-settings'), 591 swatch = minicolors.find('.minicolors-input-swatch'), 592 593 // Panel objects 594 grid = minicolors.find('.minicolors-grid'), 595 slider = minicolors.find('.minicolors-slider'), 596 opacitySlider = minicolors.find('.minicolors-opacity-slider'), 597 598 // Picker objects 599 gridPicker = grid.find('[class$=-picker]'), 600 sliderPicker = slider.find('[class$=-picker]'), 601 opacityPicker = opacitySlider.find('[class$=-picker]'); 602 603 // Determine hex/HSB values 604 if( isRgb(input.val()) ) { 605 // If input value is a rgb(a) string, convert it to hex color and update opacity 606 hex = rgbString2hex(input.val()); 607 alpha = keepWithin(parseFloat(getAlpha(input.val())).toFixed(2), 0, 1); 608 if( alpha ) { 609 input.attr('data-opacity', alpha); 610 } 611 } else { 612 hex = convertCase(parseHex(input.val(), true), settings.letterCase); 613 } 614 615 if( !hex ){ 616 hex = convertCase(parseInput(settings.defaultValue, true), settings.letterCase); 617 } 618 hsb = hex2hsb(hex); 619 620 // Get array of lowercase keywords 621 keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function(a) { 622 return $.trim(a.toLowerCase()); 623 }); 624 625 // Set color string 626 if( input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1 ) { 627 value = convertCase(input.val()); 628 } else { 629 value = isRgb(input.val()) ? parseRgb(input.val()) : hex; 630 } 631 632 // Update input value 633 if( !preserveInputValue ) input.val(value); 634 635 // Determine opacity value 636 if( settings.opacity ) { 637 // Get from data-opacity attribute and keep within 0-1 range 638 opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1); 639 if( isNaN(opacity) ) opacity = 1; 640 input.attr('data-opacity', opacity); 641 swatch.find('span').css('opacity', opacity); 642 643 // Set opacity picker position 644 y = keepWithin(opacitySlider.height() - (opacitySlider.height() * opacity), 0, opacitySlider.height()); 645 opacityPicker.css('top', y + 'px'); 646 } 647 648 // Set opacity to zero if input value is transparent 649 if( input.val().toLowerCase() === 'transparent' ) { 650 swatch.find('span').css('opacity', 0); 651 } 652 653 // Update swatch 654 swatch.find('span').css('backgroundColor', hex); 655 656 // Determine picker locations 657 switch(settings.control) { 658 659 case 'wheel': 660 // Set grid position
661 r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2); 662 phi = hsb.h * Math.PI / 180; 663 x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width()); 664 y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height()); 665 gridPicker.css({ 666 top: y + 'px', 667 left: x + 'px' 668 }); 669 670 // Set slider position 671 y = 150 - (hsb.b / (100 / grid.height())); 672 if( hex === '' ) y = 0; 673 sliderPicker.css('top', y + 'px'); 674 675 // Update panel color 676 slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 })); 677 break; 678 679 case 'saturation': 680 // Set grid position 681 x = keepWithin((5 * hsb.h) / 12, 0, 150); 682 y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height()); 683 gridPicker.css({ 684 top: y + 'px', 685 left: x + 'px' 686 }); 687 688 // Set slider position 689 y = keepWithin(slider.height() - (hsb.s * (slider.height() / 100)), 0, slider.height()); 690 sliderPicker.css('top', y + 'px'); 691 692 // Update UI 693 slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: hsb.b })); 694 minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100); 695 break; 696 697 case 'brightness': 698 // Set grid position 699 x = keepWithin((5 * hsb.h) / 12, 0, 150); 700 y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height()); 701 gridPicker.css({ 702 top: y + 'px', 703 left: x + 'px' 704 }); 705 706 // Set slider position 707 y = keepWithin(slider.height() - (hsb.b * (slider.height() / 100)), 0, slider.height()); 708 sliderPicker.css('top', y + 'px'); 709 710 // Update UI 711 slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 })); 712 minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (hsb.b / 100)); 713 break; 714 715 default: 716 // Set grid position 717 x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width()); 718 y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height()); 719 gridPicker.css({ 720 top: y + 'px', 721 left: x + 'px' 722 }); 723 724 // Set slider position 725 y = keepWithin(slider.height() - (hsb.h / (360 / slider.height())), 0, slider.height()); 726 sliderPicker.css('top', y + 'px'); 727 728 // Update panel color 729 grid.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: 100 })); 730 break; 731 732 } 733 734 // Fire change event, but only if minicolors is fully initialized 735 if( input.data('minicolors-initialized') ) { 736 doChange(input, value, opacity); 737 } 738 739 } 740 741 // Runs the change and changeDelay callbacks 742 function doChange(input, value, opacity) { 743 744 var settings = input.data('minicolors-settings'), 745 lastChange = input.data('minicolors-lastChange'), 746 obj, 747 sel, 748 i; 749 750 // Only run if it actually changed 751 if( !lastChange || lastChange.value !== value || lastChange.opacity !== opacity ) { 752 753 // Remember last-changed value 754 input.data('minicolors-lastChange', { 755 value: value, 756 opacity: opacity 757 }); 758 759 // Check and select applicable swatch 760 if (settings.swatches && settings.swatches.length !== 0) { 761 if(!isRgb(value)) { 762 obj = hex2rgb(value); 763 } 764 else { 765 obj = parseRgb(value, true); 766 } 767 sel = -1; 768 for(i = 0; i < settings.swatches.length; ++i) { 769 if (obj.r === settings.swatches[i].r && obj.g === settings.swatches[i].g && obj.b === settings.swatches[i].b && obj.a === settings.swatches[i].a) { 770 sel = i; 771 break; 772 } 773 } 774 775 input.parent().find('.minicolors-swatches .minicolors-swatch').removeClass('selected'); 776 if (i !== -1) { 777 input.parent().find('.minicolors-swatches .minicolors-swatch').eq(i).addClass('selected'); 778 } 779 } 780 781 // Fire change event 782 if( settings.change ) { 783 if( settings.changeDelay ) { 784 // Call after a delay 785 clearTimeout(input.data('minicolors-changeTimeout')); 786 input.data('minicolors-changeTimeout', setTimeout( function() { 787 settings.change.call(input.get(0), value, opacity); 788 }, settings.changeDelay)); 789 } else { 790 // Call immediately 791 settings.change.call(input.get(0), value, opacity); 792 } 793 } 794 input.trigger('change').trigger('input'); 795 } 796 797 } 798 799 // Generates an RGB(A) object based on the input's value 800 function rgbObject(input) { 801 var hex = parseHex($(input).val(), true), 802 rgb = hex2rgb(hex), 803 opacity = $(input).attr('data-opacity'); 804 if( !rgb ) return null; 805 if( opacity !== undefined ) $.extend(rgb, { a: parseFloat(opacity) }); 806 return rgb; 807 } 808 809 // Generates an RGB(A) string based on the input's value 810 function rgbString(input, alpha) { 811 var hex = parseHex($(input).val(), true), 812 rgb = hex2rgb(hex), 813 opacity = $(input).attr('data-opacity'); 814 if( !rgb ) return null; 815 if( opacity === undefined ) opacity = 1; 816 if( alpha ) { 817 return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')'; 818 } else { 819 return 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')'; 820 } 821 } 822 823 // Converts to the letter case specified in settings 824 function convertCase(string, letterCase) { 825 return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase(); 826 } 827 828 // Parses a string and returns a valid hex string when possible 829 function parseHex(string, expand) {
830 string = string.replace(/^#/g, ''); 831 if( !string.match(/^[A-F0-9]{3,6}/ig) ) return ''; 832 if( string.length !== 3 && string.length !== 6 ) return ''; 833 if( string.length === 3 && expand ) { 834 string = string[0] + string[0] + string[1] + string[1] + string[2] + string[2]; 835 } 836 return '#' + string; 837 } 838 839 // Parses a string and returns a valid RGB(A) string when possible 840 function parseRgb(string, obj) { 841 842 var values = string.replace(/[^\d,.]/g, ''), 843 rgba = values.split(','); 844 845 rgba[0] = keepWithin(parseInt(rgba[0], 10), 0, 255); 846 rgba[1] = keepWithin(parseInt(rgba[1], 10), 0, 255); 847 rgba[2] = keepWithin(parseInt(rgba[2], 10), 0, 255); 848 if( rgba[3] ) { 849 rgba[3] = keepWithin(parseFloat(rgba[3], 10), 0, 1); 850 } 851 852 // Return RGBA object 853 if( obj ) { 854 return { 855 r: rgba[0], 856 g: rgba[1], 857 b: rgba[2], 858 a: rgba[3] ? rgba[3] : null 859 }; 860 } 861 862 // Return RGBA string 863 if( typeof(rgba[3]) !== 'undefined' && rgba[3] <= 1 ) { 864 return 'rgba(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ', ' + rgba[3] + ')'; 865 } else { 866 return 'rgb(' + rgba[0] + ', ' + rgba[1] + ', ' + rgba[2] + ')'; 867 } 868 869 } 870 871 // Parses a string and returns a valid color string when possible 872 function parseInput(string, expand) { 873 if( isRgb(string) ) { 874 // Returns a valid rgb(a) string 875 return parseRgb(string); 876 } else { 877 return parseHex(string, expand); 878 } 879 } 880 881 // Keeps value within min and max 882 function keepWithin(value, min, max) { 883 if( value < min ) value = min; 884 if( value > max ) value = max; 885 return value; 886 } 887 888 // Checks if a string is a valid RGB(A) string 889 function isRgb(string) { 890 var rgb = string.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); 891 return (rgb && rgb.length === 4) ? true : false; 892 } 893 894 // Function to get alpha from a RGB(A) string 895 function getAlpha(rgba) { 896 rgba = rgba.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+(\.\d{1,2})?|\.\d{1,2})[\s+]?/i); 897 return (rgba && rgba.length === 6) ? rgba[4] : '1'; 898 } 899 900 // Converts an HSB object to an RGB object 901 function hsb2rgb(hsb) { 902 var rgb = {}; 903 var h = Math.round(hsb.h); 904 var s = Math.round(hsb.s * 255 / 100); 905 var v = Math.round(hsb.b * 255 / 100); 906 if(s === 0) { 907 rgb.r = rgb.g = rgb.b = v; 908 } else { 909 var t1 = v; 910 var t2 = (255 - s) * v / 255; 911 var t3 = (t1 - t2) * (h % 60) / 60; 912 if( h === 360 ) h = 0; 913 if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; } 914 else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; } 915 else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; } 916 else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; } 917 else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; } 918 else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; } 919 else { rgb.r = 0; rgb.g = 0; rgb.b = 0; } 920 } 921 return { 922 r: Math.round(rgb.r), 923 g: Math.round(rgb.g), 924 b: Math.round(rgb.b) 925 }; 926 } 927 928 // Converts an RGB string to a hex string 929 function rgbString2hex(rgb){ 930 rgb = rgb.match(/^rgba?[\s+]?\([\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?,[\s+]?(\d+)[\s+]?/i); 931 return (rgb && rgb.length === 4) ? '#' + 932 ('0' + parseInt(rgb[1],10).toString(16)).slice(-2) + 933 ('0' + parseInt(rgb[2],10).toString(16)).slice(-2) + 934 ('0' + parseInt(rgb[3],10).toString(16)).slice(-2) : ''; 935 } 936 937 // Converts an RGB object to a hex string 938 function rgb2hex(rgb) { 939 var hex = [ 940 rgb.r.toString(16), 941 rgb.g.toString(16), 942 rgb.b.toString(16) 943 ]; 944 $.each(hex, function(nr, val) {
945 if (val.length === 1) hex[nr] = '0' + val; 946 }); 947 return '#' + hex.join(''); 948 } 949 950 // Converts an HSB object to a hex string 951 function hsb2hex(hsb) { 952 return rgb2hex(hsb2rgb(hsb)); 953 } 954 955 // Converts a hex string to an HSB object 956 function hex2hsb(hex) { 957 var hsb = rgb2hsb(hex2rgb(hex)); 958 if( hsb.s === 0 ) hsb.h = 360; 959 return hsb; 960 } 961 962 // Converts an RGB object to an HSB object 963 function rgb2hsb(rgb) { 964 var hsb = { h: 0, s: 0, b: 0 }; 965 var min = Math.min(rgb.r, rgb.g, rgb.b); 966 var max = Math.max(rgb.r, rgb.g, rgb.b); 967 var delta = max - min; 968 hsb.b = max; 969 hsb.s = max !== 0 ? 255 * delta / max : 0; 970 if( hsb.s !== 0 ) { 971 if( rgb.r === max ) { 972 hsb.h = (rgb.g - rgb.b) / delta; 973 } else if( rgb.g === max ) { 974 hsb.h = 2 + (rgb.b - rgb.r) / delta; 975 } else { 976 hsb.h = 4 + (rgb.r - rgb.g) / delta; 977 } 978 } else { 979 hsb.h = -1; 980 } 981 hsb.h *= 60; 982 if( hsb.h < 0 ) { 983 hsb.h += 360; 984 } 985 hsb.s *= 100/255; 986 hsb.b *= 100/255; 987 return hsb; 988 } 989 990 // Converts a hex string to an RGB object 991 function hex2rgb(hex) { 992 hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16); 993 return { 994 /* jshint ignore:start */ 995 r: hex >> 16, 996 g: (hex & 0x00FF00) >> 8, 997 b: (hex & 0x0000FF) 998 /* jshint ignore:end */ 999 }; 1000 } 1001 1002 // Handle events 1003 $(document) 1004 // Hide on clicks outside of the control 1005 .on('mousedown.minicolors touchstart.minicolors', function(event) { 1006 if( !$(event.target).parents().add(event.target).hasClass('minicolors') ) { 1007 hide(); 1008 } 1009 }) 1010 // Start moving 1011 .on('mousedown.minicolors touchstart.minicolors', '.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider', function(event) { 1012 var target = $(this); 1013 event.preventDefault(); 1014 $(document).data('minicolors-target', target); 1015 move(target, event, true); 1016 }) 1017 // Move pickers 1018 .on('mousemove.minicolors touchmove.minicolors', function(event) { 1019 var target = $(document).data('minicolors-target'); 1020 if( target ) move(target, event); 1021 }) 1022 // Stop moving 1023 .on('mouseup.minicolors touchend.minicolors', function() { 1024 $(this).removeData('minicolors-target'); 1025 }) 1026 // Selected a swatch 1027 .on('click.minicolors', '.minicolors-swatches li', function(event) { 1028 event.preventDefault(); 1029 var target = $(this), input = target.parents('.minicolors').find('.minicolors-input'), color = target.data('swatch-color'); 1030 updateInput(input, color, getAlpha(color)); 1031 updateFromInput(input); 1032 }) 1033 // Show panel when swatch is clicked 1034 .on('mousedown.minicolors touchstart.minicolors', '.minicolors-input-swatch', function(event) { 1035 var input = $(this).parent().find('.minicolors-input'); 1036 event.preventDefault(); 1037 show(input); 1038 }) 1039 // Show on focus 1040 .on('focus.minicolors', '.minicolors-input', function() { 1041 var input = $(this); 1042 if( !input.data('minicolors-initialized') ) return; 1043 show(input); 1044 }) 1045 // Update value on blur 1046 .on('blur.minicolors', '.minicolors-input', function() { 1047 var input = $(this), 1048 settings = input.data('minicolors-settings'), 1049 keywords, 1050 hex, 1051 rgba, 1052 swatchOpacity, 1053 value; 1054 1055 if( !input.data('minicolors-initialized') ) return; 1056 1057 // Get array of lowercase keywords 1058 keywords = !settings.keywords ? [] : $.map(settings.keywords.split(','), function(a) { 1059 return $.trim(a.toLowerCase()); 1060 }); 1061 1062 // Set color string 1063 if( input.val() !== '' && $.inArray(input.val().toLowerCase(), keywords) > -1 ) { 1064 value = input.val(); 1065 } else { 1066 // Get RGBA values for easy conversion 1067 if( isRgb(input.val()) ) { 1068 rgba = parseRgb(input.val(), true); 1069 } else { 1070 hex = parseHex(input.val(), true); 1071 rgba = hex ? hex2rgb(hex) : null; 1072 } 1073 1074 // Convert to format 1075 if( rgba === null ) { 1076 value = settings.defaultValue; 1077 } else if( settings.format === 'rgb' ) { 1078 value = settings.opacity ? 1079 parseRgb('rgba(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ',' + input.attr('data-opacity') + ')') : 1080 parseRgb('rgb(' + rgba.r + ',' + rgba.g + ',' + rgba.b + ')'); 1081 } else { 1082 value = rgb2hex(rgba); 1083 } 1084 } 1085 1086 // Update swatch opacity 1087 swatchOpacity = settings.opacity ? input.attr('data-opacity') : 1; 1088 if( value.toLowerCase() === 'transparent' ) swatchOpacity = 0; 1089 input 1090 .closest('.minicolors') 1091 .find('.minicolors-input-swatch > span') 1092 .css('opacity', swatchOpacity); 1093 1094 // Set input value 1095 input.val(value); 1096 1097 // Is it blank? 1098 if( input.val() === '' ) input.val(parseInput(settings.defaultValue, true)); 1099 1100 // Adjust case 1101 input.val( convertCase(input.val(), settings.letterCase) ); 1102 1103 }) 1104 // Handle keypresses 1105 .on('keydown.minicolors', '.minicolors-input', function(event) { 1106 var input = $(this); 1107 if( !input.data('minicolors-initialized') ) return; 1108 switch(event.keyCode) { 1109 case 9: // tab 1110 hide(); 1111 break; 1112 case 13: // enter 1113 case 27: // esc 1114 hide(); 1115 input.blur(); 1116 break; 1117 } 1118 }) 1119 // Update on keyup 1120 .on('keyup.minicolors', '.minicolors-input', function() { 1121 var input = $(this); 1122 if( !input.data('minicolors-initialized') ) return; 1123 updateFromInput(input, true); 1124 }) 1125 // Update on paste 1126 .on('paste.minicolors', '.minicolors-input', function() { 1127 var input = $(this); 1128 if( !input.data('minicolors-initialized') ) return; 1129 setTimeout( function() { 1130 updateFromInput(input, true); 1131 }, 1); 1132 }); 1133 1134}));
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.