Skip to content

Commit baf45ea

Browse files
committed
Merge pull request #2729 from SomMeri/master
Fixing import by reference
2 parents 73e79b0 + e753a7e commit baf45ea

31 files changed

+509
-251
lines changed

lib/less/contexts.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ var parseCopyProperties = [
3030
// context
3131
'processImports', // option & context - whether to process imports. if false then imports will not be imported.
3232
// Used by the import manager to stop multiple import visitors being created.
33-
'reference', // Used to indicate that the contents are imported by reference
3433
'pluginManager' // Used as the plugin manager for the session
3534
];
3635

lib/less/parser/parser.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ var LessError = require('../less-error'),
3535
// Token matching is done with the `$` function, which either takes
3636
// a terminal string or regexp, or a non-terminal function to call.
3737
// It also takes care of moving all the indices forwards.
38-
//
38+
//`
3939
//
4040
var Parser = function Parser(context, imports, fileInfo) {
4141
var parsers,
@@ -603,7 +603,7 @@ var Parser = function Parser(context, imports, fileInfo) {
603603
if (!elements) {
604604
error("Missing target selector for :extend().");
605605
}
606-
extend = new(tree.Extend)(new(tree.Selector)(elements), option, index);
606+
extend = new(tree.Extend)(new(tree.Selector)(elements), option, index, fileInfo);
607607
if (extendList) {
608608
extendList.push(extend);
609609
} else {
@@ -1474,7 +1474,6 @@ var Parser = function Parser(context, imports, fileInfo) {
14741474
parserInput.forget();
14751475
return new (tree.Directive)(name, value, rules, index, fileInfo,
14761476
context.dumpLineNumbers ? getDebugInfo(index) : null,
1477-
false,
14781477
isRooted
14791478
);
14801479
}

lib/less/transform-tree.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module.exports = function(root, options) {
3939
var preEvalVisitors = [],
4040
visitors = [
4141
new visitor.JoinSelectorVisitor(),
42+
new visitor.MarkVisibleSelectorsVisitor(true),
4243
new visitor.ExtendVisitor(),
4344
new visitor.ToCSSVisitor({compress: Boolean(options.compress)})
4445
], i;

lib/less/tree/anonymous.js

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
var Node = require("./node");
22

3-
var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, referenced) {
3+
var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
44
this.value = value;
55
this.index = index;
66
this.mapLines = mapLines;
77
this.currentFileInfo = currentFileInfo;
88
this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
9-
this.isReferenced = referenced || false;
9+
10+
this.copyVisibilityInfo(visibilityInfo);
1011
};
1112
Anonymous.prototype = new Node();
1213
Anonymous.prototype.type = "Anonymous";
1314
Anonymous.prototype.eval = function () {
14-
return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike, this.isReferenced);
15+
return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
1516
};
1617
Anonymous.prototype.compare = function (other) {
1718
return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
@@ -22,11 +23,4 @@ Anonymous.prototype.isRulesetLike = function() {
2223
Anonymous.prototype.genCSS = function (context, output) {
2324
output.add(this.value, this.currentFileInfo, this.index, this.mapLines);
2425
};
25-
Anonymous.prototype.markReferenced = function () {
26-
this.isReferenced = true;
27-
};
28-
Anonymous.prototype.getIsReferenced = function () {
29-
return !this.currentFileInfo || !this.currentFileInfo.reference || this.isReferenced;
30-
};
31-
3226
module.exports = Anonymous;

lib/less/tree/comment.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,7 @@ Comment.prototype.genCSS = function (context, output) {
1515
output.add(this.value);
1616
};
1717
Comment.prototype.isSilent = function(context) {
18-
var isReference = (this.currentFileInfo && this.currentFileInfo.reference && !this.isReferenced),
19-
isCompressed = context.compress && this.value[2] !== "!";
20-
return this.isLineComment || isReference || isCompressed;
21-
};
22-
Comment.prototype.markReferenced = function () {
23-
this.isReferenced = true;
18+
var isCompressed = context.compress && this.value[2] !== "!";
19+
return this.isLineComment || isCompressed;
2420
};
2521
module.exports = Comment;

lib/less/tree/directive.js

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var Node = require("./node"),
22
Selector = require("./selector"),
33
Ruleset = require("./ruleset");
44

5-
var Directive = function (name, value, rules, index, currentFileInfo, debugInfo, isReferenced, isRooted) {
5+
var Directive = function (name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {
66
var i;
77

88
this.name = name;
@@ -21,8 +21,8 @@ var Directive = function (name, value, rules, index, currentFileInfo, debugInfo,
2121
this.index = index;
2222
this.currentFileInfo = currentFileInfo;
2323
this.debugInfo = debugInfo;
24-
this.isReferenced = isReferenced;
2524
this.isRooted = isRooted || false;
25+
this.copyVisibilityInfo(visibilityInfo);
2626
};
2727

2828
Directive.prototype = new Node();
@@ -79,7 +79,7 @@ Directive.prototype.eval = function (context) {
7979
context.mediaBlocks = mediaBlocksBackup;
8080

8181
return new Directive(this.name, value, rules,
82-
this.index, this.currentFileInfo, this.debugInfo, this.isReferenced, this.isRooted);
82+
this.index, this.currentFileInfo, this.debugInfo, this.isRooted, this.visibilityInfo());
8383
};
8484
Directive.prototype.variable = function (name) {
8585
if (this.rules) {
@@ -99,21 +99,6 @@ Directive.prototype.rulesets = function () {
9999
return Ruleset.prototype.rulesets.apply(this.rules[0]);
100100
}
101101
};
102-
Directive.prototype.markReferenced = function () {
103-
var i, rules;
104-
this.isReferenced = true;
105-
if (this.rules) {
106-
rules = this.rules;
107-
for (i = 0; i < rules.length; i++) {
108-
if (rules[i].markReferenced) {
109-
rules[i].markReferenced();
110-
}
111-
}
112-
}
113-
};
114-
Directive.prototype.getIsReferenced = function () {
115-
return !this.currentFileInfo || !this.currentFileInfo.reference || this.isReferenced;
116-
};
117102
Directive.prototype.outputRuleset = function (context, output, rules) {
118103
var ruleCnt = rules.length, i;
119104
context.tabLevel = (context.tabLevel | 0) + 1;

lib/less/tree/element.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ var Node = require("./node"),
22
Paren = require("./paren"),
33
Combinator = require("./combinator");
44

5-
var Element = function (combinator, value, index, currentFileInfo) {
5+
var Element = function (combinator, value, index, currentFileInfo, info) {
66
this.combinator = combinator instanceof Combinator ?
77
combinator : new Combinator(combinator);
88

@@ -15,6 +15,7 @@ var Element = function (combinator, value, index, currentFileInfo) {
1515
}
1616
this.index = index;
1717
this.currentFileInfo = currentFileInfo;
18+
this.copyVisibilityInfo(info);
1819
};
1920
Element.prototype = new Node();
2021
Element.prototype.type = "Element";
@@ -29,7 +30,13 @@ Element.prototype.eval = function (context) {
2930
return new Element(this.combinator,
3031
this.value.eval ? this.value.eval(context) : this.value,
3132
this.index,
32-
this.currentFileInfo);
33+
this.currentFileInfo, this.visibilityInfo());
34+
};
35+
Element.prototype.clone = function () {
36+
return new Element(this.combinator,
37+
this.value,
38+
this.index,
39+
this.currentFileInfo, this.visibilityInfo());
3340
};
3441
Element.prototype.genCSS = function (context, output) {
3542
output.add(this.toCSS(context), this.currentFileInfo, this.index);

lib/less/tree/expression.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,4 @@ Expression.prototype.throwAwayComments = function () {
5353
return !(v instanceof Comment);
5454
});
5555
};
56-
Expression.prototype.markReferenced = function () {
57-
this.value.forEach(function (value) {
58-
if (value.markReferenced) { value.markReferenced(); }
59-
});
60-
};
6156
module.exports = Expression;

lib/less/tree/extend.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
var Node = require("./node");
1+
var Node = require("./node"),
2+
Selector = require("./selector");
23

3-
var Extend = function Extend(selector, option, index) {
4+
var Extend = function Extend(selector, option, index, currentFileInfo, visibilityInfo) {
45
this.selector = selector;
56
this.option = option;
67
this.index = index;
78
this.object_id = Extend.next_id++;
89
this.parent_ids = [this.object_id];
10+
this.currentFileInfo = currentFileInfo || {};
11+
this.copyVisibilityInfo(visibilityInfo);
912

1013
switch(option) {
1114
case "all":
@@ -26,11 +29,12 @@ Extend.prototype.accept = function (visitor) {
2629
this.selector = visitor.visit(this.selector);
2730
};
2831
Extend.prototype.eval = function (context) {
29-
return new Extend(this.selector.eval(context), this.option, this.index);
32+
return new Extend(this.selector.eval(context), this.option, this.index, this.currentFileInfo, this.visibilityInfo());
3033
};
3134
Extend.prototype.clone = function (context) {
32-
return new Extend(this.selector, this.option, this.index);
35+
return new Extend(this.selector, this.option, this.index, this.currentFileInfo, this.visibilityInfo());
3336
};
37+
//it concatenates (joins) all selectors in selector array
3438
Extend.prototype.findSelfSelectors = function (selectors) {
3539
var selfElements = [],
3640
i,
@@ -46,6 +50,7 @@ Extend.prototype.findSelfSelectors = function (selectors) {
4650
selfElements = selfElements.concat(selectors[i].elements);
4751
}
4852

49-
this.selfSelectors = [{ elements: selfElements }];
53+
this.selfSelectors = [new Selector(selfElements)];
54+
this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
5055
};
5156
module.exports = Extend;

lib/less/tree/import.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ var Node = require("./node"),
1717
// `import,push`, we also pass it a callback, which it'll call once
1818
// the file has been fetched, and parsed.
1919
//
20-
var Import = function (path, features, options, index, currentFileInfo) {
20+
var Import = function (path, features, options, index, currentFileInfo, visibilityInfo) {
2121
this.options = options;
2222
this.index = index;
2323
this.path = path;
@@ -32,6 +32,7 @@ var Import = function (path, features, options, index, currentFileInfo) {
3232
this.css = true;
3333
}
3434
}
35+
this.copyVisibilityInfo(visibilityInfo);
3536
};
3637

3738
//
@@ -87,7 +88,7 @@ Import.prototype.evalForImport = function (context) {
8788
path = path.value;
8889
}
8990

90-
return new Import(path.eval(context), this.features, this.options, this.index, this.currentFileInfo);
91+
return new Import(path.eval(context), this.features, this.options, this.index, this.currentFileInfo, this.visibilityInfo());
9192
};
9293
Import.prototype.evalPath = function (context) {
9394
var path = this.path.eval(context);
@@ -107,6 +108,20 @@ Import.prototype.evalPath = function (context) {
107108
return path;
108109
};
109110
Import.prototype.eval = function (context) {
111+
var result = this.doEval(context);
112+
if (this.options.reference || this.blocksVisibility()) {
113+
if (result.length || result.length === 0) {
114+
result.forEach(function (node) {
115+
node.addVisibilityBlock();
116+
}
117+
);
118+
} else {
119+
result.addVisibilityBlock();
120+
}
121+
}
122+
return result;
123+
};
124+
Import.prototype.doEval = function (context) {
110125
var ruleset, registry,
111126
features = this.features && this.features.eval(context);
112127

@@ -126,13 +141,12 @@ Import.prototype.eval = function (context) {
126141
return [];
127142
}
128143
}
129-
130144
if (this.options.inline) {
131145
var contents = new Anonymous(this.root, 0,
132146
{
133147
filename: this.importedFilename,
134148
reference: this.path.currentFileInfo && this.path.currentFileInfo.reference
135-
}, true, true, false);
149+
}, true, true);
136150

137151
return this.features ? new Media([contents], this.features.value) : [contents];
138152
} else if (this.css) {
@@ -143,7 +157,6 @@ Import.prototype.eval = function (context) {
143157
return newImport;
144158
} else {
145159
ruleset = new Ruleset(null, this.root.rules.slice(0));
146-
147160
ruleset.evalImports(context);
148161

149162
return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;

lib/less/tree/media.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var Ruleset = require("./ruleset"),
55
Expression = require("./expression"),
66
Directive = require("./directive");
77

8-
var Media = function (value, features, index, currentFileInfo) {
8+
var Media = function (value, features, index, currentFileInfo, visibilityInfo) {
99
this.index = index;
1010
this.currentFileInfo = currentFileInfo;
1111

@@ -14,6 +14,7 @@ var Media = function (value, features, index, currentFileInfo) {
1414
this.features = new Value(features);
1515
this.rules = [new Ruleset(selectors, value)];
1616
this.rules[0].allowImports = true;
17+
this.copyVisibilityInfo(visibilityInfo);
1718
};
1819
Media.prototype = new Directive();
1920
Media.prototype.type = "Media";
@@ -37,7 +38,7 @@ Media.prototype.eval = function (context) {
3738
context.mediaPath = [];
3839
}
3940

40-
var media = new Media(null, [], this.index, this.currentFileInfo);
41+
var media = new Media(null, [], this.index, this.currentFileInfo, this.visibilityInfo());
4142
if (this.debugInfo) {
4243
this.rules[0].debugInfo = this.debugInfo;
4344
media.debugInfo = this.debugInfo;
@@ -77,6 +78,7 @@ Media.prototype.evalTop = function (context) {
7778
var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();
7879
result = new Ruleset(selectors, context.mediaBlocks);
7980
result.multiMedia = true;
81+
result.copyVisibilityInfo(this.visibilityInfo());
8082
}
8183

8284
delete context.mediaBlocks;

lib/less/tree/mixin-call.js

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ MixinCall.prototype.accept = function (visitor) {
2222
};
2323
MixinCall.prototype.eval = function (context) {
2424
var mixins, mixin, mixinPath, args = [], arg, argValue,
25-
rules = [], rule, match = false, i, m, f, isRecursive, isOneFound,
25+
rules = [], match = false, i, m, f, isRecursive, isOneFound,
2626
candidates = [], candidate, conditionResult = [], defaultResult, defFalseEitherCase = -1,
2727
defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter;
2828

@@ -127,26 +127,19 @@ MixinCall.prototype.eval = function (context) {
127127
mixin = candidates[m].mixin;
128128
if (!(mixin instanceof MixinDefinition)) {
129129
originalRuleset = mixin.originalRuleset || mixin;
130-
mixin = new MixinDefinition("", [], mixin.rules, null, false);
130+
mixin = new MixinDefinition("", [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
131131
mixin.originalRuleset = originalRuleset;
132132
}
133-
Array.prototype.push.apply(
134-
rules, mixin.evalCall(context, args, this.important).rules);
133+
var newRules = mixin.evalCall(context, args, this.important).rules;
134+
this._setVisibilityToReplacement(newRules);
135+
Array.prototype.push.apply(rules, newRules);
135136
} catch (e) {
136137
throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack };
137138
}
138139
}
139140
}
140141

141142
if (match) {
142-
if (!this.currentFileInfo || !this.currentFileInfo.reference) {
143-
for (i = 0; i < rules.length; i++) {
144-
rule = rules[i];
145-
if (rule.markReferenced) {
146-
rule.markReferenced();
147-
}
148-
}
149-
}
150143
return rules;
151144
}
152145
}
@@ -161,6 +154,16 @@ MixinCall.prototype.eval = function (context) {
161154
index: this.index, filename: this.currentFileInfo.filename };
162155
}
163156
};
157+
158+
MixinCall.prototype._setVisibilityToReplacement = function (replacement) {
159+
var i, rule;
160+
if (this.blocksVisibility()) {
161+
for (i = 0; i < replacement.length; i++) {
162+
rule = replacement[i];
163+
rule.addVisibilityBlock();
164+
}
165+
}
166+
};
164167
MixinCall.prototype.format = function (args) {
165168
return this.selector.toCSS().trim() + '(' +
166169
(args ? args.map(function (a) {

0 commit comments

Comments
 (0)