promethee 1.6.8 → 1.6.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/promethee.js +1 -0
  3. data/app/assets/stylesheets/promethee-edit.sass +2 -0
  4. data/app/views/promethee/_edit.html.erb +1 -1
  5. data/app/views/promethee/components/row/_edit.define.html.erb +3 -1
  6. data/app/views/promethee/components/row/_edit.inspect.html.erb +16 -1
  7. data/app/views/promethee/components/slider/_localize.html.erb +2 -2
  8. data/lib/promethee/rails/version.rb +1 -1
  9. data/node_modules/angular-bootstrap-colorpicker/CHANGELOG.md +29 -0
  10. data/node_modules/angular-bootstrap-colorpicker/MIT-LICENSE.txt +20 -0
  11. data/node_modules/angular-bootstrap-colorpicker/README.md +129 -0
  12. data/node_modules/angular-bootstrap-colorpicker/bower.json +15 -0
  13. data/node_modules/angular-bootstrap-colorpicker/css/colorpicker.css +172 -0
  14. data/node_modules/angular-bootstrap-colorpicker/css/colorpicker.min.css +1 -0
  15. data/node_modules/angular-bootstrap-colorpicker/gulpfile.js +42 -0
  16. data/node_modules/angular-bootstrap-colorpicker/img/alpha.png +0 -0
  17. data/node_modules/angular-bootstrap-colorpicker/img/hue.png +0 -0
  18. data/node_modules/angular-bootstrap-colorpicker/img/saturation.png +0 -0
  19. data/node_modules/angular-bootstrap-colorpicker/js/bootstrap-colorpicker-module.js +588 -0
  20. data/node_modules/angular-bootstrap-colorpicker/js/bootstrap-colorpicker-module.min.js +1 -0
  21. data/node_modules/angular-bootstrap-colorpicker/less/colorpicker.less +202 -0
  22. data/node_modules/angular-bootstrap-colorpicker/package.json +42 -0
  23. data/node_modules/angular-bootstrap-colorpicker/test/karma.conf.js +29 -0
  24. data/node_modules/angular-bootstrap-colorpicker/test/libs/angular-mocks.js +2382 -0
  25. data/node_modules/angular-bootstrap-colorpicker/test/libs/angular.min.js +250 -0
  26. data/node_modules/angular-bootstrap-colorpicker/test/libs/jquery-1.10.1.min.js +6 -0
  27. data/node_modules/angular-bootstrap-colorpicker/test/unit/colorpickerSpec.js +199 -0
  28. metadata +20 -1
