diff --git a/src/Framework/Framework/Compilation/Javascript/ParametrizedCode.cs b/src/Framework/Framework/Compilation/Javascript/ParametrizedCode.cs index fec592e56..4bfa3f88f 100644 --- a/src/Framework/Framework/Compilation/Javascript/ParametrizedCode.cs +++ b/src/Framework/Framework/Compilation/Javascript/ParametrizedCode.cs @@ -130,9 +130,25 @@ public ParametrizedCode AssignParameters(Func parameterAssigner, out bool allIsDefault) { - var pp = FindAssignment(parameterAssigner, optional: false, allIsDefault: out allIsDefault); + allIsDefault = true; var codes = new(CodeParameterAssignment parameter, string code)[parameters!.Length]; for (int i = 0; i < parameters.Length; i++) { - codes[i] = (pp[i], pp[i].Code!.ToString(parameterAssigner, out bool allIsDefault_local)); + var assignment = parameterAssigner(parameters[i].Parameter); + if (assignment.Code == null) + { + assignment = parameters[i].DefaultAssignment; + if (assignment.Code == null) + throw new InvalidOperationException($"Assignment of parameter '{parameters[i].Parameter}' was not found."); + } + else + allIsDefault = false; + + codes[i] = (assignment, assignment.Code!.ToString(parameterAssigner, out bool allIsDefault_local)); allIsDefault &= allIsDefault_local; } return codes; } - private CodeParameterAssignment[] FindAssignment(Func parameterAssigner, bool optional, out bool allIsDefault) + private (CodeParameterAssignment[]? assigned, ParametrizedCode?[]? newDefaults) FindAssignment(Func parameterAssigner) { - allIsDefault = true; - var pp = new CodeParameterAssignment[parameters!.Length]; + if (parameters is null) + return (null, null); + + // these are different variables, as we have to preserve the tree-like structure of the ParametrizedCodes, + // when we assign parameters in the default values. + // newDefaults -> we will change the code in the parameters[i].DefaultAssignment + // assigned -> this parameter will be removed and its assignment inlined into stringParts[i] and parameters[i] + CodeParameterAssignment[]? assigned = null; // when null, all are default + ParametrizedCode[]? newDefaults = null; // when null, no defaults were changed for (int i = 0; i < parameters.Length; i++) { - if ((pp[i] = parameterAssigner(parameters[i].Parameter)).Code == null) + var p = parameterAssigner(parameters[i].Parameter); + if (p.Code is not null) + { + assigned ??= new CodeParameterAssignment[parameters.Length]; + assigned[i] = p; + } + else if (parameters[i].DefaultAssignment is { Code: { HasParameters: true } } defaultAssignment) { - if (!optional) + // check if the default assignment contains any of the assigned parameters, and adjust the default if necessary + var newDefault = defaultAssignment.Code.AssignParameters(parameterAssigner); + if (newDefault != defaultAssignment.Code) { - pp[i] = parameters[i].DefaultAssignment; - if (pp[i].Code == null) - throw new InvalidOperationException($"Assignment of parameter '{parameters[i].Parameter}' was not found."); + newDefaults ??= new ParametrizedCode[parameters.Length]; + newDefaults[i] = newDefault; } } - else - allIsDefault = false; } - return pp; + return (assigned, newDefaults); } public IEnumerable EnumerateAllParameters() diff --git a/src/Tests/ControlTests/PostbackHandlerTests.cs b/src/Tests/ControlTests/PostbackHandlerTests.cs index 478587a7e..aa4a5ca76 100644 --- a/src/Tests/ControlTests/PostbackHandlerTests.cs +++ b/src/Tests/ControlTests/PostbackHandlerTests.cs @@ -33,7 +33,8 @@ public async Task ButtonHandlers() - 100 || SomeString.Length < 5} /> + 100} /> + diff --git a/src/Tests/ControlTests/testoutputs/PostbackHandlerTests.ButtonHandlers.html b/src/Tests/ControlTests/testoutputs/PostbackHandlerTests.ButtonHandlers.html index 08ca8d6fd..b2a163c90 100644 --- a/src/Tests/ControlTests/testoutputs/PostbackHandlerTests.ButtonHandlers.html +++ b/src/Tests/ControlTests/testoutputs/PostbackHandlerTests.ButtonHandlers.html @@ -6,7 +6,7 @@ +},this,[["suppress",(c,d)=>({suppress:c.$parent.Integer() > 100})],["suppress",(c,d)=>({suppress:d.SomeString()?.length < 5})]]).catch(dotvvm.log.logPostBackScriptError);event.stopPropagation();return false;" type="button" value="Test supress">