jquery-minicolors-rails 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,567 +1,857 @@
1
1
  /*
2
- * jQuery miniColors: A small color selector
2
+ * jQuery MiniColors: A tiny color picker built on jQuery
3
3
  *
4
- * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
4
+ * Copyright Cory LaViska for A Beautiful Site, LLC. (http://www.abeautifulsite.net/)
5
5
  *
6
- * Dual licensed under the MIT or GPL Version 2 licenses
6
+ * Dual-licensed under the MIT and GPL Version 2 licenses
7
7
  *
8
8
  */
9
9
  if(jQuery) (function($) {
10
-
11
- $.extend($.fn, {
12
-
13
- miniColors: function(o, data) {
14
-
15
- var create = function(input, o, data) {
16
- //
17
- // Creates a new instance of the miniColors selector
18
- //
19
-
20
- // Determine initial color (defaults to white)
21
- var color = expandHex(input.val());
22
- if( !color ) color = 'ffffff';
23
- var hsb = hex2hsb(color);
24
-
25
- // Create trigger
26
- var trigger = $('<a class="miniColors-trigger" style="background-color: #' + color + '" href="#"></a>');
27
- trigger.insertAfter(input);
28
-
29
- // Set input data and update attributes
30
- input
31
- .addClass('miniColors')
32
- .data('original-maxlength', input.attr('maxlength') || null)
33
- .data('original-autocomplete', input.attr('autocomplete') || null)
34
- .data('letterCase', 'uppercase')
35
- .data('trigger', trigger)
36
- .data('hsb', hsb)
37
- .data('change', o.change ? o.change : null)
38
- .attr('maxlength', 7)
39
- .attr('autocomplete', 'off')
40
- .val('#' + convertCase(color, o.letterCase));
41
-
42
- // Handle options
43
- if( o.readonly ) input.prop('readonly', true);
44
- if( o.disabled ) disable(input);
45
-
46
- // Show selector when trigger is clicked
47
- trigger.bind('click.miniColors', function(event) {
48
- event.preventDefault();
49
- if( input.val() === '' ) input.val('#');
50
- show(input);
51
-
52
- });
53
-
54
- // Show selector when input receives focus
55
- input.bind('focus.miniColors', function(event) {
56
- if( input.val() === '' ) input.val('#');
57
- show(input);
58
- });
59
-
60
- // Hide on blur
61
- input.bind('blur.miniColors', function(event) {
62
- var hex = expandHex(input.val());
63
- input.val( hex ? '#' + convertCase(hex, input.data('letterCase')) : '' );
64
- });
65
-
66
- // Hide when tabbing out of the input
67
- input.bind('keydown.miniColors', function(event) {
68
- if( event.keyCode === 9 ) hide(input);
69
- });
70
-
71
- // Update when color is typed in
72
- input.bind('keyup.miniColors', function(event) {
73
- setColorFromInput(input);
74
- });
75
-
76
- // Handle pasting
77
- input.bind('paste.miniColors', function(event) {
78
- // Short pause to wait for paste to complete
79
- setTimeout( function() {
80
- setColorFromInput(input);
81
- }, 5);
82
- });
83
-
84
- };
85
-
86
- var destroy = function(input) {
87
- //
88
- // Destroys an active instance of the miniColors selector
89
- //
90
-
91
- hide();
92
- input = $(input);
93
-
94
- // Restore to original state
95
- input.data('trigger').remove();
96
- input
97
- .attr('autocomplete', input.data('original-autocomplete'))
98
- .attr('maxlength', input.data('original-maxlength'))
99
- .removeData()
100
- .removeClass('miniColors')
101
- .unbind('.miniColors');
102
- $(document).unbind('.miniColors');
103
- };
104
-
105
- var enable = function(input) {
106
- //
107
- // Enables the input control and the selector
108
- //
109
- input
110
- .prop('disabled', false)
111
- .data('trigger')
112
- .css('opacity', 1);
113
- };
114
-
115
- var disable = function(input) {
116
- //
117
- // Disables the input control and the selector
118
- //
119
- hide(input);
120
- input
121
- .prop('disabled', true)
122
- .data('trigger')
123
- .css('opacity', 0.5);
124
- };
125
-
126
- var show = function(input) {
127
- //
128
- // Shows the miniColors selector
129
- //
130
- if( input.prop('disabled') ) return false;
131
-
132
- // Hide all other instances
133
- hide();
134
-
135
- // Generate the selector
136
- var selector = $('<div class="miniColors-selector"></div>');
137
- selector
138
- .append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"></div></div>')
139
- .append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>')
140
- .css({
141
- top: input.is(':visible') ? input.offset().top + input.outerHeight() : input.data('trigger').offset().top + input.data('trigger').outerHeight(),
142
- left: input.is(':visible') ? input.offset().left : input.data('trigger').offset().left,
143
- display: 'none'
144
- })
145
- .addClass( input.attr('class') );
146
-
147
- // Set background for colors
148
- var hsb = input.data('hsb');
149
- selector
150
- .find('.miniColors-colors')
151
- .css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
152
-
153
- // Set colorPicker position
154
- var colorPosition = input.data('colorPosition');
155
- if( !colorPosition ) colorPosition = getColorPositionFromHSB(hsb);
156
- selector.find('.miniColors-colorPicker')
157
- .css('top', colorPosition.y + 'px')
158
- .css('left', colorPosition.x + 'px');
159
-
160
- // Set huePicker position
161
- var huePosition = input.data('huePosition');
162
- if( !huePosition ) huePosition = getHuePositionFromHSB(hsb);
163
- selector.find('.miniColors-huePicker').css('top', huePosition.y + 'px');
164
-
165
- // Set input data
166
- input
167
- .data('selector', selector)
168
- .data('huePicker', selector.find('.miniColors-huePicker'))
169
- .data('colorPicker', selector.find('.miniColors-colorPicker'))
170
- .data('mousebutton', 0);
171
-
172
- $('BODY').append(selector);
173
- selector.fadeIn(100);
174
-
175
- // Prevent text selection in IE
176
- selector.bind('selectstart', function() { return false; });
177
-
178
- $(document).bind('mousedown.miniColors touchstart.miniColors', function(event) {
179
-
180
- input.data('mousebutton', 1);
181
-
182
- if( $(event.target).parents().andSelf().hasClass('miniColors-colors') ) {
183
- event.preventDefault();
184
- input.data('moving', 'colors');
185
- moveColor(input, event);
186
- }
187
-
188
- if( $(event.target).parents().andSelf().hasClass('miniColors-hues') ) {
189
- event.preventDefault();
190
- input.data('moving', 'hues');
191
- moveHue(input, event);
192
- }
193
-
194
- if( $(event.target).parents().andSelf().hasClass('miniColors-selector') ) {
195
- event.preventDefault();
196
- return;
197
- }
198
-
199
- if( $(event.target).parents().andSelf().hasClass('miniColors') ) return;
200
-
201
- hide(input);
202
- });
203
-
204
- $(document)
205
- .bind('mouseup.miniColors touchend.miniColors', function(event) {
206
- event.preventDefault();
207
- input.data('mousebutton', 0).removeData('moving');
208
- })
209
- .bind('mousemove.miniColors touchmove.miniColors', function(event) {
210
- event.preventDefault();
211
- if( input.data('mousebutton') === 1 ) {
212
- if( input.data('moving') === 'colors' ) moveColor(input, event);
213
- if( input.data('moving') === 'hues' ) moveHue(input, event);
214
- }
215
- });
216
-
217
- };
218
-
219
- var hide = function(input) {
220
-
221
- //
222
- // Hides one or more miniColors selectors
223
- //
224
-
225
- // Hide all other instances if input isn't specified
226
- if( !input ) input = '.miniColors';
227
-
228
- $(input).each( function() {
229
- var selector = $(this).data('selector');
230
- $(this).removeData('selector');
231
- $(selector).fadeOut(100, function() {
232
- $(this).remove();
233
- });
234
- });
235
-
236
- $(document).unbind('.miniColors');
237
-
238
- };
239
-
240
- var moveColor = function(input, event) {
241
-
242
- var colorPicker = input.data('colorPicker');
243
-
244
- colorPicker.hide();
245
-
246
- var position = {
247
- x: event.pageX,
248
- y: event.pageY
249
- };
250
-
251
- // Touch support
252
- if( event.originalEvent.changedTouches ) {
253
- position.x = event.originalEvent.changedTouches[0].pageX;
254
- position.y = event.originalEvent.changedTouches[0].pageY;
255
- }
256
- position.x = position.x - input.data('selector').find('.miniColors-colors').offset().left - 5;
257
- position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 5;
258
- if( position.x <= -5 ) position.x = -5;
259
- if( position.x >= 144 ) position.x = 144;
260
- if( position.y <= -5 ) position.y = -5;
261
- if( position.y >= 144 ) position.y = 144;
262
-
263
- input.data('colorPosition', position);
264
- colorPicker.css('left', position.x).css('top', position.y).show();
265
-
266
- // Calculate saturation
267
- var s = Math.round((position.x + 5) * 0.67);
268
- if( s < 0 ) s = 0;
269
- if( s > 100 ) s = 100;
270
-
271
- // Calculate brightness
272
- var b = 100 - Math.round((position.y + 5) * 0.67);
273
- if( b < 0 ) b = 0;
274
- if( b > 100 ) b = 100;
275
-
276
- // Update HSB values
277
- var hsb = input.data('hsb');
278
- hsb.s = s;
279
- hsb.b = b;
280
-
281
- // Set color
282
- setColor(input, hsb, true);
283
- };
284
-
285
- var moveHue = function(input, event) {
286
-
287
- var huePicker = input.data('huePicker');
288
-
289
- huePicker.hide();
290
-
291
- var position = {
292
- y: event.pageY
293
- };
294
-
295
- // Touch support
296
- if( event.originalEvent.changedTouches ) {
297
- position.y = event.originalEvent.changedTouches[0].pageY;
298
- }
299
-
300
- position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 1;
301
- if( position.y <= -1 ) position.y = -1;
302
- if( position.y >= 149 ) position.y = 149;
303
- input.data('huePosition', position);
304
- huePicker.css('top', position.y).show();
305
-
306
- // Calculate hue
307
- var h = Math.round((150 - position.y - 1) * 2.4);
308
- if( h < 0 ) h = 0;
309
- if( h > 360 ) h = 360;
310
-
311
- // Update HSB values
312
- var hsb = input.data('hsb');
313
- hsb.h = h;
314
-
315
- // Set color
316
- setColor(input, hsb, true);
317
-
318
- };
319
-
320
- var setColor = function(input, hsb, updateInput) {
321
- input.data('hsb', hsb);
322
- var hex = hsb2hex(hsb);
323
- if( updateInput ) input.val( '#' + convertCase(hex, input.data('letterCase')) );
324
- input.data('trigger').css('backgroundColor', '#' + hex);
325
- if( input.data('selector') ) input.data('selector').find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
326
-
327
- // Fire change callback
328
- if( input.data('change') ) {
329
- if( hex === input.data('lastChange') ) return;
330
- input.data('change').call(input.get(0), '#' + hex, hsb2rgb(hsb));
331
- input.data('lastChange', hex);
332
- }
333
-
334
- };
335
-
336
- var setColorFromInput = function(input) {
337
-
338
- input.val('#' + cleanHex(input.val()));
339
- var hex = expandHex(input.val());
340
- if( !hex ) return false;
341
-
342
- // Get HSB equivalent
343
- var hsb = hex2hsb(hex);
344
-
345
- // If color is the same, no change required
346
- var currentHSB = input.data('hsb');
347
- if( hsb.h === currentHSB.h && hsb.s === currentHSB.s && hsb.b === currentHSB.b ) return true;
348
-
349
- // Set colorPicker position
350
- var colorPosition = getColorPositionFromHSB(hsb);
351
- var colorPicker = $(input.data('colorPicker'));
352
- colorPicker.css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px');
353
- input.data('colorPosition', colorPosition);
354
-
355
- // Set huePosition position
356
- var huePosition = getHuePositionFromHSB(hsb);
357
- var huePicker = $(input.data('huePicker'));
358
- huePicker.css('top', huePosition.y + 'px');
359
- input.data('huePosition', huePosition);
360
-
361
- setColor(input, hsb);
362
-
363
- return true;
364
-
365
- };
366
-
367
- var convertCase = function(string, letterCase) {
368
- if( letterCase === 'lowercase' ) return string.toLowerCase();
369
- if( letterCase === 'uppercase' ) return string.toUpperCase();
370
- return string;
371
- };
372
-
373
- var getColorPositionFromHSB = function(hsb) {
374
- var x = Math.ceil(hsb.s / 0.67);
375
- if( x < 0 ) x = 0;
376
- if( x > 150 ) x = 150;
377
- var y = 150 - Math.ceil(hsb.b / 0.67);
378
- if( y < 0 ) y = 0;
379
- if( y > 150 ) y = 150;
380
- return { x: x - 5, y: y - 5 };
381
- };
382
-
383
- var getHuePositionFromHSB = function(hsb) {
384
- var y = 150 - (hsb.h / 2.4);
385
- if( y < 0 ) h = 0;
386
- if( y > 150 ) h = 150;
387
- return { y: y - 1 };
388
- };
389
-
390
- var cleanHex = function(hex) {
391
- return hex.replace(/[^A-F0-9]/ig, '');
392
- };
393
-
394
- var expandHex = function(hex) {
395
- hex = cleanHex(hex);
396
- if( !hex ) return null;
397
- if( hex.length === 3 ) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
398
- return hex.length === 6 ? hex : null;
399
- };
400
-
401
- var hsb2rgb = function(hsb) {
402
- var rgb = {};
403
- var h = Math.round(hsb.h);
404
- var s = Math.round(hsb.s*255/100);
405
- var v = Math.round(hsb.b*255/100);
406
- if(s === 0) {
407
- rgb.r = rgb.g = rgb.b = v;
408
- } else {
409
- var t1 = v;
410
- var t2 = (255 - s) * v / 255;
411
- var t3 = (t1 - t2) * (h % 60) / 60;
412
- if( h === 360 ) h = 0;
413
- if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
414
- else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
415
- else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
416
- else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
417
- else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
418
- else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
419
- else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
420
- }
421
- return {
422
- r: Math.round(rgb.r),
423
- g: Math.round(rgb.g),
424
- b: Math.round(rgb.b)
425
- };
426
- };
427
-
428
- var rgb2hex = function(rgb) {
429
- var hex = [
430
- rgb.r.toString(16),
431
- rgb.g.toString(16),
432
- rgb.b.toString(16)
433
- ];
434
- $.each(hex, function(nr, val) {
435
- if (val.length === 1) hex[nr] = '0' + val;
436
- });
437
- return hex.join('');
438
- };
439
-
440
- var hex2rgb = function(hex) {
441
- hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
442
-
443
- return {
444
- r: hex >> 16,
445
- g: (hex & 0x00FF00) >> 8,
446
- b: (hex & 0x0000FF)
447
- };
448
- };
449
-
450
- var rgb2hsb = function(rgb) {
451
- var hsb = { h: 0, s: 0, b: 0 };
452
- var min = Math.min(rgb.r, rgb.g, rgb.b);
453
- var max = Math.max(rgb.r, rgb.g, rgb.b);
454
- var delta = max - min;
455
- hsb.b = max;
456
- hsb.s = max !== 0 ? 255 * delta / max : 0;
457
- if( hsb.s !== 0 ) {
458
- if( rgb.r === max ) {
459
- hsb.h = (rgb.g - rgb.b) / delta;
460
- } else if( rgb.g === max ) {
461
- hsb.h = 2 + (rgb.b - rgb.r) / delta;
462
- } else {
463
- hsb.h = 4 + (rgb.r - rgb.g) / delta;
464
- }
465
- } else {
466
- hsb.h = -1;
467
- }
468
- hsb.h *= 60;
469
- if( hsb.h < 0 ) {
470
- hsb.h += 360;
471
- }
472
- hsb.s *= 100/255;
473
- hsb.b *= 100/255;
474
- return hsb;
475
- };
476
-
477
- var hex2hsb = function(hex) {
478
- var hsb = rgb2hsb(hex2rgb(hex));
479
- // Zero out hue marker for black, white, and grays (saturation === 0)
480
- if( hsb.s === 0 ) hsb.h = 360;
481
- return hsb;
482
- };
483
-
484
- var hsb2hex = function(hsb) {
485
- return rgb2hex(hsb2rgb(hsb));
486
- };
487
-
488
-
489
- // Handle calls to $([selector]).miniColors()
490
- switch(o) {
491
-
492
- case 'readonly':
493
-
494
- $(this).each( function() {
495
- if( !$(this).hasClass('miniColors') ) return;
496
- $(this).prop('readonly', data);
497
- });
498
-
499
- return $(this);
500
-
501
- case 'disabled':
502
-
503
- $(this).each( function() {
504
- if( !$(this).hasClass('miniColors') ) return;
505
- if( data ) {
506
- disable($(this));
507
- } else {
508
- enable($(this));
509
- }
510
- });
511
-
512
- return $(this);
513
-
514
- case 'value':
515
-
516
- // Getter
517
- if( data === undefined ) {
518
- if( !$(this).hasClass('miniColors') ) return;
519
- var input = $(this),
520
- hex = expandHex(input.val());
521
- return hex ? '#' + convertCase(hex, input.data('letterCase')) : null;
522
- }
523
-
524
- // Setter
525
- $(this).each( function() {
526
- if( !$(this).hasClass('miniColors') ) return;
527
- $(this).val(data);
528
- setColorFromInput($(this));
529
- });
530
-
531
- return $(this);
532
-
533
- case 'destroy':
534
-
535
- $(this).each( function() {
536
- if( !$(this).hasClass('miniColors') ) return;
537
- destroy($(this));
538
- });
539
-
540
- return $(this);
541
-
542
- default:
543
-
544
- if( !o ) o = {};
545
-
546
- $(this).each( function() {
547
-
548
- // Must be called on an input element
549
- if( $(this)[0].tagName.toLowerCase() !== 'input' ) return;
550
-
551
- // If a trigger is present, the control was already created
552
- if( $(this).data('trigger') ) return;
553
-
554
- // Create the control
555
- create($(this), o, data);
556
-
557
- });
558
-
559
- return $(this);
560
-
561
- }
562
-
563
- }
564
-
565
- });
566
-
567
- })(jQuery);
10
+
11
+ // Yay, MiniColors!
12
+ $.minicolors = {
13
+ // Default settings
14
+ defaultSettings: {
15
+ animationSpeed: 100,
16
+ animationEasing: 'swing',
17
+ change: null,
18
+ changeDelay: 0,
19
+ control: 'hue',
20
+ defaultValue: '',
21
+ hide: null,
22
+ hideSpeed: 100,
23
+ inline: false,
24
+ letterCase: 'lowercase',
25
+ opacity: false,
26
+ position: 'default',
27
+ show: null,
28
+ showSpeed: 100,
29
+ swatchPosition: 'left',
30
+ textfield: true,
31
+ theme: 'default'
32
+ }
33
+ };
34
+
35
+ // Public methods
36
+ $.extend($.fn, {
37
+ minicolors: function(method, data) {
38
+
39
+ switch(method) {
40
+
41
+ // Destroy the control
42
+ case 'destroy':
43
+ $(this).each( function() {
44
+ destroy($(this));
45
+ });
46
+ return $(this);
47
+
48
+ // Hide the color picker
49
+ case 'hide':
50
+ hide();
51
+ return $(this);
52
+
53
+ // Get/set opacity
54
+ case 'opacity':
55
+ if( data === undefined ) {
56
+ // Getter
57
+ return $(this).attr('data-opacity');
58
+ } else {
59
+ // Setter
60
+ $(this).each( function() {
61
+ refresh($(this).attr('data-opacity', data));
62
+ });
63
+ return $(this);
64
+ }
65
+
66
+ // Get an RGB(A) object based on the current color/opacity
67
+ case 'rgbObject':
68
+ return rgbObject($(this), method === 'rgbaObject');
69
+
70
+ // Get an RGB(A) string based on the current color/opacity
71
+ case 'rgbString':
72
+ case 'rgbaString':
73
+ return rgbString($(this), method === 'rgbaString')
74
+
75
+ // Get/set settings on the fly
76
+ case 'settings':
77
+ if( data === undefined ) {
78
+ return $(this).data('minicolors-settings');
79
+ } else {
80
+ // Setter
81
+ $(this).each( function() {
82
+ var settings = $(this).data('minicolors-settings') || {};
83
+ destroy($(this));
84
+ $(this).minicolors($.extend(true, settings, data));
85
+ });
86
+ return $(this);
87
+ }
88
+
89
+ // Show the color picker
90
+ case 'show':
91
+ show( $(this).eq(0) );
92
+ return $(this);
93
+
94
+ // Get/set the hex color value
95
+ case 'value':
96
+ if( data === undefined ) {
97
+ // Getter
98
+ return $(this).val();
99
+ } else {
100
+ // Setter
101
+ $(this).each( function() {
102
+ refresh($(this).val(data));
103
+ });
104
+ return $(this);
105
+ }
106
+
107
+ // Initializes the control
108
+ case 'create':
109
+ default:
110
+ if( method !== 'create' ) data = method;
111
+ $(this).each( function() {
112
+ init($(this), data);
113
+ });
114
+ return $(this);
115
+
116
+ }
117
+
118
+ }
119
+ });
120
+
121
+ // Initialize input elements
122
+ function init(input, settings) {
123
+
124
+ var minicolors = $('<span class="minicolors" />'),
125
+ defaultSettings = $.minicolors.defaultSettings;
126
+
127
+ // Do nothing if already initialized
128
+ if( input.data('minicolors-initialized') ) return;
129
+
130
+ // Handle settings
131
+ settings = $.extend(true, {}, defaultSettings, settings);
132
+
133
+ // The wrapper
134
+ minicolors
135
+ .addClass('minicolors-theme-' + settings.theme)
136
+ .addClass('minicolors-swatch-position-' + settings.swatchPosition)
137
+ .toggleClass('minicolors-swatch-left', settings.swatchPosition === 'left')
138
+ .toggleClass('minicolors-with-opacity', settings.opacity);
139
+
140
+ // Custom positioning
141
+ if( settings.position !== undefined ) {
142
+ $.each(settings.position.split(' '), function() {
143
+ minicolors.addClass('minicolors-position-' + this);
144
+ });
145
+ }
146
+
147
+ // The input
148
+ input
149
+ .addClass('minicolors-input')
150
+ .data('minicolors-initialized', true)
151
+ .data('minicolors-settings', settings)
152
+ .prop('size', 7)
153
+ .prop('maxlength', 7)
154
+ .wrap(minicolors)
155
+ .after(
156
+ '<span class="minicolors-panel minicolors-slider-' + settings.control + '">' +
157
+ '<span class="minicolors-slider">' +
158
+ '<span class="minicolors-picker"></span>' +
159
+ '</span>' +
160
+ '<span class="minicolors-opacity-slider">' +
161
+ '<span class="minicolors-picker"></span>' +
162
+ '</span>' +
163
+ '<span class="minicolors-grid">' +
164
+ '<span class="minicolors-grid-inner"></span>' +
165
+ '<span class="minicolors-picker"><span></span></span>' +
166
+ '</span>' +
167
+ '</span>'
168
+ );
169
+
170
+ // Prevent text selection in IE
171
+ input.parent().find('.minicolors-panel').on('selectstart', function() { return false; }).end();
172
+
173
+ // Detect swatch position
174
+ if( settings.swatchPosition === 'left' ) {
175
+ // Left
176
+ input.before('<span class="minicolors-swatch"><span></span></span>');
177
+ } else {
178
+ // Right
179
+ input.after('<span class="minicolors-swatch"><span></span></span>');
180
+ }
181
+
182
+ // Disable textfield
183
+ if( !settings.textfield ) input.addClass('minicolors-hidden');
184
+
185
+ // Inline controls
186
+ if( settings.inline ) input.parent().addClass('minicolors-inline');
187
+
188
+ updateFromInput(input, false, true);
189
+
190
+ }
191
+
192
+ // Returns the input back to its original state
193
+ function destroy(input) {
194
+
195
+ var minicolors = input.parent();
196
+
197
+ // Revert the input element
198
+ input
199
+ .removeData('minicolors-initialized')
200
+ .removeData('minicolors-settings')
201
+ .removeProp('size')
202
+ .removeProp('maxlength')
203
+ .removeClass('minicolors-input');
204
+
205
+ // Remove the wrap and destroy whatever remains
206
+ minicolors.before(input).remove();
207
+
208
+ }
209
+
210
+ // Refresh the specified control
211
+ function refresh(input) {
212
+ updateFromInput(input);
213
+ }
214
+
215
+ // Shows the specified dropdown panel
216
+ function show(input) {
217
+
218
+ var minicolors = input.parent(),
219
+ panel = minicolors.find('.minicolors-panel'),
220
+ settings = input.data('minicolors-settings');
221
+
222
+ // Do nothing if uninitialized, disabled, inline, or already open
223
+ if( !input.data('minicolors-initialized') ||
224
+ input.prop('disabled') ||
225
+ minicolors.hasClass('minicolors-inline') ||
226
+ minicolors.hasClass('minicolors-focus')
227
+ ) return;
228
+
229
+ hide();
230
+
231
+ minicolors.addClass('minicolors-focus');
232
+ panel
233
+ .stop(true, true)
234
+ .fadeIn(settings.showSpeed, function() {
235
+ if( settings.show ) settings.show.call(input.get(0));
236
+ });
237
+
238
+ }
239
+
240
+ // Hides all dropdown panels
241
+ function hide() {
242
+
243
+ $('.minicolors-input').each( function() {
244
+
245
+ var input = $(this),
246
+ settings = input.data('minicolors-settings'),
247
+ minicolors = input.parent();
248
+
249
+ // Don't hide inline controls
250
+ if( settings.inline ) return;
251
+
252
+ minicolors.find('.minicolors-panel').fadeOut(settings.hideSpeed, function() {
253
+ if(minicolors.hasClass('minicolors-focus')) {
254
+ if( settings.hide ) settings.hide.call(input.get(0));
255
+ }
256
+ minicolors.removeClass('minicolors-focus');
257
+ });
258
+
259
+ });
260
+ }
261
+
262
+ // Moves the selected picker
263
+ function move(target, event, animate) {
264
+
265
+ var input = target.parents('.minicolors').find('.minicolors-input'),
266
+ settings = input.data('minicolors-settings'),
267
+ picker = target.find('[class$=-picker]'),
268
+ offsetX = target.offset().left,
269
+ offsetY = target.offset().top,
270
+ x = Math.round(event.pageX - offsetX),
271
+ y = Math.round(event.pageY - offsetY),
272
+ duration = animate ? settings.animationSpeed : 0,
273
+ wx, wy, r, phi;
274
+
275
+
276
+ // Touch support
277
+ if( event.originalEvent.changedTouches ) {
278
+ x = event.originalEvent.changedTouches[0].pageX - offsetX;
279
+ y = event.originalEvent.changedTouches[0].pageY - offsetY;
280
+ }
281
+
282
+ // Constrain picker to its container
283
+ if( x < 0 ) x = 0;
284
+ if( y < 0 ) y = 0;
285
+ if( x > target.width() ) x = target.width();
286
+ if( y > target.height() ) y = target.height();
287
+
288
+ // Constrain color wheel values to the wheel
289
+ if( target.parent().is('.minicolors-slider-wheel') && picker.parent().is('.minicolors-grid') ) {
290
+ wx = 75 - x;
291
+ wy = 75 - y;
292
+ r = Math.sqrt(wx * wx + wy * wy);
293
+ phi = Math.atan2(wy, wx);
294
+ if( phi < 0 ) phi += Math.PI * 2;
295
+ if( r > 75 ) {
296
+ r = 75;
297
+ x = 75 - (75 * Math.cos(phi));
298
+ y = 75 - (75 * Math.sin(phi));
299
+ }
300
+ x = Math.round(x);
301
+ y = Math.round(y);
302
+ }
303
+
304
+ // Move the picker
305
+ if( target.is('.minicolors-grid') ) {
306
+ picker
307
+ .stop(true)
308
+ .animate({
309
+ top: y + 'px',
310
+ left: x + 'px'
311
+ }, duration, settings.animationEasing, function() {
312
+ updateFromControl(input, target);
313
+ });
314
+ } else {
315
+ picker
316
+ .stop(true)
317
+ .animate({
318
+ top: y + 'px'
319
+ }, duration, settings.animationEasing, function() {
320
+ updateFromControl(input, target);
321
+ });
322
+ }
323
+
324
+ }
325
+
326
+ // Sets the input based on the color picker values
327
+ function updateFromControl(input, target) {
328
+
329
+ function getCoords(picker, container) {
330
+
331
+ var left, top;
332
+ if( !picker.length || !container ) return null;
333
+ left = picker.offset().left;
334
+ top = picker.offset().top;
335
+
336
+ return {
337
+ x: left - container.offset().left + (picker.outerWidth() / 2),
338
+ y: top - container.offset().top + (picker.outerHeight() / 2)
339
+ };
340
+
341
+ }
342
+
343
+ var hue, saturation, brightness, rgb, x, y, r, phi,
344
+
345
+ hex = input.val(),
346
+ opacity = input.attr('data-opacity'),
347
+
348
+ // Helpful references
349
+ minicolors = input.parent(),
350
+ settings = input.data('minicolors-settings'),
351
+ panel = minicolors.find('.minicolors-panel'),
352
+ swatch = minicolors.find('.minicolors-swatch'),
353
+
354
+ // Panel objects
355
+ grid = minicolors.find('.minicolors-grid'),
356
+ slider = minicolors.find('.minicolors-slider'),
357
+ opacitySlider = minicolors.find('.minicolors-opacity-slider'),
358
+
359
+ // Picker objects
360
+ gridPicker = grid.find('[class$=-picker]'),
361
+ sliderPicker = slider.find('[class$=-picker]'),
362
+ opacityPicker = opacitySlider.find('[class$=-picker]'),
363
+
364
+ // Picker positions
365
+ gridPos = getCoords(gridPicker, grid),
366
+ sliderPos = getCoords(sliderPicker, slider),
367
+ opacityPos = getCoords(opacityPicker, opacitySlider);
368
+
369
+ // Handle colors
370
+ if( target.is('.minicolors-grid, .minicolors-slider') ) {
371
+
372
+ // Determine HSB values
373
+ switch(settings.control) {
374
+
375
+ case 'wheel':
376
+ // Calculate hue, saturation, and brightness
377
+ x = (grid.width() / 2) - gridPos.x;
378
+ y = (grid.height() / 2) - gridPos.y;
379
+ r = Math.sqrt(x * x + y * y);
380
+ phi = Math.atan2(y, x);
381
+ if( phi < 0 ) phi += Math.PI * 2;
382
+ if( r > 75 ) {
383
+ r = 75;
384
+ gridPos.x = 69 - (75 * Math.cos(phi));
385
+ gridPos.y = 69 - (75 * Math.sin(phi));
386
+ }
387
+ saturation = keepWithin(r / 0.75, 0, 100);
388
+ hue = keepWithin(phi * 180 / Math.PI, 0, 360);
389
+ brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
390
+ hex = hsb2hex({
391
+ h: hue,
392
+ s: saturation,
393
+ b: brightness
394
+ });
395
+
396
+ // Update UI
397
+ slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 }));
398
+ break;
399
+
400
+ case 'saturation':
401
+ // Calculate hue, saturation, and brightness
402
+ hue = keepWithin(parseInt(gridPos.x * (360 / grid.width())), 0, 360);
403
+ saturation = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
404
+ brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
405
+ hex = hsb2hex({
406
+ h: hue,
407
+ s: saturation,
408
+ b: brightness
409
+ });
410
+
411
+ // Update UI
412
+ slider.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: brightness }));
413
+ minicolors.find('.minicolors-grid-inner').css('opacity', saturation / 100);
414
+ break;
415
+
416
+ case 'brightness':
417
+ // Calculate hue, saturation, and brightness
418
+ hue = keepWithin(parseInt(gridPos.x * (360 / grid.width())), 0, 360);
419
+ saturation = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
420
+ brightness = keepWithin(100 - Math.floor(sliderPos.y * (100 / slider.height())), 0, 100);
421
+ hex = hsb2hex({
422
+ h: hue,
423
+ s: saturation,
424
+ b: brightness
425
+ });
426
+
427
+ // Update UI
428
+ slider.css('backgroundColor', hsb2hex({ h: hue, s: saturation, b: 100 }));
429
+ minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (brightness / 100));
430
+ break;
431
+
432
+ default:
433
+ // Calculate hue, saturation, and brightness
434
+ hue = keepWithin(360 - parseInt(sliderPos.y * (360 / slider.height())), 0, 360);
435
+ saturation = keepWithin(Math.floor(gridPos.x * (100 / grid.width())), 0, 100);
436
+ brightness = keepWithin(100 - Math.floor(gridPos.y * (100 / grid.height())), 0, 100);
437
+ hex = hsb2hex({
438
+ h: hue,
439
+ s: saturation,
440
+ b: brightness
441
+ });
442
+
443
+ // Update UI
444
+ grid.css('backgroundColor', hsb2hex({ h: hue, s: 100, b: 100 }));
445
+ break;
446
+
447
+ }
448
+
449
+ // Adjust case
450
+ input.val( convertCase(hex, settings.letterCase) );
451
+
452
+ }
453
+
454
+ // Handle opacity
455
+ if( target.is('.minicolors-opacity-slider') ) {
456
+ if( settings.opacity ) {
457
+ opacity = parseFloat(1 - (opacityPos.y / opacitySlider.height())).toFixed(2);
458
+ } else {
459
+ opacity = 1;
460
+ }
461
+ if( settings.opacity ) input.attr('data-opacity', opacity);
462
+ }
463
+
464
+ // Set swatch color
465
+ swatch.find('SPAN').css({
466
+ backgroundColor: hex,
467
+ opacity: opacity
468
+ });
469
+
470
+ // Handle change event
471
+ doChange(input, hex, opacity);
472
+
473
+ }
474
+
475
+ // Sets the color picker values from the input
476
+ function updateFromInput(input, preserveInputValue, firstRun) {
477
+
478
+ var hex,
479
+ hsb,
480
+ opacity,
481
+ x, y, r, phi,
482
+
483
+ // Helpful references
484
+ minicolors = input.parent(),
485
+ settings = input.data('minicolors-settings'),
486
+ swatch = minicolors.find('.minicolors-swatch'),
487
+
488
+ // Panel objects
489
+ grid = minicolors.find('.minicolors-grid'),
490
+ slider = minicolors.find('.minicolors-slider'),
491
+ opacitySlider = minicolors.find('.minicolors-opacity-slider'),
492
+
493
+ // Picker objects
494
+ gridPicker = grid.find('[class$=-picker]'),
495
+ sliderPicker = slider.find('[class$=-picker]'),
496
+ opacityPicker = opacitySlider.find('[class$=-picker]');
497
+
498
+ // Determine hex/HSB values
499
+ hex = convertCase(parseHex(input.val(), true), settings.letterCase);
500
+ if( !hex ) hex = convertCase(parseHex(settings.defaultValue, true));
501
+ hsb = hex2hsb(hex);
502
+
503
+ // Update input value
504
+ if( !preserveInputValue ) input.val(hex);
505
+
506
+ // Determine opacity value
507
+ if( settings.opacity ) {
508
+ // Get from data-opacity attribute and keep within 0-1 range
509
+ opacity = input.attr('data-opacity') === '' ? 1 : keepWithin(parseFloat(input.attr('data-opacity')).toFixed(2), 0, 1);
510
+ if( isNaN(opacity) ) opacity = 1;
511
+ input.attr('data-opacity', opacity);
512
+ swatch.find('SPAN').css('opacity', opacity);
513
+
514
+ // Set opacity picker position
515
+ y = keepWithin(opacitySlider.height() - (opacitySlider.height() * opacity), 0, opacitySlider.height());
516
+ opacityPicker.css('top', y + 'px');
517
+ }
518
+
519
+ // Update swatch
520
+ swatch.find('SPAN').css('backgroundColor', hex);
521
+
522
+ // Determine picker locations
523
+ switch(settings.control) {
524
+
525
+ case 'wheel':
526
+ // Set grid position
527
+ r = keepWithin(Math.ceil(hsb.s * 0.75), 0, grid.height() / 2);
528
+ phi = hsb.h * Math.PI / 180;
529
+ x = keepWithin(75 - Math.cos(phi) * r, 0, grid.width());
530
+ y = keepWithin(75 - Math.sin(phi) * r, 0, grid.height());
531
+ gridPicker.css({
532
+ top: y + 'px',
533
+ left: x + 'px'
534
+ });
535
+
536
+ // Set slider position
537
+ y = 150 - (hsb.b / (100 / grid.height()));
538
+ if( hex === '' ) y = 0;
539
+ sliderPicker.css('top', y + 'px');
540
+
541
+ // Update panel color
542
+ slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 }));
543
+ break;
544
+
545
+ case 'saturation':
546
+ // Set grid position
547
+ x = keepWithin((5 * hsb.h) / 12, 0, 150);
548
+ y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
549
+ gridPicker.css({
550
+ top: y + 'px',
551
+ left: x + 'px'
552
+ });
553
+
554
+ // Set slider position
555
+ y = keepWithin(slider.height() - (hsb.s * (slider.height() / 100)), 0, slider.height());
556
+ sliderPicker.css('top', y + 'px');
557
+
558
+ // Update UI
559
+ slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: hsb.b }));
560
+ minicolors.find('.minicolors-grid-inner').css('opacity', hsb.s / 100);
561
+
562
+ break;
563
+
564
+ case 'brightness':
565
+ // Set grid position
566
+ x = keepWithin((5 * hsb.h) / 12, 0, 150);
567
+ y = keepWithin(grid.height() - Math.ceil(hsb.s / (100 / grid.height())), 0, grid.height());
568
+ gridPicker.css({
569
+ top: y + 'px',
570
+ left: x + 'px'
571
+ });
572
+
573
+ // Set slider position
574
+ y = keepWithin(slider.height() - (hsb.b * (slider.height() / 100)), 0, slider.height());
575
+ sliderPicker.css('top', y + 'px');
576
+
577
+ // Update UI
578
+ slider.css('backgroundColor', hsb2hex({ h: hsb.h, s: hsb.s, b: 100 }));
579
+ minicolors.find('.minicolors-grid-inner').css('opacity', 1 - (hsb.b / 100));
580
+ break;
581
+
582
+ default:
583
+ // Set grid position
584
+ x = keepWithin(Math.ceil(hsb.s / (100 / grid.width())), 0, grid.width());
585
+ y = keepWithin(grid.height() - Math.ceil(hsb.b / (100 / grid.height())), 0, grid.height());
586
+ gridPicker.css({
587
+ top: y + 'px',
588
+ left: x + 'px'
589
+ });
590
+
591
+ // Set slider position
592
+ y = keepWithin(slider.height() - (hsb.h / (360 / slider.height())), 0, slider.height());
593
+ sliderPicker.css('top', y + 'px');
594
+
595
+ // Update panel color
596
+ grid.css('backgroundColor', hsb2hex({ h: hsb.h, s: 100, b: 100 }));
597
+ break;
598
+
599
+ }
600
+
601
+ // Handle change event
602
+ if( !firstRun ) doChange(input, hex, opacity);
603
+
604
+ }
605
+
606
+ // Runs the change and changeDelay callbacks
607
+ function doChange(input, hex, opacity) {
608
+
609
+ var settings = input.data('minicolors-settings');
610
+
611
+ // Only run if it actually changed
612
+ if( hex + opacity !== input.data('minicolors-lastChange') ) {
613
+
614
+ // Remember last-changed value
615
+ input.data('minicolors-lastChange', hex + opacity);
616
+
617
+ // Fire change event
618
+ if( settings.change ) {
619
+ if( settings.changeDelay ) {
620
+ // Call after a delay
621
+ clearTimeout(input.data('minicolors-changeTimeout'));
622
+ input.data('minicolors-changeTimeout', setTimeout( function() {
623
+ settings.change.call(input.get(0), hex, opacity);
624
+ }, settings.changeDelay));
625
+ } else {
626
+ // Call immediately
627
+ settings.change.call(input.get(0), hex, opacity);
628
+ }
629
+ }
630
+
631
+ }
632
+
633
+ }
634
+
635
+ // Generates an RGB(A) object based on the input's value
636
+ function rgbObject(input) {
637
+ var hex = parseHex($(input).val(), true),
638
+ rgb = hex2rgb(hex),
639
+ opacity = $(input).attr('data-opacity');
640
+ if( !rgb ) return null;
641
+ if( opacity !== undefined ) $.extend(rgb, { a: parseFloat(opacity) });
642
+ return rgb;
643
+ }
644
+
645
+ // Genearates an RGB(A) string based on the input's value
646
+ function rgbString(input, alpha) {
647
+ var hex = parseHex($(input).val(), true),
648
+ rgb = hex2rgb(hex),
649
+ opacity = $(input).attr('data-opacity');
650
+ if( !rgb ) return null;
651
+ if( opacity === undefined ) opacity = 1;
652
+ if( alpha ) {
653
+ return 'rgba(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ', ' + parseFloat(opacity) + ')';
654
+ } else {
655
+ return 'rgb(' + rgb.r + ', ' + rgb.g + ', ' + rgb.b + ')';
656
+ }
657
+ }
658
+
659
+ // Converts to the letter case specified in settings
660
+ function convertCase(string, letterCase) {
661
+ return letterCase === 'uppercase' ? string.toUpperCase() : string.toLowerCase();
662
+ }
663
+
664
+ // Parses a string and returns a valid hex string when possible
665
+ function parseHex(string, expand) {
666
+ string = string.replace(/[^A-F0-9]/ig, '');
667
+ if( string.length !== 3 && string.length !== 6 ) return '';
668
+ if( string.length === 3 && expand ) {
669
+ string = string[0] + string[0] + string[1] + string[1] + string[2] + string[2];
670
+ }
671
+ return '#' + string;
672
+ }
673
+
674
+ // Keeps value within min and max
675
+ function keepWithin(value, min, max) {
676
+ if( value < min ) value = min;
677
+ if( value > max ) value = max;
678
+ return value;
679
+ }
680
+
681
+ // Converts an HSB object to an RGB object
682
+ function hsb2rgb(hsb) {
683
+ var rgb = {};
684
+ var h = Math.round(hsb.h);
685
+ var s = Math.round(hsb.s * 255 / 100);
686
+ var v = Math.round(hsb.b * 255 / 100);
687
+ if(s === 0) {
688
+ rgb.r = rgb.g = rgb.b = v;
689
+ } else {
690
+ var t1 = v;
691
+ var t2 = (255 - s) * v / 255;
692
+ var t3 = (t1 - t2) * (h % 60) / 60;
693
+ if( h === 360 ) h = 0;
694
+ if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
695
+ else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
696
+ else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
697
+ else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
698
+ else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
699
+ else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
700
+ else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
701
+ }
702
+ return {
703
+ r: Math.round(rgb.r),
704
+ g: Math.round(rgb.g),
705
+ b: Math.round(rgb.b)
706
+ };
707
+ }
708
+
709
+ // Converts an RGB object to a hex string
710
+ function rgb2hex(rgb) {
711
+ var hex = [
712
+ rgb.r.toString(16),
713
+ rgb.g.toString(16),
714
+ rgb.b.toString(16)
715
+ ];
716
+ $.each(hex, function(nr, val) {
717
+ if (val.length === 1) hex[nr] = '0' + val;
718
+ });
719
+ return '#' + hex.join('');
720
+ }
721
+
722
+ // Converts an HSB object to a hex string
723
+ function hsb2hex(hsb) {
724
+ return rgb2hex(hsb2rgb(hsb));
725
+ }
726
+
727
+ // Converts a hex string to an HSB object
728
+ function hex2hsb(hex) {
729
+ var hsb = rgb2hsb(hex2rgb(hex));
730
+ if( hsb.s === 0 ) hsb.h = 360;
731
+ return hsb;
732
+ }
733
+
734
+ // Converts an RGB object to an HSB object
735
+ function rgb2hsb(rgb) {
736
+ var hsb = { h: 0, s: 0, b: 0 };
737
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
738
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
739
+ var delta = max - min;
740
+ hsb.b = max;
741
+ hsb.s = max !== 0 ? 255 * delta / max : 0;
742
+ if( hsb.s !== 0 ) {
743
+ if( rgb.r === max ) {
744
+ hsb.h = (rgb.g - rgb.b) / delta;
745
+ } else if( rgb.g === max ) {
746
+ hsb.h = 2 + (rgb.b - rgb.r) / delta;
747
+ } else {
748
+ hsb.h = 4 + (rgb.r - rgb.g) / delta;
749
+ }
750
+ } else {
751
+ hsb.h = -1;
752
+ }
753
+ hsb.h *= 60;
754
+ if( hsb.h < 0 ) {
755
+ hsb.h += 360;
756
+ }
757
+ hsb.s *= 100/255;
758
+ hsb.b *= 100/255;
759
+ return hsb;
760
+ }
761
+
762
+ // Converts a hex string to an RGB object
763
+ function hex2rgb(hex) {
764
+ hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
765
+ return {
766
+ r: hex >> 16,
767
+ g: (hex & 0x00FF00) >> 8,
768
+ b: (hex & 0x0000FF)
769
+ };
770
+ }
771
+
772
+ // Handle events
773
+ $(document)
774
+ // Hide on clicks outside of the control
775
+ .on('mousedown.minicolors touchstart.minicolors', function(event) {
776
+ if( !$(event.target).parents().add(event.target).hasClass('minicolors') ) {
777
+ hide();
778
+ }
779
+ })
780
+ // Start moving
781
+ .on('mousedown.minicolors touchstart.minicolors', '.minicolors-grid, .minicolors-slider, .minicolors-opacity-slider', function(event) {
782
+ var target = $(this);
783
+ event.preventDefault();
784
+ $(document).data('minicolors-target', target);
785
+ move(target, event, true);
786
+ })
787
+ // Move pickers
788
+ .on('mousemove.minicolors touchmove.minicolors', function(event) {
789
+ var target = $(document).data('minicolors-target');
790
+ if( target ) move(target, event);
791
+ })
792
+ // Stop moving
793
+ .on('mouseup.minicolors touchend.minicolors', function() {
794
+ $(this).removeData('minicolors-target');
795
+ })
796
+ // Toggle panel when swatch is clicked
797
+ .on('mousedown.minicolors touchstart.minicolors', '.minicolors-swatch', function(event) {
798
+ var input = $(this).parent().find('.minicolors-input'),
799
+ minicolors = input.parent();
800
+ if( minicolors.hasClass('minicolors-focus') ) {
801
+ hide(input);
802
+ } else {
803
+ show(input);
804
+ }
805
+ })
806
+ // Show on focus
807
+ .on('focus.minicolors', '.minicolors-input', function(event) {
808
+ var input = $(this);
809
+ if( !input.data('minicolors-initialized') ) return;
810
+ show(input);
811
+ })
812
+ // Fix hex on blur
813
+ .on('blur.minicolors', '.minicolors-input', function(event) {
814
+ var input = $(this),
815
+ settings = input.data('minicolors-settings');
816
+ if( !input.data('minicolors-initialized') ) return;
817
+
818
+ // Parse Hex
819
+ input.val(parseHex(input.val(), true));
820
+
821
+ // Is it blank?
822
+ if( input.val() === '' ) input.val(parseHex(settings.defaultValue, true));
823
+
824
+ // Adjust case
825
+ input.val( convertCase(input.val(), settings.letterCase) );
826
+
827
+ })
828
+ // Handle keypresses
829
+ .on('keydown.minicolors', '.minicolors-input', function(event) {
830
+ var input = $(this);
831
+ if( !input.data('minicolors-initialized') ) return;
832
+ switch(event.keyCode) {
833
+ case 9: // tab
834
+ hide();
835
+ break;
836
+ case 27: // esc
837
+ hide();
838
+ input.blur();
839
+ break;
840
+ }
841
+ })
842
+ // Update on keyup
843
+ .on('keyup.minicolors', '.minicolors-input', function(event) {
844
+ var input = $(this);
845
+ if( !input.data('minicolors-initialized') ) return;
846
+ updateFromInput(input, true);
847
+ })
848
+ // Update on paste
849
+ .on('paste.minicolors', '.minicolors-input', function(event) {
850
+ var input = $(this);
851
+ if( !input.data('minicolors-initialized') ) return;
852
+ setTimeout( function() {
853
+ updateFromInput(input, true);
854
+ }, 1);
855
+ });
856
+
857
+ })(jQuery);