PageRenderTime 61ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 1ms

/hippo/src/main/webapp/yui/colorpicker/colorpicker-debug.js

http://hdbc.googlecode.com/
JavaScript | 1783 lines | 850 code | 263 blank | 670 comment | 79 complexity | 8d600231b5b86bfb77a02a1d4901fd7a MD5 | raw file
  1. /*
  2. Copyright (c) 2009, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.7.0
  6. */
  7. /**
  8. * Provides color conversion and validation utils
  9. * @class YAHOO.util.Color
  10. * @namespace YAHOO.util
  11. */
  12. YAHOO.util.Color = function() {
  13. var ZERO = "0",
  14. isArray = YAHOO.lang.isArray,
  15. isNumber = YAHOO.lang.isNumber;
  16. return {
  17. /**
  18. * Converts 0-1 to 0-255
  19. * @method real2dec
  20. * @param n {float} the number to convert
  21. * @return {int} a number 0-255
  22. */
  23. real2dec: function(n) {
  24. return Math.min(255, Math.round(n*256));
  25. },
  26. /**
  27. * Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]
  28. * @method hsv2rgb
  29. * @param h {int|[int, float, float]} the hue, or an
  30. * array containing all three parameters
  31. * @param s {float} the saturation
  32. * @param v {float} the value/brightness
  33. * @return {[int, int, int]} the red, green, blue values in
  34. * decimal.
  35. */
  36. hsv2rgb: function(h, s, v) {
  37. if (isArray(h)) {
  38. return this.hsv2rgb.call(this, h[0], h[1], h[2]);
  39. }
  40. var r, g, b,
  41. i = Math.floor((h/60)%6),
  42. f = (h/60)-i,
  43. p = v*(1-s),
  44. q = v*(1-f*s),
  45. t = v*(1-(1-f)*s),
  46. fn;
  47. switch (i) {
  48. case 0: r=v; g=t; b=p; break;
  49. case 1: r=q; g=v; b=p; break;
  50. case 2: r=p; g=v; b=t; break;
  51. case 3: r=p; g=q; b=v; break;
  52. case 4: r=t; g=p; b=v; break;
  53. case 5: r=v; g=p; b=q; break;
  54. }
  55. fn=this.real2dec;
  56. return [fn(r), fn(g), fn(b)];
  57. },
  58. /**
  59. * Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]
  60. * @method rgb2hsv
  61. * @param r {int|[int, int, int]} the red value, or an
  62. * array containing all three parameters
  63. * @param g {int} the green value
  64. * @param b {int} the blue value
  65. * @return {[int, float, float]} the value converted to hsv
  66. */
  67. rgb2hsv: function(r, g, b) {
  68. if (isArray(r)) {
  69. return this.rgb2hsv.apply(this, r);
  70. }
  71. r /= 255;
  72. g /= 255;
  73. b /= 255;
  74. var h,s,
  75. min = Math.min(Math.min(r,g),b),
  76. max = Math.max(Math.max(r,g),b),
  77. delta = max-min,
  78. hsv;
  79. switch (max) {
  80. case min: h=0; break;
  81. case r: h=60*(g-b)/delta;
  82. if (g<b) {
  83. h+=360;
  84. }
  85. break;
  86. case g: h=(60*(b-r)/delta)+120; break;
  87. case b: h=(60*(r-g)/delta)+240; break;
  88. }
  89. s = (max === 0) ? 0 : 1-(min/max);
  90. hsv = [Math.round(h), s, max];
  91. return hsv;
  92. },
  93. /**
  94. * Converts decimal rgb values into a hex string
  95. * 255,255,255 -> FFFFFF
  96. * @method rgb2hex
  97. * @param r {int|[int, int, int]} the red value, or an
  98. * array containing all three parameters
  99. * @param g {int} the green value
  100. * @param b {int} the blue value
  101. * @return {string} the hex string
  102. */
  103. rgb2hex: function(r, g, b) {
  104. if (isArray(r)) {
  105. return this.rgb2hex.apply(this, r);
  106. }
  107. var f=this.dec2hex;
  108. return f(r) + f(g) + f(b);
  109. },
  110. /**
  111. * Converts an int 0...255 to hex pair 00...FF
  112. * @method dec2hex
  113. * @param n {int} the number to convert
  114. * @return {string} the hex equivalent
  115. */
  116. dec2hex: function(n) {
  117. n = parseInt(n,10)|0;
  118. n = (n > 255 || n < 0) ? 0 : n;
  119. return (ZERO+n.toString(16)).slice(-2).toUpperCase();
  120. },
  121. /**
  122. * Converts a hex pair 00...FF to an int 0...255
  123. * @method hex2dec
  124. * @param str {string} the hex pair to convert
  125. * @return {int} the decimal
  126. */
  127. hex2dec: function(str) {
  128. return parseInt(str,16);
  129. },
  130. /**
  131. * Converts a hex string to rgb
  132. * @method hex2rgb
  133. * @param str {string} the hex string
  134. * @return {[int, int, int]} an array containing the rgb values
  135. */
  136. hex2rgb: function(s) {
  137. var f = this.hex2dec;
  138. return [f(s.slice(0, 2)), f(s.slice(2, 4)), f(s.slice(4, 6))];
  139. },
  140. /**
  141. * Returns the closest websafe color to the supplied rgb value.
  142. * @method websafe
  143. * @param r {int|[int, int, int]} the red value, or an
  144. * array containing all three parameters
  145. * @param g {int} the green value
  146. * @param b {int} the blue value
  147. * @return {[int, int, int]} an array containing the closes
  148. * websafe rgb colors.
  149. */
  150. websafe: function(r, g, b) {
  151. if (isArray(r)) {
  152. return this.websafe.apply(this, r);
  153. }
  154. // returns the closest match [0, 51, 102, 153, 204, 255]
  155. var f = function(v) {
  156. if (isNumber(v)) {
  157. v = Math.min(Math.max(0, v), 255);
  158. var i, next;
  159. for (i=0; i<256; i=i+51) {
  160. next = i+51;
  161. if (v >= i && v <= next) {
  162. return (v-i > 25) ? next : i;
  163. }
  164. }
  165. YAHOO.log("Error calculating the websafe value for " + v, "warn");
  166. }
  167. return v;
  168. };
  169. return [f(r), f(g), f(b)];
  170. }
  171. };
  172. }();
  173. /**
  174. * The colorpicker module provides a widget for selecting colors
  175. * @module colorpicker
  176. * @requires yahoo, dom, event, element, slider
  177. */
  178. (function() {
  179. var _pickercount = 0,
  180. util = YAHOO.util,
  181. lang = YAHOO.lang,
  182. Slider = YAHOO.widget.Slider,
  183. Color = util.Color,
  184. Dom = util.Dom,
  185. Event = util.Event,
  186. sub = lang.substitute,
  187. b = "yui-picker";
  188. /**
  189. * A widget to select colors
  190. * @namespace YAHOO.widget
  191. * @class YAHOO.widget.ColorPicker
  192. * @extends YAHOO.util.Element
  193. * @constructor
  194. * @param {HTMLElement | String | Object} el(optional) The html
  195. * element that represents the colorpicker, or the attribute object to use.
  196. * An element will be created if none provided.
  197. * @param {Object} attr (optional) A key map of the colorpicker's
  198. * initial attributes. Ignored if first arg is attributes object.
  199. */
  200. function ColorPicker(el, attr) {
  201. _pickercount = _pickercount + 1;
  202. this.logger = new YAHOO.widget.LogWriter("ColorPicker");
  203. attr = attr || {};
  204. if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
  205. attr = el; // treat first arg as attr object
  206. el = attr.element || null;
  207. }
  208. if (!el && !attr.element) { // create if we dont have one
  209. this.logger.log("creating host element");
  210. el = this._createHostElement(attr);
  211. }
  212. ColorPicker.superclass.constructor.call(this, el, attr);
  213. this.initPicker();
  214. }
  215. YAHOO.extend(ColorPicker, YAHOO.util.Element, {
  216. /**
  217. * The element ids used by this control
  218. * @property ID
  219. * @final
  220. */
  221. ID : {
  222. /**
  223. * The id for the "red" form field
  224. * @property ID.R
  225. * @type String
  226. * @final
  227. * @default yui-picker-r
  228. */
  229. R: b + "-r",
  230. /**
  231. * The id for the "red" hex pair output
  232. * @property ID.R_HEX
  233. * @type String
  234. * @final
  235. * @default yui-picker-rhex
  236. */
  237. R_HEX: b + "-rhex",
  238. /**
  239. * The id for the "green" form field
  240. * @property ID.G
  241. * @type String
  242. * @final
  243. * @default yui-picker-g
  244. */
  245. G: b + "-g",
  246. /**
  247. * The id for the "green" hex pair output
  248. * @property ID.G_HEX
  249. * @type String
  250. * @final
  251. * @default yui-picker-ghex
  252. */
  253. G_HEX: b + "-ghex",
  254. /**
  255. * The id for the "blue" form field
  256. * @property ID.B
  257. * @type String
  258. * @final
  259. * @default yui-picker-b
  260. */
  261. B: b + "-b",
  262. /**
  263. * The id for the "blue" hex pair output
  264. * @property ID.B_HEX
  265. * @type String
  266. * @final
  267. * @default yui-picker-bhex
  268. */
  269. B_HEX: b + "-bhex",
  270. /**
  271. * The id for the "hue" form field
  272. * @property ID.H
  273. * @type String
  274. * @final
  275. * @default yui-picker-h
  276. */
  277. H: b + "-h",
  278. /**
  279. * The id for the "saturation" form field
  280. * @property ID.S
  281. * @type String
  282. * @final
  283. * @default yui-picker-s
  284. */
  285. S: b + "-s",
  286. /**
  287. * The id for the "value" form field
  288. * @property ID.V
  289. * @type String
  290. * @final
  291. * @default yui-picker-v
  292. */
  293. V: b + "-v",
  294. /**
  295. * The id for the picker region slider
  296. * @property ID.PICKER_BG
  297. * @type String
  298. * @final
  299. * @default yui-picker-bg
  300. */
  301. PICKER_BG: b + "-bg",
  302. /**
  303. * The id for the picker region thumb
  304. * @property ID.PICKER_THUMB
  305. * @type String
  306. * @final
  307. * @default yui-picker-thumb
  308. */
  309. PICKER_THUMB: b + "-thumb",
  310. /**
  311. * The id for the hue slider
  312. * @property ID.HUE_BG
  313. * @type String
  314. * @final
  315. * @default yui-picker-hue-bg
  316. */
  317. HUE_BG: b + "-hue-bg",
  318. /**
  319. * The id for the hue thumb
  320. * @property ID.HUE_THUMB
  321. * @type String
  322. * @final
  323. * @default yui-picker-hue-thumb
  324. */
  325. HUE_THUMB: b + "-hue-thumb",
  326. /**
  327. * The id for the hex value form field
  328. * @property ID.HEX
  329. * @type String
  330. * @final
  331. * @default yui-picker-hex
  332. */
  333. HEX: b + "-hex",
  334. /**
  335. * The id for the color swatch
  336. * @property ID.SWATCH
  337. * @type String
  338. * @final
  339. * @default yui-picker-swatch
  340. */
  341. SWATCH: b + "-swatch",
  342. /**
  343. * The id for the websafe color swatch
  344. * @property ID.WEBSAFE_SWATCH
  345. * @type String
  346. * @final
  347. * @default yui-picker-websafe-swatch
  348. */
  349. WEBSAFE_SWATCH: b + "-websafe-swatch",
  350. /**
  351. * The id for the control details
  352. * @property ID.CONTROLS
  353. * @final
  354. * @default yui-picker-controls
  355. */
  356. CONTROLS: b + "-controls",
  357. /**
  358. * The id for the rgb controls
  359. * @property ID.RGB_CONTROLS
  360. * @final
  361. * @default yui-picker-rgb-controls
  362. */
  363. RGB_CONTROLS: b + "-rgb-controls",
  364. /**
  365. * The id for the hsv controls
  366. * @property ID.HSV_CONTROLS
  367. * @final
  368. * @default yui-picker-hsv-controls
  369. */
  370. HSV_CONTROLS: b + "-hsv-controls",
  371. /**
  372. * The id for the hsv controls
  373. * @property ID.HEX_CONTROLS
  374. * @final
  375. * @default yui-picker-hex-controls
  376. */
  377. HEX_CONTROLS: b + "-hex-controls",
  378. /**
  379. * The id for the hex summary
  380. * @property ID.HEX_SUMMARY
  381. * @final
  382. * @default yui-picker-hex-summary
  383. */
  384. HEX_SUMMARY: b + "-hex-summary",
  385. /**
  386. * The id for the controls section header
  387. * @property ID.CONTROLS_LABEL
  388. * @final
  389. * @default yui-picker-controls-label
  390. */
  391. CONTROLS_LABEL: b + "-controls-label"
  392. },
  393. /**
  394. * Constants for any script-generated messages. The values here
  395. * are the default messages. They can be updated by providing
  396. * the complete list to the constructor for the "txt" attribute.
  397. * @property TXT
  398. * @final
  399. */
  400. TXT : {
  401. ILLEGAL_HEX: "Illegal hex value entered",
  402. SHOW_CONTROLS: "Show color details",
  403. HIDE_CONTROLS: "Hide color details",
  404. CURRENT_COLOR: "Currently selected color: {rgb}",
  405. CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",
  406. R: "R",
  407. G: "G",
  408. B: "B",
  409. H: "H",
  410. S: "S",
  411. V: "V",
  412. HEX: "#",
  413. DEG: "\u00B0",
  414. PERCENT: "%"
  415. },
  416. /**
  417. * Constants for the default image locations for img tags that are
  418. * generated by the control. They can be modified by passing the
  419. * complete list to the contructor for the "images" attribute
  420. * @property IMAGE
  421. * @final
  422. */
  423. IMAGE : {
  424. PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",
  425. HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"
  426. },
  427. /**
  428. * Constants for the control's default default values
  429. * @property DEFAULT
  430. * @final
  431. */
  432. DEFAULT : {
  433. PICKER_SIZE: 180
  434. },
  435. /**
  436. * Constants for the control's configuration attributes
  437. * @property OPT
  438. * @final
  439. */
  440. OPT : {
  441. HUE : "hue",
  442. SATURATION : "saturation",
  443. VALUE : "value",
  444. RED : "red",
  445. GREEN : "green",
  446. BLUE : "blue",
  447. HSV : "hsv",
  448. RGB : "rgb",
  449. WEBSAFE : "websafe",
  450. HEX : "hex",
  451. PICKER_SIZE : "pickersize",
  452. SHOW_CONTROLS : "showcontrols",
  453. SHOW_RGB_CONTROLS : "showrgbcontrols",
  454. SHOW_HSV_CONTROLS : "showhsvcontrols",
  455. SHOW_HEX_CONTROLS : "showhexcontrols",
  456. SHOW_HEX_SUMMARY : "showhexsummary",
  457. SHOW_WEBSAFE : "showwebsafe",
  458. CONTAINER : "container",
  459. IDS : "ids",
  460. ELEMENTS : "elements",
  461. TXT : "txt",
  462. IMAGES : "images",
  463. ANIMATE : "animate"
  464. },
  465. /**
  466. * Flag to allow individual UI updates to forego animation if available.
  467. * True during construction for initial thumb placement. Set to false
  468. * after that.
  469. *
  470. * @property skipAnim
  471. * @type Boolean
  472. * @default true
  473. */
  474. skipAnim : true,
  475. /**
  476. * Creates the host element if it doesn't exist
  477. * @method _createHostElement
  478. * @protected
  479. */
  480. _createHostElement : function () {
  481. var el = document.createElement('div');
  482. if (this.CSS.BASE) {
  483. el.className = this.CSS.BASE;
  484. }
  485. return el;
  486. },
  487. /**
  488. * Moves the hue slider into the position dictated by the current state
  489. * of the control
  490. * @method _updateHueSlider
  491. * @protected
  492. */
  493. _updateHueSlider : function() {
  494. var size = this.get(this.OPT.PICKER_SIZE),
  495. h = this.get(this.OPT.HUE);
  496. h = size - Math.round(h / 360 * size);
  497. // 0 is at the top and bottom of the hue slider. Always go to
  498. // the top so we don't end up sending the thumb to the bottom
  499. // when the value didn't actually change (e.g., a conversion
  500. // produced 360 instead of 0 and the value was already 0).
  501. if (h === size) {
  502. h = 0;
  503. }
  504. this.logger.log("Hue slider is being set to " + h);
  505. this.hueSlider.setValue(h, this.skipAnim);
  506. },
  507. /**
  508. * Moves the picker slider into the position dictated by the current state
  509. * of the control
  510. * @method _updatePickerSlider
  511. * @protected
  512. */
  513. _updatePickerSlider : function() {
  514. var size = this.get(this.OPT.PICKER_SIZE),
  515. s = this.get(this.OPT.SATURATION),
  516. v = this.get(this.OPT.VALUE);
  517. s = Math.round(s * size / 100);
  518. v = Math.round(size - (v * size / 100));
  519. this.logger.log("Setting picker slider to " + [s, v]);
  520. this.pickerSlider.setRegionValue(s, v, this.skipAnim);
  521. },
  522. /**
  523. * Moves the sliders into the position dictated by the current state
  524. * of the control
  525. * @method _updateSliders
  526. * @protected
  527. */
  528. _updateSliders : function() {
  529. this._updateHueSlider();
  530. this._updatePickerSlider();
  531. },
  532. /**
  533. * Sets the control to the specified rgb value and
  534. * moves the sliders to the proper positions
  535. * @method setValue
  536. * @param rgb {[int, int, int]} the rgb value
  537. * @param silent {boolean} whether or not to fire the change event
  538. */
  539. setValue : function(rgb, silent) {
  540. silent = (silent) || false;
  541. this.set(this.OPT.RGB, rgb, silent);
  542. this._updateSliders();
  543. },
  544. /**
  545. * The hue slider
  546. * @property hueSlider
  547. * @type YAHOO.widget.Slider
  548. */
  549. hueSlider : null,
  550. /**
  551. * The picker region
  552. * @property pickerSlider
  553. * @type YAHOO.widget.Slider
  554. */
  555. pickerSlider : null,
  556. /**
  557. * Translates the slider value into hue, int[0,359]
  558. * @method _getH
  559. * @protected
  560. * @return {int} the hue from 0 to 359
  561. */
  562. _getH : function() {
  563. var size = this.get(this.OPT.PICKER_SIZE),
  564. h = (size - this.hueSlider.getValue()) / size;
  565. h = Math.round(h*360);
  566. return (h === 360) ? 0 : h;
  567. },
  568. /**
  569. * Translates the slider value into saturation, int[0,1], left to right
  570. * @method _getS
  571. * @protected
  572. * @return {int} the saturation from 0 to 1
  573. */
  574. _getS : function() {
  575. return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);
  576. },
  577. /**
  578. * Translates the slider value into value/brightness, int[0,1], top
  579. * to bottom
  580. * @method _getV
  581. * @protected
  582. * @return {int} the value from 0 to 1
  583. */
  584. _getV : function() {
  585. var size = this.get(this.OPT.PICKER_SIZE);
  586. return (size - this.pickerSlider.getYValue()) / size;
  587. },
  588. /**
  589. * Updates the background of the swatch with the current rbg value.
  590. * Also updates the websafe swatch to the closest websafe color
  591. * @method _updateSwatch
  592. * @protected
  593. */
  594. _updateSwatch : function() {
  595. var rgb = this.get(this.OPT.RGB),
  596. websafe = this.get(this.OPT.WEBSAFE),
  597. el = this.getElement(this.ID.SWATCH),
  598. color = rgb.join(","),
  599. txt = this.get(this.OPT.TXT);
  600. Dom.setStyle(el, "background-color", "rgb(" + color + ")");
  601. el.title = sub(txt.CURRENT_COLOR, {
  602. "rgb": "#" + this.get(this.OPT.HEX)
  603. });
  604. el = this.getElement(this.ID.WEBSAFE_SWATCH);
  605. color = websafe.join(",");
  606. Dom.setStyle(el, "background-color", "rgb(" + color + ")");
  607. el.title = sub(txt.CLOSEST_WEBSAFE, {
  608. "rgb": "#" + Color.rgb2hex(websafe)
  609. });
  610. },
  611. /**
  612. * Reads the sliders and converts the values to RGB, updating the
  613. * internal state for all the individual form fields
  614. * @method _getValuesFromSliders
  615. * @protected
  616. */
  617. _getValuesFromSliders : function() {
  618. this.logger.log("hsv " + [this._getH(),this._getS(),this._getV()]);
  619. this.set(this.OPT.RGB, Color.hsv2rgb(this._getH(), this._getS(), this._getV()));
  620. },
  621. /**
  622. * Updates the form field controls with the state data contained
  623. * in the control.
  624. * @method _updateFormFields
  625. * @protected
  626. */
  627. _updateFormFields : function() {
  628. this.getElement(this.ID.H).value = this.get(this.OPT.HUE);
  629. this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);
  630. this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);
  631. this.getElement(this.ID.R).value = this.get(this.OPT.RED);
  632. this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));
  633. this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);
  634. this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));
  635. this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);
  636. this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));
  637. this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);
  638. },
  639. /**
  640. * Event handler for the hue slider.
  641. * @method _onHueSliderChange
  642. * @param newOffset {int} pixels from the start position
  643. * @protected
  644. */
  645. _onHueSliderChange : function(newOffset) {
  646. this.logger.log("hue update: " + newOffset , "warn");
  647. var h = this._getH(),
  648. rgb = Color.hsv2rgb(h, 1, 1),
  649. styleDef = "rgb(" + rgb.join(",") + ")";
  650. this.set(this.OPT.HUE, h, true);
  651. // set picker background to the hue
  652. Dom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);
  653. if (this.hueSlider.valueChangeSource !== Slider.SOURCE_SET_VALUE) {
  654. this._getValuesFromSliders();
  655. }
  656. this._updateFormFields();
  657. this._updateSwatch();
  658. },
  659. /**
  660. * Event handler for the picker slider, which controls the
  661. * saturation and value/brightness.
  662. * @method _onPickerSliderChange
  663. * @param newOffset {{x: int, y: int}} x/y pixels from the start position
  664. * @protected
  665. */
  666. _onPickerSliderChange : function(newOffset) {
  667. this.logger.log(sub("picker update [{x}, {y}]", newOffset));
  668. var s=this._getS(), v=this._getV();
  669. this.set(this.OPT.SATURATION, Math.round(s*100), true);
  670. this.set(this.OPT.VALUE, Math.round(v*100), true);
  671. if (this.pickerSlider.valueChangeSource !== Slider.SOURCE_SET_VALUE) {
  672. this._getValuesFromSliders();
  673. }
  674. this._updateFormFields();
  675. this._updateSwatch();
  676. },
  677. /**
  678. * Key map to well-known commands for txt field input
  679. * @method _getCommand
  680. * @param e {Event} the keypress or keydown event
  681. * @return {int} a command code
  682. * <ul>
  683. * <li>0 = not a number, letter in range, or special key</li>
  684. * <li>1 = number</li>
  685. * <li>2 = a-fA-F</li>
  686. * <li>3 = increment (up arrow)</li>
  687. * <li>4 = decrement (down arrow)</li>
  688. * <li>5 = special key (tab, delete, return, escape, left, right)</li>
  689. * <li>6 = return</li>
  690. * </ul>
  691. * @protected
  692. */
  693. _getCommand : function(e) {
  694. var c = Event.getCharCode(e);
  695. //alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode);
  696. // special keys
  697. if (c === 38) { // up arrow
  698. return 3;
  699. } else if (c === 13) { // return
  700. return 6;
  701. } else if (c === 40) { // down array
  702. return 4;
  703. } else if (c >= 48 && c<=57) { // 0-9
  704. return 1;
  705. } else if (c >= 97 && c<=102) { // a-f
  706. return 2;
  707. } else if (c >= 65 && c<=70) { // A-F
  708. return 2;
  709. //} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 ||
  710. // (c >= 112 && c <=123)) { // including F-keys
  711. // tab, delete, return, escape, left, right or ctrl/meta sequences
  712. } else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 ||
  713. e.ctrlKey || e.metaKey) { // special chars
  714. return 5;
  715. } else { // something we probably don't want
  716. return 0;
  717. }
  718. },
  719. /**
  720. * Use the value of the text field to update the control
  721. * @method _useFieldValue
  722. * @param e {Event} an event
  723. * @param el {HTMLElement} the field
  724. * @param prop {string} the key to the linked property
  725. * @protected
  726. */
  727. _useFieldValue : function(e, el, prop) {
  728. var val = el.value;
  729. if (prop !== this.OPT.HEX) {
  730. val = parseInt(val, 10);
  731. }
  732. if (val !== this.get(prop)) {
  733. this.set(prop, val);
  734. }
  735. },
  736. /**
  737. * Handle keypress on one of the rgb or hsv fields.
  738. * @method _rgbFieldKeypress
  739. * @param e {Event} the keypress event
  740. * @param el {HTMLElement} the field
  741. * @param prop {string} the key to the linked property
  742. * @protected
  743. */
  744. _rgbFieldKeypress : function(e, el, prop) {
  745. var command = this._getCommand(e),
  746. inc = (e.shiftKey) ? 10 : 1;
  747. switch (command) {
  748. case 6: // return, update the value
  749. this._useFieldValue.apply(this, arguments);
  750. break;
  751. case 3: // up arrow, increment
  752. this.set(prop, Math.min(this.get(prop)+inc, 255));
  753. this._updateFormFields();
  754. //Event.stopEvent(e);
  755. break;
  756. case 4: // down arrow, decrement
  757. this.set(prop, Math.max(this.get(prop)-inc, 0));
  758. this._updateFormFields();
  759. //Event.stopEvent(e);
  760. break;
  761. default:
  762. }
  763. },
  764. /**
  765. * Handle keydown on the hex field
  766. * @method _hexFieldKeypress
  767. * @param e {Event} the keypress event
  768. * @param el {HTMLElement} the field
  769. * @param prop {string} the key to the linked property
  770. * @protected
  771. */
  772. _hexFieldKeypress : function(e, el, prop) {
  773. var command = this._getCommand(e);
  774. if (command === 6) { // return, update the value
  775. this._useFieldValue.apply(this, arguments);
  776. }
  777. },
  778. /**
  779. * Allows numbers and special chars, and by default allows a-f.
  780. * Used for the hex field keypress handler.
  781. * @method _hexOnly
  782. * @param e {Event} the event
  783. * @param numbersOnly omits a-f if set to true
  784. * @protected
  785. * @return {boolean} false if we are canceling the event
  786. */
  787. _hexOnly : function(e, numbersOnly) {
  788. var command = this._getCommand(e);
  789. switch (command) {
  790. case 6: // return
  791. case 5: // special char
  792. case 1: // number
  793. break;
  794. case 2: // hex char (a-f)
  795. if (numbersOnly !== true) {
  796. break;
  797. }
  798. // fallthrough is intentional
  799. default: // prevent alpha and punctuation
  800. Event.stopEvent(e);
  801. return false;
  802. }
  803. },
  804. /**
  805. * Allows numbers and special chars only. Used for the
  806. * rgb and hsv fields keypress handler.
  807. * @method _numbersOnly
  808. * @param e {Event} the event
  809. * @protected
  810. * @return {boolean} false if we are canceling the event
  811. */
  812. _numbersOnly : function(e) {
  813. return this._hexOnly(e, true);
  814. },
  815. /**
  816. * Returns the element reference that is saved. The id can be either
  817. * the element id, or the key for this id in the "id" config attribute.
  818. * For instance, the host element id can be obtained by passing its
  819. * id (default: "yui_picker") or by its key "YUI_PICKER".
  820. * @param id {string} the element id, or key
  821. * @return {HTMLElement} a reference to the element
  822. */
  823. getElement : function(id) {
  824. return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]];
  825. },
  826. _createElements : function() {
  827. this.logger.log("Building markup");
  828. var el, child, img, fld, p,
  829. ids = this.get(this.OPT.IDS),
  830. txt = this.get(this.OPT.TXT),
  831. images = this.get(this.OPT.IMAGES),
  832. Elem = function(type, o) {
  833. var n = document.createElement(type);
  834. if (o) {
  835. lang.augmentObject(n, o, true);
  836. }
  837. return n;
  838. },
  839. RGBElem = function(type, obj) {
  840. var o = lang.merge({
  841. //type: "txt",
  842. autocomplete: "off",
  843. value: "0",
  844. size: 3,
  845. maxlength: 3
  846. }, obj);
  847. o.name = o.id;
  848. return new Elem(type, o);
  849. };
  850. p = this.get("element");
  851. // Picker slider (S and V) ---------------------------------------------
  852. el = new Elem("div", {
  853. id: ids[this.ID.PICKER_BG],
  854. className: "yui-picker-bg",
  855. tabIndex: -1,
  856. hideFocus: true
  857. });
  858. child = new Elem("div", {
  859. id: ids[this.ID.PICKER_THUMB],
  860. className: "yui-picker-thumb"
  861. });
  862. img = new Elem("img", {
  863. src: images.PICKER_THUMB
  864. });
  865. child.appendChild(img);
  866. el.appendChild(child);
  867. p.appendChild(el);
  868. // Hue slider ---------------------------------------------
  869. el = new Elem("div", {
  870. id: ids[this.ID.HUE_BG],
  871. className: "yui-picker-hue-bg",
  872. tabIndex: -1,
  873. hideFocus: true
  874. });
  875. child = new Elem("div", {
  876. id: ids[this.ID.HUE_THUMB],
  877. className: "yui-picker-hue-thumb"
  878. });
  879. img = new Elem("img", {
  880. src: images.HUE_THUMB
  881. });
  882. child.appendChild(img);
  883. el.appendChild(child);
  884. p.appendChild(el);
  885. // controls ---------------------------------------------
  886. el = new Elem("div", {
  887. id: ids[this.ID.CONTROLS],
  888. className: "yui-picker-controls"
  889. });
  890. p.appendChild(el);
  891. p = el;
  892. // controls header
  893. el = new Elem("div", {
  894. className: "hd"
  895. });
  896. child = new Elem("a", {
  897. id: ids[this.ID.CONTROLS_LABEL],
  898. //className: "yui-picker-controls-label",
  899. href: "#"
  900. });
  901. el.appendChild(child);
  902. p.appendChild(el);
  903. // bd
  904. el = new Elem("div", {
  905. className: "bd"
  906. });
  907. p.appendChild(el);
  908. p = el;
  909. // rgb
  910. el = new Elem("ul", {
  911. id: ids[this.ID.RGB_CONTROLS],
  912. className: "yui-picker-rgb-controls"
  913. });
  914. child = new Elem("li");
  915. child.appendChild(document.createTextNode(txt.R + " "));
  916. fld = new RGBElem("input", {
  917. id: ids[this.ID.R],
  918. className: "yui-picker-r"
  919. });
  920. child.appendChild(fld);
  921. el.appendChild(child);
  922. child = new Elem("li");
  923. child.appendChild(document.createTextNode(txt.G + " "));
  924. fld = new RGBElem("input", {
  925. id: ids[this.ID.G],
  926. className: "yui-picker-g"
  927. });
  928. child.appendChild(fld);
  929. el.appendChild(child);
  930. child = new Elem("li");
  931. child.appendChild(document.createTextNode(txt.B + " "));
  932. fld = new RGBElem("input", {
  933. id: ids[this.ID.B],
  934. className: "yui-picker-b"
  935. });
  936. child.appendChild(fld);
  937. el.appendChild(child);
  938. p.appendChild(el);
  939. // hsv
  940. el = new Elem("ul", {
  941. id: ids[this.ID.HSV_CONTROLS],
  942. className: "yui-picker-hsv-controls"
  943. });
  944. child = new Elem("li");
  945. child.appendChild(document.createTextNode(txt.H + " "));
  946. fld = new RGBElem("input", {
  947. id: ids[this.ID.H],
  948. className: "yui-picker-h"
  949. });
  950. child.appendChild(fld);
  951. child.appendChild(document.createTextNode(" " + txt.DEG));
  952. el.appendChild(child);
  953. child = new Elem("li");
  954. child.appendChild(document.createTextNode(txt.S + " "));
  955. fld = new RGBElem("input", {
  956. id: ids[this.ID.S],
  957. className: "yui-picker-s"
  958. });
  959. child.appendChild(fld);
  960. child.appendChild(document.createTextNode(" " + txt.PERCENT));
  961. el.appendChild(child);
  962. child = new Elem("li");
  963. child.appendChild(document.createTextNode(txt.V + " "));
  964. fld = new RGBElem("input", {
  965. id: ids[this.ID.V],
  966. className: "yui-picker-v"
  967. });
  968. child.appendChild(fld);
  969. child.appendChild(document.createTextNode(" " + txt.PERCENT));
  970. el.appendChild(child);
  971. p.appendChild(el);
  972. // hex summary
  973. el = new Elem("ul", {
  974. id: ids[this.ID.HEX_SUMMARY],
  975. className: "yui-picker-hex_summary"
  976. });
  977. child = new Elem("li", {
  978. id: ids[this.ID.R_HEX]
  979. });
  980. el.appendChild(child);
  981. child = new Elem("li", {
  982. id: ids[this.ID.G_HEX]
  983. });
  984. el.appendChild(child);
  985. child = new Elem("li", {
  986. id: ids[this.ID.B_HEX]
  987. });
  988. el.appendChild(child);
  989. p.appendChild(el);
  990. // hex field
  991. el = new Elem("div", {
  992. id: ids[this.ID.HEX_CONTROLS],
  993. className: "yui-picker-hex-controls"
  994. });
  995. el.appendChild(document.createTextNode(txt.HEX + " "));
  996. child = new RGBElem("input", {
  997. id: ids[this.ID.HEX],
  998. className: "yui-picker-hex",
  999. size: 6,
  1000. maxlength: 6
  1001. });
  1002. el.appendChild(child);
  1003. p.appendChild(el);
  1004. p = this.get("element");
  1005. // swatch
  1006. el = new Elem("div", {
  1007. id: ids[this.ID.SWATCH],
  1008. className: "yui-picker-swatch"
  1009. });
  1010. p.appendChild(el);
  1011. // websafe swatch
  1012. el = new Elem("div", {
  1013. id: ids[this.ID.WEBSAFE_SWATCH],
  1014. className: "yui-picker-websafe-swatch"
  1015. });
  1016. p.appendChild(el);
  1017. },
  1018. _attachRGBHSV : function(id, config) {
  1019. Event.on(this.getElement(id), "keydown", function(e, me) {
  1020. me._rgbFieldKeypress(e, this, config);
  1021. }, this);
  1022. Event.on(this.getElement(id), "keypress", this._numbersOnly, this, true);
  1023. Event.on(this.getElement(id), "blur", function(e, me) {
  1024. me._useFieldValue(e, this, config);
  1025. }, this);
  1026. },
  1027. /**
  1028. * Updates the rgb attribute with the current state of the r,g,b
  1029. * fields. This is invoked from change listeners on these
  1030. * attributes to facilitate updating these values from the
  1031. * individual form fields
  1032. * @method _updateRGB
  1033. * @protected
  1034. */
  1035. _updateRGB : function() {
  1036. var rgb = [this.get(this.OPT.RED),
  1037. this.get(this.OPT.GREEN),
  1038. this.get(this.OPT.BLUE)];
  1039. this.logger.log("RGB value set to " + rgb);
  1040. this.set(this.OPT.RGB, rgb);
  1041. this._updateSliders();
  1042. },
  1043. /**
  1044. * Creates any missing DOM structure.
  1045. *
  1046. * @method _initElements
  1047. * @protected
  1048. */
  1049. _initElements : function () {
  1050. // bind all of our elements
  1051. var o=this.OPT,
  1052. ids = this.get(o.IDS),
  1053. els = this.get(o.ELEMENTS),
  1054. i, el, id;
  1055. // Add the default value as a key for each element for easier lookup
  1056. for (i in this.ID) {
  1057. if (lang.hasOwnProperty(this.ID, i)) {
  1058. ids[this.ID[i]] = ids[i];
  1059. }
  1060. }
  1061. // Check for picker element, if not there, create all of them
  1062. el = Dom.get(ids[this.ID.PICKER_BG]);
  1063. if (!el) {
  1064. this._createElements();
  1065. } else {
  1066. this.logger.log("Using pre-existing markup");
  1067. }
  1068. for (i in ids) {
  1069. if (lang.hasOwnProperty(ids, i)) {
  1070. // look for element
  1071. el = Dom.get(ids[i]);
  1072. // generate an id if the implementer passed in an element reference,
  1073. // and the element did not have an id already
  1074. id = Dom.generateId(el);
  1075. // update the id in case we generated the id
  1076. ids[i] = id; // key is WEBSAFE_SWATCH
  1077. ids[ids[i]] = id; // key is websafe_swatch
  1078. // store the dom ref
  1079. els[id] = el;
  1080. }
  1081. }
  1082. },
  1083. /**
  1084. * Sets the initial state of the sliders
  1085. * @method initPicker
  1086. */
  1087. initPicker : function () {
  1088. this._initSliders();
  1089. this._bindUI();
  1090. this.syncUI(true);
  1091. },
  1092. /**
  1093. * Creates the Hue and Value/Saturation Sliders.
  1094. *
  1095. * @method _initSliders
  1096. * @protected
  1097. */
  1098. _initSliders : function () {
  1099. var ID = this.ID,
  1100. size = this.get(this.OPT.PICKER_SIZE);
  1101. this.logger.log("picker size" + size);
  1102. this.hueSlider = Slider.getVertSlider(
  1103. this.getElement(ID.HUE_BG),
  1104. this.getElement(ID.HUE_THUMB), 0, size);
  1105. this.pickerSlider = Slider.getSliderRegion(
  1106. this.getElement(ID.PICKER_BG),
  1107. this.getElement(ID.PICKER_THUMB), 0, size, 0, size);
  1108. // Apply animate attribute configuration
  1109. this.set(this.OPT.ANIMATE, this.get(this.OPT.ANIMATE));
  1110. },
  1111. /**
  1112. * Adds event listeners to Sliders and UI elements. Wires everything
  1113. * up.
  1114. *
  1115. * @method _bindUI
  1116. * @protected
  1117. */
  1118. _bindUI : function () {
  1119. var ID = this.ID,
  1120. O = this.OPT;
  1121. this.hueSlider.subscribe("change",
  1122. this._onHueSliderChange, this, true);
  1123. this.pickerSlider.subscribe("change",
  1124. this._onPickerSliderChange, this, true);
  1125. Event.on(this.getElement(ID.WEBSAFE_SWATCH), "click", function(e) {
  1126. this.setValue(this.get(O.WEBSAFE));
  1127. }, this, true);
  1128. Event.on(this.getElement(ID.CONTROLS_LABEL), "click", function(e) {
  1129. this.set(O.SHOW_CONTROLS, !this.get(O.SHOW_CONTROLS));
  1130. Event.preventDefault(e);
  1131. }, this, true);
  1132. this._attachRGBHSV(ID.R, O.RED);
  1133. this._attachRGBHSV(ID.G, O.GREEN);
  1134. this._attachRGBHSV(ID.B, O.BLUE);
  1135. this._attachRGBHSV(ID.H, O.HUE);
  1136. this._attachRGBHSV(ID.S, O.SATURATION);
  1137. this._attachRGBHSV(ID.V, O.VALUE);
  1138. Event.on(this.getElement(ID.HEX), "keydown", function(e, me) {
  1139. me._hexFieldKeypress(e, this, O.HEX);
  1140. }, this);
  1141. Event.on(this.getElement(this.ID.HEX), "keypress",
  1142. this._hexOnly, this,true);
  1143. Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) {
  1144. me._useFieldValue(e, this, O.HEX);
  1145. }, this);
  1146. },
  1147. /**
  1148. * Wrapper for _updateRGB, but allows setting
  1149. *
  1150. * @method syncUI
  1151. * @param skipAnim {Boolean} Omit Slider animation for this action
  1152. */
  1153. syncUI : function (skipAnim) {
  1154. this.skipAnim = skipAnim;
  1155. this._updateRGB();
  1156. this.skipAnim = false;
  1157. },
  1158. /**
  1159. * Updates the RGB values from the current state of the HSV
  1160. * values. Executed when the one of the HSV form fields are
  1161. * updated
  1162. * _updateRGBFromHSV
  1163. * @protected
  1164. */
  1165. _updateRGBFromHSV : function() {
  1166. var hsv = [this.get(this.OPT.HUE),
  1167. this.get(this.OPT.SATURATION)/100,
  1168. this.get(this.OPT.VALUE)/100],
  1169. rgb = Color.hsv2rgb(hsv);
  1170. this.logger.log("HSV converted to RGB " + hsv + " : " + rgb);
  1171. this.set(this.OPT.RGB, rgb);
  1172. this._updateSliders();
  1173. },
  1174. /**
  1175. * Parses the hex string to normalize shorthand values, converts
  1176. * the hex value to rgb and updates the rgb attribute (which
  1177. * updates the state for all of the other values)
  1178. * method _updateHex
  1179. * @protected
  1180. */
  1181. _updateHex : function() {
  1182. var hex = this.get(this.OPT.HEX),
  1183. l = hex.length,
  1184. c,i,rgb;
  1185. // support #369 -> #336699 shorthand
  1186. if (l === 3) {
  1187. c = hex.split("");
  1188. for (i=0; i<l; i=i+1) {
  1189. c[i] = c[i] + c[i];
  1190. }
  1191. hex = c.join("");
  1192. }
  1193. if (hex.length !== 6) {
  1194. this.logger.log(this.get(this.TXT.ILLEGAL_HEX), "error");
  1195. return false;
  1196. }
  1197. rgb = Color.hex2rgb(hex);
  1198. this.logger.log(sub("Hex value set to {hex} ({rgb})", {
  1199. hex: hex, rgb: rgb
  1200. }));
  1201. this.setValue(rgb);
  1202. },
  1203. /**
  1204. * Returns the cached element reference. If the id is not a string, it
  1205. * is assumed that it is an element and this is returned.
  1206. * @param id {string|HTMLElement} the element key, id, or ref
  1207. * @param on {boolean} hide or show. If true, show
  1208. * @protected
  1209. */
  1210. _hideShowEl : function(id, on) {
  1211. var el = (lang.isString(id) ? this.getElement(id) : id);
  1212. Dom.setStyle(el, "display", (on) ? "" : "none");
  1213. },
  1214. /**
  1215. * Sets up the config attributes and the change listeners for this
  1216. * properties
  1217. * @method initAttributes
  1218. * @param attr An object containing default attribute values
  1219. */
  1220. initAttributes : function(attr) {
  1221. attr = attr || {};
  1222. ColorPicker.superclass.initAttributes.call(this, attr);
  1223. /**
  1224. * The size of the picker. Trying to change this is not recommended.
  1225. * @attribute pickersize
  1226. * @default 180
  1227. * @type int
  1228. */
  1229. this.setAttributeConfig(this.OPT.PICKER_SIZE, {
  1230. value: attr.size || this.DEFAULT.PICKER_SIZE
  1231. });
  1232. /**
  1233. * The current hue value 0-360
  1234. * @attribute hue
  1235. * @type int
  1236. */
  1237. this.setAttributeConfig(this.OPT.HUE, {
  1238. value: attr.hue || 0,
  1239. validator: lang.isNumber
  1240. });
  1241. /**
  1242. * The current saturation value 0-100
  1243. * @attribute saturation
  1244. * @type int
  1245. */
  1246. this.setAttributeConfig(this.OPT.SATURATION, {
  1247. value: attr.saturation || 0,
  1248. validator: lang.isNumber
  1249. });
  1250. /**
  1251. * The current value/brightness value 0-100
  1252. * @attribute value
  1253. * @type int
  1254. */
  1255. this.setAttributeConfig(this.OPT.VALUE, {
  1256. value: lang.isNumber(attr.value) ? attr.value : 100,
  1257. validator: lang.isNumber
  1258. });
  1259. /**
  1260. * The current red value 0-255
  1261. * @attribute red
  1262. * @type int
  1263. */
  1264. this.setAttributeConfig(this.OPT.RED, {
  1265. value: lang.isNumber(attr.red) ? attr.red : 255,
  1266. validator: lang.isNumber
  1267. });
  1268. /**
  1269. * The current green value 0-255
  1270. * @attribute green
  1271. * @type int
  1272. */
  1273. this.setAttributeConfig(this.OPT.GREEN, {
  1274. value: lang.isNumber(attr.green) ? attr.green : 255,
  1275. validator: lang.isNumber
  1276. });
  1277. /**
  1278. * The current blue value 0-255
  1279. * @attribute blue
  1280. * @type int
  1281. */
  1282. this.setAttributeConfig(this.OPT.BLUE, {
  1283. value: lang.isNumber(attr.blue) ? attr.blue : 255,
  1284. validator: lang.isNumber
  1285. });
  1286. /**
  1287. * The current hex value #000000-#FFFFFF, without the #
  1288. * @attribute hex
  1289. * @type string
  1290. */
  1291. this.setAttributeConfig(this.OPT.HEX, {
  1292. value: attr.hex || "FFFFFF",
  1293. validator: lang.isString
  1294. });
  1295. /**
  1296. * The current rgb value. Updates the state of all of the
  1297. * other value fields. Read-only: use setValue to set the
  1298. * controls rgb value.
  1299. * @attribute hex
  1300. * @type [int, int, int]
  1301. * @readonly
  1302. */
  1303. this.setAttributeConfig(this.OPT.RGB, {
  1304. value: attr.rgb || [255,255,255],
  1305. method: function(rgb) {
  1306. this.set(this.OPT.RED, rgb[0], true);
  1307. this.set(this.OPT.GREEN, rgb[1], true);
  1308. this.set(this.OPT.BLUE, rgb[2], true);
  1309. var websafe = Color.websafe(rgb),
  1310. hex = Color.rgb2hex(rgb),
  1311. hsv = Color.rgb2hsv(rgb);
  1312. this.set(this.OPT.WEBSAFE, websafe, true);
  1313. this.set(this.OPT.HEX, hex, true);
  1314. this.logger.log(sub("RGB value set to {rgb} (hsv: {hsv})", {
  1315. "hsv": hsv, "rgb": rgb
  1316. }));
  1317. // fix bug #1754338 - when saturation is 0, hue is
  1318. // silently always set to 0, but input field not updated
  1319. if (hsv[1]) {
  1320. this.set(this.OPT.HUE, hsv[0], true);
  1321. }
  1322. this.set(this.OPT.SATURATION, Math.round(hsv[1]*100), true);
  1323. this.set(this.OPT.VALUE, Math.round(hsv[2]*100), true);
  1324. },
  1325. readonly: true
  1326. });
  1327. /**
  1328. * If the color picker will live inside of a container object,
  1329. * set, provide a reference to it so the control can use the
  1330. * container's events.
  1331. * @attribute container
  1332. * @type YAHOO.widget.Panel
  1333. */
  1334. this.setAttributeConfig(this.OPT.CONTAINER, {
  1335. value: null,
  1336. method: function(container) {
  1337. if (container) {
  1338. // Position can get out of sync when the
  1339. // control is manipulated while display is
  1340. // none. Resetting the slider constraints
  1341. // when it is visible gets the state back in
  1342. // order.
  1343. container.showEvent.subscribe(function() {
  1344. // this.pickerSlider.thumb.resetConstraints();
  1345. // this.hueSlider.thumb.resetConstraints();
  1346. this.pickerSlider.focus();
  1347. }, this, true);
  1348. }
  1349. }
  1350. });
  1351. /**
  1352. * The closest current websafe value
  1353. * @attribute websafe
  1354. * @type int
  1355. */
  1356. this.setAttributeConfig(this.OPT.WEBSAFE, {
  1357. value: attr.websafe || [255,255,255]
  1358. });
  1359. var ids = attr.ids || lang.merge({}, this.ID), i;
  1360. if (!attr.ids && _pickercount > 1) {
  1361. for (i in ids) {
  1362. if (lang.hasOwnProperty(ids, i)) {
  1363. ids[i] = ids[i] + _pickercount;
  1364. }
  1365. }
  1366. }
  1367. /**
  1368. * A list of element ids and/or element references used by the
  1369. * control. The default is the this.ID list, and can be customized
  1370. * by passing a list in the contructor
  1371. * @attribute ids
  1372. * @type {referenceid: realid}
  1373. * @writeonce
  1374. */
  1375. this.setAttributeConfig(this.OPT.IDS, {
  1376. value: ids,
  1377. writeonce: true
  1378. });
  1379. /**
  1380. * A list of txt strings for internationalization. Default
  1381. * is this.TXT
  1382. * @attribute txt
  1383. * @type {key: txt}
  1384. * @writeonce
  1385. */
  1386. this.setAttributeConfig(this.OPT.TXT, {
  1387. value: attr.txt || this.TXT,
  1388. writeonce: true
  1389. });
  1390. /**
  1391. * The img src default list
  1392. * is this.IMAGES
  1393. * @attribute images
  1394. * @type {key: image}
  1395. * @writeonce
  1396. */
  1397. this.setAttributeConfig(this.OPT.IMAGES, {
  1398. value: attr.images || this.IMAGE,
  1399. writeonce: true
  1400. });
  1401. /**
  1402. * The element refs used by this control. Set at initialization
  1403. * @attribute elements
  1404. * @type {id: HTMLElement}
  1405. * @readonly
  1406. */
  1407. this.setAttributeConfig(this.OPT.ELEMENTS, {
  1408. value: {},
  1409. readonly: true
  1410. });
  1411. /**
  1412. * Hide/show the entire set of controls
  1413. * @attribute showcontrols
  1414. * @type boolean
  1415. * @default true
  1416. */
  1417. this.setAttributeConfig(this.OPT.SHOW_CONTROLS, {
  1418. value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true,
  1419. method: function(on) {
  1420. var el = Dom.getElementsByClassName("bd", "div",
  1421. this.getElement(this.ID.CONTROLS))[0];
  1422. this._hideShowEl(el, on);
  1423. this.getElement(this.ID.CONTROLS_LABEL).innerHTML =
  1424. (on) ? this.get(this.OPT.TXT).HIDE_CONTROLS :
  1425. this.get(this.OPT.TXT).SHOW_CONTROLS;
  1426. }
  1427. });
  1428. /**
  1429. * Hide/show the rgb controls
  1430. * @attribute showrgbcontrols
  1431. * @type boolean
  1432. * @default true
  1433. */
  1434. this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, {
  1435. value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true,
  1436. method: function(on) {
  1437. this._hideShowEl(this.ID.RGB_CONTROLS, on);
  1438. }
  1439. });
  1440. /**
  1441. * Hide/show the hsv controls
  1442. * @attribute showhsvcontrols
  1443. * @type boolean
  1444. * @default false
  1445. */
  1446. this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, {
  1447. value: lang.isBoolean(attr.showhsvcontrols) ?
  1448. attr.showhsvcontrols : false,
  1449. method: function(on) {
  1450. //Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden");
  1451. this._hideShowEl(this.ID.HSV_CONTROLS, on);
  1452. // can't show both the hsv controls and the rbg hex summary
  1453. if (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) {
  1454. this.set(this.OPT.SHOW_HEX_SUMMARY, false);
  1455. }
  1456. }
  1457. });
  1458. /**
  1459. * Hide/show the hex controls
  1460. * @attribute showhexcontrols
  1461. * @type boolean
  1462. * @default true
  1463. */
  1464. this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, {
  1465. value: lang.isBoolean(attr.showhexcontrols) ?
  1466. attr.showhexcontrols : false,
  1467. method: function(on) {
  1468. this._hideShowEl(this.ID.HEX_CONTROLS, on);
  1469. }
  1470. });
  1471. /**
  1472. * Hide/show the websafe swatch
  1473. * @attribute showwebsafe
  1474. * @type boolean
  1475. * @default true
  1476. */
  1477. this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, {
  1478. value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true,
  1479. method: function(on) {
  1480. this._hideShowEl(this.ID.WEBSAFE_SWATCH, on);
  1481. }
  1482. });
  1483. /**
  1484. * Hide/show the hex summary
  1485. * @attribute showhexsummary
  1486. * @type boolean
  1487. * @default true
  1488. */
  1489. this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, {
  1490. value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true,
  1491. method: function(on) {
  1492. this._hideShowEl(this.ID.HEX_SUMMARY, on);
  1493. // can't show both the hsv controls and the rbg hex summary
  1494. if (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) {
  1495. this.set(this.OPT.SHOW_HSV_CONTROLS, false);
  1496. }
  1497. }
  1498. });
  1499. this.setAttributeConfig(this.OPT.ANIMATE, {
  1500. value: lang.isBoolean(attr.animate) ? attr.animate : true,
  1501. method: function(on) {
  1502. if (this.pickerSlider) {
  1503. this.pickerSlider.animate = on;
  1504. this.hueSlider.animate = on;
  1505. }
  1506. }
  1507. });
  1508. this.on(this.OPT.HUE + "Change", this._updateRGBFromHSV, this, true);
  1509. this.on(this.OPT.SATURATION + "Change", this._updateRGBFromHSV, this, true);
  1510. this.on(this.OPT.VALUE + "Change", this._updateRGBFromHSV, this, true);
  1511. this.on(this.OPT.RED + "Change", this._updateRGB, this, true);
  1512. this.on(this.OPT.GREEN + "Change", this._updateRGB, this, true);
  1513. this.on(this.OPT.BLUE + "Change", this._updateRGB, this, true);
  1514. this.on(this.OPT.HEX + "Change", this._updateHex, this, true);
  1515. this._initElements();
  1516. }
  1517. });
  1518. YAHOO.widget.ColorPicker = ColorPicker;
  1519. })();
  1520. YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.7.0", build: "1799"});