AutorÃa | Ultima modificación | Ver Log |
YUI.add('yui2-colorpicker', function(Y) {var YAHOO = Y.YUI2;/*Copyright (c) 2011, Yahoo! Inc. All rights reserved.Code licensed under the BSD License:http://developer.yahoo.com/yui/license.htmlversion: 2.9.0*//*** Provides color conversion and validation utils* @class YAHOO.util.Color* @namespace YAHOO.util*/YAHOO.util.Color = function() {var ZERO = "0",isArray = YAHOO.lang.isArray,isNumber = YAHOO.lang.isNumber;return {/*** Converts 0-1 to 0-255* @method real2dec* @param n {float} the number to convert* @return {int} a number 0-255*/real2dec: function(n) {return Math.min(255, Math.round(n*256));},/*** Converts HSV (h[0-360], s[0-1]), v[0-1] to RGB [255,255,255]* @method hsv2rgb* @param h {int|[int, float, float]} the hue, or an* array containing all three parameters* @param s {float} the saturation* @param v {float} the value/brightness* @return {[int, int, int]} the red, green, blue values in* decimal.*/hsv2rgb: function(h, s, v) {if (isArray(h)) {return this.hsv2rgb.call(this, h[0], h[1], h[2]);}var r, g, b,i = Math.floor((h/60)%6),f = (h/60)-i,p = v*(1-s),q = v*(1-f*s),t = v*(1-(1-f)*s),fn;switch (i) {case 0: r=v; g=t; b=p; break;case 1: r=q; g=v; b=p; break;case 2: r=p; g=v; b=t; break;case 3: r=p; g=q; b=v; break;case 4: r=t; g=p; b=v; break;case 5: r=v; g=p; b=q; break;}fn=this.real2dec;return [fn(r), fn(g), fn(b)];},/*** Converts to RGB [255,255,255] to HSV (h[0-360], s[0-1]), v[0-1]* @method rgb2hsv* @param r {int|[int, int, int]} the red value, or an* array containing all three parameters* @param g {int} the green value* @param b {int} the blue value* @return {[int, float, float]} the value converted to hsv*/rgb2hsv: function(r, g, b) {if (isArray(r)) {return this.rgb2hsv.apply(this, r);}r /= 255;g /= 255;b /= 255;var h,s,min = Math.min(Math.min(r,g),b),max = Math.max(Math.max(r,g),b),delta = max-min,hsv;switch (max) {case min: h=0; break;case r: h=60*(g-b)/delta;if (g<b) {h+=360;}break;case g: h=(60*(b-r)/delta)+120; break;case b: h=(60*(r-g)/delta)+240; break;}s = (max === 0) ? 0 : 1-(min/max);hsv = [Math.round(h), s, max];return hsv;},/*** Converts decimal rgb values into a hex string* 255,255,255 -> FFFFFF* @method rgb2hex* @param r {int|[int, int, int]} the red value, or an* array containing all three parameters* @param g {int} the green value* @param b {int} the blue value* @return {string} the hex string*/rgb2hex: function(r, g, b) {if (isArray(r)) {return this.rgb2hex.apply(this, r);}var f=this.dec2hex;return f(r) + f(g) + f(b);},/*** Converts an int 0...255 to hex pair 00...FF* @method dec2hex* @param n {int} the number to convert* @return {string} the hex equivalent*/dec2hex: function(n) {n = parseInt(n,10)|0;n = (n > 255 || n < 0) ? 0 : n;return (ZERO+n.toString(16)).slice(-2).toUpperCase();},/*** Converts a hex pair 00...FF to an int 0...255* @method hex2dec* @param str {string} the hex pair to convert* @return {int} the decimal*/hex2dec: function(str) {return parseInt(str,16);},/*** Converts a hex string to rgb* @method hex2rgb* @param str {string} the hex string* @return {[int, int, int]} an array containing the rgb values*/hex2rgb: function(s) {var f = this.hex2dec;return [f(s.slice(0, 2)), f(s.slice(2, 4)), f(s.slice(4, 6))];},/*** Returns the closest websafe color to the supplied rgb value.* @method websafe* @param r {int|[int, int, int]} the red value, or an* array containing all three parameters* @param g {int} the green value* @param b {int} the blue value* @return {[int, int, int]} an array containing the closes* websafe rgb colors.*/websafe: function(r, g, b) {if (isArray(r)) {return this.websafe.apply(this, r);}// returns the closest match [0, 51, 102, 153, 204, 255]var f = function(v) {if (isNumber(v)) {v = Math.min(Math.max(0, v), 255);var i, next;for (i=0; i<256; i=i+51) {next = i+51;if (v >= i && v <= next) {return (v-i > 25) ? next : i;}}YAHOO.log("Error calculating the websafe value for " + v, "warn");}return v;};return [f(r), f(g), f(b)];}};}();/*** The colorpicker module provides a widget for selecting colors* @module colorpicker* @requires yahoo, dom, event, element, slider*/(function() {var _pickercount = 0,util = YAHOO.util,lang = YAHOO.lang,Slider = YAHOO.widget.Slider,Color = util.Color,Dom = util.Dom,Event = util.Event,sub = lang.substitute,b = "yui-picker";/*** A widget to select colors* @namespace YAHOO.widget* @class YAHOO.widget.ColorPicker* @extends YAHOO.util.Element* @constructor* @param {HTMLElement | String | Object} el(optional) The html* element that represents the colorpicker, or the attribute object to use.* An element will be created if none provided.* @param {Object} attr (optional) A key map of the colorpicker's* initial attributes. Ignored if first arg is attributes object.*/function ColorPicker(el, attr) {_pickercount = _pickercount + 1;this.logger = new YAHOO.widget.LogWriter("ColorPicker");attr = attr || {};if (arguments.length === 1 && !YAHOO.lang.isString(el) && !el.nodeName) {attr = el; // treat first arg as attr objectel = attr.element || null;}if (!el && !attr.element) { // create if we dont have onethis.logger.log("creating host element");el = this._createHostElement(attr);}ColorPicker.superclass.constructor.call(this, el, attr);this.initPicker();}YAHOO.extend(ColorPicker, YAHOO.util.Element, {/*** The element ids used by this control* @property ID* @final*/ID : {/*** The id for the "red" form field* @property ID.R* @type String* @final* @default yui-picker-r*/R: b + "-r",/*** The id for the "red" hex pair output* @property ID.R_HEX* @type String* @final* @default yui-picker-rhex*/R_HEX: b + "-rhex",/*** The id for the "green" form field* @property ID.G* @type String* @final* @default yui-picker-g*/G: b + "-g",/*** The id for the "green" hex pair output* @property ID.G_HEX* @type String* @final* @default yui-picker-ghex*/G_HEX: b + "-ghex",/*** The id for the "blue" form field* @property ID.B* @type String* @final* @default yui-picker-b*/B: b + "-b",/*** The id for the "blue" hex pair output* @property ID.B_HEX* @type String* @final* @default yui-picker-bhex*/B_HEX: b + "-bhex",/*** The id for the "hue" form field* @property ID.H* @type String* @final* @default yui-picker-h*/H: b + "-h",/*** The id for the "saturation" form field* @property ID.S* @type String* @final* @default yui-picker-s*/S: b + "-s",/*** The id for the "value" form field* @property ID.V* @type String* @final* @default yui-picker-v*/V: b + "-v",/*** The id for the picker region slider* @property ID.PICKER_BG* @type String* @final* @default yui-picker-bg*/PICKER_BG: b + "-bg",/*** The id for the picker region thumb* @property ID.PICKER_THUMB* @type String* @final* @default yui-picker-thumb*/PICKER_THUMB: b + "-thumb",/*** The id for the hue slider* @property ID.HUE_BG* @type String* @final* @default yui-picker-hue-bg*/HUE_BG: b + "-hue-bg",/*** The id for the hue thumb* @property ID.HUE_THUMB* @type String* @final* @default yui-picker-hue-thumb*/HUE_THUMB: b + "-hue-thumb",/*** The id for the hex value form field* @property ID.HEX* @type String* @final* @default yui-picker-hex*/HEX: b + "-hex",/*** The id for the color swatch* @property ID.SWATCH* @type String* @final* @default yui-picker-swatch*/SWATCH: b + "-swatch",/*** The id for the websafe color swatch* @property ID.WEBSAFE_SWATCH* @type String* @final* @default yui-picker-websafe-swatch*/WEBSAFE_SWATCH: b + "-websafe-swatch",/*** The id for the control details* @property ID.CONTROLS* @final* @default yui-picker-controls*/CONTROLS: b + "-controls",/*** The id for the rgb controls* @property ID.RGB_CONTROLS* @final* @default yui-picker-rgb-controls*/RGB_CONTROLS: b + "-rgb-controls",/*** The id for the hsv controls* @property ID.HSV_CONTROLS* @final* @default yui-picker-hsv-controls*/HSV_CONTROLS: b + "-hsv-controls",/*** The id for the hsv controls* @property ID.HEX_CONTROLS* @final* @default yui-picker-hex-controls*/HEX_CONTROLS: b + "-hex-controls",/*** The id for the hex summary* @property ID.HEX_SUMMARY* @final* @default yui-picker-hex-summary*/HEX_SUMMARY: b + "-hex-summary",/*** The id for the controls section header* @property ID.CONTROLS_LABEL* @final* @default yui-picker-controls-label*/CONTROLS_LABEL: b + "-controls-label"},/*** Constants for any script-generated messages. The values here* are the default messages. They can be updated by providing* the complete list to the constructor for the "txt" attribute.* Note: the strings are added to the DOM as HTML.* @property TXT* @final*/TXT : {ILLEGAL_HEX: "Illegal hex value entered",SHOW_CONTROLS: "Show color details",HIDE_CONTROLS: "Hide color details",CURRENT_COLOR: "Currently selected color: {rgb}",CLOSEST_WEBSAFE: "Closest websafe color: {rgb}. Click to select.",R: "R",G: "G",B: "B",H: "H",S: "S",V: "V",HEX: "#",DEG: "\u00B0",PERCENT: "%"},/*** Constants for the default image locations for img tags that are* generated by the control. They can be modified by passing the* complete list to the contructor for the "images" attribute* @property IMAGE* @final*/IMAGE : {PICKER_THUMB: "../../build/colorpicker/assets/picker_thumb.png",HUE_THUMB: "../../build/colorpicker/assets/hue_thumb.png"},/*** Constants for the control's default default values* @property DEFAULT* @final*/DEFAULT : {PICKER_SIZE: 180},/*** Constants for the control's configuration attributes* @property OPT* @final*/OPT : {HUE : "hue",SATURATION : "saturation",VALUE : "value",RED : "red",GREEN : "green",BLUE : "blue",HSV : "hsv",RGB : "rgb",WEBSAFE : "websafe",HEX : "hex",PICKER_SIZE : "pickersize",SHOW_CONTROLS : "showcontrols",SHOW_RGB_CONTROLS : "showrgbcontrols",SHOW_HSV_CONTROLS : "showhsvcontrols",SHOW_HEX_CONTROLS : "showhexcontrols",SHOW_HEX_SUMMARY : "showhexsummary",SHOW_WEBSAFE : "showwebsafe",CONTAINER : "container",IDS : "ids",ELEMENTS : "elements",TXT : "txt",IMAGES : "images",ANIMATE : "animate"},/*** Flag to allow individual UI updates to forego animation if available.* True during construction for initial thumb placement. Set to false* after that.** @property skipAnim* @type Boolean* @default true*/skipAnim : true,/*** Creates the host element if it doesn't exist* @method _createHostElement* @protected*/_createHostElement : function () {var el = document.createElement('div');if (this.CSS.BASE) {el.className = this.CSS.BASE;}return el;},/*** Moves the hue slider into the position dictated by the current state* of the control* @method _updateHueSlider* @protected*/_updateHueSlider : function() {var size = this.get(this.OPT.PICKER_SIZE),h = this.get(this.OPT.HUE);h = size - Math.round(h / 360 * size);// 0 is at the top and bottom of the hue slider. Always go to// the top so we don't end up sending the thumb to the bottom// when the value didn't actually change (e.g., a conversion// produced 360 instead of 0 and the value was already 0).if (h === size) {h = 0;}this.logger.log("Hue slider is being set to " + h);this.hueSlider.setValue(h, this.skipAnim);},/*** Moves the picker slider into the position dictated by the current state* of the control* @method _updatePickerSlider* @protected*/_updatePickerSlider : function() {var size = this.get(this.OPT.PICKER_SIZE),s = this.get(this.OPT.SATURATION),v = this.get(this.OPT.VALUE);s = Math.round(s * size / 100);v = Math.round(size - (v * size / 100));this.logger.log("Setting picker slider to " + [s, v]);this.pickerSlider.setRegionValue(s, v, this.skipAnim);},/*** Moves the sliders into the position dictated by the current state* of the control* @method _updateSliders* @protected*/_updateSliders : function() {this._updateHueSlider();this._updatePickerSlider();},/*** Sets the control to the specified rgb value and* moves the sliders to the proper positions* @method setValue* @param rgb {[int, int, int]} the rgb value* @param silent {boolean} whether or not to fire the change event*/setValue : function(rgb, silent) {silent = (silent) || false;this.set(this.OPT.RGB, rgb, silent);this._updateSliders();},/*** The hue slider* @property hueSlider* @type YAHOO.widget.Slider*/hueSlider : null,/*** The picker region* @property pickerSlider* @type YAHOO.widget.Slider*/pickerSlider : null,/*** Translates the slider value into hue, int[0,359]* @method _getH* @protected* @return {int} the hue from 0 to 359*/_getH : function() {var size = this.get(this.OPT.PICKER_SIZE),h = (size - this.hueSlider.getValue()) / size;h = Math.round(h*360);return (h === 360) ? 0 : h;},/*** Translates the slider value into saturation, int[0,1], left to right* @method _getS* @protected* @return {int} the saturation from 0 to 1*/_getS : function() {return this.pickerSlider.getXValue() / this.get(this.OPT.PICKER_SIZE);},/*** Translates the slider value into value/brightness, int[0,1], top* to bottom* @method _getV* @protected* @return {int} the value from 0 to 1*/_getV : function() {var size = this.get(this.OPT.PICKER_SIZE);return (size - this.pickerSlider.getYValue()) / size;},/*** Updates the background of the swatch with the current rbg value.* Also updates the websafe swatch to the closest websafe color* @method _updateSwatch* @protected*/_updateSwatch : function() {var rgb = this.get(this.OPT.RGB),websafe = this.get(this.OPT.WEBSAFE),el = this.getElement(this.ID.SWATCH),color = rgb.join(","),txt = this.get(this.OPT.TXT);Dom.setStyle(el, "background-color", "rgb(" + color + ")");el.title = sub(txt.CURRENT_COLOR, {"rgb": "#" + this.get(this.OPT.HEX)});el = this.getElement(this.ID.WEBSAFE_SWATCH);color = websafe.join(",");Dom.setStyle(el, "background-color", "rgb(" + color + ")");el.title = sub(txt.CLOSEST_WEBSAFE, {"rgb": "#" + Color.rgb2hex(websafe)});},/*** Reads the sliders and converts the values to RGB, updating the* internal state for all the individual form fields* @method _getValuesFromSliders* @protected*/_getValuesFromSliders : function() {this.logger.log("hsv " + [this._getH(),this._getS(),this._getV()]);this.set(this.OPT.RGB, Color.hsv2rgb(this._getH(), this._getS(), this._getV()));},/*** Updates the form field controls with the state data contained* in the control.* @method _updateFormFields* @protected*/_updateFormFields : function() {this.getElement(this.ID.H).value = this.get(this.OPT.HUE);this.getElement(this.ID.S).value = this.get(this.OPT.SATURATION);this.getElement(this.ID.V).value = this.get(this.OPT.VALUE);this.getElement(this.ID.R).value = this.get(this.OPT.RED);this.getElement(this.ID.R_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.RED));this.getElement(this.ID.G).value = this.get(this.OPT.GREEN);this.getElement(this.ID.G_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.GREEN));this.getElement(this.ID.B).value = this.get(this.OPT.BLUE);this.getElement(this.ID.B_HEX).innerHTML = Color.dec2hex(this.get(this.OPT.BLUE));this.getElement(this.ID.HEX).value = this.get(this.OPT.HEX);},/*** Event handler for the hue slider.* @method _onHueSliderChange* @param newOffset {int} pixels from the start position* @protected*/_onHueSliderChange : function(newOffset) {this.logger.log("hue update: " + newOffset , "warn");var h = this._getH(),rgb = Color.hsv2rgb(h, 1, 1),styleDef = "rgb(" + rgb.join(",") + ")";this.set(this.OPT.HUE, h, true);// set picker background to the hueDom.setStyle(this.getElement(this.ID.PICKER_BG), "background-color", styleDef);if (this.hueSlider.valueChangeSource !== Slider.SOURCE_SET_VALUE) {this._getValuesFromSliders();}this._updateFormFields();this._updateSwatch();},/*** Event handler for the picker slider, which controls the* saturation and value/brightness.* @method _onPickerSliderChange* @param newOffset {{x: int, y: int}} x/y pixels from the start position* @protected*/_onPickerSliderChange : function(newOffset) {this.logger.log(sub("picker update [{x}, {y}]", newOffset));var s=this._getS(), v=this._getV();this.set(this.OPT.SATURATION, Math.round(s*100), true);this.set(this.OPT.VALUE, Math.round(v*100), true);if (this.pickerSlider.valueChangeSource !== Slider.SOURCE_SET_VALUE) {this._getValuesFromSliders();}this._updateFormFields();this._updateSwatch();},/*** Key map to well-known commands for txt field input* @method _getCommand* @param e {Event} the keypress or keydown event* @return {int} a command code* <ul>* <li>0 = not a number, letter in range, or special key</li>* <li>1 = number</li>* <li>2 = a-fA-F</li>* <li>3 = increment (up arrow)</li>* <li>4 = decrement (down arrow)</li>* <li>5 = special key (tab, delete, return, escape, left, right)</li>* <li>6 = return</li>* </ul>* @protected*/_getCommand : function(e) {var c = Event.getCharCode(e);//alert(Event.getCharCode(e) + ", " + e.keyCode + ", " + e.charCode);// special keysif (c === 38) { // up arrowreturn 3;} else if (c === 13) { // returnreturn 6;} else if (c === 40) { // down arrayreturn 4;} else if (c >= 48 && c<=57) { // 0-9return 1;} else if (c >= 97 && c<=102) { // a-freturn 2;} else if (c >= 65 && c<=70) { // A-Freturn 2;//} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 ||// (c >= 112 && c <=123)) { // including F-keys// tab, delete, return, escape, left, right or ctrl/meta sequences} else if ("8, 9, 13, 27, 37, 39".indexOf(c) > -1 ||e.ctrlKey || e.metaKey) { // special charsreturn 5;} else { // something we probably don't wantreturn 0;}},/*** Use the value of the text field to update the control* @method _useFieldValue* @param e {Event} an event* @param el {HTMLElement} the field* @param prop {string} the key to the linked property* @protected*/_useFieldValue : function(e, el, prop) {var val = el.value;if (prop !== this.OPT.HEX) {val = parseInt(val, 10);}if (val !== this.get(prop)) {this.set(prop, val);}},/*** Handle keypress on one of the rgb or hsv fields.* @method _rgbFieldKeypress* @param e {Event} the keypress event* @param el {HTMLElement} the field* @param prop {string} the key to the linked property* @protected*/_rgbFieldKeypress : function(e, el, prop) {var command = this._getCommand(e),inc = (e.shiftKey) ? 10 : 1;switch (command) {case 6: // return, update the valuethis._useFieldValue.apply(this, arguments);break;case 3: // up arrow, incrementthis.set(prop, Math.min(this.get(prop)+inc, 255));this._updateFormFields();//Event.stopEvent(e);break;case 4: // down arrow, decrementthis.set(prop, Math.max(this.get(prop)-inc, 0));this._updateFormFields();//Event.stopEvent(e);break;default:}},/*** Handle keydown on the hex field* @method _hexFieldKeypress* @param e {Event} the keypress event* @param el {HTMLElement} the field* @param prop {string} the key to the linked property* @protected*/_hexFieldKeypress : function(e, el, prop) {var command = this._getCommand(e);if (command === 6) { // return, update the valuethis._useFieldValue.apply(this, arguments);}},/*** Allows numbers and special chars, and by default allows a-f.* Used for the hex field keypress handler.* @method _hexOnly* @param e {Event} the event* @param numbersOnly omits a-f if set to true* @protected* @return {boolean} false if we are canceling the event*/_hexOnly : function(e, numbersOnly) {var command = this._getCommand(e);switch (command) {case 6: // returncase 5: // special charcase 1: // numberbreak;case 2: // hex char (a-f)if (numbersOnly !== true) {break;}// fallthrough is intentionaldefault: // prevent alpha and punctuationEvent.stopEvent(e);return false;}},/*** Allows numbers and special chars only. Used for the* rgb and hsv fields keypress handler.* @method _numbersOnly* @param e {Event} the event* @protected* @return {boolean} false if we are canceling the event*/_numbersOnly : function(e) {return this._hexOnly(e, true);},/*** Returns the element reference that is saved. The id can be either* the element id, or the key for this id in the "id" config attribute.* For instance, the host element id can be obtained by passing its* id (default: "yui_picker") or by its key "YUI_PICKER".* @param id {string} the element id, or key* @return {HTMLElement} a reference to the element*/getElement : function(id) {return this.get(this.OPT.ELEMENTS)[this.get(this.OPT.IDS)[id]];},_createElements : function() {this.logger.log("Building markup");var el, child, img, fld, p,ids = this.get(this.OPT.IDS),txt = this.get(this.OPT.TXT),images = this.get(this.OPT.IMAGES),Elem = function(type, o) {var n = document.createElement(type);if (o) {lang.augmentObject(n, o, true);}return n;},RGBElem = function(type, obj) {var o = lang.merge({//type: "txt",autocomplete: "off",value: "0",size: 3,maxlength: 3}, obj);o.name = o.id;return new Elem(type, o);};p = this.get("element");// Picker slider (S and V) ---------------------------------------------el = new Elem("div", {id: ids[this.ID.PICKER_BG],className: "yui-picker-bg",tabIndex: -1,hideFocus: true});child = new Elem("div", {id: ids[this.ID.PICKER_THUMB],className: "yui-picker-thumb"});img = new Elem("img", {src: images.PICKER_THUMB});child.appendChild(img);el.appendChild(child);p.appendChild(el);// Hue slider ---------------------------------------------el = new Elem("div", {id: ids[this.ID.HUE_BG],className: "yui-picker-hue-bg",tabIndex: -1,hideFocus: true});child = new Elem("div", {id: ids[this.ID.HUE_THUMB],className: "yui-picker-hue-thumb"});img = new Elem("img", {src: images.HUE_THUMB});child.appendChild(img);el.appendChild(child);p.appendChild(el);// controls ---------------------------------------------el = new Elem("div", {id: ids[this.ID.CONTROLS],className: "yui-picker-controls"});p.appendChild(el);p = el;// controls headerel = new Elem("div", {className: "hd"});child = new Elem("a", {id: ids[this.ID.CONTROLS_LABEL],//className: "yui-picker-controls-label",href: "#"});el.appendChild(child);p.appendChild(el);// bdel = new Elem("div", {className: "bd"});p.appendChild(el);p = el;// rgbel = new Elem("ul", {id: ids[this.ID.RGB_CONTROLS],className: "yui-picker-rgb-controls"});child = new Elem("li");child.appendChild(document.createTextNode(txt.R + " "));fld = new RGBElem("input", {id: ids[this.ID.R],className: "yui-picker-r"});child.appendChild(fld);el.appendChild(child);child = new Elem("li");child.appendChild(document.createTextNode(txt.G + " "));fld = new RGBElem("input", {id: ids[this.ID.G],className: "yui-picker-g"});child.appendChild(fld);el.appendChild(child);child = new Elem("li");child.appendChild(document.createTextNode(txt.B + " "));fld = new RGBElem("input", {id: ids[this.ID.B],className: "yui-picker-b"});child.appendChild(fld);el.appendChild(child);p.appendChild(el);// hsvel = new Elem("ul", {id: ids[this.ID.HSV_CONTROLS],className: "yui-picker-hsv-controls"});child = new Elem("li");child.appendChild(document.createTextNode(txt.H + " "));fld = new RGBElem("input", {id: ids[this.ID.H],className: "yui-picker-h"});child.appendChild(fld);child.appendChild(document.createTextNode(" " + txt.DEG));el.appendChild(child);child = new Elem("li");child.appendChild(document.createTextNode(txt.S + " "));fld = new RGBElem("input", {id: ids[this.ID.S],className: "yui-picker-s"});child.appendChild(fld);child.appendChild(document.createTextNode(" " + txt.PERCENT));el.appendChild(child);child = new Elem("li");child.appendChild(document.createTextNode(txt.V + " "));fld = new RGBElem("input", {id: ids[this.ID.V],className: "yui-picker-v"});child.appendChild(fld);child.appendChild(document.createTextNode(" " + txt.PERCENT));el.appendChild(child);p.appendChild(el);// hex summaryel = new Elem("ul", {id: ids[this.ID.HEX_SUMMARY],className: "yui-picker-hex_summary"});child = new Elem("li", {id: ids[this.ID.R_HEX]});el.appendChild(child);child = new Elem("li", {id: ids[this.ID.G_HEX]});el.appendChild(child);child = new Elem("li", {id: ids[this.ID.B_HEX]});el.appendChild(child);p.appendChild(el);// hex fieldel = new Elem("div", {id: ids[this.ID.HEX_CONTROLS],className: "yui-picker-hex-controls"});el.appendChild(document.createTextNode(txt.HEX + " "));child = new RGBElem("input", {id: ids[this.ID.HEX],className: "yui-picker-hex",size: 6,maxlength: 6});el.appendChild(child);p.appendChild(el);p = this.get("element");// swatchel = new Elem("div", {id: ids[this.ID.SWATCH],className: "yui-picker-swatch"});p.appendChild(el);// websafe swatchel = new Elem("div", {id: ids[this.ID.WEBSAFE_SWATCH],className: "yui-picker-websafe-swatch"});p.appendChild(el);},_attachRGBHSV : function(id, config) {Event.on(this.getElement(id), "keydown", function(e, me) {me._rgbFieldKeypress(e, this, config);}, this);Event.on(this.getElement(id), "keypress", this._numbersOnly, this, true);Event.on(this.getElement(id), "blur", function(e, me) {me._useFieldValue(e, this, config);}, this);},/*** Updates the rgb attribute with the current state of the r,g,b* fields. This is invoked from change listeners on these* attributes to facilitate updating these values from the* individual form fields* @method _updateRGB* @protected*/_updateRGB : function() {var rgb = [this.get(this.OPT.RED),this.get(this.OPT.GREEN),this.get(this.OPT.BLUE)];this.logger.log("RGB value set to " + rgb);this.set(this.OPT.RGB, rgb);this._updateSliders();},/*** Creates any missing DOM structure.** @method _initElements* @protected*/_initElements : function () {// bind all of our elementsvar o=this.OPT,ids = this.get(o.IDS),els = this.get(o.ELEMENTS),i, el, id;// Add the default value as a key for each element for easier lookupfor (i in this.ID) {if (lang.hasOwnProperty(this.ID, i)) {ids[this.ID[i]] = ids[i];}}// Check for picker element, if not there, create all of themel = Dom.get(ids[this.ID.PICKER_BG]);if (!el) {this._createElements();} else {this.logger.log("Using pre-existing markup");}for (i in ids) {if (lang.hasOwnProperty(ids, i)) {// look for elementel = Dom.get(ids[i]);// generate an id if the implementer passed in an element reference,// and the element did not have an id alreadyid = Dom.generateId(el);// update the id in case we generated the idids[i] = id; // key is WEBSAFE_SWATCHids[ids[i]] = id; // key is websafe_swatch// store the dom refels[id] = el;}}},/*** Sets the initial state of the sliders* @method initPicker*/initPicker : function () {this._initSliders();this._bindUI();this.syncUI(true);},/*** Creates the Hue and Value/Saturation Sliders.** @method _initSliders* @protected*/_initSliders : function () {var ID = this.ID,size = this.get(this.OPT.PICKER_SIZE);this.logger.log("picker size" + size);this.hueSlider = Slider.getVertSlider(this.getElement(ID.HUE_BG),this.getElement(ID.HUE_THUMB), 0, size);this.pickerSlider = Slider.getSliderRegion(this.getElement(ID.PICKER_BG),this.getElement(ID.PICKER_THUMB), 0, size, 0, size);// Apply animate attribute configurationthis.set(this.OPT.ANIMATE, this.get(this.OPT.ANIMATE));},/*** Adds event listeners to Sliders and UI elements. Wires everything* up.** @method _bindUI* @protected*/_bindUI : function () {var ID = this.ID,O = this.OPT;this.hueSlider.subscribe("change",this._onHueSliderChange, this, true);this.pickerSlider.subscribe("change",this._onPickerSliderChange, this, true);Event.on(this.getElement(ID.WEBSAFE_SWATCH), "click", function(e) {this.setValue(this.get(O.WEBSAFE));}, this, true);Event.on(this.getElement(ID.CONTROLS_LABEL), "click", function(e) {this.set(O.SHOW_CONTROLS, !this.get(O.SHOW_CONTROLS));Event.preventDefault(e);}, this, true);this._attachRGBHSV(ID.R, O.RED);this._attachRGBHSV(ID.G, O.GREEN);this._attachRGBHSV(ID.B, O.BLUE);this._attachRGBHSV(ID.H, O.HUE);this._attachRGBHSV(ID.S, O.SATURATION);this._attachRGBHSV(ID.V, O.VALUE);Event.on(this.getElement(ID.HEX), "keydown", function(e, me) {me._hexFieldKeypress(e, this, O.HEX);}, this);Event.on(this.getElement(this.ID.HEX), "keypress",this._hexOnly, this,true);Event.on(this.getElement(this.ID.HEX), "blur", function(e, me) {me._useFieldValue(e, this, O.HEX);}, this);},/*** Wrapper for _updateRGB, but allows non-animated update** @method syncUI* @param skipAnim {Boolean} Omit Slider animation for this action*/syncUI : function (skipAnim) {this.skipAnim = skipAnim;this._updateRGB();this.skipAnim = false;},/*** Updates the RGB values from the current state of the HSV* values. Executed when the one of the HSV form fields are* updated* _updateRGBFromHSV* @protected*/_updateRGBFromHSV : function() {var hsv = [this.get(this.OPT.HUE),this.get(this.OPT.SATURATION)/100,this.get(this.OPT.VALUE)/100],rgb = Color.hsv2rgb(hsv);this.logger.log("HSV converted to RGB " + hsv + " : " + rgb);this.set(this.OPT.RGB, rgb);this._updateSliders();},/*** Parses the hex string to normalize shorthand values, converts* the hex value to rgb and updates the rgb attribute (which* updates the state for all of the other values)* method _updateHex* @protected*/_updateHex : function() {var hex = this.get(this.OPT.HEX),l = hex.length,c,i,rgb;// support #369 -> #336699 shorthandif (l === 3) {c = hex.split("");for (i=0; i<l; i=i+1) {c[i] = c[i] + c[i];}hex = c.join("");}if (hex.length !== 6) {this.logger.log(this.get(this.TXT.ILLEGAL_HEX), "error");return false;}rgb = Color.hex2rgb(hex);this.logger.log(sub("Hex value set to {hex} ({rgb})", {hex: hex, rgb: rgb}));this.setValue(rgb);},/*** Returns the cached element reference. If the id is not a string, it* is assumed that it is an element and this is returned.* @param id {string|HTMLElement} the element key, id, or ref* @param on {boolean} hide or show. If true, show* @protected*/_hideShowEl : function(id, on) {var el = (lang.isString(id) ? this.getElement(id) : id);Dom.setStyle(el, "display", (on) ? "" : "none");},/*** Sets up the config attributes and the change listeners for this* properties* @method initAttributes* @param attr An object containing default attribute values*/initAttributes : function(attr) {attr = attr || {};ColorPicker.superclass.initAttributes.call(this, attr);/*** The size of the picker. Trying to change this is not recommended.* @attribute pickersize* @default 180* @type int*/this.setAttributeConfig(this.OPT.PICKER_SIZE, {value: attr.size || this.DEFAULT.PICKER_SIZE});/*** The current hue value 0-360* @attribute hue* @type int*/this.setAttributeConfig(this.OPT.HUE, {value: attr.hue || 0,validator: lang.isNumber});/*** The current saturation value 0-100* @attribute saturation* @type int*/this.setAttributeConfig(this.OPT.SATURATION, {value: attr.saturation || 0,validator: lang.isNumber});/*** The current value/brightness value 0-100* @attribute value* @type int*/this.setAttributeConfig(this.OPT.VALUE, {value: lang.isNumber(attr.value) ? attr.value : 100,validator: lang.isNumber});/*** The current red value 0-255* @attribute red* @type int*/this.setAttributeConfig(this.OPT.RED, {value: lang.isNumber(attr.red) ? attr.red : 255,validator: lang.isNumber});/*** The current green value 0-255* @attribute green* @type int*/this.setAttributeConfig(this.OPT.GREEN, {value: lang.isNumber(attr.green) ? attr.green : 255,validator: lang.isNumber});/*** The current blue value 0-255* @attribute blue* @type int*/this.setAttributeConfig(this.OPT.BLUE, {value: lang.isNumber(attr.blue) ? attr.blue : 255,validator: lang.isNumber});/*** The current hex value #000000-#FFFFFF, without the #* @attribute hex* @type string*/this.setAttributeConfig(this.OPT.HEX, {value: attr.hex || "FFFFFF",validator: lang.isString});/*** The current rgb value. Updates the state of all of the* other value fields. Read-only: use setValue to set the* controls rgb value.* @attribute hex* @type [int, int, int]* @readonly*/this.setAttributeConfig(this.OPT.RGB, {value: attr.rgb || [255,255,255],method: function(rgb) {this.set(this.OPT.RED, rgb[0], true);this.set(this.OPT.GREEN, rgb[1], true);this.set(this.OPT.BLUE, rgb[2], true);var websafe = Color.websafe(rgb),hex = Color.rgb2hex(rgb),hsv = Color.rgb2hsv(rgb);this.set(this.OPT.WEBSAFE, websafe, true);this.set(this.OPT.HEX, hex, true);this.logger.log(sub("RGB value set to {rgb} (hsv: {hsv})", {"hsv": hsv, "rgb": rgb}));// fix bug #1754338 - when saturation is 0, hue is// silently always set to 0, but input field not updatedif (hsv[1]) {this.set(this.OPT.HUE, hsv[0], true);}this.set(this.OPT.SATURATION, Math.round(hsv[1]*100), true);this.set(this.OPT.VALUE, Math.round(hsv[2]*100), true);},readonly: true});/*** If the color picker will live inside of a container object,* set, provide a reference to it so the control can use the* container's events.* @attribute container* @type YAHOO.widget.Panel*/this.setAttributeConfig(this.OPT.CONTAINER, {value: null,method: function(container) {if (container) {// Position can get out of sync when the// control is manipulated while display is// none. Resetting the slider constraints// when it is visible gets the state back in// order.container.showEvent.subscribe(function() {// this.pickerSlider.thumb.resetConstraints();// this.hueSlider.thumb.resetConstraints();this.pickerSlider.focus();}, this, true);}}});/*** The closest current websafe value* @attribute websafe* @type int*/this.setAttributeConfig(this.OPT.WEBSAFE, {value: attr.websafe || [255,255,255]});var ids = attr.ids || lang.merge({}, this.ID), i;if (!attr.ids && _pickercount > 1) {for (i in ids) {if (lang.hasOwnProperty(ids, i)) {ids[i] = ids[i] + _pickercount;}}}/*** A list of element ids and/or element references used by the* control. The default is the this.ID list, and can be customized* by passing a list in the contructor* @attribute ids* @type {referenceid: realid}* @writeonce*/this.setAttributeConfig(this.OPT.IDS, {value: ids,writeonce: true});/*** A list of txt strings for internationalization. Default* is this.TXT* @attribute txt* @type {key: txt}* @writeonce*/this.setAttributeConfig(this.OPT.TXT, {value: attr.txt || this.TXT,writeonce: true});/*** The img src default list* is this.IMAGES* @attribute images* @type {key: image}* @writeonce*/this.setAttributeConfig(this.OPT.IMAGES, {value: attr.images || this.IMAGE,writeonce: true});/*** The element refs used by this control. Set at initialization* @attribute elements* @type {id: HTMLElement}* @readonly*/this.setAttributeConfig(this.OPT.ELEMENTS, {value: {},readonly: true});/*** Hide/show the entire set of controls* @attribute showcontrols* @type boolean* @default true*/this.setAttributeConfig(this.OPT.SHOW_CONTROLS, {value: lang.isBoolean(attr.showcontrols) ? attr.showcontrols : true,method: function(on) {var el = Dom.getElementsByClassName("bd", "div",this.getElement(this.ID.CONTROLS))[0];this._hideShowEl(el, on);this.getElement(this.ID.CONTROLS_LABEL).innerHTML =(on) ? this.get(this.OPT.TXT).HIDE_CONTROLS :this.get(this.OPT.TXT).SHOW_CONTROLS;}});/*** Hide/show the rgb controls* @attribute showrgbcontrols* @type boolean* @default true*/this.setAttributeConfig(this.OPT.SHOW_RGB_CONTROLS, {value: lang.isBoolean(attr.showrgbcontrols) ? attr.showrgbcontrols : true,method: function(on) {this._hideShowEl(this.ID.RGB_CONTROLS, on);}});/*** Hide/show the hsv controls* @attribute showhsvcontrols* @type boolean* @default false*/this.setAttributeConfig(this.OPT.SHOW_HSV_CONTROLS, {value: lang.isBoolean(attr.showhsvcontrols) ?attr.showhsvcontrols : false,method: function(on) {//Dom.setStyle(this.getElement(this.ID.HSV_CONTROLS), "visibility", (on) ? "" : "hidden");this._hideShowEl(this.ID.HSV_CONTROLS, on);// can't show both the hsv controls and the rbg hex summaryif (on && this.get(this.OPT.SHOW_HEX_SUMMARY)) {this.set(this.OPT.SHOW_HEX_SUMMARY, false);}}});/*** Hide/show the hex controls* @attribute showhexcontrols* @type boolean* @default true*/this.setAttributeConfig(this.OPT.SHOW_HEX_CONTROLS, {value: lang.isBoolean(attr.showhexcontrols) ?attr.showhexcontrols : false,method: function(on) {this._hideShowEl(this.ID.HEX_CONTROLS, on);}});/*** Hide/show the websafe swatch* @attribute showwebsafe* @type boolean* @default true*/this.setAttributeConfig(this.OPT.SHOW_WEBSAFE, {value: lang.isBoolean(attr.showwebsafe) ? attr.showwebsafe : true,method: function(on) {this._hideShowEl(this.ID.WEBSAFE_SWATCH, on);}});/*** Hide/show the hex summary* @attribute showhexsummary* @type boolean* @default true*/this.setAttributeConfig(this.OPT.SHOW_HEX_SUMMARY, {value: lang.isBoolean(attr.showhexsummary) ? attr.showhexsummary : true,method: function(on) {this._hideShowEl(this.ID.HEX_SUMMARY, on);// can't show both the hsv controls and the rbg hex summaryif (on && this.get(this.OPT.SHOW_HSV_CONTROLS)) {this.set(this.OPT.SHOW_HSV_CONTROLS, false);}}});this.setAttributeConfig(this.OPT.ANIMATE, {value: lang.isBoolean(attr.animate) ? attr.animate : true,method: function(on) {if (this.pickerSlider) {this.pickerSlider.animate = on;this.hueSlider.animate = on;}}});this.on(this.OPT.HUE + "Change", this._updateRGBFromHSV, this, true);this.on(this.OPT.SATURATION + "Change", this._updateRGBFromHSV, this, true);this.on(this.OPT.VALUE + "Change", this._updateRGBFromHSV, this, true);this.on(this.OPT.RED + "Change", this._updateRGB, this, true);this.on(this.OPT.GREEN + "Change", this._updateRGB, this, true);this.on(this.OPT.BLUE + "Change", this._updateRGB, this, true);this.on(this.OPT.HEX + "Change", this._updateHex, this, true);this._initElements();}});YAHOO.widget.ColorPicker = ColorPicker;})();YAHOO.register("colorpicker", YAHOO.widget.ColorPicker, {version: "2.9.0", build: "2800"});}, '2.9.0' ,{"requires": ["yui2-yahoo", "yui2-dom", "yui2-skin-sam-slider", "yui2-event", "yui2-dragdrop", "yui2-slider", "yui2-element", "yui2-skin-sam-colorpicker"], "optional": ["yui2-animation"]});