feat: add JsFunction value type for composable executeJs#24374
Merged
Conversation
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
Legioth
requested changes
May 19, 2026
Member
Legioth
left a comment
There was a problem hiding this comment.
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.
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.
Legioth
requested changes
May 19, 2026
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.
Legioth
approved these changes
May 19, 2026
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



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