Skip to content

Commit 2c5313b

Browse files
committed
fix final issues
1 parent 4707482 commit 2c5313b

File tree

8 files changed

+71
-78
lines changed

8 files changed

+71
-78
lines changed

src/BlazorUI/Bit.BlazorUI.Extras/Components/Chart/BitChart.razor.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// a fork from https://github.com/mariusmuntean/ChartJs.Blazor
22

33
using System.Diagnostics.CodeAnalysis;
4+
using Acornima.Ast;
45

56
namespace Bit.BlazorUI;
67

@@ -130,20 +131,18 @@ protected override async Task OnAfterRenderAsync(bool firstRender)
130131
{
131132
if (firstRender)
132133
{
133-
var scripts = new List<string> { "_content/Bit.BlazorUI.Extras/chart.js/chartjs-2.9.4.js" };
134+
await _js.BitExtrasInitScripts(["_content/Bit.BlazorUI.Extras/chart.js/chartjs-2.9.4.js"]);
134135

135136
if (IsDateAdapterRequired && DateAdapterScripts is null)
136137
{
137-
scripts.Add("_content/Bit.BlazorUI.Extras/chart.js/chartjs-2.9.4-adapter.js");
138+
await _js.BitExtrasInitScripts(["_content/Bit.BlazorUI.Extras/chart.js/chartjs-2.9.4-adapter.js"]);
138139
}
139140

140141
if (DateAdapterScripts is not null)
141142
{
142-
scripts.AddRange(DateAdapterScripts);
143+
await _js.BitExtrasInitScripts(DateAdapterScripts);
143144
}
144145

145-
await _js.BitExtrasInitScripts(scripts);
146-
147146
if (Config is not null)
148147
{
149148
await _js.BitChartJsSetupChart(Config);

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.razor.cs

+41-33
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
using Jint;
2-
using System.Reflection;
3-
using System.Globalization;
4-
using Microsoft.Extensions.DependencyInjection;
1+
using System.Globalization;
2+
using Jint;
53

64
namespace Bit.BlazorUI;
75

@@ -12,12 +10,13 @@ namespace Bit.BlazorUI;
1210
public partial class BitMarkdownViewer : BitComponentBase
1311
{
1412
private string? _html;
15-
private CancellationTokenSource _cts = new();
13+
private static string? _markedScriptText;
14+
private readonly CancellationTokenSource _cts = new();
15+
private static readonly SemaphoreSlim _markedScriptReadTextSemaphore = new(1, 1);
1616

1717

1818

1919
[Inject] private IJSRuntime _js { get; set; } = default!;
20-
[Inject] private IServiceProvider _serviceProvider { get; set; } = default!;
2120

2221

2322

@@ -41,7 +40,7 @@ protected override async Task OnInitializedAsync()
4140
}
4241
catch (FileNotFoundException ex) when (ex.FileName?.StartsWith("Jint") is true)
4342
{
44-
Console.Error.WriteLine("Please install `Jint` nuget package on your SERVER project.");
43+
Console.Error.WriteLine("Please install `Jint` nuget package on the server project.");
4544
}
4645
catch (Exception ex)
4746
{
@@ -51,7 +50,7 @@ protected override async Task OnInitializedAsync()
5150
else
5251
{
5352
var scriptPath = "_content/Bit.BlazorUI.Extras/marked/marked-15.0.7.js";
54-
if (await _js.BitMarkdownViewerCheckScript(scriptPath) is false)
53+
if ((await _js.BitMarkdownViewerCheckScriptLoaded(scriptPath)) is false)
5554
{
5655
await _js.BitExtrasInitScripts([scriptPath]);
5756
}
@@ -62,52 +61,61 @@ protected override async Task OnInitializedAsync()
6261
await base.OnInitializedAsync();
6362
}
6463

65-
private static string? _script;
66-
private static SemaphoreSlim _semaphore = new(1, 1);
67-
private async Task<string> GetMarkedJSScript()
68-
{
69-
if (_script is not null)
70-
return _script;
71-
try
72-
{
73-
await _semaphore.WaitAsync(_cts.Token);
74-
if (_script is not null)
75-
return _script;
76-
var scriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "_content", "Bit.BlazorUI.Extras", "marked", "marked-15.0.7.js");
77-
if (File.Exists(scriptPath) is false)
78-
{
79-
scriptPath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "marked", "marked-15.0.7.js");
80-
}
81-
return _script = await File.ReadAllTextAsync(scriptPath);
82-
}
83-
finally
84-
{
85-
_semaphore.Release();
86-
}
87-
}
64+
8865

8966
private async Task RunJint()
9067
{
9168
if (Markdown.HasNoValue()) return;
9269

9370
await Task.Run(async () =>
9471
{
72+
await ReadMarkedScriptText();
73+
if (_markedScriptText.HasNoValue()) return;
74+
9575
using var engine = new Engine(options =>
9676
{
9777
options.Strict();
9878
options.CancellationToken(_cts.Token);
9979
options.Culture(CultureInfo.CurrentUICulture);
100-
}).Execute(await GetMarkedJSScript());
80+
}).Execute(_markedScriptText!);
10181

10282
var fn = engine.Evaluate("marked.parse").AsFunctionInstance();
10383

10484
_html = fn.Call(Markdown).AsString();
10585

10686
await InvokeAsync(StateHasChanged);
107-
10887
}, _cts.Token);
10988
}
11089

