merge with master
[platform/framework/web/web-ui-fw.git] / build-tools / lib / less / tree / color.js
1 (function (tree) {
2 //
3 // RGB Colors - #ff0014, #eee
4 //
5 tree.Color = function (rgb, a) {
6     //
7     // The end goal here, is to parse the arguments
8     // into an integer triplet, such as `128, 255, 0`
9     //
10     // This facilitates operations and conversions.
11     //
12     if (Array.isArray(rgb)) {
13         this.rgb = rgb;
14     } else if (rgb.length == 6) {
15         this.rgb = rgb.match(/.{2}/g).map(function (c) {
16             return parseInt(c, 16);
17         });
18     } else {
19         this.rgb = rgb.split('').map(function (c) {
20             return parseInt(c + c, 16);
21         });
22     }
23     this.alpha = typeof(a) === 'number' ? a : 1;
24 };
25 tree.Color.prototype = {
26     eval: function () { return this },
27
28     //
29     // If we have some transparency, the only way to represent it
30     // is via `rgba`. Otherwise, we use the hex representation,
31     // which has better compatibility with older browsers.
32     // Values are capped between `0` and `255`, rounded and zero-padded.
33     //
34     toCSS: function () {
35         if (this.alpha < 1.0) {
36             return "rgba(" + this.rgb.map(function (c) {
37                 return Math.round(c);
38             }).concat(this.alpha).join(', ') + ")";
39         } else {
40             return '#' + this.rgb.map(function (i) {
41                 i = Math.round(i);
42                 i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
43                 return i.length === 1 ? '0' + i : i;
44             }).join('');
45         }
46     },
47
48     //
49     // Operations have to be done per-channel, if not,
50     // channels will spill onto each other. Once we have
51     // our result, in the form of an integer triplet,
52     // we create a new Color node to hold the result.
53     //
54     operate: function (op, other) {
55         var result = [];
56
57         if (! (other instanceof tree.Color)) {
58             other = other.toColor();
59         }
60
61         for (var c = 0; c < 3; c++) {
62             result[c] = tree.operate(op, this.rgb[c], other.rgb[c]);
63         }
64         return new(tree.Color)(result, this.alpha + other.alpha);
65     },
66
67     toHSL: function () {
68         var r = this.rgb[0] / 255,
69             g = this.rgb[1] / 255,
70             b = this.rgb[2] / 255,
71             a = this.alpha;
72
73         var max = Math.max(r, g, b), min = Math.min(r, g, b);
74         var h, s, l = (max + min) / 2, d = max - min;
75
76         if (max === min) {
77             h = s = 0;
78         } else {
79             s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
80
81             switch (max) {
82                 case r: h = (g - b) / d + (g < b ? 6 : 0); break;
83                 case g: h = (b - r) / d + 2;               break;
84                 case b: h = (r - g) / d + 4;               break;
85             }
86             h /= 6;
87         }
88         return { h: h * 360, s: s, l: l, a: a };
89     },
90     toARGB: function () {
91         var argb = [Math.round(this.alpha * 255)].concat(this.rgb);
92         return '#' + argb.map(function (i) {
93             i = Math.round(i);
94             i = (i > 255 ? 255 : (i < 0 ? 0 : i)).toString(16);
95             return i.length === 1 ? '0' + i : i;
96         }).join('');
97     },
98     compare: function (x) {
99         if (!x.rgb) {
100             return -1;
101         }
102         
103         return (x.rgb[0] === this.rgb[0] &&
104             x.rgb[1] === this.rgb[1] &&
105             x.rgb[2] === this.rgb[2] &&
106             x.alpha === this.alpha) ? 0 : -1;
107     }
108 };
109
110
111 })(require('../tree'));