colorPicker

Advanced javaScript color picker and color conversion / calculation (rgb, hsv, hsl, hex, cmyk, cmy, XYZ, Lab, alpha, WCAG 2.0, ...)

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.gf.qytechs.cn/scripts/23181/147862/colorPicker.js

  1. /*! This library combines:
  2. * - colors.js
  3. * - colorPicker.data.js
  4. * - colorPicker.js
  5. * - javascript_implementation/jsColor.js
  6. * From latest commit 41d780c on May 31, 2016
  7. */
  8. /** jsColor Picker (https://github.com/PitPik/colorPicker)
  9. * MIT license
  10. * This library contains the following files from that same repository:
  11. * - colors.js
  12. * - colorPicker.data.js
  13. * - colorPicker.js
  14. * - javascript_implementation/jsColor.js
  15. */
  16. /*! colors.js */
  17. ;(function(window, undefined){
  18. "use strict"
  19.  
  20. var _valueRanges = {
  21. rgb: {r: [0, 255], g: [0, 255], b: [0, 255]},
  22. hsv: {h: [0, 360], s: [0, 100], v: [0, 100]},
  23. hsl: {h: [0, 360], s: [0, 100], l: [0, 100]},
  24. cmy: {c: [0, 100], m: [0, 100], y: [0, 100]},
  25. cmyk: {c: [0, 100], m: [0, 100], y: [0, 100], k: [0, 100]},
  26. Lab: {L: [0, 100], a: [-128, 127], b: [-128, 127]},
  27. XYZ: {X: [0, 100], Y: [0, 100], Z: [0, 100]},
  28. alpha: {alpha: [0, 1]},
  29. HEX: {HEX: [0, 16777215]} // maybe we don't need this
  30. },
  31.  
  32. _instance = {},
  33. _colors = {},
  34.  
  35. // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html for more
  36. XYZMatrix = { // Observer = 2° (CIE 1931), Illuminant = D65
  37. X: [ 0.4124564, 0.3575761, 0.1804375],
  38. Y: [ 0.2126729, 0.7151522, 0.0721750],
  39. Z: [ 0.0193339, 0.1191920, 0.9503041],
  40. R: [ 3.2404542, -1.5371385, -0.4985314],
  41. G: [-0.9692660, 1.8760108, 0.0415560],
  42. B: [ 0.0556434, -0.2040259, 1.0572252]
  43. },
  44. grey = {r: 0.298954, g: 0.586434, b: 0.114612}, // CIE-XYZ 1931
  45. luminance = {r: 0.2126, g: 0.7152, b: 0.0722}, // W3C 2.0
  46.  
  47. _math = window.Math,
  48. _parseint = window.parseInt,
  49.  
  50. Colors = window.Colors = function(options) {
  51. this.colors = {RND: {}};
  52. this.options = {
  53. color: 'rgba(204, 82, 37, 0.8)', // init value(s)...
  54. XYZMatrix: XYZMatrix,
  55. // XYZReference: {},
  56. grey: grey,
  57. luminance: luminance,
  58. valueRanges: _valueRanges
  59. // customBG: '#808080'
  60. // convertCallback: undefined,
  61. // allMixDetails: false
  62. };
  63. initInstance(this, options || {});
  64. },
  65. initInstance = function(THIS, options) {
  66. var matrix,
  67. importColor,
  68. _options = THIS.options,
  69. customBG;
  70.  
  71. focusInstance(THIS);
  72. for (var option in options) {
  73. if (options[option] !== undefined) _options[option] = options[option];
  74. }
  75. matrix = _options.XYZMatrix;
  76. if (!options.XYZReference) _options.XYZReference = {
  77. X: matrix.X[0] + matrix.X[1] + matrix.X[2],
  78. Y: matrix.Y[0] + matrix.Y[1] + matrix.Y[2],
  79. Z: matrix.Z[0] + matrix.Z[1] + matrix.Z[2]
  80. };
  81. customBG = _options.customBG;
  82. _options.customBG = (typeof customBG === 'string') ? ColorConverter.txt2color(customBG).rgb : customBG;
  83. _colors = setColor(THIS.colors, _options.color, undefined, true); // THIS.colors = _colors =
  84. },
  85. focusInstance = function(THIS) {
  86. if (_instance !== THIS) {
  87. _instance = THIS;
  88. _colors = THIS.colors;
  89. }
  90. };
  91.  
  92. Colors.prototype.setColor = function(newCol, type, alpha) {
  93. focusInstance(this);
  94. if (newCol) {
  95. return setColor(this.colors, newCol, type, undefined, alpha);
  96. } else {
  97. if (alpha !== undefined) {
  98. this.colors.alpha = limitValue(alpha, 0, 1);
  99. }
  100. return convertColors(type);
  101. }
  102. };
  103.  
  104. Colors.prototype.getColor = function(type) {
  105. var result = this.colors, n = 0;
  106.  
  107. if (type) {
  108. type = type.split('.');
  109. while (result[type[n]]) {
  110. result = result[type[n++]];
  111. }
  112. if (type.length !== n) {
  113. result = undefined;
  114. }
  115. }
  116. return result;
  117. };
  118.  
  119. Colors.prototype.setCustomBackground = function(col) { // wild gues,... check again...
  120. focusInstance(this); // needed???
  121. this.options.customBG = (typeof col === 'string') ? ColorConverter.txt2color(col).rgb : col;
  122. // return setColor(this.colors, this.options.customBG, 'rgb', true); // !!!!RGB
  123. return setColor(this.colors, undefined, 'rgb'); // just recalculate existing
  124. };
  125.  
  126. Colors.prototype.saveAsBackground = function() { // alpha
  127. focusInstance(this); // needed???
  128. // return setColor(this.colors, this.colors.RND.rgb, 'rgb', true);
  129. return setColor(this.colors, undefined, 'rgb', true);
  130. };
  131.  
  132. Colors.prototype.convertColor = function(color, type) {
  133. var convert = ColorConverter,
  134. ranges = _valueRanges,
  135. types = type.split('2'),
  136. fromType = types[0],
  137. toType = types[1],
  138. test = /(?:RG|HS|CM|LA)/,
  139. normalizeFrom = test.test(fromType),
  140. normalizeTo = test.test(toType),
  141. exceptions = {LAB: 'Lab'},
  142. normalize = function(color, type, reverse) {
  143. var result = {},
  144. Lab = type === 'Lab' ? 1 : 0;
  145.  
  146. for (var n in color) { // faster (but bigger) way: if/else outside 2 for loops
  147. result[n] = reverse ?
  148. _math.round(color[n] * (Lab || ranges[type][n][1])) :
  149. color[n] / (Lab || ranges[type][n][1]);
  150. }
  151.  
  152. return result;
  153. };
  154.  
  155. fromType = ranges[fromType] ? fromType : exceptions[fromType] || fromType.toLowerCase();
  156. toType = ranges[toType] ? toType : exceptions[toType] || toType.toLowerCase();
  157.  
  158. if (normalizeFrom && type !== 'RGB2HEX') { // from ABC to abc
  159. color = normalize(color, fromType);
  160. }
  161. color = fromType === toType ? color : ( // same type; returns same/normalized version
  162. convert[fromType + '2' + toType] ? convert[fromType + '2' + toType](color, true) : // existing converter
  163. toType === 'HEX' ? convert.RGB2HEX(type === 'RGB2HEX' ? color : normalize(fromType === 'rgb' ? color :
  164. convert[fromType + '2rgb'](color, true), 'rgb', true)) :
  165. convert['rgb2' + toType](convert[fromType + '2rgb'](color, true), true) // not in ColorConverter
  166. );
  167. if (normalizeTo) { // from abc to ABC
  168. color = normalize(color, toType, true);
  169. }
  170.  
  171. return color;
  172. };
  173.  
  174. Colors.prototype.toString = function(colorMode, forceAlpha) {
  175. return ColorConverter.color2text((colorMode || 'rgb').toLowerCase(), this.colors, forceAlpha);
  176. };
  177.  
  178.  
  179. // ------------------------------------------------------ //
  180. // ---------- Color calculation related stuff ---------- //
  181. // -------------------------------------------------------//
  182.  
  183. function setColor(colors, color, type, save, alpha) { // color only full range
  184. if (typeof color === 'string') {
  185. var color = ColorConverter.txt2color(color); // new object
  186. type = color.type;
  187. _colors[type] = color[type];
  188. alpha = alpha !== undefined ? alpha : color.alpha;
  189. } else if (color) {
  190. for (var n in color) {
  191. colors[type][n] = type === 'Lab' ?
  192. limitValue(color[n], _valueRanges[type][n][0], _valueRanges[type][n][1]) :
  193. limitValue(color[n] / _valueRanges[type][n][1], 0 , 1);
  194. }
  195. }
  196. if (alpha !== undefined) {
  197. colors.alpha = limitValue(+alpha, 0, 1);
  198. }
  199. return convertColors(type, save ? colors : undefined);
  200. }
  201.  
  202. function saveAsBackground(RGB, rgb, alpha) {
  203. var grey = _instance.options.grey,
  204. color = {};
  205.  
  206. color.RGB = {r: RGB.r, g: RGB.g, b: RGB.b};
  207. color.rgb = {r: rgb.r, g: rgb.g, b: rgb.b};
  208. color.alpha = alpha;
  209. // color.RGBLuminance = getLuminance(RGB);
  210. color.equivalentGrey = _math.round(grey.r * RGB.r + grey.g * RGB.g + grey.b * RGB.b);
  211.  
  212. color.rgbaMixBlack = mixColors(rgb, {r: 0, g: 0, b: 0}, alpha, 1);
  213. color.rgbaMixWhite = mixColors(rgb, {r: 1, g: 1, b: 1}, alpha, 1);
  214. color.rgbaMixBlack.luminance = getLuminance(color.rgbaMixBlack, true);
  215. color.rgbaMixWhite.luminance = getLuminance(color.rgbaMixWhite, true);
  216.  
  217. if (_instance.options.customBG) {
  218. color.rgbaMixCustom = mixColors(rgb, _instance.options.customBG, alpha, 1);
  219. color.rgbaMixCustom.luminance = getLuminance(color.rgbaMixCustom, true);
  220. _instance.options.customBG.luminance = getLuminance(_instance.options.customBG, true);
  221. }
  222.  
  223. return color;
  224. }
  225.  
  226. function convertColors(type, colorObj) {
  227. // console.time('convertColors');
  228. var _Math = _math,
  229. colors = colorObj || _colors,
  230. convert = ColorConverter,
  231. options = _instance.options,
  232. ranges = _valueRanges,
  233. RND = colors.RND,
  234. // type = colorType, // || _mode.type,
  235. modes, mode = '', from = '', // value = '',
  236. exceptions = {hsl: 'hsv', cmyk: 'cmy', rgb: type},
  237. RGB = RND.rgb, SAVE, SMART;
  238.  
  239. if (type !== 'alpha') {
  240. for (var typ in ranges) {
  241. if (!ranges[typ][typ]) { // no alpha|HEX
  242. if (type !== typ && typ !== 'XYZ') {
  243. from = exceptions[typ] || 'rgb';
  244. colors[typ] = convert[from + '2' + typ](colors[from]);
  245. }
  246.  
  247. if (!RND[typ]) RND[typ] = {};
  248. modes = colors[typ];
  249. for(mode in modes) {
  250. RND[typ][mode] = _Math.round(modes[mode] * (typ === 'Lab' ? 1 : ranges[typ][mode][1]));
  251. }
  252. }
  253. }
  254. if (type !== 'Lab') {
  255. delete colors._rgb;
  256. }
  257.  
  258. RGB = RND.rgb;
  259. colors.HEX = convert.RGB2HEX(RGB);
  260. colors.equivalentGrey =
  261. options.grey.r * colors.rgb.r +
  262. options.grey.g * colors.rgb.g +
  263. options.grey.b * colors.rgb.b;
  264. colors.webSave = SAVE = getClosestWebColor(RGB, 51);
  265. // colors.webSave.HEX = convert.RGB2HEX(colors.webSave);
  266. colors.webSmart = SMART = getClosestWebColor(RGB, 17);
  267. // colors.webSmart.HEX = convert.RGB2HEX(colors.webSmart);
  268. colors.saveColor =
  269. RGB.r === SAVE.r && RGB.g === SAVE.g && RGB.b === SAVE.b ? 'web save' :
  270. RGB.r === SMART.r && RGB.g === SMART.g && RGB.b === SMART.b ? 'web smart' : '';
  271. colors.hueRGB = convert.hue2RGB(colors.hsv.h);
  272.  
  273. if (colorObj) {
  274. colors.background = saveAsBackground(RGB, colors.rgb, colors.alpha);
  275. }
  276. } // else RGB = RND.rgb;
  277.  
  278. var rgb = colors.rgb, // for better minification...
  279. alpha = colors.alpha,
  280. luminance = 'luminance',
  281. background = colors.background,
  282. rgbaMixBlack, rgbaMixWhite, rgbaMixCustom,
  283. rgbaMixBG, rgbaMixBGMixBlack, rgbaMixBGMixWhite, rgbaMixBGMixCustom,
  284. _mixColors = mixColors,
  285. _getLuminance = getLuminance,
  286. _getWCAG2Ratio = getWCAG2Ratio,
  287. _getHueDelta = getHueDelta;
  288.  
  289. rgbaMixBlack = _mixColors(rgb, {r: 0, g: 0, b: 0}, alpha, 1);
  290. rgbaMixBlack[luminance] = _getLuminance(rgbaMixBlack, true);
  291. colors.rgbaMixBlack = rgbaMixBlack;
  292.  
  293. rgbaMixWhite = _mixColors(rgb, {r: 1, g: 1, b: 1}, alpha, 1);
  294. rgbaMixWhite[luminance] = _getLuminance(rgbaMixWhite, true);
  295. colors.rgbaMixWhite = rgbaMixWhite;
  296.  
  297. if (options.allMixDetails) {
  298. rgbaMixBlack.WCAG2Ratio = _getWCAG2Ratio(rgbaMixBlack[luminance], 0);
  299. rgbaMixWhite.WCAG2Ratio = _getWCAG2Ratio(rgbaMixWhite[luminance], 1);
  300.  
  301. if (options.customBG) {
  302. rgbaMixCustom = _mixColors(rgb, options.customBG, alpha, 1);
  303. rgbaMixCustom[luminance] = _getLuminance(rgbaMixCustom, true);
  304. rgbaMixCustom.WCAG2Ratio = _getWCAG2Ratio(rgbaMixCustom[luminance], options.customBG[luminance]);
  305. colors.rgbaMixCustom = rgbaMixCustom;
  306. }
  307.  
  308. rgbaMixBG = _mixColors(rgb, background.rgb, alpha, background.alpha);
  309. rgbaMixBG[luminance] = _getLuminance(rgbaMixBG, true); // ?? do we need this?
  310. colors.rgbaMixBG = rgbaMixBG;
  311.  
  312. rgbaMixBGMixBlack = _mixColors(rgb, background.rgbaMixBlack, alpha, 1);
  313. rgbaMixBGMixBlack[luminance] = _getLuminance(rgbaMixBGMixBlack, true);
  314. rgbaMixBGMixBlack.WCAG2Ratio = _getWCAG2Ratio(rgbaMixBGMixBlack[luminance],
  315. background.rgbaMixBlack[luminance]);
  316. /* ------ */
  317. rgbaMixBGMixBlack.luminanceDelta = _Math.abs(
  318. rgbaMixBGMixBlack[luminance] - background.rgbaMixBlack[luminance]);
  319. rgbaMixBGMixBlack.hueDelta = _getHueDelta(background.rgbaMixBlack, rgbaMixBGMixBlack, true);
  320. /* ------ */
  321. colors.rgbaMixBGMixBlack = rgbaMixBGMixBlack;
  322.  
  323. rgbaMixBGMixWhite = _mixColors(rgb, background.rgbaMixWhite, alpha, 1);
  324. rgbaMixBGMixWhite[luminance] = _getLuminance(rgbaMixBGMixWhite, true);
  325. rgbaMixBGMixWhite.WCAG2Ratio = _getWCAG2Ratio(rgbaMixBGMixWhite[luminance],
  326. background.rgbaMixWhite[luminance]);
  327. /* ------ */
  328. rgbaMixBGMixWhite.luminanceDelta = _Math.abs(
  329. rgbaMixBGMixWhite[luminance] - background.rgbaMixWhite[luminance]);
  330. rgbaMixBGMixWhite.hueDelta = _getHueDelta(background.rgbaMixWhite, rgbaMixBGMixWhite, true);
  331. /* ------ */
  332. colors.rgbaMixBGMixWhite = rgbaMixBGMixWhite;
  333. }
  334.  
  335. if (options.customBG) {
  336. rgbaMixBGMixCustom = _mixColors(rgb, background.rgbaMixCustom, alpha, 1);
  337. rgbaMixBGMixCustom[luminance] = _getLuminance(rgbaMixBGMixCustom, true);
  338. rgbaMixBGMixCustom.WCAG2Ratio = _getWCAG2Ratio(rgbaMixBGMixCustom[luminance],
  339. background.rgbaMixCustom[luminance]);
  340. colors.rgbaMixBGMixCustom = rgbaMixBGMixCustom;
  341. /* ------ */
  342. rgbaMixBGMixCustom.luminanceDelta = _Math.abs(
  343. rgbaMixBGMixCustom[luminance] - background.rgbaMixCustom[luminance]);
  344. rgbaMixBGMixCustom.hueDelta = _getHueDelta(background.rgbaMixCustom, rgbaMixBGMixCustom, true);
  345. /* ------ */
  346. }
  347.  
  348. colors.RGBLuminance = _getLuminance(RGB);
  349. colors.HUELuminance = _getLuminance(colors.hueRGB);
  350.  
  351. // renderVars.readyToRender = true;
  352. if (options.convertCallback) {
  353. options.convertCallback(colors, type); //, convert); //, _mode);
  354. }
  355.  
  356. // console.timeEnd('convertColors')
  357. // if (colorObj)
  358. return colors;
  359. }
  360.  
  361.  
  362. // ------------------------------------------------------ //
  363. // ------------------ color conversion ------------------ //
  364. // -------------------------------------------------------//
  365.  
  366. var ColorConverter = {
  367. txt2color: function(txt) {
  368. var color = {},
  369. parts = txt.replace(/(?:#|\)|%)/g, '').split('('),
  370. values = (parts[1] || '').split(/,\s*/),
  371. type = parts[1] ? parts[0].substr(0, 3) : 'rgb',
  372. m = '';
  373.  
  374. color.type = type;
  375. color[type] = {};
  376. if (parts[1]) {
  377. for (var n = 3; n--; ) {
  378. m = type[n] || type.charAt(n); // IE7
  379. color[type][m] = +values[n] / _valueRanges[type][m][1];
  380. }
  381. } else {
  382. color.rgb = ColorConverter.HEX2rgb(parts[0]);
  383. }
  384. // color.color = color[type];
  385. color.alpha = values[3] ? +values[3] : 1;
  386.  
  387. return color;
  388. },
  389.  
  390. color2text: function(colorMode, colors, forceAlpha) {
  391. var alpha = forceAlpha !== false && _math.round(colors.alpha * 100) / 100,
  392. hasAlpha = typeof alpha === 'number' &&
  393. forceAlpha !== false && (forceAlpha || alpha !== 1),
  394. RGB = colors.RND.rgb,
  395. HSL = colors.RND.hsl,
  396. shouldBeHex = colorMode === 'hex' && hasAlpha,
  397. isHex = colorMode === 'hex' && !shouldBeHex,
  398. isRgb = colorMode === 'rgb' || shouldBeHex,
  399. innerText = isRgb ? RGB.r + ', ' + RGB.g + ', ' + RGB.b :
  400. !isHex ? HSL.h + ', ' + HSL.s + '%, ' + HSL.l + '%' :
  401. '#' + colors.HEX;
  402.  
  403. return isHex ? innerText : (shouldBeHex ? 'rgb' : colorMode) +
  404. (hasAlpha ? 'a' : '') + '(' + innerText + (hasAlpha ? ', ' + alpha : '') + ')';
  405. },
  406.  
  407. RGB2HEX: function(RGB) {
  408. return (
  409. (RGB.r < 16 ? '0' : '') + RGB.r.toString(16) +
  410. (RGB.g < 16 ? '0' : '') + RGB.g.toString(16) +
  411. (RGB.b < 16 ? '0' : '') + RGB.b.toString(16)
  412. ).toUpperCase();
  413. },
  414.  
  415. HEX2rgb: function(HEX) {
  416. HEX = HEX.split(''); // IE7
  417. return {
  418. r: +('0x' + HEX[0] + HEX[HEX[3] ? 1 : 0]) / 255,
  419. g: +('0x' + HEX[HEX[3] ? 2 : 1] + (HEX[3] || HEX[1])) / 255,
  420. b: +('0x' + (HEX[4] || HEX[2]) + (HEX[5] || HEX[2])) / 255
  421. };
  422. },
  423.  
  424. hue2RGB: function(hue) {
  425. var _Math = _math,
  426. h = hue * 6,
  427. mod = ~~h % 6, // Math.floor(h) -> faster in most browsers
  428. i = h === 6 ? 0 : (h - mod);
  429.  
  430. return {
  431. r: _Math.round([1, 1 - i, 0, 0, i, 1][mod] * 255),
  432. g: _Math.round([i, 1, 1, 1 - i, 0, 0][mod] * 255),
  433. b: _Math.round([0, 0, i, 1, 1, 1 - i][mod] * 255)
  434. };
  435. },
  436.  
  437. // ------------------------ HSV ------------------------ //
  438.  
  439. rgb2hsv: function(rgb) { // faster
  440. var _Math = _math,
  441. r = rgb.r,
  442. g = rgb.g,
  443. b = rgb.b,
  444. k = 0, chroma, min, s;
  445.  
  446. if (g < b) {
  447. g = b + (b = g, 0);
  448. k = -1;
  449. }
  450. min = b;
  451. if (r < g) {
  452. r = g + (g = r, 0);
  453. k = -2 / 6 - k;
  454. min = _Math.min(g, b); // g < b ? g : b; ???
  455. }
  456. chroma = r - min;
  457. s = r ? (chroma / r) : 0;
  458. return {
  459. h: s < 1e-15 ? ((_colors && _colors.hsl && _colors.hsl.h) || 0) :
  460. chroma ? _Math.abs(k + (g - b) / (6 * chroma)) : 0,
  461. s: r ? (chroma / r) : ((_colors && _colors.hsv && _colors.hsv.s) || 0), // ??_colors.hsv.s || 0
  462. v: r
  463. };
  464. },
  465.  
  466. hsv2rgb: function(hsv) {
  467. var h = hsv.h * 6,
  468. s = hsv.s,
  469. v = hsv.v,
  470. i = ~~h, // Math.floor(h) -> faster in most browsers
  471. f = h - i,
  472. p = v * (1 - s),
  473. q = v * (1 - f * s),
  474. t = v * (1 - (1 - f) * s),
  475. mod = i % 6;
  476.  
  477. return {
  478. r: [v, q, p, p, t, v][mod],
  479. g: [t, v, v, q, p, p][mod],
  480. b: [p, p, t, v, v, q][mod]
  481. };
  482. },
  483.  
  484. // ------------------------ HSL ------------------------ //
  485.  
  486. hsv2hsl: function(hsv) {
  487. var l = (2 - hsv.s) * hsv.v,
  488. s = hsv.s * hsv.v;
  489.  
  490. s = !hsv.s ? 0 : l < 1 ? (l ? s / l : 0) : s / (2 - l);
  491.  
  492. return {
  493. h: hsv.h,
  494. s: !hsv.v && !s ? ((_colors && _colors.hsl && _colors.hsl.s) || 0) : s, // ???
  495. l: l / 2
  496. };
  497. },
  498.  
  499. rgb2hsl: function(rgb, dependent) { // not used in Color
  500. var hsv = ColorConverter.rgb2hsv(rgb);
  501.  
  502. return ColorConverter.hsv2hsl(dependent ? hsv : (_colors.hsv = hsv));
  503. },
  504.  
  505. hsl2rgb: function(hsl) {
  506. var h = hsl.h * 6,
  507. s = hsl.s,
  508. l = hsl.l,
  509. v = l < 0.5 ? l * (1 + s) : (l + s) - (s * l),
  510. m = l + l - v,
  511. sv = v ? ((v - m) / v) : 0,
  512. sextant = ~~h, // Math.floor(h) -> faster in most browsers
  513. fract = h - sextant,
  514. vsf = v * sv * fract,
  515. t = m + vsf,
  516. q = v - vsf,
  517. mod = sextant % 6;
  518.  
  519. return {
  520. r: [v, q, m, m, t, v][mod],
  521. g: [t, v, v, q, m, m][mod],
  522. b: [m, m, t, v, v, q][mod]
  523. };
  524. },
  525.  
  526. // ------------------------ CMYK ------------------------ //
  527. // Quote from Wikipedia:
  528. // "Since RGB and CMYK spaces are both device-dependent spaces, there is no
  529. // simple or general conversion formula that converts between them.
  530. // Conversions are generally done through color management systems, using
  531. // color profiles that describe the spaces being converted. Nevertheless, the
  532. // conversions cannot be exact, since these spaces have very different gamuts."
  533. // Translation: the following are just simple RGB to CMY(K) and visa versa conversion functions.
  534.  
  535. rgb2cmy: function(rgb) {
  536. return {
  537. c: 1 - rgb.r,
  538. m: 1 - rgb.g,
  539. y: 1 - rgb.b
  540. };
  541. },
  542.  
  543. cmy2cmyk: function(cmy) {
  544. var _Math = _math,
  545. k = _Math.min(_Math.min(cmy.c, cmy.m), cmy.y),
  546. t = 1 - k || 1e-20;
  547.  
  548. return { // regular
  549. c: (cmy.c - k) / t,
  550. m: (cmy.m - k) / t,
  551. y: (cmy.y - k) / t,
  552. k: k
  553. };
  554. },
  555.  
  556. cmyk2cmy: function(cmyk) {
  557. var k = cmyk.k;
  558.  
  559. return { // regular
  560. c: cmyk.c * (1 - k) + k,
  561. m: cmyk.m * (1 - k) + k,
  562. y: cmyk.y * (1 - k) + k
  563. };
  564. },
  565.  
  566. cmy2rgb: function(cmy) {
  567. return {
  568. r: 1 - cmy.c,
  569. g: 1 - cmy.m,
  570. b: 1 - cmy.y
  571. };
  572. },
  573.  
  574. rgb2cmyk: function(rgb, dependent) {
  575. var cmy = ColorConverter.rgb2cmy(rgb); // doppelt??
  576.  
  577. return ColorConverter.cmy2cmyk(dependent ? cmy : (_colors.cmy = cmy));
  578. },
  579.  
  580. cmyk2rgb: function(cmyk, dependent) {
  581. var cmy = ColorConverter.cmyk2cmy(cmyk); // doppelt??
  582.  
  583. return ColorConverter.cmy2rgb(dependent ? cmy : (_colors.cmy = cmy));
  584. },
  585.  
  586. // ------------------------ LAB ------------------------ //
  587.  
  588. XYZ2rgb: function(XYZ, skip) {
  589. var _Math = _math,
  590. M = _instance.options.XYZMatrix,
  591. X = XYZ.X,
  592. Y = XYZ.Y,
  593. Z = XYZ.Z,
  594. r = X * M.R[0] + Y * M.R[1] + Z * M.R[2],
  595. g = X * M.G[0] + Y * M.G[1] + Z * M.G[2],
  596. b = X * M.B[0] + Y * M.B[1] + Z * M.B[2],
  597. N = 1 / 2.4;
  598.  
  599. M = 0.0031308;
  600.  
  601. r = (r > M ? 1.055 * _Math.pow(r, N) - 0.055 : 12.92 * r);
  602. g = (g > M ? 1.055 * _Math.pow(g, N) - 0.055 : 12.92 * g);
  603. b = (b > M ? 1.055 * _Math.pow(b, N) - 0.055 : 12.92 * b);
  604.  
  605. if (!skip) { // out of gammut
  606. _colors._rgb = {r: r, g: g, b: b};
  607. }
  608.  
  609. return {
  610. r: limitValue(r, 0, 1),
  611. g: limitValue(g, 0, 1),
  612. b: limitValue(b, 0, 1)
  613. };
  614. },
  615.  
  616. rgb2XYZ: function(rgb) {
  617. var _Math = _math,
  618. M = _instance.options.XYZMatrix,
  619. r = rgb.r,
  620. g = rgb.g,
  621. b = rgb.b,
  622. N = 0.04045;
  623.  
  624. r = (r > N ? _Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92);
  625. g = (g > N ? _Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92);
  626. b = (b > N ? _Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92);
  627.  
  628. return {
  629. X: r * M.X[0] + g * M.X[1] + b * M.X[2],
  630. Y: r * M.Y[0] + g * M.Y[1] + b * M.Y[2],
  631. Z: r * M.Z[0] + g * M.Z[1] + b * M.Z[2]
  632. };
  633. },
  634.  
  635. XYZ2Lab: function(XYZ) {
  636. var _Math = _math,
  637. R = _instance.options.XYZReference,
  638. X = XYZ.X / R.X,
  639. Y = XYZ.Y / R.Y,
  640. Z = XYZ.Z / R.Z,
  641. N = 16 / 116, M = 1 / 3, K = 0.008856, L = 7.787037;
  642.  
  643. X = X > K ? _Math.pow(X, M) : (L * X) + N;
  644. Y = Y > K ? _Math.pow(Y, M) : (L * Y) + N;
  645. Z = Z > K ? _Math.pow(Z, M) : (L * Z) + N;
  646.  
  647. return {
  648. L: (116 * Y) - 16,
  649. a: 500 * (X - Y),
  650. b: 200 * (Y - Z)
  651. };
  652. },
  653.  
  654. Lab2XYZ: function(Lab) {
  655. var _Math = _math,
  656. R = _instance.options.XYZReference,
  657. Y = (Lab.L + 16) / 116,
  658. X = Lab.a / 500 + Y,
  659. Z = Y - Lab.b / 200,
  660. X3 = _Math.pow(X, 3),
  661. Y3 = _Math.pow(Y, 3),
  662. Z3 = _Math.pow(Z, 3),
  663. N = 16 / 116, K = 0.008856, L = 7.787037;
  664.  
  665. return {
  666. X: (X3 > K ? X3 : (X - N) / L) * R.X,
  667. Y: (Y3 > K ? Y3 : (Y - N) / L) * R.Y,
  668. Z: (Z3 > K ? Z3 : (Z - N) / L) * R.Z
  669. };
  670. },
  671.  
  672. rgb2Lab: function(rgb, dependent) {
  673. var XYZ = ColorConverter.rgb2XYZ(rgb);
  674.  
  675. return ColorConverter.XYZ2Lab(dependent ? XYZ : (_colors.XYZ = XYZ));
  676. },
  677.  
  678. Lab2rgb: function(Lab, dependent) {
  679. var XYZ = ColorConverter.Lab2XYZ(Lab);
  680.  
  681. return ColorConverter.XYZ2rgb(dependent ? XYZ : (_colors.XYZ = XYZ), dependent);
  682. }
  683. };
  684.  
  685. // ------------------------------------------------------ //
  686. // ------------------ helper functions ------------------ //
  687. // -------------------------------------------------------//
  688.  
  689. function getClosestWebColor(RGB, val) {
  690. var out = {},
  691. tmp = 0,
  692. half = val / 2;
  693.  
  694. for (var n in RGB) {
  695. tmp = RGB[n] % val; // 51 = 'web save', 17 = 'web smart'
  696. out[n] = RGB[n] + (tmp > half ? val - tmp : -tmp);
  697. }
  698. return out;
  699. }
  700.  
  701. function getHueDelta(rgb1, rgb2, nominal) {
  702. var _Math = _math;
  703.  
  704. return (_Math.max(rgb1.r - rgb2.r, rgb2.r - rgb1.r) +
  705. _Math.max(rgb1.g - rgb2.g, rgb2.g - rgb1.g) +
  706. _Math.max(rgb1.b - rgb2.b, rgb2.b - rgb1.b)) * (nominal ? 255 : 1) / 765;
  707. }
  708.  
  709. function getLuminance(rgb, normalized) {
  710. var div = normalized ? 1 : 255,
  711. RGB = [rgb.r / div, rgb.g / div, rgb.b / div],
  712. luminance = _instance.options.luminance;
  713.  
  714. for (var i = RGB.length; i--; ) {
  715. RGB[i] = RGB[i] <= 0.03928 ? RGB[i] / 12.92 : _math.pow(((RGB[i] + 0.055) / 1.055), 2.4);
  716. }
  717. return ((luminance.r * RGB[0]) + (luminance.g * RGB[1]) + (luminance.b * RGB[2]));
  718. }
  719.  
  720. function mixColors(topColor, bottomColor, topAlpha, bottomAlpha) {
  721. var newColor = {},
  722. alphaTop = (topAlpha !== undefined ? topAlpha : 1),
  723. alphaBottom = (bottomAlpha !== undefined ? bottomAlpha : 1),
  724. alpha = alphaTop + alphaBottom * (1 - alphaTop); // 1 - (1 - alphaTop) * (1 - alphaBottom);
  725.  
  726. for(var n in topColor) {
  727. newColor[n] = (topColor[n] * alphaTop + bottomColor[n] * alphaBottom * (1 - alphaTop)) / alpha;
  728. }
  729. newColor.a = alpha;
  730. return newColor;
  731. }
  732.  
  733. function getWCAG2Ratio(lum1, lum2) {
  734. var ratio = 1;
  735.  
  736. if (lum1 >= lum2) {
  737. ratio = (lum1 + 0.05) / (lum2 + 0.05);
  738. } else {
  739. ratio = (lum2 + 0.05) / (lum1 + 0.05);
  740. }
  741. return _math.round(ratio * 100) / 100;
  742. }
  743.  
  744. function limitValue(value, min, max) {
  745. // return Math.max(min, Math.min(max, value)); // faster??
  746. return (value > max ? max : value < min ? min : value);
  747. }
  748. })(window);
  749.  
  750. /*! colorPicker.data.js */
  751. ;(function(window, undefined){
  752. "use strict"
  753.  
  754. // see colorPicker.html for the following encrypted variables... will only be used in buildView()
  755. var _html = ('^§app alpha-bg-w">^§slds">^§sldl-1">$^§sldl-2">$^§sldl-3">$^§curm">$^§sldr-1">$^§sldr-2">$^§sldr-4">$^§curl">$^§curr">$$^§opacity">|^§opacity-slider">$$$^§memo">^§raster">$^§raster-bg">$|$|$|$|$|$|$|$|$^§memo-store">$^§memo-cursor">$$^§panel">^§hsv">^hsl-mode §ß">$^hsv-h-ß §ß">H$^hsv-h-~ §~">-^§nsarrow">$$^hsl-h-@ §@">H$^hsv-s-ß §ß">S$^hsv-s-~ §~">-$^hsl-s-@ §@">S$^hsv-v-ß §ß">B$^hsv-v-~ §~">-$^hsl-l-@ §@">L$$^§hsl §hide">^hsv-mode §ß">$^hsl-h-ß §ß">H$^hsl-h-~ §~">-$^hsv-h-@ §@">H$^hsl-s-ß §ß">S$^hsl-s-~ §~">-$^hsv-s-@ §@">S$^hsl-l-ß §ß">L$^hsl-l-~ §~">-$^hsv-v-@ §@">B$$^§rgb">^rgb-r-ß §ß">R$^rgb-r-~ §~">-$^rgb-r-@ §ß">&nbsp;$^rgb-g-ß §ß">G$^rgb-g-~ §~">-$^rgb-g-@ §ß">&nbsp;$^rgb-b-ß §ß">B$^rgb-b-~ §~">-$^rgb-b-@ §ß">&nbsp;$$^§cmyk">^Lab-mode §ß">$^cmyk-c-ß §@">C$^cmyk-c-~ §~">-$^Lab-L-@ §@">L$^cmyk-m-ß §@">M$^cmyk-m-~ §~">-$^Lab-a-@ §@">a$^cmyk-y-ß §@">Y$^cmyk-y-~ §~">-$^Lab-b-@ §@">b$^cmyk-k-ß §@">K$^cmyk-k-~ §~">-$^Lab-x-@ §ß">&nbsp;$$^§Lab §hide">^cmyk-mode §ß">$^Lab-L-ß §@">L$^Lab-L-~ §~">-$^cmyk-c-@ §@">C$^Lab-a-ß §@">a$^Lab-a-~ §~">-$^cmyk-m-@ §@">M$^Lab-b-ß §@">b$^Lab-b-~ §~">-$^cmyk-y-@ §@">Y$^Lab-x-ß §@">&nbsp;$^Lab-x-~ §~">-$^cmyk-k-@ §@">K$$^§alpha">^alpha-ß §ß">A$^alpha-~ §~">-$^alpha-@ §ß">W$$^§HEX">^HEX-ß §ß">#$^HEX-~ §~">-$^HEX-@ §ß">M$$^§ctrl">^§raster">$^§cont">$^§cold">$^§col1">|&nbsp;$$^§col2">|&nbsp;$$^§bres">RESET$^§bsav">SAVE$$$^§exit">$^§resize">$^§resizer">|$$$').
  756. replace(/\^/g, '<div class="').replace(/\$/g, '</div>').replace(/~/g, 'disp').replace(/ß/g, 'butt').replace(/@/g, 'labl').replace(/\|/g, '<div>'),
  757. _cssFunc = ('är^1,äg^1,äb^1,öh^1,öh?1,öh?2,ös?1,öv?1,üh^1,üh?1,üh?2,üs?1,ül?1,.no-rgb-r är?2,.no-rgb-r är?3,.no-rgb-r är?4,.no-rgb-g äg?2,.no-rgb-g äg?3,.no-rgb-g äg?4,.no-rgb-b äb?2,.no-rgb-b äb?3,.no-rgb-b äb?4{visibility:hidden}är^2,är^3,äg^2,äg^3,äb^2,äb^3{@-image:url(_patches.png)}.§slds div{@-image:url(_vertical.png)}öh^2,ös^1,öv^1,üh^2,üs^1,ül^1{@-image:url(_horizontal.png)}ös?4,öv^3,üs?4,ül^3{@:#000}üs?3,ül^4{@:#fff}är?1{@-color:#f00}äg?1{@-color:#0f0}äb?1{@-color:#00f}är^2{@|-1664px 0}är^3{@|-896px 0}är?1,äg?1,äb?1,öh^3,ös^2,öv?2Ü-2432Öär?2Ü-2944Öär?3Ü-4480Öär?4Ü-3202Öäg^2Äöh^2{@|-640px 0}äg^3{@|-384px 0}äg?2Ü-4736Öäg?3Ü-3968Öäg?4Ü-3712Öäb^2{@|-1152px 0}äb^3{@|-1408px 0}äb?2Ü-3456Öäb?3Ü-4224Öäb?4Ü-2688Ööh^2Äär^3Ääb?4Ü0}öh?4,üh?4Ü-1664Öös^1,öv^1,üs^1,ül^1Ääg^3{@|-256px 0}ös^3,öv?4,üs^3,ül?4Ü-2176Öös?2,öv^2Ü-1920Öüh^2{@|-768px 0}üh^3,üs^2,ül?2Ü-5184Öüs?2,ül^2Ü-5824Ö.S är^2{@|-128px -128Ö.S är?1Ääg?1Ääb?1Äöh^3Äös^2Äöv?2Ü-1408Ö.S är?2Ääb^3Ü-128Ö.S är?3Ü-896Ö.S är?4Ü-256Ö.S äg^2{@|-256px -128Ö.S äg?2Ü-1024Ö.S äg?3Ü-640Ö.S äg?4Ü-512Ö.S äb^2{@|-128px 0}.S äb?2Ü-384Ö.S äb?3Ü-768Ö.S öh?4Äüh?4Ü-1536Ö.S ös^1Äöv^1Äüs^1Äül^1{@|-512px 0}.S ös^3Äöv?4Äüs^3Äül?4Ü-1280Ö.S ös?2Äöv^2Ü-1152Ö.S üh^2{@|-1024px 0}.S üh^3Äüs^2Äül?2Ü-5440Ö.S üs?2Äül^2Ü-5696Ö.XXS ös^2,.XXS öv?2Ü-5120Ö.XXS ös^3,.XXS öv?4,.XXS üs^3,.XXS ül^3,.XXS ül?4Ü-5056Ö.XXS ös?2,.XXS öv^2Ü-4992Ö.XXS üs^2,.XXS ül?2Ü-5568Ö.XXS üs?2,.XXS ül^2Ü-5632Ö').
  758. replace(/Ü/g, '{@|0 ').replace(/Ö/g, 'px}').replace(/Ä/g, ',.S ').replace(/\|/g, '-position:').replace(/@/g, 'background').replace(/ü/g, '.hsl-').replace(/ö/g, '.hsv-').replace(/ä/g, '.rgb-').replace(/~/g, ' .no-rgb-}').replace(/\?/g, ' .§sldr-').replace(/\^/g, ' .§sldl-'),
  759. _cssMain = ('∑{@#bbb;font-family:monospace, "Courier New", Courier, mono;font-size:12¥line-ä15¥font-weight:bold;cursor:default;~412¥ä323¥?top-left-radius:7¥?top-Ü-radius:7¥?bottom-Ü-radius:7¥?bottom-left-radius:7¥ö@#444}.S{~266¥ä177px}.XS{~158¥ä173px}.XXS{ä105¥~154px}.no-alpha{ä308px}.no-alpha .§opacity,.no-alpha .§alpha{display:none}.S.no-alpha{ä162px}.XS.no-alpha{ä158px}.XXS.no-alpha{ä90px}∑,∑ div{border:none;padding:0¥float:none;margin:0¥outline:none;box-sizing:content-box}∑ div{|absolute}^s .§curm,«§disp,«§nsarrow,∑ .§exit,∑ ø-cursor,∑ .§resize{öimage:url(_icons.png)}∑ .do-drag div{cursor:none}∑ .§opacity,ø .§raster-bg,∑ .§raster{öimage:url(_bgs.png)}∑ ^s{~287¥ä256¥top:10¥left:10¥overflow:hidden;cursor:crosshair}.S ^s{~143¥ä128¥left:9¥top:9px}.XS ^s{left:7¥top:7px}.XXS ^s{left:5¥top:5px}^s div{~256¥ä256¥left:0px}.S ^l-1,.S ^l-2,.S ^l-3,.S ^l-4{~128¥ä128px}.XXS ^s,.XXS ^s ^l-1,.XXS ^s ^l-2,.XXS ^s ^l-3,.XXS ^s ^l-4{ä64px}^s ^r-1,^s ^r-2,^s ^r-3,^s ^r-4{~31¥left:256¥cursor:default}.S ^r-1,.S ^r-2,.S ^r-3,.S ^r-4{~15¥ä128¥left:128px}^s .§curm{margin:-5¥~11¥ä11¥ö|-36px -30px}.light .§curm{ö|-7px -30px}^s .§curl,^s .§curr{~0¥ä0¥margin:-3px -4¥border:4px solid;cursor:default;left:auto;öimage:none}^s .§curl,∑ ^s .§curl-dark,.hue-dark div.§curl{Ü:27¥?@† † † #fff}.light .§curl,∑ ^s .§curl-light,.hue-light .§curl{?@† † † #000}.S ^s .§curl,.S ^s .§curr{?~3px}.S ^s .§curl-light,.S ^s .§curl{Ü:13px}^s .§curr,∑ ^s .§curr-dark{Ü:4¥?@† #fff † †}.light .§curr,∑ ^s .§curr-light{?@† #000 † †}∑ .§opacity{bottom:44¥left:10¥ä10¥~287¥ö|0 -87px}.S .§opacity{bottom:27¥left:9¥~143¥ö|0 -100px}.XS .§opacity{left:7¥bottom:25px}.XXS .§opacity{left:5¥bottom:23px}.§opacity div{~100%;ä16¥margin-top:-3¥overflow:hidden}.§opacity .§opacity-slider{margin:0 -4¥~0¥ä8¥?~4¥?style:solid;?@#eee †}∑ ø{bottom:10¥left:10¥~288¥ä31¥ö@#fff}.S ø{ä15¥~144¥left:9¥bottom:9px}.XS ø{left:7¥bottom:7px}.XXS ø{left:5¥bottom:5px}ø div{|relative;float:left;~31¥ä31¥margin-Ü:1px}.S ø div{~15¥ä15px}∑ .§raster,ø .§raster-bg,.S ø .§raster,.S ø .§raster-bg{|absolute;top:0¥Ü:0¥bottom:0¥left:0¥~100%}.S ø .§raster-bg{ö|0 -31px}∑ .§raster{opacity:0.2;ö|0 -49px}.alpha-bg-b ø{ö@#333}.alpha-bg-b .§raster{opacity:1}ø ø-cursor{|absolute;Ü:0¥ö|-26px -87px}∑ .light ø-cursor{ö|3px -87px}.S ø-cursor{ö|-34px -95px}.S .light ø-cursor{ö|-5px -95px}∑ .§panel{|absolute;top:10¥Ü:10¥bottom:10¥~94¥?~1¥?style:solid;?@#222 #555 #555 #222;overflow:hidden;ö@#333}.S .§panel{top:9¥Ü:9¥bottom:9px}.XS .§panel{display:none}.§panel div{|relative}«§hsv,«§hsl,«§rgb,«§cmyk,«§Lab,«§alpha,.no-alpha «§HEX,«§HEX{~86¥margin:-1px 0px 1px 4¥padding:1px 0px 3¥?top-~1¥?top-style:solid;?top-@#444;?bottom-~1¥?bottom-style:solid;?bottom-@#222;float:Ö«§hsv,«§hsl{padding-top:2px}.S .§hsv,.S .§hsl{padding-top:1px}«§HEX{?bottom-style:none;?top-~0¥margin-top:-4¥padding-top:0px}.no-alpha «§HEX{?bottom-style:none}«§alpha{?bottom-style:none}.S .rgb-r .§hsv,.S .rgb-g .§hsv,.S .rgb-b .§hsv,.S .rgb-r .§hsl,.S .rgb-g .§hsl,.S .rgb-b .§hsl,.S .hsv-h .§rgb,.S .hsv-s .§rgb,.S .hsv-v .§rgb,.S .hsl-h .§rgb,.S .hsl-s .§rgb,.S .hsl-l .§rgb,.S .§cmyk,.S .§Lab{display:none}«§butt,«§labl{float:left;~14¥ä14¥margin-top:2¥text-align:center;border:1px solid}«§butt{?@#555 #222 #222 #555}«§butt:active{ö@#444}«§labl{?@†}«Lab-mode,«cmyk-mode,«hsv-mode,«hsl-mode{|absolute;Ü:0¥top:1¥ä50px}«hsv-mode,«hsl-mode{top:2px}«cmyk-mode{ä68px}.hsl-h .hsl-h-labl,.hsl-s .hsl-s-labl,.hsl-l .hsl-l-labl,.hsv-h .hsv-h-labl,.hsv-s .hsv-s-labl,.hsv-v .hsv-v-labl{@#f90}«cmyk-mode,«hsv-mode,.rgb-r .rgb-r-butt,.rgb-g .rgb-g-butt,.rgb-b .rgb-b-butt,.hsv-h .hsv-h-butt,.hsv-s .hsv-s-butt,.hsv-v .hsv-v-butt,.hsl-h .hsl-h-butt,.hsl-s .hsl-s-butt,.hsl-l .hsl-l-butt,«rgb-r-labl,«rgb-g-labl,«rgb-b-labl,«alpha-butt,«HEX-butt,«Lab-x-labl{?@#222 #555 #555 #222;ö@#444}.no-rgb-r .rgb-r-labl,.no-rgb-g .rgb-g-labl,.no-rgb-b .rgb-b-labl,.mute-alpha .alpha-butt,.no-HEX .HEX-butt,.cmy-only .Lab-x-labl{?@#555 #222 #222 #555;ö@#333}.Lab-x-disp,.cmy-only .cmyk-k-disp,.cmy-only .cmyk-k-butt{visibility:hidden}«HEX-disp{öimage:none}«§disp{float:left;~48¥ä14¥margin:2px 2px 0¥cursor:text;text-align:left;text-indent:3¥?~1¥?style:solid;?@#222 #555 #555 #222}∑ .§nsarrow{|absolute;top:0¥left:-13¥~8¥ä16¥display:none;ö|-87px -23px}∑ .start-change .§nsarrow{display:block}∑ .do-change .§nsarrow{display:block;ö|-87px -36px}.do-change .§disp{cursor:default}«§hide{display:none}«§cont,«§cold{|absolute;top:-5¥left:0¥ä3¥border:1px solid #333}«§cold{z-index:1;ö@#c00}«§cont{margin-Ü:-1¥z-index:2}«contrast .§cont{z-index:1;ö@#ccc}«orange .§cold{ö@#f90}«green .§cold{ö@#4d0}«§ctrl{|absolute;bottom:0¥left:0¥~100%;ö@#fff}.alpha-bg-b .§ctrl,«§bres,«§bsav{ö@#333}«§col1,«§col2,«§bres,«§bsav{?~1¥?style:solid;?@#555 #222 #222 #555;float:left;~45¥line-ä28¥text-align:center;top:0px}.§panel div div{ä100%}.S .§ctrl div{line-ä25px}.S «§bres,.S «§bsav{line-ä26px}∑ .§exit,∑ .§resize{Ü:3¥top:3¥~15¥ä15¥ö|0 -52px}∑ .§resize{top:auto;bottom:3¥cursor:nwse-resize;ö|-15px -52px}.S .§exit{ö|1px -52px}.XS .§resize,.XS .§exit{~10¥ä10¥Ü:0¥öimage:none}.XS .§exit{top:0px}.XS .§resize{bottom:0px}∑ .§resizer,∑ .§resizer div{|absolute;border:1px solid #888;top:-1¥Ü:-1¥bottom:-1¥left:-1¥z-index:2;display:none;cursor:nwse-resize}∑ .§resizer div{border:1px dashed #333;opacity:0.3;display:block;ö@#bbb}').
  760. replace(/Ü/g, 'right').replace(/Ö/g, 'left}').replace(/∑/g, '.§app').replace(/«/g, '.§panel .').replace(/¥/g, 'px;').replace(/\|/g, 'position:').replace(/@/g, 'color:').replace(/ö/g, 'background-').replace(/ä/g, 'height:').replace(/ø/g, '.§memo').replace(/†/g, 'transparent').replace(/\~/g, 'width:').replace(/\?/g, 'border-').replace(/\^/g, '.§sld'),
  761. _horizontalPng = 'iVBORw0KGgoAAAANSUhEUgAABIAAAAABCAYAAACmC9U0AAABT0lEQVR4Xu2S3Y6CMBCFhyqIsjGBO1/B9/F5DC/pK3DHhVkUgc7Zqus2DVlGU/cnQZKTjznttNPJBABA149HyRf1iN//4mIBCg0jV4In+j9xJiuihly1V/Z9X88v//kNeDXVvyO/lK+IPR76B019+1Riab3H1zkmeqerKnL+Bzwxx6PAgZxaSQU8vB62T28pxcQeRQ2sHw6GxCOWHvP78zwHAARBABOfdYtd30rwxXOEPDF+dj2+91r6vV/id3k+/brrXmaGUkqKhX3i+ffSt16HQ/dorTGZTHrs7ev7Tl7XdZhOpzc651nfsm1bRFF0YRiGaJoGs9nsQuN/xafTCXEco65rzOdzHI9HJEmCqqqwXC6x3++RZRnKssRqtUJRFFiv19jtdthutyAi5Hl+Jo9VZg7+7f3yXuvZf5c3KaXYzByb+WIzO5ymKW82G/0BNcFhO/tOuuMAAAAASUVORK5CYII=',
  762. _verticalPng = 'iVBORw0KGgoAAAANSUhEUgAAAAEAABfACAYAAABn2KvYAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABHtJREFUeNrtnN9SqzAQxpOF1to6zuiVvoI+j6/gva/lA/kKeqUzjtX+QTi7SzSYBg49xdIzfL34+e1usoQQklCnmLwoCjImNwDQA2xRGMqNAYB+gPEH9IdCgIUA6Aem0P1fLoMQAPYNHYDoCKAv8OMHFgKgX2AjDPQDXn4t1l+gt/1fId//yWgE/hUJ+mAn8EyY5wCwXxhrbaHzn8E9iPlv79DdHxXTqciZ4KROnXRVZMF/6U2OPhcEavtAbZH1SM7wRDD7VoHZItCiyEQf4t6+MW9UOxaZybmdCGKqNrB9Eb5SfMg3wTyiagMtigTmWofiSDCOYNTSNz6sLDIoaCU9GWDd0tdhoMMsRm+r8U/EfB0GfjmLXiqzimDd0tdhoLMsI7la45+I+ToM/HIW0kfGVQTrlr7tA91kaUr//fxrKo8jUFB7VAn6AKpHJf+EKwAAAIYD/f7F7/8MVgMo7P+gBqDKr57Lf72V8x8AAMDgYIuvH4EAAAAMDQX6AACAQcI9GGMjDADA4MA/P2KlP8IEAAAYFCz6AACAgaLA8y8AAIN+CMYXoQAADA7u/UPYCAMAMDjI7z9S+SdwDFQX2C9Gh9GMEOWriz8/Pw1lWQZsi/L3R4czzP678Ve+P8f9nCv/C7hwLq99ah8NfKrU15zPB5pVcwtiJt9qGy0IfEE+jQa+Fn0VtI/fkxUPqBlEfRENeF+tqUpbGpi1iu8epwJzvV5XA4GpWC6XGz7F+/u766EgwJ+ckiTJKU3TnI6OjnI6OzvLZf6zMggt3dzckPhIoiTlSGpQ+eEsVegdz0fbCCi4fRs+Po+4yWdeDXiT+6pBSTeHple1pkz3FZ+avpyavoiPxgLN0B7yprY08PlyQTTm0+PWmkH7ynedNKraar4F/lRj1WpTtYh+ozL/cY2sAvZl0gcbZm0gSLBLvkxGoaogiy/HDXemQk2t5pUm8OAhH8/HH6e0mkJ9q9XKKQXfb07xfZnJbZrRxcVFVt6/t7e3Kc1ms5RGo1Eq5VIZuyl9fHw4k/M5xYeoKj64A7eqCt1ZeqWFVSl8NV9OTV3fmvP5qE9VmzSoEcsXpArK1UHen/hZbgL53BZSdyEXalGau/hU8TEW0u3VcoFPy3EDFrTgT+njydeZ0+l0UV7fu7u7iVzziQQmUm4iqRw4n/NxMxw4s/Mp1NSALxf4NEtQ10cjMDwSl+b+/j6hp6enVGb+jUvrn05iKobm6PboOt8vPISY5Pr6OqGXlxe3fOokoGtAbMUJZmqvYmaLQDP+sdrecOjtO/SXeH69P8Imutm5urqy9PDwYOny8tLS4+OjpfPzc0vPz8+WTk9PLb2+vlpZbCzN53NLx8fHVtYZS5PJxMoEZWWqsjKULY3HYytTi1Pex5OMldXKRVXxuLcy/20onmms3BBOxcr5qCrZtsrd45SPel8sGlOxGoGy0neynQ6VL9fsa1YtWlCrtj9G83G7PjdVush5n5q1iJWLZW6u21a1bUvbVnVzlru0pe3RdmlV1/23fZtbZv4Dx+7FBypx77kAAAAASUVORK5CYII=',
  763. _patchesPng = ('iVBORw0KGgo^NSUhEUgAAB4^EACAI#DdoPxz#L0UlEQVR4Xu3cQWrDQBREwR7FF8/BPR3wXktnQL+KvxfypuEhvLJXcp06d/bXd71OPt+trIw95zr33Z1bk1/fudEv79wa++7OfayZ59wrO2PBzklcGQmAZggAAOBYgAYBmpWRAGg^BGgRofAENgAAN#I0CBA6w8AG^ECABgEa/QH§AI0CNDoDwAY^QIAGAVp/AM§AjQI0OgPAAY^QoEGARn8Aw§CNAjQ+gMABg#BCgQYCmGQmABgAAEKBBgEZ/AM§AjQI0PoDAAY^QoEGARn8AM^IAADQI0+gMABg#BCgQYDWHwAw^gAANAjT6A4AB^BGgQoNEfAD^C#0CtP4AgAE^EaBCgaUYCoAE#RoEKDRHwAw^gAANArT+AIAB^BGgQoNEfAAw^gQIMAjf4AgAE^EaBCg9QcAD^CBAgwCN/gBg§EaBGj0BwAM^IECDAK0/AG§ARoEaJqRAGg^BGgRo9AcAD^CBAgwCtPwBg§EaBGj0BwAD^CNAgQKM/AG§ARoEaP0BAAM^I0CBAoz8AG^ECABgEa/QEAAw^jQIEDrDwAY^QIAGAZpmJACaBw^RoEKD1BwAM^IECDAK0/AG§ARoEaPQHAAw^gQIMArT8AY§BGgRo/QEAAw^jQIECjPwBg§EaBGj9AQAD^CNAgQOsPABg#BAgAYBGv0BAANwCwAAGB6gYeckmpEAa^AEaBGj0BwAM^IECDAK0/AG§ARoEaPQHAAM^I0CBAoz8AY§BGgRo/QEAAw^jQIECjPwAY^QIAGARr9AQAD^CNAgQOsPABg#BAgAYBmmYkABoAAECABgEa/QEAAw^jQIEDrDwAY^QIAGARr9Ac§AjQI0OgPABg#BAgAYBWn8Aw§CNAjQ6A8ABg#BCgQYBGfwD§AI0CND6AwAG^EKBBgKYZCYAG#QoEGARn8Aw§CNAjQ+gMABg#BCgQYBGfwAw^gAANAjT6AwAG^EKBBgNYfAD^C#0CNPoDgAE^EaBCg0R8AM^IAADQK0/gCAAQ^RoEKBpRgKgAQAABGgQoNEfAD^C#0CtP4AgAE^EaBCg0R8AD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AG§ARoEaPQHAAw^gQIMArT8AY§BGgRomsMAM^IAADQK0/gCAAQ^RoEKDRHwAw^gAANO7fQHwAw^gAANArT+AIAB^BGgQoNEfAGg^BGgRo9AcAD^CBAgwCtPwBg§EaBGj0BwAD^RIB+Ntg5iea5AD^DAIwI0CND6AwAG^EKBBgEZ/AKAB#EaBCg0R8AM^IAADQK0/gCAAQ^RoEKDRHwAM^IECDAI3+AIAB^BGgQoPUHAAw^gQIMAjf4AY§BGgRo9AcAD^CBAgwCtPwBg§EaBGiakQBo^ARoEaPQHAAw^gQIMArT8AY§BGgRo9AcAAw^jQIECjPwBg§EaBGj9AQAD^CNAgQKM/ABg#BAgAYBGv0BAAM^I0CBA6w8AG^ECABgGaZiQAGgAAQIAGARr9AQAD^CNAgQOsPABg#BAgAYBGv0Bw§CNAjQ6A8AG^ECABgFafwD§AI0CNDoDwAG^EKBBgEZ/AM§AjQI0PoDAAY^QoEGApjkMAAM^I0CBA6w8AG^ECABgEa/QEAAw^jQsIP+AIAB^BGgQoPUHAAw^gQIMAjf4AgAE#Bea/fK+3P5/3PJOvh8t1cO4nflmQAQoAEAAF9Aw/7JHfQHAAw^gQIMArT8AY§BGvwHNPoDAA0AACBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AG§ARoEaPQHAAw^gQIMArT8AY§BGgRo9AcAAw^jQIECjPwBg§EaBGj9AQAD^CNAgQNOMBEAD#I0CBAoz8AY§BGgRo/QEAAw^jQIECjPwAY^QIAGARr9AQAD^CNAgQOsPABg#BAgAYBGv0Bw§CNAjQ6A8AG^ECABgFafwD§AI0CNA0IwHQ^AjQI0OgPABg#BAgAYBWn8Aw§CNAjQ6A8ABg#BCgQYBGfwD§AI0CND6AwAG^EKBBgEZ/AD^C#0CNPoDAAY^QoEGA1h8AM^IAADQI0DQAG^EKBBgEZ/AM§AjQI0PoDAAY^QoEGA1h8AM^IAADQI0+gMABg#BCgQYDWHwAw^gAANArT+AIAB^BGgQoNEfAD^C#0CtP4AgAE^EaBCg9QcAD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAK0/AG§ARoEaPQHAAw^gQIMArT8AY§BGgRo/QEAAw^jQIECjPwBgACDhFgC#07t9AfAD^C#0CtP4AgAE^EaBCg0R8Aa^AEaBGj0BwAM^IECDAK0/AG§ARoEaPQHAAM^I0CBAoz8AY§BGgRo/QEAAw^jQIECjPwAY^QIAGARr9AQAD^CNAgQOsPABg#BAgAYBmmYkABoAAECABgEa/QEAAw^jQIEDrDwAY^QIAGARr9Ac§AjQI0OgPABg#BAgAYBWn8Aw§CNAjQ6A8ABg#BCgQYBGfwD§AI0CND6AwAG^EKBBgKYZCYAG#QoEGARn8Aw§CNAjQ+gMABg#BCgQYBGfwAw^gAANAjT6AwAG^EKBBgNYfAD^C#0CNPoDgAE^EaBCg0R8AM^IAADQK0/gCAAQ^RoEKBpRgKgAQAABGgQoNEfAD^C#0CtP4AgAE^EaBCg0R8AD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AG§ARoEaPQHAAw^gQIMArT8AY§BGgRommEAM^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAI3+AIAB^ARoEaPQHAAw^gQIMArT8AY§BGgRo9AcAGgAAQICGCNBfRfNcABg#BgeICGnVvoDwAY^QIAGAVp/AM§AjQI0OgPADQAAIAADQI0+gMABg#BCgQYDWHwAw^gAANAjT6A4AB^BGgQoNEfAD^C#0CtP4AgAE^EaBCg0R8AD^CBAgwCN/gCAAQ^RoEKD1BwAM^IECDAE0zEgAN#gQIMAjf4AgAE^EaBCg9QcAD^CBAgwCN/gBg§EaBGj0BwAM^IECDAK0/AG§ARoEaPQHAAM^I0CBAoz8AY§BGgRo/QEAAw^jQIEDTjARAAwAACNAgQKM/AG§ARoEaP0BAAM^I0CBAoz8AG^ECABgEa/QEAAw^jQIEDrDwAY^QIAGARr9Ac§AjQI0OgPABg#BAgAYBWn8Aw§CNAjQNIcBY§BGgRo/QEAAw^jQIECjPwBg§EadtAfAD^C#0CtP4AgAE^EaBCgAQABGgAA+AO2TAbHupOgH^ABJRU5ErkJggg==').
  764. replace(/§/g, 'AAAAAA').replace(/\^/g, 'AAAA').replace(/#/g, 'AAA'),
  765. _iconsPng = 'iVBORw0KGgoAAAANSUhEUgAAAGEAAABDCAMAAAC7vJusAAAAkFBMVEUAAAAvLy9ERERubm7///8AAAD///9EREREREREREREREQAAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8AAAD///8cHBwkJCQnJycoKCgpKSkqKiouLi4vLy8/Pz9AQEBCQkJDQ0NdXV1ubm58fHykpKRERERVVVUzMzPx7Ab+AAAAHXRSTlMAAAAAAAQEBQ4QGR4eIyMtLUVFVVVqapKSnJy7u9JKTggAAAFUSURBVHja7dXbUoMwEAbgSICqLYeW88F6KIogqe//dpoYZ0W4AXbv8g9TwkxmvtndZMrEwlw/F8YIRjCCEYxgBCOsFmzqGMEI28J5zzmt0Pc9rdDL0NYgMxIYC5KiKpKAzZphWtZlGm4SjlnkOV6UHeeEUx77rh/npw1dCrI9k9lnwUwF+UG9D3m4ftJJxH4SJdPtaawXcbr+tBaeFrxiur309cIv19+4ytGCU0031a5euPVigLYGqjlAqM4ShOQ+QAYQUO80AMMAAkUGGfMfR9Ul+kmvPq2QGxXKOQBAKdjUgk0t2NiCGEVP+rHT3/iCUMBT90YrPMsKsIWP3x/VolaonJEETchHCS8AYAmaUICQQwaAQnjoXgHAES7jLkEFaHO4bdq/k25HAIpgWY34FwAE5xjCffM+D2DV8B0gRsAZT7hr5gE8wdrJcU+CJqhcqQD7Cx5L7Ph4WnrKAAAAAElFTkSuQmCC',
  766. _bgsPng = 'iVBORw0KGgoAAAANSUhEUgAAASAAAABvCAYAAABM+h2NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABORJREFUeNrs3VtTW1UYBuCEcxAI4YydWqTWdqr1V7T/2QsvvPDCCy9qjxZbamsrhZIQUHsCEtfafpmJe8qFjpUxfZ4Zuvt2feydJvAOARZUut1u5bRerl692nV913f99/f6QxWAU6KAAAUEKCAABQQoIAAFBCggAAUEKCAABQQoIAAFBCggAAUEKCAABQQoIEABASggQAEBKCBAAQEoIEABASggQAEBKCBAAQEoIGBQC+jatWvd07zxrv9+Xx8fAQEoIEABASggQAEBKCBAAQEoIEABAQoIQAEBCghAAQEKCEABAQOk2u36kS6AAgLetwJKL29toFRM1be+QrVq3rx58//KvM8BAadGAQEKCFBAAAoIGHwnfhneZ+/Nmzf/LufzrI+AAE/BAAUEoIAABQTwztgLZt68eXvBAE/BABQQoIAAFBAweOwFM2/evL1ggKdgAAoIUEAACggYPPaCmTdv3l4wwFMwAAUEKCAABQQMHnvBzJs3by8Y4CkYgAICFBCAAgIGz4lfBQNQQMDgFlCtVisaaHV1tThubW1VInciD0U+ysdnz54N5+PKysphOnRTHsvHlN9EHo/1l5FrkV9Enoz8W87b29tTOS8vLx9EnoncjlyPvBe5EbkZeT4fU96NvBDr2znv7Ows57y0tLQVeSXy08gf5mNfPhPrjyOfrVarlcXFxZ9yfv78+bl8TPlh5LU8n/KDyOuxfj/y+VjfyHl3d/dCKv28fi/yp/m4sLDwQ+SLke9GvhT5Tinfjnw5f4/F/Pz8rZybzeZn+ZjyzVK+EfnzUr4S+Xopf9/L+fxzc3M5d1qt1hf531Mu5k/IxzGf85VYL+fefHH+RqNRrO/t7RW3L+UbkS9Hvhk5/386Kd/qW8/5duRLMV/OdyJfzNebnZ0t7t92u53v/07K9yJfiLwROT9+ef7HyOux/iDyWuSHkT+K+eLtZX9//2xer9frjyOfyY9/Wn8S86v59qT1p7Ge315zLt4RU16K19+O9YXIu5HnYn435hux3opcj9yOPB3z+5E/iPXf43y1yMX778HBQS3f3pTz+28l5bHIr2N+LN3+zszMzGHkoh/S+mHMF98XlNaP8zHd/0W/pMe943NAwKlSQIACAhQQgAICFBCAAgIUEIACAhQQgAIC/n9GqtXqYbfbHa38+RtSu32llPdqdNL6aOSj+LfxyMVekLTem39Ryr/mPDQ0NBznzXtROikPRW6W8k7k3m9rzXthOsPDw73bUuylGRkZ6cR63nvTSfko8oPIr+Pnz96P/DLW816ezujoaN6DdtyX9+P8eS9QZ2xs7Hxf7qa8Xlr/JO6Ljcjrcf6cj1P+OO+N6V1/fHz8XLz+/Tjfubh+sZcorZ+N9Ycxfybyo8ircf6fc56YmFiJ1/8l8mLk7cjzkfP92U15Ns63G+u9nPcKdWq12lQ8Xu3Ixd6f9Pd8P3UmJycnUszzL2N9LM7/anNzs9V7Q2q32395w/q7ubdH6L/KrVbrpPxlKX9Vyl+X8jel/G0pf5f/aDabvXy9tH6ztH63lDdKebOUH5Xyk1LeKuWd/ry2tlap9P125Onp6Zf9eWpq6lW3b8f6zMzM6/71er3+ppSP+u/XNN/pz41Go+sjIMBTMEABASggQAEBKCBAAQEoIEABASggQAEB/CN/CDAAw78uW9AVDw4AAAAASUVORK5CYII=';
  767.  
  768. window.ColorPicker = {
  769. _html: _html,
  770. _cssFunc: _cssFunc,
  771. _cssMain: _cssMain,
  772. _horizontalPng: _horizontalPng,
  773. _verticalPng: _verticalPng,
  774. _patchesPng: _patchesPng,
  775. _iconsPng: _iconsPng,
  776. _bgsPng: _bgsPng
  777. }
  778. })(window);
  779.  
  780. /*! colorPicker.js */
  781. ;(function(window, undefined){
  782. "use strict"
  783.  
  784. var _data = window.ColorPicker, // will be deleted in buildView() and holds:
  785. // window.ColorPicker = { // comes from colorPicker.data.js and will be overwritten.
  786. // _html: ..., // holds the HTML markup of colorPicker
  787. // _cssFunc: ..., // CSS for all the sliders
  788. // _cssMain: ..., // CSS of the GUI
  789. // _horizontalPng: ..., // horizontal background images for sliders
  790. // _verticalPng: ..., // vertical background images for sliders
  791. // _patchesPng: ..., // background images for square sliders in RGB mode
  792. // _iconsPng: ..., // some icon sprite images
  793. // _bgsPng: ..., // some more icon sprite images
  794. // }
  795. _devMode = !_data, // if no _data we assume that colorPicker.data.js is missing (for development)
  796. _isIE = false,
  797. _doesOpacity = false,
  798. // _isIE8 = _isIE && document.querySelectorAll,
  799.  
  800. _valueRanges = {}, // will be assigned in initInstance() by Colors instance
  801. // _valueRanges = {
  802. // rgb: {r: [0, 255], g: [0, 255], b: [0, 255]},
  803. // hsv: {h: [0, 360], s: [0, 100], v: [0, 100]},
  804. // hsl: {h: [0, 360], s: [0, 100], l: [0, 100]},
  805. // cmyk: {c: [0, 100], m: [0, 100], y: [0, 100], k: [0, 100]},
  806. // cmy: {c: [0, 100], m: [0, 100], y: [0, 100]},
  807. // XYZ: {X: [0, 100], Y: [0, 100], Z: [0, 100]},
  808. // Lab: {L: [0, 100], a: [-128, 127], b: [-128, 127]},
  809. // alpha: {alpha: [0, 1]},
  810. // HEX: {HEX: [0, 16777215]}
  811. // },
  812. _bgTypes = {w: 'White', b: 'Black', c: 'Custom'},
  813.  
  814. _mouseMoveAction, // current mouseMove handler assigned on mouseDown
  815. _action = '', // needed for action callback; needed due to minification of javaScript
  816. _mainTarget, // target on mouseDown, might be parent element though...
  817. _valueType, // check this variable; gets missused/polutet over time
  818. _delayState = 1, // mouseMove offset (y-axis) in display elements // same here...
  819. _startCoords = {},
  820. _targetOrigin = {},
  821. _renderTimer, // animationFrame/interval variable
  822. _newData = true,
  823. // _txt = {
  824. // selection: document.selection || window.getSelection(),
  825. // range: (document.createRange ? document.createRange() : document.body.createTextRange())
  826. // },
  827.  
  828. _renderVars = {}, // used only in renderAll and convertColors
  829. _cashedVars = {}, // reset in initSliders
  830.  
  831. _colorPicker,
  832. _previousInstance, // only used for recycling purposes in buildView()
  833. _colorInstance = {},
  834. _colors = {},
  835. _options = {},
  836. _nodes = {},
  837.  
  838. _math = Math,
  839.  
  840. animationFrame = 'AnimationFrame', // we also need this later
  841. requestAnimationFrame = 'request' + animationFrame,
  842. cancelAnimationFrame = 'cancel' + animationFrame,
  843. vendors = ['ms', 'moz', 'webkit', 'o'],
  844. ColorPicker = function(options) { // as tiny as possible...
  845. this.options = {
  846. color: 'rgba(204, 82, 37, 0.8)',
  847. mode: 'rgb-b',
  848. fps: 60, // 1000 / 60 = ~16.7ms
  849. delayOffset: 8,
  850. CSSPrefix: 'cp-',
  851. allMixDetails: true,
  852. alphaBG: 'w',
  853. imagePath: ''
  854. // devPicker: false // uses existing HTML for development...
  855. // noAlpha: true,
  856. // customBG: '#808080'
  857. // size: 0,
  858. // cmyOnly: false,
  859. // initStyle: 'display: none',
  860.  
  861. // memoryColors: "'rgba(82,80,151,1)','rgba(100,200,10,0.5)','rgba(100,0,0,1)','rgba(0,0,0,1)'"
  862. // memoryColors: [{r: 100, g: 200, b: 10, a: 0.5}] //
  863.  
  864. // opacityPositionRelative: undefined,
  865. // customCSS: undefined,
  866. // appendTo: document.body,
  867. // noRangeBackground: false,
  868. // textRight: false, ?????
  869. // noHexButton: false,
  870. // noResize: false,
  871.  
  872. // noRGBr: false,
  873. // noRGBg: false,
  874. // noRGBb: false,
  875.  
  876. // ------ CSSStrength: 'div.',
  877. // XYZMatrix: XYZMatrix,
  878. // XYZReference: {},
  879. // grey: grey,
  880. // luminance: luminance,
  881.  
  882. // renderCallback: undefined,
  883. // actionCallback: undefined,
  884. // convertCallback: undefined,
  885. };
  886. initInstance(this, options || {});
  887. };
  888.  
  889. window.ColorPicker = ColorPicker; // export differently
  890. ColorPicker.addEvent = addEvent;
  891. ColorPicker.removeEvent = removeEvent;
  892. ColorPicker.getOrigin = getOrigin;
  893. ColorPicker.limitValue = limitValue;
  894. ColorPicker.changeClass = changeClass;
  895.  
  896. // ------------------------------------------------------ //
  897.  
  898. ColorPicker.prototype.setColor = function(newCol, type, alpha, forceRender) {
  899. focusInstance(this);
  900. _valueType = true; // right cursor...
  901. // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers
  902. preRenderAll(_colorInstance.setColor.apply(_colorInstance, arguments));
  903. if (forceRender) {
  904. this.startRender(true);
  905. }
  906. };
  907.  
  908. ColorPicker.prototype.saveAsBackground = function() {
  909. focusInstance(this);
  910. return saveAsBackground(true);
  911. };
  912.  
  913. ColorPicker.prototype.setCustomBackground = function(col) {
  914. focusInstance(this); // needed???
  915. return _colorInstance.setCustomBackground(col);
  916. };
  917.  
  918. ColorPicker.prototype.startRender = function(oneTime) {
  919. focusInstance(this);
  920. if (oneTime) {
  921. _mouseMoveAction = false; // prevents window[requestAnimationFrame] in renderAll()
  922. renderAll();
  923. this.stopRender();
  924. } else {
  925. _mouseMoveAction = 1;
  926. _renderTimer = window[requestAnimationFrame](renderAll);
  927. }
  928. };
  929.  
  930. ColorPicker.prototype.stopRender = function() {
  931. focusInstance(this); // check again
  932. window[cancelAnimationFrame](_renderTimer);
  933. if (_valueType) {
  934. // renderAll();
  935. _mouseMoveAction = 1;
  936. stopChange(undefined, 'external');
  937. // _valueType = undefined;
  938. }
  939. };
  940.  
  941. ColorPicker.prototype.setMode = function(mode) { // check again ... right cursor
  942. focusInstance(this);
  943. setMode(mode);
  944. initSliders();
  945. renderAll();
  946. };
  947.  
  948. ColorPicker.prototype.destroyAll = function() { // check this again...
  949. var html = this.nodes.colorPicker,
  950. destroyReferences = function(nodes) {
  951. for (var n in nodes) {
  952. if (nodes[n] && nodes[n].toString() === '[object Object]' || nodes[n] instanceof Array) {
  953. destroyReferences(nodes[n]);
  954. }
  955. nodes[n] = null;
  956. delete nodes[n];
  957. }
  958. };
  959.  
  960. this.stopRender();
  961. installEventListeners(this, true);
  962. destroyReferences(this);
  963. html.parentNode.removeChild(html);
  964. html = null;
  965. };
  966.  
  967. ColorPicker.prototype.renderMemory = function(memory) {
  968. var memos = this.nodes.memos,
  969. tmp = [];
  970.  
  971. if (typeof memory === 'string') { // revisit!!!
  972. memory = memory.replace(/^'|'$/g, '').replace(/\s*/, '').split('\',\'');
  973. }
  974. for (var n = memos.length; n--; ) { // check again how to handle alpha...
  975. if (memory && typeof memory[n] === 'string') {
  976. tmp = memory[n].replace('rgba(', '').replace(')', '').split(',');
  977. memory[n] = {r: tmp[0], g: tmp[1], b: tmp[2], a: tmp[3]}
  978. }
  979. memos[n].style.cssText = 'background-color: ' + (memory && memory[n] !== undefined ?
  980. color2string(memory[n]) + ';' + getOpacityCSS(memory[n]['a'] || 1) : 'rgb(0,0,0);');
  981. }
  982. };
  983.  
  984. // ------------------------------------------------------ //
  985.  
  986. function initInstance(THIS, options) {
  987. var exporter, // do something here..
  988. mode = '',
  989. CSSPrefix = '',
  990. optionButtons;
  991.  
  992. for (var option in options) { // deep copy ??
  993. THIS.options[option] = options[option];
  994. }
  995. _isIE = document.createStyleSheet !== undefined && document.getElementById || !!window.MSInputMethodContext;
  996. _doesOpacity = typeof document.body.style.opacity !== 'undefined';
  997. _colorInstance = new Colors(THIS.options);
  998. // We transfer the responsibility to the instance of Color (to save space and memory)
  999. delete THIS.options;
  1000. _options = _colorInstance.options;
  1001. _options.scale = 1;
  1002. CSSPrefix = _options.CSSPrefix;
  1003.  
  1004. THIS.color = _colorInstance; // check this again...
  1005. _valueRanges = _options.valueRanges;
  1006. THIS.nodes = _nodes = getInstanceNodes(buildView(THIS), THIS); // ha, ha,... make this different
  1007. setMode(_options.mode);
  1008. focusInstance(THIS);
  1009. saveAsBackground();
  1010.  
  1011. mode = ' ' + _options.mode.type + '-' + _options.mode.z;
  1012. _nodes.slds.className += mode;
  1013. _nodes.panel.className += mode;
  1014. //_nodes.colorPicker.className += ' cmy-' + _options.cmyOnly;
  1015.  
  1016. if (_options.noHexButton) {
  1017. changeClass(_nodes.HEX_butt, CSSPrefix + 'butt', CSSPrefix + 'labl');
  1018. }
  1019.  
  1020. if (_options.size !== undefined) {
  1021. resizeApp(undefined, _options.size);
  1022. }
  1023.  
  1024. optionButtons = {
  1025. alphaBG: _nodes.alpha_labl,
  1026. cmyOnly: _nodes.HEX_labl // test... take out
  1027. };
  1028. for (var n in optionButtons) {
  1029. if (_options[n] !== undefined) {
  1030. buttonActions({target: optionButtons[n], data: _options[n]});
  1031. }
  1032. }
  1033. if (_options.noAlpha) {
  1034. _nodes.colorPicker.className += ' no-alpha'; // IE6 ??? maybe for IE6 on document.body
  1035. }
  1036.  
  1037. THIS.renderMemory(_options.memoryColors);
  1038.  
  1039. installEventListeners(THIS);
  1040. _mouseMoveAction = true;
  1041. stopChange(undefined, 'init');
  1042.  
  1043. if (_previousInstance) {
  1044. focusInstance(_previousInstance);
  1045. renderAll();
  1046. }
  1047. }
  1048.  
  1049. function focusInstance(THIS) {
  1050. _newData = true;
  1051. if (_colorPicker !== THIS) {
  1052. _colorPicker = THIS;
  1053. _colors = THIS.color.colors;
  1054. _options = THIS.color.options;
  1055. _nodes = THIS.nodes;
  1056. _colorInstance = THIS.color;
  1057.  
  1058. _cashedVars = {};
  1059. preRenderAll(_colors);
  1060. }
  1061. }
  1062.  
  1063. function getUISizes() {
  1064. var sizes = ['L', 'S', 'XS', 'XXS'];
  1065. _options.sizes = {};
  1066. _nodes.testNode.style.cssText = 'position:absolute;left:-1000px;top:-1000px;';
  1067. document.body.appendChild(_nodes.testNode);
  1068. for (var n = sizes.length; n--; ) {
  1069. _nodes.testNode.className = _options.CSSPrefix + 'app ' + sizes[n];
  1070. _options.sizes[sizes[n]] = [_nodes.testNode.offsetWidth, _nodes.testNode.offsetHeight];
  1071. }
  1072. if (_nodes.testNode.removeNode) { // old IEs
  1073. _nodes.testNode.removeNode(true);
  1074. } else {
  1075. document.body.removeChild(_nodes.testNode);
  1076. }
  1077. }
  1078.  
  1079. function buildView(THIS) {
  1080. var app = document.createElement('div'),
  1081. prefix = _options.CSSPrefix,
  1082. urlData = 'data:image/png;base64,',
  1083. addStyleSheet = function(cssText, id) {
  1084. var style = document.createElement('style');
  1085.  
  1086. style.setAttribute('type', 'text/css');
  1087. if (id) {
  1088. style.setAttribute('id', id);
  1089. }
  1090. if (!style.styleSheet) {
  1091. style.appendChild(document.createTextNode(cssText));
  1092. }
  1093. document.getElementsByTagName('head')[0].appendChild(style);
  1094. if (style.styleSheet) { // IE compatible
  1095. document.styleSheets[document.styleSheets.length-1].cssText = cssText;
  1096. }
  1097. },
  1098. processCSS = function(doesBAS64){
  1099. // CSS - system
  1100. _data._cssFunc = _data._cssFunc.
  1101. replace(/§/g, prefix).
  1102. replace('_patches.png', doesBAS64 ? urlData + _data._patchesPng : _options.imagePath + '_patches.png').
  1103. replace('_vertical.png', doesBAS64 ? urlData + _data._verticalPng : _options.imagePath + '_vertical.png').
  1104. replace('_horizontal.png', doesBAS64 ? urlData + _data._horizontalPng :
  1105. _options.imagePath + '_horizontal.png');
  1106. addStyleSheet(_data._cssFunc, 'colorPickerCSS');
  1107. // CSS - main
  1108. if (!_options.customCSS) {
  1109. _data._cssMain = _data._cssMain.
  1110. replace(/§/g, prefix).
  1111. replace('_bgs.png', doesBAS64 ? urlData + _data._bgsPng : _options.imagePath + '_bgs.png').
  1112. replace('_icons.png', doesBAS64 ? urlData + _data._iconsPng : _options.imagePath + '_icons.png').
  1113. // replace('"Courier New",', !_isIE ? '' : '"Courier New",').
  1114. replace(/opacity:(\d*\.*(\d+))/g, function($1, $2){
  1115. return !_doesOpacity ? '-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=' +
  1116. _math.round(+$2 * 100) + ')";filter: alpha(opacity=' + _math.round(+$2 * 100) + ')' :
  1117. '-moz-opacity: ' + $2 + '; -khtml-opacity: ' + $2 + '; opacity: ' + $2;
  1118. });
  1119. // style.appendChild(document.createTextNode(_data._cssFunc));
  1120. addStyleSheet(_data._cssMain);
  1121. }
  1122. // for (var n in _data) { // almost 25k of memory ;o)
  1123. // _data[n] = null;
  1124. // }
  1125. },
  1126. test = document.createElement('img');
  1127.  
  1128. // development mode
  1129. if (_devMode) {
  1130. return THIS.color.options.devPicker;
  1131. }
  1132.  
  1133. // CSS
  1134. if (!document.getElementById('colorPickerCSS')) { // only once needed
  1135. test.onload = test.onerror = function(){
  1136. if (_data._cssFunc) {
  1137. processCSS(this.width === 1 && this.height === 1);
  1138. }
  1139. THIS.cssIsReady = true;
  1140. };
  1141. test.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
  1142. } else {
  1143. THIS.cssIsReady = true;
  1144. }
  1145.  
  1146. // HTML
  1147. if (_previousInstance = _colorPicker) {
  1148. // we need to be careful with recycling HTML as slider calssNames might have been changed...
  1149. initSliders();
  1150. }
  1151. // app.innerHTML = _colorPicker ? _colorPicker.nodes.colorPicker.outerHTML : _data._html.replace(/§/g, prefix);
  1152. // faster ... FF8.0 (2011) though (but IE4)
  1153. // outerHTML ... FF11 (2013)
  1154. app.insertAdjacentHTML('afterbegin',
  1155. _colorPicker ? _colorPicker.nodes.colorPicker.outerHTML ||
  1156. new XMLSerializer().serializeToString(_colorPicker.nodes.colorPicker) : // FF before F11
  1157. _data._html.replace(/§/g, prefix));
  1158. // _colorPicker ? _colorPicker.nodes.colorPicker.parentNode.innerHTML : _data._html.replace(/§/g, prefix));
  1159. // _data._html = null;
  1160.  
  1161. app = app.children[0];
  1162. app.style.cssText = _options.initStyle || ''; // for initial hiding...
  1163. // get a better addClass for this....
  1164. // app.className = app.className.split(' ')[0]; // cleanup for multy instances
  1165.  
  1166. return (_options.appendTo || document.body).appendChild(app);
  1167. }
  1168.  
  1169. function getInstanceNodes(colorPicker, THIS) { // check nodes again... are they all needed?
  1170. var all = colorPicker.getElementsByTagName('*'),
  1171. nodes = {colorPicker: colorPicker}, // length ?? // rename nodes.colorPicker
  1172. node,
  1173. className,
  1174. memoCounter = 0,
  1175. regexp = new RegExp(_options.CSSPrefix);
  1176.  
  1177. // nodes.displayStyles = {}; // not needed ... or change to CSS
  1178. nodes.styles = {};
  1179. // nodes.styles.displays = {};
  1180.  
  1181. nodes.textNodes = {};
  1182. nodes.memos = [];
  1183. nodes.testNode = document.createElement('div');
  1184.  
  1185. for (var n = 0, m = all.length; n < m; n++) {
  1186. node = all[n];
  1187. if ((className = node.className) && regexp.test(className)) {
  1188. className = className.split(' ')[0].replace(_options.CSSPrefix, '').replace(/-/g, '_');
  1189. if (/_disp/.test(className)) {
  1190. className = className.replace('_disp', '');
  1191. // nodes.styles.displays[className] = node.style;
  1192. nodes.styles[className] = node.style;
  1193. nodes.textNodes[className] = node.firstChild;
  1194. node.contentEditable = true; // does this slow down rendering??
  1195. } else {
  1196. if (!(/(?:hs|cmyk|Lab).*?(?:butt|labl)/.test(className))) {
  1197. nodes[className] = node;
  1198. }
  1199. if (/(?:cur|sld[^s]|opacity|cont|col)/.test(className)) {
  1200. nodes.styles[className] = /(?:col\d)/.test(className) ? node.children[0].style : node.style;
  1201. }
  1202. }
  1203. } else if (/memo/.test(node.parentNode.className)) {
  1204. nodes.memos.push(node);
  1205. }
  1206. }
  1207.  
  1208. // Chrome bug: focuses contenteditable on mouse over while dragging
  1209. nodes.panelCover = nodes.panel.appendChild(document.createElement('div'));
  1210.  
  1211. return nodes;
  1212. }
  1213.  
  1214. // ------------------------------------------------------ //
  1215. // ---- Add event listners to colorPicker and window ---- //
  1216. // -------------------------------------------------------//
  1217.  
  1218. function installEventListeners(THIS, off) {
  1219. var onOffEvent = off ? removeEvent : addEvent;
  1220.  
  1221. onOffEvent(_nodes.colorPicker, 'mousedown', function(e) {
  1222. var event = e || window.event,
  1223. page = getPageXY(event),
  1224. target = (event.button || event.which) < 2 ?
  1225. (event.target || event.srcElement) : {},
  1226. className = target.className;
  1227.  
  1228. focusInstance(THIS);
  1229. _mainTarget = target;
  1230. stopChange(undefined, 'resetEventListener');
  1231. _action = ''; // needed due to minification of javaScript
  1232.  
  1233. if (target === _nodes.sldl_3 || target === _nodes.curm) {
  1234. _mainTarget = _nodes.sldl_3;
  1235. _mouseMoveAction = changeXYValue;
  1236. _action = 'changeXYValue';
  1237. changeClass(_nodes.slds, 'do-drag');
  1238. } else if (/sldr/.test(className) || target === _nodes.curl || target === _nodes.curr) {
  1239. _mainTarget = _nodes.sldr_4;
  1240. _mouseMoveAction = changeZValue;
  1241. _action = 'changeZValue';
  1242. } else if (target === _nodes.opacity.children[0] || target === _nodes.opacity_slider) {
  1243. _mainTarget = _nodes.opacity;
  1244. _mouseMoveAction = changeOpacityValue;
  1245. _action = 'changeOpacityValue';
  1246. } else if (/-disp/.test(className) && !/HEX-/.test(className)) {
  1247. _mouseMoveAction = changeInputValue;
  1248. _action = 'changeInputValue';
  1249. (target.nextSibling.nodeType === 3 ? target.nextSibling.nextSibling : target.nextSibling).
  1250. appendChild(_nodes.nsarrow); // nextSibling for better text selection
  1251. _valueType = className.split('-disp')[0].split('-');
  1252. _valueType = {type: _valueType[0], z: _valueType[1] || ''};
  1253. changeClass(_nodes.panel, 'start-change');
  1254. _delayState = 0;
  1255. } else if (target === _nodes.resize && !_options.noResize) {
  1256. if (!_options.sizes) {
  1257. getUISizes();
  1258. }
  1259. _mainTarget = _nodes.resizer;
  1260. _mouseMoveAction = resizeApp;
  1261. _action = 'resizeApp';
  1262. } else {
  1263. _mouseMoveAction = undefined;
  1264. }
  1265.  
  1266. if (_mouseMoveAction) {
  1267. _startCoords = {pageX: page.X, pageY: page.Y};
  1268. _mainTarget.style.display = 'block'; // for resizer...
  1269. _targetOrigin = getOrigin(_mainTarget);
  1270. _targetOrigin.width = _nodes.opacity.offsetWidth; // ???????
  1271. _targetOrigin.childWidth = _nodes.opacity_slider.offsetWidth; // ???????
  1272. _mainTarget.style.display = ''; // ??? for resizer...
  1273. _mouseMoveAction(event);
  1274. addEvent(_isIE ? document.body : window, 'mousemove', _mouseMoveAction);
  1275. _renderTimer = window[requestAnimationFrame](renderAll);
  1276. } else {
  1277. // console.log(className)
  1278. // console.log(THIS.nodes[className.split(' ')[0].replace('cp-', '').replace('-', '_')])
  1279. // resize, button states, etc...
  1280. }
  1281.  
  1282. // if (_mouseMoveAction !== changeInputValue) preventDefault(event);
  1283. if (!/-disp/.test(className)) {
  1284. return preventDefault(event);
  1285. // document.activeElement.blur();
  1286. }
  1287. });
  1288.  
  1289. onOffEvent(_nodes.colorPicker, 'click', function(e) {
  1290. focusInstance(THIS);
  1291. buttonActions(e);
  1292. });
  1293.  
  1294. onOffEvent(_nodes.colorPicker, 'dblclick', buttonActions);
  1295.  
  1296. onOffEvent(_nodes.colorPicker, 'keydown', function(e) {
  1297. focusInstance(THIS);
  1298. keyControl(e);
  1299. });
  1300.  
  1301. // keydown is before keypress and focuses already
  1302. onOffEvent(_nodes.colorPicker, 'keypress', keyControl);
  1303. // onOffEvent(_nodes.colorPicker, 'keyup', keyControl);
  1304.  
  1305. onOffEvent(_nodes.colorPicker, 'paste', function(e) {
  1306. e.target.firstChild.data = e.clipboardData.getData('Text');
  1307. return preventDefault(e);
  1308. });
  1309. }
  1310.  
  1311. addEvent(_isIE ? document.body : window, 'mouseup', stopChange);
  1312.  
  1313. // ------------------------------------------------------ //
  1314. // --------- Event listner's callback functions -------- //
  1315. // -------------------------------------------------------//
  1316.  
  1317. function stopChange(e, action) {
  1318. var mouseMoveAction = _mouseMoveAction;
  1319.  
  1320. if (_mouseMoveAction) { // why??? please test again...
  1321. // if (document.selection && _mouseMoveAction !== changeInputValue) {
  1322. // //ie -> prevent showing the accelerator menu
  1323. // document.selection.empty();
  1324. // }
  1325. window[cancelAnimationFrame](_renderTimer);
  1326. removeEvent(_isIE ? document.body : window, 'mousemove', _mouseMoveAction);
  1327. if (_delayState) { // hapens on inputs
  1328. _valueType = {type: 'alpha'};
  1329. renderAll();
  1330. }
  1331. // this is dirty... has to do with M|W|! button
  1332. if (typeof _mouseMoveAction === 'function' || typeof _mouseMoveAction === 'number') {
  1333. delete _options.webUnsave;
  1334. }
  1335.  
  1336. _delayState = 1;
  1337. _mouseMoveAction = undefined;
  1338.  
  1339. changeClass(_nodes.slds, 'do-drag', '');
  1340. changeClass(_nodes.panel, '(?:start-change|do-change)', '');
  1341.  
  1342. _nodes.resizer.style.cssText = '';
  1343. _nodes.panelCover.style.cssText = '';
  1344.  
  1345. _nodes.memo_store.style.cssText = 'background-color: ' +
  1346. color2string(_colors.RND.rgb) + '; ' + getOpacityCSS(_colors.alpha);
  1347. _nodes.memo.className = _nodes.memo.className.replace(/\s+(?:dark|light)/, '') +
  1348. // (/dark/.test(_nodes.colorPicker.className) ? ' dark' : ' light');
  1349. (_colors['rgbaMix' + _bgTypes[_options.alphaBG]].luminance < 0.22 ? ' dark' : ' light');
  1350. // (_colors.rgbaMixCustom.luminance < 0.22 ? ' dark' : ' light')
  1351.  
  1352. _valueType = undefined;
  1353.  
  1354. resetCursors();
  1355.  
  1356. if (_options.actionCallback) {
  1357. _options.actionCallback(e, _action || mouseMoveAction.name || action || 'external');
  1358. }
  1359. }
  1360. }
  1361.  
  1362. function changeXYValue(e) {
  1363. var event = e || window.event,
  1364. scale = _options.scale,
  1365. page = getPageXY(event),
  1366. x = (page.X - _targetOrigin.left) * (scale === 4 ? 2 : scale),
  1367. y = (page.Y - _targetOrigin.top) * scale,
  1368. mode = _options.mode;
  1369.  
  1370. _colors[mode.type][mode.x] = limitValue(x / 255, 0, 1);
  1371. _colors[mode.type][mode.y] = 1 - limitValue(y / 255, 0, 1);
  1372. convertColors();
  1373. return preventDefault(event);
  1374. }
  1375.  
  1376. function changeZValue(e) { // make this part of changeXYValue
  1377. var event = e || window.event,
  1378. page = getPageXY(event),
  1379. z = (page.Y - _targetOrigin.top) * _options.scale,
  1380. mode = _options.mode;
  1381.  
  1382. _colors[mode.type][mode.z] = 1 - limitValue(z / 255, 0, 1);
  1383. convertColors();
  1384. return preventDefault(event);
  1385. }
  1386.  
  1387. function changeOpacityValue(e) {
  1388. var event = e || window.event,
  1389. page = getPageXY(event);
  1390.  
  1391. _newData = true;
  1392. _colors.alpha = limitValue(_math.round(
  1393. (page.X - _targetOrigin.left) / _targetOrigin.width * 100), 0, 100
  1394. ) / 100;
  1395. convertColors('alpha');
  1396. return preventDefault(event);
  1397. }
  1398.  
  1399. function changeInputValue(e) {
  1400. var event = e || window.event,
  1401. page = getPageXY(event),
  1402. delta = _startCoords.pageY - page.Y,
  1403. delayOffset = _options.delayOffset,
  1404. type = _valueType.type,
  1405. isAlpha = type === 'alpha',
  1406. ranges;
  1407.  
  1408. if (_delayState || _math.abs(delta) >= delayOffset) {
  1409. if (!_delayState) {
  1410. _delayState = (delta > 0 ? -delayOffset : delayOffset) +
  1411. (+_mainTarget.firstChild.data) * (isAlpha ? 100 : 1);
  1412. _startCoords.pageY += _delayState;
  1413. delta += _delayState;
  1414. _delayState = 1;
  1415. changeClass(_nodes.panel, 'start-change', 'do-change');
  1416. _nodes.panelCover.style.cssText = 'position:absolute;left:0;top:0;right:0;bottom:0';
  1417. // window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
  1418. document.activeElement.blur();
  1419. _renderTimer = window[requestAnimationFrame](renderAll);
  1420. }
  1421.  
  1422. if (type === 'cmyk' && _options.cmyOnly) {
  1423. type = 'cmy';
  1424. }
  1425.  
  1426. if (isAlpha) {
  1427. _newData = true;
  1428. _colors.alpha = limitValue(delta / 100, 0, 1);
  1429. } else {
  1430. ranges = _valueRanges[type][_valueType.z];
  1431. _colors[type][_valueType.z] = type === 'Lab' ? limitValue(delta, ranges[0], ranges[1]) :
  1432. limitValue(delta / ranges[1], 0, 1);
  1433. }
  1434. convertColors(isAlpha ? 'alpha' : type);
  1435. // event.returnValue is deprecated. Please use the standard event.preventDefault() instead.
  1436. // event.returnValue = false; // see: pauseEvent(event);
  1437. return preventDefault(event);
  1438. }
  1439. }
  1440.  
  1441. function keyControl(e) { // this is quite big for what it does...
  1442. var event = e || window.event,
  1443. keyCode = event.which || event.keyCode,
  1444. key = String.fromCharCode(keyCode),
  1445. elm = document.activeElement,
  1446.  
  1447. cln = elm.className.replace(_options.CSSPrefix, '').split('-'),
  1448. type = cln[0],
  1449. mode = cln[1],
  1450.  
  1451. isAlpha = type === 'alpha',
  1452. isHex = type === 'HEX',
  1453. arrowKey = {k40: -1, k38: 1, k34: -10, k33: 10}['k' + keyCode] / (isAlpha ? 100 : 1),
  1454. validKeys = {'HEX': /[0-9a-fA-F]/, 'Lab': /[\-0-9]/, 'alpha': /[\.0-9]/}[type] || /[0-9]/,
  1455. valueRange = _valueRanges[type][type] || _valueRanges[type][mode], // let op!
  1456.  
  1457. textNode = elm.firstChild, // chnge on TAB key
  1458. rangeData = caret(elm),
  1459. origValue = textNode.data, // do not change
  1460. value,
  1461. val = origValue === '0' && !isHex ? [] : origValue.split(''); // gefixt
  1462.  
  1463. if (/^(?:27|13)$/.test(keyCode)) { // ENTER || ESC
  1464. preventDefault(event);
  1465. elm.blur();
  1466. } else if (event.type === 'keydown') { // functional keys
  1467. if (arrowKey) { // arrow/page keys
  1468. value = limitValue(_math.round((+origValue + arrowKey) * 1e+6) / 1e+6, valueRange[0], valueRange[1]);
  1469. } else if (/^(?:8|46)$/.test(keyCode)) { // DELETE / BACKSPACE
  1470. if (!rangeData.range) {
  1471. rangeData.range++;
  1472. rangeData.start -= keyCode === 8 ? 1 : 0;
  1473. }
  1474. val.splice(rangeData.start, rangeData.range);
  1475. value = val.join('') || '0'; // never loose elm.firstChild
  1476. }
  1477.  
  1478. if (value !== undefined) { // prevent keypress
  1479. preventDefault(event, true);
  1480. }
  1481. } else if (event.type === 'keypress') {
  1482. if (!/^(?:37|39|8|46|9)$/.test(keyCode)) { // left, right,DEL, BACK, TAB for FF
  1483. preventDefault(event, true);
  1484. }
  1485. if (validKeys.test(key)) { // regular input
  1486. val.splice(rangeData.start, rangeData.range, key);
  1487. value = val.join('');
  1488. }
  1489. rangeData.start++;
  1490. }
  1491.  
  1492. if (keyCode === 13 && isHex) {
  1493. if (textNode.data.length % 3 === 0 || textNode.data === '0') { // textNode.data.length &&
  1494. return _colorPicker.setColor(textNode.data === '0' ? '000' : textNode.data, 'rgb', _colors.alpha, true);
  1495. } else {
  1496. preventDefault(event, true);
  1497. return elm.focus();
  1498. }
  1499. }
  1500.  
  1501. if (isHex && value !== undefined) {
  1502. value = /^0+/.test(value) ? value : parseInt(''+value, 16) || 0;
  1503. }
  1504.  
  1505. if (value !== undefined && value !== '' && +value >= valueRange[0] && +value <= valueRange[1]) {
  1506. if (isHex) {
  1507. value = value.toString(16).toUpperCase() || '0';
  1508. }
  1509. if (isAlpha) {
  1510. _colors[type] = +value;
  1511. } else if (!isHex) {
  1512. _colors[type][mode] = +value / (type === 'Lab' ? 1 : valueRange[1]);
  1513. }
  1514. convertColors(isAlpha ? 'alpha' : type);
  1515.  
  1516. preRenderAll(_colors);
  1517. _mouseMoveAction = true;
  1518. stopChange(e, event.type);
  1519.  
  1520. textNode.data = value; // if
  1521. caret(elm, _math.min(elm.firstChild.data.length, rangeData.start < 0 ? 0 : rangeData.start));
  1522. }
  1523. }
  1524.  
  1525. function buttonActions(e) {
  1526. var event = e || window.event,
  1527. target = event.target || event.srcElement,
  1528. targetClass = target.className,
  1529. parent = target.parentNode,
  1530. options = _options,
  1531. RGB = _colors.RND.rgb,
  1532. customBG, alphaBG,
  1533. mode = _options.mode,
  1534. newMode = '',
  1535. prefix = options.CSSPrefix,
  1536. isModeButton = /(?:hs|rgb)/.test(parent.className) && /^[HSBLRG]$/.test(
  1537. target.firstChild ? target.firstChild.data : ''
  1538. ),
  1539. isDblClick = /dblc/.test(event.type),
  1540. buttonAction = ''; // think this over again....
  1541.  
  1542. if (isDblClick && !isModeButton) {
  1543. return;
  1544. } else if (targetClass.indexOf('-labl ' + prefix + 'labl') !== -1) { // HSB -> HSL; CMYK -> Lab buttons
  1545. changeClass(_nodes[targetClass.split('-')[0]], prefix + 'hide', '');
  1546. changeClass(_nodes[parent.className.split('-')[1]], prefix + 'hide');
  1547. } else if (targetClass.indexOf(prefix + 'butt') !== -1) { // BUTTONS
  1548. if (isModeButton) { // set render modes
  1549. if (isDblClick && _options.scale === 2) {
  1550. newMode = /hs/.test(mode.type) ? 'rgb' : /hide/.test(_nodes.hsl.className) ? 'hsv' : 'hsl';
  1551. newMode = newMode + '-' + newMode[mode.type.indexOf(mode.z)];
  1552. }
  1553. _colorPicker.setMode(newMode ? newMode : targetClass.replace('-butt', '').split(' ')[0]);
  1554. buttonAction = 'modeChange';
  1555. } else if (/^[rgb]/.test(targetClass)) { // no vertical slider rendering in RGB mode
  1556. newMode = targetClass.split('-')[1];
  1557. changeClass(_nodes.colorPicker, 'no-rgb-' + newMode,
  1558. (options['noRGB' + newMode] = !options['noRGB' + newMode]) ? undefined : '');
  1559. buttonAction = 'noRGB' + newMode;
  1560. // preRenderAll();
  1561. } else if (target === _nodes.alpha_labl) { // alpha button right (background of raster)
  1562. customBG = options.customBG;
  1563. alphaBG = options.alphaBG;
  1564. changeClass(_nodes.colorPicker, 'alpha-bg-' + alphaBG, 'alpha-bg-' +
  1565. (alphaBG = options.alphaBG = e.data || (alphaBG === 'w' ? (customBG ? 'c' : 'b') :
  1566. alphaBG === 'c' ? 'b' : 'w')));
  1567. target.firstChild.data = alphaBG.toUpperCase();
  1568. _nodes.ctrl.style.backgroundColor = _nodes.memo.style.backgroundColor =
  1569. alphaBG !== 'c' ? '' : 'rgb(' + _math.round(customBG.r * 255) + ', ' +
  1570. _math.round(customBG.g * 255) + ', ' +
  1571. _math.round(customBG.b * 255) + ')';
  1572. _nodes.raster.style.cssText = _nodes.raster_bg.previousSibling.style.cssText =
  1573. alphaBG !== 'c' ? '' : getOpacityCSS(customBG.luminance < 0.22 ? 0.5 : 0.4);
  1574. buttonAction = 'alphaBackground';
  1575. } else if (target === _nodes.alpha_butt) { // alpha button left (disable alpha rendering)
  1576. changeClass(_nodes.colorPicker, 'mute-alpha', (options.muteAlpha = !options.muteAlpha) ? undefined : '');
  1577. buttonAction = 'alphaState';
  1578. } else if (target === _nodes.HEX_butt) { // make it on/off
  1579. changeClass(_nodes.colorPicker, 'no-HEX', (options.HEXState = !options.HEXState) ? undefined : '');
  1580. buttonAction = 'HEXState';
  1581. } else if (target === _nodes.HEX_labl) { // web save state change
  1582. var isWebSave = _colors.saveColor === 'web save';
  1583.  
  1584. if (_colors.saveColor !== 'web smart' && !isWebSave) {
  1585. options.webUnsave = copyColor(RGB);
  1586. _colorPicker.setColor(_colors.webSmart, 'rgb');
  1587. } else if (!isWebSave) {
  1588. if (!options.webUnsave) {
  1589. options.webUnsave = copyColor(RGB);
  1590. }
  1591. _colorPicker.setColor(_colors.webSave, 'rgb');
  1592. } else {
  1593. _colorPicker.setColor(options.webUnsave, 'rgb');
  1594. }
  1595. buttonAction = 'webColorState';
  1596. } else if (/Lab-x-labl/.test(targetClass)) { //target === _nodes.cmyk_type) {
  1597. // switch between CMYK and CMY
  1598. changeClass(_nodes.colorPicker, 'cmy-only', (options.cmyOnly = !options.cmyOnly) ? undefined : '');
  1599. buttonAction = 'cmykState';
  1600. }
  1601. } else if (target === _nodes.bsav) { // SAVE
  1602. saveAsBackground();
  1603. buttonAction = 'saveAsBackground';
  1604. } else if (target === _nodes.bres) { // RESET
  1605. var tmpColor = copyColor(RGB),
  1606. tmpAlpha = _colors.alpha;
  1607.  
  1608. // a bit heavy but... doesn't matter here
  1609. // newCol, type, alpha, forceRender
  1610. _colorPicker.setColor(options.color);
  1611. saveAsBackground();
  1612. _colorPicker.setColor(tmpColor, 'rgb', tmpAlpha);
  1613. buttonAction = 'resetColor';
  1614. } else if (parent === _nodes.col1) { // COLOR left
  1615. // _colors.hsv.h = (_colors.hsv.h + 0.5) % 1; // not acurate
  1616. _colors.hsv.h -= (_colors.hsv.h > 0.5 ? 0.5 : -0.5);
  1617. convertColors('hsv');
  1618. buttonAction = 'shiftColor';
  1619.  
  1620. } else if (parent === _nodes.col2) { // COLOR right
  1621. _colorPicker.setColor(target.style.backgroundColor, 'rgb', _colors.background.alpha);
  1622. buttonAction = 'setSavedColor';
  1623. } else if (parent === _nodes.memo) { // MEMORIES // revisit...
  1624. var resetBlink = function() {
  1625. if (_nodes.memos.blinker) _nodes.memos.blinker.style.cssText = _nodes.memos.cssText;
  1626. },
  1627. doBlink = function(elm) {
  1628. _nodes.memos.blinker = elm;
  1629. elm.style.cssText = 'background-color:' + (_colors.RGBLuminance > 0.22 ? '#333' : '#DDD');
  1630. window.setTimeout(resetBlink, 200);
  1631. };
  1632.  
  1633. if (target === _nodes.memo_cursor) { // save color in memo
  1634. resetBlink();
  1635. _nodes.memos.blinker = undefined;
  1636. _nodes.testNode.style.cssText = _nodes.memo_store.style.cssText;
  1637. _nodes.memos.cssText = _nodes.testNode.style.cssText; // ...how browser sees css
  1638. for (var n = _nodes.memos.length - 1; n--; ) { // check if color already exists
  1639. if (_nodes.memos.cssText === _nodes.memos[n].style.cssText) {
  1640. doBlink(_nodes.memos[n]); // sets _nodes.memos.blinker
  1641. break;
  1642. }
  1643. }
  1644. if (!_nodes.memos.blinker) { // right shift colors
  1645. for (var n = _nodes.memos.length - 1; n--; ) {
  1646. _nodes.memos[n + 1].style.cssText = _nodes.memos[n].style.cssText;
  1647. }
  1648. _nodes.memos[0].style.cssText = _nodes.memo_store.style.cssText;
  1649. }
  1650. buttonAction = 'toMemory';
  1651. } else { // reset color from memo
  1652. resetBlink();
  1653. _colorPicker.setColor(target.style.backgroundColor, 'rgb', target.style.opacity || 1);
  1654. _nodes.memos.cssText = target.style.cssText;
  1655. doBlink(target);
  1656. // this is dirty... has to do with M|W|! button
  1657. _mouseMoveAction = 1;
  1658. buttonAction = 'fromMemory';
  1659. }
  1660.  
  1661. }
  1662. // think this over again, does this need to be like this??
  1663. if (buttonAction) {
  1664. preRenderAll(_colors);
  1665. _mouseMoveAction = _mouseMoveAction || true; // !!!! search for: // this is dirty...
  1666. stopChange(e, buttonAction);
  1667. }
  1668. }
  1669.  
  1670. function resizeApp(e, size) {
  1671. var event = e || window.event,
  1672. page = event ? getPageXY(event) : {},
  1673. isSize = size !== undefined,
  1674. x = isSize ? size : page.X - _targetOrigin.left + 8,
  1675. y = isSize ? size : page.Y - _targetOrigin.top + 8,
  1676. values = [' S XS XXS', ' S XS', ' S', ''],
  1677. sizes = _options.sizes, // from getUISizes();
  1678. currentSize = isSize ? size :
  1679. y < sizes.XXS[1] + 25 ? 0 :
  1680. x < sizes.XS[0] + 25 ? 1 :
  1681. x < sizes.S[0] + 25 || y < sizes.S[1] + 25 ? 2 : 3,
  1682. value = values[currentSize],
  1683. isXXS = false,
  1684. mode,
  1685. tmp = '';
  1686.  
  1687. if (_cashedVars.resizer !== value) {
  1688. isXXS = /XX/.test(value);
  1689. mode = _options.mode;
  1690.  
  1691. if (isXXS && (!/hs/.test(mode.type) || mode.z === 'h')) {
  1692. tmp = mode.type + '-' + mode.z;
  1693. _colorPicker.setMode(/hs/.test(mode.type) ? mode.type + '-s': 'hsv-s');
  1694. _options.mode.original = tmp;
  1695. } else if (mode.original) {
  1696. // setMode(mode) creates a new object so mode.original gets deleted automatically
  1697. _colorPicker.setMode(mode.original);
  1698. }
  1699.  
  1700. _nodes.colorPicker.className = _nodes.colorPicker.className.replace(/\s+(?:S|XS|XXS)/g, '') + value;
  1701. _options.scale = isXXS ? 4 : /S/.test(value) ? 2 : 1;
  1702. _options.currentSize = currentSize;
  1703.  
  1704. _cashedVars.resizer = value;
  1705.  
  1706. // fix this... from this point on inside if() ... convertColors();
  1707. _newData = true;
  1708. renderAll();
  1709. resetCursors();
  1710. }
  1711.  
  1712. _nodes.resizer.style.cssText = 'display: block;' +
  1713. 'width: ' + (x > 10 ? x : 10) + 'px;' +
  1714. 'height: ' + (y > 10 ? y : 10) + 'px;';
  1715. }
  1716.  
  1717. // ------------------------------------------------------ //
  1718. // --- Colors calculation and rendering related stuff --- //
  1719. // -------------------------------------------------------//
  1720.  
  1721. function setMode(mode) {
  1722. var ModeMatrix = {
  1723. rgb_r : {x: 'b', y: 'g'},
  1724. rgb_g : {x: 'b', y: 'r'},
  1725. rgb_b : {x: 'r', y: 'g'},
  1726.  
  1727. hsv_h : {x: 's', y: 'v'},
  1728. hsv_s : {x: 'h', y: 'v'},
  1729. hsv_v : {x: 'h', y: 's'},
  1730.  
  1731. hsl_h : {x: 's', y: 'l'},
  1732. hsl_s : {x: 'h', y: 'l'},
  1733. hsl_l : {x: 'h', y: 's'}
  1734. },
  1735. key = mode.replace('-', '_'),
  1736. regex = '\\b(?:rg|hs)\\w\\-\\w\\b'; // \\b\\w{3}\\-\\w\\b';
  1737.  
  1738. // changeClass(_nodes.colorPicker, '(?:.*?)$', mode);
  1739. // changeClass(_nodes.colorPicker, '\\b\\w{3}\\-\\w\\b', mode);
  1740. // changeClass(_nodes.slds, '\\b\\w{3}\\-\\w\\b', mode);
  1741. changeClass(_nodes.panel, regex, mode);
  1742. changeClass(_nodes.slds, regex, mode);
  1743.  
  1744. mode = mode.split('-');
  1745. return _options.mode = {
  1746. type: mode[0],
  1747. x: ModeMatrix[key].x,
  1748. y: ModeMatrix[key].y,
  1749. z: mode[1]
  1750. };
  1751. }
  1752.  
  1753. function initSliders() { // function name...
  1754. var regex = /\s+(?:hue-)*(?:dark|light)/g,
  1755. className = 'className'; // minification
  1756.  
  1757. _nodes.curl[className] = _nodes.curl[className].replace(regex, ''); // .....
  1758. _nodes.curr[className] = _nodes.curr[className].replace(regex, ''); // .....
  1759. _nodes.slds[className] = _nodes.slds[className].replace(regex, '');
  1760. // var sldrs = ['sldr_2', 'sldr_4', 'sldl_3'];
  1761. // for (var n = sldrs.length; n--; ) {
  1762. // _nodes[sldrs[n]][className] = _options.CSSPrefix + sldrs[n].replace('_', '-');
  1763. // }
  1764. _nodes.sldr_2[className] = _options.CSSPrefix + 'sldr-2';
  1765. _nodes.sldr_4[className] = _options.CSSPrefix + 'sldr-4';
  1766. _nodes.sldl_3[className] = _options.CSSPrefix + 'sldl-3';
  1767.  
  1768. for (var style in _nodes.styles) {
  1769. if (!style.indexOf('sld')) _nodes.styles[style].cssText = '';
  1770. }
  1771. _cashedVars = {};
  1772. }
  1773.  
  1774. function resetCursors() {
  1775. // _renderVars.isNoRGB = undefined;
  1776. _nodes.styles.curr.cssText = _nodes.styles.curl.cssText; // only coordinates
  1777. _nodes.curl.className = _options.CSSPrefix + 'curl' + (
  1778. _renderVars.noRGBZ ? ' ' + _options.CSSPrefix + 'curl-' +_renderVars.noRGBZ: '');
  1779. _nodes.curr.className = _options.CSSPrefix + 'curr ' + _options.CSSPrefix + 'curr-' +
  1780. (_options.mode.z === 'h' ? _renderVars.HUEContrast : _renderVars.noRGBZ ?
  1781. _renderVars.noRGBZ : _renderVars.RGBLuminance);
  1782. }
  1783.  
  1784. function convertColors(type) {
  1785. preRenderAll(_colorInstance.setColor(undefined, type || _options.mode.type));
  1786. _newData = true;
  1787. }
  1788.  
  1789. function saveAsBackground(refresh) {
  1790. _colorInstance.saveAsBackground();
  1791. _nodes.styles.col2.cssText = 'background-color: ' + color2string(_colors.background.RGB) + ';' +
  1792. getOpacityCSS(_colors.background.alpha);
  1793. if (refresh) {
  1794. preRenderAll(_colors);
  1795. // renderAll();
  1796. }
  1797. return (_colors);
  1798. }
  1799.  
  1800. function preRenderAll(colors) {
  1801. var _Math = _math,
  1802. renderVars = _renderVars,
  1803. bgType = _bgTypes[_options.alphaBG];
  1804.  
  1805. renderVars.hueDelta = _Math.round(colors['rgbaMixBGMix' + bgType].hueDelta * 100);
  1806. // renderVars.RGBLuminanceDelta = _Math.round(colors.RGBLuminanceDelta * 100);
  1807. renderVars.luminanceDelta = _Math.round(colors['rgbaMixBGMix' + bgType].luminanceDelta * 100);
  1808. renderVars.RGBLuminance = colors.RGBLuminance > 0.22 ? 'light' : 'dark';
  1809. renderVars.HUEContrast = colors.HUELuminance > 0.22 ? 'light' : 'dark';
  1810. // renderVars.contrast = renderVars.RGBLuminanceDelta > renderVars.hueDelta ? 'contrast' : '';
  1811. renderVars.contrast = renderVars.luminanceDelta > renderVars.hueDelta ? 'contrast' : '';
  1812. renderVars.readabiltiy =
  1813. colors['rgbaMixBGMix' + bgType].WCAG2Ratio >= 7 ? 'green' :
  1814. colors['rgbaMixBGMix' + bgType].WCAG2Ratio >= 4.5 ? 'orange': '';
  1815. renderVars.noRGBZ = _options['no' + _options.mode.type.toUpperCase() + _options.mode.z] ?
  1816. (_options.mode.z === 'g' && colors.rgb.g < 0.59 || _options.mode.z === 'b' || _options.mode.z === 'r' ?
  1817. 'dark' : 'light') : undefined;
  1818. }
  1819.  
  1820. function renderAll() { // maybe render alpha seperately...
  1821. if (_mouseMoveAction) {
  1822. // _renderTimer = window[requestAnimationFrame](renderAll);
  1823. if (!_newData) return (_renderTimer = window[requestAnimationFrame](renderAll));
  1824. _newData = false;
  1825. }
  1826. // console.time('renderAll');
  1827. var options = _options,
  1828. mode = options.mode,
  1829. scale = options.scale,
  1830. prefix = options.CSSPrefix,
  1831. colors = _colors,
  1832. nodes = _nodes,
  1833. CSS = nodes.styles,
  1834. textNodes = nodes.textNodes,
  1835. valueRanges = _valueRanges,
  1836. valueType = _valueType,
  1837. renderVars = _renderVars,
  1838. cashedVars = _cashedVars,
  1839.  
  1840. _Math = _math,
  1841. _getOpacityCSS = getOpacityCSS,
  1842. _color2string = color2string,
  1843.  
  1844. a = 0,
  1845. b = 0,
  1846. x = colors[mode.type][mode.x],
  1847. X = _Math.round(x * 255 / (scale === 4 ? 2 : scale)),
  1848. y_ = colors[mode.type][mode.y],
  1849. y = 1 - y_,
  1850. Y = _Math.round(y * 255 / scale),
  1851. z = 1 - colors[mode.type][mode.z],
  1852. Z = _Math.round(z * 255 / scale),
  1853. coords = (1 === 1) ? [x, y_] : [0, 0], // (1 === 2) button label up
  1854.  
  1855. isRGB = mode.type === 'rgb',
  1856. isHue = mode.z === 'h',
  1857. isHSL = mode.type === 'hsl',
  1858. isHSL_S = isHSL && mode.z === 's',
  1859. moveXY = _mouseMoveAction === changeXYValue,
  1860. moveZ = _mouseMoveAction === changeZValue,
  1861. display, tmp, value, slider;
  1862.  
  1863. if (isRGB) {
  1864. if (coords[0] >= coords[1]) b = 1; else a = 1;
  1865. if (cashedVars.sliderSwap !== a) {
  1866. nodes.sldr_2.className = options.CSSPrefix + 'sldr-' + (3 - a);
  1867. cashedVars.sliderSwap = a;
  1868. }
  1869. }
  1870. if ((isRGB && !moveZ) || (isHue && !moveXY) || (!isHue && !moveZ)) {
  1871. CSS[isHue ? 'sldl_2' : 'sldr_2'][isRGB ? 'cssText' : 'backgroundColor'] =
  1872. isRGB ? _getOpacityCSS((coords[a] - coords[b]) / (1 - (coords[b]) || 0)) : _color2string(colors.hueRGB);
  1873. }
  1874. if (!isHue) {
  1875. if (!moveZ) CSS.sldr_4.cssText = _getOpacityCSS(isRGB ? coords[b] : isHSL_S ? _Math.abs(1 - y * 2) : y);
  1876. if (!moveXY) CSS.sldl_3.cssText = _getOpacityCSS(isHSL && mode.z === 'l' ? _Math.abs(1 - z * 2) : z);
  1877. if (isHSL) { // switch slider class name for black/white color half way through in HSL(S|L) mode(s)
  1878. slider = isHSL_S ? 'sldr_4' : 'sldl_3';
  1879. tmp = isHSL_S ? 'r-' : 'l-';
  1880. value = isHSL_S ? (y > 0.5 ? 4 : 3) : (z > 0.5 ? 3 : 4);
  1881.  
  1882. if (cashedVars[slider] !== value) {
  1883. nodes[slider].className = options.CSSPrefix + 'sld' + tmp + value;
  1884. cashedVars[slider] = value;
  1885. }
  1886. }
  1887. }
  1888.  
  1889. if (!moveZ) CSS.curm.cssText = 'left: ' + X + 'px; top: ' + Y + 'px;';
  1890. if (!moveXY) CSS.curl.top = Z + 'px';
  1891. if (valueType) CSS.curr.top = Z + 'px'; // && valueType.type !== mode.type
  1892. if ((valueType && valueType.type === 'alpha') || _mainTarget === nodes.opacity) {
  1893. CSS.opacity_slider.left = options.opacityPositionRelative ? (colors.alpha * (
  1894. (_targetOrigin.width || nodes.opacity.offsetWidth) -
  1895. (_targetOrigin.childWidth || nodes.opacity_slider.offsetWidth))) + 'px' :
  1896. (colors.alpha * 100) + '%';
  1897. }
  1898.  
  1899. CSS.col1.cssText = 'background-color: ' + _color2string(colors.RND.rgb) + '; ' +
  1900. (options.muteAlpha ? '' : _getOpacityCSS(colors.alpha));
  1901. CSS.opacity.backgroundColor = _color2string(colors.RND.rgb);
  1902. CSS.cold.width = renderVars.hueDelta + '%';
  1903. CSS.cont.width = renderVars.luminanceDelta + '%';
  1904.  
  1905. for (display in textNodes) {
  1906. tmp = display.split('_');
  1907. if (options.cmyOnly) {
  1908. tmp[0] = tmp[0].replace('k', '');
  1909. }
  1910. value = tmp[1] ? colors.RND[tmp[0]][tmp[1]] : colors.RND[tmp[0]] || colors[tmp[0]];
  1911. if (cashedVars[display] !== value) {
  1912. cashedVars[display] = value;
  1913. textNodes[display].data = value > 359.5 && display !== 'HEX' ? 0 : value;
  1914.  
  1915. if (display !== 'HEX' && !options.noRangeBackground) {
  1916. value = colors[tmp[0]][tmp[1]] !== undefined ? colors[tmp[0]][tmp[1]] : colors[tmp[0]];
  1917. if (tmp[0] === 'Lab') {
  1918. value = (value - valueRanges[tmp[0]][tmp[1]][0]) /
  1919. (valueRanges[tmp[0]][tmp[1]][1] - valueRanges[tmp[0]][tmp[1]][0]);
  1920. }
  1921. CSS[display].backgroundPosition = _Math.round((1 - value) * 100) + '% 0%';
  1922. }
  1923. }
  1924. }
  1925. // Lab out of gammut
  1926. tmp = colors._rgb ? [
  1927. colors._rgb.r !== colors.rgb.r,
  1928. colors._rgb.g !== colors.rgb.g,
  1929. colors._rgb.b !== colors.rgb.b
  1930. ] : [];
  1931. if (tmp.join('') !== cashedVars.outOfGammut) {
  1932. nodes.rgb_r_labl.firstChild.data = tmp[0] ? '!' : ' ';
  1933. nodes.rgb_g_labl.firstChild.data = tmp[1] ? '!' : ' ';
  1934. nodes.rgb_b_labl.firstChild.data = tmp[2] ? '!' : ' ';
  1935. cashedVars.outOfGammut = tmp.join('');
  1936. }
  1937. if (renderVars.noRGBZ) {
  1938. if (cashedVars.noRGBZ !== renderVars.noRGBZ) {
  1939. nodes.curl.className = prefix + 'curl ' + prefix + 'curl-' + renderVars.noRGBZ;
  1940. if (!moveZ) {
  1941. nodes.curr.className = prefix + 'curr ' + prefix + 'curr-' + renderVars.noRGBZ;
  1942. }
  1943. cashedVars.noRGBZ = renderVars.noRGBZ;
  1944. }
  1945. }
  1946. if (cashedVars.HUEContrast !== renderVars.HUEContrast && mode.z === 'h') {
  1947. nodes.slds.className = nodes.slds.className.replace(/\s+hue-(?:dark|light)/, '') +
  1948. ' hue-' + renderVars.HUEContrast;
  1949. if (!moveZ) {
  1950. nodes.curr.className = prefix + 'curr ' + prefix + 'curr-' + renderVars.HUEContrast;
  1951. }
  1952. cashedVars.HUEContrast = renderVars.HUEContrast;
  1953. } else if (cashedVars.RGBLuminance !== renderVars.RGBLuminance) { // test for no else
  1954. nodes.colorPicker.className = nodes.colorPicker.className.replace(/\s+(?:dark|light)/, '') +
  1955. ' ' + renderVars.RGBLuminance;
  1956. if (!moveZ && mode.z !== 'h' && !renderVars.noRGBZ) {
  1957. nodes.curr.className = prefix + 'curr ' + prefix + 'curr-' + renderVars.RGBLuminance;
  1958. }
  1959. cashedVars.RGBLuminance = renderVars.RGBLuminance;
  1960. }
  1961.  
  1962. if (cashedVars.contrast !== renderVars.contrast || cashedVars.readabiltiy !== renderVars.readabiltiy) {
  1963. nodes.ctrl.className = nodes.ctrl.className.replace(' contrast', '').replace(/\s*(?:orange|green)/, '') +
  1964. (renderVars.contrast ? ' ' + renderVars.contrast : '') +
  1965. (renderVars.readabiltiy ? ' ' + renderVars.readabiltiy : '');
  1966. cashedVars.contrast = renderVars.contrast;
  1967. cashedVars.readabiltiy = renderVars.readabiltiy;
  1968. }
  1969.  
  1970. if (cashedVars.saveColor !== colors.saveColor) {
  1971. nodes.HEX_labl.firstChild.data = !colors.saveColor ? '!' : colors.saveColor === 'web save' ? 'W' : 'M';
  1972. cashedVars.saveColor = colors.saveColor;
  1973. }
  1974.  
  1975. if (options.renderCallback) {
  1976. options.renderCallback(colors, mode); // maybe more parameters
  1977. }
  1978.  
  1979. if (_mouseMoveAction) {
  1980. _renderTimer = window[requestAnimationFrame](renderAll);
  1981. }
  1982.  
  1983. // console.timeEnd('renderAll')
  1984. }
  1985.  
  1986.  
  1987. // ------------------------------------------------------ //
  1988. // ------------------ helper functions ------------------ //
  1989. // -------------------------------------------------------//
  1990.  
  1991. function copyColor(color) {
  1992. var newColor = {};
  1993.  
  1994. for (var n in color) {
  1995. newColor[n] = color[n];
  1996. }
  1997. return newColor;
  1998. }
  1999.  
  2000. // function color2string(color, type) {
  2001. // var out = [],
  2002. // n = 0;
  2003.  
  2004. // type = type || 'rgb';
  2005. // while (type.charAt(n)) { // IE7 // V8 type[n] ||
  2006. // out.push(color[type.charAt(n)]);
  2007. // n++;
  2008. // }
  2009. // return type + '(' + out.join(', ') + ')';
  2010. // }
  2011.  
  2012. function color2string(color, type) { // ~2 x faster on V8
  2013. var out = '',
  2014. t = (type || 'rgb').split(''),
  2015. n = t.length;
  2016.  
  2017. for ( ; n--; ) {
  2018. out = ', ' + color[t[n]] + out;
  2019. }
  2020. return (type || 'rgb') + '(' + out.substr(2) + ')';
  2021. }
  2022.  
  2023.  
  2024. function limitValue(value, min, max) {
  2025. // return Math.max(min, Math.min(max, value)); // faster??
  2026. return (value > max ? max : value < min ? min : value);
  2027. }
  2028.  
  2029. function getOpacityCSS(value) {
  2030. if (value === undefined) value = 1;
  2031.  
  2032. if (_doesOpacity) {
  2033. return 'opacity: ' + (_math.round(value * 10000000000) / 10000000000) + ';'; // value.toFixed(16) = 99% slower
  2034. // some speed test:
  2035. // return ['opacity: ', (Math.round(value * 1e+10) / 1e+10), ';'].join('');
  2036. } else {
  2037. return 'filter: alpha(opacity=' + _math.round(value * 100) + ');';
  2038. }
  2039. }
  2040.  
  2041. function preventDefault(e, skip) {
  2042. e.preventDefault ? e.preventDefault() : e.returnValue = false;
  2043. if (!skip) window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
  2044. return false;
  2045. }
  2046.  
  2047. function changeClass(elm, cln, newCln) {
  2048. return !elm ? false : elm.className = (newCln !== undefined ?
  2049. elm.className.replace(new RegExp('\\s+?' + cln, 'g'), newCln ? ' ' + newCln : '') :
  2050. elm.className + ' ' + cln);
  2051. }
  2052.  
  2053. function getOrigin(elm) {
  2054. var box = (elm.getBoundingClientRect) ? elm.getBoundingClientRect() : {top: 0, left: 0},
  2055. doc = elm && elm.ownerDocument,
  2056. body = doc.body,
  2057. win = doc.defaultView || doc.parentWindow || window,
  2058. docElem = doc.documentElement || body.parentNode,
  2059. clientTop = docElem.clientTop || body.clientTop || 0, // border on html or body or both
  2060. clientLeft = docElem.clientLeft || body.clientLeft || 0;
  2061.  
  2062. return {
  2063. left: box.left + (win.pageXOffset || docElem.scrollLeft) - clientLeft,
  2064. top: box.top + (win.pageYOffset || docElem.scrollTop) - clientTop
  2065. };
  2066. }
  2067.  
  2068. function getPageXY(e) {
  2069. var doc = window.document;
  2070.  
  2071. return {
  2072. X: e.pageX || e.clientX + doc.body.scrollLeft + doc.documentElement.scrollLeft,
  2073. Y: e.pageY || e.clientY + doc.body.scrollTop + doc.documentElement.scrollTop
  2074. };
  2075. }
  2076.  
  2077. function addEvent(obj, type, func) {
  2078. addEvent.cache = addEvent.cache || {
  2079. _get: function(obj, type, func, checkOnly) {
  2080. var cache = addEvent.cache[type] || [];
  2081.  
  2082. for (var n = cache.length; n--; ) {
  2083. if (obj === cache[n].obj && '' + func === '' + cache[n].func) {
  2084. func = cache[n].func;
  2085. if (!checkOnly) {
  2086. cache[n] = cache[n].obj = cache[n].func = null;
  2087. cache.splice(n, 1);
  2088. }
  2089. return func;
  2090. }
  2091. }
  2092. },
  2093. _set: function(obj, type, func) {
  2094. var cache = addEvent.cache[type] = addEvent.cache[type] || [];
  2095. if (addEvent.cache._get(obj, type, func, true)) {
  2096. return true;
  2097. } else {
  2098. cache.push({
  2099. func: func,
  2100. obj: obj
  2101. });
  2102. }
  2103. }
  2104. };
  2105.  
  2106. if (!func.name && addEvent.cache._set(obj, type, func) || typeof func !== 'function') {
  2107. return;
  2108. }
  2109.  
  2110. if (obj.addEventListener) obj.addEventListener(type, func, false);
  2111. else obj.attachEvent('on' + type, func);
  2112. }
  2113.  
  2114. function removeEvent(obj, type, func) {
  2115. if (typeof func !== 'function') return;
  2116. if (!func.name) {
  2117. func = addEvent.cache._get(obj, type, func) || func;
  2118. }
  2119.  
  2120. if (obj.removeEventListener) obj.removeEventListener(type, func, false);
  2121. else obj.detachEvent('on' + type, func);
  2122. }
  2123.  
  2124. function caret(target, pos) { // only for contenteditable
  2125. var out = {};
  2126.  
  2127. if (pos === undefined) { // get
  2128. if (window.getSelection) { // HTML5
  2129. target.focus();
  2130. var range1 = window.getSelection().getRangeAt(0),
  2131. range2 = range1.cloneRange();
  2132. range2.selectNodeContents(target);
  2133. range2.setEnd(range1.endContainer, range1.endOffset);
  2134. out = {
  2135. end: range2.toString().length,
  2136. range: range1.toString().length
  2137. };
  2138. } else { // IE < 9
  2139. target.focus();
  2140. var range1 = document.selection.createRange(),
  2141. range2 = document.body.createTextRange();
  2142. range2.moveToElementText(target);
  2143. range2.setEndPoint('EndToEnd', range1);
  2144. out = {
  2145. end: range2.text.length,
  2146. range: range1.text.length
  2147. };
  2148. }
  2149. out.start = out.end - out.range;
  2150. return out;
  2151. }
  2152. // set
  2153. if (pos == -1) pos = target['text']().length;
  2154. if (window.getSelection) { // HTML5
  2155. target.focus();
  2156. window.getSelection().collapse(target.firstChild, pos);
  2157. } else { // IE < 9
  2158. var range = document.body.createTextRange();
  2159. range.moveToElementText(target);
  2160. range.moveStart('character', pos);
  2161. range.collapse(true);
  2162. range.select();
  2163. }
  2164. return pos;
  2165. }
  2166.  
  2167. // ------------- requestAnimationFrame shim ------------- //
  2168. // ---------- quite optimized for minification ---------- //
  2169.  
  2170. for(var n = vendors.length; n-- && !window[requestAnimationFrame]; ) {
  2171. window[requestAnimationFrame] = window[vendors[n] + 'Request' + animationFrame];
  2172. window[cancelAnimationFrame] = window[vendors[n] + 'Cancel' + animationFrame] ||
  2173. window[vendors[n] + 'CancelRequest' + animationFrame];
  2174. }
  2175.  
  2176. window[requestAnimationFrame] = window[requestAnimationFrame] || function(callback) {
  2177. // this is good enough... and better than setTimeout
  2178. return window.setTimeout(callback, 1000 / _options.fps);
  2179. // return _renderTimer ? _renderTimer : window.setInterval(callback, 1000 / _options.fps);
  2180. };
  2181.  
  2182. window[cancelAnimationFrame] = window[cancelAnimationFrame] || function(id) {
  2183. // console.log('OFF-', id + '-' + _renderTimer)
  2184. window.clearTimeout(id);
  2185. return _renderTimer = null;
  2186. };
  2187.  
  2188. })(window);
  2189.  
  2190. /*! javascript_implementation/jsColor.js */
  2191. (function (window) {
  2192. window.jsColorPicker = function(selectors, config) {
  2193. var renderCallback = function(colors, mode) {
  2194. var options = this,
  2195. input = options.input,
  2196. patch = options.patch,
  2197. RGB = colors.RND.rgb,
  2198. HSL = colors.RND.hsl,
  2199. AHEX = options.isIE8 ? (colors.alpha < 0.16 ? '0' : '') +
  2200. (Math.round(colors.alpha * 100)).toString(16).toUpperCase() + colors.HEX : '',
  2201. RGBInnerText = RGB.r + ', ' + RGB.g + ', ' + RGB.b,
  2202. RGBAText = 'rgba(' + RGBInnerText + ', ' + colors.alpha + ')',
  2203. isAlpha = colors.alpha !== 1 && !options.isIE8,
  2204. colorMode = input.getAttribute('data-colorMode');
  2205.  
  2206. patch.style.cssText =
  2207. 'color:' + (colors.rgbaMixCustom.luminance > 0.22 ? '#222' : '#ddd') + ';' + // Black...???
  2208. 'background-color:' + RGBAText + ';' +
  2209. 'filter:' + (options.isIE8 ? 'progid:DXImageTransform.Microsoft.gradient(' + // IE<9
  2210. 'startColorstr=#' + AHEX + ',' + 'endColorstr=#' + AHEX + ')' : '');
  2211.  
  2212. input.value = (colorMode === 'HEX' && !isAlpha ? '#' + (options.isIE8 ? AHEX : colors.HEX) :
  2213. colorMode === 'rgb' || (colorMode === 'HEX' && isAlpha) ?
  2214. (!isAlpha ? 'rgb(' + RGBInnerText + ')' : RGBAText) :
  2215. ('hsl' + (isAlpha ? 'a(' : '(') + HSL.h + ', ' + HSL.s + '%, ' + HSL.l + '%' +
  2216. (isAlpha ? ', ' + colors.alpha : '') + ')')
  2217. );
  2218.  
  2219. if (options.displayCallback) {
  2220. options.displayCallback(colors, mode, options);
  2221. }
  2222. },
  2223. extractValue = function(elm) {
  2224. return elm.value || elm.getAttribute('value') || elm.style.backgroundColor || '#FFFFFF';
  2225. },
  2226. actionCallback = function(event, action) {
  2227. var options = this,
  2228. colorPicker = colorPickers.current;
  2229.  
  2230. if (action === 'toMemory') {
  2231. var memos = colorPicker.nodes.memos,
  2232. backgroundColor = '',
  2233. opacity = 0,
  2234. cookieTXT = [];
  2235.  
  2236. for (var n = 0, m = memos.length; n < m; n++) {
  2237. backgroundColor = memos[n].style.backgroundColor;
  2238. opacity = memos[n].style.opacity;
  2239. opacity = Math.round((opacity === '' ? 1 : opacity) * 100) / 100;
  2240. cookieTXT.push(backgroundColor.
  2241. replace(/, /g, ',').
  2242. replace('rgb(', 'rgba(').
  2243. replace(')', ',' + opacity + ')')
  2244. );
  2245. }
  2246. cookieTXT = '\'' + cookieTXT.join('\',\'') + '\'';
  2247. ColorPicker.docCookies('colorPickerMemos' + (options.noAlpha ? 'NoAlpha' : ''), cookieTXT);
  2248. } else if (action === 'resizeApp') {
  2249. ColorPicker.docCookies('colorPickerSize', colorPicker.color.options.currentSize);
  2250. } else if (action === 'modeChange') {
  2251. var mode = colorPicker.color.options.mode;
  2252.  
  2253. ColorPicker.docCookies('colorPickerMode', mode.type + '-' + mode.z);
  2254. }
  2255. },
  2256. createInstance = function(elm, config) {
  2257. var initConfig = {
  2258. klass: window.ColorPicker,
  2259. input: elm,
  2260. patch: elm,
  2261. isIE8: !!document.all && !document.addEventListener, // Opera???
  2262. // *** animationSpeed: 200,
  2263. // *** draggable: true,
  2264. margin: {left: -1, top: 2},
  2265. customBG: '#FFFFFF',
  2266. // displayCallback: displayCallback,
  2267. /* --- regular colorPicker options from this point --- */
  2268. color: extractValue(elm),
  2269. initStyle: 'display: none',
  2270. mode: ColorPicker.docCookies('colorPickerMode') || 'hsv-h',
  2271. // memoryColors: (function(colors, config) {
  2272. // return config.noAlpha ?
  2273. // colors.replace(/\,\d*\.*\d*\)/g, ',1)') : colors;
  2274. // })($.docCookies('colorPickerMemos'), config || {}),
  2275. memoryColors: ColorPicker.docCookies('colorPickerMemos' +
  2276. ((config || {}).noAlpha ? 'NoAlpha' : '')),
  2277. size: ColorPicker.docCookies('colorPickerSize') || 1,
  2278. renderCallback: renderCallback,
  2279. actionCallback: actionCallback
  2280. };
  2281.  
  2282. for (var n in config) {
  2283. initConfig[n] = config[n];
  2284. }
  2285. return new initConfig.klass(initConfig);
  2286. },
  2287. doEventListeners = function(elm, multiple, off) {
  2288. var onOff = off ? 'removeEventListener' : 'addEventListener',
  2289. focusListener = function(e) {
  2290. var input = this,
  2291. position = window.ColorPicker.getOrigin(input),
  2292. index = multiple ? Array.prototype.indexOf.call(elms, this) : 0,
  2293. colorPicker = colorPickers[index] ||
  2294. (colorPickers[index] = createInstance(this, config)),
  2295. options = colorPicker.color.options,
  2296. colorPickerUI = colorPicker.nodes.colorPicker,
  2297. appendTo = (options.appendTo || document.body),
  2298. isStatic = /static/.test(window.getComputedStyle(appendTo).position),
  2299. atrect = isStatic ? {left: 0, top: 0} : appendTo.getBoundingClientRect(),
  2300. waitTimer = 0;
  2301.  
  2302. options.color = extractValue(elm); // brings color to default on reset
  2303. colorPickerUI.style.cssText =
  2304. 'position: absolute;' + (!colorPickers[index].cssIsReady ? 'display: none;' : '') +
  2305. 'left:' + (position.left + options.margin.left - atrect.left) + 'px;' +
  2306. 'top:' + (position.top + +input.offsetHeight + options.margin.top - atrect.top) + 'px;';
  2307.  
  2308. if (!multiple) {
  2309. options.input = elm;
  2310. options.patch = elm; // check again???
  2311. colorPicker.setColor(extractValue(elm), undefined, undefined, true);
  2312. colorPicker.saveAsBackground();
  2313. }
  2314. colorPickers.current = colorPickers[index];
  2315. appendTo.appendChild(colorPickerUI);
  2316. waitTimer = setInterval(function() { // compensating late style on onload in colorPicker
  2317. if (colorPickers.current.cssIsReady) {
  2318. waitTimer = clearInterval(waitTimer);
  2319. colorPickerUI.style.display = 'block';
  2320. }
  2321. }, 10);
  2322. },
  2323. mousDownListener = function(e) {
  2324. var colorPicker = colorPickers.current,
  2325. colorPickerUI = (colorPicker ? colorPicker.nodes.colorPicker : undefined),
  2326. animationSpeed = colorPicker ? colorPicker.color.options.animationSpeed : 0,
  2327. isColorPicker = colorPicker && (function(elm) {
  2328. while (elm) {
  2329. if ((elm.className || '').indexOf('cp-app') !== -1) return elm;
  2330. elm = elm.parentNode;
  2331. }
  2332. return false;
  2333. })(e.target),
  2334. inputIndex = Array.prototype.indexOf.call(elms, e.target);
  2335.  
  2336. if (isColorPicker && Array.prototype.indexOf.call(colorPickers, isColorPicker)) {
  2337. if (e.target === colorPicker.nodes.exit) {
  2338. colorPickerUI.style.display = 'none';
  2339. document.activeElement.blur();
  2340. } else {
  2341. // ...
  2342. }
  2343. } else if (inputIndex !== -1) {
  2344. // ...
  2345. } else if (colorPickerUI) {
  2346. colorPickerUI.style.display = 'none';
  2347. }
  2348. };
  2349.  
  2350. elm[onOff]('focus', focusListener);
  2351.  
  2352. if (!colorPickers.evt || off) {
  2353. colorPickers.evt = true; // prevent new eventListener for window
  2354.  
  2355. window[onOff]('mousedown', mousDownListener);
  2356. }
  2357. },
  2358. // this is a way to prevent data binding on HTMLElements
  2359. colorPickers = window.jsColorPicker.colorPickers || [],
  2360. elms = document.querySelectorAll(selectors),
  2361. testColors = new window.Colors({customBG: config.customBG, allMixDetails: true});
  2362.  
  2363. window.jsColorPicker.colorPickers = colorPickers;
  2364.  
  2365. for (var n = 0, m = elms.length; n < m; n++) {
  2366. var elm = elms[n];
  2367.  
  2368. if (config === 'destroy') {
  2369. doEventListeners(elm, (config && config.multipleInstances), true);
  2370. if (colorPickers[n]) {
  2371. colorPickers[n].destroyAll();
  2372. }
  2373. } else {
  2374. var color = extractValue(elm);
  2375. var value = color.split('(');
  2376.  
  2377. testColors.setColor(color);
  2378. if (config && config.init) {
  2379. config.init(elm, testColors.colors);
  2380. }
  2381. elm.setAttribute('data-colorMode', value[1] ? value[0].substr(0, 3) : 'HEX');
  2382. doEventListeners(elm, (config && config.multipleInstances), false);
  2383. if (config && config.readOnly) {
  2384. elm.readOnly = true;
  2385. }
  2386. }
  2387. };
  2388.  
  2389. return window.jsColorPicker.colorPickers;
  2390. };
  2391.  
  2392. window.ColorPicker.docCookies = function(key, val, options) {
  2393. var encode = encodeURIComponent, decode = decodeURIComponent,
  2394. cookies, n, tmp, cache = {},
  2395. days;
  2396.  
  2397. if (val === undefined) { // all about reading cookies
  2398. cookies = document.cookie.split(/;\s*/) || [];
  2399. for (n = cookies.length; n--; ) {
  2400. tmp = cookies[n].split('=');
  2401. if (tmp[0]) cache[decode(tmp.shift())] = decode(tmp.join('=')); // there might be '='s in the value...
  2402. }
  2403.  
  2404. if (!key) return cache; // return Json for easy access to all cookies
  2405. else return cache[key]; // easy access to cookies from here
  2406. } else { // write/delete cookie
  2407. options = options || {};
  2408.  
  2409. if (val === '' || options.expires < 0) { // prepare deleteing the cookie
  2410. options.expires = -1;
  2411. // options.path = options.domain = options.secure = undefined; // to make shure the cookie gets deleted...
  2412. }
  2413.  
  2414. if (options.expires !== undefined) { // prepare date if any
  2415. days = new Date();
  2416. days.setDate(days.getDate() + options.expires);
  2417. }
  2418.  
  2419. document.cookie = encode(key) + '=' + encode(val) +
  2420. (days ? '; expires=' + days.toUTCString() : '') +
  2421. (options.path ? '; path=' + options.path : '') +
  2422. (options.domain ? '; domain=' + options.domain : '') +
  2423. (options.secure ? '; secure' : '');
  2424. }
  2425. };
  2426. })(this);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址