less 2.5.1 → 2.6.1
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 +41 -0
- package/Gruntfile.js +5 -10
- package/README.md +3 -3
- package/appveyor.yml +2 -2
- package/bin/lessc +1 -0
- package/bower.json +1 -2
- package/dist/less.js +969 -605
- package/dist/less.min.js +13 -9
- package/gradlew +0 -0
- package/lib/less/contexts.js +0 -1
- package/lib/less/functions/color.js +5 -2
- package/lib/less/functions/math-helper.js +16 -0
- package/lib/less/functions/math.js +4 -16
- package/lib/less/functions/number.js +7 -2
- package/lib/less/index.js +1 -1
- package/lib/less/parser/parser-input.js +68 -68
- package/lib/less/parser/parser.js +159 -75
- package/lib/less/transform-tree.js +1 -0
- package/lib/less/tree/anonymous.js +4 -2
- package/lib/less/tree/color.js +4 -1
- package/lib/less/tree/comment.js +2 -6
- package/lib/less/tree/directive.js +3 -18
- package/lib/less/tree/element.js +9 -2
- package/lib/less/tree/extend.js +10 -5
- package/lib/less/tree/import.js +23 -5
- package/lib/less/tree/media.js +4 -2
- package/lib/less/tree/mixin-call.js +31 -18
- package/lib/less/tree/mixin-definition.js +19 -7
- package/lib/less/tree/node.js +49 -0
- package/lib/less/tree/rule.js +1 -1
- package/lib/less/tree/ruleset.js +107 -125
- package/lib/less/tree/selector.js +4 -9
- package/lib/less/tree/unit.js +2 -2
- package/lib/less/visitors/extend-visitor.js +17 -8
- package/lib/less/visitors/import-visitor.js +5 -0
- package/lib/less/visitors/index.js +1 -0
- package/lib/less/visitors/set-tree-visibility-visitor.js +38 -0
- package/lib/less/visitors/to-css-visitor.js +181 -98
- package/lib/less-browser/bootstrap.js +28 -2
- package/lib/less-browser/cache.js +11 -4
- package/lib/less-browser/error-reporting.js +10 -10
- package/lib/less-browser/file-manager.js +1 -1
- package/lib/less-browser/image-size.js +28 -0
- package/lib/less-browser/index.js +9 -10
- package/package.json +14 -14
- package/test/browser/less/errors/image-height-error.less +3 -0
- package/test/browser/less/errors/image-height-error.txt +4 -0
- package/test/browser/less/errors/image-size-error.less +3 -0
- package/test/browser/less/errors/image-size-error.txt +4 -0
- package/test/browser/less/errors/image-width-error.less +3 -0
- package/test/browser/less/errors/image-width-error.txt +4 -0
- package/test/browser/less.js +23 -19
- package/test/css/comments2.css +7 -1
- package/test/css/compression/compression.css +1 -1
- package/test/css/css-3.css +6 -0
- package/test/css/extend-selector.css +7 -0
- package/test/css/extract-and-length.css +1 -1
- package/test/css/functions.css +3 -3
- package/test/css/import-reference-issues.css +24 -0
- package/test/css/import-reference.css +5 -1
- package/test/css/include-path/include-path.css +1 -1
- package/test/css/include-path-string/include-path-string.css +1 -1
- package/test/css/mixins-args.css +51 -1
- package/test/css/mixins-guards.css +36 -0
- package/test/css/no-strict-math/mixins-guards.css +12 -0
- package/test/css/no-strict-math/no-sm-operations.css +12 -0
- package/test/css/operations.css +1 -0
- package/test/css/scope.css +1 -1
- package/test/css/strings.css +1 -1
- package/test/css/url-args/urls.css +5 -5
- package/test/css/urls.css +8 -8
- package/test/css/variables.css +5 -5
- package/test/data/image.jpg +0 -0
- package/test/data/image.svg +2 -1
- package/test/data/page.html +1 -1
- package/test/index.js +1 -0
- package/test/less/comments2.less +11 -0
- package/test/less/css-3.less +10 -2
- package/test/less/errors/at-rules-undefined-var.txt +4 -4
- package/test/less/errors/css-guard-default-func.txt +4 -4
- package/test/less/errors/javascript-undefined-var.txt +4 -4
- package/test/less/errors/mixins-guards-default-func-1.txt +4 -4
- package/test/less/errors/mixins-guards-default-func-2.txt +4 -4
- package/test/less/errors/mixins-guards-default-func-3.txt +4 -4
- package/test/less/errors/parse-error-media-no-block-1.txt +1 -1
- package/test/less/errors/parse-error-media-no-block-2.txt +1 -1
- package/test/less/errors/parse-error-media-no-block-3.txt +1 -1
- package/test/less/errors/percentage-non-number-argument.less +3 -0
- package/test/less/errors/percentage-non-number-argument.txt +4 -0
- package/test/less/errors/property-interp-not-defined.txt +2 -2
- package/test/less/extend-selector.less +12 -1
- package/test/less/import/import-inline-invalid-css.less +1 -0
- package/test/less/import/import-reference.less +10 -1
- package/test/less/import-reference-issues/appender-reference-1968.less +6 -0
- package/test/less/import-reference-issues/global-scope-import.less +13 -0
- package/test/less/import-reference-issues/global-scope-nested.less +3 -0
- package/test/less/import-reference-issues/mixin-1968.less +8 -0
- package/test/less/import-reference-issues/multiple-import-nested.less +12 -0
- package/test/less/import-reference-issues/multiple-import.less +10 -0
- package/test/less/import-reference-issues/simple-mixin.css +3 -0
- package/test/less/import-reference-issues/simple-ruleset-2162.less +3 -0
- package/test/less/import-reference-issues.less +50 -0
- package/test/less/import-reference.less +2 -0
- package/test/less/mixins-args.less +48 -0
- package/test/less/mixins-guards.less +78 -0
- package/test/less/no-strict-math/mixins-guards.less +25 -0
- package/test/less/no-strict-math/no-sm-operations.less +10 -0
- package/test/less/operations.less +1 -0
- package/test/less-bom/comments2.less +11 -0
- package/test/less-bom/css-3.less +10 -2
- package/test/less-bom/errors/at-rules-undefined-var.txt +4 -4
- package/test/less-bom/errors/css-guard-default-func.txt +4 -4
- package/test/less-bom/errors/javascript-undefined-var.txt +4 -4
- package/test/less-bom/errors/mixins-guards-default-func-1.txt +4 -4
- package/test/less-bom/errors/mixins-guards-default-func-2.txt +4 -4
- package/test/less-bom/errors/mixins-guards-default-func-3.txt +4 -4
- package/test/less-bom/errors/parse-error-media-no-block-1.txt +1 -1
- package/test/less-bom/errors/parse-error-media-no-block-2.txt +1 -1
- package/test/less-bom/errors/parse-error-media-no-block-3.txt +1 -1
- package/test/less-bom/errors/percentage-non-number-argument.less +3 -0
- package/test/less-bom/errors/percentage-non-number-argument.txt +4 -0
- package/test/less-bom/errors/property-interp-not-defined.txt +2 -2
- package/test/less-bom/extend-selector.less +12 -1
- package/test/less-bom/import/import-inline-invalid-css.less +1 -0
- package/test/less-bom/import/import-reference.less +10 -1
- package/test/less-bom/import-reference-issues/appender-reference-1968.less +6 -0
- package/test/less-bom/import-reference-issues/global-scope-import.less +13 -0
- package/test/less-bom/import-reference-issues/global-scope-nested.less +3 -0
- package/test/less-bom/import-reference-issues/mixin-1968.less +8 -0
- package/test/less-bom/import-reference-issues/multiple-import-nested.less +12 -0
- package/test/less-bom/import-reference-issues/multiple-import.less +10 -0
- package/test/less-bom/import-reference-issues/simple-mixin.css +3 -0
- package/test/less-bom/import-reference-issues/simple-ruleset-2162.less +3 -0
- package/test/less-bom/import-reference-issues.less +50 -0
- package/test/less-bom/import-reference.less +2 -0
- package/test/less-bom/mixins-args.less +48 -0
- package/test/less-bom/mixins-guards.less +78 -0
- package/test/less-bom/no-strict-math/mixins-guards.less +25 -0
- package/test/less-bom/no-strict-math/no-sm-operations.less +10 -0
- package/test/less-bom/operations.less +1 -0
- package/test/less-test.js +6 -1
- package/.idea/.name +0 -1
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/less.js.iml +0 -9
- package/.idea/libraries/less_js_node_modules.xml +0 -14
- package/.idea/misc.xml +0 -14
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -281
|
@@ -1,9 +1,97 @@
|
|
|
1
1
|
var tree = require("../tree"),
|
|
2
2
|
Visitor = require("./visitor");
|
|
3
3
|
|
|
4
|
+
var CSSVisitorUtils = function(context) {
|
|
5
|
+
this._visitor = new Visitor(this);
|
|
6
|
+
this._context = context;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
CSSVisitorUtils.prototype = {
|
|
10
|
+
containsSilentNonBlockedChild: function(bodyRules) {
|
|
11
|
+
var rule;
|
|
12
|
+
if (bodyRules == null) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
for (var r = 0; r < bodyRules.length; r++) {
|
|
16
|
+
rule = bodyRules[r];
|
|
17
|
+
if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {
|
|
18
|
+
//the directive contains something that was referenced (likely by extend)
|
|
19
|
+
//therefore it needs to be shown in output too
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return false;
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
keepOnlyVisibleChilds: function(owner) {
|
|
27
|
+
if (owner == null || owner.rules == null) {
|
|
28
|
+
return ;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
owner.rules = owner.rules.filter(function(thing) {
|
|
32
|
+
return thing.isVisible();
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
isEmpty: function(owner) {
|
|
38
|
+
if (owner == null || owner.rules == null) {
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return owner.rules.length === 0;
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
hasVisibleSelector: function(rulesetNode) {
|
|
45
|
+
if (rulesetNode == null || rulesetNode.paths == null) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return rulesetNode.paths.length > 0;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
resolveVisibility: function (node, originalRules) {
|
|
52
|
+
if (!node.blocksVisibility()) {
|
|
53
|
+
if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {
|
|
54
|
+
return ;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return node;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var compiledRulesBody = node.rules[0];
|
|
61
|
+
this.keepOnlyVisibleChilds(compiledRulesBody);
|
|
62
|
+
|
|
63
|
+
if (this.isEmpty(compiledRulesBody)) {
|
|
64
|
+
return ;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
node.ensureVisibility();
|
|
68
|
+
node.removeVisibilityBlock();
|
|
69
|
+
|
|
70
|
+
return node;
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
isVisibleRuleset: function(rulesetNode) {
|
|
74
|
+
if (rulesetNode.firstRoot) {
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.isEmpty(rulesetNode)) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
};
|
|
90
|
+
|
|
4
91
|
var ToCSSVisitor = function(context) {
|
|
5
92
|
this._visitor = new Visitor(this);
|
|
6
93
|
this._context = context;
|
|
94
|
+
this.utils = new CSSVisitorUtils(context);
|
|
7
95
|
};
|
|
8
96
|
|
|
9
97
|
ToCSSVisitor.prototype = {
|
|
@@ -13,7 +101,7 @@ ToCSSVisitor.prototype = {
|
|
|
13
101
|
},
|
|
14
102
|
|
|
15
103
|
visitRule: function (ruleNode, visitArgs) {
|
|
16
|
-
if (ruleNode.variable) {
|
|
104
|
+
if (ruleNode.blocksVisibility() || ruleNode.variable) {
|
|
17
105
|
return;
|
|
18
106
|
}
|
|
19
107
|
return ruleNode;
|
|
@@ -29,34 +117,71 @@ ToCSSVisitor.prototype = {
|
|
|
29
117
|
},
|
|
30
118
|
|
|
31
119
|
visitComment: function (commentNode, visitArgs) {
|
|
32
|
-
if (commentNode.isSilent(this._context)) {
|
|
120
|
+
if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {
|
|
33
121
|
return;
|
|
34
122
|
}
|
|
35
123
|
return commentNode;
|
|
36
124
|
},
|
|
37
125
|
|
|
38
126
|
visitMedia: function(mediaNode, visitArgs) {
|
|
127
|
+
var originalRules = mediaNode.rules[0].rules;
|
|
39
128
|
mediaNode.accept(this._visitor);
|
|
40
129
|
visitArgs.visitDeeper = false;
|
|
41
130
|
|
|
42
|
-
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
return mediaNode;
|
|
131
|
+
return this.utils.resolveVisibility(mediaNode, originalRules);
|
|
46
132
|
},
|
|
47
133
|
|
|
48
134
|
visitImport: function (importNode, visitArgs) {
|
|
49
|
-
if (importNode.
|
|
50
|
-
return;
|
|
135
|
+
if (importNode.blocksVisibility()) {
|
|
136
|
+
return ;
|
|
51
137
|
}
|
|
52
138
|
return importNode;
|
|
53
139
|
},
|
|
54
140
|
|
|
55
141
|
visitDirective: function(directiveNode, visitArgs) {
|
|
56
|
-
if (directiveNode.
|
|
57
|
-
|
|
58
|
-
|
|
142
|
+
if (directiveNode.rules && directiveNode.rules.length) {
|
|
143
|
+
return this.visitDirectiveWithBody(directiveNode, visitArgs);
|
|
144
|
+
} else {
|
|
145
|
+
return this.visitDirectiveWithoutBody(directiveNode, visitArgs);
|
|
146
|
+
}
|
|
147
|
+
return directiveNode;
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
visitDirectiveWithBody: function(directiveNode, visitArgs) {
|
|
151
|
+
//if there is only one nested ruleset and that one has no path, then it is
|
|
152
|
+
//just fake ruleset
|
|
153
|
+
function hasFakeRuleset(directiveNode) {
|
|
154
|
+
var bodyRules = directiveNode.rules;
|
|
155
|
+
return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);
|
|
156
|
+
}
|
|
157
|
+
function getBodyRules(directiveNode) {
|
|
158
|
+
var nodeRules = directiveNode.rules;
|
|
159
|
+
if (hasFakeRuleset(directiveNode)) {
|
|
160
|
+
return nodeRules[0].rules;
|
|
59
161
|
}
|
|
162
|
+
|
|
163
|
+
return nodeRules;
|
|
164
|
+
}
|
|
165
|
+
//it is still true that it is only one ruleset in array
|
|
166
|
+
//this is last such moment
|
|
167
|
+
//process childs
|
|
168
|
+
var originalRules = getBodyRules(directiveNode);
|
|
169
|
+
directiveNode.accept(this._visitor);
|
|
170
|
+
visitArgs.visitDeeper = false;
|
|
171
|
+
|
|
172
|
+
if (!this.utils.isEmpty(directiveNode)) {
|
|
173
|
+
this._mergeRules(directiveNode.rules[0].rules);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return this.utils.resolveVisibility(directiveNode, originalRules);
|
|
177
|
+
},
|
|
178
|
+
|
|
179
|
+
visitDirectiveWithoutBody: function(directiveNode, visitArgs) {
|
|
180
|
+
if (directiveNode.blocksVisibility()) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (directiveNode.name === "@charset") {
|
|
60
185
|
// Only output the debug info together with subsequent @charset definitions
|
|
61
186
|
// a comment (or @media statement) before the actual @charset directive would
|
|
62
187
|
// be considered illegal css as it has to be on the first line
|
|
@@ -70,59 +195,7 @@ ToCSSVisitor.prototype = {
|
|
|
70
195
|
}
|
|
71
196
|
this.charset = true;
|
|
72
197
|
}
|
|
73
|
-
function hasVisibleChild(directiveNode) {
|
|
74
|
-
//prepare list of childs
|
|
75
|
-
var rule, bodyRules = directiveNode.rules;
|
|
76
|
-
//if there is only one nested ruleset and that one has no path, then it is
|
|
77
|
-
//just fake ruleset that got not replaced and we need to look inside it to
|
|
78
|
-
//get real childs
|
|
79
|
-
if (bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0)) {
|
|
80
|
-
bodyRules = bodyRules[0].rules;
|
|
81
|
-
}
|
|
82
|
-
for (var r = 0; r < bodyRules.length; r++) {
|
|
83
|
-
rule = bodyRules[r];
|
|
84
|
-
if (rule.getIsReferenced && rule.getIsReferenced()) {
|
|
85
|
-
//the directive contains something that was referenced (likely by extend)
|
|
86
|
-
//therefore it needs to be shown in output too
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (directiveNode.rules && directiveNode.rules.length) {
|
|
94
|
-
//it is still true that it is only one ruleset in array
|
|
95
|
-
//this is last such moment
|
|
96
|
-
this._mergeRules(directiveNode.rules[0].rules);
|
|
97
|
-
//process childs
|
|
98
|
-
directiveNode.accept(this._visitor);
|
|
99
|
-
visitArgs.visitDeeper = false;
|
|
100
|
-
|
|
101
|
-
// the directive was directly referenced and therefore needs to be shown in the output
|
|
102
|
-
if (directiveNode.getIsReferenced()) {
|
|
103
|
-
return directiveNode;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (!directiveNode.rules || !directiveNode.rules.length) {
|
|
107
|
-
return ;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
//the directive was not directly referenced - we need to check whether some of its childs
|
|
111
|
-
//was referenced
|
|
112
|
-
if (hasVisibleChild(directiveNode)) {
|
|
113
|
-
//marking as referenced in case the directive is stored inside another directive
|
|
114
|
-
directiveNode.markReferenced();
|
|
115
|
-
return directiveNode;
|
|
116
|
-
}
|
|
117
198
|
|
|
118
|
-
//The directive was not directly referenced and does not contain anything that
|
|
119
|
-
//was referenced. Therefore it must not be shown in output.
|
|
120
|
-
return ;
|
|
121
|
-
} else {
|
|
122
|
-
if (!directiveNode.getIsReferenced()) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
199
|
return directiveNode;
|
|
127
200
|
},
|
|
128
201
|
|
|
@@ -138,28 +211,16 @@ ToCSSVisitor.prototype = {
|
|
|
138
211
|
},
|
|
139
212
|
|
|
140
213
|
visitRuleset: function (rulesetNode, visitArgs) {
|
|
214
|
+
//at this point rulesets are nested into each other
|
|
141
215
|
var rule, rulesets = [];
|
|
142
216
|
if (rulesetNode.firstRoot) {
|
|
143
217
|
this.checkPropertiesInRoot(rulesetNode.rules);
|
|
144
218
|
}
|
|
145
219
|
if (! rulesetNode.root) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
.filter(function(p) {
|
|
149
|
-
var i;
|
|
150
|
-
if (p[0].elements[0].combinator.value === ' ') {
|
|
151
|
-
p[0].elements[0].combinator = new(tree.Combinator)('');
|
|
152
|
-
}
|
|
153
|
-
for (i = 0; i < p.length; i++) {
|
|
154
|
-
if (p[i].getIsReferenced() && p[i].getIsOutput()) {
|
|
155
|
-
return true;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
return false;
|
|
159
|
-
});
|
|
160
|
-
}
|
|
220
|
+
//remove invisible paths
|
|
221
|
+
this._compileRulesetPaths(rulesetNode);
|
|
161
222
|
|
|
162
|
-
//
|
|
223
|
+
// remove rulesets from this ruleset body and compile them separately
|
|
163
224
|
var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0;
|
|
164
225
|
for (var i = 0; i < nodeRuleCnt; ) {
|
|
165
226
|
rule = nodeRules[i];
|
|
@@ -173,7 +234,8 @@ ToCSSVisitor.prototype = {
|
|
|
173
234
|
i++;
|
|
174
235
|
}
|
|
175
236
|
// accept the visitor to remove rules and refactor itself
|
|
176
|
-
// then we can decide
|
|
237
|
+
// then we can decide nogw whether we want it or not
|
|
238
|
+
// compile body
|
|
177
239
|
if (nodeRuleCnt > 0) {
|
|
178
240
|
rulesetNode.accept(this._visitor);
|
|
179
241
|
} else {
|
|
@@ -181,33 +243,46 @@ ToCSSVisitor.prototype = {
|
|
|
181
243
|
}
|
|
182
244
|
visitArgs.visitDeeper = false;
|
|
183
245
|
|
|
184
|
-
|
|
185
|
-
if (nodeRules) {
|
|
186
|
-
this._mergeRules(nodeRules);
|
|
187
|
-
nodeRules = rulesetNode.rules;
|
|
188
|
-
}
|
|
189
|
-
if (nodeRules) {
|
|
190
|
-
this._removeDuplicateRules(nodeRules);
|
|
191
|
-
nodeRules = rulesetNode.rules;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// now decide whether we keep the ruleset
|
|
195
|
-
if (nodeRules && nodeRules.length > 0 && rulesetNode.paths.length > 0) {
|
|
196
|
-
rulesets.splice(0, 0, rulesetNode);
|
|
197
|
-
}
|
|
198
|
-
} else {
|
|
246
|
+
} else { //if (! rulesetNode.root) {
|
|
199
247
|
rulesetNode.accept(this._visitor);
|
|
200
248
|
visitArgs.visitDeeper = false;
|
|
201
|
-
if (rulesetNode.firstRoot || (rulesetNode.rules && rulesetNode.rules.length > 0)) {
|
|
202
|
-
rulesets.splice(0, 0, rulesetNode);
|
|
203
|
-
}
|
|
204
249
|
}
|
|
250
|
+
|
|
251
|
+
if (rulesetNode.rules) {
|
|
252
|
+
this._mergeRules(rulesetNode.rules);
|
|
253
|
+
this._removeDuplicateRules(rulesetNode.rules);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
//now decide whether we keep the ruleset
|
|
257
|
+
if (this.utils.isVisibleRuleset(rulesetNode)) {
|
|
258
|
+
rulesetNode.ensureVisibility();
|
|
259
|
+
rulesets.splice(0, 0, rulesetNode);
|
|
260
|
+
}
|
|
261
|
+
|
|
205
262
|
if (rulesets.length === 1) {
|
|
206
263
|
return rulesets[0];
|
|
207
264
|
}
|
|
208
265
|
return rulesets;
|
|
209
266
|
},
|
|
210
267
|
|
|
268
|
+
_compileRulesetPaths: function(rulesetNode) {
|
|
269
|
+
if (rulesetNode.paths) {
|
|
270
|
+
rulesetNode.paths = rulesetNode.paths
|
|
271
|
+
.filter(function(p) {
|
|
272
|
+
var i;
|
|
273
|
+
if (p[0].elements[0].combinator.value === ' ') {
|
|
274
|
+
p[0].elements[0].combinator = new(tree.Combinator)('');
|
|
275
|
+
}
|
|
276
|
+
for (i = 0; i < p.length; i++) {
|
|
277
|
+
if (p[i].isVisible() && p[i].getIsOutput()) {
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return false;
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
|
|
211
286
|
_removeDuplicateRules: function(rules) {
|
|
212
287
|
if (!rules) { return; }
|
|
213
288
|
|
|
@@ -294,6 +369,14 @@ ToCSSVisitor.prototype = {
|
|
|
294
369
|
rule.value = toValue(spacedGroups);
|
|
295
370
|
}
|
|
296
371
|
});
|
|
372
|
+
},
|
|
373
|
+
|
|
374
|
+
visitAnonymous: function(anonymousNode, visitArgs) {
|
|
375
|
+
if (anonymousNode.blocksVisibility()) {
|
|
376
|
+
return ;
|
|
377
|
+
}
|
|
378
|
+
anonymousNode.accept(this._visitor);
|
|
379
|
+
return anonymousNode;
|
|
297
380
|
}
|
|
298
381
|
};
|
|
299
382
|
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* used in the browser distributed version of less
|
|
4
4
|
* to kick-start less using the browser api
|
|
5
5
|
*/
|
|
6
|
-
/*global window */
|
|
6
|
+
/*global window, document */
|
|
7
7
|
|
|
8
8
|
// shim Promise if required
|
|
9
9
|
require('promise/polyfill.js');
|
|
@@ -15,11 +15,37 @@ var less = module.exports = require("./index")(window, options);
|
|
|
15
15
|
|
|
16
16
|
window.less = less;
|
|
17
17
|
|
|
18
|
+
var css, head, style;
|
|
19
|
+
|
|
20
|
+
// Always restore page visibility
|
|
21
|
+
function resolveOrReject(data) {
|
|
22
|
+
if (data.filename) {
|
|
23
|
+
console.warn(data);
|
|
24
|
+
}
|
|
25
|
+
if (!options.async) {
|
|
26
|
+
head.removeChild(style);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
if (options.onReady) {
|
|
19
31
|
if (/!watch/.test(window.location.hash)) {
|
|
20
32
|
less.watch();
|
|
21
33
|
}
|
|
34
|
+
// Simulate synchronous stylesheet loading by blocking page rendering
|
|
35
|
+
if (!options.async) {
|
|
36
|
+
css = 'body { display: none !important }';
|
|
37
|
+
head = document.head || document.getElementsByTagName('head')[0];
|
|
38
|
+
style = document.createElement('style');
|
|
39
|
+
|
|
40
|
+
style.type = 'text/css';
|
|
41
|
+
if (style.styleSheet) {
|
|
42
|
+
style.styleSheet.cssText = css;
|
|
43
|
+
} else {
|
|
44
|
+
style.appendChild(document.createTextNode(css));
|
|
45
|
+
}
|
|
22
46
|
|
|
47
|
+
head.appendChild(style);
|
|
48
|
+
}
|
|
23
49
|
less.registerStylesheetsImmediately();
|
|
24
|
-
less.pageLoadFinished = less.refresh(less.env === 'development');
|
|
50
|
+
less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);
|
|
25
51
|
}
|
|
@@ -8,25 +8,32 @@ module.exports = function(window, options, logger) {
|
|
|
8
8
|
} catch (_) {}
|
|
9
9
|
}
|
|
10
10
|
return {
|
|
11
|
-
setCSS: function(path, lastModified, styles) {
|
|
11
|
+
setCSS: function(path, lastModified, modifyVars, styles) {
|
|
12
12
|
if (cache) {
|
|
13
13
|
logger.info('saving ' + path + ' to cache.');
|
|
14
14
|
try {
|
|
15
15
|
cache.setItem(path, styles);
|
|
16
16
|
cache.setItem(path + ':timestamp', lastModified);
|
|
17
|
+
if (modifyVars) {
|
|
18
|
+
cache.setItem(path + ':vars', JSON.stringify(modifyVars));
|
|
19
|
+
}
|
|
17
20
|
} catch(e) {
|
|
18
21
|
//TODO - could do with adding more robust error handling
|
|
19
22
|
logger.error('failed to save "' + path + '" to local storage for caching.');
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
},
|
|
23
|
-
getCSS: function(path, webInfo) {
|
|
26
|
+
getCSS: function(path, webInfo, modifyVars) {
|
|
24
27
|
var css = cache && cache.getItem(path),
|
|
25
|
-
timestamp = cache && cache.getItem(path + ':timestamp')
|
|
28
|
+
timestamp = cache && cache.getItem(path + ':timestamp'),
|
|
29
|
+
vars = cache && cache.getItem(path + ':vars');
|
|
30
|
+
|
|
31
|
+
modifyVars = modifyVars || {};
|
|
26
32
|
|
|
27
33
|
if (timestamp && webInfo.lastModified &&
|
|
28
34
|
(new Date(webInfo.lastModified).valueOf() ===
|
|
29
|
-
new Date(timestamp).valueOf())
|
|
35
|
+
new Date(timestamp).valueOf()) &&
|
|
36
|
+
(!modifyVars && !vars || JSON.stringify(modifyVars) === vars)) {
|
|
30
37
|
// Use local copy
|
|
31
38
|
return css;
|
|
32
39
|
}
|
|
@@ -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
|
|
@@ -39,7 +39,7 @@ module.exports = function(options, logger) {
|
|
|
39
39
|
FileManager.prototype.doXHR = function doXHR(url, type, callback, errback) {
|
|
40
40
|
|
|
41
41
|
var xhr = getXMLHttpRequest();
|
|
42
|
-
var async = options.isFileProtocol ? options.fileAsync :
|
|
42
|
+
var async = options.isFileProtocol ? options.fileAsync : true;
|
|
43
43
|
|
|
44
44
|
if (typeof xhr.overrideMimeType === 'function') {
|
|
45
45
|
xhr.overrideMimeType('text/css');
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module.exports = function() {
|
|
2
|
+
|
|
3
|
+
var functionRegistry = require("./../less/functions/function-registry");
|
|
4
|
+
|
|
5
|
+
function imageSize() {
|
|
6
|
+
throw {
|
|
7
|
+
type: "Runtime",
|
|
8
|
+
message: "Image size functions are not supported in browser version of less"
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
var imageFunctions = {
|
|
13
|
+
"image-size": function(filePathNode) {
|
|
14
|
+
imageSize(this, filePathNode);
|
|
15
|
+
return -1;
|
|
16
|
+
},
|
|
17
|
+
"image-width": function(filePathNode) {
|
|
18
|
+
imageSize(this, filePathNode);
|
|
19
|
+
return -1;
|
|
20
|
+
},
|
|
21
|
+
"image-height": function(filePathNode) {
|
|
22
|
+
imageSize(this, filePathNode);
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
functionRegistry.addMultiple(imageFunctions);
|
|
28
|
+
};
|
|
@@ -8,6 +8,7 @@ var addDataAttr = require("./utils").addDataAttr,
|
|
|
8
8
|
module.exports = function(window, options) {
|
|
9
9
|
var document = window.document;
|
|
10
10
|
var less = require('../less')();
|
|
11
|
+
|
|
11
12
|
//module.exports = less;
|
|
12
13
|
less.options = options;
|
|
13
14
|
var environment = less.environment,
|
|
@@ -19,6 +20,7 @@ module.exports = function(window, options) {
|
|
|
19
20
|
require("./log-listener")(less, options);
|
|
20
21
|
var errors = require("./error-reporting")(window, less, options);
|
|
21
22
|
var cache = less.cache = options.cache || require("./cache")(window, options, less.logger);
|
|
23
|
+
require('./image-size')(less.environment);
|
|
22
24
|
|
|
23
25
|
//Setup user functions
|
|
24
26
|
if (options.functions) {
|
|
@@ -112,14 +114,13 @@ module.exports = function(window, options) {
|
|
|
112
114
|
if (webInfo) {
|
|
113
115
|
webInfo.remaining = remaining;
|
|
114
116
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
117
|
+
var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);
|
|
118
|
+
if (!reload && css) {
|
|
119
|
+
webInfo.local = true;
|
|
120
|
+
callback(null, css, data, sheet, webInfo, path);
|
|
121
|
+
return;
|
|
122
122
|
}
|
|
123
|
+
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
//TODO add tests around how this behaves when reloading
|
|
@@ -132,9 +133,7 @@ module.exports = function(window, options) {
|
|
|
132
133
|
callback(e);
|
|
133
134
|
} else {
|
|
134
135
|
result.css = postProcessCSS(result.css);
|
|
135
|
-
|
|
136
|
-
cache.setCSS(sheet.href, webInfo.lastModified, result.css);
|
|
137
|
-
}
|
|
136
|
+
cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);
|
|
138
137
|
callback(null, result.css, data, sheet, webInfo, path);
|
|
139
138
|
}
|
|
140
139
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "less",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"description": "Leaner CSS",
|
|
5
5
|
"homepage": "http://lesscss.org",
|
|
6
6
|
"author": {
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
},
|
|
38
38
|
"optionalDependencies": {
|
|
39
39
|
"errno": "^0.1.1",
|
|
40
|
-
"graceful-fs": "^
|
|
41
|
-
"image-size": "~0.
|
|
40
|
+
"graceful-fs": "^4.1.2",
|
|
41
|
+
"image-size": "~0.4.0",
|
|
42
42
|
"mime": "^1.2.11",
|
|
43
43
|
"mkdirp": "^0.5.0",
|
|
44
|
-
"promise": "^
|
|
44
|
+
"promise": "^7.1.1",
|
|
45
45
|
"request": "^2.51.0",
|
|
46
|
-
"source-map": "^0.
|
|
46
|
+
"source-map": "^0.5.3"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"diff": "^1
|
|
49
|
+
"diff": "^2.2.1",
|
|
50
50
|
"grunt": "^0.4.5",
|
|
51
|
-
"grunt-contrib-clean": "^0.
|
|
52
|
-
"grunt-contrib-concat": "^0.
|
|
53
|
-
"grunt-contrib-connect": "^0.
|
|
54
|
-
"grunt-contrib-jasmine": "^0.
|
|
55
|
-
"grunt-contrib-jshint": "^0.
|
|
56
|
-
"grunt-contrib-uglify": "^0.
|
|
57
|
-
"grunt-jscs": "^
|
|
51
|
+
"grunt-contrib-clean": "^1.0.0",
|
|
52
|
+
"grunt-contrib-concat": "^1.0.0",
|
|
53
|
+
"grunt-contrib-connect": "^0.11.2",
|
|
54
|
+
"grunt-contrib-jasmine": "^1.0.0",
|
|
55
|
+
"grunt-contrib-jshint": "^1.0.0",
|
|
56
|
+
"grunt-contrib-uglify": "^0.11.0",
|
|
57
|
+
"grunt-jscs": "^2.7.0",
|
|
58
58
|
"grunt-shell": "^1.1.1",
|
|
59
|
-
"grunt-browserify": "~
|
|
59
|
+
"grunt-browserify": "~4.0.1",
|
|
60
60
|
"jit-grunt": "^0.9.1",
|
|
61
61
|
"time-grunt": "^1.0.0",
|
|
62
62
|
"grunt-saucelabs": "^8.3.2"
|