less 2.6.0 → 2.7.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.
- package/.travis.yml +3 -2
- package/CHANGELOG.md +30 -2
- package/Gruntfile.js +2 -3
- package/README.md +2 -2
- package/appveyor.yml +1 -0
- package/bin/lessc +47 -23
- package/dist/less.js +914 -582
- package/dist/less.min.js +9 -12
- package/lib/less/environment/abstract-file-manager.js +2 -2
- package/lib/less/functions/color.js +6 -3
- package/lib/less/index.js +1 -1
- package/lib/less/parser/parser-input.js +69 -69
- package/lib/less/parser/parser.js +111 -51
- package/lib/less/tree/anonymous.js +1 -1
- package/lib/less/tree/call.js +7 -4
- package/lib/less/tree/comment.js +2 -0
- package/lib/less/tree/directive.js +1 -0
- package/lib/less/tree/extend.js +1 -0
- package/lib/less/tree/import.js +1 -0
- package/lib/less/tree/media.js +1 -0
- package/lib/less/tree/mixin-call.js +1 -0
- package/lib/less/tree/mixin-definition.js +2 -1
- package/lib/less/tree/rule.js +1 -0
- package/lib/less/tree/ruleset-call.js +1 -0
- package/lib/less/tree/ruleset.js +86 -85
- package/lib/less/tree/unit.js +2 -2
- package/lib/less/visitors/extend-visitor.js +5 -5
- package/lib/less/visitors/to-css-visitor.js +20 -10
- package/lib/less-browser/error-reporting.js +10 -10
- package/lib/less-browser/index.js +48 -25
- package/lib/less-node/file-manager.js +1 -1
- package/lib/less-node/lessc-helper.js +2 -2
- package/lib/source-map/source-map-0.1.31.js +1 -1
- package/package.json +29 -22
- package/test/browser/common.js +29 -8
- package/test/browser/less/console-errors/test-error.txt +1 -1
- package/test/browser/less.js +13 -16
- package/test/browser/runner-production-options.js +1 -1
- package/test/css/comments2.css +6 -0
- package/test/css/no-strict-math/mixins-guards.css +12 -0
- package/test/css/no-strict-math/no-sm-operations.css +3 -0
- package/test/css/operations.css +1 -1
- package/test/css/plugin.css +5 -0
- package/test/less/comments.less +1 -1
- package/test/less/comments2.less +11 -0
- package/test/less/errors/detached-ruleset-3.txt +1 -1
- package/test/less/errors/functions-1.less +2 -0
- package/test/less/errors/functions-1.txt +3 -0
- package/test/less/errors/functions-10-keyword.less +2 -0
- package/test/less/errors/functions-10-keyword.txt +3 -0
- package/test/less/errors/functions-11-operation.less +2 -0
- package/test/less/errors/functions-11-operation.txt +3 -0
- package/test/less/errors/functions-12-quoted.less +2 -0
- package/test/less/errors/functions-12-quoted.txt +3 -0
- package/test/less/errors/functions-13-selector.less +2 -0
- package/test/less/errors/functions-13-selector.txt +3 -0
- package/test/less/errors/functions-14-url.less +2 -0
- package/test/less/errors/functions-14-url.txt +3 -0
- package/test/less/errors/functions-15-value.less +2 -0
- package/test/less/errors/functions-15-value.txt +3 -0
- package/test/less/errors/functions-2-alpha.less +2 -0
- package/test/less/errors/functions-2-alpha.txt +3 -0
- package/test/less/errors/functions-3-assignment.less +2 -0
- package/test/less/errors/functions-3-assignment.txt +3 -0
- package/test/less/errors/functions-4-call.less +2 -0
- package/test/less/errors/functions-4-call.txt +3 -0
- package/test/less/errors/functions-5-color-2.less +1 -0
- package/test/less/errors/functions-5-color-2.txt +2 -0
- package/test/less/errors/functions-5-color.less +2 -0
- package/test/less/errors/functions-5-color.txt +3 -0
- package/test/less/errors/functions-6-condition.less +2 -0
- package/test/less/errors/functions-6-condition.txt +3 -0
- package/test/less/errors/functions-7-dimension.less +2 -0
- package/test/less/errors/functions-7-dimension.txt +3 -0
- package/test/less/errors/functions-8-element.less +2 -0
- package/test/less/errors/functions-8-element.txt +3 -0
- package/test/less/errors/functions-9-expression.less +2 -0
- package/test/less/errors/functions-9-expression.txt +3 -0
- package/test/less/errors/property-in-root.txt +1 -1
- package/test/less/errors/property-in-root2.txt +1 -1
- package/test/less/errors/property-in-root3.txt +1 -1
- package/test/less/errors/root-func-undefined-1.less +1 -0
- package/test/less/errors/root-func-undefined-1.txt +2 -0
- package/test/less/errors/root-func-undefined-2.less +2 -0
- package/test/less/errors/root-func-undefined-2.txt +3 -0
- package/test/less/extend-chaining.less +1 -1
- package/test/less/merge.less +4 -4
- package/test/less/mixins-guards.less +1 -1
- package/test/less/no-strict-math/mixins-guards.less +25 -0
- package/test/less/no-strict-math/no-sm-operations.less +4 -1
- package/test/less/operations.less +1 -1
- package/test/less/plugin/plugin-tree-nodes.js +80 -0
- package/test/less/plugin.less +8 -0
- package/test/less-bom/comments.less +1 -1
- package/test/less-bom/comments2.less +11 -0
- package/test/less-bom/errors/detached-ruleset-3.txt +1 -1
- package/test/less-bom/errors/functions-1.less +2 -0
- package/test/less-bom/errors/functions-1.txt +3 -0
- package/test/less-bom/errors/functions-10-keyword.less +2 -0
- package/test/less-bom/errors/functions-10-keyword.txt +3 -0
- package/test/less-bom/errors/functions-11-operation.less +2 -0
- package/test/less-bom/errors/functions-11-operation.txt +3 -0
- package/test/less-bom/errors/functions-12-quoted.less +2 -0
- package/test/less-bom/errors/functions-12-quoted.txt +3 -0
- package/test/less-bom/errors/functions-13-selector.less +2 -0
- package/test/less-bom/errors/functions-13-selector.txt +3 -0
- package/test/less-bom/errors/functions-14-url.less +2 -0
- package/test/less-bom/errors/functions-14-url.txt +3 -0
- package/test/less-bom/errors/functions-15-value.less +2 -0
- package/test/less-bom/errors/functions-15-value.txt +3 -0
- package/test/less-bom/errors/functions-2-alpha.less +2 -0
- package/test/less-bom/errors/functions-2-alpha.txt +3 -0
- package/test/less-bom/errors/functions-3-assignment.less +2 -0
- package/test/less-bom/errors/functions-3-assignment.txt +3 -0
- package/test/less-bom/errors/functions-4-call.less +2 -0
- package/test/less-bom/errors/functions-4-call.txt +3 -0
- package/test/less-bom/errors/functions-5-color-2.less +1 -0
- package/test/less-bom/errors/functions-5-color-2.txt +2 -0
- package/test/less-bom/errors/functions-5-color.less +2 -0
- package/test/less-bom/errors/functions-5-color.txt +3 -0
- package/test/less-bom/errors/functions-6-condition.less +2 -0
- package/test/less-bom/errors/functions-6-condition.txt +3 -0
- package/test/less-bom/errors/functions-7-dimension.less +2 -0
- package/test/less-bom/errors/functions-7-dimension.txt +3 -0
- package/test/less-bom/errors/functions-8-element.less +2 -0
- package/test/less-bom/errors/functions-8-element.txt +3 -0
- package/test/less-bom/errors/functions-9-expression.less +2 -0
- package/test/less-bom/errors/functions-9-expression.txt +3 -0
- package/test/less-bom/errors/property-in-root.txt +1 -1
- package/test/less-bom/errors/property-in-root2.txt +1 -1
- package/test/less-bom/errors/property-in-root3.txt +1 -1
- package/test/less-bom/errors/root-func-undefined-1.less +1 -0
- package/test/less-bom/errors/root-func-undefined-1.txt +2 -0
- package/test/less-bom/errors/root-func-undefined-2.less +2 -0
- package/test/less-bom/errors/root-func-undefined-2.txt +3 -0
- package/test/less-bom/extend-chaining.less +1 -1
- package/test/less-bom/merge.less +4 -4
- package/test/less-bom/mixins-guards.less +1 -1
- package/test/less-bom/no-strict-math/mixins-guards.less +25 -0
- package/test/less-bom/no-strict-math/no-sm-operations.less +4 -1
- package/test/less-bom/operations.less +1 -1
- package/test/less-bom/plugin/plugin-tree-nodes.js +80 -0
- package/test/less-bom/plugin.less +8 -0
- package/test/sourcemaps/maps/import-map.map +1 -0
package/lib/less/tree/ruleset.js
CHANGED
|
@@ -14,6 +14,7 @@ var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
|
|
|
14
14
|
this._lookups = {};
|
|
15
15
|
this.strictImports = strictImports;
|
|
16
16
|
this.copyVisibilityInfo(visibilityInfo);
|
|
17
|
+
this.allowRoot = true;
|
|
17
18
|
};
|
|
18
19
|
Ruleset.prototype = new Node();
|
|
19
20
|
Ruleset.prototype.type = "Ruleset";
|
|
@@ -463,6 +464,91 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
463
464
|
return selector;
|
|
464
465
|
}
|
|
465
466
|
|
|
467
|
+
// joins selector path from `beginningPath` with selector path in `addPath`
|
|
468
|
+
// `replacedElement` contains element that is being replaced by `addPath`
|
|
469
|
+
// returns concatenated path
|
|
470
|
+
function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
|
|
471
|
+
var newSelectorPath, lastSelector, newJoinedSelector;
|
|
472
|
+
// our new selector path
|
|
473
|
+
newSelectorPath = [];
|
|
474
|
+
|
|
475
|
+
//construct the joined selector - if & is the first thing this will be empty,
|
|
476
|
+
// if not newJoinedSelector will be the last set of elements in the selector
|
|
477
|
+
if (beginningPath.length > 0) {
|
|
478
|
+
newSelectorPath = beginningPath.slice(0);
|
|
479
|
+
lastSelector = newSelectorPath.pop();
|
|
480
|
+
newJoinedSelector = originalSelector.createDerived(lastSelector.elements.slice(0));
|
|
481
|
+
}
|
|
482
|
+
else {
|
|
483
|
+
newJoinedSelector = originalSelector.createDerived([]);
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
if (addPath.length > 0) {
|
|
487
|
+
// /deep/ is a combinator that is valid without anything in front of it
|
|
488
|
+
// so if the & does not have a combinator that is "" or " " then
|
|
489
|
+
// and there is a combinator on the parent, then grab that.
|
|
490
|
+
// this also allows + a { & .b { .a & { ... though not sure why you would want to do that
|
|
491
|
+
var combinator = replacedElement.combinator, parentEl = addPath[0].elements[0];
|
|
492
|
+
if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
|
|
493
|
+
combinator = parentEl.combinator;
|
|
494
|
+
}
|
|
495
|
+
// join the elements so far with the first part of the parent
|
|
496
|
+
newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.index, replacedElement.currentFileInfo));
|
|
497
|
+
newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// now add the joined selector - but only if it is not empty
|
|
501
|
+
if (newJoinedSelector.elements.length !== 0) {
|
|
502
|
+
newSelectorPath.push(newJoinedSelector);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
//put together the parent selectors after the join (e.g. the rest of the parent)
|
|
506
|
+
if (addPath.length > 1) {
|
|
507
|
+
var restOfPath = addPath.slice(1);
|
|
508
|
+
restOfPath = restOfPath.map(function (selector) {
|
|
509
|
+
return selector.createDerived(selector.elements, []);
|
|
510
|
+
});
|
|
511
|
+
newSelectorPath = newSelectorPath.concat(restOfPath);
|
|
512
|
+
}
|
|
513
|
+
return newSelectorPath;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
// joins selector path from `beginningPath` with every selector path in `addPaths` array
|
|
517
|
+
// `replacedElement` contains element that is being replaced by `addPath`
|
|
518
|
+
// returns array with all concatenated paths
|
|
519
|
+
function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {
|
|
520
|
+
var j;
|
|
521
|
+
for (j = 0; j < beginningPath.length; j++) {
|
|
522
|
+
var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
|
|
523
|
+
result.push(newSelectorPath);
|
|
524
|
+
}
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
function mergeElementsOnToSelectors(elements, selectors) {
|
|
529
|
+
var i, sel;
|
|
530
|
+
|
|
531
|
+
if (elements.length === 0) {
|
|
532
|
+
return ;
|
|
533
|
+
}
|
|
534
|
+
if (selectors.length === 0) {
|
|
535
|
+
selectors.push([ new Selector(elements) ]);
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
for (i = 0; i < selectors.length; i++) {
|
|
540
|
+
sel = selectors[i];
|
|
541
|
+
|
|
542
|
+
// if the previous thing in sel is a parent this needs to join on to it
|
|
543
|
+
if (sel.length > 0) {
|
|
544
|
+
sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
|
|
545
|
+
}
|
|
546
|
+
else {
|
|
547
|
+
sel.push(new Selector(elements));
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
466
552
|
// replace all parent selectors inside `inSelector` by content of `context` array
|
|
467
553
|
// resulting selectors are returned inside `paths` array
|
|
468
554
|
// returns true if `inSelector` contained at least one parent selector
|
|
@@ -583,91 +669,6 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
|
|
|
583
669
|
return hadParentSelector;
|
|
584
670
|
}
|
|
585
671
|
|
|
586
|
-
// joins selector path from `beginningPath` with selector path in `addPath`
|
|
587
|
-
// `replacedElement` contains element that is being replaced by `addPath`
|
|
588
|
-
// returns concatenated path
|
|
589
|
-
function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
|
|
590
|
-
var newSelectorPath, lastSelector, newJoinedSelector;
|
|
591
|
-
// our new selector path
|
|
592
|
-
newSelectorPath = [];
|
|
593
|
-
|
|
594
|
-
//construct the joined selector - if & is the first thing this will be empty,
|
|
595
|
-
// if not newJoinedSelector will be the last set of elements in the selector
|
|
596
|
-
if (beginningPath.length > 0) {
|
|
597
|
-
newSelectorPath = beginningPath.slice(0);
|
|
598
|
-
lastSelector = newSelectorPath.pop();
|
|
599
|
-
newJoinedSelector = originalSelector.createDerived(lastSelector.elements.slice(0));
|
|
600
|
-
}
|
|
601
|
-
else {
|
|
602
|
-
newJoinedSelector = originalSelector.createDerived([]);
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (addPath.length > 0) {
|
|
606
|
-
// /deep/ is a combinator that is valid without anything in front of it
|
|
607
|
-
// so if the & does not have a combinator that is "" or " " then
|
|
608
|
-
// and there is a combinator on the parent, then grab that.
|
|
609
|
-
// this also allows + a { & .b { .a & { ... though not sure why you would want to do that
|
|
610
|
-
var combinator = replacedElement.combinator, parentEl = addPath[0].elements[0];
|
|
611
|
-
if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
|
|
612
|
-
combinator = parentEl.combinator;
|
|
613
|
-
}
|
|
614
|
-
// join the elements so far with the first part of the parent
|
|
615
|
-
newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.index, replacedElement.currentFileInfo));
|
|
616
|
-
newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
// now add the joined selector - but only if it is not empty
|
|
620
|
-
if (newJoinedSelector.elements.length !== 0) {
|
|
621
|
-
newSelectorPath.push(newJoinedSelector);
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
//put together the parent selectors after the join (e.g. the rest of the parent)
|
|
625
|
-
if (addPath.length > 1) {
|
|
626
|
-
var restOfPath = addPath.slice(1);
|
|
627
|
-
restOfPath = restOfPath.map(function (selector) {
|
|
628
|
-
return selector.createDerived(selector.elements, []);
|
|
629
|
-
});
|
|
630
|
-
newSelectorPath = newSelectorPath.concat(restOfPath);
|
|
631
|
-
}
|
|
632
|
-
return newSelectorPath;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
// joins selector path from `beginningPath` with every selector path in `addPaths` array
|
|
636
|
-
// `replacedElement` contains element that is being replaced by `addPath`
|
|
637
|
-
// returns array with all concatenated paths
|
|
638
|
-
function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {
|
|
639
|
-
var j;
|
|
640
|
-
for (j = 0; j < beginningPath.length; j++) {
|
|
641
|
-
var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
|
|
642
|
-
result.push(newSelectorPath);
|
|
643
|
-
}
|
|
644
|
-
return result;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
function mergeElementsOnToSelectors(elements, selectors) {
|
|
648
|
-
var i, sel;
|
|
649
|
-
|
|
650
|
-
if (elements.length === 0) {
|
|
651
|
-
return ;
|
|
652
|
-
}
|
|
653
|
-
if (selectors.length === 0) {
|
|
654
|
-
selectors.push([ new Selector(elements) ]);
|
|
655
|
-
return;
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
for (i = 0; i < selectors.length; i++) {
|
|
659
|
-
sel = selectors[i];
|
|
660
|
-
|
|
661
|
-
// if the previous thing in sel is a parent this needs to join on to it
|
|
662
|
-
if (sel.length > 0) {
|
|
663
|
-
sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
|
|
664
|
-
}
|
|
665
|
-
else {
|
|
666
|
-
sel.push(new Selector(elements));
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
|
|
671
672
|
function deriveSelector(visibilityInfo, deriveFrom) {
|
|
672
673
|
var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);
|
|
673
674
|
newSelector.copyVisibilityInfo(visibilityInfo);
|
package/lib/less/tree/unit.js
CHANGED
|
@@ -61,7 +61,7 @@ Unit.prototype.map = function(callback) {
|
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
63
|
Unit.prototype.usedUnits = function() {
|
|
64
|
-
var group, result = {}, mapUnit;
|
|
64
|
+
var group, result = {}, mapUnit, groupName;
|
|
65
65
|
|
|
66
66
|
mapUnit = function (atomicUnit) {
|
|
67
67
|
/*jshint loopfunc:true */
|
|
@@ -72,7 +72,7 @@ Unit.prototype.usedUnits = function() {
|
|
|
72
72
|
return atomicUnit;
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
for (
|
|
75
|
+
for (groupName in unitConversions) {
|
|
76
76
|
if (unitConversions.hasOwnProperty(groupName)) {
|
|
77
77
|
group = unitConversions[groupName];
|
|
78
78
|
|
|
@@ -95,7 +95,7 @@ var ProcessExtendsVisitor = function() {
|
|
|
95
95
|
ProcessExtendsVisitor.prototype = {
|
|
96
96
|
run: function(root) {
|
|
97
97
|
var extendFinder = new ExtendFinderVisitor();
|
|
98
|
-
this.
|
|
98
|
+
this.extendIndices = {};
|
|
99
99
|
extendFinder.run(root);
|
|
100
100
|
if (!extendFinder.foundExtends) { return root; }
|
|
101
101
|
root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
|
|
@@ -105,7 +105,7 @@ ProcessExtendsVisitor.prototype = {
|
|
|
105
105
|
return newRoot;
|
|
106
106
|
},
|
|
107
107
|
checkExtendsForNonMatched: function(extendList) {
|
|
108
|
-
var
|
|
108
|
+
var indices = this.extendIndices;
|
|
109
109
|
extendList.filter(function(extend) {
|
|
110
110
|
return !extend.hasFoundMatches && extend.parent_ids.length == 1;
|
|
111
111
|
}).forEach(function(extend) {
|
|
@@ -115,8 +115,8 @@ ProcessExtendsVisitor.prototype = {
|
|
|
115
115
|
}
|
|
116
116
|
catch(_) {}
|
|
117
117
|
|
|
118
|
-
if (!
|
|
119
|
-
|
|
118
|
+
if (!indices[extend.index + ' ' + selector]) {
|
|
119
|
+
indices[extend.index + ' ' + selector] = true;
|
|
120
120
|
logger.warn("extend '" + selector + "' has no matches");
|
|
121
121
|
}
|
|
122
122
|
});
|
|
@@ -140,7 +140,7 @@ ProcessExtendsVisitor.prototype = {
|
|
|
140
140
|
// a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
|
|
141
141
|
// e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
|
|
142
142
|
// and the second is the target.
|
|
143
|
-
// the
|
|
143
|
+
// the separation into two lists allows us to process a subset of chains with a bigger set, as is the
|
|
144
144
|
// case when processing media queries
|
|
145
145
|
for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {
|
|
146
146
|
for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {
|
|
@@ -144,7 +144,6 @@ ToCSSVisitor.prototype = {
|
|
|
144
144
|
} else {
|
|
145
145
|
return this.visitDirectiveWithoutBody(directiveNode, visitArgs);
|
|
146
146
|
}
|
|
147
|
-
return directiveNode;
|
|
148
147
|
},
|
|
149
148
|
|
|
150
149
|
visitDirectiveWithBody: function(directiveNode, visitArgs) {
|
|
@@ -199,13 +198,24 @@ ToCSSVisitor.prototype = {
|
|
|
199
198
|
return directiveNode;
|
|
200
199
|
},
|
|
201
200
|
|
|
202
|
-
|
|
203
|
-
|
|
201
|
+
checkValidNodes: function(rules, isRoot) {
|
|
202
|
+
if (!rules) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
204
206
|
for (var i = 0; i < rules.length; i++) {
|
|
205
|
-
ruleNode = rules[i];
|
|
206
|
-
if (ruleNode instanceof tree.Rule && !ruleNode.variable) {
|
|
207
|
-
throw { message: "
|
|
208
|
-
index: ruleNode.index, filename: ruleNode.currentFileInfo
|
|
207
|
+
var ruleNode = rules[i];
|
|
208
|
+
if (isRoot && ruleNode instanceof tree.Rule && !ruleNode.variable) {
|
|
209
|
+
throw { message: "Properties must be inside selector blocks. They cannot be in the root",
|
|
210
|
+
index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
|
|
211
|
+
}
|
|
212
|
+
if (ruleNode instanceof tree.Call) {
|
|
213
|
+
throw { message: "Function '" + ruleNode.name + "' is undefined",
|
|
214
|
+
index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
|
|
215
|
+
}
|
|
216
|
+
if (ruleNode.type && !ruleNode.allowRoot) {
|
|
217
|
+
throw { message: ruleNode.type + " node returned by a function is not valid here",
|
|
218
|
+
index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
|
|
209
219
|
}
|
|
210
220
|
}
|
|
211
221
|
},
|
|
@@ -213,9 +223,9 @@ ToCSSVisitor.prototype = {
|
|
|
213
223
|
visitRuleset: function (rulesetNode, visitArgs) {
|
|
214
224
|
//at this point rulesets are nested into each other
|
|
215
225
|
var rule, rulesets = [];
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
226
|
+
|
|
227
|
+
this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);
|
|
228
|
+
|
|
219
229
|
if (! rulesetNode.root) {
|
|
220
230
|
//remove invisible paths
|
|
221
231
|
this._compileRulesetPaths(rulesetNode);
|
|
@@ -104,16 +104,6 @@ module.exports = function(window, less, options) {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
function error(e, rootHref) {
|
|
108
|
-
if (!options.errorReporting || options.errorReporting === "html") {
|
|
109
|
-
errorHTML(e, rootHref);
|
|
110
|
-
} else if (options.errorReporting === "console") {
|
|
111
|
-
errorConsole(e, rootHref);
|
|
112
|
-
} else if (typeof options.errorReporting === 'function') {
|
|
113
|
-
options.errorReporting("add", e, rootHref);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
107
|
function removeErrorHTML(path) {
|
|
118
108
|
var node = window.document.getElementById('less-error-message:' + utils.extractId(path));
|
|
119
109
|
if (node) {
|
|
@@ -163,6 +153,16 @@ module.exports = function(window, less, options) {
|
|
|
163
153
|
less.logger.error(content);
|
|
164
154
|
}
|
|
165
155
|
|
|
156
|
+
function error(e, rootHref) {
|
|
157
|
+
if (!options.errorReporting || options.errorReporting === "html") {
|
|
158
|
+
errorHTML(e, rootHref);
|
|
159
|
+
} else if (options.errorReporting === "console") {
|
|
160
|
+
errorConsole(e, rootHref);
|
|
161
|
+
} else if (typeof options.errorReporting === 'function') {
|
|
162
|
+
options.errorReporting("add", e, rootHref);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
166
|
return {
|
|
167
167
|
add: error,
|
|
168
168
|
remove: removeError
|
|
@@ -225,34 +225,57 @@ module.exports = function(window, options) {
|
|
|
225
225
|
fileManager.clearFileCache();
|
|
226
226
|
}
|
|
227
227
|
return new Promise(function (resolve, reject) {
|
|
228
|
-
var startTime, endTime, totalMilliseconds;
|
|
228
|
+
var startTime, endTime, totalMilliseconds, remainingSheets;
|
|
229
229
|
startTime = endTime = new Date();
|
|
230
230
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
if (webInfo.local) {
|
|
238
|
-
less.logger.info("loading " + sheet.href + " from cache.");
|
|
239
|
-
} else {
|
|
240
|
-
less.logger.info("rendered " + sheet.href + " successfully.");
|
|
241
|
-
}
|
|
242
|
-
browser.createCSS(window.document, css, sheet);
|
|
243
|
-
less.logger.info("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
|
|
244
|
-
if (webInfo.remaining === 0) {
|
|
245
|
-
totalMilliseconds = new Date() - startTime;
|
|
246
|
-
less.logger.info("less has finished. css generated in " + totalMilliseconds + 'ms');
|
|
247
|
-
resolve({
|
|
248
|
-
startTime: startTime,
|
|
249
|
-
endTime: endTime,
|
|
250
|
-
totalMilliseconds: totalMilliseconds,
|
|
251
|
-
sheets: less.sheets.length
|
|
252
|
-
});
|
|
253
|
-
}
|
|
231
|
+
// Set counter for remaining unprocessed sheets
|
|
232
|
+
remainingSheets = less.sheets.length;
|
|
233
|
+
|
|
234
|
+
if (remainingSheets === 0) {
|
|
235
|
+
|
|
254
236
|
endTime = new Date();
|
|
255
|
-
|
|
237
|
+
totalMilliseconds = endTime - startTime;
|
|
238
|
+
less.logger.info("Less has finished and no sheets were loaded.");
|
|
239
|
+
resolve({
|
|
240
|
+
startTime: startTime,
|
|
241
|
+
endTime: endTime,
|
|
242
|
+
totalMilliseconds: totalMilliseconds,
|
|
243
|
+
sheets: less.sheets.length
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
} else {
|
|
247
|
+
// Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
|
|
248
|
+
loadStyleSheets(function (e, css, _, sheet, webInfo) {
|
|
249
|
+
if (e) {
|
|
250
|
+
errors.add(e, e.href || sheet.href);
|
|
251
|
+
reject(e);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (webInfo.local) {
|
|
255
|
+
less.logger.info("Loading " + sheet.href + " from cache.");
|
|
256
|
+
} else {
|
|
257
|
+
less.logger.info("Rendered " + sheet.href + " successfully.");
|
|
258
|
+
}
|
|
259
|
+
browser.createCSS(window.document, css, sheet);
|
|
260
|
+
less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
|
|
261
|
+
|
|
262
|
+
// Count completed sheet
|
|
263
|
+
remainingSheets--;
|
|
264
|
+
|
|
265
|
+
// Check if the last remaining sheet was processed and then call the promise
|
|
266
|
+
if (remainingSheets === 0) {
|
|
267
|
+
totalMilliseconds = new Date() - startTime;
|
|
268
|
+
less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + 'ms');
|
|
269
|
+
resolve({
|
|
270
|
+
startTime: startTime,
|
|
271
|
+
endTime: endTime,
|
|
272
|
+
totalMilliseconds: totalMilliseconds,
|
|
273
|
+
sheets: less.sheets.length
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
endTime = new Date();
|
|
277
|
+
}, reload, modifyVars);
|
|
278
|
+
}
|
|
256
279
|
|
|
257
280
|
loadStyles(modifyVars);
|
|
258
281
|
});
|
|
@@ -38,7 +38,7 @@ FileManager.prototype.loadFile = function(filename, currentDirectory, options, e
|
|
|
38
38
|
if (options.paths) { paths.push.apply(paths, options.paths); }
|
|
39
39
|
if (!isAbsoluteFilename && paths.indexOf('.') === -1) { paths.push('.'); }
|
|
40
40
|
|
|
41
|
-
// promise is
|
|
41
|
+
// promise is guaranteed to be asyncronous
|
|
42
42
|
// which helps as it allows the file handle
|
|
43
43
|
// to be closed before it continues with the next file
|
|
44
44
|
return new PromiseConstructor(function(fulfill, reject) {
|
|
@@ -15,8 +15,8 @@ var lessc_helper = {
|
|
|
15
15
|
'red' : [31, 39],
|
|
16
16
|
'grey' : [90, 39]
|
|
17
17
|
};
|
|
18
|
-
return '\
|
|
19
|
-
'\
|
|
18
|
+
return '\x1b[' + styles[style][0] + 'm' + str +
|
|
19
|
+
'\x1b[' + styles[style][1] + 'm';
|
|
20
20
|
},
|
|
21
21
|
|
|
22
22
|
//Print command line options
|
|
@@ -1338,7 +1338,7 @@ define('source-map/source-map-consumer', ['require', 'exports', 'module' , 'sou
|
|
|
1338
1338
|
/**
|
|
1339
1339
|
* Returns the original source content. The only argument is the url of the
|
|
1340
1340
|
* original source file. Returns null if no original source content is
|
|
1341
|
-
*
|
|
1341
|
+
* available.
|
|
1342
1342
|
*/
|
|
1343
1343
|
SourceMapConsumer.prototype.sourceContentFor =
|
|
1344
1344
|
function SourceMapConsumer_sourceContentFor(aSource) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "less",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"description": "Leaner CSS",
|
|
5
5
|
"homepage": "http://lesscss.org",
|
|
6
6
|
"author": {
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"type": "git",
|
|
18
18
|
"url": "https://github.com/less/less.js.git"
|
|
19
19
|
},
|
|
20
|
+
"master": {
|
|
21
|
+
"url": "https://github.com/less/less.js/blob/master/",
|
|
22
|
+
"raw": "https://raw.githubusercontent.com/less/less.js/master/"
|
|
23
|
+
},
|
|
20
24
|
"license": "Apache-2.0",
|
|
21
25
|
"bin": {
|
|
22
26
|
"lessc": "./bin/lessc"
|
|
@@ -30,36 +34,37 @@
|
|
|
30
34
|
},
|
|
31
35
|
"browser": "./dist/less.js",
|
|
32
36
|
"engines": {
|
|
33
|
-
"node": ">=0.
|
|
37
|
+
"node": ">=0.12"
|
|
34
38
|
},
|
|
35
39
|
"scripts": {
|
|
36
40
|
"test": "grunt test"
|
|
37
41
|
},
|
|
38
42
|
"optionalDependencies": {
|
|
39
43
|
"errno": "^0.1.1",
|
|
40
|
-
"graceful-fs": "^
|
|
41
|
-
"image-size": "~0.
|
|
44
|
+
"graceful-fs": "^4.1.2",
|
|
45
|
+
"image-size": "~0.5.0",
|
|
42
46
|
"mime": "^1.2.11",
|
|
43
47
|
"mkdirp": "^0.5.0",
|
|
44
|
-
"promise": "^
|
|
45
|
-
"
|
|
46
|
-
"
|
|
48
|
+
"promise": "^7.1.1",
|
|
49
|
+
"source-map": "^0.5.3",
|
|
50
|
+
"request": "^2.72.0"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
|
-
"diff": "^
|
|
50
|
-
"grunt": "
|
|
51
|
-
"grunt-browserify": "
|
|
52
|
-
"grunt-contrib-clean": "^0.
|
|
53
|
-
"grunt-contrib-concat": "^0.
|
|
54
|
-
"grunt-contrib-connect": "^0.
|
|
55
|
-
"grunt-contrib-jasmine": "^0.
|
|
56
|
-
"grunt-contrib-jshint": "^0.
|
|
57
|
-
"grunt-contrib-uglify": "^0.
|
|
58
|
-
"grunt-jscs": "^
|
|
59
|
-
"grunt-saucelabs": "^8.
|
|
60
|
-
"grunt-shell": "^1.
|
|
61
|
-
"jit-grunt": "^0.
|
|
62
|
-
"
|
|
53
|
+
"diff": "^2.2.2",
|
|
54
|
+
"grunt": "~0.4.5",
|
|
55
|
+
"grunt-browserify": "^5.0.0",
|
|
56
|
+
"grunt-contrib-clean": "^1.0.0",
|
|
57
|
+
"grunt-contrib-concat": "^1.0.1",
|
|
58
|
+
"grunt-contrib-connect": "^1.0.2",
|
|
59
|
+
"grunt-contrib-jasmine": "^1.0.3",
|
|
60
|
+
"grunt-contrib-jshint": "^1.0.0",
|
|
61
|
+
"grunt-contrib-uglify": "^1.0.1",
|
|
62
|
+
"grunt-jscs": "^2.8.0",
|
|
63
|
+
"grunt-saucelabs": "^8.6.2",
|
|
64
|
+
"grunt-shell": "^1.3.0",
|
|
65
|
+
"jit-grunt": "^0.10.0",
|
|
66
|
+
"phantomjs-prebuilt": "^2.1.7",
|
|
67
|
+
"time-grunt": "^1.3.0"
|
|
63
68
|
},
|
|
64
69
|
"keywords": [
|
|
65
70
|
"compile less",
|
|
@@ -85,5 +90,7 @@
|
|
|
85
90
|
"stylesheet",
|
|
86
91
|
"variables in css",
|
|
87
92
|
"css less"
|
|
88
|
-
]
|
|
93
|
+
],
|
|
94
|
+
"rawcurrent": "https://raw.github.com/less/less.js/v",
|
|
95
|
+
"sourcearchive": "https://github.com/less/less.js/archive/v"
|
|
89
96
|
}
|
package/test/browser/common.js
CHANGED
|
@@ -6,19 +6,40 @@ jasmine.getEnv().addReporter(new jasmine.JSReporter2());
|
|
|
6
6
|
|
|
7
7
|
var logMessages = [];
|
|
8
8
|
window.less = window.less || {};
|
|
9
|
+
|
|
10
|
+
var logLevel_debug = 4,
|
|
11
|
+
logLevel_info = 3,
|
|
12
|
+
logLevel_warn = 2,
|
|
13
|
+
logLevel_error = 1;
|
|
14
|
+
|
|
15
|
+
// The amount of logging in the javascript console.
|
|
16
|
+
// 3 - Debug, information and errors
|
|
17
|
+
// 2 - Information and errors
|
|
18
|
+
// 1 - Errors
|
|
19
|
+
// 0 - None
|
|
20
|
+
// Defaults to 2
|
|
21
|
+
|
|
9
22
|
less.loggers = [
|
|
10
23
|
{
|
|
11
|
-
|
|
12
|
-
|
|
24
|
+
debug: function(msg) {
|
|
25
|
+
if (less.options.logLevel >= logLevel_debug) {
|
|
26
|
+
logMessages.push(msg);
|
|
27
|
+
}
|
|
13
28
|
},
|
|
14
|
-
|
|
15
|
-
|
|
29
|
+
info: function(msg) {
|
|
30
|
+
if (less.options.logLevel >= logLevel_info) {
|
|
31
|
+
logMessages.push(msg);
|
|
32
|
+
}
|
|
16
33
|
},
|
|
17
|
-
warn: function
|
|
18
|
-
|
|
34
|
+
warn: function(msg) {
|
|
35
|
+
if (less.options.logLevel >= logLevel_warn) {
|
|
36
|
+
logMessages.push(msg);
|
|
37
|
+
}
|
|
19
38
|
},
|
|
20
|
-
error: function
|
|
21
|
-
|
|
39
|
+
error: function(msg) {
|
|
40
|
+
if (less.options.logLevel >= logLevel_error) {
|
|
41
|
+
logMessages.push(msg);
|
|
42
|
+
}
|
|
22
43
|
}
|
|
23
44
|
}
|
|
24
45
|
];
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
less: OperationError: Can't
|
|
1
|
+
less: OperationError: Can't subtract or divide a color from a number in {pathhref}console-errors/test-error.less on line null, column 0:
|
|
2
2
|
1 prop: (3 / #fff);
|