From b565eb72c1ca8ec647b85e5e42159c7d4f6ea4fb Mon Sep 17 00:00:00 2001 From: Anders Mikkelsen Date: Mon, 6 Feb 2023 09:18:15 +0100 Subject: [PATCH] warning on undefined controller or action --- src/core/application.ts | 7 +++++++ src/core/binding_observer.ts | 8 ++++++++ src/core/context.ts | 6 ++++++ src/core/router.ts | 11 +++++++++-- src/mutation-observers/value_list_observer.ts | 5 ++++- .../mutation-observers/value_list_observer_tests.ts | 4 ++++ 6 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/core/application.ts b/src/core/application.ts index b8b92715..3831d03b 100644 --- a/src/core/application.ts +++ b/src/core/application.ts @@ -15,6 +15,7 @@ export class Application implements ErrorHandler { readonly actionDescriptorFilters: ActionDescriptorFilters logger: Logger = console debug = false + warnings = true static start(element?: Element, schema?: Schema): Application { const application = new this(element, schema) @@ -90,6 +91,12 @@ export class Application implements ErrorHandler { window.onerror?.(message, "", 0, 0, error) } + handleWarning(warning: string, message: string, detail: object) { + if (this.warnings) { + this.logger.warn(`%s\n\n%s\n\n%o`, message, warning, detail) + } + } + // Debug logging logDebugActivity = (identifier: string, functionName: string, detail: object = {}): void => { diff --git a/src/core/binding_observer.ts b/src/core/binding_observer.ts index 62cc8355..32b77006 100644 --- a/src/core/binding_observer.ts +++ b/src/core/binding_observer.ts @@ -92,4 +92,12 @@ export class BindingObserver implements ValueListObserverDelegate { elementUnmatchedValue(element: Element, action: Action) { this.disconnectAction(action) } + + elementMatchedNoValue(element: Element, token: Token) { + this.context.handleWarning( + `Element references undefined action ${token.content}`, + `Warning connecting action ${token.content}`, + { element, action: token.content } + ) + } } diff --git a/src/core/context.ts b/src/core/context.ts index e1187add..3a17f087 100644 --- a/src/core/context.ts +++ b/src/core/context.ts @@ -101,6 +101,12 @@ export class Context implements ErrorHandler, TargetObserverDelegate, OutletObse this.application.handleError(error, `Error ${message}`, detail) } + handleWarning(warning: string, message: string, detail: object = {}) { + const { identifier, controller, element } = this + detail = Object.assign({ identifier, controller, element }, detail) + this.application.handleWarning(warning, `Warning ${message}`, detail) + } + // Debug logging logDebugActivity = (functionName: string, detail: object = {}): void => { diff --git a/src/core/router.ts b/src/core/router.ts index c06e5e57..a4bda3c4 100644 --- a/src/core/router.ts +++ b/src/core/router.ts @@ -88,10 +88,17 @@ export class Router implements ScopeObserverDelegate { } scopeConnected(scope: Scope) { - this.scopesByIdentifier.add(scope.identifier, scope) - const module = this.modulesByIdentifier.get(scope.identifier) + const { element, identifier } = scope + this.scopesByIdentifier.add(identifier, scope) + const module = this.modulesByIdentifier.get(identifier) if (module) { module.connectContextForScope(scope) + } else { + this.application.handleWarning( + `Element references undefined controller ${identifier}`, + `Warning connecting controller ${identifier}`, + { identifier, element } + ) } } diff --git a/src/mutation-observers/value_list_observer.ts b/src/mutation-observers/value_list_observer.ts index 35cd214a..8d986bb4 100644 --- a/src/mutation-observers/value_list_observer.ts +++ b/src/mutation-observers/value_list_observer.ts @@ -3,6 +3,7 @@ import { Token, TokenListObserver, TokenListObserverDelegate } from "./token_lis export interface ValueListObserverDelegate { parseValueForToken(token: Token): T | undefined elementMatchedValue(element: Element, value: T): void + elementMatchedNoValue(element: Element, token: Token): void elementUnmatchedValue(element: Element, value: T): void } @@ -50,10 +51,12 @@ export class ValueListObserver implements TokenListObserverDelegate { tokenMatched(token: Token) { const { element } = token - const { value } = this.fetchParseResultForToken(token) + const { error, value } = this.fetchParseResultForToken(token) if (value) { this.fetchValuesByTokenForElement(element).set(token, value) this.delegate.elementMatchedValue(element, value) + } else if (error) { + this.delegate.elementMatchedNoValue(element, token) } } diff --git a/src/tests/modules/mutation-observers/value_list_observer_tests.ts b/src/tests/modules/mutation-observers/value_list_observer_tests.ts index 1a4b1517..11295196 100644 --- a/src/tests/modules/mutation-observers/value_list_observer_tests.ts +++ b/src/tests/modules/mutation-observers/value_list_observer_tests.ts @@ -100,4 +100,8 @@ export default class ValueListObserverTests extends ObserverTestCase implements elementUnmatchedValue(element: Element, value: Value) { this.recordCall("elementUnmatchedValue", element, value.id, value.token.content) } + + elementMatchedNoValue(element: Element, token: Token) { + this.recordCall("elementMatchedNoValue", element, token) + } }