spectrum-rails 1.3.1 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  module Spectrum
2
2
  module Rails
3
- VERSION = "1.3.1"
3
+ VERSION = "1.3.4"
4
4
  end
5
5
  end
@@ -1,115 +1,120 @@
1
- // Spectrum Colorpicker v1.3.1
1
+ // Spectrum Colorpicker v1.3.4
2
2
  // https://github.com/bgrins/spectrum
3
3
  // Author: Brian Grinstead
4
4
  // License: MIT
5
5
 
6
6
  (function (window, $, undefined) {
7
+ "use strict";
8
+
7
9
  var defaultOpts = {
8
10
 
9
- // Callbacks
10
- beforeShow: noop,
11
- move: noop,
12
- change: noop,
13
- show: noop,
14
- hide: noop,
15
-
16
- // Options
17
- color: false,
18
- flat: false,
19
- showInput: false,
20
- allowEmpty: false,
21
- showButtons: true,
22
- clickoutFiresChange: false,
23
- showInitial: false,
24
- showPalette: false,
25
- showPaletteOnly: false,
26
- showSelectionPalette: true,
27
- localStorageKey: false,
28
- appendTo: "body",
29
- maxSelectionSize: 7,
30
- cancelText: "cancel",
31
- chooseText: "choose",
32
- clearText: "Clear Color Selection",
33
- preferredFormat: false,
34
- className: "",
35
- showAlpha: false,
36
- theme: "sp-light",
37
- palette: ['fff', '000'],
38
- selectionPalette: [],
39
- disabled: false
40
- },
41
- spectrums = [],
42
- IE = !!/msie/i.exec( window.navigator.userAgent ),
43
- rgbaSupport = (function() {
44
- function contains( str, substr ) {
45
- return !!~('' + str).indexOf(substr);
46
- }
47
-
48
- var elem = document.createElement('div');
49
- var style = elem.style;
50
- style.cssText = 'background-color:rgba(0,0,0,.5)';
51
- return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
52
- })(),
53
- inputTypeColorSupport = (function() {
54
- var colorInput = $("<input type='color' value='!' />")[0];
55
- return colorInput.type === "color" && colorInput.value !== "!";
56
- })(),
57
- replaceInput = [
58
- "<div class='sp-replacer'>",
11
+ // Callbacks
12
+ beforeShow: noop,
13
+ move: noop,
14
+ change: noop,
15
+ show: noop,
16
+ hide: noop,
17
+
18
+ // Options
19
+ color: false,
20
+ flat: false,
21
+ showInput: false,
22
+ allowEmpty: false,
23
+ showButtons: true,
24
+ clickoutFiresChange: false,
25
+ showInitial: false,
26
+ showPalette: false,
27
+ showPaletteOnly: false,
28
+ showSelectionPalette: true,
29
+ localStorageKey: false,
30
+ appendTo: "body",
31
+ maxSelectionSize: 7,
32
+ cancelText: "cancel",
33
+ chooseText: "choose",
34
+ clearText: "Clear Color Selection",
35
+ noColorSelectedText: "No Color Selected",
36
+ preferredFormat: false,
37
+ className: "", // Deprecated - use containerClassName and replacerClassName instead.
38
+ containerClassName: "",
39
+ replacerClassName: "",
40
+ showAlpha: false,
41
+ theme: "sp-light",
42
+ palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
43
+ selectionPalette: [],
44
+ disabled: false
45
+ },
46
+ spectrums = [],
47
+ IE = !!/msie/i.exec( window.navigator.userAgent ),
48
+ rgbaSupport = (function() {
49
+ function contains( str, substr ) {
50
+ return !!~('' + str).indexOf(substr);
51
+ }
52
+
53
+ var elem = document.createElement('div');
54
+ var style = elem.style;
55
+ style.cssText = 'background-color:rgba(0,0,0,.5)';
56
+ return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
57
+ })(),
58
+ inputTypeColorSupport = (function() {
59
+ var colorInput = $("<input type='color' value='!' />")[0];
60
+ return colorInput.type === "color" && colorInput.value !== "!";
61
+ })(),
62
+ replaceInput = [
63
+ "<div class='sp-replacer'>",
59
64
  "<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
60
65
  "<div class='sp-dd'>&#9660;</div>",
61
- "</div>"
62
- ].join(''),
63
- markup = (function () {
66
+ "</div>"
67
+ ].join(''),
68
+ markup = (function () {
64
69
 
65
- // IE does not support gradients with multiple stops, so we need to simulate
66
- // that for the rainbow slider with 8 divs that each have a single gradient
67
- var gradientFix = "";
68
- if (IE) {
69
- for (var i = 1; i <= 6; i++) {
70
- gradientFix += "<div class='sp-" + i + "'></div>";
71
- }
70
+ // IE does not support gradients with multiple stops, so we need to simulate
71
+ // that for the rainbow slider with 8 divs that each have a single gradient
72
+ var gradientFix = "";
73
+ if (IE) {
74
+ for (var i = 1; i <= 6; i++) {
75
+ gradientFix += "<div class='sp-" + i + "'></div>";
72
76
  }
77
+ }
73
78
 
74
- return [
75
- "<div class='sp-container sp-hidden'>",
79
+ return [
80
+ "<div class='sp-container sp-hidden'>",
76
81
  "<div class='sp-palette-container'>",
77
- "<div class='sp-palette sp-thumb sp-cf'></div>",
82
+ "<div class='sp-palette sp-thumb sp-cf'></div>",
78
83
  "</div>",
79
84
  "<div class='sp-picker-container'>",
80
- "<div class='sp-top sp-cf'>",
81
- "<div class='sp-fill'></div>",
82
- "<div class='sp-top-inner'>",
83
- "<div class='sp-color'>",
84
- "<div class='sp-sat'>",
85
- "<div class='sp-val'>",
86
- "<div class='sp-dragger'></div>",
87
- "</div>",
88
- "</div>",
85
+ "<div class='sp-top sp-cf'>",
86
+ "<div class='sp-fill'></div>",
87
+ "<div class='sp-top-inner'>",
88
+ "<div class='sp-color'>",
89
+ "<div class='sp-sat'>",
90
+ "<div class='sp-val'>",
91
+ "<div class='sp-dragger'></div>",
92
+ "</div>",
93
+ "</div>",
94
+ "</div>",
95
+ "<div class='sp-clear sp-clear-display'>",
96
+ "</div>",
97
+ "<div class='sp-hue'>",
98
+ "<div class='sp-slider'></div>",
99
+ gradientFix,
100
+ "</div>",
101
+ "</div>",
102
+ "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
103
+ "</div>",
104
+ "<div class='sp-input-container sp-cf'>",
105
+ "<input class='sp-input' type='text' spellcheck='false' />",
106
+ "</div>",
107
+ "<div class='sp-initial sp-thumb sp-cf'></div>",
108
+ "<div class='sp-button-container sp-cf'>",
109
+ "<a class='sp-cancel' href='#'></a>",
110
+ "<button type='button' class='sp-choose'></button>",
111
+ "</div>",
89
112
  "</div>",
90
- "<div class='sp-clear sp-clear-display'>",
91
- "</div>",
92
- "<div class='sp-hue'>",
93
- "<div class='sp-slider'></div>",
94
- gradientFix,
95
- "</div>",
96
- "</div>",
97
- "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
98
- "</div>",
99
- "<div class='sp-input-container sp-cf'>",
100
- "<input class='sp-input' type='text' spellcheck='false' />",
101
- "</div>",
102
- "<div class='sp-initial sp-thumb sp-cf'></div>",
103
- "<div class='sp-button-container sp-cf'>",
104
- "<a class='sp-cancel' href='#'></a>",
105
- "<button class='sp-choose'></button>",
106
- "</div>",
107
- "</div>",
108
- "</div>"
109
- ].join("");
110
- })();
113
+ "</div>"
114
+ ].join("");
115
+ })();
111
116
 
112
- function paletteTemplate (p, color, className) {
117
+ function paletteTemplate (p, color, className, opts) {
113
118
  var html = [];
114
119
  for (var i = 0; i < p.length; i++) {
115
120
  var current = p[i];
@@ -117,12 +122,17 @@
117
122
  var tiny = tinycolor(current);
118
123
  var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
119
124
  c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
120
-
125
+ var formattedString = tiny.toString(opts.preferredFormat || "rgb");
121
126
  var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
122
- html.push('<span title="' + tiny.toRgbString() + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
127
+ html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
123
128
  } else {
124
129
  var cls = 'sp-clear-display';
125
- html.push('<span title="No Color Selected" data-color="" style="background-color:transparent;" class="' + cls + '"></span>');
130
+ html.push($('<div />')
131
+ .append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
132
+ .attr('title', opts.noColorSelectedText)
133
+ )
134
+ .html()
135
+ );
126
136
  }
127
137
  }
128
138
  return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
@@ -173,6 +183,7 @@
173
183
  currentAlpha = 1,
174
184
  palette = [],
175
185
  paletteArray = [],
186
+ paletteLookup = {},
176
187
  selectionPalette = opts.selectionPalette.slice(0),
177
188
  maxSelectionSize = opts.maxSelectionSize,
178
189
  draggingClass = "sp-dragging",
@@ -199,7 +210,7 @@
199
210
  isInput = boundElement.is("input"),
200
211
  isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color",
201
212
  shouldReplace = isInput && !flat,
202
- replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className) : $([]),
213
+ replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
203
214
  offsetElement = (shouldReplace) ? replacer : boundElement,
204
215
  previewElement = replacer.find(".sp-preview-inner"),
205
216
  initialColor = opts.color || (isInput && boundElement.val()),
@@ -219,6 +230,13 @@
219
230
  if (opts.palette) {
220
231
  palette = opts.palette.slice(0);
221
232
  paletteArray = $.isArray(palette[0]) ? palette : [palette];
233
+ paletteLookup = {};
234
+ for (var i = 0; i < paletteArray.length; i++) {
235
+ for (var j = 0; j < paletteArray[i].length; j++) {
236
+ var rgb = tinycolor(paletteArray[i][j]).toRgbString();
237
+ paletteLookup[rgb] = true;
238
+ }
239
+ }
222
240
  }
223
241
 
224
242
  container.toggleClass("sp-flat", flat);
@@ -229,7 +247,7 @@
229
247
  container.toggleClass("sp-palette-disabled", !opts.showPalette);
230
248
  container.toggleClass("sp-palette-only", opts.showPaletteOnly);
231
249
  container.toggleClass("sp-initial-disabled", !opts.showInitial);
232
- container.addClass(opts.className);
250
+ container.addClass(opts.className).addClass(opts.containerClassName);
233
251
 
234
252
  reflow();
235
253
  }
@@ -263,25 +281,7 @@
263
281
  appendTo.append(container);
264
282
  }
265
283
 
