stylus-source 0.15.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.DS_Store +0 -0
- data/README.md +3 -0
- data/lib/.DS_Store +0 -0
- data/lib/node_modules/cssom/.idea/CSSOM.iml +9 -0
- data/lib/node_modules/cssom/.idea/dictionaries/nv.xml +3 -0
- data/lib/node_modules/cssom/.idea/encodings.xml +5 -0
- data/lib/node_modules/cssom/.idea/misc.xml +17 -0
- data/lib/node_modules/cssom/.idea/modules.xml +9 -0
- data/lib/node_modules/cssom/.idea/projectCodeStyle.xml +82 -0
- data/lib/node_modules/cssom/.idea/vcs.xml +8 -0
- data/lib/node_modules/cssom/.idea/workspace.xml +467 -0
- data/lib/node_modules/cssom/.livereload +19 -0
- data/lib/node_modules/cssom/Jakefile +37 -0
- data/lib/node_modules/cssom/README.mdown +33 -0
- data/lib/node_modules/cssom/Rakefile +23 -0
- data/lib/node_modules/cssom/docs/.livereload +19 -0
- data/lib/node_modules/cssom/docs/bar.css +3 -0
- data/lib/node_modules/cssom/docs/demo.css +0 -0
- data/lib/node_modules/cssom/docs/foo.css +4 -0
- data/lib/node_modules/cssom/docs/parse.html +170 -0
- data/lib/node_modules/cssom/docs/parse2.html +431 -0
- data/lib/node_modules/cssom/index.html +100 -0
- data/lib/node_modules/cssom/lib/CSSImportRule.js +34 -0
- data/lib/node_modules/cssom/lib/CSSMediaRule.js +38 -0
- data/lib/node_modules/cssom/lib/CSSOM.js +3 -0
- data/lib/node_modules/cssom/lib/CSSRule.js +38 -0
- data/lib/node_modules/cssom/lib/CSSStyleDeclaration.js +130 -0
- data/lib/node_modules/cssom/lib/CSSStyleRule.js +187 -0
- data/lib/node_modules/cssom/lib/CSSStyleSheet.js +85 -0
- data/lib/node_modules/cssom/lib/MediaList.js +61 -0
- data/lib/node_modules/cssom/lib/StyleSheet.js +15 -0
- data/lib/node_modules/cssom/lib/clone.js +69 -0
- data/lib/node_modules/cssom/lib/index.js +10 -0
- data/lib/node_modules/cssom/lib/parse.js +195 -0
- data/lib/node_modules/cssom/media.html +17 -0
- data/lib/node_modules/cssom/package.json +30 -0
- data/lib/node_modules/cssom/plugins/toHTML.js +32 -0
- data/lib/node_modules/cssom/server/index.html +22 -0
- data/lib/node_modules/cssom/server/index.js +21 -0
- data/lib/node_modules/cssom/shorthands.html +21 -0
- data/lib/node_modules/cssom/test/CSSStyleDeclaration.test.js +35 -0
- data/lib/node_modules/cssom/test/CSSStyleRule.test.js +12 -0
- data/lib/node_modules/cssom/test/CSSStyleSheet.test.js +16 -0
- data/lib/node_modules/cssom/test/MediaList.test.js +21 -0
- data/lib/node_modules/cssom/test/clone.test.js +38 -0
- data/lib/node_modules/cssom/test/fixtures/dummy.css +3 -0
- data/lib/node_modules/cssom/test/helper.js +97 -0
- data/lib/node_modules/cssom/test/index.html +42 -0
- data/lib/node_modules/cssom/test/parse.test.js +346 -0
- data/lib/node_modules/cssom/test/vendor/qunit.css +189 -0
- data/lib/node_modules/cssom/test/vendor/qunit.js +1341 -0
- data/lib/node_modules/growl/History.md +16 -0
- data/lib/node_modules/growl/Readme.md +74 -0
- data/lib/node_modules/growl/lib/growl.js +82 -0
- data/lib/node_modules/growl/package.json +6 -0
- data/lib/node_modules/growl/test.js +17 -0
- data/lib/stylus/colors.js +156 -0
- data/lib/stylus/convert/css.js +130 -0
- data/lib/stylus/errors.js +58 -0
- data/lib/stylus/functions/image.js +120 -0
- data/lib/stylus/functions/index.js +722 -0
- data/lib/stylus/functions/index.styl +123 -0
- data/lib/stylus/functions/url.js +98 -0
- data/lib/stylus/lexer.js +728 -0
- data/lib/stylus/middleware.js +223 -0
- data/lib/stylus/nodes/arguments.js +65 -0
- data/lib/stylus/nodes/binop.js +54 -0
- data/lib/stylus/nodes/block.js +99 -0
- data/lib/stylus/nodes/boolean.js +103 -0
- data/lib/stylus/nodes/call.js +57 -0
- data/lib/stylus/nodes/charset.js +42 -0
- data/lib/stylus/nodes/comment.js +32 -0
- data/lib/stylus/nodes/each.js +56 -0
- data/lib/stylus/nodes/expression.js +168 -0
- data/lib/stylus/nodes/fontface.js +55 -0
- data/lib/stylus/nodes/function.js +104 -0
- data/lib/stylus/nodes/group.js +79 -0
- data/lib/stylus/nodes/hsla.js +256 -0
- data/lib/stylus/nodes/ident.js +127 -0
- data/lib/stylus/nodes/if.js +55 -0
- data/lib/stylus/nodes/import.js +30 -0
- data/lib/stylus/nodes/index.js +52 -0
- data/lib/stylus/nodes/jsliteral.js +32 -0
- data/lib/stylus/nodes/keyframes.js +78 -0
- data/lib/stylus/nodes/literal.js +92 -0
- data/lib/stylus/nodes/media.js +42 -0
- data/lib/stylus/nodes/node.js +209 -0
- data/lib/stylus/nodes/null.js +72 -0
- data/lib/stylus/nodes/page.js +43 -0
- data/lib/stylus/nodes/params.js +72 -0
- data/lib/stylus/nodes/property.js +72 -0
- data/lib/stylus/nodes/return.js +44 -0
- data/lib/stylus/nodes/rgba.js +335 -0
- data/lib/stylus/nodes/root.js +50 -0
- data/lib/stylus/nodes/selector.js +57 -0
- data/lib/stylus/nodes/string.js +120 -0
- data/lib/stylus/nodes/ternary.js +51 -0
- data/lib/stylus/nodes/unaryop.js +46 -0
- data/lib/stylus/nodes/unit.js +207 -0
- data/lib/stylus/parser.js +1514 -0
- data/lib/stylus/renderer.js +157 -0
- data/lib/stylus/source.rb +7 -0
- data/lib/stylus/stack/frame.js +66 -0
- data/lib/stylus/stack/index.js +146 -0
- data/lib/stylus/stack/scope.js +53 -0
- data/lib/stylus/stylus.js +102 -0
- data/lib/stylus/token.js +53 -0
- data/lib/stylus/utils.js +237 -0
- data/lib/stylus/visitor/compiler.js +472 -0
- data/lib/stylus/visitor/evaluator.js +1070 -0
- data/lib/stylus/visitor/index.js +31 -0
- data/stylus-source.gemspec +15 -0
- metadata +158 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
/*!
|
|
3
|
+
* Stylus - errors
|
|
4
|
+
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Expose constructors.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
exports.ParseError = ParseError;
|
|
13
|
+
exports.SyntaxError = SyntaxError;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Inherit from `Error.prototype`.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
SyntaxError.prototype.__proto__ = Error.prototype;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Initialize a new `ParseError` with the given `msg`.
|
|
23
|
+
*
|
|
24
|
+
* @param {String} msg
|
|
25
|
+
* @api private
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
function ParseError(msg) {
|
|
29
|
+
this.name = 'ParseError';
|
|
30
|
+
this.message = msg;
|
|
31
|
+
Error.captureStackTrace(this, ParseError);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Inherit from `Error.prototype`.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
ParseError.prototype.__proto__ = Error.prototype;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Initialize a new `SyntaxError` with the given `msg`.
|
|
42
|
+
*
|
|
43
|
+
* @param {String} msg
|
|
44
|
+
* @api private
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
function SyntaxError(msg) {
|
|
48
|
+
this.name = 'SyntaxError';
|
|
49
|
+
this.message = msg;
|
|
50
|
+
Error.captureStackTrace(this, ParseError);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Inherit from `Error.prototype`.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
SyntaxError.prototype.__proto__ = Error.prototype;
|
|
58
|
+
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
/*!
|
|
4
|
+
* Stylus - plugin - url
|
|
5
|
+
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
|
|
6
|
+
* MIT Licensed
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Module dependencies.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
var utils = require('../utils')
|
|
14
|
+
, nodes = require('../nodes')
|
|
15
|
+
, fs = require('fs');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Initialize a new `Image` with the given `ctx` and `path.
|
|
19
|
+
*
|
|
20
|
+
* @param {Evaluator} ctx
|
|
21
|
+
* @param {String} path
|
|
22
|
+
* @api private
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
var Image = module.exports = function Image(ctx, path) {
|
|
26
|
+
this.ctx = ctx;
|
|
27
|
+
this.path = utils.lookup(path, ctx.paths);
|
|
28
|
+
if (!this.path) throw new Error('failed to locate file ' + path);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Open the image for reading.
|
|
33
|
+
*
|
|
34
|
+
* @api private
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
Image.prototype.open = function(){
|
|
38
|
+
this.fd = fs.openSync(this.path, 'r');
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Close the file.
|
|
43
|
+
*
|
|
44
|
+
* @api private
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
Image.prototype.close = function(){
|
|
48
|
+
if (this.fd) fs.closeSync(this.fd);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Return the type of image, supports:
|
|
53
|
+
*
|
|
54
|
+
* - gif
|
|
55
|
+
* - png
|
|
56
|
+
* - jpeg
|
|
57
|
+
*
|
|
58
|
+
* @return {String}
|
|
59
|
+
* @api private
|
|
60
|
+
*/
|
|
61
|
+
|
|
62
|
+
Image.prototype.type = function(){
|
|
63
|
+
var type
|
|
64
|
+
, buf = new Buffer(4);
|
|
65
|
+
|
|
66
|
+
fs.readSync(this.fd, buf, 0, 4, 0);
|
|
67
|
+
|
|
68
|
+
// GIF
|
|
69
|
+
if (0x47 == buf[0] && 0x49 == buf[1] && 0x46 == buf[2]) type = 'gif';
|
|
70
|
+
|
|
71
|
+
// PNG
|
|
72
|
+
else if (0x50 == buf[1] && 0x4E == buf[2] && 0x47 == buf[3]) type = 'png';
|
|
73
|
+
|
|
74
|
+
// JPEG
|
|
75
|
+
else if (0xff == buf[0] && 0xd8 == buf[1]) type = 'jpeg';
|
|
76
|
+
|
|
77
|
+
return type;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Return image dimensions `[width, height]`.
|
|
82
|
+
*
|
|
83
|
+
* @return {Array}
|
|
84
|
+
* @api private
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
Image.prototype.size = function(){
|
|
88
|
+
var width
|
|
89
|
+
, height
|
|
90
|
+
, type = this.type();
|
|
91
|
+
|
|
92
|
+
function uint16(b) { return b[1] << 8 | b[0]; }
|
|
93
|
+
function uint32(b) { return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]; }
|
|
94
|
+
|
|
95
|
+
// Determine dimensions
|
|
96
|
+
switch (type) {
|
|
97
|
+
case 'jpeg':
|
|
98
|
+
throw new Error('image-size() jpeg support not yet implemented');
|
|
99
|
+
break;
|
|
100
|
+
case 'png':
|
|
101
|
+
var buf = new Buffer(8);
|
|
102
|
+
// IHDR chunk width / height uint32_t big-endian
|
|
103
|
+
fs.readSync(this.fd, buf, 0, 8, 16);
|
|
104
|
+
width = uint32(buf);
|
|
105
|
+
height = uint32(buf.slice(4, 8));
|
|
106
|
+
break;
|
|
107
|
+
case 'gif':
|
|
108
|
+
var buf = new Buffer(4);
|
|
109
|
+
// width / height uint16_t little-endian
|
|
110
|
+
fs.readSync(this.fd, buf, 0, 4, 6);
|
|
111
|
+
width = uint16(buf);
|
|
112
|
+
height = uint16(buf.slice(2, 4));
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if ('number' != typeof width) throw new Error('failed to find width of "' + this.path + '"');
|
|
117
|
+
if ('number' != typeof height) throw new Error('failed to find height of "' + this.path + '"');
|
|
118
|
+
|
|
119
|
+
return [width, height];
|
|
120
|
+
};
|
|
@@ -0,0 +1,722 @@
|
|
|
1
|
+
|
|
2
|
+
/*!
|
|
3
|
+
* Stylus - Evaluator - built-in functions
|
|
4
|
+
* Copyright(c) 2010 LearnBoost <dev@learnboost.com>
|
|
5
|
+
* MIT Licensed
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Module dependencies.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
var Compiler = require('../visitor/compiler')
|
|
13
|
+
, nodes = require('../nodes')
|
|
14
|
+
, utils = require('../utils')
|
|
15
|
+
, Image = require('./image');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Color component name map.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
var componentMap = {
|
|
22
|
+
red: 'r'
|
|
23
|
+
, green: 'g'
|
|
24
|
+
, blue: 'b'
|
|
25
|
+
, alpha: 'a'
|
|
26
|
+
, hue: 'h'
|
|
27
|
+
, saturation: 's'
|
|
28
|
+
, lightness: 'l'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Color component unit type map.
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
var unitMap = {
|
|
36
|
+
hue: 'deg'
|
|
37
|
+
, saturation: '%'
|
|
38
|
+
, lightness: '%'
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Color type map.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
var typeMap = {
|
|
46
|
+
red: 'rgba'
|
|
47
|
+
, blue: 'rgba'
|
|
48
|
+
, green: 'rgba'
|
|
49
|
+
, alpha: 'rgba'
|
|
50
|
+
, hue: 'hsla'
|
|
51
|
+
, saturation: 'hsla'
|
|
52
|
+
, lightness: 'hsla'
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Convert the given `color` to an `HSLA` node,
|
|
57
|
+
* or h,s,l,a component values.
|
|
58
|
+
*
|
|
59
|
+
* Examples:
|
|
60
|
+
*
|
|
61
|
+
* hsla(10deg, 50%, 30%, 0.5)
|
|
62
|
+
* // => HSLA
|
|
63
|
+
*
|
|
64
|
+
* hsla(#ffcc00)
|
|
65
|
+
* // => HSLA
|
|
66
|
+
*
|
|
67
|
+
* @param {RGBA|HSLA|Unit} hue
|
|
68
|
+
* @param {Unit} saturation
|
|
69
|
+
* @param {Unit} lightness
|
|
70
|
+
* @param {Unit} alpha
|
|
71
|
+
* @return {HSLA}
|
|
72
|
+
* @api public
|
|
73
|
+
*/
|
|
74
|
+
|
|
75
|
+
exports.hsla = function hsla(hue, saturation, lightness, alpha){
|
|
76
|
+
switch (arguments.length) {
|
|
77
|
+
case 1:
|
|
78
|
+
utils.assertColor(hue);
|
|
79
|
+
return hue.hsla;
|
|
80
|
+
default:
|
|
81
|
+
utils.assertType(hue, 'unit', 'hue');
|
|
82
|
+
utils.assertType(saturation, 'unit', 'saturation');
|
|
83
|
+
utils.assertType(lightness, 'unit', 'lightness');
|
|
84
|
+
utils.assertType(alpha, 'unit', 'alpha');
|
|
85
|
+
return new nodes.HSLA(
|
|
86
|
+
hue.val
|
|
87
|
+
, saturation.val
|
|
88
|
+
, lightness.val
|
|
89
|
+
, alpha.val);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Convert the given `color` to an `HSLA` node,
|
|
95
|
+
* or h,s,l component values.
|
|
96
|
+
*
|
|
97
|
+
* Examples:
|
|
98
|
+
*
|
|
99
|
+
* hsl(10, 50, 30)
|
|
100
|
+
* // => HSLA
|
|
101
|
+
*
|
|
102
|
+
* hsl(#ffcc00)
|
|
103
|
+
* // => HSLA
|
|
104
|
+
*
|
|
105
|
+
* @param {Unit|HSLA|RGBA} hue
|
|
106
|
+
* @param {Unit} saturation
|
|
107
|
+
* @param {Unit} lightness
|
|
108
|
+
* @return {HSLA}
|
|
109
|
+
* @api public
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
exports.hsl = function hsl(hue, saturation, lightness){
|
|
113
|
+
if (1 == arguments.length) {
|
|
114
|
+
utils.assertColor(hue, 'color');
|
|
115
|
+
return hue.hsla;
|
|
116
|
+
} else {
|
|
117
|
+
return exports.hsla(
|
|
118
|
+
hue
|
|
119
|
+
, saturation
|
|
120
|
+
, lightness
|
|
121
|
+
, new nodes.Unit(1));
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Return type of `node`.
|
|
127
|
+
*
|
|
128
|
+
* Examples:
|
|
129
|
+
*
|
|
130
|
+
* type(12)
|
|
131
|
+
* // => 'unit'
|
|
132
|
+
*
|
|
133
|
+
* type(#fff)
|
|
134
|
+
* // => 'color'
|
|
135
|
+
*
|
|
136
|
+
* type(type)
|
|
137
|
+
* // => 'function'
|
|
138
|
+
*
|
|
139
|
+
* type(unbound)
|
|
140
|
+
* typeof(unbound)
|
|
141
|
+
* type-of(unbound)
|
|
142
|
+
* // => 'ident'
|
|
143
|
+
*
|
|
144
|
+
* @param {Node} node
|
|
145
|
+
* @return {String}
|
|
146
|
+
* @api public
|
|
147
|
+
*/
|
|
148
|
+
|
|
149
|
+
exports.type =
|
|
150
|
+
exports.typeof =
|
|
151
|
+
exports['type-of'] = function type(node){
|
|
152
|
+
utils.assertPresent(node, 'expression');
|
|
153
|
+
var type = node.nodeName;
|
|
154
|
+
return new nodes.String(type);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Return component `name` for the given `color`.
|
|
159
|
+
*
|
|
160
|
+
* @param {RGBA|HSLA} color
|
|
161
|
+
* @param {String} na,e
|
|
162
|
+
* @return {Unit}
|
|
163
|
+
* @api public
|
|
164
|
+
*/
|
|
165
|
+
|
|
166
|
+
exports.component = function component(color, name) {
|
|
167
|
+
utils.assertColor(color, 'color');
|
|
168
|
+
utils.assertString(name, 'name');
|
|
169
|
+
var name = name.string
|
|
170
|
+
, unit = unitMap[name]
|
|
171
|
+
, type = typeMap[name]
|
|
172
|
+
, name = componentMap[name];
|
|
173
|
+
if (!name) throw new Error('invalid color component "' + name + '"');
|
|
174
|
+
return new nodes.Unit(color[type][name], unit);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Return the red component of the given `color`.
|
|
179
|
+
*
|
|
180
|
+
* Examples:
|
|
181
|
+
*
|
|
182
|
+
* red(#c00)
|
|
183
|
+
* // => 204
|
|
184
|
+
*
|
|
185
|
+
* @param {RGBA|HSLA} color
|
|
186
|
+
* @return {Unit}
|
|
187
|
+
* @api public
|
|
188
|
+
*/
|
|
189
|
+
|
|
190
|
+
exports.red = function red(color){
|
|
191
|
+
return exports.component(color, new nodes.String('red'));
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Return the green component of the given `color`.
|
|
196
|
+
*
|
|
197
|
+
* Examples:
|
|
198
|
+
*
|
|
199
|
+
* green(#0c0)
|
|
200
|
+
* // => 204
|
|
201
|
+
*
|
|
202
|
+
* @param {RGBA|HSLA} color
|
|
203
|
+
* @return {Unit}
|
|
204
|
+
* @api public
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
exports.green = function green(color){
|
|
208
|
+
return exports.component(color, new nodes.String('green'));
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Return the blue component of the given `color`.
|
|
213
|
+
*
|
|
214
|
+
* Examples:
|
|
215
|
+
*
|
|
216
|
+
* blue(#00c)
|
|
217
|
+
* // => 204
|
|
218
|
+
*
|
|
219
|
+
* @param {RGBA|HSLA} color
|
|
220
|
+
* @return {Unit}
|
|
221
|
+
* @api public
|
|
222
|
+
*/
|
|
223
|
+
|
|
224
|
+
exports.blue = function blue(color){
|
|
225
|
+
return exports.component(color, new nodes.String('blue'));
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Return a `RGBA` from the r,g,b,a channels.
|
|
230
|
+
*
|
|
231
|
+
* Examples:
|
|
232
|
+
*
|
|
233
|
+
* rgba(255,0,0,0.5)
|
|
234
|
+
* // => rgba(255,0,0,0.5)
|
|
235
|
+
*
|
|
236
|
+
* rgba(255,0,0,1)
|
|
237
|
+
* // => #ff0000
|
|
238
|
+
*
|
|
239
|
+
* rgba(#ffcc00, 0.5)
|
|
240
|
+
* // rgba(255,204,0,0.5)
|
|
241
|
+
*
|
|
242
|
+
* @param {Unit|RGBA|HSLA} red
|
|
243
|
+
* @param {Unit} green
|
|
244
|
+
* @param {Unit} blue
|
|
245
|
+
* @param {Unit} alpha
|
|
246
|
+
* @return {RGBA}
|
|
247
|
+
* @api public
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
exports.rgba = function rgba(red, green, blue, alpha){
|
|
251
|
+
switch (arguments.length) {
|
|
252
|
+
case 1:
|
|
253
|
+
utils.assertColor(red);
|
|
254
|
+
var color = red.rgba;
|
|
255
|
+
return new nodes.RGBA(
|
|
256
|
+
color.r
|
|
257
|
+
, color.g
|
|
258
|
+
, color.b
|
|
259
|
+
, color.a);
|
|
260
|
+
case 2:
|
|
261
|
+
utils.assertColor(red);
|
|
262
|
+
var color = red.rgba;
|
|
263
|
+
utils.assertType(green, 'unit', 'alpha');
|
|
264
|
+
return new nodes.RGBA(
|
|
265
|
+
color.r
|
|
266
|
+
, color.g
|
|
267
|
+
, color.b
|
|
268
|
+
, green.val);
|
|
269
|
+
default:
|
|
270
|
+
utils.assertType(red, 'unit', 'red');
|
|
271
|
+
utils.assertType(green, 'unit', 'green');
|
|
272
|
+
utils.assertType(blue, 'unit', 'blue');
|
|
273
|
+
utils.assertType(alpha, 'unit', 'alpha');
|
|
274
|
+
return new nodes.RGBA(
|
|
275
|
+
red.val
|
|
276
|
+
, green.val
|
|
277
|
+
, blue.val
|
|
278
|
+
, alpha.val);
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Return a `RGBA` from the r,g,b channels.
|
|
284
|
+
*
|
|
285
|
+
* Examples:
|
|
286
|
+
*
|
|
287
|
+
* rgb(255,204,0)
|
|
288
|
+
* // => #ffcc00
|
|
289
|
+
*
|
|
290
|
+
* rgb(#fff)
|
|
291
|
+
* // => #fff
|
|
292
|
+
*
|
|
293
|
+
* @param {Unit|RGBA|HSLA} red
|
|
294
|
+
* @param {Unit} green
|
|
295
|
+
* @param {Unit} blue
|
|
296
|
+
* @return {RGBA}
|
|
297
|
+
* @api public
|
|
298
|
+
*/
|
|
299
|
+
|
|
300
|
+
exports.rgb = function rgb(red, green, blue){
|
|
301
|
+
switch (arguments.length) {
|
|
302
|
+
case 1:
|
|
303
|
+
utils.assertColor(red);
|
|
304
|
+
var color = red.rgba;
|
|
305
|
+
return new nodes.RGBA(
|
|
306
|
+
color.r
|
|
307
|
+
, color.g
|
|
308
|
+
, color.b
|
|
309
|
+
, 1);
|
|
310
|
+
default:
|
|
311
|
+
return exports.rgba(
|
|
312
|
+
red
|
|
313
|
+
, green
|
|
314
|
+
, blue
|
|
315
|
+
, new nodes.Unit(1));
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Unquote the given `str`.
|
|
321
|
+
*
|
|
322
|
+
* Examples:
|
|
323
|
+
*
|
|
324
|
+
* unquote("sans-serif")
|
|
325
|
+
* // => sans-serif
|
|
326
|
+
*
|
|
327
|
+
* unquote(sans-serif)
|
|
328
|
+
* // => sans-serif
|
|
329
|
+
*
|
|
330
|
+
* @param {String|Ident} string
|
|
331
|
+
* @return {Literal}
|
|
332
|
+
* @api public
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
exports.unquote = function unquote(string){
|
|
336
|
+
utils.assertString(string, 'string');
|
|
337
|
+
return new nodes.Literal(string.string);
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Assign `type` to the given `unit` or return `unit`'s type.
|
|
342
|
+
*
|
|
343
|
+
* @param {Unit} unit
|
|
344
|
+
* @param {String|Ident} type
|
|
345
|
+
* @return {Unit}
|
|
346
|
+
* @api public
|
|
347
|
+
*/
|
|
348
|
+
|
|
349
|
+
exports.unit = function unit(unit, type){
|
|
350
|
+
utils.assertType(unit, 'unit', 'unit');
|
|
351
|
+
|
|
352
|
+
// Assign
|
|
353
|
+
if (type) {
|
|
354
|
+
utils.assertString(type, 'type');
|
|
355
|
+
return new nodes.Unit(unit.val, type.string);
|
|
356
|
+
} else {
|
|
357
|
+
return new nodes.String(unit.type || '');
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Lookup variable `name` or return Null.
|
|
363
|
+
*
|
|
364
|
+
* @param {String} name
|
|
365
|
+
* @return {Mixed}
|
|
366
|
+
* @api public
|
|
367
|
+
*/
|
|
368
|
+
|
|
369
|
+
exports.lookup = function lookup(name){
|
|
370
|
+
utils.assertType(name, 'string', 'name');
|
|
371
|
+
var node = this.lookup(name.val);
|
|
372
|
+
if (!node) return nodes.null;
|
|
373
|
+
return this.visit(node);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Perform `op` on the `left` and `right` operands.
|
|
378
|
+
*
|
|
379
|
+
* @param {String} op
|
|
380
|
+
* @param {Node} left
|
|
381
|
+
* @param {Node} right
|
|
382
|
+
* @return {Node}
|
|
383
|
+
* @api public
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
exports.operate = function operate(op, left, right){
|
|
387
|
+
utils.assertType(op, 'string', 'op');
|
|
388
|
+
utils.assertPresent(left, 'left');
|
|
389
|
+
utils.assertPresent(right, 'right');
|
|
390
|
+
return left.operate(op.val, right);
|
|
391
|
+
};
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Test if `val` matches the given `pattern`.
|
|
395
|
+
*
|
|
396
|
+
* Examples:
|
|
397
|
+
*
|
|
398
|
+
* match('^foo(bar)?', foo)
|
|
399
|
+
* match('^foo(bar)?', foobar)
|
|
400
|
+
* match('^foo(bar)?', 'foo')
|
|
401
|
+
* match('^foo(bar)?', 'foobar')
|
|
402
|
+
* // => true
|
|
403
|
+
*
|
|
404
|
+
* match('^foo(bar)?', 'bar')
|
|
405
|
+
* // => false
|
|
406
|
+
*
|
|
407
|
+
* @param {String} pattern
|
|
408
|
+
* @param {String|Ident} val
|
|
409
|
+
* @return {Boolean}
|
|
410
|
+
* @api public
|
|
411
|
+
*/
|
|
412
|
+
|
|
413
|
+
exports.match = function match(pattern, val){
|
|
414
|
+
utils.assertType(pattern, 'string', 'pattern');
|
|
415
|
+
utils.assertString(val, 'val');
|
|
416
|
+
var re = new RegExp(pattern.val);
|
|
417
|
+
return nodes.Boolean(re.test(val.string));
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Return length of the given `expr`.
|
|
422
|
+
*
|
|
423
|
+
* @param {Expression} expr
|
|
424
|
+
* @return {Unit}
|
|
425
|
+
* @api public
|
|
426
|
+
*/
|
|
427
|
+
|
|
428
|
+
(exports.length = function length(expr){
|
|
429
|
+
if (expr) {
|
|
430
|
+
if (expr.nodes) {
|
|
431
|
+
return new nodes.Unit(utils.unwrap(expr).nodes.length);
|
|
432
|
+
} else {
|
|
433
|
+
return new nodes.Unit(1);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return new nodes.Unit(0);
|
|
437
|
+
}).raw = true;
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Inspect the given `expr`.
|
|
441
|
+
*
|
|
442
|
+
* @param {Expression} expr
|
|
443
|
+
* @api public
|
|
444
|
+
*/
|
|
445
|
+
|
|
446
|
+
(exports.p = function p(expr){
|
|
447
|
+
expr = utils.unwrap(expr);
|
|
448
|
+
console.log('\033[90minspect:\033[0m %s'
|
|
449
|
+
, expr.toString().replace(/^\(|\)$/g, ''));
|
|
450
|
+
return nodes.null;
|
|
451
|
+
}).raw = true;
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Throw an error with the given `msg`.
|
|
455
|
+
*
|
|
456
|
+
* @param {String} msg
|
|
457
|
+
* @api public
|
|
458
|
+
*/
|
|
459
|
+
|
|
460
|
+
exports.error = function error(msg){
|
|
461
|
+
utils.assertType(msg, 'string', 'msg');
|
|
462
|
+
throw new Error(msg.val);
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Warn with the given `msg` prefixed by "Warning: ".
|
|
467
|
+
*
|
|
468
|
+
* @param {String} msg
|
|
469
|
+
* @api public
|
|
470
|
+
*/
|
|
471
|
+
|
|
472
|
+
exports.warn = function warn(msg){
|
|
473
|
+
utils.assertType(msg, 'string', 'msg');
|
|
474
|
+
console.warn('Warning: %s', msg.val);
|
|
475
|
+
return nodes.null;
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Output stack trace.
|
|
480
|
+
*
|
|
481
|
+
* @api public
|
|
482
|
+
*/
|
|
483
|
+
|
|
484
|
+
exports.trace = function trace(){
|
|
485
|
+
console.log(this.stack);
|
|
486
|
+
return nodes.null;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Push the given args to `expr`.
|
|
491
|
+
*
|
|
492
|
+
* @param {Expression} expr
|
|
493
|
+
* @param {Node} ...
|
|
494
|
+
* @return {Unit}
|
|
495
|
+
* @api public
|
|
496
|
+
*/
|
|
497
|
+
|
|
498
|
+
(exports.push = exports.append = function(expr){
|
|
499
|
+
expr = utils.unwrap(expr);
|
|
500
|
+
for (var i = 1, len = arguments.length; i < len; ++i) {
|
|
501
|
+
expr.nodes.push(utils.unwrap(arguments[i]));
|
|
502
|
+
}
|
|
503
|
+
return new nodes.Unit(expr.nodes.length);
|
|
504
|
+
}).raw = true;
|
|
505
|
+
|
|
506
|
+
/**
|
|
507
|
+
* Unshift the given args to `expr`.
|
|
508
|
+
*
|
|
509
|
+
* @param {Expression} expr
|
|
510
|
+
* @param {Node} ...
|
|
511
|
+
* @return {Unit}
|
|
512
|
+
* @api public
|
|
513
|
+
*/
|
|
514
|
+
|
|
515
|
+
(exports.unshift = exports.prepend = function(expr){
|
|
516
|
+
expr = utils.unwrap(expr);
|
|
517
|
+
for (var i = 1, len = arguments.length; i < len; ++i) {
|
|
518
|
+
expr.nodes.unshift(utils.unwrap(arguments[i]));
|
|
519
|
+
}
|
|
520
|
+
return new nodes.Unit(expr.nodes.length);
|
|
521
|
+
}).raw = true;
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Return a `Literal` with the given `fmt`, and
|
|
525
|
+
* variable number of arguments.
|
|
526
|
+
*
|
|
527
|
+
* @param {String} fmt
|
|
528
|
+
* @param {Node} ...
|
|
529
|
+
* @return {Literal}
|
|
530
|
+
* @api public
|
|
531
|
+
*/
|
|
532
|
+
|
|
533
|
+
(exports.s = function s(fmt){
|
|
534
|
+
fmt = utils.unwrap(fmt).nodes[0];
|
|
535
|
+
utils.assertString(fmt);
|
|
536
|
+
var self = this
|
|
537
|
+
, str = fmt.string
|
|
538
|
+
, args = arguments
|
|
539
|
+
, i = 1;
|
|
540
|
+
|
|
541
|
+
// format
|
|
542
|
+
str = str.replace(/%(s|d)/g, function(_, specifier){
|
|
543
|
+
var arg = args[i++] || nodes.null;
|
|
544
|
+
switch (specifier) {
|
|
545
|
+
case 's':
|
|
546
|
+
return new Compiler(arg, self.options).compile();
|
|
547
|
+
case 'd':
|
|
548
|
+
arg = utils.unwrap(arg).first;
|
|
549
|
+
if ('unit' != arg.nodeName) throw new Error('%d requires a unit');
|
|
550
|
+
return arg.val;
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
return new nodes.Literal(str);
|
|
555
|
+
}).raw = true;
|
|
556
|
+
|
|
557
|
+
/**
|
|
558
|
+
* Return the opposites of the given `positions`.
|
|
559
|
+
*
|
|
560
|
+
* Examples:
|
|
561
|
+
*
|
|
562
|
+
* opposite-position(top left)
|
|
563
|
+
* // => bottom right
|
|
564
|
+
*
|
|
565
|
+
* @param {Expression} positions
|
|
566
|
+
* @return {Expression}
|
|
567
|
+
* @api public
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
(exports['opposite-position'] = function oppositePosition(positions){
|
|
571
|
+
var expr = new nodes.Expression;
|
|
572
|
+
utils.unwrap(positions).nodes.forEach(function(pos, i){
|
|
573
|
+
utils.assertString(pos, 'position ' + i);
|
|
574
|
+
pos = (function(){ switch (pos.string) {
|
|
575
|
+
case 'top': return 'bottom';
|
|
576
|
+
case 'bottom': return 'top';
|
|
577
|
+
case 'left': return 'right';
|
|
578
|
+
case 'right': return 'left';
|
|
579
|
+
default: throw new Error('invalid position ' + pos);
|
|
580
|
+
}})();
|
|
581
|
+
expr.push(new nodes.Literal(pos));
|
|
582
|
+
});
|
|
583
|
+
return expr;
|
|
584
|
+
}).raw = true;
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Return the width and height of the given `img` path.
|
|
588
|
+
*
|
|
589
|
+
* Examples:
|
|
590
|
+
*
|
|
591
|
+
* image-size('foo.png')
|
|
592
|
+
* // => 200px 100px
|
|
593
|
+
*
|
|
594
|
+
* image-size('foo.png')[0]
|
|
595
|
+
* // => 200px
|
|
596
|
+
*
|
|
597
|
+
* image-size('foo.png')[1]
|
|
598
|
+
* // => 100px
|
|
599
|
+
*
|
|
600
|
+
* @param {String} img
|
|
601
|
+
* @return {Expression}
|
|
602
|
+
* @api public
|
|
603
|
+
*/
|
|
604
|
+
|
|
605
|
+
exports['image-size'] = function imageSize(img) {
|
|
606
|
+
utils.assertType(img, 'string', 'img');
|
|
607
|
+
var img = new Image(this, img.string);
|
|
608
|
+
|
|
609
|
+
// Read size
|
|
610
|
+
img.open();
|
|
611
|
+
var size = img.size();
|
|
612
|
+
img.close();
|
|
613
|
+
|
|
614
|
+
// Return (w h)
|
|
615
|
+
var expr = new nodes.Expression;
|
|
616
|
+
expr.push(new nodes.Unit(size[0], 'px'));
|
|
617
|
+
expr.push(new nodes.Unit(size[1], 'px'));
|
|
618
|
+
|
|
619
|
+
return expr;
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Apply Math `fn` to `n`.
|
|
624
|
+
*
|
|
625
|
+
* @param {Unit} n
|
|
626
|
+
* @param {String} fn
|
|
627
|
+
* @return {Unit}
|
|
628
|
+
* @api private
|
|
629
|
+
*/
|
|
630
|
+
|
|
631
|
+
exports['-math'] = function math(n, fn){
|
|
632
|
+
return new nodes.Unit(Math[fn.string](n.val), n.type);
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Get Math `prop`.
|
|
637
|
+
*
|
|
638
|
+
* @param {String} prop
|
|
639
|
+
* @return {Unit}
|
|
640
|
+
* @api private
|
|
641
|
+
*/
|
|
642
|
+
|
|
643
|
+
exports['-math-prop'] = function math(prop){
|
|
644
|
+
return new nodes.Unit(Math[prop.string]);
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Buffer the given js `str`.
|
|
649
|
+
*
|
|
650
|
+
* @param {String} str
|
|
651
|
+
* @return {JSLiteral}
|
|
652
|
+
* @api private
|
|
653
|
+
*/
|
|
654
|
+
|
|
655
|
+
exports.js = function js(str){
|
|
656
|
+
utils.assertString(str, 'str');
|
|
657
|
+
return new nodes.JSLiteral(str.val);
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
/**
|
|
661
|
+
* Adjust HSL `color` `prop` by `amount`.
|
|
662
|
+
*
|
|
663
|
+
* @param {RGBA|HSLA} color
|
|
664
|
+
* @param {String} prop
|
|
665
|
+
* @param {Unit} amount
|
|
666
|
+
* @return {RGBA}
|
|
667
|
+
* @api private
|
|
668
|
+
*/
|
|
669
|
+
|
|
670
|
+
exports['-adjust'] = function adjust(color, prop, amount){
|
|
671
|
+
var hsl = color.hsla.clone();
|
|
672
|
+
prop = { hue: 'h', saturation: 's', lightness: 'l' }[prop.string];
|
|
673
|
+
if (!prop) throw new Error('invalid adjustment property');
|
|
674
|
+
var val = amount.val;
|
|
675
|
+
if ('%' == amount.type){
|
|
676
|
+
val = 'l' == prop && val > 0
|
|
677
|
+
? (100 - hsl[prop]) * val / 100
|
|
678
|
+
: hsl[prop] * (val / 100);
|
|
679
|
+
}
|
|
680
|
+
hsl[prop] += val;
|
|
681
|
+
return hsl.rgba;
|
|
682
|
+
};
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Return a clone of the given `expr`.
|
|
686
|
+
*
|
|
687
|
+
* @param {Expression} expr
|
|
688
|
+
* @return {Node}
|
|
689
|
+
* @api public
|
|
690
|
+
*/
|
|
691
|
+
|
|
692
|
+
(exports.clone = function clone(expr){
|
|
693
|
+
utils.assertPresent(expr, 'expr');
|
|
694
|
+
return expr.clone();
|
|
695
|
+
}).raw = true;
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Add property `name` with the given `expr`
|
|
699
|
+
* to the mixin-able block.
|
|
700
|
+
*
|
|
701
|
+
* @param {String|Ident|Literal} name
|
|
702
|
+
* @param {Expression} expr
|
|
703
|
+
* @return {Property}
|
|
704
|
+
* @api public
|
|
705
|
+
*/
|
|
706
|
+
|
|
707
|
+
(exports['add-property'] = function addProperty(name, expr){
|
|
708
|
+
utils.assertType(name, 'expression', 'name');
|
|
709
|
+
name = utils.unwrap(name).first;
|
|
710
|
+
utils.assertString(name, 'name');
|
|
711
|
+
utils.assertType(expr, 'expression', 'expr');
|
|
712
|
+
var prop = new nodes.Property([name], expr);
|
|
713
|
+
var block = this.closestBlock;
|
|
714
|
+
|
|
715
|
+
var len = block.nodes.length
|
|
716
|
+
, head = block.nodes.slice(0, block.index)
|
|
717
|
+
, tail = block.nodes.slice(block.index++, len);
|
|
718
|
+
head.push(prop);
|
|
719
|
+
block.nodes = head.concat(tail);
|
|
720
|
+
|
|
721
|
+
return prop;
|
|
722
|
+
}).raw = true;
|