diff --git a/src/Framework/Framework/Compilation/Javascript/JavascriptTranslator.cs b/src/Framework/Framework/Compilation/Javascript/JavascriptTranslator.cs
index 36df1249b..f90154890 100644
--- a/src/Framework/Framework/Compilation/Javascript/JavascriptTranslator.cs
+++ b/src/Framework/Framework/Compilation/Javascript/JavascriptTranslator.cs
@@ -261,19 +261,25 @@ public ViewModelInfoAnnotation(Type type, bool isControl, BindingExtensionParame
}
}
+ /// Specified if properties of the current object are wrapped in knockout observables or not. Observability of the current value is not specified in this annotation, but using .
public sealed record JsObjectObservableMap: IEquatable
{
- /// The default value for all descendants, unless overriden using the other properties
+ /// The default value for all descendants, unless overridden using the other properties. If null, the default nullability for the current expression will be used.
public bool? ContainsObservables { get; set; }
/// Default value for all properties. Null means that `ContainsObservables` is assumed to be the same as the parent's
public JsObjectObservableMap? DefaultChild { get; set; }
+ /// Observable mapping for child objects.
public Dictionary? ChildObjects { get; set; }
+ /// Specifies if the specific property is ko.observable or not. Does not include more nested properties, that is specified in the property.
public Dictionary? PropertyIsObservable { get; set; }
+ /// If is null, returns the default property observability.
public bool? IsPropertyObservable(string? name) => name is {} && PropertyIsObservable?.TryGetValue(name, out var value) == true ? value : ContainsObservables;
+
+ /// If objectPath[x] is null, returns the default property observability.
public bool? IsPropertyObservable(ReadOnlySpan objectPath)
{
if (objectPath.Length == 0) return null;
@@ -297,6 +303,7 @@ public JsObjectObservableMap GetChildObject(ReadOnlySpan objectPath)
return current;
}
+ /// Replaces properties in this with non-default properties in
public JsObjectObservableMap OverrideWith(JsObjectObservableMap? @override)
{
if (@override is null || @override == Default || this == @override || this == Default) return this;
diff --git a/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs b/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs
index 853440385..7a540625a 100644
--- a/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs
+++ b/src/Framework/Framework/Compilation/Javascript/JsViewModelPropertyAdjuster.cs
@@ -178,37 +178,43 @@ public override void VisitSymbolicParameter(JsSymbolicParameter expr)
}
}
+ /// Indicates that this invocation only unwraps a knockout observable and was automatically inserted by
public sealed class ObservableUnwrapInvocationAnnotation
{
private ObservableUnwrapInvocationAnnotation() { }
public static ObservableUnwrapInvocationAnnotation Instance = new ObservableUnwrapInvocationAnnotation();
}
+ /// Indicates that this invocation is a knockout observable value assignment and was automatically inserted by
public sealed class ObservableSetterInvocationAnnotation
{
private ObservableSetterInvocationAnnotation() { }
public static ObservableSetterInvocationAnnotation Instance = new ObservableSetterInvocationAnnotation();
}
+ /// Result of the annotated expression is always a knockout observable. DotVVM will automatically unwrap the observable, unless the is also specified.
public sealed class ResultIsObservableAnnotation
{
private ResultIsObservableAnnotation() { }
public static ResultIsObservableAnnotation Instance = new ResultIsObservableAnnotation();
}
+ /// Result is a knockout observable array.
public sealed class ResultIsObservableArrayAnnotation
{
private ResultIsObservableArrayAnnotation() { }
public static ResultIsObservableArrayAnnotation Instance = new ResultIsObservableArrayAnnotation();
}
+ /// Result of the annotated expression may or may not be a knockout observable. DotVVM will automatically unwrap the observable, unless the is also specified.
public sealed class ResultMayBeObservableAnnotation
{
private ResultMayBeObservableAnnotation() { }
public static ResultMayBeObservableAnnotation Instance = new ResultMayBeObservableAnnotation();
}
+ /// This node should return observable - instructs the to not unwrap the node and the to not use .state in the subexpression.
public sealed class ShouldBeObservableAnnotation
{
private ShouldBeObservableAnnotation() { }
public static ShouldBeObservableAnnotation Instance = new ShouldBeObservableAnnotation();
}
- /// Instruct the to process the node after it's children are resolved and before it is handled itself by the rules
+ /// Instruct the to process the node after it's children are resolved and before it is handled itself by the rules
public sealed class ObservableTransformationAnnotation
{
public readonly Func TransformExpression;
@@ -217,7 +223,7 @@ public ObservableTransformationAnnotation(Func trans
TransformExpression = transformExpression;
}
- /// Makes sure that the observable is fully wrapped in observable (i.e. wraps the expression in `ko.pureComputed(...)` when needed)
+ /// Makes sure that the observable is fully wrapped in observable (i.e. wraps the expression in `ko.pureComputed(...)` when needed)
public static readonly ObservableTransformationAnnotation EnsureWrapped = new ObservableTransformationAnnotation(JsAstHelpers.EnsureObservableWrapped);
}
}
diff --git a/src/Framework/Framework/Hosting/DotvvmPresenter.cs b/src/Framework/Framework/Hosting/DotvvmPresenter.cs
index db046d877..dee997e54 100644
--- a/src/Framework/Framework/Hosting/DotvvmPresenter.cs
+++ b/src/Framework/Framework/Hosting/DotvvmPresenter.cs
@@ -538,8 +538,7 @@ Cross site iframe are disabled in this application.
await context.RejectRequest($"""
Pages can not be loaded using Javascript for security reasons.
Try refreshing the page to get rid of the error.
- If you are the developer, you can disable this check by setting DotvvmConfiguration.Security.VerifySecFetchForPages.ExcludeRoute("{route}"). [dest: {dest}, site: {site}].
- Note that this security check is not compatible with JavaScript-based prefetching, such as TurboLinks, Cloudflare Speed Brain, or similar, and you'll need to disable one of them. The check is "only" a deference-in-depth measure against XSS, and disabling it is not a vulnerability by itself.
+ If you are the developer, you can disable this check by setting DotvvmConfiguration.Security.VerifySecFetchForPages.ExcludeRoute("{route}"). [dest: {dest}, site: {site}]
""");
if (site != "same-origin")
await context.RejectRequest($"Cross site SPA requests are disabled.");