Skip to content

Commit fe46cbb

Browse files
authored
Improve unification of :host and :host-context (#1471)
See sass/sass#3134
1 parent cbdcd58 commit fe46cbb

File tree

5 files changed

+44
-7
lines changed

5 files changed

+44
-7
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 1.40.2
2+
3+
* The `selector.unify()` function now correctly returns `null` when one selector
4+
is a `:host` or `:host-context` and the other is a selector that's guaranteed
5+
to be within the current shadow DOM. The `@extend` logic has been updated
6+
accordingly as well.
7+
18
## 1.40.1
29

310
* **Potentially breaking bug fix:** `min()` and `max()` expressions outside of

lib/src/ast/selector/pseudo.dart

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import 'dart:math' as math;
66

77
import 'package:charcode/charcode.dart';
8+
import 'package:meta/meta.dart';
89

910
import '../../utils.dart';
1011
import '../../visitor/interface/selector.dart';
@@ -47,6 +48,15 @@ class PseudoSelector extends SimpleSelector {
4748
/// This is `true` if and only if [isSyntacticClass] is `false`.
4849
bool get isSyntacticElement => !isSyntacticClass;
4950

51+
/// Whether this is a valid `:host` selector.
52+
@internal
53+
bool get isHost => isClass && name == 'host';
54+
55+
/// Whether this is a valid `:host-context` selector.
56+
@internal
57+
bool get isHostContext =>
58+
isClass && name == 'host-context' && selector != null;
59+
5060
/// The non-selector argument passed to this selector.
5161
///
5262
/// This is `null` if there's no argument. If [argument] and [selector] are
@@ -125,9 +135,20 @@ class PseudoSelector extends SimpleSelector {
125135
}
126136

127137
List<SimpleSelector>? unify(List<SimpleSelector> compound) {
128-
if (compound.length == 1 && compound.first is UniversalSelector) {
129-
return compound.first.unify([this]);
138+
if (name == 'host' || name == 'host-context') {
139+
if (!compound.every((simple) =>
140+
simple is PseudoSelector &&
141+
(simple.isHost || simple.selector != null))) {
142+
return null;
143+
}
144+
} else if (compound.length == 1) {
145+
var other = compound.first;
146+
if (other is UniversalSelector ||
147+
(other is PseudoSelector && (other.isHost || other.isHostContext))) {
148+
return other.unify([this]);
149+
}
130150
}
151+
131152
if (compound.contains(this)) return compound;
132153

133154
var result = <SimpleSelector>[];

lib/src/ast/selector/simple.dart

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,12 @@ abstract class SimpleSelector extends Selector {
5858
/// Returns `null` if unification is impossible—for example, if there are
5959
/// multiple ID selectors.
6060
List<SimpleSelector>? unify(List<SimpleSelector> compound) {
61-
if (compound.length == 1 && compound.first is UniversalSelector) {
62-
return compound.first.unify([this]);
61+
if (compound.length == 1) {
62+
var other = compound.first;
63+
if (other is UniversalSelector ||
64+
(other is PseudoSelector && (other.isHost || other.isHostContext))) {
65+
return other.unify([this]);
66+
}
6367
}
6468
if (compound.contains(this)) return compound;
6569

lib/src/ast/selector/universal.dart

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,15 @@ class UniversalSelector extends SimpleSelector {
2424
visitor.visitUniversalSelector(this);
2525

2626
List<SimpleSelector>? unify(List<SimpleSelector> compound) {
27-
if (compound.first is UniversalSelector || compound.first is TypeSelector) {
28-
var unified = unifyUniversalAndElement(this, compound.first);
27+
var first = compound.first;
28+
if (first is UniversalSelector || first is TypeSelector) {
29+
var unified = unifyUniversalAndElement(this, first);
2930
if (unified == null) return null;
3031
return [unified, ...compound.skip(1)];
32+
} else if (compound.length == 1 &&
33+
first is PseudoSelector &&
34+
(first.isHost || first.isHostContext)) {
35+
return null;
3136
}
3237

3338
if (namespace != null && namespace != "*") return [this, ...compound];

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: sass
2-
version: 1.40.1
2+
version: 1.40.2-dev
33
description: A Sass implementation in Dart.
44
homepage: https://github.com/sass/dart-sass
55

0 commit comments

Comments
 (0)