mirror of
https://github.com/less/less.js.git
synced 2026-02-08 22:15:04 -05:00
add browserify (not yet working) and refactor tree nodes to not be dependent on their parent (currently breaks browser build)
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
tree.colors = {
|
||||
'aliceblue':'#f0f8ff',
|
||||
'antiquewhite':'#faebd7',
|
||||
@@ -148,4 +148,4 @@
|
||||
'yellow':'#ffff00',
|
||||
'yellowgreen':'#9acd32'
|
||||
};
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
// base64 encoder implementation for node
|
||||
exports.encodeBase64 = function(str) {
|
||||
return new Buffer(str).toString('base64');
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
var parseCopyProperties = [
|
||||
'paths', // option - unmodified - paths to search for imports on
|
||||
@@ -132,4 +132,4 @@
|
||||
}
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
@@ -8,6 +8,9 @@ module.exports = {
|
||||
warn: function(env, msg) {
|
||||
console.warn(msg);
|
||||
},
|
||||
encodeBase64: function encodeBase64(env, str) {
|
||||
return new Buffer(str).toString('base64');
|
||||
},
|
||||
getPath: function (env, filename) {
|
||||
var j = filename.lastIndexOf('/');
|
||||
if (j < 0) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
/*jshint loopfunc:true */
|
||||
|
||||
tree.extendFinderVisitor = function() {
|
||||
@@ -413,4 +413,4 @@
|
||||
}
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (tree) {
|
||||
module.exports = function (less, tree) {
|
||||
|
||||
tree.functions = {
|
||||
var functions = {
|
||||
rgb: function (r, g, b) {
|
||||
return this.rgba(r, g, b, 1.0);
|
||||
},
|
||||
@@ -530,7 +530,7 @@ tree.functions = {
|
||||
|
||||
if (useBase64) {
|
||||
try {
|
||||
returner = require('./encoder').encodeBase64(returner); // TODO browser implementation
|
||||
returner = less.Parser.environment.encodeBase64(this.env, returner);
|
||||
} catch(e) {
|
||||
useBase64 = false;
|
||||
}
|
||||
@@ -687,30 +687,30 @@ tree.defaultFunc = {
|
||||
};
|
||||
|
||||
function initFunctions() {
|
||||
var f, tf = tree.functions;
|
||||
var f;
|
||||
|
||||
// math
|
||||
for (f in mathFunctions) {
|
||||
if (mathFunctions.hasOwnProperty(f)) {
|
||||
tf[f] = _math.bind(null, Math[f], mathFunctions[f]);
|
||||
functions[f] = _math.bind(null, Math[f], mathFunctions[f]);
|
||||
}
|
||||
}
|
||||
|
||||
// color blending
|
||||
for (f in colorBlendMode) {
|
||||
if (colorBlendMode.hasOwnProperty(f)) {
|
||||
tf[f] = colorBlend.bind(null, colorBlendMode[f]);
|
||||
functions[f] = colorBlend.bind(null, colorBlendMode[f]);
|
||||
}
|
||||
}
|
||||
|
||||
// default
|
||||
f = tree.defaultFunc;
|
||||
tf["default"] = f.eval.bind(f);
|
||||
functions["default"] = f.eval.bind(f);
|
||||
|
||||
} initFunctions();
|
||||
|
||||
function hsla(color) {
|
||||
return tree.functions.hsla(color.h, color.s, color.l, color.a);
|
||||
return functions.hsla(color.h, color.s, color.l, color.a);
|
||||
}
|
||||
|
||||
function scaled(n, size) {
|
||||
@@ -748,11 +748,14 @@ tree.fround = function(env, value) {
|
||||
}
|
||||
};
|
||||
|
||||
tree.functionCall = function(env, currentFileInfo) {
|
||||
tree.functionCall = function(env, currentFileInfo, environment) {
|
||||
this.env = env;
|
||||
this.environment = environment;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
};
|
||||
|
||||
tree.functionCall.prototype = tree.functions;
|
||||
tree.functionCall.prototype = functions;
|
||||
|
||||
})(require('./tree'));
|
||||
return functions;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
tree.importVisitor = function(importer, finish, evalEnv) {
|
||||
this._visitor = new tree.visitor(this);
|
||||
this._importer = importer;
|
||||
@@ -115,4 +115,4 @@
|
||||
}
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
@@ -1,137 +1,95 @@
|
||||
var less = {
|
||||
version: [1, 6, 3],
|
||||
Parser: require('./parser').Parser,
|
||||
tree: require('./tree'),
|
||||
render: function (input, options, callback) {
|
||||
options = options || {};
|
||||
var less = require("./non-node-index.js");
|
||||
|
||||
if (typeof(options) === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
less.render = function (input, options, callback) {
|
||||
options = options || {};
|
||||
|
||||
var parser = new(less.Parser)(options),
|
||||
ee;
|
||||
|
||||
if (callback) {
|
||||
parser.parse(input, function (e, root) {
|
||||
if (e) { callback(e); return; }
|
||||
var css;
|
||||
try {
|
||||
css = root && root.toCSS && root.toCSS(options);
|
||||
}
|
||||
catch (err) { callback(err); return; }
|
||||
callback(null, css);
|
||||
});
|
||||
} else {
|
||||
ee = new (require('events').EventEmitter)();
|
||||
|
||||
process.nextTick(function () {
|
||||
parser.parse(input, function (e, root) {
|
||||
if (e) { return ee.emit('error', e); }
|
||||
try { ee.emit('success', root.toCSS(options)); }
|
||||
catch (err) { ee.emit('error', err); }
|
||||
});
|
||||
});
|
||||
return ee;
|
||||
}
|
||||
},
|
||||
formatError: function(ctx, options) {
|
||||
options = options || {};
|
||||
|
||||
var message = "";
|
||||
var extract = ctx.extract;
|
||||
var error = [];
|
||||
var stylize = options.color ? require('./lessc_helper').stylize : function (str) { return str; };
|
||||
|
||||
// only output a stack if it isn't a less error
|
||||
if (ctx.stack && !ctx.type) { return stylize(ctx.stack, 'red'); }
|
||||
|
||||
if (!ctx.hasOwnProperty('index') || !extract) {
|
||||
return ctx.stack || ctx.message;
|
||||
}
|
||||
|
||||
if (typeof(extract[0]) === 'string') {
|
||||
error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
|
||||
}
|
||||
|
||||
if (typeof(extract[1]) === 'string') {
|
||||
var errorTxt = ctx.line + ' ';
|
||||
if (extract[1]) {
|
||||
errorTxt += extract[1].slice(0, ctx.column) +
|
||||
stylize(stylize(stylize(extract[1][ctx.column], 'bold') +
|
||||
extract[1].slice(ctx.column + 1), 'red'), 'inverse');
|
||||
}
|
||||
error.push(errorTxt);
|
||||
}
|
||||
|
||||
if (typeof(extract[2]) === 'string') {
|
||||
error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
|
||||
}
|
||||
error = error.join('\n') + stylize('', 'reset') + '\n';
|
||||
|
||||
message += stylize(ctx.type + 'Error: ' + ctx.message, 'red');
|
||||
if (ctx.filename) {
|
||||
message += stylize(' in ', 'red') + ctx.filename +
|
||||
stylize(' on line ' + ctx.line + ', column ' + (ctx.column + 1) + ':', 'grey');
|
||||
}
|
||||
|
||||
message += '\n' + error;
|
||||
|
||||
if (ctx.callLine) {
|
||||
message += stylize('from ', 'red') + (ctx.filename || '') + '/n';
|
||||
message += stylize(ctx.callLine, 'grey') + ' ' + ctx.callExtract + '/n';
|
||||
}
|
||||
|
||||
return message;
|
||||
},
|
||||
writeError: function (ctx, options) {
|
||||
options = options || {};
|
||||
if (options.silent) { return; }
|
||||
console.error(less.formatError(ctx, options));
|
||||
if (typeof(options) === 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
var parser = new(less.Parser)(options),
|
||||
ee;
|
||||
|
||||
if (callback) {
|
||||
parser.parse(input, function (e, root) {
|
||||
if (e) { callback(e); return; }
|
||||
var css;
|
||||
try {
|
||||
css = root && root.toCSS && root.toCSS(options);
|
||||
}
|
||||
catch (err) { callback(err); return; }
|
||||
callback(null, css);
|
||||
});
|
||||
} else {
|
||||
ee = new (require('events').EventEmitter)();
|
||||
|
||||
process.nextTick(function () {
|
||||
parser.parse(input, function (e, root) {
|
||||
if (e) { return ee.emit('error', e); }
|
||||
try { ee.emit('success', root.toCSS(options)); }
|
||||
catch (err) { ee.emit('error', err); }
|
||||
});
|
||||
});
|
||||
return ee;
|
||||
}
|
||||
};
|
||||
less.formatError = function(ctx, options) {
|
||||
options = options || {};
|
||||
|
||||
var message = "";
|
||||
var extract = ctx.extract;
|
||||
var error = [];
|
||||
var stylize = options.color ? require('./lessc_helper').stylize : function (str) { return str; };
|
||||
|
||||
// only output a stack if it isn't a less error
|
||||
if (ctx.stack && !ctx.type) { return stylize(ctx.stack, 'red'); }
|
||||
|
||||
if (!ctx.hasOwnProperty('index') || !extract) {
|
||||
return ctx.stack || ctx.message;
|
||||
}
|
||||
|
||||
if (typeof(extract[0]) === 'string') {
|
||||
error.push(stylize((ctx.line - 1) + ' ' + extract[0], 'grey'));
|
||||
}
|
||||
|
||||
if (typeof(extract[1]) === 'string') {
|
||||
var errorTxt = ctx.line + ' ';
|
||||
if (extract[1]) {
|
||||
errorTxt += extract[1].slice(0, ctx.column) +
|
||||
stylize(stylize(stylize(extract[1][ctx.column], 'bold') +
|
||||
extract[1].slice(ctx.column + 1), 'red'), 'inverse');
|
||||
}
|
||||
error.push(errorTxt);
|
||||
}
|
||||
|
||||
if (typeof(extract[2]) === 'string') {
|
||||
error.push(stylize((ctx.line + 1) + ' ' + extract[2], 'grey'));
|
||||
}
|
||||
error = error.join('\n') + stylize('', 'reset') + '\n';
|
||||
|
||||
message += stylize(ctx.type + 'Error: ' + ctx.message, 'red');
|
||||
if (ctx.filename) {
|
||||
message += stylize(' in ', 'red') + ctx.filename +
|
||||
stylize(' on line ' + ctx.line + ', column ' + (ctx.column + 1) + ':', 'grey');
|
||||
}
|
||||
|
||||
message += '\n' + error;
|
||||
|
||||
if (ctx.callLine) {
|
||||
message += stylize('from ', 'red') + (ctx.filename || '') + '/n';
|
||||
message += stylize(ctx.callLine, 'grey') + ' ' + ctx.callExtract + '/n';
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
less.writeError = function (ctx, options) {
|
||||
options = options || {};
|
||||
if (options.silent) { return; }
|
||||
console.error(less.formatError(ctx, options));
|
||||
};
|
||||
|
||||
less.Parser.environment = require("./environments/node");
|
||||
|
||||
require('./tree/color');
|
||||
require('./tree/directive');
|
||||
require('./tree/detached-ruleset');
|
||||
require('./tree/operation');
|
||||
require('./tree/dimension');
|
||||
require('./tree/keyword');
|
||||
require('./tree/variable');
|
||||
require('./tree/ruleset');
|
||||
require('./tree/element');
|
||||
require('./tree/selector');
|
||||
require('./tree/quoted');
|
||||
require('./tree/expression');
|
||||
require('./tree/rule');
|
||||
require('./tree/call');
|
||||
require('./tree/url');
|
||||
require('./tree/alpha');
|
||||
require('./tree/import');
|
||||
require('./tree/mixin');
|
||||
require('./tree/comment');
|
||||
require('./tree/anonymous');
|
||||
require('./tree/value');
|
||||
require('./tree/javascript');
|
||||
require('./tree/assignment');
|
||||
require('./tree/condition');
|
||||
require('./tree/paren');
|
||||
require('./tree/media');
|
||||
require('./tree/unicode-descriptor');
|
||||
require('./tree/negative');
|
||||
require('./tree/extend');
|
||||
require('./tree/ruleset-call');
|
||||
require('./env');
|
||||
require('./functions');
|
||||
require('./colors');
|
||||
require('./visitor.js');
|
||||
require('./import-visitor.js');
|
||||
require('./extend-visitor.js');
|
||||
require('./join-selector-visitor.js');
|
||||
require('./to-css-visitor.js');
|
||||
require('./source-map-output.js');
|
||||
|
||||
module.exports = less;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
tree.joinSelectorVisitor = function() {
|
||||
this.contexts = [[]];
|
||||
this._visitor = new tree.visitor(this);
|
||||
@@ -41,4 +41,4 @@
|
||||
}
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
18
lib/less/non-node-index.js
Normal file
18
lib/less/non-node-index.js
Normal file
@@ -0,0 +1,18 @@
|
||||
var less = {
|
||||
version: [1, 6, 3]
|
||||
};
|
||||
|
||||
less.tree = (require('./tree'))(less);
|
||||
less.Parser = (require('./parser'))(less, less.tree);
|
||||
less.tree.functions = (require('./functions'))(less, less.tree);
|
||||
require('./env')(less.tree);
|
||||
|
||||
require('./colors')(less.tree);
|
||||
require('./visitor.js')(less.tree);
|
||||
require('./import-visitor.js')(less.tree);
|
||||
require('./extend-visitor.js')(less.tree);
|
||||
require('./join-selector-visitor.js')(less.tree);
|
||||
require('./to-css-visitor.js')(less.tree);
|
||||
require('./source-map-output.js')(less.tree);
|
||||
|
||||
module.exports = less;
|
||||
@@ -1,11 +1,4 @@
|
||||
var less, tree;
|
||||
|
||||
// Node.js does not have a header file added which defines less
|
||||
if (less === undefined) {
|
||||
less = exports;
|
||||
tree = require('./tree');
|
||||
less.mode = 'node';
|
||||
}
|
||||
module.exports = function(less, tree) {
|
||||
//
|
||||
// less.js - parser
|
||||
//
|
||||
@@ -39,7 +32,7 @@ if (less === undefined) {
|
||||
// It also takes care of moving all the indices forwards.
|
||||
//
|
||||
//
|
||||
less.Parser = function Parser(env) {
|
||||
var Parser = function Parser(env) {
|
||||
var input, // LeSS input string
|
||||
i, // current index in `input`
|
||||
j, // current chunk
|
||||
@@ -2064,16 +2057,19 @@ less.Parser = function Parser(env) {
|
||||
};
|
||||
return parser;
|
||||
};
|
||||
less.Parser.serializeVars = function(vars) {
|
||||
Parser.serializeVars = function(vars) {
|
||||
var s = '';
|
||||
|
||||
for (var name in vars) {
|
||||
if (Object.hasOwnProperty.call(vars, name)) {
|
||||
var value = vars[name];
|
||||
s += ((name[0] === '@') ? '' : '@') + name +': '+ value +
|
||||
((('' + value).slice(-1) === ';') ? '' : ';');
|
||||
((('' + value).slice(-1) === ';') ? '' : ';');
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
return Parser;
|
||||
};
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.sourceMapOutput = function (options) {
|
||||
this._css = [];
|
||||
@@ -138,4 +138,4 @@
|
||||
return this._css.join('');
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
tree.toCSSVisitor = function(env) {
|
||||
this._visitor = new tree.visitor(this);
|
||||
this._env = env;
|
||||
@@ -236,5 +236,4 @@
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
(function (tree) {
|
||||
module.exports = function (less) {
|
||||
|
||||
var tree = {};
|
||||
|
||||
tree.debugInfo = function(env, ctx, lineSeperator) {
|
||||
var result="";
|
||||
if (env.dumpLineNumbers && !env.compress) {
|
||||
@@ -94,4 +96,43 @@ tree.outputRuleset = function (env, output, rules) {
|
||||
env.tabLevel--;
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
tree.Alpha = require('./tree/alpha')(tree);
|
||||
tree.Color = require('./tree/color')(tree);
|
||||
tree.Directive = require('./tree/directive')(tree);
|
||||
tree.DetachedRuleset = require('./tree/detached-ruleset')(tree);
|
||||
tree.Operation = require('./tree/operation')(tree);
|
||||
tree.Dimension = require('./tree/dimension')(tree, require('./tree/unit-conversions')); //todo move conversions
|
||||
tree.Unit = require('./tree/unit')(tree, require('./tree/unit-conversions'));
|
||||
tree.Keyword = require('./tree/keyword')(tree);
|
||||
tree.Variable = require('./tree/variable')(tree);
|
||||
tree.Ruleset = require('./tree/ruleset')(tree);
|
||||
tree.Element = require('./tree/element')(tree);
|
||||
tree.Attribute = require('./tree/attribute')(tree);
|
||||
tree.Combinator = require('./tree/combinator')(tree);
|
||||
tree.Selector = require('./tree/selector')(tree);
|
||||
tree.Quoted = require('./tree/quoted')(tree);
|
||||
tree.Expression = require('./tree/expression')(tree);
|
||||
tree.Rule = require('./tree/rule')(tree);
|
||||
tree.Call = require('./tree/call')(tree);
|
||||
tree.URL = require('./tree/url')(tree);
|
||||
tree.Import = require('./tree/import')(tree);
|
||||
tree.mixin = {
|
||||
Call: require('./tree/mixin-call')(tree),
|
||||
Definition: require('./tree/mixin-definition')(tree)
|
||||
};
|
||||
tree.Comment = require('./tree/comment')(tree);
|
||||
tree.Anonymous = require('./tree/anonymous')(tree);
|
||||
tree.Value = require('./tree/value')(tree);
|
||||
tree.JavaScript = require('./tree/javascript')(tree);
|
||||
tree.Assignment = require('./tree/assignment')(tree);
|
||||
tree.Condition = require('./tree/condition')(tree);
|
||||
tree.Paren = require('./tree/paren')(tree);
|
||||
tree.Media = require('./tree/media')(tree);
|
||||
tree.UnicodeDescriptor = require('./tree/unicode-descriptor')(tree);
|
||||
tree.Negative = require('./tree/negative')(tree);
|
||||
tree.Extend = require('./tree/extend')(tree);
|
||||
tree.RulesetCall = require('./tree/ruleset-call')(tree);
|
||||
|
||||
return tree;
|
||||
|
||||
};
|
||||
@@ -1,15 +1,15 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Alpha = function (val) {
|
||||
var Alpha = function (val) {
|
||||
this.value = val;
|
||||
};
|
||||
tree.Alpha.prototype = {
|
||||
Alpha.prototype = {
|
||||
type: "Alpha",
|
||||
accept: function (visitor) {
|
||||
this.value = visitor.visit(this.value);
|
||||
},
|
||||
eval: function (env) {
|
||||
if (this.value.eval) { return new tree.Alpha(this.value.eval(env)); }
|
||||
if (this.value.eval) { return new Alpha(this.value.eval(env)); }
|
||||
return this;
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
@@ -25,5 +25,5 @@ tree.Alpha.prototype = {
|
||||
},
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Alpha;
|
||||
};
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Anonymous = function (string, index, currentFileInfo, mapLines) {
|
||||
var Anonymous = function (string, index, currentFileInfo, mapLines) {
|
||||
this.value = string.value || string;
|
||||
this.index = index;
|
||||
this.mapLines = mapLines;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
};
|
||||
tree.Anonymous.prototype = {
|
||||
Anonymous.prototype = {
|
||||
type: "Anonymous",
|
||||
eval: function () {
|
||||
return new tree.Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines);
|
||||
return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines);
|
||||
},
|
||||
compare: function (x) {
|
||||
if (!x.toCSS) {
|
||||
@@ -30,5 +30,5 @@ tree.Anonymous.prototype = {
|
||||
},
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Anonymous;
|
||||
};
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Assignment = function (key, val) {
|
||||
var Assignment = function (key, val) {
|
||||
this.key = key;
|
||||
this.value = val;
|
||||
};
|
||||
tree.Assignment.prototype = {
|
||||
Assignment.prototype = {
|
||||
type: "Assignment",
|
||||
accept: function (visitor) {
|
||||
this.value = visitor.visit(this.value);
|
||||
},
|
||||
eval: function (env) {
|
||||
if (this.value.eval) {
|
||||
return new(tree.Assignment)(this.key, this.value.eval(env));
|
||||
return new(Assignment)(this.key, this.value.eval(env));
|
||||
}
|
||||
return this;
|
||||
},
|
||||
@@ -25,5 +25,5 @@ tree.Assignment.prototype = {
|
||||
},
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Assignment;
|
||||
};
|
||||
|
||||
29
lib/less/tree/attribute.js
Normal file
29
lib/less/tree/attribute.js
Normal file
@@ -0,0 +1,29 @@
|
||||
module.exports = function (tree) {
|
||||
|
||||
var Attribute = function (key, op, value) {
|
||||
this.key = key;
|
||||
this.op = op;
|
||||
this.value = value;
|
||||
};
|
||||
Attribute.prototype = {
|
||||
type: "Attribute",
|
||||
eval: function (env) {
|
||||
return new(Attribute)(this.key.eval ? this.key.eval(env) : this.key,
|
||||
this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value);
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
output.add(this.toCSS(env));
|
||||
},
|
||||
toCSS: function (env) {
|
||||
var value = this.key.toCSS ? this.key.toCSS(env) : this.key;
|
||||
|
||||
if (this.op) {
|
||||
value += this.op;
|
||||
value += (this.value.toCSS ? this.value.toCSS(env) : this.value);
|
||||
}
|
||||
|
||||
return '[' + value + ']';
|
||||
}
|
||||
};
|
||||
return Attribute;
|
||||
};
|
||||
@@ -1,15 +1,15 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
//
|
||||
// A function call node.
|
||||
//
|
||||
tree.Call = function (name, args, index, currentFileInfo) {
|
||||
var Call = function (name, args, index, currentFileInfo) {
|
||||
this.name = name;
|
||||
this.args = args;
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
};
|
||||
tree.Call.prototype = {
|
||||
Call.prototype = {
|
||||
type: "Call",
|
||||
accept: function (visitor) {
|
||||
if (this.args) {
|
||||
@@ -49,7 +49,7 @@ tree.Call.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
return new tree.Call(this.name, args, this.index, this.currentFileInfo);
|
||||
return new Call(this.name, args, this.index, this.currentFileInfo);
|
||||
},
|
||||
|
||||
genCSS: function (env, output) {
|
||||
@@ -67,5 +67,5 @@ tree.Call.prototype = {
|
||||
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Call;
|
||||
};
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
//
|
||||
// RGB Colors - #ff0014, #eee
|
||||
//
|
||||
tree.Color = function (rgb, a) {
|
||||
var Color = function (rgb, a) {
|
||||
//
|
||||
// The end goal here, is to parse the arguments
|
||||
// into an integer triplet, such as `128, 255, 0`
|
||||
@@ -23,7 +23,7 @@ tree.Color = function (rgb, a) {
|
||||
this.alpha = typeof(a) === 'number' ? a : 1;
|
||||
};
|
||||
|
||||
tree.Color.prototype = {
|
||||
Color.prototype = {
|
||||
type: "Color",
|
||||
eval: function () { return this; },
|
||||
luma: function () { return (0.2126 * this.rgb[0] / 255) + (0.7152 * this.rgb[1] / 255) + (0.0722 * this.rgb[2] / 255); },
|
||||
@@ -79,7 +79,7 @@ tree.Color.prototype = {
|
||||
for (var c = 0; c < 3; c++) {
|
||||
rgb[c] = tree.operate(env, op, this.rgb[c], other.rgb[c]);
|
||||
}
|
||||
return new(tree.Color)(rgb, alpha);
|
||||
return new(Color)(rgb, alpha);
|
||||
},
|
||||
|
||||
toRGB: function () {
|
||||
@@ -153,13 +153,13 @@ tree.Color.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
tree.Color.fromKeyword = function(keyword) {
|
||||
Color.fromKeyword = function(keyword) {
|
||||
var c, key = keyword.toLowerCase();
|
||||
if (tree.colors.hasOwnProperty(key)) {
|
||||
c = new(tree.Color)(tree.colors[key].slice(1));
|
||||
c = new(Color)(tree.colors[key].slice(1));
|
||||
}
|
||||
else if (key === "transparent") {
|
||||
c = new(tree.Color)([0, 0, 0], 0);
|
||||
c = new(Color)([0, 0, 0], 0);
|
||||
}
|
||||
|
||||
if (c) {
|
||||
@@ -178,5 +178,5 @@ function toHex(v) {
|
||||
function clamp(v, max) {
|
||||
return Math.min(Math.max(v, 0), max);
|
||||
}
|
||||
|
||||
})(require('../tree'));
|
||||
return Color;
|
||||
};
|
||||
|
||||
40
lib/less/tree/combinator.js
Normal file
40
lib/less/tree/combinator.js
Normal file
@@ -0,0 +1,40 @@
|
||||
module.exports = function (tree) {
|
||||
|
||||
var Combinator = function (value) {
|
||||
if (value === ' ') {
|
||||
this.value = ' ';
|
||||
} else {
|
||||
this.value = value ? value.trim() : "";
|
||||
}
|
||||
};
|
||||
Combinator.prototype = {
|
||||
type: "Combinator",
|
||||
_outputMap: {
|
||||
'' : '',
|
||||
' ' : ' ',
|
||||
':' : ' :',
|
||||
'+' : ' + ',
|
||||
'~' : ' ~ ',
|
||||
'>' : ' > ',
|
||||
'|' : '|',
|
||||
'^' : ' ^ ',
|
||||
'^^' : ' ^^ '
|
||||
},
|
||||
_outputMapCompressed: {
|
||||
'' : '',
|
||||
' ' : ' ',
|
||||
':' : ' :',
|
||||
'+' : '+',
|
||||
'~' : '~',
|
||||
'>' : '>',
|
||||
'|' : '|',
|
||||
'^' : '^',
|
||||
'^^' : '^^'
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]);
|
||||
},
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
return Combinator;
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Comment = function (value, silent, index, currentFileInfo) {
|
||||
var Comment = function (value, silent, index, currentFileInfo) {
|
||||
this.value = value;
|
||||
this.silent = !!silent;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
};
|
||||
tree.Comment.prototype = {
|
||||
Comment.prototype = {
|
||||
type: "Comment",
|
||||
genCSS: function (env, output) {
|
||||
if (this.debugInfo) {
|
||||
@@ -24,5 +24,5 @@ tree.Comment.prototype = {
|
||||
this.isReferenced = true;
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Comment;
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Condition = function (op, l, r, i, negate) {
|
||||
var Condition = function (op, l, r, i, negate) {
|
||||
this.op = op.trim();
|
||||
this.lvalue = l;
|
||||
this.rvalue = r;
|
||||
this.index = i;
|
||||
this.negate = negate;
|
||||
};
|
||||
tree.Condition.prototype = {
|
||||
Condition.prototype = {
|
||||
type: "Condition",
|
||||
accept: function (visitor) {
|
||||
this.lvalue = visitor.visit(this.lvalue);
|
||||
@@ -45,5 +45,5 @@ tree.Condition.prototype = {
|
||||
return this.negate ? !result : result;
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Condition;
|
||||
};
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.DetachedRuleset = function (ruleset, frames) {
|
||||
var DetachedRuleset = function (ruleset, frames) {
|
||||
this.ruleset = ruleset;
|
||||
this.frames = frames;
|
||||
};
|
||||
tree.DetachedRuleset.prototype = {
|
||||
DetachedRuleset.prototype = {
|
||||
type: "DetachedRuleset",
|
||||
accept: function (visitor) {
|
||||
this.ruleset = visitor.visit(this.ruleset);
|
||||
},
|
||||
eval: function (env) {
|
||||
var frames = this.frames || env.frames.slice(0);
|
||||
return new tree.DetachedRuleset(this.ruleset, frames);
|
||||
return new DetachedRuleset(this.ruleset, frames);
|
||||
},
|
||||
callEval: function (env) {
|
||||
return this.ruleset.eval(this.frames ? new(tree.evalEnv)(env, this.frames.concat(env.frames)) : env);
|
||||
}
|
||||
};
|
||||
})(require('../tree'));
|
||||
return DetachedRuleset;
|
||||
};
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree, unitConversions) {
|
||||
|
||||
//
|
||||
// A number with a unit
|
||||
//
|
||||
tree.Dimension = function (value, unit) {
|
||||
var Dimension = function (value, unit) {
|
||||
this.value = parseFloat(value);
|
||||
this.unit = (unit && unit instanceof tree.Unit) ? unit :
|
||||
new(tree.Unit)(unit ? [unit] : undefined);
|
||||
};
|
||||
|
||||
tree.Dimension.prototype = {
|
||||
Dimension.prototype = {
|
||||
type: "Dimension",
|
||||
accept: function (visitor) {
|
||||
this.unit = visitor.visit(this.unit);
|
||||
@@ -84,11 +84,11 @@ tree.Dimension.prototype = {
|
||||
unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
|
||||
unit.cancel();
|
||||
}
|
||||
return new(tree.Dimension)(value, unit);
|
||||
return new(Dimension)(value, unit);
|
||||
},
|
||||
|
||||
compare: function (other) {
|
||||
if (other instanceof tree.Dimension) {
|
||||
if (other instanceof Dimension) {
|
||||
var a, b,
|
||||
aValue, bValue;
|
||||
|
||||
@@ -126,8 +126,8 @@ tree.Dimension.prototype = {
|
||||
i, groupName, group, targetUnit, derivedConversions = {}, applyUnit;
|
||||
|
||||
if (typeof conversions === 'string') {
|
||||
for(i in tree.UnitConversions) {
|
||||
if (tree.UnitConversions[i].hasOwnProperty(conversions)) {
|
||||
for(i in unitConversions) {
|
||||
if (unitConversions[i].hasOwnProperty(conversions)) {
|
||||
derivedConversions = {};
|
||||
derivedConversions[i] = conversions;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ tree.Dimension.prototype = {
|
||||
for (groupName in conversions) {
|
||||
if (conversions.hasOwnProperty(groupName)) {
|
||||
targetUnit = conversions[groupName];
|
||||
group = tree.UnitConversions[groupName];
|
||||
group = unitConversions[groupName];
|
||||
|
||||
unit.map(applyUnit);
|
||||
}
|
||||
@@ -160,165 +160,8 @@ tree.Dimension.prototype = {
|
||||
|
||||
unit.cancel();
|
||||
|
||||
return new(tree.Dimension)(value, unit);
|
||||
return new(Dimension)(value, unit);
|
||||
}
|
||||
};
|
||||
|
||||
// http://www.w3.org/TR/css3-values/#absolute-lengths
|
||||
tree.UnitConversions = {
|
||||
length: {
|
||||
'm': 1,
|
||||
'cm': 0.01,
|
||||
'mm': 0.001,
|
||||
'in': 0.0254,
|
||||
'px': 0.0254 / 96,
|
||||
'pt': 0.0254 / 72,
|
||||
'pc': 0.0254 / 72 * 12
|
||||
},
|
||||
duration: {
|
||||
's': 1,
|
||||
'ms': 0.001
|
||||
},
|
||||
angle: {
|
||||
'rad': 1/(2*Math.PI),
|
||||
'deg': 1/360,
|
||||
'grad': 1/400,
|
||||
'turn': 1
|
||||
}
|
||||
return Dimension;
|
||||
};
|
||||
|
||||
tree.Unit = function (numerator, denominator, backupUnit) {
|
||||
this.numerator = numerator ? numerator.slice(0).sort() : [];
|
||||
this.denominator = denominator ? denominator.slice(0).sort() : [];
|
||||
this.backupUnit = backupUnit;
|
||||
};
|
||||
|
||||
tree.Unit.prototype = {
|
||||
type: "Unit",
|
||||
clone: function () {
|
||||
return new tree.Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit);
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
if (this.numerator.length >= 1) {
|
||||
output.add(this.numerator[0]);
|
||||
} else
|
||||
if (this.denominator.length >= 1) {
|
||||
output.add(this.denominator[0]);
|
||||
} else
|
||||
if ((!env || !env.strictUnits) && this.backupUnit) {
|
||||
output.add(this.backupUnit);
|
||||
}
|
||||
},
|
||||
toCSS: tree.toCSS,
|
||||
|
||||
toString: function () {
|
||||
var i, returnStr = this.numerator.join("*");
|
||||
for (i = 0; i < this.denominator.length; i++) {
|
||||
returnStr += "/" + this.denominator[i];
|
||||
}
|
||||
return returnStr;
|
||||
},
|
||||
|
||||
compare: function (other) {
|
||||
return this.is(other.toString()) ? 0 : -1;
|
||||
},
|
||||
|
||||
is: function (unitString) {
|
||||
return this.toString() === unitString;
|
||||
},
|
||||
|
||||
isLength: function () {
|
||||
return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/));
|
||||
},
|
||||
|
||||
isEmpty: function () {
|
||||
return this.numerator.length === 0 && this.denominator.length === 0;
|
||||
},
|
||||
|
||||
isSingular: function() {
|
||||
return this.numerator.length <= 1 && this.denominator.length === 0;
|
||||
},
|
||||
|
||||
map: function(callback) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.numerator.length; i++) {
|
||||
this.numerator[i] = callback(this.numerator[i], false);
|
||||
}
|
||||
|
||||
for (i = 0; i < this.denominator.length; i++) {
|
||||
this.denominator[i] = callback(this.denominator[i], true);
|
||||
}
|
||||
},
|
||||
|
||||
usedUnits: function() {
|
||||
var group, result = {}, mapUnit;
|
||||
|
||||
mapUnit = function (atomicUnit) {
|
||||
/*jshint loopfunc:true */
|
||||
if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
|
||||
result[groupName] = atomicUnit;
|
||||
}
|
||||
|
||||
return atomicUnit;
|
||||
};
|
||||
|
||||
for (var groupName in tree.UnitConversions) {
|
||||
if (tree.UnitConversions.hasOwnProperty(groupName)) {
|
||||
group = tree.UnitConversions[groupName];
|
||||
|
||||
this.map(mapUnit);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
cancel: function () {
|
||||
var counter = {}, atomicUnit, i, backup;
|
||||
|
||||
for (i = 0; i < this.numerator.length; i++) {
|
||||
atomicUnit = this.numerator[i];
|
||||
if (!backup) {
|
||||
backup = atomicUnit;
|
||||
}
|
||||
counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < this.denominator.length; i++) {
|
||||
atomicUnit = this.denominator[i];
|
||||
if (!backup) {
|
||||
backup = atomicUnit;
|
||||
}
|
||||
counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
|
||||
}
|
||||
|
||||
this.numerator = [];
|
||||
this.denominator = [];
|
||||
|
||||
for (atomicUnit in counter) {
|
||||
if (counter.hasOwnProperty(atomicUnit)) {
|
||||
var count = counter[atomicUnit];
|
||||
|
||||
if (count > 0) {
|
||||
for (i = 0; i < count; i++) {
|
||||
this.numerator.push(atomicUnit);
|
||||
}
|
||||
} else if (count < 0) {
|
||||
for (i = 0; i < -count; i++) {
|
||||
this.denominator.push(atomicUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.numerator.length === 0 && this.denominator.length === 0 && backup) {
|
||||
this.backupUnit = backup;
|
||||
}
|
||||
|
||||
this.numerator.sort();
|
||||
this.denominator.sort();
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Directive = function (name, value, rules, index, currentFileInfo, debugInfo) {
|
||||
var Directive = function (name, value, rules, index, currentFileInfo, debugInfo) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
if (rules) {
|
||||
@@ -12,7 +12,7 @@ tree.Directive = function (name, value, rules, index, currentFileInfo, debugInfo
|
||||
this.debugInfo = debugInfo;
|
||||
};
|
||||
|
||||
tree.Directive.prototype = {
|
||||
Directive.prototype = {
|
||||
type: "Directive",
|
||||
accept: function (visitor) {
|
||||
var value = this.value, rules = this.rules;
|
||||
@@ -46,7 +46,7 @@ tree.Directive.prototype = {
|
||||
rules = rules.eval(env);
|
||||
rules.root = true;
|
||||
}
|
||||
return new(tree.Directive)(this.name, value, rules,
|
||||
return new(Directive)(this.name, value, rules,
|
||||
this.index, this.currentFileInfo, this.debugInfo);
|
||||
},
|
||||
variable: function (name) { if (this.rules) return tree.Ruleset.prototype.variable.call(this.rules, name); },
|
||||
@@ -65,5 +65,5 @@ tree.Directive.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Directive;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Element = function (combinator, value, index, currentFileInfo) {
|
||||
var Element = function (combinator, value, index, currentFileInfo) {
|
||||
this.combinator = combinator instanceof tree.Combinator ?
|
||||
combinator : new(tree.Combinator)(combinator);
|
||||
|
||||
@@ -14,7 +14,7 @@ tree.Element = function (combinator, value, index, currentFileInfo) {
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
};
|
||||
tree.Element.prototype = {
|
||||
Element.prototype = {
|
||||
type: "Element",
|
||||
accept: function (visitor) {
|
||||
var value = this.value;
|
||||
@@ -24,7 +24,7 @@ tree.Element.prototype = {
|
||||
}
|
||||
},
|
||||
eval: function (env) {
|
||||
return new(tree.Element)(this.combinator,
|
||||
return new(Element)(this.combinator,
|
||||
this.value.eval ? this.value.eval(env) : this.value,
|
||||
this.index,
|
||||
this.currentFileInfo);
|
||||
@@ -41,68 +41,5 @@ tree.Element.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
tree.Attribute = function (key, op, value) {
|
||||
this.key = key;
|
||||
this.op = op;
|
||||
this.value = value;
|
||||
return Element;
|
||||
};
|
||||
tree.Attribute.prototype = {
|
||||
type: "Attribute",
|
||||
eval: function (env) {
|
||||
return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key,
|
||||
this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value);
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
output.add(this.toCSS(env));
|
||||
},
|
||||
toCSS: function (env) {
|
||||
var value = this.key.toCSS ? this.key.toCSS(env) : this.key;
|
||||
|
||||
if (this.op) {
|
||||
value += this.op;
|
||||
value += (this.value.toCSS ? this.value.toCSS(env) : this.value);
|
||||
}
|
||||
|
||||
return '[' + value + ']';
|
||||
}
|
||||
};
|
||||
|
||||
tree.Combinator = function (value) {
|
||||
if (value === ' ') {
|
||||
this.value = ' ';
|
||||
} else {
|
||||
this.value = value ? value.trim() : "";
|
||||
}
|
||||
};
|
||||
tree.Combinator.prototype = {
|
||||
type: "Combinator",
|
||||
_outputMap: {
|
||||
'' : '',
|
||||
' ' : ' ',
|
||||
':' : ' :',
|
||||
'+' : ' + ',
|
||||
'~' : ' ~ ',
|
||||
'>' : ' > ',
|
||||
'|' : '|',
|
||||
'^' : ' ^ ',
|
||||
'^^' : ' ^^ '
|
||||
},
|
||||
_outputMapCompressed: {
|
||||
'' : '',
|
||||
' ' : ' ',
|
||||
':' : ' :',
|
||||
'+' : '+',
|
||||
'~' : '~',
|
||||
'>' : '>',
|
||||
'|' : '|',
|
||||
'^' : '^',
|
||||
'^^' : '^^'
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
output.add((env.compress ? this._outputMapCompressed : this._outputMap)[this.value]);
|
||||
},
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Expression = function (value) { this.value = value; };
|
||||
tree.Expression.prototype = {
|
||||
var Expression = function (value) { this.value = value; };
|
||||
Expression.prototype = {
|
||||
type: "Expression",
|
||||
accept: function (visitor) {
|
||||
if (this.value) {
|
||||
@@ -16,7 +16,7 @@ tree.Expression.prototype = {
|
||||
env.inParenthesis();
|
||||
}
|
||||
if (this.value.length > 1) {
|
||||
returnValue = new(tree.Expression)(this.value.map(function (e) {
|
||||
returnValue = new(Expression)(this.value.map(function (e) {
|
||||
return e.eval(env);
|
||||
}));
|
||||
} else if (this.value.length === 1) {
|
||||
@@ -50,5 +50,5 @@ tree.Expression.prototype = {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Expression;
|
||||
};
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Extend = function Extend(selector, option, index) {
|
||||
var Extend = function Extend(selector, option, index) {
|
||||
this.selector = selector;
|
||||
this.option = option;
|
||||
this.index = index;
|
||||
this.object_id = tree.Extend.next_id++;
|
||||
this.object_id = Extend.next_id++;
|
||||
this.parent_ids = [this.object_id];
|
||||
|
||||
switch(option) {
|
||||
@@ -18,18 +18,18 @@ tree.Extend = function Extend(selector, option, index) {
|
||||
break;
|
||||
}
|
||||
};
|
||||
tree.Extend.next_id = 0;
|
||||
Extend.next_id = 0;
|
||||
|
||||
tree.Extend.prototype = {
|
||||
Extend.prototype = {
|
||||
type: "Extend",
|
||||
accept: function (visitor) {
|
||||
this.selector = visitor.visit(this.selector);
|
||||
},
|
||||
eval: function (env) {
|
||||
return new(tree.Extend)(this.selector.eval(env), this.option, this.index);
|
||||
return new(Extend)(this.selector.eval(env), this.option, this.index);
|
||||
},
|
||||
clone: function (env) {
|
||||
return new(tree.Extend)(this.selector, this.option, this.index);
|
||||
return new(Extend)(this.selector, this.option, this.index);
|
||||
},
|
||||
findSelfSelectors: function (selectors) {
|
||||
var selfElements = [],
|
||||
@@ -49,5 +49,5 @@ tree.Extend.prototype = {
|
||||
this.selfSelectors = [{ elements: selfElements }];
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Extend;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
//
|
||||
// CSS @import node
|
||||
//
|
||||
@@ -11,7 +11,7 @@
|
||||
// `import,push`, we also pass it a callback, which it'll call once
|
||||
// the file has been fetched, and parsed.
|
||||
//
|
||||
tree.Import = function (path, features, options, index, currentFileInfo) {
|
||||
var Import = function (path, features, options, index, currentFileInfo) {
|
||||
this.options = options;
|
||||
this.index = index;
|
||||
this.path = path;
|
||||
@@ -37,7 +37,7 @@ tree.Import = function (path, features, options, index, currentFileInfo) {
|
||||
// we end up with a flat structure, which can easily be imported in the parent
|
||||
// ruleset.
|
||||
//
|
||||
tree.Import.prototype = {
|
||||
Import.prototype = {
|
||||
type: "Import",
|
||||
accept: function (visitor) {
|
||||
if (this.features) {
|
||||
@@ -70,7 +70,7 @@ tree.Import.prototype = {
|
||||
return null;
|
||||
},
|
||||
evalForImport: function (env) {
|
||||
return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo);
|
||||
return new(Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo);
|
||||
},
|
||||
evalPath: function (env) {
|
||||
var path = this.path.eval(env);
|
||||
@@ -99,7 +99,7 @@ tree.Import.prototype = {
|
||||
var contents = new(tree.Anonymous)(this.root, 0, {filename: this.importedFilename}, true);
|
||||
return this.features ? new(tree.Media)([contents], this.features.value) : [contents];
|
||||
} else if (this.css) {
|
||||
var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index);
|
||||
var newImport = new(Import)(this.evalPath(env), features, this.options, this.index);
|
||||
if (!newImport.css && this.error) {
|
||||
throw this.error;
|
||||
}
|
||||
@@ -113,5 +113,5 @@ tree.Import.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Import;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.JavaScript = function (string, index, escaped) {
|
||||
var JavaScript = function (string, index, escaped) {
|
||||
this.escaped = escaped;
|
||||
this.expression = string;
|
||||
this.index = index;
|
||||
};
|
||||
tree.JavaScript.prototype = {
|
||||
JavaScript.prototype = {
|
||||
type: "JavaScript",
|
||||
eval: function (env) {
|
||||
var result,
|
||||
@@ -53,6 +53,5 @@ tree.JavaScript.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
|
||||
return JavaScript;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Keyword = function (value) { this.value = value; };
|
||||
tree.Keyword.prototype = {
|
||||
var Keyword = function (value) { this.value = value; };
|
||||
Keyword.prototype = {
|
||||
type: "Keyword",
|
||||
eval: function () { return this; },
|
||||
genCSS: function (env, output) {
|
||||
@@ -10,7 +10,7 @@ tree.Keyword.prototype = {
|
||||
},
|
||||
toCSS: tree.toCSS,
|
||||
compare: function (other) {
|
||||
if (other instanceof tree.Keyword) {
|
||||
if (other instanceof Keyword) {
|
||||
return other.value === this.value ? 0 : 1;
|
||||
} else {
|
||||
return -1;
|
||||
@@ -18,7 +18,10 @@ tree.Keyword.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
tree.True = new(tree.Keyword)('true');
|
||||
tree.False = new(tree.Keyword)('false');
|
||||
//TODO move?
|
||||
tree.True = new(Keyword)('true');
|
||||
tree.False = new(Keyword)('false');
|
||||
|
||||
})(require('../tree'));
|
||||
return Keyword;
|
||||
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Media = function (value, features, index, currentFileInfo) {
|
||||
var Media = function (value, features, index, currentFileInfo) {
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
|
||||
@@ -10,7 +10,7 @@ tree.Media = function (value, features, index, currentFileInfo) {
|
||||
this.rules = [new(tree.Ruleset)(selectors, value)];
|
||||
this.rules[0].allowImports = true;
|
||||
};
|
||||
tree.Media.prototype = {
|
||||
Media.prototype = {
|
||||
type: "Media",
|
||||
accept: function (visitor) {
|
||||
if (this.features) {
|
||||
@@ -32,7 +32,7 @@ tree.Media.prototype = {
|
||||
env.mediaPath = [];
|
||||
}
|
||||
|
||||
var media = new(tree.Media)(null, [], this.index, this.currentFileInfo);
|
||||
var media = new(Media)(null, [], this.index, this.currentFileInfo);
|
||||
if(this.debugInfo) {
|
||||
this.rules[0].debugInfo = this.debugInfo;
|
||||
media.debugInfo = this.debugInfo;
|
||||
@@ -153,5 +153,5 @@ tree.Media.prototype = {
|
||||
this.rules = [new(tree.Ruleset)(selectors.slice(0), [this.rules[0]])];
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Media;
|
||||
};
|
||||
|
||||
152
lib/less/tree/mixin-call.js
Normal file
152
lib/less/tree/mixin-call.js
Normal file
@@ -0,0 +1,152 @@
|
||||
module.exports = function (tree) {
|
||||
|
||||
var Call = function (elements, args, index, currentFileInfo, important) {
|
||||
this.selector = new(tree.Selector)(elements);
|
||||
this.arguments = (args && args.length) ? args : null;
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
this.important = important;
|
||||
};
|
||||
Call.prototype = {
|
||||
type: "MixinCall",
|
||||
accept: function (visitor) {
|
||||
if (this.selector) {
|
||||
this.selector = visitor.visit(this.selector);
|
||||
}
|
||||
if (this.arguments) {
|
||||
this.arguments = visitor.visitArray(this.arguments);
|
||||
}
|
||||
},
|
||||
eval: function (env) {
|
||||
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule,
|
||||
candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc,
|
||||
defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count;
|
||||
|
||||
args = this.arguments && this.arguments.map(function (a) {
|
||||
return { name: a.name, value: a.value.eval(env) };
|
||||
});
|
||||
|
||||
for (i = 0; i < env.frames.length; i++) {
|
||||
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
||||
isOneFound = true;
|
||||
|
||||
// To make `default()` function independent of definition order we have two "subpasses" here.
|
||||
// At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
|
||||
// and build candidate list with corresponding flags. Then, when we know all possible matches,
|
||||
// we make a final decision.
|
||||
|
||||
for (m = 0; m < mixins.length; m++) {
|
||||
mixin = mixins[m];
|
||||
isRecursive = false;
|
||||
for(f = 0; f < env.frames.length; f++) {
|
||||
if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
|
||||
isRecursive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isRecursive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mixin.matchArgs(args, env)) {
|
||||
candidate = {mixin: mixin, group: defNone};
|
||||
|
||||
if (mixin.matchCondition) {
|
||||
for (f = 0; f < 2; f++) {
|
||||
defaultFunc.value(f);
|
||||
conditionResult[f] = mixin.matchCondition(args, env);
|
||||
}
|
||||
if (conditionResult[0] || conditionResult[1]) {
|
||||
if (conditionResult[0] != conditionResult[1]) {
|
||||
candidate.group = conditionResult[1] ?
|
||||
defTrue : defFalse;
|
||||
}
|
||||
|
||||
candidates.push(candidate);
|
||||
}
|
||||
}
|
||||
else {
|
||||
candidates.push(candidate);
|
||||
}
|
||||
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
defaultFunc.reset();
|
||||
|
||||
count = [0, 0, 0];
|
||||
for (m = 0; m < candidates.length; m++) {
|
||||
count[candidates[m].group]++;
|
||||
}
|
||||
|
||||
if (count[defNone] > 0) {
|
||||
defaultResult = defFalse;
|
||||
} else {
|
||||
defaultResult = defTrue;
|
||||
if ((count[defTrue] + count[defFalse]) > 1) {
|
||||
throw { type: 'Runtime',
|
||||
message: 'Ambiguous use of `default()` found when matching for `'
|
||||
+ this.format(args) + '`',
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
}
|
||||
}
|
||||
|
||||
for (m = 0; m < candidates.length; m++) {
|
||||
candidate = candidates[m].group;
|
||||
if ((candidate === defNone) || (candidate === defaultResult)) {
|
||||
try {
|
||||
mixin = candidates[m].mixin;
|
||||
if (!(mixin instanceof tree.mixin.Definition)) {
|
||||
mixin = new tree.mixin.Definition("", [], mixin.rules, null, false);
|
||||
mixin.originalRuleset = mixins[m].originalRuleset || mixins[m];
|
||||
}
|
||||
Array.prototype.push.apply(
|
||||
rules, mixin.evalCall(env, args, this.important).rules);
|
||||
} catch (e) {
|
||||
throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
if (!this.currentFileInfo || !this.currentFileInfo.reference) {
|
||||
for (i = 0; i < rules.length; i++) {
|
||||
rule = rules[i];
|
||||
if (rule.markReferenced) {
|
||||
rule.markReferenced();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isOneFound) {
|
||||
throw { type: 'Runtime',
|
||||
message: 'No matching definition was found for `' + this.format(args) + '`',
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
} else {
|
||||
throw { type: 'Name',
|
||||
message: this.selector.toCSS().trim() + " is undefined",
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
}
|
||||
},
|
||||
format: function (args) {
|
||||
return this.selector.toCSS().trim() + '(' +
|
||||
(args ? args.map(function (a) {
|
||||
var argValue = "";
|
||||
if (a.name) {
|
||||
argValue += a.name + ":";
|
||||
}
|
||||
if (a.value.toCSS) {
|
||||
argValue += a.value.toCSS();
|
||||
} else {
|
||||
argValue += "???";
|
||||
}
|
||||
return argValue;
|
||||
}).join(', ') : "") + ")";
|
||||
}
|
||||
};
|
||||
return Call;
|
||||
};
|
||||
165
lib/less/tree/mixin-definition.js
Normal file
165
lib/less/tree/mixin-definition.js
Normal file
@@ -0,0 +1,165 @@
|
||||
module.exports = function (tree) {
|
||||
|
||||
var Definition = function (name, params, rules, condition, variadic, frames) {
|
||||
this.name = name;
|
||||
this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])];
|
||||
this.params = params;
|
||||
this.condition = condition;
|
||||
this.variadic = variadic;
|
||||
this.arity = params.length;
|
||||
this.rules = rules;
|
||||
this._lookups = {};
|
||||
this.required = params.reduce(function (count, p) {
|
||||
if (!p.name || (p.name && !p.value)) { return count + 1; }
|
||||
else { return count; }
|
||||
}, 0);
|
||||
this.parent = tree.Ruleset.prototype;
|
||||
this.frames = frames;
|
||||
};
|
||||
Definition.prototype = {
|
||||
type: "MixinDefinition",
|
||||
accept: function (visitor) {
|
||||
if (this.params && this.params.length) {
|
||||
this.params = visitor.visitArray(this.params);
|
||||
}
|
||||
this.rules = visitor.visitArray(this.rules);
|
||||
if (this.condition) {
|
||||
this.condition = visitor.visit(this.condition);
|
||||
}
|
||||
},
|
||||
variable: function (name) { return this.parent.variable.call(this, name); },
|
||||
variables: function () { return this.parent.variables.call(this); },
|
||||
find: function () { return this.parent.find.apply(this, arguments); },
|
||||
rulesets: function () { return this.parent.rulesets.apply(this); },
|
||||
|
||||
evalParams: function (env, mixinEnv, args, evaldArguments) {
|
||||
/*jshint boss:true */
|
||||
var frame = new(tree.Ruleset)(null, null),
|
||||
varargs, arg,
|
||||
params = this.params.slice(0),
|
||||
i, j, val, name, isNamedFound, argIndex, argsLength = 0;
|
||||
|
||||
mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames));
|
||||
|
||||
if (args) {
|
||||
args = args.slice(0);
|
||||
argsLength = args.length;
|
||||
|
||||
for(i = 0; i < argsLength; i++) {
|
||||
arg = args[i];
|
||||
if (name = (arg && arg.name)) {
|
||||
isNamedFound = false;
|
||||
for(j = 0; j < params.length; j++) {
|
||||
if (!evaldArguments[j] && name === params[j].name) {
|
||||
evaldArguments[j] = arg.value.eval(env);
|
||||
frame.prependRule(new(tree.Rule)(name, arg.value.eval(env)));
|
||||
isNamedFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isNamedFound) {
|
||||
args.splice(i, 1);
|
||||
i--;
|
||||
continue;
|
||||
} else {
|
||||
throw { type: 'Runtime', message: "Named argument for " + this.name +
|
||||
' ' + args[i].name + ' not found' };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
argIndex = 0;
|
||||
for (i = 0; i < params.length; i++) {
|
||||
if (evaldArguments[i]) { continue; }
|
||||
|
||||
arg = args && args[argIndex];
|
||||
|
||||
if (name = params[i].name) {
|
||||
if (params[i].variadic) {
|
||||
varargs = [];
|
||||
for (j = argIndex; j < argsLength; j++) {
|
||||
varargs.push(args[j].value.eval(env));
|
||||
}
|
||||
frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
|
||||
} else {
|
||||
val = arg && arg.value;
|
||||
if (val) {
|
||||
val = val.eval(env);
|
||||
} else if (params[i].value) {
|
||||
val = params[i].value.eval(mixinEnv);
|
||||
frame.resetCache();
|
||||
} else {
|
||||
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
|
||||
' (' + argsLength + ' for ' + this.arity + ')' };
|
||||
}
|
||||
|
||||
frame.prependRule(new(tree.Rule)(name, val));
|
||||
evaldArguments[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (params[i].variadic && args) {
|
||||
for (j = argIndex; j < argsLength; j++) {
|
||||
evaldArguments[j] = args[j].value.eval(env);
|
||||
}
|
||||
}
|
||||
argIndex++;
|
||||
}
|
||||
|
||||
return frame;
|
||||
},
|
||||
eval: function (env) {
|
||||
return new tree.mixin.Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || env.frames.slice(0));
|
||||
},
|
||||
evalCall: function (env, args, important) {
|
||||
var _arguments = [],
|
||||
mixinFrames = this.frames ? this.frames.concat(env.frames) : env.frames,
|
||||
frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments),
|
||||
rules, ruleset;
|
||||
|
||||
frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
||||
|
||||
rules = this.rules.slice(0);
|
||||
|
||||
ruleset = new(tree.Ruleset)(null, rules);
|
||||
ruleset.originalRuleset = this;
|
||||
ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames)));
|
||||
if (important) {
|
||||
ruleset = this.parent.makeImportant.apply(ruleset);
|
||||
}
|
||||
return ruleset;
|
||||
},
|
||||
matchCondition: function (args, env) {
|
||||
if (this.condition && !this.condition.eval(
|
||||
new(tree.evalEnv)(env,
|
||||
[this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])] // the parameter variables
|
||||
.concat(this.frames) // the parent namespace/mixin frames
|
||||
.concat(env.frames)))) { // the current environment frames
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
matchArgs: function (args, env) {
|
||||
var argsLength = (args && args.length) || 0, len;
|
||||
|
||||
if (! this.variadic) {
|
||||
if (argsLength < this.required) { return false; }
|
||||
if (argsLength > this.params.length) { return false; }
|
||||
} else {
|
||||
if (argsLength < (this.required - 1)) { return false; }
|
||||
}
|
||||
|
||||
len = Math.min(argsLength, this.arity);
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (!this.params[i].name && !this.params[i].variadic) {
|
||||
if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return Definition;
|
||||
};
|
||||
@@ -1,315 +0,0 @@
|
||||
(function (tree) {
|
||||
|
||||
tree.mixin = {};
|
||||
tree.mixin.Call = function (elements, args, index, currentFileInfo, important) {
|
||||
this.selector = new(tree.Selector)(elements);
|
||||
this.arguments = (args && args.length) ? args : null;
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
this.important = important;
|
||||
};
|
||||
tree.mixin.Call.prototype = {
|
||||
type: "MixinCall",
|
||||
accept: function (visitor) {
|
||||
if (this.selector) {
|
||||
this.selector = visitor.visit(this.selector);
|
||||
}
|
||||
if (this.arguments) {
|
||||
this.arguments = visitor.visitArray(this.arguments);
|
||||
}
|
||||
},
|
||||
eval: function (env) {
|
||||
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound, rule,
|
||||
candidates = [], candidate, conditionResult = [], defaultFunc = tree.defaultFunc,
|
||||
defaultResult, defNone = 0, defTrue = 1, defFalse = 2, count;
|
||||
|
||||
args = this.arguments && this.arguments.map(function (a) {
|
||||
return { name: a.name, value: a.value.eval(env) };
|
||||
});
|
||||
|
||||
for (i = 0; i < env.frames.length; i++) {
|
||||
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
||||
isOneFound = true;
|
||||
|
||||
// To make `default()` function independent of definition order we have two "subpasses" here.
|
||||
// At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
|
||||
// and build candidate list with corresponding flags. Then, when we know all possible matches,
|
||||
// we make a final decision.
|
||||
|
||||
for (m = 0; m < mixins.length; m++) {
|
||||
mixin = mixins[m];
|
||||
isRecursive = false;
|
||||
for(f = 0; f < env.frames.length; f++) {
|
||||
if ((!(mixin instanceof tree.mixin.Definition)) && mixin === (env.frames[f].originalRuleset || env.frames[f])) {
|
||||
isRecursive = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isRecursive) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mixin.matchArgs(args, env)) {
|
||||
candidate = {mixin: mixin, group: defNone};
|
||||
|
||||
if (mixin.matchCondition) {
|
||||
for (f = 0; f < 2; f++) {
|
||||
defaultFunc.value(f);
|
||||
conditionResult[f] = mixin.matchCondition(args, env);
|
||||
}
|
||||
if (conditionResult[0] || conditionResult[1]) {
|
||||
if (conditionResult[0] != conditionResult[1]) {
|
||||
candidate.group = conditionResult[1] ?
|
||||
defTrue : defFalse;
|
||||
}
|
||||
|
||||
candidates.push(candidate);
|
||||
}
|
||||
}
|
||||
else {
|
||||
candidates.push(candidate);
|
||||
}
|
||||
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
|
||||
defaultFunc.reset();
|
||||
|
||||
count = [0, 0, 0];
|
||||
for (m = 0; m < candidates.length; m++) {
|
||||
count[candidates[m].group]++;
|
||||
}
|
||||
|
||||
if (count[defNone] > 0) {
|
||||
defaultResult = defFalse;
|
||||
} else {
|
||||
defaultResult = defTrue;
|
||||
if ((count[defTrue] + count[defFalse]) > 1) {
|
||||
throw { type: 'Runtime',
|
||||
message: 'Ambiguous use of `default()` found when matching for `'
|
||||
+ this.format(args) + '`',
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
}
|
||||
}
|
||||
|
||||
for (m = 0; m < candidates.length; m++) {
|
||||
candidate = candidates[m].group;
|
||||
if ((candidate === defNone) || (candidate === defaultResult)) {
|
||||
try {
|
||||
mixin = candidates[m].mixin;
|
||||
if (!(mixin instanceof tree.mixin.Definition)) {
|
||||
mixin = new tree.mixin.Definition("", [], mixin.rules, null, false);
|
||||
mixin.originalRuleset = mixins[m].originalRuleset || mixins[m];
|
||||
}
|
||||
Array.prototype.push.apply(
|
||||
rules, mixin.evalCall(env, args, this.important).rules);
|
||||
} catch (e) {
|
||||
throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match) {
|
||||
if (!this.currentFileInfo || !this.currentFileInfo.reference) {
|
||||
for (i = 0; i < rules.length; i++) {
|
||||
rule = rules[i];
|
||||
if (rule.markReferenced) {
|
||||
rule.markReferenced();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isOneFound) {
|
||||
throw { type: 'Runtime',
|
||||
message: 'No matching definition was found for `' + this.format(args) + '`',
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
} else {
|
||||
throw { type: 'Name',
|
||||
message: this.selector.toCSS().trim() + " is undefined",
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
}
|
||||
},
|
||||
format: function (args) {
|
||||
return this.selector.toCSS().trim() + '(' +
|
||||
(args ? args.map(function (a) {
|
||||
var argValue = "";
|
||||
if (a.name) {
|
||||
argValue += a.name + ":";
|
||||
}
|
||||
if (a.value.toCSS) {
|
||||
argValue += a.value.toCSS();
|
||||
} else {
|
||||
argValue += "???";
|
||||
}
|
||||
return argValue;
|
||||
}).join(', ') : "") + ")";
|
||||
}
|
||||
};
|
||||
|
||||
tree.mixin.Definition = function (name, params, rules, condition, variadic, frames) {
|
||||
this.name = name;
|
||||
this.selectors = [new(tree.Selector)([new(tree.Element)(null, name, this.index, this.currentFileInfo)])];
|
||||
this.params = params;
|
||||
this.condition = condition;
|
||||
this.variadic = variadic;
|
||||
this.arity = params.length;
|
||||
this.rules = rules;
|
||||
this._lookups = {};
|
||||
this.required = params.reduce(function (count, p) {
|
||||
if (!p.name || (p.name && !p.value)) { return count + 1; }
|
||||
else { return count; }
|
||||
}, 0);
|
||||
this.parent = tree.Ruleset.prototype;
|
||||
this.frames = frames;
|
||||
};
|
||||
tree.mixin.Definition.prototype = {
|
||||
type: "MixinDefinition",
|
||||
accept: function (visitor) {
|
||||
if (this.params && this.params.length) {
|
||||
this.params = visitor.visitArray(this.params);
|
||||
}
|
||||
this.rules = visitor.visitArray(this.rules);
|
||||
if (this.condition) {
|
||||
this.condition = visitor.visit(this.condition);
|
||||
}
|
||||
},
|
||||
variable: function (name) { return this.parent.variable.call(this, name); },
|
||||
variables: function () { return this.parent.variables.call(this); },
|
||||
find: function () { return this.parent.find.apply(this, arguments); },
|
||||
rulesets: function () { return this.parent.rulesets.apply(this); },
|
||||
|
||||
evalParams: function (env, mixinEnv, args, evaldArguments) {
|
||||
/*jshint boss:true */
|
||||
var frame = new(tree.Ruleset)(null, null),
|
||||
varargs, arg,
|
||||
params = this.params.slice(0),
|
||||
i, j, val, name, isNamedFound, argIndex, argsLength = 0;
|
||||
|
||||
mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames));
|
||||
|
||||
if (args) {
|
||||
args = args.slice(0);
|
||||
argsLength = args.length;
|
||||
|
||||
for(i = 0; i < argsLength; i++) {
|
||||
arg = args[i];
|
||||
if (name = (arg && arg.name)) {
|
||||
isNamedFound = false;
|
||||
for(j = 0; j < params.length; j++) {
|
||||
if (!evaldArguments[j] && name === params[j].name) {
|
||||
evaldArguments[j] = arg.value.eval(env);
|
||||
frame.prependRule(new(tree.Rule)(name, arg.value.eval(env)));
|
||||
isNamedFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isNamedFound) {
|
||||
args.splice(i, 1);
|
||||
i--;
|
||||
continue;
|
||||
} else {
|
||||
throw { type: 'Runtime', message: "Named argument for " + this.name +
|
||||
' ' + args[i].name + ' not found' };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
argIndex = 0;
|
||||
for (i = 0; i < params.length; i++) {
|
||||
if (evaldArguments[i]) { continue; }
|
||||
|
||||
arg = args && args[argIndex];
|
||||
|
||||
if (name = params[i].name) {
|
||||
if (params[i].variadic) {
|
||||
varargs = [];
|
||||
for (j = argIndex; j < argsLength; j++) {
|
||||
varargs.push(args[j].value.eval(env));
|
||||
}
|
||||
frame.prependRule(new(tree.Rule)(name, new(tree.Expression)(varargs).eval(env)));
|
||||
} else {
|
||||
val = arg && arg.value;
|
||||
if (val) {
|
||||
val = val.eval(env);
|
||||
} else if (params[i].value) {
|
||||
val = params[i].value.eval(mixinEnv);
|
||||
frame.resetCache();
|
||||
} else {
|
||||
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
|
||||
' (' + argsLength + ' for ' + this.arity + ')' };
|
||||
}
|
||||
|
||||
frame.prependRule(new(tree.Rule)(name, val));
|
||||
evaldArguments[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (params[i].variadic && args) {
|
||||
for (j = argIndex; j < argsLength; j++) {
|
||||
evaldArguments[j] = args[j].value.eval(env);
|
||||
}
|
||||
}
|
||||
argIndex++;
|
||||
}
|
||||
|
||||
return frame;
|
||||
},
|
||||
eval: function (env) {
|
||||
return new tree.mixin.Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || env.frames.slice(0));
|
||||
},
|
||||
evalCall: function (env, args, important) {
|
||||
var _arguments = [],
|
||||
mixinFrames = this.frames ? this.frames.concat(env.frames) : env.frames,
|
||||
frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments),
|
||||
rules, ruleset;
|
||||
|
||||
frame.prependRule(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
||||
|
||||
rules = this.rules.slice(0);
|
||||
|
||||
ruleset = new(tree.Ruleset)(null, rules);
|
||||
ruleset.originalRuleset = this;
|
||||
ruleset = ruleset.eval(new(tree.evalEnv)(env, [this, frame].concat(mixinFrames)));
|
||||
if (important) {
|
||||
ruleset = this.parent.makeImportant.apply(ruleset);
|
||||
}
|
||||
return ruleset;
|
||||
},
|
||||
matchCondition: function (args, env) {
|
||||
if (this.condition && !this.condition.eval(
|
||||
new(tree.evalEnv)(env,
|
||||
[this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])] // the parameter variables
|
||||
.concat(this.frames) // the parent namespace/mixin frames
|
||||
.concat(env.frames)))) { // the current environment frames
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
matchArgs: function (args, env) {
|
||||
var argsLength = (args && args.length) || 0, len;
|
||||
|
||||
if (! this.variadic) {
|
||||
if (argsLength < this.required) { return false; }
|
||||
if (argsLength > this.params.length) { return false; }
|
||||
} else {
|
||||
if (argsLength < (this.required - 1)) { return false; }
|
||||
}
|
||||
|
||||
len = Math.min(argsLength, this.arity);
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (!this.params[i].name && !this.params[i].variadic) {
|
||||
if (args[i].value.eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Negative = function (node) {
|
||||
var Negative = function (node) {
|
||||
this.value = node;
|
||||
};
|
||||
tree.Negative.prototype = {
|
||||
Negative.prototype = {
|
||||
type: "Negative",
|
||||
accept: function (visitor) {
|
||||
this.value = visitor.visit(this.value);
|
||||
@@ -17,8 +17,8 @@ tree.Negative.prototype = {
|
||||
if (env.isMathOn()) {
|
||||
return (new(tree.Operation)('*', [new(tree.Dimension)(-1), this.value])).eval(env);
|
||||
}
|
||||
return new(tree.Negative)(this.value.eval(env));
|
||||
return new(Negative)(this.value.eval(env));
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Negative;
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Operation = function (op, operands, isSpaced) {
|
||||
var Operation = function (op, operands, isSpaced) {
|
||||
this.op = op.trim();
|
||||
this.operands = operands;
|
||||
this.isSpaced = isSpaced;
|
||||
};
|
||||
tree.Operation.prototype = {
|
||||
Operation.prototype = {
|
||||
type: "Operation",
|
||||
accept: function (visitor) {
|
||||
this.operands = visitor.visit(this.operands);
|
||||
@@ -28,7 +28,7 @@ tree.Operation.prototype = {
|
||||
|
||||
return a.operate(env, this.op, b);
|
||||
} else {
|
||||
return new(tree.Operation)(this.op, [a, b], this.isSpaced);
|
||||
return new(Operation)(this.op, [a, b], this.isSpaced);
|
||||
}
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
@@ -45,6 +45,7 @@ tree.Operation.prototype = {
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
// todo move!
|
||||
tree.operate = function (env, op, a, b) {
|
||||
switch (op) {
|
||||
case '+': return a + b;
|
||||
@@ -53,5 +54,7 @@ tree.operate = function (env, op, a, b) {
|
||||
case '/': return a / b;
|
||||
}
|
||||
};
|
||||
|
||||
return Operation;
|
||||
|
||||
})(require('../tree'));
|
||||
};
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
module.exports = function (tree) {
|
||||
|
||||
(function (tree) {
|
||||
|
||||
tree.Paren = function (node) {
|
||||
var Paren = function (node) {
|
||||
this.value = node;
|
||||
};
|
||||
tree.Paren.prototype = {
|
||||
Paren.prototype = {
|
||||
type: "Paren",
|
||||
accept: function (visitor) {
|
||||
this.value = visitor.visit(this.value);
|
||||
@@ -16,8 +15,8 @@ tree.Paren.prototype = {
|
||||
},
|
||||
toCSS: tree.toCSS,
|
||||
eval: function (env) {
|
||||
return new(tree.Paren)(this.value.eval(env));
|
||||
return new(Paren)(this.value.eval(env));
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Paren;
|
||||
};
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Quoted = function (str, content, escaped, index, currentFileInfo) {
|
||||
var Quoted = function (str, content, escaped, index, currentFileInfo) {
|
||||
this.escaped = escaped;
|
||||
this.value = content || '';
|
||||
this.quote = str.charAt(0);
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
};
|
||||
tree.Quoted.prototype = {
|
||||
Quoted.prototype = {
|
||||
type: "Quoted",
|
||||
genCSS: function (env, output) {
|
||||
if (!this.escaped) {
|
||||
@@ -44,5 +44,5 @@ tree.Quoted.prototype = {
|
||||
return left < right ? -1 : 1;
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Quoted;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Rule = function (name, value, important, merge, index, currentFileInfo, inline) {
|
||||
var Rule = function (name, value, important, merge, index, currentFileInfo, inline) {
|
||||
this.name = name;
|
||||
this.value = (value instanceof tree.Value || value instanceof tree.Ruleset) ? value : new(tree.Value)([value]);
|
||||
this.important = important ? ' ' + important.trim() : '';
|
||||
@@ -11,7 +11,7 @@ tree.Rule = function (name, value, important, merge, index, currentFileInfo, inl
|
||||
this.variable = name.charAt && (name.charAt(0) === '@');
|
||||
};
|
||||
|
||||
tree.Rule.prototype = {
|
||||
Rule.prototype = {
|
||||
type: "Rule",
|
||||
accept: function (visitor) {
|
||||
this.value = visitor.visit(this.value);
|
||||
@@ -50,7 +50,7 @@ tree.Rule.prototype = {
|
||||
index: this.index, filename: this.currentFileInfo.filename };
|
||||
}
|
||||
|
||||
return new(tree.Rule)(name,
|
||||
return new(Rule)(name,
|
||||
evaldValue,
|
||||
this.important,
|
||||
this.merge,
|
||||
@@ -70,7 +70,7 @@ tree.Rule.prototype = {
|
||||
}
|
||||
},
|
||||
makeImportant: function () {
|
||||
return new(tree.Rule)(this.name,
|
||||
return new(Rule)(this.name,
|
||||
this.value,
|
||||
"!important",
|
||||
this.merge,
|
||||
@@ -86,5 +86,7 @@ function evalName(env, name) {
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
return Rule;
|
||||
|
||||
})(require('../tree'));
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.RulesetCall = function (variable) {
|
||||
var RulesetCall = function (variable) {
|
||||
this.variable = variable;
|
||||
};
|
||||
tree.RulesetCall.prototype = {
|
||||
RulesetCall.prototype = {
|
||||
type: "RulesetCall",
|
||||
accept: function (visitor) {
|
||||
},
|
||||
@@ -12,5 +12,5 @@ tree.RulesetCall.prototype = {
|
||||
return detachedRuleset.callEval(env);
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return RulesetCall;
|
||||
};
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Ruleset = function (selectors, rules, strictImports) {
|
||||
var Ruleset = function (selectors, rules, strictImports) {
|
||||
this.selectors = selectors;
|
||||
this.rules = rules;
|
||||
this._lookups = {};
|
||||
this.strictImports = strictImports;
|
||||
};
|
||||
tree.Ruleset.prototype = {
|
||||
Ruleset.prototype = {
|
||||
type: "Ruleset",
|
||||
accept: function (visitor) {
|
||||
if (this.paths) {
|
||||
@@ -41,7 +41,7 @@ tree.Ruleset.prototype = {
|
||||
}
|
||||
|
||||
var rules = this.rules ? this.rules.slice(0) : null,
|
||||
ruleset = new(tree.Ruleset)(selectors, rules, this.strictImports),
|
||||
ruleset = new(Ruleset)(selectors, rules, this.strictImports),
|
||||
rule, subRule;
|
||||
|
||||
ruleset.originalRuleset = this;
|
||||
@@ -129,7 +129,7 @@ tree.Ruleset.prototype = {
|
||||
for (i = 0; i < rsRules.length; i++) {
|
||||
rule = rsRules[i];
|
||||
// for rulesets, check if it is a css guard and can be removed
|
||||
if (rule instanceof tree.Ruleset && rule.selectors && rule.selectors.length === 1) {
|
||||
if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
|
||||
// check if it can be folded in (e.g. & where)
|
||||
if (rule.selectors[0].isJustParentSelector()) {
|
||||
rsRules.splice(i--, 1);
|
||||
@@ -174,7 +174,7 @@ tree.Ruleset.prototype = {
|
||||
}
|
||||
},
|
||||
makeImportant: function() {
|
||||
return new tree.Ruleset(this.selectors, this.rules.map(function (r) {
|
||||
return new Ruleset(this.selectors, this.rules.map(function (r) {
|
||||
if (r.makeImportant) {
|
||||
return r.makeImportant();
|
||||
} else {
|
||||
@@ -221,13 +221,13 @@ tree.Ruleset.prototype = {
|
||||
rulesets: function () {
|
||||
if (!this.rules) { return null; }
|
||||
|
||||
var _Ruleset = tree.Ruleset, _MixinDefinition = tree.mixin.Definition,
|
||||
var _MixinDefinition = tree.mixin.Definition,
|
||||
filtRules = [], rules = this.rules, cnt = rules.length,
|
||||
i, rule;
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
rule = rules[i];
|
||||
if ((rule instanceof _Ruleset) || (rule instanceof _MixinDefinition)) {
|
||||
if ((rule instanceof Ruleset) || (rule instanceof _MixinDefinition)) {
|
||||
filtRules.push(rule);
|
||||
}
|
||||
}
|
||||
@@ -551,4 +551,5 @@ tree.Ruleset.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
})(require('../tree'));
|
||||
return Ruleset;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) {
|
||||
var Selector = function (elements, extendList, condition, index, currentFileInfo, isReferenced) {
|
||||
this.elements = elements;
|
||||
this.extendList = extendList;
|
||||
this.condition = condition;
|
||||
@@ -10,7 +10,7 @@ tree.Selector = function (elements, extendList, condition, index, currentFileInf
|
||||
this.evaldCondition = true;
|
||||
}
|
||||
};
|
||||
tree.Selector.prototype = {
|
||||
Selector.prototype = {
|
||||
type: "Selector",
|
||||
accept: function (visitor) {
|
||||
if (this.elements) {
|
||||
@@ -25,7 +25,7 @@ tree.Selector.prototype = {
|
||||
},
|
||||
createDerived: function(elements, extendList, evaldCondition) {
|
||||
evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;
|
||||
var newSelector = new(tree.Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced);
|
||||
var newSelector = new(Selector)(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, this.isReferenced);
|
||||
newSelector.evaldCondition = evaldCondition;
|
||||
newSelector.mediaEmpty = this.mediaEmpty;
|
||||
return newSelector;
|
||||
@@ -125,5 +125,5 @@ tree.Selector.prototype = {
|
||||
return this.evaldCondition;
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Selector;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.UnicodeDescriptor = function (value) {
|
||||
var UnicodeDescriptor = function (value) {
|
||||
this.value = value;
|
||||
};
|
||||
tree.UnicodeDescriptor.prototype = {
|
||||
UnicodeDescriptor.prototype = {
|
||||
type: "UnicodeDescriptor",
|
||||
genCSS: function (env, output) {
|
||||
output.add(this.value);
|
||||
@@ -11,5 +11,5 @@ tree.UnicodeDescriptor.prototype = {
|
||||
toCSS: tree.toCSS,
|
||||
eval: function () { return this; }
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return UnicodeDescriptor;
|
||||
};
|
||||
|
||||
21
lib/less/tree/unit-conversions.js
Normal file
21
lib/less/tree/unit-conversions.js
Normal file
@@ -0,0 +1,21 @@
|
||||
module.exports = {
|
||||
length: {
|
||||
'm': 1,
|
||||
'cm': 0.01,
|
||||
'mm': 0.001,
|
||||
'in': 0.0254,
|
||||
'px': 0.0254 / 96,
|
||||
'pt': 0.0254 / 72,
|
||||
'pc': 0.0254 / 72 * 12
|
||||
},
|
||||
duration: {
|
||||
's': 1,
|
||||
'ms': 0.001
|
||||
},
|
||||
angle: {
|
||||
'rad': 1/(2*Math.PI),
|
||||
'deg': 1/360,
|
||||
'grad': 1/400,
|
||||
'turn': 1
|
||||
}
|
||||
};
|
||||
137
lib/less/tree/unit.js
Normal file
137
lib/less/tree/unit.js
Normal file
@@ -0,0 +1,137 @@
|
||||
module.exports = function(tree, unitConversions) {
|
||||
|
||||
var Unit = function (numerator, denominator, backupUnit) {
|
||||
this.numerator = numerator ? numerator.slice(0).sort() : [];
|
||||
this.denominator = denominator ? denominator.slice(0).sort() : [];
|
||||
this.backupUnit = backupUnit;
|
||||
};
|
||||
|
||||
Unit.prototype = {
|
||||
type: "Unit",
|
||||
clone: function () {
|
||||
return new Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit);
|
||||
},
|
||||
genCSS: function (env, output) {
|
||||
if (this.numerator.length >= 1) {
|
||||
output.add(this.numerator[0]);
|
||||
} else
|
||||
if (this.denominator.length >= 1) {
|
||||
output.add(this.denominator[0]);
|
||||
} else
|
||||
if ((!env || !env.strictUnits) && this.backupUnit) {
|
||||
output.add(this.backupUnit);
|
||||
}
|
||||
},
|
||||
toCSS: tree.toCSS,
|
||||
|
||||
toString: function () {
|
||||
var i, returnStr = this.numerator.join("*");
|
||||
for (i = 0; i < this.denominator.length; i++) {
|
||||
returnStr += "/" + this.denominator[i];
|
||||
}
|
||||
return returnStr;
|
||||
},
|
||||
|
||||
compare: function (other) {
|
||||
return this.is(other.toString()) ? 0 : -1;
|
||||
},
|
||||
|
||||
is: function (unitString) {
|
||||
return this.toString() === unitString;
|
||||
},
|
||||
|
||||
isLength: function () {
|
||||
return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/));
|
||||
},
|
||||
|
||||
isEmpty: function () {
|
||||
return this.numerator.length === 0 && this.denominator.length === 0;
|
||||
},
|
||||
|
||||
isSingular: function() {
|
||||
return this.numerator.length <= 1 && this.denominator.length === 0;
|
||||
},
|
||||
|
||||
map: function(callback) {
|
||||
var i;
|
||||
|
||||
for (i = 0; i < this.numerator.length; i++) {
|
||||
this.numerator[i] = callback(this.numerator[i], false);
|
||||
}
|
||||
|
||||
for (i = 0; i < this.denominator.length; i++) {
|
||||
this.denominator[i] = callback(this.denominator[i], true);
|
||||
}
|
||||
},
|
||||
|
||||
usedUnits: function() {
|
||||
var group, result = {}, mapUnit;
|
||||
|
||||
mapUnit = function (atomicUnit) {
|
||||
/*jshint loopfunc:true */
|
||||
if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
|
||||
result[groupName] = atomicUnit;
|
||||
}
|
||||
|
||||
return atomicUnit;
|
||||
};
|
||||
|
||||
for (var groupName in unitConversions) {
|
||||
if (unitConversions.hasOwnProperty(groupName)) {
|
||||
group = unitConversions[groupName];
|
||||
|
||||
this.map(mapUnit);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
cancel: function () {
|
||||
var counter = {}, atomicUnit, i, backup;
|
||||
|
||||
for (i = 0; i < this.numerator.length; i++) {
|
||||
atomicUnit = this.numerator[i];
|
||||
if (!backup) {
|
||||
backup = atomicUnit;
|
||||
}
|
||||
counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < this.denominator.length; i++) {
|
||||
atomicUnit = this.denominator[i];
|
||||
if (!backup) {
|
||||
backup = atomicUnit;
|
||||
}
|
||||
counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
|
||||
}
|
||||
|
||||
this.numerator = [];
|
||||
this.denominator = [];
|
||||
|
||||
for (atomicUnit in counter) {
|
||||
if (counter.hasOwnProperty(atomicUnit)) {
|
||||
var count = counter[atomicUnit];
|
||||
|
||||
if (count > 0) {
|
||||
for (i = 0; i < count; i++) {
|
||||
this.numerator.push(atomicUnit);
|
||||
}
|
||||
} else if (count < 0) {
|
||||
for (i = 0; i < -count; i++) {
|
||||
this.denominator.push(atomicUnit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (this.numerator.length === 0 && this.denominator.length === 0 && backup) {
|
||||
this.backupUnit = backup;
|
||||
}
|
||||
|
||||
this.numerator.sort();
|
||||
this.denominator.sort();
|
||||
}
|
||||
};
|
||||
return Unit;
|
||||
};
|
||||
@@ -1,11 +1,11 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.URL = function (val, currentFileInfo, isEvald) {
|
||||
var URL = function (val, currentFileInfo, isEvald) {
|
||||
this.value = val;
|
||||
this.currentFileInfo = currentFileInfo;
|
||||
this.isEvald = isEvald;
|
||||
};
|
||||
tree.URL.prototype = {
|
||||
URL.prototype = {
|
||||
type: "Url",
|
||||
accept: function (visitor) {
|
||||
this.value = visitor.visit(this.value);
|
||||
@@ -46,8 +46,8 @@ tree.URL.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
return new(tree.URL)(val, this.currentFileInfo, true);
|
||||
return new(URL)(val, this.currentFileInfo, true);
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return URL;
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Value = function (value) {
|
||||
var Value = function (value) {
|
||||
this.value = value;
|
||||
};
|
||||
tree.Value.prototype = {
|
||||
Value.prototype = {
|
||||
type: "Value",
|
||||
accept: function (visitor) {
|
||||
if (this.value) {
|
||||
@@ -14,7 +14,7 @@ tree.Value.prototype = {
|
||||
if (this.value.length === 1) {
|
||||
return this.value[0].eval(env);
|
||||
} else {
|
||||
return new(tree.Value)(this.value.map(function (v) {
|
||||
return new(Value)(this.value.map(function (v) {
|
||||
return v.eval(env);
|
||||
}));
|
||||
}
|
||||
@@ -30,5 +30,5 @@ tree.Value.prototype = {
|
||||
},
|
||||
toCSS: tree.toCSS
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Value;
|
||||
};
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
tree.Variable = function (name, index, currentFileInfo) {
|
||||
var Variable = function (name, index, currentFileInfo) {
|
||||
this.name = name;
|
||||
this.index = index;
|
||||
this.currentFileInfo = currentFileInfo || {};
|
||||
};
|
||||
tree.Variable.prototype = {
|
||||
Variable.prototype = {
|
||||
type: "Variable",
|
||||
eval: function (env) {
|
||||
var variable, name = this.name;
|
||||
|
||||
if (name.indexOf('@@') === 0) {
|
||||
name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
|
||||
name = '@' + new(Variable)(name.slice(1)).eval(env).value;
|
||||
}
|
||||
|
||||
if (this.evaluating) {
|
||||
@@ -40,5 +40,5 @@ tree.Variable.prototype = {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(require('../tree'));
|
||||
return Variable;
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
(function (tree) {
|
||||
module.exports = function (tree) {
|
||||
|
||||
var _visitArgs = { visitDeeper: true },
|
||||
_hasIndexed = false;
|
||||
@@ -143,4 +143,4 @@
|
||||
}
|
||||
};
|
||||
|
||||
})(require('./tree'));
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user