Files
echo-nexus/node_modules/@codesandbox/sandpack-client/sandpack/static/js/stylus.min.js
T

8164 lines
258 KiB
JavaScript

if (
Function.prototype.name === undefined &&
Object.defineProperty !== undefined
) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var regex = /function\s([^(]{1,})\(/,
match = regex.exec(this.toString());
return match && match.length > 1 ? match[1].trim() : '';
},
});
}
if (String.prototype.trimRight === undefined) {
String.prototype.trimRight = function() {
return String(this).replace(/\s+$/, '');
};
}
var stylus = (function() {
function require(p) {
var path = require.resolve(p),
mod = require.modules[path];
if (!mod) throw new Error('failed to require "' + p + '"');
if (!mod.exports) {
mod.exports = {};
mod.call(mod.exports, mod, mod.exports, require.relative(path));
}
return mod.exports;
}
var bifs =
"called-from = ()\n\nvendors = moz webkit o ms official\n\n// stringify the given arg\n\n-string(arg)\n type(arg) + ' ' + arg\n\n// require a color\n\nrequire-color(color)\n unless color is a 'color'\n error('RGB or HSL value expected, got a ' + -string(color))\n\n// require a unit\n\nrequire-unit(n)\n unless n is a 'unit'\n error('unit expected, got a ' + -string(n))\n\n// require a string\n\nrequire-string(str)\n unless str is a 'string' or str is a 'ident'\n error('string expected, got a ' + -string(str))\n\n// Math functions\n\nabs(n) { math(n, 'abs') }\nmin(a, b) { a < b ? a : b }\nmax(a, b) { a > b ? a : b }\n\n// Trigonometrics\nPI = -math-prop('PI')\n\nradians-to-degrees(angle)\n angle * (180 / PI)\n\ndegrees-to-radians(angle)\n unit(angle * (PI / 180),'')\n\nsin(n)\n n = degrees-to-radians(n) if unit(n) == 'deg'\n round(math(n, 'sin'), 9)\n\ncos(n)\n n = degrees-to-radians(n) if unit(n) == 'deg'\n round(math(n, 'cos'), 9)\n\n// Rounding Math functions\n\nceil(n, precision = 0)\n multiplier = 10 ** precision\n math(n * multiplier, 'ceil') / multiplier\n\nfloor(n, precision = 0)\n multiplier = 10 ** precision\n math(n * multiplier, 'floor') / multiplier\n\nround(n, precision = 0)\n multiplier = 10 ** precision\n math(n * multiplier, 'round') / multiplier\n\n// return the sum of the given numbers\n\nsum(nums)\n sum = 0\n sum += n for n in nums\n\n// return the average of the given numbers\n\navg(nums)\n sum(nums) / length(nums)\n\n// return a unitless number, or pass through\n\nremove-unit(n)\n if typeof(n) is 'unit'\n unit(n, '')\n else\n n\n\n// convert a percent to a decimal, or pass through\n\npercent-to-decimal(n)\n if unit(n) is '%'\n remove-unit(n) / 100\n else\n n\n\n// check if n is an odd number\n\nodd(n)\n 1 == n % 2\n\n// check if n is an even number\n\neven(n)\n 0 == n % 2\n\n// check if color is light\n\nlight(color)\n lightness(color) >= 50%\n\n// check if color is dark\n\ndark(color)\n lightness(color) < 50%\n\n// desaturate color by amount\n\ndesaturate(color, amount)\n adjust(color, 'saturation', - amount)\n\n// saturate color by amount\n\nsaturate(color = '', amount = 100%)\n if color is a 'color'\n adjust(color, 'saturation', amount)\n else\n unquote( 'saturate(' + color + ')' )\n\n// darken by the given amount\n\ndarken(color, amount)\n adjust(color, 'lightness', - amount)\n\n// lighten by the given amount\n\nlighten(color, amount)\n adjust(color, 'lightness', amount)\n\n// decrease opacity by amount\n\nfade-out(color, amount)\n color - rgba(black, percent-to-decimal(amount))\n\n// increase opacity by amount\n\nfade-in(color, amount)\n color + rgba(black, percent-to-decimal(amount))\n\n// spin hue by a given amount\n\nspin(color, amount)\n color + unit(amount, deg)\n\n// mix two colors by a given amount\n\nmix(color1, color2, weight = 50%)\n unless weight in 0..100\n error('Weight must be between 0% and 100%')\n\n if length(color1) == 2\n weight = color1[0]\n color1 = color1[1]\n\n else if length(color2) == 2\n weight = 100 - color2[0]\n color2 = color2[1]\n\n require-color(color1)\n require-color(color2)\n\n p = unit(weight / 100, '')\n w = p * 2 - 1\n\n a = alpha(color1) - alpha(color2)\n\n w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2\n w2 = 1 - w1\n\n channels = (red(color1) red(color2)) (green(color1) green(color2)) (blue(color1) blue(color2))\n rgb = ()\n\n for pair in channels\n push(rgb, floor(pair[0] * w1 + pair[1] * w2))\n\n a1 = alpha(color1) * p\n a2 = alpha(color2) * (1 - p)\n alpha = a1 + a2\n\n rgba(rgb[0], rgb[1], rgb[2], alpha)\n\n// invert colors, leave alpha intact\n\ninvert(color = '')\n if color is a 'color'\n rgba(#fff - color, alpha(color))\n else\n unquote( 'invert(' + color + ')' )\n\n// give complement of the given color\n\ncomplement( color )\n spin( color, 180 )\n\n// give grayscale of the given color\n\ngrayscale( color = '' )\n if color is a 'color'\n desaturate( color, 100% )\n else\n unquote( 'grayscale(' + color + ')' )\n\n// mix the given color with white\n\ntint( color, percent )\n mix( white, color, percent )\n\n// mix the given color with black\n\nshade( color, percent )\n mix( black, color, percent )\n\n// return the last value in the given expr\n\nlast(expr)\n expr[length(expr) - 1]\n\n// return keys in the given pairs or object\n\nkeys(pairs)\n ret = ()\n if type(pairs) == 'object'\n for key in pairs\n push(ret, key)\n else\n for pair in pairs\n push(ret, pair[0]);\n ret\n\n// return values in the given pairs or object\n\nvalues(pairs)\n ret = ()\n if type(pairs) == 'object'\n for key, val in pairs\n push(ret, val)\n else\n for pair in pairs\n push(ret, pair[1]);\n ret\n\n// join values with the given delimiter\n\njoin(delim, vals...)\n buf = ''\n vals = vals[0] if length(vals) == 1\n for val, i in vals\n buf += i ? delim + val : val\n\n// add a CSS rule to the containing block\n\n// - This definition allows add-property to be used as a mixin\n// - It has the same effect as interpolation but allows users\n// to opt for a functional style\n\nadd-property-function = add-property\nadd-property(name, expr)\n if mixin\n {name} expr\n else\n add-property-function(name, expr)\n\nprefix-classes(prefix)\n -prefix-classes(prefix, block)\n\n// Caching mixin, use inside your functions to enable caching by extending.\n\n$stylus_mixin_cache = {}\ncache()\n $key = (current-media() or 'no-media') + '__' + called-from[0] + '__' + arguments\n if $key in $stylus_mixin_cache\n @extend {'$cache_placeholder_for_' + $stylus_mixin_cache[$key]}\n else if 'cache' in called-from\n {block}\n else\n $id = length($stylus_mixin_cache)\n\n &,\n /$cache_placeholder_for_{$id}\n $stylus_mixin_cache[$key] = $id\n {block}\n\n// Percentage function to convert a number, e.g. '.45', into a percentage, e.g. '45%'\n\npercentage(num)\n return unit(num * 100, '%')\n\n// Returns the position of a `value` within a `list`\n\nindex(list, value)\n for val, i in list\n return i if val == value\n";
require.modules = {};
require.resolve = function(path) {
var orig = path,
reg = path + '.js',
index = path + '/index.js';
return (
(require.modules[reg] && reg) || (require.modules[index] && index) || orig
);
};
require.register = function(path, fn) {
require.modules[path] = fn;
};
require.relative = function(parent) {
return function(p) {
if ('.' != p[0]) return require(p);
var path = parent.split('/'),
segs = p.split('/');
path.pop();
for (var i = 0; i < segs.length; i++) {
var seg = segs[i];
if ('..' == seg) path.pop();
else if ('.' != seg) path.push(seg);
}
return require(path.join('/'));
};
};
require.register('path.js', function(module, exports, require) {
var isWindows = false;
function normalizeArray(parts, allowAboveRoot) {
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last == '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
var splitPathRe = /^([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
exports.normalize = function(path) {
var isAbsolute = path.charAt(0) === '/',
trailingSlash = path.slice(-1) === '/';
path = normalizeArray(
path.split('/').filter(function(p) {
return !!p;
}),
!isAbsolute,
).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(
paths
.filter(function(p, index) {
return p && typeof p === 'string';
})
.join('/'),
);
};
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
exports.dirname = function(path) {
var dir = splitPathRe.exec(path)[1] || '';
if (!dir) {
return '.';
} else if (
dir.length === 1 ||
(isWindows && dir.length <= 3 && dir.charAt(1) === ':')
) {
return dir;
} else {
return dir.substring(0, dir.length - 1);
}
};
exports.basename = function(path, ext) {
var f = splitPathRe.exec(path)[2] || '';
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPathRe.exec(path)[3] || '';
};
});
require.register('colors.js', function(module, exports, require) {
module.exports = {
aliceblue: [240, 248, 255, 1],
antiquewhite: [250, 235, 215, 1],
aqua: [0, 255, 255, 1],
aquamarine: [127, 255, 212, 1],
azure: [240, 255, 255, 1],
beige: [245, 245, 220, 1],
bisque: [255, 228, 196, 1],
black: [0, 0, 0, 1],
blanchedalmond: [255, 235, 205, 1],
blue: [0, 0, 255, 1],
blueviolet: [138, 43, 226, 1],
brown: [165, 42, 42, 1],
burlywood: [222, 184, 135, 1],
cadetblue: [95, 158, 160, 1],
chartreuse: [127, 255, 0, 1],
chocolate: [210, 105, 30, 1],
coral: [255, 127, 80, 1],
cornflowerblue: [100, 149, 237, 1],
cornsilk: [255, 248, 220, 1],
crimson: [220, 20, 60, 1],
cyan: [0, 255, 255, 1],
darkblue: [0, 0, 139, 1],
darkcyan: [0, 139, 139, 1],
darkgoldenrod: [184, 134, 11, 1],
darkgray: [169, 169, 169, 1],
darkgreen: [0, 100, 0, 1],
darkgrey: [169, 169, 169, 1],
darkkhaki: [189, 183, 107, 1],
darkmagenta: [139, 0, 139, 1],
darkolivegreen: [85, 107, 47, 1],
darkorange: [255, 140, 0, 1],
darkorchid: [153, 50, 204, 1],
darkred: [139, 0, 0, 1],
darksalmon: [233, 150, 122, 1],
darkseagreen: [143, 188, 143, 1],
darkslateblue: [72, 61, 139, 1],
darkslategray: [47, 79, 79, 1],
darkslategrey: [47, 79, 79, 1],
darkturquoise: [0, 206, 209, 1],
darkviolet: [148, 0, 211, 1],
deeppink: [255, 20, 147, 1],
deepskyblue: [0, 191, 255, 1],
dimgray: [105, 105, 105, 1],
dimgrey: [105, 105, 105, 1],
dodgerblue: [30, 144, 255, 1],
firebrick: [178, 34, 34, 1],
floralwhite: [255, 250, 240, 1],
forestgreen: [34, 139, 34, 1],
fuchsia: [255, 0, 255, 1],
gainsboro: [220, 220, 220, 1],
ghostwhite: [248, 248, 255, 1],
gold: [255, 215, 0, 1],
goldenrod: [218, 165, 32, 1],
gray: [128, 128, 128, 1],
green: [0, 128, 0, 1],
greenyellow: [173, 255, 47, 1],
grey: [128, 128, 128, 1],
honeydew: [240, 255, 240, 1],
hotpink: [255, 105, 180, 1],
indianred: [205, 92, 92, 1],
indigo: [75, 0, 130, 1],
ivory: [255, 255, 240, 1],
khaki: [240, 230, 140, 1],
lavender: [230, 230, 250, 1],
lavenderblush: [255, 240, 245, 1],
lawngreen: [124, 252, 0, 1],
lemonchiffon: [255, 250, 205, 1],
lightblue: [173, 216, 230, 1],
lightcoral: [240, 128, 128, 1],
lightcyan: [224, 255, 255, 1],
lightgoldenrodyellow: [250, 250, 210, 1],
lightgray: [211, 211, 211, 1],
lightgreen: [144, 238, 144, 1],
lightgrey: [211, 211, 211, 1],
lightpink: [255, 182, 193, 1],
lightsalmon: [255, 160, 122, 1],
lightseagreen: [32, 178, 170, 1],
lightskyblue: [135, 206, 250, 1],
lightslategray: [119, 136, 153, 1],
lightslategrey: [119, 136, 153, 1],
lightsteelblue: [176, 196, 222, 1],
lightyellow: [255, 255, 224, 1],
lime: [0, 255, 0, 1],
limegreen: [50, 205, 50, 1],
linen: [250, 240, 230, 1],
magenta: [255, 0, 255, 1],
maroon: [128, 0, 0, 1],
mediumaquamarine: [102, 205, 170, 1],
mediumblue: [0, 0, 205, 1],
mediumorchid: [186, 85, 211, 1],
mediumpurple: [147, 112, 219, 1],
mediumseagreen: [60, 179, 113, 1],
mediumslateblue: [123, 104, 238, 1],
mediumspringgreen: [0, 250, 154, 1],
mediumturquoise: [72, 209, 204, 1],
mediumvioletred: [199, 21, 133, 1],
midnightblue: [25, 25, 112, 1],
mintcream: [245, 255, 250, 1],
mistyrose: [255, 228, 225, 1],
moccasin: [255, 228, 181, 1],
navajowhite: [255, 222, 173, 1],
navy: [0, 0, 128, 1],
oldlace: [253, 245, 230, 1],
olive: [128, 128, 0, 1],
olivedrab: [107, 142, 35, 1],
orange: [255, 165, 0, 1],
orangered: [255, 69, 0, 1],
orchid: [218, 112, 214, 1],
palegoldenrod: [238, 232, 170, 1],
palegreen: [152, 251, 152, 1],
paleturquoise: [175, 238, 238, 1],
palevioletred: [219, 112, 147, 1],
papayawhip: [255, 239, 213, 1],
peachpuff: [255, 218, 185, 1],
peru: [205, 133, 63, 1],
pink: [255, 192, 203, 1],
plum: [221, 160, 221, 1],
powderblue: [176, 224, 230, 1],
purple: [128, 0, 128, 1],
red: [255, 0, 0, 1],
rosybrown: [188, 143, 143, 1],
royalblue: [65, 105, 225, 1],
saddlebrown: [139, 69, 19, 1],
salmon: [250, 128, 114, 1],
sandybrown: [244, 164, 96, 1],
seagreen: [46, 139, 87, 1],
seashell: [255, 245, 238, 1],
sienna: [160, 82, 45, 1],
silver: [192, 192, 192, 1],
skyblue: [135, 206, 235, 1],
slateblue: [106, 90, 205, 1],
slategray: [112, 128, 144, 1],
slategrey: [112, 128, 144, 1],
snow: [255, 250, 250, 1],
springgreen: [0, 255, 127, 1],
steelblue: [70, 130, 180, 1],
tan: [210, 180, 140, 1],
teal: [0, 128, 128, 1],
thistle: [216, 191, 216, 1],
tomato: [255, 99, 71, 1],
transparent: [0, 0, 0, 0],
turquoise: [64, 224, 208, 1],
violet: [238, 130, 238, 1],
wheat: [245, 222, 179, 1],
white: [255, 255, 255, 1],
whitesmoke: [245, 245, 245, 1],
yellow: [255, 255, 0, 1],
yellowgreen: [154, 205, 50, 1],
rebeccapurple: [102, 51, 153, 1],
};
});
require.register('errors.js', function(module, exports, require) {
exports.ParseError = ParseError;
exports.SyntaxError = SyntaxError;
SyntaxError.prototype.__proto__ = Error.prototype;
function ParseError(msg) {
this.name = 'ParseError';
this.message = msg;
Error.captureStackTrace(this, ParseError);
}
ParseError.prototype.__proto__ = Error.prototype;
function SyntaxError(msg) {
this.name = 'SyntaxError';
this.message = msg;
Error.captureStackTrace(this, ParseError);
}
SyntaxError.prototype.__proto__ = Error.prototype;
});
require.register('units.js', function(module, exports, require) {
module.exports = [
'em',
'ex',
'ch',
'rem',
'vw',
'vh',
'vmin',
'vmax',
'cm',
'mm',
'in',
'pt',
'pc',
'px',
'deg',
'grad',
'rad',
'turn',
's',
'ms',
'Hz',
'kHz',
'dpi',
'dpcm',
'dppx',
'x',
'%',
'fr',
];
});
require.register('functions/index.js', function(module, exports, require) {
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.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.warn = require('./warn');
exports['-math-prop'] = require('./math-prop');
exports['-prefix-classes'] = require('./prefix-classes');
});
require.register('functions/url.js', function(module, exports, require) {
var Compiler = require('../visitor/compiler'),
events = require('../renderer').events,
nodes = require('../nodes'),
extname = require('../path').extname,
utils = require('../utils');
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',
};
var encodingTypes = { BASE_64: 'base64', UTF8: 'charset=utf-8' };
module.exports = function(options) {
options = options || {};
var _paths = options.paths || [];
var sizeLimit = null != options.limit ? options.limit : 3e4;
var mimes = options.mimes || defaultMimes;
function fn(url, enc) {
var compiler = new Compiler(url),
encoding = encodingTypes.BASE_64;
compiler.isURL = true;
url = url.nodes
.map(function(node) {
return compiler.visit(node);
})
.join('');
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;
if (!mime) return literal;
if (url.protocol) return literal;
var found = utils.lookup(url.pathname, paths);
if (!found) {
events.emit(
'file not found',
'File ' + literal + ' could not be found, literal url retained!',
);
return literal;
}
buf = fs.readFileSync(found);
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;
}
return new nodes.Literal(
'url("data:' + mime + ';' + encoding + ',' + result + '")',
);
}
fn.raw = true;
return fn;
};
module.exports.mimes = defaultMimes;
});
require.register('functions/add-property.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
(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;
});
require.register('functions/adjust.js', function(module, exports, require) {
var utils = require('../utils');
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;
};
});
require.register('functions/alpha.js', function(module, exports, require) {
var nodes = require('../nodes'),
rgba = require('./rgba');
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, '');
};
});
require.register('functions/base-convert.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
(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;
});
require.register('functions/basename.js', function(module, exports, require) {
var utils = require('../utils'),
path = require('../path');
module.exports = function basename(p, ext) {
utils.assertString(p, 'path');
return path.basename(p.val, ext && ext.val);
};
});
require.register('functions/blend.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
module.exports = function blend(top, bottom) {
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,
);
};
});
require.register('functions/blue.js', function(module, exports, require) {
var nodes = require('../nodes'),
rgba = require('./rgba');
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, '');
};
});
require.register('functions/clone.js', function(module, exports, require) {
var utils = require('../utils');
(module.exports = function clone(expr) {
utils.assertPresent(expr, 'expr');
return expr.clone();
}).raw = true;
});
require.register('functions/component.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
var componentMap = {
red: 'r',
green: 'g',
blue: 'b',
alpha: 'a',
hue: 'h',
saturation: 's',
lightness: 'l',
};
var unitMap = { hue: 'deg', saturation: '%', lightness: '%' };
var typeMap = {
red: 'rgba',
blue: 'rgba',
green: 'rgba',
alpha: 'rgba',
hue: 'hsla',
saturation: 'hsla',
lightness: 'hsla',
};
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);
};
});
require.register('functions/contrast.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes'),
blend = require('./blend'),
luminosity = require('./luminosity');
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;
};
});
require.register('functions/convert.js', function(module, exports, require) {
var utils = require('../utils');
module.exports = function convert(str) {
utils.assertString(str, 'str');
return utils.parseString(str.string);
};
});
require.register('functions/current-media.js', function(
module,
exports,
require,
) {
var nodes = require('../nodes');
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);
}
}
};
});
require.register('functions/define.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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.nil;
};
});
require.register('functions/dirname.js', function(module, exports, require) {
var utils = require('../utils'),
path = require('../path');
module.exports = function dirname(p) {
utils.assertString(p, 'path');
return path.dirname(p.val).replace(/\\/g, '/');
};
});
require.register('functions/error.js', function(module, exports, require) {
var utils = require('../utils');
module.exports = function error(msg) {
utils.assertType(msg, 'string', 'msg');
var err = new Error(msg.val);
err.fromStylus = true;
throw err;
};
});
require.register('functions/extname.js', function(module, exports, require) {
var utils = require('../utils'),
path = require('../path');
module.exports = function extname(p) {
utils.assertString(p, 'path');
return path.extname(p.val);
};
});
require.register('functions/green.js', function(module, exports, require) {
var nodes = require('../nodes'),
rgba = require('./rgba');
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, '');
};
});
require.register('functions/hsl.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes'),
hsla = require('./hsla');
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));
}
};
});
require.register('functions/hsla.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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,
);
}
};
});
require.register('functions/hue.js', function(module, exports, require) {
var nodes = require('../nodes'),
hsla = require('./hsla'),
component = require('./component');
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'));
};
});
require.register('functions/length.js', function(module, exports, require) {
var utils = require('../utils');
(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;
});
require.register('functions/lightness.js', function(
module,
exports,
require,
) {
var nodes = require('../nodes'),
hsla = require('./hsla'),
component = require('./component');
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'));
};
});
require.register('functions/list-separator.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
(module.exports = function listSeparator(list) {
list = utils.unwrap(list);
return new nodes.String(list.isList ? ',' : ' ');
}).raw = true;
});
require.register('functions/lookup.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
module.exports = function lookup(name) {
utils.assertType(name, 'string', 'name');
var node = this.lookup(name.val);
if (!node) return nodes.nil;
return this.visit(node);
};
});
require.register('functions/luminosity.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
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),
);
};
});
require.register('functions/match.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
var VALID_FLAGS = 'igm';
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;
}
});
require.register('functions/math-prop.js', function(
module,
exports,
require,
) {
var nodes = require('../nodes');
module.exports = function math(prop) {
return new nodes.Unit(Math[prop.string]);
};
});
require.register('functions/math.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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);
};
});
require.register('functions/merge.js', function(module, exports, require) {
var utils = require('../utils');
(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;
});
require.register('functions/operate.js', function(module, exports, require) {
var utils = require('../utils');
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);
};
});
require.register('functions/opposite-position.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
(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;
});
require.register('functions/p.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
(module.exports = function p() {
[].slice.call(arguments).forEach(function(expr) {
expr = utils.unwrap(expr);
if (!expr.nodes.length) return;
console.log(
'inspect: %s',
expr.toString().replace(/^\(|\)$/g, ''),
);
});
return nodes.nil;
}).raw = true;
});
require.register('functions/pathjoin.js', function(module, exports, require) {
var path = require('../path');
(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;
});
require.register('functions/pop.js', function(module, exports, require) {
var utils = require('../utils');
(module.exports = function pop(expr) {
expr = utils.unwrap(expr);
return expr.nodes.pop();
}).raw = true;
});
require.register('functions/prefix-classes.js', function(
module,
exports,
require,
) {
var utils = require('../utils');
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;
};
});
require.register('functions/push.js', function(module, exports, require) {
var utils = require('../utils');
(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;
});
require.register('functions/range.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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;
};
});
require.register('functions/red.js', function(module, exports, require) {
var nodes = require('../nodes'),
rgba = require('./rgba');
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, '');
};
});
require.register('functions/remove.js', function(module, exports, require) {
var utils = require('../utils');
module.exports = function remove(object, key) {
utils.assertType(object, 'object', 'object');
utils.assertString(key, 'key');
delete object.vals[key.string];
return object;
};
});
require.register('functions/replace.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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);
};
});
require.register('functions/rgb.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes'),
rgba = require('./rgba');
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));
}
};
});
require.register('functions/rgba.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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);
}
};
});
require.register('functions/s.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes'),
Compiler = require('../visitor/compiler');
(module.exports = function s(fmt) {
fmt = utils.unwrap(fmt).nodes[0];
utils.assertString(fmt);
var self = this,
str = fmt.string,
args = arguments,
i = 1;
str = str.replace(/%(s|d)/g, function(_, specifier) {
var arg = args[i++] || nodes.nil;
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;
});
require.register('functions/saturation.js', function(
module,
exports,
require,
) {
var nodes = require('../nodes'),
hsla = require('./hsla'),
component = require('./component');
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'));
};
});
require.register('functions/selector-exists.js', function(
module,
exports,
require,
) {
var utils = require('../utils');
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__;
};
});
require.register('functions/selector.js', function(module, exports, require) {
var utils = require('../utils');
(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;
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) {
if (expr.isList) {
pushToStack(expr.nodes, stack);
} else {
stack.push(
parse(
expr.nodes
.map(function(node) {
utils.assertString(node, 'selector');
return node.string;
})
.join(' '),
),
);
}
}
} 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;
}
});
require.register('functions/selectors.js', function(
module,
exports,
require,
) {
var nodes = require('../nodes'),
Parser = require('../selector-parser');
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;
};
});
require.register('functions/shift.js', function(module, exports, require) {
var utils = require('../utils');
(module.exports = function(expr) {
expr = utils.unwrap(expr);
return expr.nodes.shift();
}).raw = true;
});
require.register('functions/split.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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;
};
});
require.register('functions/slice.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
(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;
});
require.register('functions/substr.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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);
};
});
require.register('functions/tan.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
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, '');
};
});
require.register('functions/trace.js', function(module, exports, require) {
var nodes = require('../nodes');
module.exports = function trace() {
console.log(this.stack);
return nodes.nil;
};
});
require.register('functions/transparentify.js', function(
module,
exports,
require,
) {
var utils = require('../utils'),
nodes = require('../nodes');
module.exports = function transparentify(top, bottom, alpha) {
utils.assertColor(top);
top = top.rgba;
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);
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,
);
};
});
require.register('functions/type.js', function(module, exports, require) {
var utils = require('../utils');
module.exports = function type(node) {
utils.assertPresent(node, 'expression');
return node.nodeName;
};
});
require.register('functions/unit.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
module.exports = function unit(unit, type) {
utils.assertType(unit, 'unit', 'unit');
if (type) {
utils.assertString(type, 'type');
return new nodes.Unit(unit.val, type.string);
} else {
return unit.type || '';
}
};
});
require.register('functions/unquote.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
module.exports = function unquote(string) {
utils.assertString(string, 'string');
return new nodes.Literal(string.string);
};
});
require.register('functions/unshift.js', function(module, exports, require) {
var utils = require('../utils');
(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;
});
require.register('functions/warn.js', function(module, exports, require) {
var utils = require('../utils'),
nodes = require('../nodes');
module.exports = function warn(msg) {
utils.assertType(msg, 'string', 'msg');
console.warn('Warning: %s', msg.val);
return nodes.nil;
};
});
require.register('lexer.js', function(module, exports, require) {
var Token = require('./token'),
nodes = require('./nodes'),
errors = require('./errors');
exports = module.exports = Lexer;
var alias = {
and: '&&',
or: '||',
is: '==',
isnt: '!=',
'is not': '!=',
':=': '?=',
};
function Lexer(str, options) {
options = options || {};
this.stash = [];
this.indentStack = [];
this.indentRe = null;
this.lineno = 1;
this.column = 1;
function comment(str, val, offset, s) {
var inComment =
s.lastIndexOf('/*', offset) > s.lastIndexOf('*/', offset),
commentIdx = s.lastIndexOf('//', offset),
i = s.lastIndexOf('\n', offset),
double = 0,
single = 0;
if (~commentIdx && commentIdx > i) {
while (i != offset) {
if ("'" == s[i]) single ? single-- : single++;
if ('"' == s[i]) double ? double-- : double++;
if ('/' == s[i] && '/' == s[i + 1]) {
inComment = !single && !double;
break;
}
++i;
}
}
return inComment ? str : val + '\r';
}
if ('\ufeff' == str.charAt(0)) str = str.slice(1);
this.str = str
.replace(/\s+$/, '\n')
.replace(/\r\n?/g, '\n')
.replace(/\\ *\n/g, '\r')
.replace(
/([,(:](?!\/\/[^ ])) *(?:\/\/[^\n]*|\/\*.*?\*\/)?\n\s*/g,
comment,
)
.replace(/\s*\n[ \t]*([,)])/g, comment);
}
Lexer.prototype = {
inspect: function() {
var tok,
tmp = this.str,
buf = [];
while ('eos' != (tok = this.next()).type) {
buf.push(tok.inspect());
}
this.str = tmp;
return buf.concat(tok.inspect()).join('\n');
},
lookahead: function(n) {
var fetch = n - this.stash.length;
while (fetch-- > 0) this.stash.push(this.advance());
return this.stash[--n];
},
skip: function(len) {
var chunk = len[0];
len = chunk ? chunk.length : len;
this.str = this.str.substr(len);
if (chunk) {
this.move(chunk);
} else {
this.column += len;
}
},
move: function(str) {
var lines = str.match(/\n/g),
idx = str.lastIndexOf('\n');
if (lines) this.lineno += lines.length;
this.column = ~idx ? str.length - idx : this.column + str.length;
},
next: function() {
var tok = this.stashed() || this.advance();
this.prev = tok;
return tok;
},
isPartOfSelector: function() {
var tok = this.stash[this.stash.length - 1] || this.prev;
switch (tok && tok.type) {
case 'color':
return 2 == tok.val.raw.length;
case '.':
case '[':
return true;
}
return false;
},
advance: function() {
var column = this.column,
line = this.lineno,
tok =
this.eos() ||
this.nil() ||
this.sep() ||
this.keyword() ||
this.urlchars() ||
this.comment() ||
this.newline() ||
this.escaped() ||
this.important() ||
this.literal() ||
this.fun() ||
this.anonFunc() ||
this.atrule() ||
this.brace() ||
this.paren() ||
this.color() ||
this.string() ||
this.unit() ||
this.namedop() ||
this.boolean() ||
this.unicode() ||
this.ident() ||
this.op() ||
this.eol() ||
this.space() ||
this.selector();
tok.lineno = line;
tok.column = column;
return tok;
},
peek: function() {
return this.lookahead(1);
},
stashed: function() {
return this.stash.shift();
},
eos: function() {
if (this.str.length) return;
if (this.indentStack.length) {
this.indentStack.shift();
return new Token('outdent');
} else {
return new Token('eos');
}
},
urlchars: function() {
var captures;
if (!this.isURL) return;
if ((captures = /^[\/:@.;?&=*!,<>#%0-9]+/.exec(this.str))) {
this.skip(captures);
return new Token('literal', new nodes.Literal(captures[0]));
}
},
sep: function() {
var captures;
if ((captures = /^;[ \t]*/.exec(this.str))) {
this.skip(captures);
return new Token(';');
}
},
eol: function() {
if ('\r' == this.str[0]) {
++this.lineno;
this.skip(1);
return this.advance();
}
},
space: function() {
var captures;
if ((captures = /^([ \t]+)/.exec(this.str))) {
this.skip(captures);
return new Token('space');
}
},
escaped: function() {
var captures;
if ((captures = /^\\(.)[ \t]*/.exec(this.str))) {
var c = captures[1];
this.skip(captures);
return new Token('ident', new nodes.Literal(c));
}
},
literal: function() {
var captures;
if ((captures = /^@css[ \t]*\{/.exec(this.str))) {
this.skip(captures);
var c,
braces = 1,
css = '',
node;
while ((c = this.str[0])) {
this.str = this.str.substr(1);
switch (c) {
case '{':
++braces;
break;
case '}':
--braces;
break;
case '\n':
case '\r':
++this.lineno;
break;
}
css += c;
if (!braces) break;
}
css = css.replace(/\s*}$/, '');
node = new nodes.Literal(css);
node.css = true;
return new Token('literal', node);
}
},
important: function() {
var captures;
if ((captures = /^!important[ \t]*/.exec(this.str))) {
this.skip(captures);
return new Token('ident', new nodes.Literal('!important'));
}
},
brace: function() {
var captures;
if ((captures = /^([{}])/.exec(this.str))) {
this.skip(1);
var brace = captures[1];
return new Token(brace, brace);
}
},
paren: function() {
var captures;
if ((captures = /^([()])([ \t]*)/.exec(this.str))) {
var paren = captures[1];
this.skip(captures);
if (')' == paren) this.isURL = false;
var tok = new Token(paren, paren);
tok.space = captures[2];
return tok;
}
},
nil: function() {
var captures, tok;
if ((captures = /^(null)\b[ \t]*/.exec(this.str))) {
this.skip(captures);
if (this.isPartOfSelector()) {
tok = new Token('ident', new nodes.Ident(captures[0]));
} else {
tok = new Token('null', nodes.nil);
}
return tok;
}
},
keyword: function() {
var captures, tok;
if (
(captures = /^(return|if|else|unless|for|in)\b[ \t]*/.exec(this.str))
) {
var keyword = captures[1];
this.skip(captures);
if (this.isPartOfSelector()) {
tok = new Token('ident', new nodes.Ident(captures[0]));
} else {
tok = new Token(keyword, keyword);
}
return tok;
}
},
namedop: function() {
var captures, tok;
if (
(captures = /^(not|and|or|is a|is defined|isnt|is not|is)(?!-)\b([ \t]*)/.exec(
this.str,
))
) {
var op = captures[1];
this.skip(captures);
if (this.isPartOfSelector()) {
tok = new Token('ident', new nodes.Ident(captures[0]));
} else {
op = alias[op] || op;
tok = new Token(op, op);
}
tok.space = captures[2];
return tok;
}
},
op: function() {
var captures;
if (
(captures = /^([.]{1,3}|&&|\|\||[!<>=?:]=|\*\*|[-+*\/%]=?|[,=?:!~<>&\[\]])([ \t]*)/.exec(
this.str,
))
) {
var op = captures[1];
this.skip(captures);
op = alias[op] || op;
var tok = new Token(op, op);
tok.space = captures[2];
this.isURL = false;
return tok;
}
},
anonFunc: function() {
var tok;
if ('@' == this.str[0] && '(' == this.str[1]) {
this.skip(2);
tok = new Token('function', new nodes.Ident('anonymous'));
tok.anonymous = true;
return tok;
}
},
atrule: function() {
var captures;
if (
(captures = /^@(?:-(\w+)-)?([a-zA-Z0-9-_]+)[ \t]*/.exec(this.str))
) {
this.skip(captures);
var vendor = captures[1],
type = captures[2],
tok;
switch (type) {
case 'require':
case 'import':
case 'charset':
case 'namespace':
case 'media':
case 'scope':
case 'supports':
return new Token(type);
case 'document':
return new Token('-moz-document');
case 'block':
return new Token('atblock');
case 'extend':
case 'extends':
return new Token('extend');
case 'keyframes':
return new Token(type, vendor);
default:
return new Token(
'atrule',
vendor ? '-' + vendor + '-' + type : type,
);
}
}
},
comment: function() {
if ('/' == this.str[0] && '/' == this.str[1]) {
var end = this.str.indexOf('\n');
if (-1 == end) end = this.str.length;
this.skip(end);
return this.advance();
}
if ('/' == this.str[0] && '*' == this.str[1]) {
var end = this.str.indexOf('*/');
if (-1 == end) end = this.str.length;
var str = this.str.substr(0, end + 2),
lines = str.split(/\n|\r/).length - 1,
suppress = true,
inline = false;
this.lineno += lines;
this.skip(end + 2);
if ('!' == str[2]) {
str = str.replace('*!', '*');
suppress = false;
}
if (this.prev && ';' == this.prev.type) inline = true;
return new Token('comment', new nodes.Comment(str, suppress, inline));
}
},
boolean: function() {
var captures;
if ((captures = /^(true|false)\b([ \t]*)/.exec(this.str))) {
var val = nodes.Boolean('true' == captures[1]);
this.skip(captures);
var tok = new Token('boolean', val);
tok.space = captures[2];
return tok;
}
},
unicode: function() {
var captures;
if (
(captures = /^u\+[0-9a-f?]{1,6}(?:-[0-9a-f]{1,6})?/i.exec(this.str))
) {
this.skip(captures);
return new Token('literal', new nodes.Literal(captures[0]));
}
},
fun: function() {
var captures;
if ((captures = /^(-*[_a-zA-Z$][-\w\d$]*)\(([ \t]*)/.exec(this.str))) {
var name = captures[1];
this.skip(captures);
this.isURL = 'url' == name;
var tok = new Token('function', new nodes.Ident(name));
tok.space = captures[2];
return tok;
}
},
ident: function() {
var captures;
if ((captures = /^-*[_a-zA-Z$][-\w\d$]*/.exec(this.str))) {
this.skip(captures);
return new Token('ident', new nodes.Ident(captures[0]));
}
},
newline: function() {
var captures, re;
if (this.indentRe) {
captures = this.indentRe.exec(this.str);
} else {
re = /^\n([\t]*)[ \t]*/;
captures = re.exec(this.str);
if (captures && !captures[1].length) {
re = /^\n([ \t]*)/;
captures = re.exec(this.str);
}
if (captures && captures[1].length) this.indentRe = re;
}
if (captures) {
var tok,
indents = captures[1].length;
this.skip(captures);
if (this.str[0] === ' ' || this.str[0] === ' ') {
throw new errors.SyntaxError(
'Invalid indentation. You can use tabs or spaces to indent, but not both.',
);
}
if ('\n' == this.str[0]) return this.advance();
if (this.indentStack.length && indents < this.indentStack[0]) {
while (this.indentStack.length && this.indentStack[0] > indents) {
this.stash.push(new Token('outdent'));
this.indentStack.shift();
}
tok = this.stash.pop();
} else if (indents && indents != this.indentStack[0]) {
this.indentStack.unshift(indents);
tok = new Token('indent');
} else {
tok = new Token('newline');
}
return tok;
}
},
unit: function() {
var captures;
if (
(captures = /^(-)?(\d+\.\d+|\d+|\.\d+)(%|[a-zA-Z]+)?[ \t]*/.exec(
this.str,
))
) {
this.skip(captures);
var n = parseFloat(captures[2]);
if ('-' == captures[1]) n = -n;
var node = new nodes.Unit(n, captures[3]);
node.raw = captures[0];
return new Token('unit', node);
}
},
string: function() {
var captures;
if ((captures = /^("[^"]*"|'[^']*')[ \t]*/.exec(this.str))) {
var str = captures[1],
quote = captures[0][0];
this.skip(captures);
str = str.slice(1, -1).replace(/\\n/g, '\n');
return new Token('string', new nodes.String(str, quote));
}
},
color: function() {
return (
this.rrggbbaa() ||
this.rrggbb() ||
this.rgba() ||
this.rgb() ||
this.nn() ||
this.n()
);
},
n: function() {
var captures;
if ((captures = /^#([a-fA-F0-9]{1})[ \t]*/.exec(this.str))) {
this.skip(captures);
var n = parseInt(captures[1] + captures[1], 16),
color = new nodes.RGBA(n, n, n, 1);
color.raw = captures[0];
return new Token('color', color);
}
},
nn: function() {
var captures;
if ((captures = /^#([a-fA-F0-9]{2})[ \t]*/.exec(this.str))) {
this.skip(captures);
var n = parseInt(captures[1], 16),
color = new nodes.RGBA(n, n, n, 1);
color.raw = captures[0];
return new Token('color', color);
}
},
rgb: function() {
var captures;
if ((captures = /^#([a-fA-F0-9]{3})[ \t]*/.exec(this.str))) {
this.skip(captures);
var rgb = captures[1],
r = parseInt(rgb[0] + rgb[0], 16),
g = parseInt(rgb[1] + rgb[1], 16),
b = parseInt(rgb[2] + rgb[2], 16),
color = new nodes.RGBA(r, g, b, 1);
color.raw = captures[0];
return new Token('color', color);
}
},
rgba: function() {
var captures;
if ((captures = /^#([a-fA-F0-9]{4})[ \t]*/.exec(this.str))) {
this.skip(captures);
var rgb = captures[1],
r = parseInt(rgb[0] + rgb[0], 16),
g = parseInt(rgb[1] + rgb[1], 16),
b = parseInt(rgb[2] + rgb[2], 16),
a = parseInt(rgb[3] + rgb[3], 16),
color = new nodes.RGBA(r, g, b, a / 255);
color.raw = captures[0];
return new Token('color', color);
}
},
rrggbb: function() {
var captures;
if ((captures = /^#([a-fA-F0-9]{6})[ \t]*/.exec(this.str))) {
this.skip(captures);
var rgb = captures[1],
r = parseInt(rgb.substr(0, 2), 16),
g = parseInt(rgb.substr(2, 2), 16),
b = parseInt(rgb.substr(4, 2), 16),
color = new nodes.RGBA(r, g, b, 1);
color.raw = captures[0];
return new Token('color', color);
}
},
rrggbbaa: function() {
var captures;
if ((captures = /^#([a-fA-F0-9]{8})[ \t]*/.exec(this.str))) {
this.skip(captures);
var rgb = captures[1],
r = parseInt(rgb.substr(0, 2), 16),
g = parseInt(rgb.substr(2, 2), 16),
b = parseInt(rgb.substr(4, 2), 16),
a = parseInt(rgb.substr(6, 2), 16),
color = new nodes.RGBA(r, g, b, a / 255);
color.raw = captures[0];
return new Token('color', color);
}
},
selector: function() {
var captures;
if ((captures = /^\^|.*?(?=\/\/(?![^\[]*\])|[,\n{])/.exec(this.str))) {
var selector = captures[0];
this.skip(captures);
return new Token('selector', selector);
}
},
};
});
require.register('nodes/arguments.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('../nodes'),
utils = require('../utils');
var Arguments = (module.exports = function Arguments() {
nodes.Expression.call(this);
this.map = {};
});
Arguments.prototype.__proto__ = nodes.Expression.prototype;
Arguments.fromExpression = function(expr) {
var args = new Arguments(),
len = expr.nodes.length;
args.lineno = expr.lineno;
args.column = expr.column;
args.isList = expr.isList;
for (var i = 0; i < len; ++i) {
args.push(expr.nodes[i]);
}
return args;
};
Arguments.prototype.clone = function(parent) {
var clone = nodes.Expression.prototype.clone.call(this, parent);
clone.map = {};
for (var key in this.map) {
clone.map[key] = this.map[key].clone(parent, clone);
}
clone.isList = this.isList;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Arguments.prototype.toJSON = function() {
return {
__type: 'Arguments',
map: this.map,
isList: this.isList,
preserve: this.preserve,
lineno: this.lineno,
column: this.column,
filename: this.filename,
nodes: this.nodes,
};
};
});
require.register('nodes/binop.js', function(module, exports, require) {
var Node = require('./node');
var BinOp = (module.exports = function BinOp(op, left, right) {
Node.call(this);
this.op = op;
this.left = left;
this.right = right;
});
BinOp.prototype.__proto__ = Node.prototype;
BinOp.prototype.clone = function(parent) {
var clone = new BinOp(this.op);
clone.left = this.left.clone(parent, clone);
clone.right = this.right && this.right.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
if (this.val) clone.val = this.val.clone(parent, clone);
return clone;
};
BinOp.prototype.toString = function() {
return this.left.toString() + ' ' + this.op + ' ' + this.right.toString();
};
BinOp.prototype.toJSON = function() {
var json = {
__type: 'BinOp',
left: this.left,
right: this.right,
op: this.op,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.val) json.val = this.val;
return json;
};
});
require.register('nodes/block.js', function(module, exports, require) {
var Node = require('./node');
var Block = (module.exports = function Block(parent, node) {
Node.call(this);
this.nodes = [];
this.parent = parent;
this.node = node;
this.scope = true;
});
Block.prototype.__proto__ = Node.prototype;
Block.prototype.__defineGetter__('hasProperties', function() {
for (var i = 0, len = this.nodes.length; i < len; ++i) {
if ('property' == this.nodes[i].nodeName) {
return true;
}
}
});
Block.prototype.__defineGetter__('hasMedia', function() {
for (var i = 0, len = this.nodes.length; i < len; ++i) {
var nodeName = this.nodes[i].nodeName;
if ('media' == nodeName) {
return true;
}
}
return false;
});
Block.prototype.__defineGetter__('isEmpty', function() {
return !this.nodes.length;
});
Block.prototype.clone = function(parent, node) {
parent = parent || this.parent;
var clone = new Block(parent, node || this.node);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
clone.scope = this.scope;
this.nodes.forEach(function(node) {
clone.push(node.clone(clone, clone));
});
return clone;
};
Block.prototype.push = function(node) {
this.nodes.push(node);
};
Block.prototype.toJSON = function() {
return {
__type: 'Block',
scope: this.scope,
lineno: this.lineno,
column: this.column,
filename: this.filename,
nodes: this.nodes,
};
};
});
require.register('nodes/boolean.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var Boolean = (module.exports = function Boolean(val) {
Node.call(this);
if (this.nodeName) {
this.val = !!val;
} else {
return new Boolean(val);
}
});
Boolean.prototype.__proto__ = Node.prototype;
Boolean.prototype.toBoolean = function() {
return this;
};
Boolean.prototype.__defineGetter__('isTrue', function() {
return this.val;
});
Boolean.prototype.__defineGetter__('isFalse', function() {
return !this.val;
});
Boolean.prototype.negate = function() {
return new Boolean(!this.val);
};
Boolean.prototype.inspect = function() {
return '[Boolean ' + this.val + ']';
};
Boolean.prototype.toString = function() {
return this.val ? 'true' : 'false';
};
Boolean.prototype.toJSON = function() {
return { __type: 'Boolean', val: this.val };
};
});
require.register('nodes/call.js', function(module, exports, require) {
var Node = require('./node');
var Call = (module.exports = function Call(name, args) {
Node.call(this);
this.name = name;
this.args = args;
});
Call.prototype.__proto__ = Node.prototype;
Call.prototype.clone = function(parent) {
var clone = new Call(this.name);
clone.args = this.args.clone(parent, clone);
if (this.block) clone.block = this.block.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Call.prototype.toString = function() {
var args = this.args.nodes
.map(function(node) {
var str = node.toString();
return str.slice(1, str.length - 1);
})
.join(', ');
return this.name + '(' + args + ')';
};
Call.prototype.toJSON = function() {
var json = {
__type: 'Call',
name: this.name,
args: this.args,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.block) json.block = this.block;
return json;
};
});
require.register('nodes/charset.js', function(module, exports, require) {
var Node = require('./node');
var Charset = (module.exports = function Charset(val) {
Node.call(this);
this.val = val;
});
Charset.prototype.__proto__ = Node.prototype;
Charset.prototype.toString = function() {
return '@charset ' + this.val;
};
Charset.prototype.toJSON = function() {
return {
__type: 'Charset',
val: this.val,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/namespace.js', function(module, exports, require) {
var Node = require('./node');
var Namespace = (module.exports = function Namespace(val, prefix) {
Node.call(this);
this.val = val;
this.prefix = prefix;
});
Namespace.prototype.__proto__ = Node.prototype;
Namespace.prototype.toString = function() {
return '@namespace ' + (this.prefix ? this.prefix + ' ' : '') + this.val;
};
Namespace.prototype.toJSON = function() {
return {
__type: 'Namespace',
val: this.val,
prefix: this.prefix,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/comment.js', function(module, exports, require) {
var Node = require('./node');
var Comment = (module.exports = function Comment(str, suppress, inline) {
Node.call(this);
this.str = str;
this.suppress = suppress;
this.inline = inline;
});
Comment.prototype.__proto__ = Node.prototype;
Comment.prototype.toJSON = function() {
return {
__type: 'Comment',
str: this.str,
suppress: this.suppress,
inline: this.inline,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Comment.prototype.toString = function() {
return this.str;
};
});
require.register('nodes/each.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var Each = (module.exports = function Each(val, key, expr, block) {
Node.call(this);
this.val = val;
this.key = key;
this.expr = expr;
this.block = block;
});
Each.prototype.__proto__ = Node.prototype;
Each.prototype.clone = function(parent) {
var clone = new Each(this.val, this.key);
clone.expr = this.expr.clone(parent, clone);
clone.block = this.block.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Each.prototype.toJSON = function() {
return {
__type: 'Each',
val: this.val,
key: this.key,
expr: this.expr,
block: this.block,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/expression.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('../nodes'),
utils = require('../utils');
var Expression = (module.exports = function Expression(isList) {
Node.call(this);
this.nodes = [];
this.isList = isList;
});
Expression.prototype.__defineGetter__('isEmpty', function() {
return !this.nodes.length;
});
Expression.prototype.__defineGetter__('first', function() {
return this.nodes[0] ? this.nodes[0].first : nodes.nil;
});
Expression.prototype.__defineGetter__('hash', function() {
return this.nodes
.map(function(node) {
return node.hash;
})
.join('::');
});
Expression.prototype.__proto__ = Node.prototype;
Expression.prototype.clone = function(parent) {
var clone = new this.constructor(this.isList);
clone.preserve = this.preserve;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
clone.nodes = this.nodes.map(function(node) {
return node.clone(parent, clone);
});
return clone;
};
Expression.prototype.push = function(node) {
this.nodes.push(node);
};
Expression.prototype.operate = function(op, right, val) {
switch (op) {
case '[]=':
var self = this,
range = utils.unwrap(right).nodes,
val = utils.unwrap(val),
len,
node;
range.forEach(function(unit) {
len = self.nodes.length;
if ('unit' == unit.nodeName) {
var i = unit.val < 0 ? len + unit.val : unit.val,
n = i;
while (i-- > len) self.nodes[i] = nodes.nil;
self.nodes[n] = val;
} else if (unit.string) {
node = self.nodes[0];
if (node && 'object' == node.nodeName)
node.set(unit.string, val.clone());
}
});
return val;
case '[]':
var expr = new nodes.Expression(),
vals = utils.unwrap(this).nodes,
range = utils.unwrap(right).nodes,
node;
range.forEach(function(unit) {
if ('unit' == unit.nodeName) {
node = vals[unit.val < 0 ? vals.length + unit.val : unit.val];
} else if ('object' == vals[0].nodeName) {
node = vals[0].get(unit.string);
}
if (node) expr.push(node);
});
return expr.isEmpty ? nodes.nil : utils.unwrap(expr);
case '||':
return this.toBoolean().isTrue ? this : right;
case 'in':
return Node.prototype.operate.call(this, op, right);
case '!=':
return this.operate('==', right, val).negate();
case '==':
var len = this.nodes.length,
right = right.toExpression(),
a,
b;
if (len != right.nodes.length) return nodes.no;
for (var i = 0; i < len; ++i) {
a = this.nodes[i];
b = right.nodes[i];
if (a.operate(op, b).isTrue) continue;
return nodes.no;
}
return nodes.yes;
break;
default:
return this.first.operate(op, right, val);
}
};
Expression.prototype.toBoolean = function() {
if (this.nodes.length > 1) return nodes.yes;
return this.first.toBoolean();
};
Expression.prototype.toString = function() {
return (
'(' +
this.nodes
.map(function(node) {
return node.toString();
})
.join(this.isList ? ', ' : ' ') +
')'
);
};
Expression.prototype.toJSON = function() {
return {
__type: 'Expression',
isList: this.isList,
preserve: this.preserve,
lineno: this.lineno,
column: this.column,
filename: this.filename,
nodes: this.nodes,
};
};
});
require.register('nodes/function.js', function(module, exports, require) {
var Node = require('./node');
var Function = (module.exports = function Function(name, params, body) {
Node.call(this);
this.name = name;
this.params = params;
this.block = body;
if ('function' == typeof params) this.fn = params;
});
Function.prototype.__defineGetter__('arity', function() {
return this.params.length;
});
Function.prototype.__proto__ = Node.prototype;
Function.prototype.__defineGetter__('hash', function() {
return 'function ' + this.name;
});
Function.prototype.clone = function(parent) {
if (this.fn) {
var clone = new Function(this.name, this.fn);
} else {
var clone = new Function(this.name);
clone.params = this.params.clone(parent, clone);
clone.block = this.block.clone(parent, clone);
}
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Function.prototype.toString = function() {
if (this.fn) {
return (
this.name +
'(' +
this.fn
.toString()
.match(/^function *\w*\((.*?)\)/)
.slice(1)
.join(', ') +
')'
);
} else {
return this.name + '(' + this.params.nodes.join(', ') + ')';
}
};
Function.prototype.toJSON = function() {
var json = {
__type: 'Function',
name: this.name,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.fn) {
json.fn = this.fn;
} else {
json.params = this.params;
json.block = this.block;
}
return json;
};
});
require.register('nodes/group.js', function(module, exports, require) {
var Node = require('./node');
var Group = (module.exports = function Group() {
Node.call(this);
this.nodes = [];
this.extends = [];
});
Group.prototype.__proto__ = Node.prototype;
Group.prototype.push = function(selector) {
this.nodes.push(selector);
};
Group.prototype.__defineGetter__('block', function() {
return this.nodes[0].block;
});
Group.prototype.__defineSetter__('block', function(block) {
for (var i = 0, len = this.nodes.length; i < len; ++i) {
this.nodes[i].block = block;
}
});
Group.prototype.__defineGetter__('hasOnlyPlaceholders', function() {
return this.nodes.every(function(selector) {
return selector.isPlaceholder;
});
});
Group.prototype.clone = function(parent) {
var clone = new Group();
clone.lineno = this.lineno;
clone.column = this.column;
this.nodes.forEach(function(node) {
clone.push(node.clone(parent, clone));
});
clone.filename = this.filename;
clone.block = this.block.clone(parent, clone);
return clone;
};
Group.prototype.toJSON = function() {
return {
__type: 'Group',
nodes: this.nodes,
block: this.block,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/hsla.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var HSLA = (exports = module.exports = function HSLA(h, s, l, a) {
Node.call(this);
this.h = clampDegrees(h);
this.s = clampPercentage(s);
this.l = clampPercentage(l);
this.a = clampAlpha(a);
this.hsla = this;
});
HSLA.prototype.__proto__ = Node.prototype;
HSLA.prototype.toString = function() {
return (
'hsla(' +
this.h +
',' +
this.s.toFixed(0) +
'%,' +
this.l.toFixed(0) +
'%,' +
this.a +
')'
);
};
HSLA.prototype.clone = function(parent) {
var clone = new HSLA(this.h, this.s, this.l, this.a);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
HSLA.prototype.toJSON = function() {
return {
__type: 'HSLA',
h: this.h,
s: this.s,
l: this.l,
a: this.a,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
HSLA.prototype.__defineGetter__('rgba', function() {
return nodes.RGBA.fromHSLA(this);
});
HSLA.prototype.__defineGetter__('hash', function() {
return this.rgba.toString();
});
HSLA.prototype.add = function(h, s, l) {
return new HSLA(this.h + h, this.s + s, this.l + l, this.a);
};
HSLA.prototype.sub = function(h, s, l) {
return this.add(-h, -s, -l);
};
HSLA.prototype.operate = function(op, right) {
switch (op) {
case '==':
case '!=':
case '<=':
case '>=':
case '<':
case '>':
case 'is a':
case '||':
case '&&':
return this.rgba.operate(op, right);
default:
return this.rgba.operate(op, right).hsla;
}
};
exports.fromRGBA = function(rgba) {
var r = rgba.r / 255,
g = rgba.g / 255,
b = rgba.b / 255,
a = rgba.a;
var min = Math.min(r, g, b),
max = Math.max(r, g, b),
l = (max + min) / 2,
d = max - min,
h,
s;
switch (max) {
case min:
h = 0;
break;
case r:
h = 60 * (g - b) / d;
break;
case g:
h = 60 * (b - r) / d + 120;
break;
case b:
h = 60 * (r - g) / d + 240;
break;
}
if (max == min) {
s = 0;
} else if (l < 0.5) {
s = d / (2 * l);
} else {
s = d / (2 - 2 * l);
}
h %= 360;
s *= 100;
l *= 100;
return new HSLA(h, s, l, a);
};
HSLA.prototype.adjustLightness = function(percent) {
this.l = clampPercentage(this.l + this.l * (percent / 100));
return this;
};
HSLA.prototype.adjustHue = function(deg) {
this.h = clampDegrees(this.h + deg);
return this;
};
function clampDegrees(n) {
n = n % 360;
return n >= 0 ? n : 360 + n;
}
function clampPercentage(n) {
return Math.max(0, Math.min(n, 100));
}
function clampAlpha(n) {
return Math.max(0, Math.min(n, 1));
}
});
require.register('nodes/ident.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var Ident = (module.exports = function Ident(name, val, mixin) {
Node.call(this);
this.name = name;
this.string = name;
this.val = val || nodes.nil;
this.mixin = !!mixin;
});
Ident.prototype.__defineGetter__('isEmpty', function() {
return undefined == this.val;
});
Ident.prototype.__defineGetter__('hash', function() {
return this.name;
});
Ident.prototype.__proto__ = Node.prototype;
Ident.prototype.clone = function(parent) {
var clone = new Ident(this.name);
clone.val = this.val.clone(parent, clone);
clone.mixin = this.mixin;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
clone.property = this.property;
clone.rest = this.rest;
return clone;
};
Ident.prototype.toJSON = function() {
return {
__type: 'Ident',
name: this.name,
val: this.val,
mixin: this.mixin,
property: this.property,
rest: this.rest,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Ident.prototype.toString = function() {
return this.name;
};
Ident.prototype.coerce = function(other) {
switch (other.nodeName) {
case 'ident':
case 'string':
case 'literal':
return new Ident(other.string);
case 'unit':
return new Ident(other.toString());
default:
return Node.prototype.coerce.call(this, other);
}
};
Ident.prototype.operate = function(op, right) {
var val = right.first;
switch (op) {
case '-':
if ('unit' == val.nodeName) {
var expr = new nodes.Expression();
val = val.clone();
val.val = -val.val;
expr.push(this);
expr.push(val);
return expr;
}
case '+':
return new nodes.Ident(this.string + this.coerce(val).string);
}
return Node.prototype.operate.call(this, op, right);
};
});
require.register('nodes/if.js', function(module, exports, require) {
var Node = require('./node');
var If = (module.exports = function If(cond, negate) {
Node.call(this);
this.cond = cond;
this.elses = [];
if (negate && negate.nodeName) {
this.block = negate;
} else {
this.negate = negate;
}
});
If.prototype.__proto__ = Node.prototype;
If.prototype.clone = function(parent) {
var clone = new If();
clone.cond = this.cond.clone(parent, clone);
clone.block = this.block.clone(parent, clone);
clone.elses = this.elses.map(function(node) {
return node.clone(parent, clone);
});
clone.negate = this.negate;
clone.postfix = this.postfix;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
If.prototype.toJSON = function() {
return {
__type: 'If',
cond: this.cond,
block: this.block,
elses: this.elses,
negate: this.negate,
postfix: this.postfix,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/import.js', function(module, exports, require) {
var Node = require('./node');
var Import = (module.exports = function Import(expr, once) {
Node.call(this);
this.path = expr;
this.once = once || false;
});
Import.prototype.__proto__ = Node.prototype;
Import.prototype.clone = function(parent) {
var clone = new Import();
clone.path = this.path.nodeName
? this.path.clone(parent, clone)
: this.path;
clone.once = this.once;
clone.mtime = this.mtime;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Import.prototype.toJSON = function() {
return {
__type: 'Import',
path: this.path,
once: this.once,
mtime: this.mtime,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/extend.js', function(module, exports, require) {
var Node = require('./node');
var Extend = (module.exports = function Extend(selectors) {
Node.call(this);
this.selectors = selectors;
});
Extend.prototype.__proto__ = Node.prototype;
Extend.prototype.clone = function() {
return new Extend(this.selectors);
};
Extend.prototype.toString = function() {
return '@extend ' + this.selectors.join(', ');
};
Extend.prototype.toJSON = function() {
return {
__type: 'Extend',
selectors: this.selectors,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/index.js', function(module, exports, require) {
exports.Node = require('./node');
exports.Root = require('./root');
exports.Null = require('./null');
exports.Each = require('./each');
exports.If = require('./if');
exports.Call = require('./call');
exports.UnaryOp = require('./unaryop');
exports.BinOp = require('./binop');
exports.Ternary = require('./ternary');
exports.Block = require('./block');
exports.Unit = require('./unit');
exports.String = require('./string');
exports.HSLA = require('./hsla');
exports.RGBA = require('./rgba');
exports.Ident = require('./ident');
exports.Group = require('./group');
exports.Literal = require('./literal');
exports.Boolean = require('./boolean');
exports.Return = require('./return');
exports.Media = require('./media');
exports.QueryList = require('./query-list');
exports.Query = require('./query');
exports.Feature = require('./feature');
exports.Params = require('./params');
exports.Comment = require('./comment');
exports.Keyframes = require('./keyframes');
exports.Member = require('./member');
exports.Charset = require('./charset');
exports.Namespace = require('./namespace');
exports.Import = require('./import');
exports.Extend = require('./extend');
exports.Object = require('./object');
exports.Function = require('./function');
exports.Property = require('./property');
exports.Selector = require('./selector');
exports.Expression = require('./expression');
exports.Arguments = require('./arguments');
exports.Atblock = require('./atblock');
exports.Atrule = require('./atrule');
exports.Supports = require('./supports');
exports.yes = new exports.Boolean(true);
exports.no = new exports.Boolean(false);
exports.nil = new exports.Null();
});
require.register('nodes/keyframes.js', function(module, exports, require) {
var Atrule = require('./atrule');
var Keyframes = (module.exports = function Keyframes(segs, prefix) {
Atrule.call(this, 'keyframes');
this.segments = segs;
this.prefix = prefix || 'official';
});
Keyframes.prototype.__proto__ = Atrule.prototype;
Keyframes.prototype.clone = function(parent) {
var clone = new Keyframes();
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
clone.segments = this.segments.map(function(node) {
return node.clone(parent, clone);
});
clone.prefix = this.prefix;
clone.block = this.block.clone(parent, clone);
return clone;
};
Keyframes.prototype.toJSON = function() {
return {
__type: 'Keyframes',
segments: this.segments,
prefix: this.prefix,
block: this.block,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Keyframes.prototype.toString = function() {
return '@keyframes ' + this.segments.join('');
};
});
require.register('nodes/literal.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var Literal = (module.exports = function Literal(str) {
Node.call(this);
this.val = str;
this.string = str;
this.prefixed = false;
});
Literal.prototype.__proto__ = Node.prototype;
Literal.prototype.__defineGetter__('hash', function() {
return this.val;
});
Literal.prototype.toString = function() {
return this.val;
};
Literal.prototype.coerce = function(other) {
switch (other.nodeName) {
case 'ident':
case 'string':
case 'literal':
return new Literal(other.string);
default:
return Node.prototype.coerce.call(this, other);
}
};
Literal.prototype.operate = function(op, right) {
var val = right.first;
switch (op) {
case '+':
return new nodes.Literal(this.string + this.coerce(val).string);
default:
return Node.prototype.operate.call(this, op, right);
}
};
Literal.prototype.toJSON = function() {
return {
__type: 'Literal',
val: this.val,
string: this.string,
prefixed: this.prefixed,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/media.js', function(module, exports, require) {
var Atrule = require('./atrule');
var Media = (module.exports = function Media(val) {
Atrule.call(this, 'media');
this.val = val;
});
Media.prototype.__proto__ = Atrule.prototype;
Media.prototype.clone = function(parent) {
var clone = new Media();
clone.val = this.val.clone(parent, clone);
clone.block = this.block.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Media.prototype.toJSON = function() {
return {
__type: 'Media',
val: this.val,
block: this.block,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Media.prototype.toString = function() {
return '@media ' + this.val;
};
});
require.register('nodes/query-list.js', function(module, exports, require) {
var Node = require('./node');
var QueryList = (module.exports = function QueryList() {
Node.call(this);
this.nodes = [];
});
QueryList.prototype.__proto__ = Node.prototype;
QueryList.prototype.clone = function(parent) {
var clone = new QueryList();
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
for (var i = 0; i < this.nodes.length; ++i) {
clone.push(this.nodes[i].clone(parent, clone));
}
return clone;
};
QueryList.prototype.push = function(node) {
this.nodes.push(node);
};
QueryList.prototype.merge = function(other) {
var list = new QueryList(),
merged;
this.nodes.forEach(function(query) {
for (var i = 0, len = other.nodes.length; i < len; ++i) {
merged = query.merge(other.nodes[i]);
if (merged) list.push(merged);
}
});
return list;
};
QueryList.prototype.toString = function() {
return (
'(' +
this.nodes
.map(function(node) {
return node.toString();
})
.join(', ') +
')'
);
};
QueryList.prototype.toJSON = function() {
return {
__type: 'QueryList',
nodes: this.nodes,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/query.js', function(module, exports, require) {
var Node = require('./node');
var Query = (module.exports = function Query() {
Node.call(this);
this.nodes = [];
this.type = '';
this.predicate = '';
});
Query.prototype.__proto__ = Node.prototype;
Query.prototype.clone = function(parent) {
var clone = new Query();
clone.predicate = this.predicate;
clone.type = this.type;
for (var i = 0, len = this.nodes.length; i < len; ++i) {
clone.push(this.nodes[i].clone(parent, clone));
}
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Query.prototype.push = function(feature) {
this.nodes.push(feature);
};
Query.prototype.__defineGetter__('resolvedType', function() {
if (this.type) {
return this.type.nodeName ? this.type.string : this.type;
}
});
Query.prototype.__defineGetter__('resolvedPredicate', function() {
if (this.predicate) {
return this.predicate.nodeName ? this.predicate.string : this.predicate;
}
});
Query.prototype.merge = function(other) {
var query = new Query(),
p1 = this.resolvedPredicate,
p2 = other.resolvedPredicate,
t1 = this.resolvedType,
t2 = other.resolvedType,
type,
pred;
t1 = t1 || t2;
t2 = t2 || t1;
if (('not' == p1) ^ ('not' == p2)) {
if (t1 == t2) return;
type = 'not' == p1 ? t2 : t1;
pred = 'not' == p1 ? p2 : p1;
} else if ('not' == p1 && 'not' == p2) {
if (t1 != t2) return;
type = t1;
pred = 'not';
} else if (t1 != t2) {
return;
} else {
type = t1;
pred = p1 || p2;
}
query.predicate = pred;
query.type = type;
query.nodes = this.nodes.concat(other.nodes);
return query;
};
Query.prototype.toString = function() {
var pred = this.predicate ? this.predicate + ' ' : '',
type = this.type || '',
len = this.nodes.length,
str = pred + type;
if (len) {
str +=
(type && ' and ') +
this.nodes
.map(function(expr) {
return expr.toString();
})
.join(' and ');
}
return str;
};
Query.prototype.toJSON = function() {
return {
__type: 'Query',
predicate: this.predicate,
type: this.type,
nodes: this.nodes,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/feature.js', function(module, exports, require) {
var Node = require('./node');
var Feature = (module.exports = function Feature(segs) {
Node.call(this);
this.segments = segs;
this.expr = null;
});
Feature.prototype.__proto__ = Node.prototype;
Feature.prototype.clone = function(parent) {
var clone = new Feature();
clone.segments = this.segments.map(function(node) {
return node.clone(parent, clone);
});
if (this.expr) clone.expr = this.expr.clone(parent, clone);
if (this.name) clone.name = this.name;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Feature.prototype.toString = function() {
if (this.expr) {
return '(' + this.segments.join('') + ': ' + this.expr.toString() + ')';
} else {
return this.segments.join('');
}
};
Feature.prototype.toJSON = function() {
var json = {
__type: 'Feature',
segments: this.segments,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.expr) json.expr = this.expr;
if (this.name) json.name = this.name;
return json;
};
});
require.register('nodes/node.js', function(module, exports, require) {
var Evaluator = require('../visitor/evaluator'),
utils = require('../utils'),
nodes = require('./index');
function CoercionError(msg) {
this.name = 'CoercionError';
this.message = msg;
Error.captureStackTrace(this, CoercionError);
}
CoercionError.prototype.__proto__ = Error.prototype;
var Node = (module.exports = function Node() {
this.lineno = nodes.lineno || 1;
this.column = nodes.column || 1;
this.filename = nodes.filename;
});
Node.prototype = {
constructor: Node,
get first() {
return this;
},
get hash() {
return this.val;
},
get nodeName() {
return this.constructor.name.toLowerCase();
},
clone: function() {
return this;
},
toJSON: function() {
return {
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
},
eval: function() {
return new Evaluator(this).evaluate();
},
toBoolean: function() {
return nodes.yes;
},
toExpression: function() {
if ('expression' == this.nodeName) return this;
var expr = new nodes.Expression();
expr.push(this);
return expr;
},
shouldCoerce: function(op) {
switch (op) {
case 'is a':
case 'in':
case '||':
case '&&':
return false;
default:
return true;
}
},
operate: function(op, right) {
switch (op) {
case 'is a':
if ('string' == right.first.nodeName) {
return nodes.Boolean(this.nodeName == right.val);
} else {
throw new Error(
'"is a" expects a string, got ' + right.toString(),
);
}
case '==':
return nodes.Boolean(this.hash == right.hash);
case '!=':
return nodes.Boolean(this.hash != right.hash);
case '>=':
return nodes.Boolean(this.hash >= right.hash);
case '<=':
return nodes.Boolean(this.hash <= right.hash);
case '>':
return nodes.Boolean(this.hash > right.hash);
case '<':
return nodes.Boolean(this.hash < right.hash);
case '||':
return this.toBoolean().isTrue ? this : right;
case 'in':
var vals = utils.unwrap(right).nodes,
len = vals && vals.length,
hash = this.hash;
if (!vals)
throw new Error(
'"in" given invalid right-hand operand, expecting an expression',
);
if (1 == len && 'object' == vals[0].nodeName) {
return nodes.Boolean(vals[0].has(this.hash));
}
for (var i = 0; i < len; ++i) {
if (hash == vals[i].hash) {
return nodes.yes;
}
}
return nodes.no;
case '&&':
var a = this.toBoolean(),
b = right.toBoolean();
return a.isTrue && b.isTrue ? right : a.isFalse ? this : right;
default:
if ('[]' == op) {
var msg = 'cannot perform ' + this + '[' + right + ']';
} else {
var msg = 'cannot perform' + ' ' + this + ' ' + op + ' ' + right;
}
throw new Error(msg);
}
},
coerce: function(other) {
if (other.nodeName == this.nodeName) return other;
throw new CoercionError(
'cannot coerce ' + other + ' to ' + this.nodeName,
);
},
};
});
require.register('nodes/null.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var Null = (module.exports = function Null() {});
Null.prototype.__proto__ = Node.prototype;
Null.prototype.inspect = Null.prototype.toString = function() {
return 'null';
};
Null.prototype.toBoolean = function() {
return nodes.no;
};
Null.prototype.__defineGetter__('isNull', function() {
return true;
});
Null.prototype.__defineGetter__('hash', function() {
return null;
});
Null.prototype.toJSON = function() {
return {
__type: 'Null',
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/params.js', function(module, exports, require) {
var Node = require('./node');
var Params = (module.exports = function Params() {
Node.call(this);
this.nodes = [];
});
Params.prototype.__defineGetter__('length', function() {
return this.nodes.length;
});
Params.prototype.__proto__ = Node.prototype;
Params.prototype.push = function(node) {
this.nodes.push(node);
};
Params.prototype.clone = function(parent) {
var clone = new Params();
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
this.nodes.forEach(function(node) {
clone.push(node.clone(parent, clone));
});
return clone;
};
Params.prototype.toJSON = function() {
return {
__type: 'Params',
nodes: this.nodes,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/property.js', function(module, exports, require) {
var Node = require('./node');
var Property = (module.exports = function Property(segs, expr) {
Node.call(this);
this.segments = segs;
this.expr = expr;
});
Property.prototype.__proto__ = Node.prototype;
Property.prototype.clone = function(parent) {
var clone = new Property(this.segments);
clone.name = this.name;
if (this.literal) clone.literal = this.literal;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
clone.segments = this.segments.map(function(node) {
return node.clone(parent, clone);
});
if (this.expr) clone.expr = this.expr.clone(parent, clone);
return clone;
};
Property.prototype.toJSON = function() {
var json = {
__type: 'Property',
segments: this.segments,
name: this.name,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.expr) json.expr = this.expr;
if (this.literal) json.literal = this.literal;
return json;
};
Property.prototype.toString = function() {
return 'property(' + this.segments.join('') + ', ' + this.expr + ')';
};
Property.prototype.operate = function(op, right, val) {
return this.expr.operate(op, right, val);
};
});
require.register('nodes/return.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var Return = (module.exports = function Return(expr) {
this.expr = expr || nodes.nil;
});
Return.prototype.__proto__ = Node.prototype;
Return.prototype.clone = function(parent) {
var clone = new Return();
clone.expr = this.expr.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Return.prototype.toJSON = function() {
return {
__type: 'Return',
expr: this.expr,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/rgba.js', function(module, exports, require) {
var Node = require('./node'),
HSLA = require('./hsla'),
functions = require('../functions'),
adjust = functions.adjust,
nodes = require('./index');
var RGBA = (exports = module.exports = function RGBA(r, g, b, a) {
Node.call(this);
this.r = clamp(r);
this.g = clamp(g);
this.b = clamp(b);
this.a = clampAlpha(a);
this.name = '';
this.rgba = this;
});
RGBA.prototype.__proto__ = Node.prototype;
RGBA.withoutClamping = function(r, g, b, a) {
var rgba = new RGBA(0, 0, 0, 0);
rgba.r = r;
rgba.g = g;
rgba.b = b;
rgba.a = a;
return rgba;
};
RGBA.prototype.clone = function() {
var clone = new RGBA(this.r, this.g, this.b, this.a);
clone.raw = this.raw;
clone.name = this.name;
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
RGBA.prototype.toJSON = function() {
return {
__type: 'RGBA',
r: this.r,
g: this.g,
b: this.b,
a: this.a,
raw: this.raw,
name: this.name,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
RGBA.prototype.toBoolean = function() {
return nodes.yes;
};
RGBA.prototype.__defineGetter__('hsla', function() {
return HSLA.fromRGBA(this);
});
RGBA.prototype.__defineGetter__('hash', function() {
return this.toString();
});
RGBA.prototype.add = function(r, g, b, a) {
return new RGBA(this.r + r, this.g + g, this.b + b, this.a + a);
};
RGBA.prototype.sub = function(r, g, b, a) {
return new RGBA(
this.r - r,
this.g - g,
this.b - b,
a == 1 ? this.a : this.a - a,
);
};
RGBA.prototype.multiply = function(n) {
return new RGBA(this.r * n, this.g * n, this.b * n, this.a);
};
RGBA.prototype.divide = function(n) {
return new RGBA(this.r / n, this.g / n, this.b / n, this.a);
};
RGBA.prototype.operate = function(op, right) {
if ('in' != op) right = right.first;
switch (op) {
case 'is a':
if ('string' == right.nodeName && 'color' == right.string) {
return nodes.yes;
}
break;
case '+':
switch (right.nodeName) {
case 'unit':
var n = right.val;
switch (right.type) {
case '%':
return adjust(this, new nodes.String('lightness'), right);
case 'deg':
return this.hsla.adjustHue(n).rgba;
default:
return this.add(n, n, n, 0);
}
case 'rgba':
return this.add(right.r, right.g, right.b, right.a);
case 'hsla':
return this.hsla.add(right.h, right.s, right.l);
}
break;
case '-':
switch (right.nodeName) {
case 'unit':
var n = right.val;
switch (right.type) {
case '%':
return adjust(
this,
new nodes.String('lightness'),
new nodes.Unit(-n, '%'),
);
case 'deg':
return this.hsla.adjustHue(-n).rgba;
default:
return this.sub(n, n, n, 0);
}
case 'rgba':
return this.sub(right.r, right.g, right.b, right.a);
case 'hsla':
return this.hsla.sub(right.h, right.s, right.l);
}
break;
case '*':
switch (right.nodeName) {
case 'unit':
return this.multiply(right.val);
}
break;
case '/':
switch (right.nodeName) {
case 'unit':
return this.divide(right.val);
}
break;
}
return Node.prototype.operate.call(this, op, right);
};
RGBA.prototype.toString = function() {
function pad(n) {
return n < 16 ? '0' + n.toString(16) : n.toString(16);
}
if ('transparent' == this.name) return this.name;
if (1 == this.a) {
var r = pad(this.r),
g = pad(this.g),
b = pad(this.b);
if (r[0] == r[1] && g[0] == g[1] && b[0] == b[1]) {
return '#' + r[0] + g[0] + b[0];
} else {
return '#' + r + g + b;
}
} else {
return (
'rgba(' +
this.r +
',' +
this.g +
',' +
this.b +
',' +
+this.a.toFixed(3) +
')'
);
}
};
exports.fromHSLA = function(hsla) {
var h = hsla.h / 360,
s = hsla.s / 100,
l = hsla.l / 100,
a = hsla.a;
var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s,
m1 = l * 2 - m2;
var r = hue(h + 1 / 3) * 255,
g = hue(h) * 255,
b = hue(h - 1 / 3) * 255;
function hue(h) {
if (h < 0) ++h;
if (h > 1) --h;
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
if (h * 2 < 1) return m2;
if (h * 3 < 2) return m1 + (m2 - m1) * (2 / 3 - h) * 6;
return m1;
}
return new RGBA(r, g, b, a);
};
function clamp(n) {
return Math.max(0, Math.min(n.toFixed(0), 255));
}
function clampAlpha(n) {
return Math.max(0, Math.min(n, 1));
}
});
require.register('nodes/root.js', function(module, exports, require) {
var Node = require('./node');
var Root = (module.exports = function Root() {
this.nodes = [];
});
Root.prototype.__proto__ = Node.prototype;
Root.prototype.push = function(node) {
this.nodes.push(node);
};
Root.prototype.unshift = function(node) {
this.nodes.unshift(node);
};
Root.prototype.clone = function() {
var clone = new Root();
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
this.nodes.forEach(function(node) {
clone.push(node.clone(clone, clone));
});
return clone;
};
Root.prototype.toString = function() {
return '[Root]';
};
Root.prototype.toJSON = function() {
return {
__type: 'Root',
nodes: this.nodes,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/selector.js', function(module, exports, require) {
var Block = require('./block'),
Node = require('./node');
var Selector = (module.exports = function Selector(segs) {
Node.call(this);
this.inherits = true;
this.segments = segs;
this.optional = false;
});
Selector.prototype.__proto__ = Node.prototype;
Selector.prototype.toString = function() {
return this.segments.join('') + (this.optional ? ' !optional' : '');
};
Selector.prototype.__defineGetter__('isPlaceholder', function() {
return this.val && ~this.val.substr(0, 2).indexOf('$');
});
Selector.prototype.clone = function(parent) {
var clone = new Selector();
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
clone.inherits = this.inherits;
clone.val = this.val;
clone.segments = this.segments.map(function(node) {
return node.clone(parent, clone);
});
clone.optional = this.optional;
return clone;
};
Selector.prototype.toJSON = function() {
return {
__type: 'Selector',
inherits: this.inherits,
segments: this.segments,
optional: this.optional,
val: this.val,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/string.js', function(module, exports, require) {
var Node = require('./node'),
sprintf = require('../functions').s,
utils = require('../utils'),
nodes = require('./index');
var String = (module.exports = function String(val, quote) {
Node.call(this);
this.val = val;
this.string = val;
this.prefixed = false;
if (typeof quote !== 'string') {
this.quote = "'";
} else {
this.quote = quote;
}
});
String.prototype.__proto__ = Node.prototype;
String.prototype.toString = function() {
return this.quote + this.val + this.quote;
};
String.prototype.clone = function() {
var clone = new String(this.val, this.quote);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
String.prototype.toJSON = function() {
return {
__type: 'String',
val: this.val,
quote: this.quote,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
String.prototype.toBoolean = function() {
return nodes.Boolean(this.val.length);
};
String.prototype.coerce = function(other) {
switch (other.nodeName) {
case 'string':
return other;
case 'expression':
return new String(
other.nodes
.map(function(node) {
return this.coerce(node).val;
}, this)
.join(' '),
);
default:
return new String(other.toString());
}
};
String.prototype.operate = function(op, right) {
switch (op) {
case '%':
var expr = new nodes.Expression();
expr.push(this);
var args =
'expression' == right.nodeName
? utils.unwrap(right).nodes
: [right];
return sprintf.apply(null, [expr].concat(args));
case '+':
var expr = new nodes.Expression();
expr.push(new String(this.val + this.coerce(right).val));
return expr;
default:
return Node.prototype.operate.call(this, op, right);
}
};
});
require.register('nodes/ternary.js', function(module, exports, require) {
var Node = require('./node');
var Ternary = (module.exports = function Ternary(
cond,
trueExpr,
falseExpr,
) {
Node.call(this);
this.cond = cond;
this.trueExpr = trueExpr;
this.falseExpr = falseExpr;
});
Ternary.prototype.__proto__ = Node.prototype;
Ternary.prototype.clone = function(parent) {
var clone = new Ternary();
clone.cond = this.cond.clone(parent, clone);
clone.trueExpr = this.trueExpr.clone(parent, clone);
clone.falseExpr = this.falseExpr.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Ternary.prototype.toJSON = function() {
return {
__type: 'Ternary',
cond: this.cond,
trueExpr: this.trueExpr,
falseExpr: this.falseExpr,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/unaryop.js', function(module, exports, require) {
var Node = require('./node');
var UnaryOp = (module.exports = function UnaryOp(op, expr) {
Node.call(this);
this.op = op;
this.expr = expr;
});
UnaryOp.prototype.__proto__ = Node.prototype;
UnaryOp.prototype.clone = function(parent) {
var clone = new UnaryOp(this.op);
clone.expr = this.expr.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
UnaryOp.prototype.toJSON = function() {
return {
__type: 'UnaryOp',
op: this.op,
expr: this.expr,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
});
require.register('nodes/unit.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index');
var FACTOR_TABLE = {
mm: { val: 1, label: 'mm' },
cm: { val: 10, label: 'mm' },
in: { val: 25.4, label: 'mm' },
pt: { val: 25.4 / 72, label: 'mm' },
ms: { val: 1, label: 'ms' },
s: { val: 1e3, label: 'ms' },
Hz: { val: 1, label: 'Hz' },
kHz: { val: 1e3, label: 'Hz' },
};
var Unit = (module.exports = function Unit(val, type) {
Node.call(this);
this.val = val;
this.type = type;
});
Unit.prototype.__proto__ = Node.prototype;
Unit.prototype.toBoolean = function() {
return nodes.Boolean(this.type ? true : this.val);
};
Unit.prototype.toString = function() {
return this.val + (this.type || '');
};
Unit.prototype.clone = function() {
var clone = new Unit(this.val, this.type);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Unit.prototype.toJSON = function() {
return {
__type: 'Unit',
val: this.val,
type: this.type,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Unit.prototype.operate = function(op, right) {
var type = this.type || right.first.type;
if ('rgba' == right.nodeName || 'hsla' == right.nodeName) {
return right.operate(op, this);
}
if (this.shouldCoerce(op)) {
right = right.first;
if ('%' != this.type && ('-' == op || '+' == op) && '%' == right.type) {
right = new Unit(this.val * (right.val / 100), '%');
} else {
right = this.coerce(right);
}
switch (op) {
case '-':
return new Unit(this.val - right.val, type);
case '+':
type = type || (right.type == '%' && right.type);
return new Unit(this.val + right.val, type);
case '/':
return new Unit(this.val / right.val, type);
case '*':
return new Unit(this.val * right.val, type);
case '%':
return new Unit(this.val % right.val, type);
case '**':
return new Unit(Math.pow(this.val, right.val), type);
case '..':
case '...':
var start = this.val,
end = right.val,
expr = new nodes.Expression(),
inclusive = '..' == op;
if (start < end) {
do {
expr.push(new nodes.Unit(start));
} while (inclusive ? ++start <= end : ++start < end);
} else {
do {
expr.push(new nodes.Unit(start));
} while (inclusive ? --start >= end : --start > end);
}
return expr;
}
}
return Node.prototype.operate.call(this, op, right);
};
Unit.prototype.coerce = function(other) {
if ('unit' == other.nodeName) {
var a = this,
b = other,
factorA = FACTOR_TABLE[a.type],
factorB = FACTOR_TABLE[b.type];
if (factorA && factorB && factorA.label == factorB.label) {
var bVal = b.val * (factorB.val / factorA.val);
return new nodes.Unit(bVal, a.type);
} else {
return new nodes.Unit(b.val, a.type);
}
} else if ('string' == other.nodeName) {
if ('%' == other.val) return new nodes.Unit(0, '%');
var val = parseFloat(other.val);
if (isNaN(val)) Node.prototype.coerce.call(this, other);
return new nodes.Unit(val);
} else {
return Node.prototype.coerce.call(this, other);
}
};
});
require.register('nodes/object.js', function(module, exports, require) {
var Node = require('./node'),
nodes = require('./index'),
nativeObj = {}.constructor;
var Object = (module.exports = function Object() {
Node.call(this);
this.vals = {};
});
Object.prototype.__proto__ = Node.prototype;
Object.prototype.set = function(key, val) {
this.vals[key] = val;
return this;
};
Object.prototype.__defineGetter__('length', function() {
return nativeObj.keys(this.vals).length;
});
Object.prototype.get = function(key) {
return this.vals[key] || nodes.nil;
};
Object.prototype.has = function(key) {
return key in this.vals;
};
Object.prototype.operate = function(op, right) {
switch (op) {
case '.':
case '[]':
return this.get(right.hash);
case '==':
var vals = this.vals,
a,
b;
if ('object' != right.nodeName || this.length != right.length)
return nodes.no;
for (var key in vals) {
a = vals[key];
b = right.vals[key];
if (a.operate(op, b).isFalse) return nodes.no;
}
return nodes.yes;
case '!=':
return this.operate('==', right).negate();
default:
return Node.prototype.operate.call(this, op, right);
}
};
Object.prototype.toBoolean = function() {
return nodes.Boolean(this.length);
};
Object.prototype.toBlock = function() {
var str = '{',
key,
val;
for (key in this.vals) {
val = this.get(key);
if ('object' == val.first.nodeName) {
str += key + ' ' + val.first.toBlock();
} else {
switch (key) {
case '@charset':
str += key + ' ' + val.first.toString() + ';';
break;
default:
str += key + ':' + toString(val) + ';';
}
}
}
str += '}';
return str;
function toString(node) {
if (node.nodes) {
return node.nodes.map(toString).join(node.isList ? ',' : ' ');
} else if ('literal' == node.nodeName && ',' == node.val) {
return '\\,';
}
return node.toString();
}
};
Object.prototype.clone = function(parent) {
var clone = new Object();
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
for (var key in this.vals) {
clone.vals[key] = this.vals[key].clone(parent, clone);
}
return clone;
};
Object.prototype.toJSON = function() {
return {
__type: 'Object',
vals: this.vals,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Object.prototype.toString = function() {
var obj = {};
for (var prop in this.vals) {
obj[prop] = this.vals[prop].toString();
}
return JSON.stringify(obj);
};
});
require.register('nodes/supports.js', function(module, exports, require) {
var Atrule = require('./atrule');
var Supports = (module.exports = function Supports(condition) {
Atrule.call(this, 'supports');
this.condition = condition;
});
Supports.prototype.__proto__ = Atrule.prototype;
Supports.prototype.clone = function(parent) {
var clone = new Supports();
clone.condition = this.condition.clone(parent, clone);
clone.block = this.block.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Supports.prototype.toJSON = function() {
return {
__type: 'Supports',
condition: this.condition,
block: this.block,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
};
Supports.prototype.toString = function() {
return '@supports ' + this.condition;
};
});
require.register('nodes/member.js', function(module, exports, require) {
var Node = require('./node');
var Member = (module.exports = function Member(left, right) {
Node.call(this);
this.left = left;
this.right = right;
});
Member.prototype.__proto__ = Node.prototype;
Member.prototype.clone = function(parent) {
var clone = new Member();
clone.left = this.left.clone(parent, clone);
clone.right = this.right.clone(parent, clone);
if (this.val) clone.val = this.val.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Member.prototype.toJSON = function() {
var json = {
__type: 'Member',
left: this.left,
right: this.right,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.val) json.val = this.val;
return json;
};
Member.prototype.toString = function() {
return this.left.toString() + '.' + this.right.toString();
};
});
require.register('nodes/atblock.js', function(module, exports, require) {
var Node = require('./node');
var Atblock = (module.exports = function Atblock() {
Node.call(this);
});
Atblock.prototype.__defineGetter__('nodes', function() {
return this.block.nodes;
});
Atblock.prototype.__proto__ = Node.prototype;
Atblock.prototype.clone = function(parent) {
var clone = new Atblock();
clone.block = this.block.clone(parent, clone);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Atblock.prototype.toString = function() {
return '@block';
};
Atblock.prototype.toJSON = function() {
return {
__type: 'Atblock',
block: this.block,
lineno: this.lineno,
column: this.column,
fileno: this.fileno,
};
};
});
require.register('nodes/atrule.js', function(module, exports, require) {
var Node = require('./node');
var Atrule = (module.exports = function Atrule(type) {
Node.call(this);
this.type = type;
});
Atrule.prototype.__proto__ = Node.prototype;
Atrule.prototype.__defineGetter__('hasOnlyProperties', function() {
if (!this.block) return false;
var nodes = this.block.nodes;
for (var i = 0, len = nodes.length; i < len; ++i) {
var nodeName = nodes[i].nodeName;
switch (nodes[i].nodeName) {
case 'property':
case 'expression':
case 'comment':
continue;
default:
return false;
}
}
return true;
});
Atrule.prototype.clone = function(parent) {
var clone = new Atrule(this.type);
if (this.block) clone.block = this.block.clone(parent, clone);
clone.segments = this.segments.map(function(node) {
return node.clone(parent, clone);
});
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
Atrule.prototype.toJSON = function() {
var json = {
__type: 'Atrule',
type: this.type,
segments: this.segments,
lineno: this.lineno,
column: this.column,
filename: this.filename,
};
if (this.block) json.block = this.block;
return json;
};
Atrule.prototype.toString = function() {
return '@' + this.type;
};
Atrule.prototype.__defineGetter__('hasOutput', function() {
return !!this.block && hasOutput(this.block);
});
function hasOutput(block) {
var nodes = block.nodes;
if (
nodes.every(function(node) {
return 'group' == node.nodeName && node.hasOnlyPlaceholders;
})
)
return false;
return nodes.some(function(node) {
switch (node.nodeName) {
case 'property':
case 'literal':
case 'import':
return true;
case 'block':
return hasOutput(node);
default:
if (node.block) return hasOutput(node.block);
}
});
}
});
require.register('parser.js', function(module, exports, require) {
var Lexer = require('./lexer'),
nodes = require('./nodes'),
Token = require('./token'),
units = require('./units'),
errors = require('./errors');
var selectorTokens = [
'ident',
'string',
'selector',
'function',
'comment',
'boolean',
'space',
'color',
'unit',
'for',
'in',
'[',
']',
'(',
')',
'+',
'-',
'*',
'*=',
'<',
'>',
'=',
':',
'&',
'&&',
'~',
'{',
'}',
'.',
'..',
'/',
];
var pseudoSelectors = [
'matches',
'not',
'dir',
'lang',
'any-link',
'link',
'visited',
'local-link',
'target',
'scope',
'hover',
'active',
'focus',
'drop',
'current',
'past',
'future',
'enabled',
'disabled',
'read-only',
'read-write',
'placeholder-shown',
'checked',
'indeterminate',
'valid',
'invalid',
'in-range',
'out-of-range',
'required',
'optional',
'user-error',
'root',
'empty',
'blank',
'nth-child',
'nth-last-child',
'first-child',
'last-child',
'only-child',
'nth-of-type',
'nth-last-of-type',
'first-of-type',
'last-of-type',
'only-of-type',
'nth-match',
'nth-last-match',
'nth-column',
'nth-last-column',
'first-line',
'first-letter',
'before',
'after',
'selection',
];
var Parser = (module.exports = function Parser(str, options) {
var self = this;
options = options || {};
this.lexer = new Lexer(str, options);
this.prefix = options.prefix || '';
this.root = options.root || new nodes.Root();
this.state = ['root'];
this.stash = [];
this.parens = 0;
this.css = 0;
this.state.pop = function() {
self.prevState = [].pop.call(this);
};
});
Parser.prototype = {
constructor: Parser,
currentState: function() {
return this.state[this.state.length - 1];
},
previousState: function() {
return this.state[this.state.length - 2];
},
parse: function() {
var block = (this.parent = this.root);
while ('eos' != this.peek().type) {
this.skipWhitespace();
if ('eos' == this.peek().type) break;
var stmt = this.statement();
this.accept(';');
if (!stmt)
this.error(
'unexpected token {peek}, not allowed at the root level',
);
block.push(stmt);
}
return block;
},
error: function(msg) {
var type = this.peek().type,
val =
undefined == this.peek().val ? '' : ' ' + this.peek().toString();
if (val.trim() == type.trim()) val = '';
throw new errors.ParseError(
msg.replace('{peek}', '"' + type + val + '"'),
);
},
accept: function(type) {
if (type == this.peek().type) {
return this.next();
}
},
expect: function(type) {
if (type != this.peek().type) {
this.error('expected "' + type + '", got {peek}');
}
return this.next();
},
next: function() {
var tok = this.stash.length ? this.stash.pop() : this.lexer.next(),
line = tok.lineno,
column = tok.column || 1;
if (tok.val && tok.val.nodeName) {
tok.val.lineno = line;
tok.val.column = column;
}
nodes.lineno = line;
nodes.column = column;
return tok;
},
peek: function() {
return this.lexer.peek();
},
lookahead: function(n) {
return this.lexer.lookahead(n);
},
isSelectorToken: function(n) {
var la = this.lookahead(n).type;
switch (la) {
case 'for':
return this.bracketed;
case '[':
this.bracketed = true;
return true;
case ']':
this.bracketed = false;
return true;
default:
return ~selectorTokens.indexOf(la);
}
},
isPseudoSelector: function(n) {
var val = this.lookahead(n).val;
return val && ~pseudoSelectors.indexOf(val.name);
},
lineContains: function(type) {
var i = 1,
la;
while ((la = this.lookahead(i++))) {
if (~['indent', 'outdent', 'newline', 'eos'].indexOf(la.type)) return;
if (type == la.type) return true;
}
},
selectorToken: function() {
if (this.isSelectorToken(1)) {
if ('{' == this.peek().type) {
if (!this.lineContains('}')) return;
var i = 0,
la;
while ((la = this.lookahead(++i))) {
if ('}' == la.type) {
if (i == 2 || (i == 3 && this.lookahead(i - 1).type == 'space'))
return;
break;
}
if (':' == la.type) return;
}
}
return this.next();
}
},
skip: function(tokens) {
while (~tokens.indexOf(this.peek().type)) this.next();
},
skipWhitespace: function() {
this.skip(['space', 'indent', 'outdent', 'newline']);
},
skipNewlines: function() {
while ('newline' == this.peek().type) this.next();
},
skipSpaces: function() {
while ('space' == this.peek().type) this.next();
},
skipSpacesAndComments: function() {
while ('space' == this.peek().type || 'comment' == this.peek().type)
this.next();
},
looksLikeFunctionDefinition: function(i) {
return (
'indent' == this.lookahead(i).type || '{' == this.lookahead(i).type
);
},
looksLikeSelector: function(fromProperty) {
var i = 1,
brace;
if (
fromProperty &&
':' == this.lookahead(i + 1).type &&
(this.lookahead(i + 1).space ||
'indent' == this.lookahead(i + 2).type)
)
return false;
while (
'ident' == this.lookahead(i).type &&
('newline' == this.lookahead(i + 1).type ||
',' == this.lookahead(i + 1).type)
)
i += 2;
while (this.isSelectorToken(i) || ',' == this.lookahead(i).type) {
if ('selector' == this.lookahead(i).type) return true;
if ('&' == this.lookahead(i + 1).type) return true;
if (
'.' == this.lookahead(i).type &&
'ident' == this.lookahead(i + 1).type
)
return true;
if (
'*' == this.lookahead(i).type &&
'newline' == this.lookahead(i + 1).type
)
return true;
if (
':' == this.lookahead(i).type &&
':' == this.lookahead(i + 1).type
)
return true;
if (
'color' == this.lookahead(i).type &&
'newline' == this.lookahead(i - 1).type
)
return true;
if (this.looksLikeAttributeSelector(i)) return true;
if (
('=' == this.lookahead(i).type ||
'function' == this.lookahead(i).type) &&
'{' == this.lookahead(i + 1).type
)
return false;
if (
':' == this.lookahead(i).type &&
!this.isPseudoSelector(i + 1) &&
this.lineContains('.')
)
return false;
if ('{' == this.lookahead(i).type) brace = true;
else if ('}' == this.lookahead(i).type) brace = false;
if (brace && ':' == this.lookahead(i).type) return true;
if (
'space' == this.lookahead(i).type &&
'{' == this.lookahead(i + 1).type
)
return true;
if (
':' == this.lookahead(i++).type &&
!this.lookahead(i - 1).space &&
this.isPseudoSelector(i)
)
return true;
if (
'space' == this.lookahead(i).type &&
'newline' == this.lookahead(i + 1).type &&
'{' == this.lookahead(i + 2).type
)
return true;
if (
',' == this.lookahead(i).type &&
'newline' == this.lookahead(i + 1).type
)
return true;
}
if (
',' == this.lookahead(i).type &&
'newline' == this.lookahead(i + 1).type
)
return true;
if (
'{' == this.lookahead(i).type &&
'newline' == this.lookahead(i + 1).type
)
return true;
if (this.css) {
if (
';' == this.lookahead(i).type ||
'}' == this.lookahead(i - 1).type
)
return false;
}
while (
!~[
'indent',
'outdent',
'newline',
'for',
'if',
';',
'}',
'eos',
].indexOf(this.lookahead(i).type)
)
++i;
if ('indent' == this.lookahead(i).type) return true;
},
looksLikeAttributeSelector: function(n) {
var type = this.lookahead(n).type;
if ('=' == type && this.bracketed) return true;
return (
('ident' == type || 'string' == type) &&
']' == this.lookahead(n + 1).type &&
('newline' == this.lookahead(n + 2).type ||
this.isSelectorToken(n + 2)) &&
!this.lineContains(':') &&
!this.lineContains('=')
);
},
looksLikeKeyframe: function() {
var i = 2,
type;
switch (this.lookahead(i).type) {
case '{':
case 'indent':
case ',':
return true;
case 'newline':
while (
'unit' == this.lookahead(++i).type ||
'newline' == this.lookahead(i).type
);
type = this.lookahead(i).type;
return 'indent' == type || '{' == type;
}
},
stateAllowsSelector: function() {
switch (this.currentState()) {
case 'root':
case 'atblock':
case 'selector':
case 'conditional':
case 'function':
case 'atrule':
case 'for':
return true;
}
},
assignAtblock: function(expr) {
try {
expr.push(this.atblock(expr));
} catch (err) {
this.error(
'invalid right-hand side operand in assignment, got {peek}',
);
}
},
statement: function() {
var stmt = this.stmt(),
state = this.prevState,
block,
op;
if (this.allowPostfix) {
this.allowPostfix = false;
state = 'expression';
}
switch (state) {
case 'assignment':
case 'expression':
case 'function arguments':
while (
(op =
this.accept('if') ||
this.accept('unless') ||
this.accept('for'))
) {
switch (op.type) {
case 'if':
case 'unless':
stmt = new nodes.If(this.expression(), stmt);
stmt.postfix = true;
stmt.negate = 'unless' == op.type;
this.accept(';');
break;
case 'for':
var key,
val = this.id().name;
if (this.accept(',')) key = this.id().name;
this.expect('in');
var each = new nodes.Each(val, key, this.expression());
block = new nodes.Block(this.parent, each);
block.push(stmt);
each.block = block;
stmt = each;
}
}
}
return stmt;
},
stmt: function() {
var type = this.peek().type;
switch (type) {
case 'keyframes':
return this.keyframes();
case '-moz-document':
return this.mozdocument();
case 'comment':
case 'selector':
case 'extend':
case 'literal':
case 'charset':
case 'namespace':
case 'require':
case 'extend':
case 'media':
case 'atrule':
case 'ident':
case 'scope':
case 'supports':
case 'unless':
return this[type]();
case 'function':
return this.fun();
case 'import':
return this.atimport();
case 'if':
return this.ifstmt();
case 'for':
return this.forin();
case 'return':
return this.ret();
case '{':
return this.property();
default:
if (this.stateAllowsSelector()) {
switch (type) {
case 'color':
case '~':
case '>':
case '<':
case ':':
case '&':
case '&&':
case '[':
case '.':
case '/':
return this.selector();
case '..':
if ('/' == this.lookahead(2).type) return this.selector();
case '+':
return 'function' == this.lookahead(2).type
? this.functionCall()
: this.selector();
case '*':
return this.property();
case 'unit':
if (this.looksLikeKeyframe()) return this.selector();
case '-':
if ('{' == this.lookahead(2).type) return this.property();
}
}
var expr = this.expression();
if (expr.isEmpty) this.error('unexpected {peek}');
return expr;
}
},
block: function(node, scope) {
var delim,
stmt,
next,
block = (this.parent = new nodes.Block(this.parent, node));
if (false === scope) block.scope = false;
this.accept('newline');
if (this.accept('{')) {
this.css++;
delim = '}';
this.skipWhitespace();
} else {
delim = 'outdent';
this.expect('indent');
}
while (delim != this.peek().type) {
if (this.css) {
if (this.accept('newline') || this.accept('indent')) continue;
stmt = this.statement();
this.accept(';');
this.skipWhitespace();
} else {
if (this.accept('newline')) continue;
next = this.lookahead(2).type;
if (
'indent' == this.peek().type &&
~['outdent', 'newline', 'comment'].indexOf(next)
) {
this.skip(['indent', 'outdent']);
continue;
}
if ('eos' == this.peek().type) return block;
stmt = this.statement();
this.accept(';');
}
if (!stmt) this.error('unexpected token {peek} in block');
block.push(stmt);
}
if (this.css) {
this.skipWhitespace();
this.expect('}');
this.skipSpaces();
this.css--;
} else {
this.expect('outdent');
}
this.parent = block.parent;
return block;
},
comment: function() {
var node = this.next().val;
this.skipSpaces();
return node;
},
forin: function() {
this.expect('for');
var key,
val = this.id().name;
if (this.accept(',')) key = this.id().name;
this.expect('in');
this.state.push('for');
this.cond = true;
var each = new nodes.Each(val, key, this.expression());
this.cond = false;
each.block = this.block(each, false);
this.state.pop();
return each;
},
ret: function() {
this.expect('return');
var expr = this.expression();
return expr.isEmpty ? new nodes.Return() : new nodes.Return(expr);
},
unless: function() {
this.expect('unless');
this.state.push('conditional');
this.cond = true;
var node = new nodes.If(this.expression(), true);
this.cond = false;
node.block = this.block(node, false);
this.state.pop();
return node;
},
ifstmt: function() {
this.expect('if');
this.state.push('conditional');
this.cond = true;
var node = new nodes.If(this.expression()),
cond,
block;
this.cond = false;
node.block = this.block(node, false);
this.skip(['newline', 'comment']);
while (this.accept('else')) {
if (this.accept('if')) {
this.cond = true;
cond = this.expression();
this.cond = false;
block = this.block(node, false);
node.elses.push(new nodes.If(cond, block));
} else {
node.elses.push(this.block(node, false));
break;
}
this.skip(['newline', 'comment']);
}
this.state.pop();
return node;
},
atblock: function(node) {
if (!node) this.expect('atblock');
node = new nodes.Atblock();
this.state.push('atblock');
node.block = this.block(node, false);
this.state.pop();
return node;
},
atrule: function() {
var type = this.expect('atrule').val,
node = new nodes.Atrule(type),
tok;
this.skipSpacesAndComments();
node.segments = this.selectorParts();
this.skipSpacesAndComments();
tok = this.peek().type;
if (
'indent' == tok ||
'{' == tok ||
('newline' == tok && '{' == this.lookahead(2).type)
) {
this.state.push('atrule');
node.block = this.block(node);
this.state.pop();
}
return node;
},
scope: function() {
this.expect('scope');
var selector = this.selectorParts()
.map(function(selector) {
return selector.val;
})
.join('');
this.selectorScope = selector.trim();
return nodes.nil;
},
supports: function() {
this.expect('supports');
var node = new nodes.Supports(this.supportsCondition());
this.state.push('atrule');
node.block = this.block(node);
this.state.pop();
return node;
},
supportsCondition: function() {
var node = this.supportsNegation() || this.supportsOp();
if (!node) {
this.cond = true;
node = this.expression();
this.cond = false;
}
return node;
},
supportsNegation: function() {
if (this.accept('not')) {
var node = new nodes.Expression();
node.push(new nodes.Literal('not'));
node.push(this.supportsFeature());
return node;
}
},
supportsOp: function() {
var feature = this.supportsFeature(),
op,
expr;
if (feature) {
expr = new nodes.Expression();
expr.push(feature);
while ((op = this.accept('&&') || this.accept('||'))) {
expr.push(new nodes.Literal('&&' == op.val ? 'and' : 'or'));
expr.push(this.supportsFeature());
}
return expr;
}
},
supportsFeature: function() {
this.skipSpacesAndComments();
if ('(' == this.peek().type) {
var la = this.lookahead(2).type;
if ('ident' == la || '{' == la) {
return this.feature();
} else {
this.expect('(');
var node = new nodes.Expression();
node.push(new nodes.Literal('('));
node.push(this.supportsCondition());
this.expect(')');
node.push(new nodes.Literal(')'));
this.skipSpacesAndComments();
return node;
}
}
},
extend: function() {
var tok = this.expect('extend'),
selectors = [],
sel,
node,
arr;
do {
arr = this.selectorParts();
if (!arr.length) continue;
sel = new nodes.Selector(arr);
selectors.push(sel);
if ('!' !== this.peek().type) continue;
tok = this.lookahead(2);
if ('ident' !== tok.type || 'optional' !== tok.val.name) continue;
this.skip(['!', 'ident']);
sel.optional = true;
} while (this.accept(','));
node = new nodes.Extend(selectors);
node.lineno = tok.lineno;
node.column = tok.column;
return node;
},
media: function() {
this.expect('media');
this.state.push('atrule');
var media = new nodes.Media(this.queries());
media.block = this.block(media);
this.state.pop();
return media;
},
queries: function() {
var queries = new nodes.QueryList(),
skip = ['comment', 'newline', 'space'];
do {
this.skip(skip);
queries.push(this.query());
this.skip(skip);
} while (this.accept(','));
return queries;
},
query: function() {
var query = new nodes.Query(),
expr,
pred,
id;
if (
'ident' == this.peek().type &&
('.' == this.lookahead(2).type || '[' == this.lookahead(2).type)
) {
this.cond = true;
expr = this.expression();
this.cond = false;
query.push(new nodes.Feature(expr.nodes));
return query;
}
if ((pred = this.accept('ident') || this.accept('not'))) {
pred = new nodes.Literal(pred.val.string || pred.val);
this.skipSpacesAndComments();
if ((id = this.accept('ident'))) {
query.type = id.val;
query.predicate = pred;
} else {
query.type = pred;
}
this.skipSpacesAndComments();
if (!this.accept('&&')) return query;
}
do {
query.push(this.feature());
} while (this.accept('&&'));
return query;
},
feature: function() {
this.skipSpacesAndComments();
this.expect('(');
this.skipSpacesAndComments();
var node = new nodes.Feature(this.interpolate());
this.skipSpacesAndComments();
this.accept(':');
this.skipSpacesAndComments();
this.inProperty = true;
node.expr = this.list();
this.inProperty = false;
this.skipSpacesAndComments();
this.expect(')');
this.skipSpacesAndComments();
return node;
},
mozdocument: function() {
this.expect('-moz-document');
var mozdocument = new nodes.Atrule('-moz-document'),
calls = [];
do {
this.skipSpacesAndComments();
calls.push(this.functionCall());
this.skipSpacesAndComments();
} while (this.accept(','));
mozdocument.segments = [new nodes.Literal(calls.join(', '))];
this.state.push('atrule');
mozdocument.block = this.block(mozdocument, false);
this.state.pop();
return mozdocument;
},
atimport: function() {
this.expect('import');
this.allowPostfix = true;
return new nodes.Import(this.expression(), false);
},
require: function() {
this.expect('require');
this.allowPostfix = true;
return new nodes.Import(this.expression(), true);
},
charset: function() {
this.expect('charset');
var str = this.expect('string').val;
this.allowPostfix = true;
return new nodes.Charset(str);
},
namespace: function() {
var str, prefix;
this.expect('namespace');
this.skipSpacesAndComments();
if ((prefix = this.accept('ident'))) {
prefix = prefix.val;
}
this.skipSpacesAndComments();
str = this.accept('string') || this.url();
this.allowPostfix = true;
return new nodes.Namespace(str, prefix);
},
keyframes: function() {
var tok = this.expect('keyframes'),
keyframes;
this.skipSpacesAndComments();
keyframes = new nodes.Keyframes(this.selectorParts(), tok.val);
this.skipSpacesAndComments();
this.state.push('atrule');
keyframes.block = this.block(keyframes);
this.state.pop();
return keyframes;
},
literal: function() {
return this.expect('literal').val;
},
id: function() {
var tok = this.expect('ident');
this.accept('space');
return tok.val;
},
ident: function() {
var i = 2,
la = this.lookahead(i).type;
while ('space' == la) la = this.lookahead(++i).type;
switch (la) {
case '=':
case '?=':
case '-=':
case '+=':
case '*=':
case '/=':
case '%=':
return this.assignment();
case '.':
if ('space' == this.lookahead(i - 1).type) return this.selector();
if (this._ident == this.peek()) return this.id();
while (
'=' != this.lookahead(++i).type &&
!~['[', ',', 'newline', 'indent', 'eos'].indexOf(
this.lookahead(i).type,
)
);
if ('=' == this.lookahead(i).type) {
this._ident = this.peek();
return this.expression();
} else if (this.looksLikeSelector() && this.stateAllowsSelector()) {
return this.selector();
}
case '[':
if (this._ident == this.peek()) return this.id();
while (
']' != this.lookahead(i++).type &&
'selector' != this.lookahead(i).type &&
'eos' != this.lookahead(i).type
);
if ('=' == this.lookahead(i).type) {
this._ident = this.peek();
return this.expression();
} else if (this.looksLikeSelector() && this.stateAllowsSelector()) {
return this.selector();
}
case '-':
case '+':
case '/':
case '*':
case '%':
case '**':
case '&&':
case '||':
case '>':
case '<':
case '>=':
case '<=':
case '!=':
case '==':
case '?':
case 'in':
case 'is a':
case 'is defined':
if (this._ident == this.peek()) {
return this.id();
} else {
this._ident = this.peek();
switch (this.currentState()) {
case 'for':
case 'selector':
return this.property();
case 'root':
case 'atblock':
case 'atrule':
return '[' == la ? this.subscript() : this.selector();
case 'function':
case 'conditional':
return this.looksLikeSelector()
? this.selector()
: this.expression();
default:
return this.operand ? this.id() : this.expression();
}
}
default:
switch (this.currentState()) {
case 'root':
return this.selector();
case 'for':
case 'selector':
case 'function':
case 'conditional':
case 'atblock':
case 'atrule':
return this.property();
default:
var id = this.id();
if ('interpolation' == this.previousState()) id.mixin = true;
return id;
}
}
},
interpolate: function() {
var node,
segs = [],
star;
star = this.accept('*');
if (star) segs.push(new nodes.Literal('*'));
while (true) {
if (this.accept('{')) {
this.state.push('interpolation');
segs.push(this.expression());
this.expect('}');
this.state.pop();
} else if ((node = this.accept('-'))) {
segs.push(new nodes.Literal('-'));
} else if ((node = this.accept('ident'))) {
segs.push(node.val);
} else {
break;
}
}
if (!segs.length) this.expect('ident');
return segs;
},
property: function() {
if (this.looksLikeSelector(true)) return this.selector();
var ident = this.interpolate(),
prop = new nodes.Property(ident),
ret = prop;
this.accept('space');
if (this.accept(':')) this.accept('space');
this.state.push('property');
this.inProperty = true;
prop.expr = this.list();
if (prop.expr.isEmpty) ret = ident[0];
this.inProperty = false;
this.allowPostfix = true;
this.state.pop();
this.accept(';');
return ret;
},
selector: function() {
var arr,
group = new nodes.Group(),
scope = this.selectorScope,
isRoot = 'root' == this.currentState(),
selector;
do {
this.accept('newline');
arr = this.selectorParts();
if (isRoot && scope) arr.unshift(new nodes.Literal(scope + ' '));
if (arr.length) {
selector = new nodes.Selector(arr);
selector.lineno = arr[0].lineno;
selector.column = arr[0].column;
group.push(selector);
}
} while (this.accept(',') || this.accept('newline'));
if ('selector-parts' == this.currentState()) return group.nodes;
this.state.push('selector');
group.block = this.block(group);
this.state.pop();
return group;
},
selectorParts: function() {
var tok,
arr = [];
while ((tok = this.selectorToken())) {
switch (tok.type) {
case '{':
this.skipSpaces();
var expr = this.expression();
this.skipSpaces();
this.expect('}');
arr.push(expr);
break;
case this.prefix && '.':
var literal = new nodes.Literal(tok.val + this.prefix);
literal.prefixed = true;
arr.push(literal);
break;
case 'comment':
break;
case 'color':
case 'unit':
arr.push(new nodes.Literal(tok.val.raw));
break;
case 'space':
arr.push(new nodes.Literal(' '));
break;
case 'function':
arr.push(new nodes.Literal(tok.val.name + '('));
break;
case 'ident':
arr.push(new nodes.Literal(tok.val.name || tok.val.string));
break;
default:
arr.push(new nodes.Literal(tok.val));
if (tok.space) arr.push(new nodes.Literal(' '));
}
}
return arr;
},
assignment: function() {
var op,
node,
name = this.id().name;
if (
(op =
this.accept('=') ||
this.accept('?=') ||
this.accept('+=') ||
this.accept('-=') ||
this.accept('*=') ||
this.accept('/=') ||
this.accept('%='))
) {
this.state.push('assignment');
var expr = this.list();
if (expr.isEmpty) this.assignAtblock(expr);
node = new nodes.Ident(name, expr);
this.state.pop();
switch (op.type) {
case '?=':
var defined = new nodes.BinOp('is defined', node),
lookup = new nodes.Expression();
lookup.push(new nodes.Ident(name));
node = new nodes.Ternary(defined, lookup, node);
break;
case '+=':
case '-=':
case '*=':
case '/=':
case '%=':
node.val = new nodes.BinOp(
op.type[0],
new nodes.Ident(name),
expr,
);
break;
}
}
return node;
},
fun: function() {
var parens = 1,
i = 2,
tok;
out: while ((tok = this.lookahead(i++))) {
switch (tok.type) {
case 'function':
case '(':
++parens;
break;
case ')':
if (!--parens) break out;
break;
case 'eos':
this.error('failed to find closing paren ")"');
}
}
switch (this.currentState()) {
case 'expression':
return this.functionCall();
default:
return this.looksLikeFunctionDefinition(i)
? this.functionDefinition()
: this.expression();
}
},
url: function() {
this.expect('function');
this.state.push('function arguments');
var args = this.args();
this.expect(')');
this.state.pop();
return new nodes.Call('url', args);
},
functionCall: function() {
var withBlock = this.accept('+');
if ('url' == this.peek().val.name) return this.url();
var name = this.expect('function').val.name;
this.state.push('function arguments');
this.parens++;
var args = this.args();
this.expect(')');
this.parens--;
this.state.pop();
var call = new nodes.Call(name, args);
if (withBlock) {
this.state.push('function');
call.block = this.block(call);
this.state.pop();
}
return call;
},
functionDefinition: function() {
var name = this.expect('function').val.name;
this.state.push('function params');
this.skipWhitespace();
var params = this.params();
this.skipWhitespace();
this.expect(')');
this.state.pop();
this.state.push('function');
var fn = new nodes.Function(name, params);
fn.block = this.block(fn);
this.state.pop();
return new nodes.Ident(name, fn);
},
params: function() {
var tok,
node,
params = new nodes.Params();
while ((tok = this.accept('ident'))) {
this.accept('space');
params.push((node = tok.val));
if (this.accept('...')) {
node.rest = true;
} else if (this.accept('=')) {
node.val = this.expression();
}
this.skipWhitespace();
this.accept(',');
this.skipWhitespace();
}
return params;
},
args: function() {
var args = new nodes.Arguments(),
keyword;
do {
if ('ident' == this.peek().type && ':' == this.lookahead(2).type) {
keyword = this.next().val.string;
this.expect(':');
args.map[keyword] = this.expression();
} else {
args.push(this.expression());
}
} while (this.accept(','));
return args;
},
list: function() {
var node = this.expression();
while (this.accept(',')) {
if (node.isList) {
list.push(this.expression());
} else {
var list = new nodes.Expression(true);
list.push(node);
list.push(this.expression());
node = list;
}
}
return node;
},
expression: function() {
var node,
expr = new nodes.Expression();
this.state.push('expression');
while ((node = this.negation())) {
if (!node) this.error('unexpected token {peek} in expression');
expr.push(node);
}
this.state.pop();
if (expr.nodes.length) {
expr.lineno = expr.nodes[0].lineno;
expr.column = expr.nodes[0].column;
}
return expr;
},
negation: function() {
if (this.accept('not')) {
return new nodes.UnaryOp('!', this.negation());
}
return this.ternary();
},
ternary: function() {
var node = this.logical();
if (this.accept('?')) {
var trueExpr = this.expression();
this.expect(':');
var falseExpr = this.expression();
node = new nodes.Ternary(node, trueExpr, falseExpr);
}
return node;
},
logical: function() {
var op,
node = this.typecheck();
while ((op = this.accept('&&') || this.accept('||'))) {
node = new nodes.BinOp(op.type, node, this.typecheck());
}
return node;
},
typecheck: function() {
var op,
node = this.equality();
while ((op = this.accept('is a'))) {
this.operand = true;
if (!node)
this.error('illegal unary "' + op + '", missing left-hand operand');
node = new nodes.BinOp(op.type, node, this.equality());
this.operand = false;
}
return node;
},
equality: function() {
var op,
node = this.inop();
while ((op = this.accept('==') || this.accept('!='))) {
this.operand = true;
if (!node)
this.error('illegal unary "' + op + '", missing left-hand operand');
node = new nodes.BinOp(op.type, node, this.inop());
this.operand = false;
}
return node;
},
inop: function() {
var node = this.relational();
while (this.accept('in')) {
this.operand = true;
if (!node)
this.error('illegal unary "in", missing left-hand operand');
node = new nodes.BinOp('in', node, this.relational());
this.operand = false;
}
return node;
},
relational: function() {
var op,
node = this.range();
while (
(op =
this.accept('>=') ||
this.accept('<=') ||
this.accept('<') ||
this.accept('>'))
) {
this.operand = true;
if (!node)
this.error('illegal unary "' + op + '", missing left-hand operand');
node = new nodes.BinOp(op.type, node, this.range());
this.operand = false;
}
return node;
},
range: function() {
var op,
node = this.additive();
if ((op = this.accept('...') || this.accept('..'))) {
this.operand = true;
if (!node)
this.error('illegal unary "' + op + '", missing left-hand operand');
node = new nodes.BinOp(op.val, node, this.additive());
this.operand = false;
}
return node;
},
additive: function() {
var op,
node = this.multiplicative();
while ((op = this.accept('+') || this.accept('-'))) {
this.operand = true;
node = new nodes.BinOp(op.type, node, this.multiplicative());
this.operand = false;
}
return node;
},
multiplicative: function() {
var op,
node = this.defined();
while (
(op =
this.accept('**') ||
this.accept('*') ||
this.accept('/') ||
this.accept('%'))
) {
this.operand = true;
if ('/' == op && this.inProperty && !this.parens) {
this.stash.push(new Token('literal', new nodes.Literal('/')));
this.operand = false;
return node;
} else {
if (!node)
this.error(
'illegal unary "' + op + '", missing left-hand operand',
);
node = new nodes.BinOp(op.type, node, this.defined());
this.operand = false;
}
}
return node;
},
defined: function() {
var node = this.unary();
if (this.accept('is defined')) {
if (!node)
this.error('illegal unary "is defined", missing left-hand operand');
node = new nodes.BinOp('is defined', node);
}
return node;
},
unary: function() {
var op, node;
if (
(op =
this.accept('!') ||
this.accept('~') ||
this.accept('+') ||
this.accept('-'))
) {
this.operand = true;
node = this.unary();
if (!node) this.error('illegal unary "' + op + '"');
node = new nodes.UnaryOp(op.type, node);
this.operand = false;
return node;
}
return this.subscript();
},
subscript: function() {
var node = this.member(),
id;
while (this.accept('[')) {
node = new nodes.BinOp('[]', node, this.expression());
this.expect(']');
}
if (this.accept('=')) {
node.op += '=';
node.val = this.list();
if (node.val.isEmpty) this.assignAtblock(node.val);
}
return node;
},
member: function() {
var node = this.primary();
if (node) {
while (this.accept('.')) {
var id = new nodes.Ident(this.expect('ident').val.string);
node = new nodes.Member(node, id);
}
this.skipSpaces();
if (this.accept('=')) {
node.val = this.list();
if (node.val.isEmpty) this.assignAtblock(node.val);
}
}
return node;
},
object: function() {
var obj = new nodes.Object(),
id,
val,
comma;
this.expect('{');
this.skipWhitespace();
while (!this.accept('}')) {
if (this.accept('comment') || this.accept('newline')) continue;
if (!comma) this.accept(',');
id = this.accept('ident') || this.accept('string');
if (!id) this.error('expected "ident" or "string", got {peek}');
id = id.val.hash;
this.skipSpacesAndComments();
this.expect(':');
val = this.expression();
obj.set(id, val);
comma = this.accept(',');
this.skipWhitespace();
}
return obj;
},
primary: function() {
var tok;
this.skipSpaces();
if (this.accept('(')) {
++this.parens;
var expr = this.expression(),
paren = this.expect(')');
--this.parens;
if (this.accept('%')) expr.push(new nodes.Ident('%'));
tok = this.peek();
if (
!paren.space &&
'ident' == tok.type &&
~units.indexOf(tok.val.string)
) {
expr.push(new nodes.Ident(tok.val.string));
this.next();
}
return expr;
}
tok = this.peek();
switch (tok.type) {
case 'null':
case 'unit':
case 'color':
case 'string':
case 'literal':
case 'boolean':
case 'comment':
return this.next().val;
case !this.cond && '{':
return this.object();
case 'atblock':
return this.atblock();
case 'atrule':
var id = new nodes.Ident(this.next().val);
id.property = true;
return id;
case 'ident':
return this.ident();
case 'function':
return tok.anonymous
? this.functionDefinition()
: this.functionCall();
}
},
};
});
require.register('renderer.js', function(module, exports, require) {
var Parser = require('./parser'),
Evaluator = require('./visitor/evaluator'),
Normalizer = require('./visitor/normalizer'),
utils = require('./utils'),
nodes = require('./nodes'),
join = require('./path').join;
module.exports = Renderer;
function Renderer(str, options) {
options = options || {};
options.globals = options.globals || {};
options.functions = options.functions || {};
options.use = options.use || [];
options.use = Array.isArray(options.use) ? options.use : [options.use];
options.imports = [];
options.paths = options.paths || [];
options.filename = options.filename || 'stylus';
options.Evaluator = options.Evaluator || Evaluator;
this.options = options;
this.str = str;
}
Renderer.prototype.render = function(fn) {
var parser = (this.parser = new Parser(this.str, this.options));
for (var i = 0, len = this.options.use.length; i < len; i++) {
this.use(this.options.use[i]);
}
try {
nodes.filename = this.options.filename;
var ast = parser.parse();
this.evaluator = new this.options.Evaluator(ast, this.options);
this.nodes = nodes;
this.evaluator.renderer = this;
ast = this.evaluator.evaluate();
var normalizer = new Normalizer(ast, this.options);
ast = normalizer.normalize();
var compiler = this.options.sourcemap
? new (require('./visitor/sourcemapper'))(ast, this.options)
: new (require('./visitor/compiler'))(ast, this.options),
css = compiler.compile();
if (this.options.sourcemap) this.sourcemap = compiler.map.toJSON();
} catch (err) {
var options = {};
options.input = err.input || this.str;
options.filename = err.filename || this.options.filename;
options.lineno = err.lineno || parser.lexer.lineno;
options.column = err.column || parser.lexer.column;
if (!fn) throw utils.formatException(err, options);
return fn(utils.formatException(err, options));
}
if (!fn) return css;
fn(null, css);
};
Renderer.prototype.deps = function(filename) {
var opts = utils.merge({ cache: false }, this.options);
if (filename) opts.filename = filename;
var DepsResolver = require('./visitor/deps-resolver'),
parser = new Parser(this.str, opts);
try {
nodes.filename = opts.filename;
var ast = parser.parse(),
resolver = new DepsResolver(ast, opts);
return resolver.resolve();
} catch (err) {
var options = {};
options.input = err.input || this.str;
options.filename = err.filename || opts.filename;
options.lineno = err.lineno || parser.lexer.lineno;
options.column = err.column || parser.lexer.column;
throw utils.formatException(err, options);
}
};
Renderer.prototype.set = function(key, val) {
this.options[key] = val;
return this;
};
Renderer.prototype.get = function(key) {
return this.options[key];
};
Renderer.prototype.include = function(path) {
this.options.paths.push(path);
return this;
};
Renderer.prototype.use = function(fn) {
fn.call(this, this);
return this;
};
Renderer.prototype.define = function(name, fn, raw) {
fn = utils.coerce(fn, raw);
if (fn.nodeName) {
this.options.globals[name] = fn;
return this;
}
this.options.functions[name] = fn;
if (undefined != raw) fn.raw = raw;
return this;
};
});
require.register('selector-parser.js', function(module, exports, require) {
var COMBINATORS = ['>', '+', '~'];
var SelectorParser = (module.exports = function SelectorParser(
str,
stack,
parts,
) {
this.str = str;
this.stack = stack || [];
this.parts = parts || [];
this.pos = 0;
this.level = 2;
this.nested = true;
this.ignore = false;
});
SelectorParser.prototype.skip = function(len) {
this.str = this.str.substr(len);
this.pos += len;
};
SelectorParser.prototype.skipSpaces = function() {
while (' ' == this.str[0]) this.skip(1);
};
SelectorParser.prototype.advance = function() {
return (
this.root() ||
this.relative() ||
this.initial() ||
this.escaped() ||
this.parent() ||
this.partial() ||
this.char()
);
};
SelectorParser.prototype.root = function() {
if (!this.pos && '/' == this.str[0] && 'deep' != this.str.slice(1, 5)) {
this.nested = false;
this.skip(1);
}
};
SelectorParser.prototype.relative = function(multi) {
if ((!this.pos || multi) && '../' == this.str.slice(0, 3)) {
this.nested = false;
this.skip(3);
while (this.relative(true)) this.level++;
if (!this.raw) {
var ret = this.stack[this.stack.length - this.level];
if (ret) {
return ret;
} else {
this.ignore = true;
}
}
}
};
SelectorParser.prototype.initial = function() {
if (!this.pos && '~' == this.str[0] && '/' == this.str[1]) {
this.nested = false;
this.skip(2);
return this.stack[0];
}
};
SelectorParser.prototype.escaped = function() {
if ('\\' == this.str[0]) {
var char = this.str[1];
if ('&' == char || '^' == char) {
this.skip(2);
return char;
}
}
};
SelectorParser.prototype.parent = function() {
if ('&' == this.str[0]) {
this.nested = false;
if (!this.pos && (!this.stack.length || this.raw)) {
var i = 0;
while (' ' == this.str[++i]);
if (~COMBINATORS.indexOf(this.str[i])) {
this.skip(i + 1);
return;
}
}
this.skip(1);
if (!this.raw) return this.stack[this.stack.length - 1];
}
};
SelectorParser.prototype.partial = function() {
if ('^' == this.str[0] && '[' == this.str[1]) {
this.skip(2);
this.skipSpaces();
var ret = this.range();
this.skipSpaces();
if (']' != this.str[0]) return '^[';
this.nested = false;
this.skip(1);
if (ret) {
return ret;
} else {
this.ignore = true;
}
}
};
SelectorParser.prototype.number = function() {
var i = 0,
ret = '';
if ('-' == this.str[i]) ret += this.str[i++];
while (this.str.charCodeAt(i) >= 48 && this.str.charCodeAt(i) <= 57)
ret += this.str[i++];
if (ret) {
this.skip(i);
return Number(ret);
}
};
SelectorParser.prototype.range = function() {
var start = this.number(),
ret;
if ('..' == this.str.slice(0, 2)) {
this.skip(2);
var end = this.number(),
len = this.parts.length;
if (start < 0) start = len + start - 1;
if (end < 0) end = len + end - 1;
if (start > end) {
var tmp = start;
start = end;
end = tmp;
}
if (end < len - 1) {
ret = this.parts
.slice(start, end + 1)
.map(function(part) {
var selector = new SelectorParser(part, this.stack, this.parts);
selector.raw = true;
return selector.parse();
}, this)
.map(function(selector) {
return (selector.nested ? ' ' : '') + selector.val;
})
.join('')
.trim();
}
} else {
ret = this.stack[start < 0 ? this.stack.length + start - 1 : start];
}
if (ret) {
return ret;
} else {
this.ignore = true;
}
};
SelectorParser.prototype.char = function() {
var char = this.str[0];
this.skip(1);
return char;
};
SelectorParser.prototype.parse = function() {
var val = '';
while (this.str.length) {
val += this.advance() || '';
if (this.ignore) {
val = '';
break;
}
}
return { val: val.trimRight(), nested: this.nested };
};
});
require.register('stack/index.js', function(module, exports, require) {
var Stack = (module.exports = function Stack() {
Array.apply(this, arguments);
});
Stack.prototype.__proto__ = Array.prototype;
Stack.prototype.push = function(frame) {
frame.stack = this;
frame.parent = this.currentFrame;
return [].push.apply(this, arguments);
};
Stack.prototype.__defineGetter__('currentFrame', function() {
return this[this.length - 1];
});
Stack.prototype.getBlockFrame = function(block) {
for (var i = 0; i < this.length; ++i) {
if (block == this[i].block) {
return this[i];
}
}
};
Stack.prototype.lookup = function(name) {
var block = this.currentFrame.block,
val,
ret;
do {
var frame = this.getBlockFrame(block);
if (frame && (val = frame.lookup(name))) {
return val;
}
} while ((block = block.parent));
};
Stack.prototype.inspect = function() {
return this.reverse()
.map(function(frame) {
return frame.inspect();
})
.join('\n');
};
Stack.prototype.toString = function() {
var block,
node,
buf = [],
location,
len = this.length;
while (len--) {
block = this[len].block;
if ((node = block.node)) {
location =
'(' +
node.filename +
':' +
(node.lineno + 1) +
':' +
node.column +
')';
switch (node.nodeName) {
case 'function':
buf.push(' at ' + node.name + '() ' + location);
break;
case 'group':
buf.push(' at "' + node.nodes[0].val + '" ' + location);
break;
}
}
}
return buf.join('\n');
};
});
require.register('stack/frame.js', function(module, exports, require) {
var Scope = require('./scope');
var Frame = (module.exports = function Frame(block) {
this._scope = false === block.scope ? null : new Scope();
this.block = block;
});
Frame.prototype.__defineGetter__('scope', function() {
return this._scope || this.parent.scope;
});
Frame.prototype.lookup = function(name) {
return this.scope.lookup(name);
};
Frame.prototype.inspect = function() {
return (
'[Frame ' +
(false === this.block.scope ? 'scope-less' : this.scope.inspect()) +
']'
);
};
});
require.register('stack/scope.js', function(module, exports, require) {
var Scope = (module.exports = function Scope() {
this.locals = {};
});
Scope.prototype.add = function(ident) {
this.locals[ident.name] = ident.val;
};
Scope.prototype.lookup = function(name) {
return this.locals[name];
};
Scope.prototype.inspect = function() {
var keys = Object.keys(this.locals).map(function(key) {
return '@' + key;
});
return '[Scope' + (keys.length ? ' ' + keys.join(', ') : '') + ']';
};
});
require.register('stylus.js', function(module, exports, require) {
var Renderer = require('./renderer'),
nodes = require('./nodes'),
utils = require('./utils');
exports = module.exports = render;
exports.version = '0.54.5';
exports.nodes = nodes;
exports.functions = require('./functions');
exports.utils = require('./utils');
exports.Visitor = require('./visitor');
exports.Parser = require('./parser');
exports.Evaluator = require('./visitor/evaluator');
exports.Normalizer = require('./visitor/normalizer');
exports.Compiler = require('./visitor/compiler');
exports.render = function(str, options, fn) {
if ('function' == typeof options) (fn = options), (options = {});
if (bifs) str = bifs + str;
return new Renderer(str, options).render(fn);
};
function render(str, options) {
if (bifs) str = bifs + str;
return new Renderer(str, options);
}
exports.url = require('./functions/url');
});
require.register('token.js', function(module, exports, require) {
var Token = (exports = module.exports = function Token(type, val) {
this.type = type;
this.val = val;
});
Token.prototype.inspect = function() {
var val = ' ' + this.val;
return (
'[Token:' +
this.lineno +
':' +
this.column +
' ' +
'' +
this.type +
'' +
'' +
(this.val ? val : '') +
'' +
']'
);
};
Token.prototype.toString = function() {
return (undefined === this.val ? this.type : this.val).toString();
};
});
require.register('utils.js', function(module, exports, require) {
var nodes = require('./nodes'),
join = require('./path').join,
isAbsolute = require('./path').isAbsolute;
exports.absolute =
isAbsolute ||
function(path) {
return (
path.substr(0, 2) == '\\\\' ||
'/' === path.charAt(0) ||
/^[a-z]:[\\\/]/i.test(path)
);
};
exports.lookup = function(path, paths, ignore) {
var lookup,
i = paths.length;
if (exports.absolute(path)) {
try {
return path;
} catch (err) {}
}
while (i--) {
try {
lookup = join(paths[i], path);
if (ignore == lookup) continue;
return lookup;
} catch (err) {}
}
};
exports.find = function(path, paths, ignore) {
var lookup,
found,
i = paths.length;
if (exports.absolute(path)) {
if ((found = glob.sync(path)).length) {
return found;
}
}
while (i--) {
lookup = join(paths[i], path);
if (ignore == lookup) continue;
if ((found = glob.sync(lookup)).length) {
return found;
}
}
};
exports.lookupIndex = function(name, paths, filename) {
var found = exports.find(join(name, 'index.styl'), paths, filename);
if (!found) {
found = exports.find(
join(name, basename(name).replace(/\.styl/i, '') + '.styl'),
paths,
filename,
);
}
if (!found && !~name.indexOf('node_modules')) {
found = lookupPackage(join('node_modules', name));
}
return found;
function lookupPackage(dir) {
var pkg = exports.lookup(join(dir, 'package.json'), paths, filename);
if (!pkg) {
return /\.styl$/i.test(dir)
? exports.lookupIndex(dir, paths, filename)
: lookupPackage(dir + '.styl');
}
var main = require(relative(__dirname, pkg)).main;
if (main) {
found = exports.find(join(dir, main), paths, filename);
} else {
found = exports.lookupIndex(dir, paths, filename);
}
return found;
}
};
exports.formatException = function(err, options) {
var lineno = options.lineno,
column = options.column,
filename = options.filename,
str = options.input,
context = options.context || 8,
context = context / 2,
lines = ('\n' + str).split('\n'),
start = Math.max(lineno - context, 1),
end = Math.min(lines.length, lineno + context),
pad = end.toString().length;
var context = lines
.slice(start, end)
.map(function(line, i) {
var curr = i + start;
return (
' ' +
Array(pad - curr.toString().length + 1).join(' ') +
curr +
'| ' +
line +
(curr == lineno
? '\n' +
Array(curr.toString().length + 5 + column).join('-') +
'^'
: '')
);
})
.join('\n');
err.message =
filename +
':' +
lineno +
':' +
column +
'\n' +
context +
'\n\n' +
err.message +
'\n' +
(err.stylusStack ? err.stylusStack + '\n' : '');
if (err.fromStylus) err.stack = 'Error: ' + err.message;
return err;
};
exports.assertType = function(node, type, param) {
exports.assertPresent(node, param);
if (node.nodeName == type) return;
var actual = node.nodeName,
msg =
'expected ' +
(param ? '"' + param + '" to be a ' : '') +
type +
', but got ' +
actual +
':' +
node;
throw new Error('TypeError: ' + msg);
};
exports.assertString = function(node, param) {
exports.assertPresent(node, param);
switch (node.nodeName) {
case 'string':
case 'ident':
case 'literal':
return;
default:
var actual = node.nodeName,
msg =
'expected string, ident or literal, but got ' +
actual +
':' +
node;
throw new Error('TypeError: ' + msg);
}
};
exports.assertColor = function(node, param) {
exports.assertPresent(node, param);
switch (node.nodeName) {
case 'rgba':
case 'hsla':
return;
default:
var actual = node.nodeName,
msg = 'expected rgba or hsla, but got ' + actual + ':' + node;
throw new Error('TypeError: ' + msg);
}
};
exports.assertPresent = function(node, name) {
if (node) return;
if (name) throw new Error('"' + name + '" argument required');
throw new Error('argument missing');
};
exports.unwrap = function(expr) {
if (expr.preserve) return expr;
if ('arguments' != expr.nodeName && 'expression' != expr.nodeName)
return expr;
if (1 != expr.nodes.length) return expr;
if (
'arguments' != expr.nodes[0].nodeName &&
'expression' != expr.nodes[0].nodeName
)
return expr;
return exports.unwrap(expr.nodes[0]);
};
exports.coerce = function(val, raw) {
switch (typeof val) {
case 'function':
return val;
case 'string':
return new nodes.String(val);
case 'boolean':
return new nodes.Boolean(val);
case 'number':
return new nodes.Unit(val);
default:
if (null == val) return nodes.nil;
if (Array.isArray(val)) return exports.coerceArray(val, raw);
if (val.nodeName) return val;
return exports.coerceObject(val, raw);
}
};
exports.coerceArray = function(val, raw) {
var expr = new nodes.Expression();
val.forEach(function(val) {
expr.push(exports.coerce(val, raw));
});
return expr;
};
exports.coerceObject = function(obj, raw) {
var node = raw ? new nodes.Object() : new nodes.Expression(),
val;
for (var key in obj) {
val = exports.coerce(obj[key], raw);
key = new nodes.Ident(key);
if (raw) {
node.set(key, val);
} else {
node.push(exports.coerceArray([key, val]));
}
}
return node;
};
exports.params = function(fn) {
return fn.toString().match(/\(([^)]*)\)/)[1].split(/ *, */);
};
exports.merge = function(a, b, deep) {
for (var k in b) {
if (deep && a[k]) {
var nodeA = exports.unwrap(a[k]).first,
nodeB = exports.unwrap(b[k]).first;
if ('object' == nodeA.nodeName && 'object' == nodeB.nodeName) {
a[k].first.vals = exports.merge(nodeA.vals, nodeB.vals, deep);
} else {
a[k] = b[k];
}
} else {
a[k] = b[k];
}
}
return a;
};
exports.uniq = function(arr) {
var obj = {},
ret = [];
for (var i = 0, len = arr.length; i < len; ++i) {
if (arr[i] in obj) continue;
obj[arr[i]] = true;
ret.push(arr[i]);
}
return ret;
};
exports.compileSelectors = function(arr, leaveHidden) {
var selectors = [],
Parser = require('./selector-parser'),
indent = this.indent || '',
buf = [];
function parse(selector, buf) {
var parts = [selector.val],
str = new Parser(parts[0], parents, parts).parse().val,
parents = [];
if (buf.length) {
for (var i = 0, len = buf.length; i < len; ++i) {
parts.push(buf[i]);
parents.push(str);
var child = new Parser(buf[i], parents, parts).parse();
if (child.nested) {
str += ' ' + child.val;
} else {
str = child.val;
}
}
}
return str.trim();
}
function compile(arr, i) {
if (i) {
arr[i].forEach(function(selector) {
if (!leaveHidden && selector.isPlaceholder) return;
if (selector.inherits) {
buf.unshift(selector.val);
compile(arr, i - 1);
buf.shift();
} else {
selectors.push(indent + parse(selector, buf));
}
});
} else {
arr[0].forEach(function(selector) {
if (!leaveHidden && selector.isPlaceholder) return;
var str = parse(selector, buf);
if (str) selectors.push(indent + str);
});
}
}
compile(arr, arr.length - 1);
return exports.uniq(selectors);
};
exports.parseString = function(str) {
var Parser = require('./parser'),
parser,
ret;
try {
parser = new Parser(str);
parser.state.push('expression');
ret = new nodes.Expression();
ret.nodes = parser.parse().nodes;
} catch (e) {
ret = new nodes.Literal(str);
}
return ret;
};
});
require.register('visitor/index.js', function(module, exports, require) {
var Visitor = (module.exports = function Visitor(root) {
this.root = root;
});
Visitor.prototype.visit = function(node, fn) {
var method = 'visit' + node.constructor.name;
if (this[method]) return this[method](node);
return node;
};
});
require.register('visitor/compiler.js', function(module, exports, require) {
var Visitor = require('./index'),
utils = require('../utils');
var Compiler = (module.exports = function Compiler(root, options) {
options = options || {};
this.compress = options.compress;
this.firebug = options.firebug;
this.linenos = options.linenos;
this.spaces = options['indent spaces'] || 2;
this.indents = 1;
Visitor.call(this, root);
this.stack = [];
});
Compiler.prototype.__proto__ = Visitor.prototype;
Compiler.prototype.compile = function() {
return this.visit(this.root);
};
Compiler.prototype.out = function(str, node) {
return str;
};
Compiler.prototype.__defineGetter__('indent', function() {
if (this.compress) return '';
return new Array(this.indents).join(Array(this.spaces + 1).join(' '));
});
Compiler.prototype.needBrackets = function(node) {
return (
1 == this.indents || 'atrule' != node.nodeName || node.hasOnlyProperties
);
};
Compiler.prototype.visitRoot = function(block) {
this.buf = '';
for (var i = 0, len = block.nodes.length; i < len; ++i) {
var node = block.nodes[i];
if (this.linenos || this.firebug) this.debugInfo(node);
var ret = this.visit(node);
if (ret) this.buf += this.out(ret + '\n', node);
}
return this.buf;
};
Compiler.prototype.visitBlock = function(block) {
var node,
separator = this.compress ? '' : '\n',
needBrackets;
if (block.hasProperties && !block.lacksRenderedSelectors) {
needBrackets = this.needBrackets(block.node);
if (needBrackets) {
this.buf += this.out(this.compress ? '{' : ' {\n');
++this.indents;
}
for (var i = 0, len = block.nodes.length; i < len; ++i) {
this.last = len - 1 == i;
node = block.nodes[i];
switch (node.nodeName) {
case 'null':
case 'expression':
case 'function':
case 'group':
case 'block':
case 'unit':
case 'media':
case 'keyframes':
case 'atrule':
case 'supports':
continue;
case !this.compress && node.inline && 'comment':
this.buf = this.buf.slice(0, -1);
this.buf += this.out(' ' + this.visit(node) + '\n', node);
break;
case 'property':
var ret = this.visit(node) + separator;
this.buf += this.compress ? ret : this.out(ret, node);
break;
default:
this.buf += this.out(this.visit(node) + separator, node);
}
}
if (needBrackets) {
--this.indents;
this.buf += this.out(this.indent + '}' + separator);
}
}
for (var i = 0, len = block.nodes.length; i < len; ++i) {
node = block.nodes[i];
switch (node.nodeName) {
case 'group':
case 'block':
case 'keyframes':
if (this.linenos || this.firebug) this.debugInfo(node);
this.visit(node);
break;
case 'media':
case 'import':
case 'atrule':
case 'supports':
this.visit(node);
break;
case 'comment':
if (!node.suppress) {
this.buf += this.out(this.indent + this.visit(node) + '\n', node);
}
break;
case 'charset':
case 'literal':
case 'namespace':
this.buf += this.out(this.visit(node) + '\n', node);
break;
}
}
};
Compiler.prototype.visitKeyframes = function(node) {
if (!node.frames) return;
var prefix = 'official' == node.prefix ? '' : '-' + node.prefix + '-';
this.buf += this.out(
'@' +
prefix +
'keyframes ' +
this.visit(node.val) +
(this.compress ? '{' : ' {\n'),
node,
);
this.keyframe = true;
++this.indents;
this.visit(node.block);
--this.indents;
this.keyframe = false;
this.buf += this.out('}' + (this.compress ? '' : '\n'));
};
Compiler.prototype.visitMedia = function(media) {
var val = media.val;
if (!media.hasOutput || !val.nodes.length) return;
this.buf += this.out('@media ', media);
this.visit(val);
this.buf += this.out(this.compress ? '{' : ' {\n');
++this.indents;
this.visit(media.block);
--this.indents;
this.buf += this.out('}' + (this.compress ? '' : '\n'));
};
Compiler.prototype.visitQueryList = function(queries) {
for (var i = 0, len = queries.nodes.length; i < len; ++i) {
this.visit(queries.nodes[i]);
if (len - 1 != i)
this.buf += this.out(',' + (this.compress ? '' : ' '));
}
};
Compiler.prototype.visitQuery = function(node) {
var len = node.nodes.length;
if (node.predicate) this.buf += this.out(node.predicate + ' ');
if (node.type) this.buf += this.out(node.type + (len ? ' and ' : ''));
for (var i = 0; i < len; ++i) {
this.buf += this.out(this.visit(node.nodes[i]));
if (len - 1 != i) this.buf += this.out(' and ');
}
};
Compiler.prototype.visitFeature = function(node) {
if (!node.expr) {
return node.name;
} else if (node.expr.isEmpty) {
return '(' + node.name + ')';
} else {
return (
'(' +
node.name +
':' +
(this.compress ? '' : ' ') +
this.visit(node.expr) +
')'
);
}
};
Compiler.prototype.visitImport = function(imported) {
this.buf += this.out(
'@import ' + this.visit(imported.path) + ';\n',
imported,
);
};
Compiler.prototype.visitAtrule = function(atrule) {
var newline = this.compress ? '' : '\n';
this.buf += this.out(this.indent + '@' + atrule.type, atrule);
if (atrule.val) this.buf += this.out(' ' + atrule.val.trim());
if (atrule.block) {
if (atrule.hasOnlyProperties) {
this.visit(atrule.block);
} else {
this.buf += this.out(this.compress ? '{' : ' {\n');
++this.indents;
this.visit(atrule.block);
--this.indents;
this.buf += this.out(this.indent + '}' + newline);
}
} else {
this.buf += this.out(';' + newline);
}
};
(Compiler.prototype.visitSupports = function(node) {
if (!node.hasOutput) return;
this.buf += this.out(this.indent + '@supports ', node);
this.isCondition = true;
this.buf += this.out(this.visit(node.condition));
this.isCondition = false;
this.buf += this.out(this.compress ? '{' : ' {\n');
++this.indents;
this.visit(node.block);
--this.indents;
this.buf += this.out(this.indent + '}' + (this.compress ? '' : '\n'));
}), (Compiler.prototype.visitComment = function(comment) {
return this.compress
? comment.suppress ? '' : comment.str
: comment.str;
});
Compiler.prototype.visitFunction = function(fn) {
return fn.name;
};
Compiler.prototype.visitCharset = function(charset) {
return '@charset ' + this.visit(charset.val) + ';';
};
Compiler.prototype.visitNamespace = function(namespace) {
return (
'@namespace ' +
(namespace.prefix ? this.visit(namespace.prefix) + ' ' : '') +
this.visit(namespace.val) +
';'
);
};
Compiler.prototype.visitLiteral = function(lit) {
var val = lit.val;
if (lit.css) val = val.replace(/^ /gm, '');
return val;
};
Compiler.prototype.visitBoolean = function(bool) {
return bool.toString();
};
Compiler.prototype.visitRGBA = function(rgba) {
return rgba.toString();
};
Compiler.prototype.visitHSLA = function(hsla) {
return hsla.rgba.toString();
};
Compiler.prototype.visitUnit = function(unit) {
var type = unit.type || '',
n = unit.val,
float = n != (n | 0);
if (this.compress) {
if ('%' != type && 's' != type && 'ms' != type && 0 == n) return '0';
if (float && n < 1 && n > -1) {
return n.toString().replace('0.', '.') + type;
}
}
return (float ? parseFloat(n.toFixed(15)) : n).toString() + type;
};
Compiler.prototype.visitGroup = function(group) {
var stack = this.keyframe ? [] : this.stack,
comma = this.compress ? ',' : ',\n';
stack.push(group.nodes);
if (group.block.hasProperties) {
var selectors = utils.compileSelectors.call(this, stack),
len = selectors.length;
if (len) {
if (this.keyframe) comma = this.compress ? ',' : ', ';
for (var i = 0; i < len; ++i) {
var selector = selectors[i],
last = i == len - 1;
if (this.keyframe) selector = i ? selector.trim() : selector;
this.buf += this.out(
selector + (last ? '' : comma),
group.nodes[i],
);
}
} else {
group.block.lacksRenderedSelectors = true;
}
}
this.visit(group.block);
stack.pop();
};
Compiler.prototype.visitIdent = function(ident) {
return ident.name;
};
Compiler.prototype.visitString = function(string) {
return this.isURL ? string.val : string.toString();
};
Compiler.prototype.visitNull = function(node) {
return '';
};
Compiler.prototype.visitCall = function(call) {
this.isURL = 'url' == call.name;
var args = call.args.nodes
.map(function(arg) {
return this.visit(arg);
}, this)
.join(this.compress ? ',' : ', ');
if (this.isURL) args = '"' + args + '"';
this.isURL = false;
return call.name + '(' + args + ')';
};
Compiler.prototype.visitExpression = function(expr) {
var buf = [],
self = this,
len = expr.nodes.length,
nodes = expr.nodes.map(function(node) {
return self.visit(node);
});
nodes.forEach(function(node, i) {
var last = i == len - 1;
buf.push(node);
if ('/' == nodes[i + 1] || '/' == node) return;
if (last) return;
var space =
self.isURL ||
(self.isCondition && (')' == nodes[i + 1] || '(' == node))
? ''
: ' ';
buf.push(expr.isList ? (self.compress ? ',' : ', ') : space);
});
return buf.join('');
};
Compiler.prototype.visitArguments = Compiler.prototype.visitExpression;
Compiler.prototype.visitProperty = function(prop) {
var val = this.visit(prop.expr).trim(),
name = prop.name || prop.segments.join(''),
arr = [];
arr.push(
this.out(this.indent),
this.out(name + (this.compress ? ':' : ': '), prop),
this.out(val, prop.expr),
this.out(this.compress ? (this.last ? '' : ';') : ';'),
);
return arr.join('');
};
Compiler.prototype.debugInfo = function(node) {
var path =
node.filename == 'stdin' ? 'stdin' : fs.realpathSync(node.filename),
line =
(node.nodes && node.nodes.length
? node.nodes[0].lineno
: node.lineno) || 1;
if (this.linenos) {
this.buf += '\n/* ' + 'line ' + line + ' : ' + path + ' */\n';
}
if (this.firebug) {
path =
'file\\:\\/\\/' +
path.replace(/([.:\/\\])/g, function(m) {
return '\\' + (m === '\\' ? '/' : m);
});
line = '\\00003' + line;
this.buf +=
'\n@media -stylus-debug-info' +
'{filename{font-family:' +
path +
'}line{font-family:' +
line +
'}}\n';
}
};
});
require.register('visitor/evaluator.js', function(module, exports, require) {
var Visitor = require('./index'),
nodes = require('../nodes'),
Stack = require('../stack'),
Frame = require('../stack/frame'),
utils = require('../utils'),
bifs = require('../functions'),
dirname = require('../path').dirname,
colors = require('../colors'),
units = require('../units');
function cloneNode(node) {
if (node.block && node.block.node) {
node.block.node = node.block.node.clone();
}
if (node.nodes && node.nodes.length) {
node.nodes.map(cloneNode);
}
return node;
}
function importFile(node, file, literal) {
var importStack = this.importStack,
Parser = require('../parser'),
stat;
if (node.once) {
if (this.requireHistory[file]) return nodes.nil;
this.requireHistory[file] = true;
if (literal && !this.includeCSS) {
return node;
}
}
if (~importStack.indexOf(file))
throw new Error('import loop has been found');
var str = fs.readFileSync(file, 'utf8');
if (!str.trim()) return nodes.nil;
node.path = file;
node.dirname = dirname(file);
stat = fs.statSync(file);
node.mtime = stat.mtime;
this.paths.push(node.dirname);
if (this.options._imports) this.options._imports.push(node.clone());
importStack.push(file);
nodes.filename = file;
if (literal) {
literal = new nodes.Literal(str.replace(/\r\n?/g, '\n'));
literal.lineno = literal.column = 1;
if (!this.resolveURL) return literal;
}
var block = new nodes.Block(),
parser = new Parser(str, utils.merge({ root: block }, this.options));
try {
block = parser.parse();
} catch (err) {
var line = parser.lexer.lineno,
column = parser.lexer.column;
if (literal && this.includeCSS && this.resolveURL) {
this.warn(
'ParseError: ' +
file +
':' +
line +
':' +
column +
'. This file included as-is',
);
return literal;
} else {
err.filename = file;
err.lineno = line;
err.column = column;
err.input = str;
throw err;
}
}
block = block.clone(this.currentBlock);
block.parent = this.currentBlock;
block.scope = false;
var ret = this.visit(block);
importStack.pop();
if (!this.resolveURL || this.resolveURL.nocheck) this.paths.pop();
return ret;
}
var Evaluator = (module.exports = function Evaluator(root, options) {
options = options || {};
Visitor.call(this, root);
var functions = (this.functions = options.functions || {});
this.stack = new Stack();
this.imports = options.imports || [];
this.globals = options.globals || {};
this.paths = options.paths || [];
this.prefix = options.prefix || '';
this.filename = options.filename;
this.includeCSS = options['include css'];
this.resolveURL =
functions.url &&
'resolver' == functions.url.name &&
functions.url.options;
this.paths.push(dirname(options.filename || '.'));
this.stack.push((this.global = new Frame(root)));
this.warnings = options.warn;
this.options = options;
this.calling = [];
this.importStack = [];
this.ret = 0;
this.requireHistory = {};
});
Evaluator.prototype.__proto__ = Visitor.prototype;
var visit = Visitor.prototype.visit;
Evaluator.prototype.visit = function(node) {
try {
return visit.call(this, node);
} catch (err) {
if (err.filename) throw err;
err.lineno = node.lineno;
err.column = node.column;
err.filename = node.filename;
err.stylusStack = this.stack.toString();
try {
} catch (err) {}
throw err;
}
};
Evaluator.prototype.setup = function() {
var root = this.root;
var imports = [];
this.populateGlobalScope();
this.imports.forEach(function(file) {
var expr = new nodes.Expression();
expr.push(new nodes.String(file));
imports.push(new nodes.Import(expr));
}, this);
root.nodes = imports.concat(root.nodes);
};
Evaluator.prototype.populateGlobalScope = function() {
var scope = this.global.scope;
Object.keys(colors).forEach(function(name) {
var color = colors[name],
rgba = new nodes.RGBA(color[0], color[1], color[2], color[3]),
node = new nodes.Ident(name, rgba);
rgba.name = name;
scope.add(node);
});
scope.add(
new nodes.Ident(
'embedurl',
new nodes.Function(
'embedurl',
require('../functions/url')({ limit: false }),
),
),
);
var globals = this.globals;
Object.keys(globals).forEach(function(name) {
var val = globals[name];
if (!val.nodeName) val = new nodes.Literal(val);
scope.add(new nodes.Ident(name, val));
});
};
Evaluator.prototype.evaluate = function() {
this.setup();
return this.visit(this.root);
};
Evaluator.prototype.visitGroup = function(group) {
group.nodes = group.nodes.map(function(selector) {
selector.val = this.interpolate(selector);
return selector;
}, this);
group.block = this.visit(group.block);
return group;
};
Evaluator.prototype.visitReturn = function(ret) {
ret.expr = this.visit(ret.expr);
throw ret;
};
Evaluator.prototype.visitMedia = function(media) {
media.block = this.visit(media.block);
media.val = this.visit(media.val);
return media;
};
Evaluator.prototype.visitQueryList = function(queries) {
var val, query;
queries.nodes.forEach(this.visit, this);
if (1 == queries.nodes.length) {
query = queries.nodes[0];
if ((val = this.lookup(query.type))) {
val = val.first.string;
if (!val) return queries;
var Parser = require('../parser'),
parser = new Parser(val, this.options);
queries = this.visit(parser.queries());
}
}
return queries;
};
Evaluator.prototype.visitQuery = function(node) {
node.predicate = this.visit(node.predicate);
node.type = this.visit(node.type);
node.nodes.forEach(this.visit, this);
return node;
};
Evaluator.prototype.visitFeature = function(node) {
node.name = this.interpolate(node);
if (node.expr) {
this.ret++;
node.expr = this.visit(node.expr);
this.ret--;
}
return node;
};
Evaluator.prototype.visitObject = function(obj) {
for (var key in obj.vals) {
obj.vals[key] = this.visit(obj.vals[key]);
}
return obj;
};
Evaluator.prototype.visitMember = function(node) {
var left = node.left,
right = node.right,
obj = this.visit(left).first;
if ('object' != obj.nodeName) {
throw new Error(left.toString() + ' has no property .' + right);
}
if (node.val) {
this.ret++;
obj.set(right.name, this.visit(node.val));
this.ret--;
}
return obj.get(right.name);
};
Evaluator.prototype.visitKeyframes = function(keyframes) {
var val;
if (keyframes.fabricated) return keyframes;
keyframes.val = this.interpolate(keyframes).trim();
if ((val = this.lookup(keyframes.val))) {
keyframes.val = val.first.string || val.first.name;
}
keyframes.block = this.visit(keyframes.block);
if ('official' != keyframes.prefix) return keyframes;
this.vendors.forEach(function(prefix) {
if ('ms' == prefix) return;
var node = keyframes.clone();
node.val = keyframes.val;
node.prefix = prefix;
node.block = keyframes.block;
node.fabricated = true;
this.currentBlock.push(node);
}, this);
return nodes.nil;
};
Evaluator.prototype.visitFunction = function(fn) {
var local = this.stack.currentFrame.scope.lookup(fn.name);
if (local)
this.warn(
'local ' +
local.nodeName +
' "' +
fn.name +
'" previously defined in this scope',
);
var user = this.functions[fn.name];
if (user)
this.warn('user-defined function "' + fn.name + '" is already defined');
var bif = bifs[fn.name];
if (bif)
this.warn('built-in function "' + fn.name + '" is already defined');
return fn;
};
Evaluator.prototype.visitEach = function(each) {
this.ret++;
var expr = utils.unwrap(this.visit(each.expr)),
len = expr.nodes.length,
val = new nodes.Ident(each.val),
key = new nodes.Ident(each.key || '__index__'),
scope = this.currentScope,
block = this.currentBlock,
vals = [],
self = this,
body,
obj;
this.ret--;
each.block.scope = false;
function visitBody(key, val) {
scope.add(val);
scope.add(key);
body = self.visit(each.block.clone());
vals = vals.concat(body.nodes);
}
if (1 == len && 'object' == expr.nodes[0].nodeName) {
obj = expr.nodes[0];
for (var prop in obj.vals) {
val.val = new nodes.String(prop);
key.val = obj.get(prop);
visitBody(key, val);
}
} else {
for (var i = 0; i < len; ++i) {
val.val = expr.nodes[i];
key.val = new nodes.Unit(i);
visitBody(key, val);
}
}
this.mixin(vals, block);
return vals[vals.length - 1] || nodes.nil;
};
Evaluator.prototype.visitCall = function(call) {
var fn = this.lookup(call.name),
literal,
ret;
this.ignoreColors = 'url' == call.name;
if (fn && 'expression' == fn.nodeName) {
fn = fn.nodes[0];
}
if (fn && 'function' != fn.nodeName) {
fn = this.lookupFunction(call.name);
}
if (!fn || fn.nodeName != 'function') {
if ('calc' == this.unvendorize(call.name)) {
literal = call.args.nodes && call.args.nodes[0];
if (literal) ret = new nodes.Literal(call.name + literal);
} else {
ret = this.literalCall(call);
}
this.ignoreColors = false;
return ret;
}
this.calling.push(call.name);
if (this.calling.length > 200) {
throw new RangeError('Maximum stylus call stack size exceeded');
}
if ('expression' == fn.nodeName) fn = fn.first;
this.ret++;
var args = this.visit(call.args);
for (var key in args.map) {
args.map[key] = this.visit(args.map[key].clone());
}
this.ret--;
if (fn.fn) {
ret = this.invokeBuiltin(fn.fn, args);
} else if ('function' == fn.nodeName) {
if (call.block) call.block = this.visit(call.block);
ret = this.invokeFunction(fn, args, call.block);
}
this.calling.pop();
this.ignoreColors = false;
return ret;
};
Evaluator.prototype.visitIdent = function(ident) {
var prop;
if (ident.property) {
if ((prop = this.lookupProperty(ident.name))) {
return this.visit(prop.expr.clone());
}
return nodes.nil;
} else if (ident.val.isNull) {
var val = this.lookup(ident.name);
if (val && ident.mixin) this.mixinNode(val);
return val ? this.visit(val) : ident;
} else {
this.ret++;
ident.val = this.visit(ident.val);
this.ret--;
this.currentScope.add(ident);
return ident.val;
}
};
Evaluator.prototype.visitBinOp = function(binop) {
if ('is defined' == binop.op) return this.isDefined(binop.left);
this.ret++;
var op = binop.op,
left = this.visit(binop.left),
right =
'||' == op || '&&' == op ? binop.right : this.visit(binop.right);
var val = binop.val ? this.visit(binop.val) : null;
this.ret--;
try {
return this.visit(left.operate(op, right, val));
} catch (err) {
if ('CoercionError' == err.name) {
switch (op) {
case '==':
return nodes.no;
case '!=':
return nodes.yes;
}
}
throw err;
}
};
Evaluator.prototype.visitUnaryOp = function(unary) {
var op = unary.op,
node = this.visit(unary.expr);
if ('!' != op) {
node = node.first.clone();
utils.assertType(node, 'unit');
}
switch (op) {
case '-':
node.val = -node.val;
break;
case '+':
node.val = +node.val;
break;
case '~':
node.val = ~node.val;
break;
case '!':
return node.toBoolean().negate();
}
return node;
};
Evaluator.prototype.visitTernary = function(ternary) {
var ok = this.visit(ternary.cond).toBoolean();
return ok.isTrue
? this.visit(ternary.trueExpr)
: this.visit(ternary.falseExpr);
};
Evaluator.prototype.visitExpression = function(expr) {
for (var i = 0, len = expr.nodes.length; i < len; ++i) {
expr.nodes[i] = this.visit(expr.nodes[i]);
}
if (this.castable(expr)) expr = this.cast(expr);
return expr;
};
Evaluator.prototype.visitArguments = Evaluator.prototype.visitExpression;
Evaluator.prototype.visitProperty = function(prop) {
var name = this.interpolate(prop),
fn = this.lookup(name),
call = fn && 'function' == fn.first.nodeName,
literal = ~this.calling.indexOf(name),
_prop = this.property;
if (call && !literal && !prop.literal) {
var args = nodes.Arguments.fromExpression(
utils.unwrap(prop.expr.clone()),
);
prop.name = name;
this.property = prop;
this.ret++;
this.property.expr = this.visit(prop.expr);
this.ret--;
var ret = this.visit(new nodes.Call(name, args));
this.property = _prop;
return ret;
} else {
this.ret++;
prop.name = name;
prop.literal = true;
this.property = prop;
prop.expr = this.visit(prop.expr);
this.property = _prop;
this.ret--;
return prop;
}
};
Evaluator.prototype.visitRoot = function(block) {
if (block != this.root) {
block.constructor = nodes.Block;
return this.visit(block);
}
for (var i = 0; i < block.nodes.length; ++i) {
block.index = i;
block.nodes[i] = this.visit(block.nodes[i]);
}
return block;
};
Evaluator.prototype.visitBlock = function(block) {
this.stack.push(new Frame(block));
for (block.index = 0; block.index < block.nodes.length; ++block.index) {
try {
block.nodes[block.index] = this.visit(block.nodes[block.index]);
} catch (err) {
if ('return' == err.nodeName) {
if (this.ret) {
this.stack.pop();
throw err;
} else {
block.nodes[block.index] = err;
break;
}
} else {
throw err;
}
}
}
this.stack.pop();
return block;
};
Evaluator.prototype.visitAtblock = function(atblock) {
atblock.block = this.visit(atblock.block);
return atblock;
};
Evaluator.prototype.visitAtrule = function(atrule) {
atrule.val = this.interpolate(atrule);
if (atrule.block) atrule.block = this.visit(atrule.block);
return atrule;
};
Evaluator.prototype.visitSupports = function(node) {
var condition = node.condition,
val;
this.ret++;
node.condition = this.visit(condition);
this.ret--;
val = condition.first;
if (1 == condition.nodes.length && 'string' == val.nodeName) {
node.condition = val.string;
}
node.block = this.visit(node.block);
return node;
};
Evaluator.prototype.visitIf = function(node) {
var ret,
block = this.currentBlock,
negate = node.negate;
this.ret++;
var ok = this.visit(node.cond).first.toBoolean();
this.ret--;
node.block.scope = node.block.hasMedia;
if (negate) {
if (ok.isFalse) {
ret = this.visit(node.block);
}
} else {
if (ok.isTrue) {
ret = this.visit(node.block);
} else if (node.elses.length) {
var elses = node.elses,
len = elses.length,
cond;
for (var i = 0; i < len; ++i) {
if (elses[i].cond) {
elses[i].block.scope = elses[i].block.hasMedia;
this.ret++;
cond = this.visit(elses[i].cond).first.toBoolean();
this.ret--;
if (cond.isTrue) {
ret = this.visit(elses[i].block);
break;
}
} else {
elses[i].scope = elses[i].hasMedia;
ret = this.visit(elses[i]);
}
}
}
}
if (
ret &&
!node.postfix &&
block.node &&
~['group', 'atrule', 'media', 'supports', 'keyframes'].indexOf(
block.node.nodeName,
)
) {
this.mixin(ret.nodes, block);
return nodes.nil;
}
return ret || nodes.nil;
};
Evaluator.prototype.visitExtend = function(extend) {
var block = this.currentBlock;
if ('group' != block.node.nodeName) block = this.closestGroup;
extend.selectors.forEach(function(selector) {
block.node.extends.push({
selector: this.interpolate(selector.clone()).trim(),
optional: selector.optional,
lineno: selector.lineno,
column: selector.column,
});
}, this);
return nodes.nil;
};
Evaluator.prototype.visitImport = function(imported) {
this.ret++;
var path = this.visit(imported.path).first,
nodeName = imported.once ? 'require' : 'import',
found,
literal;
this.ret--;
if ('url' == path.name) {
if (imported.once) throw new Error('You cannot @require a url');
return imported;
}
if (!path.string) throw new Error('@' + nodeName + ' string expected');
var name = (path = path.string);
if (/(?:url\s*\(\s*)?['"]?(?:#|(?:https?:)?\/\/)/i.test(path)) {
if (imported.once) throw new Error('You cannot @require a url');
return imported;
}
if (/\.css(?:"|$)/.test(path)) {
literal = true;
if (!imported.once && !this.includeCSS) {
return imported;
}
}
if (!literal && !/\.styl$/i.test(path)) path += '.styl';
found = utils.find(path, this.paths, this.filename);
if (!found) {
found = utils.lookupIndex(name, this.paths, this.filename);
}
if (!found)
throw new Error('failed to locate @' + nodeName + ' file ' + path);
var block = new nodes.Block();
for (var i = 0, len = found.length; i < len; ++i) {
block.push(importFile.call(this, imported, found[i], literal));
}
return block;
};
Evaluator.prototype.invokeFunction = function(fn, args, content) {
var block = new nodes.Block(fn.block.parent);
var body = fn.block.clone(block);
var mixinBlock = this.stack.currentFrame.block;
this.stack.push(new Frame(block));
var scope = this.currentScope;
if ('arguments' != args.nodeName) {
var expr = new nodes.Expression();
expr.push(args);
args = nodes.Arguments.fromExpression(expr);
}
scope.add(new nodes.Ident('arguments', args));
scope.add(
new nodes.Ident(
'mixin',
this.ret ? nodes.no : new nodes.String(mixinBlock.nodeName),
),
);
if (this.property) {
var prop = this.propertyExpression(this.property, fn.name);
scope.add(new nodes.Ident('current-property', prop));
} else {
scope.add(new nodes.Ident('current-property', nodes.nil));
}
var expr = new nodes.Expression();
for (var i = this.calling.length - 1; i--; ) {
expr.push(new nodes.Literal(this.calling[i]));
}
scope.add(new nodes.Ident('called-from', expr));
var i = 0,
len = args.nodes.length;
fn.params.nodes.forEach(function(node) {
if (node.rest) {
node.val = new nodes.Expression();
for (; i < len; ++i) node.val.push(args.nodes[i]);
node.val.preserve = true;
node.val.isList = args.isList;
} else {
var arg = args.map[node.name] || args.nodes[i++];
node = node.clone();
if (arg) {
arg.isEmpty
? (args.nodes[i - 1] = this.visit(node))
: (node.val = arg);
} else {
args.push(node.val);
}
if (node.val.isNull) {
throw new Error('argument "' + node + '" required for ' + fn);
}
}
scope.add(node);
}, this);
if (content) scope.add(new nodes.Ident('block', content, true));
return this.invoke(body, true, fn.filename);
};
Evaluator.prototype.invokeBuiltin = function(fn, args) {
if (fn.raw) {
args = args.nodes;
} else {
args = utils.params(fn).reduce(function(ret, param) {
var arg = args.map[param] || args.nodes.shift();
if (arg) {
arg = utils.unwrap(arg);
var len = arg.nodes.length;
if (len > 1) {
for (var i = 0; i < len; ++i) {
ret.push(utils.unwrap(arg.nodes[i].first));
}
} else {
ret.push(arg.first);
}
}
return ret;
}, []);
}
var body = utils.coerce(fn.apply(this, args));
var expr = new nodes.Expression();
expr.push(body);
body = expr;
return this.invoke(body);
};
Evaluator.prototype.invoke = function(body, stack, filename) {
var self = this,
ret;
if (filename) this.paths.push(dirname(filename));
if (this.ret) {
ret = this.eval(body.nodes);
if (stack) this.stack.pop();
} else {
body = this.visit(body);
if (stack) this.stack.pop();
this.mixin(body.nodes, this.currentBlock);
ret = nodes.nil;
}
if (filename) this.paths.pop();
return ret;
};
Evaluator.prototype.mixin = function(nodes, block) {
if (!nodes.length) return;
var len = block.nodes.length,
head = block.nodes.slice(0, block.index),
tail = block.nodes.slice(block.index + 1, len);
this._mixin(nodes, head, block);
block.index = 0;
block.nodes = head.concat(tail);
};
Evaluator.prototype._mixin = function(items, dest, block) {
var node,
len = items.length;
for (var i = 0; i < len; ++i) {
switch ((node = items[i]).nodeName) {
case 'return':
return;
case 'block':
this._mixin(node.nodes, dest, block);
break;
case 'media':
var parentNode = node.block.parent.node;
if (parentNode && 'call' != parentNode.nodeName) {
node.block.parent = block;
}
case 'property':
var val = node.expr;
if (node.literal && 'block' == val.first.name) {
val = utils.unwrap(val);
val.nodes[0] = new nodes.Literal('block');
}
default:
dest.push(node);
}
}
};
Evaluator.prototype.mixinNode = function(node) {
node = this.visit(node.first);
switch (node.nodeName) {
case 'object':
this.mixinObject(node);
return nodes.nil;
case 'block':
case 'atblock':
this.mixin(node.nodes, this.currentBlock);
return nodes.nil;
}
};
Evaluator.prototype.mixinObject = function(object) {
var Parser = require('../parser'),
root = this.root,
str = '$block ' + object.toBlock(),
parser = new Parser(str, utils.merge({ root: block }, this.options)),
block;
try {
block = parser.parse();
} catch (err) {
err.filename = this.filename;
err.lineno = parser.lexer.lineno;
err.column = parser.lexer.column;
err.input = str;
throw err;
}
block.parent = root;
block.scope = false;
var ret = this.visit(block),
vals = ret.first.nodes;
for (var i = 0, len = vals.length; i < len; ++i) {
if (vals[i].block) {
this.mixin(vals[i].block.nodes, this.currentBlock);
break;
}
}
};
Evaluator.prototype.eval = function(vals) {
if (!vals) return nodes.nil;
var len = vals.length,
node = nodes.nil;
try {
for (var i = 0; i < len; ++i) {
node = vals[i];
switch (node.nodeName) {
case 'if':
if ('block' != node.block.nodeName) {
node = this.visit(node);
break;
}
case 'each':
case 'block':
node = this.visit(node);
if (node.nodes) node = this.eval(node.nodes);
break;
default:
node = this.visit(node);
}
}
} catch (err) {
if ('return' == err.nodeName) {
return err.expr;
} else {
throw err;
}
}
return node;
};
Evaluator.prototype.literalCall = function(call) {
call.args = this.visit(call.args);
return call;
};
Evaluator.prototype.lookupProperty = function(name) {
var i = this.stack.length,
index = this.currentBlock.index,
top = i,
nodes,
block,
len,
other;
while (i--) {
block = this.stack[i].block;
if (!block.node) continue;
switch (block.node.nodeName) {
case 'group':
case 'function':
case 'if':
case 'each':
case 'atrule':
case 'media':
case 'atblock':
case 'call':
nodes = block.nodes;
if (i + 1 == top) {
while (index--) {
if (this.property == nodes[index]) continue;
other = this.interpolate(nodes[index]);
if (name == other) return nodes[index].clone();
}
} else {
len = nodes.length;
while (len--) {
if (
'property' != nodes[len].nodeName ||
this.property == nodes[len]
)
continue;
other = this.interpolate(nodes[len]);
if (name == other) return nodes[len].clone();
}
}
break;
}
}
return nodes.nil;
};
Evaluator.prototype.__defineGetter__('closestBlock', function() {
var i = this.stack.length,
block;
while (i--) {
block = this.stack[i].block;
if (block.node) {
switch (block.node.nodeName) {
case 'group':
case 'keyframes':
case 'atrule':
case 'atblock':
case 'media':
case 'call':
return block;
}
}
}
});
Evaluator.prototype.__defineGetter__('closestGroup', function() {
var i = this.stack.length,
block;
while (i--) {
block = this.stack[i].block;
if (block.node && 'group' == block.node.nodeName) {
return block;
}
}
});
Evaluator.prototype.__defineGetter__('selectorStack', function() {
var block,
stack = [];
for (var i = 0, len = this.stack.length; i < len; ++i) {
block = this.stack[i].block;
if (block.node && 'group' == block.node.nodeName) {
block.node.nodes.forEach(function(selector) {
if (!selector.val) selector.val = this.interpolate(selector);
}, this);
stack.push(block.node.nodes);
}
}
return stack;
});
Evaluator.prototype.lookup = function(name) {
var val;
if (this.ignoreColors && name in colors) return;
if ((val = this.stack.lookup(name))) {
return utils.unwrap(val);
} else {
return this.lookupFunction(name);
}
};
Evaluator.prototype.interpolate = function(node) {
var self = this,
isSelector = 'selector' == node.nodeName;
function toString(node) {
switch (node.nodeName) {
case 'function':
case 'ident':
return node.name;
case 'literal':
case 'string':
if (self.prefix && !node.prefixed && !node.val.nodeName) {
node.val = node.val.replace(/\./g, '.' + self.prefix);
node.prefixed = true;
}
return node.val;
case 'unit':
return '%' == node.type ? node.val + '%' : node.val;
case 'member':
return toString(self.visit(node));
case 'expression':
if (
self.calling &&
~self.calling.indexOf('selector') &&
self._selector
)
return self._selector;
self.ret++;
var ret = toString(self.visit(node).first);
self.ret--;
if (isSelector) self._selector = ret;
return ret;
}
}
if (node.segments) {
return node.segments.map(toString).join('');
} else {
return toString(node);
}
};
Evaluator.prototype.lookupFunction = function(name) {
var fn = this.functions[name] || bifs[name];
if (fn) return new nodes.Function(name, fn);
};
Evaluator.prototype.isDefined = function(node) {
if ('ident' == node.nodeName) {
return nodes.Boolean(this.lookup(node.name));
} else {
throw new Error('invalid "is defined" check on non-variable ' + node);
}
};
Evaluator.prototype.propertyExpression = function(prop, name) {
var expr = new nodes.Expression(),
val = prop.expr.clone();
expr.push(new nodes.String(prop.name));
function replace(node) {
if ('call' == node.nodeName && name == node.name) {
return new nodes.Literal('__CALL__');
}
if (node.nodes) node.nodes = node.nodes.map(replace);
return node;
}
replace(val);
expr.push(val);
return expr;
};
Evaluator.prototype.cast = function(expr) {
return new nodes.Unit(expr.first.val, expr.nodes[1].name);
};
Evaluator.prototype.castable = function(expr) {
return (
2 == expr.nodes.length &&
'unit' == expr.first.nodeName &&
~units.indexOf(expr.nodes[1].name)
);
};
Evaluator.prototype.warn = function(msg) {
if (!this.warnings) return;
console.warn('Warning: ' + msg);
};
Evaluator.prototype.__defineGetter__('currentBlock', function() {
return this.stack.currentFrame.block;
});
Evaluator.prototype.__defineGetter__('vendors', function() {
return this.lookup('vendors').nodes.map(function(node) {
return node.string;
});
});
Evaluator.prototype.unvendorize = function(prop) {
for (var i = 0, len = this.vendors.length; i < len; i++) {
if ('official' != this.vendors[i]) {
var vendor = '-' + this.vendors[i] + '-';
if (~prop.indexOf(vendor)) return prop.replace(vendor, '');
}
}
return prop;
};
Evaluator.prototype.__defineGetter__('currentScope', function() {
return this.stack.currentFrame.scope;
});
Evaluator.prototype.__defineGetter__('currentFrame', function() {
return this.stack.currentFrame;
});
});
require.register('visitor/normalizer.js', function(module, exports, require) {
var Visitor = require('./index'),
nodes = require('../nodes/index'),
utils = require('../utils');
var Normalizer = (module.exports = function Normalizer(root, options) {
options = options || {};
Visitor.call(this, root);
this.hoist = options['hoist atrules'];
this.stack = [];
this.map = {};
this.imports = [];
});
Normalizer.prototype.__proto__ = Visitor.prototype;
Normalizer.prototype.normalize = function() {
var ret = this.visit(this.root);
if (this.hoist) {
if (this.imports.length) ret.nodes = this.imports.concat(ret.nodes);
if (this.charset) ret.nodes = [this.charset].concat(ret.nodes);
}
return ret;
};
Normalizer.prototype.bubble = function(node) {
var props = [],
other = [],
self = this;
function filterProps(block) {
block.nodes.forEach(function(node) {
node = self.visit(node);
switch (node.nodeName) {
case 'property':
props.push(node);
break;
case 'block':
filterProps(node);
break;
default:
other.push(node);
}
});
}
filterProps(node.block);
if (props.length) {
var selector = new nodes.Selector([new nodes.Literal('&')]);
selector.lineno = node.lineno;
selector.column = node.column;
selector.filename = node.filename;
selector.val = '&';
var group = new nodes.Group();
group.lineno = node.lineno;
group.column = node.column;
group.filename = node.filename;
var block = new nodes.Block(node.block, group);
block.lineno = node.lineno;
block.column = node.column;
block.filename = node.filename;
props.forEach(function(prop) {
block.push(prop);
});
group.push(selector);
group.block = block;
node.block.nodes = [];
node.block.push(group);
other.forEach(function(n) {
node.block.push(n);
});
var group = this.closestGroup(node.block);
if (group) node.group = group.clone();
node.bubbled = true;
}
};
Normalizer.prototype.closestGroup = function(block) {
var parent = block.parent,
node;
while (parent && (node = parent.node)) {
if ('group' == node.nodeName) return node;
parent = node.block && node.block.parent;
}
};
Normalizer.prototype.visitRoot = function(block) {
var ret = new nodes.Root(),
node;
for (var i = 0; i < block.nodes.length; ++i) {
node = block.nodes[i];
switch (node.nodeName) {
case 'null':
case 'expression':
case 'function':
case 'unit':
case 'atblock':
continue;
default:
this.rootIndex = i;
ret.push(this.visit(node));
}
}
return ret;
};
Normalizer.prototype.visitProperty = function(prop) {
this.visit(prop.expr);
return prop;
};
Normalizer.prototype.visitExpression = function(expr) {
expr.nodes = expr.nodes.map(function(node) {
if ('block' == node.nodeName) {
var literal = new nodes.Literal('block');
literal.lineno = expr.lineno;
literal.column = expr.column;
return literal;
}
return node;
});
return expr;
};
Normalizer.prototype.visitBlock = function(block) {
var node;
if (block.hasProperties) {
for (var i = 0, len = block.nodes.length; i < len; ++i) {
node = block.nodes[i];
switch (node.nodeName) {
case 'null':
case 'expression':
case 'function':
case 'group':
case 'unit':
case 'atblock':
continue;
default:
block.nodes[i] = this.visit(node);
}
}
}
for (var i = 0, len = block.nodes.length; i < len; ++i) {
node = block.nodes[i];
block.nodes[i] = this.visit(node);
}
return block;
};
Normalizer.prototype.visitGroup = function(group) {
var stack = this.stack,
map = this.map,
parts;
group.nodes.forEach(function(selector, i) {
if (!~selector.val.indexOf(',')) return;
if (~selector.val.indexOf('\\,')) {
selector.val = selector.val.replace(/\\,/g, ',');
return;
}
parts = selector.val.split(',');
var root = '/' == selector.val.charAt(0),
part,
s;
for (var k = 0, len = parts.length; k < len; ++k) {
part = parts[k].trim();
if (root && k > 0 && !~part.indexOf('&')) {
part = '/' + part;
}
s = new nodes.Selector([new nodes.Literal(part)]);
s.val = part;
s.block = group.block;
group.nodes[i++] = s;
}
});
stack.push(group.nodes);
var selectors = utils.compileSelectors(stack, true);
selectors.forEach(function(selector) {
map[selector] = map[selector] || [];
map[selector].push(group);
});
this.extend(group, selectors);
stack.pop();
return group;
};
Normalizer.prototype.visitFunction = function() {
return nodes.nil;
};
Normalizer.prototype.visitMedia = function(media) {
var medias = [],
group = this.closestGroup(media.block),
parent;
function mergeQueries(block) {
block.nodes.forEach(function(node, i) {
switch (node.nodeName) {
case 'media':
node.val = media.val.merge(node.val);
medias.push(node);
block.nodes[i] = nodes.nil;
break;
case 'block':
mergeQueries(node);
break;
default:
if (node.block && node.block.nodes) mergeQueries(node.block);
}
});
}
mergeQueries(media.block);
this.bubble(media);
if (medias.length) {
medias.forEach(function(node) {
if (group) {
group.block.push(node);
} else {
this.root.nodes.splice(++this.rootIndex, 0, node);
}
node = this.visit(node);
parent = node.block.parent;
if (node.bubbled && (!group || 'group' == parent.node.nodeName)) {
node.group.block = node.block.nodes[0].block;
node.block.nodes[0] = node.group;
}
}, this);
}
return media;
};
Normalizer.prototype.visitSupports = function(node) {
this.bubble(node);
return node;
};
Normalizer.prototype.visitAtrule = function(node) {
if (node.block) node.block = this.visit(node.block);
return node;
};
Normalizer.prototype.visitKeyframes = function(node) {
var frames = node.block.nodes.filter(function(frame) {
return frame.block && frame.block.hasProperties;
});
node.frames = frames.length;
return node;
};
Normalizer.prototype.visitImport = function(node) {
this.imports.push(node);
return this.hoist ? nodes.nil : node;
};
Normalizer.prototype.visitCharset = function(node) {
this.charset = node;
return this.hoist ? nodes.nil : node;
};
Normalizer.prototype.extend = function(group, selectors) {
var map = this.map,
self = this,
parent = this.closestGroup(group.block);
group.extends.forEach(function(extend) {
var groups = map[extend.selector];
if (!groups) {
if (extend.optional) return;
var err = new Error('Failed to @extend "' + extend.selector + '"');
err.lineno = extend.lineno;
err.column = extend.column;
throw err;
}
selectors.forEach(function(selector) {
var node = new nodes.Selector();
node.val = selector;
node.inherits = false;
groups.forEach(function(group) {
if (!parent || parent != group) self.extend(group, selectors);
group.push(node);
});
});
});
group.block = this.visit(group.block);
};
});
return require('stylus');
})();