diff options
Diffstat (limited to 'node_modules/stylus/lib/functions')
67 files changed, 2705 insertions, 0 deletions
diff --git a/node_modules/stylus/lib/functions/add-property.js b/node_modules/stylus/lib/functions/add-property.js new file mode 100644 index 00000000..dfe55caf --- /dev/null +++ b/node_modules/stylus/lib/functions/add-property.js @@ -0,0 +1,29 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Add property `name` with the given `expr` + * to the mixin-able block. + * + * @param {String|Ident|Literal} name + * @param {Expression} expr + * @return {Property} + * @api public + */ + +(module.exports = function addProperty(name, expr){ + utils.assertType(name, 'expression', 'name'); + name = utils.unwrap(name).first; + utils.assertString(name, 'name'); + utils.assertType(expr, 'expression', 'expr'); + var prop = new nodes.Property([name], expr); + var block = this.closestBlock; + + var len = block.nodes.length + , head = block.nodes.slice(0, block.index) + , tail = block.nodes.slice(block.index++, len); + head.push(prop); + block.nodes = head.concat(tail); + + return prop; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/adjust.js b/node_modules/stylus/lib/functions/adjust.js new file mode 100644 index 00000000..58abb7ae --- /dev/null +++ b/node_modules/stylus/lib/functions/adjust.js @@ -0,0 +1,28 @@ +var utils = require('../utils'); + +/** + * Adjust HSL `color` `prop` by `amount`. + * + * @param {RGBA|HSLA} color + * @param {String} prop + * @param {Unit} amount + * @return {RGBA} + * @api private + */ + +module.exports = function adjust(color, prop, amount){ + utils.assertColor(color, 'color'); + utils.assertString(prop, 'prop'); + utils.assertType(amount, 'unit', 'amount'); + var hsl = color.hsla.clone(); + prop = { hue: 'h', saturation: 's', lightness: 'l' }[prop.string]; + if (!prop) throw new Error('invalid adjustment property'); + var val = amount.val; + if ('%' == amount.type){ + val = 'l' == prop && val > 0 + ? (100 - hsl[prop]) * val / 100 + : hsl[prop] * (val / 100); + } + hsl[prop] += val; + return hsl.rgba; +}; diff --git a/node_modules/stylus/lib/functions/alpha.js b/node_modules/stylus/lib/functions/alpha.js new file mode 100644 index 00000000..769a276b --- /dev/null +++ b/node_modules/stylus/lib/functions/alpha.js @@ -0,0 +1,36 @@ +var nodes = require('../nodes') + , rgba = require('./rgba'); + +/** + * Return the alpha component of the given `color`, + * or set the alpha component to the optional second `value` argument. + * + * Examples: + * + * alpha(#fff) + * // => 1 + * + * alpha(rgba(0,0,0,0.3)) + * // => 0.3 + * + * alpha(#fff, 0.5) + * // => rgba(255,255,255,0.5) + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function alpha(color, value){ + color = color.rgba; + if (value) { + return rgba( + new nodes.Unit(color.r), + new nodes.Unit(color.g), + new nodes.Unit(color.b), + value + ); + } + return new nodes.Unit(color.a, ''); +}; diff --git a/node_modules/stylus/lib/functions/base-convert.js b/node_modules/stylus/lib/functions/base-convert.js new file mode 100644 index 00000000..55150948 --- /dev/null +++ b/node_modules/stylus/lib/functions/base-convert.js @@ -0,0 +1,26 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Return a `Literal` `num` converted to the provided `base`, padded to `width` + * with zeroes (default width is 2) + * + * @param {Number} num + * @param {Number} base + * @param {Number} width + * @return {Literal} + * @api public + */ + +(module.exports = function(num, base, width) { + utils.assertPresent(num, 'number'); + utils.assertPresent(base, 'base'); + num = utils.unwrap(num).nodes[0].val; + base = utils.unwrap(base).nodes[0].val; + width = (width && utils.unwrap(width).nodes[0].val) || 2; + var result = Number(num).toString(base); + while (result.length < width) { + result = '0' + result; + } + return new nodes.Literal(result); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/basename.js b/node_modules/stylus/lib/functions/basename.js new file mode 100644 index 00000000..e1a32831 --- /dev/null +++ b/node_modules/stylus/lib/functions/basename.js @@ -0,0 +1,15 @@ +var utils = require('../utils') + , path = require('path'); + +/** + * Return the basename of `path`. + * + * @param {String} path + * @return {String} + * @api public + */ + +module.exports = function basename(p, ext){ + utils.assertString(p, 'path'); + return path.basename(p.val, ext && ext.val); +}; diff --git a/node_modules/stylus/lib/functions/blend.js b/node_modules/stylus/lib/functions/blend.js new file mode 100644 index 00000000..537e8978 --- /dev/null +++ b/node_modules/stylus/lib/functions/blend.js @@ -0,0 +1,37 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Blend the `top` color over the `bottom` + * + * Examples: + * + * blend(rgba(#FFF, 0.5), #000) + * // => #808080 + * + * blend(rgba(#FFDE00,.42), #19C261) + * // => #7ace38 + * + * blend(rgba(lime, 0.5), rgba(red, 0.25)) + * // => rgba(128,128,0,0.625) + * + * @param {RGBA|HSLA} top + * @param {RGBA|HSLA} [bottom=#fff] + * @return {RGBA} + * @api public + */ + +module.exports = function blend(top, bottom){ + // TODO: different blend modes like overlay etc. + utils.assertColor(top); + top = top.rgba; + bottom = bottom || new nodes.RGBA(255, 255, 255, 1); + utils.assertColor(bottom); + bottom = bottom.rgba; + + return new nodes.RGBA( + top.r * top.a + bottom.r * (1 - top.a), + top.g * top.a + bottom.g * (1 - top.a), + top.b * top.a + bottom.b * (1 - top.a), + top.a + bottom.a - top.a * bottom.a); +}; diff --git a/node_modules/stylus/lib/functions/blue.js b/node_modules/stylus/lib/functions/blue.js new file mode 100644 index 00000000..c07895cb --- /dev/null +++ b/node_modules/stylus/lib/functions/blue.js @@ -0,0 +1,33 @@ +var nodes = require('../nodes') + , rgba = require('./rgba'); + +/** + * Return the blue component of the given `color`, + * or set the blue component to the optional second `value` argument. + * + * Examples: + * + * blue(#00c) + * // => 204 + * + * blue(#000, 255) + * // => #00f + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function blue(color, value){ + color = color.rgba; + if (value) { + return rgba( + new nodes.Unit(color.r), + new nodes.Unit(color.g), + value, + new nodes.Unit(color.a) + ); + } + return new nodes.Unit(color.b, ''); +}; diff --git a/node_modules/stylus/lib/functions/clone.js b/node_modules/stylus/lib/functions/clone.js new file mode 100644 index 00000000..38c02c54 --- /dev/null +++ b/node_modules/stylus/lib/functions/clone.js @@ -0,0 +1,14 @@ +var utils = require('../utils'); + +/** + * Return a clone of the given `expr`. + * + * @param {Expression} expr + * @return {Node} + * @api public + */ + +(module.exports = function clone(expr){ + utils.assertPresent(expr, 'expr'); + return expr.clone(); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/component.js b/node_modules/stylus/lib/functions/component.js new file mode 100644 index 00000000..37a9b237 --- /dev/null +++ b/node_modules/stylus/lib/functions/component.js @@ -0,0 +1,60 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Color component name map. + */ + +var componentMap = { + red: 'r' + , green: 'g' + , blue: 'b' + , alpha: 'a' + , hue: 'h' + , saturation: 's' + , lightness: 'l' +}; + +/** + * Color component unit type map. + */ + +var unitMap = { + hue: 'deg' + , saturation: '%' + , lightness: '%' +}; + +/** + * Color type map. + */ + +var typeMap = { + red: 'rgba' + , blue: 'rgba' + , green: 'rgba' + , alpha: 'rgba' + , hue: 'hsla' + , saturation: 'hsla' + , lightness: 'hsla' +}; + +/** + * Return component `name` for the given `color`. + * + * @param {RGBA|HSLA} color + * @param {String} name + * @return {Unit} + * @api public + */ + +module.exports = function component(color, name) { + utils.assertColor(color, 'color'); + utils.assertString(name, 'name'); + var name = name.string + , unit = unitMap[name] + , type = typeMap[name] + , name = componentMap[name]; + if (!name) throw new Error('invalid color component "' + name + '"'); + return new nodes.Unit(color[type][name], unit); +}; diff --git a/node_modules/stylus/lib/functions/contrast.js b/node_modules/stylus/lib/functions/contrast.js new file mode 100644 index 00000000..7e59c891 --- /dev/null +++ b/node_modules/stylus/lib/functions/contrast.js @@ -0,0 +1,75 @@ +var utils = require('../utils') + , nodes = require('../nodes') + , blend = require('./blend') + , luminosity = require('./luminosity'); + +/** + * Returns the contrast ratio object between `top` and `bottom` colors, + * based on http://leaverou.github.io/contrast-ratio/ + * and https://github.com/LeaVerou/contrast-ratio/blob/gh-pages/color.js#L108 + * + * Examples: + * + * contrast(#000, #fff).ratio + * => 21 + * + * contrast(#000, rgba(#FFF, 0.5)) + * => { "ratio": "13.15;", "error": "7.85", "min": "5.3", "max": "21" } + * + * @param {RGBA|HSLA} top + * @param {RGBA|HSLA} [bottom=#fff] + * @return {Object} + * @api public + */ + +module.exports = function contrast(top, bottom){ + if ('rgba' != top.nodeName && 'hsla' != top.nodeName) { + return new nodes.Literal('contrast(' + (top.isNull ? '' : top.toString()) + ')'); + } + var result = new nodes.Object(); + top = top.rgba; + bottom = bottom || new nodes.RGBA(255, 255, 255, 1); + utils.assertColor(bottom); + bottom = bottom.rgba; + function contrast(top, bottom) { + if (1 > top.a) { + top = blend(top, bottom); + } + var l1 = luminosity(bottom).val + 0.05 + , l2 = luminosity(top).val + 0.05 + , ratio = l1 / l2; + + if (l2 > l1) { + ratio = 1 / ratio; + } + return Math.round(ratio * 10) / 10; + } + + if (1 <= bottom.a) { + var resultRatio = new nodes.Unit(contrast(top, bottom)); + result.set('ratio', resultRatio); + result.set('error', new nodes.Unit(0)); + result.set('min', resultRatio); + result.set('max', resultRatio); + } else { + var onBlack = contrast(top, blend(bottom, new nodes.RGBA(0, 0, 0, 1))) + , onWhite = contrast(top, blend(bottom, new nodes.RGBA(255, 255, 255, 1))) + , max = Math.max(onBlack, onWhite); + function processChannel(topChannel, bottomChannel) { + return Math.min(Math.max(0, (topChannel - bottomChannel * bottom.a) / (1 - bottom.a)), 255); + } + var closest = new nodes.RGBA( + processChannel(top.r, bottom.r), + processChannel(top.g, bottom.g), + processChannel(top.b, bottom.b), + 1 + ); + var min = contrast(top, blend(bottom, closest)); + + result.set('ratio', new nodes.Unit(Math.round((min + max) * 50) / 100)); + result.set('error', new nodes.Unit(Math.round((max - min) * 50) / 100)); + result.set('min', new nodes.Unit(min)); + result.set('max', new nodes.Unit(max)); + } + return result; +} diff --git a/node_modules/stylus/lib/functions/convert.js b/node_modules/stylus/lib/functions/convert.js new file mode 100644 index 00000000..d64f1631 --- /dev/null +++ b/node_modules/stylus/lib/functions/convert.js @@ -0,0 +1,15 @@ +var utils = require('../utils'); + +/** + * Like `unquote` but tries to convert + * the given `str` to a Stylus node. + * + * @param {String} str + * @return {Node} + * @api public + */ + +module.exports = function convert(str){ + utils.assertString(str, 'str'); + return utils.parseString(str.string); +}; diff --git a/node_modules/stylus/lib/functions/current-media.js b/node_modules/stylus/lib/functions/current-media.js new file mode 100644 index 00000000..e88e3e81 --- /dev/null +++ b/node_modules/stylus/lib/functions/current-media.js @@ -0,0 +1,22 @@ +var nodes = require('../nodes'); + +/** + * Returns the @media string for the current block + * + * @return {String} + * @api public + */ + +module.exports = function currentMedia(){ + var self = this; + return new nodes.String(lookForMedia(this.closestBlock.node) || ''); + + function lookForMedia(node){ + if ('media' == node.nodeName) { + node.val = self.visit(node.val); + return node.toString(); + } else if (node.block.parent.node) { + return lookForMedia(node.block.parent.node); + } + } +}; diff --git a/node_modules/stylus/lib/functions/define.js b/node_modules/stylus/lib/functions/define.js new file mode 100644 index 00000000..35b704f6 --- /dev/null +++ b/node_modules/stylus/lib/functions/define.js @@ -0,0 +1,23 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Set a variable `name` on current scope. + * + * @param {String} name + * @param {Expression} expr + * @param {Boolean} [global] + * @api public + */ + +module.exports = function define(name, expr, global){ + utils.assertType(name, 'string', 'name'); + expr = utils.unwrap(expr); + var scope = this.currentScope; + if (global && global.toBoolean().isTrue) { + scope = this.global.scope; + } + var node = new nodes.Ident(name.val, expr); + scope.add(node); + return nodes.null; +}; diff --git a/node_modules/stylus/lib/functions/dirname.js b/node_modules/stylus/lib/functions/dirname.js new file mode 100644 index 00000000..469c82a8 --- /dev/null +++ b/node_modules/stylus/lib/functions/dirname.js @@ -0,0 +1,15 @@ +var utils = require('../utils') + , path = require('path'); + +/** + * Return the dirname of `path`. + * + * @param {String} path + * @return {String} + * @api public + */ + +module.exports = function dirname(p){ + utils.assertString(p, 'path'); + return path.dirname(p.val).replace(/\\/g, '/'); +}; diff --git a/node_modules/stylus/lib/functions/error.js b/node_modules/stylus/lib/functions/error.js new file mode 100644 index 00000000..0330552f --- /dev/null +++ b/node_modules/stylus/lib/functions/error.js @@ -0,0 +1,15 @@ +var utils = require('../utils'); + +/** + * Throw an error with the given `msg`. + * + * @param {String} msg + * @api public + */ + +module.exports = function error(msg){ + utils.assertType(msg, 'string', 'msg'); + var err = new Error(msg.val); + err.fromStylus = true; + throw err; +}; diff --git a/node_modules/stylus/lib/functions/extname.js b/node_modules/stylus/lib/functions/extname.js new file mode 100644 index 00000000..d425045d --- /dev/null +++ b/node_modules/stylus/lib/functions/extname.js @@ -0,0 +1,15 @@ +var utils = require('../utils') + , path = require('path'); + +/** + * Return the extname of `path`. + * + * @param {String} path + * @return {String} + * @api public + */ + +module.exports = function extname(p){ + utils.assertString(p, 'path'); + return path.extname(p.val); +}; diff --git a/node_modules/stylus/lib/functions/green.js b/node_modules/stylus/lib/functions/green.js new file mode 100644 index 00000000..355b56a5 --- /dev/null +++ b/node_modules/stylus/lib/functions/green.js @@ -0,0 +1,33 @@ +var nodes = require('../nodes') + , rgba = require('./rgba'); + +/** + * Return the green component of the given `color`, + * or set the green component to the optional second `value` argument. + * + * Examples: + * + * green(#0c0) + * // => 204 + * + * green(#000, 255) + * // => #0f0 + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function green(color, value){ + color = color.rgba; + if (value) { + return rgba( + new nodes.Unit(color.r), + value, + new nodes.Unit(color.b), + new nodes.Unit(color.a) + ); + } + return new nodes.Unit(color.g, ''); +}; diff --git a/node_modules/stylus/lib/functions/hsl.js b/node_modules/stylus/lib/functions/hsl.js new file mode 100644 index 00000000..960eb237 --- /dev/null +++ b/node_modules/stylus/lib/functions/hsl.js @@ -0,0 +1,35 @@ +var utils = require('../utils') + , nodes = require('../nodes') + , hsla = require('./hsla'); + +/** + * Convert the given `color` to an `HSLA` node, + * or h,s,l component values. + * + * Examples: + * + * hsl(10, 50, 30) + * // => HSLA + * + * hsl(#ffcc00) + * // => HSLA + * + * @param {Unit|HSLA|RGBA} hue + * @param {Unit} saturation + * @param {Unit} lightness + * @return {HSLA} + * @api public + */ + +module.exports = function hsl(hue, saturation, lightness){ + if (1 == arguments.length) { + utils.assertColor(hue, 'color'); + return hue.hsla; + } else { + return hsla( + hue + , saturation + , lightness + , new nodes.Unit(1)); + } +}; diff --git a/node_modules/stylus/lib/functions/hsla.js b/node_modules/stylus/lib/functions/hsla.js new file mode 100644 index 00000000..484f9ae6 --- /dev/null +++ b/node_modules/stylus/lib/functions/hsla.js @@ -0,0 +1,53 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Convert the given `color` to an `HSLA` node, + * or h,s,l,a component values. + * + * Examples: + * + * hsla(10deg, 50%, 30%, 0.5) + * // => HSLA + * + * hsla(#ffcc00) + * // => HSLA + * + * @param {RGBA|HSLA|Unit} hue + * @param {Unit} saturation + * @param {Unit} lightness + * @param {Unit} alpha + * @return {HSLA} + * @api public + */ + +module.exports = function hsla(hue, saturation, lightness, alpha){ + switch (arguments.length) { + case 1: + utils.assertColor(hue); + return hue.hsla; + case 2: + utils.assertColor(hue); + var color = hue.hsla; + utils.assertType(saturation, 'unit', 'alpha'); + var alpha = saturation.clone(); + if ('%' == alpha.type) alpha.val /= 100; + return new nodes.HSLA( + color.h + , color.s + , color.l + , alpha.val); + default: + utils.assertType(hue, 'unit', 'hue'); + utils.assertType(saturation, 'unit', 'saturation'); + utils.assertType(lightness, 'unit', 'lightness'); + utils.assertType(alpha, 'unit', 'alpha'); + var alpha = alpha.clone(); + if (alpha && '%' == alpha.type) alpha.val /= 100; + return new nodes.HSLA( + hue.val + , saturation.val + , lightness.val + , alpha.val); + } +}; diff --git a/node_modules/stylus/lib/functions/hue.js b/node_modules/stylus/lib/functions/hue.js new file mode 100644 index 00000000..3652f9d3 --- /dev/null +++ b/node_modules/stylus/lib/functions/hue.js @@ -0,0 +1,34 @@ +var nodes = require('../nodes') + , hsla = require('./hsla') + , component = require('./component'); + +/** + * Return the hue component of the given `color`, + * or set the hue component to the optional second `value` argument. + * + * Examples: + * + * hue(#00c) + * // => 240deg + * + * hue(#00c, 90deg) + * // => #6c0 + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function hue(color, value){ + if (value) { + var hslaColor = color.hsla; + return hsla( + value, + new nodes.Unit(hslaColor.s), + new nodes.Unit(hslaColor.l), + new nodes.Unit(hslaColor.a) + ) + } + return component(color, new nodes.String('hue')); +}; diff --git a/node_modules/stylus/lib/functions/image-size.js b/node_modules/stylus/lib/functions/image-size.js new file mode 100644 index 00000000..56fab0cd --- /dev/null +++ b/node_modules/stylus/lib/functions/image-size.js @@ -0,0 +1,58 @@ +var utils = require('../utils') + , nodes = require('../nodes') + , Image = require('./image'); + +/** + * Return the width and height of the given `img` path. + * + * Examples: + * + * image-size('foo.png') + * // => 200px 100px + * + * image-size('foo.png')[0] + * // => 200px + * + * image-size('foo.png')[1] + * // => 100px + * + * Can be used to test if the image exists, + * using an optional argument set to `true` + * (without this argument this function throws error + * if there is no such image). + * + * Example: + * + * image-size('nosuchimage.png', true)[0] + * // => 0 + * + * @param {String} img + * @param {Boolean} ignoreErr + * @return {Expression} + * @api public + */ + +module.exports = function imageSize(img, ignoreErr) { + utils.assertType(img, 'string', 'img'); + try { + var img = new Image(this, img.string); + } catch (err) { + if (ignoreErr) { + return [new nodes.Unit(0), new nodes.Unit(0)]; + } else { + throw err; + } + } + + // Read size + img.open(); + var size = img.size(); + img.close(); + + // Return (w h) + var expr = []; + expr.push(new nodes.Unit(size[0], 'px')); + expr.push(new nodes.Unit(size[1], 'px')); + + return expr; +}; diff --git a/node_modules/stylus/lib/functions/image.js b/node_modules/stylus/lib/functions/image.js new file mode 100644 index 00000000..5a2c186c --- /dev/null +++ b/node_modules/stylus/lib/functions/image.js @@ -0,0 +1,162 @@ + + +/*! + * Stylus - plugin - url + * Copyright (c) Automattic <developer.wordpress.com> + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('../utils') + , nodes = require('../nodes') + , fs = require('fs') + , path = require('path') + , sax = require('sax'); + +/** + * Initialize a new `Image` with the given `ctx` and `path. + * + * @param {Evaluator} ctx + * @param {String} path + * @api private + */ + +var Image = module.exports = function Image(ctx, path) { + this.ctx = ctx; + this.path = utils.lookup(path, ctx.paths); + if (!this.path) throw new Error('failed to locate file ' + path); +}; + +/** + * Open the image for reading. + * + * @api private + */ + +Image.prototype.open = function(){ + this.fd = fs.openSync(this.path, 'r'); + this.length = fs.fstatSync(this.fd).size; + this.extname = path.extname(this.path).slice(1); +}; + +/** + * Close the file. + * + * @api private + */ + +Image.prototype.close = function(){ + if (this.fd) fs.closeSync(this.fd); +}; + +/** + * Return the type of image, supports: + * + * - gif + * - png + * - jpeg + * - svg + * + * @return {String} + * @api private + */ + +Image.prototype.type = function(){ + var type + , buf = new Buffer(4); + + fs.readSync(this.fd, buf, 0, 4, 0); + + // GIF + if (0x47 == buf[0] && 0x49 == buf[1] && 0x46 == buf[2]) type = 'gif'; + + // PNG + else if (0x50 == buf[1] && 0x4E == buf[2] && 0x47 == buf[3]) type = 'png'; + + // JPEG + else if (0xff == buf[0] && 0xd8 == buf[1]) type = 'jpeg'; + + // SVG + else if ('svg' == this.extname) type = this.extname; + + return type; +}; + +/** + * Return image dimensions `[width, height]`. + * + * @return {Array} + * @api private + */ + +Image.prototype.size = function(){ + var type = this.type() + , width + , height + , buf + , offset + , blockSize + , parser; + + function uint16(b) { return b[1] << 8 | b[0]; } + function uint32(b) { return b[0] << 24 | b[1] << 16 | b[2] << 8 | b[3]; } + + // Determine dimensions + switch (type) { + case 'jpeg': + buf = new Buffer(this.length); + fs.readSync(this.fd, buf, 0, this.length, 0); + offset = 4; + blockSize = buf[offset] << 8 | buf[offset + 1]; + + while (offset < this.length) { + offset += blockSize; + if (offset >= this.length || 0xff != buf[offset]) break; + // SOF0 or SOF2 (progressive) + if (0xc0 == buf[offset + 1] || 0xc2 == buf[offset + 1]) { + height = buf[offset + 5] << 8 | buf[offset + 6]; + width = buf[offset + 7] << 8 | buf[offset + 8]; + } else { + offset += 2; + blockSize = buf[offset] << 8 | buf[offset + 1]; + } + } + break; + case 'png': + buf = new Buffer(8); + // IHDR chunk width / height uint32_t big-endian + fs.readSync(this.fd, buf, 0, 8, 16); + width = uint32(buf); + height = uint32(buf.slice(4, 8)); + break; + case 'gif': + buf = new Buffer(4); + // width / height uint16_t little-endian + fs.readSync(this.fd, buf, 0, 4, 6); + width = uint16(buf); + height = uint16(buf.slice(2, 4)); + break; + case 'svg': + offset = Math.min(this.length, 1024); + buf = new Buffer(offset); + fs.readSync(this.fd, buf, 0, offset, 0); + buf = buf.toString('utf8'); + parser = sax.parser(true); + parser.onopentag = function(node) { + if ('svg' == node.name && node.attributes.width && node.attributes.height) { + width = parseInt(node.attributes.width, 10); + height = parseInt(node.attributes.height, 10); + } + }; + parser.write(buf).close(); + break; + } + + if ('number' != typeof width) throw new Error('failed to find width of "' + this.path + '"'); + if ('number' != typeof height) throw new Error('failed to find height of "' + this.path + '"'); + + return [width, height]; +}; diff --git a/node_modules/stylus/lib/functions/index.js b/node_modules/stylus/lib/functions/index.js new file mode 100644 index 00000000..e292ed47 --- /dev/null +++ b/node_modules/stylus/lib/functions/index.js @@ -0,0 +1,69 @@ + +/*! + * Stylus - Evaluator - built-in functions + * Copyright (c) Automattic <developer.wordpress.com> + * MIT Licensed + */ + +exports['add-property'] = require('./add-property'); +exports.adjust = require('./adjust'); +exports.alpha = require('./alpha'); +exports['base-convert'] = require('./base-convert'); +exports.basename = require('./basename'); +exports.blend = require('./blend'); +exports.blue = require('./blue'); +exports.clone = require('./clone'); +exports.component = require('./component'); +exports.contrast = require('./contrast'); +exports.convert = require('./convert'); +exports['current-media'] = require('./current-media'); +exports.define = require('./define'); +exports.dirname = require('./dirname'); +exports.error = require('./error'); +exports.extname = require('./extname'); +exports.green = require('./green'); +exports.hsl = require('./hsl'); +exports.hsla = require('./hsla'); +exports.hue = require('./hue'); +exports['image-size'] = require('./image-size'); +exports.json = require('./json'); +exports.length = require('./length'); +exports.lightness = require('./lightness'); +exports['list-separator'] = require('./list-separator'); +exports.lookup = require('./lookup'); +exports.luminosity = require('./luminosity'); +exports.match = require('./match'); +exports.math = require('./math'); +exports.merge = exports.extend = require('./merge'); +exports.operate = require('./operate'); +exports['opposite-position'] = require('./opposite-position'); +exports.p = require('./p'); +exports.pathjoin = require('./pathjoin'); +exports.pop = require('./pop'); +exports.push = exports.append = require('./push'); +exports.range = require('./range'); +exports.red = require('./red'); +exports.remove = require('./remove'); +exports.replace = require('./replace'); +exports.rgb = require('./rgb'); +exports.rgba = require('./rgba'); +exports.s = require('./s'); +exports.saturation = require('./saturation'); +exports['selector-exists'] = require('./selector-exists'); +exports.selector = require('./selector'); +exports.selectors = require('./selectors'); +exports.shift = require('./shift'); +exports.split = require('./split'); +exports.substr = require('./substr'); +exports.slice = require('./slice'); +exports.tan = require('./tan'); +exports.trace = require('./trace'); +exports.transparentify = require('./transparentify'); +exports.type = exports.typeof = exports['type-of'] = require('./type'); +exports.unit = require('./unit'); +exports.unquote = require('./unquote'); +exports.unshift = exports.prepend = require('./unshift'); +exports.use = require('./use'); +exports.warn = require('./warn'); +exports['-math-prop'] = require('./math-prop'); +exports['-prefix-classes'] = require('./prefix-classes'); diff --git a/node_modules/stylus/lib/functions/index.styl b/node_modules/stylus/lib/functions/index.styl new file mode 100644 index 00000000..2ac9eba5 --- /dev/null +++ b/node_modules/stylus/lib/functions/index.styl @@ -0,0 +1,297 @@ +called-from = () + +vendors = moz webkit o ms official + +// stringify the given arg + +-string(arg) + type(arg) + ' ' + arg + +// require a color + +require-color(color) + unless color is a 'color' + error('RGB or HSL value expected, got a ' + -string(color)) + +// require a unit + +require-unit(n) + unless n is a 'unit' + error('unit expected, got a ' + -string(n)) + +// require a string + +require-string(str) + unless str is a 'string' or str is a 'ident' + error('string expected, got a ' + -string(str)) + +// Math functions + +abs(n) { math(n, 'abs') } +min(a, b) { a < b ? a : b } +max(a, b) { a > b ? a : b } + +// Trigonometrics +PI = -math-prop('PI') + +radians-to-degrees(angle) + angle * (180 / PI) + +degrees-to-radians(angle) + unit(angle * (PI / 180),'') + +sin(n) + n = degrees-to-radians(n) if unit(n) == 'deg' + round(math(n, 'sin'), 9) + +cos(n) + n = degrees-to-radians(n) if unit(n) == 'deg' + round(math(n, 'cos'), 9) + +// Rounding Math functions + +ceil(n, precision = 0) + multiplier = 10 ** precision + math(n * multiplier, 'ceil') / multiplier + +floor(n, precision = 0) + multiplier = 10 ** precision + math(n * multiplier, 'floor') / multiplier + +round(n, precision = 0) + multiplier = 10 ** precision + math(n * multiplier, 'round') / multiplier + +// return the sum of the given numbers + +sum(nums) + sum = 0 + sum += n for n in nums + +// return the average of the given numbers + +avg(nums) + sum(nums) / length(nums) + +// return a unitless number, or pass through + +remove-unit(n) + if typeof(n) is "unit" + unit(n, "") + else + n + +// convert a percent to a decimal, or pass through + +percent-to-decimal(n) + if unit(n) is "%" + remove-unit(n) / 100 + else + n + +// check if n is an odd number + +odd(n) + 1 == n % 2 + +// check if n is an even number + +even(n) + 0 == n % 2 + +// check if color is light + +light(color) + lightness(color) >= 50% + +// check if color is dark + +dark(color) + lightness(color) < 50% + +// desaturate color by amount + +desaturate(color, amount) + adjust(color, 'saturation', - amount) + +// saturate color by amount + +saturate(color = '', amount = 100%) + if color is a 'color' + adjust(color, 'saturation', amount) + else + unquote( "saturate(" + color + ")" ) + +// darken by the given amount + +darken(color, amount) + adjust(color, 'lightness', - amount) + +// lighten by the given amount + +lighten(color, amount) + adjust(color, 'lightness', amount) + +// decrease opacity by amount + +fade-out(color, amount) + color - rgba(black, percent-to-decimal(amount)) + +// increase opacity by amount + +fade-in(color, amount) + color + rgba(black, percent-to-decimal(amount)) + +// spin hue by a given amount + +spin(color, amount) + color + unit(amount, deg) + +// mix two colors by a given amount + +mix(color1, color2, weight = 50%) + unless weight in 0..100 + error("Weight must be between 0% and 100%") + + if length(color1) == 2 + weight = color1[0] + color1 = color1[1] + + else if length(color2) == 2 + weight = 100 - color2[0] + color2 = color2[1] + + require-color(color1) + require-color(color2) + + p = unit(weight / 100, '') + w = p * 2 - 1 + + a = alpha(color1) - alpha(color2) + + w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2 + w2 = 1 - w1 + + channels = (red(color1) red(color2)) (green(color1) green(color2)) (blue(color1) blue(color2)) + rgb = () + + for pair in channels + push(rgb, floor(pair[0] * w1 + pair[1] * w2)) + + a1 = alpha(color1) * p + a2 = alpha(color2) * (1 - p) + alpha = a1 + a2 + + rgba(rgb[0], rgb[1], rgb[2], alpha) + +// invert colors, leave alpha intact + +invert(color = '') + if color is a 'color' + rgba(#fff - color, alpha(color)) + else + unquote( "invert(" + color + ")" ) + +// give complement of the given color + +complement( color ) + spin( color, 180 ) + +// give grayscale of the given color + +grayscale( color = '' ) + if color is a 'color' + desaturate( color, 100% ) + else + unquote( "grayscale(" + color + ")" ) + +// mix the given color with white + +tint( color, percent ) + mix( white, color, percent ) + +// mix the given color with black + +shade( color, percent ) + mix( black, color, percent ) + +// return the last value in the given expr + +last(expr) + expr[length(expr) - 1] + +// return keys in the given pairs or object + +keys(pairs) + ret = () + if type(pairs) == 'object' + for key in pairs + push(ret, key) + else + for pair in pairs + push(ret, pair[0]); + ret + +// return values in the given pairs or object + +values(pairs) + ret = () + if type(pairs) == 'object' + for key, val in pairs + push(ret, val) + else + for pair in pairs + push(ret, pair[1]); + ret + +// join values with the given delimiter + +join(delim, vals...) + buf = '' + vals = vals[0] if length(vals) == 1 + for val, i in vals + buf += i ? delim + val : val + +// add a CSS rule to the containing block + +// - This definition allows add-property to be used as a mixin +// - It has the same effect as interpolation but allows users +// to opt for a functional style + +add-property-function = add-property +add-property(name, expr) + if mixin + {name} expr + else + add-property-function(name, expr) + +prefix-classes(prefix) + -prefix-classes(prefix, block) + +// Caching mixin, use inside your functions to enable caching by extending. + +$stylus_mixin_cache = {} +cache() + $key = (current-media() or 'no-media') + '__' + called-from[0] + '__' + arguments + if $key in $stylus_mixin_cache + @extend {"$cache_placeholder_for_" + $stylus_mixin_cache[$key]} + else if 'cache' in called-from + {block} + else + $id = length($stylus_mixin_cache) + + &, + /$cache_placeholder_for_{$id} + $stylus_mixin_cache[$key] = $id + {block} + +// Percentage function to convert a number, e.g. ".45", into a percentage, e.g. "45%" + +percentage(num) + return unit(num * 100, '%') + +// Returns the position of a `value` within a `list` + +index(list, value) + for val, i in list + return i if val == value diff --git a/node_modules/stylus/lib/functions/json.js b/node_modules/stylus/lib/functions/json.js new file mode 100644 index 00000000..6b9c5d56 --- /dev/null +++ b/node_modules/stylus/lib/functions/json.js @@ -0,0 +1,116 @@ +var utils = require('../utils') + , nodes = require('../nodes') + , readFile = require('fs').readFileSync; + +/** + * Convert a .json file into stylus variables or object. + * Nested variable object keys are joined with a dash (-) + * + * Given this sample media-queries.json file: + * { + * "small": "screen and (max-width:400px)", + * "tablet": { + * "landscape": "screen and (min-width:600px) and (orientation:landscape)", + * "portrait": "screen and (min-width:600px) and (orientation:portrait)" + * } + * } + * + * Examples: + * + * json('media-queries.json') + * + * @media small + * // => @media screen and (max-width:400px) + * + * @media tablet-landscape + * // => @media screen and (min-width:600px) and (orientation:landscape) + * + * vars = json('vars.json', { hash: true }) + * body + * width: vars.width + * + * @param {String} path + * @param {Boolean} [local] + * @param {String} [namePrefix] + * @api public +*/ + +module.exports = function(path, local, namePrefix){ + utils.assertString(path, 'path'); + + // lookup + path = path.string; + var found = utils.lookup(path, this.options.paths, this.options.filename) + , options = (local && 'object' == local.nodeName) && local; + + if (!found) { + // optional JSON file + if (options && options.get('optional').toBoolean().isTrue) { + return nodes.null; + } + throw new Error('failed to locate .json file ' + path); + } + + // read + var json = JSON.parse(readFile(found, 'utf8')); + + if (options) { + return convert(json, options); + } else { + oldJson.call(this, json, local, namePrefix); + } + + function convert(obj, options){ + var ret = new nodes.Object() + , leaveStrings = options.get('leave-strings').toBoolean(); + + for (var key in obj) { + var val = obj[key]; + if ('object' == typeof val) { + ret.set(key, convert(val, options)); + } else { + val = utils.coerce(val); + if ('string' == val.nodeName && leaveStrings.isFalse) { + val = utils.parseString(val.string); + } + ret.set(key, val); + } + } + return ret; + } +}; + +/** + * Old `json` BIF. + * + * @api private + */ + +function oldJson(json, local, namePrefix){ + if (namePrefix) { + utils.assertString(namePrefix, 'namePrefix'); + namePrefix = namePrefix.val; + } else { + namePrefix = ''; + } + local = local ? local.toBoolean() : new nodes.Boolean(local); + var scope = local.isTrue ? this.currentScope : this.global.scope; + + convert(json); + return; + + function convert(obj, prefix){ + prefix = prefix ? prefix + '-' : ''; + for (var key in obj){ + var val = obj[key]; + var name = prefix + key; + if ('object' == typeof val) { + convert(val, name); + } else { + val = utils.coerce(val); + if ('string' == val.nodeName) val = utils.parseString(val.string); + scope.add({ name: namePrefix + name, val: val }); + } + } + } +}; diff --git a/node_modules/stylus/lib/functions/length.js b/node_modules/stylus/lib/functions/length.js new file mode 100644 index 00000000..8c0a1c98 --- /dev/null +++ b/node_modules/stylus/lib/functions/length.js @@ -0,0 +1,25 @@ +var utils = require('../utils'); + +/** + * Return length of the given `expr`. + * + * @param {Expression} expr + * @return {Unit} + * @api public + */ + +(module.exports = function length(expr){ + if (expr) { + if (expr.nodes) { + var nodes = utils.unwrap(expr).nodes; + if (1 == nodes.length && 'object' == nodes[0].nodeName) { + return nodes[0].length; + } else { + return nodes.length; + } + } else { + return 1; + } + } + return 0; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/lightness.js b/node_modules/stylus/lib/functions/lightness.js new file mode 100644 index 00000000..b324a5bb --- /dev/null +++ b/node_modules/stylus/lib/functions/lightness.js @@ -0,0 +1,34 @@ +var nodes = require('../nodes') + , hsla = require('./hsla') + , component = require('./component'); + +/** + * Return the lightness component of the given `color`, + * or set the lightness component to the optional second `value` argument. + * + * Examples: + * + * lightness(#00c) + * // => 100% + * + * lightness(#00c, 80%) + * // => #99f + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function lightness(color, value){ + if (value) { + var hslaColor = color.hsla; + return hsla( + new nodes.Unit(hslaColor.h), + new nodes.Unit(hslaColor.s), + value, + new nodes.Unit(hslaColor.a) + ) + } + return component(color, new nodes.String('lightness')); +}; diff --git a/node_modules/stylus/lib/functions/list-separator.js b/node_modules/stylus/lib/functions/list-separator.js new file mode 100644 index 00000000..55205409 --- /dev/null +++ b/node_modules/stylus/lib/functions/list-separator.js @@ -0,0 +1,25 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Return the separator of the given `list`. + * + * Examples: + * + * list1 = a b c + * list-separator(list1) + * // => ' ' + * + * list2 = a, b, c + * list-separator(list2) + * // => ',' + * + * @param {Experssion} list + * @return {String} + * @api public + */ + +(module.exports = function listSeparator(list){ + list = utils.unwrap(list); + return new nodes.String(list.isList ? ',' : ' '); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/lookup.js b/node_modules/stylus/lib/functions/lookup.js new file mode 100644 index 00000000..cce33a30 --- /dev/null +++ b/node_modules/stylus/lib/functions/lookup.js @@ -0,0 +1,17 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Lookup variable `name` or return Null. + * + * @param {String} name + * @return {Mixed} + * @api public + */ + +module.exports = function lookup(name){ + utils.assertType(name, 'string', 'name'); + var node = this.lookup(name.val); + if (!node) return nodes.null; + return this.visit(node); +}; diff --git a/node_modules/stylus/lib/functions/luminosity.js b/node_modules/stylus/lib/functions/luminosity.js new file mode 100644 index 00000000..6b6cf7d0 --- /dev/null +++ b/node_modules/stylus/lib/functions/luminosity.js @@ -0,0 +1,38 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Returns the relative luminance of the given `color`, + * see http://www.w3.org/TR/WCAG20/#relativeluminancedef + * + * Examples: + * + * luminosity(white) + * // => 1 + * + * luminosity(#000) + * // => 0 + * + * luminosity(red) + * // => 0.2126 + * + * @param {RGBA|HSLA} color + * @return {Unit} + * @api public + */ + +module.exports = function luminosity(color){ + utils.assertColor(color); + color = color.rgba; + function processChannel(channel) { + channel = channel / 255; + return (0.03928 > channel) + ? channel / 12.92 + : Math.pow(((channel + 0.055) / 1.055), 2.4); + } + return new nodes.Unit( + 0.2126 * processChannel(color.r) + + 0.7152 * processChannel(color.g) + + 0.0722 * processChannel(color.b) + ); +}; diff --git a/node_modules/stylus/lib/functions/match.js b/node_modules/stylus/lib/functions/match.js new file mode 100644 index 00000000..3d07cc71 --- /dev/null +++ b/node_modules/stylus/lib/functions/match.js @@ -0,0 +1,43 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +var VALID_FLAGS = 'igm'; + +/** + * retrieves the matches when matching a `val`(string) + * against a `pattern`(regular expression). + * + * Examples: + * $regex = '^(height|width)?([<>=]{1,})(.*)' + * + * match($regex,'height>=sm') + * // => ('height>=sm' 'height' '>=' 'sm') + * // => also truthy + * + * match($regex, 'lorem ipsum') + * // => null + * + * @param {String} pattern + * @param {String|Ident} val + * @param {String|Ident} [flags=''] + * @return {String|Null} + * @api public + */ + +module.exports = function match(pattern, val, flags){ + utils.assertType(pattern, 'string', 'pattern'); + utils.assertString(val, 'val'); + var re = new RegExp(pattern.val, validateFlags(flags) ? flags.string : ''); + return val.string.match(re); +}; + +function validateFlags(flags) { + flags = flags && flags.string; + + if (flags) { + return flags.split('').every(function(flag) { + return ~VALID_FLAGS.indexOf(flag); + }); + } + return false; +} diff --git a/node_modules/stylus/lib/functions/math-prop.js b/node_modules/stylus/lib/functions/math-prop.js new file mode 100644 index 00000000..06c25e2a --- /dev/null +++ b/node_modules/stylus/lib/functions/math-prop.js @@ -0,0 +1,13 @@ +var nodes = require('../nodes'); + +/** + * Get Math `prop`. + * + * @param {String} prop + * @return {Unit} + * @api private + */ + +module.exports = function math(prop){ + return new nodes.Unit(Math[prop.string]); +}; diff --git a/node_modules/stylus/lib/functions/math.js b/node_modules/stylus/lib/functions/math.js new file mode 100644 index 00000000..c3ef6818 --- /dev/null +++ b/node_modules/stylus/lib/functions/math.js @@ -0,0 +1,17 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Apply Math `fn` to `n`. + * + * @param {Unit} n + * @param {String} fn + * @return {Unit} + * @api private + */ + +module.exports = function math(n, fn){ + utils.assertType(n, 'unit', 'n'); + utils.assertString(fn, 'fn'); + return new nodes.Unit(Math[fn.string](n.val), n.type); +}; diff --git a/node_modules/stylus/lib/functions/merge.js b/node_modules/stylus/lib/functions/merge.js new file mode 100644 index 00000000..a524973b --- /dev/null +++ b/node_modules/stylus/lib/functions/merge.js @@ -0,0 +1,24 @@ +var utils = require('../utils'); + +/** + * Merge the object `dest` with the given args. + * + * @param {Object} dest + * @param {Object} ... + * @return {Object} dest + * @api public + */ + +(module.exports = function merge(dest){ + utils.assertPresent(dest, 'dest'); + dest = utils.unwrap(dest).first; + utils.assertType(dest, 'object', 'dest'); + + var last = utils.unwrap(arguments[arguments.length - 1]).first + , deep = (true === last.val); + + for (var i = 1, len = arguments.length - deep; i < len; ++i) { + utils.merge(dest.vals, utils.unwrap(arguments[i]).first.vals, deep); + } + return dest; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/operate.js b/node_modules/stylus/lib/functions/operate.js new file mode 100644 index 00000000..ae244bab --- /dev/null +++ b/node_modules/stylus/lib/functions/operate.js @@ -0,0 +1,18 @@ +var utils = require('../utils'); + +/** + * Perform `op` on the `left` and `right` operands. + * + * @param {String} op + * @param {Node} left + * @param {Node} right + * @return {Node} + * @api public + */ + +module.exports = function operate(op, left, right){ + utils.assertType(op, 'string', 'op'); + utils.assertPresent(left, 'left'); + utils.assertPresent(right, 'right'); + return left.operate(op.val, right); +}; diff --git a/node_modules/stylus/lib/functions/opposite-position.js b/node_modules/stylus/lib/functions/opposite-position.js new file mode 100644 index 00000000..8a8f4101 --- /dev/null +++ b/node_modules/stylus/lib/functions/opposite-position.js @@ -0,0 +1,32 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Return the opposites of the given `positions`. + * + * Examples: + * + * opposite-position(top left) + * // => bottom right + * + * @param {Expression} positions + * @return {Expression} + * @api public + */ + +(module.exports = function oppositePosition(positions){ + var expr = []; + utils.unwrap(positions).nodes.forEach(function(pos, i){ + utils.assertString(pos, 'position ' + i); + pos = (function(){ switch (pos.string) { + case 'top': return 'bottom'; + case 'bottom': return 'top'; + case 'left': return 'right'; + case 'right': return 'left'; + case 'center': return 'center'; + default: throw new Error('invalid position ' + pos); + }})(); + expr.push(new nodes.Literal(pos)); + }); + return expr; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/p.js b/node_modules/stylus/lib/functions/p.js new file mode 100644 index 00000000..7d32e572 --- /dev/null +++ b/node_modules/stylus/lib/functions/p.js @@ -0,0 +1,18 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Inspect the given `expr`. + * + * @param {Expression} expr + * @api public + */ + +(module.exports = function p(){ + [].slice.call(arguments).forEach(function(expr){ + expr = utils.unwrap(expr); + if (!expr.nodes.length) return; + console.log('\u001b[90minspect:\u001b[0m %s', expr.toString().replace(/^\(|\)$/g, '')); + }) + return nodes.null; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/pathjoin.js b/node_modules/stylus/lib/functions/pathjoin.js new file mode 100644 index 00000000..853fe460 --- /dev/null +++ b/node_modules/stylus/lib/functions/pathjoin.js @@ -0,0 +1,16 @@ +var path = require('path'); + +/** + * Peform a path join. + * + * @param {String} path + * @return {String} + * @api public + */ + +(module.exports = function pathjoin(){ + var paths = [].slice.call(arguments).map(function(path){ + return path.first.string; + }); + return path.join.apply(null, paths).replace(/\\/g, '/'); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/pop.js b/node_modules/stylus/lib/functions/pop.js new file mode 100644 index 00000000..90f7f4b0 --- /dev/null +++ b/node_modules/stylus/lib/functions/pop.js @@ -0,0 +1,14 @@ +var utils = require('../utils'); + +/** + * Pop a value from `expr`. + * + * @param {Expression} expr + * @return {Node} + * @api public + */ + +(module.exports = function pop(expr) { + expr = utils.unwrap(expr); + return expr.nodes.pop(); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/prefix-classes.js b/node_modules/stylus/lib/functions/prefix-classes.js new file mode 100644 index 00000000..12aa816f --- /dev/null +++ b/node_modules/stylus/lib/functions/prefix-classes.js @@ -0,0 +1,22 @@ +var utils = require('../utils'); + +/** + * Prefix css classes in a block + * + * @param {String} prefix + * @param {Block} block + * @return {Block} + * @api private + */ + +module.exports = function prefixClasses(prefix, block){ + utils.assertString(prefix, 'prefix'); + utils.assertType(block, 'block', 'block'); + + var _prefix = this.prefix; + + this.options.prefix = this.prefix = prefix.string; + block = this.visit(block); + this.options.prefix = this.prefix = _prefix; + return block; +}; diff --git a/node_modules/stylus/lib/functions/push.js b/node_modules/stylus/lib/functions/push.js new file mode 100644 index 00000000..f9448067 --- /dev/null +++ b/node_modules/stylus/lib/functions/push.js @@ -0,0 +1,18 @@ +var utils = require('../utils'); + +/** + * Push the given args to `expr`. + * + * @param {Expression} expr + * @param {Node} ... + * @return {Unit} + * @api public + */ + +(module.exports = function(expr){ + expr = utils.unwrap(expr); + for (var i = 1, len = arguments.length; i < len; ++i) { + expr.nodes.push(utils.unwrap(arguments[i]).clone()); + } + return expr.nodes.length; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/range.js b/node_modules/stylus/lib/functions/range.js new file mode 100644 index 00000000..7b4660c7 --- /dev/null +++ b/node_modules/stylus/lib/functions/range.js @@ -0,0 +1,32 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Returns a list of units from `start` to `stop` + * by `step`. If `step` argument is omitted, + * it defaults to 1. + * + * @param {Unit} start + * @param {Unit} stop + * @param {Unit} [step] + * @return {Expression} + * @api public + */ + +module.exports = function range(start, stop, step){ + utils.assertType(start, 'unit', 'start'); + utils.assertType(stop, 'unit', 'stop'); + if (step) { + utils.assertType(step, 'unit', 'step'); + if (0 == step.val) { + throw new Error('ArgumentError: "step" argument must not be zero'); + } + } else { + step = new nodes.Unit(1); + } + var list = new nodes.Expression; + for (var i = start.val; i <= stop.val; i += step.val) { + list.push(new nodes.Unit(i, start.type)); + } + return list; +}; diff --git a/node_modules/stylus/lib/functions/red.js b/node_modules/stylus/lib/functions/red.js new file mode 100644 index 00000000..0b794121 --- /dev/null +++ b/node_modules/stylus/lib/functions/red.js @@ -0,0 +1,33 @@ +var nodes = require('../nodes') + , rgba = require('./rgba'); + +/** + * Return the red component of the given `color`, + * or set the red component to the optional second `value` argument. + * + * Examples: + * + * red(#c00) + * // => 204 + * + * red(#000, 255) + * // => #f00 + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function red(color, value){ + color = color.rgba; + if (value) { + return rgba( + value, + new nodes.Unit(color.g), + new nodes.Unit(color.b), + new nodes.Unit(color.a) + ); + } + return new nodes.Unit(color.r, ''); +}; diff --git a/node_modules/stylus/lib/functions/remove.js b/node_modules/stylus/lib/functions/remove.js new file mode 100644 index 00000000..d8e157aa --- /dev/null +++ b/node_modules/stylus/lib/functions/remove.js @@ -0,0 +1,17 @@ +var utils = require('../utils'); + +/** + * Remove the given `key` from the `object`. + * + * @param {Object} object + * @param {String} key + * @return {Object} + * @api public + */ + +module.exports = function remove(object, key){ + utils.assertType(object, 'object', 'object'); + utils.assertString(key, 'key'); + delete object.vals[key.string]; + return object; +}; diff --git a/node_modules/stylus/lib/functions/replace.js b/node_modules/stylus/lib/functions/replace.js new file mode 100644 index 00000000..15d9c904 --- /dev/null +++ b/node_modules/stylus/lib/functions/replace.js @@ -0,0 +1,23 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Returns string with all matches of `pattern` replaced by `replacement` in given `val` + * + * @param {String} pattern + * @param {String} replacement + * @param {String|Ident} val + * @return {String|Ident} + * @api public + */ + +module.exports = function replace(pattern, replacement, val){ + utils.assertString(pattern, 'pattern'); + utils.assertString(replacement, 'replacement'); + utils.assertString(val, 'val'); + pattern = new RegExp(pattern.string, 'g'); + var res = val.string.replace(pattern, replacement.string); + return val instanceof nodes.Ident + ? new nodes.Ident(res) + : new nodes.String(res); +}; diff --git a/node_modules/stylus/lib/functions/resolver.js b/node_modules/stylus/lib/functions/resolver.js new file mode 100644 index 00000000..e2ce4d01 --- /dev/null +++ b/node_modules/stylus/lib/functions/resolver.js @@ -0,0 +1,85 @@ +/** + * Module dependencies. + */ + +var Compiler = require('../visitor/compiler') + , nodes = require('../nodes') + , parse = require('url').parse + , relative = require('path').relative + , join = require('path').join + , dirname = require('path').dirname + , extname = require('path').extname + , sep = require('path').sep; + +/** + * Return a url() function which resolves urls. + * + * Options: + * + * - `paths` resolution path(s), merged with general lookup paths + * - `nocheck` don't check file existence + * + * Examples: + * + * stylus(str) + * .set('filename', __dirname + '/css/test.styl') + * .define('url', stylus.resolver({ nocheck: true })) + * .render(function(err, css){ ... }) + * + * @param {Object} [options] + * @return {Function} + * @api public + */ + +module.exports = function(options) { + options = options || {}; + + function resolver(url) { + // Compile the url + var compiler = new Compiler(url) + , filename = url.filename; + compiler.isURL = true; + url = parse(url.nodes.map(function(node){ + return compiler.visit(node); + }).join('')); + + // Parse literal + var literal = new nodes.Literal('url("' + url.href + '")') + , path = url.pathname + , dest = this.options.dest + , tail = '' + , res; + + // Absolute or hash + if (url.protocol || !path || '/' == path[0]) return literal; + + // Check that file exists + if (!options.nocheck) { + var _paths = options.paths || []; + path = require('../utils').lookup(path, _paths.concat(this.paths)); + if (!path) return literal; + } + + if (this.includeCSS && extname(path) == '.css') + return new nodes.Literal(url.href); + + if (url.search) tail += url.search; + if (url.hash) tail += url.hash; + + if (dest && extname(dest) == '.css') + dest = dirname(dest); + + res = relative(dest || dirname(this.filename), options.nocheck + ? join(dirname(filename), path) + : path) + tail; + + if ('\\' == sep) res = res.replace(/\\/g, '/'); + + return new nodes.Literal('url("' + res + '")'); + }; + + // Expose options to Evaluator + resolver.options = options; + resolver.raw = true; + return resolver; +}; diff --git a/node_modules/stylus/lib/functions/rgb.js b/node_modules/stylus/lib/functions/rgb.js new file mode 100644 index 00000000..316e90bb --- /dev/null +++ b/node_modules/stylus/lib/functions/rgb.js @@ -0,0 +1,40 @@ +var utils = require('../utils') + , nodes = require('../nodes') + , rgba = require('./rgba'); + +/** + * Return a `RGBA` from the r,g,b channels. + * + * Examples: + * + * rgb(255,204,0) + * // => #ffcc00 + * + * rgb(#fff) + * // => #fff + * + * @param {Unit|RGBA|HSLA} red + * @param {Unit} green + * @param {Unit} blue + * @return {RGBA} + * @api public + */ + +module.exports = function rgb(red, green, blue){ + switch (arguments.length) { + case 1: + utils.assertColor(red); + var color = red.rgba; + return new nodes.RGBA( + color.r + , color.g + , color.b + , 1); + default: + return rgba( + red + , green + , blue + , new nodes.Unit(1)); + } +}; diff --git a/node_modules/stylus/lib/functions/rgba.js b/node_modules/stylus/lib/functions/rgba.js new file mode 100644 index 00000000..81320a17 --- /dev/null +++ b/node_modules/stylus/lib/functions/rgba.js @@ -0,0 +1,59 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Return a `RGBA` from the r,g,b,a channels. + * + * Examples: + * + * rgba(255,0,0,0.5) + * // => rgba(255,0,0,0.5) + * + * rgba(255,0,0,1) + * // => #ff0000 + * + * rgba(#ffcc00, 50%) + * // rgba(255,204,0,0.5) + * + * @param {Unit|RGBA|HSLA} red + * @param {Unit} green + * @param {Unit} blue + * @param {Unit} alpha + * @return {RGBA} + * @api public + */ + +module.exports = function rgba(red, green, blue, alpha){ + switch (arguments.length) { + case 1: + utils.assertColor(red); + return red.rgba; + case 2: + utils.assertColor(red); + var color = red.rgba; + utils.assertType(green, 'unit', 'alpha'); + alpha = green.clone(); + if ('%' == alpha.type) alpha.val /= 100; + return new nodes.RGBA( + color.r + , color.g + , color.b + , alpha.val); + default: + utils.assertType(red, 'unit', 'red'); + utils.assertType(green, 'unit', 'green'); + utils.assertType(blue, 'unit', 'blue'); + utils.assertType(alpha, 'unit', 'alpha'); + var r = '%' == red.type ? Math.round(red.val * 2.55) : red.val + , g = '%' == green.type ? Math.round(green.val * 2.55) : green.val + , b = '%' == blue.type ? Math.round(blue.val * 2.55) : blue.val; + + alpha = alpha.clone(); + if (alpha && '%' == alpha.type) alpha.val /= 100; + return new nodes.RGBA( + r + , g + , b + , alpha.val); + } +}; diff --git a/node_modules/stylus/lib/functions/s.js b/node_modules/stylus/lib/functions/s.js new file mode 100644 index 00000000..6106c9fc --- /dev/null +++ b/node_modules/stylus/lib/functions/s.js @@ -0,0 +1,37 @@ +var utils = require('../utils') + , nodes = require('../nodes') + , Compiler = require('../visitor/compiler'); + +/** + * Return a `Literal` with the given `fmt`, and + * variable number of arguments. + * + * @param {String} fmt + * @param {Node} ... + * @return {Literal} + * @api public + */ + +(module.exports = function s(fmt){ + fmt = utils.unwrap(fmt).nodes[0]; + utils.assertString(fmt); + var self = this + , str = fmt.string + , args = arguments + , i = 1; + + // format + str = str.replace(/%(s|d)/g, function(_, specifier){ + var arg = args[i++] || nodes.null; + switch (specifier) { + case 's': + return new Compiler(arg, self.options).compile(); + case 'd': + arg = utils.unwrap(arg).first; + if ('unit' != arg.nodeName) throw new Error('%d requires a unit'); + return arg.val; + } + }); + + return new nodes.Literal(str); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/saturation.js b/node_modules/stylus/lib/functions/saturation.js new file mode 100644 index 00000000..6ad5956d --- /dev/null +++ b/node_modules/stylus/lib/functions/saturation.js @@ -0,0 +1,35 @@ +var nodes = require('../nodes') + , hsla = require('./hsla') + , component = require('./component'); + +/** + * Return the saturation component of the given `color`, + * or set the saturation component to the optional second `value` argument. + * + * Examples: + * + * saturation(#00c) + * // => 100% + * + * saturation(#00c, 50%) + * // => #339 + * + * @param {RGBA|HSLA} color + * @param {Unit} [value] + * @return {Unit|RGBA} + * @api public + */ + +module.exports = function saturation(color, value){ + if (value) { + var hslaColor = color.hsla; + return hsla( + new nodes.Unit(hslaColor.h), + value, + new nodes.Unit(hslaColor.l), + new nodes.Unit(hslaColor.a) + ) + } + return component(color, new nodes.String('saturation')); +}; + diff --git a/node_modules/stylus/lib/functions/selector-exists.js b/node_modules/stylus/lib/functions/selector-exists.js new file mode 100644 index 00000000..68914af5 --- /dev/null +++ b/node_modules/stylus/lib/functions/selector-exists.js @@ -0,0 +1,23 @@ +var utils = require('../utils'); + +/** + * Returns true if the given selector exists. + * + * @param {String} sel + * @return {Boolean} + * @api public + */ + +module.exports = function selectorExists(sel) { + utils.assertString(sel, 'selector'); + + if (!this.__selectorsMap__) { + var Normalizer = require('../visitor/normalizer') + , visitor = new Normalizer(this.root.clone()); + visitor.visit(visitor.root); + + this.__selectorsMap__ = visitor.map; + } + + return sel.string in this.__selectorsMap__; +}; diff --git a/node_modules/stylus/lib/functions/selector.js b/node_modules/stylus/lib/functions/selector.js new file mode 100644 index 00000000..45a421d6 --- /dev/null +++ b/node_modules/stylus/lib/functions/selector.js @@ -0,0 +1,71 @@ +var utils = require('../utils'); + +/** + * Return the current selector or compile + * selector from a string or a list. + * + * @param {String|Expression} + * @return {String} + * @api public + */ + +(module.exports = function selector(){ + var stack = this.selectorStack + , args = [].slice.call(arguments); + + if (1 == args.length) { + var expr = utils.unwrap(args[0]) + , len = expr.nodes.length; + + // selector('.a') + if (1 == len) { + utils.assertString(expr.first, 'selector'); + var SelectorParser = require('../selector-parser') + , val = expr.first.string + , parsed = new SelectorParser(val).parse().val; + + if (parsed == val) return val; + + stack.push(parse(val)); + } else if (len > 1) { + // selector-list = '.a', '.b', '.c' + // selector(selector-list) + if (expr.isList) { + pushToStack(expr.nodes, stack); + // selector('.a' '.b' '.c') + } else { + stack.push(parse(expr.nodes.map(function(node){ + utils.assertString(node, 'selector'); + return node.string; + }).join(' '))); + } + } + // selector('.a', '.b', '.c') + } else if (args.length > 1) { + pushToStack(args, stack); + } + + return stack.length ? utils.compileSelectors(stack).join(',') : '&'; +}).raw = true; + +function pushToStack(selectors, stack) { + selectors.forEach(function(sel) { + sel = sel.first; + utils.assertString(sel, 'selector'); + stack.push(parse(sel.string)); + }); +} + +function parse(selector) { + var Parser = new require('../parser') + , parser = new Parser(selector) + , nodes; + parser.state.push('selector-parts'); + nodes = parser.selector(); + nodes.forEach(function(node) { + node.val = node.segments.map(function(seg){ + return seg.toString(); + }).join(''); + }); + return nodes; +} diff --git a/node_modules/stylus/lib/functions/selectors.js b/node_modules/stylus/lib/functions/selectors.js new file mode 100644 index 00000000..ba09d4b6 --- /dev/null +++ b/node_modules/stylus/lib/functions/selectors.js @@ -0,0 +1,43 @@ +var nodes = require('../nodes') + , Parser = require('../selector-parser'); + +/** + * Return a list with raw selectors parts + * of the current group. + * + * For example: + * + * .a, .b + * .c + * .d + * test: selectors() // => '.a,.b', '& .c', '& .d' + * + * @return {Expression} + * @api public + */ + +module.exports = function selectors(){ + var stack = this.selectorStack + , expr = new nodes.Expression(true); + + if (stack.length) { + for (var i = 0; i < stack.length; i++) { + var group = stack[i] + , nested; + + if (group.length > 1) { + expr.push(new nodes.String(group.map(function(selector) { + nested = new Parser(selector.val).parse().nested; + return (nested && i ? '& ' : '') + selector.val; + }).join(','))) + } else { + var selector = group[0].val + nested = new Parser(selector).parse().nested; + expr.push(new nodes.String((nested && i ? '& ' : '') + selector)); + } + } + } else { + expr.push(new nodes.String('&')); + } + return expr; +}; diff --git a/node_modules/stylus/lib/functions/shift.js b/node_modules/stylus/lib/functions/shift.js new file mode 100644 index 00000000..8a2b5292 --- /dev/null +++ b/node_modules/stylus/lib/functions/shift.js @@ -0,0 +1,15 @@ +var utils = require('../utils'); + +/** + * Shift an element from `expr`. + * + * @param {Expression} expr + * @return {Node} + * @api public + */ + + (module.exports = function(expr){ + expr = utils.unwrap(expr); + return expr.nodes.shift(); + }).raw = true; + diff --git a/node_modules/stylus/lib/functions/slice.js b/node_modules/stylus/lib/functions/slice.js new file mode 100644 index 00000000..d5b9282c --- /dev/null +++ b/node_modules/stylus/lib/functions/slice.js @@ -0,0 +1,28 @@ +var utils = require('../utils'), + nodes = require('../nodes'); + +/** + * This is a heler function for the slice method + * + * @param {String|Ident} vals + * @param {Unit} start [0] + * @param {Unit} end [vals.length] + * @return {String|Literal|Null} + * @api public +*/ +(module.exports = function slice(val, start, end) { + start = start && start.nodes[0].val; + end = end && end.nodes[0].val; + + val = utils.unwrap(val).nodes; + + if (val.length > 1) { + return utils.coerce(val.slice(start, end), true); + } + + var result = val[0].string.slice(start, end); + + return val[0] instanceof nodes.Ident + ? new nodes.Ident(result) + : new nodes.String(result); +}).raw = true; diff --git a/node_modules/stylus/lib/functions/split.js b/node_modules/stylus/lib/functions/split.js new file mode 100644 index 00000000..8513c2ff --- /dev/null +++ b/node_modules/stylus/lib/functions/split.js @@ -0,0 +1,25 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Splits the given `val` by `delim` + * + * @param {String} delim + * @param {String|Ident} val + * @return {Expression} + * @api public + */ + +module.exports = function split(delim, val){ + utils.assertString(delim, 'delimiter'); + utils.assertString(val, 'val'); + var splitted = val.string.split(delim.string); + var expr = new nodes.Expression(); + var ItemNode = val instanceof nodes.Ident + ? nodes.Ident + : nodes.String; + for (var i = 0, len = splitted.length; i < len; ++i) { + expr.nodes.push(new ItemNode(splitted[i])); + } + return expr; +}; diff --git a/node_modules/stylus/lib/functions/substr.js b/node_modules/stylus/lib/functions/substr.js new file mode 100644 index 00000000..75bffaf6 --- /dev/null +++ b/node_modules/stylus/lib/functions/substr.js @@ -0,0 +1,22 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Returns substring of the given `val`. + * + * @param {String|Ident} val + * @param {Number} start + * @param {Number} [length] + * @return {String|Ident} + * @api public + */ + +module.exports = function substr(val, start, length){ + utils.assertString(val, 'val'); + utils.assertType(start, 'unit', 'start'); + length = length && length.val; + var res = val.string.substr(start.val, length); + return val instanceof nodes.Ident + ? new nodes.Ident(res) + : new nodes.String(res); +}; diff --git a/node_modules/stylus/lib/functions/tan.js b/node_modules/stylus/lib/functions/tan.js new file mode 100644 index 00000000..311a086a --- /dev/null +++ b/node_modules/stylus/lib/functions/tan.js @@ -0,0 +1,28 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Return the tangent of the given `angle`. + * + * @param {Unit} angle + * @return {Unit} + * @api public + */ + +module.exports = function tan(angle) { + utils.assertType(angle, 'unit', 'angle'); + + var radians = angle.val; + + if (angle.type === 'deg') { + radians *= Math.PI / 180; + } + + var m = Math.pow(10, 9); + + var sin = Math.round(Math.sin(radians) * m) / m + , cos = Math.round(Math.cos(radians) * m) / m + , tan = Math.round(m * sin / cos ) / m; + + return new nodes.Unit(tan, ''); +}; diff --git a/node_modules/stylus/lib/functions/trace.js b/node_modules/stylus/lib/functions/trace.js new file mode 100644 index 00000000..6d75b815 --- /dev/null +++ b/node_modules/stylus/lib/functions/trace.js @@ -0,0 +1,12 @@ +var nodes = require('../nodes'); + +/** + * Output stack trace. + * + * @api public + */ + +module.exports = function trace(){ + console.log(this.stack); + return nodes.null; +}; diff --git a/node_modules/stylus/lib/functions/transparentify.js b/node_modules/stylus/lib/functions/transparentify.js new file mode 100644 index 00000000..b7758e81 --- /dev/null +++ b/node_modules/stylus/lib/functions/transparentify.js @@ -0,0 +1,63 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Returns the transparent version of the given `top` color, + * as if it was blend over the given `bottom` color. + * + * Examples: + * + * transparentify(#808080) + * => rgba(0,0,0,0.5) + * + * transparentify(#414141, #000) + * => rgba(255,255,255,0.25) + * + * transparentify(#91974C, #F34949, 0.5) + * => rgba(47,229,79,0.5) + * + * @param {RGBA|HSLA} top + * @param {RGBA|HSLA} [bottom=#fff] + * @param {Unit} [alpha] + * @return {RGBA} + * @api public + */ + +module.exports = function transparentify(top, bottom, alpha){ + utils.assertColor(top); + top = top.rgba; + // Handle default arguments + bottom = bottom || new nodes.RGBA(255, 255, 255, 1); + if (!alpha && bottom && !bottom.rgba) { + alpha = bottom; + bottom = new nodes.RGBA(255, 255, 255, 1); + } + utils.assertColor(bottom); + bottom = bottom.rgba; + var bestAlpha = ['r', 'g', 'b'].map(function(channel){ + return (top[channel] - bottom[channel]) / ((0 < (top[channel] - bottom[channel]) ? 255 : 0) - bottom[channel]); + }).sort(function(a, b){return a < b;})[0]; + if (alpha) { + utils.assertType(alpha, 'unit', 'alpha'); + if ('%' == alpha.type) { + bestAlpha = alpha.val / 100; + } else if (!alpha.type) { + bestAlpha = alpha = alpha.val; + } + } + bestAlpha = Math.max(Math.min(bestAlpha, 1), 0); + // Calculate the resulting color + function processChannel(channel) { + if (0 == bestAlpha) { + return bottom[channel] + } else { + return bottom[channel] + (top[channel] - bottom[channel]) / bestAlpha + } + } + return new nodes.RGBA( + processChannel('r'), + processChannel('g'), + processChannel('b'), + Math.round(bestAlpha * 100) / 100 + ); +} diff --git a/node_modules/stylus/lib/functions/type.js b/node_modules/stylus/lib/functions/type.js new file mode 100644 index 00000000..acb5ff35 --- /dev/null +++ b/node_modules/stylus/lib/functions/type.js @@ -0,0 +1,30 @@ +var utils = require('../utils'); + +/** + * Return type of `node`. + * + * Examples: + * + * type(12) + * // => 'unit' + * + * type(#fff) + * // => 'color' + * + * type(type) + * // => 'function' + * + * type(unbound) + * typeof(unbound) + * type-of(unbound) + * // => 'ident' + * + * @param {Node} node + * @return {String} + * @api public + */ + +module.exports = function type(node){ + utils.assertPresent(node, 'expression'); + return node.nodeName; +}; diff --git a/node_modules/stylus/lib/functions/unit.js b/node_modules/stylus/lib/functions/unit.js new file mode 100644 index 00000000..bd904a55 --- /dev/null +++ b/node_modules/stylus/lib/functions/unit.js @@ -0,0 +1,23 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Assign `type` to the given `unit` or return `unit`'s type. + * + * @param {Unit} unit + * @param {String|Ident} type + * @return {Unit} + * @api public + */ + +module.exports = function unit(unit, type){ + utils.assertType(unit, 'unit', 'unit'); + + // Assign + if (type) { + utils.assertString(type, 'type'); + return new nodes.Unit(unit.val, type.string); + } else { + return unit.type || ''; + } +}; diff --git a/node_modules/stylus/lib/functions/unquote.js b/node_modules/stylus/lib/functions/unquote.js new file mode 100644 index 00000000..41ebb807 --- /dev/null +++ b/node_modules/stylus/lib/functions/unquote.js @@ -0,0 +1,23 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Unquote the given `string`. + * + * Examples: + * + * unquote("sans-serif") + * // => sans-serif + * + * unquote(sans-serif) + * // => sans-serif + * + * @param {String|Ident} string + * @return {Literal} + * @api public + */ + +module.exports = function unquote(string){ + utils.assertString(string, 'string'); + return new nodes.Literal(string.string); +}; diff --git a/node_modules/stylus/lib/functions/unshift.js b/node_modules/stylus/lib/functions/unshift.js new file mode 100644 index 00000000..377ef01c --- /dev/null +++ b/node_modules/stylus/lib/functions/unshift.js @@ -0,0 +1,18 @@ +var utils = require('../utils'); + +/** + * Unshift the given args to `expr`. + * + * @param {Expression} expr + * @param {Node} ... + * @return {Unit} + * @api public + */ + +(module.exports = function(expr){ + expr = utils.unwrap(expr); + for (var i = 1, len = arguments.length; i < len; ++i) { + expr.nodes.unshift(utils.unwrap(arguments[i])); + } + return expr.nodes.length; +}).raw = true; diff --git a/node_modules/stylus/lib/functions/url.js b/node_modules/stylus/lib/functions/url.js new file mode 100644 index 00000000..616db430 --- /dev/null +++ b/node_modules/stylus/lib/functions/url.js @@ -0,0 +1,142 @@ + +/*! + * Stylus - plugin - url + * Copyright (c) Automattic <developer.wordpress.com> + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var Compiler = require('../visitor/compiler') + , events = require('../renderer').events + , nodes = require('../nodes') + , parse = require('url').parse + , extname = require('path').extname + , utils = require('../utils') + , fs = require('fs'); + +/** + * Mime table. + */ + +var defaultMimes = { + '.gif': 'image/gif' + , '.png': 'image/png' + , '.jpg': 'image/jpeg' + , '.jpeg': 'image/jpeg' + , '.svg': 'image/svg+xml' + , '.webp': 'image/webp' + , '.ttf': 'application/x-font-ttf' + , '.eot': 'application/vnd.ms-fontobject' + , '.woff': 'application/font-woff' + , '.woff2': 'application/font-woff2' +}; + +/** + * Supported encoding types + */ +var encodingTypes = { + BASE_64: 'base64', + UTF8: 'charset=utf-8' +} + +/** + * Return a url() function with the given `options`. + * + * Options: + * + * - `limit` bytesize limit defaulting to 30Kb + * - `paths` image resolution path(s), merged with general lookup paths + * + * Examples: + * + * stylus(str) + * .set('filename', __dirname + '/css/test.styl') + * .define('url', stylus.url({ paths: [__dirname + '/public'] })) + * .render(function(err, css){ ... }) + * + * @param {Object} options + * @return {Function} + * @api public + */ + +module.exports = function(options) { + options = options || {}; + + var _paths = options.paths || []; + var sizeLimit = null != options.limit ? options.limit : 30000; + var mimes = options.mimes || defaultMimes; + + /** + * @param {object} url - The path to the image you want to encode. + * @param {object} enc - The encoding for the image. Defaults to base64, the + * other valid option is `utf8`. + */ + function fn(url, enc){ + // Compile the url + var compiler = new Compiler(url) + , encoding = encodingTypes.BASE_64; + + compiler.isURL = true; + url = url.nodes.map(function(node){ + return compiler.visit(node); + }).join(''); + + // Parse literal + url = parse(url); + var ext = extname(url.pathname) + , mime = mimes[ext] + , hash = url.hash || '' + , literal = new nodes.Literal('url("' + url.href + '")') + , paths = _paths.concat(this.paths) + , buf + , result; + + // Not supported + if (!mime) return literal; + + // Absolute + if (url.protocol) return literal; + + // Lookup + var found = utils.lookup(url.pathname, paths); + + // Failed to lookup + if (!found) { + events.emit( + 'file not found' + , 'File ' + literal + ' could not be found, literal url retained!' + ); + + return literal; + } + + // Read data + buf = fs.readFileSync(found); + + // Too large + if (false !== sizeLimit && buf.length > sizeLimit) return literal; + + if (enc && 'utf8' == enc.first.val.toLowerCase()) { + encoding = encodingTypes.UTF8; + result = buf.toString('utf8').replace(/\s+/g, ' ') + .replace(/[{}\|\\\^~\[\]`"<>#%]/g, function(match) { + return '%' + match[0].charCodeAt(0).toString(16).toUpperCase(); + }).trim(); + } else { + result = buf.toString(encoding) + hash; + } + + // Encode + return new nodes.Literal('url("data:' + mime + ';' + encoding + ',' + result + '")'); + }; + + fn.raw = true; + return fn; +}; + +// Exporting default mimes so we could easily access them +module.exports.mimes = defaultMimes; + diff --git a/node_modules/stylus/lib/functions/use.js b/node_modules/stylus/lib/functions/use.js new file mode 100644 index 00000000..da28e4d0 --- /dev/null +++ b/node_modules/stylus/lib/functions/use.js @@ -0,0 +1,74 @@ +var utils = require('../utils') + , path = require('path'); + +/** +* Use the given `plugin` +* +* Examples: +* +* use("plugins/add.js") +* +* width add(10, 100) +* // => width: 110 +*/ + +module.exports = function use(plugin, options){ + utils.assertString(plugin, 'plugin'); + + if (options) { + utils.assertType(options, 'object', 'options'); + options = parseObject(options); + } + + // lookup + plugin = plugin.string; + var found = utils.lookup(plugin, this.options.paths, this.options.filename); + if (!found) throw new Error('failed to locate plugin file "' + plugin + '"'); + + // use + var fn = require(path.resolve(found)); + if ('function' != typeof fn) { + throw new Error('plugin "' + plugin + '" does not export a function'); + } + this.renderer.use(fn(options || this.options)); +}; + +/** + * Attempt to parse object node to the javascript object. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function parseObject(obj){ + obj = obj.vals; + for (var key in obj) { + var nodes = obj[key].nodes[0].nodes; + if (nodes && nodes.length) { + obj[key] = []; + for (var i = 0, len = nodes.length; i < len; ++i) { + obj[key].push(convert(nodes[i])); + } + } else { + obj[key] = convert(obj[key].first); + } + } + return obj; + + function convert(node){ + switch (node.nodeName) { + case 'object': + return parseObject(node); + case 'boolean': + return node.isTrue; + case 'unit': + return node.type ? node.toString() : +node.val; + case 'string': + case 'literal': + return node.val; + default: + return node.toString(); + } + } +} diff --git a/node_modules/stylus/lib/functions/warn.js b/node_modules/stylus/lib/functions/warn.js new file mode 100644 index 00000000..eee647d6 --- /dev/null +++ b/node_modules/stylus/lib/functions/warn.js @@ -0,0 +1,15 @@ +var utils = require('../utils') + , nodes = require('../nodes'); + +/** + * Warn with the given `msg` prefixed by "Warning: ". + * + * @param {String} msg + * @api public + */ + +module.exports = function warn(msg){ + utils.assertType(msg, 'string', 'msg'); + console.warn('Warning: %s', msg.val); + return nodes.null; +}; |
