simple_form_extension 1.2.19 → 1.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22e98e292dd6f5ddf0199df1e697798826f6e4b7
4
- data.tar.gz: 64cb61b550409b2853d1f15e2c0cf16020e0cc93
3
+ metadata.gz: f7d4974ee71c785990804759ea8d876ba5a6a438
4
+ data.tar.gz: 7635b712c21ea6a73e05de4f94e51afc5d4ebb2c
5
5
  SHA512:
6
- metadata.gz: d1a82161531c515e994aa94f802a8d14f3080c71a86ec0023af1350d576dadf366c501aaf5cab9673e30f4e1a67ba70d58dae32896c062746fc8390fe48f9574
7
- data.tar.gz: 023658d5ff65269fc8efcc6dc6255a054bc6e2fe6e1b3f4f91ef834c8378b1cab525c2654808de219bd15ae5535edb19496084614efa0978a23e86310cd91012
6
+ metadata.gz: 0a286f7b7053e0cfe64d096a69bc9d24bcf4dc59316d10acd8a11f15d0f12f54953cecba85d2bf19adc9ddb19dad499b6be9e628dbc8df3570c4461f8676c1c6
7
+ data.tar.gz: 24bf49b3a78231b040f27e416ac87ed8843c67100768d1f964b363867edf3ac3a5cd59ce63f60a3c4de39733a9a62f3df73f60225457fd17eda0ba0f05807a2f
@@ -1,14 +1,22 @@
1
1
  module SimpleFormExtension
2
2
  module Inputs
3
3
  class ColorInput < SimpleForm::Inputs::Base
4
+
5
+ delegate :content_tag, to: :template
6
+
4
7
  def input(wrapper_options = nil)
5
8
  input_html_options[:class] << "colorpicker form-control"
6
- "<div class=\"input-group color\">
7
- #{@builder.text_field(attribute_name, input_html_options)}
8
- <span class=\"input-group-addon\">
9
- <i style=\"background-color: ;\"></i>
10
- </span>
11
- </div>".html_safe
9
+
10
+ # Fetch value
11
+ color = object.send(attribute_name)
12
+
13
+ content_tag(:div, class: 'input-group color', data: { colorpicker: true }) do
14
+ @builder.text_field(attribute_name, input_html_options) +
15
+
16
+ content_tag(:span, class: 'input-group-addon') do
17
+ content_tag(:i, '')
18
+ end
19
+ end
12
20
  end
13
21
  end
14
22
  end
@@ -23,7 +23,8 @@ module SimpleFormExtension
23
23
  :'multi' => multi?,
24
24
  :'add-translation' => _translate('selectize.add'),
25
25
  :'collection' => collection,
26
- :'max-items' => max_items
26
+ :'max-items' => max_items,
27
+ :'sort-field' => sort_field
27
28
  )
28
29
 
29
30
  @builder.hidden_field attribute_name, input_html_options
@@ -42,6 +43,10 @@ module SimpleFormExtension
42
43
  options[:max_items]
43
44
  end
44
45
 
46
+ def sort_field
47
+ options[:sort_field] ||= 'text'
48
+ end
49
+
45
50
  def collection
46
51
  if (collection = options[:collection])
47
52
  if enumerable?(collection)
@@ -87,7 +92,7 @@ module SimpleFormExtension
87
92
  [options, input_html_options].each do |hash|
88
93
  return hash[key] if hash.key?(key)
89
94
  end
90
-
95
+
91
96
  # Return default block value or nil if no block was given
92
97
  block ? block.call : nil
93
98
  end
@@ -1,12 +1,21 @@
1
1
  module SimpleFormExtension
2
2
  class Railtie < Rails::Railtie
3
3
  initializer 'add vendor path to assets pipeline' do |app|
4
- %w(javascripts stylesheets).each do |folder|
5
- app.config.assets.paths << File.expand_path(
6
- "../../../vendor/assets/#{ folder }",
7
- __FILE__
8
- )
4
+ %w(javascripts stylesheets images).each do |folder|
5
+ app.config.assets.paths << vendor_asset_path_for(folder)
9
6
  end
10
7
  end
8
+
9
+ initializer 'add images to precompile hook' do |app|
10
+ Dir[vendor_asset_path_for('images/**/*.*')].each do |image_path|
11
+ app.config.assets.precompile << image_path.split('/images/').pop
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def vendor_asset_path_for(sub_path)
18
+ File.expand_path("../../../vendor/assets/#{ sub_path }", __FILE__)
19
+ end
11
20
  end
12
21
  end
@@ -1,3 +1,3 @@
1
1
  module SimpleFormExtension
2
- VERSION = "1.2.19"
2
+ VERSION = "1.2.20"
3
3
  end