266
- if (localStorageKey && window.localStorage) {
267
-
268
- // Migrate old palettes over to new format. May want to remove this eventually.
269
- try {
270
- var oldPalette = window.localStorage[localStorageKey].split(",#");
271
- if (oldPalette.length > 1) {
272
- delete window.localStorage[localStorageKey];
273
- $.each(oldPalette, function(i, c) {
274
- addColorToSelectionPalette(c);
275
- });
276
- }
277
- }
278
- catch(e) { }
279
-
280
- try {
281
- selectionPalette = window.localStorage[localStorageKey].split(";");
282
- }
283
- catch (e) { }
284
- }
284
+ updateSelectionPaletteFromStorage();
285
285
 
286
286
  offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
287
287
  if (!disabled) {
@@ -412,11 +412,11 @@
412
412
 
413
413
  function palletElementClick(e) {
414
414
  if (e.data && e.data.ignore) {
415
- set($(this).data("color"));
415
+ set($(e.target).data("color"));
416
416
  move();
417
417
  }
418
418
  else {
419
- set($(this).data("color"));
419
+ set($(e.target).data("color"));
420
420
  move();
421
421
  updateOriginalInput(true);
422
422
  hide();
@@ -430,11 +430,34 @@
430
430
  initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick);
431
431
  }
432
432
 
433
+ function updateSelectionPaletteFromStorage() {
434
+
435
+ if (localStorageKey && window.localStorage) {
436
+
437
+ // Migrate old palettes over to new format. May want to remove this eventually.
438
+ try {
439
+ var oldPalette = window.localStorage[localStorageKey].split(",#");
440
+ if (oldPalette.length > 1) {
441
+ delete window.localStorage[localStorageKey];
442
+ $.each(oldPalette, function(i, c) {
443
+ addColorToSelectionPalette(c);
444
+ });
445
+ }
446
+ }
447
+ catch(e) { }
448
+
449
+ try {
450
+ selectionPalette = window.localStorage[localStorageKey].split(";");
451
+ }
452
+ catch (e) { }
453
+ }
454
+ }
455
+
433
456
  function addColorToSelectionPalette(color) {
434
457
  if (showSelectionPalette) {
435
- var colorRgb = tinycolor(color).toRgbString();
436
- if ($.inArray(colorRgb, selectionPalette) === -1) {
437
- selectionPalette.push(colorRgb);
458
+ var rgb = tinycolor(color).toRgbString();
459
+ if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
460
+ selectionPalette.push(rgb);
438
461
  while(selectionPalette.length > maxSelectionSize) {
439
462
  selectionPalette.shift();
440
463
  }
@@ -451,25 +474,12 @@
451
474
 
452
475
  function getUniqueSelectionPalette() {
453
476
  var unique = [];
454
- var p = selectionPalette;
455
- var paletteLookup = {};
456
- var rgb;
457
-
458
477
  if (opts.showPalette) {
478
+ for (var i = 0; i < selectionPalette.length; i++) {
479
+ var rgb = tinycolor(selectionPalette[i]).toRgbString();
459
480
 
460
- for (var i = 0; i < paletteArray.length; i++) {
461
- for (var j = 0; j < paletteArray[i].length; j++) {
462
- rgb = tinycolor(paletteArray[i][j]).toRgbString();
463
- paletteLookup[rgb] = true;
464
- }
465
- }
466
-
467
- for (i = 0; i < p.length; i++) {
468
- rgb = tinycolor(p[i]).toRgbString();
469
-
470
- if (!paletteLookup.hasOwnProperty(rgb)) {
471
- unique.push(p[i]);
472
- paletteLookup[rgb] = true;
481
+ if (!paletteLookup[rgb]) {
482
+ unique.push(selectionPalette[i]);
473
483
  }
474
484
  }
475
485
  }
@@ -482,11 +492,13 @@
482
492
  var currentColor = get();
483
493
 
484
494
  var html = $.map(paletteArray, function (palette, i) {
485
- return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i);
495
+ return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
486
496
  });
487
497
 
498
+ updateSelectionPaletteFromStorage();
499
+
488
500
  if (selectionPalette) {
489
- html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection"));
501
+ html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
490
502
  }
491
503
 
492
504
  paletteContainer.html(html.join(""));
@@ -496,7 +508,7 @@
496
508
  if (opts.showInitial) {
497
509
  var initial = colorOnShow;
498
510
  var current = get();
499
- initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial"));
511
+ initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
500
512
  }
501
513
  }
502
514
 
@@ -524,7 +536,7 @@
524
536
  }
525
537
  else {
526
538
  var tiny = tinycolor(value);
527
- if (tiny.ok) {
539
+ if (tiny.isValid()) {
528
540
  set(tiny);
529
541
  updateOriginalInput(true);
530
542
  }
@@ -632,8 +644,8 @@
632
644
  }
633
645
  updateUI();
634
646
 
635
- if (newColor && newColor.ok && !ignoreFormatChange) {
636
- currentPreferredFormat = preferredFormat || newColor.format;
647
+ if (newColor && newColor.isValid() && !ignoreFormatChange) {
648
+ currentPreferredFormat = preferredFormat || newColor.getFormat();
637
649
  }
638
650
  }
639
651
 
@@ -684,7 +696,7 @@
684
696
  var realColor = get({ format: format }),
685
697
  displayColor = '';
686
698
 
687
- //reset background info for preview element
699
+ //reset background info for preview element
688
700
  previewElement.removeClass("sp-clear-display");
689
701
  previewElement.css('background-color', 'transparent');
690
702
 
@@ -889,9 +901,9 @@
889
901
  }
890
902
 
891
903
  /**
892
- * checkOffset - get the offset below/above and left/right element depending on screen position
893
- * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
894
- */
904
+ * checkOffset - get the offset below/above and left/right element depending on screen position
905
+ * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
906
+ */
895
907
  function getOffset(picker, input) {
896
908
  var extraY = 0;
897
909
  var dpWidth = picker.outerWidth();
@@ -906,33 +918,33 @@
906
918
 
907
919
  offset.left -=
908
920
  Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
909
- Math.abs(offset.left + dpWidth - viewWidth) : 0);
921
+ Math.abs(offset.left + dpWidth - viewWidth) : 0);
910
922
 
911
923
  offset.top -=
912
924
  Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
913
- Math.abs(dpHeight + inputHeight - extraY) : extraY));
925
+ Math.abs(dpHeight + inputHeight - extraY) : extraY));
914
926
 
915
927
  return offset;
916
928
  }
917
929
 
918
930
  /**
919
- * noop - do nothing
920
- */
931
+ * noop - do nothing
932
+ */
921
933
  function noop() {
922
934
 
923
935
  }
924
936
 
925
937
  /**
926
- * stopPropagation - makes the code only doing this a little easier to read in line
927
- */
938
+ * stopPropagation - makes the code only doing this a little easier to read in line
939
+ */
928
940
  function stopPropagation(e) {
929
941
  e.stopPropagation();
930
942
  }
931
943
 
932
944
  /**
933
- * Create a function bound to a given object
934
- * Thanks to underscore.js
935
- */
945
+ * Create a function bound to a given object
946
+ * Thanks to underscore.js
947
+ */
936
948
  function bind(func, obj) {
937
949
  var slice = Array.prototype.slice;
938
950
  var args = slice.call(arguments, 2);
@@ -942,9 +954,9 @@
942
954
  }
943
955
 
944
956
  /**
945
- * Lightweight drag helper. Handles containment within the element, so that
946
- * when dragging, the x is within [0,element.width] and y is within [0,element.height]
947
- */
957
+ * Lightweight drag helper. Handles containment within the element, so that
958
+ * when dragging, the x is within [0,element.width] and y is within [0,element.height]
959
+ */
948
960
  function draggable(element, onmove, onstart, onstop) {
949
961
  onmove = onmove || function () { };
950
962
  onstart = onstart || function () { };
@@ -1043,11 +1055,9 @@
1043
1055
  };
1044
1056
  }
1045
1057
 
1046
- function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}}
1047
-
1048
1058
  /**
1049
- * Define a jQuery plugin
1050
- */
1059
+ * Define a jQuery plugin
1060
+ */
1051
1061
  var dataID = "spectrum.id";
1052
1062
  $.fn.spectrum = function (opts, extra) {
1053
1063
 
@@ -1111,412 +1121,430 @@
1111
1121
  }
1112
1122
  };
1113
1123
 
1114
- // TinyColor v0.9.17
1124
+ // TinyColor v0.10.0
1115
1125
  // https://github.com/bgrins/TinyColor
1116
1126
  // 2013-08-10, Brian Grinstead, MIT License
1117
1127
 
