mirror of
https://github.com/danog/dart-sass.git
synced 2024-11-27 04:34:59 +01:00
Add _selectorPseudoIsSuperselector.
This commit is contained in:
parent
b5b4cd5a8b
commit
51c8213a6d
@ -2,6 +2,8 @@
|
|||||||
// MIT-style license that can be found in the LICENSE file or at
|
// MIT-style license that can be found in the LICENSE file or at
|
||||||
// https://opensource.org/licenses/MIT.
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import '../../extend/functions.dart';
|
||||||
|
import '../../utils.dart';
|
||||||
import '../selector.dart';
|
import '../selector.dart';
|
||||||
|
|
||||||
class ComplexSelector extends Selector {
|
class ComplexSelector extends Selector {
|
||||||
@ -27,6 +29,9 @@ class ComplexSelector extends Selector {
|
|||||||
: components = new List.unmodifiable(components),
|
: components = new List.unmodifiable(components),
|
||||||
lineBreaks = new List.unmodifiable(lineBreaks);
|
lineBreaks = new List.unmodifiable(lineBreaks);
|
||||||
|
|
||||||
|
bool isSuperselector(ComplexSelector other) =>
|
||||||
|
complexIsSuperselector(components, other.components);
|
||||||
|
|
||||||
void _computeSpecificity() {
|
void _computeSpecificity() {
|
||||||
_minSpecificity = 0;
|
_minSpecificity = 0;
|
||||||
_maxSpecificity = 0;
|
_maxSpecificity = 0;
|
||||||
@ -38,6 +43,11 @@ class ComplexSelector extends Selector {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get hashCode => listHash(components);
|
||||||
|
|
||||||
|
bool operator ==(other) =>
|
||||||
|
other is ComplexSelector && listEquals(components, other.components);
|
||||||
|
|
||||||
String toString() => components.join(" ");
|
String toString() => components.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// https://opensource.org/licenses/MIT.
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
import '../../extend/functions.dart';
|
import '../../extend/functions.dart';
|
||||||
|
import '../../utils.dart';
|
||||||
import '../selector.dart';
|
import '../selector.dart';
|
||||||
|
|
||||||
class CompoundSelector extends Selector implements ComplexSelectorComponent {
|
class CompoundSelector extends Selector implements ComplexSelectorComponent {
|
||||||
@ -35,5 +36,10 @@ class CompoundSelector extends Selector implements ComplexSelectorComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get hashCode => listHash(components);
|
||||||
|
|
||||||
|
bool operator ==(other) =>
|
||||||
|
other is ComplexSelector && listEquals(components, other.components);
|
||||||
|
|
||||||
String toString() => components.join("");
|
String toString() => components.join("");
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// MIT-style license that can be found in the LICENSE file or at
|
// MIT-style license that can be found in the LICENSE file or at
|
||||||
// https://opensource.org/licenses/MIT.
|
// https://opensource.org/licenses/MIT.
|
||||||
|
|
||||||
|
import '../../extend/functions.dart';
|
||||||
|
import '../../utils.dart';
|
||||||
import '../selector.dart';
|
import '../selector.dart';
|
||||||
|
|
||||||
class SelectorList extends Selector {
|
class SelectorList extends Selector {
|
||||||
@ -14,5 +16,13 @@ class SelectorList extends Selector {
|
|||||||
: components = new List.unmodifiable(components),
|
: components = new List.unmodifiable(components),
|
||||||
lineBreaks = new List.unmodifiable(lineBreaks);
|
lineBreaks = new List.unmodifiable(lineBreaks);
|
||||||
|
|
||||||
|
bool isSuperselector(SelectorList other) =>
|
||||||
|
listIsSuperslector(components, other.components);
|
||||||
|
|
||||||
|
int get hashCode => listHash(components);
|
||||||
|
|
||||||
|
bool operator ==(other) =>
|
||||||
|
other is ComplexSelector && listEquals(components, other.components);
|
||||||
|
|
||||||
String toString() => components.join(", ");
|
String toString() => components.join(", ");
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ import 'package:charcode/charcode.dart';
|
|||||||
|
|
||||||
import '../selector.dart';
|
import '../selector.dart';
|
||||||
|
|
||||||
final _vendorPrefix = new Regex(r'^-[a-zA-Z0-9]+-');
|
final _vendorPrefix = new RegExp(r'^-[a-zA-Z0-9]+-');
|
||||||
|
|
||||||
class PseudoSelector extends SimpleSelector {
|
class PseudoSelector extends SimpleSelector {
|
||||||
final String name;
|
final String name;
|
||||||
|
@ -61,6 +61,11 @@ SimpleSelector unifyUniversalAndElement(SimpleSelector selector1,
|
|||||||
new NamespacedIdentifier(name, namespace: namespace));
|
new NamespacedIdentifier(name, namespace: namespace));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool listIsSuperslector(List<ComplexSelector> list1,
|
||||||
|
List<ComplexSelector> list2) =>
|
||||||
|
list2.every((complex1) =>
|
||||||
|
list1.any((complex2) => complex2.isSuperselector(complex1)));
|
||||||
|
|
||||||
bool complexIsParentSuperselector(List<ComplexSelectorComponent> complex1,
|
bool complexIsParentSuperselector(List<ComplexSelectorComponent> complex1,
|
||||||
List<ComplexSelectorComponent> complex2) {
|
List<ComplexSelectorComponent> complex2) {
|
||||||
// Try some simple heuristics to see if we can avoid allocations.
|
// Try some simple heuristics to see if we can avoid allocations.
|
||||||
@ -198,3 +203,70 @@ bool _simpleIsSuperselectorOfCompound(SimpleSelector simple,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _selectorPseudoIsSuperselector(PseudoSelector pseudo1,
|
||||||
|
CompoundSelector compound2, {Iterable<ComplexSelectorComponent> parents}) {
|
||||||
|
switch (pseudo1.normalizedName) {
|
||||||
|
case 'matches':
|
||||||
|
case 'any':
|
||||||
|
var pseudos = _selectorPseudosNamed(compound2, pseudo1.normalizedName);
|
||||||
|
return pseudos.any((pseudo2) {
|
||||||
|
return pseudo1.selector.isSuperselector(pseudo2.selector);
|
||||||
|
}) || pseudo1.selector.components.any((complex1) {
|
||||||
|
var complex2 = (parents?.toList() ?? [])..add(compound2);
|
||||||
|
return complexIsSuperselector(complex1.components, complex2);
|
||||||
|
});
|
||||||
|
|
||||||
|
case 'has':
|
||||||
|
case 'host':
|
||||||
|
case 'host-context':
|
||||||
|
return _selectorPseudosNamed(compound2, pseudo1.normalizedName)
|
||||||
|
.any((pseudo2) => pseudo1.selector.isSuperselector(pseudo2.selector));
|
||||||
|
|
||||||
|
case 'not':
|
||||||
|
return pseudo1.selector.components.every((complex) {
|
||||||
|
return compound2.components.every((simple2) {
|
||||||
|
if (simple2 is TypeSelector) {
|
||||||
|
var compound1 = complex.components.last;
|
||||||
|
return compound1 is CompoundSelector &&
|
||||||
|
compound1.components.any((simple1) =>
|
||||||
|
simple1 is TypeSelector && simple1 != simple2);
|
||||||
|
} else if (simple2 is IDSelector) {
|
||||||
|
var compound1 = complex.components.last;
|
||||||
|
return compound1 is CompoundSelector &&
|
||||||
|
compound1.components.any((simple1) =>
|
||||||
|
simple1 is IDSelector && simple1 != simple2);
|
||||||
|
} else if (simple2 is PseudoSelector &&
|
||||||
|
simple2.name == pseudo1.name &&
|
||||||
|
simple2.selector != null) {
|
||||||
|
return listIsSuperslector(simple2.selector.components, [complex]);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
case 'current':
|
||||||
|
return _selectorPseudosNamed(compound2, 'current')
|
||||||
|
.any((pseudo2) => pseudo1.selector == pseudo2.selector);
|
||||||
|
|
||||||
|
case 'nth-child':
|
||||||
|
case 'nth-last-child':
|
||||||
|
return compound2.components.any((pseudo2) =>
|
||||||
|
pseudo2 is PseudoSelector &&
|
||||||
|
pseudo2.name == pseudo1.name &&
|
||||||
|
pseudo2.argument == pseudo1.argument &&
|
||||||
|
pseudo1.selector.isSuperselector(pseudo2.selector));
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw "unreachable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable<PseudoSelector> _selectorPseudosNamed(CompoundSelector compound,
|
||||||
|
String name) =>
|
||||||
|
compound.components.where((simple) =>
|
||||||
|
simple is PseudoSelector &&
|
||||||
|
simple.type == PseudoType.klass &&
|
||||||
|
simple.selector != null &&
|
||||||
|
simple.name == name);
|
||||||
|
@ -23,6 +23,8 @@ class LinkedListValue<T> extends LinkedListEntry<LinkedListValue<T>> {
|
|||||||
bool listEquals/*<T>*/(List/*<T>*/ list1, List/*<T>*/ list2) =>
|
bool listEquals/*<T>*/(List/*<T>*/ list1, List/*<T>*/ list2) =>
|
||||||
const ListEquality().equals(list1, list2);
|
const ListEquality().equals(list1, list2);
|
||||||
|
|
||||||
|
int listHash(List list) => const ListEquality().hash(list);
|
||||||
|
|
||||||
FileSpan spanForList(List<AstNode> nodes) {
|
FileSpan spanForList(List<AstNode> nodes) {
|
||||||
if (nodes.isEmpty) return null;
|
if (nodes.isEmpty) return null;
|
||||||
return nodes.first.span.expand(nodes.last.span);
|
return nodes.first.span.expand(nodes.last.span);
|
||||||
|
Loading…
Reference in New Issue
Block a user