Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
name: Publish NuGet Package

on:
workflow_dispatch:
inputs:
version:
description: Optional package version; defaults to the release tag or project version
required: false
type: string
release:
types: [published]

concurrency:
group: publish-nuget
cancel-in-progress: false

env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: true
NUGET_DIRECTORY: ${{ github.workspace }}/artifacts/packages

permissions:
contents: read

jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Restore dependencies
run: dotnet restore src/ToastUIEditor/ToastUIEditor.csproj
- name: Pack
shell: bash
env:
RELEASE_VERSION: ${{ github.event.release.tag_name || inputs.version }}
run: |
version="${RELEASE_VERSION#v}"
args=(src/ToastUIEditor/ToastUIEditor.csproj --configuration Release --no-restore --output "$NUGET_DIRECTORY" -p:ContinuousIntegrationBuild=true)
if [ -n "$version" ]; then args+=("-p:Version=$version"); fi
dotnet pack "${args[@]}"
- name: Publish to NuGet.org
shell: bash
run: |
packages=$(find "$NUGET_DIRECTORY" -maxdepth 1 -name '*.nupkg' ! -name '*.snupkg' -print)
if [ -z "$packages" ]; then
echo "No NuGet package was produced." >&2
exit 1
fi
while IFS= read -r package; do
dotnet nuget push "$package" --api-key "${{ secrets.NUGET_API_KEY }}" --source https://api.nuget.org/v3/index.json --skip-duplicate
done <<< "$packages"
41 changes: 41 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Build and Test

on:
workflow_dispatch:
push:
branches: [master, develop]
pull_request:
branches: [master, develop]

concurrency:
group: test-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
DOTNET_CLI_TELEMETRY_OPTOUT: 1
DOTNET_NOLOGO: true

permissions:
contents: read

jobs:
test:
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 10.0.x
- name: Restore dependencies
run: dotnet restore ToastUIEditor.sln
- name: Build
run: dotnet build ToastUIEditor.sln --configuration Release --no-restore -p:ContinuousIntegrationBuild=true
- name: Run tests
run: dotnet test tests/ToastUIEditor.Tests/ToastUIEditor.Tests.csproj --configuration Release --no-build --no-restore --verbosity normal
- name: Verify NuGet package can be created
run: dotnet pack src/ToastUIEditor/ToastUIEditor.csproj --configuration Release --no-build --no-restore --output ./artifacts/packages -p:ContinuousIntegrationBuild=true
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

