-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix @plugin
scoping rules
#2522
Changes from 5 commits
7a80a82
4d17c8b
56f5db8
0a6e2f8
56687b9
aa66271
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#ns { | ||
@plugin "../test/less/plugin/plugin-local"; | ||
|
||
.mixin() { | ||
result : test-local(); | ||
} | ||
} | ||
|
||
.test { | ||
#ns > .mixin(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -103,6 +103,7 @@ ImportVisitor.prototype = { | |
|
||
var importVisitor = this, | ||
inlineCSS = importNode.options.inline, | ||
isPlugin = importNode.options.plugin, | ||
duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; | ||
|
||
if (!context.importMultiple) { | ||
|
@@ -123,7 +124,7 @@ ImportVisitor.prototype = { | |
importNode.root = root; | ||
importNode.importedFilename = fullPath; | ||
|
||
if (!inlineCSS && (context.importMultiple || !duplicateImport)) { | ||
if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { | ||
importVisitor.recursionDetector[fullPath] = true; | ||
|
||
var oldContext = this.context; | ||
|
@@ -144,7 +145,16 @@ ImportVisitor.prototype = { | |
} | ||
}, | ||
visitRule: function (ruleNode, visitArgs) { | ||
visitArgs.visitDeeper = false; | ||
if (ruleNode.value.type === "DetachedRuleset") { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. import and plugin directives inside detached rulesets didn't work as expected because the visitor was stopping at the rule level, never entering the detached ruleset declaration. This change enables it for the simple form of |
||
this.context.frames.unshift(ruleNode); | ||
} else { | ||
visitArgs.visitDeeper = false; | ||
} | ||
}, | ||
visitRuleOut : function(ruleNode) { | ||
if (ruleNode.value.type === "DetachedRuleset") { | ||
this.context.frames.shift(); | ||
} | ||
}, | ||
visitDirective: function (directiveNode, visitArgs) { | ||
this.context.frames.unshift(directiveNode); | ||
|
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
.other { | ||
trans: transitive; | ||
} | ||
.class { | ||
trans: transitive; | ||
global: global; | ||
local: test-local(); | ||
shadow: global; | ||
} | ||
.class .local { | ||
global: global; | ||
local: local; | ||
shadow: local; | ||
} | ||
.class { | ||
ns-mixin-global: global; | ||
ns-mixin-local: local; | ||
ns-mixin-shadow: local; | ||
mixin-local: local; | ||
mixin-global: global; | ||
mixin-shadow: local; | ||
ruleset-local: local; | ||
ruleset-global: global; | ||
ruleset-shadow: local; | ||
class-local: test-local(); | ||
} | ||
@media screen { | ||
.test { | ||
result: global; | ||
} | ||
} | ||
@font-face { | ||
result: global; | ||
} | ||
@media screen and (min-width: 100px) and (max-width: 400px) { | ||
.test { | ||
result: global; | ||
} | ||
} | ||
@media screen { | ||
.test { | ||
result: local; | ||
} | ||
} |
This file was deleted.
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// importing plugin globally | ||
@plugin "./plugin/plugin-global"; | ||
|
||
// transitively include plugins from importing another sheet | ||
@import "./plugin/plugin-transitive"; | ||
|
||
|
||
// `test-global` function should be reachable | ||
// `test-local` function should not be reachable | ||
// `test-shadow` function should return global version | ||
.class { | ||
trans : test-transitive(); | ||
global : test-global(); | ||
local : test-local(); | ||
shadow : test-shadow(); | ||
|
||
// `test-global` function should propagate and be reachable | ||
// `test-local` function should be reachable | ||
// `test-shadow` function should return local version, shadowing global version | ||
.local { | ||
@plugin "./plugin/plugin-local"; | ||
global : test-global(); | ||
local : test-local(); | ||
shadow : test-shadow(); | ||
} | ||
} | ||
|
||
// calling a mixin or detached ruleset should not bubble local plugins | ||
// imported inside either into the parent scope. | ||
.mixin() { | ||
@plugin "./plugin/plugin-local"; | ||
mixin-local : test-local(); | ||
mixin-global : test-global(); | ||
mixin-shadow : test-shadow(); | ||
} | ||
@ruleset : { | ||
@plugin "./plugin/plugin-local"; | ||
ruleset-local : test-local(); | ||
ruleset-global : test-global(); | ||
ruleset-shadow : test-shadow(); | ||
}; | ||
#ns { | ||
@plugin "./plugin/plugin-local"; | ||
.mixin() { | ||
ns-mixin-global : test-global(); | ||
ns-mixin-local : test-local(); | ||
ns-mixin-shadow : test-shadow(); | ||
} | ||
} | ||
.class { | ||
#ns > .mixin(); | ||
.mixin(); | ||
@ruleset(); | ||
class-local : test-local(); | ||
} | ||
|
||
|
||
// `test-global` function should propagate into directive scope | ||
@media screen { | ||
.test { | ||
result : test-global(); | ||
} | ||
} | ||
@font-face { | ||
result : test-global(); | ||
} | ||
|
||
// `test-global` function should propagate into nested directive scopes | ||
@media screen and (min-width:100px) { | ||
@media (max-width:400px) { | ||
.test { | ||
result : test-global(); | ||
} | ||
} | ||
} | ||
|
||
.test { | ||
@media screen { | ||
@plugin "./plugin/plugin-local"; | ||
result : test-local(); | ||
} | ||
} | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
|
||
functions.addMultiple({ | ||
"test-shadow" : function() { | ||
return new tree.Anonymous( "global" ); | ||
}, | ||
"test-global" : function() { | ||
return new tree.Anonymous( "global" ); | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
functions.addMultiple({ | ||
"test-shadow" : function() { | ||
return new tree.Anonymous( "local" ); | ||
}, | ||
"test-local" : function() { | ||
return new tree.Anonymous( "local" ); | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
functions.addMultiple({ | ||
"test-transitive" : function() { | ||
return new tree.Anonymous( "transitive" ); | ||
} | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
@plugin "plugin-transitive"; | ||
|
||
.other { | ||
trans : test-transitive(); | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was this file checked in by mistake?