Skip to content

Commit 4c9d41b

Browse files
Allow to use scoped (':scope' and '&') selectors relative to controller's element in outlets selectors
1 parent 7a6de52 commit 4c9d41b

5 files changed

Lines changed: 20 additions & 10 deletions

File tree

src/core/outlet_observer.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export class OutletObserver implements AttributeObserverDelegate, SelectorObserv
9595
const hasOutletController = element.matches(`[${this.schema.controllerAttribute}~=${outletName}]`)
9696

9797
if (selector) {
98-
return hasOutlet && hasOutletController && element.matches(selector)
98+
const matches =
99+
element.matches(selector) || Array.from(this.context.element.querySelectorAll(selector)).includes(element)
100+
return hasOutlet && hasOutletController && matches
99101
} else {
100102
return false
101103
}

src/core/outlet_set.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ export class OutletSet {
6666

6767
private matchesElement(element: Element, selector: string, outletName: string): boolean {
6868
const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || ""
69-
return element.matches(selector) && controllerAttribute.split(" ").includes(outletName)
69+
const matches =
70+
element.matches(selector) || Array.from(this.controllerElement.querySelectorAll(selector)).includes(element)
71+
return matches && controllerAttribute.split(" ").includes(outletName)
7072
}
7173
}

src/mutation-observers/selector_observer.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,11 @@ export class SelectorObserver implements ElementObserverDelegate {
6161
const { selector } = this
6262

6363
if (selector) {
64-
const matches = element.matches(selector)
65-
6664
if (this.delegate.selectorMatchElement) {
67-
return matches && this.delegate.selectorMatchElement(element, this.details)
65+
return this.delegate.selectorMatchElement(element, this.details)
6866
}
6967

70-
return matches
68+
return element.matches(selector)
7169
} else {
7270
return false
7371
}

src/tests/controllers/outlet_controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class BaseOutletController extends Controller {
1212

1313
export class OutletController extends BaseOutletController {
1414
static classes = ["connected", "disconnected"]
15-
static outlets = ["beta", "gamma", "delta", "omega", "namespaced--epsilon"]
15+
static outlets = ["beta", "gamma", "delta", "omega", "namespaced--epsilon", "zeta"]
1616

1717
static values = {
1818
alphaOutletConnectedCallCount: Number,

src/tests/modules/core/outlet_tests.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ export default class OutletTests extends ControllerTestCase(OutletController) {
1212
<div id="beta3"></div>
1313
<div data-controller="beta" id="beta4"></div>
1414
</div>
15+
16+
<div data-controller="zeta" class="zeta"></div>
1517
1618
<div
1719
data-controller="${this.identifier}"
@@ -21,8 +23,10 @@ export default class OutletTests extends ControllerTestCase(OutletController) {
2123
data-${this.identifier}-beta-outlet=".beta"
2224
data-${this.identifier}-delta-outlet=".delta"
2325
data-${this.identifier}-namespaced--epsilon-outlet=".epsilon"
26+
data-${this.identifier}-zeta-outlet=":scope .zeta"
2427
>
2528
<div data-controller="gamma" class="gamma" id="gamma2"></div>
29+
<div data-controller="zeta" class="zeta" id="inner-zeta"></div>
2630
</div>
2731
2832
<div data-controller="delta gamma" class="delta gamma" id="delta1">
@@ -36,15 +40,17 @@ export default class OutletTests extends ControllerTestCase(OutletController) {
3640
<div class="beta" id="beta5"></div>
3741
</div>
3842
`
43+
3944
get identifiers() {
40-
return ["test", "alpha", "beta", "gamma", "delta", "omega", "namespaced--epsilon"]
45+
return ["test", "alpha", "beta", "gamma", "delta", "omega", "namespaced--epsilon", "zeta"]
4146
}
4247

4348
"test OutletSet#find"() {
4449
this.assert.equal(this.controller.outlets.find("alpha"), this.findElement("#alpha1"))
4550
this.assert.equal(this.controller.outlets.find("beta"), this.findElement("#beta1"))
4651
this.assert.equal(this.controller.outlets.find("delta"), this.findElement("#delta1"))
4752
this.assert.equal(this.controller.outlets.find("namespaced--epsilon"), this.findElement("#epsilon1"))
53+
this.assert.equal(this.controller.outlets.find("zeta"), this.findElement("#inner-zeta"))
4854
}
4955

5056
"test OutletSet#findAll"() {
@@ -54,12 +60,13 @@ export default class OutletTests extends ControllerTestCase(OutletController) {
5460
this.controller.outlets.findAll("namespaced--epsilon"),
5561
this.findElements("#epsilon1", "#epsilon2")
5662
)
63+
this.assert.deepEqual(this.controller.outlets.findAll("zeta"), this.findElements("#inner-zeta"))
5764
}
5865

5966
"test OutletSet#findAll with multiple arguments"() {
6067
this.assert.deepEqual(
61-
this.controller.outlets.findAll("alpha", "beta", "namespaced--epsilon"),
62-
this.findElements("#alpha1", "#alpha2", "#beta1", "#beta2", "#epsilon1", "#epsilon2")
68+
this.controller.outlets.findAll("alpha", "beta", "namespaced--epsilon", "zeta"),
69+
this.findElements("#alpha1", "#alpha2", "#beta1", "#beta2", "#epsilon1", "#epsilon2", "#inner-zeta")
6370
)
6471
}
6572

@@ -70,6 +77,7 @@ export default class OutletTests extends ControllerTestCase(OutletController) {
7077
this.assert.equal(this.controller.outlets.has("delta"), true)
7178
this.assert.equal(this.controller.outlets.has("omega"), false)
7279
this.assert.equal(this.controller.outlets.has("namespaced--epsilon"), true)
80+
this.assert.equal(this.controller.outlets.has("zeta"), true)
7381
}
7482

7583
"test OutletSet#has when attribute gets added later"() {

0 commit comments

Comments
 (0)