`tui.editor.blazor` is a Blazor component that provides a Markdown editor based on the [tui.editor](https://github.com/nhn/tui.editor) library.

Supports .NET 9 and .NET 10 for Blazor Server and Blazor WebAssembly applications.

## Development

```shell
dotnet build ToastUIEditor.sln --configuration Release
dotnet test tests/ToastUIEditor.Tests/ToastUIEditor.Tests.csproj --configuration Release
```

Packages are built automatically by GitHub Actions for pushes and pull requests. A NuGet
publication can be triggered by publishing a GitHub Release (the tag is used as the package
version) or manually from the `Publish NuGet Package` workflow. The repository must have a
`NUGET_API_KEY` secret configured for publishing.


## Installation

Expand Down
7 changes: 7 additions & 0 deletions ToastUIEditor.sln
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "git", "git", "{F6BA15F6-D72
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToastUIEditor.Generators", "src\ToastUIEditor.Generators\ToastUIEditor.Generators.csproj", "{F3C426CF-BC81-4EB3-A765-D535B545F889}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ToastUIEditor.Tests", "tests\ToastUIEditor.Tests\ToastUIEditor.Tests.csproj", "{A4E75D31-4D8D-4F3E-9C93-7A2C4C95D8D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.BlazorApp", "samples\Sample.BlazorApp\Sample.BlazorApp\Sample.BlazorApp.csproj", "{17C9C8F2-94AD-46CD-8B8D-BD6739800509}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.BlazorApp.Client", "samples\Sample.BlazorApp\Sample.BlazorApp.Client\Sample.BlazorApp.Client.csproj", "{C35EAE3A-68AF-4EC8-9B91-7C2CE00EB577}"
Expand All @@ -40,6 +42,10 @@ Global
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F3C426CF-BC81-4EB3-A765-D535B545F889}.Release|Any CPU.Build.0 = Release|Any CPU
{A4E75D31-4D8D-4F3E-9C93-7A2C4C95D8D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A4E75D31-4D8D-4F3E-9C93-7A2C4C95D8D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A4E75D31-4D8D-4F3E-9C93-7A2C4C95D8D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A4E75D31-4D8D-4F3E-9C93-7A2C4C95D8D7}.Release|Any CPU.Build.0 = Release|Any CPU
{17C9C8F2-94AD-46CD-8B8D-BD6739800509}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{17C9C8F2-94AD-46CD-8B8D-BD6739800509}.Debug|Any CPU.Build.0 = Debug|Any CPU
{17C9C8F2-94AD-46CD-8B8D-BD6739800509}.Release|Any CPU.ActiveCfg = Release|Any CPU
Expand All @@ -63,6 +69,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{8D6E935A-3EDC-4774-95ED-1D4C2D7C71F0} = {3EFCFD32-EC2A-40B3-9A4D-32DD3FD98A29}
{F3C426CF-BC81-4EB3-A765-D535B545F889} = {3EFCFD32-EC2A-40B3-9A4D-32DD3FD98A29}
{A4E75D31-4D8D-4F3E-9C93-7A2C4C95D8D7} = {3EFCFD32-EC2A-40B3-9A4D-32DD3FD98A29}
{17C9C8F2-94AD-46CD-8B8D-BD6739800509} = {73CA8193-E7DD-47DD-91E9-A3183F63AF53}
{C35EAE3A-68AF-4EC8-9B91-7C2CE00EB577} = {73CA8193-E7DD-47DD-91E9-A3183F63AF53}
{59E5EE05-8208-424D-9A01-CB6E5590D171} = {73CA8193-E7DD-47DD-91E9-A3183F63AF53}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<NoDefaultLaunchSettingsFile>true</NoDefaultLaunchSettingsFile>
<StaticWebAssetProjectMode>Default</StaticWebAssetProjectMode>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
<PackageReference Include="ToastUIEditor" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.*" />
<ProjectReference Include="..\..\..\src\ToastUIEditor\ToastUIEditor.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Sample.BlazorApp.Client\Sample.BlazorApp.Client.csproj" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="10.*" />
</ItemGroup>

</Project>
4 changes: 2 additions & 2 deletions samples/Sample.BlazorServer/Sample.BlazorServer.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="ToastUIEditor" Version="1.0.0" />
<ProjectReference Include="..\..\src\ToastUIEditor\ToastUIEditor.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
<PackageReference Include="ToastUIEditor" Version="1.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="10.*" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="10.*" PrivateAssets="all" />
<ProjectReference Include="..\..\src\ToastUIEditor\ToastUIEditor.csproj" />
</ItemGroup>

</Project>
10 changes: 5 additions & 5 deletions src/ToastUIEditor/Editor.events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,23 +91,23 @@ public async Task InvokeLoadAsync()
await Task.Delay(100);
time -= 100;
}
_ = Load.InvokeAsync();
await Load.InvokeAsync();
}

/// <summary>
/// Do not call this method directly. This method is called by JavaScript.
/// </summary>
[JSInvokable("change")]
public Task InvokeChangeAsync(string editorType, string value)
public async Task InvokeChangeAsync(string editorType, string value)
{
if (value != CurrentValueAsString)
{
CurrentValueAsString = value;
StateHasChanged();
_ = ValueChanged.InvokeAsync(value);
_ = Change.InvokeAsync(value);
await ValueChanged.InvokeAsync(value);
await Change.InvokeAsync(value);
}
return Task.CompletedTask;
await Task.CompletedTask;
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/ToastUIEditor/Editor.methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -454,5 +454,6 @@ private async Task DisposeJavaScriptObjects()
{
await _module.DisposeAsync();
}
Options.Reference?.Dispose();
}
}
52 changes: 50 additions & 2 deletions src/ToastUIEditor/Internals/EnumValueConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,23 @@ internal sealed class EnumValueJsonConverter<T> : JsonConverter<T> where T : Enu
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException($"Expected a string value for {typeof(T).Name}.");
}

