jquery-minicolors-rails 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);