Files
radzen-blazor/RadzenBlazorDemos/Shared/CodeViewer.razor
Vladimir Enchev 43d2c24267 Js csp (#2500)
* Fixed all JS CSP related errors across all components
2026-06-15 18:44:02 +03:00

159 lines
6.3 KiB
Plaintext

@using System.Text.RegularExpressions;
@using System.IO;
@using System.Net.Http;
@using System.Reflection;
@using Microsoft.Extensions.DependencyInjection;
@using System.Linq;
@inject IJSRuntime JSRuntime
@inject HttpClient Http
@inject NavigationManager NavigationManager
@inject IServiceProvider ServiceProvider
<RadzenRow class="rz-p-2" Gap="0.5rem" Style="border-bottom: var(--rz-border-disabled);">
<RadzenColumn>
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.Start" Gap="0.5rem">
<RadzenButton Visible=@(!ReadOnly) IsBusy=@isBusy Disabled=@isBusy Click="Run" Text="Run" Icon="play_circle" ButtonStyle="ButtonStyle.Base" Size="ButtonSize.ExtraSmall" Variant="Variant.Text" Title="Preview edits" class="rz-text-truncate" />
<button class="rz-button rz-button-xs rz-variant-text rz-base rz-shade-default rz-text-truncate" Title="Copy source code" onclick=@Copy >
<RadzenIcon Icon="content_copy" />
Copy
</button>
<RadzenButton Visible=@(!ReadOnly) Disabled=@isBusy Click="@Reset" Text="Reset" Icon="refresh" ButtonStyle="ButtonStyle.Base" Size="ButtonSize.ExtraSmall" Variant="Variant.Text" class="rz-text-truncate" />
<RadzenLink Visible=@(!ReadOnly) Path="@($"/playground?example={Uri.EscapeDataString(Path.GetFileNameWithoutExtension(PageName))}")" Text="Open in Playground" target="_blank" class="rz-button rz-button-xs rz-variant-outlined rz-base rz-shade-default rz-text-truncate" Title="Open in Playground" />
</RadzenStack>
</RadzenColumn>
<RadzenColumn>
@if (String.IsNullOrEmpty(ComponentName))
{
}
else
{
<RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.End" Gap="0.5rem">
@if (ComponentName == "Dialog" || ComponentName == "Tooltip" || ComponentName == "Notification" || ComponentName == "ContextMenu")
{
<a target="blank" class="rz-button rz-button-xs rz-variant-text rz-base rz-shade-default rz-text-truncate rz-text-capitalize" href=@($"https://github.com/radzenhq/radzen-blazor/blob/master/Radzen.Blazor/Radzen{ComponentName}.razor") title=@($"View Radzen{ComponentName} component source code in new tab") >
<RadzenIcon Icon="open_in_new" /> @($"Radzen{ComponentName}") Source
</a>
<a target="blank" class="rz-button rz-button-xs rz-variant-text rz-base rz-shade-default rz-text-truncate rz-text-capitalize" href=@($"https://github.com/radzenhq/radzen-blazor/blob/master/Radzen.Blazor/{ComponentName}Service.cs") title=@($"View {ComponentName}Service source code in new tab") >
<RadzenIcon Icon="open_in_new" /> @($"{ComponentName}Service") Source
</a>
}
else {
<a target="blank" class="rz-button rz-button-xs rz-variant-text rz-base rz-shade-default rz-text-truncate rz-text-capitalize" href="@ComponentSourceHref" title=@($"View Radzen{ComponentName} component source code in new tab") >
<RadzenIcon Icon="open_in_new" /> @($"Radzen{ComponentName}") Source
</a>
}
</RadzenStack>
}
</RadzenColumn>
</RadzenRow>
<RadzenAlert Visible=@(error != null) AlertStyle="AlertStyle.Danger" Variant="Variant.Flat" Shade="Shade.Lighter">@error</RadzenAlert>
<Monaco Value=@source Language="@language" ValueChanged=@OnValueChanged @ref="@monaco" Style="border: var(--rz-border-disabled)" Disabled=@isBusy ReadOnly=@ReadOnly />
@code {
private string Copy => $"copy('{monaco?.Id}')";
private Monaco monaco;
private string source;
private string error;
private string language = "razor";
private CompilerServiceFactory compilerFactory;
[Parameter]
public EventCallback<Type> Compiled { get; set; }
[Parameter]
public string Value { get; set; }
[Parameter]
public EventCallback<string> ValueChanged { get; set; }
[Parameter]
public string PageName { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
/* Source */
[Parameter]
public string ComponentSource { get; set; }
[Parameter]
public string ComponentName { get; set; }
string ComponentSourceHref => ComponentSource ?? $"https://github.com/radzenhq/radzen-blazor/blob/master/Radzen.Blazor/Radzen{ComponentName}.razor.cs";
string PageSourceHref => Path.ChangeExtension(PageName != null && PageName.StartsWith("/") ? PageName : $"/demos/Pages/{PageName}", ".txt");
protected override async Task OnParametersSetAsync()
{
language = PageName == null ? "razor" : PageName.EndsWith(".razor") ? "razor" : "csharp";
try
{
error = null;
source = Value ?? await Fetch();
source = Clean(source);
}
catch (Exception ex)
{
error = $"<p>Cannot fetch the example source code: <code>{ex.Message}</code></p><p>Make sure your browser has access to <a href=\"{PageSourceHref}\" target=\"_blank\">{PageSourceHref}</a></p>";
}
}
async Task<string> Fetch()
{
return await Http.GetStringAsync(PageSourceHref);
}
string Clean(string source)
{
return Regex.Replace(source, "</?RadzenExample[^>]*>\n", "");
}
async Task OnValueChanged(string value)
{
source = value;
await ValueChanged.InvokeAsync(value);
}
async Task Reset()
{
var source = await Fetch();
source = Clean(source);
await OnValueChanged(source);
}
bool isBusy;
async Task Run()
{
try
{
error = null;
isBusy = true;
await JSRuntime.InvokeVoidAsync("updateEditorOptions", monaco.Id, new { domReadOnly = true, readOnly = true });
await Task.Yield();
compilerFactory ??= new CompilerServiceFactory(ServiceProvider, NavigationManager);
var compiler = await compilerFactory.GetCompilerAsync();
var type = await compiler.CompileAsync(source);
await Compiled.InvokeAsync(type);
}
catch (Exception ex)
{
error = ex.Message;
}
isBusy = false;
await JSRuntime.InvokeVoidAsync("updateEditorOptions", monaco.Id, new { domReadOnly = false, readOnly = false });
}
}