less-js-source 1.1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +1 -0
- data/less-js-source.gemspec +1 -1
- data/lib/less_js/less.js +579 -572
- metadata +4 -5
data/Gemfile
CHANGED
data/less-js-source.gemspec
CHANGED
data/lib/less_js/less.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
//
|
2
|
-
// LESS - Leaner CSS v1.1.
|
2
|
+
// LESS - Leaner CSS v1.1.2
|
3
3
|
// http://lesscss.org
|
4
4
|
//
|
5
5
|
// Copyright (c) 2009-2011, Alexis Sellier
|
@@ -625,7 +625,7 @@ less.Parser = function Parser(env) {
|
|
625
625
|
// The arguments are parsed with the `entities.arguments` parser.
|
626
626
|
//
|
627
627
|
call: function () {
|
628
|
-
var name, args;
|
628
|
+
var name, args, index = i;
|
629
629
|
|
630
630
|
if (! (name = /^([\w-]+|%)\(/.exec(chunks[j]))) return;
|
631
631
|
|
@@ -642,7 +642,7 @@ less.Parser = function Parser(env) {
|
|
642
642
|
|
643
643
|
if (! $(')')) return;
|
644
644
|
|
645
|
-
if (name) { return new(tree.Call)(name, args) }
|
645
|
+
if (name) { return new(tree.Call)(name, args, index) }
|
646
646
|
},
|
647
647
|
arguments: function () {
|
648
648
|
var args = [], arg;
|
@@ -1231,6 +1231,78 @@ if (typeof(window) !== 'undefined') {
|
|
1231
1231
|
};
|
1232
1232
|
}
|
1233
1233
|
|
1234
|
+
(function (tree) {
|
1235
|
+
|
1236
|
+
tree.Alpha = function (val) {
|
1237
|
+
this.value = val;
|
1238
|
+
};
|
1239
|
+
tree.Alpha.prototype = {
|
1240
|
+
toCSS: function () {
|
1241
|
+
return "alpha(opacity=" +
|
1242
|
+
(this.value.toCSS ? this.value.toCSS() : this.value) + ")";
|
1243
|
+
},
|
1244
|
+
eval: function () { return this }
|
1245
|
+
};
|
1246
|
+
|
1247
|
+
})(require('less/tree'));
|
1248
|
+
(function (tree) {
|
1249
|
+
|
1250
|
+
tree.Anonymous = function (string) {
|
1251
|
+
this.value = string.value || string;
|
1252
|
+
};
|
1253
|
+
tree.Anonymous.prototype = {
|
1254
|
+
toCSS: function () {
|
1255
|
+
return this.value;
|
1256
|
+
},
|
1257
|
+
eval: function () { return this }
|
1258
|
+
};
|
1259
|
+
|
1260
|
+
})(require('less/tree'));
|
1261
|
+
(function (tree) {
|
1262
|
+
|
1263
|
+
//
|
1264
|
+
// A function call node.
|
1265
|
+
//
|
1266
|
+
tree.Call = function (name, args, index) {
|
1267
|
+
this.name = name;
|
1268
|
+
this.args = args;
|
1269
|
+
this.index = index;
|
1270
|
+
};
|
1271
|
+
tree.Call.prototype = {
|
1272
|
+
//
|
1273
|
+
// When evaluating a function call,
|
1274
|
+
// we either find the function in `tree.functions` [1],
|
1275
|
+
// in which case we call it, passing the evaluated arguments,
|
1276
|
+
// or we simply print it out as it appeared originally [2].
|
1277
|
+
//
|
1278
|
+
// The *functions.js* file contains the built-in functions.
|
1279
|
+
//
|
1280
|
+
// The reason why we evaluate the arguments, is in the case where
|
1281
|
+
// we try to pass a variable to a function, like: `saturate(@color)`.
|
1282
|
+
// The function should receive the value, not the variable.
|
1283
|
+
//
|
1284
|
+
eval: function (env) {
|
1285
|
+
var args = this.args.map(function (a) { return a.eval(env) });
|
1286
|
+
|
1287
|
+
if (this.name in tree.functions) { // 1.
|
1288
|
+
try {
|
1289
|
+
return tree.functions[this.name].apply(tree.functions, args);
|
1290
|
+
} catch (e) {
|
1291
|
+
throw { message: "error evaluating function `" + this.name + "`",
|
1292
|
+
index: this.index };
|
1293
|
+
}
|
1294
|
+
} else { // 2.
|
1295
|
+
return new(tree.Anonymous)(this.name +
|
1296
|
+
"(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
|
1297
|
+
}
|
1298
|
+
},
|
1299
|
+
|
1300
|
+
toCSS: function (env) {
|
1301
|
+
return this.eval(env).toCSS();
|
1302
|
+
}
|
1303
|
+
};
|
1304
|
+
|
1305
|
+
})(require('less/tree'));
|
1234
1306
|
(function (tree) {
|
1235
1307
|
//
|
1236
1308
|
// RGB Colors - #ff0014, #eee
|
@@ -1331,66 +1403,15 @@ tree.Color.prototype = {
|
|
1331
1403
|
})(require('less/tree'));
|
1332
1404
|
(function (tree) {
|
1333
1405
|
|
1334
|
-
tree.
|
1335
|
-
this.
|
1336
|
-
|
1337
|
-
this.ruleset = new(tree.Ruleset)([], value);
|
1338
|
-
} else {
|
1339
|
-
this.value = value;
|
1340
|
-
}
|
1406
|
+
tree.Comment = function (value, silent) {
|
1407
|
+
this.value = value;
|
1408
|
+
this.silent = !!silent;
|
1341
1409
|
};
|
1342
|
-
tree.
|
1343
|
-
toCSS: function (
|
1344
|
-
|
1345
|
-
this.ruleset.root = true;
|
1346
|
-
return this.name + (env.compress ? '{' : ' {\n ') +
|
1347
|
-
this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
|
1348
|
-
(env.compress ? '}': '\n}\n');
|
1349
|
-
} else {
|
1350
|
-
return this.name + ' ' + this.value.toCSS() + ';\n';
|
1351
|
-
}
|
1352
|
-
},
|
1353
|
-
eval: function (env) {
|
1354
|
-
env.frames.unshift(this);
|
1355
|
-
this.ruleset = this.ruleset && this.ruleset.eval(env);
|
1356
|
-
env.frames.shift();
|
1357
|
-
return this;
|
1410
|
+
tree.Comment.prototype = {
|
1411
|
+
toCSS: function (env) {
|
1412
|
+
return env.compress ? '' : this.value;
|
1358
1413
|
},
|
1359
|
-
|
1360
|
-
find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
|
1361
|
-
rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
|
1362
|
-
};
|
1363
|
-
|
1364
|
-
})(require('less/tree'));
|
1365
|
-
(function (tree) {
|
1366
|
-
|
1367
|
-
tree.Operation = function (op, operands) {
|
1368
|
-
this.op = op.trim();
|
1369
|
-
this.operands = operands;
|
1370
|
-
};
|
1371
|
-
tree.Operation.prototype.eval = function (env) {
|
1372
|
-
var a = this.operands[0].eval(env),
|
1373
|
-
b = this.operands[1].eval(env),
|
1374
|
-
temp;
|
1375
|
-
|
1376
|
-
if (a instanceof tree.Dimension && b instanceof tree.Color) {
|
1377
|
-
if (this.op === '*' || this.op === '+') {
|
1378
|
-
temp = b, b = a, a = temp;
|
1379
|
-
} else {
|
1380
|
-
throw { name: "OperationError",
|
1381
|
-
message: "Can't substract or divide a color from a number" };
|
1382
|
-
}
|
1383
|
-
}
|
1384
|
-
return a.operate(this.op, b);
|
1385
|
-
};
|
1386
|
-
|
1387
|
-
tree.operate = function (op, a, b) {
|
1388
|
-
switch (op) {
|
1389
|
-
case '+': return a + b;
|
1390
|
-
case '-': return a - b;
|
1391
|
-
case '*': return a * b;
|
1392
|
-
case '/': return a / b;
|
1393
|
-
}
|
1414
|
+
eval: function () { return this }
|
1394
1415
|
};
|
1395
1416
|
|
1396
1417
|
})(require('less/tree'));
|
@@ -1430,273 +1451,364 @@ tree.Dimension.prototype = {
|
|
1430
1451
|
})(require('less/tree'));
|
1431
1452
|
(function (tree) {
|
1432
1453
|
|
1433
|
-
tree.
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1454
|
+
tree.Directive = function (name, value) {
|
1455
|
+
this.name = name;
|
1456
|
+
if (Array.isArray(value)) {
|
1457
|
+
this.ruleset = new(tree.Ruleset)([], value);
|
1458
|
+
} else {
|
1459
|
+
this.value = value;
|
1460
|
+
}
|
1461
|
+
};
|
1462
|
+
tree.Directive.prototype = {
|
1463
|
+
toCSS: function (ctx, env) {
|
1464
|
+
if (this.ruleset) {
|
1465
|
+
this.ruleset.root = true;
|
1466
|
+
return this.name + (env.compress ? '{' : ' {\n ') +
|
1467
|
+
this.ruleset.toCSS(ctx, env).trim().replace(/\n/g, '\n ') +
|
1468
|
+
(env.compress ? '}': '\n}\n');
|
1469
|
+
} else {
|
1470
|
+
return this.name + ' ' + this.value.toCSS() + ';\n';
|
1471
|
+
}
|
1472
|
+
},
|
1473
|
+
eval: function (env) {
|
1474
|
+
env.frames.unshift(this);
|
1475
|
+
this.ruleset = this.ruleset && this.ruleset.eval(env);
|
1476
|
+
env.frames.shift();
|
1477
|
+
return this;
|
1478
|
+
},
|
1479
|
+
variable: function (name) { return tree.Ruleset.prototype.variable.call(this.ruleset, name) },
|
1480
|
+
find: function () { return tree.Ruleset.prototype.find.apply(this.ruleset, arguments) },
|
1481
|
+
rulesets: function () { return tree.Ruleset.prototype.rulesets.apply(this.ruleset) }
|
1437
1482
|
};
|
1438
1483
|
|
1439
1484
|
})(require('less/tree'));
|
1440
1485
|
(function (tree) {
|
1441
1486
|
|
1442
|
-
tree.
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1487
|
+
tree.Element = function (combinator, value) {
|
1488
|
+
this.combinator = combinator instanceof tree.Combinator ?
|
1489
|
+
combinator : new(tree.Combinator)(combinator);
|
1490
|
+
this.value = value.trim();
|
1491
|
+
};
|
1492
|
+
tree.Element.prototype.toCSS = function (env) {
|
1493
|
+
return this.combinator.toCSS(env || {}) + this.value;
|
1494
|
+
};
|
1450
1495
|
|
1451
|
-
|
1452
|
-
|
1453
|
-
|
1454
|
-
|
1455
|
-
|
1456
|
-
else {
|
1457
|
-
throw { message: "variable " + name + " is undefined",
|
1458
|
-
index: this.index };
|
1459
|
-
}
|
1496
|
+
tree.Combinator = function (value) {
|
1497
|
+
if (value === ' ') {
|
1498
|
+
this.value = ' ';
|
1499
|
+
} else {
|
1500
|
+
this.value = value ? value.trim() : "";
|
1460
1501
|
}
|
1461
1502
|
};
|
1503
|
+
tree.Combinator.prototype.toCSS = function (env) {
|
1504
|
+
return {
|
1505
|
+
'' : '',
|
1506
|
+
' ' : ' ',
|
1507
|
+
'&' : '',
|
1508
|
+
':' : ' :',
|
1509
|
+
'::': '::',
|
1510
|
+
'+' : env.compress ? '+' : ' + ',
|
1511
|
+
'~' : env.compress ? '~' : ' ~ ',
|
1512
|
+
'>' : env.compress ? '>' : ' > '
|
1513
|
+
}[this.value];
|
1514
|
+
};
|
1462
1515
|
|
1463
1516
|
})(require('less/tree'));
|
1464
1517
|
(function (tree) {
|
1465
1518
|
|
1466
|
-
tree.
|
1467
|
-
|
1468
|
-
this.rules = rules;
|
1469
|
-
this._lookups = {};
|
1470
|
-
};
|
1471
|
-
tree.Ruleset.prototype = {
|
1519
|
+
tree.Expression = function (value) { this.value = value };
|
1520
|
+
tree.Expression.prototype = {
|
1472
1521
|
eval: function (env) {
|
1473
|
-
|
1522
|
+
if (this.value.length > 1) {
|
1523
|
+
return new(tree.Expression)(this.value.map(function (e) {
|
1524
|
+
return e.eval(env);
|
1525
|
+
}));
|
1526
|
+
} else if (this.value.length === 1) {
|
1527
|
+
return this.value[0].eval(env);
|
1528
|
+
} else {
|
1529
|
+
return this;
|
1530
|
+
}
|
1531
|
+
},
|
1532
|
+
toCSS: function (env) {
|
1533
|
+
return this.value.map(function (e) {
|
1534
|
+
return e.toCSS(env);
|
1535
|
+
}).join(' ');
|
1536
|
+
}
|
1537
|
+
};
|
1474
1538
|
|
1475
|
-
|
1539
|
+
})(require('less/tree'));
|
1540
|
+
(function (tree) {
|
1541
|
+
//
|
1542
|
+
// CSS @import node
|
1543
|
+
//
|
1544
|
+
// The general strategy here is that we don't want to wait
|
1545
|
+
// for the parsing to be completed, before we start importing
|
1546
|
+
// the file. That's because in the context of a browser,
|
1547
|
+
// most of the time will be spent waiting for the server to respond.
|
1548
|
+
//
|
1549
|
+
// On creation, we push the import path to our import queue, though
|
1550
|
+
// `import,push`, we also pass it a callback, which it'll call once
|
1551
|
+
// the file has been fetched, and parsed.
|
1552
|
+
//
|
1553
|
+
tree.Import = function (path, imports) {
|
1554
|
+
var that = this;
|
1476
1555
|
|
1477
|
-
|
1478
|
-
env.frames.unshift(ruleset);
|
1556
|
+
this._path = path;
|
1479
1557
|
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
}
|
1487
|
-
}
|
1488
|
-
}
|
1558
|
+
// The '.less' extension is optional
|
1559
|
+
if (path instanceof tree.Quoted) {
|
1560
|
+
this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
|
1561
|
+
} else {
|
1562
|
+
this.path = path.value.value || path.value;
|
1563
|
+
}
|
1489
1564
|
|
1490
|
-
|
1491
|
-
// so they can be evaluated like closures when the time comes.
|
1492
|
-
for (var i = 0; i < ruleset.rules.length; i++) {
|
1493
|
-
if (ruleset.rules[i] instanceof tree.mixin.Definition) {
|
1494
|
-
ruleset.rules[i].frames = env.frames.slice(0);
|
1495
|
-
}
|
1496
|
-
}
|
1565
|
+
this.css = /css$/.test(this.path);
|
1497
1566
|
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1567
|
+
// Only pre-compile .less files
|
1568
|
+
if (! this.css) {
|
1569
|
+
imports.push(this.path, function (root) {
|
1570
|
+
if (! root) {
|
1571
|
+
throw new(Error)("Error parsing " + that.path);
|
1503
1572
|
}
|
1573
|
+
that.root = root;
|
1574
|
+
});
|
1575
|
+
}
|
1576
|
+
};
|
1577
|
+
|
1578
|
+
//
|
1579
|
+
// The actual import node doesn't return anything, when converted to CSS.
|
1580
|
+
// The reason is that it's used at the evaluation stage, so that the rules
|
1581
|
+
// it imports can be treated like any other rules.
|
1582
|
+
//
|
1583
|
+
// In `eval`, we make sure all Import nodes get evaluated, recursively, so
|
1584
|
+
// we end up with a flat structure, which can easily be imported in the parent
|
1585
|
+
// ruleset.
|
1586
|
+
//
|
1587
|
+
tree.Import.prototype = {
|
1588
|
+
toCSS: function () {
|
1589
|
+
if (this.css) {
|
1590
|
+
return "@import " + this._path.toCSS() + ';\n';
|
1591
|
+
} else {
|
1592
|
+
return "";
|
1504
1593
|
}
|
1594
|
+
},
|
1595
|
+
eval: function (env) {
|
1596
|
+
var ruleset;
|
1505
1597
|
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
1598
|
+
if (this.css) {
|
1599
|
+
return this;
|
1600
|
+
} else {
|
1601
|
+
ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
|
1509
1602
|
|
1510
|
-
|
1511
|
-
ruleset.rules[i]
|
1603
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
1604
|
+
if (ruleset.rules[i] instanceof tree.Import) {
|
1605
|
+
Array.prototype
|
1606
|
+
.splice
|
1607
|
+
.apply(ruleset.rules,
|
1608
|
+
[i, 1].concat(ruleset.rules[i].eval(env)));
|
1609
|
+
}
|
1512
1610
|
}
|
1611
|
+
return ruleset.rules;
|
1513
1612
|
}
|
1613
|
+
}
|
1614
|
+
};
|
1514
1615
|
|
1515
|
-
|
1516
|
-
|
1616
|
+
})(require('less/tree'));
|
1617
|
+
(function (tree) {
|
1517
1618
|
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1619
|
+
tree.JavaScript = function (string, index, escaped) {
|
1620
|
+
this.escaped = escaped;
|
1621
|
+
this.expression = string;
|
1622
|
+
this.index = index;
|
1623
|
+
};
|
1624
|
+
tree.JavaScript.prototype = {
|
1625
|
+
eval: function (env) {
|
1626
|
+
var result,
|
1627
|
+
that = this,
|
1628
|
+
context = {};
|
1629
|
+
|
1630
|
+
var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
|
1631
|
+
return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
|
1632
|
+
});
|
1633
|
+
|
1634
|
+
try {
|
1635
|
+
expression = new(Function)('return (' + expression + ')');
|
1636
|
+
} catch (e) {
|
1637
|
+
throw { message: "JavaScript evaluation error: `" + expression + "`" ,
|
1638
|
+
index: this.index };
|
1639
|
+
}
|
1640
|
+
|
1641
|
+
for (var k in env.frames[0].variables()) {
|
1642
|
+
context[k.slice(1)] = {
|
1643
|
+
value: env.frames[0].variables()[k].value,
|
1644
|
+
toJS: function () {
|
1645
|
+
return this.value.eval(env).toCSS();
|
1529
1646
|
}
|
1530
|
-
|
1531
|
-
}, {});
|
1647
|
+
};
|
1532
1648
|
}
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1538
|
-
|
1539
|
-
else {
|
1540
|
-
return this._rulesets = this.rules.filter(function (r) {
|
1541
|
-
return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
|
1542
|
-
});
|
1649
|
+
|
1650
|
+
try {
|
1651
|
+
result = expression.call(context);
|
1652
|
+
} catch (e) {
|
1653
|
+
throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
|
1654
|
+
index: this.index };
|
1543
1655
|
}
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1656
|
+
if (typeof(result) === 'string') {
|
1657
|
+
return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
|
1658
|
+
} else if (Array.isArray(result)) {
|
1659
|
+
return new(tree.Anonymous)(result.join(', '));
|
1660
|
+
} else {
|
1661
|
+
return new(tree.Anonymous)(result);
|
1662
|
+
}
|
1663
|
+
}
|
1664
|
+
};
|
1549
1665
|
|
1550
|
-
|
1666
|
+
})(require('less/tree'));
|
1551
1667
|
|
1552
|
-
|
1553
|
-
if (rule !== self) {
|
1554
|
-
for (var j = 0; j < rule.selectors.length; j++) {
|
1555
|
-
if (match = selector.match(rule.selectors[j])) {
|
1556
|
-
if (selector.elements.length > 1) {
|
1557
|
-
Array.prototype.push.apply(rules, rule.find(
|
1558
|
-
new(tree.Selector)(selector.elements.slice(1)), self));
|
1559
|
-
} else {
|
1560
|
-
rules.push(rule);
|
1561
|
-
}
|
1562
|
-
break;
|
1563
|
-
}
|
1564
|
-
}
|
1565
|
-
}
|
1566
|
-
});
|
1567
|
-
return this._lookups[key] = rules;
|
1568
|
-
},
|
1569
|
-
//
|
1570
|
-
// Entry point for code generation
|
1571
|
-
//
|
1572
|
-
// `context` holds an array of arrays.
|
1573
|
-
//
|
1574
|
-
toCSS: function (context, env) {
|
1575
|
-
var css = [], // The CSS output
|
1576
|
-
rules = [], // node.Rule instances
|
1577
|
-
rulesets = [], // node.Ruleset instances
|
1578
|
-
paths = [], // Current selectors
|
1579
|
-
selector, // The fully rendered selector
|
1580
|
-
rule;
|
1668
|
+
(function (tree) {
|
1581
1669
|
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
for (var c = 0; c < context.length; c++) {
|
1588
|
-
paths.push(context[c].concat([this.selectors[s]]));
|
1589
|
-
}
|
1590
|
-
}
|
1591
|
-
}
|
1592
|
-
}
|
1670
|
+
tree.Keyword = function (value) { this.value = value };
|
1671
|
+
tree.Keyword.prototype = {
|
1672
|
+
eval: function () { return this },
|
1673
|
+
toCSS: function () { return this.value }
|
1674
|
+
};
|
1593
1675
|
|
1594
|
-
|
1595
|
-
|
1596
|
-
rule = this.rules[i];
|
1676
|
+
})(require('less/tree'));
|
1677
|
+
(function (tree) {
|
1597
1678
|
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1679
|
+
tree.mixin = {};
|
1680
|
+
tree.mixin.Call = function (elements, args, index) {
|
1681
|
+
this.selector = new(tree.Selector)(elements);
|
1682
|
+
this.arguments = args;
|
1683
|
+
this.index = index;
|
1684
|
+
};
|
1685
|
+
tree.mixin.Call.prototype = {
|
1686
|
+
eval: function (env) {
|
1687
|
+
var mixins, args, rules = [], match = false;
|
1688
|
+
|
1689
|
+
for (var i = 0; i < env.frames.length; i++) {
|
1690
|
+
if ((mixins = env.frames[i].find(this.selector)).length > 0) {
|
1691
|
+
args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
|
1692
|
+
for (var m = 0; m < mixins.length; m++) {
|
1693
|
+
if (mixins[m].match(args, env)) {
|
1694
|
+
try {
|
1695
|
+
Array.prototype.push.apply(
|
1696
|
+
rules, mixins[m].eval(env, this.arguments).rules);
|
1697
|
+
match = true;
|
1698
|
+
} catch (e) {
|
1699
|
+
throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
|
1700
|
+
}
|
1606
1701
|
}
|
1607
1702
|
}
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1612
|
-
|
1703
|
+
if (match) {
|
1704
|
+
return rules;
|
1705
|
+
} else {
|
1706
|
+
throw { message: 'No matching definition was found for `' +
|
1707
|
+
this.selector.toCSS().trim() + '(' +
|
1708
|
+
this.arguments.map(function (a) {
|
1709
|
+
return a.toCSS();
|
1710
|
+
}).join(', ') + ")`",
|
1711
|
+
index: this.index };
|
1613
1712
|
}
|
1614
1713
|
}
|
1615
|
-
}
|
1714
|
+
}
|
1715
|
+
throw { message: this.selector.toCSS().trim() + " is undefined",
|
1716
|
+
index: this.index };
|
1717
|
+
}
|
1718
|
+
};
|
1616
1719
|
|
1617
|
-
|
1720
|
+
tree.mixin.Definition = function (name, params, rules) {
|
1721
|
+
this.name = name;
|
1722
|
+
this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
|
1723
|
+
this.params = params;
|
1724
|
+
this.arity = params.length;
|
1725
|
+
this.rules = rules;
|
1726
|
+
this._lookups = {};
|
1727
|
+
this.required = params.reduce(function (count, p) {
|
1728
|
+
if (!p.name || (p.name && !p.value)) { return count + 1 }
|
1729
|
+
else { return count }
|
1730
|
+
}, 0);
|
1731
|
+
this.parent = tree.Ruleset.prototype;
|
1732
|
+
this.frames = [];
|
1733
|
+
};
|
1734
|
+
tree.mixin.Definition.prototype = {
|
1735
|
+
toCSS: function () { return "" },
|
1736
|
+
variable: function (name) { return this.parent.variable.call(this, name) },
|
1737
|
+
variables: function () { return this.parent.variables.call(this) },
|
1738
|
+
find: function () { return this.parent.find.apply(this, arguments) },
|
1739
|
+
rulesets: function () { return this.parent.rulesets.apply(this) },
|
1618
1740
|
|
1619
|
-
|
1620
|
-
|
1621
|
-
|
1622
|
-
|
1623
|
-
|
1624
|
-
|
1625
|
-
|
1626
|
-
|
1627
|
-
|
1628
|
-
|
1629
|
-
|
1630
|
-
}).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
|
1631
|
-
css.push(selector,
|
1632
|
-
(env.compress ? '{' : ' {\n ') +
|
1633
|
-
rules.join(env.compress ? '' : '\n ') +
|
1634
|
-
(env.compress ? '}' : '\n}\n'));
|
1741
|
+
eval: function (env, args) {
|
1742
|
+
var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
|
1743
|
+
|
1744
|
+
for (var i = 0, val; i < this.params.length; i++) {
|
1745
|
+
if (this.params[i].name) {
|
1746
|
+
if (val = (args && args[i]) || this.params[i].value) {
|
1747
|
+
frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
|
1748
|
+
} else {
|
1749
|
+
throw { message: "wrong number of arguments for " + this.name +
|
1750
|
+
' (' + args.length + ' for ' + this.arity + ')' };
|
1751
|
+
}
|
1635
1752
|
}
|
1636
1753
|
}
|
1637
|
-
|
1754
|
+
for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
|
1755
|
+
_arguments.push(args[i] || this.params[i].value);
|
1756
|
+
}
|
1757
|
+
frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
1638
1758
|
|
1639
|
-
return
|
1640
|
-
|
1641
|
-
};
|
1642
|
-
}
|
1643
|
-
|
1759
|
+
return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
|
1760
|
+
frames: [this, frame].concat(this.frames, env.frames)
|
1761
|
+
});
|
1762
|
+
},
|
1763
|
+
match: function (args, env) {
|
1764
|
+
var argsLength = (args && args.length) || 0, len;
|
1644
1765
|
|
1645
|
-
|
1646
|
-
|
1647
|
-
combinator : new(tree.Combinator)(combinator);
|
1648
|
-
this.value = value.trim();
|
1649
|
-
};
|
1650
|
-
tree.Element.prototype.toCSS = function (env) {
|
1651
|
-
return this.combinator.toCSS(env || {}) + this.value;
|
1652
|
-
};
|
1766
|
+
if (argsLength < this.required) { return false }
|
1767
|
+
if ((this.required > 0) && (argsLength > this.params.length)) { return false }
|
1653
1768
|
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
1769
|
+
len = Math.min(argsLength, this.arity);
|
1770
|
+
|
1771
|
+
for (var i = 0; i < len; i++) {
|
1772
|
+
if (!this.params[i].name) {
|
1773
|
+
if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
|
1774
|
+
return false;
|
1775
|
+
}
|
1776
|
+
}
|
1777
|
+
}
|
1778
|
+
return true;
|
1659
1779
|
}
|
1660
1780
|
};
|
1661
|
-
tree.Combinator.prototype.toCSS = function (env) {
|
1662
|
-
return {
|
1663
|
-
'' : '',
|
1664
|
-
' ' : ' ',
|
1665
|
-
'&' : '',
|
1666
|
-
':' : ' :',
|
1667
|
-
'::': '::',
|
1668
|
-
'+' : env.compress ? '+' : ' + ',
|
1669
|
-
'~' : env.compress ? '~' : ' ~ ',
|
1670
|
-
'>' : env.compress ? '>' : ' > '
|
1671
|
-
}[this.value];
|
1672
|
-
};
|
1673
1781
|
|
1674
1782
|
})(require('less/tree'));
|
1675
1783
|
(function (tree) {
|
1676
1784
|
|
1677
|
-
tree.
|
1678
|
-
this.
|
1679
|
-
|
1680
|
-
this.elements[0].combinator.value = ' ';
|
1681
|
-
}
|
1682
|
-
};
|
1683
|
-
tree.Selector.prototype.match = function (other) {
|
1684
|
-
if (this.elements[0].value === other.elements[0].value) {
|
1685
|
-
return true;
|
1686
|
-
} else {
|
1687
|
-
return false;
|
1688
|
-
}
|
1785
|
+
tree.Operation = function (op, operands) {
|
1786
|
+
this.op = op.trim();
|
1787
|
+
this.operands = operands;
|
1689
1788
|
};
|
1690
|
-
tree.
|
1691
|
-
|
1789
|
+
tree.Operation.prototype.eval = function (env) {
|
1790
|
+
var a = this.operands[0].eval(env),
|
1791
|
+
b = this.operands[1].eval(env),
|
1792
|
+
temp;
|
1692
1793
|
|
1693
|
-
|
1694
|
-
if (
|
1695
|
-
|
1794
|
+
if (a instanceof tree.Dimension && b instanceof tree.Color) {
|
1795
|
+
if (this.op === '*' || this.op === '+') {
|
1796
|
+
temp = b, b = a, a = temp;
|
1696
1797
|
} else {
|
1697
|
-
|
1798
|
+
throw { name: "OperationError",
|
1799
|
+
message: "Can't substract or divide a color from a number" };
|
1698
1800
|
}
|
1699
|
-
}
|
1801
|
+
}
|
1802
|
+
return a.operate(this.op, b);
|
1803
|
+
};
|
1804
|
+
|
1805
|
+
tree.operate = function (op, a, b) {
|
1806
|
+
switch (op) {
|
1807
|
+
case '+': return a + b;
|
1808
|
+
case '-': return a - b;
|
1809
|
+
case '*': return a * b;
|
1810
|
+
case '/': return a / b;
|
1811
|
+
}
|
1700
1812
|
};
|
1701
1813
|
|
1702
1814
|
})(require('less/tree'));
|
@@ -1731,29 +1843,6 @@ tree.Quoted.prototype = {
|
|
1731
1843
|
})(require('less/tree'));
|
1732
1844
|
(function (tree) {
|
1733
1845
|
|
1734
|
-
tree.Expression = function (value) { this.value = value };
|
1735
|
-
tree.Expression.prototype = {
|
1736
|
-
eval: function (env) {
|
1737
|
-
if (this.value.length > 1) {
|
1738
|
-
return new(tree.Expression)(this.value.map(function (e) {
|
1739
|
-
return e.eval(env);
|
1740
|
-
}));
|
1741
|
-
} else if (this.value.length === 1) {
|
1742
|
-
return this.value[0].eval(env);
|
1743
|
-
} else {
|
1744
|
-
return this;
|
1745
|
-
}
|
1746
|
-
},
|
1747
|
-
toCSS: function (env) {
|
1748
|
-
return this.value.map(function (e) {
|
1749
|
-
return e.toCSS(env);
|
1750
|
-
}).join(' ');
|
1751
|
-
}
|
1752
|
-
};
|
1753
|
-
|
1754
|
-
})(require('less/tree'));
|
1755
|
-
(function (tree) {
|
1756
|
-
|
1757
1846
|
tree.Rule = function (name, value, important, index) {
|
1758
1847
|
this.name = name;
|
1759
1848
|
this.value = (value instanceof tree.Value) ? value : new(tree.Value)([value]);
|
@@ -1792,288 +1881,233 @@ tree.Shorthand.prototype = {
|
|
1792
1881
|
})(require('less/tree'));
|
1793
1882
|
(function (tree) {
|
1794
1883
|
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
this.name = name;
|
1800
|
-
this.args = args;
|
1884
|
+
tree.Ruleset = function (selectors, rules) {
|
1885
|
+
this.selectors = selectors;
|
1886
|
+
this.rules = rules;
|
1887
|
+
this._lookups = {};
|
1801
1888
|
};
|
1802
|
-
tree.
|
1803
|
-
//
|
1804
|
-
// When evaluating a function call,
|
1805
|
-
// we either find the function in `tree.functions` [1],
|
1806
|
-
// in which case we call it, passing the evaluated arguments,
|
1807
|
-
// or we simply print it out as it appeared originally [2].
|
1808
|
-
//
|
1809
|
-
// The *functions.js* file contains the built-in functions.
|
1810
|
-
//
|
1811
|
-
// The reason why we evaluate the arguments, is in the case where
|
1812
|
-
// we try to pass a variable to a function, like: `saturate(@color)`.
|
1813
|
-
// The function should receive the value, not the variable.
|
1814
|
-
//
|
1889
|
+
tree.Ruleset.prototype = {
|
1815
1890
|
eval: function (env) {
|
1816
|
-
var
|
1817
|
-
|
1818
|
-
if (this.name in tree.functions) { // 1.
|
1819
|
-
return tree.functions[this.name].apply(tree.functions, args);
|
1820
|
-
} else { // 2.
|
1821
|
-
return new(tree.Anonymous)(this.name +
|
1822
|
-
"(" + args.map(function (a) { return a.toCSS() }).join(', ') + ")");
|
1823
|
-
}
|
1824
|
-
},
|
1891
|
+
var ruleset = new(tree.Ruleset)(this.selectors, this.rules.slice(0));
|
1825
1892
|
|
1826
|
-
|
1827
|
-
return this.eval(env).toCSS();
|
1828
|
-
}
|
1829
|
-
};
|
1893
|
+
ruleset.root = this.root;
|
1830
1894
|
|
1831
|
-
|
1832
|
-
(
|
1895
|
+
// push the current ruleset to the frames stack
|
1896
|
+
env.frames.unshift(ruleset);
|
1833
1897
|
|
1834
|
-
|
1835
|
-
|
1836
|
-
|
1837
|
-
|
1838
|
-
|
1839
|
-
|
1840
|
-
|
1898
|
+
// Evaluate imports
|
1899
|
+
if (ruleset.root) {
|
1900
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
1901
|
+
if (ruleset.rules[i] instanceof tree.Import) {
|
1902
|
+
Array.prototype.splice
|
1903
|
+
.apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
|
1904
|
+
}
|
1905
|
+
}
|
1841
1906
|
}
|
1842
|
-
this.value = val;
|
1843
|
-
this.paths = paths;
|
1844
|
-
}
|
1845
|
-
};
|
1846
|
-
tree.URL.prototype = {
|
1847
|
-
toCSS: function () {
|
1848
|
-
return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
|
1849
|
-
: this.value.toCSS()) + ")";
|
1850
|
-
},
|
1851
|
-
eval: function (ctx) {
|
1852
|
-
return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
|
1853
|
-
}
|
1854
|
-
};
|
1855
|
-
|
1856
|
-
})(require('less/tree'));
|
1857
|
-
(function (tree) {
|
1858
|
-
|
1859
|
-
tree.Alpha = function (val) {
|
1860
|
-
this.value = val;
|
1861
|
-
};
|
1862
|
-
tree.Alpha.prototype = {
|
1863
|
-
toCSS: function () {
|
1864
|
-
return "alpha(opacity=" +
|
1865
|
-
(this.value.toCSS ? this.value.toCSS() : this.value) + ")";
|
1866
|
-
},
|
1867
|
-
eval: function () { return this }
|
1868
|
-
};
|
1869
|
-
|
1870
|
-
})(require('less/tree'));
|
1871
|
-
(function (tree) {
|
1872
|
-
//
|
1873
|
-
// CSS @import node
|
1874
|
-
//
|
1875
|
-
// The general strategy here is that we don't want to wait
|
1876
|
-
// for the parsing to be completed, before we start importing
|
1877
|
-
// the file. That's because in the context of a browser,
|
1878
|
-
// most of the time will be spent waiting for the server to respond.
|
1879
|
-
//
|
1880
|
-
// On creation, we push the import path to our import queue, though
|
1881
|
-
// `import,push`, we also pass it a callback, which it'll call once
|
1882
|
-
// the file has been fetched, and parsed.
|
1883
|
-
//
|
1884
|
-
tree.Import = function (path, imports) {
|
1885
|
-
var that = this;
|
1886
|
-
|
1887
|
-
this._path = path;
|
1888
|
-
|
1889
|
-
// The '.less' extension is optional
|
1890
|
-
if (path instanceof tree.Quoted) {
|
1891
|
-
this.path = /\.(le?|c)ss$/.test(path.value) ? path.value : path.value + '.less';
|
1892
|
-
} else {
|
1893
|
-
this.path = path.value.value || path.value;
|
1894
|
-
}
|
1895
|
-
|
1896
|
-
this.css = /css$/.test(this.path);
|
1897
1907
|
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
if (
|
1902
|
-
|
1908
|
+
// Store the frames around mixin definitions,
|
1909
|
+
// so they can be evaluated like closures when the time comes.
|
1910
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
1911
|
+
if (ruleset.rules[i] instanceof tree.mixin.Definition) {
|
1912
|
+
ruleset.rules[i].frames = env.frames.slice(0);
|
1903
1913
|
}
|
1904
|
-
|
1905
|
-
});
|
1906
|
-
}
|
1907
|
-
};
|
1914
|
+
}
|
1908
1915
|
|
1909
|
-
//
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1913
|
-
|
1914
|
-
|
1915
|
-
// we end up with a flat structure, which can easily be imported in the parent
|
1916
|
-
// ruleset.
|
1917
|
-
//
|
1918
|
-
tree.Import.prototype = {
|
1919
|
-
toCSS: function () {
|
1920
|
-
if (this.css) {
|
1921
|
-
return "@import " + this._path.toCSS() + ';\n';
|
1922
|
-
} else {
|
1923
|
-
return "";
|
1916
|
+
// Evaluate mixin calls.
|
1917
|
+
for (var i = 0; i < ruleset.rules.length; i++) {
|
1918
|
+
if (ruleset.rules[i] instanceof tree.mixin.Call) {
|
1919
|
+
Array.prototype.splice
|
1920
|
+
.apply(ruleset.rules, [i, 1].concat(ruleset.rules[i].eval(env)));
|
1921
|
+
}
|
1924
1922
|
}
|
1925
|
-
},
|
1926
|
-
eval: function (env) {
|
1927
|
-
var ruleset;
|
1928
1923
|
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
ruleset = new(tree.Ruleset)(null, this.root.rules.slice(0));
|
1924
|
+
// Evaluate everything else
|
1925
|
+
for (var i = 0, rule; i < ruleset.rules.length; i++) {
|
1926
|
+
rule = ruleset.rules[i];
|
1933
1927
|
|
1934
|
-
|
1935
|
-
|
1936
|
-
Array.prototype
|
1937
|
-
.splice
|
1938
|
-
.apply(ruleset.rules,
|
1939
|
-
[i, 1].concat(ruleset.rules[i].eval(env)));
|
1940
|
-
}
|
1928
|
+
if (! (rule instanceof tree.mixin.Definition)) {
|
1929
|
+
ruleset.rules[i] = rule.eval ? rule.eval(env) : rule;
|
1941
1930
|
}
|
1942
|
-
return ruleset.rules;
|
1943
1931
|
}
|
1944
|
-
}
|
1945
|
-
};
|
1946
1932
|
|
1947
|
-
|
1948
|
-
(
|
1933
|
+
// Pop the stack
|
1934
|
+
env.frames.shift();
|
1949
1935
|
|
1950
|
-
|
1951
|
-
|
1952
|
-
|
1953
|
-
|
1954
|
-
|
1955
|
-
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1936
|
+
return ruleset;
|
1937
|
+
},
|
1938
|
+
match: function (args) {
|
1939
|
+
return !args || args.length === 0;
|
1940
|
+
},
|
1941
|
+
variables: function () {
|
1942
|
+
if (this._variables) { return this._variables }
|
1943
|
+
else {
|
1944
|
+
return this._variables = this.rules.reduce(function (hash, r) {
|
1945
|
+
if (r instanceof tree.Rule && r.variable === true) {
|
1946
|
+
hash[r.name] = r;
|
1947
|
+
}
|
1948
|
+
return hash;
|
1949
|
+
}, {});
|
1950
|
+
}
|
1951
|
+
},
|
1952
|
+
variable: function (name) {
|
1953
|
+
return this.variables()[name];
|
1954
|
+
},
|
1955
|
+
rulesets: function () {
|
1956
|
+
if (this._rulesets) { return this._rulesets }
|
1957
|
+
else {
|
1958
|
+
return this._rulesets = this.rules.filter(function (r) {
|
1959
|
+
return (r instanceof tree.Ruleset) || (r instanceof tree.mixin.Definition);
|
1960
|
+
});
|
1961
|
+
}
|
1962
|
+
},
|
1963
|
+
find: function (selector, self) {
|
1964
|
+
self = self || this;
|
1965
|
+
var rules = [], rule, match,
|
1966
|
+
key = selector.toCSS();
|
1959
1967
|
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1968
|
+
if (key in this._lookups) { return this._lookups[key] }
|
1969
|
+
|
1970
|
+
this.rulesets().forEach(function (rule) {
|
1971
|
+
if (rule !== self) {
|
1972
|
+
for (var j = 0; j < rule.selectors.length; j++) {
|
1973
|
+
if (match = selector.match(rule.selectors[j])) {
|
1974
|
+
if (selector.elements.length > 1) {
|
1975
|
+
Array.prototype.push.apply(rules, rule.find(
|
1976
|
+
new(tree.Selector)(selector.elements.slice(1)), self));
|
1977
|
+
} else {
|
1978
|
+
rules.push(rule);
|
1970
1979
|
}
|
1980
|
+
break;
|
1971
1981
|
}
|
1972
1982
|
}
|
1973
|
-
if (match) {
|
1974
|
-
return rules;
|
1975
|
-
} else {
|
1976
|
-
throw { message: 'No matching definition was found for `' +
|
1977
|
-
this.selector.toCSS().trim() + '(' +
|
1978
|
-
this.arguments.map(function (a) {
|
1979
|
-
return a.toCSS();
|
1980
|
-
}).join(', ') + ")`",
|
1981
|
-
index: this.index };
|
1982
|
-
}
|
1983
1983
|
}
|
1984
|
-
}
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
|
1999
|
-
else { return count }
|
2000
|
-
}, 0);
|
2001
|
-
this.parent = tree.Ruleset.prototype;
|
2002
|
-
this.frames = [];
|
2003
|
-
};
|
2004
|
-
tree.mixin.Definition.prototype = {
|
2005
|
-
toCSS: function () { return "" },
|
2006
|
-
variable: function (name) { return this.parent.variable.call(this, name) },
|
2007
|
-
variables: function () { return this.parent.variables.call(this) },
|
2008
|
-
find: function () { return this.parent.find.apply(this, arguments) },
|
2009
|
-
rulesets: function () { return this.parent.rulesets.apply(this) },
|
2010
|
-
|
2011
|
-
eval: function (env, args) {
|
2012
|
-
var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
|
1984
|
+
});
|
1985
|
+
return this._lookups[key] = rules;
|
1986
|
+
},
|
1987
|
+
//
|
1988
|
+
// Entry point for code generation
|
1989
|
+
//
|
1990
|
+
// `context` holds an array of arrays.
|
1991
|
+
//
|
1992
|
+
toCSS: function (context, env) {
|
1993
|
+
var css = [], // The CSS output
|
1994
|
+
rules = [], // node.Rule instances
|
1995
|
+
rulesets = [], // node.Ruleset instances
|
1996
|
+
paths = [], // Current selectors
|
1997
|
+
selector, // The fully rendered selector
|
1998
|
+
rule;
|
2013
1999
|
|
2014
|
-
|
2015
|
-
if (
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2019
|
-
|
2020
|
-
|
2000
|
+
if (! this.root) {
|
2001
|
+
if (context.length === 0) {
|
2002
|
+
paths = this.selectors.map(function (s) { return [s] });
|
2003
|
+
} else {
|
2004
|
+
for (var s = 0; s < this.selectors.length; s++) {
|
2005
|
+
for (var c = 0; c < context.length; c++) {
|
2006
|
+
paths.push(context[c].concat([this.selectors[s]]));
|
2007
|
+
}
|
2021
2008
|
}
|
2022
2009
|
}
|
2023
2010
|
}
|
2024
|
-
for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
|
2025
|
-
_arguments.push(args[i] || this.params[i].value);
|
2026
|
-
}
|
2027
|
-
frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
2028
2011
|
|
2029
|
-
|
2030
|
-
|
2031
|
-
|
2032
|
-
},
|
2033
|
-
match: function (args, env) {
|
2034
|
-
var argsLength = (args && args.length) || 0, len;
|
2012
|
+
// Compile rules and rulesets
|
2013
|
+
for (var i = 0; i < this.rules.length; i++) {
|
2014
|
+
rule = this.rules[i];
|
2035
2015
|
|
2036
|
-
|
2037
|
-
|
2016
|
+
if (rule.rules || (rule instanceof tree.Directive)) {
|
2017
|
+
rulesets.push(rule.toCSS(paths, env));
|
2018
|
+
} else if (rule instanceof tree.Comment) {
|
2019
|
+
if (!rule.silent) {
|
2020
|
+
if (this.root) {
|
2021
|
+
rulesets.push(rule.toCSS(env));
|
2022
|
+
} else {
|
2023
|
+
rules.push(rule.toCSS(env));
|
2024
|
+
}
|
2025
|
+
}
|
2026
|
+
} else {
|
2027
|
+
if (rule.toCSS && !rule.variable) {
|
2028
|
+
rules.push(rule.toCSS(env));
|
2029
|
+
} else if (rule.value && !rule.variable) {
|
2030
|
+
rules.push(rule.value.toString());
|
2031
|
+
}
|
2032
|
+
}
|
2033
|
+
}
|
2038
2034
|
|
2039
|
-
|
2035
|
+
rulesets = rulesets.join('');
|
2040
2036
|
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
|
2045
|
-
|
2037
|
+
// If this is the root node, we don't render
|
2038
|
+
// a selector, or {}.
|
2039
|
+
// Otherwise, only output if this ruleset has rules.
|
2040
|
+
if (this.root) {
|
2041
|
+
css.push(rules.join(env.compress ? '' : '\n'));
|
2042
|
+
} else {
|
2043
|
+
if (rules.length > 0) {
|
2044
|
+
selector = paths.map(function (p) {
|
2045
|
+
return p.map(function (s) {
|
2046
|
+
return s.toCSS(env);
|
2047
|
+
}).join('').trim();
|
2048
|
+
}).join(env.compress ? ',' : (paths.length > 3 ? ',\n' : ', '));
|
2049
|
+
css.push(selector,
|
2050
|
+
(env.compress ? '{' : ' {\n ') +
|
2051
|
+
rules.join(env.compress ? '' : '\n ') +
|
2052
|
+
(env.compress ? '}' : '\n}\n'));
|
2046
2053
|
}
|
2047
2054
|
}
|
2048
|
-
|
2055
|
+
css.push(rulesets);
|
2056
|
+
|
2057
|
+
return css.join('') + (env.compress ? '\n' : '');
|
2049
2058
|
}
|
2050
2059
|
};
|
2051
|
-
|
2052
2060
|
})(require('less/tree'));
|
2053
2061
|
(function (tree) {
|
2054
2062
|
|
2055
|
-
tree.
|
2056
|
-
this.
|
2057
|
-
this.
|
2063
|
+
tree.Selector = function (elements) {
|
2064
|
+
this.elements = elements;
|
2065
|
+
if (this.elements[0].combinator.value === "") {
|
2066
|
+
this.elements[0].combinator.value = ' ';
|
2067
|
+
}
|
2058
2068
|
};
|
2059
|
-
tree.
|
2060
|
-
|
2061
|
-
return
|
2062
|
-
}
|
2063
|
-
|
2069
|
+
tree.Selector.prototype.match = function (other) {
|
2070
|
+
if (this.elements[0].value === other.elements[0].value) {
|
2071
|
+
return true;
|
2072
|
+
} else {
|
2073
|
+
return false;
|
2074
|
+
}
|
2075
|
+
};
|
2076
|
+
tree.Selector.prototype.toCSS = function (env) {
|
2077
|
+
if (this._css) { return this._css }
|
2078
|
+
|
2079
|
+
return this._css = this.elements.map(function (e) {
|
2080
|
+
if (typeof(e) === 'string') {
|
2081
|
+
return ' ' + e.trim();
|
2082
|
+
} else {
|
2083
|
+
return e.toCSS(env);
|
2084
|
+
}
|
2085
|
+
}).join('');
|
2064
2086
|
};
|
2065
2087
|
|
2066
2088
|
})(require('less/tree'));
|
2067
2089
|
(function (tree) {
|
2068
2090
|
|
2069
|
-
tree.
|
2070
|
-
|
2091
|
+
tree.URL = function (val, paths) {
|
2092
|
+
if (val.data) {
|
2093
|
+
this.attrs = val;
|
2094
|
+
} else {
|
2095
|
+
// Add the base path if the URL is relative and we are in the browser
|
2096
|
+
if (!/^(?:https?:\/|file:\/|data:\/)?\//.test(val.value) && paths.length > 0 && typeof(window) !== 'undefined') {
|
2097
|
+
val.value = paths[0] + (val.value.charAt(0) === '/' ? val.value.slice(1) : val.value);
|
2098
|
+
}
|
2099
|
+
this.value = val;
|
2100
|
+
this.paths = paths;
|
2101
|
+
}
|
2071
2102
|
};
|
2072
|
-
tree.
|
2103
|
+
tree.URL.prototype = {
|
2073
2104
|
toCSS: function () {
|
2074
|
-
return this.
|
2105
|
+
return "url(" + (this.attrs ? 'data:' + this.attrs.mime + this.attrs.charset + this.attrs.base64 + this.attrs.data
|
2106
|
+
: this.value.toCSS()) + ")";
|
2075
2107
|
},
|
2076
|
-
eval: function () {
|
2108
|
+
eval: function (ctx) {
|
2109
|
+
return this.attrs ? this : new(tree.URL)(this.value.eval(ctx), this.paths);
|
2110
|
+
}
|
2077
2111
|
};
|
2078
2112
|
|
2079
2113
|
})(require('less/tree'));
|
@@ -2103,55 +2137,28 @@ tree.Value.prototype = {
|
|
2103
2137
|
})(require('less/tree'));
|
2104
2138
|
(function (tree) {
|
2105
2139
|
|
2106
|
-
tree.
|
2107
|
-
|
2108
|
-
this.expression = string;
|
2109
|
-
this.index = index;
|
2110
|
-
};
|
2111
|
-
tree.JavaScript.prototype = {
|
2140
|
+
tree.Variable = function (name, index) { this.name = name, this.index = index };
|
2141
|
+
tree.Variable.prototype = {
|
2112
2142
|
eval: function (env) {
|
2113
|
-
var
|
2114
|
-
that = this,
|
2115
|
-
context = {};
|
2116
|
-
|
2117
|
-
var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
|
2118
|
-
return tree.jsify(new(tree.Variable)('@' + name, that.index).eval(env));
|
2119
|
-
});
|
2120
|
-
|
2121
|
-
try {
|
2122
|
-
expression = new(Function)('return (' + expression + ')');
|
2123
|
-
} catch (e) {
|
2124
|
-
throw { message: "JavaScript evaluation error: `" + expression + "`" ,
|
2125
|
-
index: this.index };
|
2126
|
-
}
|
2143
|
+
var variable, v, name = this.name;
|
2127
2144
|
|
2128
|
-
|
2129
|
-
|
2130
|
-
value: env.frames[0].variables()[k].value,
|
2131
|
-
toJS: function () {
|
2132
|
-
return this.value.eval(env).toCSS();
|
2133
|
-
}
|
2134
|
-
};
|
2145
|
+
if (name.indexOf('@@') == 0) {
|
2146
|
+
name = '@' + new(tree.Variable)(name.slice(1)).eval(env).value;
|
2135
2147
|
}
|
2136
2148
|
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
|
2149
|
+
if (variable = tree.find(env.frames, function (frame) {
|
2150
|
+
if (v = frame.variable(name)) {
|
2151
|
+
return v.value.eval(env);
|
2152
|
+
}
|
2153
|
+
})) { return variable }
|
2154
|
+
else {
|
2155
|
+
throw { message: "variable " + name + " is undefined",
|
2141
2156
|
index: this.index };
|
2142
2157
|
}
|
2143
|
-
if (typeof(result) === 'string') {
|
2144
|
-
return new(tree.Quoted)('"' + result + '"', result, this.escaped, this.index);
|
2145
|
-
} else if (Array.isArray(result)) {
|
2146
|
-
return new(tree.Anonymous)(result.join(', '));
|
2147
|
-
} else {
|
2148
|
-
return new(tree.Anonymous)(result);
|
2149
|
-
}
|
2150
2158
|
}
|
2151
2159
|
};
|
2152
2160
|
|
2153
2161
|
})(require('less/tree'));
|
2154
|
-
|
2155
2162
|
require('less/tree').find = function (obj, fun) {
|
2156
2163
|
for (var i = 0, r; i < obj.length; i++) {
|
2157
2164
|
if (r = fun.call(obj, obj[i])) { return r }
|