Extend looses @supports imported by reference

New logic: directive with body that contains something referenced (for
example by extend) will be shown in output too. @Media works with the same
logic - it shows up in output if it contains something visible.

Related to: #2359
This commit is contained in:
jurcovicovam
2015-01-23 17:48:26 +01:00
parent 8ed6a9748e
commit 8f1c35a814
6 changed files with 96 additions and 9 deletions

View File

@@ -73,6 +73,9 @@ Directive.prototype.markReferenced = function () {
}
}
};
Directive.prototype.getIsReferenced = function () {
return !this.currentFileInfo || !this.currentFileInfo.reference || this.isReferenced;
};
Directive.prototype.outputRuleset = function (context, output, rules) {
var ruleCnt = rules.length, i;
context.tabLevel = (context.tabLevel | 0) + 1;

View File

@@ -414,13 +414,44 @@ Ruleset.prototype.genCSS = function (context, output) {
}
};
Ruleset.prototype.markReferenced = function () {
if (!this.selectors) {
return;
var s;
if (this.selectors) {
for (s = 0; s < this.selectors.length; s++) {
this.selectors[s].markReferenced();
}
}
for (var s = 0; s < this.selectors.length; s++) {
this.selectors[s].markReferenced();
if (this.rules) {
for (s = 0; s < this.rules.length; s++) {
if (this.rules[s].markReferenced)
this.rules[s].markReferenced();
}
}
};
Ruleset.prototype.getIsReferenced = function() {
var i, j, path, selector;
if (this.paths) {
for (i=0; i<this.paths.length; i++) {
path = this.paths[i];
for (j=0; j<path.length; j++) {
if (path[j].getIsReferenced && path[j].getIsReferenced())
return true;
}
}
}
if (this.selectors) {
for (i=0;i<this.selectors.length;i++) {
selector = this.selectors[i];
if (selector.getIsReferenced && selector.getIsReferenced())
return true;
}
}
return false;
};
Ruleset.prototype.joinSelectors = function (paths, context, selectors) {
for (var s = 0; s < selectors.length; s++) {
this.joinSelector(paths, context, selectors[s]);

View File

@@ -46,10 +46,10 @@ ToCSSVisitor.prototype = {
},
visitDirective: function(directiveNode, visitArgs) {
if (directiveNode.currentFileInfo.reference && !directiveNode.isReferenced) {
return;
}
if (directiveNode.name === "@charset") {
if (!directiveNode.getIsReferenced()) {
return;
}
// Only output the debug info together with subsequent @charset definitions
// a comment (or @media statement) before the actual @charset directive would
// be considered illegal css as it has to be on the first line
@@ -65,6 +65,37 @@ ToCSSVisitor.prototype = {
}
if (directiveNode.rules && directiveNode.rules.rules) {
this._mergeRules(directiveNode.rules.rules);
//process childs
directiveNode.accept(this._visitor);
visitArgs.visitDeeper = false;
// the directive was directly referenced and therefore needs to be shown in the output
if (directiveNode.getIsReferenced()) {
return directiveNode;
}
if (!directiveNode.rules.rules) {
return ;
}
//the directive was not directly referenced
for (var r = 0; r<directiveNode.rules.rules.length; r++) {
var rule = directiveNode.rules.rules[r];
if (rule.getIsReferenced && rule.getIsReferenced()) {
//the directive contains something that was referenced (likely by extend)
//therefore it needs to be shown in output too
//marking as referenced in case the directive is stored inside another directive
directiveNode.markReferenced();
return directiveNode;
}
}
//The directive was not directly referenced and does not contain anything that
//was referenced. Therefore it must not be shown in output.
return ;
} else {
if (!directiveNode.getIsReferenced())
return;
}
return directiveNode;
},

View File

@@ -34,6 +34,14 @@ div#id.class[a=1][b=2].class:not(1) {
.visible + .visible .sub {
color: green;
}
@supports (something: else) {
.class {
something: else;
}
.nestedToo .class {
something: else;
}
}
.b {
color: red;
color: green;

View File

@@ -18,4 +18,4 @@
}
.class:extend(.class all) {
}
}

View File

@@ -48,4 +48,18 @@
@media (max-size: @max-size) {
color: red;
}
}
}
@supports (something: else) {
.class {
something: else;
}
.nestedToo {
.class {
something: else;
}
}
.invisible {
something: else;
}
}