spectrum-rails 1.2.0 → 1.8.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e0056a77b0e6e14c395beae83632e947cdba7740889850cf387b0760fd0780ec
4
+ data.tar.gz: 95a6f7caa9446684f05cb7fae3d69e07f2b05c19e838ae3cb3ee89d78e13f85d
5
+ SHA512:
6
+ metadata.gz: 343a9444e178da55a8a91f8a949f7b6877b27d9d011c6d3f015edce7689069ea78df903ac1245a02e82c64dafc22a74a2900facb8a657bd4f40cc574118e2786
7
+ data.tar.gz: 974f376b3d4e7e9603f1a1124b88450d84e9490e75c46b790acbc9e9e3451bfe96d765c122db485b19f4a0968a3fa27fd9a6c2f52ebd6bfcedc5fe0fa0f4da15
@@ -1,5 +1,5 @@
1
1
  module Spectrum
2
2
  module Rails
3
- VERSION = "1.2.0"
3
+ VERSION = "1.8.1"
4
4
  end
5
5
  end
@@ -0,0 +1 @@
1
+ !function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof exports&&"object"==typeof module?module.exports=t(require("jquery")):t(jQuery)}(function(jt,Et){"use strict";var t,Dt={beforeShow:r,move:r,change:r,show:r,hide:r,color:!1,flat:!1,showInput:!1,allowEmpty:!1,showButtons:!0,clickoutFiresChange:!0,showInitial:!1,showPalette:!1,showPaletteOnly:!1,hideAfterPaletteSelect:!1,togglePaletteOnly:!1,showSelectionPalette:!0,localStorageKey:!1,appendTo:"body",maxSelectionSize:7,cancelText:"cancel",chooseText:"choose",togglePaletteMoreText:"more",togglePaletteLessText:"less",clearText:"Clear Color Selection",noColorSelectedText:"No Color Selected",preferredFormat:!1,className:"",containerClassName:"",replacerClassName:"",showAlpha:!1,theme:"sp-light",palette:[["#ffffff","#000000","#ff0000","#ff8000","#ffff00","#008000","#0000ff","#4b0082","#9400d3"]],selectionPalette:[],disabled:!1,offset:null},It=[],zt=!!/msie/i.exec(window.navigator.userAgent),Bt=((t=document.createElement("div").style).cssText="background-color:rgba(0,0,0,.5)",e(t.backgroundColor,"rgba")||e(t.backgroundColor,"hsla")),Lt=["<div class='sp-replacer'>","<div class='sp-preview'><div class='sp-preview-inner'></div></div>","<div class='sp-dd'>&#9660;</div>","</div>"].join(""),Kt=function(){var t="";if(zt)for(var e=1;e<=6;e++)t+="<div class='sp-"+e+"'></div>";return["<div class='sp-container sp-hidden'>","<div class='sp-palette-container'>","<div class='sp-palette sp-thumb sp-cf'></div>","<div class='sp-palette-button-container sp-cf'>","<button type='button' class='sp-palette-toggle'></button>","</div>","</div>","<div class='sp-picker-container'>","<div class='sp-top sp-cf'>","<div class='sp-fill'></div>","<div class='sp-top-inner'>","<div class='sp-color'>","<div class='sp-sat'>","<div class='sp-val'>","<div class='sp-dragger'></div>","</div>","</div>","</div>","<div class='sp-clear sp-clear-display'>","</div>","<div class='sp-hue'>","<div class='sp-slider'></div>",t,"</div>","</div>","<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>","</div>","<div class='sp-input-container sp-cf'>","<input class='sp-input' type='text' spellcheck='false' />","</div>","<div class='sp-initial sp-thumb sp-cf'></div>","<div class='sp-button-container sp-cf'>","<a class='sp-cancel' href='#'></a>","<button type='button' class='sp-choose'></button>","</div>","</div>","</div>"].join("")}();function e(t,e){return!!~(""+t).indexOf(e)}function Vt(t,e,r,a){for(var n=[],o=0;o<t.length;o++){var i,s,l,c,f=t[o];f?(s=(i=tinycolor(f)).toHsl().l<.5?"sp-thumb-el sp-thumb-dark":"sp-thumb-el sp-thumb-light",s+=tinycolor.equals(e,f)?" sp-thumb-active":"",l=i.toString(a.preferredFormat||"rgb"),c=Bt?"background-color:"+i.toRgbString():"filter:"+i.toFilter(),n.push('<span title="'+l+'" data-color="'+i.toRgbString()+'" class="'+s+'"><span class="sp-thumb-inner" style="'+c+';"></span></span>')):n.push(jt("<div />").append(jt('<span data-color="" style="background-color:transparent;" class="sp-clear-display"></span>').attr("title",a.noColorSelectedText)).html())}return"<div class='sp-cf "+r+"'>"+n.join("")+"</div>"}function o(t,e){var r,a,n,o,i,s,l,u=(i=e,s=t,(l=jt.extend({},Dt,i)).callbacks={move:Wt(l.move,s),change:Wt(l.change,s),show:Wt(l.show,s),hide:Wt(l.hide,s),beforeShow:Wt(l.beforeShow,s)},l),d=u.flat,c=u.showSelectionPalette,f=u.localStorageKey,h=u.theme,p=u.callbacks,g=(r=Ot,function(){var t=this,e=arguments;n&&clearTimeout(o),!n&&o||(o=setTimeout(function(){o=null,r.apply(t,e)},a))}),b=!(a=10),v=!1,m=0,y=0,w=0,_=0,x=0,k=0,S=0,C=0,P=0,A=0,M=1,R=[],H=[],F={},T=u.selectionPalette.slice(0),O=u.maxSelectionSize,q="sp-dragging",N=null,j=t.ownerDocument,E=(j.body,jt(t)),D=!1,I=jt(Kt,j).addClass(h),z=I.find(".sp-picker-container"),B=I.find(".sp-color"),L=I.find(".sp-dragger"),K=I.find(".sp-hue"),V=I.find(".sp-slider"),$=I.find(".sp-alpha-inner"),W=I.find(".sp-alpha"),X=I.find(".sp-alpha-handle"),Y=I.find(".sp-input"),G=I.find(".sp-palette"),Q=I.find(".sp-initial"),J=I.find(".sp-cancel"),U=I.find(".sp-clear"),Z=I.find(".sp-choose"),tt=I.find(".sp-palette-toggle"),et=E.is("input"),rt=et&&"color"===E.attr("type")&&Yt(),at=et&&!d,nt=at?jt(Lt).addClass(h).addClass(u.className).addClass(u.replacerClassName):jt([]),ot=at?nt:E,it=nt.find(".sp-preview-inner"),st=u.color||et&&E.val(),lt=!1,ct=u.preferredFormat,ft=!u.showButtons||u.clickoutFiresChange,ht=!st,ut=u.allowEmpty&&!rt;function dt(){if(u.showPaletteOnly&&(u.showPalette=!0),tt.text(u.showPaletteOnly?u.togglePaletteMoreText:u.togglePaletteLessText),u.palette){R=u.palette.slice(0),H=jt.isArray(R[0])?R:[R],F={};for(var t=0;t<H.length;t++)for(var e=0;e<H[t].length;e++){var r=tinycolor(H[t][e]).toRgbString();F[r]=!0}}I.toggleClass("sp-flat",d),I.toggleClass("sp-input-disabled",!u.showInput),I.toggleClass("sp-alpha-enabled",u.showAlpha),I.toggleClass("sp-clear-enabled",ut),I.toggleClass("sp-buttons-disabled",!u.showButtons),I.toggleClass("sp-palette-buttons-disabled",!u.togglePaletteOnly),I.toggleClass("sp-palette-disabled",!u.showPalette),I.toggleClass("sp-palette-only",u.showPaletteOnly),I.toggleClass("sp-initial-disabled",!u.showInitial),I.addClass(u.className).addClass(u.containerClassName),Ot()}function pt(){if(f&&window.localStorage){try{var t=window.localStorage[f].split(",#");1<t.length&&(delete window.localStorage[f],jt.each(t,function(t,e){gt(e)}))}catch(t){}try{T=window.localStorage[f].split(";")}catch(t){}}}function gt(t){if(c){var e=tinycolor(t).toRgbString();if(!F[e]&&-1===jt.inArray(e,T))for(T.push(e);T.length>O;)T.shift();if(f&&window.localStorage)try{window.localStorage[f]=T.join(";")}catch(t){}}}function bt(){var r=Mt(),t=jt.map(H,function(t,e){return Vt(t,r,"sp-palette-row sp-palette-row-"+e,u)});pt(),T&&t.push(Vt(function(){var t=[];if(u.showPalette)for(var e=0;e<T.length;e++){var r=tinycolor(T[e]).toRgbString();F[r]||t.push(T[e])}return t.reverse().slice(0,u.maxSelectionSize)}(),r,"sp-palette-row sp-palette-row-selection",u)),G.html(t.join(""))}function vt(){var t,e;u.showInitial&&(t=lt,e=Mt(),Q.html(Vt([t,e],e,"sp-palette-row-initial",u)))}function mt(){(y<=0||m<=0||_<=0)&&Ot(),v=!0,I.addClass(q),N=null,E.trigger("dragstart.spectrum",[Mt()])}function yt(){v=!1,I.removeClass(q),E.trigger("dragstop.spectrum",[Mt()])}function wt(){var t,e=Y.val();null!==e&&""!==e||!ut?(t=tinycolor(e)).isValid()?(At(t),Rt(),Tt()):Y.addClass("sp-validation-error"):(At(null),Rt(),Tt())}function _t(){(b?Ct:xt)()}function xt(){var t=jt.Event("beforeShow.spectrum");b?Ot():(E.trigger(t,[Mt()]),!1===p.beforeShow(Mt())||t.isDefaultPrevented()||(function(){for(var t=0;t<It.length;t++)It[t]&&It[t].hide()}(),b=!0,jt(j).on("keydown.spectrum",kt),jt(j).on("click.spectrum",St),jt(window).on("resize.spectrum",g),nt.addClass("sp-active"),I.removeClass("sp-hidden"),Ot(),Ht(),lt=Mt(),vt(),p.show(lt),E.trigger("show.spectrum",[lt])))}function kt(t){27===t.keyCode&&Ct()}function St(t){2!=t.button&&(v||(ft?Tt(!0):Pt(),Ct()))}function Ct(){b&&!d&&(b=!1,jt(j).off("keydown.spectrum",kt),jt(j).off("click.spectrum",St),jt(window).off("resize.spectrum",g),nt.removeClass("sp-active"),I.addClass("sp-hidden"),p.hide(Mt()),E.trigger("hide.spectrum",[Mt()]))}function Pt(){At(lt,!0),Tt(!0)}function At(t,e){var r,a;tinycolor.equals(t,Mt())?Ht():(!t&&ut?ht=!0:(ht=!1,a=(r=tinycolor(t)).toHsv(),C=a.h%360/360,P=a.s,A=a.v,M=a.a),Ht(),r&&r.isValid()&&!e&&(ct=u.preferredFormat||r.getFormat()))}function Mt(t){return t=t||{},ut&&ht?null:tinycolor.fromRatio({h:C,s:P,v:A,a:Math.round(1e3*M)/1e3},{format:t.format||ct})}function Rt(){Ht(),p.move(Mt()),E.trigger("move.spectrum",[Mt()])}function Ht(){Y.removeClass("sp-validation-error"),Ft();var t=tinycolor.fromRatio({h:C,s:1,v:1});B.css("background-color",t.toHexString());var e=ct;M<1&&(0!==M||"name"!==e)&&("hex"!==e&&"hex3"!==e&&"hex6"!==e&&"name"!==e||(e="rgb"));var r,a,n,o,i,s=Mt({format:e}),l="";it.removeClass("sp-clear-display"),it.css("background-color","transparent"),!s&&ut?it.addClass("sp-clear-display"):(r=s.toHexString(),a=s.toRgbString(),Bt||1===s.alpha?it.css("background-color",a):(it.css("background-color","transparent"),it.css("filter",s.toFilter())),u.showAlpha&&((n=s.toRgb()).a=0,i="linear-gradient(left, "+(o=tinycolor(n).toRgbString())+", "+r+")",zt?$.css("filter",tinycolor(o).toFilter({gradientType:1},r)):($.css("background","-webkit-"+i),$.css("background","-moz-"+i),$.css("background","-ms-"+i),$.css("background","linear-gradient(to right, "+o+", "+r+")"))),l=s.toString(e)),u.showInput&&Y.val(l),u.showPalette&&bt(),vt()}function Ft(){var t,e,r,a,n=P,o=A;ut&&ht?(X.hide(),V.hide(),L.hide()):(X.show(),V.show(),L.show(),t=n*m,e=y-o*y,t=Math.max(-w,Math.min(m-w,t-w)),e=Math.max(-w,Math.min(y-w,e-w)),L.css({top:e+"px",left:t+"px"}),r=M*x,X.css({left:r-k/2+"px"}),a=C*_,V.css({top:a-S+"px"}))}function Tt(t){var e=Mt(),r="",a=!tinycolor.equals(e,lt);e&&(r=e.toString(ct),gt(e)),et&&E.val(r),t&&a&&(p.change(e),E.trigger("change",[e]))}function Ot(){var t,e,r,a,n,o,i,s,l,c,f,h;b&&(m=B.width(),y=B.height(),w=L.height(),K.width(),_=K.height(),S=V.height(),x=W.width(),k=X.width(),d||(I.css("position","absolute"),u.offset?I.offset(u.offset):I.offset((e=ot,r=(t=I).outerWidth(),a=t.outerHeight(),n=e.outerHeight(),o=t[0].ownerDocument,i=o.documentElement,s=i.clientWidth+jt(o).scrollLeft(),l=i.clientHeight+jt(o).scrollTop(),c=e.offset(),f=c.left,h=c.top,h+=n,f-=Math.min(f,s<f+r&&r<s?Math.abs(f+r-s):0),{top:h-=Math.min(h,l<h+a&&a<l?Math.abs(+(a+n)):0),bottom:c.bottom,left:f,right:c.right,width:c.width,height:c.height}))),Ft(),u.showPalette&&bt(),E.trigger("reflow.spectrum"))}function qt(){Ct(),D=!0,E.attr("disabled",!0),ot.addClass("sp-disabled")}!function(){var t;function e(t){return t.data&&t.data.ignore?(At(jt(t.target).closest(".sp-thumb-el").data("color")),Rt()):(At(jt(t.target).closest(".sp-thumb-el").data("color")),Rt(),u.hideAfterPaletteSelect?(Tt(!0),Ct()):Tt()),!1}zt&&I.find("*:not(input)").attr("unselectable","on"),dt(),at&&E.after(nt).hide(),ut||U.hide(),d?E.after(I).hide():(1!==(t="parent"===u.appendTo?E.parent():jt(u.appendTo)).length&&(t=jt("body")),t.append(I)),pt(),ot.on("click.spectrum touchstart.spectrum",function(t){D||_t(),t.stopPropagation(),jt(t.target).is("input")||t.preventDefault()}),!E.is(":disabled")&&!0!==u.disabled||qt(),I.click($t),Y.change(wt),Y.on("paste",function(){setTimeout(wt,1)}),Y.keydown(function(t){13==t.keyCode&&wt()}),J.text(u.cancelText),J.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),Pt(),Ct()}),U.attr("title",u.clearText),U.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),ht=!0,Rt(),d&&Tt(!0)}),Z.text(u.chooseText),Z.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),zt&&Y.is(":focus")&&Y.trigger("change"),Y.hasClass("sp-validation-error")||(Tt(!0),Ct())}),tt.text(u.showPaletteOnly?u.togglePaletteMoreText:u.togglePaletteLessText),tt.on("click.spectrum",function(t){t.stopPropagation(),t.preventDefault(),u.showPaletteOnly=!u.showPaletteOnly,u.showPaletteOnly||d||I.css("left","-="+(z.outerWidth(!0)+5)),dt()}),Xt(W,function(t,e,r){M=t/x,ht=!1,r.shiftKey&&(M=Math.round(10*M)/10),Rt()},mt,yt),Xt(K,function(t,e){C=parseFloat(e/_),ht=!1,u.showAlpha||(M=1),Rt()},mt,yt),Xt(B,function(t,e,r){var a,n,o;r.shiftKey?N||(a=P*m,n=y-A*y,o=Math.abs(t-a)>Math.abs(e-n),N=o?"x":"y"):N=null;var i=!N||"y"===N;N&&"x"!==N||(P=parseFloat(t/m)),i&&(A=parseFloat((y-e)/y)),ht=!1,u.showAlpha||(M=1),Rt()},mt,yt),st?(At(st),Ht(),ct=u.preferredFormat||tinycolor(st).format,gt(st)):Ht(),d&&xt();var r=zt?"mousedown.spectrum":"click.spectrum touchstart.spectrum";G.on(r,".sp-thumb-el",e),Q.on(r,".sp-thumb-el:nth-child(1)",{ignore:!0},e)}();var Nt={show:xt,hide:Ct,toggle:_t,reflow:Ot,option:function(t,e){return t===Et?jt.extend({},u):e===Et?u[t]:(u[t]=e,"preferredFormat"===t&&(ct=u.preferredFormat),void dt())},enable:function(){D=!1,E.attr("disabled",!1),ot.removeClass("sp-disabled")},disable:qt,offset:function(t){u.offset=t,Ot()},set:function(t){At(t),Tt()},get:Mt,destroy:function(){E.show(),ot.off("click.spectrum touchstart.spectrum"),I.remove(),nt.remove(),It[Nt.id]=null},container:I};return Nt.id=It.push(Nt)-1,Nt}function r(){}function $t(t){t.stopPropagation()}function Wt(t,e){var r=Array.prototype.slice,a=r.call(arguments,2);return function(){return t.apply(e,a.concat(r.call(arguments)))}}function Xt(i,s,e,t){s=s||function(){},e=e||function(){},t=t||function(){};var l=document,c=!1,f={},h=0,u=0,d="ontouchstart"in window,r={};function p(t){t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.returnValue=!1}function a(t){if(c){if(zt&&l.documentMode<9&&!t.button)return g();var e=t.originalEvent&&t.originalEvent.touches&&t.originalEvent.touches[0],r=e&&e.pageX||t.pageX,a=e&&e.pageY||t.pageY,n=Math.max(0,Math.min(r-f.left,u)),o=Math.max(0,Math.min(a-f.top,h));d&&p(t),s.apply(i,[n,o,t])}}function g(){c&&(jt(l).off(r),jt(l.body).removeClass("sp-dragging"),setTimeout(function(){t.apply(i,arguments)},0)),c=!1}r.selectstart=p,r.dragstart=p,r["touchmove mousemove"]=a,r["touchend mouseup"]=g,jt(i).on("touchstart mousedown",function(t){(t.which?3==t.which:2==t.button)||c||!1!==e.apply(i,arguments)&&(c=!0,h=jt(i).height(),u=jt(i).width(),f=jt(i).offset(),jt(l).on(r),jt(l.body).addClass("sp-dragging"),a(t),p(t))})}function Yt(){return jt.fn.spectrum.inputTypeColorSupport()}var i="spectrum.id";jt.fn.spectrum=function(r,t){if("string"!=typeof r)return this.spectrum("destroy").each(function(){var t=o(this,jt.extend({},jt(this).data(),r));jt(this).data(i,t.id)});var a=this,n=Array.prototype.slice.call(arguments,1);return this.each(function(){var t=It[jt(this).data(i)];if(t){var e=t[r];if(!e)throw new Error("Spectrum: no such method: '"+r+"'");"get"==r?a=t.get():"container"==r?a=t.container:"option"==r?a=t.option.apply(t,n):"destroy"==r?(t.destroy(),jt(this).removeData(i)):e.apply(t,n)}}),a},jt.fn.spectrum.load=!0,jt.fn.spectrum.loadOpts={},jt.fn.spectrum.draggable=Xt,jt.fn.spectrum.defaults=Dt,jt.fn.spectrum.inputTypeColorSupport=function t(){var e;return void 0===t._cachedResult&&(e=jt("<input type='color'/>")[0],t._cachedResult="color"===e.type&&""!==e.value),t._cachedResult},jt.spectrum={},jt.spectrum.localization={},jt.spectrum.palettes={},jt.fn.spectrum.processNativeColorInputs=function(){var t=jt("input[type=color]");t.length&&!Yt()&&t.spectrum({preferredFormat:"hex6"})},function(){var o=/^[\s,#]+/,i=/\s+$/,a=0,c=Math,s=c.round,f=c.min,h=c.max,t=c.random,u=function(t,e){if(e=e||{},(t=t||"")instanceof u)return t;if(!(this instanceof u))return new u(t,e);var r=function(t){var e={r:0,g:0,b:0},r=1,a=!1,n=!1;"string"==typeof t&&(t=function(t){t=t.replace(o,"").replace(i,"").toLowerCase();var e,r=!1;if(P[t])t=P[t],r=!0;else if("transparent"==t)return{r:0,g:0,b:0,a:0,format:"name"};if(e=E.rgb.exec(t))return{r:e[1],g:e[2],b:e[3]};if(e=E.rgba.exec(t))return{r:e[1],g:e[2],b:e[3],a:e[4]};if(e=E.hsl.exec(t))return{h:e[1],s:e[2],l:e[3]};if(e=E.hsla.exec(t))return{h:e[1],s:e[2],l:e[3],a:e[4]};if(e=E.hsv.exec(t))return{h:e[1],s:e[2],v:e[3]};if(e=E.hsva.exec(t))return{h:e[1],s:e[2],v:e[3],a:e[4]};if(e=E.hex8.exec(t))return{a:function(t){return F(t)/255}(e[1]),r:F(e[2]),g:F(e[3]),b:F(e[4]),format:r?"name":"hex8"};if(e=E.hex6.exec(t))return{r:F(e[1]),g:F(e[2]),b:F(e[3]),format:r?"name":"hex"};if(e=E.hex3.exec(t))return{r:F(e[1]+""+e[1]),g:F(e[2]+""+e[2]),b:F(e[3]+""+e[3]),format:r?"name":"hex"};return!1}(t));"object"==typeof t&&(t.hasOwnProperty("r")&&t.hasOwnProperty("g")&&t.hasOwnProperty("b")?(e=function(t,e,r){return{r:255*R(t,255),g:255*R(e,255),b:255*R(r,255)}}(t.r,t.g,t.b),a=!0,n="%"===String(t.r).substr(-1)?"prgb":"rgb"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("v")?(t.s=O(t.s),t.v=O(t.v),e=function(t,e,r){t=6*R(t,360),e=R(e,100),r=R(r,100);var a=c.floor(t),n=t-a,o=r*(1-e),i=r*(1-n*e),s=r*(1-(1-n)*e),l=a%6;return{r:255*[r,i,o,o,s,r][l],g:255*[s,r,r,i,o,o][l],b:255*[o,o,s,r,r,i][l]}}(t.h,t.s,t.v),a=!0,n="hsv"):t.hasOwnProperty("h")&&t.hasOwnProperty("s")&&t.hasOwnProperty("l")&&(t.s=O(t.s),t.l=O(t.l),e=function(t,e,r){var a,n,o;function i(t,e,r){return r<0&&(r+=1),1<r&&--r,r<1/6?t+6*(e-t)*r:r<.5?e:r<2/3?t+(e-t)*(2/3-r)*6:t}{var s,l;t=R(t,360),e=R(e,100),r=R(r,100),0===e?a=n=o=r:(a=i(l=2*r-(s=r<.5?r*(1+e):r+e-r*e),s,t+1/3),n=i(l,s,t),o=i(l,s,t-1/3))}return{r:255*a,g:255*n,b:255*o}}(t.h,t.s,t.l),a=!0,n="hsl"),t.hasOwnProperty("a")&&(r=t.a));return r=M(r),{ok:a,format:t.format||n,r:f(255,h(e.r,0)),g:f(255,h(e.g,0)),b:f(255,h(e.b,0)),a:r}}(t);this._originalInput=t,this._r=r.r,this._g=r.g,this._b=r.b,this._a=r.a,this._roundA=s(1e3*this._a)/1e3,this._format=e.format||r.format,this._gradientType=e.gradientType,this._r<1&&(this._r=s(this._r)),this._g<1&&(this._g=s(this._g)),this._b<1&&(this._b=s(this._b)),this._ok=r.ok,this._tc_id=a++};function n(t,e,r){t=R(t,255),e=R(e,255),r=R(r,255);var a,n=h(t,e,r),o=f(t,e,r),i=(n+o)/2;if(n==o)a=l=0;else{var s=n-o,l=.5<i?s/(2-n-o):s/(n+o);switch(n){case t:a=(e-r)/s+(e<r?6:0);break;case e:a=(r-t)/s+2;break;case r:a=(t-e)/s+4}a/=6}return{h:a,s:l,l:i}}function l(t,e,r){t=R(t,255),e=R(e,255),r=R(r,255);var a,n=h(t,e,r),o=f(t,e,r),i=n,s=n-o,l=0===n?0:s/n;if(n==o)a=0;else{switch(n){case t:a=(e-r)/s+(e<r?6:0);break;case e:a=(r-t)/s+2;break;case r:a=(t-e)/s+4}a/=6}return{h:a,s:l,v:i}}function e(t,e,r,a){var n=[T(s(t).toString(16)),T(s(e).toString(16)),T(s(r).toString(16))];return a&&n[0].charAt(0)==n[0].charAt(1)&&n[1].charAt(0)==n[1].charAt(1)&&n[2].charAt(0)==n[2].charAt(1)?n[0].charAt(0)+n[1].charAt(0)+n[2].charAt(0):n.join("")}function d(t,e,r,a){var n;return[T((n=a,Math.round(255*parseFloat(n)).toString(16))),T(s(t).toString(16)),T(s(e).toString(16)),T(s(r).toString(16))].join("")}function r(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.s-=e/100,r.s=H(r.s),u(r)}function p(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.s+=e/100,r.s=H(r.s),u(r)}function g(t){return u(t).desaturate(100)}function b(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.l+=e/100,r.l=H(r.l),u(r)}function v(t,e){e=0===e?0:e||10;var r=u(t).toRgb();return r.r=h(0,f(255,r.r-s(-e/100*255))),r.g=h(0,f(255,r.g-s(-e/100*255))),r.b=h(0,f(255,r.b-s(-e/100*255))),u(r)}function m(t,e){e=0===e?0:e||10;var r=u(t).toHsl();return r.l-=e/100,r.l=H(r.l),u(r)}function y(t,e){var r=u(t).toHsl(),a=(s(r.h)+e)%360;return r.h=a<0?360+a:a,u(r)}function w(t){var e=u(t).toHsl();return e.h=(e.h+180)%360,u(e)}function _(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+120)%360,s:e.s,l:e.l}),u({h:(r+240)%360,s:e.s,l:e.l})]}function x(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+90)%360,s:e.s,l:e.l}),u({h:(r+180)%360,s:e.s,l:e.l}),u({h:(r+270)%360,s:e.s,l:e.l})]}function k(t){var e=u(t).toHsl(),r=e.h;return[u(t),u({h:(r+72)%360,s:e.s,l:e.l}),u({h:(r+216)%360,s:e.s,l:e.l})]}function S(t,e,r){e=e||6,r=r||30;var a=u(t).toHsl(),n=360/r,o=[u(t)];for(a.h=(a.h-(n*e>>1)+720)%360;--e;)a.h=(a.h+n)%360,o.push(u(a));return o}function C(t,e){e=e||6;for(var r=u(t).toHsv(),a=r.h,n=r.s,o=r.v,i=[],s=1/e;e--;)i.push(u({h:a,s:n,v:o})),o=(o+s)%1;return i}u.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var t=this.toRgb();return(299*t.r+587*t.g+114*t.b)/1e3},setAlpha:function(t){return this._a=M(t),this._roundA=s(1e3*this._a)/1e3,this},toHsv:function(){var t=l(this._r,this._g,this._b);return{h:360*t.h,s:t.s,v:t.v,a:this._a}},toHsvString:function(){var t=l(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.v);return 1==this._a?"hsv("+e+", "+r+"%, "+a+"%)":"hsva("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHsl:function(){var t=n(this._r,this._g,this._b);return{h:360*t.h,s:t.s,l:t.l,a:this._a}},toHslString:function(){var t=n(this._r,this._g,this._b),e=s(360*t.h),r=s(100*t.s),a=s(100*t.l);return 1==this._a?"hsl("+e+", "+r+"%, "+a+"%)":"hsla("+e+", "+r+"%, "+a+"%, "+this._roundA+")"},toHex:function(t){return e(this._r,this._g,this._b,t)},toHexString:function(t){return"#"+this.toHex(t)},toHex8:function(){return d(this._r,this._g,this._b,this._a)},toHex8String:function(){return"#"+this.toHex8()},toRgb:function(){return{r:s(this._r),g:s(this._g),b:s(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+s(this._r)+", "+s(this._g)+", "+s(this._b)+")":"rgba("+s(this._r)+", "+s(this._g)+", "+s(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:s(100*R(this._r,255))+"%",g:s(100*R(this._g,255))+"%",b:s(100*R(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%)":"rgba("+s(100*R(this._r,255))+"%, "+s(100*R(this._g,255))+"%, "+s(100*R(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&A[e(this._r,this._g,this._b,!0)]||!1},toFilter:function(t){var e="#"+d(this._r,this._g,this._b,this._a),r=e,a=this._gradientType?"GradientType = 1, ":"";return t&&(r=u(t).toHex8String()),"progid:DXImageTransform.Microsoft.gradient("+a+"startColorstr="+e+",endColorstr="+r+")"},toString:function(t){var e=!!t;t=t||this._format;var r=!1,a=this._a<1&&0<=this._a;return e||!a||"hex"!==t&&"hex6"!==t&&"hex3"!==t&&"name"!==t?("rgb"===t&&(r=this.toRgbString()),"prgb"===t&&(r=this.toPercentageRgbString()),"hex"!==t&&"hex6"!==t||(r=this.toHexString()),"hex3"===t&&(r=this.toHexString(!0)),"hex8"===t&&(r=this.toHex8String()),"name"===t&&(r=this.toName()),"hsl"===t&&(r=this.toHslString()),"hsv"===t&&(r=this.toHsvString()),r||this.toHexString()):"name"===t&&0===this._a?this.toName():this.toRgbString()},_applyModification:function(t,e){var r=t.apply(null,[this].concat([].slice.call(e)));return this._r=r._r,this._g=r._g,this._b=r._b,this.setAlpha(r._a),this},lighten:function(){return this._applyModification(b,arguments)},brighten:function(){return this._applyModification(v,arguments)},darken:function(){return this._applyModification(m,arguments)},desaturate:function(){return this._applyModification(r,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(g,arguments)},spin:function(){return this._applyModification(y,arguments)},_applyCombination:function(t,e){return t.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(S,arguments)},complement:function(){return this._applyCombination(w,arguments)},monochromatic:function(){return this._applyCombination(C,arguments)},splitcomplement:function(){return this._applyCombination(k,arguments)},triad:function(){return this._applyCombination(_,arguments)},tetrad:function(){return this._applyCombination(x,arguments)}},u.fromRatio=function(t,e){if("object"==typeof t){var r={};for(var a in t)t.hasOwnProperty(a)&&(r[a]="a"===a?t[a]:O(t[a]));t=r}return u(t,e)},u.equals=function(t,e){return!(!t||!e)&&u(t).toRgbString()==u(e).toRgbString()},u.random=function(){return u.fromRatio({r:t(),g:t(),b:t()})},u.mix=function(t,e,r){r=0===r?0:r||50;var a=u(t).toRgb(),n=u(e).toRgb(),o=r/100,i=2*o-1,s=n.a-a.a,l=i*s==-1?i:(i+s)/(1+i*s),c=1-(l=(l+1)/2),f={r:n.r*l+a.r*c,g:n.g*l+a.g*c,b:n.b*l+a.b*c,a:n.a*o+a.a*(1-o)};return u(f)},u.readability=function(t,e){var r=u(t),a=u(e),n=r.toRgb(),o=a.toRgb(),i=r.getBrightness(),s=a.getBrightness(),l=Math.max(n.r,o.r)-Math.min(n.r,o.r)+Math.max(n.g,o.g)-Math.min(n.g,o.g)+Math.max(n.b,o.b)-Math.min(n.b,o.b);return{brightness:Math.abs(i-s),color:l}},u.isReadable=function(t,e){var r=u.readability(t,e);return 125<r.brightness&&500<r.color},u.mostReadable=function(t,e){for(var r=null,a=0,n=!1,o=0;o<e.length;o++){var i=u.readability(t,e[o]),s=125<i.brightness&&500<i.color,l=i.brightness/125*3+i.color/500;(s&&!n||s&&n&&a<l||!s&&!n&&a<l)&&(n=s,a=l,r=u(e[o]))}return r};var P=u.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},A=u.hexNames=function(t){var e={};for(var r in t)t.hasOwnProperty(r)&&(e[t[r]]=r);return e}(P);function M(t){return t=parseFloat(t),(isNaN(t)||t<0||1<t)&&(t=1),t}function R(t,e){var r;"string"==typeof(r=t)&&-1!=r.indexOf(".")&&1===parseFloat(r)&&(t="100%");var a,n="string"==typeof(a=t)&&-1!=a.indexOf("%");return t=f(e,h(0,parseFloat(t))),n&&(t=parseInt(t*e,10)/100),c.abs(t-e)<1e-6?1:t%e/parseFloat(e)}function H(t){return f(1,h(0,t))}function F(t){return parseInt(t,16)}function T(t){return 1==t.length?"0"+t:""+t}function O(t){return t<=1&&(t=100*t+"%"),t}var q,N,j,E=(N="[\\s|\\(]+("+(q="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",j="[\\s|\\(]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")[,|\\s]+("+q+")\\s*\\)?",{rgb:new RegExp("rgb"+N),rgba:new RegExp("rgba"+j),hsl:new RegExp("hsl"+N),hsla:new RegExp("hsla"+j),hsv:new RegExp("hsv"+N),hsva:new RegExp("hsva"+j),hex3:/^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex8:/^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});window.tinycolor=u}(),jt(function(){jt.fn.spectrum.load&&jt.fn.spectrum.processNativeColorInputs()})});
@@ -1,114 +1,136 @@
1
- // Spectrum Colorpicker v1.2.0
1
+ // Spectrum Colorpicker v1.8.1
2
2
  // https://github.com/bgrins/spectrum
3
3
  // Author: Brian Grinstead
4
4
  // License: MIT
5
5
 
6
- (function (window, $, undefined) {
6
+ (function (factory) {
7
+ "use strict";
8
+
9
+ if (typeof define === 'function' && define.amd) { // AMD
10
+ define(['jquery'], factory);
11
+ }
12
+ else if (typeof exports == "object" && typeof module == "object") { // CommonJS
13
+ module.exports = factory(require('jquery'));
14
+ }
15
+ else { // Browser
16
+ factory(jQuery);
17
+ }
18
+ })(function($, undefined) {
19
+ "use strict";
20
+
7
21
  var defaultOpts = {
8
22
 
9
- // Callbacks
10
- beforeShow: noop,
11
- move: noop,
12
- change: noop,
13
- show: noop,
14
- hide: noop,
15
-
16
- // Options
17
- color: false,
18
- flat: false,
19
- showInput: false,
20
- allowEmpty: false,
21
- showButtons: true,
22
- clickoutFiresChange: false,
23
- showInitial: false,
24
- showPalette: false,
25
- showPaletteOnly: false,
26
- showSelectionPalette: true,
27
- localStorageKey: false,
28
- appendTo: "body",
29
- maxSelectionSize: 7,
30
- cancelText: "cancel",
31
- chooseText: "choose",
32
- preferredFormat: false,
33
- className: "",
34
- showAlpha: false,
35
- theme: "sp-light",
36
- palette: ['fff', '000'],
37
- selectionPalette: [],
38
- disabled: false
39
- },
40
- spectrums = [],
41
- IE = !!/msie/i.exec( window.navigator.userAgent ),
42
- rgbaSupport = (function() {
43
- function contains( str, substr ) {
44
- return !!~('' + str).indexOf(substr);
45
- }
46
-
47
- var elem = document.createElement('div');
48
- var style = elem.style;
49
- style.cssText = 'background-color:rgba(0,0,0,.5)';
50
- return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
51
- })(),
52
- inputTypeColorSupport = (function() {
53
- var colorInput = $("<input type='color' value='!' />")[0];
54
- return colorInput.type === "color" && colorInput.value !== "!";
55
- })(),
56
- replaceInput = [
57
- "<div class='sp-replacer'>",
23
+ // Callbacks
24
+ beforeShow: noop,
25
+ move: noop,
26
+ change: noop,
27
+ show: noop,
28
+ hide: noop,
29
+
30
+ // Options
31
+ color: false,
32
+ flat: false,
33
+ showInput: false,
34
+ allowEmpty: false,
35
+ showButtons: true,
36
+ clickoutFiresChange: true,
37
+ showInitial: false,
38
+ showPalette: false,
39
+ showPaletteOnly: false,
40
+ hideAfterPaletteSelect: false,
41
+ togglePaletteOnly: false,
42
+ showSelectionPalette: true,
43
+ localStorageKey: false,
44
+ appendTo: "body",
45
+ maxSelectionSize: 7,
46
+ cancelText: "cancel",
47
+ chooseText: "choose",
48
+ togglePaletteMoreText: "more",
49
+ togglePaletteLessText: "less",
50
+ clearText: "Clear Color Selection",
51
+ noColorSelectedText: "No Color Selected",
52
+ preferredFormat: false,
53
+ className: "", // Deprecated - use containerClassName and replacerClassName instead.
54
+ containerClassName: "",
55
+ replacerClassName: "",
56
+ showAlpha: false,
57
+ theme: "sp-light",
58
+ palette: [["#ffffff", "#000000", "#ff0000", "#ff8000", "#ffff00", "#008000", "#0000ff", "#4b0082", "#9400d3"]],
59
+ selectionPalette: [],
60
+ disabled: false,
61
+ offset: null
62
+ },
63
+ spectrums = [],
64
+ IE = !!/msie/i.exec( window.navigator.userAgent ),
65
+ rgbaSupport = (function() {
66
+ function contains( str, substr ) {
67
+ return !!~('' + str).indexOf(substr);
68
+ }
69
+
70
+ var elem = document.createElement('div');
71
+ var style = elem.style;
72
+ style.cssText = 'background-color:rgba(0,0,0,.5)';
73
+ return contains(style.backgroundColor, 'rgba') || contains(style.backgroundColor, 'hsla');
74
+ })(),
75
+ replaceInput = [
76
+ "<div class='sp-replacer'>",
58
77
  "<div class='sp-preview'><div class='sp-preview-inner'></div></div>",
59
78
  "<div class='sp-dd'>&#9660;</div>",
60
- "</div>"
61
- ].join(''),
62
- markup = (function () {
79
+ "</div>"
80
+ ].join(''),
81
+ markup = (function () {
63
82
 
64
- // IE does not support gradients with multiple stops, so we need to simulate
65
- // that for the rainbow slider with 8 divs that each have a single gradient
66
- var gradientFix = "";
67
- if (IE) {
68
- for (var i = 1; i <= 6; i++) {
69
- gradientFix += "<div class='sp-" + i + "'></div>";
70
- }
83
+ // IE does not support gradients with multiple stops, so we need to simulate
84
+ // that for the rainbow slider with 8 divs that each have a single gradient
85
+ var gradientFix = "";
86
+ if (IE) {
87
+ for (var i = 1; i <= 6; i++) {
88
+ gradientFix += "<div class='sp-" + i + "'></div>";
71
89
  }
90
+ }
72
91
 
73
- return [
74
- "<div class='sp-container sp-hidden'>",
92
+ return [
93
+ "<div class='sp-container sp-hidden'>",
75
94
  "<div class='sp-palette-container'>",
76
- "<div class='sp-palette sp-thumb sp-cf'></div>",
95
+ "<div class='sp-palette sp-thumb sp-cf'></div>",
96
+ "<div class='sp-palette-button-container sp-cf'>",
97
+ "<button type='button' class='sp-palette-toggle'></button>",
98
+ "</div>",
77
99
  "</div>",
78
100
  "<div class='sp-picker-container'>",
79
- "<div class='sp-top sp-cf'>",
80
- "<div class='sp-fill'></div>",
81
- "<div class='sp-top-inner'>",
82
- "<div class='sp-color'>",
83
- "<div class='sp-sat'>",
84
- "<div class='sp-val'>",
85
- "<div class='sp-dragger'></div>",
86
- "</div>",
101
+ "<div class='sp-top sp-cf'>",
102
+ "<div class='sp-fill'></div>",
103
+ "<div class='sp-top-inner'>",
104
+ "<div class='sp-color'>",
105
+ "<div class='sp-sat'>",
106
+ "<div class='sp-val'>",
107
+ "<div class='sp-dragger'></div>",
108
+ "</div>",
109
+ "</div>",
110
+ "</div>",
111
+ "<div class='sp-clear sp-clear-display'>",
112
+ "</div>",
113
+ "<div class='sp-hue'>",
114
+ "<div class='sp-slider'></div>",
115
+ gradientFix,
116
+ "</div>",
117
+ "</div>",
118
+ "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
119
+ "</div>",
120
+ "<div class='sp-input-container sp-cf'>",
121
+ "<input class='sp-input' type='text' spellcheck='false' />",
122
+ "</div>",
123
+ "<div class='sp-initial sp-thumb sp-cf'></div>",
124
+ "<div class='sp-button-container sp-cf'>",
125
+ "<a class='sp-cancel' href='#'></a>",
126
+ "<button type='button' class='sp-choose'></button>",
127
+ "</div>",
87
128
  "</div>",
88
- "</div>",
89
- "<div class='sp-clear sp-clear-display' title='Clear Color Selection'>",
90
- "</div>",
91
- "<div class='sp-hue'>",
92
- "<div class='sp-slider'></div>",
93
- gradientFix,
94
- "</div>",
95
- "</div>",
96
- "<div class='sp-alpha'><div class='sp-alpha-inner'><div class='sp-alpha-handle'></div></div></div>",
97
- "</div>",
98
- "<div class='sp-input-container sp-cf'>",
99
- "<input class='sp-input' type='text' spellcheck='false' />",
100
- "</div>",
101
- "<div class='sp-initial sp-thumb sp-cf'></div>",
102
- "<div class='sp-button-container sp-cf'>",
103
- "<a class='sp-cancel' href='#'></a>",
104
- "<button class='sp-choose'></button>",
105
- "</div>",
106
- "</div>",
107
- "</div>"
108
- ].join("");
109
- })();
129
+ "</div>"
130
+ ].join("");
131
+ })();
110
132
 
111
- function paletteTemplate (p, color, className) {
133
+ function paletteTemplate (p, color, className, opts) {
112
134
  var html = [];
113
135
  for (var i = 0; i < p.length; i++) {
114
136
  var current = p[i];
@@ -116,12 +138,17 @@
116
138
  var tiny = tinycolor(current);
117
139
  var c = tiny.toHsl().l < 0.5 ? "sp-thumb-el sp-thumb-dark" : "sp-thumb-el sp-thumb-light";
118
140
  c += (tinycolor.equals(color, current)) ? " sp-thumb-active" : "";
119
-
141
+ var formattedString = tiny.toString(opts.preferredFormat || "rgb");
120
142
  var swatchStyle = rgbaSupport ? ("background-color:" + tiny.toRgbString()) : "filter:" + tiny.toFilter();
121
- html.push('<span title="' + tiny.toRgbString() + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';" /></span>');
143
+ html.push('<span title="' + formattedString + '" data-color="' + tiny.toRgbString() + '" class="' + c + '"><span class="sp-thumb-inner" style="' + swatchStyle + ';"></span></span>');
122
144
  } else {
123
145
  var cls = 'sp-clear-display';
124
- html.push('<span title="No Color Selected" data-color="" style="background-color:transparent;" class="' + cls + '"></span>');
146
+ html.push($('<div />')
147
+ .append($('<span data-color="" style="background-color:transparent;" class="' + cls + '"></span>')
148
+ .attr('title', opts.noColorSelectedText)
149
+ )
150
+ .html()
151
+ );
125
152
  }
126
153
  }
127
154
  return "<div class='sp-cf " + className + "'>" + html.join('') + "</div>";
@@ -158,6 +185,7 @@
158
185
  callbacks = opts.callbacks,
159
186
  resize = throttle(reflow, 10),
160
187
  visible = false,
188
+ isDragging = false,
161
189
  dragWidth = 0,
162
190
  dragHeight = 0,
163
191
  dragHelperHeight = 0,
@@ -170,8 +198,9 @@
170
198
  currentSaturation = 0,
171
199
  currentValue = 0,
172
200
  currentAlpha = 1,
173
- palette = opts.palette.slice(0),
174
- paletteArray = $.isArray(palette[0]) ? palette : [palette],
201
+ palette = [],
202
+ paletteArray = [],
203
+ paletteLookup = {},
175
204
  selectionPalette = opts.selectionPalette.slice(0),
176
205
  maxSelectionSize = opts.maxSelectionSize,
177
206
  draggingClass = "sp-dragging",
@@ -182,6 +211,7 @@
182
211
  boundElement = $(element),
183
212
  disabled = false,
184
213
  container = $(markup, doc).addClass(theme),
214
+ pickerContainer = container.find(".sp-picker-container"),
185
215
  dragger = container.find(".sp-color"),
186
216
  dragHelper = container.find(".sp-dragger"),
187
217
  slider = container.find(".sp-hue"),
@@ -195,16 +225,16 @@
195
225
  cancelButton = container.find(".sp-cancel"),
196
226
  clearButton = container.find(".sp-clear"),
197
227
  chooseButton = container.find(".sp-choose"),
228
+ toggleButton = container.find(".sp-palette-toggle"),
198
229
  isInput = boundElement.is("input"),
199
- isInputTypeColor = isInput && inputTypeColorSupport && boundElement.attr("type") === "color",
230
+ isInputTypeColor = isInput && boundElement.attr("type") === "color" && inputTypeColorSupport(),
200
231
  shouldReplace = isInput && !flat,
201
- replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className) : $([]),
232
+ replacer = (shouldReplace) ? $(replaceInput).addClass(theme).addClass(opts.className).addClass(opts.replacerClassName) : $([]),
202
233
  offsetElement = (shouldReplace) ? replacer : boundElement,
203
234
  previewElement = replacer.find(".sp-preview-inner"),
204
235
  initialColor = opts.color || (isInput && boundElement.val()),
205
236
  colorOnShow = false,
206
- preferredFormat = opts.preferredFormat,
207
- currentPreferredFormat = preferredFormat,
237
+ currentPreferredFormat = opts.preferredFormat,
208
238
  clickoutFiresChange = !opts.showButtons || opts.clickoutFiresChange,
209
239
  isEmpty = !initialColor,
210
240
  allowEmpty = opts.allowEmpty && !isInputTypeColor;
@@ -215,15 +245,30 @@
215
245
  opts.showPalette = true;
216
246
  }
217
247
 
248
+ toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
249
+
250
+ if (opts.palette) {
251
+ palette = opts.palette.slice(0);
252
+ paletteArray = $.isArray(palette[0]) ? palette : [palette];
253
+ paletteLookup = {};
254
+ for (var i = 0; i < paletteArray.length; i++) {
255
+ for (var j = 0; j < paletteArray[i].length; j++) {
256
+ var rgb = tinycolor(paletteArray[i][j]).toRgbString();
257
+ paletteLookup[rgb] = true;
258
+ }
259
+ }
260
+ }
261
+
218
262
  container.toggleClass("sp-flat", flat);
219
263
  container.toggleClass("sp-input-disabled", !opts.showInput);
220
264
  container.toggleClass("sp-alpha-enabled", opts.showAlpha);
221
265
  container.toggleClass("sp-clear-enabled", allowEmpty);
222
266
  container.toggleClass("sp-buttons-disabled", !opts.showButtons);
267
+ container.toggleClass("sp-palette-buttons-disabled", !opts.togglePaletteOnly);
223
268
  container.toggleClass("sp-palette-disabled", !opts.showPalette);
224
269
  container.toggleClass("sp-palette-only", opts.showPaletteOnly);
225
270
  container.toggleClass("sp-initial-disabled", !opts.showInitial);
226
- container.addClass(opts.className);
271
+ container.addClass(opts.className).addClass(opts.containerClassName);
227
272
 
228
273
  reflow();
229
274
  }
@@ -257,27 +302,9 @@
257
302
  appendTo.append(container);
258
303
  }
259
304
 
260
- if (localStorageKey && window.localStorage) {
261
-
262
- // Migrate old palettes over to new format. May want to remove this eventually.
263
- try {
264
- var oldPalette = window.localStorage[localStorageKey].split(",#");
265
- if (oldPalette.length > 1) {
266
- delete window.localStorage[localStorageKey];
267
- $.each(oldPalette, function(i, c) {
268
- addColorToSelectionPalette(c);
269
- });
270
- }
271
- }
272
- catch(e) { }
273
-
274
- try {
275
- selectionPalette = window.localStorage[localStorageKey].split(";");
276
- }
277
- catch (e) { }
278
- }
305
+ updateSelectionPaletteFromStorage();
279
306
 
280
- offsetElement.bind("click.spectrum touchstart.spectrum", function (e) {
307
+ offsetElement.on("click.spectrum touchstart.spectrum", function (e) {
281
308
  if (!disabled) {
282
309
  toggle();
283
310
  }
@@ -298,44 +325,65 @@
298
325
 
299
326
  // Handle user typed input
300
327
  textInput.change(setFromTextInput);
301
- textInput.bind("paste", function () {
328
+ textInput.on("paste", function () {
302
329
  setTimeout(setFromTextInput, 1);
303
330
  });
304
331
  textInput.keydown(function (e) { if (e.keyCode == 13) { setFromTextInput(); } });
305
332
 
306
333
  cancelButton.text(opts.cancelText);
307
- cancelButton.bind("click.spectrum", function (e) {
334
+ cancelButton.on("click.spectrum", function (e) {
308
335
  e.stopPropagation();
309
336
  e.preventDefault();
310
- hide("cancel");
337
+ revert();
338
+ hide();
311
339
  });
312
340
 
313
-
314
- clearButton.bind("click.spectrum", function (e) {
341
+ clearButton.attr("title", opts.clearText);
342
+ clearButton.on("click.spectrum", function (e) {
315
343
  e.stopPropagation();
316
344
  e.preventDefault();
317
-
318
345
  isEmpty = true;
319
-
320
346
  move();
347
+
321
348
  if(flat) {
322
349
  //for the flat style, this is a change event
323
350
  updateOriginalInput(true);
324
351
  }
325
352
  });
326
353
 
327
-
328
354
  chooseButton.text(opts.chooseText);
329
- chooseButton.bind("click.spectrum", function (e) {
355
+ chooseButton.on("click.spectrum", function (e) {
330
356
  e.stopPropagation();
331
357
  e.preventDefault();
332
358
 
359
+ if (IE && textInput.is(":focus")) {
360
+ textInput.trigger('change');
361
+ }
362
+
333
363
  if (isValid()) {
334
364
  updateOriginalInput(true);
335
365
  hide();
336
366
  }
337
367
  });
338
368
 
369
+ toggleButton.text(opts.showPaletteOnly ? opts.togglePaletteMoreText : opts.togglePaletteLessText);
370
+ toggleButton.on("click.spectrum", function (e) {
371
+ e.stopPropagation();
372
+ e.preventDefault();
373
+
374
+ opts.showPaletteOnly = !opts.showPaletteOnly;
375
+
376
+ // To make sure the Picker area is drawn on the right, next to the
377
+ // Palette area (and not below the palette), first move the Palette
378
+ // to the left to make space for the picker, plus 5px extra.
379
+ // The 'applyOptions' function puts the whole container back into place
380
+ // and takes care of the button-text and the sp-palette-only CSS class.
381
+ if (!opts.showPaletteOnly && !flat) {
382
+ container.css('left', '-=' + (pickerContainer.outerWidth(true) + 5));
383
+ }
384
+ applyOptions();
385
+ });
386
+
339
387
  draggable(alphaSlider, function (dragX, dragY, e) {
340
388
  currentAlpha = (dragX / alphaWidth);
341
389
  isEmpty = false;
@@ -344,11 +392,14 @@
344
392
  }
345
393
 
346
394
  move();
347
- });
395
+ }, dragStart, dragStop);
348
396
 
349
397
  draggable(slider, function (dragX, dragY) {
350
398
  currentHue = parseFloat(dragY / slideHeight);
351
399
  isEmpty = false;
400
+ if (!opts.showAlpha) {
401
+ currentAlpha = 1;
402
+ }
352
403
  move();
353
404
  }, dragStart, dragStop);
354
405
 
@@ -377,6 +428,9 @@
377
428
  }
378
429
 
379
430
  isEmpty = false;
431
+ if (!opts.showAlpha) {
432
+ currentAlpha = 1;
433
+ }
380
434
 
381
435
  move();
382
436
 
@@ -388,7 +442,7 @@
388
442
  // In case color was black - update the preview UI and set the format
389
443
  // since the set function will not run (default color is black).
390
444
  updateUI();
391
- currentPreferredFormat = preferredFormat || tinycolor(initialColor).format;
445
+ currentPreferredFormat = opts.preferredFormat || tinycolor(initialColor).format;
392
446
 
393
447
  addColorToSelectionPalette(initialColor);
394
448
  }
@@ -400,31 +454,61 @@
400
454
  show();
401
455
  }
402
456
 
403
- function palletElementClick(e) {
457
+ function paletteElementClick(e) {
404
458
  if (e.data && e.data.ignore) {
405
- set($(this).data("color"));
459
+ set($(e.target).closest(".sp-thumb-el").data("color"));
406
460
  move();
407
461
  }
408
462
  else {
409
- set($(this).data("color"));
410
- updateOriginalInput(true);
463
+ set($(e.target).closest(".sp-thumb-el").data("color"));
411
464
  move();
412
- hide();
465
+
466
+ // If the picker is going to close immediately, a palette selection
467
+ // is a change. Otherwise, it's a move only.
468
+ if (opts.hideAfterPaletteSelect) {
469
+ updateOriginalInput(true);
470
+ hide();
471
+ } else {
472
+ updateOriginalInput();
473
+ }
413
474
  }
414
475
 
415
476
  return false;
416
477
  }
417
478
 
418
479
  var paletteEvent = IE ? "mousedown.spectrum" : "click.spectrum touchstart.spectrum";
419
- paletteContainer.delegate(".sp-thumb-el", paletteEvent, palletElementClick);
420
- initialColorContainer.delegate(".sp-thumb-el:nth-child(1)", paletteEvent, { ignore: true }, palletElementClick);
480
+ paletteContainer.on(paletteEvent, ".sp-thumb-el", paletteElementClick);
481
+ initialColorContainer.on(paletteEvent, ".sp-thumb-el:nth-child(1)", { ignore: true }, paletteElementClick);
482
+ }
483
+
484
+ function updateSelectionPaletteFromStorage() {
485
+
486
+ if (localStorageKey && window.localStorage) {
487
+
488
+ // Migrate old palettes over to new format. May want to remove this eventually.
489
+ try {
490
+ var oldPalette = window.localStorage[localStorageKey].split(",#");
491
+ if (oldPalette.length > 1) {
492
+ delete window.localStorage[localStorageKey];
493
+ $.each(oldPalette, function(i, c) {
494
+ addColorToSelectionPalette(c);
495
+ });
496
+ }
497
+ }
498
+ catch(e) { }
499
+
500
+ try {
501
+ selectionPalette = window.localStorage[localStorageKey].split(";");
502
+ }
503
+ catch (e) { }
504
+ }
421
505
  }
422
506
 
423
507
  function addColorToSelectionPalette(color) {
424
508
  if (showSelectionPalette) {
425
- var colorRgb = tinycolor(color).toRgbString();
426
- if ($.inArray(colorRgb, selectionPalette) === -1) {
427
- selectionPalette.push(colorRgb);
509
+ var rgb = tinycolor(color).toRgbString();
510
+ if (!paletteLookup[rgb] && $.inArray(rgb, selectionPalette) === -1) {
511
+ selectionPalette.push(rgb);
428
512
  while(selectionPalette.length > maxSelectionSize) {
429
513
  selectionPalette.shift();
430
514
  }
@@ -441,25 +525,12 @@
441
525
 
442
526
  function getUniqueSelectionPalette() {
443
527
  var unique = [];
444
- var p = selectionPalette;
445
- var paletteLookup = {};
446
- var rgb;
447
-
448
528
  if (opts.showPalette) {
529
+ for (var i = 0; i < selectionPalette.length; i++) {
530
+ var rgb = tinycolor(selectionPalette[i]).toRgbString();
449
531
 
450
- for (var i = 0; i < paletteArray.length; i++) {
451
- for (var j = 0; j < paletteArray[i].length; j++) {
452
- rgb = tinycolor(paletteArray[i][j]).toRgbString();
453
- paletteLookup[rgb] = true;
454
- }
455
- }
456
-
457
- for (i = 0; i < p.length; i++) {
458
- rgb = tinycolor(p[i]).toRgbString();
459
-
460
- if (!paletteLookup.hasOwnProperty(rgb)) {
461
- unique.push(p[i]);
462
- paletteLookup[rgb] = true;
532
+ if (!paletteLookup[rgb]) {
533
+ unique.push(selectionPalette[i]);
463
534
  }
464
535
  }
465
536
  }
@@ -472,11 +543,13 @@
472
543
  var currentColor = get();
473
544
 
474
545
  var html = $.map(paletteArray, function (palette, i) {
475
- return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i);
546
+ return paletteTemplate(palette, currentColor, "sp-palette-row sp-palette-row-" + i, opts);
476
547
  });
477
548
 
549
+ updateSelectionPaletteFromStorage();
550
+
478
551
  if (selectionPalette) {
479
- html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection"));
552
+ html.push(paletteTemplate(getUniqueSelectionPalette(), currentColor, "sp-palette-row sp-palette-row-selection", opts));
480
553
  }
481
554
 
482
555
  paletteContainer.html(html.join(""));
@@ -486,7 +559,7 @@
486
559
  if (opts.showInitial) {
487
560
  var initial = colorOnShow;
488
561
  var current = get();
489
- initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial"));
562
+ initialColorContainer.html(paletteTemplate([initial, current], current, "sp-palette-row-initial", opts));
490
563
  }
491
564
  }
492
565
 
@@ -494,12 +567,16 @@
494
567
  if (dragHeight <= 0 || dragWidth <= 0 || slideHeight <= 0) {
495
568
  reflow();
496
569
  }
570
+ isDragging = true;
497
571
  container.addClass(draggingClass);
498
572
  shiftMovementDirection = null;
573
+ boundElement.trigger('dragstart.spectrum', [ get() ]);
499
574
  }
500
575
 
501
576
  function dragStop() {
577
+ isDragging = false;
502
578
  container.removeClass(draggingClass);
579
+ boundElement.trigger('dragstop.spectrum', [ get() ]);
503
580
  }
504
581
 
505
582
  function setFromTextInput() {
@@ -508,11 +585,15 @@
508
585
 
509
586
  if ((value === null || value === "") && allowEmpty) {
510
587
  set(null);
588
+ move();
589
+ updateOriginalInput();
511
590
  }
512
591
  else {
513
592
  var tiny = tinycolor(value);
514
- if (tiny.ok) {
593
+ if (tiny.isValid()) {
515
594
  set(tiny);
595
+ move();
596
+ updateOriginalInput();
516
597
  }
517
598
  else {
518
599
  textInput.addClass("sp-validation-error");
@@ -546,14 +627,12 @@
546
627
  hideAll();
547
628
  visible = true;
548
629
 
549
- $(doc).bind("click.spectrum", hide);
550
- $(window).bind("resize.spectrum", resize);
630
+ $(doc).on("keydown.spectrum", onkeydown);
631
+ $(doc).on("click.spectrum", clickout);
632
+ $(window).on("resize.spectrum", resize);
551
633
  replacer.addClass("sp-active");
552
634
  container.removeClass("sp-hidden");
553
635
 
554
- if (opts.showPalette) {
555
- drawPalette();
556
- }
557
636
  reflow();
558
637
  updateUI();
559
638
 
@@ -564,52 +643,66 @@
564
643
  boundElement.trigger('show.spectrum', [ colorOnShow ]);
565
644
  }
566
645
 
567
- function hide(e) {
646
+ function onkeydown(e) {
647
+ // Close on ESC
648
+ if (e.keyCode === 27) {
649
+ hide();
650
+ }
651
+ }
652
+
653
+ function clickout(e) {
654
+ // Return on right click.
655
+ if (e.button == 2) { return; }
656
+
657
+ // If a drag event was happening during the mouseup, don't hide
658
+ // on click.
659
+ if (isDragging) { return; }
568
660
 
569
- // Return on right click
570
- if (e && e.type == "click" && e.button == 2) { return; }
661
+ if (clickoutFiresChange) {
662
+ updateOriginalInput(true);
663
+ }
664
+ else {
665
+ revert();
666
+ }
667
+ hide();
668
+ }
571
669
 
670
+ function hide() {
572
671
  // Return if hiding is unnecessary
573
672
  if (!visible || flat) { return; }
574
673
  visible = false;
575
674
 
576
- $(doc).unbind("click.spectrum", hide);
577
- $(window).unbind("resize.spectrum", resize);
675
+ $(doc).off("keydown.spectrum", onkeydown);
676
+ $(doc).off("click.spectrum", clickout);
677
+ $(window).off("resize.spectrum", resize);
578
678
 
579
679
  replacer.removeClass("sp-active");
580
680
  container.addClass("sp-hidden");
581
681
 
582
- var colorHasChanged = !tinycolor.equals(get(), colorOnShow);
583
-
584
- if (colorHasChanged) {
585
- if (clickoutFiresChange && e !== "cancel") {
586
- updateOriginalInput(true);
587
- }
588
- else {
589
- revert();
590
- }
591
- }
592
-
593
682
  callbacks.hide(get());
594
683
  boundElement.trigger('hide.spectrum', [ get() ]);
595
684
  }
596
685
 
597
686
  function revert() {
598
687
  set(colorOnShow, true);
688
+ updateOriginalInput(true);
599
689
  }
600
690
 
601
691
  function set(color, ignoreFormatChange) {
602
692
  if (tinycolor.equals(color, get())) {
693
+ // Update UI just in case a validation error needs
694
+ // to be cleared.
695
+ updateUI();
603
696
  return;
604
697
  }
605
698
 
606
- var newColor;
699
+ var newColor, newHsv;
607
700
  if (!color && allowEmpty) {
608
701
  isEmpty = true;
609
702
  } else {
610
703
  isEmpty = false;
611
704
  newColor = tinycolor(color);
612
- var newHsv = newColor.toHsv();
705
+ newHsv = newColor.toHsv();
613
706
 
614
707
  currentHue = (newHsv.h % 360) / 360;
615
708
  currentSaturation = newHsv.s;
@@ -618,8 +711,8 @@
618
711
  }
619
712
  updateUI();
620
713
 
621
- if (newColor && newColor.ok && !ignoreFormatChange) {
622
- currentPreferredFormat = preferredFormat || newColor.format;
714
+ if (newColor && newColor.isValid() && !ignoreFormatChange) {
715
+ currentPreferredFormat = opts.preferredFormat || newColor.getFormat();
623
716
  }
624
717
  }
625
718
 
@@ -634,7 +727,7 @@
634
727
  h: currentHue,
635
728
  s: currentSaturation,
636
729
  v: currentValue,
637
- a: Math.round(currentAlpha * 100) / 100
730
+ a: Math.round(currentAlpha * 1000) / 1000
638
731
  }, { format: opts.format || currentPreferredFormat });
639
732
  }
640
733
 
@@ -661,7 +754,7 @@
661
754
 
662
755
  // Get a format that alpha will be included in (hex and names ignore alpha)
663
756
  var format = currentPreferredFormat;
664
- if (currentAlpha < 1) {
757
+ if (currentAlpha < 1 && !(currentAlpha === 0 && format === "name")) {
665
758
  if (format === "hex" || format === "hex3" || format === "hex6" || format === "name") {
666
759
  format = "rgb";
667
760
  }
@@ -670,7 +763,7 @@
670
763
  var realColor = get({ format: format }),
671
764
  displayColor = '';
672
765
 
673
- //reset background info for preview element
766
+ //reset background info for preview element
674
767
  previewElement.removeClass("sp-clear-display");
675
768
  previewElement.css('background-color', 'transparent');
676
769
 
@@ -704,12 +797,15 @@
704
797
  alphaSliderInner.css("background", "-webkit-" + gradient);
705
798
  alphaSliderInner.css("background", "-moz-" + gradient);
706
799
  alphaSliderInner.css("background", "-ms-" + gradient);
707
- alphaSliderInner.css("background", gradient);
800
+ // Use current syntax gradient on unprefixed property.
801
+ alphaSliderInner.css("background",
802
+ "linear-gradient(to right, " + realAlpha + ", " + realHex + ")");
708
803
  }
709
804
  }
710
805
 
711
806
  displayColor = realColor.toString(format);
712
807
  }
808
+
713
809
  // Update the text entry input as it changes happen
714
810
  if (opts.showInput) {
715
811
  textInput.val(displayColor);
@@ -750,19 +846,19 @@
750
846
  Math.min(dragHeight - dragHelperHeight, dragY - dragHelperHeight)
751
847
  );
752
848
  dragHelper.css({
753
- "top": dragY,
754
- "left": dragX
849
+ "top": dragY + "px",
850
+ "left": dragX + "px"
755
851
  });
756
852
 
757
853
  var alphaX = currentAlpha * alphaWidth;
758
854
  alphaSlideHelper.css({
759
- "left": alphaX - (alphaSlideHelperWidth / 2)
855
+ "left": (alphaX - (alphaSlideHelperWidth / 2)) + "px"
760
856
  });
761
857
 
762
858
  // Where to show the bar that displays your current selected hue
763
859
  var slideY = (currentHue) * slideHeight;
764
860
  slideHelper.css({
765
- "top": slideY - slideHelperHeight
861
+ "top": (slideY - slideHelperHeight) + "px"
766
862
  });
767
863
  }
768
864
  }
@@ -772,7 +868,7 @@
772
868
  displayColor = '',
773
869
  hasChanged = !tinycolor.equals(color, colorOnShow);
774
870
 
775
- if(color) {
871
+ if (color) {
776
872
  displayColor = color.toString(currentPreferredFormat);
777
873
  // Update the selection palette with the current color
778
874
  addColorToSelectionPalette(color);
@@ -782,8 +878,6 @@
782
878
  boundElement.val(displayColor);
783
879
  }
784
880
 
785
- colorOnShow = color;
786
-
787
881
  if (fireCallback && hasChanged) {
788
882
  callbacks.change(color);
789
883
  boundElement.trigger('change', [ color ]);
@@ -791,6 +885,9 @@
791
885
  }
792
886
 
793
887
  function reflow() {
888
+ if (!visible) {
889
+ return; // Calculations would be useless and wouldn't be reliable anyways
890
+ }
794
891
  dragWidth = dragger.width();
795
892
  dragHeight = dragger.height();
796
893
  dragHelperHeight = dragHelper.height();
@@ -802,15 +899,25 @@
802
899
 
803
900
  if (!flat) {
804
901
  container.css("position", "absolute");
805
- container.offset(getOffset(container, offsetElement));
902
+ if (opts.offset) {
903
+ container.offset(opts.offset);
904
+ } else {
905
+ container.offset(getOffset(container, offsetElement));
906
+ }
806
907
  }
807
908
 
808
909
  updateHelperLocations();
910
+
911
+ if (opts.showPalette) {
912
+ drawPalette();
913
+ }
914
+
915
+ boundElement.trigger('reflow.spectrum');
809
916
  }
810
917
 
811
918
  function destroy() {
812
919
  boundElement.show();
813
- offsetElement.unbind("click.spectrum touchstart.spectrum");
920
+ offsetElement.off("click.spectrum touchstart.spectrum");
814
921
  container.remove();
815
922
  replacer.remove();
816
923
  spectrums[spect.id] = null;
@@ -825,6 +932,10 @@
825
932
  }
826
933
 
827
934
  opts[optionName] = optionValue;
935
+
936
+ if (optionName === "preferredFormat") {
937
+ currentPreferredFormat = opts.preferredFormat;
938
+ }
828
939
  applyOptions();
829
940
  }
830
941
 
@@ -841,6 +952,11 @@
841
952
  offsetElement.addClass("sp-disabled");
842
953
  }
843
954
 
955
+ function setOffset(coord) {
956
+ opts.offset = coord;
957
+ reflow();
958
+ }
959
+
844
960
  initialize();
845
961
 
846
962
  var spect = {
@@ -851,6 +967,7 @@
851
967
  option: option,
852
968
  enable: enable,
853
969
  disable: disable,
970
+ offset: setOffset,
854
971
  set: function (c) {
855
972
  set(c);
856
973
  updateOriginalInput();
@@ -866,9 +983,9 @@
866
983
  }
867
984
 
868
985
  /**
869
- * checkOffset - get the offset below/above and left/right element depending on screen position
870
- * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
871
- */
986
+ * checkOffset - get the offset below/above and left/right element depending on screen position
987
+ * Thanks https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.datepicker.js
988
+ */
872
989
  function getOffset(picker, input) {
873
990
  var extraY = 0;
874
991
  var dpWidth = picker.outerWidth();
@@ -879,37 +996,47 @@
879
996
  var viewWidth = docElem.clientWidth + $(doc).scrollLeft();
880
997
  var viewHeight = docElem.clientHeight + $(doc).scrollTop();
881
998
  var offset = input.offset();
882
- offset.top += inputHeight;
883
-
884
- offset.left -=
885
- Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
886
- Math.abs(offset.left + dpWidth - viewWidth) : 0);
887
-
888
- offset.top -=
889
- Math.min(offset.top, ((offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
890
- Math.abs(dpHeight + inputHeight - extraY) : extraY));
891
-
892
- return offset;
999
+ var offsetLeft = offset.left;
1000
+ var offsetTop = offset.top;
1001
+
1002
+ offsetTop += inputHeight;
1003
+
1004
+ offsetLeft -=
1005
+ Math.min(offsetLeft, (offsetLeft + dpWidth > viewWidth && viewWidth > dpWidth) ?
1006
+ Math.abs(offsetLeft + dpWidth - viewWidth) : 0);
1007
+
1008
+ offsetTop -=
1009
+ Math.min(offsetTop, ((offsetTop + dpHeight > viewHeight && viewHeight > dpHeight) ?
1010
+ Math.abs(dpHeight + inputHeight - extraY) : extraY));
1011
+
1012
+ return {
1013
+ top: offsetTop,
1014
+ bottom: offset.bottom,
1015
+ left: offsetLeft,
1016
+ right: offset.right,
1017
+ width: offset.width,
1018
+ height: offset.height
1019
+ };
893
1020
  }
894
1021
 
895
1022
  /**
896
- * noop - do nothing
897
- */
1023
+ * noop - do nothing
1024
+ */
898
1025
  function noop() {
899
1026
 
900
1027
  }
901
1028
 
902
1029
  /**
903
- * stopPropagation - makes the code only doing this a little easier to read in line
904
- */
1030
+ * stopPropagation - makes the code only doing this a little easier to read in line
1031
+ */
905
1032
  function stopPropagation(e) {
906
1033
  e.stopPropagation();
907
1034
  }
908
1035
 
909
1036
  /**
910
- * Create a function bound to a given object
911
- * Thanks to underscore.js
912
- */
1037
+ * Create a function bound to a given object
1038
+ * Thanks to underscore.js
1039
+ */
913
1040
  function bind(func, obj) {
914
1041
  var slice = Array.prototype.slice;
915
1042
  var args = slice.call(arguments, 2);
@@ -919,14 +1046,14 @@
919
1046
  }
920
1047
 
921
1048
  /**
922
- * Lightweight drag helper. Handles containment within the element, so that
923
- * when dragging, the x is within [0,element.width] and y is within [0,element.height]
924
- */
1049
+ * Lightweight drag helper. Handles containment within the element, so that
1050
+ * when dragging, the x is within [0,element.width] and y is within [0,element.height]
1051
+ */
925
1052
  function draggable(element, onmove, onstart, onstop) {
926
1053
  onmove = onmove || function () { };
927
1054
  onstart = onstart || function () { };
928
1055
  onstop = onstop || function () { };
929
- var doc = element.ownerDocument || document;
1056
+ var doc = document;
930
1057
  var dragging = false;
931
1058
  var offset = {};
932
1059
  var maxHeight = 0;
@@ -952,13 +1079,13 @@
952
1079
  function move(e) {
953
1080
  if (dragging) {
954
1081
  // Mouseup happened outside of window
955
- if (IE && document.documentMode < 9 && !e.button) {
1082
+ if (IE && doc.documentMode < 9 && !e.button) {
956
1083
  return stop();
957
1084
  }
958
1085
 
959
- var touches = e.originalEvent.touches;
960
- var pageX = touches ? touches[0].pageX : e.pageX;
961
- var pageY = touches ? touches[0].pageY : e.pageY;
1086
+ var t0 = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0];
1087
+ var pageX = t0 && t0.pageX || e.pageX;
1088
+ var pageY = t0 && t0.pageY || e.pageY;
962
1089
 
963
1090
  var dragX = Math.max(0, Math.min(pageX - offset.left, maxWidth));
964
1091
  var dragY = Math.max(0, Math.min(pageY - offset.top, maxHeight));
@@ -971,9 +1098,9 @@
971
1098
  onmove.apply(element, [dragX, dragY, e]);
972
1099
  }
973
1100
  }
1101
+
974
1102
  function start(e) {
975
1103
  var rightclick = (e.which) ? (e.which == 3) : (e.button == 2);
976
- var touches = e.originalEvent.touches;
977
1104
 
978
1105
  if (!rightclick && !dragging) {
979
1106
  if (onstart.apply(element, arguments) !== false) {
@@ -982,27 +1109,31 @@
982
1109
  maxWidth = $(element).width();
983
1110
  offset = $(element).offset();
984
1111
 
985
- $(doc).bind(duringDragEvents);
1112
+ $(doc).on(duringDragEvents);
986
1113
  $(doc.body).addClass("sp-dragging");
987
1114
 
988
- if (!hasTouch) {
989
- move(e);
990
- }
1115
+ move(e);
991
1116
 
992
1117
  prevent(e);
993
1118
  }
994
1119
  }
995
1120
  }
1121
+
996
1122
  function stop() {
997
1123
  if (dragging) {
998
- $(doc).unbind(duringDragEvents);
1124
+ $(doc).off(duringDragEvents);
999
1125
  $(doc.body).removeClass("sp-dragging");
1000
- onstop.apply(element, arguments);
1126
+
1127
+ // Wait a tick before notifying observers to allow the click event
1128
+ // to fire in Chrome.
1129
+ setTimeout(function() {
1130
+ onstop.apply(element, arguments);
1131
+ }, 0);
1001
1132
  }
1002
1133
  dragging = false;
1003
1134
  }
1004
1135
 
1005
- $(element).bind("touchstart mousedown", start);
1136
+ $(element).on("touchstart mousedown", start);
1006
1137
  }
1007
1138
 
1008
1139
  function throttle(func, wait, debounce) {
@@ -1018,12 +1149,13 @@
1018
1149
  };
1019
1150
  }
1020
1151
 
1021
-
1022
- function log(){/* jshint -W021 */if(window.console){if(Function.prototype.bind)log=Function.prototype.bind.call(console.log,console);else log=function(){Function.prototype.apply.call(console.log,console,arguments);};log.apply(this,arguments);}}
1152
+ function inputTypeColorSupport() {
1153
+ return $.fn.spectrum.inputTypeColorSupport();
1154
+ }
1023
1155
 
1024
1156
  /**
1025
- * Define a jQuery plugin
1026
- */
1157
+ * Define a jQuery plugin
1158
+ */
1027
1159
  var dataID = "spectrum.id";
1028
1160
  $.fn.spectrum = function (opts, extra) {
1029
1161
 
@@ -1035,7 +1167,6 @@
1035
1167
  this.each(function () {
1036
1168
  var spect = spectrums[$(this).data(dataID)];
1037
1169
  if (spect) {
1038
-
1039
1170
  var method = spect[opts];
1040
1171
  if (!method) {
1041
1172
  throw new Error( "Spectrum: no such method: '" + opts + "'" );
@@ -1065,7 +1196,8 @@
1065
1196
 
1066
1197
  // Initializing a new instance of spectrum
1067
1198
  return this.spectrum("destroy").each(function () {
1068
- var spect = spectrum(this, opts);
1199
+ var options = $.extend({}, $(this).data(), opts);
1200
+ var spect = spectrum(this, options);
1069
1201
  $(this).data(dataID, spect.id);
1070
1202
  });
1071
1203
  };
@@ -1074,937 +1206,1136 @@
1074
1206
  $.fn.spectrum.loadOpts = {};
1075
1207
  $.fn.spectrum.draggable = draggable;
1076
1208
  $.fn.spectrum.defaults = defaultOpts;
1209
+ $.fn.spectrum.inputTypeColorSupport = function inputTypeColorSupport() {
1210
+ if (typeof inputTypeColorSupport._cachedResult === "undefined") {
1211
+ var colorInput = $("<input type='color'/>")[0]; // if color element is supported, value will default to not null
1212
+ inputTypeColorSupport._cachedResult = colorInput.type === "color" && colorInput.value !== "";
1213
+ }
1214
+ return inputTypeColorSupport._cachedResult;
1215
+ };
1077
1216
 
1078
1217
  $.spectrum = { };
1079
1218
  $.spectrum.localization = { };
1080
1219
  $.spectrum.palettes = { };
1081
1220
 
1082
1221
  $.fn.spectrum.processNativeColorInputs = function () {
1083
- if (!inputTypeColorSupport) {
1084
- $("input[type=color]").spectrum({
1222
+ var colorInputs = $("input[type=color]");
1223
+ if (colorInputs.length && !inputTypeColorSupport()) {
1224
+ colorInputs.spectrum({
1085
1225
  preferredFormat: "hex6"
1086
1226
  });
1087
1227
  }
1088
1228
  };
1089
1229
 
1090
- // TinyColor v0.9.16
1230
+ // TinyColor v1.1.2
1091
1231
  // https://github.com/bgrins/TinyColor
1092
- // 2013-08-10, Brian Grinstead, MIT License
1232
+ // Brian Grinstead, MIT License
1093
1233
 
1094
1234
  (function() {
1095
1235
 
1096
- var trimLeft = /^[\s,#]+/,
1097
- trimRight = /\s+$/,
1098
- tinyCounter = 0,
1099
- math = Math,
1100
- mathRound = math.round,
1101
- mathMin = math.min,
1102
- mathMax = math.max,
1103
- mathRandom = math.random;
1236
+ var trimLeft = /^[\s,#]+/,
1237
+ trimRight = /\s+$/,
1238
+ tinyCounter = 0,
1239
+ math = Math,
1240
+ mathRound = math.round,
1241
+ mathMin = math.min,
1242
+ mathMax = math.max,
1243
+ mathRandom = math.random;
1104
1244
 
1105
- function tinycolor (color, opts) {
1245
+ var tinycolor = function(color, opts) {
1106
1246
 
1107
- color = (color) ? color : '';
1108
- opts = opts || { };
1247
+ color = (color) ? color : '';
1248
+ opts = opts || { };
1109
1249
 
1110
- // If input is already a tinycolor, return itself
1111
- if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
1112
- return color;
1113
- }
1250
+ // If input is already a tinycolor, return itself
1251
+ if (color instanceof tinycolor) {
1252
+ return color;
1253
+ }
1254
+ // If we are called as a function, call using new instead
1255
+ if (!(this instanceof tinycolor)) {
1256
+ return new tinycolor(color, opts);
1257
+ }
1114
1258
 
1115
- var rgb = inputToRGB(color);
1116
- var r = rgb.r,
1117
- g = rgb.g,
1118
- b = rgb.b,
1119
- a = rgb.a,
1120
- roundA = mathRound(100*a) / 100,
1121
- format = opts.format || rgb.format;
1259
+ var rgb = inputToRGB(color);
1260
+ this._originalInput = color;
1261
+ this._r = rgb.r;
1262
+ this._g = rgb.g;
1263
+ this._b = rgb.b;
1264
+ this._a = rgb.a;
1265
+ this._roundA = mathRound(1000 * this._a) / 1000;
1266
+ this._format = opts.format || rgb.format;
1267
+ this._gradientType = opts.gradientType;
1268
+
1269
+ // Don't let the range of [0,255] come back in [0,1].
1270
+ // Potentially lose a little bit of precision here, but will fix issues where
1271
+ // .5 gets interpreted as half of the total, instead of half of 1
1272
+ // If it was supposed to be 128, this was already taken care of by `inputToRgb`
1273
+ if (this._r < 1) { this._r = mathRound(this._r); }
1274
+ if (this._g < 1) { this._g = mathRound(this._g); }
1275
+ if (this._b < 1) { this._b = mathRound(this._b); }
1276
+
1277
+ this._ok = rgb.ok;
1278
+ this._tc_id = tinyCounter++;
1279
+ };
1122
1280
 
1123
- // Don't let the range of [0,255] come back in [0,1].
1124
- // Potentially lose a little bit of precision here, but will fix issues where
1125
- // .5 gets interpreted as half of the total, instead of half of 1
1126
- // If it was supposed to be 128, this was already taken care of by `inputToRgb`
1127
- if (r < 1) { r = mathRound(r); }
1128
- if (g < 1) { g = mathRound(g); }
1129
- if (b < 1) { b = mathRound(b); }
1281
+ tinycolor.prototype = {
1282
+ isDark: function() {
1283
+ return this.getBrightness() < 128;
1284
+ },
1285
+ isLight: function() {
1286
+ return !this.isDark();
1287
+ },
1288
+ isValid: function() {
1289
+ return this._ok;
1290
+ },
1291
+ getOriginalInput: function() {
1292
+ return this._originalInput;
1293
+ },
1294
+ getFormat: function() {
1295
+ return this._format;
1296
+ },
1297
+ getAlpha: function() {
1298
+ return this._a;
1299
+ },
1300
+ getBrightness: function() {
1301
+ var rgb = this.toRgb();
1302
+ return (rgb.r * 299 + rgb.g * 587 + rgb.b * 114) / 1000;
1303
+ },
1304
+ setAlpha: function(value) {
1305
+ this._a = boundAlpha(value);
1306
+ this._roundA = mathRound(1000 * this._a) / 1000;
1307
+ return this;
1308
+ },
1309
+ toHsv: function() {
1310
+ var hsv = rgbToHsv(this._r, this._g, this._b);
1311
+ return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: this._a };
1312
+ },
1313
+ toHsvString: function() {
1314
+ var hsv = rgbToHsv(this._r, this._g, this._b);
1315
+ var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1316
+ return (this._a == 1) ?
1317
+ "hsv(" + h + ", " + s + "%, " + v + "%)" :
1318
+ "hsva(" + h + ", " + s + "%, " + v + "%, "+ this._roundA + ")";
1319
+ },
1320
+ toHsl: function() {
1321
+ var hsl = rgbToHsl(this._r, this._g, this._b);
1322
+ return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: this._a };
1323
+ },
1324
+ toHslString: function() {
1325
+ var hsl = rgbToHsl(this._r, this._g, this._b);
1326
+ var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1327
+ return (this._a == 1) ?
1328
+ "hsl(" + h + ", " + s + "%, " + l + "%)" :
1329
+ "hsla(" + h + ", " + s + "%, " + l + "%, "+ this._roundA + ")";
1330
+ },
1331
+ toHex: function(allow3Char) {
1332
+ return rgbToHex(this._r, this._g, this._b, allow3Char);
1333
+ },
1334
+ toHexString: function(allow3Char) {
1335
+ return '#' + this.toHex(allow3Char);
1336
+ },
1337
+ toHex8: function() {
1338
+ return rgbaToHex(this._r, this._g, this._b, this._a);
1339
+ },
1340
+ toHex8String: function() {
1341
+ return '#' + this.toHex8();
1342
+ },
1343
+ toRgb: function() {
1344
+ return { r: mathRound(this._r), g: mathRound(this._g), b: mathRound(this._b), a: this._a };
1345
+ },
1346
+ toRgbString: function() {
1347
+ return (this._a == 1) ?
1348
+ "rgb(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ")" :
1349
+ "rgba(" + mathRound(this._r) + ", " + mathRound(this._g) + ", " + mathRound(this._b) + ", " + this._roundA + ")";
1350
+ },
1351
+ toPercentageRgb: function() {
1352
+ return { r: mathRound(bound01(this._r, 255) * 100) + "%", g: mathRound(bound01(this._g, 255) * 100) + "%", b: mathRound(bound01(this._b, 255) * 100) + "%", a: this._a };
1353
+ },
1354
+ toPercentageRgbString: function() {
1355
+ return (this._a == 1) ?
1356
+ "rgb(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%)" :
1357
+ "rgba(" + mathRound(bound01(this._r, 255) * 100) + "%, " + mathRound(bound01(this._g, 255) * 100) + "%, " + mathRound(bound01(this._b, 255) * 100) + "%, " + this._roundA + ")";
1358
+ },
1359
+ toName: function() {
1360
+ if (this._a === 0) {
1361
+ return "transparent";
1362
+ }
1130
1363
 
1131
- return {
1132
- ok: rgb.ok,
1133
- format: format,
1134
- _tc_id: tinyCounter++,
1135
- alpha: a,
1136
- getAlpha: function() {
1137
- return a;
1138
- },
1139
- setAlpha: function(value) {
1140
- a = boundAlpha(value);
1141
- roundA = mathRound(100*a) / 100;
1142
- },
1143
- toHsv: function() {
1144
- var hsv = rgbToHsv(r, g, b);
1145
- return { h: hsv.h * 360, s: hsv.s, v: hsv.v, a: a };
1146
- },
1147
- toHsvString: function() {
1148
- var hsv = rgbToHsv(r, g, b);
1149
- var h = mathRound(hsv.h * 360), s = mathRound(hsv.s * 100), v = mathRound(hsv.v * 100);
1150
- return (a == 1) ?
1151
- "hsv(" + h + ", " + s + "%, " + v + "%)" :
1152
- "hsva(" + h + ", " + s + "%, " + v + "%, "+ roundA + ")";
1153
- },
1154
- toHsl: function() {
1155
- var hsl = rgbToHsl(r, g, b);
1156
- return { h: hsl.h * 360, s: hsl.s, l: hsl.l, a: a };
1157
- },
1158
- toHslString: function() {
1159
- var hsl = rgbToHsl(r, g, b);
1160
- var h = mathRound(hsl.h * 360), s = mathRound(hsl.s * 100), l = mathRound(hsl.l * 100);
1161
- return (a == 1) ?
1162
- "hsl(" + h + ", " + s + "%, " + l + "%)" :
1163
- "hsla(" + h + ", " + s + "%, " + l + "%, "+ roundA + ")";
1164
- },
1165
- toHex: function(allow3Char) {
1166
- return rgbToHex(r, g, b, allow3Char);
1167
- },
1168
- toHexString: function(allow3Char) {
1169
- return '#' + rgbToHex(r, g, b, allow3Char);
1170
- },
1171
- toRgb: function() {
1172
- return { r: mathRound(r), g: mathRound(g), b: mathRound(b), a: a };
1173
- },
1174
- toRgbString: function() {
1175
- return (a == 1) ?
1176
- "rgb(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ")" :
1177
- "rgba(" + mathRound(r) + ", " + mathRound(g) + ", " + mathRound(b) + ", " + roundA + ")";
1178
- },
1179
- toPercentageRgb: function() {
1180
- return { r: mathRound(bound01(r, 255) * 100) + "%", g: mathRound(bound01(g, 255) * 100) + "%", b: mathRound(bound01(b, 255) * 100) + "%", a: a };
1181
- },
1182
- toPercentageRgbString: function() {
1183
- return (a == 1) ?
1184
- "rgb(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%)" :
1185
- "rgba(" + mathRound(bound01(r, 255) * 100) + "%, " + mathRound(bound01(g, 255) * 100) + "%, " + mathRound(bound01(b, 255) * 100) + "%, " + roundA + ")";
1186
- },
1187
- toName: function() {
1188
- if (a === 0) {
1189
- return "transparent";
1190
- }
1364
+ if (this._a < 1) {
1365
+ return false;
1366
+ }
1191
1367
 
1192
- return hexNames[rgbToHex(r, g, b, true)] || false;
1193
- },
1194
- toFilter: function(secondColor) {
1195
- var hex = rgbToHex(r, g, b);
1196
- var secondHex = hex;
1197
- var alphaHex = Math.round(parseFloat(a) * 255).toString(16);
1198
- var secondAlphaHex = alphaHex;
1199
- var gradientType = opts && opts.gradientType ? "GradientType = 1, " : "";
1200
-
1201
- if (secondColor) {
1202
- var s = tinycolor(secondColor);
1203
- secondHex = s.toHex();
1204
- secondAlphaHex = Math.round(parseFloat(s.alpha) * 255).toString(16);
1205
- }
1368
+ return hexNames[rgbToHex(this._r, this._g, this._b, true)] || false;
1369
+ },
1370
+ toFilter: function(secondColor) {
1371
+ var hex8String = '#' + rgbaToHex(this._r, this._g, this._b, this._a);
1372
+ var secondHex8String = hex8String;
1373
+ var gradientType = this._gradientType ? "GradientType = 1, " : "";
1206
1374
 
1207
- return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr=#" + pad2(alphaHex) + hex + ",endColorstr=#" + pad2(secondAlphaHex) + secondHex + ")";
1208
- },
1209
- toString: function(format) {
1210
- var formatSet = !!format;
1211
- format = format || this.format;
1375
+ if (secondColor) {
1376
+ var s = tinycolor(secondColor);
1377
+ secondHex8String = s.toHex8String();
1378
+ }
1212
1379
 
1213
- var formattedString = false;
1214
- var hasAlphaAndFormatNotSet = !formatSet && a < 1 && a > 0;
1215
- var formatWithAlpha = hasAlphaAndFormatNotSet && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
1380
+ return "progid:DXImageTransform.Microsoft.gradient("+gradientType+"startColorstr="+hex8String+",endColorstr="+secondHex8String+")";
1381
+ },
1382
+ toString: function(format) {
1383
+ var formatSet = !!format;
1384
+ format = format || this._format;
1385
+
1386
+ var formattedString = false;
1387
+ var hasAlpha = this._a < 1 && this._a >= 0;
1388
+ var needsAlphaFormat = !formatSet && hasAlpha && (format === "hex" || format === "hex6" || format === "hex3" || format === "name");
1389
+
1390
+ if (needsAlphaFormat) {
1391
+ // Special case for "transparent", all other non-alpha formats
1392
+ // will return rgba when there is transparency.
1393
+ if (format === "name" && this._a === 0) {
1394
+ return this.toName();
1395
+ }
1396
+ return this.toRgbString();
1397
+ }
1398
+ if (format === "rgb") {
1399
+ formattedString = this.toRgbString();
1400
+ }
1401
+ if (format === "prgb") {
1402
+ formattedString = this.toPercentageRgbString();
1403
+ }
1404
+ if (format === "hex" || format === "hex6") {
1405
+ formattedString = this.toHexString();
1406
+ }
1407
+ if (format === "hex3") {
1408
+ formattedString = this.toHexString(true);
1409
+ }
1410
+ if (format === "hex8") {
1411
+ formattedString = this.toHex8String();
1412
+ }
1413
+ if (format === "name") {
1414
+ formattedString = this.toName();
1415
+ }
1416
+ if (format === "hsl") {
1417
+ formattedString = this.toHslString();
1418
+ }
1419
+ if (format === "hsv") {
1420
+ formattedString = this.toHsvString();
1421
+ }
1216
1422
 
1217
- if (format === "rgb") {
1218
- formattedString = this.toRgbString();
1219
- }
1220
- if (format === "prgb") {
1221
- formattedString = this.toPercentageRgbString();
1222
- }
1223
- if (format === "hex" || format === "hex6") {
1224
- formattedString = this.toHexString();
1225
- }
1226
- if (format === "hex3") {
1227
- formattedString = this.toHexString(true);
1228
- }
1229
- if (format === "name") {
1230
- formattedString = this.toName();
1231
- }
1232
- if (format === "hsl") {
1233
- formattedString = this.toHslString();
1234
- }
1235
- if (format === "hsv") {
1236
- formattedString = this.toHsvString();
1237
- }
1423
+ return formattedString || this.toHexString();
1424
+ },
1238
1425
 
1239
- if (formatWithAlpha) {
1240
- return this.toRgbString();
1241
- }
1426
+ _applyModification: function(fn, args) {
1427
+ var color = fn.apply(null, [this].concat([].slice.call(args)));
1428
+ this._r = color._r;
1429
+ this._g = color._g;
1430
+ this._b = color._b;
1431
+ this.setAlpha(color._a);
1432
+ return this;
1433
+ },
1434
+ lighten: function() {
1435
+ return this._applyModification(lighten, arguments);
1436
+ },
1437
+ brighten: function() {
1438
+ return this._applyModification(brighten, arguments);
1439
+ },
1440
+ darken: function() {
1441
+ return this._applyModification(darken, arguments);
1442
+ },
1443
+ desaturate: function() {
1444
+ return this._applyModification(desaturate, arguments);
1445
+ },
1446
+ saturate: function() {
1447
+ return this._applyModification(saturate, arguments);
1448
+ },
1449
+ greyscale: function() {
1450
+ return this._applyModification(greyscale, arguments);
1451
+ },
1452
+ spin: function() {
1453
+ return this._applyModification(spin, arguments);
1454
+ },
1242
1455
 
1243
- return formattedString || this.toHexString();
1244
- }
1245
- };
1456
+ _applyCombination: function(fn, args) {
1457
+ return fn.apply(null, [this].concat([].slice.call(args)));
1458
+ },
1459
+ analogous: function() {
1460
+ return this._applyCombination(analogous, arguments);
1461
+ },
1462
+ complement: function() {
1463
+ return this._applyCombination(complement, arguments);
1464
+ },
1465
+ monochromatic: function() {
1466
+ return this._applyCombination(monochromatic, arguments);
1467
+ },
1468
+ splitcomplement: function() {
1469
+ return this._applyCombination(splitcomplement, arguments);
1470
+ },
1471
+ triad: function() {
1472
+ return this._applyCombination(triad, arguments);
1473
+ },
1474
+ tetrad: function() {
1475
+ return this._applyCombination(tetrad, arguments);
1246
1476
  }
1477
+ };
1247
1478
 
1248
- // If input is an object, force 1 into "1.0" to handle ratios properly
1249
- // String input requires "1.0" as input, so 1 will be treated as 1
1250
- tinycolor.fromRatio = function(color, opts) {
1251
- if (typeof color == "object") {
1252
- var newColor = {};
1253
- for (var i in color) {
1254
- if (color.hasOwnProperty(i)) {
1255
- if (i === "a") {
1256
- newColor[i] = color[i];
1257
- }
1258
- else {
1259
- newColor[i] = convertToPercentage(color[i]);
1260
- }
1479
+ // If input is an object, force 1 into "1.0" to handle ratios properly
1480
+ // String input requires "1.0" as input, so 1 will be treated as 1
1481
+ tinycolor.fromRatio = function(color, opts) {
1482
+ if (typeof color == "object") {
1483
+ var newColor = {};
1484
+ for (var i in color) {
1485
+ if (color.hasOwnProperty(i)) {
1486
+ if (i === "a") {
1487
+ newColor[i] = color[i];
1488
+ }
1489
+ else {
1490
+ newColor[i] = convertToPercentage(color[i]);
1261
1491
  }
1262
1492
  }
1263
- color = newColor;
1264
1493
  }
1494
+ color = newColor;
1495
+ }
1265
1496
 
1266
- return tinycolor(color, opts);
1267
- };
1497
+ return tinycolor(color, opts);
1498
+ };
1268
1499
 
1269
- // Given a string or object, convert that input to RGB
1270
- // Possible string inputs:
1271
- //
1272
- // "red"
1273
- // "#f00" or "f00"
1274
- // "#ff0000" or "ff0000"
1275
- // "rgb 255 0 0" or "rgb (255, 0, 0)"
1276
- // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
1277
- // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
1278
- // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
1279
- // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
1280
- // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
1281
- // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
1282
- //
1283
- function inputToRGB(color) {
1284
-
1285
- var rgb = { r: 0, g: 0, b: 0 };
1286
- var a = 1;
1287
- var ok = false;
1288
- var format = false;
1289
-
1290
- if (typeof color == "string") {
1291
- color = stringInputToObject(color);
1292
- }
1293
-
1294
- if (typeof color == "object") {
1295
- if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
1296
- rgb = rgbToRgb(color.r, color.g, color.b);
1297
- ok = true;
1298
- format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
1299
- }
1300
- else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
1301
- color.s = convertToPercentage(color.s);
1302
- color.v = convertToPercentage(color.v);
1303
- rgb = hsvToRgb(color.h, color.s, color.v);
1304
- ok = true;
1305
- format = "hsv";
1306
- }
1307
- else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
1308
- color.s = convertToPercentage(color.s);
1309
- color.l = convertToPercentage(color.l);
1310
- rgb = hslToRgb(color.h, color.s, color.l);
1311
- ok = true;
1312
- format = "hsl";
1313
- }
1500
+ // Given a string or object, convert that input to RGB
1501
+ // Possible string inputs:
1502
+ //
1503
+ // "red"
1504
+ // "#f00" or "f00"
1505
+ // "#ff0000" or "ff0000"
1506
+ // "#ff000000" or "ff000000"
1507
+ // "rgb 255 0 0" or "rgb (255, 0, 0)"
1508
+ // "rgb 1.0 0 0" or "rgb (1, 0, 0)"
1509
+ // "rgba (255, 0, 0, 1)" or "rgba 255, 0, 0, 1"
1510
+ // "rgba (1.0, 0, 0, 1)" or "rgba 1.0, 0, 0, 1"
1511
+ // "hsl(0, 100%, 50%)" or "hsl 0 100% 50%"
1512
+ // "hsla(0, 100%, 50%, 1)" or "hsla 0 100% 50%, 1"
1513
+ // "hsv(0, 100%, 100%)" or "hsv 0 100% 100%"
1514
+ //
1515
+ function inputToRGB(color) {
1516
+
1517
+ var rgb = { r: 0, g: 0, b: 0 };
1518
+ var a = 1;
1519
+ var ok = false;
1520
+ var format = false;
1521
+
1522
+ if (typeof color == "string") {
1523
+ color = stringInputToObject(color);
1524
+ }
1314
1525
 
1315
- if (color.hasOwnProperty("a")) {
1316
- a = color.a;
1317
- }
1526
+ if (typeof color == "object") {
1527
+ if (color.hasOwnProperty("r") && color.hasOwnProperty("g") && color.hasOwnProperty("b")) {
1528
+ rgb = rgbToRgb(color.r, color.g, color.b);
1529
+ ok = true;
1530
+ format = String(color.r).substr(-1) === "%" ? "prgb" : "rgb";
1531
+ }
1532
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("v")) {
1533
+ color.s = convertToPercentage(color.s);
1534
+ color.v = convertToPercentage(color.v);
1535
+ rgb = hsvToRgb(color.h, color.s, color.v);
1536
+ ok = true;
1537
+ format = "hsv";
1538
+ }
1539
+ else if (color.hasOwnProperty("h") && color.hasOwnProperty("s") && color.hasOwnProperty("l")) {
1540
+ color.s = convertToPercentage(color.s);
1541
+ color.l = convertToPercentage(color.l);
1542
+ rgb = hslToRgb(color.h, color.s, color.l);
1543
+ ok = true;
1544
+ format = "hsl";
1318
1545
  }
1319
1546
 
1320
- a = boundAlpha(a);
1321
-
1322
- return {
1323
- ok: ok,
1324
- format: color.format || format,
1325
- r: mathMin(255, mathMax(rgb.r, 0)),
1326
- g: mathMin(255, mathMax(rgb.g, 0)),
1327
- b: mathMin(255, mathMax(rgb.b, 0)),
1328
- a: a
1329
- };
1547
+ if (color.hasOwnProperty("a")) {
1548
+ a = color.a;
1549
+ }
1330
1550
  }
1331
1551
 
1552
+ a = boundAlpha(a);
1553
+
1554
+ return {
1555
+ ok: ok,
1556
+ format: color.format || format,
1557
+ r: mathMin(255, mathMax(rgb.r, 0)),
1558
+ g: mathMin(255, mathMax(rgb.g, 0)),
1559
+ b: mathMin(255, mathMax(rgb.b, 0)),
1560
+ a: a
1561
+ };
1562
+ }
1332
1563
 
1333
- // Conversion Functions
1334
- // --------------------
1335
1564
 
1336
- // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
1337
- // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
1565
+ // Conversion Functions
1566
+ // --------------------
1338
1567
 
1339
- // `rgbToRgb`
1340
- // Handle bounds / percentage checking to conform to CSS color spec
1341
- // <http://www.w3.org/TR/css3-color/>
1342
- // *Assumes:* r, g, b in [0, 255] or [0, 1]
1343
- // *Returns:* { r, g, b } in [0, 255]
1344
- function rgbToRgb(r, g, b){
1345
- return {
1346
- r: bound01(r, 255) * 255,
1347
- g: bound01(g, 255) * 255,
1348
- b: bound01(b, 255) * 255
1349
- };
1350
- }
1568
+ // `rgbToHsl`, `rgbToHsv`, `hslToRgb`, `hsvToRgb` modified from:
1569
+ // <http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript>
1351
1570
 
1352
- // `rgbToHsl`
1353
- // Converts an RGB color value to HSL.
1354
- // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
1355
- // *Returns:* { h, s, l } in [0,1]
1356
- function rgbToHsl(r, g, b) {
1571
+ // `rgbToRgb`
1572
+ // Handle bounds / percentage checking to conform to CSS color spec
1573
+ // <http://www.w3.org/TR/css3-color/>
1574
+ // *Assumes:* r, g, b in [0, 255] or [0, 1]
1575
+ // *Returns:* { r, g, b } in [0, 255]
1576
+ function rgbToRgb(r, g, b){
1577
+ return {
1578
+ r: bound01(r, 255) * 255,
1579
+ g: bound01(g, 255) * 255,
1580
+ b: bound01(b, 255) * 255
1581
+ };
1582
+ }
1357
1583
 
1358
- r = bound01(r, 255);
1359
- g = bound01(g, 255);
1360
- b = bound01(b, 255);
1584
+ // `rgbToHsl`
1585
+ // Converts an RGB color value to HSL.
1586
+ // *Assumes:* r, g, and b are contained in [0, 255] or [0, 1]
1587
+ // *Returns:* { h, s, l } in [0,1]
1588
+ function rgbToHsl(r, g, b) {
1361
1589
 
1362
- var max = mathMax(r, g, b), min = mathMin(r, g, b);
1363
- var h, s, l = (max + min) / 2;
1590
+ r = bound01(r, 255);
1591
+ g = bound01(g, 255);
1592
+ b = bound01(b, 255);
1364
1593
 
1365
- if(max == min) {
1366
- h = s = 0; // achromatic
1367
- }
1368
- else {
1369
- var d = max - min;
1370
- s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1371
- switch(max) {
1372
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1373
- case g: h = (b - r) / d + 2; break;
1374
- case b: h = (r - g) / d + 4; break;
1375
- }
1594
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
1595
+ var h, s, l = (max + min) / 2;
1376
1596
 
1377
- h /= 6;
1597
+ if(max == min) {
1598
+ h = s = 0; // achromatic
1599
+ }
1600
+ else {
1601
+ var d = max - min;
1602
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
1603
+ switch(max) {
1604
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1605
+ case g: h = (b - r) / d + 2; break;
1606
+ case b: h = (r - g) / d + 4; break;
1378
1607
  }
1379
1608
 
1380
- return { h: h, s: s, l: l };
1609
+ h /= 6;
1381
1610
  }
1382
1611
 
1383
- // `hslToRgb`
1384
- // Converts an HSL color value to RGB.
1385
- // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
1386
- // *Returns:* { r, g, b } in the set [0, 255]
1387
- function hslToRgb(h, s, l) {
1388
- var r, g, b;
1389
-
1390
- h = bound01(h, 360);
1391
- s = bound01(s, 100);
1392
- l = bound01(l, 100);
1393
-
1394
- function hue2rgb(p, q, t) {
1395
- if(t < 0) t += 1;
1396
- if(t > 1) t -= 1;
1397
- if(t < 1/6) return p + (q - p) * 6 * t;
1398
- if(t < 1/2) return q;
1399
- if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
1400
- return p;
1401
- }
1612
+ return { h: h, s: s, l: l };
1613
+ }
1402
1614
 
1403
- if(s === 0) {
1404
- r = g = b = l; // achromatic
1405
- }
1406
- else {
1407
- var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1408
- var p = 2 * l - q;
1409
- r = hue2rgb(p, q, h + 1/3);
1410
- g = hue2rgb(p, q, h);
1411
- b = hue2rgb(p, q, h - 1/3);
1412
- }
1615
+ // `hslToRgb`
1616
+ // Converts an HSL color value to RGB.
1617
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and l are contained [0, 1] or [0, 100]
1618
+ // *Returns:* { r, g, b } in the set [0, 255]
1619
+ function hslToRgb(h, s, l) {
1620
+ var r, g, b;
1621
+
1622
+ h = bound01(h, 360);
1623
+ s = bound01(s, 100);
1624
+ l = bound01(l, 100);
1625
+
1626
+ function hue2rgb(p, q, t) {
1627
+ if(t < 0) t += 1;
1628
+ if(t > 1) t -= 1;
1629
+ if(t < 1/6) return p + (q - p) * 6 * t;
1630
+ if(t < 1/2) return q;
1631
+ if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
1632
+ return p;
1633
+ }
1413
1634
 
1414
- return { r: r * 255, g: g * 255, b: b * 255 };
1635
+ if(s === 0) {
1636
+ r = g = b = l; // achromatic
1637
+ }
1638
+ else {
1639
+ var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
1640
+ var p = 2 * l - q;
1641
+ r = hue2rgb(p, q, h + 1/3);
1642
+ g = hue2rgb(p, q, h);
1643
+ b = hue2rgb(p, q, h - 1/3);
1415
1644
  }
1416
1645
 
1417
- // `rgbToHsv`
1418
- // Converts an RGB color value to HSV
1419
- // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
1420
- // *Returns:* { h, s, v } in [0,1]
1421
- function rgbToHsv(r, g, b) {
1646
+ return { r: r * 255, g: g * 255, b: b * 255 };
1647
+ }
1422
1648
 
1423
- r = bound01(r, 255);
1424
- g = bound01(g, 255);
1425
- b = bound01(b, 255);
1649
+ // `rgbToHsv`
1650
+ // Converts an RGB color value to HSV
1651
+ // *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
1652
+ // *Returns:* { h, s, v } in [0,1]
1653
+ function rgbToHsv(r, g, b) {
1426
1654
 
1427
- var max = mathMax(r, g, b), min = mathMin(r, g, b);
1428
- var h, s, v = max;
1655
+ r = bound01(r, 255);
1656
+ g = bound01(g, 255);
1657
+ b = bound01(b, 255);
1429
1658
 
1430
- var d = max - min;
1431
- s = max === 0 ? 0 : d / max;
1659
+ var max = mathMax(r, g, b), min = mathMin(r, g, b);
1660
+ var h, s, v = max;
1432
1661
 
1433
- if(max == min) {
1434
- h = 0; // achromatic
1435
- }
1436
- else {
1437
- switch(max) {
1438
- case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1439
- case g: h = (b - r) / d + 2; break;
1440
- case b: h = (r - g) / d + 4; break;
1441
- }
1442
- h /= 6;
1662
+ var d = max - min;
1663
+ s = max === 0 ? 0 : d / max;
1664
+
1665
+ if(max == min) {
1666
+ h = 0; // achromatic
1667
+ }
1668
+ else {
1669
+ switch(max) {
1670
+ case r: h = (g - b) / d + (g < b ? 6 : 0); break;
1671
+ case g: h = (b - r) / d + 2; break;
1672
+ case b: h = (r - g) / d + 4; break;
1443
1673
  }
1444
- return { h: h, s: s, v: v };
1674
+ h /= 6;
1445
1675
  }
1676
+ return { h: h, s: s, v: v };
1677
+ }
1446
1678
 
1447
- // `hsvToRgb`
1448
- // Converts an HSV color value to RGB.
1449
- // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
1450
- // *Returns:* { r, g, b } in the set [0, 255]
1451
- function hsvToRgb(h, s, v) {
1452
-
1453
- h = bound01(h, 360) * 6;
1454
- s = bound01(s, 100);
1455
- v = bound01(v, 100);
1456
-
1457
- var i = math.floor(h),
1458
- f = h - i,
1459
- p = v * (1 - s),
1460
- q = v * (1 - f * s),
1461
- t = v * (1 - (1 - f) * s),
1462
- mod = i % 6,
1463
- r = [v, q, p, p, t, v][mod],
1464
- g = [t, v, v, q, p, p][mod],
1465
- b = [p, p, t, v, v, q][mod];
1679
+ // `hsvToRgb`
1680
+ // Converts an HSV color value to RGB.
1681
+ // *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
1682
+ // *Returns:* { r, g, b } in the set [0, 255]
1683
+ function hsvToRgb(h, s, v) {
1684
+
1685
+ h = bound01(h, 360) * 6;
1686
+ s = bound01(s, 100);
1687
+ v = bound01(v, 100);
1688
+
1689
+ var i = math.floor(h),
1690
+ f = h - i,
1691
+ p = v * (1 - s),
1692
+ q = v * (1 - f * s),
1693
+ t = v * (1 - (1 - f) * s),
1694
+ mod = i % 6,
1695
+ r = [v, q, p, p, t, v][mod],
1696
+ g = [t, v, v, q, p, p][mod],
1697
+ b = [p, p, t, v, v, q][mod];
1698
+
1699
+ return { r: r * 255, g: g * 255, b: b * 255 };
1700
+ }
1466
1701
 
1467
- return { r: r * 255, g: g * 255, b: b * 255 };
1702
+ // `rgbToHex`
1703
+ // Converts an RGB color to hex
1704
+ // Assumes r, g, and b are contained in the set [0, 255]
1705
+ // Returns a 3 or 6 character hex
1706
+ function rgbToHex(r, g, b, allow3Char) {
1707
+
1708
+ var hex = [
1709
+ pad2(mathRound(r).toString(16)),
1710
+ pad2(mathRound(g).toString(16)),
1711
+ pad2(mathRound(b).toString(16))
1712
+ ];
1713
+
1714
+ // Return a 3 character hex if possible
1715
+ if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
1716
+ return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1468
1717
  }
1469
1718
 
1470
- // `rgbToHex`
1471
- // Converts an RGB color to hex
1472
- // Assumes r, g, and b are contained in the set [0, 255]
1473
- // Returns a 3 or 6 character hex
1474
- function rgbToHex(r, g, b, allow3Char) {
1719
+ return hex.join("");
1720
+ }
1721
+ // `rgbaToHex`
1722
+ // Converts an RGBA color plus alpha transparency to hex
1723
+ // Assumes r, g, b and a are contained in the set [0, 255]
1724
+ // Returns an 8 character hex
1725
+ function rgbaToHex(r, g, b, a) {
1475
1726
 
1476
1727
  var hex = [
1728
+ pad2(convertDecimalToHex(a)),
1477
1729
  pad2(mathRound(r).toString(16)),
1478
1730
  pad2(mathRound(g).toString(16)),
1479
1731
  pad2(mathRound(b).toString(16))
1480
1732
  ];
1481
1733
 
1482
- // Return a 3 character hex if possible
1483
- if (allow3Char && hex[0].charAt(0) == hex[0].charAt(1) && hex[1].charAt(0) == hex[1].charAt(1) && hex[2].charAt(0) == hex[2].charAt(1)) {
1484
- return hex[0].charAt(0) + hex[1].charAt(0) + hex[2].charAt(0);
1485
- }
1486
-
1487
1734
  return hex.join("");
1488
1735
  }
1489
1736
 
1490
- // `equals`
1491
- // Can be called with any tinycolor input
1492
- tinycolor.equals = function (color1, color2) {
1493
- if (!color1 || !color2) { return false; }
1494
- return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
1495
- };
1496
- tinycolor.random = function() {
1497
- return tinycolor.fromRatio({
1498
- r: mathRandom(),
1499
- g: mathRandom(),
1500
- b: mathRandom()
1501
- });
1502
- };
1737
+ // `equals`
1738
+ // Can be called with any tinycolor input
1739
+ tinycolor.equals = function (color1, color2) {
1740
+ if (!color1 || !color2) { return false; }
1741
+ return tinycolor(color1).toRgbString() == tinycolor(color2).toRgbString();
1742
+ };
1743
+ tinycolor.random = function() {
1744
+ return tinycolor.fromRatio({
1745
+ r: mathRandom(),
1746
+ g: mathRandom(),
1747
+ b: mathRandom()
1748
+ });
1749
+ };
1503
1750
 
1504
1751
 
1505
- // Modification Functions
1506
- // ----------------------
1507
- // Thanks to less.js for some of the basics here
1508
- // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
1752
+ // Modification Functions
1753
+ // ----------------------
1754
+ // Thanks to less.js for some of the basics here
1755
+ // <https://github.com/cloudhead/less.js/blob/master/lib/less/functions.js>
1509
1756
 
1510
- tinycolor.desaturate = function (color, amount) {
1511
- amount = (amount === 0) ? 0 : (amount || 10);
1512
- var hsl = tinycolor(color).toHsl();
1513
- hsl.s -= amount / 100;
1514
- hsl.s = clamp01(hsl.s);
1515
- return tinycolor(hsl);
1516
- };
1517
- tinycolor.saturate = function (color, amount) {
1518
- amount = (amount === 0) ? 0 : (amount || 10);
1519
- var hsl = tinycolor(color).toHsl();
1520
- hsl.s += amount / 100;
1521
- hsl.s = clamp01(hsl.s);
1522
- return tinycolor(hsl);
1523
- };
1524
- tinycolor.greyscale = function(color) {
1525
- return tinycolor.desaturate(color, 100);
1526
- };
1527
- tinycolor.lighten = function(color, amount) {
1528
- amount = (amount === 0) ? 0 : (amount || 10);
1529
- var hsl = tinycolor(color).toHsl();
1530
- hsl.l += amount / 100;
1531
- hsl.l = clamp01(hsl.l);
1532
- return tinycolor(hsl);
1533
- };
1534
- tinycolor.darken = function (color, amount) {
1535
- amount = (amount === 0) ? 0 : (amount || 10);
1536
- var hsl = tinycolor(color).toHsl();
1537
- hsl.l -= amount / 100;
1538
- hsl.l = clamp01(hsl.l);
1539
- return tinycolor(hsl);
1540
- };
1541
- tinycolor.complement = function(color) {
1542
- var hsl = tinycolor(color).toHsl();
1543
- hsl.h = (hsl.h + 180) % 360;
1544
- return tinycolor(hsl);
1545
- };
1757
+ function desaturate(color, amount) {
1758
+ amount = (amount === 0) ? 0 : (amount || 10);
1759
+ var hsl = tinycolor(color).toHsl();
1760
+ hsl.s -= amount / 100;
1761
+ hsl.s = clamp01(hsl.s);
1762
+ return tinycolor(hsl);
1763
+ }
1546
1764
 
1765
+ function saturate(color, amount) {
1766
+ amount = (amount === 0) ? 0 : (amount || 10);
1767
+ var hsl = tinycolor(color).toHsl();
1768
+ hsl.s += amount / 100;
1769
+ hsl.s = clamp01(hsl.s);
1770
+ return tinycolor(hsl);
1771
+ }
1547
1772
 
1548
- // Combination Functions
1549
- // ---------------------
1550
- // Thanks to jQuery xColor for some of the ideas behind these
1551
- // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
1773
+ function greyscale(color) {
1774
+ return tinycolor(color).desaturate(100);
1775
+ }
1552
1776
 
1553
- tinycolor.triad = function(color) {
1554
- var hsl = tinycolor(color).toHsl();
1555
- var h = hsl.h;
1556
- return [
1557
- tinycolor(color),
1558
- tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1559
- tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
1560
- ];
1561
- };
1562
- tinycolor.tetrad = function(color) {
1563
- var hsl = tinycolor(color).toHsl();
1564
- var h = hsl.h;
1565
- return [
1566
- tinycolor(color),
1567
- tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1568
- tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1569
- tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
1570
- ];
1571
- };
1572
- tinycolor.splitcomplement = function(color) {
1573
- var hsl = tinycolor(color).toHsl();
1574
- var h = hsl.h;
1575
- return [
1576
- tinycolor(color),
1577
- tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
1578
- tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
1579
- ];
1580
- };
1581
- tinycolor.analogous = function(color, results, slices) {
1582
- results = results || 6;
1583
- slices = slices || 30;
1777
+ function lighten (color, amount) {
1778
+ amount = (amount === 0) ? 0 : (amount || 10);
1779
+ var hsl = tinycolor(color).toHsl();
1780
+ hsl.l += amount / 100;
1781
+ hsl.l = clamp01(hsl.l);
1782
+ return tinycolor(hsl);
1783
+ }
1584
1784
 
1585
- var hsl = tinycolor(color).toHsl();
1586
- var part = 360 / slices;
1587
- var ret = [tinycolor(color)];
1785
+ function brighten(color, amount) {
1786
+ amount = (amount === 0) ? 0 : (amount || 10);
1787
+ var rgb = tinycolor(color).toRgb();
1788
+ rgb.r = mathMax(0, mathMin(255, rgb.r - mathRound(255 * - (amount / 100))));
1789
+ rgb.g = mathMax(0, mathMin(255, rgb.g - mathRound(255 * - (amount / 100))));
1790
+ rgb.b = mathMax(0, mathMin(255, rgb.b - mathRound(255 * - (amount / 100))));
1791
+ return tinycolor(rgb);
1792
+ }
1588
1793
 
1589
- for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
1590
- hsl.h = (hsl.h + part) % 360;
1591
- ret.push(tinycolor(hsl));
1592
- }
1593
- return ret;
1594
- };
1595
- tinycolor.monochromatic = function(color, results) {
1596
- results = results || 6;
1597
- var hsv = tinycolor(color).toHsv();
1598
- var h = hsv.h, s = hsv.s, v = hsv.v;
1599
- var ret = [];
1600
- var modification = 1 / results;
1794
+ function darken (color, amount) {
1795
+ amount = (amount === 0) ? 0 : (amount || 10);
1796
+ var hsl = tinycolor(color).toHsl();
1797
+ hsl.l -= amount / 100;
1798
+ hsl.l = clamp01(hsl.l);
1799
+ return tinycolor(hsl);
1800
+ }
1601
1801
 
1602
- while (results--) {
1603
- ret.push(tinycolor({ h: h, s: s, v: v}));
1604
- v = (v + modification) % 1;
1605
- }
1802
+ // Spin takes a positive or negative amount within [-360, 360] indicating the change of hue.
1803
+ // Values outside of this range will be wrapped into this range.
1804
+ function spin(color, amount) {
1805
+ var hsl = tinycolor(color).toHsl();
1806
+ var hue = (mathRound(hsl.h) + amount) % 360;
1807
+ hsl.h = hue < 0 ? 360 + hue : hue;
1808
+ return tinycolor(hsl);
1809
+ }
1606
1810
 
1607
- return ret;
1608
- };
1811
+ // Combination Functions
1812
+ // ---------------------
1813
+ // Thanks to jQuery xColor for some of the ideas behind these
1814
+ // <https://github.com/infusion/jQuery-xcolor/blob/master/jquery.xcolor.js>
1609
1815
 
1816
+ function complement(color) {
1817
+ var hsl = tinycolor(color).toHsl();
1818
+ hsl.h = (hsl.h + 180) % 360;
1819
+ return tinycolor(hsl);
1820
+ }
1610
1821
 
1611
- // Readability Functions
1612
- // ---------------------
1613
- // <http://www.w3.org/TR/AERT#color-contrast>
1614
-
1615
- // `readability`
1616
- // Analyze the 2 colors and returns an object with the following properties:
1617
- // `brightness`: difference in brightness between the two colors
1618
- // `color`: difference in color/hue between the two colors
1619
- tinycolor.readability = function(color1, color2) {
1620
- var a = tinycolor(color1).toRgb();
1621
- var b = tinycolor(color2).toRgb();
1622
- var brightnessA = (a.r * 299 + a.g * 587 + a.b * 114) / 1000;
1623
- var brightnessB = (b.r * 299 + b.g * 587 + b.b * 114) / 1000;
1624
- var colorDiff = (
1625
- Math.max(a.r, b.r) - Math.min(a.r, b.r) +
1626
- Math.max(a.g, b.g) - Math.min(a.g, b.g) +
1627
- Math.max(a.b, b.b) - Math.min(a.b, b.b)
1628
- );
1822
+ function triad(color) {
1823
+ var hsl = tinycolor(color).toHsl();
1824
+ var h = hsl.h;
1825
+ return [
1826
+ tinycolor(color),
1827
+ tinycolor({ h: (h + 120) % 360, s: hsl.s, l: hsl.l }),
1828
+ tinycolor({ h: (h + 240) % 360, s: hsl.s, l: hsl.l })
1829
+ ];
1830
+ }
1629
1831
 
1630
- return {
1631
- brightness: Math.abs(brightnessA - brightnessB),
1632
- color: colorDiff
1633
- };
1634
- };
1832
+ function tetrad(color) {
1833
+ var hsl = tinycolor(color).toHsl();
1834
+ var h = hsl.h;
1835
+ return [
1836
+ tinycolor(color),
1837
+ tinycolor({ h: (h + 90) % 360, s: hsl.s, l: hsl.l }),
1838
+ tinycolor({ h: (h + 180) % 360, s: hsl.s, l: hsl.l }),
1839
+ tinycolor({ h: (h + 270) % 360, s: hsl.s, l: hsl.l })
1840
+ ];
1841
+ }
1635
1842
 
1636
- // `readable`
1637
- // http://www.w3.org/TR/AERT#color-contrast
1638
- // Ensure that foreground and background color combinations provide sufficient contrast.
1639
- // *Example*
1640
- // tinycolor.readable("#000", "#111") => false
1641
- tinycolor.readable = function(color1, color2) {
1642
- var readability = tinycolor.readability(color1, color2);
1643
- return readability.brightness > 125 && readability.color > 500;
1644
- };
1843
+ function splitcomplement(color) {
1844
+ var hsl = tinycolor(color).toHsl();
1845
+ var h = hsl.h;
1846
+ return [
1847
+ tinycolor(color),
1848
+ tinycolor({ h: (h + 72) % 360, s: hsl.s, l: hsl.l}),
1849
+ tinycolor({ h: (h + 216) % 360, s: hsl.s, l: hsl.l})
1850
+ ];
1851
+ }
1645
1852
 
1646
- // `mostReadable`
1647
- // Given a base color and a list of possible foreground or background
1648
- // colors for that base, returns the most readable color.
1649
- // *Example*
1650
- // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
1651
- tinycolor.mostReadable = function(baseColor, colorList) {
1652
- var bestColor = null;
1653
- var bestScore = 0;
1654
- var bestIsReadable = false;
1655
- for (var i=0; i < colorList.length; i++) {
1656
-
1657
- // We normalize both around the "acceptable" breaking point,
1658
- // but rank brightness constrast higher than hue.
1659
-
1660
- var readability = tinycolor.readability(baseColor, colorList[i]);
1661
- var readable = readability.brightness > 125 && readability.color > 500;
1662
- var score = 3 * (readability.brightness / 125) + (readability.color / 500);
1663
-
1664
- if ((readable && ! bestIsReadable) ||
1665
- (readable && bestIsReadable && score > bestScore) ||
1666
- ((! readable) && (! bestIsReadable) && score > bestScore)) {
1667
- bestIsReadable = readable;
1668
- bestScore = score;
1669
- bestColor = tinycolor(colorList[i]);
1670
- }
1671
- }
1672
- return bestColor;
1673
- };
1853
+ function analogous(color, results, slices) {
1854
+ results = results || 6;
1855
+ slices = slices || 30;
1856
+
1857
+ var hsl = tinycolor(color).toHsl();
1858
+ var part = 360 / slices;
1859
+ var ret = [tinycolor(color)];
1860
+
1861
+ for (hsl.h = ((hsl.h - (part * results >> 1)) + 720) % 360; --results; ) {
1862
+ hsl.h = (hsl.h + part) % 360;
1863
+ ret.push(tinycolor(hsl));
1864
+ }
1865
+ return ret;
1866
+ }
1674
1867
 
1868
+ function monochromatic(color, results) {
1869
+ results = results || 6;
1870
+ var hsv = tinycolor(color).toHsv();
1871
+ var h = hsv.h, s = hsv.s, v = hsv.v;
1872
+ var ret = [];
1873
+ var modification = 1 / results;
1675
1874
 
1676
- // Big List of Colors
1677
- // ------------------
1678
- // <http://www.w3.org/TR/css3-color/#svg-color>
1679
- var names = tinycolor.names = {
1680
- aliceblue: "f0f8ff",
1681
- antiquewhite: "faebd7",
1682
- aqua: "0ff",
1683
- aquamarine: "7fffd4",
1684
- azure: "f0ffff",
1685
- beige: "f5f5dc",
1686
- bisque: "ffe4c4",
1687
- black: "000",
1688
- blanchedalmond: "ffebcd",
1689
- blue: "00f",
1690
- blueviolet: "8a2be2",
1691
- brown: "a52a2a",
1692
- burlywood: "deb887",
1693
- burntsienna: "ea7e5d",
1694
- cadetblue: "5f9ea0",
1695
- chartreuse: "7fff00",
1696
- chocolate: "d2691e",
1697
- coral: "ff7f50",
1698
- cornflowerblue: "6495ed",
1699
- cornsilk: "fff8dc",
1700
- crimson: "dc143c",
1701
- cyan: "0ff",
1702
- darkblue: "00008b",
1703
- darkcyan: "008b8b",
1704
- darkgoldenrod: "b8860b",
1705
- darkgray: "a9a9a9",
1706
- darkgreen: "006400",
1707
- darkgrey: "a9a9a9",
1708
- darkkhaki: "bdb76b",
1709
- darkmagenta: "8b008b",
1710
- darkolivegreen: "556b2f",
1711
- darkorange: "ff8c00",
1712
- darkorchid: "9932cc",
1713
- darkred: "8b0000",
1714
- darksalmon: "e9967a",
1715
- darkseagreen: "8fbc8f",
1716
- darkslateblue: "483d8b",
1717
- darkslategray: "2f4f4f",
1718
- darkslategrey: "2f4f4f",
1719
- darkturquoise: "00ced1",
1720
- darkviolet: "9400d3",
1721
- deeppink: "ff1493",
1722
- deepskyblue: "00bfff",
1723
- dimgray: "696969",
1724
- dimgrey: "696969",
1725
- dodgerblue: "1e90ff",
1726
- firebrick: "b22222",
1727
- floralwhite: "fffaf0",
1728
- forestgreen: "228b22",
1729
- fuchsia: "f0f",
1730
- gainsboro: "dcdcdc",
1731
- ghostwhite: "f8f8ff",
1732
- gold: "ffd700",
1733
- goldenrod: "daa520",
1734
- gray: "808080",
1735
- green: "008000",
1736
- greenyellow: "adff2f",
1737
- grey: "808080",
1738
- honeydew: "f0fff0",
1739
- hotpink: "ff69b4",
1740
- indianred: "cd5c5c",
1741
- indigo: "4b0082",
1742
- ivory: "fffff0",
1743
- khaki: "f0e68c",
1744
- lavender: "e6e6fa",
1745
- lavenderblush: "fff0f5",
1746
- lawngreen: "7cfc00",
1747
- lemonchiffon: "fffacd",
1748
- lightblue: "add8e6",
1749
- lightcoral: "f08080",
1750
- lightcyan: "e0ffff",
1751
- lightgoldenrodyellow: "fafad2",
1752
- lightgray: "d3d3d3",
1753
- lightgreen: "90ee90",
1754
- lightgrey: "d3d3d3",
1755
- lightpink: "ffb6c1",
1756
- lightsalmon: "ffa07a",
1757
- lightseagreen: "20b2aa",
1758
- lightskyblue: "87cefa",
1759
- lightslategray: "789",
1760
- lightslategrey: "789",
1761
- lightsteelblue: "b0c4de",
1762
- lightyellow: "ffffe0",
1763
- lime: "0f0",
1764
- limegreen: "32cd32",
1765
- linen: "faf0e6",
1766
- magenta: "f0f",
1767
- maroon: "800000",
1768
- mediumaquamarine: "66cdaa",
1769
- mediumblue: "0000cd",
1770
- mediumorchid: "ba55d3",
1771
- mediumpurple: "9370db",
1772
- mediumseagreen: "3cb371",
1773
- mediumslateblue: "7b68ee",
1774
- mediumspringgreen: "00fa9a",
1775
- mediumturquoise: "48d1cc",
1776
- mediumvioletred: "c71585",
1777
- midnightblue: "191970",
1778
- mintcream: "f5fffa",
1779
- mistyrose: "ffe4e1",
1780
- moccasin: "ffe4b5",
1781
- navajowhite: "ffdead",
1782
- navy: "000080",
1783
- oldlace: "fdf5e6",
1784
- olive: "808000",
1785
- olivedrab: "6b8e23",
1786
- orange: "ffa500",
1787
- orangered: "ff4500",
1788
- orchid: "da70d6",
1789
- palegoldenrod: "eee8aa",
1790
- palegreen: "98fb98",
1791
- paleturquoise: "afeeee",
1792
- palevioletred: "db7093",
1793
- papayawhip: "ffefd5",
1794
- peachpuff: "ffdab9",
1795
- peru: "cd853f",
1796
- pink: "ffc0cb",
1797
- plum: "dda0dd",
1798
- powderblue: "b0e0e6",
1799
- purple: "800080",
1800
- red: "f00",
1801
- rosybrown: "bc8f8f",
1802
- royalblue: "4169e1",
1803
- saddlebrown: "8b4513",
1804
- salmon: "fa8072",
1805
- sandybrown: "f4a460",
1806
- seagreen: "2e8b57",
1807
- seashell: "fff5ee",
1808
- sienna: "a0522d",
1809
- silver: "c0c0c0",
1810
- skyblue: "87ceeb",
1811
- slateblue: "6a5acd",
1812
- slategray: "708090",
1813
- slategrey: "708090",
1814
- snow: "fffafa",
1815
- springgreen: "00ff7f",
1816
- steelblue: "4682b4",
1817
- tan: "d2b48c",
1818
- teal: "008080",
1819
- thistle: "d8bfd8",
1820
- tomato: "ff6347",
1821
- turquoise: "40e0d0",
1822
- violet: "ee82ee",
1823
- wheat: "f5deb3",
1824
- white: "fff",
1825
- whitesmoke: "f5f5f5",
1826
- yellow: "ff0",
1827
- yellowgreen: "9acd32"
1875
+ while (results--) {
1876
+ ret.push(tinycolor({ h: h, s: s, v: v}));
1877
+ v = (v + modification) % 1;
1878
+ }
1879
+
1880
+ return ret;
1881
+ }
1882
+
1883
+ // Utility Functions
1884
+ // ---------------------
1885
+
1886
+ tinycolor.mix = function(color1, color2, amount) {
1887
+ amount = (amount === 0) ? 0 : (amount || 50);
1888
+
1889
+ var rgb1 = tinycolor(color1).toRgb();
1890
+ var rgb2 = tinycolor(color2).toRgb();
1891
+
1892
+ var p = amount / 100;
1893
+ var w = p * 2 - 1;
1894
+ var a = rgb2.a - rgb1.a;
1895
+
1896
+ var w1;
1897
+
1898
+ if (w * a == -1) {
1899
+ w1 = w;
1900
+ } else {
1901
+ w1 = (w + a) / (1 + w * a);
1902
+ }
1903
+
1904
+ w1 = (w1 + 1) / 2;
1905
+
1906
+ var w2 = 1 - w1;
1907
+
1908
+ var rgba = {
1909
+ r: rgb2.r * w1 + rgb1.r * w2,
1910
+ g: rgb2.g * w1 + rgb1.g * w2,
1911
+ b: rgb2.b * w1 + rgb1.b * w2,
1912
+ a: rgb2.a * p + rgb1.a * (1 - p)
1828
1913
  };
1829
1914
 
1830
- // Make it easy to access colors via `hexNames[hex]`
1831
- var hexNames = tinycolor.hexNames = flip(names);
1915
+ return tinycolor(rgba);
1916
+ };
1917
+
1832
1918
 
1919
+ // Readability Functions
1920
+ // ---------------------
1921
+ // <http://www.w3.org/TR/AERT#color-contrast>
1922
+
1923
+ // `readability`
1924
+ // Analyze the 2 colors and returns an object with the following properties:
1925
+ // `brightness`: difference in brightness between the two colors
1926
+ // `color`: difference in color/hue between the two colors
1927
+ tinycolor.readability = function(color1, color2) {
1928
+ var c1 = tinycolor(color1);
1929
+ var c2 = tinycolor(color2);
1930
+ var rgb1 = c1.toRgb();
1931
+ var rgb2 = c2.toRgb();
1932
+ var brightnessA = c1.getBrightness();
1933
+ var brightnessB = c2.getBrightness();
1934
+ var colorDiff = (
1935
+ Math.max(rgb1.r, rgb2.r) - Math.min(rgb1.r, rgb2.r) +
1936
+ Math.max(rgb1.g, rgb2.g) - Math.min(rgb1.g, rgb2.g) +
1937
+ Math.max(rgb1.b, rgb2.b) - Math.min(rgb1.b, rgb2.b)
1938
+ );
1939
+
1940
+ return {
1941
+ brightness: Math.abs(brightnessA - brightnessB),
1942
+ color: colorDiff
1943
+ };
1944
+ };
1833
1945
 
1834
- // Utilities
1835
- // ---------
1946
+ // `readable`
1947
+ // http://www.w3.org/TR/AERT#color-contrast
1948
+ // Ensure that foreground and background color combinations provide sufficient contrast.
1949
+ // *Example*
1950
+ // tinycolor.isReadable("#000", "#111") => false
1951
+ tinycolor.isReadable = function(color1, color2) {
1952
+ var readability = tinycolor.readability(color1, color2);
1953
+ return readability.brightness > 125 && readability.color > 500;
1954
+ };
1836
1955
 
1837
- // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
1838
- function flip(o) {
1839
- var flipped = { };
1840
- for (var i in o) {
1841
- if (o.hasOwnProperty(i)) {
1842
- flipped[o[i]] = i;
1843
- }
1956
+ // `mostReadable`
1957
+ // Given a base color and a list of possible foreground or background
1958
+ // colors for that base, returns the most readable color.
1959
+ // *Example*
1960
+ // tinycolor.mostReadable("#123", ["#fff", "#000"]) => "#000"
1961
+ tinycolor.mostReadable = function(baseColor, colorList) {
1962
+ var bestColor = null;
1963
+ var bestScore = 0;
1964
+ var bestIsReadable = false;
1965
+ for (var i=0; i < colorList.length; i++) {
1966
+
1967
+ // We normalize both around the "acceptable" breaking point,
1968
+ // but rank brightness constrast higher than hue.
1969
+
1970
+ var readability = tinycolor.readability(baseColor, colorList[i]);
1971
+ var readable = readability.brightness > 125 && readability.color > 500;
1972
+ var score = 3 * (readability.brightness / 125) + (readability.color / 500);
1973
+
1974
+ if ((readable && ! bestIsReadable) ||
1975
+ (readable && bestIsReadable && score > bestScore) ||
1976
+ ((! readable) && (! bestIsReadable) && score > bestScore)) {
1977
+ bestIsReadable = readable;
1978
+ bestScore = score;
1979
+ bestColor = tinycolor(colorList[i]);
1844
1980
  }
1845
- return flipped;
1846
1981
  }
1982
+ return bestColor;
1983
+ };
1847
1984
 
1848
- // Return a valid alpha value [0,1] with all invalid values being set to 1
1849
- function boundAlpha(a) {
1850
- a = parseFloat(a);
1851
1985
 
1852
- if (isNaN(a) || a < 0 || a > 1) {
1853
- a = 1;
1854
- }
1986
+ // Big List of Colors
1987
+ // ------------------
1988
+ // <http://www.w3.org/TR/css3-color/#svg-color>
1989
+ var names = tinycolor.names = {
1990
+ aliceblue: "f0f8ff",
1991
+ antiquewhite: "faebd7",
1992
+ aqua: "0ff",
1993
+ aquamarine: "7fffd4",
1994
+ azure: "f0ffff",
1995
+ beige: "f5f5dc",
1996
+ bisque: "ffe4c4",
1997
+ black: "000",
1998
+ blanchedalmond: "ffebcd",
1999
+ blue: "00f",
2000
+ blueviolet: "8a2be2",
2001
+ brown: "a52a2a",
2002
+ burlywood: "deb887",
2003
+ burntsienna: "ea7e5d",
2004
+ cadetblue: "5f9ea0",
2005
+ chartreuse: "7fff00",
2006
+ chocolate: "d2691e",
2007
+ coral: "ff7f50",
2008
+ cornflowerblue: "6495ed",
2009
+ cornsilk: "fff8dc",
2010
+ crimson: "dc143c",
2011
+ cyan: "0ff",
2012
+ darkblue: "00008b",
2013
+ darkcyan: "008b8b",
2014
+ darkgoldenrod: "b8860b",
2015
+ darkgray: "a9a9a9",
2016
+ darkgreen: "006400",
2017
+ darkgrey: "a9a9a9",
2018
+ darkkhaki: "bdb76b",
2019
+ darkmagenta: "8b008b",
2020
+ darkolivegreen: "556b2f",
2021
+ darkorange: "ff8c00",
2022
+ darkorchid: "9932cc",
2023
+ darkred: "8b0000",
2024
+ darksalmon: "e9967a",
2025
+ darkseagreen: "8fbc8f",
2026
+ darkslateblue: "483d8b",
2027
+ darkslategray: "2f4f4f",
2028
+ darkslategrey: "2f4f4f",
2029
+ darkturquoise: "00ced1",
2030
+ darkviolet: "9400d3",
2031
+ deeppink: "ff1493",
2032
+ deepskyblue: "00bfff",
2033
+ dimgray: "696969",
2034
+ dimgrey: "696969",
2035
+ dodgerblue: "1e90ff",
2036
+ firebrick: "b22222",
2037
+ floralwhite: "fffaf0",
2038
+ forestgreen: "228b22",
2039
+ fuchsia: "f0f",
2040
+ gainsboro: "dcdcdc",
2041
+ ghostwhite: "f8f8ff",
2042
+ gold: "ffd700",
2043
+ goldenrod: "daa520",
2044
+ gray: "808080",
2045
+ green: "008000",
2046
+ greenyellow: "adff2f",
2047
+ grey: "808080",
2048
+ honeydew: "f0fff0",
2049
+ hotpink: "ff69b4",
2050
+ indianred: "cd5c5c",
2051
+ indigo: "4b0082",
2052
+ ivory: "fffff0",
2053
+ khaki: "f0e68c",
2054
+ lavender: "e6e6fa",
2055
+ lavenderblush: "fff0f5",
2056
+ lawngreen: "7cfc00",
2057
+ lemonchiffon: "fffacd",
2058
+ lightblue: "add8e6",
2059
+ lightcoral: "f08080",
2060
+ lightcyan: "e0ffff",
2061
+ lightgoldenrodyellow: "fafad2",
2062
+ lightgray: "d3d3d3",
2063
+ lightgreen: "90ee90",
2064
+ lightgrey: "d3d3d3",
2065
+ lightpink: "ffb6c1",
2066
+ lightsalmon: "ffa07a",
2067
+ lightseagreen: "20b2aa",
2068
+ lightskyblue: "87cefa",
2069
+ lightslategray: "789",
2070
+ lightslategrey: "789",
2071
+ lightsteelblue: "b0c4de",
2072
+ lightyellow: "ffffe0",
2073
+ lime: "0f0",
2074
+ limegreen: "32cd32",
2075
+ linen: "faf0e6",
2076
+ magenta: "f0f",
2077
+ maroon: "800000",
2078
+ mediumaquamarine: "66cdaa",
2079
+ mediumblue: "0000cd",
2080
+ mediumorchid: "ba55d3",
2081
+ mediumpurple: "9370db",
2082
+ mediumseagreen: "3cb371",
2083
+ mediumslateblue: "7b68ee",
2084
+ mediumspringgreen: "00fa9a",
2085
+ mediumturquoise: "48d1cc",
2086
+ mediumvioletred: "c71585",
2087
+ midnightblue: "191970",
2088
+ mintcream: "f5fffa",
2089
+ mistyrose: "ffe4e1",
2090
+ moccasin: "ffe4b5",
2091
+ navajowhite: "ffdead",
2092
+ navy: "000080",
2093
+ oldlace: "fdf5e6",
2094
+ olive: "808000",
2095
+ olivedrab: "6b8e23",
2096
+ orange: "ffa500",
2097
+ orangered: "ff4500",
2098
+ orchid: "da70d6",
2099
+ palegoldenrod: "eee8aa",
2100
+ palegreen: "98fb98",
2101
+ paleturquoise: "afeeee",
2102
+ palevioletred: "db7093",
2103
+ papayawhip: "ffefd5",
2104
+ peachpuff: "ffdab9",
2105
+ peru: "cd853f",
2106
+ pink: "ffc0cb",
2107
+ plum: "dda0dd",
2108
+ powderblue: "b0e0e6",
2109
+ purple: "800080",
2110
+ rebeccapurple: "663399",
2111
+ red: "f00",
2112
+ rosybrown: "bc8f8f",
2113
+ royalblue: "4169e1",
2114
+ saddlebrown: "8b4513",
2115
+ salmon: "fa8072",
2116
+ sandybrown: "f4a460",
2117
+ seagreen: "2e8b57",
2118
+ seashell: "fff5ee",
2119
+ sienna: "a0522d",
2120
+ silver: "c0c0c0",
2121
+ skyblue: "87ceeb",
2122
+ slateblue: "6a5acd",
2123
+ slategray: "708090",
2124
+ slategrey: "708090",
2125
+ snow: "fffafa",
2126
+ springgreen: "00ff7f",
2127
+ steelblue: "4682b4",
2128
+ tan: "d2b48c",
2129
+ teal: "008080",
2130
+ thistle: "d8bfd8",
2131
+ tomato: "ff6347",
2132
+ turquoise: "40e0d0",
2133
+ violet: "ee82ee",
2134
+ wheat: "f5deb3",
2135
+ white: "fff",
2136
+ whitesmoke: "f5f5f5",
2137
+ yellow: "ff0",
2138
+ yellowgreen: "9acd32"
2139
+ };
1855
2140
 
1856
- return a;
1857
- }
2141
+ // Make it easy to access colors via `hexNames[hex]`
2142
+ var hexNames = tinycolor.hexNames = flip(names);
1858
2143
 
1859
- // Take input from [0, n] and return it as [0, 1]
1860
- function bound01(n, max) {
1861
- if (isOnePointZero(n)) { n = "100%"; }
1862
2144
 
1863
- var processPercent = isPercentage(n);
1864
- n = mathMin(max, mathMax(0, parseFloat(n)));
2145
+ // Utilities
2146
+ // ---------
1865
2147
 
1866
- // Automatically convert percentage into number
1867
- if (processPercent) {
1868
- n = parseInt(n * max, 10) / 100;
2148
+ // `{ 'name1': 'val1' }` becomes `{ 'val1': 'name1' }`
2149
+ function flip(o) {
2150
+ var flipped = { };
2151
+ for (var i in o) {
2152
+ if (o.hasOwnProperty(i)) {
2153
+ flipped[o[i]] = i;
1869
2154
  }
2155
+ }
2156
+ return flipped;
2157
+ }
1870
2158
 
1871
- // Handle floating point rounding errors
1872
- if ((math.abs(n - max) < 0.000001)) {
1873
- return 1;
1874
- }
2159
+ // Return a valid alpha value [0,1] with all invalid values being set to 1
2160
+ function boundAlpha(a) {
2161
+ a = parseFloat(a);
1875
2162
 
1876
- // Convert into [0, 1] range if it isn't already
1877
- return (n % max) / parseFloat(max);
2163
+ if (isNaN(a) || a < 0 || a > 1) {
2164
+ a = 1;
1878
2165
  }
1879
2166
 
1880
- // Force a number between 0 and 1
1881
- function clamp01(val) {
1882
- return mathMin(1, mathMax(0, val));
1883
- }
2167
+ return a;
2168
+ }
1884
2169
 
1885
- // Parse an integer into hex
1886
- function parseHex(val) {
1887
- return parseInt(val, 16);
1888
- }
2170
+ // Take input from [0, n] and return it as [0, 1]
2171
+ function bound01(n, max) {
2172
+ if (isOnePointZero(n)) { n = "100%"; }
1889
2173
 
1890
- // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
1891
- // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
1892
- function isOnePointZero(n) {
1893
- return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
1894
- }
2174
+ var processPercent = isPercentage(n);
2175
+ n = mathMin(max, mathMax(0, parseFloat(n)));
1895
2176
 
1896
- // Check to see if string passed in is a percentage
1897
- function isPercentage(n) {
1898
- return typeof n === "string" && n.indexOf('%') != -1;
2177
+ // Automatically convert percentage into number
2178
+ if (processPercent) {
2179
+ n = parseInt(n * max, 10) / 100;
1899
2180
  }
1900
2181
 
1901
- // Force a hex value to have 2 characters
1902
- function pad2(c) {
1903
- return c.length == 1 ? '0' + c : '' + c;
2182
+ // Handle floating point rounding errors
2183
+ if ((math.abs(n - max) < 0.000001)) {
2184
+ return 1;
1904
2185
  }
1905
2186
 
1906
- // Replace a decimal with it's percentage value
1907
- function convertToPercentage(n) {
1908
- if (n <= 1) {
1909
- n = (n * 100) + "%";
1910
- }
2187
+ // Convert into [0, 1] range if it isn't already
2188
+ return (n % max) / parseFloat(max);
2189
+ }
1911
2190
 
1912
- return n;
1913
- }
2191
+ // Force a number between 0 and 1
2192
+ function clamp01(val) {
2193
+ return mathMin(1, mathMax(0, val));
2194
+ }
1914
2195
 
1915
- var matchers = (function() {
2196
+ // Parse a base-16 hex value into a base-10 integer
2197
+ function parseIntFromHex(val) {
2198
+ return parseInt(val, 16);
2199
+ }
1916
2200
 
1917
- // <http://www.w3.org/TR/css3-values/#integers>
1918
- var CSS_INTEGER = "[-\\+]?\\d+%?";
2201
+ // Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
2202
+ // <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
2203
+ function isOnePointZero(n) {
2204
+ return typeof n == "string" && n.indexOf('.') != -1 && parseFloat(n) === 1;
2205
+ }
1919
2206
 
1920
- // <http://www.w3.org/TR/css3-values/#number-value>
1921
- var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
2207
+ // Check to see if string passed in is a percentage
2208
+ function isPercentage(n) {
2209
+ return typeof n === "string" && n.indexOf('%') != -1;
2210
+ }
1922
2211
 
1923
- // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
1924
- var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
2212
+ // Force a hex value to have 2 characters
2213
+ function pad2(c) {
2214
+ return c.length == 1 ? '0' + c : '' + c;
2215
+ }
1925
2216
 
1926
- // Actual matching.
1927
- // Parentheses and commas are optional, but not required.
1928
- // Whitespace can take the place of commas or opening paren
1929
- var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
1930
- var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2217
+ // Replace a decimal with it's percentage value
2218
+ function convertToPercentage(n) {
2219
+ if (n <= 1) {
2220
+ n = (n * 100) + "%";
2221
+ }
1931
2222
 
1932
- return {
1933
- rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
1934
- rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
1935
- hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
1936
- hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
1937
- hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
1938
- hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
1939
- hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
1940
- };
1941
- })();
2223
+ return n;
2224
+ }
1942
2225
 
1943
- // `stringInputToObject`
1944
- // Permissive string parsing. Take in a number of formats, and output an object
1945
- // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
1946
- function stringInputToObject(color) {
2226
+ // Converts a decimal to a hex value
2227
+ function convertDecimalToHex(d) {
2228
+ return Math.round(parseFloat(d) * 255).toString(16);
2229
+ }
2230
+ // Converts a hex value to a decimal
2231
+ function convertHexToDecimal(h) {
2232
+ return (parseIntFromHex(h) / 255);
2233
+ }
1947
2234
 
1948
- color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
1949
- var named = false;
1950
- if (names[color]) {
1951
- color = names[color];
1952
- named = true;
1953
- }
1954
- else if (color == 'transparent') {
1955
- return { r: 0, g: 0, b: 0, a: 0, format: "name" };
1956
- }
2235
+ var matchers = (function() {
2236
+
2237
+ // <http://www.w3.org/TR/css3-values/#integers>
2238
+ var CSS_INTEGER = "[-\\+]?\\d+%?";
2239
+
2240
+ // <http://www.w3.org/TR/css3-values/#number-value>
2241
+ var CSS_NUMBER = "[-\\+]?\\d*\\.\\d+%?";
2242
+
2243
+ // Allow positive/negative integer/number. Don't capture the either/or, just the entire outcome.
2244
+ var CSS_UNIT = "(?:" + CSS_NUMBER + ")|(?:" + CSS_INTEGER + ")";
2245
+
2246
+ // Actual matching.
2247
+ // Parentheses and commas are optional, but not required.
2248
+ // Whitespace can take the place of commas or opening paren
2249
+ var PERMISSIVE_MATCH3 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2250
+ var PERMISSIVE_MATCH4 = "[\\s|\\(]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")[,|\\s]+(" + CSS_UNIT + ")\\s*\\)?";
2251
+
2252
+ return {
2253
+ rgb: new RegExp("rgb" + PERMISSIVE_MATCH3),
2254
+ rgba: new RegExp("rgba" + PERMISSIVE_MATCH4),
2255
+ hsl: new RegExp("hsl" + PERMISSIVE_MATCH3),
2256
+ hsla: new RegExp("hsla" + PERMISSIVE_MATCH4),
2257
+ hsv: new RegExp("hsv" + PERMISSIVE_MATCH3),
2258
+ hsva: new RegExp("hsva" + PERMISSIVE_MATCH4),
2259
+ hex3: /^([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,
2260
+ hex6: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,
2261
+ hex8: /^([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/
2262
+ };
2263
+ })();
1957
2264
 
1958
- // Try to match string input using regular expressions.
1959
- // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
1960
- // Just return an object and let the conversion functions handle that.
1961
- // This way the result will be the same whether the tinycolor is initialized with string or object.
1962
- var match;
1963
- if ((match = matchers.rgb.exec(color))) {
1964
- return { r: match[1], g: match[2], b: match[3] };
1965
- }
1966
- if ((match = matchers.rgba.exec(color))) {
1967
- return { r: match[1], g: match[2], b: match[3], a: match[4] };
1968
- }
1969
- if ((match = matchers.hsl.exec(color))) {
1970
- return { h: match[1], s: match[2], l: match[3] };
1971
- }
1972
- if ((match = matchers.hsla.exec(color))) {
1973
- return { h: match[1], s: match[2], l: match[3], a: match[4] };
1974
- }
1975
- if ((match = matchers.hsv.exec(color))) {
1976
- return { h: match[1], s: match[2], v: match[3] };
1977
- }
1978
- if ((match = matchers.hex6.exec(color))) {
1979
- return {
1980
- r: parseHex(match[1]),
1981
- g: parseHex(match[2]),
1982
- b: parseHex(match[3]),
1983
- format: named ? "name" : "hex"
1984
- };
1985
- }
1986
- if ((match = matchers.hex3.exec(color))) {
1987
- return {
1988
- r: parseHex(match[1] + '' + match[1]),
1989
- g: parseHex(match[2] + '' + match[2]),
1990
- b: parseHex(match[3] + '' + match[3]),
1991
- format: named ? "name" : "hex"
1992
- };
1993
- }
2265
+ // `stringInputToObject`
2266
+ // Permissive string parsing. Take in a number of formats, and output an object
2267
+ // based on detected format. Returns `{ r, g, b }` or `{ h, s, l }` or `{ h, s, v}`
2268
+ function stringInputToObject(color) {
2269
+
2270
+ color = color.replace(trimLeft,'').replace(trimRight, '').toLowerCase();
2271
+ var named = false;
2272
+ if (names[color]) {
2273
+ color = names[color];
2274
+ named = true;
2275
+ }
2276
+ else if (color == 'transparent') {
2277
+ return { r: 0, g: 0, b: 0, a: 0, format: "name" };
2278
+ }
1994
2279
 
1995
- return false;
2280
+ // Try to match string input using regular expressions.
2281
+ // Keep most of the number bounding out of this function - don't worry about [0,1] or [0,100] or [0,360]
2282
+ // Just return an object and let the conversion functions handle that.
2283
+ // This way the result will be the same whether the tinycolor is initialized with string or object.
2284
+ var match;
2285
+ if ((match = matchers.rgb.exec(color))) {
2286
+ return { r: match[1], g: match[2], b: match[3] };
2287
+ }
2288
+ if ((match = matchers.rgba.exec(color))) {
2289
+ return { r: match[1], g: match[2], b: match[3], a: match[4] };
2290
+ }
2291
+ if ((match = matchers.hsl.exec(color))) {
2292
+ return { h: match[1], s: match[2], l: match[3] };
2293
+ }
2294
+ if ((match = matchers.hsla.exec(color))) {
2295
+ return { h: match[1], s: match[2], l: match[3], a: match[4] };
2296
+ }
2297
+ if ((match = matchers.hsv.exec(color))) {
2298
+ return { h: match[1], s: match[2], v: match[3] };
2299
+ }
2300
+ if ((match = matchers.hsva.exec(color))) {
2301
+ return { h: match[1], s: match[2], v: match[3], a: match[4] };
2302
+ }
2303
+ if ((match = matchers.hex8.exec(color))) {
2304
+ return {
2305
+ a: convertHexToDecimal(match[1]),
2306
+ r: parseIntFromHex(match[2]),
2307
+ g: parseIntFromHex(match[3]),
2308
+ b: parseIntFromHex(match[4]),
2309
+ format: named ? "name" : "hex8"
2310
+ };
2311
+ }
2312
+ if ((match = matchers.hex6.exec(color))) {
2313
+ return {
2314
+ r: parseIntFromHex(match[1]),
2315
+ g: parseIntFromHex(match[2]),
2316
+ b: parseIntFromHex(match[3]),
2317
+ format: named ? "name" : "hex"
2318
+ };
2319
+ }
2320
+ if ((match = matchers.hex3.exec(color))) {
2321
+ return {
2322
+ r: parseIntFromHex(match[1] + '' + match[1]),
2323
+ g: parseIntFromHex(match[2] + '' + match[2]),
2324
+ b: parseIntFromHex(match[3] + '' + match[3]),
2325
+ format: named ? "name" : "hex"
2326
+ };
1996
2327
  }
1997
2328
 
1998
- // Expose tinycolor to window, does not need to run in non-browser context.
1999
- window.tinycolor = tinycolor;
2329
+ return false;
2330
+ }
2000
2331
 
2332
+ window.tinycolor = tinycolor;
2001
2333
  })();
2002
2334
 
2003
-
2004
2335
  $(function () {
2005
2336
  if ($.fn.spectrum.load) {
2006
2337
  $.fn.spectrum.processNativeColorInputs();
2007
2338
  }
2008
2339
  });
2009
2340
 
2010
- })(window, jQuery);
2341
+ });