mirror of
https://github.com/danog/dart-sass.git
synced 2024-11-27 04:34:59 +01:00
Make transitive @extend work.
Loops are still kind of iffy.
This commit is contained in:
parent
9d2d8652dc
commit
9f21fa943e
@ -26,13 +26,19 @@ class Extender {
|
||||
|
||||
static SelectorList extend(
|
||||
SelectorList selector, SelectorList source, SimpleSelector target) =>
|
||||
new Extender()._extendList(
|
||||
selector, {target: new Set()..add(new ExtendSource(source, null))});
|
||||
new Extender()._extendList(selector, {
|
||||
target: new Set()
|
||||
..add(new ExtendSource(new CssValue(source, null), null))
|
||||
});
|
||||
|
||||
static SelectorList replace(
|
||||
SelectorList selector, SelectorList source, SimpleSelector target) =>
|
||||
new Extender()._extendList(
|
||||
selector, {target: new Set()..add(new ExtendSource(source, null))},
|
||||
selector,
|
||||
{
|
||||
target: new Set()
|
||||
..add(new ExtendSource(new CssValue(source, null), null))
|
||||
},
|
||||
replace: true);
|
||||
|
||||
CssStyleRule addSelector(CssValue<SelectorList> selector, FileSpan span) {
|
||||
@ -72,19 +78,18 @@ class Extender {
|
||||
}
|
||||
}
|
||||
|
||||
void addExtension(
|
||||
SelectorList sourceList, SimpleSelector target, ExtendRule extend) {
|
||||
var source = new ExtendSource(sourceList, extend.span);
|
||||
void addExtension(CssValue<SelectorList> extender, SimpleSelector target,
|
||||
ExtendRule extend) {
|
||||
var source = new ExtendSource(extender, extend.span);
|
||||
source.isUsed = extend.isOptional;
|
||||
_extensions.putIfAbsent(target, () => new Set()).add(source);
|
||||
|
||||
var rules = _selectors[target];
|
||||
if (rules == null) return;
|
||||
|
||||
var extensions = {target: new Set()..add(source)};
|
||||
for (var rule in rules) {
|
||||
var list = rule.selector.value;
|
||||
rule.selector.value = _extendList(list, extensions);
|
||||
for (var rule in rules.toList()) {
|
||||
rule.selector.value = _extendList(rule.selector.value, extensions);
|
||||
_registerSelector(rule.selector.value, rule);
|
||||
}
|
||||
}
|
||||
|
||||
@ -163,7 +168,7 @@ class Extender {
|
||||
}
|
||||
if (!changed) return null;
|
||||
|
||||
return _trim(paths(extendedNotExpanded).map((path) {
|
||||
var result = _trim(paths(extendedNotExpanded).map((path) {
|
||||
return weave(path.map((complex) => complex.components).toList())
|
||||
.map((outputComplex) {
|
||||
return new ComplexSelector(outputComplex,
|
||||
@ -171,6 +176,7 @@ class Extender {
|
||||
path.any((inputComplex) => inputComplex.lineBreak));
|
||||
});
|
||||
}).toList());
|
||||
return result;
|
||||
}
|
||||
|
||||
List<ComplexSelector> _extendCompound(CompoundSelector compound,
|
||||
@ -203,9 +209,9 @@ class Extender {
|
||||
new List<SimpleSelector>(compound.components.length - 1);
|
||||
compoundWithoutSimple.setRange(0, i, compound.components);
|
||||
compoundWithoutSimple.setRange(
|
||||
i, compound.components.length - 1, compound.components, i);
|
||||
i, compound.components.length - 1, compound.components, i + 1);
|
||||
for (var source in sources) {
|
||||
for (var complex in source.extender.components) {
|
||||
for (var complex in source.extender.value.components) {
|
||||
var extenderBase = complex.components.last as CompoundSelector;
|
||||
var unified = compoundWithoutSimple.isEmpty
|
||||
? extenderBase
|
||||
@ -246,7 +252,6 @@ class Extender {
|
||||
List<PseudoSelector> _extendPseudo(
|
||||
PseudoSelector pseudo, Map<SimpleSelector, Set<ExtendSource>> extensions,
|
||||
{bool replace: false}) {
|
||||
// TODO: avoid recursive loops when extending.
|
||||
var extended = _extendList(pseudo.selector, extensions, replace: replace);
|
||||
if (extended == null) return null;
|
||||
|
||||
|
@ -4,10 +4,11 @@
|
||||
|
||||
import 'package:source_span/source_span.dart';
|
||||
|
||||
import '../ast/css.dart';
|
||||
import '../ast/selector.dart';
|
||||
|
||||
class ExtendSource {
|
||||
final SelectorList extender;
|
||||
final CssValue<SelectorList> extender;
|
||||
|
||||
final FileSpan span;
|
||||
|
||||
|
@ -263,7 +263,7 @@ class PerformVisitor implements StatementVisitor, ExpressionVisitor<Value> {
|
||||
// TODO: recontextualize parse errors.
|
||||
// TODO: disallow parent selectors.
|
||||
var target = new SimpleSelector.parse(targetText.value.trim());
|
||||
_extender.addExtension(_selector.value, target, node);
|
||||
_extender.addExtension(_selector, target, node);
|
||||
}
|
||||
|
||||
void visitAtRule(AtRule node) {
|
||||
@ -498,8 +498,9 @@ class PerformVisitor implements StatementVisitor, ExpressionVisitor<Value> {
|
||||
var selector =
|
||||
new CssValue<SelectorList>(parsedSelector, node.selector.span);
|
||||
|
||||
_withParent(_extender.addSelector(selector, node.span), () {
|
||||
_withSelector(selector, () {
|
||||
var rule = _extender.addSelector(selector, node.span);
|
||||
_withParent(rule, () {
|
||||
_withSelector(rule.selector, () {
|
||||
for (var child in node.children) {
|
||||
child.accept(this);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user