jsColor.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. (function (window) {
  2. window.jsColorPicker = function(selectors, config) {
  3. var renderCallback = function(colors, mode) {
  4. var options = this,
  5. input = options.input,
  6. patch = options.patch,
  7. RGB = colors.RND.rgb,
  8. HSL = colors.RND.hsl,
  9. AHEX = options.isIE8 ? (colors.alpha < 0.16 ? '0' : '') +
  10. (Math.round(colors.alpha * 100)).toString(16).toUpperCase() + colors.HEX : '',
  11. RGBInnerText = RGB.r + ', ' + RGB.g + ', ' + RGB.b,
  12. RGBAText = 'rgba(' + RGBInnerText + ', ' + colors.alpha + ')',
  13. isAlpha = colors.alpha !== 1 && !options.isIE8,
  14. colorMode = input.getAttribute('data-colorMode');
  15. patch.style.cssText =
  16. 'color:' + (colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd') + ';' + // Black...???
  17. 'background-color:' + RGBAText + ';' +
  18. 'filter:' + (options.isIE8 ? 'progid:DXImageTransform.Microsoft.gradient(' + // IE<9
  19. 'startColorstr=#' + AHEX + ',' + 'endColorstr=#' + AHEX + ')' : '');
  20. input.value = (colorMode === 'HEX' && !isAlpha ? '#' + (options.isIE8 ? AHEX : colors.HEX) :
  21. colorMode === 'rgb' || (colorMode === 'HEX' && isAlpha) ?
  22. (!isAlpha ? 'rgb(' + RGBInnerText + ')' : RGBAText) :
  23. ('hsl' + (isAlpha ? 'a(' : '(') + HSL.h + ', ' + HSL.s + '%, ' + HSL.l + '%' +
  24. (isAlpha ? ', ' + colors.alpha : '') + ')')
  25. );
  26. if (options.displayCallback) {
  27. options.displayCallback(colors, mode, options);
  28. }
  29. },
  30. extractValue = function(elm) {
  31. return elm.value || elm.getAttribute('value') || elm.style.backgroundColor || '#987654';
  32. },
  33. actionCallback = function(event, action) {
  34. var options = this,
  35. colorPicker = colorPickers.current;
  36. if (action === 'toMemory') {
  37. var memos = colorPicker.nodes.memos,
  38. backgroundColor = '',
  39. opacity = 0,
  40. cookieTXT = [];
  41. for (var n = 0, m = memos.length; n < m; n++) {
  42. backgroundColor = memos[n].style.backgroundColor;
  43. opacity = memos[n].style.opacity;
  44. opacity = Math.round((opacity === '' ? 1 : opacity) * 100) / 100;
  45. cookieTXT.push(backgroundColor.
  46. replace(/, /g, ',').
  47. replace('rgb(', 'rgba(').
  48. replace(')', ',' + opacity + ')')
  49. );
  50. }
  51. cookieTXT = '\'' + cookieTXT.join('\',\'') + '\'';
  52. ColorPicker.docCookies('colorPickerMemos' + (options.noAlpha ? 'NoAlpha' : ''), cookieTXT);
  53. } else if (action === 'resizeApp') {
  54. ColorPicker.docCookies('colorPickerSize', colorPicker.color.options.currentSize);
  55. } else if (action === 'modeChange') {
  56. var mode = colorPicker.color.options.mode;
  57. ColorPicker.docCookies('colorPickerMode', mode.type + '-' + mode.z);
  58. }
  59. },
  60. createInstance = function(elm, config) {
  61. var initConfig = {
  62. klass: window.ColorPicker,
  63. input: elm,
  64. patch: elm,
  65. isIE8: !!document.all && !document.addEventListener, // Opera???
  66. // *** animationSpeed: 200,
  67. // *** draggable: true,
  68. margin: {left: -1, top: 2},
  69. customBG: '#FFFFFF',
  70. // displayCallback: displayCallback,
  71. /* --- regular colorPicker options from this point --- */
  72. color: extractValue(elm),
  73. initStyle: 'display: none',
  74. mode: ColorPicker.docCookies('colorPickerMode') || 'hsv-h',
  75. // memoryColors: (function(colors, config) {
  76. // return config.noAlpha ?
  77. // colors.replace(/\,\d*\.*\d*\)/g, ',1)') : colors;
  78. // })($.docCookies('colorPickerMemos'), config || {}),
  79. memoryColors: ColorPicker.docCookies('colorPickerMemos' +
  80. ((config || {}).noAlpha ? 'NoAlpha' : '')),
  81. size: ColorPicker.docCookies('colorPickerSize') || 1,
  82. renderCallback: renderCallback,
  83. actionCallback: actionCallback
  84. };
  85. for (var n in config) {
  86. initConfig[n] = config[n];
  87. }
  88. return new initConfig.klass(initConfig);
  89. },
  90. doEventListeners = function(elm, multiple, off) {
  91. var onOff = off ? 'removeEventListener' : 'addEventListener',
  92. focusListener = function(e) {
  93. var input = this,
  94. position = window.ColorPicker.getOrigin(input),
  95. index = multiple ? Array.prototype.indexOf.call(elms, this) : 0,
  96. colorPicker = colorPickers[index] ||
  97. (colorPickers[index] = createInstance(this, config)),
  98. options = colorPicker.color.options,
  99. colorPickerUI = colorPicker.nodes.colorPicker,
  100. appendTo = (options.appendTo || document.body),
  101. isStatic = /static/.test(window.getComputedStyle(appendTo).position),
  102. atrect = isStatic ? {left: 0, top: 0} : appendTo.getBoundingClientRect(),
  103. waitTimer = 0;
  104. options.color = extractValue(elm); // brings color to default on reset
  105. colorPickerUI.style.cssText =
  106. 'position: absolute;' + (!colorPickers[index].cssIsReady ? 'display: none;' : '') +
  107. 'left:' + (position.left + options.margin.left - atrect.left) + 'px;' +
  108. 'top:' + (position.top + +input.offsetHeight + options.margin.top - atrect.top) + 'px;';
  109. if (!multiple) {
  110. options.input = elm;
  111. options.patch = elm; // check again???
  112. colorPicker.setColor(extractValue(elm), undefined, undefined, true);
  113. colorPicker.saveAsBackground();
  114. }
  115. colorPickers.current = colorPickers[index];
  116. appendTo.appendChild(colorPickerUI);
  117. waitTimer = setInterval(function() { // compensating late style on onload in colorPicker
  118. if (colorPickers.current.cssIsReady) {
  119. waitTimer = clearInterval(waitTimer);
  120. colorPickerUI.style.display = 'block';
  121. }
  122. }, 10);
  123. },
  124. mousDownListener = function(e) {
  125. var colorPicker = colorPickers.current,
  126. colorPickerUI = (colorPicker ? colorPicker.nodes.colorPicker : undefined),
  127. animationSpeed = colorPicker ? colorPicker.color.options.animationSpeed : 0,
  128. isColorPicker = colorPicker && (function(elm) {
  129. while (elm) {
  130. if ((elm.className || '').indexOf('cp-app') !== -1) return elm;
  131. elm = elm.parentNode;
  132. }
  133. return false;
  134. })(e.target),
  135. inputIndex = Array.prototype.indexOf.call(elms, e.target);
  136. if (isColorPicker && Array.prototype.indexOf.call(colorPickers, isColorPicker)) {
  137. if (e.target === colorPicker.nodes.exit) {
  138. colorPickerUI.style.display = 'none';
  139. document.activeElement.blur();
  140. } else {
  141. // ...
  142. }
  143. } else if (inputIndex !== -1) {
  144. // ...
  145. } else if (colorPickerUI) {
  146. colorPickerUI.style.display = 'none';
  147. }
  148. };
  149. elm[onOff]('focus', focusListener);
  150. if (!colorPickers.evt || off) {
  151. colorPickers.evt = true; // prevent new eventListener for window
  152. window[onOff]('mousedown', mousDownListener);
  153. }
  154. },
  155. // this is a way to prevent data binding on HTMLElements
  156. colorPickers = window.jsColorPicker.colorPickers || [],
  157. elms = document.querySelectorAll(selectors),
  158. testColors = new window.Colors({customBG: config.customBG, allMixDetails: true});
  159. window.jsColorPicker.colorPickers = colorPickers;
  160. for (var n = 0, m = elms.length; n < m; n++) {
  161. var elm = elms[n];
  162. if (config === 'destroy') {
  163. doEventListeners(elm, (config && config.multipleInstances), true);
  164. if (colorPickers[n]) {
  165. colorPickers[n].destroyAll();
  166. }
  167. } else {
  168. var color = extractValue(elm);
  169. var value = color.split('(');
  170. testColors.setColor(color);
  171. if (config && config.init) {
  172. config.init(elm, testColors.colors);
  173. }
  174. elm.setAttribute('data-colorMode', value[1] ? value[0].substr(0, 3) : 'HEX');
  175. doEventListeners(elm, (config && config.multipleInstances), false);
  176. if (config && config.readOnly) {
  177. elm.readOnly = true;
  178. }
  179. }
  180. };
  181. return window.jsColorPicker.colorPickers;
  182. };
  183. window.ColorPicker.docCookies = function(key, val, options) {
  184. var encode = encodeURIComponent, decode = decodeURIComponent,
  185. cookies, n, tmp, cache = {},
  186. days;
  187. if (val === undefined) { // all about reading cookies
  188. cookies = document.cookie.split(/;\s*/) || [];
  189. for (n = cookies.length; n--; ) {
  190. tmp = cookies[n].split('=');
  191. if (tmp[0]) cache[decode(tmp.shift())] = decode(tmp.join('=')); // there might be '='s in the value...
  192. }
  193. if (!key) return cache; // return Json for easy access to all cookies
  194. else return cache[key]; // easy access to cookies from here
  195. } else { // write/delete cookie
  196. options = options || {};
  197. if (val === '' || options.expires < 0) { // prepare deleteing the cookie
  198. options.expires = -1;
  199. // options.path = options.domain = options.secure = undefined; // to make shure the cookie gets deleted...
  200. }
  201. if (options.expires !== undefined) { // prepare date if any
  202. days = new Date();
  203. days.setDate(days.getDate() + options.expires);
  204. }
  205. document.cookie = encode(key) + '=' + encode(val) +
  206. (days ? '; expires=' + days.toUTCString() : '') +
  207. (options.path ? '; path=' + options.path : '') +
  208. (options.domain ? '; domain=' + options.domain : '') +
  209. (options.secure ? '; secure' : '');
  210. }
  211. };
  212. })(this);