Skip to content

feat: support named parameters for executeJs#24386

Draft
Artur- wants to merge 4 commits into
mainfrom
claude/fix-vaadin-flow-24385-TESgu
Draft

feat: support named parameters for executeJs#24386
Artur- wants to merge 4 commits into
mainfrom
claude/fix-vaadin-flow-24385-TESgu

Conversation

@Artur-

@Artur- Artur- commented May 20, 2026

Copy link
Copy Markdown
Member

Add withParameter(name, value) to a new PendingJavaScriptExecution
subtype returned from Element.executeJs and Page.executeJs, so the
JavaScript expression can read values by name instead of $0, $1,
…:

element.executeJs("doSomething(foo)")
        .withParameter("foo", "Some value");

The mechanism is purely server-side: each withParameter call appends
the value to the invocation's parameter list and prepends
let <name>=$N; to the expression. Positional $0/$1/... parameters
keep their meaning, and parameters cannot be added after the execution
has been sent to the browser. The same withParameter(name, value)
helper is added to JsFunction, where it captures the value and aliases
it in the body the same way.

callJsFunction keeps returning PendingJavaScriptResult so it
doesn't expose withParameter, matching the issue's request to scope
the feature to executeJs only.

Fixes #24385

@cla-assistant

cla-assistant Bot commented May 20, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions

github-actions Bot commented May 20, 2026

Copy link
Copy Markdown

Test Results

 1 425 files  ± 0   1 425 suites  ±0   1h 26m 30s ⏱️ + 4m 28s
10 045 tests +10   9 977 ✅ +10  68 💤 ±0  0 ❌ ±0 
10 517 runs  +10  10 448 ✅ +10  69 💤 ±0  0 ❌ ±0 

Results for commit 762602d. ± Comparison against base commit 8ced9f7.

♻️ This comment has been updated with latest results.

@Artur- Artur- marked this pull request as draft May 20, 2026 11:14
Comment thread flow-server/src/main/java/com/vaadin/flow/dom/JsFunction.java Outdated
Artur- added a commit that referenced this pull request May 20, 2026
Lead the keydown handler body and the listenOn delegate registration JS
with `const name = $N;` lines, so the rest of each body reads in terms
of `allowedKeys`, `requiredModifiers`, `resetFocus`, `preventDefault`
and `locator`, `handler`, `locatorSource` instead of `$0`..`$4`. Once
PR #24386 (issue #24385) lands these aliases can be replaced by
`JsFunction.withParameter(name, value)` directly.
@Artur- Artur- force-pushed the claude/fix-vaadin-flow-24385-TESgu branch from 7185220 to ba38bc1 Compare May 25, 2026 10:28
claude and others added 4 commits May 28, 2026 16:34
Add `withParameter(name, value)` to a new `PendingJavaScriptExecution`
subtype returned from `Element.executeJs` and `Page.executeJs`, so the
JavaScript expression can read values by name instead of `$0`, `$1`,
&hellip;:

    element.executeJs("doSomething(foo)")
            .withParameter("foo", "Some value");

The mechanism is purely server-side: each `withParameter` call appends
the value to the invocation's parameter list and prepends
`let <name>=$N;` to the expression. Positional `$0`/`$1`/... parameters
keep their meaning, and parameters cannot be added after the execution
has been sent to the browser. The same `withParameter(name, value)`
helper is added to `JsFunction`, where it captures the value and aliases
it in the body the same way.

`callJsFunction` keeps returning `PendingJavaScriptResult` so it
doesn't expose `withParameter`, matching the issue's request to scope
the feature to `executeJs` only.

Fixes #24385
Mockito.when(page.executeJs(...)).thenReturn(...) now requires
PendingJavaScriptExecution instead of PendingJavaScriptResult since
that's the new return type of executeJs.
Validation runs again when the invocation is serialised via JacksonCodec,
so the explicit dry-run on every withParameter / addNamedParameter call
just doubles the work without adding signal.
Changing `Element.executeJs` / `Page.executeJs` to return the new
`PendingJavaScriptExecution` subtype broke binary compatibility for any
pre-built component (e.g. `Upload`) whose bytecode references the
original `PendingJavaScriptResult Element.executeJs(String, Object[])`
signature: the JVM method descriptor includes the return type, so
covariant narrowing on the same class is not link-compatible. The
spring-flow IT job surfaced this as a flood of
`NoSuchMethodError: PendingJavaScriptResult Element.executeJs(...)`
when the constructor of `PrivateView` instantiated `Upload`.

Drop the `PendingJavaScriptExecution` interface and instead expose
`withParameter(String, Object)` as a default method on
`PendingJavaScriptResult` itself, returning `PendingJavaScriptResult`.
`executeJs` keeps its original return type, the chained
`element.executeJs("doSomething(foo)").withParameter("foo", value)` API
keeps working, and pre-built bytecode resolves the method as before.
The default throws `UnsupportedOperationException`; the real behaviour
lives in `PendingJavaScriptInvocation`.
@Artur- Artur- force-pushed the claude/fix-vaadin-flow-24385-TESgu branch from ba38bc1 to 762602d Compare May 28, 2026 13:36
@github-actions github-actions Bot added +0.1.0 and removed +1.0.0 labels May 28, 2026
@sonarqubecloud

Copy link
Copy Markdown

@Legioth

Legioth commented Jun 1, 2026

Copy link
Copy Markdown
Member

I'm not sure this is a good idea after all. See
#24385 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support named parameters for executeJs.

3 participants