Skip to content

feat: add JsFunction value type for composable executeJs#24374

Merged
Artur- merged 4 commits into
mainfrom
js-decomposition
May 19, 2026
Merged

feat: add JsFunction value type for composable executeJs#24374
Artur- merged 4 commits into
mainfrom
js-decomposition

Conversation

@Artur-
Copy link
Copy Markdown
Member

@Artur- Artur- commented May 19, 2026

Lets server code build a JS function value with captured parameters
and pass it as an executeJs parameter, removing the need to
string-concatenate framework boilerplate around user-supplied JS.
Captures may themselves be Elements or other JsFunctions; the codec
encodes them recursively as @v-fn, and the client reifies the value
as a callable function with the captures pre-bound.

Fixes #24373

Artur- added 2 commits May 19, 2026 13:21
Lets server code build a JS function value with captured parameters
and pass it as an executeJs parameter, removing the need to
string-concatenate framework boilerplate around user-supplied JS.
Captures may themselves be Elements or other JsFunctions; the codec
encodes them recursively as @v-fn, and the client reifies the value
as a callable function with the captures pre-bound.
Adds JsFunction.withArguments(String...) so the materialised function
accepts caller-supplied arguments at invocation time, in addition to
the pre-bound captures. The wire format gains an "args" field listing
the parameter names, which the client passes through to new Function
after the capture slots.

Closes #24373
@Artur- Artur- requested a review from Legioth May 19, 2026 10:21
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

Test Results

 1 412 files  +2   1 412 suites  +2   1h 20m 10s ⏱️ +15s
10 168 tests +8  10 099 ✅ +8  69 💤 ±0  0 ❌ ±0 
10 643 runs  +8  10 572 ✅ +8  71 💤 ±0  0 ❌ ±0 

Results for commit 1cb9ab4. ± Comparison against base commit 3697241.

♻️ This comment has been updated with latest results.

Copy link
Copy Markdown
Member

@Legioth Legioth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no test that verifies that this works end-to-end. There are also no tests for the client-side functionality, but it might be enough with the end-to-end test without any dedicated client-side tests.

Comment thread flow-server/src/main/java/com/vaadin/flow/dom/JsFunction.java Outdated
Comment thread flow-server/src/main/java/com/vaadin/flow/dom/JsFunction.java Outdated
Comment thread flow-server/src/main/java/com/vaadin/flow/dom/JsFunction.java Outdated
Client-side, switch from Function.prototype.bind to a wrapper that
applies captures while letting the caller control this. The previous
.bind implementation also bound this to undefined, so callers could
not later set it via .call() or .apply() — which breaks the intended
"$0.call(element)" composition pattern from the design discussion.

JsFunction: drop the redundant constructor-side defensive copies (the
of() factory already clones, and withArguments() now uses List.of()
so the constructor can trust both lists). argumentNames defaults to
Collections.emptyList(), avoiding a fresh String[0] per instance.

Document JsFunction support alongside the existing Element and
BaseJsonNode special cases in Element.executeJs and Page.executeJs.

Add JsFunctionView + JsFunctionIT exercising captures-only, named
runtime arguments, Element captures, and caller-supplied this so the
binding fix is verified end-to-end.
@Artur- Artur- requested a review from Legioth May 19, 2026 11:49
Comment thread flow-server/src/main/java/com/vaadin/flow/dom/JsFunction.java
Throw IllegalStateException if withArguments is called on a
JsFunction that already has argument names. Silent overwrite would
hide a mistake where two callers each thought they owned the
parameter list.
@Artur- Artur- enabled auto-merge May 19, 2026 13:07
@sonarqubecloud
Copy link
Copy Markdown

@Artur- Artur- added this pull request to the merge queue May 19, 2026
Merged via the queue into main with commit 27a6962 May 19, 2026
31 checks passed
@Artur- Artur- deleted the js-decomposition branch May 19, 2026 13:35
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 executeJs decomposition through passing an JS function to executeJs

2 participants