diff --git a/vendor-overwrites/colorpicker/LICENSE b/vendor-overwrites/colorpicker/LICENSE new file mode 100644 index 00000000..1ea38875 --- /dev/null +++ b/vendor-overwrites/colorpicker/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 jinho park (cyberuls@gmail.com, easylogic) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor-overwrites/colorpicker/colorpicker.css b/vendor-overwrites/colorpicker/colorpicker.css new file mode 100644 index 00000000..f80b45c2 --- /dev/null +++ b/vendor-overwrites/colorpicker/colorpicker.css @@ -0,0 +1,310 @@ + +/* codemirror colorview */ + +.codemirror-colorview { + border : 1px solid #8e8e8e; + position: relative; + display : inline-block; + box-sizing : border-box; + margin : 0px 2px; + width : 10px; + height : 10px; + cursor: pointer; + background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAJElEQVQYV2NctWrVfwYkEBYWxojMZ6SDAmT7QGx0K1EcRBsFAADeG/3M/HteAAAAAElFTkSuQmCC"); + background-repeat: repeat; +} + +.codemirror-colorview .codemirror-colorview-background { + content: ""; + position: absolute; + left:0px; + right:0px; + bottom:0px; + top:0px; +} + +.codemirror-colorview:hover { + border-color: #494949; +} + + +/* codemirror-colorpicker */ + +.codemirror-colorpicker { + position: relative; + width: 226px; + z-index: 1000; +} +.codemirror-colorpicker > .color { + position: relative; + height: 120px; + overflow: hidden; + cursor: pointer; +} +.codemirror-colorpicker > .color > .saturation { + position: relative; + width: 100%; + height: 100%; +} +.codemirror-colorpicker > .color > .saturation > .value { + position: relative; + width: 100%; + height: 100%; +} +.codemirror-colorpicker > .color > .saturation > .value > .drag-pointer { + position: absolute; + width: 10px; + height: 10px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + left: -5px; + top: -5px; +} +.codemirror-colorpicker > .control { + position: relative; + padding: 18px 0px 14px 0px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; +} +.codemirror-colorpicker > .control > .color, +.codemirror-colorpicker > .control > .empty { + position: absolute; + left: 11px; + top: 24px; + width: 30px; + height: 30px; + -webkit-border-radius: 50%; + -moz-border-radius: 50%; + border-radius: 50%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.codemirror-colorpicker > .control > .hue { + position: relative; + padding: 6px 12px; + margin: 0px 0px 0px 45px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; +} +.codemirror-colorpicker > .control > .hue > .hue-container { + position: relative; + width: 100%; + height: 10px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.codemirror-colorpicker > .control > .opacity { + position: relative; + padding: 3px 12px; + margin: 0px 0px 0px 45px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + cursor: pointer; +} +.codemirror-colorpicker > .control > .opacity > .opacity-container { + position: relative; + width: 100%; + height: 10px; + z-index: 2; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.codemirror-colorpicker > .control .drag-bar, +.codemirror-colorpicker > .control .drag-bar2 { + position: absolute; + cursor: pointer; + top: 50% !important; + margin-top: -7px !important; + left: -3px; + width: 12px; + height: 12px; + -webkit-border-radius: 50px; + -moz-border-radius: 50px; + border-radius: 50px; +} +.codemirror-colorpicker > .information { + position: relative; + -webkit-box-sizing: padding-box; + -moz-box-sizing: padding-box; + box-sizing: padding-box; +} + +.codemirror-colorpicker > .information.hex > .information-item.hex { + display: flex; +} + +.codemirror-colorpicker > .information.rgb > .information-item.rgb { + display: flex; +} + +.codemirror-colorpicker > .information.hsl > .information-item.hsl { + display: flex; +} + +.codemirror-colorpicker > .information > .information-item { + display:none; + position: relative; + padding: 0px 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + margin-right:40px; +} + +.codemirror-colorpicker > .information > .information-change { + position:absolute; + display:block; + width:40px; + top:0px; + right:0px; + bottom:0px; +} + +.codemirror-colorpicker > .information > .information-change > .format-change-button { + width:100%; + height:100%; + background:transparent; + border:0px; + cursor:pointer; + outline:none; +} + +.codemirror-colorpicker > .information > .information-item > .input-field { + display:block; + flex:1; + padding: 5px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.codemirror-colorpicker > .information > .information-item > .input-field > input { + text-align: center; + width:100%; + padding:3px 5px; + font-size:11px; + color: #333; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + -o-user-select: text; + user-select: text; + border: 1px solid #cbcbcb; +} + +.codemirror-colorpicker > .information > .information-item > .input-field > .title { + text-align:center; + font-size:12px; + color:#a9a9a9; +} + +.codemirror-colorpicker > .information > input { + position: absolute; + font-size: 10px; + height: 20px; + bottom: 20px; + padding: 0 0 0 2px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + -o-user-select: text; + user-select: text; +} + + +.codemirror-colorpicker { + border: 1px solid #ececec; + background-color: #fff; + -webkit-box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.12); + -moz-box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.12); + box-shadow: 0 0px 10px 0px rgba(0, 0, 0, 0.12); +} +.codemirror-colorpicker > .color > .saturation { + background-color: rgba(204, 154, 129, 0); + background-image: -moz-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); + background-image: -webkit-gradient(linear, 0 0, 100% 0, from(#FFF), to(rgba(204, 154, 129, 0))); + background-image: -webkit-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); + background-image: -o-linear-gradient(left, #FFF, rgba(204, 154, 129, 0)); + background-image: linear-gradient(to right, #FFF, rgba(204, 154, 129, 0)); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#00cc9a81', GradientType=1); +} +.codemirror-colorpicker > .color > .saturation > .value { + background-image: -webkit-gradient(linear, 0 100%, 0 0, from(#000000), to(rgba(204, 154, 129, 0))); + background-image: -webkit-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); + background-image: -moz-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); + background-image: -o-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); + background-image: -ms-linear-gradient(bottom, #000000, rgba(204, 154, 129, 0)); + background-image: linear-gradient(to top, #000000, rgba(204, 154, 129, 0)); +} +.codemirror-colorpicker > .color > .saturation > .value > .drag-pointer { + border: 1px solid #fff; + -webkit-box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.05); + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.05); +} +.codemirror-colorpicker > .control > .hue > .hue-container { + background: -moz-linear-gradient(left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: -ms-linear-gradient(left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: -o-linear-gradient(left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: -webkit-gradient(linear, left top, right top, from(#ff0000), color-stop(0.17, #ffff00), color-stop(0.33, #00ff00), color-stop(0.5, #00ffff), color-stop(0.67, #0000ff), color-stop(0.83, #ff00ff), to(#ff0000)); + background: -webkit-linear-gradient(left, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); + background: linear-gradient(to right, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); +} +.codemirror-colorpicker > .control > .opacity > .opacity-container > .color-bar { + position:absolute; + display:block; + content:""; + left:0px; + right:0px; + bottom:0px; + top:0px; + background: -moz-linear-gradient(left, rgba(232, 232, 232, 0), rgba(232, 232, 232, 1)); + background: -ms-linear-gradient(left, rgba(232, 232, 232, 0), rgba(232, 232, 232, 1)); + background: -o-linear-gradient(left, rgba(232, 232, 232, 0), rgba(232, 232, 232, 1)); + background: -webkit-gradient(linear, left top, right top, from(rgba(232, 232, 232, 0)), to(rgba(232, 232, 232, 1))); + background: -webkit-linear-gradient(left, rgba(232, 232, 232, 0), rgba(232, 232, 232, 1)); + background: linear-gradient(to right, rgba(232, 232, 232, 0) , rgba(232, 232, 232, 1) ); +} +.codemirror-colorpicker > .control > .opacity > .opacity-container { + background-image : url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAJElEQVQYV2NctWrVfwYkEBYWxojMZ6SDAmT7QGx0K1EcRBsFAADeG/3M/HteAAAAAElFTkSuQmCC"); + background-repeat: repeat; +} + +.codemirror-colorpicker > .control > .empty { + background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAJElEQVQYV2NctWrVfwYkEBYWxojMZ6SDAmT7QGx0K1EcRBsFAADeG/3M/HteAAAAAElFTkSuQmCC") repeat; +} +.codemirror-colorpicker > .control .drag-bar, +.codemirror-colorpicker > .control .drag-bar2 { + border: 1px solid rgba(0, 0, 0, 0.5); + -webkit-box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1); + box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1); + background-color: #FFFFFF; +} +.codemirror-colorpicker > .information { + /*border-top: 1px solid #e8e8e8;*/ +} +.codemirror-colorpicker > .information > .title { + color: #a3a3a3; +} +.codemirror-colorpicker > .information > .input { + color: #333; +} \ No newline at end of file diff --git a/vendor-overwrites/colorpicker/colorpicker.js b/vendor-overwrites/colorpicker/colorpicker.js new file mode 100644 index 00000000..25fc8741 --- /dev/null +++ b/vendor-overwrites/colorpicker/colorpicker.js @@ -0,0 +1,1369 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["codemirror" ], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + + CodeMirror.defineExtension("colorpicker", function () { + + var cm = this; + + var color = { + + trim : function (str) { + return str.replace(/^\s+|\s+$/g, ''); + }, + + /** + * @method format + * + * convert color to format string + * + * // hex + * color.format({ r : 255, g : 255, b : 255 }, 'hex') // #FFFFFF + * + * // rgb + * color.format({ r : 255, g : 255, b : 255 }, 'rgb') // rgba(255, 255, 255, 0.5); + * + * // rgba + * color.format({ r : 255, g : 255, b : 255, a : 0.5 }, 'rgb') // rgba(255, 255, 255, 0.5); + * + * @param {Object} obj obj has r, g, b and a attributes + * @param {"hex"/"rgb"} type format string type + * @returns {*} + */ + format : function(obj, type) { + if (type == 'hex') { + var r = obj.r.toString(16); + if (obj.r < 16) r = "0" + r; + + var g = obj.g.toString(16); + if (obj.g < 16) g = "0" + g; + + var b = obj.b.toString(16); + if (obj.b < 16) b = "0" + b; + + return "#" + [r, g, b].join(""); + } else if (type == 'rgb') { + if (typeof obj.a == 'undefined') { + return "rgb(" + [obj.r, obj.g, obj.b].join(",") + ")"; + } else { + return "rgba(" + [obj.r, obj.g, obj.b, obj.a].join(",") + ")"; + } + } else if (type == 'hsl') { + if (typeof obj.a == 'undefined') { + return "hsl(" + [obj.h, obj.s + '%', obj.l + '%'].join(",") + ")"; + } else { + return "hsla(" + [obj.h, obj.s + '%', obj.l + '%', obj.a].join(",") + ")"; + } + } + + return obj; + }, + + /** + * @method rgb + * + * parse string to rgb color + * + * color.rgb("#FF0000") === { r : 255, g : 0, b : 0 } + * + * color.rgb("rgb(255, 0, 0)") == { r : 255, g : 0, b : } + * + * @param {String} str color string + * @returns {Object} rgb object + */ + parse : function (str) { + if (typeof str == 'string') { + if (str.indexOf("rgb(") > -1) { + var arr = str.replace("rgb(", "").replace(")","").split(","); + + for(var i = 0, len = arr.length; i < len; i++) { + arr[i] = parseInt(color.trim(arr[i]), 10); + } + + return { type : 'rgb', r : arr[0], g : arr[1], b : arr[2], a : 1 }; + } else if (str.indexOf("rgba(") > -1) { + var arr = str.replace("rgba(", "").replace(")", "").split(","); + + for (var i = 0, len = arr.length; i < len; i++) { + + if (len - 1 == i) { + arr[i] = parseFloat(color.trim(arr[i])); + } else { + arr[i] = parseInt(color.trim(arr[i]), 10); + } + } + + return {type: 'rgb', r: arr[0], g: arr[1], b: arr[2], a: arr[3]}; + } else if (str.indexOf("hsl(") > -1) { + var arr = str.replace("hsl(", "").replace(")","").split(","); + + for(var i = 0, len = arr.length; i < len; i++) { + arr[i] = parseInt(color.trim(arr[i]), 10); + } + + var obj = { type : 'hsl', h : arr[0], s : arr[1], l : arr[2], a : 1 }; + + var temp = color.HSLtoRGB(obj.h, obj.s, obj.l); + + obj.r = temp.r; + obj.g = temp.g; + obj.b = temp.b; + + return obj; + } else if (str.indexOf("hsla(") > -1) { + var arr = str.replace("hsla(", "").replace(")", "").split(","); + + for (var i = 0, len = arr.length; i < len; i++) { + + if (len - 1 == i) { + arr[i] = parseFloat(color.trim(arr[i])); + } else { + arr[i] = parseInt(color.trim(arr[i]), 10); + } + } + + var obj = {type: 'hsl', h: arr[0], s: arr[1], l: arr[2], a: arr[3]}; + + var temp = color.HSLtoRGB(obj.h, obj.s, obj.l); + + obj.r = temp.r; + obj.g = temp.g; + obj.b = temp.b; + + return obj; + } else if (str.indexOf("#") == 0) { + + str = str.replace("#", ""); + + var arr = []; + if (str.length == 3) { + for(var i = 0, len = str.length; i < len; i++) { + var char = str.substr(i, 1); + arr.push(parseInt(char+char, 16)); + } + } else { + for(var i = 0, len = str.length; i < len; i+=2) { + arr.push(parseInt(str.substr(i, 2), 16)); + } + } + + return { type : 'hex', r : arr[0], g : arr[1], b : arr[2], a : 1 }; + } + } + + return str; + + }, + + /** + * @method HSVtoRGB + * + * convert hsv to rgb + * + * color.HSVtoRGB(0,0,1) === #FFFFF === { r : 255, g : 0, b : 0 } + * + * @param {Number} H hue color number (min : 0, max : 360) + * @param {Number} S Saturation number (min : 0, max : 1) + * @param {Number} V Value number (min : 0, max : 1 ) + * @returns {Object} + */ + HSVtoRGB : function (H, S, V) { + + if (H == 360) { + H = 0; + } + + var C = S * V; + var X = C * (1 - Math.abs((H/60) % 2 -1) ); + var m = V - C; + + var temp = []; + + if (0 <= H && H < 60) { temp = [C, X, 0]; } + else if (60 <= H && H < 120) { temp = [X, C, 0]; } + else if (120 <= H && H < 180) { temp = [0, C, X]; } + else if (180 <= H && H < 240) { temp = [0, X, C]; } + else if (240 <= H && H < 300) { temp = [X, 0, C]; } + else if (300 <= H && H < 360) { temp = [C, 0, X]; } + + return { + r : Math.ceil((temp[0] + m) * 255), + g : Math.ceil((temp[1] + m) * 255), + b : Math.ceil((temp[2] + m) * 255) + }; + }, + + /** + * @method RGBtoHSV + * + * convert rgb to hsv + * + * color.RGBtoHSV(0, 0, 255) === { h : 240, s : 1, v : 1 } === '#FFFF00' + * + * @param {Number} R red color value + * @param {Number} G green color value + * @param {Number} B blue color value + * @return {Object} hsv color code + */ + RGBtoHSV : function (R, G, B) { + + var R1 = R / 255; + var G1 = G / 255; + var B1 = B / 255; + + var MaxC = Math.max(R1, G1, B1); + var MinC = Math.min(R1, G1, B1); + + var DeltaC = MaxC - MinC; + + var H = 0; + + if (DeltaC == 0) { H = 0; } + else if (MaxC == R1) { + H = 60 * (( (G1 - B1) / DeltaC) % 6); + } else if (MaxC == G1) { + H = 60 * (( (B1 - R1) / DeltaC) + 2); + } else if (MaxC == B1) { + H = 60 * (( (R1 - G1) / DeltaC) + 4); + } + + if (H < 0) { + H = 360 + H; + } + + var S = 0; + + if (MaxC == 0) S = 0; + else S = DeltaC / MaxC; + + var V = MaxC; + + return { h : H, s : S, v : V }; + }, + + RGBtoHSL : function (r, g, b) { + r /= 255, g /= 255, b /= 255; + var max = Math.max(r, g, b), min = Math.min(r, g, b); + var h, s, l = (max + min) / 2; + + if(max == min){ + h = s = 0; // achromatic + }else{ + var d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch(max){ + case r: h = (g - b) / d + (g < b ? 6 : 0); break; + case g: h = (b - r) / d + 2; break; + case b: h = (r - g) / d + 4; break; + } + h /= 6; + } + + return { h : Math.round(h * 360) , s : Math.round(s * 100), l : Math.round(l * 100)}; + }, + + HUEtoRGB : function (p, q, t) { + if(t < 0) t += 1; + if(t > 1) t -= 1; + if(t < 1/6) return p + (q - p) * 6 * t; + if(t < 1/2) return q; + if(t < 2/3) return p + (q - p) * (2/3 - t) * 6; + return p; + }, + + HSLtoRGB : function (h, s, l) { + var r, g, b; + + h /= 360; + s /= 100; + l /= 100; + + if(s == 0){ + r = g = b = l; // achromatic + }else{ + var q = l < 0.5 ? l * (1 + s) : l + s - l * s; + var p = 2 * l - q; + r = this.HUEtoRGB(p, q, h + 1/3); + g = this.HUEtoRGB(p, q, h); + b = this.HUEtoRGB(p, q, h - 1/3); + } + + return { r : r * 255, g : g * 255, b : b * 255 }; + } + }; + + var hue_color = [ + { rgb : '#ff0000', start : .0 }, + { rgb : '#ffff00', start : .17 }, + { rgb : '#00ff00', start : .33 }, + { rgb : '#00ffff', start : .50 }, + { rgb : '#0000ff', start : .67 }, + { rgb : '#ff00ff', start : .83 }, + { rgb : '#ff0000', start : 1 } + ]; + + var $body, $root, $hue, $color, $value, $saturation, $drag_pointer, $drag_bar, + $control, $controlPattern, $controlColor, $hueContainer, $opacity, $opacityContainer, $opacityColorBar, $formatChangeButton, + $opacity_drag_bar, $information, $informationChange; + + var currentA, currentH, currentS, currentV; + var $hexCode; + var $rgb_r, $rgb_g, $rgb_b, $rgb_a; + var $hsl_h, $hsl_s, $hsl_l, $hsl_a; + var cssPrefix = getCssValuePrefix(); + + var colorpickerCallback = function () {}; + var counter = 0; + var cached = {}; + var isColorPickerShow = false; + var isShortCut = false; + var hideDelay = 2000; + + function dom(tag, className, attr) { + + if (typeof tag != 'string') { + this.el = tag; + } else { + + var el = document.createElement(tag); + + this.uniqId = counter++; + + el.className = className; + + attr = attr || {}; + + for(var k in attr) { + el.setAttribute(k, attr[k]); + } + + this.el = el; + } + } + + dom.prototype.closest = function (cls) { + + var temp = this; + var checkCls = false; + + while(!(checkCls = temp.hasClass(cls))) { + if (temp.el.parentNode) { + temp = new dom(temp.el.parentNode); + } else { + return null; + } + } + + if (checkCls) { + return temp; + } + + return null; + } + + dom.prototype.removeClass = function (cls) { + this.el.className = color.trim((" " + this.el.className + " ").replace(' ' + cls + ' ', ' ')); + } + + dom.prototype.hasClass = function (cls) { + if (!this.el.className) + { + return false; + } else { + var newClass = ' ' + this.el.className + ' '; + return newClass.indexOf(' ' + cls + ' ') > -1; + } + } + + dom.prototype.addClass = function (cls) { + if (!this.hasClass(cls)) { + this.el.className = this.el.className + " " + cls; + } + + } + + dom.prototype.html = function (html) { + this.el.innerHTML = html; + + return this; + } + + dom.prototype.empty = function () { + return this.html(''); + } + + dom.prototype.append = function (el) { + + if (typeof el == 'string') { + this.el.appendChild(document.createTextNode(el)); + } else { + this.el.appendChild(el.el || el); + } + + return this; + } + + dom.prototype.appendTo = function (target) { + var t = target.el ? target.el : target; + + t.appendChild(this.el); + + return this; + } + + dom.prototype.remove = function () { + if (this.el.parentNode) { + this.el.parentNode.removeChild(this.el); + } + + return this; + } + + dom.prototype.text = function () { + return this.el.textContent; + } + + dom.prototype.css = function (key, value) { + if (arguments.length == 2) { + this.el.style[key] = value; + } else if (arguments.length == 1) { + + if (typeof key == 'string') { + return getComputedStyle(this.el)[key]; + } else { + var keys = key || {}; + for(var k in keys) { + this.el.style[k] = keys[k]; + } + } + + } + + return this; + } + + dom.prototype.offset = function () { + var rect = this.el.getBoundingClientRect(); + + return { + top: rect.top + document.body.scrollTop, + left: rect.left + document.body.scrollLeft + }; + } + + dom.prototype.position = function () { + return { + top: parseFloat(this.el.style.top), + left: parseFloat(this.el.style.left) + }; + } + + dom.prototype.width = function () { + return this.el.offsetWidth; + } + + dom.prototype.height = function () { + return this.el.offsetHeight; + } + + dom.prototype.dataKey = function (key) { + return this.uniqId + '.' + key; + } + + dom.prototype.data = function (key, value) { + if (arguments.length == 2) { + cached[this.dataKey(key)] = value; + } else if (arguments.length == 1) { + return cached[this.dataKey(key)]; + } else { + var keys = Object.keys(cached); + + var uniqId = this.uniqId + "."; + return keys.filter(function (key) { + if (key.indexOf(uniqId) == 0) { + return true; + } + + return false; + }).map(function (value) { + return cached[value]; + }) + } + + return this; + } + + dom.prototype.val = function (value) { + if (arguments.length == 0) { + return this.el.value; + } else if (arguments.length == 1) { + this.el.value = value; + } + + return this; + } + + dom.prototype.int = function () { + return parseInt(this.val(), 10); + } + + dom.prototype.show = function () { + return this.css('display', 'block'); + } + + dom.prototype.hide = function () { + return this.css('display', 'none'); + } + + function setRGBInput(r, g, b) { + $rgb_r.val(r); + $rgb_g.val(g); + $rgb_b.val(b); + $rgb_a.val(currentA); + } + + function setHSLInput(h, s, l) { + $hsl_h.val(h); + $hsl_s.val(s + '%'); + $hsl_l.val(l + '%'); + $hsl_a.val(currentA); + } + + function getHexFormat() { + return color.format({ + r : $rgb_r.int(), + g : $rgb_g.int(), + b : $rgb_b.int() + }, 'hex'); + } + + function convertRGB() { + return color.HSVtoRGB(currentH, currentS, currentV); + } + + function convertHEX() { + return color.format(convertRGB(), 'hex'); + } + + function convertHSL() { + var rgb = color.HSVtoRGB(currentH, currentS, currentV); + return color.RGBtoHSL(rgb.r, rgb.g, rgb.b); + } + + function getFormattedColor (format) { + format = format || 'hex'; + + if (format == 'rgb') { + var rgb = convertRGB(); + rgb.a = currentA == 1 ? undefined : currentA; + return color.format(rgb, 'rgb'); + } else if (format == 'hsl') { + var hsl = convertHSL(); + hsl.a = currentA == 1 ? undefined : currentA; + return color.format(hsl, 'hsl'); + } else { + var rgb = convertRGB(); + return color.format(rgb, 'hex'); + } + } + + function setControlColor (color) { + $controlColor.css('background-color', color); + } + + function setInputColor() { + + var format = $information.data('format') || 'hex'; + + var rgb = null; + if (format == 'hex') { + $hexCode.val(convertHEX()); + } else if (format == 'rgb') { + var rgb = convertRGB(); + setRGBInput(rgb.r, rgb.g, rgb.b); + } else if (format == 'hsl') { + var hsl = convertHSL(); + setHSLInput(hsl.h, hsl.s, hsl.l); + } + + // set background + setControlColor(getFormattedColor('rgb')); + + var rgb = convertRGB(); + var colorString = color.format(rgb, 'rgb'); + setOpacityColorBar(colorString); + + if (typeof colorpickerCallback == 'function') { + + if (!isNaN(currentA)) { + colorpickerCallback(getFormattedColor(format)); + } + + } + } + + function setMainColor(e) { + e.preventDefault(); + var pos = $root.position(); // position for screen + var w = $color.width(); + var h = $color.height(); + + var x = e.clientX - pos.left; + var y = e.clientY - pos.top; + + if (x < 0) x = 0; + else if (x > w) x = w; + + if (y < 0) y = 0; + else if (y > h) y = h; + + $drag_pointer.css({ + left: (x - 5) + 'px', + top: (y - 5) + 'px' + }); + + $drag_pointer.data('pos', { x: x, y : y}); + + caculateHSV() + setInputColor(); + } + + function scale (startColor, endColor, t) { + var obj = { + r : parseInt(startColor.r + (endColor.r - startColor.r) * t, 10) , + g : parseInt(startColor.g + (endColor.g - startColor.g) * t, 10), + b : parseInt(startColor.b + (endColor.b - startColor.b) * t, 10) + }; + + return color.format(obj, 'hex'); + + } + + function checkHueColor(p) { + var startColor, endColor; + + for(var i = 0; i < hue_color.length;i++) { + if (hue_color[i].start >= p) { + startColor = hue_color[i-1]; + endColor = hue_color[i]; + break; + } + } + + if (startColor && endColor) { + return scale(startColor, endColor, (p - startColor.start)/(endColor.start - startColor.start)); + } + + return hue_color[0].rgb; + } + + function setBackgroundColor (color) { + $color.css("background-color", color); + } + + function setCurrentH (h) { + currentH = h; + } + + function setHueColor(e) { + var min = $hueContainer.offset().left; + var max = min + $hueContainer.width(); + var current = e ? pos(e).clientX : min + (max - min) * (currentH / 360); + + var dist; + if (current < min) { + dist = 0; + } else if (current > max) { + dist = 100; + } else { + dist = (current - min) / (max - min) * 100; + } + + var x = ($hueContainer.width() * (dist/100)); + + $drag_bar.css({ + left: (x -Math.ceil($drag_bar.width()/2)) + 'px' + }); + + $drag_bar.data('pos', { x : x}); + + var hueColor = checkHueColor(dist/100); + + setBackgroundColor(hueColor); + setCurrentH((dist/100) * 360); + setInputColor(); + } + + function getCssValuePrefix() + { + var rtrnVal = '';//default to standard syntax + var prefixes = ['', '-o-', '-ms-', '-moz-', '-webkit-']; + + // Create a temporary DOM object for testing + var dom = document.createElement('div'); + + for (var i = 0; i < prefixes.length; i++) + { + // Attempt to set the style + dom.style.background = prefixes[i] + 'linear-gradient(#000000, #ffffff)'; + + // Detect if the style was successfully set + if (dom.style.background) + { + rtrnVal = prefixes[i]; + } + } + + dom = null; + delete dom; + + return rtrnVal; + } + + function setOpacityColorBar(hueColor) { + var rgb = color.parse(hueColor); + + rgb.a = 0; + var start = color.format(rgb, 'rgb'); + + rgb.a = 1; + var end = color.format(rgb, 'rgb'); + + var prefix = cssPrefix; + $opacityColorBar.css('background', 'linear-gradient(to right, ' + start + ', ' + end + ')'); + } + + function setOpacity(e) { + var min = $opacityContainer.offset().left; + var max = min + $opacityContainer.width(); + var current = pos(e).clientX; + var dist; + + if (current < min) { + dist = 0; + } else if (current > max) { + dist = 100; + } else { + dist = (current - min) / (max - min) * 100; + } + + var x = ($opacityContainer.width() * (dist/100)); + + $opacity_drag_bar.css({ + left: (x -Math.ceil($opacity_drag_bar.width()/2)) + 'px' + }); + + $opacity_drag_bar.data('pos', { x : x }); + + caculateOpacity(); + currentFormat(); + setInputColor(); + } + + function caculateOpacity() { + var opacityPos = $opacity_drag_bar.data('pos') || { x : 0 }; + var a = Math.round((opacityPos.x / $opacityContainer.width()) * 100) / 100; + + currentA = isNaN(a) ? 1 : a; + } + + function caculateHSV() { + var pos = $drag_pointer.data('pos') || { x : 0, y : 0 }; + var huePos = $drag_bar.data('pos') || { x : 0 }; + + var width = $color.width(); + var height = $color.height(); + + var h = (huePos.x / $hueContainer.width()) * 360; + var s = (pos.x / width); + var v = ((height - pos.y) / height); + + if (width == 0) { + h = 0; + s = 0; + v = 0; + } + + currentH = h; + currentS = s; + currentV = v; + } + + function pos(e) { + if (e.touches && e.touches[0]) { + return e.touches[0]; + } + + return e; + } + + function checkNumberKey(e) { + var code = e.which, + isExcept = false; + + if(code == 37 || code == 39 || code == 8 || code == 46 || code == 9) + isExcept = true; + + if(!isExcept && (code < 48 || code > 57)) + return false; + + return true; + } + + function setRGBtoHexColor(e) { + var r = $rgb_r.val(), + g = $rgb_g.val(), + b = $rgb_b.val(); + + if(r == "" || g == "" || b == "") return; + + if(parseInt(r) > 255) $rgb_r.val(255); + else $rgb_r.val(parseInt(r)); + + if(parseInt(g) > 255) $rgb_g.val(255); + else $rgb_g.val(parseInt(g)); + + if(parseInt(b) > 255) $rgb_b.val(255); + else $rgb_b.val(parseInt(b)); + + initColor(getHexFormat()); + } + + function setColorUI() { + var x = $color.width() * currentS, y = $color.height() * ( 1 - currentV ); + + $drag_pointer.css({ + left : (x - 5) + "px", + top : (y - 5) + "px" + }); + + $drag_pointer.data('pos', { x : x, y : y }); + + var hueX = $hueContainer.width() * (currentH / 360); + + $drag_bar.css({ + left : (hueX - 7.5) + 'px' + }); + + $drag_bar.data('pos', { x : hueX }); + + var opacityX = $opacityContainer.width() * (currentA || 0); + + $opacity_drag_bar.css({ + left : (opacityX - 7.5) + 'px' + }); + + $opacity_drag_bar.data('pos', { x : opacityX }); + } + + function setCurrentHSV (h, s, v, a) { + currentA = a; + currentH = h; + currentS = s; + currentV = v; + } + + function setCurrentFormat (format) { + $information.data('format', format); + initFormat(); + } + + + + function initColor(newColor) { + var c = newColor || "#FF0000", colorObj = color.parse(c); + + setCurrentFormat(colorObj.type); + setBackgroundColor(c); + + var hsv = color.RGBtoHSV(colorObj.r, colorObj.g, colorObj.b); + + setCurrentHSV(hsv.h, hsv.s, hsv.v, colorObj.a); + setColorUI(); + setHueColor(); + setInputColor(); + } + + function addEvent (dom, eventName, callback) { + dom.addEventListener(eventName, callback); + } + + function removeEvent(dom, eventName, callback) { + dom.removeEventListener(eventName, callback); + } + + function EventColorMouseDown(e) { + $color.data('isDown', true); + setMainColor(e); + } + + function EventColorMouseUp(e) { + $color.data('isDown', false); + } + + function EventDragBarMouseDown (e) { + e.preventDefault(); + $hue.data('isDown', true); + } + + function EventOpacityDragBarMouseDown(e) { + e.preventDefault(); + $opacity.data('isDown', true); + } + + function EventHueMouseDown (e) { + $hue.data('isDown', true); + setHueColor(e); + } + + function EventOpacityMouseDown (e) { + $opacity.data('isDown', true); + setOpacity(e); + } + + function EventHexCodeKeyDown(e) { + if(e.which < 65 || e.which > 70) { + return checkNumberKey(e); + } + } + + function EventHexCodeKeyUp (e) { + var code = $hexCode.val(); + + if(code.charAt(0) == '#' && code.length == 7) { + initColor(code); + } + } + + function EventFormatChangeClick(e) { + nextFormat(); + } + + function initEvent() { + addEvent($color.el, 'mousedown', EventColorMouseDown); + addEvent($color.el, 'mouseup', EventColorMouseUp); + addEvent($drag_bar.el, 'mousedown', EventDragBarMouseDown); + addEvent($opacity_drag_bar.el, 'mousedown', EventOpacityDragBarMouseDown); + addEvent($hueContainer.el, 'mousedown', EventHueMouseDown); + addEvent($opacityContainer.el, 'mousedown', EventOpacityMouseDown); + addEvent($hexCode.el, 'keydown', EventHexCodeKeyDown); + addEvent($hexCode.el, 'keyup', EventHexCodeKeyUp); + + addEvent($rgb_r.el, 'keydown', checkNumberKey); + addEvent($rgb_r.el, 'keyup', setRGBtoHexColor); + addEvent($rgb_g.el, 'keydown', checkNumberKey); + addEvent($rgb_g.el, 'keyup', setRGBtoHexColor); + addEvent($rgb_b.el, 'keydown', checkNumberKey); + addEvent($rgb_b.el, 'keyup', setRGBtoHexColor); + + addEvent(document, 'mouseup', EventDocumentMouseUp); + addEvent(document, 'mousemove', EventDocumentMouseMove); + + addEvent($formatChangeButton.el, 'click', EventFormatChangeClick) + } + + function checkColorPickerClass(el) { + var hasColorView = new dom(el).closest('codemirror-colorview'); + var hasColorPicker = new dom(el).closest('codemirror-colorpicker'); + var hasCodeMirror = new dom(el).closest('CodeMirror'); + var IsInHtml = el.nodeName == 'HTML'; + + return !!(hasColorPicker || hasColorView || hasCodeMirror); + } + + function checkInHtml (el) { + var IsInHtml = el.nodeName == 'HTML'; + + return IsInHtml; + } + + function EventDocumentMouseUp (e) { + $color.data('isDown', false); + $hue.data('isDown', false); + $opacity.data('isDown', false); + + // when color picker clicked in outside + if (checkInHtml(e.target)) { + //setHideDelay(hideDelay); + } else if (checkColorPickerClass(e.target) == false ) { + hide(); + } + + } + + function EventDocumentMouseMove(e) { + if ($color.data('isDown')) { + setMainColor(e); + } + + if ($hue.data('isDown')) { + setHueColor(e); + } + + if ($opacity.data('isDown')) { + setOpacity(e); + } + } + + function destroy() { + removeEvent($color.el, 'mousedown', EventColorMouseDown); + removeEvent($color.el, 'mouseup', EventColorMouseUp); + removeEvent($drag_bar.el, 'mousedown', EventDragBarMouseDown); + removeEvent($opacity_drag_bar.el, 'mousedown', EventOpacityDragBarMouseDown); + removeEvent($hueContainer.el, 'mousedown', EventHueMouseDown); + removeEvent($opacityContainer.el, 'mousedown', EventOpacityMouseDown); + removeEvent($hexCode.el, 'keydown', EventHexCodeKeyDown); + removeEvent($hexCode.el, 'keyup', EventHexCodeKeyUp); + removeEvent($rgb_r.el, 'keydown', checkNumberKey); + removeEvent($rgb_r.el, 'keyup', setRGBtoHexColor); + removeEvent($rgb_g.el, 'keydown', checkNumberKey); + removeEvent($rgb_g.el, 'keyup', setRGBtoHexColor); + removeEvent($rgb_b.el, 'keydown', checkNumberKey); + removeEvent($rgb_b.el, 'keyup', setRGBtoHexColor); + removeEvent(document, 'mouseup', EventDocumentMouseUp); + removeEvent(document, 'mousemove', EventDocumentMouseMove); + removeEvent($formatChangeButton.el, 'click', EventFormatChangeClick); + + // remove color picker callback + colorpickerCallback = undefined; + } + + function currentFormat () { + var current_format = $information.data('format') || 'hex'; + if (currentA < 1 && current_format == 'hex' ) { + var next_format = 'rgb'; + $information.removeClass(current_format); + $information.addClass(next_format); + $information.data('format', next_format); + + setInputColor(); + } + } + + function initFormat () { + var current_format = $information.data('format') || 'hex'; + + $information.removeClass('hex'); + $information.removeClass('rgb'); + $information.removeClass('hsl'); + $information.addClass(current_format); + } + + function nextFormat() { + var current_format = $information.data('format') || 'hex'; + + var next_format = 'hex'; + if (current_format == 'hex') { + next_format = 'rgb'; + } else if (current_format == 'rgb') { + next_format = 'hsl'; + } else if (current_format == 'hsl') { + if (currentA == 1) { + next_format = 'hex'; + } else { + next_format = 'rgb'; + } + } + + $information.removeClass(current_format); + $information.addClass(next_format); + $information.data('format', next_format); + + setInputColor(); + } + + function makeInputField(type) { + var item = new dom('div', 'information-item '+ type); + + if (type == 'hex') { + var field = new dom('div', 'input-field hex'); + + $hexCode = new dom('input', 'input', { type : 'text' }); + + field.append($hexCode); + field.append(new dom('div', 'title').html('HEX')); + + item.append(field); + + } else if (type == 'rgb') { + var field = new dom('div', 'input-field rgb-r'); + $rgb_r = new dom('input', 'input', { type : 'text' }); + + field.append($rgb_r); + field.append(new dom('div', 'title').html('R')); + + item.append(field); + + field = new dom('div', 'input-field rgb-g'); + $rgb_g = new dom('input', 'input', { type : 'text' }); + + field.append($rgb_g); + field.append(new dom('div', 'title').html('G')); + + item.append(field); + + field = new dom('div', 'input-field rgb-b'); + $rgb_b = new dom('input', 'input', { type : 'text' }); + + field.append($rgb_b); + field.append(new dom('div', 'title').html('B')); + + item.append(field); + + // rgba + field = new dom('div', 'input-field rgb-a'); + $rgb_a = new dom('input', 'input', { type : 'text' }); + + field.append($rgb_a); + field.append(new dom('div', 'title').html('A')); + + item.append(field); + + } else if (type == 'hsl') { + var field = new dom('div', 'input-field hsl-h'); + $hsl_h = new dom('input', 'input', { type : 'text' }); + + field.append($hsl_h); + field.append(new dom('div', 'title').html('H')); + + item.append(field); + + field = new dom('div', 'input-field hsl-s'); + $hsl_s = new dom('input', 'input', { type : 'text' }); + + field.append($hsl_s); + field.append(new dom('div', 'title').html('S')); + + item.append(field); + + field = new dom('div', 'input-field hsl-l'); + $hsl_l = new dom('input', 'input', { type : 'text' }); + + field.append($hsl_l); + field.append(new dom('div', 'title').html('L')); + + item.append(field); + + // rgba + field = new dom('div', 'input-field hsl-a'); + $hsl_a = new dom('input', 'input', { type : 'text' }); + + field.append($hsl_a); + field.append(new dom('div', 'title').html('A')); + + item.append(field); + } + + return item; + } + + function init() { + $body = new dom(document.body); + + $root = new dom('div', 'codemirror-colorpicker'); + $color = new dom('div', 'color'); + $drag_pointer = new dom('div', 'drag-pointer' ); + $value = new dom( 'div', 'value' ); + $saturation = new dom('div', 'saturation' ); + + $control = new dom('div', 'control' ); + $controlPattern = new dom('div', 'empty' ); + $controlColor = new dom('div', 'color' ); + $hue = new dom('div', 'hue' ); + $hueContainer = new dom('div', 'hue-container' ); + $drag_bar = new dom('div', 'drag-bar' ); + $opacity = new dom('div', 'opacity' ); + $opacityContainer = new dom('div', 'opacity-container' ); + $opacityColorBar = new dom('div', 'color-bar' ); + + $opacity_drag_bar = new dom('div', 'drag-bar2' ); + + $information = new dom('div', 'information hex' ); + + $informationChange = new dom('div', 'information-change'); + + $formatChangeButton = new dom('button', 'format-change-button', { type : 'button'}).html('↔'); + $informationChange.append($formatChangeButton); + + + $information.append(makeInputField('hex')); + $information.append(makeInputField('rgb')); + $information.append(makeInputField('hsl')); + $information.append($informationChange); + + + $value.append($drag_pointer); + $saturation.append($value); + $color.append($saturation); + + $hueContainer.append($drag_bar); + $hue.append($hueContainer); + + $opacityContainer.append($opacityColorBar); + $opacityContainer.append($opacity_drag_bar); + $opacity.append($opacityContainer); + + $control.append($hue); + $control.append($opacity); + $control.append($controlPattern); + $control.append($controlColor); + + $root.append($color); + $root.append($control); + $root.append($information); + + initHueColors(); + //initEvent(); + initColor(); + }; + + function initHueColors () { + for(var i = 0, len = hue_color.length; i < len; i++) { + var hue = hue_color[i]; + + var obj = color.parse(hue.rgb); + + hue.r = obj.r; + hue.g = obj.g; + hue.b = obj.b; + } + } + + /** + * public methods + */ + function setColor(value) { + if(typeof(value) == "object") { + if(!value.r || !value.g || !value.b) + return; + + initColor(color.format(value, "hex")); + } else if(typeof(value) == "string") { + if(value.charAt(0) != "#") + return; + + initColor(value); + } + } + + function getColor(type) { + caculateHSV(); + var rgb = convertRGB(); + + if (type) { + return color.format(rgb, type); + } + + return rgb; + } + + function definePostion (opt) { + + var width = $root.width(); + var height = $root.height(); + + // set left position for color picker + var elementScreenLeft = opt.left - $body.el.scrollLeft ; + if (width + elementScreenLeft > window.innerWidth) { + elementScreenLeft -= (width + elementScreenLeft) - window.innerWidth; + } + if (elementScreenLeft < 0) { elementScreenLeft = 0; } + + // set top position for color picker + var elementScreenTop = opt.top - $body.el.scrollTop ; + if (height + elementScreenTop > window.innerHeight) { + elementScreenTop -= (height + elementScreenTop) - window.innerHeight; + } + if (elementScreenTop < 0) { elementScreenTop = 0; } + + // set position + $root.css({ + left : elementScreenLeft + 'px', + top : elementScreenTop + 'px' + }); + } + + function show (opt, color, callback) { + destroy(); + initEvent(); + $root.appendTo(document.body); + + $root.css({ + position: 'fixed', // color picker has fixed position + left : '-10000px', + top : '-10000px' + }); + + $root.show(); + + definePostion(opt); + + isColorPickerShow = true; + + isShortCut = opt.isShortCut || false; + + initColor(color); + + // define colorpicker callback + colorpickerCallback = function (colorString) { + callback(colorString); + } + + // define hide delay + hideDelay = opt.hideDelay || 2000; + if (hideDelay > 0) { + setHideDelay(hideDelay); + } + + } + + + var timerCloseColorPicker; + function setHideDelay (delayTime) { + delayTime = delayTime || 0; + removeEvent($root.el, 'mouseenter'); + removeEvent($root.el, 'mouseleave'); + + addEvent($root.el, 'mouseenter', function () { + clearTimeout(timerCloseColorPicker); + }); + + addEvent($root.el, 'mouseleave', function () { + clearTimeout(timerCloseColorPicker); + timerCloseColorPicker = setTimeout(hide, delayTime); + }); + + clearTimeout(timerCloseColorPicker); + timerCloseColorPicker = setTimeout(hide, delayTime); + } + + function hide () { + if (isColorPickerShow) { + destroy(); + $root.hide(); + $root.remove(); + isColorPickerShow = false; + } + + } + + init(); + + return { + isShortCut : function () { + return isShortCut; + }, + $root: $root, + show: show, + hide: hide, + setColor: setColor, + getColor: getColor + } + }) + +}); diff --git a/vendor-overwrites/colorpicker/colorview.js b/vendor-overwrites/colorpicker/colorview.js new file mode 100644 index 00000000..b53fec3e --- /dev/null +++ b/vendor-overwrites/colorpicker/colorview.js @@ -0,0 +1,434 @@ +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + "use strict"; + + // color names + var color_names={aliceblue:"rgb(240, 248, 255)",antiquewhite:"rgb(250, 235, 215)",aqua:"rgb(0, 255, 255)",aquamarine:"rgb(127, 255, 212)",azure:"rgb(240, 255, 255)",beige:"rgb(245, 245, 220)",bisque:"rgb(255, 228, 196)",black:"rgb(0, 0, 0)",blanchedalmond:"rgb(255, 235, 205)",blue:"rgb(0, 0, 255)",blueviolet:"rgb(138, 43, 226)",brown:"rgb(165, 42, 42)",burlywood:"rgb(222, 184, 135)",cadetblue:"rgb(95, 158, 160)",chartreuse:"rgb(127, 255, 0)",chocolate:"rgb(210, 105, 30)",coral:"rgb(255, 127, 80)",cornflowerblue:"rgb(100, 149, 237)",cornsilk:"rgb(255, 248, 220)",crimson:"rgb(237, 20, 61)",cyan:"rgb(0, 255, 255)",darkblue:"rgb(0, 0, 139)",darkcyan:"rgb(0, 139, 139)",darkgoldenrod:"rgb(184, 134, 11)",darkgray:"rgb(169, 169, 169)",darkgrey:"rgb(169, 169, 169)",darkgreen:"rgb(0, 100, 0)",darkkhaki:"rgb(189, 183, 107)",darkmagenta:"rgb(139, 0, 139)",darkolivegreen:"rgb(85, 107, 47)",darkorange:"rgb(255, 140, 0)",darkorchid:"rgb(153, 50, 204)",darkred:"rgb(139, 0, 0)",darksalmon:"rgb(233, 150, 122)",darkseagreen:"rgb(143, 188, 143)",darkslateblue:"rgb(72, 61, 139)",darkslategray:"rgb(47, 79, 79)",darkslategrey:"rgb(47, 79, 79)",darkturquoise:"rgb(0, 206, 209)",darkviolet:"rgb(148, 0, 211)",deeppink:"rgb(255, 20, 147)",deepskyblue:"rgb(0, 191, 255)",dimgray:"rgb(105, 105, 105)",dimgrey:"rgb(105, 105, 105)",dodgerblue:"rgb(30, 144, 255)",firebrick:"rgb(178, 34, 34)",floralwhite:"rgb(255, 250, 240)",forestgreen:"rgb(34, 139, 34)",fuchsia:"rgb(255, 0, 255)",gainsboro:"rgb(220, 220, 220)",ghostwhite:"rgb(248, 248, 255)",gold:"rgb(255, 215, 0)",goldenrod:"rgb(218, 165, 32)",gray:"rgb(128, 128, 128)",grey:"rgb(128, 128, 128)",green:"rgb(0, 128, 0)",greenyellow:"rgb(173, 255, 47)",honeydew:"rgb(240, 255, 240)",hotpink:"rgb(255, 105, 180)",indianred:"rgb(205, 92, 92)",indigo:"rgb(75, 0, 130)",ivory:"rgb(255, 255, 240)",khaki:"rgb(240, 230, 140)",lavender:"rgb(230, 230, 250)",lavenderblush:"rgb(255, 240, 245)",lawngreen:"rgb(124, 252, 0)",lemonchiffon:"rgb(255, 250, 205)",lightblue:"rgb(173, 216, 230)",lightcoral:"rgb(240, 128, 128)",lightcyan:"rgb(224, 255, 255)",lightgoldenrodyellow:"rgb(250, 250, 210)",lightgreen:"rgb(144, 238, 144)",lightgray:"rgb(211, 211, 211)",lightgrey:"rgb(211, 211, 211)",lightpink:"rgb(255, 182, 193)",lightsalmon:"rgb(255, 160, 122)",lightseagreen:"rgb(32, 178, 170)",lightskyblue:"rgb(135, 206, 250)",lightslategray:"rgb(119, 136, 153)",lightslategrey:"rgb(119, 136, 153)",lightsteelblue:"rgb(176, 196, 222)",lightyellow:"rgb(255, 255, 224)",lime:"rgb(0, 255, 0)",limegreen:"rgb(50, 205, 50)",linen:"rgb(250, 240, 230)",magenta:"rgb(255, 0, 255)",maroon:"rgb(128, 0, 0)",mediumaquamarine:"rgb(102, 205, 170)",mediumblue:"rgb(0, 0, 205)",mediumorchid:"rgb(186, 85, 211)",mediumpurple:"rgb(147, 112, 219)",mediumseagreen:"rgb(60, 179, 113)",mediumslateblue:"rgb(123, 104, 238)",mediumspringgreen:"rgb(0, 250, 154)",mediumturquoise:"rgb(72, 209, 204)",mediumvioletred:"rgb(199, 21, 133)",midnightblue:"rgb(25, 25, 112)",mintcream:"rgb(245, 255, 250)",mistyrose:"rgb(255, 228, 225)",moccasin:"rgb(255, 228, 181)",navajowhite:"rgb(255, 222, 173)",navy:"rgb(0, 0, 128)",oldlace:"rgb(253, 245, 230)",olive:"rgb(128, 128, 0)",olivedrab:"rgb(107, 142, 35)",orange:"rgb(255, 165, 0)",orangered:"rgb(255, 69, 0)",orchid:"rgb(218, 112, 214)",palegoldenrod:"rgb(238, 232, 170)",palegreen:"rgb(152, 251, 152)",paleturquoise:"rgb(175, 238, 238)",palevioletred:"rgb(219, 112, 147)",papayawhip:"rgb(255, 239, 213)",peachpuff:"rgb(255, 218, 185)",peru:"rgb(205, 133, 63)",pink:"rgb(255, 192, 203)",plum:"rgb(221, 160, 221)",powderblue:"rgb(176, 224, 230)",purple:"rgb(128, 0, 128)",rebeccapurple:"rgb(102, 51, 153)",red:"rgb(255, 0, 0)",rosybrown:"rgb(188, 143, 143)",royalblue:"rgb(65, 105, 225)",saddlebrown:"rgb(139, 69, 19)",salmon:"rgb(250, 128, 114)",sandybrown:"rgb(244, 164, 96)",seagreen:"rgb(46, 139, 87)",seashell:"rgb(255, 245, 238)",sienna:"rgb(160, 82, 45)",silver:"rgb(192, 192, 192)",skyblue:"rgb(135, 206, 235)",slateblue:"rgb(106, 90, 205)",slategray:"rgb(112, 128, 144)",slategrey:"rgb(112, 128, 144)",snow:"rgb(255, 250, 250)",springgreen:"rgb(0, 255, 127)",steelblue:"rgb(70, 130, 180)",tan:"rgb(210, 180, 140)",teal:"rgb(0, 128, 128)",thistle:"rgb(216, 191, 216)",tomato:"rgb(255, 99, 71)",turquoise:"rgb(64, 224, 208)",violet:"rgb(238, 130, 238)",wheat:"rgb(245, 222, 179)",white:"rgb(255, 255, 255)",whitesmoke:"rgb(245, 245, 245)",yellow:"rgb(255, 255, 0)",yellowgreen:"rgb(154, 205, 50)",transparent:"rgba(0, 0, 0, 0)"}; + + var colorpicker_class = 'codemirror-colorview'; + var colorpicker_background_class = 'codemirror-colorview-background'; + + // Excluded tokens do not show color views.. + var excluded_token = ['comment']; + + CodeMirror.defineOption("colorpicker", false, function (cm, val, old) { + + if (old && old != CodeMirror.Init) { + + if (cm.state.colorpicker) + { + cm.state.colorpicker.destroy(); + cm.state.colorpicker = null; + + } + // remove event listener + } + + if (val) + { + cm.state.colorpicker = new codemirror_colorpicker(cm, val); + } + }); + + function onChange(cm, evt) { + if (evt.origin == 'setValue') { // if content is changed by setValue method, it initialize markers + cm.state.colorpicker.close_color_picker(); + cm.state.colorpicker.init_color_update(); + cm.state.colorpicker.style_color_update(); + } else { + cm.state.colorpicker.style_color_update(cm.getCursor().line); + } + + } + + function onUpdate(cm, evt) { + if (!cm.state.colorpicker.isUpdate) { + cm.state.colorpicker.isUpdate = true; + cm.state.colorpicker.close_color_picker(); + cm.state.colorpicker.init_color_update(); + cm.state.colorpicker.style_color_update(); + } + } + + function onRefresh(cm, evt) { + onChange(cm, { origin : 'setValue'}); + } + + function onKeyup(cm, evt) { + cm.state.colorpicker.keyup(evt); + } + + function onMousedown(cm, evt) { + if (cm.state.colorpicker.is_edit_mode()) + { + cm.state.colorpicker.check_mousedown(evt); + } + } + + function onPaste (cm, evt) { + onChange(cm, { origin : 'setValue'}); + } + + function onScroll (cm) { + cm.state.colorpicker.close_color_picker(); + } + + function debounce (callback, delay) { + + var t = undefined; + + return function (cm, e) { + if (t) { + clearTimeout(t); + } + + t = setTimeout(function () { + callback(cm, e); + }, delay || 300); + } + } + + function has_class(el, cls) { + if (!el || !el.className) { + return false; + } else { + var newClass = ' ' + el.className + ' '; + return newClass.indexOf(' ' + cls + ' ') > -1; + } + } + + function codemirror_colorpicker (cm, opt) { + var self = this; + + if (typeof opt == 'boolean') + { + opt = { mode : 'view' }; + } else { + opt = Object.assign({ mode: 'view' }, opt || {}); + } + + this.opt = opt; + this.cm = cm; + this.markers = {}; + + // set excluded token + excluded_token = this.opt.excluded_token || excluded_token; + + if (this.cm.colorpicker) { + this.colorpicker = this.cm.colorpicker(); + } else if (this.opt.colorpicker) { + this.colorpicker = this.opt.colorpicker; + } + + this.init_event(); + + } + + codemirror_colorpicker.prototype.init_event = function () { + + this.cm.on('mousedown', onMousedown); + this.cm.on('keyup', onKeyup); + this.cm.on('change', onChange); + this.cm.on('update', onUpdate); + this.cm.on('refresh', onRefresh); + + // create paste callback + this.onPasteCallback = (function (cm, callback) { + return function (evt) { + callback.call(this, cm, evt); + } + })(this.cm, onPaste); + + this.cm.getWrapperElement().addEventListener('paste', this.onPasteCallback); + + if (this.is_edit_mode()) + { + this.cm.on('scroll', debounce(onScroll, 50)); + } + + } + + codemirror_colorpicker.prototype.is_edit_mode = function () { + return this.opt.mode == 'edit'; + } + + codemirror_colorpicker.prototype.is_view_mode = function () { + return this.opt.mode == 'view'; + } + + codemirror_colorpicker.prototype.destroy = function () { + this.cm.off('mousedown', onMousedown); + this.cm.off('keyup', onKeyup); + this.cm.off('change', onChange) + this.cm.getWrapperElement().removeEventListener('paste', this.onPasteCallback); + + if (this.is_edit_mode()) + { + this.cm.off('scroll'); + } + } + + codemirror_colorpicker.prototype.hasClass = function (el, className) { + if (!el.className) + { + return false; + } else { + var newClass = ' ' + el.className + ' '; + return newClass.indexOf(' ' + className + ' ') > -1; + } + } + + codemirror_colorpicker.prototype.check_mousedown = function (evt) { + if (this.hasClass(evt.target, colorpicker_background_class) ) + { + this.open_color_picker(evt.target.parentNode); + } else { + this.close_color_picker(); + } + } + + codemirror_colorpicker.prototype.popup_color_picker = function (defalutColor) { + var cursor = this.cm.getCursor(); + var self = this; + var colorMarker = { + lineNo : cursor.line, + ch : cursor.ch, + color: defalutColor || '#FFFFFF', + isShortCut : true + }; + + Object.keys(this.markers).forEach(function(key) { + var searchKey = "#" + key; + if (searchKey.indexOf( "#" + colorMarker.lineNo + ":") > -1) { + var marker = self.markers[key]; + + if (marker.ch <= colorMarker.ch && colorMarker.ch <= marker.ch + marker.color.length) { + // when cursor has marker + colorMarker.ch = marker.ch; + colorMarker.color = marker.color; + colorMarker.nameColor = marker.nameColor; + } + + } + }); + + this.open_color_picker(colorMarker); + } + + codemirror_colorpicker.prototype.open_color_picker = function (el) { + var lineNo = el.lineNo; + var ch = el.ch; + var nameColor = el.nameColor; + var color = el.color; + + + if (this.colorpicker) { + var self = this; + var prevColor = color; + var pos = this.cm.charCoords({line : lineNo, ch : ch }); + this.colorpicker.show({ + left : pos.left, + top : pos.bottom, + isShortCut : el.isShortCut || false, + hideDelay : self.opt.hideDelay || 2000 + }, nameColor || color, function (newColor) { + self.cm.replaceRange(newColor, { line : lineNo, ch : ch } , { line : lineNo, ch : ch + prevColor.length }, '*colorpicker'); + prevColor = newColor; + }); + + } + + } + + codemirror_colorpicker.prototype.close_color_picker = function (el) { + if (this.colorpicker) + { + this.colorpicker.hide(); + } + } + + codemirror_colorpicker.prototype.key = function (lineNo, ch) { + return [lineNo, ch].join(":"); + } + + + codemirror_colorpicker.prototype.keyup = function (evt) { + + if (this.colorpicker ) { + if (evt.key == 'Escape') { + this.colorpicker.hide(); + } else if (this.colorpicker.isShortCut() == false) { + this.colorpicker.hide(); + } + } + } + + codemirror_colorpicker.prototype.init_color_update = function () { + this.markers = {}; // initialize marker list + } + + codemirror_colorpicker.prototype.style_color_update = function (lineHandle) { + + if (lineHandle) { + this.match(lineHandle); + } else { + var max = this.cm.lineCount(); + + for(var lineNo = 0; lineNo < max; lineNo++) { + this.match(lineNo); + } + } + + } + + codemirror_colorpicker.prototype.empty_marker = function (lineNo, lineHandle) { + var list = lineHandle.markedSpans || []; + + for(var i = 0, len = list.length; i < len; i++) { + var key = this.key(lineNo, list[i].from); + + if (key && has_class(list[i].marker.replacedWith, colorpicker_class)) { + delete this.markers[key]; + list[i].marker.clear(); + } + + } + } + + codemirror_colorpicker.prototype.color_regexp = /(#(?:[\da-f]{3}){1,2}|rgb\((?:\s*\d{1,3},\s*){2}\d{1,3}\s*\)|rgba\((?:\s*\d{1,3},\s*){3}\d*\.?\d+\s*\)|hsl\(\s*\d{1,3}(?:,\s*\d{1,3}%){2}\s*\)|hsla\(\s*\d{1,3}(?:,\s*\d{1,3}%){2},\s*\d*\.?\d+\s*\)|([\w_\-]+))/gi; + + codemirror_colorpicker.prototype.match_result = function (lineHandle) { + return lineHandle.text.match(this.color_regexp); + } + + codemirror_colorpicker.prototype.match = function (lineNo) { + var lineHandle = this.cm.getLineHandle(lineNo); + + this.empty_marker(lineNo, lineHandle); + + var result = this.match_result(lineHandle); + if (result) + { + var obj = { next : 0 }; + for(var i = 0, len = result.length; i < len; i++) { + + if (result[i].indexOf('#') > -1 || result[i].indexOf('rgb') > -1 || result[i].indexOf('hsl') > -1) { + this.render(obj, lineNo, lineHandle, result[i]); + } else { + var nameColor = color_names[result[i]]; + if (nameColor) { + this.render(obj, lineNo, lineHandle, result[i], nameColor); + } + } + } + } + } + + codemirror_colorpicker.prototype.make_element = function () { + var el = document.createElement('div'); + + el.className = colorpicker_class; + + if (this.is_edit_mode()) + { + el.title ="open color picker"; + } else { + el.title =""; + } + + el.back_element = this.make_background_element(); + el.appendChild(el.back_element); + + return el; + } + + codemirror_colorpicker.prototype.make_background_element = function () { + var el = document.createElement('div'); + + el.className = colorpicker_background_class; + + return el; + } + + codemirror_colorpicker.prototype.set_state = function (lineNo, start, color, nameColor) { + var marker = this.create_marker(lineNo, start); + + + marker.lineNo = lineNo; + marker.ch = start; + marker.color = color; + marker.nameColor = nameColor; + + return marker; + } + + codemirror_colorpicker.prototype.create_marker = function (lineNo, start) { + + var key = this.key(lineNo,start); + + if (!this.markers[key]) { + this.markers[key] = this.make_element(); + } + + + return this.markers[key]; + + } + + codemirror_colorpicker.prototype.has_marker = function (lineNo, start) { + var key = this.key(lineNo,start); + return !!(this.markers[key]) + } + + codemirror_colorpicker.prototype.update_element = function (el, color) { + el.back_element.style.backgroundColor = color; + } + + codemirror_colorpicker.prototype.set_mark = function (line, ch, el) { + this.cm.setBookmark({ line : line, ch : ch}, { widget : el, handleMouseEvents : true} ); + + } + + codemirror_colorpicker.prototype.is_excluded_token = function (line, ch) { + var token = this.cm.getTokenAt({line : line, ch : ch}); + var count = 0; + for(var i = 0, len = excluded_token.length; i < len; i++) { + if (token.type === excluded_token[i]) { + count++; + break; + } + } + + return count > 0; // true is that it has a excluded token + } + + codemirror_colorpicker.prototype.render = function (cursor, lineNo, lineHandle, color, nameColor) { + var start = lineHandle.text.indexOf(color, cursor.next); + + if (this.is_excluded_token(lineNo, start) === true) { + // excluded token do not show. + return; + } + + cursor.next = start + color.length; + + if (this.has_marker(lineNo, start)) + { + this.update_element(this.create_marker(lineNo, start), nameColor || color); + this.set_state(lineNo, start, color, nameColor); + return; + } + + var el = this.create_marker(lineNo, start); + + this.update_element(el, nameColor || color); + this.set_state(lineNo, start, color, nameColor || color); + this.set_mark(lineNo, start, el); + } +});