@@ -0,0 +1 @@
1
+ .colorpicker-visible,.colorpicker-visible .dropdown-menu{display:block!important}colorpicker-saturation{display:block;width:100px;height:100px;background-image:url(data:image/png;base64,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);background-size:contain;cursor:crosshair;float:left}colorpicker-saturation i{display:block;height:7px;width:7px;border:1px solid #000;border-radius:5px;position:absolute;top:0;left:0;margin:-4px 0 0 -4px}colorpicker-saturation i::after{content:'';display:block;height:7px;width:7px;border:1px solid #fff;border-radius:5px}colorpicker-alpha,colorpicker-hue{width:15px;height:100px;float:left;cursor:row-resize;margin-left:4px;margin-bottom:4px}colorpicker-alpha i,colorpicker-hue i{display:block;height:2px;background:#000;border-top:1px solid #fff;position:absolute;top:0;left:0;width:100%;margin-top:-1px}.colorpicker,colorpicker-alpha{display:none}colorpicker-hue{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABkCAMAAABw8qpSAAABLFBMVEUA/z8AuP//JAAA/33/3AAA/1ABAv8A/7r/AH7/jgD2AP8A//j/AEHmAP/XAP/HAP+4AP//ALyoAP+aAP+JAP97AP9rAP9cAP9MAP8+AP8tAP8fAP8PAP8ATv//AG7/cAD/vgD/APoAmv//ADH/AKwB/wMA5//4Eg4AL///AOr/UQD/nwAA/27/7AAA/+kAe/8Ayf8A/5sA/zEA/6z/ABEAEP8A/17/MgAA/9n/ACL/gAD/AJ0AXP8Aqv//AMoA/yHqFBb/zAD/AGD/ANsA9//1/wDk/wDV/wDF/wC3/wD/AI2m/wD/FACY/wCI/wB5/wBp/wD/YgBb/wBK/wA8/wAs/wAd/wAN/wAAPv8A/xH/AFAAi///rQAA/8r/+gAA1///QwAAH/8Abf8A/43c/JNGAAAAiUlEQVR4AQXBg2EDAAAAsMy2bds2ttp2+/8PTby79mDLsKJPq/oFPdk24dWXAxsGjRg1ZtykKdNmzJozb8GiJct63WjYl7fiWdOZkk0vOpyr2fVtyKl7FX2uXGjpcuxWDy69KdiRk5WRlpIUFxMVERLw78+vH1Unun1YV3ZkwKM1CYfq7nQK22sD03ITV2Aqp0IAAAAASUVORK5CYII=);background-size:contain}.colorpicker-color,colorpicker-alpha{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAMAAACIElGlAAADAFBMVEUAAADT09PT09P////T09P////e3t7q6urT09Px8fHT09P////////T09PT09P////////T09PT09P////////////T09PT09P////////////T09P////T09PT09PT09P////T09PT09P////////////////T09P////T09PT09P////T09PT09PT09PT09PT09PT09P////T09P////T09PT09P////////////T09P////T09P////////////T09PT09P////T09P////////////////////T09P////////T09PT09P////////////////////////T09PT09P////////////////////////T09PT09P////T09PT09P////////T09P////////////T09P////////T09P////T09P////T09P////T09PT09PT09PT09P////T09PT09PT09PT09PT09PT09P////T09P////T09PT09P////////////T09PT09PT09P////T09PT09PT09PT09PT09PT09PT09P////////////////T09PT09P////////////T09P////////T09P////T09PT09PT09P////////T09P////////T09P////T09PT09P////////////////T09PT09PT09PT09P////T09PT09PT09PT09PT09PT09PT09P////T09P////T09PT09PT09PT09PT09P////////////////////////////////////T09P////T09P////T09P////T09PT09P////////////T09P////T09P////T09P////////////T09PT09P////////////////T09PT09P////T09P////T09PT09P////T09P////T09PT09P////T09PT09PT09PT09P////T09PT09P////////////T09PT09P////T09P////////T09MQsm1FAAABAHRSTlMAgJN8/vcDAfcCnJyGaZmZlomGk4yJOmM/eTxs8wY0YDFC7HNdLx18n5/7aUvzCcW9+qKiK8P0ZiltRwfdw/n8Px3WduJjItj78ss5PDHUNELbwP5wplA2FglEVwvkqNarCs4Z7b2sDLgQ0xNdyLrr0eLLUeW1Vs5TWQLwjPI3ZvQGdvxFyFrAeevaLCLvGd0kpRskGyf4qK605xKvFrGyDRHnBYMEkJaDkIBvB/gpH99O6CrbIC4nH3Lg2SXp4A7Qul/GDEgPSlMQ6LjqFU0SjyCCj5V/gnBN7xglL3O70WBU7gjFFEfft0sPTo1ndRipwXr2yRemWRVENq+ytbGuxGaWGQAAAnpJREFUeNpNxmdcDHAAxvEHOWXvmXX23ntv2XvvMg/Z44x0KaRBSnfcKSqlnYZKp1QqGpT20KZh783/eePj+3vzw3/q/AM9iURPTy6XS+RwcXNzcZMQTE1dTE3bE7y9S0u9xxD600rCGtpI2ErOsbGxzoiMrIqscnaOi4vDdnp4XYSrguwxQSb7KpMllycnl2MFaTSaTxrY5NrY5BoKb2BnZ2doZ29vb2OPSdSd4Bcc7OcXGhqamgqrYCsrq+mEiEtC3gUBDg55Dg53IkQYSYG+gb6+GEqB5wV0o5D8/JAQdKK5hA40n3BS+L6c0JJmE+ZQW8JEak1YQJ0Jq+jbaQEPnotGE+IrK+Pj+xKqU6pTUrIDAgKysZ+WEY5QQkJxcQIO0WrCUbL4YmFhgZ3UlVAUHR1d1JEwjVoRRpDJKxMTE/ShBoRR1I6whLyyvLyyUFAQFhbWhTCFFArFawXOCu/bEHpQLYKnZ0aGZw2CR1qah0dmpqurK+pTU0ILakJoTi+PC7j5RHTrqQg1qRkh3T3d3b0xoSE1ItSleoSe1IswmIYQPl8UlhLWkaOj41tHbKENBLX6j1qt/KFUKnFN+Onk9NvJCQdJpfqlUqGiIjExcRthN91/JsJmGkhYRO/OCBhHwwgxMWUxZQMIu8j8o7m5OfbRLMJh2kTYQ1FRhYVR2EHzCOtpMmEG3SUsJEvLoKAg2Prb2tqOJYSH+/uH33shwlTaS1hLBwhX6AYX2tuiRwStVntOa5yUZJwEqbREKjUi5Bjl5BhZW1uXWOMYGRBOnNDX1zfoxz1FwwkfSJfgo6vr41P7soBBNJ7Qm2YSzHTMzMwmEHRoMf0Fm5mYOUrzNBYAAAAASUVORK5CYII=);background-size:10px 100%}.colorpicker{top:0;left:0;z-index:99999}.colorpicker colorpicker-alpha,.colorpicker colorpicker-hue,.colorpicker colorpicker-saturation{position:relative}.colorpicker input{width:100px;font-size:11px;color:#000;background-color:#fff}.colorpicker.alpha{min-width:140px}.colorpicker.alpha colorpicker-alpha{display:block}.colorpicker.dropdown{position:absolute}.colorpicker.colorpicker-fixed-position{position:fixed}.colorpicker .dropdown-menu::after,.colorpicker .dropdown-menu::before{content:'';display:inline-block;position:absolute}.colorpicker .dropdown-menu::after{clear:both;border:6px solid transparent;top:-5px;left:7px}.colorpicker .dropdown-menu::before{border:7px solid transparent;top:-6px;left:6px}.colorpicker .dropdown-menu{position:static;top:0;left:0;min-width:129px;padding:4px;margin-top:0}.colorpicker-position-top .dropdown-menu::after{border-top:6px solid #fff;border-bottom:0;top:auto;bottom:-5px}.colorpicker-position-top .dropdown-menu::before{border-top:7px solid rgba(0,0,0,.2);border-bottom:0;top:auto;bottom:-6px}.colorpicker-position-right .dropdown-menu::after{border-right:6px solid #fff;border-left:0;top:11px;left:-5px}.colorpicker-position-right .dropdown-menu::before{border-right:7px solid rgba(0,0,0,.2);border-left:0;top:10px;left:-6px}.colorpicker-position-bottom .dropdown-menu::after{border-bottom:6px solid #fff;border-top:0}.colorpicker-position-bottom .dropdown-menu::before{border-bottom:7px solid rgba(0,0,0,.2);border-top:0}.colorpicker-position-left .dropdown-menu::after{border-left:6px solid #fff;border-right:0;top:11px;left:auto;right:-5px}.colorpicker-position-left .dropdown-menu::before{border-left:7px solid rgba(0,0,0,.2);border-right:0;top:10px;left:auto;right:-6px}colorpicker-preview{display:block;height:10px;margin:5px 0 3px;clear:both;background-position:0 100%}
@@ -0,0 +1,42 @@
1
+ var gulp = require('gulp');
2
+ var rename = require('gulp-rename');
3
+ var less = require('gulp-less');
4
+ var minifyCss = require('gulp-minify-css');
5
+ var jshint = require('gulp-jshint');
6
+ var uglify = require('gulp-uglify');
7
+ var karma = require('karma').server;
8
+
9
+ gulp.task('default', ['css', 'jshint', 'test', 'compress']);
10
+
11
+ gulp.task('less', function() {
12
+ return gulp.src('./less/*.less')
13
+ .pipe(less())
14
+ .pipe(gulp.dest('./css'));
15
+ });
16
+
17
+ gulp.task('css', ['less'], function() {
18
+ return gulp.src('./css/colorpicker.css')
19
+ .pipe(minifyCss())
20
+ .pipe(rename('colorpicker.min.css'))
21
+ .pipe(gulp.dest('./css'));
22
+ });
23
+
24
+ gulp.task('jshint', function () {
25
+ return gulp.src(['js/*.js', 'test/unit/*.js', '!js/bootstrap-colorpicker-module.min.js'])
26
+ .pipe(jshint('.jshintrc'))
27
+ .pipe(jshint.reporter('default'));
28
+ });
29
+
30
+ gulp.task('compress', function() {
31
+ gulp.src('./js/bootstrap-colorpicker-module.js')
32
+ .pipe(uglify())
33
+ .pipe(rename('bootstrap-colorpicker-module.min.js'))
34
+ .pipe(gulp.dest('./js'))
35
+ });
36
+
37
+ gulp.task('test', function (done) {
38
+ karma.start({
39
+ configFile: __dirname + '/test/karma.conf.js',
40
+ singleRun: true
41
+ }, done);
42
+ });
@@ -0,0 +1,588 @@
1
+ angular.module('colorpicker.module', [])
2
+ .factory('Helper', function () {
3
+ 'use strict';
4
+ return {
5
+ closestSlider: function (elem) {
6
+ var matchesSelector = elem.matches || elem.webkitMatchesSelector || elem.mozMatchesSelector || elem.msMatchesSelector;
7
+ if (matchesSelector.bind(elem)('I')) {
8
+ return elem.parentNode;
9
+ }
10
+ return elem;
11
+ },
12
+ getOffset: function (elem, fixedPosition) {
13
+ var
14
+ scrollX = 0,
15
+ scrollY = 0,
16
+ rect = elem.getBoundingClientRect();
17
+ while (elem && !isNaN(elem.offsetLeft) && !isNaN(elem.offsetTop)) {
18
+ if (!fixedPosition && elem.tagName === 'BODY') {
19
+ scrollX += document.documentElement.scrollLeft || elem.scrollLeft;
20
+ scrollY += document.documentElement.scrollTop || elem.scrollTop;
21
+ } else {
22
+ scrollX += elem.scrollLeft;
23
+ scrollY += elem.scrollTop;
24
+ }
25
+ elem = elem.offsetParent;
26
+ }
27
+ return {
28
+ top: rect.top + window.pageYOffset,
29
+ left: rect.left + window.pageXOffset,
30
+ scrollX: scrollX,
31
+ scrollY: scrollY
32
+ };
33
+ },
34
+ // a set of RE's that can match strings and generate color tuples. https://github.com/jquery/jquery-color/
35
+ stringParsers: [
36
+ {
37
+ re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
38
+ parse: function (execResult) {
39
+ return [
40
+ execResult[1],
41
+ execResult[2],
42
+ execResult[3],
43
+ execResult[4]
44
+ ];
45
+ }
46
+ },
47
+ {
48
+ re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d+(?:\.\d+)?)\s*)?\)/,
49
+ parse: function (execResult) {
50
+ return [
51
+ 2.55 * execResult[1],
52
+ 2.55 * execResult[2],
53
+ 2.55 * execResult[3],
54
+ execResult[4]
55
+ ];
56
+ }
57
+ },
58
+ {
59
+ re: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,
60
+ parse: function (execResult) {
61
+ return [
62
+ parseInt(execResult[1], 16),
63
+ parseInt(execResult[2], 16),
64
+ parseInt(execResult[3], 16)
65
+ ];
66
+ }
67
+ },
68
+ {
69
+ re: /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,
70
+ parse: function (execResult) {
71
+ return [
72
+ parseInt(execResult[1] + execResult[1], 16),
73
+ parseInt(execResult[2] + execResult[2], 16),
74
+ parseInt(execResult[3] + execResult[3], 16)
75
+ ];
76
+ }
77
+ }
78
+ ]
79
+ };
80
+ })
81
+ .factory('Color', ['Helper', function (Helper) {
82
+ 'use strict';
83
+ return {
84
+ value: {
85
+ h: 1,
86
+ s: 1,
87
+ b: 1,
88
+ a: 1
89
+ },
90
+ // translate a format from Color object to a string
91
+ 'rgb': function () {
92
+ var rgb = this.toRGB();
93
+ return 'rgb(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ')';
94
+ },
95
+ 'rgba': function () {
96
+ var rgb = this.toRGB();
97
+ return 'rgba(' + rgb.r + ',' + rgb.g + ',' + rgb.b + ',' + rgb.a + ')';
98
+ },
99
+ 'hex': function () {
100
+ return this.toHex();
101
+ },
102
+
103
+ // HSBtoRGB from RaphaelJS
104
+ RGBtoHSB: function (r, g, b, a) {
105
+ r /= 255;
106
+ g /= 255;
107
+ b /= 255;
108
+
109
+ var H, S, V, C;
110
+ V = Math.max(r, g, b);
111
+ C = V - Math.min(r, g, b);
112
+ H = (C === 0 ? null :
113
+ V === r ? (g - b) / C :
114
+ V === g ? (b - r) / C + 2 :
115
+ (r - g) / C + 4
116
+ );
117
+ H = ((H + 360) % 6) * 60 / 360;
118
+ S = C === 0 ? 0 : C / V;
119
+ return {h: H || 1, s: S, b: V, a: a || 1};
120
+ },
121
+
122
+ //parse a string to HSB
123
+ setColor: function (val) {
124
+ val = (val) ? val.toLowerCase() : val;
125
+ for (var key in Helper.stringParsers) {
126
+ if (Helper.stringParsers.hasOwnProperty(key)) {
127
+ var parser = Helper.stringParsers[key];
128
+ var match = parser.re.exec(val),
129
+ values = match && parser.parse(match);
130
+ if (values) {
131
+ this.value = this.RGBtoHSB.apply(null, values);
132
+ return false;
133
+ }
134
+ }
135
+ }
136
+ },
137
+
138
+ setHue: function (h) {
139
+ this.value.h = 1 - h;
140
+ },
141
+
142
+ setSaturation: function (s) {
143
+ this.value.s = s;
144
+ },
145
+
146
+ setLightness: function (b) {
147
+ this.value.b = 1 - b;
148
+ },
149
+
150
+ setAlpha: function (a) {
151
+ this.value.a = parseInt((1 - a) * 100, 10) / 100;
152
+ },
153
+
154
+ // HSBtoRGB from RaphaelJS
155
+ // https://github.com/DmitryBaranovskiy/raphael/
156
+ toRGB: function (h, s, b, a) {
157
+ if (!h) {
158
+ h = this.value.h;
159
+ s = this.value.s;
160
+ b = this.value.b;
161
+ }
162
+ h *= 360;
163
+ var R, G, B, X, C;
164
+ h = (h % 360) / 60;
165
+ C = b * s;
166
+ X = C * (1 - Math.abs(h % 2 - 1));
167
+ R = G = B = b - C;
168
+
169
+ h = ~~h;
170
+ R += [C, X, 0, 0, X, C][h];
171
+ G += [X, C, C, X, 0, 0][h];
172
+ B += [0, 0, X, C, C, X][h];
173
+ return {
174
+ r: Math.round(R * 255),
175
+ g: Math.round(G * 255),
176
+ b: Math.round(B * 255),
177
+ a: a || this.value.a
178
+ };
179
+ },
180
+
181
+ toHex: function (h, s, b, a) {
182
+ var rgb = this.toRGB(h, s, b, a);
183
+ return '#' + ((1 << 24) | (parseInt(rgb.r, 10) << 16) | (parseInt(rgb.g, 10) << 8) | parseInt(rgb.b, 10)).toString(16).substr(1);
184
+ }
185
+ };
186
+ }])
187
+ .factory('Slider', ['Helper', function (Helper) {
188
+ 'use strict';
189
+ var
190
+ slider = {
191
+ maxLeft: 0,
192
+ maxTop: 0,
193
+ callLeft: null,
194
+ callTop: null,
195
+ knob: {
196
+ top: 0,
197
+ left: 0
198
+ }
199
+ },
200
+ pointer = {};
201
+
202
+ return {
203
+ getSlider: function() {
204
+ return slider;
205
+ },
206
+ getLeftPosition: function(event) {
207
+ return Math.max(0, Math.min(slider.maxLeft, slider.left + ((event.pageX || pointer.left) - pointer.left)));
208
+ },
209
+ getTopPosition: function(event) {
210
+ return Math.max(0, Math.min(slider.maxTop, slider.top + ((event.pageY || pointer.top) - pointer.top)));
211
+ },
212
+ setSlider: function (event, fixedPosition) {
213
+ var
214
+ target = Helper.closestSlider(event.target),
215
+ targetOffset = Helper.getOffset(target, fixedPosition),
216
+ rect = target.getBoundingClientRect(),
217
+ offsetX = event.clientX - rect.left,
218
+ offsetY = event.clientY - rect.top;
219
+
220
+ slider.knob = target.children[0].style;
221
+ slider.left = event.pageX - targetOffset.left - window.pageXOffset + targetOffset.scrollX;
222
+ slider.top = event.pageY - targetOffset.top - window.pageYOffset + targetOffset.scrollY;
223
+
224
+ pointer = {
225
+ left: event.pageX - (offsetX - slider.left),
226
+ top: event.pageY - (offsetY - slider.top)
227
+ };
228
+ },
229
+ setSaturation: function(event, fixedPosition, componentSize) {
230
+ slider = {
231
+ maxLeft: componentSize,
232
+ maxTop: componentSize,
233
+ callLeft: 'setSaturation',
234
+ callTop: 'setLightness'
235
+ };
236
+ this.setSlider(event, fixedPosition);
237
+ },
238
+ setHue: function(event, fixedPosition, componentSize) {
239
+ slider = {
240
+ maxLeft: 0,
241
+ maxTop: componentSize,
242
+ callLeft: false,
243
+ callTop: 'setHue'
244
+ };
245
+ this.setSlider(event, fixedPosition);
246
+ },
247
+ setAlpha: function(event, fixedPosition, componentSize) {
248
+ slider = {
249
+ maxLeft: 0,
250
+ maxTop: componentSize,
251
+ callLeft: false,
252
+ callTop: 'setAlpha'
253
+ };
254
+ this.setSlider(event, fixedPosition);
255
+ },
256
+ setKnob: function(top, left) {
257
+ slider.knob.top = top + 'px';
258
+ slider.knob.left = left + 'px';
259
+ }
260
+ };
261
+ }])
262
+ .directive('colorpicker', ['$document', '$compile', 'Color', 'Slider', 'Helper', function ($document, $compile, Color, Slider, Helper) {
263
+ 'use strict';
264
+ return {
265
+ require: '?ngModel',
266
+ restrict: 'A',
267
+ link: function ($scope, elem, attrs, ngModel) {
268
+ var
269
+ thisFormat = attrs.colorpicker ? attrs.colorpicker : 'hex',
270
+ position = angular.isDefined(attrs.colorpickerPosition) ? attrs.colorpickerPosition : 'bottom',
271
+ inline = angular.isDefined(attrs.colorpickerInline) ? attrs.colorpickerInline : false,
272
+ fixedPosition = angular.isDefined(attrs.colorpickerFixedPosition) ? attrs.colorpickerFixedPosition : false,
273
+ target = angular.isDefined(attrs.colorpickerParent) ? elem.parent() : angular.element(document.body),
274
+ withInput = angular.isDefined(attrs.colorpickerWithInput) ? attrs.colorpickerWithInput : false,
275
+ componentSize = angular.isDefined(attrs.colorpickerSize) ? attrs.colorpickerSize : 100,
276
+ componentSizePx = componentSize + 'px',
277
+ inputTemplate = withInput ? '<input type="text" name="colorpicker-input" spellcheck="false">' : '',
278
+ closeButton = !inline ? '<button type="button" class="close close-colorpicker">&times;</button>' : '',
279
+ template =
280
+ '<div class="colorpicker dropdown">' +
281
+ '<div class="dropdown-menu">' +
282
+ '<colorpicker-saturation><i></i></colorpicker-saturation>' +
283
+ '<colorpicker-hue><i></i></colorpicker-hue>' +
284
+ '<colorpicker-alpha><i></i></colorpicker-alpha>' +
285
+ '<colorpicker-preview></colorpicker-preview>' +
286
+ inputTemplate +
287
+ closeButton +
288
+ '</div>' +
289
+ '</div>',
290
+ colorpickerTemplate = angular.element(template),
291
+ pickerColor = Color,
292
+ colorpickerValue = {
293
+ h: 1,
294
+ s: 0,
295
+ b: 1,
296
+ a: 1
297
+ },
298
+ sliderAlpha,
299
+ sliderHue = colorpickerTemplate.find('colorpicker-hue'),
300
+ sliderSaturation = colorpickerTemplate.find('colorpicker-saturation'),
301
+ colorpickerPreview = colorpickerTemplate.find('colorpicker-preview'),
302
+ pickerColorPointers = colorpickerTemplate.find('i'),
303
+ componentWidthWithToolbars = parseInt(componentSize) + 29 + (thisFormat === 'rgba' ? 15 : 0),
304
+ componentHeightWithToolbars = parseInt(componentSize) + 55;
305
+
306
+ $compile(colorpickerTemplate)($scope);
307
+ colorpickerTemplate.css('min-width', componentWidthWithToolbars + 'px');
308
+ sliderSaturation.css({
309
+ 'width' : componentSizePx,
310
+ 'height' : componentSizePx
311
+ });
312
+ sliderHue.css('height', componentSizePx);
313
+
314
+ if (withInput) {
315
+ var pickerColorInput = colorpickerTemplate.find('input');
316
+ pickerColorInput.css('width', componentSizePx);
317
+ pickerColorInput
318
+ .on('mousedown', function(event) {
319
+ event.stopPropagation();
320
+ })
321
+ .on('keyup', function() {
322
+ var newColor = this.value;
323
+ elem.val(newColor);
324
+ if (ngModel && ngModel.$modelValue !== newColor) {
325
+ $scope.$apply(ngModel.$setViewValue(newColor));
326
+ update(true);
327
+ }
328
+ });
329
+ }
330
+
331
+ function bindMouseEvents() {
332
+ $document.on('mousemove', mousemove);
333
+ $document.on('mouseup', mouseup);
334
+ }
335
+
336
+ if (thisFormat === 'rgba') {
337
+ colorpickerTemplate.addClass('alpha');
338
+ sliderAlpha = colorpickerTemplate.find('colorpicker-alpha');
339
+ sliderAlpha.css('height', componentSizePx);
340
+ sliderAlpha
341
+ .on('click', function(event) {
342
+ Slider.setAlpha(event, fixedPosition, componentSize);
343
+ mousemove(event);
344
+ })
345
+ .on('mousedown', function(event) {
346
+ Slider.setAlpha(event, fixedPosition, componentSize);
347
+ bindMouseEvents();
348
+ })
349
+ .on('mouseup', function(event){
350
+ emitEvent('colorpicker-selected-alpha');
351
+ });
352
+ }
353
+
354
+ sliderHue
355
+ .on('click', function(event) {
356
+ Slider.setHue(event, fixedPosition, componentSize);
357
+ mousemove(event);
358
+ })
359
+ .on('mousedown', function(event) {
360
+ Slider.setHue(event, fixedPosition, componentSize);
361
+ bindMouseEvents();
362
+ })
363
+ .on('mouseup', function(event){
364
+ emitEvent('colorpicker-selected-hue');
365
+ });
366
+
367
+ sliderSaturation
368
+ .on('click', function(event) {
369
+ Slider.setSaturation(event, fixedPosition, componentSize);
370
+ mousemove(event);
371
+ if (angular.isDefined(attrs.colorpickerCloseOnSelect)) {
372
+ hideColorpickerTemplate();
373
+ }
374
+ })
375
+ .on('mousedown', function(event) {
376
+ Slider.setSaturation(event, fixedPosition, componentSize);
377
+ bindMouseEvents();
378
+ })
379
+ .on('mouseup', function(event){
380
+ emitEvent('colorpicker-selected-saturation');
381
+ });
382
+
383
+ if (fixedPosition) {
384
+ colorpickerTemplate.addClass('colorpicker-fixed-position');
385
+ }
386
+
387
+ colorpickerTemplate.addClass('colorpicker-position-' + position);
388
+ if (inline === 'true') {
389
+ colorpickerTemplate.addClass('colorpicker-inline');
390
+ }
391
+
392
+ target.append(colorpickerTemplate);
393
+
394
+ if (ngModel) {
395
+ ngModel.$render = function () {
396
+ elem.val(ngModel.$viewValue);
397
+
398
+ update();
399
+ };
400
+ }
401
+
402
+ elem.on('blur keyup change', function() {
403
+ update();
404
+ });
405
+
406
+ elem.on('$destroy', function() {
407
+ colorpickerTemplate.remove();
408
+ });
409
+
410
+ function previewColor() {
411
+ try {
412
+ colorpickerPreview.css('backgroundColor', pickerColor[thisFormat]());
413
+ } catch (e) {
414
+ colorpickerPreview.css('backgroundColor', pickerColor.toHex());
415
+ }
416
+ sliderSaturation.css('backgroundColor', pickerColor.toHex(pickerColor.value.h, 1, 1, 1));
417
+ if (thisFormat === 'rgba') {
418
+ sliderAlpha.css.backgroundColor = pickerColor.toHex();
419
+ }
420
+ }
421
+
422
+ function mousemove(event) {
423
+ var
424
+ left = Slider.getLeftPosition(event),
425
+ top = Slider.getTopPosition(event),
426
+ slider = Slider.getSlider();
427
+
428
+ Slider.setKnob(top, left);
429
+
430
+ if (slider.callLeft) {
431
+ pickerColor[slider.callLeft].call(pickerColor, left / componentSize);
432
+ }
433
+ if (slider.callTop) {
434
+ pickerColor[slider.callTop].call(pickerColor, top / componentSize);
435
+ }
436
+ previewColor();
437
+ var newColor = pickerColor[thisFormat]();
438
+ elem.val(newColor);
439
+ if (ngModel) {
440
+ $scope.$apply(ngModel.$setViewValue(newColor));
441
+ }
442
+ if (withInput) {
443
+ pickerColorInput.val(newColor);
444
+ }
445
+ return false;
446
+ }
447
+
448
+ function mouseup() {
449
+ emitEvent('colorpicker-selected');
450
+ $document.off('mousemove', mousemove);
451
+ $document.off('mouseup', mouseup);
452
+ }
453
+
454
+ function update(omitInnerInput) {
455
+ pickerColor.value = colorpickerValue;
456
+ pickerColor.setColor(elem.val());
457
+ if (withInput && !omitInnerInput) {
458
+ pickerColorInput.val(elem.val());
459
+ }
460
+ pickerColorPointers.eq(0).css({
461
+ left: pickerColor.value.s * componentSize + 'px',
462
+ top: componentSize - pickerColor.value.b * componentSize + 'px'
463
+ });
464
+ pickerColorPointers.eq(1).css('top', componentSize * (1 - pickerColor.value.h) + 'px');
465
+ pickerColorPointers.eq(2).css('top', componentSize * (1 - pickerColor.value.a) + 'px');
466
+ colorpickerValue = pickerColor.value;
467
+ previewColor();
468
+ }
469
+
470
+ function getColorpickerTemplatePosition() {
471
+ var
472
+ positionValue,
473
+ positionOffset = Helper.getOffset(elem[0]),
474
+ additionalSpaceBetweenElements = 2;
475
+
476
+ if(angular.isDefined(attrs.colorpickerParent)) {
477
+ positionOffset.left = 0;
478
+ positionOffset.top = 0;
479
+ }
480
+
481
+ if (position === 'top') {
482
+ positionValue = {
483
+ 'top': positionOffset.top - componentHeightWithToolbars - additionalSpaceBetweenElements,
484
+ 'left': positionOffset.left
485
+ };
486
+ } else if (position === 'right') {
487
+ positionValue = {
488
+ 'top': positionOffset.top,
489
+ 'left': positionOffset.left + elem[0].offsetWidth + additionalSpaceBetweenElements
490
+ };
491
+ } else if (position === 'bottom') {
492
+ positionValue = {
493
+ 'top': positionOffset.top + elem[0].offsetHeight + additionalSpaceBetweenElements,
494
+ 'left': positionOffset.left
495
+ };
496
+ } else if (position === 'left') {
497
+ positionValue = {
498
+ 'top': positionOffset.top,
499
+ 'left': positionOffset.left - componentWidthWithToolbars - additionalSpaceBetweenElements
500
+ };
501
+ }
502
+ return {
503
+ 'top': positionValue.top + 'px',
504
+ 'left': positionValue.left + 'px'
505
+ };
506
+ }
507
+
508
+ function documentMousedownHandler() {
509
+ hideColorpickerTemplate();
510
+ }
511
+
512
+ function showColorpickerTemplate() {
513
+
514
+ if (!colorpickerTemplate.hasClass('colorpicker-visible')) {
515
+ update();
516
+ colorpickerTemplate
517
+ .addClass('colorpicker-visible')
518
+ .css(getColorpickerTemplatePosition());
519
+ emitEvent('colorpicker-shown');
520
+
521
+ if (inline === false) {
522
+ // register global mousedown event to hide the colorpicker
523
+ $document.on('mousedown', documentMousedownHandler);
524
+ }
525
+
526
+ if (attrs.colorpickerIsOpen) {
527
+ $scope[attrs.colorpickerIsOpen] = true;
528
+ if (!$scope.$$phase || !$scope.$root.$$phase) {
529
+ $scope.$digest(); //trigger the watcher to fire
530
+ }
531
+ }
532
+ }
533
+ }
534
+
535
+ if (inline === false) {
536
+ elem.on('click', showColorpickerTemplate);
537
+ } else {
538
+ showColorpickerTemplate();
539
+ }
540
+
541
+ colorpickerTemplate.on('mousedown', function (event) {
542
+ event.stopPropagation();
543
+ event.preventDefault();
544
+ });
545
+
546
+ function emitEvent(name) {
547
+ if (ngModel) {
548
+ $scope.$emit(name, {
549
+ name: attrs.ngModel,
550
+ value: ngModel.$modelValue
551
+ });
552
+ }
553
+ }
554
+
555
+ function hideColorpickerTemplate() {
556
+ if (colorpickerTemplate.hasClass('colorpicker-visible')) {
557
+ colorpickerTemplate.removeClass('colorpicker-visible');
558
+ emitEvent('colorpicker-closed');
559
+ // unregister the global mousedown event
560
+ $document.off('mousedown', documentMousedownHandler);
561
+
562
+ if (attrs.colorpickerIsOpen) {
563
+ $scope[attrs.colorpickerIsOpen] = false;
564
+ if (!$scope.$$phase || !$scope.$root.$$phase) {
565
+ $scope.$digest(); //trigger the watcher to fire
566
+ }
567
+ }
568
+ }
569
+ }
570
+
571
+ colorpickerTemplate.find('button').on('click', function () {
572
+ hideColorpickerTemplate();
573
+ });
574
+
575
+ if (attrs.colorpickerIsOpen) {
576
+ $scope.$watch(attrs.colorpickerIsOpen, function(shouldBeOpen) {
577
+
578
+ if (shouldBeOpen === true) {
579
+ showColorpickerTemplate();
580
+ } else if (shouldBeOpen === false) {
581
+ hideColorpickerTemplate();
582
+ }
583
+
584
+ });
585
+ }
586
+ }
587
+ };
588
+ }]);