Best JavaScript code snippet using fast-check-monorepo
jscolor.js
Source:jscolor.js
1/**2 * jscolor - JavaScript Color Picker3 *4 * @link http://jscolor.com5 * @license For open source use: GPLv36 * For commercial use: JSColor Commercial License7 * @author Jan Odvarko8 * @version 2.1.19 *10 * See usage examples at http://jscolor.com/examples/11 */121314"use strict";151617if (!window.jscolor) {1819window.jscolor = (function () { // BEGIN window.jscolor2021var jsc = {222324 register : function () {25 jsc.attachDOMReadyEvent(jsc.jscolor.init);26 jsc.attachEvent(document, 'mousedown', jsc.onDocumentMouseDown);27 jsc.attachEvent(document, 'touchstart', jsc.onDocumentTouchStart);28 jsc.attachEvent(document, 'keyup', jsc.onDocumentKeyUp);29 jsc.attachEvent(window, 'resize', jsc.onWindowResize);30 },313233 tryInstallOnElements : function (elms, className) {34 var matchClass = new RegExp('(^|\\s)(' + className + ')(\\s*(\\{[^}]*\\})|\\s|$)', 'i');3536 for (var i = 0; i < elms.length; i += 1) {37 if (elms[i].type !== undefined && elms[i].type.toLowerCase() == 'color') {38 if (jsc.isColorAttrSupported) {39 // skip inputs of type 'color' if supported by the browser40 continue;41 }42 }4344 if (elms[i].jscolor) {45 // jscolor is already installed on this element46 continue;47 }4849 var m, dataOpts;5051 if (52 (dataOpts = jsc.getDataAttr(elms[i], 'jscolor')) !== null ||53 (elms[i].className && (m = elms[i].className.match(matchClass)))54 ) {55 var targetElm = elms[i];56 var optsStr = null;5758 if (dataOpts !== null) {59 optsStr = dataOpts;60 } else if (m && m[4]) {61 optsStr = m[4];62 }6364 var opts = {};65 if (optsStr) {66 try {67 opts = (new Function ('return (' + optsStr + ')'))();68 } catch(eParseError) {69 jsc.warn('Error parsing jscolor options: ' + eParseError + ':\n' + optsStr);70 }71 }72 targetElm.jscolor = new jsc.jscolor(targetElm, opts);73 }74 }75 },767778 isColorAttrSupported : (function () {79 var elm = document.createElement('input');80 if (elm.setAttribute) {81 elm.setAttribute('type', 'color');82 if (elm.type.toLowerCase() == 'color') {83 return true;84 }85 }86 return false;87 })(),888990 isCanvasSupported : (function () {91 var elm = document.createElement('canvas');92 return !!(elm.getContext && elm.getContext('2d'));93 })(),949596 fetchElement : function (mixed) {97 return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;98 },99100101 isElementType : function (elm, type) {102 return elm.nodeName.toLowerCase() === type.toLowerCase();103 },104105106 getDataAttr : function (el, name) {107 var attrName = 'data-' + name;108 var attrValue = el.getAttribute(attrName);109 if (attrValue !== null) {110 return attrValue;111 }112 return null;113 },114115116 attachEvent : function (el, evnt, func) {117 if (el.addEventListener) {118 el.addEventListener(evnt, func, false);119 } else if (el.attachEvent) {120 el.attachEvent('on' + evnt, func);121 }122 },123124125 detachEvent : function (el, evnt, func) {126 if (el.removeEventListener) {127 el.removeEventListener(evnt, func, false);128 } else if (el.detachEvent) {129 el.detachEvent('on' + evnt, func);130 }131 },132133134 _attachedGroupEvents : {},135136137 attachGroupEvent : function (groupName, el, evnt, func) {138 if (!jsc._attachedGroupEvents.hasOwnProperty(groupName)) {139 jsc._attachedGroupEvents[groupName] = [];140 }141 jsc._attachedGroupEvents[groupName].push([el, evnt, func]);142 jsc.attachEvent(el, evnt, func);143 },144145146 detachGroupEvents : function (groupName) {147 if (jsc._attachedGroupEvents.hasOwnProperty(groupName)) {148 for (var i = 0; i < jsc._attachedGroupEvents[groupName].length; i += 1) {149 var evt = jsc._attachedGroupEvents[groupName][i];150 jsc.detachEvent(evt[0], evt[1], evt[2]);151 }152 delete jsc._attachedGroupEvents[groupName];153 }154 },155156157 attachDOMReadyEvent : function (func) {158 var fired = false;159 var fireOnce = function () {160 if (!fired) {161 fired = true;162 func();163 }164 };165166 if (document.readyState === 'complete') {167 setTimeout(fireOnce, 1); // async168 return;169 }170171 if (document.addEventListener) {172 document.addEventListener('DOMContentLoaded', fireOnce, false);173174 // Fallback175 window.addEventListener('load', fireOnce, false);176177 } else if (document.attachEvent) {178 // IE179 document.attachEvent('onreadystatechange', function () {180 if (document.readyState === 'complete') {181 document.detachEvent('onreadystatechange', arguments.callee);182 fireOnce();183 }184 })185186 // Fallback187 window.attachEvent('onload', fireOnce);188189 // IE7/8190 if (document.documentElement.doScroll && window == window.top) {191 var tryScroll = function () {192 if (!document.body) { return; }193 try {194 document.documentElement.doScroll('left');195 fireOnce();196 } catch (e) {197 setTimeout(tryScroll, 1);198 }199 };200 tryScroll();201 }202 }203 },204205206 warn : function (msg) {207 if (window.console && window.console.warn) {208 window.console.warn(msg);209 }210 },211212213 preventDefault : function (e) {214 if (e.preventDefault) { e.preventDefault(); }215 e.returnValue = false;216 },217218219 captureTarget : function (target) {220 // IE221 if (target.setCapture) {222 jsc._capturedTarget = target;223 jsc._capturedTarget.setCapture();224 }225 },226227228 releaseTarget : function () {229 // IE230 if (jsc._capturedTarget) {231 jsc._capturedTarget.releaseCapture();232 jsc._capturedTarget = null;233 }234 },235236237 fireEvent : function (el, evnt) {238 if (!el) {239 return;240 }241 if (document.createEvent) {242 var ev = document.createEvent('HTMLEvents');243 ev.initEvent(evnt, true, true);244 el.dispatchEvent(ev);245 } else if (document.createEventObject) {246 var ev = document.createEventObject();247 el.fireEvent('on' + evnt, ev);248 } else if (el['on' + evnt]) { // alternatively use the traditional event model249 el['on' + evnt]();250 }251 },252253254 classNameToList : function (className) {255 return className.replace(/^\s+|\s+$/g, '').split(/\s+/);256 },257258259 // The className parameter (str) can only contain a single class name260 hasClass : function (elm, className) {261 if (!className) {262 return false;263 }264 return -1 != (' ' + elm.className.replace(/\s+/g, ' ') + ' ').indexOf(' ' + className + ' ');265 },266267268 // The className parameter (str) can contain multiple class names separated by whitespace269 setClass : function (elm, className) {270 var classList = jsc.classNameToList(className);271 for (var i = 0; i < classList.length; i += 1) {272 if (!jsc.hasClass(elm, classList[i])) {273 elm.className += (elm.className ? ' ' : '') + classList[i];274 }275 }276 },277278279 // The className parameter (str) can contain multiple class names separated by whitespace280 unsetClass : function (elm, className) {281 var classList = jsc.classNameToList(className);282 for (var i = 0; i < classList.length; i += 1) {283 var repl = new RegExp(284 '^\\s*' + classList[i] + '\\s*|' +285 '\\s*' + classList[i] + '\\s*$|' +286 '\\s+' + classList[i] + '(\\s+)',287 'g'288 );289 elm.className = elm.className.replace(repl, '$1');290 }291 },292293294 getStyle : function (elm) {295 return window.getComputedStyle ? window.getComputedStyle(elm) : elm.currentStyle;296 },297298299 setStyle : (function () {300 var helper = document.createElement('div');301 var getSupportedProp = function (names) {302 for (var i = 0; i < names.length; i += 1) {303 if (names[i] in helper.style) {304 return names[i];305 }306 }307 };308 var props = {309 borderRadius: getSupportedProp(['borderRadius', 'MozBorderRadius', 'webkitBorderRadius']),310 boxShadow: getSupportedProp(['boxShadow', 'MozBoxShadow', 'webkitBoxShadow'])311 };312 return function (elm, prop, value) {313 switch (prop.toLowerCase()) {314 case 'opacity':315 var alphaOpacity = Math.round(parseFloat(value) * 100);316 elm.style.opacity = value;317 elm.style.filter = 'alpha(opacity=' + alphaOpacity + ')';318 break;319 default:320 elm.style[props[prop]] = value;321 break;322 }323 };324 })(),325326327 setBorderRadius : function (elm, value) {328 jsc.setStyle(elm, 'borderRadius', value || '0');329 },330331332 setBoxShadow : function (elm, value) {333 jsc.setStyle(elm, 'boxShadow', value || 'none');334 },335336337 getElementPos : function (e, relativeToViewport) {338 var x=0, y=0;339 var rect = e.getBoundingClientRect();340 x = rect.left;341 y = rect.top;342 if (!relativeToViewport) {343 var viewPos = jsc.getViewPos();344 x += viewPos[0];345 y += viewPos[1];346 }347 return [x, y];348 },349350351 getElementSize : function (e) {352 return [e.offsetWidth, e.offsetHeight];353 },354355356 // get pointer's X/Y coordinates relative to viewport357 getAbsPointerPos : function (e) {358 if (!e) { e = window.event; }359 var x = 0, y = 0;360 if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {361 // touch devices362 x = e.changedTouches[0].clientX;363 y = e.changedTouches[0].clientY;364 } else if (typeof e.clientX === 'number') {365 x = e.clientX;366 y = e.clientY;367 }368 return { x: x, y: y };369 },370371372 // get pointer's X/Y coordinates relative to target element373 getRelPointerPos : function (e) {374 if (!e) { e = window.event; }375 var target = e.target || e.srcElement;376 var targetRect = target.getBoundingClientRect();377378 var x = 0, y = 0;379380 var clientX = 0, clientY = 0;381 if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {382 // touch devices383 clientX = e.changedTouches[0].clientX;384 clientY = e.changedTouches[0].clientY;385 } else if (typeof e.clientX === 'number') {386 clientX = e.clientX;387 clientY = e.clientY;388 }389390 x = clientX - targetRect.left;391 y = clientY - targetRect.top;392 return { x: x, y: y };393 },394395396 getViewPos : function () {397 var doc = document.documentElement;398 return [399 (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),400 (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)401 ];402 },403404405 getViewSize : function () {406 var doc = document.documentElement;407 return [408 (window.innerWidth || doc.clientWidth),409 (window.innerHeight || doc.clientHeight),410 ];411 },412413414 setOption : function (option, value) {415 if (typeof this[option] === 'undefined') {416 jsc.warn('Unrecognized option \'' + option + '\'');417 return false;418 }419 this[option] = value;420 },421422423 redrawPosition : function () {424425 if (jsc.picker && jsc.picker.owner) {426 var thisObj = jsc.picker.owner;427428 var tp, vp;429430 if (thisObj.fixed) {431 // Fixed elements are positioned relative to viewport,432 // therefore we can ignore the scroll offset433 tp = jsc.getElementPos(thisObj.targetElement, true); // target pos434 vp = [0, 0]; // view pos435 } else {436 tp = jsc.getElementPos(thisObj.targetElement); // target pos437 vp = jsc.getViewPos(); // view pos438 }439440 var ts = jsc.getElementSize(thisObj.targetElement); // target size441 var vs = jsc.getViewSize(); // view size442 var ps = jsc.getPickerOuterDims(thisObj); // picker size443 var a, b, c;444 switch (thisObj.position.toLowerCase()) {445 case 'left': a=1; b=0; c=-1; break;446 case 'right':a=1; b=0; c=1; break;447 case 'top': a=0; b=1; c=-1; break;448 default: a=0; b=1; c=1; break;449 }450 var l = (ts[b]+ps[b])/2;451452 // compute picker position453 if (!thisObj.smartPosition) {454 var pp = [455 tp[a],456 tp[b]+ts[b]-l+l*c457 ];458 } else {459 var pp = [460 -vp[a]+tp[a]+ps[a] > vs[a] ?461 (-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]) :462 tp[a],463 -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?464 (-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) :465 (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)466 ];467 }468469 var x = pp[a];470 var y = pp[b];471 var positionValue = thisObj.fixed ? 'fixed' : 'absolute';472 var contractShadow =473 (pp[0] + ps[0] > tp[0] || pp[0] < tp[0] + ts[0]) &&474 (pp[1] + ps[1] < tp[1] + ts[1]);475476 jsc._drawPosition(thisObj, x, y, positionValue, contractShadow);477 }478 },479480481 _drawPosition : function (thisObj, x, y, positionValue, contractShadow) {482 var vShadow = contractShadow ? 0 : thisObj.shadowBlur; // px483484 jsc.picker.wrap.style.position = positionValue;485 jsc.picker.wrap.style.left = x + 'px';486 jsc.picker.wrap.style.top = y + 'px';487488 jsc.setBoxShadow(489 jsc.picker.boxS,490 thisObj.shadow ?491 new jsc.BoxShadow(0, vShadow, thisObj.shadowBlur, 0, thisObj.shadowColor) :492 null);493 },494495496 getPickerDims : function (thisObj) {497 var displaySlider = !!jsc.getSliderComponent(thisObj);498 var dims = [499 2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.width +500 (displaySlider ? 2 * thisObj.insetWidth + jsc.getPadToSliderPadding(thisObj) + thisObj.sliderSize : 0),501 2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.height +502 (thisObj.closable ? 2 * thisObj.insetWidth + thisObj.padding + thisObj.buttonHeight : 0)503 ];504 return dims;505 },506507508 getPickerOuterDims : function (thisObj) {509 var dims = jsc.getPickerDims(thisObj);510 return [511 dims[0] + 2 * thisObj.borderWidth,512 dims[1] + 2 * thisObj.borderWidth513 ];514 },515516517 getPadToSliderPadding : function (thisObj) {518 return Math.max(thisObj.padding, 1.5 * (2 * thisObj.pointerBorderWidth + thisObj.pointerThickness));519 },520521522 getPadYComponent : function (thisObj) {523 switch (thisObj.mode.charAt(1).toLowerCase()) {524 case 'v': return 'v'; break;525 }526 return 's';527 },528529530 getSliderComponent : function (thisObj) {531 if (thisObj.mode.length > 2) {532 switch (thisObj.mode.charAt(2).toLowerCase()) {533 case 's': return 's'; break;534 case 'v': return 'v'; break;535 }536 }537 return null;538 },539540541 onDocumentMouseDown : function (e) {542 if (!e) { e = window.event; }543 var target = e.target || e.srcElement;544545 if (target._jscLinkedInstance) {546 if (target._jscLinkedInstance.showOnClick) {547 target._jscLinkedInstance.show();548 }549 } else if (target._jscControlName) {550 jsc.onControlPointerStart(e, target, target._jscControlName, 'mouse');551 } else {552 // Mouse is outside the picker controls -> hide the color picker!553 if (jsc.picker && jsc.picker.owner) {554 jsc.picker.owner.hide();555 }556 }557 },558559560 onDocumentTouchStart : function (e) {561 if (!e) { e = window.event; }562 var target = e.target || e.srcElement;563564 if (target._jscLinkedInstance) {565 if (target._jscLinkedInstance.showOnClick) {566 target._jscLinkedInstance.show();567 }568 } else if (target._jscControlName) {569 jsc.onControlPointerStart(e, target, target._jscControlName, 'touch');570 } else {571 if (jsc.picker && jsc.picker.owner) {572 jsc.picker.owner.hide();573 }574 }575 },576577578 onDocumentKeyUp : function (e) {579 if (!e) { e = window.event; }580581 if (582 (e.code && e.code === 'Enter' || e.keyCode === 13) ||583 (e.code && e.code === 'Escape' || e.keyCode === 27)584 ) {585 if (jsc.picker && jsc.picker.owner) {586 jsc.picker.owner.hide();587 }588 }589 },590591592 onWindowResize : function (e) {593 jsc.redrawPosition();594 },595596597 onParentScroll : function (e) {598 // hide the picker when one of the parent elements is scrolled599 if (jsc.picker && jsc.picker.owner) {600 jsc.picker.owner.hide();601 }602 },603604605 _pointerMoveEvent : {606 mouse: 'mousemove',607 touch: 'touchmove'608 },609 _pointerEndEvent : {610 mouse: 'mouseup',611 touch: 'touchend'612 },613614615 _pointerOrigin : null,616 _capturedTarget : null,617618619 onControlPointerStart : function (e, target, controlName, pointerType) {620 var thisObj = target._jscInstance;621622 jsc.preventDefault(e);623 jsc.captureTarget(target);624625 var registerDragEvents = function (doc, offset) {626 jsc.attachGroupEvent('drag', doc, jsc._pointerMoveEvent[pointerType],627 jsc.onDocumentPointerMove(e, target, controlName, pointerType, offset));628 jsc.attachGroupEvent('drag', doc, jsc._pointerEndEvent[pointerType],629 jsc.onDocumentPointerEnd(e, target, controlName, pointerType));630 };631632 registerDragEvents(document, [0, 0]);633634 if (window.parent && window.frameElement) {635 var rect = window.frameElement.getBoundingClientRect();636 var ofs = [-rect.left, -rect.top];637 registerDragEvents(window.parent.window.document, ofs);638 }639640 var abs = jsc.getAbsPointerPos(e);641 var rel = jsc.getRelPointerPos(e);642 jsc._pointerOrigin = {643 x: abs.x - rel.x,644 y: abs.y - rel.y645 };646647 switch (controlName) {648 case 'pad':649 // if the slider is at the bottom, move it up650 switch (jsc.getSliderComponent(thisObj)) {651 case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break;652 case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break;653 }654 jsc.setPad(thisObj, e, 0, 0);655 break;656657 case 'sld':658 jsc.setSld(thisObj, e, 0);659 break;660 }661662 jsc.dispatchFineChange(thisObj);663 },664665666 onDocumentPointerMove : function (e, target, controlName, pointerType, offset) {667 return function (e) {668 var thisObj = target._jscInstance;669 switch (controlName) {670 case 'pad':671 if (!e) { e = window.event; }672 jsc.setPad(thisObj, e, offset[0], offset[1]);673 jsc.dispatchFineChange(thisObj);674 break;675676 case 'sld':677 if (!e) { e = window.event; }678 jsc.setSld(thisObj, e, offset[1]);679 jsc.dispatchFineChange(thisObj);680 break;681 }682 }683 },684685686 onDocumentPointerEnd : function (e, target, controlName, pointerType) {687 return function (e) {688 var thisObj = target._jscInstance;689 jsc.detachGroupEvents('drag');690 jsc.releaseTarget();691 // Always dispatch changes after detaching outstanding mouse handlers,692 // in case some user interaction will occur in user's onchange callback693 // that would intrude with current mouse events694 jsc.dispatchChange(thisObj);695 };696 },697698699 dispatchChange : function (thisObj) {700 if (thisObj.valueElement) {701 if (jsc.isElementType(thisObj.valueElement, 'input')) {702 jsc.fireEvent(thisObj.valueElement, 'change');703 }704 }705 },706707708 dispatchFineChange : function (thisObj) {709 if (thisObj.onFineChange) {710 var callback;711 if (typeof thisObj.onFineChange === 'string') {712 callback = new Function (thisObj.onFineChange);713 } else {714 callback = thisObj.onFineChange;715 }716 callback.call(thisObj);717 }718 },719720721 setPad : function (thisObj, e, ofsX, ofsY) {722 var pointerAbs = jsc.getAbsPointerPos(e);723 var x = ofsX + pointerAbs.x - jsc._pointerOrigin.x - thisObj.padding - thisObj.insetWidth;724 var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;725726 var xVal = x * (360 / (thisObj.width - 1));727 var yVal = 100 - (y * (100 / (thisObj.height - 1)));728729 switch (jsc.getPadYComponent(thisObj)) {730 case 's': thisObj.fromHSV(xVal, yVal, null, jsc.leaveSld); break;731 case 'v': thisObj.fromHSV(xVal, null, yVal, jsc.leaveSld); break;732 }733 },734735736 setSld : function (thisObj, e, ofsY) {737 var pointerAbs = jsc.getAbsPointerPos(e);738 var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;739740 var yVal = 100 - (y * (100 / (thisObj.height - 1)));741742 switch (jsc.getSliderComponent(thisObj)) {743 case 's': thisObj.fromHSV(null, yVal, null, jsc.leavePad); break;744 case 'v': thisObj.fromHSV(null, null, yVal, jsc.leavePad); break;745 }746 },747748749 _vmlNS : 'jsc_vml_',750 _vmlCSS : 'jsc_vml_css_',751 _vmlReady : false,752753754 initVML : function () {755 if (!jsc._vmlReady) {756 // init VML namespace757 var doc = document;758 if (!doc.namespaces[jsc._vmlNS]) {759 doc.namespaces.add(jsc._vmlNS, 'urn:schemas-microsoft-com:vml');760 }761 if (!doc.styleSheets[jsc._vmlCSS]) {762 var tags = ['shape', 'shapetype', 'group', 'background', 'path', 'formulas', 'handles', 'fill', 'stroke', 'shadow', 'textbox', 'textpath', 'imagedata', 'line', 'polyline', 'curve', 'rect', 'roundrect', 'oval', 'arc', 'image'];763 var ss = doc.createStyleSheet();764 ss.owningElement.id = jsc._vmlCSS;765 for (var i = 0; i < tags.length; i += 1) {766 ss.addRule(jsc._vmlNS + '\\:' + tags[i], 'behavior:url(#default#VML);');767 }768 }769 jsc._vmlReady = true;770 }771 },772773774 createPalette : function () {775776 var paletteObj = {777 elm: null,778 draw: null779 };780781 if (jsc.isCanvasSupported) {782 // Canvas implementation for modern browsers783784 var canvas = document.createElement('canvas');785 var ctx = canvas.getContext('2d');786787 var drawFunc = function (width, height, type) {788 canvas.width = width;789 canvas.height = height;790791 ctx.clearRect(0, 0, canvas.width, canvas.height);792793 var hGrad = ctx.createLinearGradient(0, 0, canvas.width, 0);794 hGrad.addColorStop(0 / 6, '#F00');795 hGrad.addColorStop(1 / 6, '#FF0');796 hGrad.addColorStop(2 / 6, '#0F0');797 hGrad.addColorStop(3 / 6, '#0FF');798 hGrad.addColorStop(4 / 6, '#00F');799 hGrad.addColorStop(5 / 6, '#F0F');800 hGrad.addColorStop(6 / 6, '#F00');801802 ctx.fillStyle = hGrad;803 ctx.fillRect(0, 0, canvas.width, canvas.height);804805 var vGrad = ctx.createLinearGradient(0, 0, 0, canvas.height);806 switch (type.toLowerCase()) {807 case 's':808 vGrad.addColorStop(0, 'rgba(255,255,255,0)');809 vGrad.addColorStop(1, 'rgba(255,255,255,1)');810 break;811 case 'v':812 vGrad.addColorStop(0, 'rgba(0,0,0,0)');813 vGrad.addColorStop(1, 'rgba(0,0,0,1)');814 break;815 }816 ctx.fillStyle = vGrad;817 ctx.fillRect(0, 0, canvas.width, canvas.height);818 };819820 paletteObj.elm = canvas;821 paletteObj.draw = drawFunc;822823 } else {824 // VML fallback for IE 7 and 8825826 jsc.initVML();827828 var vmlContainer = document.createElement('div');829 vmlContainer.style.position = 'relative';830 vmlContainer.style.overflow = 'hidden';831832 var hGrad = document.createElement(jsc._vmlNS + ':fill');833 hGrad.type = 'gradient';834 hGrad.method = 'linear';835 hGrad.angle = '90';836 hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0'837838 var hRect = document.createElement(jsc._vmlNS + ':rect');839 hRect.style.position = 'absolute';840 hRect.style.left = -1 + 'px';841 hRect.style.top = -1 + 'px';842 hRect.stroked = false;843 hRect.appendChild(hGrad);844 vmlContainer.appendChild(hRect);845846 var vGrad = document.createElement(jsc._vmlNS + ':fill');847 vGrad.type = 'gradient';848 vGrad.method = 'linear';849 vGrad.angle = '180';850 vGrad.opacity = '0';851852 var vRect = document.createElement(jsc._vmlNS + ':rect');853 vRect.style.position = 'absolute';854 vRect.style.left = -1 + 'px';855 vRect.style.top = -1 + 'px';856 vRect.stroked = false;857 vRect.appendChild(vGrad);858 vmlContainer.appendChild(vRect);859860 var drawFunc = function (width, height, type) {861 vmlContainer.style.width = width + 'px';862 vmlContainer.style.height = height + 'px';863864 hRect.style.width =865 vRect.style.width =866 (width + 1) + 'px';867 hRect.style.height =868 vRect.style.height =869 (height + 1) + 'px';870871 // Colors must be specified during every redraw, otherwise IE won't display872 // a full gradient during a subsequential redraw873 hGrad.color = '#F00';874 hGrad.color2 = '#F00';875876 switch (type.toLowerCase()) {877 case 's':878 vGrad.color = vGrad.color2 = '#FFF';879 break;880 case 'v':881 vGrad.color = vGrad.color2 = '#000';882 break;883 }884 };885886 paletteObj.elm = vmlContainer;887 paletteObj.draw = drawFunc;888 }889890 return paletteObj;891 },892893894 createSliderGradient : function () {895896 var sliderObj = {897 elm: null,898 draw: null899 };900901 if (jsc.isCanvasSupported) {902 // Canvas implementation for modern browsers903904 var canvas = document.createElement('canvas');905 var ctx = canvas.getContext('2d');906907 var drawFunc = function (width, height, color1, color2) {908 canvas.width = width;909 canvas.height = height;910911 ctx.clearRect(0, 0, canvas.width, canvas.height);912913 var grad = ctx.createLinearGradient(0, 0, 0, canvas.height);914 grad.addColorStop(0, color1);915 grad.addColorStop(1, color2);916917 ctx.fillStyle = grad;918 ctx.fillRect(0, 0, canvas.width, canvas.height);919 };920921 sliderObj.elm = canvas;922 sliderObj.draw = drawFunc;923924 } else {925 // VML fallback for IE 7 and 8926927 jsc.initVML();928929 var vmlContainer = document.createElement('div');930 vmlContainer.style.position = 'relative';931 vmlContainer.style.overflow = 'hidden';932933 var grad = document.createElement(jsc._vmlNS + ':fill');934 grad.type = 'gradient';935 grad.method = 'linear';936 grad.angle = '180';937938 var rect = document.createElement(jsc._vmlNS + ':rect');939 rect.style.position = 'absolute';940 rect.style.left = -1 + 'px';941 rect.style.top = -1 + 'px';942 rect.stroked = false;943 rect.appendChild(grad);944 vmlContainer.appendChild(rect);945946 var drawFunc = function (width, height, color1, color2) {947 vmlContainer.style.width = width + 'px';948 vmlContainer.style.height = height + 'px';949950 rect.style.width = (width + 1) + 'px';951 rect.style.height = (height + 1) + 'px';952953 grad.color = color1;954 grad.color2 = color2;955 };956957 sliderObj.elm = vmlContainer;958 sliderObj.draw = drawFunc;959 }960961 return sliderObj;962 },963964965 leaveValue : 1<<0,966 leaveStyle : 1<<1,967 leavePad : 1<<2,968 leaveSld : 1<<3,969970971 BoxShadow : (function () {972 var BoxShadow = function (hShadow, vShadow, blur, spread, color, inset) {973 this.hShadow = hShadow;974 this.vShadow = vShadow;975 this.blur = blur;976 this.spread = spread;977 this.color = color;978 this.inset = !!inset;979 };980981 BoxShadow.prototype.toString = function () {982 var vals = [983 Math.round(this.hShadow) + 'px',984 Math.round(this.vShadow) + 'px',985 Math.round(this.blur) + 'px',986 Math.round(this.spread) + 'px',987 this.color988 ];989 if (this.inset) {990 vals.push('inset');991 }992 return vals.join(' ');993 };994995 return BoxShadow;996 })(),997998999 //1000 // Usage:1001 // var myColor = new jscolor(<targetElement> [, <options>])1002 //1003 // (you can use both 'new jscolor' and 'new JSColor')1004 //10051006 jscolor : function (targetElement, opts) {10071008 // General options1009 //1010 this.value = null; // initial HEX color. To change it later, use methods fromString(), fromHSV() and fromRGB()1011 this.valueElement = targetElement; // element that will be used to display and input the color code1012 this.styleElement = targetElement; // element that will preview the picked color using CSS backgroundColor1013 this.required = true; // whether the associated text <input> can be left empty1014 this.refine = true; // whether to refine the entered color code (e.g. uppercase it and remove whitespace)1015 this.hash = false; // whether to prefix the HEX color code with # symbol1016 this.uppercase = true; // whether to show the color code in upper case1017 this.onFineChange = null; // called instantly every time the color changes (value can be either a function or a string with javascript code)1018 this.activeClass = 'jscolor-active'; // class to be set to the target element when a picker window is open on it1019 this.overwriteImportant = false; // whether to overwrite colors of styleElement using !important1020 this.minS = 0; // min allowed saturation (0 - 100)1021 this.maxS = 100; // max allowed saturation (0 - 100)1022 this.minV = 0; // min allowed value (brightness) (0 - 100)1023 this.maxV = 100; // max allowed value (brightness) (0 - 100)10241025 // Accessing the picked color1026 //1027 this.hsv = [0, 0, 100]; // read-only [0-360, 0-100, 0-100]1028 this.rgb = [255, 255, 255]; // read-only [0-255, 0-255, 0-255]10291030 // Color Picker options1031 //1032 this.width = 181; // width of color palette (in px)1033 this.height = 101; // height of color palette (in px)1034 this.showOnClick = true; // whether to display the color picker when user clicks on its target element1035 this.mode = 'HSV'; // HSV | HVS | HS | HV - layout of the color picker controls1036 this.position = 'bottom'; // left | right | top | bottom - position relative to the target element1037 this.smartPosition = true; // automatically change picker position when there is not enough space for it1038 this.sliderSize = 16; // px1039 this.crossSize = 8; // px1040 this.closable = false; // whether to display the Close button1041 this.closeText = 'Close';1042 this.buttonColor = '#000000'; // CSS color1043 this.buttonHeight = 18; // px1044 this.padding = 12; // px1045 this.backgroundColor = '#FFFFFF'; // CSS color1046 this.borderWidth = 1; // px1047 this.borderColor = '#BBBBBB'; // CSS color1048 this.borderRadius = 8; // px1049 this.insetWidth = 1; // px1050 this.insetColor = '#BBBBBB'; // CSS color1051 this.shadow = true; // whether to display shadow1052 this.shadowBlur = 15; // px1053 this.shadowColor = 'rgba(0,0,0,0.2)'; // CSS color1054 this.pointerColor = '#4C4C4C'; // px1055 this.pointerBorderColor = '#FFFFFF'; // CSS color1056 this.pointerBorderWidth = 1; // px1057 this.pointerThickness = 2; // px1058 this.zIndex = 1000;1059 this.container = null; // where to append the color picker (BODY element by default)106010611062 // let's process the DEPRECATED jscolor.options property (this will be later removed)1063 if (jsc.jscolor.options) {1064 // let's set custom default options, if specified1065 for (var opt in jsc.jscolor.options) {1066 if (jsc.jscolor.options.hasOwnProperty(opt)) {1067 jsc.setOption.call(this, opt, jsc.jscolor.options[opt]);1068 }1069 }1070 }107110721073 // let's apply configuration presets1074 //1075 var presetsArr = [];10761077 if (opts.preset) {1078 if (typeof opts.preset === 'string') {1079 presetsArr = opts.preset.split(/\s+/);1080 } else if (Array.isArray(opts.preset)) {1081 presetsArr = opts.preset.slice(); // to clone1082 } else {1083 jsc.warn('Unrecognized preset value');1084 }1085 }10861087 // always use the 'default' preset as a baseline1088 presetsArr.push('default');10891090 // let's apply the presets in reverse order, so that should there be any overlapping options,1091 // then the formerly listed preset overrides the latter1092 for (var i = presetsArr.length - 1; i >= 0; i -= 1) {1093 var pres = presetsArr[i];1094 if (!pres) {1095 continue; // preset is empty string1096 }1097 if (!jsc.jscolor.presets.hasOwnProperty(pres)) {1098 jsc.warn('Unknown preset \'' + pres + '\'');1099 continue;1100 }1101 for (var opt in jsc.jscolor.presets[pres]) {1102 if (jsc.jscolor.presets[pres].hasOwnProperty(opt)) {1103 jsc.setOption.call(this, opt, jsc.jscolor.presets[pres][opt]);1104 }1105 }1106 }110711081109 // let's set specific options for this color picker1110 var nonProperties = ['preset']; // these options won't be set as instance properties1111 for (var opt in opts) {1112 if (opts.hasOwnProperty(opt)) {1113 if (nonProperties.indexOf(opt) === -1) {1114 jsc.setOption.call(this, opt, opts[opt]);1115 }1116 }1117 }111811191120 this.hide = function () {1121 if (isPickerOwner()) {1122 detachPicker();1123 }1124 };112511261127 this.show = function () {1128 drawPicker();1129 };113011311132 this.redraw = function () {1133 if (isPickerOwner()) {1134 drawPicker();1135 }1136 };113711381139 this.importColor = function () {1140 if (!this.valueElement) {1141 this.exportColor();1142 } else {1143 if (jsc.isElementType(this.valueElement, 'input')) {1144 if (!this.refine) {1145 if (!this.fromString(this.valueElement.value, jsc.leaveValue)) {1146 if (this.styleElement) {1147 this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;1148 this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;1149 this.styleElement.style.color = this.styleElement._jscOrigStyle.color;1150 }1151 this.exportColor(jsc.leaveValue | jsc.leaveStyle);1152 }1153 } else if (!this.required && /^\s*$/.test(this.valueElement.value)) {1154 this.valueElement.value = '';1155 if (this.styleElement) {1156 this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;1157 this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;1158 this.styleElement.style.color = this.styleElement._jscOrigStyle.color;1159 }1160 this.exportColor(jsc.leaveValue | jsc.leaveStyle);11611162 } else if (this.fromString(this.valueElement.value)) {1163 // managed to import color successfully from the value -> OK, don't do anything1164 } else {1165 this.exportColor();1166 }1167 } else {1168 // not an input element -> doesn't have any value1169 this.exportColor();1170 }1171 }1172 };117311741175 this.exportColor = function (flags) {1176 if (!(flags & jsc.leaveValue) && this.valueElement) {1177 var value = this.toString();1178 if (this.uppercase) { value = value.toUpperCase(); }1179 if (this.hash) { value = '#' + value; }11801181 if (jsc.isElementType(this.valueElement, 'input')) {1182 if (this.valueElement.value !== value) {1183 this.valueElement.value = value;1184 }1185 } else {1186 this.valueElement.innerHTML = value;1187 }1188 }1189 if (!(flags & jsc.leaveStyle)) {1190 if (this.styleElement) {1191 var bgColor = '#' + this.toString();1192 var fgColor = this.isLight() ? '#000' : '#FFF';11931194 this.styleElement.style.backgroundImage = 'none';1195 this.styleElement.style.backgroundColor = bgColor;1196 this.styleElement.style.color = fgColor;11971198 if (this.overwriteImportant) {1199 this.styleElement.setAttribute('style',1200 'background: ' + bgColor + ' !important; ' +1201 'color: ' + fgColor + ' !important;'1202 );1203 }1204 }1205 }1206 if (!(flags & jsc.leavePad) && isPickerOwner()) {1207 redrawPad();1208 }1209 if (!(flags & jsc.leaveSld) && isPickerOwner()) {1210 redrawSld();1211 }1212 };121312141215 // h: 0-3601216 // s: 0-1001217 // v: 0-1001218 //1219 this.fromHSV = function (h, s, v, flags) { // null = don't change1220 if (h !== null) {1221 if (isNaN(h)) { return false; }1222 h = Math.max(0, Math.min(360, h));1223 }1224 if (s !== null) {1225 if (isNaN(s)) { return false; }1226 s = Math.max(0, Math.min(100, this.maxS, s), this.minS);1227 }1228 if (v !== null) {1229 if (isNaN(v)) { return false; }1230 v = Math.max(0, Math.min(100, this.maxV, v), this.minV);1231 }12321233 this.rgb = HSV_RGB(1234 h===null ? this.hsv[0] : (this.hsv[0]=h),1235 s===null ? this.hsv[1] : (this.hsv[1]=s),1236 v===null ? this.hsv[2] : (this.hsv[2]=v)1237 );12381239 this.exportColor(flags);1240 };124112421243 // r: 0-2551244 // g: 0-2551245 // b: 0-2551246 //1247 this.fromRGB = function (r, g, b, flags) { // null = don't change1248 if (r !== null) {1249 if (isNaN(r)) { return false; }1250 r = Math.max(0, Math.min(255, r));1251 }1252 if (g !== null) {1253 if (isNaN(g)) { return false; }1254 g = Math.max(0, Math.min(255, g));1255 }1256 if (b !== null) {1257 if (isNaN(b)) { return false; }1258 b = Math.max(0, Math.min(255, b));1259 }12601261 var hsv = RGB_HSV(1262 r===null ? this.rgb[0] : r,1263 g===null ? this.rgb[1] : g,1264 b===null ? this.rgb[2] : b1265 );1266 if (hsv[0] !== null) {1267 this.hsv[0] = Math.max(0, Math.min(360, hsv[0]));1268 }1269 if (hsv[2] !== 0) {1270 this.hsv[1] = hsv[1]===null ? null : Math.max(0, this.minS, Math.min(100, this.maxS, hsv[1]));1271 }1272 this.hsv[2] = hsv[2]===null ? null : Math.max(0, this.minV, Math.min(100, this.maxV, hsv[2]));12731274 // update RGB according to final HSV, as some values might be trimmed1275 var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);1276 this.rgb[0] = rgb[0];1277 this.rgb[1] = rgb[1];1278 this.rgb[2] = rgb[2];12791280 this.exportColor(flags);1281 };128212831284 this.fromString = function (str, flags) {1285 var m;1286 if (m = str.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i)) {1287 // HEX notation1288 //12891290 if (m[1].length === 6) {1291 // 6-char notation1292 this.fromRGB(1293 parseInt(m[1].substr(0,2),16),1294 parseInt(m[1].substr(2,2),16),1295 parseInt(m[1].substr(4,2),16),1296 flags1297 );1298 } else {1299 // 3-char notation1300 this.fromRGB(1301 parseInt(m[1].charAt(0) + m[1].charAt(0),16),1302 parseInt(m[1].charAt(1) + m[1].charAt(1),16),1303 parseInt(m[1].charAt(2) + m[1].charAt(2),16),1304 flags1305 );1306 }1307 return true;13081309 } else if (m = str.match(/^\W*rgba?\(([^)]*)\)\W*$/i)) {1310 var params = m[1].split(',');1311 var re = /^\s*(\d*)(\.\d+)?\s*$/;1312 var mR, mG, mB;1313 if (1314 params.length >= 3 &&1315 (mR = params[0].match(re)) &&1316 (mG = params[1].match(re)) &&1317 (mB = params[2].match(re))1318 ) {1319 var r = parseFloat((mR[1] || '0') + (mR[2] || ''));1320 var g = parseFloat((mG[1] || '0') + (mG[2] || ''));1321 var b = parseFloat((mB[1] || '0') + (mB[2] || ''));1322 this.fromRGB(r, g, b, flags);1323 return true;1324 }1325 }1326 return false;1327 };132813291330 this.toString = function () {1331 return (1332 (0x100 | Math.round(this.rgb[0])).toString(16).substr(1) +1333 (0x100 | Math.round(this.rgb[1])).toString(16).substr(1) +1334 (0x100 | Math.round(this.rgb[2])).toString(16).substr(1)1335 );1336 };133713381339 this.toHEXString = function () {1340 return '#' + this.toString().toUpperCase();1341 };134213431344 this.toRGBString = function () {1345 return ('rgb(' +1346 Math.round(this.rgb[0]) + ',' +1347 Math.round(this.rgb[1]) + ',' +1348 Math.round(this.rgb[2]) + ')'1349 );1350 };135113521353 this.toGrayscale = function () {1354 return (1355 0.213 * this.rgb[0] +1356 0.715 * this.rgb[1] +1357 0.072 * this.rgb[2]1358 );1359 };136013611362 this.isLight = function () {1363 return this.toGrayscale() > 255 / 2;1364 };136513661367 this._processParentElementsInDOM = function () {1368 if (this._linkedElementsProcessed) { return; }1369 this._linkedElementsProcessed = true;13701371 var elm = this.targetElement;1372 do {1373 // If the target element or one of its parent nodes has fixed position,1374 // then use fixed positioning instead1375 //1376 // Note: In Firefox, getComputedStyle returns null in a hidden iframe,1377 // that's why we need to check if the returned style object is non-empty1378 var currStyle = jsc.getStyle(elm);1379 if (currStyle && currStyle.position.toLowerCase() === 'fixed') {1380 this.fixed = true;1381 }13821383 if (elm !== this.targetElement) {1384 // Ensure to attach onParentScroll only once to each parent element1385 // (multiple targetElements can share the same parent nodes)1386 //1387 // Note: It's not just offsetParents that can be scrollable,1388 // that's why we loop through all parent nodes1389 if (!elm._jscEventsAttached) {1390 jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);1391 elm._jscEventsAttached = true;1392 }1393 }1394 } while ((elm = elm.parentNode) && !jsc.isElementType(elm, 'body'));1395 };139613971398 // r: 0-2551399 // g: 0-2551400 // b: 0-2551401 //1402 // returns: [ 0-360, 0-100, 0-100 ]1403 //1404 function RGB_HSV (r, g, b) {1405 r /= 255;1406 g /= 255;1407 b /= 255;1408 var n = Math.min(Math.min(r,g),b);1409 var v = Math.max(Math.max(r,g),b);1410 var m = v - n;1411 if (m === 0) { return [ null, 0, 100 * v ]; }1412 var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);1413 return [1414 60 * (h===6?0:h),1415 100 * (m/v),1416 100 * v1417 ];1418 }141914201421 // h: 0-3601422 // s: 0-1001423 // v: 0-1001424 //1425 // returns: [ 0-255, 0-255, 0-255 ]1426 //1427 function HSV_RGB (h, s, v) {1428 var u = 255 * (v / 100);14291430 if (h === null) {1431 return [ u, u, u ];1432 }14331434 h /= 60;1435 s /= 100;14361437 var i = Math.floor(h);1438 var f = i%2 ? h-i : 1-(h-i);1439 var m = u * (1 - s);1440 var n = u * (1 - s * f);1441 switch (i) {1442 case 6:1443 case 0: return [u,n,m];1444 case 1: return [n,u,m];1445 case 2: return [m,u,n];1446 case 3: return [m,n,u];1447 case 4: return [n,m,u];1448 case 5: return [u,m,n];1449 }1450 }145114521453 function detachPicker () {1454 jsc.unsetClass(THIS.targetElement, THIS.activeClass);1455 jsc.picker.wrap.parentNode.removeChild(jsc.picker.wrap);1456 delete jsc.picker.owner;1457 }145814591460 function drawPicker () {14611462 // At this point, when drawing the picker, we know what the parent elements are1463 // and we can do all related DOM operations, such as registering events on them1464 // or checking their positioning1465 THIS._processParentElementsInDOM();14661467 if (!jsc.picker) {1468 jsc.picker = {1469 owner: null,1470 wrap : document.createElement('div'),1471 box : document.createElement('div'),1472 boxS : document.createElement('div'), // shadow area1473 boxB : document.createElement('div'), // border1474 pad : document.createElement('div'),1475 padB : document.createElement('div'), // border1476 padM : document.createElement('div'), // mouse/touch area1477 padPal : jsc.createPalette(),1478 cross : document.createElement('div'),1479 crossBY : document.createElement('div'), // border Y1480 crossBX : document.createElement('div'), // border X1481 crossLY : document.createElement('div'), // line Y1482 crossLX : document.createElement('div'), // line X1483 sld : document.createElement('div'),1484 sldB : document.createElement('div'), // border1485 sldM : document.createElement('div'), // mouse/touch area1486 sldGrad : jsc.createSliderGradient(),1487 sldPtrS : document.createElement('div'), // slider pointer spacer1488 sldPtrIB : document.createElement('div'), // slider pointer inner border1489 sldPtrMB : document.createElement('div'), // slider pointer middle border1490 sldPtrOB : document.createElement('div'), // slider pointer outer border1491 btn : document.createElement('div'),1492 btnT : document.createElement('span') // text1493 };14941495 jsc.picker.pad.appendChild(jsc.picker.padPal.elm);1496 jsc.picker.padB.appendChild(jsc.picker.pad);1497 jsc.picker.cross.appendChild(jsc.picker.crossBY);1498 jsc.picker.cross.appendChild(jsc.picker.crossBX);1499 jsc.picker.cross.appendChild(jsc.picker.crossLY);1500 jsc.picker.cross.appendChild(jsc.picker.crossLX);1501 jsc.picker.padB.appendChild(jsc.picker.cross);1502 jsc.picker.box.appendChild(jsc.picker.padB);1503 jsc.picker.box.appendChild(jsc.picker.padM);15041505 jsc.picker.sld.appendChild(jsc.picker.sldGrad.elm);1506 jsc.picker.sldB.appendChild(jsc.picker.sld);1507 jsc.picker.sldB.appendChild(jsc.picker.sldPtrOB);1508 jsc.picker.sldPtrOB.appendChild(jsc.picker.sldPtrMB);1509 jsc.picker.sldPtrMB.appendChild(jsc.picker.sldPtrIB);1510 jsc.picker.sldPtrIB.appendChild(jsc.picker.sldPtrS);1511 jsc.picker.box.appendChild(jsc.picker.sldB);1512 jsc.picker.box.appendChild(jsc.picker.sldM);15131514 jsc.picker.btn.appendChild(jsc.picker.btnT);1515 jsc.picker.box.appendChild(jsc.picker.btn);15161517 jsc.picker.boxB.appendChild(jsc.picker.box);1518 jsc.picker.wrap.appendChild(jsc.picker.boxS);1519 jsc.picker.wrap.appendChild(jsc.picker.boxB);1520 }15211522 var p = jsc.picker;15231524 var displaySlider = !!jsc.getSliderComponent(THIS);1525 var dims = jsc.getPickerDims(THIS);1526 var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);1527 var padToSliderPadding = jsc.getPadToSliderPadding(THIS);1528 var borderRadius = Math.min(1529 THIS.borderRadius,1530 Math.round(THIS.padding * Math.PI)); // px1531 var padCursor = 'crosshair';15321533 // wrap1534 p.wrap.className = 'jscolor-picker-wrap';1535 p.wrap.style.clear = 'both';1536 p.wrap.style.width = (dims[0] + 2 * THIS.borderWidth) + 'px';1537 p.wrap.style.height = (dims[1] + 2 * THIS.borderWidth) + 'px';1538 p.wrap.style.zIndex = THIS.zIndex;15391540 // picker1541 p.box.className = 'jscolor-picker';1542 p.box.style.width = dims[0] + 'px';1543 p.box.style.height = dims[1] + 'px';15441545 // picker shadow1546 p.boxS.className = 'jscolor-picker-shadow';1547 p.boxS.style.position = 'absolute';1548 p.boxS.style.left = '0';1549 p.boxS.style.top = '0';1550 p.boxS.style.width = '100%';1551 p.boxS.style.height = '100%';1552 jsc.setBorderRadius(p.boxS, borderRadius + 'px');15531554 // picker border1555 p.boxB.className = 'jscolor-picker-border';1556 p.boxB.style.position = 'relative';1557 p.boxB.style.border = THIS.borderWidth + 'px solid';1558 p.boxB.style.borderColor = THIS.borderColor;1559 p.boxB.style.background = THIS.backgroundColor;1560 jsc.setBorderRadius(p.boxB, borderRadius + 'px');15611562 // IE hack:1563 // If the element is transparent, IE will trigger the event on the elements under it,1564 // e.g. on Canvas or on elements with border1565 p.padM.style.background =1566 p.sldM.style.background =1567 '#FFF';1568 jsc.setStyle(p.padM, 'opacity', '0');1569 jsc.setStyle(p.sldM, 'opacity', '0');15701571 // pad1572 p.pad.style.position = 'relative';1573 p.pad.style.width = THIS.width + 'px';1574 p.pad.style.height = THIS.height + 'px';15751576 // pad palettes (HSV and HVS)1577 p.padPal.draw(THIS.width, THIS.height, jsc.getPadYComponent(THIS));15781579 // pad border1580 p.padB.style.position = 'absolute';1581 p.padB.style.left = THIS.padding + 'px';1582 p.padB.style.top = THIS.padding + 'px';1583 p.padB.style.border = THIS.insetWidth + 'px solid';1584 p.padB.style.borderColor = THIS.insetColor;15851586 // pad mouse area1587 p.padM._jscInstance = THIS;1588 p.padM._jscControlName = 'pad';1589 p.padM.style.position = 'absolute';1590 p.padM.style.left = '0';1591 p.padM.style.top = '0';1592 p.padM.style.width = (THIS.padding + 2 * THIS.insetWidth + THIS.width + padToSliderPadding / 2) + 'px';1593 p.padM.style.height = dims[1] + 'px';1594 p.padM.style.cursor = padCursor;15951596 // pad cross1597 p.cross.style.position = 'absolute';1598 p.cross.style.left =1599 p.cross.style.top =1600 '0';1601 p.cross.style.width =1602 p.cross.style.height =1603 crossOuterSize + 'px';16041605 // pad cross border Y and X1606 p.crossBY.style.position =1607 p.crossBX.style.position =1608 'absolute';1609 p.crossBY.style.background =1610 p.crossBX.style.background =1611 THIS.pointerBorderColor;1612 p.crossBY.style.width =1613 p.crossBX.style.height =1614 (2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';1615 p.crossBY.style.height =1616 p.crossBX.style.width =1617 crossOuterSize + 'px';1618 p.crossBY.style.left =1619 p.crossBX.style.top =1620 (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2) - THIS.pointerBorderWidth) + 'px';1621 p.crossBY.style.top =1622 p.crossBX.style.left =1623 '0';16241625 // pad cross line Y and X1626 p.crossLY.style.position =1627 p.crossLX.style.position =1628 'absolute';1629 p.crossLY.style.background =1630 p.crossLX.style.background =1631 THIS.pointerColor;1632 p.crossLY.style.height =1633 p.crossLX.style.width =1634 (crossOuterSize - 2 * THIS.pointerBorderWidth) + 'px';1635 p.crossLY.style.width =1636 p.crossLX.style.height =1637 THIS.pointerThickness + 'px';1638 p.crossLY.style.left =1639 p.crossLX.style.top =1640 (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2)) + 'px';1641 p.crossLY.style.top =1642 p.crossLX.style.left =1643 THIS.pointerBorderWidth + 'px';16441645 // slider1646 p.sld.style.overflow = 'hidden';1647 p.sld.style.width = THIS.sliderSize + 'px';1648 p.sld.style.height = THIS.height + 'px';16491650 // slider gradient1651 p.sldGrad.draw(THIS.sliderSize, THIS.height, '#000', '#000');16521653 // slider border1654 p.sldB.style.display = displaySlider ? 'block' : 'none';1655 p.sldB.style.position = 'absolute';1656 p.sldB.style.right = THIS.padding + 'px';1657 p.sldB.style.top = THIS.padding + 'px';1658 p.sldB.style.border = THIS.insetWidth + 'px solid';1659 p.sldB.style.borderColor = THIS.insetColor;16601661 // slider mouse area1662 p.sldM._jscInstance = THIS;1663 p.sldM._jscControlName = 'sld';1664 p.sldM.style.display = displaySlider ? 'block' : 'none';1665 p.sldM.style.position = 'absolute';1666 p.sldM.style.right = '0';1667 p.sldM.style.top = '0';1668 p.sldM.style.width = (THIS.sliderSize + padToSliderPadding / 2 + THIS.padding + 2 * THIS.insetWidth) + 'px';1669 p.sldM.style.height = dims[1] + 'px';1670 p.sldM.style.cursor = 'default';16711672 // slider pointer inner and outer border1673 p.sldPtrIB.style.border =1674 p.sldPtrOB.style.border =1675 THIS.pointerBorderWidth + 'px solid ' + THIS.pointerBorderColor;16761677 // slider pointer outer border1678 p.sldPtrOB.style.position = 'absolute';1679 p.sldPtrOB.style.left = -(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';1680 p.sldPtrOB.style.top = '0';16811682 // slider pointer middle border1683 p.sldPtrMB.style.border = THIS.pointerThickness + 'px solid ' + THIS.pointerColor;16841685 // slider pointer spacer1686 p.sldPtrS.style.width = THIS.sliderSize + 'px';1687 p.sldPtrS.style.height = sliderPtrSpace + 'px';16881689 // the Close button1690 function setBtnBorder () {1691 var insetColors = THIS.insetColor.split(/\s+/);1692 var outsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];1693 p.btn.style.borderColor = outsetColor;1694 }1695 p.btn.className = 'jscolor-btn-close';1696 p.btn.style.display = THIS.closable ? 'block' : 'none';1697 p.btn.style.position = 'absolute';1698 p.btn.style.left = THIS.padding + 'px';1699 p.btn.style.bottom = THIS.padding + 'px';1700 p.btn.style.padding = '0 15px';1701 p.btn.style.height = THIS.buttonHeight + 'px';1702 p.btn.style.border = THIS.insetWidth + 'px solid';1703 setBtnBorder();1704 p.btn.style.color = THIS.buttonColor;1705 p.btn.style.font = '12px sans-serif';1706 p.btn.style.textAlign = 'center';1707 try {1708 p.btn.style.cursor = 'pointer';1709 } catch(eOldIE) {1710 p.btn.style.cursor = 'hand';1711 }1712 p.btn.onmousedown = function () {1713 THIS.hide();1714 };1715 p.btnT.style.lineHeight = THIS.buttonHeight + 'px';1716 p.btnT.innerHTML = '';1717 p.btnT.appendChild(document.createTextNode(THIS.closeText));17181719 // place pointers1720 redrawPad();1721 redrawSld();17221723 // If we are changing the owner without first closing the picker,1724 // make sure to first deal with the old owner1725 if (jsc.picker.owner && jsc.picker.owner !== THIS) {1726 jsc.unsetClass(jsc.picker.owner.targetElement, THIS.activeClass);1727 }17281729 // Set the new picker owner1730 jsc.picker.owner = THIS;17311732 // The redrawPosition() method needs picker.owner to be set, that's why we call it here,1733 // after setting the owner1734 if (jsc.isElementType(container, 'body')) {1735 jsc.redrawPosition();1736 } else {1737 jsc._drawPosition(THIS, 0, 0, 'relative', false);1738 }17391740 if (p.wrap.parentNode != container) {1741 container.appendChild(p.wrap);1742 }17431744 jsc.setClass(THIS.targetElement, THIS.activeClass);1745 }174617471748 function redrawPad () {1749 // redraw the pad pointer1750 switch (jsc.getPadYComponent(THIS)) {1751 case 's': var yComponent = 1; break;1752 case 'v': var yComponent = 2; break;1753 }1754 var x = Math.round((THIS.hsv[0] / 360) * (THIS.width - 1));1755 var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));1756 var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);1757 var ofs = -Math.floor(crossOuterSize / 2);1758 jsc.picker.cross.style.left = (x + ofs) + 'px';1759 jsc.picker.cross.style.top = (y + ofs) + 'px';17601761 // redraw the slider1762 switch (jsc.getSliderComponent(THIS)) {1763 case 's':1764 var rgb1 = HSV_RGB(THIS.hsv[0], 100, THIS.hsv[2]);1765 var rgb2 = HSV_RGB(THIS.hsv[0], 0, THIS.hsv[2]);1766 var color1 = 'rgb(' +1767 Math.round(rgb1[0]) + ',' +1768 Math.round(rgb1[1]) + ',' +1769 Math.round(rgb1[2]) + ')';1770 var color2 = 'rgb(' +1771 Math.round(rgb2[0]) + ',' +1772 Math.round(rgb2[1]) + ',' +1773 Math.round(rgb2[2]) + ')';1774 jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);1775 break;1776 case 'v':1777 var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 100);1778 var color1 = 'rgb(' +1779 Math.round(rgb[0]) + ',' +1780 Math.round(rgb[1]) + ',' +1781 Math.round(rgb[2]) + ')';1782 var color2 = '#000';1783 jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);1784 break;1785 }1786 }178717881789 function redrawSld () {1790 var sldComponent = jsc.getSliderComponent(THIS);1791 if (sldComponent) {1792 // redraw the slider pointer1793 switch (sldComponent) {1794 case 's': var yComponent = 1; break;1795 case 'v': var yComponent = 2; break;1796 }1797 var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));1798 jsc.picker.sldPtrOB.style.top = (y - (2 * THIS.pointerBorderWidth + THIS.pointerThickness) - Math.floor(sliderPtrSpace / 2)) + 'px';1799 }1800 }180118021803 function isPickerOwner () {1804 return jsc.picker && jsc.picker.owner === THIS;1805 }180618071808 function handleValueBlur () {1809 THIS.importColor();1810 }181118121813 // Find the target element1814 if (typeof targetElement === 'string') {1815 var id = targetElement;1816 var elm = document.getElementById(id);1817 if (elm) {1818 this.targetElement = elm;1819 } else {1820 jsc.warn('Could not find target element with ID \'' + id + '\'');1821 }1822 } else if (targetElement) {1823 this.targetElement = targetElement;1824 } else {1825 jsc.warn('Invalid target element: \'' + targetElement + '\'');1826 }18271828 if (this.targetElement._jscLinkedInstance) {1829 jsc.warn('Cannot link jscolor twice to the same element. Skipping.');1830 return;1831 }1832 this.targetElement._jscLinkedInstance = this;18331834 // Find the value element1835 this.valueElement = jsc.fetchElement(this.valueElement);1836 // Find the style element1837 this.styleElement = jsc.fetchElement(this.styleElement);18381839 var THIS = this;1840 var container =1841 this.container ?1842 jsc.fetchElement(this.container) :1843 document.getElementsByTagName('body')[0];1844 var sliderPtrSpace = 3; // px18451846 // For BUTTON elements it's important to stop them from sending the form when clicked1847 // (e.g. in Safari)1848 if (jsc.isElementType(this.targetElement, 'button')) {1849 if (this.targetElement.onclick) {1850 var origCallback = this.targetElement.onclick;1851 this.targetElement.onclick = function (evt) {1852 origCallback.call(this, evt);1853 return false;1854 };1855 } else {1856 this.targetElement.onclick = function () { return false; };1857 }1858 }18591860 /*1861 var elm = this.targetElement;1862 do {1863 // If the target element or one of its offsetParents has fixed position,1864 // then use fixed positioning instead1865 //1866 // Note: In Firefox, getComputedStyle returns null in a hidden iframe,1867 // that's why we need to check if the returned style object is non-empty1868 var currStyle = jsc.getStyle(elm);1869 if (currStyle && currStyle.position.toLowerCase() === 'fixed') {1870 this.fixed = true;1871 }18721873 if (elm !== this.targetElement) {1874 // attach onParentScroll so that we can recompute the picker position1875 // when one of the offsetParents is scrolled1876 if (!elm._jscEventsAttached) {1877 jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);1878 elm._jscEventsAttached = true;1879 }1880 }1881 } while ((elm = elm.offsetParent) && !jsc.isElementType(elm, 'body'));1882 */18831884 // valueElement1885 if (this.valueElement) {1886 if (jsc.isElementType(this.valueElement, 'input')) {1887 var handleValueInput = function () {1888 THIS.fromString(THIS.valueElement.value, jsc.leaveValue);1889 jsc.dispatchFineChange(THIS);1890 };1891 jsc.attachEvent(this.valueElement, 'keyup', handleValueInput);1892 jsc.attachEvent(this.valueElement, 'input', handleValueInput);1893 jsc.attachEvent(this.valueElement, 'blur', handleValueBlur);1894 this.valueElement.setAttribute('autocomplete', 'off');1895 }1896 }18971898 // styleElement1899 if (this.styleElement) {1900 this.styleElement._jscOrigStyle = {1901 backgroundImage : this.styleElement.style.backgroundImage,1902 backgroundColor : this.styleElement.style.backgroundColor,1903 color : this.styleElement.style.color1904 };1905 }19061907 if (this.value) {1908 // Try to set the color from the .value option and if unsuccessful,1909 // export the current color1910 this.fromString(this.value) || this.exportColor();1911 } else {1912 this.importColor();1913 }1914 }19151916};191719181919//================================1920// Public properties and methods1921//================================1922//1923// These will be publicly available via jscolor.<name> and JSColor.<name>1924//192519261927// Initializes jscolor on current DOM tree1928jsc.jscolor.init = function () {1929 if (jsc.jscolor.lookupClass) {1930 jsc.jscolor.installByClassName(jsc.jscolor.lookupClass);1931 }1932};193319341935jsc.jscolor.presets = {};19361937jsc.jscolor.presets['default'] = {}; // baseline for customization19381939jsc.jscolor.presets['light'] = { backgroundColor:'#FFFFFF', insetColor:'#BBBBBB' }; // default color scheme1940jsc.jscolor.presets['dark'] = { backgroundColor:'#333333', insetColor:'#999999' };19411942jsc.jscolor.presets['small'] = { width:101, height:101 };1943jsc.jscolor.presets['medium'] = { width:181, height:101 }; // default size1944jsc.jscolor.presets['large'] = { width:271, height:151 };19451946jsc.jscolor.presets['thin'] = { borderWidth:1, insetWidth:1, pointerBorderWidth:1 }; // default thickness1947jsc.jscolor.presets['thick'] = { borderWidth:2, insetWidth:2, pointerBorderWidth:2 };194819491950// DEPRECATED. Use jscolor.presets.default instead.1951//1952// Custom default options for all color pickers, e.g. { hash: true, width: 300 }1953jsc.jscolor.options = {};195419551956// DEPRECATED. Use data-jscolor attribute instead, which installs jscolor on given element.1957//1958// By default, we'll search for all elements with class="jscolor" and install a color picker on them.1959//1960// You can change what class name will be looked for by setting the property jscolor.lookupClass1961// anywhere in your HTML document. To completely disable the automatic lookup, set it to null.1962//1963jsc.jscolor.lookupClass = 'jscolor';196419651966// DEPRECATED. Use data-jscolor attribute instead, which installs jscolor on given element.1967//1968// Install jscolor on all elements that have the specified class name1969jsc.jscolor.installByClassName = function (className) {1970 var inputElms = document.getElementsByTagName('input');1971 var buttonElms = document.getElementsByTagName('button');19721973 jsc.tryInstallOnElements(inputElms, className);1974 jsc.tryInstallOnElements(buttonElms, className);1975};197619771978jsc.register();197919801981return jsc.jscolor;198219831984})(); // END window.jscolor19851986window.JSColor = window.jscolor; // 'JSColor' is an alias to 'jscolor'1987
...
jscolor.c56e46632a68.js
Source:jscolor.c56e46632a68.js
1/**2 * jscolor - JavaScript Color Picker3 *4 * @link http://jscolor.com5 * @license For open source use: GPLv36 * For commercial use: JSColor Commercial License7 * @author Jan Odvarko8 *9 * See usage examples at http://jscolor.com/examples/10 */111213"use strict";141516if (!window.jscolor) { window.jscolor = (function () {171819var jsc = {202122 register : function () {23 jsc.attachDOMReadyEvent(jsc.init);24 jsc.attachEvent(document, 'mousedown', jsc.onDocumentMouseDown);25 jsc.attachEvent(document, 'touchstart', jsc.onDocumentTouchStart);26 jsc.attachEvent(window, 'resize', jsc.onWindowResize);27 },282930 init : function () {31 if (jsc.jscolor.lookupClass) {32 jsc.jscolor.installByClassName(jsc.jscolor.lookupClass);33 }34 },353637 tryInstallOnElements : function (elms, className) {38 var matchClass = new RegExp('(^|\\s)(' + className + ')(\\s*(\\{[^}]*\\})|\\s|$)', 'i');3940 for (var i = 0; i < elms.length; i += 1) {41 if (elms[i].type !== undefined && elms[i].type.toLowerCase() == 'color') {42 if (jsc.isColorAttrSupported) {43 // skip inputs of type 'color' if supported by the browser44 continue;45 }46 }47 var m;48 if (!elms[i].jscolor && elms[i].className && (m = elms[i].className.match(matchClass))) {49 var targetElm = elms[i];50 var optsStr = null;5152 var dataOptions = jsc.getDataAttr(targetElm, 'jscolor');53 if (dataOptions !== null) {54 optsStr = dataOptions;55 } else if (m[4]) {56 optsStr = m[4];57 }5859 var opts = {};60 if (optsStr) {61 try {62 opts = (new Function ('return (' + optsStr + ')'))();63 } catch(eParseError) {64 jsc.warn('Error parsing jscolor options: ' + eParseError + ':\n' + optsStr);65 }66 }67 targetElm.jscolor = new jsc.jscolor(targetElm, opts);68 }69 }70 },717273 isColorAttrSupported : (function () {74 var elm = document.createElement('input');75 if (elm.setAttribute) {76 elm.setAttribute('type', 'color');77 if (elm.type.toLowerCase() == 'color') {78 return true;79 }80 }81 return false;82 })(),838485 isCanvasSupported : (function () {86 var elm = document.createElement('canvas');87 return !!(elm.getContext && elm.getContext('2d'));88 })(),899091 fetchElement : function (mixed) {92 return typeof mixed === 'string' ? document.getElementById(mixed) : mixed;93 },949596 isElementType : function (elm, type) {97 return elm.nodeName.toLowerCase() === type.toLowerCase();98 },99100101 getDataAttr : function (el, name) {102 var attrName = 'data-' + name;103 var attrValue = el.getAttribute(attrName);104 if (attrValue !== null) {105 return attrValue;106 }107 return null;108 },109110111 attachEvent : function (el, evnt, func) {112 if (el.addEventListener) {113 el.addEventListener(evnt, func, false);114 } else if (el.attachEvent) {115 el.attachEvent('on' + evnt, func);116 }117 },118119120 detachEvent : function (el, evnt, func) {121 if (el.removeEventListener) {122 el.removeEventListener(evnt, func, false);123 } else if (el.detachEvent) {124 el.detachEvent('on' + evnt, func);125 }126 },127128129 _attachedGroupEvents : {},130131132 attachGroupEvent : function (groupName, el, evnt, func) {133 if (!jsc._attachedGroupEvents.hasOwnProperty(groupName)) {134 jsc._attachedGroupEvents[groupName] = [];135 }136 jsc._attachedGroupEvents[groupName].push([el, evnt, func]);137 jsc.attachEvent(el, evnt, func);138 },139140141 detachGroupEvents : function (groupName) {142 if (jsc._attachedGroupEvents.hasOwnProperty(groupName)) {143 for (var i = 0; i < jsc._attachedGroupEvents[groupName].length; i += 1) {144 var evt = jsc._attachedGroupEvents[groupName][i];145 jsc.detachEvent(evt[0], evt[1], evt[2]);146 }147 delete jsc._attachedGroupEvents[groupName];148 }149 },150151152 attachDOMReadyEvent : function (func) {153 var fired = false;154 var fireOnce = function () {155 if (!fired) {156 fired = true;157 func();158 }159 };160161 if (document.readyState === 'complete') {162 setTimeout(fireOnce, 1); // async163 return;164 }165166 if (document.addEventListener) {167 document.addEventListener('DOMContentLoaded', fireOnce, false);168169 // Fallback170 window.addEventListener('load', fireOnce, false);171172 } else if (document.attachEvent) {173 // IE174 document.attachEvent('onreadystatechange', function () {175 if (document.readyState === 'complete') {176 document.detachEvent('onreadystatechange', arguments.callee);177 fireOnce();178 }179 })180181 // Fallback182 window.attachEvent('onload', fireOnce);183184 // IE7/8185 if (document.documentElement.doScroll && window == window.top) {186 var tryScroll = function () {187 if (!document.body) { return; }188 try {189 document.documentElement.doScroll('left');190 fireOnce();191 } catch (e) {192 setTimeout(tryScroll, 1);193 }194 };195 tryScroll();196 }197 }198 },199200201 warn : function (msg) {202 if (window.console && window.console.warn) {203 window.console.warn(msg);204 }205 },206207208 preventDefault : function (e) {209 if (e.preventDefault) { e.preventDefault(); }210 e.returnValue = false;211 },212213214 captureTarget : function (target) {215 // IE216 if (target.setCapture) {217 jsc._capturedTarget = target;218 jsc._capturedTarget.setCapture();219 }220 },221222223 releaseTarget : function () {224 // IE225 if (jsc._capturedTarget) {226 jsc._capturedTarget.releaseCapture();227 jsc._capturedTarget = null;228 }229 },230231232 fireEvent : function (el, evnt) {233 if (!el) {234 return;235 }236 if (document.createEvent) {237 var ev = document.createEvent('HTMLEvents');238 ev.initEvent(evnt, true, true);239 el.dispatchEvent(ev);240 } else if (document.createEventObject) {241 var ev = document.createEventObject();242 el.fireEvent('on' + evnt, ev);243 } else if (el['on' + evnt]) { // alternatively use the traditional event model244 el['on' + evnt]();245 }246 },247248249 classNameToList : function (className) {250 return className.replace(/^\s+|\s+$/g, '').split(/\s+/);251 },252253254 // The className parameter (str) can only contain a single class name255 hasClass : function (elm, className) {256 if (!className) {257 return false;258 }259 return -1 != (' ' + elm.className.replace(/\s+/g, ' ') + ' ').indexOf(' ' + className + ' ');260 },261262263 // The className parameter (str) can contain multiple class names separated by whitespace264 setClass : function (elm, className) {265 var classList = jsc.classNameToList(className);266 for (var i = 0; i < classList.length; i += 1) {267 if (!jsc.hasClass(elm, classList[i])) {268 elm.className += (elm.className ? ' ' : '') + classList[i];269 }270 }271 },272273274 // The className parameter (str) can contain multiple class names separated by whitespace275 unsetClass : function (elm, className) {276 var classList = jsc.classNameToList(className);277 for (var i = 0; i < classList.length; i += 1) {278 var repl = new RegExp(279 '^\\s*' + classList[i] + '\\s*|' +280 '\\s*' + classList[i] + '\\s*$|' +281 '\\s+' + classList[i] + '(\\s+)',282 'g'283 );284 elm.className = elm.className.replace(repl, '$1');285 }286 },287288289 getStyle : function (elm) {290 return window.getComputedStyle ? window.getComputedStyle(elm) : elm.currentStyle;291 },292293294 setStyle : (function () {295 var helper = document.createElement('div');296 var getSupportedProp = function (names) {297 for (var i = 0; i < names.length; i += 1) {298 if (names[i] in helper.style) {299 return names[i];300 }301 }302 };303 var props = {304 borderRadius: getSupportedProp(['borderRadius', 'MozBorderRadius', 'webkitBorderRadius']),305 boxShadow: getSupportedProp(['boxShadow', 'MozBoxShadow', 'webkitBoxShadow'])306 };307 return function (elm, prop, value) {308 switch (prop.toLowerCase()) {309 case 'opacity':310 var alphaOpacity = Math.round(parseFloat(value) * 100);311 elm.style.opacity = value;312 elm.style.filter = 'alpha(opacity=' + alphaOpacity + ')';313 break;314 default:315 elm.style[props[prop]] = value;316 break;317 }318 };319 })(),320321322 setBorderRadius : function (elm, value) {323 jsc.setStyle(elm, 'borderRadius', value || '0');324 },325326327 setBoxShadow : function (elm, value) {328 jsc.setStyle(elm, 'boxShadow', value || 'none');329 },330331332 getElementPos : function (e, relativeToViewport) {333 var x=0, y=0;334 var rect = e.getBoundingClientRect();335 x = rect.left;336 y = rect.top;337 if (!relativeToViewport) {338 var viewPos = jsc.getViewPos();339 x += viewPos[0];340 y += viewPos[1];341 }342 return [x, y];343 },344345346 getElementSize : function (e) {347 return [e.offsetWidth, e.offsetHeight];348 },349350351 // get pointer's X/Y coordinates relative to viewport352 getAbsPointerPos : function (e) {353 if (!e) { e = window.event; }354 var x = 0, y = 0;355 if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {356 // touch devices357 x = e.changedTouches[0].clientX;358 y = e.changedTouches[0].clientY;359 } else if (typeof e.clientX === 'number') {360 x = e.clientX;361 y = e.clientY;362 }363 return { x: x, y: y };364 },365366367 // get pointer's X/Y coordinates relative to target element368 getRelPointerPos : function (e) {369 if (!e) { e = window.event; }370 var target = e.target || e.srcElement;371 var targetRect = target.getBoundingClientRect();372373 var x = 0, y = 0;374375 var clientX = 0, clientY = 0;376 if (typeof e.changedTouches !== 'undefined' && e.changedTouches.length) {377 // touch devices378 clientX = e.changedTouches[0].clientX;379 clientY = e.changedTouches[0].clientY;380 } else if (typeof e.clientX === 'number') {381 clientX = e.clientX;382 clientY = e.clientY;383 }384385 x = clientX - targetRect.left;386 y = clientY - targetRect.top;387 return { x: x, y: y };388 },389390391 getViewPos : function () {392 var doc = document.documentElement;393 return [394 (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0),395 (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)396 ];397 },398399400 getViewSize : function () {401 var doc = document.documentElement;402 return [403 (window.innerWidth || doc.clientWidth),404 (window.innerHeight || doc.clientHeight),405 ];406 },407408409 redrawPosition : function () {410411 if (jsc.picker && jsc.picker.owner) {412 var thisObj = jsc.picker.owner;413414 var tp, vp;415416 if (thisObj.fixed) {417 // Fixed elements are positioned relative to viewport,418 // therefore we can ignore the scroll offset419 tp = jsc.getElementPos(thisObj.targetElement, true); // target pos420 vp = [0, 0]; // view pos421 } else {422 tp = jsc.getElementPos(thisObj.targetElement); // target pos423 vp = jsc.getViewPos(); // view pos424 }425426 var ts = jsc.getElementSize(thisObj.targetElement); // target size427 var vs = jsc.getViewSize(); // view size428 var ps = jsc.getPickerOuterDims(thisObj); // picker size429 var a, b, c;430 switch (thisObj.position.toLowerCase()) {431 case 'left': a=1; b=0; c=-1; break;432 case 'right':a=1; b=0; c=1; break;433 case 'top': a=0; b=1; c=-1; break;434 default: a=0; b=1; c=1; break;435 }436 var l = (ts[b]+ps[b])/2;437438 // compute picker position439 if (!thisObj.smartPosition) {440 var pp = [441 tp[a],442 tp[b]+ts[b]-l+l*c443 ];444 } else {445 var pp = [446 -vp[a]+tp[a]+ps[a] > vs[a] ?447 (-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]) :448 tp[a],449 -vp[b]+tp[b]+ts[b]+ps[b]-l+l*c > vs[b] ?450 (-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) :451 (tp[b]+ts[b]-l+l*c >= 0 ? tp[b]+ts[b]-l+l*c : tp[b]+ts[b]-l-l*c)452 ];453 }454455 var x = pp[a];456 var y = pp[b];457 var positionValue = thisObj.fixed ? 'fixed' : 'absolute';458 var contractShadow =459 (pp[0] + ps[0] > tp[0] || pp[0] < tp[0] + ts[0]) &&460 (pp[1] + ps[1] < tp[1] + ts[1]);461462 jsc._drawPosition(thisObj, x, y, positionValue, contractShadow);463 }464 },465466467 _drawPosition : function (thisObj, x, y, positionValue, contractShadow) {468 var vShadow = contractShadow ? 0 : thisObj.shadowBlur; // px469470 jsc.picker.wrap.style.position = positionValue;471 jsc.picker.wrap.style.left = x + 'px';472 jsc.picker.wrap.style.top = y + 'px';473474 jsc.setBoxShadow(475 jsc.picker.boxS,476 thisObj.shadow ?477 new jsc.BoxShadow(0, vShadow, thisObj.shadowBlur, 0, thisObj.shadowColor) :478 null);479 },480481482 getPickerDims : function (thisObj) {483 var displaySlider = !!jsc.getSliderComponent(thisObj);484 var dims = [485 2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.width +486 (displaySlider ? 2 * thisObj.insetWidth + jsc.getPadToSliderPadding(thisObj) + thisObj.sliderSize : 0),487 2 * thisObj.insetWidth + 2 * thisObj.padding + thisObj.height +488 (thisObj.closable ? 2 * thisObj.insetWidth + thisObj.padding + thisObj.buttonHeight : 0)489 ];490 return dims;491 },492493494 getPickerOuterDims : function (thisObj) {495 var dims = jsc.getPickerDims(thisObj);496 return [497 dims[0] + 2 * thisObj.borderWidth,498 dims[1] + 2 * thisObj.borderWidth499 ];500 },501502503 getPadToSliderPadding : function (thisObj) {504 return Math.max(thisObj.padding, 1.5 * (2 * thisObj.pointerBorderWidth + thisObj.pointerThickness));505 },506507508 getPadYComponent : function (thisObj) {509 switch (thisObj.mode.charAt(1).toLowerCase()) {510 case 'v': return 'v'; break;511 }512 return 's';513 },514515516 getSliderComponent : function (thisObj) {517 if (thisObj.mode.length > 2) {518 switch (thisObj.mode.charAt(2).toLowerCase()) {519 case 's': return 's'; break;520 case 'v': return 'v'; break;521 }522 }523 return null;524 },525526527 onDocumentMouseDown : function (e) {528 if (!e) { e = window.event; }529 var target = e.target || e.srcElement;530531 if (target._jscLinkedInstance) {532 if (target._jscLinkedInstance.showOnClick) {533 target._jscLinkedInstance.show();534 }535 } else if (target._jscControlName) {536 jsc.onControlPointerStart(e, target, target._jscControlName, 'mouse');537 } else {538 // Mouse is outside the picker controls -> hide the color picker!539 if (jsc.picker && jsc.picker.owner) {540 jsc.picker.owner.hide();541 }542 }543 },544545546 onDocumentTouchStart : function (e) {547 if (!e) { e = window.event; }548 var target = e.target || e.srcElement;549550 if (target._jscLinkedInstance) {551 if (target._jscLinkedInstance.showOnClick) {552 target._jscLinkedInstance.show();553 }554 } else if (target._jscControlName) {555 jsc.onControlPointerStart(e, target, target._jscControlName, 'touch');556 } else {557 if (jsc.picker && jsc.picker.owner) {558 jsc.picker.owner.hide();559 }560 }561 },562563564 onWindowResize : function (e) {565 jsc.redrawPosition();566 },567568569 onParentScroll : function (e) {570 // hide the picker when one of the parent elements is scrolled571 if (jsc.picker && jsc.picker.owner) {572 jsc.picker.owner.hide();573 }574 },575576577 _pointerMoveEvent : {578 mouse: 'mousemove',579 touch: 'touchmove'580 },581 _pointerEndEvent : {582 mouse: 'mouseup',583 touch: 'touchend'584 },585586587 _pointerOrigin : null,588 _capturedTarget : null,589590591 onControlPointerStart : function (e, target, controlName, pointerType) {592 var thisObj = target._jscInstance;593594 jsc.preventDefault(e);595 jsc.captureTarget(target);596597 var registerDragEvents = function (doc, offset) {598 jsc.attachGroupEvent('drag', doc, jsc._pointerMoveEvent[pointerType],599 jsc.onDocumentPointerMove(e, target, controlName, pointerType, offset));600 jsc.attachGroupEvent('drag', doc, jsc._pointerEndEvent[pointerType],601 jsc.onDocumentPointerEnd(e, target, controlName, pointerType));602 };603604 registerDragEvents(document, [0, 0]);605606 if (window.parent && window.frameElement) {607 var rect = window.frameElement.getBoundingClientRect();608 var ofs = [-rect.left, -rect.top];609 registerDragEvents(window.parent.window.document, ofs);610 }611612 var abs = jsc.getAbsPointerPos(e);613 var rel = jsc.getRelPointerPos(e);614 jsc._pointerOrigin = {615 x: abs.x - rel.x,616 y: abs.y - rel.y617 };618619 switch (controlName) {620 case 'pad':621 // if the slider is at the bottom, move it up622 switch (jsc.getSliderComponent(thisObj)) {623 case 's': if (thisObj.hsv[1] === 0) { thisObj.fromHSV(null, 100, null); }; break;624 case 'v': if (thisObj.hsv[2] === 0) { thisObj.fromHSV(null, null, 100); }; break;625 }626 jsc.setPad(thisObj, e, 0, 0);627 break;628629 case 'sld':630 jsc.setSld(thisObj, e, 0);631 break;632 }633634 jsc.dispatchFineChange(thisObj);635 },636637638 onDocumentPointerMove : function (e, target, controlName, pointerType, offset) {639 return function (e) {640 var thisObj = target._jscInstance;641 switch (controlName) {642 case 'pad':643 if (!e) { e = window.event; }644 jsc.setPad(thisObj, e, offset[0], offset[1]);645 jsc.dispatchFineChange(thisObj);646 break;647648 case 'sld':649 if (!e) { e = window.event; }650 jsc.setSld(thisObj, e, offset[1]);651 jsc.dispatchFineChange(thisObj);652 break;653 }654 }655 },656657658 onDocumentPointerEnd : function (e, target, controlName, pointerType) {659 return function (e) {660 var thisObj = target._jscInstance;661 jsc.detachGroupEvents('drag');662 jsc.releaseTarget();663 // Always dispatch changes after detaching outstanding mouse handlers,664 // in case some user interaction will occur in user's onchange callback665 // that would intrude with current mouse events666 jsc.dispatchChange(thisObj);667 };668 },669670671 dispatchChange : function (thisObj) {672 if (thisObj.valueElement) {673 if (jsc.isElementType(thisObj.valueElement, 'input')) {674 jsc.fireEvent(thisObj.valueElement, 'change');675 }676 }677 },678679680 dispatchFineChange : function (thisObj) {681 if (thisObj.onFineChange) {682 var callback;683 if (typeof thisObj.onFineChange === 'string') {684 callback = new Function (thisObj.onFineChange);685 } else {686 callback = thisObj.onFineChange;687 }688 callback.call(thisObj);689 }690 },691692693 setPad : function (thisObj, e, ofsX, ofsY) {694 var pointerAbs = jsc.getAbsPointerPos(e);695 var x = ofsX + pointerAbs.x - jsc._pointerOrigin.x - thisObj.padding - thisObj.insetWidth;696 var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;697698 var xVal = x * (360 / (thisObj.width - 1));699 var yVal = 100 - (y * (100 / (thisObj.height - 1)));700701 switch (jsc.getPadYComponent(thisObj)) {702 case 's': thisObj.fromHSV(xVal, yVal, null, jsc.leaveSld); break;703 case 'v': thisObj.fromHSV(xVal, null, yVal, jsc.leaveSld); break;704 }705 },706707708 setSld : function (thisObj, e, ofsY) {709 var pointerAbs = jsc.getAbsPointerPos(e);710 var y = ofsY + pointerAbs.y - jsc._pointerOrigin.y - thisObj.padding - thisObj.insetWidth;711712 var yVal = 100 - (y * (100 / (thisObj.height - 1)));713714 switch (jsc.getSliderComponent(thisObj)) {715 case 's': thisObj.fromHSV(null, yVal, null, jsc.leavePad); break;716 case 'v': thisObj.fromHSV(null, null, yVal, jsc.leavePad); break;717 }718 },719720721 _vmlNS : 'jsc_vml_',722 _vmlCSS : 'jsc_vml_css_',723 _vmlReady : false,724725726 initVML : function () {727 if (!jsc._vmlReady) {728 // init VML namespace729 var doc = document;730 if (!doc.namespaces[jsc._vmlNS]) {731 doc.namespaces.add(jsc._vmlNS, 'urn:schemas-microsoft-com:vml');732 }733 if (!doc.styleSheets[jsc._vmlCSS]) {734 var tags = ['shape', 'shapetype', 'group', 'background', 'path', 'formulas', 'handles', 'fill', 'stroke', 'shadow', 'textbox', 'textpath', 'imagedata', 'line', 'polyline', 'curve', 'rect', 'roundrect', 'oval', 'arc', 'image'];735 var ss = doc.createStyleSheet();736 ss.owningElement.id = jsc._vmlCSS;737 for (var i = 0; i < tags.length; i += 1) {738 ss.addRule(jsc._vmlNS + '\\:' + tags[i], 'behavior:url(#default#VML);');739 }740 }741 jsc._vmlReady = true;742 }743 },744745746 createPalette : function () {747748 var paletteObj = {749 elm: null,750 draw: null751 };752753 if (jsc.isCanvasSupported) {754 // Canvas implementation for modern browsers755756 var canvas = document.createElement('canvas');757 var ctx = canvas.getContext('2d');758759 var drawFunc = function (width, height, type) {760 canvas.width = width;761 canvas.height = height;762763 ctx.clearRect(0, 0, canvas.width, canvas.height);764765 var hGrad = ctx.createLinearGradient(0, 0, canvas.width, 0);766 hGrad.addColorStop(0 / 6, '#F00');767 hGrad.addColorStop(1 / 6, '#FF0');768 hGrad.addColorStop(2 / 6, '#0F0');769 hGrad.addColorStop(3 / 6, '#0FF');770 hGrad.addColorStop(4 / 6, '#00F');771 hGrad.addColorStop(5 / 6, '#F0F');772 hGrad.addColorStop(6 / 6, '#F00');773774 ctx.fillStyle = hGrad;775 ctx.fillRect(0, 0, canvas.width, canvas.height);776777 var vGrad = ctx.createLinearGradient(0, 0, 0, canvas.height);778 switch (type.toLowerCase()) {779 case 's':780 vGrad.addColorStop(0, 'rgba(255,255,255,0)');781 vGrad.addColorStop(1, 'rgba(255,255,255,1)');782 break;783 case 'v':784 vGrad.addColorStop(0, 'rgba(0,0,0,0)');785 vGrad.addColorStop(1, 'rgba(0,0,0,1)');786 break;787 }788 ctx.fillStyle = vGrad;789 ctx.fillRect(0, 0, canvas.width, canvas.height);790 };791792 paletteObj.elm = canvas;793 paletteObj.draw = drawFunc;794795 } else {796 // VML fallback for IE 7 and 8797798 jsc.initVML();799800 var vmlContainer = document.createElement('div');801 vmlContainer.style.position = 'relative';802 vmlContainer.style.overflow = 'hidden';803804 var hGrad = document.createElement(jsc._vmlNS + ':fill');805 hGrad.type = 'gradient';806 hGrad.method = 'linear';807 hGrad.angle = '90';808 hGrad.colors = '16.67% #F0F, 33.33% #00F, 50% #0FF, 66.67% #0F0, 83.33% #FF0'809810 var hRect = document.createElement(jsc._vmlNS + ':rect');811 hRect.style.position = 'absolute';812 hRect.style.left = -1 + 'px';813 hRect.style.top = -1 + 'px';814 hRect.stroked = false;815 hRect.appendChild(hGrad);816 vmlContainer.appendChild(hRect);817818 var vGrad = document.createElement(jsc._vmlNS + ':fill');819 vGrad.type = 'gradient';820 vGrad.method = 'linear';821 vGrad.angle = '180';822 vGrad.opacity = '0';823824 var vRect = document.createElement(jsc._vmlNS + ':rect');825 vRect.style.position = 'absolute';826 vRect.style.left = -1 + 'px';827 vRect.style.top = -1 + 'px';828 vRect.stroked = false;829 vRect.appendChild(vGrad);830 vmlContainer.appendChild(vRect);831832 var drawFunc = function (width, height, type) {833 vmlContainer.style.width = width + 'px';834 vmlContainer.style.height = height + 'px';835836 hRect.style.width =837 vRect.style.width =838 (width + 1) + 'px';839 hRect.style.height =840 vRect.style.height =841 (height + 1) + 'px';842843 // Colors must be specified during every redraw, otherwise IE won't display844 // a full gradient during a subsequential redraw845 hGrad.color = '#F00';846 hGrad.color2 = '#F00';847848 switch (type.toLowerCase()) {849 case 's':850 vGrad.color = vGrad.color2 = '#FFF';851 break;852 case 'v':853 vGrad.color = vGrad.color2 = '#000';854 break;855 }856 };857 858 paletteObj.elm = vmlContainer;859 paletteObj.draw = drawFunc;860 }861862 return paletteObj;863 },864865866 createSliderGradient : function () {867868 var sliderObj = {869 elm: null,870 draw: null871 };872873 if (jsc.isCanvasSupported) {874 // Canvas implementation for modern browsers875876 var canvas = document.createElement('canvas');877 var ctx = canvas.getContext('2d');878879 var drawFunc = function (width, height, color1, color2) {880 canvas.width = width;881 canvas.height = height;882883 ctx.clearRect(0, 0, canvas.width, canvas.height);884885 var grad = ctx.createLinearGradient(0, 0, 0, canvas.height);886 grad.addColorStop(0, color1);887 grad.addColorStop(1, color2);888889 ctx.fillStyle = grad;890 ctx.fillRect(0, 0, canvas.width, canvas.height);891 };892893 sliderObj.elm = canvas;894 sliderObj.draw = drawFunc;895896 } else {897 // VML fallback for IE 7 and 8898899 jsc.initVML();900901 var vmlContainer = document.createElement('div');902 vmlContainer.style.position = 'relative';903 vmlContainer.style.overflow = 'hidden';904905 var grad = document.createElement(jsc._vmlNS + ':fill');906 grad.type = 'gradient';907 grad.method = 'linear';908 grad.angle = '180';909910 var rect = document.createElement(jsc._vmlNS + ':rect');911 rect.style.position = 'absolute';912 rect.style.left = -1 + 'px';913 rect.style.top = -1 + 'px';914 rect.stroked = false;915 rect.appendChild(grad);916 vmlContainer.appendChild(rect);917918 var drawFunc = function (width, height, color1, color2) {919 vmlContainer.style.width = width + 'px';920 vmlContainer.style.height = height + 'px';921922 rect.style.width = (width + 1) + 'px';923 rect.style.height = (height + 1) + 'px';924925 grad.color = color1;926 grad.color2 = color2;927 };928 929 sliderObj.elm = vmlContainer;930 sliderObj.draw = drawFunc;931 }932933 return sliderObj;934 },935936937 leaveValue : 1<<0,938 leaveStyle : 1<<1,939 leavePad : 1<<2,940 leaveSld : 1<<3,941942943 BoxShadow : (function () {944 var BoxShadow = function (hShadow, vShadow, blur, spread, color, inset) {945 this.hShadow = hShadow;946 this.vShadow = vShadow;947 this.blur = blur;948 this.spread = spread;949 this.color = color;950 this.inset = !!inset;951 };952953 BoxShadow.prototype.toString = function () {954 var vals = [955 Math.round(this.hShadow) + 'px',956 Math.round(this.vShadow) + 'px',957 Math.round(this.blur) + 'px',958 Math.round(this.spread) + 'px',959 this.color960 ];961 if (this.inset) {962 vals.push('inset');963 }964 return vals.join(' ');965 };966967 return BoxShadow;968 })(),969970971 //972 // Usage:973 // var myColor = new jscolor(<targetElement> [, <options>])974 //975976 jscolor : function (targetElement, options) {977978 // General options979 //980 this.value = null; // initial HEX color. To change it later, use methods fromString(), fromHSV() and fromRGB()981 this.valueElement = targetElement; // element that will be used to display and input the color code982 this.styleElement = targetElement; // element that will preview the picked color using CSS backgroundColor983 this.required = true; // whether the associated text <input> can be left empty984 this.refine = true; // whether to refine the entered color code (e.g. uppercase it and remove whitespace)985 this.hash = false; // whether to prefix the HEX color code with # symbol986 this.uppercase = true; // whether to uppercase the color code987 this.onFineChange = null; // called instantly every time the color changes (value can be either a function or a string with javascript code)988 this.activeClass = 'jscolor-active'; // class to be set to the target element when a picker window is open on it989 this.minS = 0; // min allowed saturation (0 - 100)990 this.maxS = 100; // max allowed saturation (0 - 100)991 this.minV = 0; // min allowed value (brightness) (0 - 100)992 this.maxV = 100; // max allowed value (brightness) (0 - 100)993994 // Accessing the picked color995 //996 this.hsv = [0, 0, 100]; // read-only [0-360, 0-100, 0-100]997 this.rgb = [255, 255, 255]; // read-only [0-255, 0-255, 0-255]998999 // Color Picker options1000 //1001 this.width = 181; // width of color palette (in px)1002 this.height = 101; // height of color palette (in px)1003 this.showOnClick = true; // whether to display the color picker when user clicks on its target element1004 this.mode = 'HSV'; // HSV | HVS | HS | HV - layout of the color picker controls1005 this.position = 'bottom'; // left | right | top | bottom - position relative to the target element1006 this.smartPosition = true; // automatically change picker position when there is not enough space for it1007 this.sliderSize = 16; // px1008 this.crossSize = 8; // px1009 this.closable = false; // whether to display the Close button1010 this.closeText = 'Close';1011 this.buttonColor = '#000000'; // CSS color1012 this.buttonHeight = 18; // px1013 this.padding = 12; // px1014 this.backgroundColor = '#FFFFFF'; // CSS color1015 this.borderWidth = 1; // px1016 this.borderColor = '#BBBBBB'; // CSS color1017 this.borderRadius = 8; // px1018 this.insetWidth = 1; // px1019 this.insetColor = '#BBBBBB'; // CSS color1020 this.shadow = true; // whether to display shadow1021 this.shadowBlur = 15; // px1022 this.shadowColor = 'rgba(0,0,0,0.2)'; // CSS color1023 this.pointerColor = '#4C4C4C'; // px1024 this.pointerBorderColor = '#FFFFFF'; // px1025 this.pointerBorderWidth = 1; // px1026 this.pointerThickness = 2; // px1027 this.zIndex = 1000;1028 this.container = null; // where to append the color picker (BODY element by default)102910301031 for (var opt in options) {1032 if (options.hasOwnProperty(opt)) {1033 this[opt] = options[opt];1034 }1035 }103610371038 this.hide = function () {1039 if (isPickerOwner()) {1040 detachPicker();1041 }1042 };104310441045 this.show = function () {1046 drawPicker();1047 };104810491050 this.redraw = function () {1051 if (isPickerOwner()) {1052 drawPicker();1053 }1054 };105510561057 this.importColor = function () {1058 if (!this.valueElement) {1059 this.exportColor();1060 } else {1061 if (jsc.isElementType(this.valueElement, 'input')) {1062 if (!this.refine) {1063 if (!this.fromString(this.valueElement.value, jsc.leaveValue)) {1064 if (this.styleElement) {1065 this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;1066 this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;1067 this.styleElement.style.color = this.styleElement._jscOrigStyle.color;1068 }1069 this.exportColor(jsc.leaveValue | jsc.leaveStyle);1070 }1071 } else if (!this.required && /^\s*$/.test(this.valueElement.value)) {1072 this.valueElement.value = '';1073 if (this.styleElement) {1074 this.styleElement.style.backgroundImage = this.styleElement._jscOrigStyle.backgroundImage;1075 this.styleElement.style.backgroundColor = this.styleElement._jscOrigStyle.backgroundColor;1076 this.styleElement.style.color = this.styleElement._jscOrigStyle.color;1077 }1078 this.exportColor(jsc.leaveValue | jsc.leaveStyle);10791080 } else if (this.fromString(this.valueElement.value)) {1081 // managed to import color successfully from the value -> OK, don't do anything1082 } else {1083 this.exportColor();1084 }1085 } else {1086 // not an input element -> doesn't have any value1087 this.exportColor();1088 }1089 }1090 };109110921093 this.exportColor = function (flags) {1094 if (!(flags & jsc.leaveValue) && this.valueElement) {1095 var value = this.toString();1096 if (this.uppercase) { value = value.toUpperCase(); }1097 if (this.hash) { value = '#' + value; }10981099 if (jsc.isElementType(this.valueElement, 'input')) {1100 this.valueElement.value = value;1101 } else {1102 this.valueElement.innerHTML = value;1103 }1104 }1105 if (!(flags & jsc.leaveStyle)) {1106 if (this.styleElement) {1107 this.styleElement.style.backgroundImage = 'none';1108 this.styleElement.style.backgroundColor = '#' + this.toString();1109 this.styleElement.style.color = this.isLight() ? '#000' : '#FFF';1110 }1111 }1112 if (!(flags & jsc.leavePad) && isPickerOwner()) {1113 redrawPad();1114 }1115 if (!(flags & jsc.leaveSld) && isPickerOwner()) {1116 redrawSld();1117 }1118 };111911201121 // h: 0-3601122 // s: 0-1001123 // v: 0-1001124 //1125 this.fromHSV = function (h, s, v, flags) { // null = don't change1126 if (h !== null) {1127 if (isNaN(h)) { return false; }1128 h = Math.max(0, Math.min(360, h));1129 }1130 if (s !== null) {1131 if (isNaN(s)) { return false; }1132 s = Math.max(0, Math.min(100, this.maxS, s), this.minS);1133 }1134 if (v !== null) {1135 if (isNaN(v)) { return false; }1136 v = Math.max(0, Math.min(100, this.maxV, v), this.minV);1137 }11381139 this.rgb = HSV_RGB(1140 h===null ? this.hsv[0] : (this.hsv[0]=h),1141 s===null ? this.hsv[1] : (this.hsv[1]=s),1142 v===null ? this.hsv[2] : (this.hsv[2]=v)1143 );11441145 this.exportColor(flags);1146 };114711481149 // r: 0-2551150 // g: 0-2551151 // b: 0-2551152 //1153 this.fromRGB = function (r, g, b, flags) { // null = don't change1154 if (r !== null) {1155 if (isNaN(r)) { return false; }1156 r = Math.max(0, Math.min(255, r));1157 }1158 if (g !== null) {1159 if (isNaN(g)) { return false; }1160 g = Math.max(0, Math.min(255, g));1161 }1162 if (b !== null) {1163 if (isNaN(b)) { return false; }1164 b = Math.max(0, Math.min(255, b));1165 }11661167 var hsv = RGB_HSV(1168 r===null ? this.rgb[0] : r,1169 g===null ? this.rgb[1] : g,1170 b===null ? this.rgb[2] : b1171 );1172 if (hsv[0] !== null) {1173 this.hsv[0] = Math.max(0, Math.min(360, hsv[0]));1174 }1175 if (hsv[2] !== 0) {1176 this.hsv[1] = hsv[1]===null ? null : Math.max(0, this.minS, Math.min(100, this.maxS, hsv[1]));1177 }1178 this.hsv[2] = hsv[2]===null ? null : Math.max(0, this.minV, Math.min(100, this.maxV, hsv[2]));11791180 // update RGB according to final HSV, as some values might be trimmed1181 var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);1182 this.rgb[0] = rgb[0];1183 this.rgb[1] = rgb[1];1184 this.rgb[2] = rgb[2];11851186 this.exportColor(flags);1187 };118811891190 this.fromString = function (str, flags) {1191 var m;1192 if (m = str.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i)) {1193 // HEX notation1194 //11951196 if (m[1].length === 6) {1197 // 6-char notation1198 this.fromRGB(1199 parseInt(m[1].substr(0,2),16),1200 parseInt(m[1].substr(2,2),16),1201 parseInt(m[1].substr(4,2),16),1202 flags1203 );1204 } else {1205 // 3-char notation1206 this.fromRGB(1207 parseInt(m[1].charAt(0) + m[1].charAt(0),16),1208 parseInt(m[1].charAt(1) + m[1].charAt(1),16),1209 parseInt(m[1].charAt(2) + m[1].charAt(2),16),1210 flags1211 );1212 }1213 return true;12141215 } else if (m = str.match(/^\W*rgba?\(([^)]*)\)\W*$/i)) {1216 var params = m[1].split(',');1217 var re = /^\s*(\d*)(\.\d+)?\s*$/;1218 var mR, mG, mB;1219 if (1220 params.length >= 3 &&1221 (mR = params[0].match(re)) &&1222 (mG = params[1].match(re)) &&1223 (mB = params[2].match(re))1224 ) {1225 var r = parseFloat((mR[1] || '0') + (mR[2] || ''));1226 var g = parseFloat((mG[1] || '0') + (mG[2] || ''));1227 var b = parseFloat((mB[1] || '0') + (mB[2] || ''));1228 this.fromRGB(r, g, b, flags);1229 return true;1230 }1231 }1232 return false;1233 };123412351236 this.toString = function () {1237 return (1238 (0x100 | Math.round(this.rgb[0])).toString(16).substr(1) +1239 (0x100 | Math.round(this.rgb[1])).toString(16).substr(1) +1240 (0x100 | Math.round(this.rgb[2])).toString(16).substr(1)1241 );1242 };124312441245 this.toHEXString = function () {1246 return '#' + this.toString().toUpperCase();1247 };124812491250 this.toRGBString = function () {1251 return ('rgb(' +1252 Math.round(this.rgb[0]) + ',' +1253 Math.round(this.rgb[1]) + ',' +1254 Math.round(this.rgb[2]) + ')'1255 );1256 };125712581259 this.isLight = function () {1260 return (1261 0.213 * this.rgb[0] +1262 0.715 * this.rgb[1] +1263 0.072 * this.rgb[2] >1264 255 / 21265 );1266 };126712681269 this._processParentElementsInDOM = function () {1270 if (this._linkedElementsProcessed) { return; }1271 this._linkedElementsProcessed = true;12721273 var elm = this.targetElement;1274 do {1275 // If the target element or one of its parent nodes has fixed position,1276 // then use fixed positioning instead1277 //1278 // Note: In Firefox, getComputedStyle returns null in a hidden iframe,1279 // that's why we need to check if the returned style object is non-empty1280 var currStyle = jsc.getStyle(elm);1281 if (currStyle && currStyle.position.toLowerCase() === 'fixed') {1282 this.fixed = true;1283 }12841285 if (elm !== this.targetElement) {1286 // Ensure to attach onParentScroll only once to each parent element1287 // (multiple targetElements can share the same parent nodes)1288 //1289 // Note: It's not just offsetParents that can be scrollable,1290 // that's why we loop through all parent nodes1291 if (!elm._jscEventsAttached) {1292 jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);1293 elm._jscEventsAttached = true;1294 }1295 }1296 } while ((elm = elm.parentNode) && !jsc.isElementType(elm, 'body'));1297 };129812991300 // r: 0-2551301 // g: 0-2551302 // b: 0-2551303 //1304 // returns: [ 0-360, 0-100, 0-100 ]1305 //1306 function RGB_HSV (r, g, b) {1307 r /= 255;1308 g /= 255;1309 b /= 255;1310 var n = Math.min(Math.min(r,g),b);1311 var v = Math.max(Math.max(r,g),b);1312 var m = v - n;1313 if (m === 0) { return [ null, 0, 100 * v ]; }1314 var h = r===n ? 3+(b-g)/m : (g===n ? 5+(r-b)/m : 1+(g-r)/m);1315 return [1316 60 * (h===6?0:h),1317 100 * (m/v),1318 100 * v1319 ];1320 }132113221323 // h: 0-3601324 // s: 0-1001325 // v: 0-1001326 //1327 // returns: [ 0-255, 0-255, 0-255 ]1328 //1329 function HSV_RGB (h, s, v) {1330 var u = 255 * (v / 100);13311332 if (h === null) {1333 return [ u, u, u ];1334 }13351336 h /= 60;1337 s /= 100;13381339 var i = Math.floor(h);1340 var f = i%2 ? h-i : 1-(h-i);1341 var m = u * (1 - s);1342 var n = u * (1 - s * f);1343 switch (i) {1344 case 6:1345 case 0: return [u,n,m];1346 case 1: return [n,u,m];1347 case 2: return [m,u,n];1348 case 3: return [m,n,u];1349 case 4: return [n,m,u];1350 case 5: return [u,m,n];1351 }1352 }135313541355 function detachPicker () {1356 jsc.unsetClass(THIS.targetElement, THIS.activeClass);1357 jsc.picker.wrap.parentNode.removeChild(jsc.picker.wrap);1358 delete jsc.picker.owner;1359 }136013611362 function drawPicker () {13631364 // At this point, when drawing the picker, we know what the parent elements are1365 // and we can do all related DOM operations, such as registering events on them1366 // or checking their positioning1367 THIS._processParentElementsInDOM();13681369 if (!jsc.picker) {1370 jsc.picker = {1371 owner: null,1372 wrap : document.createElement('div'),1373 box : document.createElement('div'),1374 boxS : document.createElement('div'), // shadow area1375 boxB : document.createElement('div'), // border1376 pad : document.createElement('div'),1377 padB : document.createElement('div'), // border1378 padM : document.createElement('div'), // mouse/touch area1379 padPal : jsc.createPalette(),1380 cross : document.createElement('div'),1381 crossBY : document.createElement('div'), // border Y1382 crossBX : document.createElement('div'), // border X1383 crossLY : document.createElement('div'), // line Y1384 crossLX : document.createElement('div'), // line X1385 sld : document.createElement('div'),1386 sldB : document.createElement('div'), // border1387 sldM : document.createElement('div'), // mouse/touch area1388 sldGrad : jsc.createSliderGradient(),1389 sldPtrS : document.createElement('div'), // slider pointer spacer1390 sldPtrIB : document.createElement('div'), // slider pointer inner border1391 sldPtrMB : document.createElement('div'), // slider pointer middle border1392 sldPtrOB : document.createElement('div'), // slider pointer outer border1393 btn : document.createElement('div'),1394 btnT : document.createElement('span') // text1395 };13961397 jsc.picker.pad.appendChild(jsc.picker.padPal.elm);1398 jsc.picker.padB.appendChild(jsc.picker.pad);1399 jsc.picker.cross.appendChild(jsc.picker.crossBY);1400 jsc.picker.cross.appendChild(jsc.picker.crossBX);1401 jsc.picker.cross.appendChild(jsc.picker.crossLY);1402 jsc.picker.cross.appendChild(jsc.picker.crossLX);1403 jsc.picker.padB.appendChild(jsc.picker.cross);1404 jsc.picker.box.appendChild(jsc.picker.padB);1405 jsc.picker.box.appendChild(jsc.picker.padM);14061407 jsc.picker.sld.appendChild(jsc.picker.sldGrad.elm);1408 jsc.picker.sldB.appendChild(jsc.picker.sld);1409 jsc.picker.sldB.appendChild(jsc.picker.sldPtrOB);1410 jsc.picker.sldPtrOB.appendChild(jsc.picker.sldPtrMB);1411 jsc.picker.sldPtrMB.appendChild(jsc.picker.sldPtrIB);1412 jsc.picker.sldPtrIB.appendChild(jsc.picker.sldPtrS);1413 jsc.picker.box.appendChild(jsc.picker.sldB);1414 jsc.picker.box.appendChild(jsc.picker.sldM);14151416 jsc.picker.btn.appendChild(jsc.picker.btnT);1417 jsc.picker.box.appendChild(jsc.picker.btn);14181419 jsc.picker.boxB.appendChild(jsc.picker.box);1420 jsc.picker.wrap.appendChild(jsc.picker.boxS);1421 jsc.picker.wrap.appendChild(jsc.picker.boxB);1422 }14231424 var p = jsc.picker;14251426 var displaySlider = !!jsc.getSliderComponent(THIS);1427 var dims = jsc.getPickerDims(THIS);1428 var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);1429 var padToSliderPadding = jsc.getPadToSliderPadding(THIS);1430 var borderRadius = Math.min(1431 THIS.borderRadius,1432 Math.round(THIS.padding * Math.PI)); // px1433 var padCursor = 'crosshair';14341435 // wrap1436 p.wrap.style.clear = 'both';1437 p.wrap.style.width = (dims[0] + 2 * THIS.borderWidth) + 'px';1438 p.wrap.style.height = (dims[1] + 2 * THIS.borderWidth) + 'px';1439 p.wrap.style.zIndex = THIS.zIndex;14401441 // picker1442 p.box.style.width = dims[0] + 'px';1443 p.box.style.height = dims[1] + 'px';14441445 p.boxS.style.position = 'absolute';1446 p.boxS.style.left = '0';1447 p.boxS.style.top = '0';1448 p.boxS.style.width = '100%';1449 p.boxS.style.height = '100%';1450 jsc.setBorderRadius(p.boxS, borderRadius + 'px');14511452 // picker border1453 p.boxB.style.position = 'relative';1454 p.boxB.style.border = THIS.borderWidth + 'px solid';1455 p.boxB.style.borderColor = THIS.borderColor;1456 p.boxB.style.background = THIS.backgroundColor;1457 jsc.setBorderRadius(p.boxB, borderRadius + 'px');14581459 // IE hack:1460 // If the element is transparent, IE will trigger the event on the elements under it,1461 // e.g. on Canvas or on elements with border1462 p.padM.style.background =1463 p.sldM.style.background =1464 '#FFF';1465 jsc.setStyle(p.padM, 'opacity', '0');1466 jsc.setStyle(p.sldM, 'opacity', '0');14671468 // pad1469 p.pad.style.position = 'relative';1470 p.pad.style.width = THIS.width + 'px';1471 p.pad.style.height = THIS.height + 'px';14721473 // pad palettes (HSV and HVS)1474 p.padPal.draw(THIS.width, THIS.height, jsc.getPadYComponent(THIS));14751476 // pad border1477 p.padB.style.position = 'absolute';1478 p.padB.style.left = THIS.padding + 'px';1479 p.padB.style.top = THIS.padding + 'px';1480 p.padB.style.border = THIS.insetWidth + 'px solid';1481 p.padB.style.borderColor = THIS.insetColor;14821483 // pad mouse area1484 p.padM._jscInstance = THIS;1485 p.padM._jscControlName = 'pad';1486 p.padM.style.position = 'absolute';1487 p.padM.style.left = '0';1488 p.padM.style.top = '0';1489 p.padM.style.width = (THIS.padding + 2 * THIS.insetWidth + THIS.width + padToSliderPadding / 2) + 'px';1490 p.padM.style.height = dims[1] + 'px';1491 p.padM.style.cursor = padCursor;14921493 // pad cross1494 p.cross.style.position = 'absolute';1495 p.cross.style.left =1496 p.cross.style.top =1497 '0';1498 p.cross.style.width =1499 p.cross.style.height =1500 crossOuterSize + 'px';15011502 // pad cross border Y and X1503 p.crossBY.style.position =1504 p.crossBX.style.position =1505 'absolute';1506 p.crossBY.style.background =1507 p.crossBX.style.background =1508 THIS.pointerBorderColor;1509 p.crossBY.style.width =1510 p.crossBX.style.height =1511 (2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';1512 p.crossBY.style.height =1513 p.crossBX.style.width =1514 crossOuterSize + 'px';1515 p.crossBY.style.left =1516 p.crossBX.style.top =1517 (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2) - THIS.pointerBorderWidth) + 'px';1518 p.crossBY.style.top =1519 p.crossBX.style.left =1520 '0';15211522 // pad cross line Y and X1523 p.crossLY.style.position =1524 p.crossLX.style.position =1525 'absolute';1526 p.crossLY.style.background =1527 p.crossLX.style.background =1528 THIS.pointerColor;1529 p.crossLY.style.height =1530 p.crossLX.style.width =1531 (crossOuterSize - 2 * THIS.pointerBorderWidth) + 'px';1532 p.crossLY.style.width =1533 p.crossLX.style.height =1534 THIS.pointerThickness + 'px';1535 p.crossLY.style.left =1536 p.crossLX.style.top =1537 (Math.floor(crossOuterSize / 2) - Math.floor(THIS.pointerThickness / 2)) + 'px';1538 p.crossLY.style.top =1539 p.crossLX.style.left =1540 THIS.pointerBorderWidth + 'px';15411542 // slider1543 p.sld.style.overflow = 'hidden';1544 p.sld.style.width = THIS.sliderSize + 'px';1545 p.sld.style.height = THIS.height + 'px';15461547 // slider gradient1548 p.sldGrad.draw(THIS.sliderSize, THIS.height, '#000', '#000');15491550 // slider border1551 p.sldB.style.display = displaySlider ? 'block' : 'none';1552 p.sldB.style.position = 'absolute';1553 p.sldB.style.right = THIS.padding + 'px';1554 p.sldB.style.top = THIS.padding + 'px';1555 p.sldB.style.border = THIS.insetWidth + 'px solid';1556 p.sldB.style.borderColor = THIS.insetColor;15571558 // slider mouse area1559 p.sldM._jscInstance = THIS;1560 p.sldM._jscControlName = 'sld';1561 p.sldM.style.display = displaySlider ? 'block' : 'none';1562 p.sldM.style.position = 'absolute';1563 p.sldM.style.right = '0';1564 p.sldM.style.top = '0';1565 p.sldM.style.width = (THIS.sliderSize + padToSliderPadding / 2 + THIS.padding + 2 * THIS.insetWidth) + 'px';1566 p.sldM.style.height = dims[1] + 'px';1567 p.sldM.style.cursor = 'default';15681569 // slider pointer inner and outer border1570 p.sldPtrIB.style.border =1571 p.sldPtrOB.style.border =1572 THIS.pointerBorderWidth + 'px solid ' + THIS.pointerBorderColor;15731574 // slider pointer outer border1575 p.sldPtrOB.style.position = 'absolute';1576 p.sldPtrOB.style.left = -(2 * THIS.pointerBorderWidth + THIS.pointerThickness) + 'px';1577 p.sldPtrOB.style.top = '0';15781579 // slider pointer middle border1580 p.sldPtrMB.style.border = THIS.pointerThickness + 'px solid ' + THIS.pointerColor;15811582 // slider pointer spacer1583 p.sldPtrS.style.width = THIS.sliderSize + 'px';1584 p.sldPtrS.style.height = sliderPtrSpace + 'px';15851586 // the Close button1587 function setBtnBorder () {1588 var insetColors = THIS.insetColor.split(/\s+/);1589 var outsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];1590 p.btn.style.borderColor = outsetColor;1591 }1592 p.btn.style.display = THIS.closable ? 'block' : 'none';1593 p.btn.style.position = 'absolute';1594 p.btn.style.left = THIS.padding + 'px';1595 p.btn.style.bottom = THIS.padding + 'px';1596 p.btn.style.padding = '0 15px';1597 p.btn.style.height = THIS.buttonHeight + 'px';1598 p.btn.style.border = THIS.insetWidth + 'px solid';1599 setBtnBorder();1600 p.btn.style.color = THIS.buttonColor;1601 p.btn.style.font = '12px sans-serif';1602 p.btn.style.textAlign = 'center';1603 try {1604 p.btn.style.cursor = 'pointer';1605 } catch(eOldIE) {1606 p.btn.style.cursor = 'hand';1607 }1608 p.btn.onmousedown = function () {1609 THIS.hide();1610 };1611 p.btnT.style.lineHeight = THIS.buttonHeight + 'px';1612 p.btnT.innerHTML = '';1613 p.btnT.appendChild(document.createTextNode(THIS.closeText));16141615 // place pointers1616 redrawPad();1617 redrawSld();16181619 // If we are changing the owner without first closing the picker,1620 // make sure to first deal with the old owner1621 if (jsc.picker.owner && jsc.picker.owner !== THIS) {1622 jsc.unsetClass(jsc.picker.owner.targetElement, THIS.activeClass);1623 }16241625 // Set the new picker owner1626 jsc.picker.owner = THIS;16271628 // The redrawPosition() method needs picker.owner to be set, that's why we call it here,1629 // after setting the owner1630 if (jsc.isElementType(container, 'body')) {1631 jsc.redrawPosition();1632 } else {1633 jsc._drawPosition(THIS, 0, 0, 'relative', false);1634 }16351636 if (p.wrap.parentNode != container) {1637 container.appendChild(p.wrap);1638 }16391640 jsc.setClass(THIS.targetElement, THIS.activeClass);1641 }164216431644 function redrawPad () {1645 // redraw the pad pointer1646 switch (jsc.getPadYComponent(THIS)) {1647 case 's': var yComponent = 1; break;1648 case 'v': var yComponent = 2; break;1649 }1650 var x = Math.round((THIS.hsv[0] / 360) * (THIS.width - 1));1651 var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));1652 var crossOuterSize = (2 * THIS.pointerBorderWidth + THIS.pointerThickness + 2 * THIS.crossSize);1653 var ofs = -Math.floor(crossOuterSize / 2);1654 jsc.picker.cross.style.left = (x + ofs) + 'px';1655 jsc.picker.cross.style.top = (y + ofs) + 'px';16561657 // redraw the slider1658 switch (jsc.getSliderComponent(THIS)) {1659 case 's':1660 var rgb1 = HSV_RGB(THIS.hsv[0], 100, THIS.hsv[2]);1661 var rgb2 = HSV_RGB(THIS.hsv[0], 0, THIS.hsv[2]);1662 var color1 = 'rgb(' +1663 Math.round(rgb1[0]) + ',' +1664 Math.round(rgb1[1]) + ',' +1665 Math.round(rgb1[2]) + ')';1666 var color2 = 'rgb(' +1667 Math.round(rgb2[0]) + ',' +1668 Math.round(rgb2[1]) + ',' +1669 Math.round(rgb2[2]) + ')';1670 jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);1671 break;1672 case 'v':1673 var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 100);1674 var color1 = 'rgb(' +1675 Math.round(rgb[0]) + ',' +1676 Math.round(rgb[1]) + ',' +1677 Math.round(rgb[2]) + ')';1678 var color2 = '#000';1679 jsc.picker.sldGrad.draw(THIS.sliderSize, THIS.height, color1, color2);1680 break;1681 }1682 }168316841685 function redrawSld () {1686 var sldComponent = jsc.getSliderComponent(THIS);1687 if (sldComponent) {1688 // redraw the slider pointer1689 switch (sldComponent) {1690 case 's': var yComponent = 1; break;1691 case 'v': var yComponent = 2; break;1692 }1693 var y = Math.round((1 - THIS.hsv[yComponent] / 100) * (THIS.height - 1));1694 jsc.picker.sldPtrOB.style.top = (y - (2 * THIS.pointerBorderWidth + THIS.pointerThickness) - Math.floor(sliderPtrSpace / 2)) + 'px';1695 }1696 }169716981699 function isPickerOwner () {1700 return jsc.picker && jsc.picker.owner === THIS;1701 }170217031704 function blurValue () {1705 THIS.importColor();1706 }170717081709 // Find the target element1710 if (typeof targetElement === 'string') {1711 var id = targetElement;1712 var elm = document.getElementById(id);1713 if (elm) {1714 this.targetElement = elm;1715 } else {1716 jsc.warn('Could not find target element with ID \'' + id + '\'');1717 }1718 } else if (targetElement) {1719 this.targetElement = targetElement;1720 } else {1721 jsc.warn('Invalid target element: \'' + targetElement + '\'');1722 }17231724 if (this.targetElement._jscLinkedInstance) {1725 jsc.warn('Cannot link jscolor twice to the same element. Skipping.');1726 return;1727 }1728 this.targetElement._jscLinkedInstance = this;17291730 // Find the value element1731 this.valueElement = jsc.fetchElement(this.valueElement);1732 // Find the style element1733 this.styleElement = jsc.fetchElement(this.styleElement);17341735 var THIS = this;1736 var container =1737 this.container ?1738 jsc.fetchElement(this.container) :1739 document.getElementsByTagName('body')[0];1740 var sliderPtrSpace = 3; // px17411742 // For BUTTON elements it's important to stop them from sending the form when clicked1743 // (e.g. in Safari)1744 if (jsc.isElementType(this.targetElement, 'button')) {1745 if (this.targetElement.onclick) {1746 var origCallback = this.targetElement.onclick;1747 this.targetElement.onclick = function (evt) {1748 origCallback.call(this, evt);1749 return false;1750 };1751 } else {1752 this.targetElement.onclick = function () { return false; };1753 }1754 }17551756 /*1757 var elm = this.targetElement;1758 do {1759 // If the target element or one of its offsetParents has fixed position,1760 // then use fixed positioning instead1761 //1762 // Note: In Firefox, getComputedStyle returns null in a hidden iframe,1763 // that's why we need to check if the returned style object is non-empty1764 var currStyle = jsc.getStyle(elm);1765 if (currStyle && currStyle.position.toLowerCase() === 'fixed') {1766 this.fixed = true;1767 }17681769 if (elm !== this.targetElement) {1770 // attach onParentScroll so that we can recompute the picker position1771 // when one of the offsetParents is scrolled1772 if (!elm._jscEventsAttached) {1773 jsc.attachEvent(elm, 'scroll', jsc.onParentScroll);1774 elm._jscEventsAttached = true;1775 }1776 }1777 } while ((elm = elm.offsetParent) && !jsc.isElementType(elm, 'body'));1778 */17791780 // valueElement1781 if (this.valueElement) {1782 if (jsc.isElementType(this.valueElement, 'input')) {1783 var updateField = function () {1784 THIS.fromString(THIS.valueElement.value, jsc.leaveValue);1785 jsc.dispatchFineChange(THIS);1786 };1787 jsc.attachEvent(this.valueElement, 'keyup', updateField);1788 jsc.attachEvent(this.valueElement, 'input', updateField);1789 jsc.attachEvent(this.valueElement, 'blur', blurValue);1790 this.valueElement.setAttribute('autocomplete', 'off');1791 }1792 }17931794 // styleElement1795 if (this.styleElement) {1796 this.styleElement._jscOrigStyle = {1797 backgroundImage : this.styleElement.style.backgroundImage,1798 backgroundColor : this.styleElement.style.backgroundColor,1799 color : this.styleElement.style.color1800 };1801 }18021803 if (this.value) {1804 // Try to set the color from the .value option and if unsuccessful,1805 // export the current color1806 this.fromString(this.value) || this.exportColor();1807 } else {1808 this.importColor();1809 }1810 }18111812};181318141815//================================1816// Public properties and methods1817//================================181818191820// By default, search for all elements with class="jscolor" and install a color picker on them.1821//1822// You can change what class name will be looked for by setting the property jscolor.lookupClass1823// anywhere in your HTML document. To completely disable the automatic lookup, set it to null.1824//1825jsc.jscolor.lookupClass = 'jscolor';182618271828jsc.jscolor.installByClassName = function (className) {1829 var inputElms = document.getElementsByTagName('input');1830 var buttonElms = document.getElementsByTagName('button');18311832 jsc.tryInstallOnElements(inputElms, className);1833 jsc.tryInstallOnElements(buttonElms, className);1834};183518361837jsc.register();183818391840return jsc.jscolor;18411842
...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!