90+
private async Task<string> ReadMarkedScriptText()
91+
{
92+
if (_markedScriptText is not null) return _markedScriptText;
93+
94+
try
95+
{
96+
await _markedScriptReadTextSemaphore.WaitAsync(_cts.Token);
97+
if (_markedScriptText is not null) return _markedScriptText;
98+
99+
var scriptPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "_content", "Bit.BlazorUI.Extras", "marked", "marked-15.0.7.js");
100+
101+
if (File.Exists(scriptPath) is false)
102+
{
103+
scriptPath = Path.Combine(AppContext.BaseDirectory, "wwwroot", "marked", "marked-15.0.7.js");
104+
}
105+
106+
if (File.Exists(scriptPath) is false)
107+
{
108+
return _markedScriptText = string.Empty;
109+
}
110+
111+
return _markedScriptText = await File.ReadAllTextAsync(scriptPath);
112+
}
113+
finally
114+
{
115+
_markedScriptReadTextSemaphore.Release();
116+
}
117+
}
118+
111119
private async Task OnMarkdownSet()
112120
{
113121
if (IsRendered is false) return;

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewer.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
namespace BitBlazorUI {
22
export class MarkdownViewer {
3-
private static _initPromise?: Promise<unknown>;
4-
5-
public static checkScript(script: string) {
6-
const allScripts = Array.from(document.scripts).map(s => s.src);
7-
return !!allScripts.find(as => as.includes(script));
3+
public static checkScriptLoaded(script: string) {
4+
return window.marked !== undefined;
85
}
96

107
public static parse(md: string) {

src/BlazorUI/Bit.BlazorUI.Extras/Components/MarkdownViewer/BitMarkdownViewerJsRuntimeExtensions.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
namespace Bit.BlazorUI;
22

3-
[System.Diagnostics.CodeAnalysis.SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
43
internal static class BitMarkdownViewerJsRuntimeExtensions
54
{
6-
public static ValueTask<bool> BitMarkdownViewerCheckScript(this IJSRuntime jsRuntime, string script)
5+
public static ValueTask<bool> BitMarkdownViewerCheckScriptLoaded(this IJSRuntime jsRuntime, string script)
76
{
8-
return jsRuntime.FastInvoke<bool>("BitBlazorUI.MarkdownViewer.checkScript", script);
7+
return jsRuntime.FastInvoke<bool>("BitBlazorUI.MarkdownViewer.checkScriptLoaded", script);
98
}
109

1110
public static ValueTask<string> BitMarkdownViewerParse(this IJSRuntime jsRuntime, string markdown)

src/BlazorUI/Bit.BlazorUI.Extras/Extensions/JsInterop/ExtrasJsRuntimeExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ internal static ValueTask BitExtrasScrollBy(this IJSRuntime jsRuntime, ElementRe
1919

2020
public static ValueTask BitExtrasInitScripts(this IJSRuntime jsRuntime, IEnumerable<string> scripts, bool isModule = false)
2121
{
22-
return jsRuntime.InvokeVoid("BitBlazorUI.Extras.initScript", scripts, isModule);
22+
return jsRuntime.InvokeVoid("BitBlazorUI.Extras.initScripts", scripts, isModule);
2323
}
2424
}

src/BlazorUI/Bit.BlazorUI.Extras/Scripts/Extras.ts

+11-16
Original file line numberDiff line numberDiff line change
@@ -19,33 +19,28 @@ namespace BitBlazorUI {
1919
element.scrollBy(x, y);
2020
}
2121

22-
private static _initScriptPromises: { [key: string]: Promise<unknown> } = {};
23-
public static async initScript(scripts: string[], isModule: boolean) {
22+
private static _initScriptsPromises: { [key: string]: Promise<unknown> } = {};
23+
public static async initScripts(scripts: string[], isModule: boolean) {
2424
const key = scripts.join('|');
25-
if (Extras._initScriptPromises[key] !== undefined) {
26-
return await Extras._initScriptPromises[key];
25+
if (Extras._initScriptsPromises[key] !== undefined) {
26+
return Extras._initScriptsPromises[key];
2727
}
2828

2929
const allScripts = Array.from(document.scripts).map(s => s.src);
30-
const notAddedScripts = scripts.filter(s => !allScripts.find(as => as.endsWith(s)));
30+
const notAddedScripts = scripts.filter(s => !allScripts.find(as => as.includes(s)));
3131

3232
if (notAddedScripts.length == 0) return Promise.resolve();
3333

34-
const promise = new Promise((resolve: any, reject: any) => {
34+
const promise = new Promise(async (res: any, rej: any) => {
3535
try {
36-
(async function loadScripts() {
37-
try {
38-
await Promise.all(notAddedScripts.map(addScript));
39-
resolve();
40-
} catch (e: any) {
41-
reject(e);
42-
}
43-
}());
36+
await Promise.all(notAddedScripts.map(addScript));
37+
res();
4438
} catch (e: any) {
45-
reject(e);
39+
rej(e);
4640
}
4741
});
48-
Extras._initScriptPromises[key] = promise;
42+
43+
Extras._initScriptsPromises[key] = promise;
4944
return promise;
5045

5146
async function addScript(url: string) {

src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeExtensions.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,31 @@ public static class IJSRuntimeExtensions
1212
/// <summary>
1313
/// Only tries to Invoke the js call when the runtime is valid.
1414
/// </summary>
15-
public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
15+
public static ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
1616
{
17-
if (jsRuntime.IsRuntimeInvalid()) return;
17+
if (jsRuntime.IsRuntimeInvalid()) return ValueTask.CompletedTask;
1818

19-
await jsRuntime.InvokeVoidAsync(identifier, args);
19+
return jsRuntime.InvokeVoidAsync(identifier, args);
2020
}
2121

2222
/// <summary>
2323
/// Only tries to Invoke the js call when the runtime is valid.
2424
/// </summary>
25-
public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
25+
public static ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
2626
{
27-
if (jsRuntime.IsRuntimeInvalid()) return;
27+
if (jsRuntime.IsRuntimeInvalid()) return ValueTask.CompletedTask;
2828

29-
await jsRuntime.InvokeVoidAsync(identifier, timeout, args);
29+
return jsRuntime.InvokeVoidAsync(identifier, timeout, args);
3030
}
3131

3232
/// <summary>
3333
/// Only tries to Invoke the js call when the runtime is valid.
3434
/// </summary>
35-
public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
35+
public static ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
3636
{
37-
if (jsRuntime.IsRuntimeInvalid()) return;
37+
if (jsRuntime.IsRuntimeInvalid()) return ValueTask.CompletedTask;
3838

39-
await jsRuntime.InvokeVoidAsync(identifier, cancellationToken, args);
39+
return jsRuntime.InvokeVoidAsync(identifier, cancellationToken, args);
4040
}
4141

4242

src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeFastExtensions.cs

+1-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Bit.BlazorUI;
66

7+
[SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>", Scope = "member", Target = "~M:Bit.BlazorUI.IJSRuntimeFastExtensions.FastInvokeVoid(Microsoft.JSInterop.IJSRuntime,System.String,System.Threading.CancellationToken,System.Object[])~System.Threading.Tasks.ValueTask")]
78
public static class IJSRuntimeFastExtensions
89
{
910
public const DynamicallyAccessedMemberTypes JsonSerialized = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties;
@@ -15,7 +16,6 @@ public static class IJSRuntimeFastExtensions
1516
/// </summary>
1617
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>window.someScope.someFunction</c>.</param>
1718
/// <param name="args">JSON-serializable arguments.</param>
18-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
1919
public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
2020
{
2121
return FastInvokeVoid(jsRuntime, identifier, CancellationToken.None, args);
@@ -27,7 +27,6 @@ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identif
2727
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>window.someScope.someFunction</c>.</param>
2828
/// <param name="timeout">The duration after which to cancel the async operation. Overrides default timeouts (<see cref="JSRuntime.DefaultAsyncTimeout"/>).</param>
2929
/// <param name="args">JSON-serializable arguments.</param>
30-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
3130
public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
3231
{
3332
using var cancellationTokenSource = timeout == Timeout.InfiniteTimeSpan ? null : new CancellationTokenSource(timeout);
@@ -45,7 +44,6 @@ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identif
4544
/// (<see cref="JSRuntime.DefaultAsyncTimeout"/>) from being applied.
4645
/// </param>
4746
/// <param name="args">JSON-serializable arguments.</param>
48-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
4947
public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
5048
{
5149
if (jsRuntime is IJSInProcessRuntime jsInProcessRuntime)
@@ -77,7 +75,6 @@ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identif
7775
/// <param name="identifier">An identifier for the function to invoke. For example, the value <c>"someScope.someFunction"</c> will invoke the function <c>window.someScope.someFunction</c>.</param>
7876
/// <param name="args">JSON-serializable arguments.</param>
7977
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
80-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
8178
public static ValueTask<TValue> FastInvoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
8279
{
8380
return FastInvoke<TValue>(jsRuntime, identifier, CancellationToken.None, args);
@@ -92,7 +89,6 @@ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identif
9289
/// <param name="timeout">The duration after which to cancel the async operation. Overrides default timeouts (<see cref="JSRuntime.DefaultAsyncTimeout"/>).</param>
9390
/// <param name="args">JSON-serializable arguments.</param>
9491
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
95-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
9692
public static ValueTask<TValue> FastInvoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
9793
{
9894
using var cancellationTokenSource = timeout == Timeout.InfiniteTimeSpan ? null : new CancellationTokenSource(timeout);
@@ -113,7 +109,6 @@ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identif
113109
/// </param>
114110
/// <param name="args">JSON-serializable arguments.</param>
115111
/// <returns>An instance of <typeparamref name="TValue"/> obtained by JSON-deserializing the return value.</returns>
116-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
117112
public static ValueTask<TValue> FastInvoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
118113
{
119114
if (jsRuntime is IJSInProcessRuntime jsInProcessRuntime)

0 commit comments

Comments
 (0)