mirror of
https://gitee.com/ant-design-blazor/ant-design-blazor.git
synced 2024-12-01 19:48:17 +08:00
docs: add monaco code view for demos (#3499)
* docs: add monaco code view * fix code view render * clean up * fix css * clean up * try load wasm * try copy dll files to output * fix directory * fix directory * enable aot in preview build * fix copy dll * fix action * fix * show code before loaded
This commit is contained in:
parent
ab8135c1cf
commit
beb9491bb1
3
.github/workflows/preview-build.yml
vendored
3
.github/workflows/preview-build.yml
vendored
@ -49,7 +49,8 @@ jobs:
|
||||
npm install
|
||||
dotnet build
|
||||
sed -i s/{version}/$PACKAGE_VERSION/g ./site/AntDesign.Docs/Shared/HeaderMenu.razor
|
||||
dotnet publish ./site/AntDesign.Docs.Wasm -c Release -f net8 -o _site
|
||||
dotnet publish ./site/AntDesign.Docs.Wasm -c Release -f net8 -o _site -p:EnableAOT=true
|
||||
cp -rf ./site/AntDesign.Docs.Wasm/bin/Debug/net8/*.dll _site/wwwroot/_framework
|
||||
env:
|
||||
PACKAGE_VERSION: ${{ github.event.number }}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
<link href="manifest.json" rel="manifest" />
|
||||
<link rel="stylesheet/less" type="text/css" href="_content/AntDesign.Docs/color.less" />
|
||||
<link rel="stylesheet" type="text/css" href="./css/toast.css" />
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -239,6 +240,27 @@
|
||||
<script src="/_content/AntDesign.Charts/g2plot.js?v={version}"></script>
|
||||
<script src="/_content/AntDesign.Charts/ant-design-charts-blazor.js?v={version}"></script>
|
||||
<script src="/_content/AntDesign.Docs/js/prism.js?v={version}"></script>
|
||||
<script>var require = { paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs' } }</script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/loader.min.js"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.js"></script>
|
||||
<script>
|
||||
var instances = {};
|
||||
function createEditor(element, id, ref, options) {
|
||||
console.log(id);
|
||||
var instance = monaco.editor.create(element, options);
|
||||
instance.onDidChangeModelContent(function () {
|
||||
ref.invokeMethodAsync('OnChangeAsync', instance.getValue());
|
||||
});
|
||||
instances[id] = instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
function copy(id) {
|
||||
var text = instances[id].getValue();
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
window.XPrism = {};
|
||||
window.XPrism.highlight = function (code, language) {
|
||||
|
@ -50,6 +50,28 @@
|
||||
Prism.highlightAll();
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>var require = { paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs' } }</script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/loader.min.js"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.js"></script>
|
||||
<script>
|
||||
var instances = {};
|
||||
function createEditor(element, id, ref, options) {
|
||||
console.log(id);
|
||||
var instance = monaco.editor.create(element, options);
|
||||
instance.onDidChangeModelContent(function() {
|
||||
ref.invokeMethodAsync('OnChangeAsync', instance.getValue());
|
||||
});
|
||||
instances[id] = instance;
|
||||
return instance;
|
||||
}
|
||||
function copy(id) {
|
||||
var text = instances[id].getValue();
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="@("https://fastly.jsdelivr.net/npm/@docsearch/js@3")"></script>
|
||||
<script src="_content/AntDesign.Docs/js/docsearch.js"></script>
|
||||
@if (!isNET6)
|
||||
|
@ -13,6 +13,7 @@
|
||||
<link rel="stylesheet" href="https://fastly.jsdelivr.net/npm/@docsearch/css@3" />
|
||||
<link href="_content/AntDesign.Docs/css/default.css" rel="stylesheet">
|
||||
<link rel="stylesheet/less" type="text/css" href="_content/AntDesign.Docs/color.less">
|
||||
<link rel="stylesheet" data-name="vs/editor/editor.main" href="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.min.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -202,6 +203,27 @@
|
||||
<script src="_content/AntDesign.Charts/ant-design-charts-blazor.js"></script>
|
||||
|
||||
<script src="_content/AntDesign.Docs/js/prism.js"></script>
|
||||
<script>var require = { paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs' } }</script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/loader.min.js"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.nls.js"></script>
|
||||
<script async src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.34.1/min/vs/editor/editor.main.js"></script>
|
||||
<script>
|
||||
var instances = {};
|
||||
function createEditor(element, id, ref, options) {
|
||||
console.log(id);
|
||||
var instance = monaco.editor.create(element, options);
|
||||
instance.onDidChangeModelContent(function () {
|
||||
ref.invokeMethodAsync('OnChangeAsync', instance.getValue());
|
||||
});
|
||||
instances[id] = instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
function copy(id) {
|
||||
var text = instances[id].getValue();
|
||||
navigator.clipboard.writeText(text);
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
window.XPrism = {};
|
||||
window.XPrism.highlight = function (code, language) {
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AntDesign.Charts" Version="0.5.5" />
|
||||
<PackageReference Include="System.Net.Http.Json" Version="7.0.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Razor" Version="6.0.24" />
|
||||
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -37,6 +37,7 @@ namespace Microsoft.Extensions.DependencyInjection
|
||||
//}, ServiceLifetime.Singleton);
|
||||
//services.AddLocalization(options => options.ResourcesPath = "Resources");
|
||||
|
||||
services.AddScoped<CompilerService>();
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
212
site/AntDesign.Docs/Services/CompilerService.cs
Normal file
212
site/AntDesign.Docs/Services/CompilerService.cs
Normal file
@ -0,0 +1,212 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
|
||||
namespace AntDesign.Docs.Services
|
||||
{
|
||||
public class CompilerService
|
||||
{
|
||||
class CollectibleAssemblyLoadContext : AssemblyLoadContext
|
||||
{
|
||||
public CollectibleAssemblyLoadContext() : base(isCollectible: true)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
class InMemoryProjectItem : RazorProjectItem
|
||||
{
|
||||
private readonly string _source;
|
||||
private readonly string _fileName;
|
||||
|
||||
public override string BasePath => _fileName;
|
||||
|
||||
public override string FilePath => _fileName;
|
||||
|
||||
public override string PhysicalPath => _fileName;
|
||||
|
||||
public override bool Exists => true;
|
||||
|
||||
public override Stream Read()
|
||||
{
|
||||
return new MemoryStream(Encoding.UTF8.GetBytes(_source));
|
||||
}
|
||||
|
||||
private readonly string _fileKind = FileKinds.Component;
|
||||
|
||||
public override string FileKind => _fileKind;
|
||||
|
||||
public InMemoryProjectItem(string source)
|
||||
{
|
||||
this._source = source;
|
||||
_fileName = "DynamicComponent.razor";
|
||||
_fileKind = "component";
|
||||
}
|
||||
}
|
||||
|
||||
private CSharpCompilation _compilation;
|
||||
private RazorProjectEngine _razorProjectEngine;
|
||||
private CollectibleAssemblyLoadContext _loadContext;
|
||||
|
||||
private AssemblyLoadContext GetLoadContext()
|
||||
{
|
||||
if (_loadContext != null)
|
||||
{
|
||||
_loadContext.Unload();
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
_loadContext = new CollectibleAssemblyLoadContext();
|
||||
|
||||
return _loadContext; ;
|
||||
}
|
||||
private const string Imports = @"@using System.Net.Http
|
||||
@using System
|
||||
@using System.Collections.Generic
|
||||
@using System.Linq
|
||||
@using System.Threading.Tasks
|
||||
@using Microsoft.AspNetCore.Components
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using AntDesign
|
||||
@using AntDesign.Docs.Pages
|
||||
@using AntDesign.Docs.Shared
|
||||
@using System.Text.Json
|
||||
";
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public CompilerService(HttpClient httpClient)
|
||||
{
|
||||
this._httpClient = httpClient;
|
||||
}
|
||||
|
||||
private async Task InitializeAsync()
|
||||
{
|
||||
var streams = await GetStreamsAsync();
|
||||
|
||||
var referenceAssemblies = streams.Select(stream => MetadataReference.CreateFromStream(stream)).ToList();
|
||||
|
||||
_compilation = CSharpCompilation.Create(
|
||||
"AntDesign.Docs.DynamicAssembly",
|
||||
Array.Empty<SyntaxTree>(),
|
||||
referenceAssemblies,
|
||||
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
|
||||
);
|
||||
|
||||
_razorProjectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, RazorProjectFileSystem.Create("/"), builder =>
|
||||
{
|
||||
builder.SetRootNamespace("AntDesign.Docs.Demo");
|
||||
|
||||
CompilerFeatures.Register(builder);
|
||||
|
||||
var metadataReferenceFeature = new DefaultMetadataReferenceFeature { References = referenceAssemblies.ToArray() };
|
||||
|
||||
builder.Features.Add(metadataReferenceFeature);
|
||||
|
||||
builder.Features.Add(new CompilationTagHelperFeature());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async Task<IEnumerable<Stream>> GetStreamsAsync()
|
||||
{
|
||||
var referenceAssemblyRoots = new[]
|
||||
{
|
||||
typeof(System.Runtime.AssemblyTargetedPatchBandAttribute).Assembly, // System.Runtime
|
||||
typeof(ComponentBase).Assembly,
|
||||
typeof(AntDesign._Imports).Assembly,
|
||||
typeof(ExpandoObject).Assembly,
|
||||
typeof(_Imports).Assembly,
|
||||
};
|
||||
|
||||
var referencedAssemblies = referenceAssemblyRoots
|
||||
.SelectMany(assembly => assembly.GetReferencedAssemblies().Append(assembly.GetName()))
|
||||
.Select(Assembly.Load)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
if (referencedAssemblies.Any(assembly => string.IsNullOrEmpty(assembly.Location)))
|
||||
{
|
||||
var list = new List<Stream>();
|
||||
|
||||
await Task.WhenAll(
|
||||
referencedAssemblies.Select(async assembly =>
|
||||
{
|
||||
var result = await _httpClient.GetAsync($"/_framework/{assembly.GetName().Name}.dll");
|
||||
|
||||
result.EnsureSuccessStatusCode();
|
||||
|
||||
list.Add(await result.Content.ReadAsStreamAsync());
|
||||
})
|
||||
);
|
||||
|
||||
return list;
|
||||
}
|
||||
else
|
||||
{
|
||||
return referencedAssemblies.Select(assembly => File.OpenRead(assembly.Location));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<Type> CompileAsync(string source)
|
||||
{
|
||||
if (_compilation == null)
|
||||
{
|
||||
await InitializeAsync();
|
||||
}
|
||||
|
||||
var projectItem = new InMemoryProjectItem(source);
|
||||
|
||||
var codeDocument = _razorProjectEngine.Process(RazorSourceDocument.ReadFrom(projectItem), FileKinds.Component,
|
||||
new[] { RazorSourceDocument.Create(Imports, "_Imports.razor") }, null);
|
||||
|
||||
var csharpDocument = codeDocument.GetCSharpDocument();
|
||||
|
||||
var syntaxTree = CSharpSyntaxTree.ParseText(csharpDocument.GeneratedCode, CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp10));
|
||||
|
||||
_compilation = _compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(syntaxTree);
|
||||
|
||||
var errors = _compilation.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error);
|
||||
|
||||
if (errors.Any())
|
||||
{
|
||||
throw new ApplicationException(string.Join(Environment.NewLine, errors.Select(e => e.GetMessage())));
|
||||
}
|
||||
|
||||
using var stream = new MemoryStream();
|
||||
|
||||
var emitResult = _compilation.Emit(stream);
|
||||
|
||||
if (!emitResult.Success)
|
||||
{
|
||||
throw new ApplicationException(string.Join(Environment.NewLine, emitResult.Diagnostics.Select(d => d.GetMessage())));
|
||||
}
|
||||
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
var assembly = GetLoadContext().LoadFromStream(stream);
|
||||
|
||||
var type = assembly.GetType("AntDesign.Docs.Demo.DynamicComponent");
|
||||
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,9 +13,22 @@
|
||||
{
|
||||
<MockBrowser Height="@Demo.Iframe.Value" WithUrl="@(Demo.Link??$"/mock?demoId={DemoId}&type={Demo.Type}")" />
|
||||
}
|
||||
else if (_demoType != null)
|
||||
else
|
||||
{
|
||||
<DynamicComponent Type="_demoType" />
|
||||
@if (_demoType != null)
|
||||
{
|
||||
<ErrorBoundary @ref="_errorBoundary">
|
||||
<ChildContent>
|
||||
<DynamicComponent Type="_demoType" />
|
||||
</ChildContent>
|
||||
<ErrorContent Context="ex">
|
||||
<Alert Type="@AlertType.Error"
|
||||
Message="@ex.Message"
|
||||
Description="@ex.StackTrace">
|
||||
</Alert>
|
||||
</ErrorContent>
|
||||
</ErrorBoundary>
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -43,7 +56,7 @@
|
||||
<Icon RefBack="context" Type="@(_copied?"check" : "snippets")" Class="code-box-code-copy code-box-code-action" OnClick="Copy" />
|
||||
</Unbound>
|
||||
</Tooltip>
|
||||
<Tooltip Title="@(CodeExpand? Localizer["app.demo.code.hide"] : Localizer["app.demo.code.show"])">
|
||||
<Tooltip Title="@(CodeExpand?Localizer["app.demo.code.hide"] : Localizer["app.demo.code.show"])">
|
||||
<Unbound>
|
||||
<span @ref="context.Current" class="code-expand-icon code-box-code-action" @onclick="_ => CodeExpand = !CodeExpand">
|
||||
<img alt="expand code" src="https://gw.alipayobjects.com/zos/rmsportal/wSAkBuJFbdxsosKKpqyq.svg" class="@(CodeExpand ? "code-expand-icon-hide" : "code-expand-icon-show")">
|
||||
@ -55,9 +68,14 @@
|
||||
</div>
|
||||
</section>
|
||||
<section class="highlight-wrapper @(CodeExpand?"highlight-wrapper-expand":"")">
|
||||
<div class="highlight">
|
||||
@* <div class="highlight">
|
||||
<HighlightedCode Code="@Demo.Code" CanLoad="CodeExpand" Language="html"></HighlightedCode>
|
||||
</div>
|
||||
</div> *@
|
||||
@if (CodeExpand || _codeViewRendered)
|
||||
{
|
||||
_codeViewRendered = true;
|
||||
<CodeView @bind-Value="@Demo.Code" Compiled="OnCompiled" />
|
||||
}
|
||||
</section>
|
||||
<style>
|
||||
@Demo.Style
|
||||
@ -68,6 +86,7 @@
|
||||
@inject DemoService demoService;
|
||||
@inject ILocalizationService lang;
|
||||
@inject IStringLocalizer Localizer;
|
||||
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
@ -85,31 +104,26 @@
|
||||
|
||||
private bool _copied;
|
||||
private bool _rendered;
|
||||
private bool _codeViewRendered;
|
||||
private ErrorBoundary _errorBoundary;
|
||||
|
||||
protected string DemoId => $"components-{ComponentName.ToLower()}-demo-{Demo.Name.ToLower()}";
|
||||
protected string DemoId => $"components-{ComponentName.ToLower()}-demo-{Demo.Name}";
|
||||
|
||||
private string EditUrl => $"https://github.com/ant-design-blazor/ant-design-blazor/edit/master/site/AntDesign.Docs/{Demo.Type.Replace(".", "/")}.razor";
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
await base.OnInitializedAsync();
|
||||
|
||||
lang.LanguageChanged += OnLangeChanged;
|
||||
|
||||
#if DEBUG
|
||||
DebugIcon =
|
||||
@<a href="@($"{(Demo.Link??"mock")}?type={Demo.Type}")" class="code-box-code-action" target="_blank">
|
||||
@<a href="@(Demo.Link??$"mock?type={Demo.Type}")" class="code-box-code-action" target="_blank">
|
||||
<Icon Type="bug" />
|
||||
</a>
|
||||
;
|
||||
#endif
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
lang.LanguageChanged -= OnLangeChanged;
|
||||
}
|
||||
|
||||
async Task Copy()
|
||||
{
|
||||
await InteropService.Copy(Demo.Code);
|
||||
@ -121,6 +135,11 @@
|
||||
await InteropService.JsInvokeAsync("window.eval", $"window.location.hash='{DemoId}'");
|
||||
}
|
||||
|
||||
void IDisposable.Dispose()
|
||||
{
|
||||
lang.LanguageChanged -= OnLangeChanged;
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
@ -138,6 +157,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
void OnCompiled(Type type)
|
||||
{
|
||||
_demoType = type;
|
||||
_errorBoundary.Recover();
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
private void OnLangeChanged(object sender, CultureInfo e)
|
||||
{
|
||||
_demoType = null;
|
||||
|
104
site/AntDesign.Docs/Shared/CodeView.razor
Normal file
104
site/AntDesign.Docs/Shared/CodeView.razor
Normal file
@ -0,0 +1,104 @@
|
||||
@using System.Text.RegularExpressions;
|
||||
@using AntDesign.Docs.Services
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject CompilerService Compiler
|
||||
|
||||
@if (_error != null)
|
||||
{
|
||||
<Alert Type="error">
|
||||
@((MarkupString)_error)
|
||||
</Alert>
|
||||
}
|
||||
|
||||
@if (!_loaded)
|
||||
{
|
||||
<div class="highlight">
|
||||
<HighlightedCode Code="@Value" CanLoad Language="html"></HighlightedCode>
|
||||
</div>
|
||||
}
|
||||
|
||||
<Monaco Value=@_source Language="@_language" ValueChanged=@OnValueChanged @ref="@_monaco" OnLoaded="OnLoaded" />
|
||||
|
||||
@code {
|
||||
private string Copy => $"copy('{_monaco?.Id}')";
|
||||
private Monaco _monaco;
|
||||
private ElementReference pre;
|
||||
|
||||
private string _error;
|
||||
private string _language = "razor";
|
||||
private string _source;
|
||||
private string _initValue;
|
||||
private bool _loaded;
|
||||
|
||||
bool _loading;
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<Type> Compiled { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
_language = "razor";
|
||||
_initValue ??= Value;
|
||||
_source = Value;
|
||||
|
||||
_error = null;
|
||||
}
|
||||
|
||||
async Task OnValueChanged(string value)
|
||||
{
|
||||
_source = value;
|
||||
|
||||
await ValueChanged.InvokeAsync(value);
|
||||
|
||||
await Run();
|
||||
}
|
||||
|
||||
void OnLoaded()
|
||||
{
|
||||
_loaded = true;
|
||||
}
|
||||
|
||||
async Task Reset()
|
||||
{
|
||||
_source = _initValue;
|
||||
|
||||
await OnValueChanged(_source);
|
||||
}
|
||||
|
||||
async Task CopyCode()
|
||||
{
|
||||
await JSRuntime.InvokeVoidAsync(Copy);
|
||||
}
|
||||
|
||||
async Task Run()
|
||||
{
|
||||
try
|
||||
{
|
||||
_error = null;
|
||||
_loading = true;
|
||||
// await _monaco.SetReadOnly(true);
|
||||
|
||||
await Task.Yield();
|
||||
|
||||
var type = await Compiler.CompileAsync(_source);
|
||||
|
||||
await Compiled.InvokeAsync(type);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_error = ex.Message;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// await _monaco.SetReadOnly(false);
|
||||
_loading = false;
|
||||
}
|
||||
}
|
||||
}
|
124
site/AntDesign.Docs/Shared/Monaco.razor
Normal file
124
site/AntDesign.Docs/Shared/Monaco.razor
Normal file
@ -0,0 +1,124 @@
|
||||
@implements IDisposable
|
||||
|
||||
<div @ref="_editor" style="height: 500px; width: 100%; @(_loaded?"":"display:hidden;")"></div>
|
||||
|
||||
@code {
|
||||
|
||||
|
||||
[Inject]
|
||||
private IJSRuntime JSRuntime { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Value { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<string> ValueChanged { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public EventCallback<bool> OnLoaded { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Language { get; set; }
|
||||
|
||||
IJSObjectReference _monaco;
|
||||
ElementReference _editor;
|
||||
DotNetObjectReference<Monaco> _reference;
|
||||
public string Id => _id;
|
||||
private string _id;
|
||||
private string _value;
|
||||
private bool _loaded;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
base.OnInitialized();
|
||||
_id = Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace("/", "-").Replace("+", "-").Substring(0, 10);
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
_reference = DotNetObjectReference.Create(this);
|
||||
|
||||
_monaco = await JSRuntime.InvokeAsync<IJSObjectReference>("createEditor", _editor, _id, _reference, new
|
||||
{
|
||||
language = Language,
|
||||
theme = "vs",
|
||||
codeLens = false,
|
||||
readOnly = ReadOnly,
|
||||
minimap = new
|
||||
{
|
||||
enabled = false
|
||||
},
|
||||
automaticLaout = true
|
||||
});
|
||||
|
||||
_value = Value;
|
||||
|
||||
await _monaco.InvokeVoidAsync("setValue", _value);
|
||||
}
|
||||
}
|
||||
|
||||
[JSInvokable]
|
||||
public async Task OnChangeAsync(string value)
|
||||
{
|
||||
if (!_loaded)
|
||||
{
|
||||
_loaded = true;
|
||||
if (OnLoaded.HasDelegate)
|
||||
{
|
||||
OnLoaded.InvokeAsync();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (Value != value)
|
||||
{
|
||||
_value = value;
|
||||
await ValueChanged.InvokeAsync(value);
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task SetParametersAsync(ParameterView parameters)
|
||||
{
|
||||
var valueChanged = parameters.IsParameterChanged(nameof(Value), Value);
|
||||
var readOnlyChanged = parameters.IsParameterChanged(nameof(ReadOnly), ReadOnly);
|
||||
|
||||
await base.SetParametersAsync(parameters);
|
||||
|
||||
if (_monaco != null && valueChanged && _value != Value)
|
||||
{
|
||||
_value = Value;
|
||||
|
||||
await _monaco.InvokeVoidAsync("setValue", _value);
|
||||
}
|
||||
|
||||
if (_monaco != null && readOnlyChanged)
|
||||
{
|
||||
await _monaco.InvokeVoidAsync("setOptions", new { readOnly = ReadOnly });
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (JSRuntime != null && _monaco != null)
|
||||
{
|
||||
_monaco.InvokeVoidAsync("dispose");
|
||||
}
|
||||
|
||||
_monaco?.DisposeAsync();
|
||||
|
||||
_reference?.Dispose();
|
||||
}
|
||||
|
||||
public async Task SetReadOnly(bool isReadOnly)
|
||||
{
|
||||
if (_monaco != null)
|
||||
{
|
||||
await _monaco.InvokeVoidAsync("updateOptions", new { domReadOnly = isReadOnly, readOnly = isReadOnly });
|
||||
}
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
@using AntDesign.Docs.Services
|
||||
@using System.Reflection;
|
||||
@inherits ComponentBase
|
||||
|
||||
@if (_demoType != null)
|
||||
{
|
||||
<DynamicComponent Type="_demoType" />
|
||||
}
|
||||
|
||||
@inject DemoService demoService;
|
||||
@code {
|
||||
|
||||
[Parameter]
|
||||
public DemoItem Demo { get; set; }
|
||||
|
||||
private Type _demoType;
|
||||
|
||||
private bool _render;
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
_render = true;
|
||||
StateHasChanged();
|
||||
return;
|
||||
}
|
||||
if (_render && _demoType == null)
|
||||
{
|
||||
_demoType = demoService.GetShowCase(Demo.Type);
|
||||
StateHasChanged();
|
||||
}
|
||||
|
||||
base.OnAfterRender(firstRender);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user