1118
1128
  (function() {
1119
1129
 
1120
- var trimLeft = /^[\s,#]+/,
1121
- trimRight = /\s+$/,
1122
- tinyCounter = 0,
1123
- math = Math,
1124
- mathRound = math.round,
1125
- mathMin = math.min,
1126
- mathMax = math.max,
1127
- mathRandom = math.random;
1128
-
1129
- function tinycolor (color, opts) {
1130
-
1131
- color = (color) ? color : '';
1132
- opts = opts || { };
1133
-
1134
- // If input is already a tinycolor, return itself
1135
- if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
1136
- return color;
1137
- }
1130
+ var trimLeft = /^[\s,#]+/,
1131
+ trimRight = /\s+$/,
1132
+ tinyCounter = 0,
1133
+ math = Math,
1134
+ mathRound = math.round,
1135
+ mathMin = math.min,
1136
+ mathMax = math.max,
1137
+ mathRandom = math.random;
1138
1138
 
1139
- var rgb = inputToRGB(color);
1140
- var r = rgb.r,
1141
- g = rgb.g,
1142
- b = rgb.b,
1143
- a = rgb.a,
1144
- roundA = mathRound(100*a) / 100,
1145
- format = opts.format || rgb.format;
1139
+ var tinycolor = function tinycolor (color, opts) {
1146
1140
 
1147
- // Don't let the range of [0,255] come back in [0,1].
1148
- // Potentially lose a little bit of precision here, but will fix issues where
1149
- // .5 gets interpreted as half of the total, instead of half of 1
1150
- // If it was supposed to be 128, this was already taken care of by `inputToRgb`
1151
- if (r < 1) { r = mathRound(r); }
1152
- if (g < 1) { g = mathRound(g); }
1153
- if (b < 1) { b = mathRound(b); }
1141
+ color = (color) ? color : '';
1142
+ opts = opts || { };
1154
1143
 
1155
- return {
1156
- ok: rgb.ok,
1157
- format: format,
1158
- _tc_id: tinyCounter++,
1159
- alpha: a,
1160
- getAlpha: function() {
1161
- return a;
1162
- },
1163
- setAlpha: function(value) {
1164
- a = boundAlpha(value);
1165
- roundA = mathRound(100*a) / 100;
1166
- },
1167
- toHsv: function() {
1168
- var hsv = rgbToHsv(r, g, b);
1169
- return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
1170
- },
1171
- toHsvString: function() {
1172
- var hsv = rgbToHsv(r, g, b);
1173
- var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1174
- return (a == 1) ?
1175
- "hsv(" + h + ", " + s + "%, " + v + "%)" :
1176
- "hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
1177
- },
1178
- toHsl: function() {
1179
- var hsl = rgbToHsl(r, g, b);
1180
- return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
1181
- },
1182
- toHslString: function() {
1183
- var hsl = rgbToHsl(r, g, b);
1184
- var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1185
- return (a == 1) ?
1186
- "hsl(" + h + ", " + s + "%, " + l + "%)" :
1187
- "hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
1188
- },
1189
- toHex: function(allow3Char) {
1190
- return rgbToHex(r, g, b, allow3Char);
1191
- },
1192
- toHexString: function(allow3Char) {
1193
- return '#' + this.toHex(allow3Char);
1194
- },
1195
- toHex8: function() {
1196
- return rgbaToHex(r, g, b, a);
1197
- },
1198
- toHex8String: function() {
1199
- return '#' + this.toHex8();
1200
- },
1201
- toRgb: function() {
1202
- return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
1203
- },
1204
- toRgbString: function() {
1205
- return (a == 1) ?
1206
- "rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
1207
- "rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
1208
- },
1209
- toPercentageRgb: function() {
1210
- return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
1211
- },
1212
- toPercentageRgbString: function() {
1213
- return (a == 1) ?
1214
- "rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
1215
- "rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
1216
- },
1217
- toName: function() {
1218
- if (a === 0) {
1219
- return "transparent";
1220
- }
1221
-
1222
- return hexNames[rgbToHex(r, g, b, true)] || false;
1223
- },
1224
- toFilter: function(secondColor) {
1225
- var hex8String = '#' + rgbaToHex(r, g, b, a);
1226
- var secondHex8String = hex8String;
1227
- var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
1144
+ // If input is already a tinycolor, return itself
1145
+ if (color instanceof tinycolor) {
1146
+ return color;
1147
+ }
1148
+ // If we are called as a function, call using new instead
1149
+ if (!(this instanceof tinycolor)) {
1150
+ return new tinycolor(color, opts);
1151
+ }
1228
1152
 
1229
- if (secondColor) {
1230
- var s = tinycolor(secondColor);
1231
- secondHex8String = s.toHex8String();
1232
- }
1153
+ var rgb = inputToRGB(color);
1154
+ this._r = rgb.r,
1155
+ this._g = rgb.g,
1156
+ this._b = rgb.b,
1157
+ this._a = rgb.a,
1158
+ this._roundA = mathRound(100*this._a) / 100,
1159
+ this._format = opts.format || rgb.format;
1160
+ this._gradientType = opts.gradientType;
1161
+
1162
+ // Don't let the range of [0,255] come back in [0,1].
1163
+ // Potentially lose a little bit of precision here, but will fix issues where
1164
+ // .5 gets interpreted as half of the total, instead of half of 1
1165
+ // If it was supposed to be 128, this was already taken care of by `inputToRgb`
1166
+ if (this._r < 1) { this._r = mathRound(this._r); }
1167
+ if (this._g < 1) { this._g = mathRound(this._g); }
1168
+ if (this._b < 1) { this._b = mathRound(this._b); }
1169
+
1170
+ this._ok = rgb.ok;
1171
+ this._tc_id = tinyCounter++;
1172
+ };
1233
1173
 
1234
- return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
1235
- },
1236
- toString: function(format) {
1237
- var formatSet = !!format;
1238
- format = format || this.format;
1174
+ tinycolor.prototype = {
1175
+ isValid: function() {
1176
+ return this._ok;
1177
+ },
1178
+ getFormat: function() {
1179
+ return this._format;
1180
+ },
1181
+ getAlpha: function() {
1182
+ return this._a;
1183
+ },
1184
+ setAlpha: function(value) {
1185
+ this._a = boundAlpha(value);
1186
+ this._roundA = mathRound(100*this._a) / 100;
1187
+ },
1188
+ toHsv: function() {
1189
+ var hsv = rgbToHsv(this._r, this._g, this._b);
1190
+ return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
1191
+ },
1192
+ toHsvString: function() {
1193
+ var hsv = rgbToHsv(this._r, this._g, this._b);
1194
+ var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1195
+ return (this._a == 1) ?
1196
+ "hsv(" + h + ", " + s + "%, " + v + "%)" :
1197
+ "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
1198
+ },
1199
+ toHsl: function() {
1200
+ var hsl = rgbToHsl(this._r, this._g, this._b);
1201
+ return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
1202
+ },
1203
+ toHslString: function() {
1204
+ var hsl = rgbToHsl(this._r, this._g, this._b);
1205
+ var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1206
+ return (this._a == 1) ?
1207
+ "hsl(" + h + ", " + s + "%, " + l + "%)" :
1208
+ "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
1209
+ },
1210
+ toHex: function(allow3Char) {
1211
+ return rgbToHex(this._r, this._g, this._b, allow3Char);
1212
+ },
1213
+ toHexString: function(allow3Char) {
1214
+ return '#' + this.toHex(allow3Char);
1215
+ },
1216
+ toHex8: function() {
1217
+ return rgbaToHex(this._r, this._g, this._b, this._a);
1218
+ },
1219
+ toHex8String: function() {
1220
+ return '#' + this.toHex8();
1221
+ },
1222
+ toRgb: function() {
1223
+ return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
1224
+ },
1225
+ toRgbString: function() {
1226
+ return (this._a == 1) ?
1227
+ "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
1228
+ "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
1229
+ },
1230
+ toPercentageRgb: function() {
1231
+ return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
1232
+ },
1233
+ toPercentageRgbString: function() {
1234
+ return (this._a == 1) ?
1235
+ "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
1236
+ "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
1237
+ },
1238
+ toName: function() {
1239
+ if (this._a === 0) {
1240
+ return "transparent";
1241
+ }
1239
1242
 
1240
- var formattedString = false;
1241
- var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
1242
- var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
1243
+ if (this._a < 1) {
1244
+ return false;
1245
+ }
1243
1246
 
1244
- if (format === "rgb") {
1245
- formattedString = this.toRgbString();
1246
- }
1247
- if (format === "prgb") {
1248
- formattedString = this.toPercentageRgbString();
1249
- }
1250
- if (format === "hex" || format === "hex6") {
1251
- formattedString = this.toHexString();
1252
- }
1253
- if (format === "hex3") {
1254
- formattedString = this.toHexString(true);
1255
- }
1256
- if (format === "hex8") {
1257
- formattedString = this.toHex8String();
1258
- }
1259
- if (format === "name") {
1260
- formattedString = this.toName();
1261
- }
1262
- if (format === "hsl") {
1263
- formattedString = this.toHslString();
1264
- }
1265
- if (format === "hsv") {
1266
- formattedString = this.toHsvString();
1267
- }
1247
+ return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
1248
+ },
1249
+ toFilter: function(secondColor) {
1250
+ var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
1251
+ var secondHex8String = hex8String;
1252
+ var gradientType = this._gradientType ? "GradientType = 1, " : "";
1268
1253
 
1269
- if (formatWithAlpha) {
1270
- return this.toRgbString();
1271
- }
1254
+ if (secondColor) {
1255
+ var s = tinycolor(secondColor);
1256
+ secondHex8String = s.toHex8String();
1257
+ }
1272
1258
 
1273
- return formattedString || this.toHexString();
1259
+ return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
1260
+ },
1261
+ toString: function(format) {
1262
+ var formatSet = !!format;
1263
+ format = format || this._format;
1264
+
1265
+ var formattedString = false;
1266
+ var hasAlpha = this._a < 1 && this._a >= 0;
1267
+ var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
1268
+
1269
+ if (needsAlphaFormat) {
1270
+ // Special case for "transparent", all other non-alpha formats
1271
+ // will return rgba when there is transparency.
1272
+ if (format === "name" && this._a === 0) {
1273
+ return this.toName();
1274
1274
  }
1275
- };
1275
+ return this.toRgbString();
1276
+ }
1277
+ if (format === "rgb") {
1278
+ formattedString = this.toRgbString();
1279
+ }
1280
+ if (format === "prgb") {
1281
+ formattedString = this.toPercentageRgbString();
1282
+ }
1283
+ if (format === "hex" || format === "hex6") {
1284
+ formattedString = this.toHexString();
1285
+ }
1286
+ if (format === "hex3") {
1287
+ formattedString = this.toHexString(true);
1288
+ }
1289
+ if (format === "hex8") {
1290
+ formattedString = this.toHex8String();
1291
+ }
1292
+ if (format === "name") {
1293
+ formattedString = this.toName();
1294
+ }
1295
+ if (format === "hsl") {
1296
+ formattedString = this.toHslString();
1297
+ }
1298
+ if (format === "hsv") {
1299
+ formattedString = this.toHsvString();
1300
+ }
1301
+
1302
+ return formattedString || this.toHexString();
1276
1303
  }
1304
+ };
1277
1305
 
1278
- // If input is an object, force 1 into "1.0" to handle ratios properly
1279
- // String input requires "1.0" as input, so 1 will be treated as 1
1280
- tinycolor.fromRatio = function(color, opts) {
1281
- if (typeof color == "object") {
1282
- var newColor = {};
1283
- for (var i in color) {
1284
- if (color.hasOwnProperty(i)) {
1285
- if (i === "a") {
1286
- newColor[i] = color[i];
1287
- }
1288
- else {
1289
- newColor[i] = convertToPercentage(color[i]);
1290
- }
1306
+ // If input is an object, force 1 into "1.0" to handle ratios properly
1307
+ // String input requires "1.0" as input, so 1 will be treated as 1
1308
+ tinycolor.fromRatio = function(color, opts) {
1309
+ if (typeof color == "object") {
1310
+ var newColor = {};
1311
+ for (var i in color) {
1312
+ if (color.hasOwnProperty(i)) {
1313
+ if (i === "a") {
1314
+ newColor[i] = color[i];
1315
+ }
1316
+ else {
1317
+ newColor[i] = convertToPercentage(color[i]);
1291
1318
  }
1292
1319
  }
1293
- color = newColor;
1294
1320
  }
1321
+ color = newColor;
1322
+ }
1295
1323
 
1296
- return tinycolor(color, opts);
1297
- };
1324
+ return tinycolor(color, opts);
1325
+ };
1298
1326
 
1299
- // Given a string or object, convert that input to RGB
1300
- // Possible string inputs:
1301
- //
1302
- // "red"
1303
- // "#f00" or "f00"
1304
- // "#ff0000" or "ff0000"
1305
- // "#ff000000" or "ff000000"
1306
- // "rgb 255 0 0" or "rgb (255, 0, 0)"
1307
- // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
1308
- // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
1309
- // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
1310
- // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
1311
- // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
1312
- // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
1313
- //
1314
- function inputToRGB(color) {
1315
-
1316
- var rgb = { r: 0, g: 0, b: 0 };
1317
- var a = 1;
1318
- var ok = false;
1319
- var format = false;
1320
-
1321
- if (typeof color == "string") {
1322
- color = stringInputToObject(color);
1323
- }
1324
-
1325
- if (typeof color == "object") {
1326
- if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
1327
- rgb = rgbToRgb(color.r, color.g, color.b);
1328
- ok = true;
1329
- format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
1330
- }
1331
- else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
1332
- color.s = convertToPercentage(color.s);
1333
- color.v = convertToPercentage(color.v);
1334
- rgb = hsvToRgb(color.h, color.s, color.v);
1335
- ok = true;
1336
- format = "hsv";
1337
- }
1338
- else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
1339
- color.s = convertToPercentage(color.s);
1340
- color.l = convertToPercentage(color.l);
1341
- rgb = hslToRgb(color.h, color.s, color.l);
1342
- ok = true;
1343
- format = "hsl";
1344
- }
1327
+ // Given a string or object, convert that input to RGB
1328
+ // Possible string inputs:
1329
+ //
1330
+ // "red"
1331
+ // "#f00" or "f00"
1332
+ // "#ff0000" or "ff0000"
1333
+ // "#ff000000" or "ff000000"
1334
+ // "rgb 255 0 0" or "rgb (255, 0, 0)"
1335
+ // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
1336
+ // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
1337
+ // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
1338
+ // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
1339
+ // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
1340
+ // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
1341
+ //
1342
+ function inputToRGB(color) {
1343
+
1344
+ var rgb = { r: 0, g: 0, b: 0 };
1345
+ var a = 1;
1346
+ var ok = false;
1347
+ var format = false;
1348
+
1349
+ if (typeof color == "string") {
1350
+ color = stringInputToObject(color);
1351
+ }
1345
1352
 
1346
- if (color.hasOwnProperty("a")) {
1347
- a = color.a;
1348
- }
1353
+ if (typeof color == "object") {
1354
+ if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
1355
+ rgb = rgbToRgb(color.r, color.g, color.b);
1356
+ ok = true;
1357
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
1358
+ }
1359
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
1360
+ color.s = convertToPercentage(color.s);
1361
+ color.v = convertToPercentage(color.v);
1362
+ rgb = hsvToRgb(color.h, color.s, color.v);
1363
+ ok = true;
1364
+ format = "hsv";
1365
+ }
1366
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
1367
+ color.s = convertToPercentage(color.s);
1368
+ color.l = convertToPercentage(color.l);
1369
+ rgb = hslToRgb(color.h, color.s, color.l);
1370
+ ok = true;
1371
+ format = "hsl";
1349
1372
  }
1350
1373
 
1351
- a = boundAlpha(a);
1352
-
1353
- return {
1354
- ok: ok,
1355
- format: color.format || format,
1356
- r: mathMin(255, mathMax(rgb.r, 0)),
1357
- g: mathMin(255, mathMax(rgb.g, 0)),
1358
- b: mathMin(255, mathMax(rgb.b, 0)),
1359
- a: a
1360
- };
1374
+ if (color.hasOwnProperty("a")) {
1375
+ a = color.a;
1376
+ }
1361
1377
  }
1362
1378
 
1379
+ a = boundAlpha(a);
1380
+
1381
+ return {
1382
+ ok: ok,
1383
+ format: color.format || format,
1384
+ r: mathMin(255, mathMax(rgb.r, 0)),
1385
+ g: mathMin(255, mathMax(rgb.g, 0)),
1386
+ b: mathMin(255, mathMax(rgb.b, 0)),
1387
+ a: a
1388
+ };
1389
+ }
1363
1390
 
1364
- // Conversion Functions
1365
- // --------------------
1366
1391
 
1367
- // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
1368
- // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
1392
+ // Conversion Functions
1393
+ // --------------------
1369
1394
 
1370
- // `rgbToRgb`
1371
- // Handle bounds / percentage checking to conform to CSS color spec
1372
- // <http://www.w3.org/TR/css3-color/>
1373
- // *Assumes:* r, g, b in [0, 255] or [0, 1]
1374
- // *Returns:* { r, g, b } in [0, 255]
1375
- function rgbToRgb(r, g, b){
1376
- return {
1377
- r: bound01(r, 255) * 255,
1378
- g: bound01(g, 255) * 255,
1379
- b: bound01(b, 255) * 255
1380
- };
1381
- }
1395
+ // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
1396
+ // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
1382
1397
 
1383
- // `rgbToHsl`
1384
- // Converts an RGB color value to HSL.
1385
- // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
1386
- // *Returns:* { h, s, l } in [0,1]
1387
- function rgbToHsl(r, g, b) {
1398
+ // `rgbToRgb`
1399
+ // Handle bounds / percentage checking to conform to CSS color spec
1400
+ // <http://www.w3.org/TR/css3-color/>
1401
+ // *Assumes:* r, g, b in [0, 255] or [0, 1]
1402
+ // *Returns:* { r, g, b } in [0, 255]
1403
+ function rgbToRgb(r, g, b){
1404
+ return {
1405
+ r: bound01(r, 255) * 255,
1406
+ g: bound01(g, 255) * 255,
1407
+ b: bound01(b, 255) * 255
1408
+ };
1409
+ }
1388
1410
 
1389
- r = bound01(r, 255);
1390
- g = bound01(g, 255);
1391
- b = bound01(b, 255);
1411
+ // `rgbToHsl`
1412
+ // Converts an RGB color value to HSL.
1413
+ // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
1414
+ // *Returns:* { h, s, l } in [0,1]
1415
+ function rgbToHsl(r, g, b) {
1392
1416
 
1393
- var max = mathMax(r, g, b), min = mathMin(r, g, b);
1394
- var h, s, l = (max + min) / 2;
1417
+ r = bound01(r, 255);
1418
+ g = bound01(g, 255);
1419
+ b = bound01(b, 255);
1395
1420
 
1396
- if(max == min) {
1397
- h = s = 0; // achromatic
1398
- }
1399
- else {
1400
- var d = max - min;
1401
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1402
- switch(max) {
1403
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1404
- case g: h = (b - r) / d + 2; break;
1405
- case b: h = (r - g) / d + 4; break;
1406
- }
1421
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
1422
+ var h, s, l = (max + min) / 2;
1407
1423
 
1408
- h /= 6;
1424
+ if(max == min) {
1425
+ h = s = 0; // achromatic
1426
+ }
1427
+ else {
1428
+ var d = max - min;
1429
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1430
+ switch(max) {
1431
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1432
+ case g: h = (b - r) / d + 2; break;
1433
+ case b: h = (r - g) / d + 4; break;
1409
1434
  }
1410
1435
 
1411
- return { h: h, s: s, l: l };
1436
+ h /= 6;
1412
1437
  }
1413
1438
 
1414
- // `hslToRgb`
1415
- // Converts an HSL color value to RGB.
1416
- // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
1417
- // *Returns:* { r, g, b } in the set [0, 255]
1418
- function hslToRgb(h, s, l) {
1419
- var r, g, b;
1420
-
1421
- h = bound01(h, 360);
1422
- s = bound01(s, 100);
1423
- l = bound01(l, 100);
1424
-
1425
- function hue2rgb(p, q, t) {
1426
- if(t < 0) t += 1;
1427
- if(t > 1) t -= 1;
1428
- if(t < 1/6) return p + (q - p) * 6 * t;
1429
- if(t < 1/2) return q;
1430
- if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
1431
- return p;
1432
- }
1439
+ return { h: h, s: s, l: l };
1440
+ }
1433
1441
 
1434
- if(s === 0) {
1435
- r = g = b = l; // achromatic
1436
- }
1437
- else {
1438
- var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1439
- var p = 2 * l - q;
1440
- r = hue2rgb(p, q, h + 1/3);
1441
- g = hue2rgb(p, q, h);
1442
- b = hue2rgb(p, q, h - 1/3);
1443
- }
1442
+ // `hslToRgb`
1443
+ // Converts an HSL color value to RGB.
1444
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
1445
+ // *Returns:* { r, g, b } in the set [0, 255]
1446
+ function hslToRgb(h, s, l) {
1447
+ var r, g, b;
1448
+
1449
+ h = bound01(h, 360);
1450
+ s = bound01(s, 100);
1451
+ l = bound01(l, 100);
1452
+
1453
+ function hue2rgb(p, q, t) {
1454
+ if(t < 0) t += 1;
1455
+ if(t > 1) t -= 1;
1456
+ if(t < 1/6) return p + (q - p) * 6 * t;
1457
+ if(t < 1/2) return q;
1458
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
1459
+ return p;
1460
+ }
1444
1461
 
1445
- return { r: r * 255, g: g * 255, b: b * 255 };
1462
+ if(s === 0) {
1463
+ r = g = b = l; // achromatic
1464
+ }
1465
+ else {
1466
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1467
+ var p = 2 * l - q;
1468
+ r = hue2rgb(p, q, h + 1/3);
1469
+ g = hue2rgb(p, q, h);
1470
+ b = hue2rgb(p, q, h - 1/3);
1446
1471
  }
1447
1472
 
1448
- // `rgbToHsv`
1449
- // Converts an RGB color value to HSV
1450
- // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
1451
- // *Returns:* { h, s, v } in [0,1]
1452
- function rgbToHsv(r, g, b) {
1473
+ return { r: r * 255, g: g * 255, b: b * 255 };
1474
+ }
1453
1475
 
1454
- r = bound01(r, 255);
1455
- g = bound01(g, 255);
1456
- b = bound01(b, 255);
1476
+ // `rgbToHsv`
1477
+ // Converts an RGB color value to HSV
1478
+ // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
1479
+ // *Returns:* { h, s, v } in [0,1]
1480
+ function rgbToHsv(r, g, b) {
1457
1481
 
1458
- var max = mathMax(r, g, b), min = mathMin(r, g, b);
1459
- var h, s, v = max;
1482
+ r = bound01(r, 255);
1483
+ g = bound01(g, 255);
1484
+ b = bound01(b, 255);
1460
1485
 
1461
- var d = max - min;
1462
- s = max === 0 ? 0 : d / max;
1486
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
1487
+ var h, s, v = max;
1463
1488
 
1464
- if(max == min) {
1465
- h = 0; // achromatic
1466
- }
1467
- else {
1468
- switch(max) {
1469
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1470
- case g: h = (b - r) / d + 2; break;
1471
- case b: h = (r - g) / d + 4; break;
1472
- }
1473
- h /= 6;
1489
+ var d = max - min;
1490
+ s = max === 0 ? 0 : d / max;
1491
+
1492
+ if(max == min) {
1493
+ h = 0; // achromatic
1494
+ }
1495
+ else {
1496
+ switch(max) {
1497
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1498
+ case g: h = (b - r) / d + 2; break;
1499
+ case b: h = (r - g) / d + 4; break;
1474
1500
  }
1475
- return { h: h, s: s, v: v };
1501
+ h /= 6;
1476
1502
  }
1503
+ return { h: h, s: s, v: v };
1504
+ }
1477
1505
 
1478
- // `hsvToRgb`
1479
- // Converts an HSV color value to RGB.
1480
- // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
1481
- // *Returns:* { r, g, b } in the set [0, 255]
1482
- function hsvToRgb(h, s, v) {
1483
-
1484
- h = bound01(h, 360) * 6;
1485
- s = bound01(s, 100);
1486
- v = bound01(v, 100);
1487
-
1488
- var i = math.floor(h),
1489
- f = h - i,
1490
- p = v * (1 - s),
1491
- q = v * (1 - f * s),
1492
- t = v * (1 - (1 - f) * s),
1493
- mod = i % 6,
1494
- r = [v, q, p, p, t, v][mod],
1495
- g = [t, v, v, q, p, p][mod],
1496
- b = [p, p, t, v, v, q][mod];
1506
+ // `hsvToRgb`
1507
+ // Converts an HSV color value to RGB.
1508
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
1509
+ // *Returns:* { r, g, b } in the set [0, 255]
1510
+ function hsvToRgb(h, s, v) {
1511
+
1512
+ h = bound01(h, 360) * 6;
1513
+ s = bound01(s, 100);
1514
+ v = bound01(v, 100);
1515
+
1516
+ var i = math.floor(h),
1517
+ f = h - i,
1518
+ p = v * (1 - s),
1519
+ q = v * (1 - f * s),
1520
+ t = v * (1 - (1 - f) * s),
1521
+ mod = i % 6,
1522
+ r = [v, q, p, p, t, v][mod],
1523
+ g = [t, v, v, q, p, p][mod],
1524
+ b = [p, p, t, v, v, q][mod];
1525
+
1526
+ return { r: r * 255, g: g * 255, b: b * 255 };
1527
+ }
1497
1528
 
1498
- return { r: r * 255, g: g * 255, b: b * 255 };
1529
+ // `rgbToHex`
1530
+ // Converts an RGB color to hex
1531
+ // Assumes r, g, and b are contained in the set [0, 255]
1532
+ // Returns a 3 or 6 character hex
1533
+ function rgbToHex(r, g, b, allow3Char) {
1534
+
1535
+ var hex = [
1536
+ pad2(mathRound(r).toString(16)),
1537
+ pad2(mathRound(g).toString(16)),
1538
+ pad2(mathRound(b).toString(16))
1539
+ ];
1540
+
1541
+ // Return a 3 character hex if possible
1542
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
1543
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1499
1544
  }
1500
1545
 
1501
- // `rgbToHex`
1502
- // Converts an RGB color to hex
1503
- // Assumes r, g, and b are contained in the set [0, 255]
1504
- // Returns a 3 or 6 character hex
1505
- function rgbToHex(r, g, b, allow3Char) {
1506
-
1507
- var hex = [
1508
- pad2(mathRound(r).toString(16)),
1509
- pad2(mathRound(g).toString(16)),
1510
- pad2(mathRound(b).toString(16))
1511
- ];
1512
-
1513
- // Return a 3 character hex if possible
1514
- if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
1515
- return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1516
- }
1517
-
1518
- return hex.join("");
1519
- }
1546
+ return hex.join("");
1547
+ }
1520
1548
  // `rgbaToHex`
1521
1549
  // Converts an RGBA color plus alpha transparency to hex
1522
1550
  // Assumes r, g, b and a are contained in the set [0, 255]
@@ -1533,536 +1561,542 @@
1533
1561
  return hex.join("");
1534
1562
  }
1535
1563
 
1536
- // `equals`
1537
- // Can be called with any tinycolor input
1538
- tinycolor.equals = function (color1, color2) {
1539
- if (!color1 || !color2) { return false; }
1540
- return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
1541
- };
1542
- tinycolor.random = function() {
1543
- return tinycolor.fromRatio({
1544
- r: mathRandom(),
1545
- g: mathRandom(),
1546
- b: mathRandom()
1547
- });
1548
- };
1549
-
1564
+ // `equals`
1565
+ // Can be called with any tinycolor input
1566
+ tinycolor.equals = function (color1, color2) {
1567
+ if (!color1 || !color2) { return false; }
1568
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
1569
+ };
1570
+ tinycolor.random = function() {
1571
+ return tinycolor.fromRatio({
1572
+ r: mathRandom(),
1573
+ g: mathRandom(),
1574
+ b: mathRandom()
1575
+ });
1576
+ };
1550
1577
 
1551
- // Modification Functions
1552
- // ----------------------
1553
- // Thanks to less.js for some of the basics here
1554
- // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
1555
1578
 
1556
- tinycolor.desaturate = function (color, amount) {
1557
- amount = (amount === 0) ? 0 : (amount || 10);
1558
- var hsl = tinycolor(color).toHsl();
1559
- hsl.s -= amount / 100;
1560
- hsl.s = clamp01(hsl.s);
1561
- return tinycolor(hsl);
1562
- };
1563
- tinycolor.saturate = function (color, amount) {
1564
- amount = (amount === 0) ? 0 : (amount || 10);
1565
- var hsl = tinycolor(color).toHsl();
1566
- hsl.s += amount / 100;
1567
- hsl.s = clamp01(hsl.s);
1568
- return tinycolor(hsl);
1569
- };
1570
- tinycolor.greyscale = function(color) {
1571
- return tinycolor.desaturate(color, 100);
1572
- };
1573
- tinycolor.lighten = function(color, amount) {
1574
- amount = (amount === 0) ? 0 : (amount || 10);
1575
- var hsl = tinycolor(color).toHsl();
1576
- hsl.l += amount / 100;
1577
- hsl.l = clamp01(hsl.l);
1578
- return tinycolor(hsl);
1579
- };
1580
- tinycolor.darken = function (color, amount) {
1581
- amount = (amount === 0) ? 0 : (amount || 10);
1582
- var hsl = tinycolor(color).toHsl();
1583
- hsl.l -= amount / 100;
1584
- hsl.l = clamp01(hsl.l);
1585
- return tinycolor(hsl);
1586
- };
1587
- tinycolor.complement = function(color) {
1588
- var hsl = tinycolor(color).toHsl();
1589
- hsl.h = (hsl.h + 180) % 360;
1590
- return tinycolor(hsl);
1591
- };
1579
+ // Modification Functions
1580
+ // ----------------------
1581
+ // Thanks to less.js for some of the basics here
1582
+ // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
1592
1583
 
1584
+ tinycolor.desaturate = function (color, amount) {
1585
+ amount = (amount === 0) ? 0 : (amount || 10);
1586
+ var hsl = tinycolor(color).toHsl();
1587
+ hsl.s -= amount / 100;
1588
+ hsl.s = clamp01(hsl.s);
1589
+ return tinycolor(hsl);
1590
+ };
1591
+ tinycolor.saturate = function (color, amount) {
1592
+ amount = (amount === 0) ? 0 : (amount || 10);
1593
+ var hsl = tinycolor(color).toHsl();
1594
+ hsl.s += amount / 100;
1595
+ hsl.s = clamp01(hsl.s);
1596
+ return tinycolor(hsl);
1597
+ };
1598
+ tinycolor.greyscale = function(color) {
1599
+ return tinycolor.desaturate(color, 100);
1600
+ };
1601
+ tinycolor.lighten = function(color, amount) {
1602
+ amount = (amount === 0) ? 0 : (amount || 10);
1603
+ var hsl = tinycolor(color).toHsl();
1604
+ hsl.l += amount / 100;
1605
+ hsl.l = clamp01(hsl.l);
1606
+ return tinycolor(hsl);
1607
+ };
1608
+ tinycolor.brighten = function(color, amount) {
1609
+ amount = (amount === 0) ? 0 : (amount || 10);
1610
+ var rgb = tinycolor(color).toRgb();
1611
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
1612
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
1613
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
1614
+ return tinycolor(rgb);
1615
+ };
1616
+ tinycolor.darken = function (color, amount) {
1617
+ amount = (amount === 0) ? 0 : (amount || 10);
1618
+ var hsl = tinycolor(color).toHsl();
1619
+ hsl.l -= amount / 100;
1620
+ hsl.l = clamp01(hsl.l);
1621
+ return tinycolor(hsl);
1622
+ };
1623
+ tinycolor.complement = function(color) {
1624
+ var hsl = tinycolor(color).toHsl();
1625
+ hsl.h = (hsl.h + 180) % 360;
1626
+ return tinycolor(hsl);
1627
+ };
1593
1628
 
1594
- // Combination Functions
1595
- // ---------------------
1596
- // Thanks to jQuery xColor for some of the ideas behind these
1597
- // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
1598
-
1599
- tinycolor.triad = function(color) {
1600
- var hsl = tinycolor(color).toHsl();
1601
- var h = hsl.h;
1602
- return [
1603
- tinycolor(color),
1604
- tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1605
- tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
1606
- ];
1607
- };
1608
- tinycolor.tetrad = function(color) {
1609
- var hsl = tinycolor(color).toHsl();
1610
- var h = hsl.h;
1611
- return [
1612
- tinycolor(color),
1613
- tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1614
- tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1615
- tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
1616
- ];
1617
- };
1618
- tinycolor.splitcomplement = function(color) {
1619
- var hsl = tinycolor(color).toHsl();
1620
- var h = hsl.h;
1621
- return [
1622
- tinycolor(color),
1623
- tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
1624
- tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
1625
- ];
1626
- };
1627
- tinycolor.analogous = function(color, results, slices) {
1628
- results = results || 6;
1629
- slices = slices || 30;
1630
1629
 
1631
- var hsl = tinycolor(color).toHsl();
1632
- var part = 360 / slices;
1633
- var ret = [tinycolor(color)];
1630
+ // Combination Functions
1631
+ // ---------------------
1632
+ // Thanks to jQuery xColor for some of the ideas behind these
1633
+ // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
1634
1634
 
1635
- for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
1636
- hsl.h = (hsl.h + part) % 360;
1637
- ret.push(tinycolor(hsl));
1638
- }
1639
- return ret;
1640
- };
1641
- tinycolor.monochromatic = function(color, results) {
1642
- results = results || 6;
1643
- var hsv = tinycolor(color).toHsv();
1644
- var h = hsv.h, s = hsv.s, v = hsv.v;
1645
- var ret = [];
1646
- var modification = 1 / results;
1635
+ tinycolor.triad = function(color) {
1636
+ var hsl = tinycolor(color).toHsl();
1637
+ var h = hsl.h;
1638
+ return [
1639
+ tinycolor(color),
1640
+ tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1641
+ tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
1642
+ ];
1643
+ };
1644
+ tinycolor.tetrad = function(color) {
1645
+ var hsl = tinycolor(color).toHsl();
1646
+ var h = hsl.h;
1647
+ return [
1648
+ tinycolor(color),
1649
+ tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1650
+ tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1651
+ tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
1652
+ ];
1653
+ };
1654
+ tinycolor.splitcomplement = function(color) {
1655
+ var hsl = tinycolor(color).toHsl();
1656
+ var h = hsl.h;
1657
+ return [
1658
+ tinycolor(color),
1659
+ tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
1660
+ tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
1661
+ ];
1662
+ };
1663
+ tinycolor.analogous = function(color, results, slices) {
1664
+ results = results || 6;
1665
+ slices = slices || 30;
1647
1666
 
1648
- while (results--) {
1649
- ret.push(tinycolor({ h: h, s: s, v: v}));
1650
- v = (v + modification) % 1;
1651
- }
1667
+ var hsl = tinycolor(color).toHsl();
1668
+ var part = 360 / slices;
1669
+ var ret = [tinycolor(color)];
1652
1670
 
1653
- return ret;
1654
- };
1671
+ for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
1672
+ hsl.h = (hsl.h + part) % 360;
1673
+ ret.push(tinycolor(hsl));
1674
+ }
1675
+ return ret;
1676
+ };
1677
+ tinycolor.monochromatic = function(color, results) {
1678
+ results = results || 6;
1679
+ var hsv = tinycolor(color).toHsv();
1680
+ var h = hsv.h, s = hsv.s, v = hsv.v;
1681
+ var ret = [];
1682
+ var modification = 1 / results;
1683
+
1684
+ while (results--) {
1685
+ ret.push(tinycolor({ h: h, s: s, v: v}));
1686
+ v = (v + modification) % 1;
1687
+ }
1655
1688
 
1689
+ return ret;
1690
+ };
1656
1691
 
1657
- // Readability Functions
1658
- // ---------------------
1659
- // <http://www.w3.org/TR/AERT#color-contrast>
1660
-
1661
- // `readability`
1662
- // Analyze the 2 colors and returns an object with the following properties:
1663
- // `brightness`: difference in brightness between the two colors
1664
- // `color`: difference in color/hue between the two colors
1665
- tinycolor.readability = function(color1, color2) {
1666
- var a = tinycolor(color1).toRgb();
1667
- var b = tinycolor(color2).toRgb();
1668
- var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
1669
- var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
1670
- var colorDiff = (
1671
- Math.max(a.r, b.r) - Math.min(a.r, b.r) +
1672
- Math.max(a.g, b.g) - Math.min(a.g, b.g) +
1673
- Math.max(a.b, b.b) - Math.min(a.b, b.b)
1674
- );
1675
1692
 
1676
- return {
1677
- brightness: Math.abs(brightnessA - brightnessB),
1678
- color: colorDiff
1679
- };
1693
+ // Readability Functions
1694
+ // ---------------------
1695
+ // <http://www.w3.org/TR/AERT#color-contrast>
1696
+
1697
+ // `readability`
1698
+ // Analyze the 2 colors and returns an object with the following properties:
1699
+ // `brightness`: difference in brightness between the two colors
1700
+ // `color`: difference in color/hue between the two colors
1701
+ tinycolor.readability = function(color1, color2) {
1702
+ var a = tinycolor(color1).toRgb();
1703
+ var b = tinycolor(color2).toRgb();
1704
+ var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
1705
+ var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
1706
+ var colorDiff = (
1707
+ Math.max(a.r, b.r) - Math.min(a.r, b.r) +
1708
+ Math.max(a.g, b.g) - Math.min(a.g, b.g) +
1709
+ Math.max(a.b, b.b) - Math.min(a.b, b.b)
1710
+ );
1711
+
1712
+ return {
1713
+ brightness: Math.abs(brightnessA - brightnessB),
1714
+ color: colorDiff
1680
1715
  };
1716
+ };
1681
1717
 
1682
- // `readable`
1683
- // http://www.w3.org/TR/AERT#color-contrast
1684
- // Ensure that foreground and background color combinations provide sufficient contrast.
1685
- // *Example*
1686
- // tinycolor.readable("#000", "#111") => false
1687
- tinycolor.readable = function(color1, color2) {
1688
- var readability = tinycolor.readability(color1, color2);
1689
- return readability.brightness > 125 && readability.color > 500;
1690
- };
1718
+ // `readable`
1719
+ // http://www.w3.org/TR/AERT#color-contrast
1720
+ // Ensure that foreground and background color combinations provide sufficient contrast.
1721
+ // *Example*
1722
+ // tinycolor.readable("#000", "#111") => false
1723
+ tinycolor.readable = function(color1, color2) {
1724
+ var readability = tinycolor.readability(color1, color2);
1725
+ return readability.brightness > 125 && readability.color > 500;
1726
+ };
1691
1727
 
1692
- // `mostReadable`
1693
- // Given a base color and a list of possible foreground or background
1694
- // colors for that base, returns the most readable color.
1695
- // *Example*
1696
- // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
1697
- tinycolor.mostReadable = function(baseColor, colorList) {
1698
- var bestColor = null;
1699
- var bestScore = 0;
1700
- var bestIsReadable = false;
1701
- for (var i=0; i < colorList.length; i++) {
1702
-
1703
- // We normalize both around the "acceptable" breaking point,
1704
- // but rank brightness constrast higher than hue.
1705
-
1706
- var readability = tinycolor.readability(baseColor, colorList[i]);
1707
- var readable = readability.brightness > 125 && readability.color > 500;
1708
- var score = 3 * (readability.brightness / 125) + (readability.color / 500);
1709
-
1710
- if ((readable && ! bestIsReadable) ||
1711
- (readable && bestIsReadable && score > bestScore) ||
1712
- ((! readable) && (! bestIsReadable) && score > bestScore)) {
1713
- bestIsReadable = readable;
1714
- bestScore = score;
1715
- bestColor = tinycolor(colorList[i]);
1716
- }
1728
+ // `mostReadable`
1729
+ // Given a base color and a list of possible foreground or background
1730
+ // colors for that base, returns the most readable color.
1731
+ // *Example*
1732
+ // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
1733
+ tinycolor.mostReadable = function(baseColor, colorList) {
1734
+ var bestColor = null;
1735
+ var bestScore = 0;
1736
+ var bestIsReadable = false;
1737
+ for (var i=0; i < colorList.length; i++) {
1738
+
1739
+ // We normalize both around the "acceptable" breaking point,
1740
+ // but rank brightness constrast higher than hue.
1741
+
1742
+ var readability = tinycolor.readability(baseColor, colorList[i]);
1743
+ var readable = readability.brightness > 125 && readability.color > 500;
1744
+ var score = 3 * (readability.brightness / 125) + (readability.color / 500);
1745
+
1746
+ if ((readable && ! bestIsReadable) ||
1747
+ (readable && bestIsReadable && score > bestScore) ||
1748
+ ((! readable) && (! bestIsReadable) && score > bestScore)) {
1749
+ bestIsReadable = readable;
1750
+ bestScore = score;
1751
+ bestColor = tinycolor(colorList[i]);
1717
1752
  }
1718
- return bestColor;
1719
- };
1753
+ }
1754
+ return bestColor;
1755
+ };
1720
1756
 
1721
1757
 
1722
- // Big List of Colors
1723
- // ------------------
1724
- // <http://www.w3.org/TR/css3-color/#svg-color>
1725
- var names = tinycolor.names = {
1726
- aliceblue: "f0f8ff",
1727
- antiquewhite: "faebd7",
1728
- aqua: "0ff",
1729
- aquamarine: "7fffd4",
1730
- azure: "f0ffff",
1731
- beige: "f5f5dc",
1732
- bisque: "ffe4c4",
1733
- black: "000",
1734
- blanchedalmond: "ffebcd",
1735
- blue: "00f",
1736
- blueviolet: "8a2be2",
1737
- brown: "a52a2a",
1738
- burlywood: "deb887",
1739
- burntsienna: "ea7e5d",
1740
- cadetblue: "5f9ea0",
1741
- chartreuse: "7fff00",
1742
- chocolate: "d2691e",
1743
- coral: "ff7f50",
1744
- cornflowerblue: "6495ed",
1745
- cornsilk: "fff8dc",
1746
- crimson: "dc143c",
1747
- cyan: "0ff",
1748
- darkblue: "00008b",
1749
- darkcyan: "008b8b",
1750
- darkgoldenrod: "b8860b",
1751
- darkgray: "a9a9a9",
1752
- darkgreen: "006400",
1753
- darkgrey: "a9a9a9",
1754
- darkkhaki: "bdb76b",
1755
- darkmagenta: "8b008b",
1756
- darkolivegreen: "556b2f",
1757
- darkorange: "ff8c00",
1758
- darkorchid: "9932cc",
1759
- darkred: "8b0000",
1760
- darksalmon: "e9967a",
1761
- darkseagreen: "8fbc8f",
1762
- darkslateblue: "483d8b",
1763
- darkslategray: "2f4f4f",
1764
- darkslategrey: "2f4f4f",
1765
- darkturquoise: "00ced1",
1766
- darkviolet: "9400d3",
1767
- deeppink: "ff1493",
1768
- deepskyblue: "00bfff",
1769
- dimgray: "696969",
1770
- dimgrey: "696969",
1771
- dodgerblue: "1e90ff",
1772
- firebrick: "b22222",
1773
- floralwhite: "fffaf0",
1774
- forestgreen: "228b22",
1775
- fuchsia: "f0f",
1776
- gainsboro: "dcdcdc",
1777
- ghostwhite: "f8f8ff",
1778
- gold: "ffd700",
1779
- goldenrod: "daa520",
1780
- gray: "808080",
1781
- green: "008000",
1782
- greenyellow: "adff2f",
1783
- grey: "808080",
1784
- honeydew: "f0fff0",
1785
- hotpink: "ff69b4",
1786
- indianred: "cd5c5c",
1787
- indigo: "4b0082",
1788
- ivory: "fffff0",
1789
- khaki: "f0e68c",
1790
- lavender: "e6e6fa",
1791
- lavenderblush: "fff0f5",
1792
- lawngreen: "7cfc00",
1793
- lemonchiffon: "fffacd",
1794
- lightblue: "add8e6",
1795
- lightcoral: "f08080",
1796
- lightcyan: "e0ffff",
1797
- lightgoldenrodyellow: "fafad2",
1798
- lightgray: "d3d3d3",
1799
- lightgreen: "90ee90",
1800
- lightgrey: "d3d3d3",
1801
- lightpink: "ffb6c1",
1802
- lightsalmon: "ffa07a",
1803
- lightseagreen: "20b2aa",
1804
- lightskyblue: "87cefa",
1805
- lightslategray: "789",
1806
- lightslategrey: "789",
1807
- lightsteelblue: "b0c4de",
1808
- lightyellow: "ffffe0",
1809
- lime: "0f0",
1810
- limegreen: "32cd32",
1811
- linen: "faf0e6",
1812
- magenta: "f0f",
1813
- maroon: "800000",
1814
- mediumaquamarine: "66cdaa",
1815
- mediumblue: "0000cd",
1816
- mediumorchid: "ba55d3",
1817
- mediumpurple: "9370db",
1818
- mediumseagreen: "3cb371",
1819
- mediumslateblue: "7b68ee",
1820
- mediumspringgreen: "00fa9a",
1821
- mediumturquoise: "48d1cc",
1822
- mediumvioletred: "c71585",
1823
- midnightblue: "191970",
1824
- mintcream: "f5fffa",
1825
- mistyrose: "ffe4e1",
1826
- moccasin: "ffe4b5",
1827
- navajowhite: "ffdead",
1828
- navy: "000080",
1829
- oldlace: "fdf5e6",
1830
- olive: "808000",
1831
- olivedrab: "6b8e23",
1832
- orange: "ffa500",
1833
- orangered: "ff4500",
1834
- orchid: "da70d6",
1835
- palegoldenrod: "eee8aa",
1836
- palegreen: "98fb98",
1837
- paleturquoise: "afeeee",
1838
- palevioletred: "db7093",
1839
- papayawhip: "ffefd5",
1840
- peachpuff: "ffdab9",
1841
- peru: "cd853f",
1842
- pink: "ffc0cb",
1843
- plum: "dda0dd",
1844
- powderblue: "b0e0e6",
1845
- purple: "800080",
1846
- red: "f00",
1847
- rosybrown: "bc8f8f",
1848
- royalblue: "4169e1",
1849
- saddlebrown: "8b4513",
1850
- salmon: "fa8072",
1851
- sandybrown: "f4a460",
1852
- seagreen: "2e8b57",
1853
- seashell: "fff5ee",
1854
- sienna: "a0522d",
1855
- silver: "c0c0c0",
1856
- skyblue: "87ceeb",
1857
- slateblue: "6a5acd",
1858
- slategray: "708090",
1859
- slategrey: "708090",
1860
- snow: "fffafa",
1861
- springgreen: "00ff7f",
1862
- steelblue: "4682b4",
1863
- tan: "d2b48c",
1864
- teal: "008080",
1865
- thistle: "d8bfd8",
1866
- tomato: "ff6347",
1867
- turquoise: "40e0d0",
1868
- violet: "ee82ee",
1869
- wheat: "f5deb3",
1870
- white: "fff",
1871
- whitesmoke: "f5f5f5",
1872
- yellow: "ff0",
1873
- yellowgreen: "9acd32"
1874
- };
1758
+ // Big List of Colors
1759
+ // ------------------
1760
+ // <http://www.w3.org/TR/css3-color/#svg-color>
1761
+ var names = tinycolor.names = {
1762
+ aliceblue: "f0f8ff",
1763
+ antiquewhite: "faebd7",
1764
+ aqua: "0ff",
1765
+ aquamarine: "7fffd4",
1766
+ azure: "f0ffff",
1767
+ beige: "f5f5dc",
1768
+ bisque: "ffe4c4",
1769
+ black: "000",
1770
+ blanchedalmond: "ffebcd",
1771
+ blue: "00f",
1772
+ blueviolet: "8a2be2",
1773
+ brown: "a52a2a",
1774
+ burlywood: "deb887",
1775
+ burntsienna: "ea7e5d",
1776
+ cadetblue: "5f9ea0",
1777
+ chartreuse: "7fff00",
1778
+ chocolate: "d2691e",
1779
+ coral: "ff7f50",
1780
+ cornflowerblue: "6495ed",
1781
+ cornsilk: "fff8dc",
1782
+ crimson: "dc143c",
1783
+ cyan: "0ff",
1784
+ darkblue: "00008b",
1785
+ darkcyan: "008b8b",
1786
+ darkgoldenrod: "b8860b",
1787
+ darkgray: "a9a9a9",
1788
+ darkgreen: "006400",
1789
+ darkgrey: "a9a9a9",
1790
+ darkkhaki: "bdb76b",
1791
+ darkmagenta: "8b008b",
1792
+ darkolivegreen: "556b2f",
1793
+ darkorange: "ff8c00",
1794
+ darkorchid: "9932cc",
1795
+ darkred: "8b0000",
1796
+ darksalmon: "e9967a",
1797
+ darkseagreen: "8fbc8f",
1798
+ darkslateblue: "483d8b",
1799
+ darkslategray: "2f4f4f",
1800
+ darkslategrey: "2f4f4f",
1801
+ darkturquoise: "00ced1",
1802
+ darkviolet: "9400d3",
1803
+ deeppink: "ff1493",
1804
+ deepskyblue: "00bfff",
1805
+ dimgray: "696969",
1806
+ dimgrey: "696969",
1807
+ dodgerblue: "1e90ff",
1808
+ firebrick: "b22222",
1809
+ floralwhite: "fffaf0",
1810
+ forestgreen: "228b22",
1811
+ fuchsia: "f0f",
1812
+ gainsboro: "dcdcdc",
1813
+ ghostwhite: "f8f8ff",
1814
+ gold: "ffd700",
1815
+ goldenrod: "daa520",
1816
+ gray: "808080",
1817
+ green: "008000",
1818
+ greenyellow: "adff2f",
1819
+ grey: "808080",
1820
+ honeydew: "f0fff0",
1821
+ hotpink: "ff69b4",
1822
+ indianred: "cd5c5c",
1823
+ indigo: "4b0082",
1824
+ ivory: "fffff0",
1825
+ khaki: "f0e68c",
1826
+ lavender: "e6e6fa",
1827
+ lavenderblush: "fff0f5",
1828
+ lawngreen: "7cfc00",
1829
+ lemonchiffon: "fffacd",
1830
+ lightblue: "add8e6",
1831
+ lightcoral: "f08080",
1832
+ lightcyan: "e0ffff",
1833
+ lightgoldenrodyellow: "fafad2",
1834
+ lightgray: "d3d3d3",
1835
+ lightgreen: "90ee90",
1836
+ lightgrey: "d3d3d3",
1837
+ lightpink: "ffb6c1",
1838
+ lightsalmon: "ffa07a",
1839
+ lightseagreen: "20b2aa",
1840
+ lightskyblue: "87cefa",
1841
+ lightslategray: "789",
1842
+ lightslategrey: "789",
1843
+ lightsteelblue: "b0c4de",
1844
+ lightyellow: "ffffe0",
1845
+ lime: "0f0",
1846
+ limegreen: "32cd32",
1847
+ linen: "faf0e6",
1848
+ magenta: "f0f",
1849
+ maroon: "800000",
1850
+ mediumaquamarine: "66cdaa",
1851
+ mediumblue: "0000cd",
1852
+ mediumorchid: "ba55d3",
1853
+ mediumpurple: "9370db",
1854
+ mediumseagreen: "3cb371",
1855
+ mediumslateblue: "7b68ee",
1856
+ mediumspringgreen: "00fa9a",
1857
+ mediumturquoise: "48d1cc",
1858
+ mediumvioletred: "c71585",
1859
+ midnightblue: "191970",
1860
+ mintcream: "f5fffa",
1861
+ mistyrose: "ffe4e1",
1862
+ moccasin: "ffe4b5",
1863
+ navajowhite: "ffdead",
1864
+ navy: "000080",
1865
+ oldlace: "fdf5e6",
1866
+ olive: "808000",
1867
+ olivedrab: "6b8e23",
1868
+ orange: "ffa500",
1869
+ orangered: "ff4500",
1870
+ orchid: "da70d6",
1871
+ palegoldenrod: "eee8aa",
1872
+ palegreen: "98fb98",
1873
+ paleturquoise: "afeeee",
1874
+ palevioletred: "db7093",
1875
+ papayawhip: "ffefd5",
1876
+ peachpuff: "ffdab9",
1877
+ peru: "cd853f",
1878
+ pink: "ffc0cb",
1879
+ plum: "dda0dd",
1880
+ powderblue: "b0e0e6",
1881
+ purple: "800080",
1882
+ red: "f00",
1883
+ rosybrown: "bc8f8f",
1884
+ royalblue: "4169e1",
1885
+ saddlebrown: "8b4513",
1886
+ salmon: "fa8072",
1887
+ sandybrown: "f4a460",
1888
+ seagreen: "2e8b57",
1889
+ seashell: "fff5ee",
1890
+ sienna: "a0522d",
1891
+ silver: "c0c0c0",
1892
+ skyblue: "87ceeb",
1893
+ slateblue: "6a5acd",
1894
+ slategray: "708090",
1895
+ slategrey: "708090",
1896
+ snow: "fffafa",
1897
+ springgreen: "00ff7f",
1898
+ steelblue: "4682b4",
1899
+ tan: "d2b48c",
1900
+ teal: "008080",
1901
+ thistle: "d8bfd8",
1902
+ tomato: "ff6347",
1903
+ turquoise: "40e0d0",
1904
+ violet: "ee82ee",
1905
+ wheat: "f5deb3",
1906
+ white: "fff",
1907
+ whitesmoke: "f5f5f5",
1908
+ yellow: "ff0",
1909
+ yellowgreen: "9acd32"
1910
+ };
1875
1911
 
1876
- // Make it easy to access colors via `hexNames[hex]`
1877
- var hexNames = tinycolor.hexNames = flip(names);
1912
+ // Make it easy to access colors via `hexNames[hex]`
1913
+ var hexNames = tinycolor.hexNames = flip(names);
1878
1914
 
1879
1915
 
1880
- // Utilities
1881
- // ---------
1916
+ // Utilities
1917
+ // ---------
1882
1918
 
1883
- // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
1884
- function flip(o) {
1885
- var flipped = { };
1886
- for (var i in o) {
1887
- if (o.hasOwnProperty(i)) {
1888
- flipped[o[i]] = i;
1889
- }
1919
+ // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
1920
+ function flip(o) {
1921
+ var flipped = { };
1922
+ for (var i in o) {
1923
+ if (o.hasOwnProperty(i)) {
1924
+ flipped[o[i]] = i;
1890
1925
  }
1891
- return flipped;
1892
1926
  }
1927
+ return flipped;
1928
+ }
1893
1929
 
1894
- // Return a valid alpha value [0,1] with all invalid values being set to 1
1895
- function boundAlpha(a) {
1896
- a = parseFloat(a);
1930
+ // Return a valid alpha value [0,1] with all invalid values being set to 1
1931
+ function boundAlpha(a) {
1932
+ a = parseFloat(a);
1897
1933
 
1898
- if (isNaN(a) || a < 0 || a > 1) {
1899
- a = 1;
1900
- }
1901
-
1902
- return a;
1934
+ if (isNaN(a) || a < 0 || a > 1) {
1935
+ a = 1;
1903
1936
  }
1904
1937
 
1905
- // Take input from [0, n] and return it as [0, 1]
1906
- function bound01(n, max) {
1907
- if (isOnePointZero(n)) { n = "100%"; }
1908
-
1909
- var processPercent = isPercentage(n);
1910
- n = mathMin(max, mathMax(0, parseFloat(n)));
1938
+ return a;
1939
+ }
1911
1940
 
1912
- // Automatically convert percentage into number
1913
- if (processPercent) {
1914
- n = parseInt(n * max, 10) / 100;
1915
- }
1941
+ // Take input from [0, n] and return it as [0, 1]
1942
+ function bound01(n, max) {
1943
+ if (isOnePointZero(n)) { n = "100%"; }
1916
1944
 
1917
- // Handle floating point rounding errors
1918
- if ((math.abs(n - max) < 0.000001)) {
1919
- return 1;
1920
- }
1945
+ var processPercent = isPercentage(n);
1946
+ n = mathMin(max, mathMax(0, parseFloat(n)));
1921
1947
 
1922
- // Convert into [0, 1] range if it isn't already
1923
- return (n % max) / parseFloat(max);
1948
+ // Automatically convert percentage into number
1949
+ if (processPercent) {
1950
+ n = parseInt(n * max, 10) / 100;
1924
1951
  }
1925
1952
 
1926
- // Force a number between 0 and 1
1927
- function clamp01(val) {
1928
- return mathMin(1, mathMax(0, val));
1953
+ // Handle floating point rounding errors
1954
+ if ((math.abs(n - max) < 0.000001)) {
1955
+ return 1;
1929
1956
  }
1930
1957
 
1931
- // Parse a base-16 hex value into a base-10 integer
1932
- function parseIntFromHex(val) {
1933
- return parseInt(val, 16);
1934
- }
1958
+ // Convert into [0, 1] range if it isn't already
1959
+ return (n % max) / parseFloat(max);
1960
+ }
1935
1961
 
1936
- // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
1937
- // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
1938
- function isOnePointZero(n) {
1939
- return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
1940
- }
1962
+ // Force a number between 0 and 1
1963
+ function clamp01(val) {
1964
+ return mathMin(1, mathMax(0, val));
1965
+ }
1941
1966
 
1942
- // Check to see if string passed in is a percentage
1943
- function isPercentage(n) {
1944
- return typeof n === "string" && n.indexOf('%') != -1;
1945
- }
1967
+ // Parse a base-16 hex value into a base-10 integer
1968
+ function parseIntFromHex(val) {
1969
+ return parseInt(val, 16);
1970
+ }
1946
1971
 
1947
- // Force a hex value to have 2 characters
1948
- function pad2(c) {
1949
- return c.length == 1 ? '0' + c : '' + c;
1950
- }
1972
+ // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
1973
+ // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
1974
+ function isOnePointZero(n) {
1975
+ return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
1976
+ }
1951
1977
 
1952
- // Replace a decimal with it's percentage value
1953
- function convertToPercentage(n) {
1954
- if (n <= 1) {
1955
- n = (n * 100) + "%";
1956
- }
1978
+ // Check to see if string passed in is a percentage
1979
+ function isPercentage(n) {
1980
+ return typeof n === "string" && n.indexOf('%') != -1;
1981
+ }
1957
1982
 
1958
- return n;
1959
- }
1983
+ // Force a hex value to have 2 characters
1984
+ function pad2(c) {
1985
+ return c.length == 1 ? '0' + c : '' + c;
1986
+ }
1960
1987
 
1961
- // Converts a decimal to a hex value
1962
- function convertDecimalToHex(d) {
1963
- return Math.round(parseFloat(d) * 255).toString(16);
1964
- }
1965
- // Converts a hex value to a decimal
1966
- function convertHexToDecimal(h) {
1967
- return (parseIntFromHex(h) / 255);
1988
+ // Replace a decimal with it's percentage value
1989
+ function convertToPercentage(n) {
1990
+ if (n <= 1) {
1991
+ n = (n * 100) + "%";
1968
1992
  }
1969
1993
 
1970
- var matchers = (function() {
1994
+ return n;
1995
+ }
1971
1996
 
1972
- // <http://www.w3.org/TR/css3-values/#integers>
1973
- var CSS_INTEGER = "[-\\+]?\\d+%?";
1997
+ // Converts a decimal to a hex value
1998
+ function convertDecimalToHex(d) {
1999
+ return Math.round(parseFloat(d) * 255).toString(16);
2000
+ }
2001
+ // Converts a hex value to a decimal
2002
+ function convertHexToDecimal(h) {
2003
+ return (parseIntFromHex(h) / 255);
2004
+ }
1974
2005
 
1975
- // <http://www.w3.org/TR/css3-values/#number-value>
1976
- var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
2006
+ var matchers = (function() {
1977
2007
 
1978
- // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
1979
- var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
2008
+ // <http://www.w3.org/TR/css3-values/#integers>
2009
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
1980
2010
 
1981
- // Actual matching.
1982
- // Parentheses and commas are optional, but not required.
1983
- // Whitespace can take the place of commas or opening paren
1984
- var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
1985
- var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2011
+ // <http://www.w3.org/TR/css3-values/#number-value>
2012
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
1986
2013
 
1987
- return {
1988
- rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
1989
- rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
1990
- hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
1991
- hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
1992
- hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
1993
- hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
1994
- hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
1995
- hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
1996
- };
1997
- })();
2014
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
2015
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
1998
2016
 
1999
- // `stringInputToObject`
2000
- // Permissive string parsing. Take in a number of formats, and output an object
2001
- // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
2002
- function stringInputToObject(color) {
2017
+ // Actual matching.
2018
+ // Parentheses and commas are optional, but not required.
2019
+ // Whitespace can take the place of commas or opening paren
2020
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2021
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2003
2022
 
2004
- color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
2005
- var named = false;
2006
- if (names[color]) {
2007
- color = names[color];
2008
- named = true;
2009
- }
2010
- else if (color == 'transparent') {
2011
- return { r: 0, g: 0, b: 0, a: 0, format: "name" };
2012
- }
2023
+ return {
2024
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
2025
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
2026
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
2027
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
2028
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
2029
+ hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
2030
+ hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
2031
+ hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
2032
+ };
2033
+ })();
2013
2034
 
2014
- // Try to match string input using regular expressions.
2015
- // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
2016
- // Just return an object and let the conversion functions handle that.
2017
- // This way the result will be the same whether the tinycolor is initialized with string or object.
2018
- var match;
2019
- if ((match = matchers.rgb.exec(color))) {
2020
- return { r: match[1], g: match[2], b: match[3] };
2021
- }
2022
- if ((match = matchers.rgba.exec(color))) {
2023
- return { r: match[1], g: match[2], b: match[3], a: match[4] };
2024
- }
2025
- if ((match = matchers.hsl.exec(color))) {
2026
- return { h: match[1], s: match[2], l: match[3] };
2027
- }
2028
- if ((match = matchers.hsla.exec(color))) {
2029
- return { h: match[1], s: match[2], l: match[3], a: match[4] };
2030
- }
2031
- if ((match = matchers.hsv.exec(color))) {
2032
- return { h: match[1], s: match[2], v: match[3] };
2033
- }
2034
- if ((match = matchers.hex8.exec(color))) {
2035
- return {
2036
- a: convertHexToDecimal(match[1]),
2037
- r: parseIntFromHex(match[2]),
2038
- g: parseIntFromHex(match[3]),
2039
- b: parseIntFromHex(match[4]),
2040
- format: named ? "name" : "hex8"
2041
- };
2042
- }
2043
- if ((match = matchers.hex6.exec(color))) {
2044
- return {
2045
- r: parseIntFromHex(match[1]),
2046
- g: parseIntFromHex(match[2]),
2047
- b: parseIntFromHex(match[3]),
2048
- format: named ? "name" : "hex"
2049
- };
2050
- }
2051
- if ((match = matchers.hex3.exec(color))) {
2052
- return {
2053
- r: parseIntFromHex(match[1] + '' + match[1]),
2054
- g: parseIntFromHex(match[2] + '' + match[2]),
2055
- b: parseIntFromHex(match[3] + '' + match[3]),
2056
- format: named ? "name" : "hex"
2057
- };
2058
- }
2035
+ // `stringInputToObject`
2036
+ // Permissive string parsing. Take in a number of formats, and output an object
2037
+ // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
2038
+ function stringInputToObject(color) {
2059
2039
 
2060
- return false;
2040
+ color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
2041
+ var named = false;
2042
+ if (names[color]) {
2043
+ color = names[color];
2044
+ named = true;
2045
+ }
2046
+ else if (color == 'transparent') {
2047
+ return { r: 0, g: 0, b: 0, a: 0, format: "name" };
2048
+ }
2049
+
2050
+ // Try to match string input using regular expressions.
2051
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
2052
+ // Just return an object and let the conversion functions handle that.
2053
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
2054
+ var match;
2055
+ if ((match = matchers.rgb.exec(color))) {
2056
+ return { r: match[1], g: match[2], b: match[3] };
2057
+ }
2058
+ if ((match = matchers.rgba.exec(color))) {
2059
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
2060
+ }
2061
+ if ((match = matchers.hsl.exec(color))) {
2062
+ return { h: match[1], s: match[2], l: match[3] };
2063
+ }
2064
+ if ((match = matchers.hsla.exec(color))) {
2065
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
2066
+ }
2067
+ if ((match = matchers.hsv.exec(color))) {
2068
+ return { h: match[1], s: match[2], v: match[3] };
2069
+ }
2070
+ if ((match = matchers.hex8.exec(color))) {
2071
+ return {
2072
+ a: convertHexToDecimal(match[1]),
2073
+ r: parseIntFromHex(match[2]),
2074
+ g: parseIntFromHex(match[3]),
2075
+ b: parseIntFromHex(match[4]),
2076
+ format: named ? "name" : "hex8"
2077
+ };
2078
+ }
2079
+ if ((match = matchers.hex6.exec(color))) {
2080
+ return {
2081
+ r: parseIntFromHex(match[1]),
2082
+ g: parseIntFromHex(match[2]),
2083
+ b: parseIntFromHex(match[3]),
2084
+ format: named ? "name" : "hex"
2085
+ };
2086
+ }
2087
+ if ((match = matchers.hex3.exec(color))) {
2088
+ return {
2089
+ r: parseIntFromHex(match[1] + '' + match[1]),
2090
+ g: parseIntFromHex(match[2] + '' + match[2]),
2091
+ b: parseIntFromHex(match[3] + '' + match[3]),
2092
+ format: named ? "name" : "hex"
2093
+ };
2061
2094
  }
2062
2095
 
2063
- // Expose tinycolor to window, does not need to run in non-browser context.
2064
- window.tinycolor = tinycolor;
2096
+ return false;
2097
+ }
2065
2098
 
2099
+ window.tinycolor = tinycolor;
2066
2100
  })();
2067
2101
 
2068
2102