data/vendor/.DS_Store ADDED
Binary file
Binary file
@@ -0,0 +1,1025 @@
1
+ /*!
2
+ * Bootstrap Colorpicker
3
+ * http://mjolnic.github.io/bootstrap-colorpicker/
4
+ *
5
+ * Originally written by (c) 2012 Stefan Petre
6
+ * Licensed under the Apache License v2.0
7
+ * http://www.apache.org/licenses/LICENSE-2.0.txt
8
+ *
9
+ * @todo Update DOCS
10
+ */
11
+
12
+ (function(factory) {
13
+ "use strict";
14
+ if (typeof define === 'function' && define.amd) {
15
+ define(['jquery'], factory);
16
+ } else if (window.jQuery && !window.jQuery.fn.colorpicker) {
17
+ factory(window.jQuery);
18
+ }
19
+ }
20
+ (function($) {
21
+ 'use strict';
22
+
23
+ // Color object
24
+ var Color = function(val) {
25
+ this.value = {
26
+ h: 0,
27
+ s: 0,
28
+ b: 0,
29
+ a: 1
30
+ };
31
+ this.origFormat = null; // original string format
32
+ if (val) {
33
+ if (val.toLowerCase !== undefined) {
34
+ // cast to string
35
+ val = val + '';
36
+ this.setColor(val);
37
+ } else if (val.h !== undefined) {
38
+ this.value = val;
39
+ }
40
+ }
41
+ };
42
+
43
+ Color.prototype = {
44
+ constructor: Color,
45
+ // 140 predefined colors from the HTML Colors spec
46
+ colors: {
47
+ "aliceblue": "#f0f8ff",
48
+ "antiquewhite": "#faebd7",
49
+ "aqua": "#00ffff",
50
+ "aquamarine": "#7fffd4",
51
+ "azure": "#f0ffff",
52
+ "beige": "#f5f5dc",
53
+ "bisque": "#ffe4c4",
54
+ "black": "#000000",
55
+ "blanchedalmond": "#ffebcd",
56
+ "blue": "#0000ff",
57
+ "blueviolet": "#8a2be2",
58
+ "brown": "#a52a2a",
59
+ "burlywood": "#deb887",
60
+ "cadetblue": "#5f9ea0",
61
+ "chartreuse": "#7fff00",
62
+ "chocolate": "#d2691e",
63
+ "coral": "#ff7f50",
64
+ "cornflowerblue": "#6495ed",
65
+ "cornsilk": "#fff8dc",
66
+ "crimson": "#dc143c",
67
+ "cyan": "#00ffff",
68
+ "darkblue": "#00008b",
69
+ "darkcyan": "#008b8b",
70
+ "darkgoldenrod": "#b8860b",
71
+ "darkgray": "#a9a9a9",
72
+ "darkgreen": "#006400",
73
+ "darkkhaki": "#bdb76b",
74
+ "darkmagenta": "#8b008b",
75
+ "darkolivegreen": "#556b2f",
76
+ "darkorange": "#ff8c00",
77
+ "darkorchid": "#9932cc",
78
+ "darkred": "#8b0000",
79
+ "darksalmon": "#e9967a",
80
+ "darkseagreen": "#8fbc8f",
81
+ "darkslateblue": "#483d8b",
82
+ "darkslategray": "#2f4f4f",
83
+ "darkturquoise": "#00ced1",
84
+ "darkviolet": "#9400d3",
85
+ "deeppink": "#ff1493",
86
+ "deepskyblue": "#00bfff",
87
+ "dimgray": "#696969",
88
+ "dodgerblue": "#1e90ff",
89
+ "firebrick": "#b22222",
90
+ "floralwhite": "#fffaf0",
91
+ "forestgreen": "#228b22",
92
+ "fuchsia": "#ff00ff",
93
+ "gainsboro": "#dcdcdc",
94
+ "ghostwhite": "#f8f8ff",
95
+ "gold": "#ffd700",
96
+ "goldenrod": "#daa520",
97
+ "gray": "#808080",
98
+ "green": "#008000",
99
+ "greenyellow": "#adff2f",
100
+ "honeydew": "#f0fff0",
101
+ "hotpink": "#ff69b4",
102
+ "indianred ": "#cd5c5c",
103
+ "indigo ": "#4b0082",
104
+ "ivory": "#fffff0",
105
+ "khaki": "#f0e68c",
106
+ "lavender": "#e6e6fa",
107
+ "lavenderblush": "#fff0f5",
108
+ "lawngreen": "#7cfc00",
109
+ "lemonchiffon": "#fffacd",
110
+ "lightblue": "#add8e6",
111
+ "lightcoral": "#f08080",
112
+ "lightcyan": "#e0ffff",
113
+ "lightgoldenrodyellow": "#fafad2",
114
+ "lightgrey": "#d3d3d3",
115
+ "lightgreen": "#90ee90",
116
+ "lightpink": "#ffb6c1",
117
+ "lightsalmon": "#ffa07a",
118
+ "lightseagreen": "#20b2aa",
119
+ "lightskyblue": "#87cefa",
120
+ "lightslategray": "#778899",
121
+ "lightsteelblue": "#b0c4de",
122
+ "lightyellow": "#ffffe0",
123
+ "lime": "#00ff00",
124
+ "limegreen": "#32cd32",
125
+ "linen": "#faf0e6",
126
+ "magenta": "#ff00ff",
127
+ "maroon": "#800000",
128
+ "mediumaquamarine": "#66cdaa",
129
+ "mediumblue": "#0000cd",
130
+ "mediumorchid": "#ba55d3",
131
+ "mediumpurple": "#9370d8",
132
+ "mediumseagreen": "#3cb371",
133
+ "mediumslateblue": "#7b68ee",
134
+ "mediumspringgreen": "#00fa9a",
135
+ "mediumturquoise": "#48d1cc",
136
+ "mediumvioletred": "#c71585",
137
+ "midnightblue": "#191970",
138
+ "mintcream": "#f5fffa",
139
+ "mistyrose": "#ffe4e1",
140
+ "moccasin": "#ffe4b5",
141
+ "navajowhite": "#ffdead",
142
+ "navy": "#000080",
143
+ "oldlace": "#fdf5e6",
144
+ "olive": "#808000",
145
+ "olivedrab": "#6b8e23",
146
+ "orange": "#ffa500",
147
+ "orangered": "#ff4500",
148
+ "orchid": "#da70d6",
149
+ "palegoldenrod": "#eee8aa",
150
+ "palegreen": "#98fb98",
151
+ "paleturquoise": "#afeeee",
152
+ "palevioletred": "#d87093",
153
+ "papayawhip": "#ffefd5",
154
+ "peachpuff": "#ffdab9",
155
+ "peru": "#cd853f",
156
+ "pink": "#ffc0cb",
157
+ "plum": "#dda0dd",
158
+ "powderblue": "#b0e0e6",
159
+ "purple": "#800080",
160
+ "red": "#ff0000",
161
+ "rosybrown": "#bc8f8f",
162
+ "royalblue": "#4169e1",
163
+ "saddlebrown": "#8b4513",
164
+ "salmon": "#fa8072",
165
+ "sandybrown": "#f4a460",
166
+ "seagreen": "#2e8b57",
167
+ "seashell": "#fff5ee",
168
+ "sienna": "#a0522d",
169
+ "silver": "#c0c0c0",
170
+ "skyblue": "#87ceeb",
171
+ "slateblue": "#6a5acd",
172
+ "slategray": "#708090",
173
+ "snow": "#fffafa",
174
+ "springgreen": "#00ff7f",
175
+ "steelblue": "#4682b4",
176
+ "tan": "#d2b48c",
177
+ "teal": "#008080",
178
+ "thistle": "#d8bfd8",
179
+ "tomato": "#ff6347",
180
+ "turquoise": "#40e0d0",
181
+ "violet": "#ee82ee",
182
+ "wheat": "#f5deb3",
183
+ "white": "#ffffff",
184
+ "whitesmoke": "#f5f5f5",
185
+ "yellow": "#ffff00",
186
+ "yellowgreen": "#9acd32",
187
+ "transparent": "transparent"
188
+ },
189
+ _sanitizeNumber: function(val) {
190
+ if (typeof val === 'number') {
191
+ return val;
192
+ }
193
+ if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) {
194
+ return 1;
195
+ }
196
+ if (val.toLowerCase !== undefined) {
197
+ return parseFloat(val);
198
+ }
199
+ return 1;
200
+ },
201
+ isTransparent: function(strVal) {
202
+ if (!strVal) {
203
+ return false;
204
+ }
205
+ strVal = strVal.toLowerCase().trim();
206
+ return (strVal == 'transparent') || (strVal.match(/#?00000000/)) || (strVal.match(/(rgba|hsla)\(0,0,0,0?\.?0\)/));
207
+ },
208
+ rgbaIsTransparent: function(rgba) {
209
+ return ((rgba.r == 0) && (rgba.g == 0) && (rgba.b == 0) && (rgba.a == 0));
210
+ },
211
+ //parse a string to HSB
212
+ setColor: function(strVal) {
213
+ strVal = strVal.toLowerCase().trim();
214
+ if (strVal) {
215
+ if (this.isTransparent(strVal)) {
216
+ this.value = {
217
+ h: 0,
218
+ s: 0,
219
+ b: 0,
220
+ a: 0
221
+ }
222
+ } else {
223
+ this.value = this.stringToHSB(strVal) || {
224
+ h: 0,
225
+ s: 0,
226
+ b: 0,
227
+ a: 1
228
+ }; // if parser fails, defaults to black
229
+ }
230
+ }
231
+ },
232
+ stringToHSB: function(strVal) {
233
+ strVal = strVal.toLowerCase();
234
+ var that = this,
235
+ result = false;
236
+ $.each(this.stringParsers, function(i, parser) {
237
+ var match = parser.re.exec(strVal),
238
+ values = match && parser.parse.apply(that, [match]),
239
+ format = parser.format || 'rgba';
240
+ if (values) {
241
+ if (format.match(/hsla?/)) {
242
+ result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values));
243
+ } else {
244
+ result = that.RGBtoHSB.apply(that, values);
245
+ }
246
+ that.origFormat = format;
247
+ return false;
248
+ }
249
+ return true;
250
+ });
251
+ return result;
252
+ },
253
+ setHue: function(h) {
254
+ this.value.h = 1 - h;
255
+ },
256
+ setSaturation: function(s) {
257
+ this.value.s = s;
258
+ },
259
+ setBrightness: function(b) {
260
+ this.value.b = 1 - b;
261
+ },
262
+ setAlpha: function(a) {
263
+ this.value.a = parseInt((1 - a) * 100, 10) / 100;
264
+ },
265
+ toRGB: function(h, s, b, a) {
266
+ if (!h) {
267
+ h = this.value.h;
268
+ s = this.value.s;
269
+ b = this.value.b;
270
+ }
271
+ h *= 360;
272
+ var R, G, B, X, C;
273
+ h = (h % 360) / 60;
274
+ C = b * s;
275
+ X = C * (1 - Math.abs(h % 2 - 1));
276
+ R = G = B = b - C;
277
+
278
+ h = ~~h;
279
+ R += [C, X, 0, 0, X, C][h];
280
+ G += [X, C, C, X, 0, 0][h];
281
+ B += [0, 0, X, C, C, X][h];
282
+ return {
283
+ r: Math.round(R * 255),
284
+ g: Math.round(G * 255),
285
+ b: Math.round(B * 255),
286
+ a: a || this.value.a
287
+ };
288
+ },
289
+ toHex: function(h, s, b, a) {
290
+ var rgb = this.toRGB(h, s, b, a);
291
+ if (this.rgbaIsTransparent(rgb)) {
292
+ return 'transparent';
293
+ }
294
+ return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
295
+ },
296
+ toHSL: function(h, s, b, a) {
297
+ h = h || this.value.h;
298
+ s = s || this.value.s;
299
+ b = b || this.value.b;
300
+ a = a || this.value.a;
301
+
302
+ var H = h,
303
+ L = (2 - s) * b,
304
+ S = s * b;
305
+ if (L > 0 && L <= 1) {
306
+ S /= L;
307
+ } else {
308
+ S /= 2 - L;
309
+ }
310
+ L /= 2;
311
+ if (S > 1) {
312
+ S = 1;
313
+ }
314
+ return {
315
+ h: isNaN(H) ? 0 : H,
316
+ s: isNaN(S) ? 0 : S,
317
+ l: isNaN(L) ? 0 : L,
318
+ a: isNaN(a) ? 0 : a
319
+ };
320
+ },
321
+ toAlias: function(r, g, b, a) {
322
+ var rgb = this.toHex(r, g, b, a);
323
+ for (var alias in this.colors) {
324
+ if (this.colors[alias] == rgb) {
325
+ return alias;
326
+ }
327
+ }
328
+ return false;
329
+ },
330
+ RGBtoHSB: function(r, g, b, a) {
331
+ r /= 255;
332
+ g /= 255;
333
+ b /= 255;
334
+
335
+ var H, S, V, C;
336
+ V = Math.max(r, g, b);
337
+ C = V - Math.min(r, g, b);
338
+ H = (C === 0 ? null :
339
+ V === r ? (g - b) / C :
340
+ V === g ? (b - r) / C + 2 :
341
+ (r - g) / C + 4
342
+ );
343
+ H = ((H + 360) % 6) * 60 / 360;
344
+ S = C === 0 ? 0 : C / V;
345
+ return {
346
+ h: this._sanitizeNumber(H),
347
+ s: S,
348
+ b: V,
349
+ a: this._sanitizeNumber(a)
350
+ };
351
+ },
352
+ HueToRGB: function(p, q, h) {
353
+ if (h < 0) {
354
+ h += 1;
355
+ } else if (h > 1) {
356
+ h -= 1;
357
+ }
358
+ if ((h * 6) < 1) {
359
+ return p + (q - p) * h * 6;
360
+ } else if ((h * 2) < 1) {
361
+ return q;
362
+ } else if ((h * 3) < 2) {
363
+ return p + (q - p) * ((2 / 3) - h) * 6;
364
+ } else {
365
+ return p;
366
+ }
367
+ },
368
+ HSLtoRGB: function(h, s, l, a) {
369
+ if (s < 0) {
370
+ s = 0;
371
+ }
372
+ var q;
373
+ if (l <= 0.5) {
374
+ q = l * (1 + s);
375
+ } else {
376
+ q = l + s - (l * s);
377
+ }
378
+
379
+ var p = 2 * l - q;
380
+
381
+ var tr = h + (1 / 3);
382
+ var tg = h;
383
+ var tb = h - (1 / 3);
384
+
385
+ var r = Math.round(this.HueToRGB(p, q, tr) * 255);
386
+ var g = Math.round(this.HueToRGB(p, q, tg) * 255);
387
+ var b = Math.round(this.HueToRGB(p, q, tb) * 255);
388
+ return [r, g, b, this._sanitizeNumber(a)];
389
+ },
390
+ toString: function(format) {
391
+ format = format || 'rgba';
392
+ switch (format) {
393
+ case 'rgb':
394
+ {
395
+ var rgb = this.toRGB();
396
+ if (this.rgbaIsTransparent(rgb)) {
397
+ return 'transparent';
398
+ }
399
+ return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
400
+ }
401
+ break;
402
+ case 'rgba':
403
+ {
404
+ var rgb = this.toRGB();
405
+ return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
406
+ }
407
+ break;
408
+ case 'hsl':
409
+ {
410
+ var hsl = this.toHSL();
411
+ return 'hsl(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%)';
412
+ }
413
+ break;
414
+ case 'hsla':
415
+ {
416
+ var hsl = this.toHSL();
417
+ return 'hsla(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%,' + hsl.a + ')';
418
+ }
419
+ break;
420
+ case 'hex':
421
+ {
422
+ return this.toHex();
423
+ }
424
+ break;
425
+ case 'alias':
426
+ return this.toAlias() || this.toHex();
427
+ default:
428
+ {
429
+ return false;
430
+ }
431
+ break;
432
+ }
433
+ },
434
+ // a set of RE's that can match strings and generate color tuples.
435
+ // from John Resig color plugin
436
+ // https://github.com/jquery/jquery-color/
437
+ stringParsers: [{
438
+ re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/,
439
+ format: 'rgb',
440
+ parse: function(execResult) {
441
+ return [
442
+ execResult[1],
443
+ execResult[2],
444
+ execResult[3],
445
+ 1
446
+ ];
447
+ }
448
+ }, {
449
+ re: /rgb\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/,
450
+ format: 'rgb',
451
+ parse: function(execResult) {
452
+ return [
453
+ 2.55 * execResult[1],
454
+ 2.55 * execResult[2],
455
+ 2.55 * execResult[3],
456
+ 1
457
+ ];
458
+ }
459
+ }, {
460
+ re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
461
+ format: 'rgba',
462
+ parse: function(execResult) {
463
+ return [
464
+ execResult[1],
465
+ execResult[2],
466
+ execResult[3],
467
+ execResult[4]
468
+ ];
469
+ }
470
+ }, {
471
+ re: /rgba\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
472
+ format: 'rgba',
473
+ parse: function(execResult) {
474
+ return [
475
+ 2.55 * execResult[1],
476
+ 2.55 * execResult[2],
477
+ 2.55 * execResult[3],
478
+ execResult[4]
479
+ ];
480
+ }
481
+ }, {
482
+ re: /hsl\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/,
483
+ format: 'hsl',
484
+ parse: function(execResult) {
485
+ return [
486
+ execResult[1] / 360,
487
+ execResult[2] / 100,
488
+ execResult[3] / 100,
489
+ execResult[4]
490
+ ];
491
+ }
492
+ }, {
493
+ re: /hsla\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
494
+ format: 'hsla',
495
+ parse: function(execResult) {
496
+ return [
497
+ execResult[1] / 360,
498
+ execResult[2] / 100,
499
+ execResult[3] / 100,
500
+ execResult[4]
501
+ ];
502
+ }
503
+ }, {
504
+ re: /#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
505
+ format: 'hex',
506
+ parse: function(execResult) {
507
+ return [
508
+ parseInt(execResult[1], 16),
509
+ parseInt(execResult[2], 16),
510
+ parseInt(execResult[3], 16),
511
+ 1
512
+ ];
513
+ }
514
+ }, {
515
+ re: /#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
516
+ format: 'hex',
517
+ parse: function(execResult) {
518
+ return [
519
+ parseInt(execResult[1] + execResult[1], 16),
520
+ parseInt(execResult[2] + execResult[2], 16),
521
+ parseInt(execResult[3] + execResult[3], 16),
522
+ 1
523
+ ];
524
+ }
525
+ }, {
526
+ //predefined color name
527
+ re: /^([a-z]{3,})$/,
528
+ format: 'alias',
529
+ parse: function(execResult) {
530
+ var hexval = this.colorNameToHex(execResult[0]) || '#000000';
531
+ var match = this.stringParsers[6].re.exec(hexval),
532
+ values = match && this.stringParsers[6].parse.apply(this, [match]);
533
+ return values;
534
+ }
535
+ }],
536
+ colorNameToHex: function(name) {
537
+ if (typeof this.colors[name.toLowerCase()] !== 'undefined') {
538
+ return this.colors[name.toLowerCase()];
539
+ }
540
+ return false;
541
+ }
542
+ };
543
+
544
+
545
+ var defaults = {
546
+ horizontal: false, // horizontal mode layout ?
547
+ inline: false, //forces to show the colorpicker as an inline element
548
+ color: false, //forces a color
549
+ format: false, //forces a format
550
+ input: 'input', // children input selector
551
+ container: false, // container selector
552
+ component: '.add-on, .input-group-addon', // children component selector
553
+ sliders: {
554
+ saturation: {
555
+ maxLeft: 100,
556
+ maxTop: 100,
557
+ callLeft: 'setSaturation',
558
+ callTop: 'setBrightness'
559
+ },
560
+ hue: {
561
+ maxLeft: 0,
562
+ maxTop: 100,
563
+ callLeft: false,
564
+ callTop: 'setHue'
565
+ },
566
+ alpha: {
567
+ maxLeft: 0,
568
+ maxTop: 100,
569
+ callLeft: false,
570
+ callTop: 'setAlpha'
571
+ }
572
+ },
573
+ slidersHorz: {
574
+ saturation: {
575
+ maxLeft: 100,
576
+ maxTop: 100,
577
+ callLeft: 'setSaturation',
578
+ callTop: 'setBrightness'
579
+ },
580
+ hue: {
581
+ maxLeft: 100,
582
+ maxTop: 0,
583
+ callLeft: 'setHue',
584
+ callTop: false
585
+ },
586
+ alpha: {
587
+ maxLeft: 100,
588
+ maxTop: 0,
589
+ callLeft: 'setAlpha',
590
+ callTop: false
591
+ }
592
+ },
593
+ template: '<div class="colorpicker dropdown-menu">' +
594
+ '<div class="colorpicker-saturation"><i><b></b></i></div>' +
595
+ '<div class="colorpicker-hue"><i></i></div>' +
596
+ '<div class="colorpicker-alpha"><i></i></div>' +
597
+ '<div class="colorpicker-color"><div /></div>' +
598
+ '</div>'
599
+ };
600
+
601
+ var Colorpicker = function(element, options) {
602
+ this.element = $(element).addClass('colorpicker-element');
603
+ this.options = $.extend({}, defaults, this.element.data(), options);
604
+ this.component = this.options.component;
605
+ this.component = (this.component !== false) ? this.element.find(this.component) : false;
606
+ if (this.component && (this.component.length === 0)) {
607
+ this.component = false;
608
+ }
609
+ this.container = (this.options.container === true) ? this.element : this.options.container;
610
+ this.container = (this.container !== false) ? $(this.container) : false;
611
+
612
+ // Is the element an input? Should we search inside for any input?
613
+ this.input = this.element.is('input') ? this.element : (this.options.input ?
614
+ this.element.find(this.options.input) : false);
615
+ if (this.input && (this.input.length === 0)) {
616
+ this.input = false;
617
+ }
618
+ // Set HSB color
619
+ this.color = new Color(this.options.color !== false ? this.options.color : this.getValue());
620
+ this.format = this.options.format !== false ? this.options.format : this.color.origFormat;
621
+
622
+ // Setup picker
623
+ this.picker = $(this.options.template);
624
+ if (this.options.inline) {
625
+ this.picker.addClass('colorpicker-inline colorpicker-visible');
626
+ } else {
627
+ this.picker.addClass('colorpicker-hidden');
628
+ }
629
+ if (this.options.horizontal) {
630
+ this.picker.addClass('colorpicker-horizontal');
631
+ }
632
+ if (this.format === 'rgba' || this.format === 'hsla') {
633
+ this.picker.addClass('colorpicker-with-alpha');
634
+ }
635
+ if (this.options.align === 'right') {
636
+ this.picker.addClass('colorpicker-right');
637
+ }
638
+ this.picker.on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.mousedown, this));
639
+ this.picker.appendTo(this.container ? this.container : $('body'));
640
+
641
+ // Bind events
642
+ if (this.input !== false) {
643
+ this.input.on({
644
+ 'keyup.colorpicker': $.proxy(this.keyup, this)
645
+ });
646
+ if (this.component === false) {
647
+ this.element.on({
648
+ 'focus.colorpicker': $.proxy(this.show, this)
649
+ });
650
+ }
651
+ if (this.options.inline === false) {
652
+ this.element.on({
653
+ 'focusout.colorpicker': $.proxy(this.hide, this)
654
+ });
655
+ }
656
+ }
657
+
658
+ if (this.component !== false) {
659
+ this.component.on({
660
+ 'click.colorpicker': $.proxy(this.show, this)
661
+ });
662
+ }
663
+
664
+ if ((this.input === false) && (this.component === false)) {
665
+ this.element.on({
666
+ 'click.colorpicker': $.proxy(this.show, this)
667
+ });
668
+ }
669
+
670
+ // for HTML5 input[type='color']
671
+ if ((this.input !== false) && (this.component !== false) && (this.input.attr('type') === 'color')) {
672
+
673
+ this.input.on({
674
+ 'click.colorpicker': $.proxy(this.show, this),
675
+ 'focus.colorpicker': $.proxy(this.show, this)
676
+ });
677
+ }
678
+ this.update();
679
+
680
+ $($.proxy(function() {
681
+ this.element.trigger('create');
682
+ }, this));
683
+ };
684
+
685
+ Colorpicker.Color = Color;
686
+
687
+ Colorpicker.prototype = {
688
+ constructor: Colorpicker,
689
+ destroy: function() {
690
+ this.picker.remove();
691
+ this.element.removeData('colorpicker').off('.colorpicker');
692
+ if (this.input !== false) {
693
+ this.input.off('.colorpicker');
694
+ }
695
+ if (this.component !== false) {
696
+ this.component.off('.colorpicker');
697
+ }
698
+ this.element.removeClass('colorpicker-element');
699
+ this.element.trigger({
700
+ type: 'destroy'
701
+ });
702
+ },
703
+ reposition: function() {
704
+ if (this.options.inline !== false || this.options.container) {
705
+ return false;
706
+ }
707
+ var type = this.container && this.container[0] !== document.body ? 'position' : 'offset';
708
+ var element = this.component || this.element;
709
+ var offset = element[type]();
710
+ if (this.options.align === 'right') {
711
+ offset.left -= this.picker.outerWidth() - element.outerWidth()
712
+ }
713
+ this.picker.css({
714
+ top: offset.top + element.outerHeight(),
715
+ left: offset.left
716
+ });
717
+ },
718
+ show: function(e) {
719
+ if (this.isDisabled()) {
720
+ return false;
721
+ }
722
+ this.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden');
723
+ this.reposition();
724
+ $(window).on('resize.colorpicker', $.proxy(this.reposition, this));
725
+ if (e && (!this.hasInput() || this.input.attr('type') === 'color')) {
726
+ if (e.stopPropagation && e.preventDefault) {
727
+ e.stopPropagation();
728
+ e.preventDefault();
729
+ }
730
+ }
731
+ if (this.options.inline === false) {
732
+ $(window.document).on({
733
+ 'mousedown.colorpicker': $.proxy(this.hide, this)
734
+ });
735
+ }
736
+ this.element.trigger({
737
+ type: 'showPicker',
738
+ color: this.color
739
+ });
740
+ },
741
+ hide: function() {
742
+ this.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible');
743
+ $(window).off('resize.colorpicker', this.reposition);
744
+ $(document).off({
745
+ 'mousedown.colorpicker': this.hide
746
+ });
747
+ this.update();
748
+ this.element.trigger({
749
+ type: 'hidePicker',
750
+ color: this.color
751
+ });
752
+ },
753
+ updateData: function(val) {
754
+ val = val || this.color.toString(this.format);
755
+ this.element.data('color', val);
756
+ return val;
757
+ },
758
+ updateInput: function(val) {
759
+ val = val || this.color.toString(this.format);
760
+ if (this.input !== false) {
761
+ this.input.prop('value', val);
762
+ }
763
+ return val;
764
+ },
765
+ updatePicker: function(val) {
766
+ if (val !== undefined) {
767
+ this.color = new Color(val);
768
+ }
769
+ var sl = (this.options.horizontal === false) ? this.options.sliders : this.options.slidersHorz;
770
+ var icns = this.picker.find('i');
771
+ if (icns.length === 0) {
772
+ return;
773
+ }
774
+ if (this.options.horizontal === false) {
775
+ sl = this.options.sliders;
776
+ icns.eq(1).css('top', sl.hue.maxTop * (1 - this.color.value.h)).end()
777
+ .eq(2).css('top', sl.alpha.maxTop * (1 - this.color.value.a));
778
+ } else {
779
+ sl = this.options.slidersHorz;
780
+ icns.eq(1).css('left', sl.hue.maxLeft * (1 - this.color.value.h)).end()
781
+ .eq(2).css('left', sl.alpha.maxLeft * (1 - this.color.value.a));
782
+ }
783
+ icns.eq(0).css({
784
+ 'top': sl.saturation.maxTop - this.color.value.b * sl.saturation.maxTop,
785
+ 'left': this.color.value.s * sl.saturation.maxLeft
786
+ });
787
+ this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.toHex(this.color.value.h, 1, 1, 1));
788
+ this.picker.find('.colorpicker-alpha').css('backgroundColor', this.color.toHex());
789
+ this.picker.find('.colorpicker-color, .colorpicker-color div').css('backgroundColor', this.color.toString(this.format));
790
+ return val;
791
+ },
792
+ updateComponent: function(val) {
793
+ val = val || this.color.toString(this.format);
794
+ if (this.component !== false) {
795
+ var icn = this.component.find('i').eq(0);
796
+ if (icn.length > 0) {
797
+ icn.css({
798
+ 'backgroundColor': val
799
+ });
800
+ } else {
801
+ this.component.css({
802
+ 'backgroundColor': val
803
+ });
804
+ }
805
+ }
806
+ return val;
807
+ },
808
+ update: function(force) {
809
+ var val;
810
+ if ((this.getValue(false) !== false) || (force === true)) {
811
+ // Update input/data only if the current value is not empty
812
+ val = this.updateComponent();
813
+ this.updateInput(val);
814
+ this.updateData(val);
815
+ this.updatePicker(); // only update picker if value is not empty
816
+ }
817
+ return val;
818
+
819
+ },
820
+ setValue: function(val) { // set color manually
821
+ this.color = new Color(val);
822
+ this.update();
823
+ this.element.trigger({
824
+ type: 'changeColor',
825
+ color: this.color,
826
+ value: val
827
+ });
828
+ },
829
+ getValue: function(defaultValue) {
830
+ defaultValue = (defaultValue === undefined) ? '#000000' : defaultValue;
831
+ var val;
832
+ if (this.hasInput()) {
833
+ val = this.input.val();
834
+ } else {
835
+ val = this.element.data('color');
836
+ }
837
+ if ((val === undefined) || (val === '') || (val === null)) {
838
+ // if not defined or empty, return default
839
+ val = defaultValue;
840
+ }
841
+ return val;
842
+ },
843
+ hasInput: function() {
844
+ return (this.input !== false);
845
+ },
846
+ isDisabled: function() {
847
+ if (this.hasInput()) {
848
+ return (this.input.prop('disabled') === true);
849
+ }
850
+ return false;
851
+ },
852
+ disable: function() {
853
+ if (this.hasInput()) {
854
+ this.input.prop('disabled', true);
855
+ this.element.trigger({
856
+ type: 'disable',
857
+ color: this.color,
858
+ value: this.getValue()
859
+ });
860
+ return true;
861
+ }
862
+ return false;
863
+ },
864
+ enable: function() {
865
+ if (this.hasInput()) {
866
+ this.input.prop('disabled', false);
867
+ this.element.trigger({
868
+ type: 'enable',
869
+ color: this.color,
870
+ value: this.getValue()
871
+ });
872
+ return true;
873
+ }
874
+ return false;
875
+ },
876
+ currentSlider: null,
877
+ mousePointer: {
878
+ left: 0,
879
+ top: 0
880
+ },
881
+ mousedown: function(e) {
882
+ if (!e.pageX && !e.pageY && e.originalEvent) {
883
+ e.pageX = e.originalEvent.touches[0].pageX;
884
+ e.pageY = e.originalEvent.touches[0].pageY;
885
+ }
886
+ e.stopPropagation();
887
+ e.preventDefault();
888
+
889
+ var target = $(e.target);
890
+
891
+ //detect the slider and set the limits and callbacks
892
+ var zone = target.closest('div');
893
+ var sl = this.options.horizontal ? this.options.slidersHorz : this.options.sliders;
894
+ if (!zone.is('.colorpicker')) {
895
+ if (zone.is('.colorpicker-saturation')) {
896
+ this.currentSlider = $.extend({}, sl.saturation);
897
+ } else if (zone.is('.colorpicker-hue')) {
898
+ this.currentSlider = $.extend({}, sl.hue);
899
+ } else if (zone.is('.colorpicker-alpha')) {
900
+ this.currentSlider = $.extend({}, sl.alpha);
901
+ } else {
902
+ return false;
903
+ }
904
+ var offset = zone.offset();
905
+ //reference to guide's style
906
+ this.currentSlider.guide = zone.find('i')[0].style;
907
+ this.currentSlider.left = e.pageX - offset.left;
908
+ this.currentSlider.top = e.pageY - offset.top;
909
+ this.mousePointer = {
910
+ left: e.pageX,
911
+ top: e.pageY
912
+ };
913
+ //trigger mousemove to move the guide to the current position
914
+ $(document).on({
915
+ 'mousemove.colorpicker': $.proxy(this.mousemove, this),
916
+ 'touchmove.colorpicker': $.proxy(this.mousemove, this),
917
+ 'mouseup.colorpicker': $.proxy(this.mouseup, this),
918
+ 'touchend.colorpicker': $.proxy(this.mouseup, this)
919
+ }).trigger('mousemove');
920
+ }
921
+ return false;
922
+ },
923
+ mousemove: function(e) {
924
+ if (!e.pageX && !e.pageY && e.originalEvent) {
925
+ e.pageX = e.originalEvent.touches[0].pageX;
926
+ e.pageY = e.originalEvent.touches[0].pageY;
927
+ }
928
+ e.stopPropagation();
929
+ e.preventDefault();
930
+ var left = Math.max(
931
+ 0,
932
+ Math.min(
933
+ this.currentSlider.maxLeft,
934
+ this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left)
935
+ )
936
+ );
937
+ var top = Math.max(
938
+ 0,
939
+ Math.min(
940
+ this.currentSlider.maxTop,
941
+ this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top)
942
+ )
943
+ );
944
+ this.currentSlider.guide.left = left + 'px';
945
+ this.currentSlider.guide.top = top + 'px';
946
+ if (this.currentSlider.callLeft) {
947
+ this.color[this.currentSlider.callLeft].call(this.color, left / this.currentSlider.maxLeft);
948
+ }
949
+ if (this.currentSlider.callTop) {
950
+ this.color[this.currentSlider.callTop].call(this.color, top / this.currentSlider.maxTop);
951
+ }
952
+ this.update(true);
953
+
954
+ this.element.trigger({
955
+ type: 'changeColor',
956
+ color: this.color
957
+ });
958
+ return false;
959
+ },
960
+ mouseup: function(e) {
961
+ e.stopPropagation();
962
+ e.preventDefault();
963
+ $(document).off({
964
+ 'mousemove.colorpicker': this.mousemove,
965
+ 'touchmove.colorpicker': this.mousemove,
966
+ 'mouseup.colorpicker': this.mouseup,
967
+ 'touchend.colorpicker': this.mouseup
968
+ });
969
+ return false;
970
+ },
971
+ keyup: function(e) {
972
+ if ((e.keyCode === 38)) {
973
+ if (this.color.value.a < 1) {
974
+ this.color.value.a = Math.round((this.color.value.a + 0.01) * 100) / 100;
975
+ }
976
+ this.update(true);
977
+ } else if ((e.keyCode === 40)) {
978
+ if (this.color.value.a > 0) {
979
+ this.color.value.a = Math.round((this.color.value.a - 0.01) * 100) / 100;
980
+ }
981
+ this.update(true);
982
+ } else {
983
+ var val = this.input.val();
984
+ this.color = new Color(val);
985
+ if (this.getValue(false) !== false) {
986
+ this.updateData();
987
+ this.updateComponent();
988
+ this.updatePicker();
989
+ }
990
+ }
991
+ this.element.trigger({
992
+ type: 'changeColor',
993
+ color: this.color,
994
+ value: val
995
+ });
996
+ }
997
+ };
998
+
999
+ $.colorpicker = Colorpicker;
1000
+
1001
+ $.fn.colorpicker = function(option) {
1002
+ var pickerArgs = arguments,
1003
+ rv;
1004
+
1005
+ var $returnValue = this.each(function() {
1006
+ var $this = $(this),
1007
+ inst = $this.data('colorpicker'),
1008
+ options = ((typeof option === 'object') ? option : {});
1009
+ if ((!inst) && (typeof option !== 'string')) {
1010
+ $this.data('colorpicker', new Colorpicker(this, options));
1011
+ } else {
1012
+ if (typeof option === 'string') {
1013
+ rv = inst[option].apply(inst, Array.prototype.slice.call(pickerArgs, 1));
1014
+ }
1015
+ }
1016
+ });
1017
+ if (option === 'getValue') {
1018
+ return rv;
1019
+ }
1020
+ return $returnValue;
1021
+ };
1022
+
1023
+ $.fn.colorpicker.constructor = Colorpicker;
1024
+
1025
+ }));