-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathServerSideValuesVueSingleFileComponentShapeAmenderBase.cs
64 lines (56 loc) · 2.56 KB
/
ServerSideValuesVueSingleFileComponentShapeAmenderBase.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
using Microsoft.AspNetCore.Html;
using System.Collections.Generic;
using System.Text.Json;
using System.Threading.Tasks;
namespace Lombiq.VueJs.Services;
/// <summary>
/// Classes that inherit from this type will prepend some server-side calculated values in a JavaScript block before the
/// template. These are accessible through a new property attached to <c>window.Vue</c> (as Vue must already be imported
/// in the header, it is guaranteed to be available here).
/// </summary>
/// <remarks>
/// <para>
/// For example if you set the value of <see cref="PropertyName"/> to <c>myComponent</c> then in JavaScript the result
/// of <see cref="GetPropertyValueAsync"/> will be available as <c>window.Vue.$orchardCore.myComponent</c>.
/// </para>
/// </remarks>
public abstract class ServerSideValuesVueSingleFileComponentShapeAmenderBase : IVueSingleFileComponentShapeAmender
{
private static readonly JsonSerializerOptions _camelCaseJsonSerializerOptions = new()
{
WriteIndented = false,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
/// <summary>
/// Gets the value used to compare in <see cref="PrependAsync"/>. If this value is <see langword="null"/> then <see
/// cref="PrependAsync"/> will be called on every Vue.js shape, otherwise only if its name is the value of <see
/// cref="ShapeName"/>.
/// </summary>
protected virtual string ShapeName => null;
/// <summary>
/// Gets the name of the property that gets serialized and delivered along with the template.
/// </summary>
protected abstract string PropertyName { get; }
/// <summary>
/// Turns the value resolved by <see cref="GetPropertyValueAsync"/> into JavaScript and appends it before the
/// template.
/// </summary>
public async ValueTask<IEnumerable<IHtmlContent>> PrependAsync(string shapeName)
{
if (ShapeName != null && ShapeName != shapeName) return [];
var propertyName = JsonSerializer.Serialize(PropertyName);
var json = JsonSerializer.SerializeToNode(await GetPropertyValueAsync(shapeName), _camelCaseJsonSerializerOptions);
return
[
new HtmlString(
"<script>" +
"if (!window.Vue.$orchardCore) window.Vue.$orchardCore = {};" +
$"window.Vue.$orchardCore[{propertyName}] = {json};" +
"</script>"),
];
}
/// <summary>
/// When awaited, returns the object which will be turned into JavaScript value.
/// </summary>
protected abstract ValueTask<object> GetPropertyValueAsync(string shapeName);
}