var value = reader.GetString();
foreach (var member in typeof(T).GetMembers(BindingFlags.Public | BindingFlags.Static))
{
var attribute = member.GetCustomAttribute<JsonValueAttribute>();
if (attribute?.Value.Equals(value, StringComparison.OrdinalIgnoreCase) == true ||
member.Name.Equals(value, StringComparison.OrdinalIgnoreCase))
{
return (T)Enum.Parse(typeof(T), member.Name);
}
}

throw new JsonException($"Unknown {typeof(T).Name} value '{value}'.");
}

public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
Expand All @@ -25,7 +41,39 @@ internal sealed class EnumDictionaryKeyJsonConverter<TKey, TValue> : JsonConvert
{
public override Dictionary<TKey, TValue> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
throw new NotImplementedException();
using var document = JsonDocument.ParseValue(ref reader);
if (document.RootElement.ValueKind != JsonValueKind.Object)
{
throw new JsonException($"Expected an object for {typeof(TKey).Name} dictionary.");
}

var result = new Dictionary<TKey, TValue>();
foreach (var property in document.RootElement.EnumerateObject())
{
TKey key = default!;
var found = false;
foreach (TKey item in Enum.GetValues(typeof(TKey)))
{
var member = typeof(TKey).GetMember(item.ToString())[0];
var attribute = member.GetCustomAttribute<JsonValueAttribute>();
if (attribute?.Value.Equals(property.Name, StringComparison.OrdinalIgnoreCase) == true ||
item.ToString().Equals(property.Name, StringComparison.OrdinalIgnoreCase))
{
key = item;
found = true;
break;
}
}

if (!found)
{
throw new JsonException($"Unknown {typeof(TKey).Name} value '{property.Name}'.");
}

result[key] = property.Value.Deserialize<TValue>(options)!;
}

return result;
}

public override void Write(Utf8JsonWriter writer, Dictionary<TKey, TValue> value, JsonSerializerOptions options)
Expand Down
16 changes: 6 additions & 10 deletions src/ToastUIEditor/ToastUIEditor.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<TargetFrameworks>net6.0;net7.0;net8.0;</TargetFrameworks>
<TargetFrameworks>net9.0;net10.0</TargetFrameworks>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>ToastUI</RootNamespace>
Expand All @@ -14,7 +14,7 @@

<PropertyGroup>
<PackageId>ToastUIEditor</PackageId>
<PackageVersion>1.0.0</PackageVersion>
<VersionPrefix>1.1.0</VersionPrefix>
<Authors>ling921;</Authors>
<Description>Blazor wrapper for ToastUI Editor, see README.md file for more details.</Description>
<Copyright>Copyright © ling921 All rights reserved.</Copyright>
Expand All @@ -31,16 +31,12 @@
<SupportedPlatform Include="browser" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net6.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.*" />
<ItemGroup Condition="'$(TargetFramework)' == 'net9.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="9.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="7.*" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net8.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.*" />
<ItemGroup Condition="'$(TargetFramework)' == 'net10.0'">
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="10.*" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/ToastUIEditor/Viewer.events.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public async Task InvokeLoadAsync()
await Task.Delay(100);
time -= 100;
}
_ = Load.InvokeAsync();
await Load.InvokeAsync();
}

/// <summary>
Expand Down
1 change: 1 addition & 0 deletions src/ToastUIEditor/Viewer.methods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ private async Task DisposeJavaScriptObjects()
{
await _module.DisposeAsync();
}
Options.Reference?.Dispose();
}
}
Loading
Loading