aboutsummaryrefslogtreecommitdiff
path: root/node_modules/stylus/lib/nodes/rgba.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/stylus/lib/nodes/rgba.js')
-rw-r--r--node_modules/stylus/lib/nodes/rgba.js367
1 files changed, 367 insertions, 0 deletions
diff --git a/node_modules/stylus/lib/nodes/rgba.js b/node_modules/stylus/lib/nodes/rgba.js
new file mode 100644
index 00000000..a961dc9c
--- /dev/null
+++ b/node_modules/stylus/lib/nodes/rgba.js
@@ -0,0 +1,367 @@
+
+/*!
+ * Stylus - RGBA
+ * Copyright (c) Automattic <developer.wordpress.com>
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var Node = require('./node')
+ , HSLA = require('./hsla')
+ , functions = require('../functions')
+ , adjust = functions.adjust
+ , nodes = require('./');
+
+/**
+ * Initialize a new `RGBA` with the given r,g,b,a component values.
+ *
+ * @param {Number} r
+ * @param {Number} g
+ * @param {Number} b
+ * @param {Number} a
+ * @api public
+ */
+
+var RGBA = exports = module.exports = function RGBA(r,g,b,a){
+ Node.call(this);
+ this.r = clamp(r);
+ this.g = clamp(g);
+ this.b = clamp(b);
+ this.a = clampAlpha(a);
+ this.name = '';
+ this.rgba = this;
+};
+
+/**
+ * Inherit from `Node.prototype`.
+ */
+
+RGBA.prototype.__proto__ = Node.prototype;
+
+/**
+ * Return an `RGBA` without clamping values.
+ *
+ * @param {Number} r
+ * @param {Number} g
+ * @param {Number} b
+ * @param {Number} a
+ * @return {RGBA}
+ * @api public
+ */
+
+RGBA.withoutClamping = function(r,g,b,a){
+ var rgba = new RGBA(0,0,0,0);
+ rgba.r = r;
+ rgba.g = g;
+ rgba.b = b;
+ rgba.a = a;
+ return rgba;
+};
+
+/**
+ * Return a clone of this node.
+ *
+ * @return {Node}
+ * @api public
+ */
+
+RGBA.prototype.clone = function(){
+ var clone = new RGBA(
+ this.r
+ , this.g
+ , this.b
+ , this.a);
+ clone.raw = this.raw;
+ clone.name = this.name;
+ clone.lineno = this.lineno;
+ clone.column = this.column;
+ clone.filename = this.filename;
+ return clone;
+};
+
+/**
+ * Return a JSON representation of this node.
+ *
+ * @return {Object}
+ * @api public
+ */
+
+RGBA.prototype.toJSON = function(){
+ return {
+ __type: 'RGBA',
+ r: this.r,
+ g: this.g,
+ b: this.b,
+ a: this.a,
+ raw: this.raw,
+ name: this.name,
+ lineno: this.lineno,
+ column: this.column,
+ filename: this.filename
+ };
+};
+
+/**
+ * Return true.
+ *
+ * @return {Boolean}
+ * @api public
+ */
+
+RGBA.prototype.toBoolean = function(){
+ return nodes.true;
+};
+
+/**
+ * Return `HSLA` representation.
+ *
+ * @return {HSLA}
+ * @api public
+ */
+
+RGBA.prototype.__defineGetter__('hsla', function(){
+ return HSLA.fromRGBA(this);
+});
+
+/**
+ * Return hash.
+ *
+ * @return {String}
+ * @api public
+ */
+
+RGBA.prototype.__defineGetter__('hash', function(){
+ return this.toString();
+});
+
+/**
+ * Add r,g,b,a to the current component values.
+ *
+ * @param {Number} r
+ * @param {Number} g
+ * @param {Number} b
+ * @param {Number} a
+ * @return {RGBA} new node
+ * @api public
+ */
+
+RGBA.prototype.add = function(r,g,b,a){
+ return new RGBA(
+ this.r + r
+ , this.g + g
+ , this.b + b
+ , this.a + a);
+};
+
+/**
+ * Subtract r,g,b,a from the current component values.
+ *
+ * @param {Number} r
+ * @param {Number} g
+ * @param {Number} b
+ * @param {Number} a
+ * @return {RGBA} new node
+ * @api public
+ */
+
+RGBA.prototype.sub = function(r,g,b,a){
+ return new RGBA(
+ this.r - r
+ , this.g - g
+ , this.b - b
+ , a == 1 ? this.a : this.a - a);
+};
+
+/**
+ * Multiply rgb components by `n`.
+ *
+ * @param {String} n
+ * @return {RGBA} new node
+ * @api public
+ */
+
+RGBA.prototype.multiply = function(n){
+ return new RGBA(
+ this.r * n
+ , this.g * n
+ , this.b * n
+ , this.a);
+};
+
+/**
+ * Divide rgb components by `n`.
+ *
+ * @param {String} n
+ * @return {RGBA} new node
+ * @api public
+ */
+
+RGBA.prototype.divide = function(n){
+ return new RGBA(
+ this.r / n
+ , this.g / n
+ , this.b / n
+ , this.a);
+};
+
+/**
+ * Operate on `right` with the given `op`.
+ *
+ * @param {String} op
+ * @param {Node} right
+ * @return {Node}
+ * @api public
+ */
+
+RGBA.prototype.operate = function(op, right){
+ if ('in' != op) right = right.first
+
+ switch (op) {
+ case 'is a':
+ if ('string' == right.nodeName && 'color' == right.string) {
+ return nodes.true;
+ }
+ break;
+ case '+':
+ switch (right.nodeName) {
+ case 'unit':
+ var n = right.val;
+ switch (right.type) {
+ case '%': return adjust(this, new nodes.String('lightness'), right);
+ case 'deg': return this.hsla.adjustHue(n).rgba;
+ default: return this.add(n,n,n,0);
+ }
+ case 'rgba':
+ return this.add(right.r, right.g, right.b, right.a);
+ case 'hsla':
+ return this.hsla.add(right.h, right.s, right.l);
+ }
+ break;
+ case '-':
+ switch (right.nodeName) {
+ case 'unit':
+ var n = right.val;
+ switch (right.type) {
+ case '%': return adjust(this, new nodes.String('lightness'), new nodes.Unit(-n, '%'));
+ case 'deg': return this.hsla.adjustHue(-n).rgba;
+ default: return this.sub(n,n,n,0);
+ }
+ case 'rgba':
+ return this.sub(right.r, right.g, right.b, right.a);
+ case 'hsla':
+ return this.hsla.sub(right.h, right.s, right.l);
+ }
+ break;
+ case '*':
+ switch (right.nodeName) {
+ case 'unit':
+ return this.multiply(right.val);
+ }
+ break;
+ case '/':
+ switch (right.nodeName) {
+ case 'unit':
+ return this.divide(right.val);
+ }
+ break;
+ }
+ return Node.prototype.operate.call(this, op, right);
+};
+
+/**
+ * Return #nnnnnn, #nnn, or rgba(n,n,n,n) string representation of the color.
+ *
+ * @return {String}
+ * @api public
+ */
+
+RGBA.prototype.toString = function(){
+ function pad(n) {
+ return n < 16
+ ? '0' + n.toString(16)
+ : n.toString(16);
+ }
+
+ // special case for transparent named color
+ if ('transparent' == this.name)
+ return this.name;
+
+ if (1 == this.a) {
+ var r = pad(this.r)
+ , g = pad(this.g)
+ , b = pad(this.b);
+
+ // Compress
+ if (r[0] == r[1] && g[0] == g[1] && b[0] == b[1]) {
+ return '#' + r[0] + g[0] + b[0];
+ } else {
+ return '#' + r + g + b;
+ }
+ } else {
+ return 'rgba('
+ + this.r + ','
+ + this.g + ','
+ + this.b + ','
+ + (+this.a.toFixed(3)) + ')';
+ }
+};
+
+/**
+ * Return a `RGBA` from the given `hsla`.
+ *
+ * @param {HSLA} hsla
+ * @return {RGBA}
+ * @api public
+ */
+
+exports.fromHSLA = function(hsla){
+ var h = hsla.h / 360
+ , s = hsla.s / 100
+ , l = hsla.l / 100
+ , a = hsla.a;
+
+ var m2 = l <= .5 ? l * (s + 1) : l + s - l * s
+ , m1 = l * 2 - m2;
+
+ var r = hue(h + 1/3) * 0xff
+ , g = hue(h) * 0xff
+ , b = hue(h - 1/3) * 0xff;
+
+ function hue(h) {
+ if (h < 0) ++h;
+ if (h > 1) --h;
+ if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
+ if (h * 2 < 1) return m2;
+ if (h * 3 < 2) return m1 + (m2 - m1) * (2/3 - h) * 6;
+ return m1;
+ }
+
+ return new RGBA(r,g,b,a);
+};
+
+/**
+ * Clamp `n` >= 0 and <= 255.
+ *
+ * @param {Number} n
+ * @return {Number}
+ * @api private
+ */
+
+function clamp(n) {
+ return Math.max(0, Math.min(n.toFixed(0), 255));
+}
+
+/**
+ * Clamp alpha `n` >= 0 and <= 1.
+ *
+ * @param {Number} n
+ * @return {Number}
+ * @api private
+ */
+
+function clampAlpha(n) {
+ return Math.max(0, Math.min(n, 1));
+}