diff --git a/src/core/controller.ts b/src/core/controller.ts index 4b412716..02d2b096 100644 --- a/src/core/controller.ts +++ b/src/core/controller.ts @@ -2,7 +2,7 @@ import { Application } from "./application" import { ClassPropertiesBlessing } from "./class_properties" import { Constructor } from "./constructor" import { Context } from "./context" -import { OutletPropertiesBlessing } from "./outlet_properties" +import { OutletPropertiesBlessing, OutletRenameObject } from "./outlet_properties" import { TargetPropertiesBlessing } from "./target_properties" import { ValuePropertiesBlessing, ValueDefinitionMap } from "./value_properties" @@ -24,7 +24,7 @@ export class Controller { OutletPropertiesBlessing, ] static targets: string[] = [] - static outlets: string[] = [] + static outlets: (string | OutletRenameObject)[] = [] static values: ValueDefinitionMap = {} static get shouldLoad() { diff --git a/src/core/outlet_observer.ts b/src/core/outlet_observer.ts index b0956f47..8bcae6fc 100644 --- a/src/core/outlet_observer.ts +++ b/src/core/outlet_observer.ts @@ -5,6 +5,7 @@ import { Context } from "./context" import { Controller } from "./controller" import { readInheritableStaticArrayValues } from "./inheritable_statics" +import { OutletRenameObject } from "./outlet_properties" type OutletObserverDetails = { outletName: string } @@ -206,7 +207,15 @@ export class OutletObserver implements AttributeObserverDelegate, SelectorObserv const constructor = module.definition.controllerConstructor const outlets = readInheritableStaticArrayValues(constructor, "outlets") - outlets.forEach((outlet) => dependencies.add(outlet, module.identifier)) + outlets.forEach((outlet: string | OutletRenameObject) => { + let name: string + if (typeof outlet === "object") { + name = Object.values(outlet)[0] + } else { + name = outlet + } + return dependencies.add(name, module.identifier) + }) }) return dependencies diff --git a/src/core/outlet_properties.ts b/src/core/outlet_properties.ts index 4af436a4..7cbce1a6 100644 --- a/src/core/outlet_properties.ts +++ b/src/core/outlet_properties.ts @@ -24,8 +24,18 @@ function getControllerAndEnsureConnectedScope(controller: Controller, element: E if (outletController) return outletController } -function propertiesForOutletDefinition(name: string) { - const camelizedName = namespaceCamelize(name) +function propertiesForOutletDefinition(outletDescription: string | OutletRenameObject) { + let camelizedName: string; + let name: string; + + if (typeof outletDescription === 'object') { + const [[newName, originalName]] = Object.entries(outletDescription) + name = originalName + camelizedName = namespaceCamelize(newName) + } else { + name = outletDescription; + camelizedName = namespaceCamelize(name) + } return { [`${camelizedName}Outlet`]: { @@ -100,3 +110,6 @@ function propertiesForOutletDefinition(name: string) { }, } } + +export type OutletRenameObject = { [key: string]: string }; + diff --git a/src/tests/controllers/outlet_controller.ts b/src/tests/controllers/outlet_controller.ts index b382f80c..9104f5fe 100644 --- a/src/tests/controllers/outlet_controller.ts +++ b/src/tests/controllers/outlet_controller.ts @@ -1,7 +1,8 @@ +import { OutletRenameObject } from "src/core/outlet_properties" import { Controller } from "../../core/controller" class BaseOutletController extends Controller { - static outlets = ["alpha"] + static outlets: (string | OutletRenameObject)[] = ["alpha"] alphaOutlet!: Controller | null alphaOutlets!: Controller[] @@ -12,7 +13,7 @@ class BaseOutletController extends Controller { export class OutletController extends BaseOutletController { static classes = ["connected", "disconnected"] - static outlets = ["beta", "gamma", "delta", "omega", "namespaced--epsilon"] + static outlets = ["beta", "gamma", "delta", "omega", "namespaced--epsilon", { input: "helpers--common--input" }] static values = { alphaOutletConnectedCallCount: Number, @@ -32,6 +33,9 @@ export class OutletController extends BaseOutletController { betaOutletElements!: Element[] hasBetaOutlet!: boolean + inputOutlet!: Controller | null + inputOutletElement!: Element | null + namespacedEpsilonOutlet!: Controller | null namespacedEpsilonOutlets!: Controller[] namespacedEpsilonOutletElement!: Element | null diff --git a/src/tests/modules/core/outlet_tests.ts b/src/tests/modules/core/outlet_tests.ts index fb87ba12..8b659f2a 100644 --- a/src/tests/modules/core/outlet_tests.ts +++ b/src/tests/modules/core/outlet_tests.ts @@ -13,6 +13,8 @@ export default class OutletTests extends ControllerTestCase(OutletController) {
+
+
@@ -37,7 +40,7 @@ export default class OutletTests extends ControllerTestCase(OutletController) { ` get identifiers() { - return ["test", "alpha", "beta", "gamma", "delta", "omega", "namespaced--epsilon"] + return ["test", "alpha", "beta", "gamma", "delta", "omega", "namespaced--epsilon", "helpers--common--input"] } "test OutletSet#find"() { @@ -366,4 +369,14 @@ export default class OutletTests extends ControllerTestCase(OutletController) { `expected "${alpha2.className}" to contain "disconnected"` ) } + + "test outlet renaming"() { + const element = this.findElement(".inputs") + const inputOutlet = this.controller.application.getControllerForElementAndIdentifier( + element, + "helpers--common--input" + ) + this.assert.equal(this.controller.inputOutlet, inputOutlet) + this.assert.equal(this.controller.inputOutletElement, element) + } }