less 2.3.3 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +5 -0
- data/less.gemspec +1 -1
- data/lib/less/js/.gitattributes +9 -0
- data/lib/less/js/.gitignore +1 -0
- data/lib/less/js/.npmignore +1 -1
- data/lib/less/js/CHANGELOG.md +68 -0
- data/lib/less/js/CONTRIBUTING.md +33 -34
- data/lib/less/js/Makefile +24 -9
- data/lib/less/js/README.md +2 -2
- data/lib/less/js/bin/lessc +102 -25
- data/lib/less/js/build/amd.js +1 -1
- data/lib/less/js/build/header.js +9 -7
- data/lib/less/js/dist/less-1.3.3.js +2 -2
- data/lib/less/js/dist/less-1.3.3.min.js +2 -2
- data/lib/less/js/dist/less-1.4.0-beta.js +5830 -0
- data/lib/less/js/dist/less-1.4.0-beta.min.js +11 -0
- data/lib/less/js/dist/less-1.4.0.js +5830 -0
- data/lib/less/js/dist/less-1.4.0.min.js +11 -0
- data/lib/less/js/dist/less-1.4.1.js +5837 -0
- data/lib/less/js/dist/less-1.4.1.min.js +11 -0
- data/lib/less/js/dist/less-1.4.2.js +5837 -0
- data/lib/less/js/dist/less-1.4.2.min.js +11 -0
- data/lib/less/js/dist/less-rhino-1.4.0.js +4273 -0
- data/lib/less/js/lib/less/browser.js +131 -101
- data/lib/less/js/lib/less/env.js +105 -0
- data/lib/less/js/lib/less/extend-visitor.js +391 -0
- data/lib/less/js/lib/less/functions.js +174 -19
- data/lib/less/js/lib/less/import-visitor.js +107 -0
- data/lib/less/js/lib/less/index.js +70 -63
- data/lib/less/js/lib/less/join-selector-visitor.js +37 -0
- data/lib/less/js/lib/less/lessc_helper.js +13 -4
- data/lib/less/js/lib/less/parser.js +353 -264
- data/lib/less/js/lib/less/rhino.js +5 -2
- data/lib/less/js/lib/less/tree.js +1 -1
- data/lib/less/js/lib/less/tree/alpha.js +7 -3
- data/lib/less/js/lib/less/tree/anonymous.js +1 -0
- data/lib/less/js/lib/less/tree/assignment.js +4 -0
- data/lib/less/js/lib/less/tree/call.js +14 -8
- data/lib/less/js/lib/less/tree/color.js +50 -5
- data/lib/less/js/lib/less/tree/comment.js +1 -0
- data/lib/less/js/lib/less/tree/condition.js +35 -28
- data/lib/less/js/lib/less/tree/dimension.js +270 -16
- data/lib/less/js/lib/less/tree/directive.js +7 -2
- data/lib/less/js/lib/less/tree/element.js +57 -21
- data/lib/less/js/lib/less/tree/expression.js +29 -4
- data/lib/less/js/lib/less/tree/extend.js +43 -0
- data/lib/less/js/lib/less/tree/import.js +49 -28
- data/lib/less/js/lib/less/tree/javascript.js +1 -0
- data/lib/less/js/lib/less/tree/keyword.js +3 -2
- data/lib/less/js/lib/less/tree/media.js +20 -4
- data/lib/less/js/lib/less/tree/mixin.js +38 -18
- data/lib/less/js/lib/less/tree/negative.js +22 -0
- data/lib/less/js/lib/less/tree/operation.js +32 -17
- data/lib/less/js/lib/less/tree/paren.js +5 -1
- data/lib/less/js/lib/less/tree/quoted.js +5 -3
- data/lib/less/js/lib/less/tree/rule.js +44 -31
- data/lib/less/js/lib/less/tree/ruleset.js +50 -23
- data/lib/less/js/lib/less/tree/selector.js +49 -39
- data/lib/less/js/lib/less/tree/unicode-descriptor.js +1 -0
- data/lib/less/js/lib/less/tree/url.js +9 -5
- data/lib/less/js/lib/less/tree/value.js +4 -1
- data/lib/less/js/lib/less/tree/variable.js +4 -3
- data/lib/less/js/lib/less/visitor.js +54 -0
- data/lib/less/js/package.json +69 -19
- data/lib/less/js/test/browser-test-prepare.js +23 -6
- data/lib/less/js/test/browser/common.js +55 -3
- data/lib/less/js/test/browser/css/urls.css +13 -0
- data/lib/less/js/test/browser/less/relative-urls/urls.less +1 -1
- data/lib/less/js/test/browser/less/urls.less +16 -0
- data/lib/less/js/test/browser/phantom-runner.js +7 -5
- data/lib/less/js/test/browser/runner-browser.js +5 -1
- data/lib/less/js/test/browser/runner-errors.js +5 -0
- data/lib/less/js/test/browser/runner-legacy.js +6 -0
- data/lib/less/js/test/browser/runner-production.js +7 -0
- data/lib/less/js/test/browser/template.htm +6 -6
- data/lib/less/js/test/css/comments.css +1 -0
- data/lib/less/js/test/css/compression/compression.css +2 -0
- data/lib/less/js/test/css/css-3.css +4 -0
- data/lib/less/js/test/css/css.css +9 -3
- data/lib/less/js/test/css/extend-chaining.css +72 -0
- data/lib/less/js/test/css/extend-clearfix.css +19 -0
- data/lib/less/js/test/css/extend-exact.css +37 -0
- data/lib/less/js/test/css/extend-media.css +24 -0
- data/lib/less/js/test/css/extend-nest.css +57 -0
- data/lib/less/js/test/css/extend-selector.css +72 -0
- data/lib/less/js/test/css/extend.css +76 -0
- data/lib/less/js/test/css/functions.css +28 -0
- data/lib/less/js/test/css/import-interpolation.css +6 -0
- data/lib/less/js/test/css/import.css +18 -1
- data/lib/less/js/test/css/legacy/legacy.css +7 -0
- data/lib/less/js/test/css/media.css +9 -1
- data/lib/less/js/test/css/mixins-args.css +18 -0
- data/lib/less/js/test/css/mixins-guards.css +5 -0
- data/lib/less/js/test/css/parens.css +18 -5
- data/lib/less/js/test/css/selectors.css +14 -6
- data/lib/less/js/test/css/urls.css +17 -0
- data/lib/less/js/test/css/variables.css +22 -3
- data/lib/less/js/test/data/data-uri-fail.png +0 -0
- data/lib/less/js/test/data/image.jpg +0 -0
- data/lib/less/js/test/data/page.html +1 -0
- data/lib/less/js/test/less-test.js +41 -9
- data/lib/less/js/test/less/colors.less +4 -4
- data/lib/less/js/test/less/comments.less +2 -2
- data/lib/less/js/test/less/compression/compression.less +16 -0
- data/lib/less/js/test/less/css-3.less +5 -1
- data/lib/less/js/test/less/css.less +9 -3
- data/lib/less/js/test/less/errors/add-mixed-units.less +3 -0
- data/lib/less/js/test/less/errors/add-mixed-units.txt +2 -0
- data/lib/less/js/test/less/errors/add-mixed-units2.less +3 -0
- data/lib/less/js/test/less/errors/add-mixed-units2.txt +2 -0
- data/lib/less/js/test/less/errors/bad-variable-declaration1.txt +1 -1
- data/lib/less/js/test/less/errors/color-operation-error.less +3 -0
- data/lib/less/js/test/less/errors/color-operation-error.txt +2 -0
- data/lib/less/js/test/less/errors/comment-in-selector.txt +1 -1
- data/lib/less/js/test/less/errors/divide-mixed-units.less +3 -0
- data/lib/less/js/test/less/errors/divide-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/extend-no-selector.less +3 -0
- data/lib/less/js/test/less/errors/extend-no-selector.txt +3 -0
- data/lib/less/js/test/less/errors/extend-not-at-end.less +3 -0
- data/lib/less/js/test/less/errors/extend-not-at-end.txt +3 -0
- data/lib/less/js/test/less/errors/import-missing.less +5 -0
- data/lib/less/js/test/less/errors/import-missing.txt +3 -3
- data/lib/less/js/test/less/errors/import-no-semi.txt +1 -1
- data/lib/less/js/test/less/errors/import-subfolder1.txt +1 -1
- data/lib/less/js/test/less/errors/import-subfolder2.txt +1 -1
- data/lib/less/js/test/less/errors/javascript-error.txt +1 -1
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.txt +1 -1
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.txt +1 -1
- data/lib/less/js/test/less/errors/mixin-not-defined.txt +1 -1
- data/lib/less/js/test/less/errors/mixin-not-matched.txt +1 -1
- data/lib/less/js/test/less/errors/mixin-not-matched2.txt +1 -1
- data/lib/less/js/test/less/errors/multiply-mixed-units.less +7 -0
- data/lib/less/js/test/less/errors/multiply-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-1.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-1.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-2.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-2.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-3.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-3.txt +4 -0
- data/lib/less/js/test/less/errors/parse-error-curly-bracket.txt +1 -1
- data/lib/less/js/test/less/errors/parse-error-missing-bracket.txt +2 -1
- data/lib/less/js/test/less/errors/parse-error-with-import.txt +1 -1
- data/lib/less/js/test/less/errors/property-ie5-hack.txt +1 -1
- data/lib/less/js/test/less/errors/property-in-root.less +4 -0
- data/lib/less/js/test/less/errors/property-in-root.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root2.less +1 -0
- data/lib/less/js/test/less/errors/property-in-root2.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root3.less +4 -0
- data/lib/less/js/test/less/errors/property-in-root3.txt +3 -0
- data/lib/less/js/test/less/errors/recursive-variable.txt +1 -1
- data/lib/less/js/test/less/extend-chaining.less +79 -0
- data/lib/less/js/test/less/extend-clearfix.less +19 -0
- data/lib/less/js/test/less/extend-exact.less +46 -0
- data/lib/less/js/test/less/extend-media.less +24 -0
- data/lib/less/js/test/less/extend-nest.less +65 -0
- data/lib/less/js/test/less/extend-selector.less +84 -0
- data/lib/less/js/test/less/extend.less +81 -0
- data/lib/less/js/test/less/functions.less +37 -6
- data/lib/less/js/test/less/import-interpolation.less +8 -0
- data/lib/less/js/test/less/import-once.less +4 -4
- data/lib/less/js/test/less/import.less +11 -2
- data/lib/less/js/test/less/import/deeper/import-once-test-a.less +1 -1
- data/lib/less/js/test/less/import/import-interpolation.less +1 -0
- data/lib/less/js/test/less/import/import-interpolation2.less +5 -0
- data/lib/less/js/test/less/javascript.less +1 -1
- data/lib/less/js/test/less/legacy/legacy.less +7 -0
- data/lib/less/js/test/less/media.less +14 -3
- data/lib/less/js/test/less/mixins-args.less +43 -5
- data/lib/less/js/test/less/mixins-guards.less +13 -0
- data/lib/less/js/test/less/mixins-named-args.less +5 -5
- data/lib/less/js/test/less/mixins-nested.less +2 -2
- data/lib/less/js/test/less/mixins-pattern.less +1 -1
- data/lib/less/js/test/less/mixins.less +1 -1
- data/lib/less/js/test/less/operations.less +27 -27
- data/lib/less/js/test/less/parens.less +20 -5
- data/lib/less/js/test/less/selectors.less +14 -7
- data/lib/less/js/test/less/urls.less +24 -0
- data/lib/less/js/test/less/variables.less +42 -12
- data/lib/less/loader.rb +33 -0
- data/lib/less/version.rb +1 -1
- data/spec/less/parser_spec.rb +5 -5
- metadata +76 -6
- data/lib/less/js/build/ecma-5.js +0 -120
- data/lib/less/js/lib/less/tree/ratio.js +0 -13
@@ -11,11 +11,16 @@ tree.Directive = function (name, value) {
|
|
11
11
|
}
|
12
12
|
};
|
13
13
|
tree.Directive.prototype = {
|
14
|
-
|
14
|
+
type: "Directive",
|
15
|
+
accept: function (visitor) {
|
16
|
+
this.ruleset = visitor.visit(this.ruleset);
|
17
|
+
this.value = visitor.visit(this.value);
|
18
|
+
},
|
19
|
+
toCSS: function (env) {
|
15
20
|
if (this.ruleset) {
|
16
21
|
this.ruleset.root = true;
|
17
22
|
return this.name + (env.compress ? '{' : ' {\n ') +
|
18
|
-
this.ruleset.toCSS(
|
23
|
+
this.ruleset.toCSS(env).trim().replace(/\n/g, '\n ') +
|
19
24
|
(env.compress ? '}': '\n}\n');
|
20
25
|
} else {
|
21
26
|
return this.name + ' ' + this.value.toCSS() + ';\n';
|
@@ -13,18 +13,51 @@ tree.Element = function (combinator, value, index) {
|
|
13
13
|
}
|
14
14
|
this.index = index;
|
15
15
|
};
|
16
|
-
tree.Element.prototype
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
tree.Element.prototype = {
|
17
|
+
type: "Element",
|
18
|
+
accept: function (visitor) {
|
19
|
+
this.combinator = visitor.visit(this.combinator);
|
20
|
+
this.value = visitor.visit(this.value);
|
21
|
+
},
|
22
|
+
eval: function (env) {
|
23
|
+
return new(tree.Element)(this.combinator,
|
24
|
+
this.value.eval ? this.value.eval(env) : this.value,
|
25
|
+
this.index);
|
26
|
+
},
|
27
|
+
toCSS: function (env) {
|
28
|
+
var value = (this.value.toCSS ? this.value.toCSS(env) : this.value);
|
29
|
+
if (value == '' && this.combinator.value.charAt(0) == '&') {
|
30
|
+
return '';
|
31
|
+
} else {
|
32
|
+
return this.combinator.toCSS(env || {}) + value;
|
33
|
+
}
|
34
|
+
}
|
20
35
|
};
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
36
|
+
|
37
|
+
tree.Attribute = function (key, op, value) {
|
38
|
+
this.key = key;
|
39
|
+
this.op = op;
|
40
|
+
this.value = value;
|
41
|
+
};
|
42
|
+
tree.Attribute.prototype = {
|
43
|
+
type: "Attribute",
|
44
|
+
accept: function (visitor) {
|
45
|
+
this.value = visitor.visit(this.value);
|
46
|
+
},
|
47
|
+
eval: function (env) {
|
48
|
+
return new(tree.Attribute)(this.key.eval ? this.key.eval(env) : this.key,
|
49
|
+
this.op, (this.value && this.value.eval) ? this.value.eval(env) : this.value);
|
50
|
+
},
|
51
|
+
toCSS: function (env) {
|
52
|
+
var value = this.key.toCSS ? this.key.toCSS(env) : this.key;
|
53
|
+
|
54
|
+
if (this.op) {
|
55
|
+
value += this.op;
|
56
|
+
value += (this.value.toCSS ? this.value.toCSS(env) : this.value);
|
57
|
+
}
|
58
|
+
|
59
|
+
return '[' + value + ']';
|
60
|
+
}
|
28
61
|
};
|
29
62
|
|
30
63
|
tree.Combinator = function (value) {
|
@@ -34,16 +67,19 @@ tree.Combinator = function (value) {
|
|
34
67
|
this.value = value ? value.trim() : "";
|
35
68
|
}
|
36
69
|
};
|
37
|
-
tree.Combinator.prototype
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
70
|
+
tree.Combinator.prototype = {
|
71
|
+
type: "Combinator",
|
72
|
+
toCSS: function (env) {
|
73
|
+
return {
|
74
|
+
'' : '',
|
75
|
+
' ' : ' ',
|
76
|
+
':' : ' :',
|
77
|
+
'+' : env.compress ? '+' : ' + ',
|
78
|
+
'~' : env.compress ? '~' : ' ~ ',
|
79
|
+
'>' : env.compress ? '>' : ' > ',
|
80
|
+
'|' : env.compress ? '|' : ' | '
|
81
|
+
}[this.value];
|
82
|
+
}
|
47
83
|
};
|
48
84
|
|
49
85
|
})(require('../tree'));
|
@@ -1,22 +1,47 @@
|
|
1
1
|
(function (tree) {
|
2
2
|
|
3
|
-
tree.Expression = function (value) { this.value = value };
|
3
|
+
tree.Expression = function (value) { this.value = value; };
|
4
4
|
tree.Expression.prototype = {
|
5
|
+
type: "Expression",
|
6
|
+
accept: function (visitor) {
|
7
|
+
this.value = visitor.visit(this.value);
|
8
|
+
},
|
5
9
|
eval: function (env) {
|
10
|
+
var returnValue,
|
11
|
+
inParenthesis = this.parens && !this.parensInOp,
|
12
|
+
doubleParen = false;
|
13
|
+
if (inParenthesis) {
|
14
|
+
env.inParenthesis();
|
15
|
+
}
|
6
16
|
if (this.value.length > 1) {
|
7
|
-
|
17
|
+
returnValue = new(tree.Expression)(this.value.map(function (e) {
|
8
18
|
return e.eval(env);
|
9
19
|
}));
|
10
20
|
} else if (this.value.length === 1) {
|
11
|
-
|
21
|
+
if (this.value[0].parens && !this.value[0].parensInOp) {
|
22
|
+
doubleParen = true;
|
23
|
+
}
|
24
|
+
returnValue = this.value[0].eval(env);
|
12
25
|
} else {
|
13
|
-
|
26
|
+
returnValue = this;
|
27
|
+
}
|
28
|
+
if (inParenthesis) {
|
29
|
+
env.outOfParenthesis();
|
14
30
|
}
|
31
|
+
if (this.parens && this.parensInOp && !(env.isMathOn()) && !doubleParen) {
|
32
|
+
returnValue = new(tree.Paren)(returnValue);
|
33
|
+
}
|
34
|
+
return returnValue;
|
15
35
|
},
|
16
36
|
toCSS: function (env) {
|
17
37
|
return this.value.map(function (e) {
|
18
38
|
return e.toCSS ? e.toCSS(env) : '';
|
19
39
|
}).join(' ');
|
40
|
+
},
|
41
|
+
throwAwayComments: function () {
|
42
|
+
this.value = this.value.filter(function(v) {
|
43
|
+
return !(v instanceof tree.Comment);
|
44
|
+
});
|
20
45
|
}
|
21
46
|
};
|
22
47
|
|
@@ -0,0 +1,43 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
tree.Extend = function Extend(selector, option, index) {
|
4
|
+
this.selector = selector;
|
5
|
+
this.option = option;
|
6
|
+
this.index = index;
|
7
|
+
|
8
|
+
switch(option) {
|
9
|
+
case "all":
|
10
|
+
this.allowBefore = true;
|
11
|
+
this.allowAfter = true;
|
12
|
+
break;
|
13
|
+
default:
|
14
|
+
this.allowBefore = false;
|
15
|
+
this.allowAfter = false;
|
16
|
+
break;
|
17
|
+
}
|
18
|
+
};
|
19
|
+
|
20
|
+
tree.Extend.prototype = {
|
21
|
+
type: "Extend",
|
22
|
+
accept: function (visitor) {
|
23
|
+
this.selector = visitor.visit(this.selector);
|
24
|
+
},
|
25
|
+
eval: function (env) {
|
26
|
+
return new(tree.Extend)(this.selector.eval(env), this.option, this.index);
|
27
|
+
},
|
28
|
+
clone: function (env) {
|
29
|
+
return new(tree.Extend)(this.selector, this.option, this.index);
|
30
|
+
},
|
31
|
+
findSelfSelectors: function (selectors) {
|
32
|
+
var selfElements = [],
|
33
|
+
i;
|
34
|
+
|
35
|
+
for(i = 0; i < selectors.length; i++) {
|
36
|
+
selfElements = selfElements.concat(selectors[i].elements);
|
37
|
+
}
|
38
|
+
|
39
|
+
this.selfSelectors = [{ elements: selfElements }];
|
40
|
+
}
|
41
|
+
};
|
42
|
+
|
43
|
+
})(require('../tree'));
|
@@ -11,31 +11,22 @@
|
|
11
11
|
// `import,push`, we also pass it a callback, which it'll call once
|
12
12
|
// the file has been fetched, and parsed.
|
13
13
|
//
|
14
|
-
tree.Import = function (path,
|
14
|
+
tree.Import = function (path, features, options, index, currentFileInfo) {
|
15
15
|
var that = this;
|
16
16
|
|
17
|
-
this.
|
17
|
+
this.options = options;
|
18
18
|
this.index = index;
|
19
|
-
this.
|
20
|
-
this.features = features
|
21
|
-
this.
|
22
|
-
|
23
|
-
// The '.less' extension is optional
|
24
|
-
if (path instanceof tree.Quoted) {
|
25
|
-
this.path = /(\.[a-z]*$)|([\?;].*)$/.test(path.value) ? path.value : path.value + '.less';
|
26
|
-
} else {
|
27
|
-
this.path = path.value.value || path.value;
|
28
|
-
}
|
19
|
+
this.path = path;
|
20
|
+
this.features = features;
|
21
|
+
this.currentFileInfo = currentFileInfo;
|
29
22
|
|
30
|
-
this.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
that.root = root || new(tree.Ruleset)([], []);
|
38
|
-
});
|
23
|
+
if (this.options.less !== undefined) {
|
24
|
+
this.css = !this.options.less;
|
25
|
+
} else {
|
26
|
+
var pathValue = this.getPath();
|
27
|
+
if (pathValue && /css([\?;].*)?$/.test(pathValue)) {
|
28
|
+
this.css = true;
|
29
|
+
}
|
39
30
|
}
|
40
31
|
};
|
41
32
|
|
@@ -49,26 +40,56 @@ tree.Import = function (path, imports, features, once, index, rootpath) {
|
|
49
40
|
// ruleset.
|
50
41
|
//
|
51
42
|
tree.Import.prototype = {
|
43
|
+
type: "Import",
|
44
|
+
accept: function (visitor) {
|
45
|
+
this.features = visitor.visit(this.features);
|
46
|
+
this.path = visitor.visit(this.path);
|
47
|
+
this.root = visitor.visit(this.root);
|
48
|
+
},
|
52
49
|
toCSS: function (env) {
|
53
50
|
var features = this.features ? ' ' + this.features.toCSS(env) : '';
|
54
51
|
|
55
52
|
if (this.css) {
|
56
|
-
|
57
|
-
if (typeof this._path.value === "string" && !/^(?:[a-z-]+:|\/)/.test(this._path.value)) {
|
58
|
-
this._path.value = this.rootpath + this._path.value;
|
59
|
-
}
|
60
|
-
return "@import " + this._path.toCSS() + features + ';\n';
|
53
|
+
return "@import " + this.path.toCSS() + features + ';\n';
|
61
54
|
} else {
|
62
55
|
return "";
|
63
56
|
}
|
64
57
|
},
|
58
|
+
getPath: function () {
|
59
|
+
if (this.path instanceof tree.Quoted) {
|
60
|
+
var path = this.path.value;
|
61
|
+
return (this.css !== undefined || /(\.[a-z]*$)|([\?;].*)$/.test(path)) ? path : path + '.less';
|
62
|
+
} else if (this.path instanceof tree.URL) {
|
63
|
+
return this.path.value.value;
|
64
|
+
}
|
65
|
+
return null;
|
66
|
+
},
|
67
|
+
evalForImport: function (env) {
|
68
|
+
return new(tree.Import)(this.path.eval(env), this.features, this.options, this.index, this.currentFileInfo);
|
69
|
+
},
|
70
|
+
evalPath: function (env) {
|
71
|
+
var path = this.path.eval(env);
|
72
|
+
var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath;
|
73
|
+
if (rootpath && !(path instanceof tree.URL)) {
|
74
|
+
var pathValue = path.value;
|
75
|
+
// Add the base path if the import is relative
|
76
|
+
if (pathValue && env.isPathRelative(pathValue)) {
|
77
|
+
path.value = rootpath + pathValue;
|
78
|
+
}
|
79
|
+
}
|
80
|
+
return path;
|
81
|
+
},
|
65
82
|
eval: function (env) {
|
66
83
|
var ruleset, features = this.features && this.features.eval(env);
|
67
84
|
|
68
|
-
if (this.skip) return [];
|
85
|
+
if (this.skip) { return []; }
|
69
86
|
|
70
87
|
if (this.css) {
|
71
|
-
|
88
|
+
var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index);
|
89
|
+
if (!newImport.css && this.error) {
|
90
|
+
throw this.error;
|
91
|
+
}
|
92
|
+
return newImport;
|
72
93
|
} else {
|
73
94
|
ruleset = new(tree.Ruleset)([], this.root.rules.slice(0));
|
74
95
|
|
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
tree.Keyword = function (value) { this.value = value };
|
4
4
|
tree.Keyword.prototype = {
|
5
|
-
|
6
|
-
|
5
|
+
type: "Keyword",
|
6
|
+
eval: function () { return this; },
|
7
|
+
toCSS: function () { return this.value; },
|
7
8
|
compare: function (other) {
|
8
9
|
if (other instanceof tree.Keyword) {
|
9
10
|
return other.value === this.value ? 0 : 1;
|
@@ -8,12 +8,16 @@ tree.Media = function (value, features) {
|
|
8
8
|
this.ruleset.allowImports = true;
|
9
9
|
};
|
10
10
|
tree.Media.prototype = {
|
11
|
-
|
11
|
+
type: "Media",
|
12
|
+
accept: function (visitor) {
|
13
|
+
this.features = visitor.visit(this.features);
|
14
|
+
this.ruleset = visitor.visit(this.ruleset);
|
15
|
+
},
|
16
|
+
toCSS: function (env) {
|
12
17
|
var features = this.features.toCSS(env);
|
13
18
|
|
14
|
-
this.ruleset.root = (ctx.length === 0 || ctx[0].multiMedia);
|
15
19
|
return '@media ' + features + (env.compress ? '{' : ' {\n ') +
|
16
|
-
this.ruleset.toCSS(
|
20
|
+
this.ruleset.toCSS(env).trim().replace(/\n/g, '\n ') +
|
17
21
|
(env.compress ? '}': '\n}\n');
|
18
22
|
},
|
19
23
|
eval: function (env) {
|
@@ -27,7 +31,19 @@ tree.Media.prototype = {
|
|
27
31
|
this.ruleset.debugInfo = this.debugInfo;
|
28
32
|
media.debugInfo = this.debugInfo;
|
29
33
|
}
|
30
|
-
|
34
|
+
var strictMathBypass = false;
|
35
|
+
if (!env.strictMath) {
|
36
|
+
strictMathBypass = true;
|
37
|
+
env.strictMath = true;
|
38
|
+
}
|
39
|
+
try {
|
40
|
+
media.features = this.features.eval(env);
|
41
|
+
}
|
42
|
+
finally {
|
43
|
+
if (strictMathBypass) {
|
44
|
+
env.strictMath = false;
|
45
|
+
}
|
46
|
+
}
|
31
47
|
|
32
48
|
env.mediaPath.push(media);
|
33
49
|
env.mediaBlocks.push(media);
|
@@ -1,14 +1,19 @@
|
|
1
1
|
(function (tree) {
|
2
2
|
|
3
3
|
tree.mixin = {};
|
4
|
-
tree.mixin.Call = function (elements, args, index,
|
4
|
+
tree.mixin.Call = function (elements, args, index, currentFileInfo, important) {
|
5
5
|
this.selector = new(tree.Selector)(elements);
|
6
6
|
this.arguments = args;
|
7
7
|
this.index = index;
|
8
|
-
this.
|
8
|
+
this.currentFileInfo = currentFileInfo;
|
9
9
|
this.important = important;
|
10
10
|
};
|
11
11
|
tree.mixin.Call.prototype = {
|
12
|
+
type: "MixinCall",
|
13
|
+
accept: function (visitor) {
|
14
|
+
this.selector = visitor.visit(this.selector);
|
15
|
+
this.arguments = visitor.visit(this.arguments);
|
16
|
+
},
|
12
17
|
eval: function (env) {
|
13
18
|
var mixins, mixin, args, rules = [], match = false, i, m, f, isRecursive, isOneFound;
|
14
19
|
|
@@ -37,7 +42,7 @@ tree.mixin.Call.prototype = {
|
|
37
42
|
Array.prototype.push.apply(
|
38
43
|
rules, mixin.eval(env, args, this.important).rules);
|
39
44
|
} catch (e) {
|
40
|
-
throw { message: e.message, index: this.index, filename: this.filename, stack: e.stack };
|
45
|
+
throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack };
|
41
46
|
}
|
42
47
|
}
|
43
48
|
match = true;
|
@@ -64,11 +69,11 @@ tree.mixin.Call.prototype = {
|
|
64
69
|
}
|
65
70
|
return argValue;
|
66
71
|
}).join(', ') : "") + ")`",
|
67
|
-
index: this.index, filename: this.filename };
|
72
|
+
index: this.index, filename: this.currentFileInfo.filename };
|
68
73
|
} else {
|
69
74
|
throw { type: 'Name',
|
70
75
|
message: this.selector.toCSS().trim() + " is undefined",
|
71
|
-
index: this.index, filename: this.filename };
|
76
|
+
index: this.index, filename: this.currentFileInfo.filename };
|
72
77
|
}
|
73
78
|
}
|
74
79
|
};
|
@@ -90,14 +95,25 @@ tree.mixin.Definition = function (name, params, rules, condition, variadic) {
|
|
90
95
|
this.frames = [];
|
91
96
|
};
|
92
97
|
tree.mixin.Definition.prototype = {
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
+
type: "MixinDefinition",
|
99
|
+
accept: function (visitor) {
|
100
|
+
this.params = visitor.visit(this.params);
|
101
|
+
this.rules = visitor.visit(this.rules);
|
102
|
+
this.condition = visitor.visit(this.condition);
|
103
|
+
},
|
104
|
+
toCSS: function () { return ""; },
|
105
|
+
variable: function (name) { return this.parent.variable.call(this, name); },
|
106
|
+
variables: function () { return this.parent.variables.call(this); },
|
107
|
+
find: function () { return this.parent.find.apply(this, arguments); },
|
108
|
+
rulesets: function () { return this.parent.rulesets.apply(this); },
|
98
109
|
|
99
110
|
evalParams: function (env, mixinEnv, args, evaldArguments) {
|
100
|
-
var frame = new(tree.Ruleset)(null, []),
|
111
|
+
var frame = new(tree.Ruleset)(null, []),
|
112
|
+
varargs, arg,
|
113
|
+
params = this.params.slice(0),
|
114
|
+
i, j, val, name, isNamedFound, argIndex;
|
115
|
+
|
116
|
+
mixinEnv = new tree.evalEnv(mixinEnv, [frame].concat(mixinEnv.frames));
|
101
117
|
|
102
118
|
if (args) {
|
103
119
|
args = args.slice(0);
|
@@ -144,6 +160,7 @@ tree.mixin.Definition.prototype = {
|
|
144
160
|
val = val.eval(env);
|
145
161
|
} else if (params[i].value) {
|
146
162
|
val = params[i].value.eval(mixinEnv);
|
163
|
+
frame.resetCache();
|
147
164
|
} else {
|
148
165
|
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
|
149
166
|
' (' + args.length + ' for ' + this.arity + ')' };
|
@@ -167,7 +184,7 @@ tree.mixin.Definition.prototype = {
|
|
167
184
|
eval: function (env, args, important) {
|
168
185
|
var _arguments = [],
|
169
186
|
mixinFrames = this.frames.concat(env.frames),
|
170
|
-
frame = this.evalParams(env,
|
187
|
+
frame = this.evalParams(env, new(tree.evalEnv)(env, mixinFrames), args, _arguments),
|
171
188
|
context, rules, start, ruleset;
|
172
189
|
|
173
190
|
frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
|
@@ -175,16 +192,19 @@ tree.mixin.Definition.prototype = {
|
|
175
192
|
rules = important ?
|
176
193
|
this.parent.makeImportant.apply(this).rules : this.rules.slice(0);
|
177
194
|
|
178
|
-
ruleset = new(tree.Ruleset)(null, rules).eval(
|
179
|
-
|
180
|
-
});
|
195
|
+
ruleset = new(tree.Ruleset)(null, rules).eval(new(tree.evalEnv)(env,
|
196
|
+
[this, frame].concat(mixinFrames)));
|
181
197
|
ruleset.originalRuleset = this;
|
182
198
|
return ruleset;
|
183
199
|
},
|
184
200
|
matchCondition: function (args, env) {
|
185
|
-
|
186
|
-
|
187
|
-
|
201
|
+
|
202
|
+
if (this.condition && !this.condition.eval(
|
203
|
+
new(tree.evalEnv)(env,
|
204
|
+
[this.evalParams(env, new(tree.evalEnv)(env, this.frames.concat(env.frames)), args, [])]
|
205
|
+
.concat(env.frames)))) {
|
206
|
+
return false;
|
207
|
+
}
|
188
208
|
return true;
|
189
209
|
},
|
190
210
|
matchArgs: function (args, env) {
|