bootstrap_colorpicker_rails 0.1.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f3bee5067e60adca951a56625bc4e00d7001a7b
4
+ data.tar.gz: e01e4b881e80eb4cd8983d46b479d50028303ac0
5
+ SHA512:
6
+ metadata.gz: f7b5f8b149c459e0b2bb3d100709d29e0dc5919f78ff1f36730947ce25eb2035085d8e30e320158b4705a5b185d201817777476487c0d833d031d8332d3ef85a
7
+ data.tar.gz: fc287d6daa7a2d90d6bd72194b437849429ac1343f8d96c0772609b639b59b27db3fecd0fa2ef4b9d282d57a747d189dd1ad9152ff269aabca35dc153f5fcb8d
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ .ruby-version
16
+ .ruby-gemset
17
+ *.gem
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ ## v0.1.0
2
+
3
+ * Rails integration for Bootstrap Colorpicker
4
+ * simpel_form input for Bootstrap Colorpicker
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in bootstrap_colorpicker_rails.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Pavel Shpak
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # BootstrapColorpickerRails
2
+
3
+ This gem is Rails integration for Bootstrap Colorpicker. It includes simpel_form input for Colorpicker.
4
+
5
+ [Bootstrap Colorpicker](http://mjolnic.github.io/bootstrap-colorpicker/) originally written by Stefan Petre ([@eyecon](http://twitter.com/stefanpetre/)) and maintained in Github by Javier Aguilar ([@mjolnic](http://twitter.com/mjolnic/)) and the community.
6
+
7
+ *Note*: This gem doesn't include Bootstrap itself, it inludes only Bootstrap Colorpicker. You can get [Bootstrap here](https://github.com/twbs/bootstrap-sass)
8
+
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem 'bootstrap_colorpicker_rails'
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install bootstrap_colorpicker_rails
25
+
26
+
27
+ ## Usage
28
+
29
+ Add stylesheet file to app/assets/stylesheets/application.css.scss
30
+
31
+ ```scss
32
+ @import "bootstrap-colorpicker";
33
+ ```
34
+
35
+ Add javascript file to app/assets/javascripts/application.js
36
+
37
+ ```javascript
38
+ //= require bootstrap-colorpicker
39
+ ```
40
+
41
+ ### Using directly
42
+
43
+ Just call `colorpicker()` with any selector.
44
+
45
+ ```html
46
+ <input class='colorpicker'>
47
+
48
+ <script type="text/javascript">
49
+ $(document).ready(function(){
50
+ $('.colorpicker').colorpicker();
51
+ })
52
+ </script>
53
+ ```
54
+
55
+ There are some options you can pass to `colorpicker()`. They are documented at http://mjolnic.github.io/bootstrap-colorpicker/
56
+
57
+ ### Using with simple_form
58
+
59
+ There is `simple_form` input which you can apply via `as: :colorpicker` option.
60
+
61
+ ```erb
62
+ <%= f.input :color, as: :colorpicker %>
63
+ ```
64
+
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it ( https://github.com/ShPakvel/bootstrap_colorpicker_rails/fork )
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create a new Pull Request
73
+
74
+
75
+ ## License
76
+
77
+ This gem is licensed under the MIT License.
78
+ Bootstrap Colorpicker itself is licensed under the Apache License, Version 2.0.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'bootstrap_colorpicker_rails/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bootstrap_colorpicker_rails"
8
+ spec.version = BootstrapColorpickerRails::VERSION
9
+ spec.authors = ["Pavel Shpak"]
10
+ spec.email = ["shpakvel@gmail.com"]
11
+ spec.summary = %q{Rails integration for Bootstrap Colorpicker, with simpel_form input.}
12
+ spec.description = spec.summary
13
+ spec.homepage = "http://github.com/ShPakvel/bootstrap_colorpicker_rails"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "railties", ">= 3.0"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ end
@@ -0,0 +1,12 @@
1
+ require "rails"
2
+ require "bootstrap_colorpicker_rails/version"
3
+
4
+ autoload :ColorpickerInput, 'bootstrap_colorpicker_rails/simple_form/colorpicker_input'
5
+
6
+ module BootstrapColorpickerRails
7
+ if ::Rails.version < "3.1"
8
+ require "bootstrap_colorpicker_rails/railtie"
9
+ else
10
+ require "bootstrap_colorpicker_rails/engine"
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module BootstrapColorpickerRails
2
+ class Engine < ::Rails::Engine
3
+ config.to_prepare do
4
+ ::Rails.application.config.assets.precompile += %w(
5
+ alpha-horizontal.png
6
+ alpha.png
7
+ hue-horizontal.png
8
+ hue.png
9
+ saturation.png
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module BootstrapColorpickerRails
2
+ class Railtie < ::Rails::Railtie
3
+ config.to_prepare do
4
+ ::Rails.application.config.assets.precompile += %w(
5
+ alpha-horizontal.png
6
+ alpha.png
7
+ hue-horizontal.png
8
+ hue.png
9
+ saturation.png
10
+ )
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,10 @@
1
+ class ColorpickerInput < SimpleForm::Inputs::StringInput
2
+ def input
3
+ idf = "#{lookup_model_names.join("_")}_#{reflection_or_attribute_name}"
4
+ script = template.content_tag(:script, type: 'text/javascript') do
5
+ "$('input[id=#{idf}]').colorpicker();".html_safe
6
+ end
7
+
8
+ super + script
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module BootstrapColorpickerRails
2
+ VERSION = "0.1.0"
3
+ end
Binary file
Binary file
Binary file
@@ -0,0 +1,979 @@
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
+ if (val.charAt(0) !== "#" && (val.length === 3 || val.length === 6)) {
37
+ val = '#' + val;
38
+ }
39
+ this.setColor(val);
40
+ } else if (val.h !== undefined) {
41
+ this.value = val;
42
+ }
43
+ }
44
+ };
45
+
46
+ Color.prototype = {
47
+ constructor: Color,
48
+ // 140 predefined colors from the HTML Colors spec
49
+ colors: {
50
+ "aliceblue": "#f0f8ff",
51
+ "antiquewhite": "#faebd7",
52
+ "aqua": "#00ffff",
53
+ "aquamarine": "#7fffd4",
54
+ "azure": "#f0ffff",
55
+ "beige": "#f5f5dc",
56
+ "bisque": "#ffe4c4",
57
+ "black": "#000000",
58
+ "blanchedalmond": "#ffebcd",
59
+ "blue": "#0000ff",
60
+ "blueviolet": "#8a2be2",
61
+ "brown": "#a52a2a",
62
+ "burlywood": "#deb887",
63
+ "cadetblue": "#5f9ea0",
64
+ "chartreuse": "#7fff00",
65
+ "chocolate": "#d2691e",
66
+ "coral": "#ff7f50",
67
+ "cornflowerblue": "#6495ed",
68
+ "cornsilk": "#fff8dc",
69
+ "crimson": "#dc143c",
70
+ "cyan": "#00ffff",
71
+ "darkblue": "#00008b",
72
+ "darkcyan": "#008b8b",
73
+ "darkgoldenrod": "#b8860b",
74
+ "darkgray": "#a9a9a9",
75
+ "darkgreen": "#006400",
76
+ "darkkhaki": "#bdb76b",
77
+ "darkmagenta": "#8b008b",
78
+ "darkolivegreen": "#556b2f",
79
+ "darkorange": "#ff8c00",
80
+ "darkorchid": "#9932cc",
81
+ "darkred": "#8b0000",
82
+ "darksalmon": "#e9967a",
83
+ "darkseagreen": "#8fbc8f",
84
+ "darkslateblue": "#483d8b",
85
+ "darkslategray": "#2f4f4f",
86
+ "darkturquoise": "#00ced1",
87
+ "darkviolet": "#9400d3",
88
+ "deeppink": "#ff1493",
89
+ "deepskyblue": "#00bfff",
90
+ "dimgray": "#696969",
91
+ "dodgerblue": "#1e90ff",
92
+ "firebrick": "#b22222",
93
+ "floralwhite": "#fffaf0",
94
+ "forestgreen": "#228b22",
95
+ "fuchsia": "#ff00ff",
96
+ "gainsboro": "#dcdcdc",
97
+ "ghostwhite": "#f8f8ff",
98
+ "gold": "#ffd700",
99
+ "goldenrod": "#daa520",
100
+ "gray": "#808080",
101
+ "green": "#008000",
102
+ "greenyellow": "#adff2f",
103
+ "honeydew": "#f0fff0",
104
+ "hotpink": "#ff69b4",
105
+ "indianred ": "#cd5c5c",
106
+ "indigo ": "#4b0082",
107
+ "ivory": "#fffff0",
108
+ "khaki": "#f0e68c",
109
+ "lavender": "#e6e6fa",
110
+ "lavenderblush": "#fff0f5",
111
+ "lawngreen": "#7cfc00",
112
+ "lemonchiffon": "#fffacd",
113
+ "lightblue": "#add8e6",
114
+ "lightcoral": "#f08080",
115
+ "lightcyan": "#e0ffff",
116
+ "lightgoldenrodyellow": "#fafad2",
117
+ "lightgrey": "#d3d3d3",
118
+ "lightgreen": "#90ee90",
119
+ "lightpink": "#ffb6c1",
120
+ "lightsalmon": "#ffa07a",
121
+ "lightseagreen": "#20b2aa",
122
+ "lightskyblue": "#87cefa",
123
+ "lightslategray": "#778899",
124
+ "lightsteelblue": "#b0c4de",
125
+ "lightyellow": "#ffffe0",
126
+ "lime": "#00ff00",
127
+ "limegreen": "#32cd32",
128
+ "linen": "#faf0e6",
129
+ "magenta": "#ff00ff",
130
+ "maroon": "#800000",
131
+ "mediumaquamarine": "#66cdaa",
132
+ "mediumblue": "#0000cd",
133
+ "mediumorchid": "#ba55d3",
134
+ "mediumpurple": "#9370d8",
135
+ "mediumseagreen": "#3cb371",
136
+ "mediumslateblue": "#7b68ee",
137
+ "mediumspringgreen": "#00fa9a",
138
+ "mediumturquoise": "#48d1cc",
139
+ "mediumvioletred": "#c71585",
140
+ "midnightblue": "#191970",
141
+ "mintcream": "#f5fffa",
142
+ "mistyrose": "#ffe4e1",
143
+ "moccasin": "#ffe4b5",
144
+ "navajowhite": "#ffdead",
145
+ "navy": "#000080",
146
+ "oldlace": "#fdf5e6",
147
+ "olive": "#808000",
148
+ "olivedrab": "#6b8e23",
149
+ "orange": "#ffa500",
150
+ "orangered": "#ff4500",
151
+ "orchid": "#da70d6",
152
+ "palegoldenrod": "#eee8aa",
153
+ "palegreen": "#98fb98",
154
+ "paleturquoise": "#afeeee",
155
+ "palevioletred": "#d87093",
156
+ "papayawhip": "#ffefd5",
157
+ "peachpuff": "#ffdab9",
158
+ "peru": "#cd853f",
159
+ "pink": "#ffc0cb",
160
+ "plum": "#dda0dd",
161
+ "powderblue": "#b0e0e6",
162
+ "purple": "#800080",
163
+ "red": "#ff0000",
164
+ "rosybrown": "#bc8f8f",
165
+ "royalblue": "#4169e1",
166
+ "saddlebrown": "#8b4513",
167
+ "salmon": "#fa8072",
168
+ "sandybrown": "#f4a460",
169
+ "seagreen": "#2e8b57",
170
+ "seashell": "#fff5ee",
171
+ "sienna": "#a0522d",
172
+ "silver": "#c0c0c0",
173
+ "skyblue": "#87ceeb",
174
+ "slateblue": "#6a5acd",
175
+ "slategray": "#708090",
176
+ "snow": "#fffafa",
177
+ "springgreen": "#00ff7f",
178
+ "steelblue": "#4682b4",
179
+ "tan": "#d2b48c",
180
+ "teal": "#008080",
181
+ "thistle": "#d8bfd8",
182
+ "tomato": "#ff6347",
183
+ "turquoise": "#40e0d0",
184
+ "violet": "#ee82ee",
185
+ "wheat": "#f5deb3",
186
+ "white": "#ffffff",
187
+ "whitesmoke": "#f5f5f5",
188
+ "yellow": "#ffff00",
189
+ "yellowgreen": "#9acd32"
190
+ },
191
+ _sanitizeNumber: function(val) {
192
+ if (typeof val === 'number') {
193
+ return val;
194
+ }
195
+ if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) {
196
+ return 1;
197
+ }
198
+ if (val.toLowerCase !== undefined) {
199
+ return parseFloat(val);
200
+ }
201
+ return 1;
202
+ },
203
+ //parse a string to HSB
204
+ setColor: function(strVal) {
205
+ strVal = strVal.toLowerCase();
206
+ this.value = this.stringToHSB(strVal) || {
207
+ h: 0,
208
+ s: 0,
209
+ b: 0,
210
+ a: 1
211
+ };
212
+ },
213
+ stringToHSB: function(strVal) {
214
+ strVal = strVal.toLowerCase();
215
+ var that = this,
216
+ result = false;
217
+ $.each(this.stringParsers, function(i, parser) {
218
+ var match = parser.re.exec(strVal),
219
+ values = match && parser.parse.apply(that, [match]),
220
+ format = parser.format || 'rgba';
221
+ if (values) {
222
+ if (format.match(/hsla?/)) {
223
+ result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values));
224
+ } else {
225
+ result = that.RGBtoHSB.apply(that, values);
226
+ }
227
+ that.origFormat = format;
228
+ return false;
229
+ }
230
+ return true;
231
+ });
232
+ return result;
233
+ },
234
+ setHue: function(h) {
235
+ this.value.h = 1 - h;
236
+ },
237
+ setSaturation: function(s) {
238
+ this.value.s = s;
239
+ },
240
+ setBrightness: function(b) {
241
+ this.value.b = 1 - b;
242
+ },
243
+ setAlpha: function(a) {
244
+ this.value.a = parseInt((1 - a) * 100, 10) / 100;
245
+ },
246
+ toRGB: function(h, s, b, a) {
247
+ if (!h) {
248
+ h = this.value.h;
249
+ s = this.value.s;
250
+ b = this.value.b;
251
+ }
252
+ h *= 360;
253
+ var R, G, B, X, C;
254
+ h = (h % 360) / 60;
255
+ C = b * s;
256
+ X = C * (1 - Math.abs(h % 2 - 1));
257
+ R = G = B = b - C;
258
+
259
+ h = ~~h;
260
+ R += [C, X, 0, 0, X, C][h];
261
+ G += [X, C, C, X, 0, 0][h];
262
+ B += [0, 0, X, C, C, X][h];
263
+ return {
264
+ r: Math.round(R * 255),
265
+ g: Math.round(G * 255),
266
+ b: Math.round(B * 255),
267
+ a: a || this.value.a
268
+ };
269
+ },
270
+ toHex: function(h, s, b, a) {
271
+ var rgb = this.toRGB(h, s, b, a);
272
+ return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);
273
+ },
274
+ toHSL: function(h, s, b, a) {
275
+ h = h || this.value.h;
276
+ s = s || this.value.s;
277
+ b = b || this.value.b;
278
+ a = a || this.value.a;
279
+
280
+ var H = h,
281
+ L = (2 - s) * b,
282
+ S = s * b;
283
+ if (L > 0 && L <= 1) {
284
+ S /= L;
285
+ } else {
286
+ S /= 2 - L;
287
+ }
288
+ L /= 2;
289
+ if (S > 1) {
290
+ S = 1;
291
+ }
292
+ return {
293
+ h: isNaN(H) ? 0 : H,
294
+ s: isNaN(S) ? 0 : S,
295
+ l: isNaN(L) ? 0 : L,
296
+ a: isNaN(a) ? 0 : a
297
+ };
298
+ },
299
+ toAlias: function(r, g, b, a) {
300
+ var rgb = this.toHex(r, g, b, a);
301
+ for (var alias in this.colors) {
302
+ if (this.colors[alias] == rgb) {
303
+ return alias;
304
+ }
305
+ }
306
+ return false;
307
+ },
308
+ RGBtoHSB: function(r, g, b, a) {
309
+ r /= 255;
310
+ g /= 255;
311
+ b /= 255;
312
+
313
+ var H, S, V, C;
314
+ V = Math.max(r, g, b);
315
+ C = V - Math.min(r, g, b);
316
+ H = (C === 0 ? null :
317
+ V === r ? (g - b) / C :
318
+ V === g ? (b - r) / C + 2 :
319
+ (r - g) / C + 4
320
+ );
321
+ H = ((H + 360) % 6) * 60 / 360;
322
+ S = C === 0 ? 0 : C / V;
323
+ return {
324
+ h: this._sanitizeNumber(H),
325
+ s: S,
326
+ b: V,
327
+ a: this._sanitizeNumber(a)
328
+ };
329
+ },
330
+ HueToRGB: function(p, q, h) {
331
+ if (h < 0) {
332
+ h += 1;
333
+ } else if (h > 1) {
334
+ h -= 1;
335
+ }
336
+ if ((h * 6) < 1) {
337
+ return p + (q - p) * h * 6;
338
+ } else if ((h * 2) < 1) {
339
+ return q;
340
+ } else if ((h * 3) < 2) {
341
+ return p + (q - p) * ((2 / 3) - h) * 6;
342
+ } else {
343
+ return p;
344
+ }
345
+ },
346
+ HSLtoRGB: function(h, s, l, a) {
347
+ if (s < 0) {
348
+ s = 0;
349
+ }
350
+ var q;
351
+ if (l <= 0.5) {
352
+ q = l * (1 + s);
353
+ } else {
354
+ q = l + s - (l * s);
355
+ }
356
+
357
+ var p = 2 * l - q;
358
+
359
+ var tr = h + (1 / 3);
360
+ var tg = h;
361
+ var tb = h - (1 / 3);
362
+
363
+ var r = Math.round(this.HueToRGB(p, q, tr) * 255);
364
+ var g = Math.round(this.HueToRGB(p, q, tg) * 255);
365
+ var b = Math.round(this.HueToRGB(p, q, tb) * 255);
366
+ return [r, g, b, this._sanitizeNumber(a)];
367
+ },
368
+ toString: function(format) {
369
+ format = format || 'rgba';
370
+ switch (format) {
371
+ case 'rgb':
372
+ {
373
+ var rgb = this.toRGB();
374
+ return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
375
+ }
376
+ break;
377
+ case 'rgba':
378
+ {
379
+ var rgb = this.toRGB();
380
+ return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
381
+ }
382
+ break;
383
+ case 'hsl':
384
+ {
385
+ var hsl = this.toHSL();
386
+ return 'hsl(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%)';
387
+ }
388
+ break;
389
+ case 'hsla':
390
+ {
391
+ var hsl = this.toHSL();
392
+ return 'hsla(' + Math.round(hsl.h * 360) + ',' + Math.round(hsl.s * 100) + '%,' + Math.round(hsl.l * 100) + '%,' + hsl.a + ')';
393
+ }
394
+ break;
395
+ case 'hex':
396
+ {
397
+ return this.toHex();
398
+ }
399
+ break;
400
+ case 'alias':
401
+ return this.toAlias() || this.toHex();
402
+ default:
403
+ {
404
+ return false;
405
+ }
406
+ break;
407
+ }
408
+ },
409
+ // a set of RE's that can match strings and generate color tuples.
410
+ // from John Resig color plugin
411
+ // https://github.com/jquery/jquery-color/
412
+ stringParsers: [{
413
+ re: /#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
414
+ format: 'hex',
415
+ parse: function(execResult) {
416
+ return [
417
+ parseInt(execResult[1], 16),
418
+ parseInt(execResult[2], 16),
419
+ parseInt(execResult[3], 16),
420
+ 1
421
+ ];
422
+ }
423
+ }, {
424
+ re: /#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
425
+ format: 'hex',
426
+ parse: function(execResult) {
427
+ return [
428
+ parseInt(execResult[1] + execResult[1], 16),
429
+ parseInt(execResult[2] + execResult[2], 16),
430
+ parseInt(execResult[3] + execResult[3], 16),
431
+ 1
432
+ ];
433
+ }
434
+ }, {
435
+ re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/,
436
+ format: 'rgb',
437
+ parse: function(execResult) {
438
+ return [
439
+ execResult[1],
440
+ execResult[2],
441
+ execResult[3],
442
+ 1
443
+ ];
444
+ }
445
+ }, {
446
+ re: /rgb\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/,
447
+ format: 'rgb',
448
+ parse: function(execResult) {
449
+ return [
450
+ 2.55 * execResult[1],
451
+ 2.55 * execResult[2],
452
+ 2.55 * execResult[3],
453
+ 1
454
+ ];
455
+ }
456
+ }, {
457
+ re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
458
+ format: 'rgba',
459
+ parse: function(execResult) {
460
+ return [
461
+ execResult[1],
462
+ execResult[2],
463
+ execResult[3],
464
+ execResult[4]
465
+ ];
466
+ }
467
+ }, {
468
+ re: /rgba\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
469
+ format: 'rgba',
470
+ parse: function(execResult) {
471
+ return [
472
+ 2.55 * execResult[1],
473
+ 2.55 * execResult[2],
474
+ 2.55 * execResult[3],
475
+ execResult[4]
476
+ ];
477
+ }
478
+ }, {
479
+ re: /hsl\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*?\)/,
480
+ format: 'hsl',
481
+ parse: function(execResult) {
482
+ return [
483
+ execResult[1] / 360,
484
+ execResult[2] / 100,
485
+ execResult[3] / 100,
486
+ execResult[4]
487
+ ];
488
+ }
489
+ }, {
490
+ re: /hsla\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
491
+ format: 'hsla',
492
+ parse: function(execResult) {
493
+ return [
494
+ execResult[1] / 360,
495
+ execResult[2] / 100,
496
+ execResult[3] / 100,
497
+ execResult[4]
498
+ ];
499
+ }
500
+ }, {
501
+ //predefined color name
502
+ re: /^([a-z]{3,})$/,
503
+ format: 'alias',
504
+ parse: function(execResult) {
505
+ var hexval = this.colorNameToHex(execResult[0]) || '#000000';
506
+ var match = this.stringParsers[0].re.exec(hexval),
507
+ values = match && this.stringParsers[0].parse.apply(this, [match]);
508
+ return values;
509
+ }
510
+ }],
511
+ colorNameToHex: function(name) {
512
+ if (typeof this.colors[name.toLowerCase()] !== 'undefined') {
513
+ return this.colors[name.toLowerCase()];
514
+ }
515
+ return false;
516
+ }
517
+ };
518
+
519
+
520
+ var defaults = {
521
+ horizontal: false, // horizontal mode layout ?
522
+ inline: false, //forces to show the colorpicker as an inline element
523
+ color: false, //forces a color
524
+ format: false, //forces a format
525
+ input: 'input', // children input selector
526
+ container: false, // container selector
527
+ component: '.add-on, .input-group-addon', // children component selector
528
+ sliders: {
529
+ saturation: {
530
+ maxLeft: 100,
531
+ maxTop: 100,
532
+ callLeft: 'setSaturation',
533
+ callTop: 'setBrightness'
534
+ },
535
+ hue: {
536
+ maxLeft: 0,
537
+ maxTop: 100,
538
+ callLeft: false,
539
+ callTop: 'setHue'
540
+ },
541
+ alpha: {
542
+ maxLeft: 0,
543
+ maxTop: 100,
544
+ callLeft: false,
545
+ callTop: 'setAlpha'
546
+ }
547
+ },
548
+ slidersHorz: {
549
+ saturation: {
550
+ maxLeft: 100,
551
+ maxTop: 100,
552
+ callLeft: 'setSaturation',
553
+ callTop: 'setBrightness'
554
+ },
555
+ hue: {
556
+ maxLeft: 100,
557
+ maxTop: 0,
558
+ callLeft: 'setHue',
559
+ callTop: false
560
+ },
561
+ alpha: {
562
+ maxLeft: 100,
563
+ maxTop: 0,
564
+ callLeft: 'setAlpha',
565
+ callTop: false
566
+ }
567
+ },
568
+ template: '<div class="colorpicker dropdown-menu">' +
569
+ '<div class="colorpicker-saturation"><i><b></b></i></div>' +
570
+ '<div class="colorpicker-hue"><i></i></div>' +
571
+ '<div class="colorpicker-alpha"><i></i></div>' +
572
+ '<div class="colorpicker-color"><div /></div>' +
573
+ '</div>'
574
+ };
575
+
576
+ var Colorpicker = function(element, options) {
577
+ this.element = $(element).addClass('colorpicker-element');
578
+ this.options = $.extend({}, defaults, this.element.data(), options);
579
+ this.component = this.options.component;
580
+ this.component = (this.component !== false) ? this.element.find(this.component) : false;
581
+ if (this.component && (this.component.length === 0)) {
582
+ this.component = false;
583
+ }
584
+ this.container = (this.options.container === true) ? this.element : this.options.container;
585
+ this.container = (this.container !== false) ? $(this.container) : false;
586
+
587
+ // Is the element an input? Should we search inside for any input?
588
+ this.input = this.element.is('input') ? this.element : (this.options.input ?
589
+ this.element.find(this.options.input) : false);
590
+ if (this.input && (this.input.length === 0)) {
591
+ this.input = false;
592
+ }
593
+ // Set HSB color
594
+ this.color = new Color(this.options.color !== false ? this.options.color : this.getValue());
595
+ this.format = this.options.format !== false ? this.options.format : this.color.origFormat;
596
+
597
+ // Setup picker
598
+ this.picker = $(this.options.template);
599
+ if (this.options.inline) {
600
+ this.picker.addClass('colorpicker-inline colorpicker-visible');
601
+ } else {
602
+ this.picker.addClass('colorpicker-hidden');
603
+ }
604
+ if (this.options.horizontal) {
605
+ this.picker.addClass('colorpicker-horizontal');
606
+ }
607
+ if (this.format === 'rgba' || this.format === 'hsla') {
608
+ this.picker.addClass('colorpicker-with-alpha');
609
+ }
610
+ this.picker.on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.mousedown, this));
611
+ this.picker.appendTo(this.container ? this.container : $('body'));
612
+
613
+ // Bind events
614
+ if (this.input !== false) {
615
+ this.input.on({
616
+ 'keyup.colorpicker': $.proxy(this.keyup, this)
617
+ });
618
+ if (this.component === false) {
619
+ this.element.on({
620
+ 'focus.colorpicker': $.proxy(this.show, this)
621
+ });
622
+ }
623
+ if (this.options.inline === false) {
624
+ this.element.on({
625
+ 'focusout.colorpicker': $.proxy(this.hide, this)
626
+ });
627
+ }
628
+ }
629
+
630
+ if (this.component !== false) {
631
+ this.component.on({
632
+ 'click.colorpicker': $.proxy(this.show, this)
633
+ });
634
+ }
635
+
636
+ if ((this.input === false) && (this.component === false)) {
637
+ this.element.on({
638
+ 'click.colorpicker': $.proxy(this.show, this)
639
+ });
640
+ }
641
+
642
+ // for HTML5 input[type='color']
643
+ if ((this.input !== false) && (this.component !== false) && (this.input.attr('type') === 'color')) {
644
+
645
+ this.input.on({
646
+ 'click.colorpicker': $.proxy(this.show, this),
647
+ 'focus.colorpicker': $.proxy(this.show, this)
648
+ });
649
+ }
650
+ this.update();
651
+
652
+ $($.proxy(function() {
653
+ this.element.trigger('create');
654
+ }, this));
655
+ };
656
+
657
+ Colorpicker.version = '2.0.0-beta';
658
+
659
+ Colorpicker.Color = Color;
660
+
661
+ Colorpicker.prototype = {
662
+ constructor: Colorpicker,
663
+ destroy: function() {
664
+ this.picker.remove();
665
+ this.element.removeData('colorpicker').off('.colorpicker');
666
+ if (this.input !== false) {
667
+ this.input.off('.colorpicker');
668
+ }
669
+ if (this.component !== false) {
670
+ this.component.off('.colorpicker');
671
+ }
672
+ this.element.removeClass('colorpicker-element');
673
+ this.element.trigger({
674
+ type: 'destroy'
675
+ });
676
+ },
677
+ reposition: function() {
678
+ if (this.options.inline !== false || this.options.container) {
679
+ return false;
680
+ }
681
+ var type = this.container && this.container[0] !== document.body ? 'position' : 'offset';
682
+ var offset = this.component ? this.component[type]() : this.element[type]();
683
+ this.picker.css({
684
+ top: offset.top + (this.component ? this.component.outerHeight() : this.element.outerHeight()),
685
+ left: offset.left
686
+ });
687
+ },
688
+ show: function(e) {
689
+ if (this.isDisabled()) {
690
+ return false;
691
+ }
692
+ this.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden');
693
+ this.reposition();
694
+ $(window).on('resize.colorpicker', $.proxy(this.reposition, this));
695
+ if (e && (!this.hasInput() || this.input.attr('type') === 'color')) {
696
+ if (e.stopPropagation && e.preventDefault) {
697
+ e.stopPropagation();
698
+ e.preventDefault();
699
+ }
700
+ }
701
+ if (this.options.inline === false) {
702
+ $(window.document).on({
703
+ 'mousedown.colorpicker': $.proxy(this.hide, this)
704
+ });
705
+ }
706
+ this.element.trigger({
707
+ type: 'showPicker',
708
+ color: this.color
709
+ });
710
+ },
711
+ hide: function() {
712
+ this.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible');
713
+ $(window).off('resize.colorpicker', this.reposition);
714
+ $(document).off({
715
+ 'mousedown.colorpicker': this.hide
716
+ });
717
+ this.update();
718
+ this.element.trigger({
719
+ type: 'hidePicker',
720
+ color: this.color
721
+ });
722
+ },
723
+ updateData: function(val) {
724
+ val = val || this.color.toString(this.format);
725
+ this.element.data('color', val);
726
+ return val;
727
+ },
728
+ updateInput: function(val) {
729
+ val = val || this.color.toString(this.format);
730
+ if (this.input !== false) {
731
+ this.input.prop('value', val);
732
+ }
733
+ return val;
734
+ },
735
+ updatePicker: function(val) {
736
+ if (val !== undefined) {
737
+ this.color = new Color(val);
738
+ }
739
+ var sl = (this.options.horizontal === false) ? this.options.sliders : this.options.slidersHorz;
740
+ var icns = this.picker.find('i');
741
+ if (icns.length === 0) {
742
+ return;
743
+ }
744
+ if (this.options.horizontal === false) {
745
+ sl = this.options.sliders;
746
+ icns.eq(1).css('top', sl.hue.maxTop * (1 - this.color.value.h)).end()
747
+ .eq(2).css('top', sl.alpha.maxTop * (1 - this.color.value.a));
748
+ } else {
749
+ sl = this.options.slidersHorz;
750
+ icns.eq(1).css('left', sl.hue.maxLeft * (1 - this.color.value.h)).end()
751
+ .eq(2).css('left', sl.alpha.maxLeft * (1 - this.color.value.a));
752
+ }
753
+ icns.eq(0).css({
754
+ 'top': sl.saturation.maxTop - this.color.value.b * sl.saturation.maxTop,
755
+ 'left': this.color.value.s * sl.saturation.maxLeft
756
+ });
757
+ this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.toHex(this.color.value.h, 1, 1, 1));
758
+ this.picker.find('.colorpicker-alpha').css('backgroundColor', this.color.toHex());
759
+ this.picker.find('.colorpicker-color, .colorpicker-color div').css('backgroundColor', this.color.toString(this.format));
760
+ return val;
761
+ },
762
+ updateComponent: function(val) {
763
+ val = val || this.color.toString(this.format);
764
+ if (this.component !== false) {
765
+ var icn = this.component.find('i').eq(0);
766
+ if (icn.length > 0) {
767
+ icn.css({
768
+ 'backgroundColor': val
769
+ });
770
+ } else {
771
+ this.component.css({
772
+ 'backgroundColor': val
773
+ });
774
+ }
775
+ }
776
+ return val;
777
+ },
778
+ update: function(force) {
779
+ var val = this.updateComponent();
780
+ if ((this.getValue(false) !== false) || (force === true)) {
781
+ // Update input/data only if the current value is not blank
782
+ this.updateInput(val);
783
+ this.updateData(val);
784
+ }
785
+ this.updatePicker();
786
+ return val;
787
+
788
+ },
789
+ setValue: function(val) { // set color manually
790
+ this.color = new Color(val);
791
+ this.update();
792
+ this.element.trigger({
793
+ type: 'changeColor',
794
+ color: this.color,
795
+ value: val
796
+ });
797
+ },
798
+ getValue: function(defaultValue) {
799
+ defaultValue = (defaultValue === undefined) ? '#000000' : defaultValue;
800
+ var val;
801
+ if (this.hasInput()) {
802
+ val = this.input.val();
803
+ } else {
804
+ val = this.element.data('color');
805
+ }
806
+ if ((val === undefined) || (val === '') || (val === null)) {
807
+ // if not defined or empty, return default
808
+ val = defaultValue;
809
+ }
810
+ return val;
811
+ },
812
+ hasInput: function() {
813
+ return (this.input !== false);
814
+ },
815
+ isDisabled: function() {
816
+ if (this.hasInput()) {
817
+ return (this.input.prop('disabled') === true);
818
+ }
819
+ return false;
820
+ },
821
+ disable: function() {
822
+ if (this.hasInput()) {
823
+ this.input.prop('disabled', true);
824
+ return true;
825
+ }
826
+ return false;
827
+ },
828
+ enable: function() {
829
+ if (this.hasInput()) {
830
+ this.input.prop('disabled', false);
831
+ return true;
832
+ }
833
+ return false;
834
+ },
835
+ currentSlider: null,
836
+ mousePointer: {
837
+ left: 0,
838
+ top: 0
839
+ },
840
+ mousedown: function(e) {
841
+ if (!e.pageX && !e.pageY && e.originalEvent) {
842
+ e.pageX = e.originalEvent.touches[0].pageX;
843
+ e.pageY = e.originalEvent.touches[0].pageY;
844
+ }
845
+ e.stopPropagation();
846
+ e.preventDefault();
847
+
848
+ var target = $(e.target);
849
+
850
+ //detect the slider and set the limits and callbacks
851
+ var zone = target.closest('div');
852
+ var sl = this.options.horizontal ? this.options.slidersHorz : this.options.sliders;
853
+ if (!zone.is('.colorpicker')) {
854
+ if (zone.is('.colorpicker-saturation')) {
855
+ this.currentSlider = $.extend({}, sl.saturation);
856
+ } else if (zone.is('.colorpicker-hue')) {
857
+ this.currentSlider = $.extend({}, sl.hue);
858
+ } else if (zone.is('.colorpicker-alpha')) {
859
+ this.currentSlider = $.extend({}, sl.alpha);
860
+ } else {
861
+ return false;
862
+ }
863
+ var offset = zone.offset();
864
+ //reference to guide's style
865
+ this.currentSlider.guide = zone.find('i')[0].style;
866
+ this.currentSlider.left = e.pageX - offset.left;
867
+ this.currentSlider.top = e.pageY - offset.top;
868
+ this.mousePointer = {
869
+ left: e.pageX,
870
+ top: e.pageY
871
+ };
872
+ //trigger mousemove to move the guide to the current position
873
+ $(document).on({
874
+ 'mousemove.colorpicker': $.proxy(this.mousemove, this),
875
+ 'touchmove.colorpicker': $.proxy(this.mousemove, this),
876
+ 'mouseup.colorpicker': $.proxy(this.mouseup, this),
877
+ 'touchend.colorpicker': $.proxy(this.mouseup, this)
878
+ }).trigger('mousemove');
879
+ }
880
+ return false;
881
+ },
882
+ mousemove: function(e) {
883
+ if (!e.pageX && !e.pageY && e.originalEvent) {
884
+ e.pageX = e.originalEvent.touches[0].pageX;
885
+ e.pageY = e.originalEvent.touches[0].pageY;
886
+ }
887
+ e.stopPropagation();
888
+ e.preventDefault();
889
+ var left = Math.max(
890
+ 0,
891
+ Math.min(
892
+ this.currentSlider.maxLeft,
893
+ this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left)
894
+ )
895
+ );
896
+ var top = Math.max(
897
+ 0,
898
+ Math.min(
899
+ this.currentSlider.maxTop,
900
+ this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top)
901
+ )
902
+ );
903
+ this.currentSlider.guide.left = left + 'px';
904
+ this.currentSlider.guide.top = top + 'px';
905
+ if (this.currentSlider.callLeft) {
906
+ this.color[this.currentSlider.callLeft].call(this.color, left / this.currentSlider.maxLeft);
907
+ }
908
+ if (this.currentSlider.callTop) {
909
+ this.color[this.currentSlider.callTop].call(this.color, top / this.currentSlider.maxTop);
910
+ }
911
+ this.update(true);
912
+
913
+ this.element.trigger({
914
+ type: 'changeColor',
915
+ color: this.color
916
+ });
917
+ return false;
918
+ },
919
+ mouseup: function(e) {
920
+ e.stopPropagation();
921
+ e.preventDefault();
922
+ $(document).off({
923
+ 'mousemove.colorpicker': this.mousemove,
924
+ 'touchmove.colorpicker': this.mousemove,
925
+ 'mouseup.colorpicker': this.mouseup,
926
+ 'touchend.colorpicker': this.mouseup
927
+ });
928
+ return false;
929
+ },
930
+ keyup: function(e) {
931
+ if ((e.keyCode === 38)) {
932
+ if (this.color.value.a < 1) {
933
+ this.color.value.a = Math.round((this.color.value.a + 0.01) * 100) / 100;
934
+ }
935
+ this.update(true);
936
+ } else if ((e.keyCode === 40)) {
937
+ if (this.color.value.a > 0) {
938
+ this.color.value.a = Math.round((this.color.value.a - 0.01) * 100) / 100;
939
+ }
940
+ this.update(true);
941
+ } else {
942
+ var val = this.input.val();
943
+ this.color = new Color(val);
944
+ if (this.getValue(false) !== false) {
945
+ this.updateData();
946
+ this.updateComponent();
947
+ this.updatePicker();
948
+ }
949
+ }
950
+ this.element.trigger({
951
+ type: 'changeColor',
952
+ color: this.color,
953
+ value: val
954
+ });
955
+ }
956
+ };
957
+
958
+ $.colorpicker = Colorpicker;
959
+
960
+ $.fn.colorpicker = function(option) {
961
+ var pickerArgs = arguments;
962
+
963
+ return this.each(function() {
964
+ var $this = $(this),
965
+ inst = $this.data('colorpicker'),
966
+ options = ((typeof option === 'object') ? option : {});
967
+ if ((!inst) && (typeof option !== 'string')) {
968
+ $this.data('colorpicker', new Colorpicker(this, options));
969
+ } else {
970
+ if (typeof option === 'string') {
971
+ inst[option].apply(inst, Array.prototype.slice.call(pickerArgs, 1));
972
+ }
973
+ }
974
+ });
975
+ };
976
+
977
+ $.fn.colorpicker.constructor = Colorpicker;
978
+
979
+ }));