From 50c3b99b83ea6a2bdde81f479df34f7b6a10c00e Mon Sep 17 00:00:00 2001 From: phillipc Date: Wed, 22 Apr 2026 19:52:24 +0200 Subject: [PATCH 1/2] Fix Parser instantiation and globals in ComponentProvider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove `as any` downcast on Parser constructor. Parser takes no constructor arguments; context, globals, and node are parameters of `.parse()`. The old code silently dropped `this.globals` (passed to the no-op constructor) and sent `undefined` to `.parse()`, so global variables could not resolve in component params. Add test that exercises globals resolution through component params. Adversarial review: subagent audit — no backwards-compat, disposal, perf, or API surface concerns; fix aligns with every other provider. --- .../spec/componentProviderBehaviors.ts | 23 +++++++++++++++++++ .../src/ComponentProvider.ts | 4 ++-- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/packages/provider.component/spec/componentProviderBehaviors.ts b/packages/provider.component/spec/componentProviderBehaviors.ts index 5a7661238..0a1c67f46 100644 --- a/packages/provider.component/spec/componentProviderBehaviors.ts +++ b/packages/provider.component/spec/componentProviderBehaviors.ts @@ -150,6 +150,29 @@ describe('Components: Provider', function () { applyBindings({}, ne) // No error raised. }) + + it('resolves globals in component params', function () { + const provider = new MultiProvider({ + providers: [new DataBindProvider(), new ComponentProvider()], + globals: { GLOBAL_CONST: 42 } + }) + options.bindingProviderInstance = provider + bindingHandlers = provider.bindingHandlers + bindingHandlers.set(componentBindings) + bindingHandlers.set(coreBindings) + + components.register('xenon', { + viewModel: function (params) { + expect(params.answer).to.equal(42) + }, + template: 'ok', + synchronous: true, + ignoreCustomElementWarning: true + }) + const xe = document.createElement('xenon') + xe.setAttribute('params', 'answer: GLOBAL_CONST') + applyBindings({}, xe) + }) }) /* describe("nodeParamsToObject", function() { diff --git a/packages/provider.component/src/ComponentProvider.ts b/packages/provider.component/src/ComponentProvider.ts index fe496cc2c..5fb3f9bc3 100644 --- a/packages/provider.component/src/ComponentProvider.ts +++ b/packages/provider.component/src/ComponentProvider.ts @@ -72,9 +72,9 @@ export default class ComponentProvider extends Provider { return { $raw: {} } } - const parser = new (Parser as any)(node, context, this.globals) as Parser + const parser = new Parser() const paramsString = (node.getAttribute('params') || '').trim() - const accessors = parser.parse(paramsString, context, undefined, node) + const accessors = parser.parse(paramsString, context, this.globals, node) if (!accessors || Object.keys(accessors).length === 0) { return { $raw: {} } } From 5452efcd72462abcae062635ba3fd288160902a0 Mon Sep 17 00:00:00 2001 From: phillipc Date: Tue, 5 May 2026 20:57:17 +0200 Subject: [PATCH 2/2] Fix review findings --- .changeset/fix-component-provider-parser-globals.md | 10 ++++++++++ packages/utils.parser/src/Parser.ts | 6 +----- 2 files changed, 11 insertions(+), 5 deletions(-) create mode 100644 .changeset/fix-component-provider-parser-globals.md diff --git a/.changeset/fix-component-provider-parser-globals.md b/.changeset/fix-component-provider-parser-globals.md new file mode 100644 index 000000000..279cc3c25 --- /dev/null +++ b/.changeset/fix-component-provider-parser-globals.md @@ -0,0 +1,10 @@ +--- +"@tko/provider.component": patch +--- + +Fix component params globals resolution in `ComponentProvider`. + +`getComponentParams` now instantiates `Parser` with `new Parser()` and passes +provider globals to `parser.parse(...)`, matching canonical parser usage in +other providers. This restores resolution of globals in component `params` +expressions (for example, `params="answer: GLOBAL_CONST"`). diff --git a/packages/utils.parser/src/Parser.ts b/packages/utils.parser/src/Parser.ts index 7b9860950..62d13ba1a 100644 --- a/packages/utils.parser/src/Parser.ts +++ b/packages/utils.parser/src/Parser.ts @@ -32,11 +32,7 @@ type InnerFilterType = (value: any, ignored: any, context: any, globals: any, no type FilterType = InnerFilterType & { precedence: number } /** - * Construct a new Parser instance with new Parser(node, context) - * @param {Node} node The DOM element from which we parsed the - * content. - * @param {object} context The Knockout context. - * @param {object} globals An object containing any desired globals. + * Parser for binding and params expressions. */ export default class Parser { ch: any