jquery-minicolors-rails 2.1.4.1 → 2.2.2.0

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