MyNihongo / MudBlazor.Markdown

Markdown component based on the MudBlazor environment
https://mudblazor.com/
MIT License
112 stars 13 forks source link

v1.0.1 - MudMarkdown fails to render newline characters #261

Open kelltom opened 1 month ago

kelltom commented 1 month ago

Prior to this update, MudMarkdown was able to handle the following component without issue:

<MudMarkdown Value="`MudMarkdown` is a third party component that renders markdown text." />

<MudText Typo="Typo.caption">C#</MudText>
<MudMarkdown Value="@codeSnippet" />

@code {
    string codeSnippet = "```csharp\n// comment\nvar x = 5;\nvoid Increment() {\n  x++;\n  Console.WriteLine(x);\n}\nIncrement();\n```";
}

But we're met with the following error: chrome_nPkYDJVbI9

Plaintext:

Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
      Unhandled exception rendering component: Could not resolve type with token 01000041 from typeref (expected class 'Enumerator' in assembly '')
System.TypeLoadException: Could not resolve type with token 01000041 from typeref (expected class 'Enumerator' in assembly '')
   at MudBlazor.MudMarkdown.RenderFencedCodeBlock(RenderTreeBuilder& builder, FencedCodeBlock& code)
   at MudBlazor.MudMarkdown.RenderMarkdown(ContainerBlock container, RenderTreeBuilder builder)
   at MudBlazor.MudMarkdown.BuildRenderTree(RenderTreeBuilder builder)
   at Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder builder)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)

Is this intended, and if so, are there other ways to render newline characters in the Value property?

MihailsKuzmins commented 1 month ago

In v1.0.0 rendering of the code block has been completely transferred to javascript (because of https://github.com/MyNihongo/MudBlazor.Markdown/issues/209), so it seems to have caused quite a lot of unexpected issues.

MihailsKuzmins commented 1 month ago

@kelltom

I have tried reproducing the issue, but your snippet seems to work without any issues with the development branch. Could you please provide a repository where it fails? In the meantime, I will try to reproduce it by using the NuGet package..

Server project

image

Wasm project

image

kelltom commented 1 month ago

Woah, interesting. The repo I'm using is proprietary for work so I'll have to see if I can reproduce it somewhere else. Maybe it has something to do with my script load order...

kelltom commented 1 month ago

Doesn't seem to be related to load orders...

I should clarify that I'm using Dotnet 8 and MudBlazor v7.0 preview. That's probably why there are issues. I believe the error is indicating that there are some missing references/assemblies.

MihailsKuzmins commented 1 month ago

I see, the version 7.0.0-preview.4 seems to introduce certain API breaking changes.. For now, I think I can try to generate a pre-release package where the pre-release version of MudBlazor is supported

kelltom commented 1 month ago

That sounds good to me. I'm sure many would appreciate a stable version of MudMarkdown to line up with the official 7.0 release 😄

MihailsKuzmins commented 1 month ago

After more investigation, it seems that there is a problem with the .net8 SSR implementation of Blazor (that comes by default in new project templates).

But at least it seems that I can reproduce this behavior and come up with a fix for that.

MihailsKuzmins commented 4 weeks ago

@kelltom According to OnAfterRenderAsync not triggered in .net8 OnAfterRender is not called for SSR and some components in the library require this method (then invoke JS runtime).

For now, a solution is adding @rendermode="InteractiveServer" to the Markdown component, so the code will look like this:

@page "/"

<PageTitle>Home</PageTitle>

<MudText Typo="Typo.caption">C#</MudText>
<MudMarkdown @rendermode="InteractiveServer" Value="@codeSnippet" />

@code {
    string codeSnippet = "```csharp\n// comment\nvar x = 5;\nvoid Increment() {\n  x++;\n  Console.WriteLine(x);\n}\nIncrement();\n```";
}

But hopefully there is a way to detect whether Blazor is running in SSR and invoke the JS runtime during initialization.

kelltom commented 3 weeks ago

Sorry for re-opening this, late getting to it.

I was noticing the issue in a Wasm app. I personally don't use the new hybrid Web App template and instead am still using a Server Hosted Wasm application (typical client-server app). I don't believe it supports SSR. It behaves much like a Standalone Wasm app, where everything is client-side rendered.

Looks like Microsoft has removed their template options for making a Wasm application ASP.NET Core Hosted... So we only have two options:

Do you know if your fix works with the Standalone Wasm setup?

MihailsKuzmins commented 3 weeks ago

Yes, as I posted previously in works in a server and a WASM application. It does not work in a web app because OnAfterRenderAsync life cycle method is not invoked. In your example - if you hover over the last code block component I will notice that a copy button appears there (or at least I suppose it should).

No hover:
image

Hover:
image

Gif:
aaa

As I said, it is difficult to guess what is wrong in your case with having the actual project where it can be reproduced.

kelltom commented 2 weeks ago

I see... The gist of the errors in my console is that some javascript is trying to call replace() on a value that doesn't exist, somewhere. That's as far as I can get with it.

Unfortunately I can't really send over a reproducable example unless I spend some serious time stripping down my project, which I might do if I find the time.