diff --git a/src/core/controller.ts b/src/core/controller.ts index 4b412716..c0ff5e3e 100644 --- a/src/core/controller.ts +++ b/src/core/controller.ts @@ -73,6 +73,20 @@ export class Controller { return this.scope.data } + findElement(selector: string): Element | undefined { + const elementWithId = document.getElementById(selector) + if (elementWithId && this.scope.containsElement(elementWithId)) { + return elementWithId + } + const newSelector = this.classifySelector(selector) + return this.scope.findElement(newSelector) + } + + findAllElements(selector: string): Element[] { + const newSelector = this.classifySelector(selector) + return this.scope.findAllElements(newSelector) + } + initialize() { // Override in your subclass to set up initial controller state } @@ -100,4 +114,16 @@ export class Controller { target.dispatchEvent(event) return event } + + private classifySelector(selector: string | string[]): string { + const tokens = Array.isArray(selector) ? selector : [selector] + + const definedClasses: string[] = (this.constructor as any).classes.flatMap((key: string) => { + const value = (this as any)[`${key}Classes`] as string[] | undefined + return value ?? [] + }) + + const allTokensDefined = tokens.every((token) => definedClasses.includes(token)) + return "." + tokens.join(allTokensDefined ? "." : " ") + } } diff --git a/src/tests/modules/core/find_element_test.ts b/src/tests/modules/core/find_element_test.ts new file mode 100644 index 00000000..b41d8d56 --- /dev/null +++ b/src/tests/modules/core/find_element_test.ts @@ -0,0 +1,37 @@ +import { ClassController } from "../../controllers/class_controller" +import { ControllerTestCase } from "../../cases/controller_test_case" + +export default class FindElementTests extends ControllerTestCase(ClassController) { + fixtureHTML = ` +
+
+
+
+ + "test findElement finds element by id inside scope"() { + const result = this.controller.findElement("inside") + this.assert.equal(result?.id, "inside") + } + + "test findElement does not find element by id outside scope"() { + const result = this.controller.findElement("outside") + this.assert.equal(result, undefined) + } + + "test findElement finds element by defined class"() { + const result = this.controller.findElement(this.controller.loadingClass) + this.assert.ok(result instanceof Element) + this.assert.ok(result?.classList.contains("busy")) + } + + "test findAllElements returns multiple matches for defined class"() { + const results = this.controller.findAllElements(this.controller.loadingClass) + this.assert.ok(Array.isArray(results)) + this.assert.equal(results.length, 1) + this.assert.ok(results[0].classList.contains("busy")) + } + ` +}