comparison src/nabble/view/web/util/jscolor/jscolor.js @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:7ecd1a4ef557
1 /**
2 * jscolor, JavaScript Color Picker
3 *
4 * @version 1.3.9
5 * @license GNU Lesser General Public License, http://www.gnu.org/copyleft/lesser.html
6 * @author Jan Odvarko, http://odvarko.cz
7 * @created 2008-06-15
8 * @updated 2011-07-28
9 * @link http://jscolor.com
10 */
11
12
13 var jscolor = {
14
15
16 dir : '', // location of jscolor directory (leave empty to autodetect)
17 bindClass : 'color', // class name
18 binding : true, // automatic binding via <input class="...">
19 preloading : true, // use image preloading?
20
21
22 install : function() {
23 jscolor.addEvent(window, 'load', jscolor.init);
24 },
25
26
27 init : function() {
28 if(jscolor.binding) {
29 jscolor.bind();
30 }
31 if(jscolor.preloading) {
32 jscolor.preload();
33 }
34 },
35
36
37 getDir : function() {
38 if(!jscolor.dir) {
39 var detected = jscolor.detectDir();
40 jscolor.dir = detected!==false ? detected : 'jscolor/';
41 }
42 return jscolor.dir;
43 },
44
45
46 detectDir : function() {
47 var base = location.href;
48
49 var e = document.getElementsByTagName('base');
50 for(var i=0; i<e.length; i+=1) {
51 if(e[i].href) { base = e[i].href; }
52 }
53
54 var e = document.getElementsByTagName('script');
55 for(var i=0; i<e.length; i+=1) {
56 if(e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
57 var src = new jscolor.URI(e[i].src);
58 var srcAbs = src.toAbsolute(base);
59 srcAbs.path = srcAbs.path.replace(/[^\/]+$/, ''); // remove filename
60 srcAbs.query = null;
61 srcAbs.fragment = null;
62 return srcAbs.toString();
63 }
64 }
65 return false;
66 },
67
68
69 bind : function() {
70 var matchClass = new RegExp('(^|\\s)('+jscolor.bindClass+')\\s*(\\{[^}]*\\})?', 'i');
71 var e = document.getElementsByTagName('input');
72 for(var i=0; i<e.length; i+=1) {
73 var m;
74 if(!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
75 var prop = {};
76 if(m[3]) {
77 try {
78 eval('prop='+m[3]);
79 } catch(eInvalidProp) {}
80 }
81 e[i].color = new jscolor.color(e[i], prop);
82 }
83 }
84 },
85
86
87 preload : function() {
88 for(var fn in jscolor.imgRequire) {
89 if(jscolor.imgRequire.hasOwnProperty(fn)) {
90 jscolor.loadImage(fn);
91 }
92 }
93 },
94
95
96 images : {
97 pad : [ 181, 101 ],
98 sld : [ 16, 101 ],
99 cross : [ 15, 15 ],
100 arrow : [ 7, 11 ]
101 },
102
103
104 imgRequire : {},
105 imgLoaded : {},
106
107
108 requireImage : function(filename) {
109 jscolor.imgRequire[filename] = true;
110 },
111
112
113 loadImage : function(filename) {
114 if(!jscolor.imgLoaded[filename]) {
115 jscolor.imgLoaded[filename] = new Image();
116 jscolor.imgLoaded[filename].src = jscolor.getDir()+filename;
117 }
118 },
119
120
121 fetchElement : function(mixed) {
122 return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;
123 },
124
125
126 addEvent : function(el, evnt, func) {
127 if(el.addEventListener) {
128 el.addEventListener(evnt, func, false);
129 } else if(el.attachEvent) {
130 el.attachEvent('on'+evnt, func);
131 }
132 },
133
134
135 fireEvent : function(el, evnt) {
136 if(!el) {
137 return;
138 }
139 if(document.createEvent) {
140 var ev = document.createEvent('HTMLEvents');
141 ev.initEvent(evnt, true, true);
142 el.dispatchEvent(ev);
143 } else if(document.createEventObject) {
144 var ev = document.createEventObject();
145 el.fireEvent('on'+evnt, ev);
146 } else if(el['on'+evnt]) { // alternatively use the traditional event model (IE5)
147 el['on'+evnt]();
148 }
149 },
150
151
152 getElementPos : function(e) {
153 var e1=e, e2=e;
154 var x=0, y=0;
155 if(e1.offsetParent) {
156 do {
157 x += e1.offsetLeft;
158 y += e1.offsetTop;
159 } while(e1 = e1.offsetParent);
160 }
161 while((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
162 x -= e2.scrollLeft;
163 y -= e2.scrollTop;
164 }
165 return [x, y];
166 },
167
168
169 getElementSize : function(e) {
170 return [e.offsetWidth, e.offsetHeight];
171 },
172
173
174 getRelMousePos : function(e) {
175 var x = 0, y = 0;
176 if (!e) { e = window.event; }
177 if (typeof e.offsetX === 'number') {
178 x = e.offsetX;
179 y = e.offsetY;
180 } else if (typeof e.layerX === 'number') {
181 x = e.layerX;
182 y = e.layerY;
183 }
184 return { x: x, y: y };
185 },
186
187
188 getViewPos : function() {
189 if(typeof window.pageYOffset === 'number') {
190 return [window.pageXOffset, window.pageYOffset];
191 } else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
192 return [document.body.scrollLeft, document.body.scrollTop];
193 } else if(document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
194 return [document.documentElement.scrollLeft, document.documentElement.scrollTop];
195 } else {
196 return [0, 0];
197 }
198 },
199
200
201 getViewSize : function() {
202 if(typeof window.innerWidth === 'number') {
203 return [window.innerWidth, window.innerHeight];
204 } else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
205 return [document.body.clientWidth, document.body.clientHeight];
206 } else if(document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
207 return [document.documentElement.clientWidth, document.documentElement.clientHeight];
208 } else {
209 return [0, 0];
210 }
211 },
212
213
214 URI : function(uri) { // See RFC3986
215
216 this.scheme = null;
217 this.authority = null;
218 this.path = '';
219 this.query = null;
220 this.fragment = null;
221
222 this.parse = function(uri) {
223 var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
224 this.scheme = m[3] ? m[2] : null;
225 this.authority = m[5] ? m[6] : null;
226 this.path = m[7];
227 this.query = m[9] ? m[10] : null;
228 this.fragment = m[12] ? m[13] : null;
229 return this;
230 };
231
232 this.toString = function() {
233 var result = '';
234 if(this.scheme !== null) { result = result + this.scheme + ':'; }
235 if(this.authority !== null) { result = result + '//' + this.authority; }
236 if(this.path !== null) { result = result + this.path; }
237 if(this.query !== null) { result = result + '?' + this.query; }
238 if(this.fragment !== null) { result = result + '#' + this.fragment; }
239 return result;
240 };
241
242 this.toAbsolute = function(base) {
243 var base = new jscolor.URI(base);
244 var r = this;
245 var t = new jscolor.URI;
246
247 if(base.scheme === null) { return false; }
248
249 if(r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
250 r.scheme = null;
251 }
252
253 if(r.scheme !== null) {
254 t.scheme = r.scheme;
255 t.authority = r.authority;
256 t.path = removeDotSegments(r.path);
257 t.query = r.query;
258 } else {
259 if(r.authority !== null) {
260 t.authority = r.authority;
261 t.path = removeDotSegments(r.path);
262 t.query = r.query;
263 } else {
264 if(r.path === '') { // TODO: == or === ?
265 t.path = base.path;
266 if(r.query !== null) {
267 t.query = r.query;
268 } else {
269 t.query = base.query;
270 }
271 } else {
272 if(r.path.substr(0,1) === '/') {
273 t.path = removeDotSegments(r.path);
274 } else {
275 if(base.authority !== null && base.path === '') { // TODO: == or === ?
276 t.path = '/'+r.path;
277 } else {
278 t.path = base.path.replace(/[^\/]+$/,'')+r.path;
279 }
280 t.path = removeDotSegments(t.path);
281 }
282 t.query = r.query;
283 }
284 t.authority = base.authority;
285 }
286 t.scheme = base.scheme;
287 }
288 t.fragment = r.fragment;
289
290 return t;
291 };
292
293 function removeDotSegments(path) {
294 var out = '';
295 while(path) {
296 if(path.substr(0,3)==='../' || path.substr(0,2)==='./') {
297 path = path.replace(/^\.+/,'').substr(1);
298 } else if(path.substr(0,3)==='/./' || path==='/.') {
299 path = '/'+path.substr(3);
300 } else if(path.substr(0,4)==='/../' || path==='/..') {
301 path = '/'+path.substr(4);
302 out = out.replace(/\/?[^\/]*$/, '');
303 } else if(path==='.' || path==='..') {
304 path = '';
305 } else {
306 var rm = path.match(/^\/?[^\/]*/)[0];
307 path = path.substr(rm.length);
308 out = out + rm;
309 }
310 }
311 return out;
312 }
313
314 if(uri) {
315 this.parse(uri);
316 }
317
318 },
319
320
321 /*
322 * Usage example:
323 * var myColor = new jscolor.color(myInputElement)
324 */
325
326 color : function(target, prop) {
327
328
329 this.required = true; // refuse empty values?
330 this.adjust = true; // adjust value to uniform notation?
331 this.hash = false; // prefix color with # symbol?
332 this.caps = true; // uppercase?
333 this.slider = true; // show the value/saturation slider?
334 this.valueElement = target; // value holder
335 this.styleElement = target; // where to reflect current color
336 this.hsv = [0, 0, 1]; // read-only 0-6, 0-1, 0-1
337 this.rgb = [1, 1, 1]; // read-only 0-1, 0-1, 0-1
338
339 this.pickerOnfocus = true; // display picker on focus?
340 this.pickerMode = 'HSV'; // HSV | HVS
341 this.pickerPosition = 'bottom'; // left | right | top | bottom
342 this.pickerButtonHeight = 20; // px
343 this.pickerClosable = false;
344 this.pickerCloseText = 'Close';
345 this.pickerButtonColor = 'ButtonText'; // px
346 this.pickerFace = 10; // px
347 this.pickerFaceColor = '#333'; // CSS color
348 this.pickerBorder = 1; // px
349 this.pickerBorderColor = '#777'; // CSS color
350 this.pickerInset = 1; // px
351 this.pickerInsetColor = '#999'; // CSS color
352 this.pickerZIndex = 10000;
353
354
355 for(var p in prop) {
356 if(prop.hasOwnProperty(p)) {
357 this[p] = prop[p];
358 }
359 }
360
361
362 this.hidePicker = function() {
363 if(isPickerOwner()) {
364 removePicker();
365 }
366 };
367
368
369 this.showPicker = function() {
370 if(!isPickerOwner()) {
371 var tp = jscolor.getElementPos(target); // target pos
372 var ts = jscolor.getElementSize(target); // target size
373 var vp = jscolor.getViewPos(); // view pos
374 var vs = jscolor.getViewSize(); // view size
375 var ps = getPickerDims(this); // picker size
376 var a, b, c;
377 switch(this.pickerPosition.toLowerCase()) {
378 case 'left': a=1; b=0; c=-1; break;
379 case 'right':a=1; b=0; c=1; break;
380 case 'top': a=0; b=1; c=-1; break;
381 default: a=0; b=1; c=1; break;
382 }
383 var l = (ts[b]+ps[b])/2;
384 var pp = [ // picker pos
385 -vp[a]+tp[a]+ps[a] > vs[a] ?
386 (-vp[a]+tp[a]+ts[a]/2 > vs[a]/2 && tp[a]+ts[a]-ps[a] >= 0 ? tp[a]+ts[a]-ps[a] : tp[a]) :
387 tp[a],
388 -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?
389 (-vp[b]+tp[b]+ts[b]/2 > vs[b]/2 && tp[b]+ts[b]-l-l*c >= 0 ? tp[b]+ts[b]-l-l*c : tp[b]+ts[b]-l+l*c) :
390 (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)
391 ];
392 drawPicker(pp[a], pp[b]);
393 }
394 };
395
396
397 this.importColor = function() {
398 if(!valueElement) {
399 this.exportColor();
400 } else {
401 if(!this.adjust) {
402 if(!this.fromString(valueElement.value, leaveValue)) {
403 styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
404 styleElement.style.color = styleElement.jscStyle.color;
405 this.exportColor(leaveValue | leaveStyle);
406 }
407 } else if(!this.required && /^\s*$/.test(valueElement.value)) {
408 valueElement.value = '';
409 styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
410 styleElement.style.color = styleElement.jscStyle.color;
411 this.exportColor(leaveValue | leaveStyle);
412
413 } else if(this.fromString(valueElement.value)) {
414 // OK
415 } else {
416 this.exportColor();
417 }
418 }
419 };
420
421
422 this.exportColor = function(flags) {
423 if(!(flags & leaveValue) && valueElement) {
424 var value = this.toString();
425 if(this.caps) { value = value.toUpperCase(); }
426 if(this.hash) { value = '#'+value; }
427 valueElement.value = value;
428 }
429 if(!(flags & leaveStyle) && styleElement) {
430 styleElement.style.backgroundColor =
431 '#'+this.toString();
432 styleElement.style.color =
433 0.213 * this.rgb[0] +
434 0.715 * this.rgb[1] +
435 0.072 * this.rgb[2]
436 < 0.5 ? '#FFF' : '#000';
437 }
438 if(!(flags & leavePad) && isPickerOwner()) {
439 redrawPad();
440 }
441 if(!(flags & leaveSld) && isPickerOwner()) {
442 redrawSld();
443 }
444 };
445
446
447 this.fromHSV = function(h, s, v, flags) { // null = don't change
448 h<0 && (h=0) || h>6 && (h=6);
449 s<0 && (s=0) || s>1 && (s=1);
450 v<0 && (v=0) || v>1 && (v=1);
451 this.rgb = HSV_RGB(
452 h===null ? this.hsv[0] : (this.hsv[0]=h),
453 s===null ? this.hsv[1] : (this.hsv[1]=s),
454 v===null ? this.hsv[2] : (this.hsv[2]=v)
455 );
456 this.exportColor(flags);
457 };
458
459
460 this.fromRGB = function(r, g, b, flags) { // null = don't change
461 r<0 && (r=0) || r>1 && (r=1);
462 g<0 && (g=0) || g>1 && (g=1);
463 b<0 && (b=0) || b>1 && (b=1);
464 var hsv = RGB_HSV(
465 r===null ? this.rgb[0] : (this.rgb[0]=r),
466 g===null ? this.rgb[1] : (this.rgb[1]=g),
467 b===null ? this.rgb[2] : (this.rgb[2]=b)
468 );
469 if(hsv[0] !== null) {
470 this.hsv[0] = hsv[0];
471 }
472 if(hsv[2] !== 0) {
473 this.hsv[1] = hsv[1];
474 }
475 this.hsv[2] = hsv[2];
476 this.exportColor(flags);
477 };
478
479
480 this.fromString = function(hex, flags) {
481 var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
482 if(!m) {
483 return false;
484 } else {
485 if(m[1].length === 6) { // 6-char notation
486 this.fromRGB(
487 parseInt(m[1].substr(0,2),16) / 255,
488 parseInt(m[1].substr(2,2),16) / 255,
489 parseInt(m[1].substr(4,2),16) / 255,
490 flags
491 );
492 } else { // 3-char notation
493 this.fromRGB(
494 parseInt(m[1].charAt(0)+m[1].charAt(0),16) / 255,
495 parseInt(m[1].charAt(1)+m[1].charAt(1),16) / 255,
496 parseInt(m[1].charAt(2)+m[1].charAt(2),16) / 255,
497 flags
498 );
499 }
500 return true;
501 }
502 };
503
504
505 this.toString = function() {
506 return (
507 (0x100 | Math.round(255*this.rgb[0])).toString(16).substr(1) +
508 (0x100 | Math.round(255*this.rgb[1])).toString(16).substr(1) +
509 (0x100 | Math.round(255*this.rgb[2])).toString(16).substr(1)
510 );
511 };
512
513
514 function RGB_HSV(r, g, b) {
515 var n = Math.min(Math.min(r,g),b);
516 var v = Math.max(Math.max(r,g),b);
517 var m = v - n;
518 if(m === 0) { return [ null, 0, v ]; }
519 var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);
520 return [ h===6?0:h, m/v, v ];
521 }
522
523
524 function HSV_RGB(h, s, v) {
525 if(h === null) { return [ v, v, v ]; }
526 var i = Math.floor(h);
527 var f = i%2 ? h-i : 1-(h-i);
528 var m = v * (1 - s);
529 var n = v * (1 - s*f);
530 switch(i) {
531 case 6:
532 case 0: return [v,n,m];
533 case 1: return [n,v,m];
534 case 2: return [m,v,n];
535 case 3: return [m,n,v];
536 case 4: return [n,m,v];
537 case 5: return [v,m,n];
538 }
539 }
540
541
542 function removePicker() {
543 delete jscolor.picker.owner;
544 document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB);
545 }
546
547
548 function drawPicker(x, y) {
549 if(!jscolor.picker) {
550 jscolor.picker = {
551 box : document.createElement('div'),
552 boxB : document.createElement('div'),
553 pad : document.createElement('div'),
554 padB : document.createElement('div'),
555 padM : document.createElement('div'),
556 sld : document.createElement('div'),
557 sldB : document.createElement('div'),
558 sldM : document.createElement('div'),
559 btn : document.createElement('div'),
560 btnS : document.createElement('span'),
561 btnT : document.createTextNode(THIS.pickerCloseText)
562 };
563 for(var i=0,segSize=4; i<jscolor.images.sld[1]; i+=segSize) {
564 var seg = document.createElement('div');
565 seg.style.height = segSize+'px';
566 seg.style.fontSize = '1px';
567 seg.style.lineHeight = '0';
568 jscolor.picker.sld.appendChild(seg);
569 }
570 jscolor.picker.sldB.appendChild(jscolor.picker.sld);
571 jscolor.picker.box.appendChild(jscolor.picker.sldB);
572 jscolor.picker.box.appendChild(jscolor.picker.sldM);
573 jscolor.picker.padB.appendChild(jscolor.picker.pad);
574 jscolor.picker.box.appendChild(jscolor.picker.padB);
575 jscolor.picker.box.appendChild(jscolor.picker.padM);
576 jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
577 jscolor.picker.btn.appendChild(jscolor.picker.btnS);
578 jscolor.picker.box.appendChild(jscolor.picker.btn);
579 jscolor.picker.boxB.appendChild(jscolor.picker.box);
580 }
581
582 var p = jscolor.picker;
583
584 // controls interaction
585 p.box.onmouseup =
586 p.box.onmouseout = function() { target.focus(); };
587 p.box.onmousedown = function() { abortBlur=true; };
588 p.box.onmousemove = function(e) {
589 if (holdPad || holdSld) {
590 holdPad && setPad(e);
591 holdSld && setSld(e);
592 if (document.selection) {
593 document.selection.empty();
594 } else if (window.getSelection) {
595 window.getSelection().removeAllRanges();
596 }
597 }
598 };
599 p.padM.onmouseup =
600 p.padM.onmouseout = function() { if(holdPad) { holdPad=false; jscolor.fireEvent(valueElement,'change'); } };
601 p.padM.onmousedown = function(e) { holdPad=true; setPad(e); };
602 p.sldM.onmouseup =
603 p.sldM.onmouseout = function() { if(holdSld) { holdSld=false; jscolor.fireEvent(valueElement,'change'); } };
604 p.sldM.onmousedown = function(e) { holdSld=true; setSld(e); };
605
606 // picker
607 var dims = getPickerDims(THIS);
608 p.box.style.width = dims[0] + 'px';
609 p.box.style.height = dims[1] + 'px';
610
611 // picker border
612 p.boxB.style.position = 'absolute';
613 p.boxB.style.clear = 'both';
614 p.boxB.style.left = x+'px';
615 p.boxB.style.top = y+'px';
616 p.boxB.style.zIndex = THIS.pickerZIndex;
617 p.boxB.style.border = THIS.pickerBorder+'px solid';
618 p.boxB.style.borderColor = THIS.pickerBorderColor;
619 p.boxB.style.background = THIS.pickerFaceColor;
620 p.boxB.className = 'jscolor';
621
622 // pad image
623 p.pad.style.width = jscolor.images.pad[0]+'px';
624 p.pad.style.height = jscolor.images.pad[1]+'px';
625
626 // pad border
627 p.padB.style.position = 'absolute';
628 p.padB.style.left = THIS.pickerFace+'px';
629 p.padB.style.top = THIS.pickerFace+'px';
630 p.padB.style.border = THIS.pickerInset+'px solid';
631 p.padB.style.borderColor = THIS.pickerInsetColor;
632
633 // pad mouse area
634 p.padM.style.position = 'absolute';
635 p.padM.style.left = '0';
636 p.padM.style.top = '0';
637 p.padM.style.width = THIS.pickerFace + 2*THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
638 p.padM.style.height = p.box.style.height;
639 p.padM.style.cursor = 'crosshair';
640
641 // slider image
642 p.sld.style.overflow = 'hidden';
643 p.sld.style.width = jscolor.images.sld[0]+'px';
644 p.sld.style.height = jscolor.images.sld[1]+'px';
645
646 // slider border
647 p.sldB.style.display = THIS.slider ? 'block' : 'none';
648 p.sldB.style.position = 'absolute';
649 p.sldB.style.right = THIS.pickerFace+'px';
650 p.sldB.style.top = THIS.pickerFace+'px';
651 p.sldB.style.border = THIS.pickerInset+'px solid';
652 p.sldB.style.borderColor = THIS.pickerInsetColor;
653
654 // slider mouse area
655 p.sldM.style.display = THIS.slider ? 'block' : 'none';
656 p.sldM.style.position = 'absolute';
657 p.sldM.style.right = '0';
658 p.sldM.style.top = '0';
659 p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2*THIS.pickerInset + 'px';
660 p.sldM.style.height = p.box.style.height;
661 try {
662 p.sldM.style.cursor = 'pointer';
663 } catch(eOldIE) {
664 p.sldM.style.cursor = 'hand';
665 }
666
667 // "close" button
668 function setBtnBorder() {
669 var insetColors = THIS.pickerInsetColor.split(/\s+/);
670 var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
671 p.btn.style.borderColor = pickerOutsetColor;
672 }
673 p.btn.style.display = THIS.pickerClosable ? 'block' : 'none';
674 p.btn.style.position = 'absolute';
675 p.btn.style.left = THIS.pickerFace + 'px';
676 p.btn.style.bottom = THIS.pickerFace + 'px';
677 p.btn.style.padding = '0 15px';
678 p.btn.style.height = '18px';
679 p.btn.style.border = THIS.pickerInset + 'px solid';
680 setBtnBorder();
681 p.btn.style.color = THIS.pickerButtonColor;
682 p.btn.style.font = '12px sans-serif';
683 p.btn.style.textAlign = 'center';
684 try {
685 p.btn.style.cursor = 'pointer';
686 } catch(eOldIE) {
687 p.btn.style.cursor = 'hand';
688 }
689 p.btn.onmousedown = function () {
690 THIS.hidePicker();
691 };
692 p.btnS.style.lineHeight = p.btn.style.height;
693
694 // load images in optimal order
695 switch(modeID) {
696 case 0: var padImg = 'hs.png'; break;
697 case 1: var padImg = 'hv.png'; break;
698 }
699 p.padM.style.backgroundImage = "url('"+jscolor.getDir()+"cross.gif')";
700 p.padM.style.backgroundRepeat = "no-repeat";
701 p.sldM.style.backgroundImage = "url('"+jscolor.getDir()+"arrow.gif')";
702 p.sldM.style.backgroundRepeat = "no-repeat";
703 p.pad.style.backgroundImage = "url('"+jscolor.getDir()+padImg+"')";
704 p.pad.style.backgroundRepeat = "no-repeat";
705 p.pad.style.backgroundPosition = "0 0";
706
707 // place pointers
708 redrawPad();
709 redrawSld();
710
711 jscolor.picker.owner = THIS;
712 document.getElementsByTagName('body')[0].appendChild(p.boxB);
713 }
714
715
716 function getPickerDims(o) {
717 var dims = [
718 2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[0] +
719 (o.slider ? 2*o.pickerInset + 2*jscolor.images.arrow[0] + jscolor.images.sld[0] : 0),
720 o.pickerClosable ?
721 4*o.pickerInset + 3*o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight :
722 2*o.pickerInset + 2*o.pickerFace + jscolor.images.pad[1]
723 ];
724 return dims;
725 }
726
727
728 function redrawPad() {
729 // redraw the pad pointer
730 switch(modeID) {
731 case 0: var yComponent = 1; break;
732 case 1: var yComponent = 2; break;
733 }
734 var x = Math.round((THIS.hsv[0]/6) * (jscolor.images.pad[0]-1));
735 var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.pad[1]-1));
736 jscolor.picker.padM.style.backgroundPosition =
737 (THIS.pickerFace+THIS.pickerInset+x - Math.floor(jscolor.images.cross[0]/2)) + 'px ' +
738 (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.cross[1]/2)) + 'px';
739
740 // redraw the slider image
741 var seg = jscolor.picker.sld.childNodes;
742
743 switch(modeID) {
744 case 0:
745 var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
746 for(var i=0; i<seg.length; i+=1) {
747 seg[i].style.backgroundColor = 'rgb('+
748 (rgb[0]*(1-i/seg.length)*100)+'%,'+
749 (rgb[1]*(1-i/seg.length)*100)+'%,'+
750 (rgb[2]*(1-i/seg.length)*100)+'%)';
751 }
752 break;
753 case 1:
754 var rgb, s, c = [ THIS.hsv[2], 0, 0 ];
755 var i = Math.floor(THIS.hsv[0]);
756 var f = i%2 ? THIS.hsv[0]-i : 1-(THIS.hsv[0]-i);
757 switch(i) {
758 case 6:
759 case 0: rgb=[0,1,2]; break;
760 case 1: rgb=[1,0,2]; break;
761 case 2: rgb=[2,0,1]; break;
762 case 3: rgb=[2,1,0]; break;
763 case 4: rgb=[1,2,0]; break;
764 case 5: rgb=[0,2,1]; break;
765 }
766 for(var i=0; i<seg.length; i+=1) {
767 s = 1 - 1/(seg.length-1)*i;
768 c[1] = c[0] * (1 - s*f);
769 c[2] = c[0] * (1 - s);
770 seg[i].style.backgroundColor = 'rgb('+
771 (c[rgb[0]]*100)+'%,'+
772 (c[rgb[1]]*100)+'%,'+
773 (c[rgb[2]]*100)+'%)';
774 }
775 break;
776 }
777 }
778
779
780 function redrawSld() {
781 // redraw the slider pointer
782 switch(modeID) {
783 case 0: var yComponent = 2; break;
784 case 1: var yComponent = 1; break;
785 }
786 var y = Math.round((1-THIS.hsv[yComponent]) * (jscolor.images.sld[1]-1));
787 jscolor.picker.sldM.style.backgroundPosition =
788 '0 ' + (THIS.pickerFace+THIS.pickerInset+y - Math.floor(jscolor.images.arrow[1]/2)) + 'px';
789 }
790
791
792 function isPickerOwner() {
793 return jscolor.picker && jscolor.picker.owner === THIS;
794 }
795
796
797 function blurTarget() {
798 if(valueElement === target) {
799 THIS.importColor();
800 }
801 if(THIS.pickerOnfocus) {
802 THIS.hidePicker();
803 }
804 }
805
806
807 function blurValue() {
808 if(valueElement !== target) {
809 THIS.importColor();
810 }
811 }
812
813
814 function setPad(e) {
815 var mpos = jscolor.getRelMousePos(e);
816 var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
817 var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
818 switch(modeID) {
819 case 0: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), 1 - y/(jscolor.images.pad[1]-1), null, leaveSld); break;
820 case 1: THIS.fromHSV(x*(6/(jscolor.images.pad[0]-1)), null, 1 - y/(jscolor.images.pad[1]-1), leaveSld); break;
821 }
822 }
823
824
825 function setSld(e) {
826 var mpos = jscolor.getRelMousePos(e);
827 var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
828 switch(modeID) {
829 case 0: THIS.fromHSV(null, null, 1 - y/(jscolor.images.sld[1]-1), leavePad); break;
830 case 1: THIS.fromHSV(null, 1 - y/(jscolor.images.sld[1]-1), null, leavePad); break;
831 }
832 }
833
834
835 var THIS = this;
836 var modeID = this.pickerMode.toLowerCase()==='hvs' ? 1 : 0;
837 var abortBlur = false;
838 var
839 valueElement = jscolor.fetchElement(this.valueElement),
840 styleElement = jscolor.fetchElement(this.styleElement);
841 var
842 holdPad = false,
843 holdSld = false;
844 var
845 leaveValue = 1<<0,
846 leaveStyle = 1<<1,
847 leavePad = 1<<2,
848 leaveSld = 1<<3;
849
850 // target
851 jscolor.addEvent(target, 'focus', function() {
852 if(THIS.pickerOnfocus) { THIS.showPicker(); }
853 });
854 jscolor.addEvent(target, 'blur', function() {
855 if(!abortBlur) {
856 window.setTimeout(function(){ abortBlur || blurTarget(); abortBlur=false; }, 0);
857 } else {
858 abortBlur = false;
859 }
860 });
861
862 // valueElement
863 if(valueElement) {
864 var updateField = function() {
865 THIS.fromString(valueElement.value, leaveValue);
866 };
867 jscolor.addEvent(valueElement, 'keyup', updateField);
868 jscolor.addEvent(valueElement, 'input', updateField);
869 jscolor.addEvent(valueElement, 'blur', blurValue);
870 valueElement.setAttribute('autocomplete', 'off');
871 }
872
873 // styleElement
874 if(styleElement) {
875 styleElement.jscStyle = {
876 backgroundColor : styleElement.style.backgroundColor,
877 color : styleElement.style.color
878 };
879 }
880
881 // require images
882 switch(modeID) {
883 case 0: jscolor.requireImage('hs.png'); break;
884 case 1: jscolor.requireImage('hv.png'); break;
885 }
886 jscolor.requireImage('cross.gif');
887 jscolor.requireImage('arrow.gif');
888
889 this.importColor();
890 }
891
892 };
893
894
895 jscolor.install();