diff --git a/src/core/outlet_set.ts b/src/core/outlet_set.ts index d32de2ca..5f745fe2 100644 --- a/src/core/outlet_set.ts +++ b/src/core/outlet_set.ts @@ -42,10 +42,7 @@ export class OutletSet { getSelectorForOutletName(outletName: string) { const attributeName = this.schema.outletAttributeForScope(this.identifier, outletName) const selector = this.controllerElement.getAttribute(attributeName) - - if (selector) return selector - - return this.scope.controllerSelector + return selector || this.getControllerSelectorForOutletName(outletName) } private findOutlet(outletName: string) { @@ -69,7 +66,11 @@ export class OutletSet { } private matchesElement(element: Element, selector: string, outletName: string): boolean { - const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || "" - return element.matches(selector) && controllerAttribute.split(" ").includes(outletName) + const controllerSelector = this.getControllerSelectorForOutletName(outletName) + return element.matches(selector) && element.matches(controllerSelector) + } + + private getControllerSelectorForOutletName(outletName: string) { + return `[${this.schema.controllerAttribute}~="${outletName}"]` } } diff --git a/src/tests/modules/core/outlet_fallback_selector_tests.ts b/src/tests/modules/core/outlet_fallback_selector_tests.ts new file mode 100644 index 00000000..4557afd5 --- /dev/null +++ b/src/tests/modules/core/outlet_fallback_selector_tests.ts @@ -0,0 +1,83 @@ +import { ControllerTestCase } from "../../cases/controller_test_case" +import { OutletController } from "../../controllers/outlet_controller" + +export default class OutletFallbackSelectorTests extends ControllerTestCase(OutletController) { + fixtureHTML = ` +
+
+ +
+
+
+
+ +
+
+
+ ` + get identifiers() { + return ["test", "alpha", "beta", "delta"] + } + + "test OutletSet#find"() { + this.assert.equal(this.controller.outlets.find("alpha"), this.findElement("#alpha1")) + this.assert.equal(this.controller.outlets.find("beta"), this.findElement("#beta1")) + this.assert.equal(this.controller.outlets.find("delta"), undefined) + } + + "test OutletSet#findAll"() { + this.assert.deepEqual(this.controller.outlets.findAll("alpha"), this.findElements("#alpha1", "#mixed")) + this.assert.deepEqual(this.controller.outlets.findAll("beta"), this.findElements("#beta1", "#mixed", "#beta2")) + this.assert.deepEqual(this.controller.outlets.findAll("delta"), []) + } + + "test OutletSet#findAll with multiple arguments"() { + this.assert.deepEqual( + this.controller.outlets.findAll("alpha", "beta"), + this.findElements("#alpha1", "#mixed", "#beta1", "#mixed", "#beta2") + ) + } + + "test OutletSet#has"() { + this.assert.equal(this.controller.outlets.has("alpha"), true) + this.assert.equal(this.controller.outlets.has("beta"), true) + this.assert.equal(this.controller.outlets.has("gamma"), false) + } + + "test OutletSet#has when no element with selector exists"() { + const element = document.createElement("div") + element.setAttribute("data-controller", "gamma") + + this.assert.equal(this.controller.outlets.has("gamma"), false) + + this.controller.element.appendChild(element) + this.assert.equal(this.controller.outlets.has("gamma"), true) + } + + "test singular linked outlet property throws an error when no outlet is found"() { + this.findElements("#alpha1", "#mixed", "#beta1", "#mixed", "#beta2").forEach((e) => e.remove()) + + this.assert.equal(this.controller.hasAlphaOutlet, false) + this.assert.equal(this.controller.alphaOutlets.length, 0) + this.assert.equal(this.controller.alphaOutletElements.length, 0) + this.assert.throws(() => this.controller.alphaOutlet) + this.assert.throws(() => this.controller.alphaOutletElement) + + this.assert.equal(this.controller.hasBetaOutlet, false) + this.assert.equal(this.controller.betaOutlets.length, 0) + this.assert.equal(this.controller.betaOutletElements.length, 0) + this.assert.throws(() => this.controller.betaOutlet) + this.assert.throws(() => this.controller.betaOutletElement) + } + + "test outlet connected callback fires"() { + const alphaOutlets = this.controller.alphaOutletElements.filter((outlet) => outlet.classList.contains("connected")) + + this.assert.equal(alphaOutlets.length, 2) + this.assert.equal(this.controller.alphaOutletConnectedCallCountValue, 2) + } +} diff --git a/src/tests/modules/core/outlet_tests.ts b/src/tests/modules/core/outlet_tests.ts index 0ff686d8..96ea74f6 100644 --- a/src/tests/modules/core/outlet_tests.ts +++ b/src/tests/modules/core/outlet_tests.ts @@ -20,6 +20,7 @@ export default class OutletTests extends ControllerTestCase(OutletController) { data-${this.identifier}-alpha-outlet="#alpha1,#alpha2" data-${this.identifier}-beta-outlet=".beta" data-${this.identifier}-delta-outlet=".delta" + data-${this.identifier}-gamma-outlet="#gamma-doesnt-exist" data-${this.identifier}-namespaced--epsilon-outlet=".epsilon" >