8164 lines
258 KiB
JavaScript
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(
|
||
'[90minspect:[0m %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 +
|
||
' ' +
|
||
'[32m' +
|
||
this.type +
|
||
'[0m' +
|
||
'[33m' +
|
||
(this.val ? val : '') +
|
||
'[0m' +
|
||
']'
|
||
);
|
||
};
|
||
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('[33mWarning:[0m ' + 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');
|
||
})();
|