I'm having issues linking to a header in the same document with CommonMark, Markdig, MAUI, and Visual Studio 2022?

117 views Asked by At

Here is an excerpt from my Markdown text.

This window is divided into 5 regions -
[*Naming Fields*](#namingfields),
...
Each region is described in more detail below.

<a name="namingfields"></a>
### Naming Fields

Here is my C# code to convert from Markdown to HTML:

var result = Markdig.Markdown.ToHtml(text);

And here is the resulting HTML.

<p>This window is divided into 5 regions -
<a href="#namingfields"><em>Naming Fields</em></a>,
...
Each region is described in more detail below.</p>
<p><a name="namingfields"></a></p>
<h3>Naming Fields</h3>

I get the same behavior using this Markup.

<a id="namingfields"></a>

That is, using id in place of name.

The strange behavior I'm seeing is that when I set a breakpoint to examine result as HTML, I can click the "Naming Fields" link, and I get the desired behavior - focus moves to the target header. However, when I continue from my breakpoint, and click the link in the context of the running application, I get the following error: Can't reach the webpage at https://appdir/#namingfields.

I'm using the MAUI WebView control, and I have verified that BaseUrl is null. I have also inspected the HTML in the WebView control, and it is unchanged from what I see in the debugger. But obviously, my link is being redirected, and I don't understand why. I would appreciate any insights anyone has to offer.

And by the way, isn't there a way I can use Markup, instead of embedded HTML, to specify the "namingfields" target?

Thanks. Chuck

---- Updated post ----

In response to @GuangyuBai-MSFT's request for the demo, here are the relevant files.

HelpPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit"
             x:Class="AzureResourceNaming.HelpPage"
             >
    <StackLayout BackgroundColor="LightGray">
        <WebView Source="{Binding HelpViewSource}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" />
    </StackLayout>
</ContentPage>


HelpPage.xaml.cs:
using Markdig;

namespace AzureResourceNaming;

public partial class HelpPage : ContentPage
{
    private HtmlWebViewSource _helpViewSource = new();
    public HtmlWebViewSource HelpViewSource
    {
        get { return _helpViewSource; }
        set
        {
            if (_helpViewSource != value)
            {
                _helpViewSource = value;
                OnPropertyChanged(nameof(HelpViewSource));
            }
        }
    }

    public HelpPage()
    {
        InitializeComponent();
        if (Content != null)
        {
            Content.BindingContext = this;
        }

        var text = LoadMarkdownContent().GetAwaiter().GetResult();
        var result = Markdown.ToHtml(text);
        var viewSource = new HtmlWebViewSource
        {
            Html = result,
            BaseUrl = string.Empty
        };
        HelpViewSource = viewSource;
    }

    private static async Task<string> LoadMarkdownContent()
    {
        using var stream = await FileSystem.OpenAppPackageFileAsync("HelpFile.txt");
        using var reader = new StreamReader(stream);

        var contents = reader.ReadToEnd();
        return contents;
    }
}

HelpFile.txt is shown at the top of the post. I launch the HelpText view with the following:

   var helpWindow = new Window(new HelpPage())
   {
       Width = 850,
       Height = 700
   };
   Application.Current?.OpenWindow(helpWindow);

---- More information ----

I added an event handler, WebView_Navigating(object sender, WebNavigatingEventArgs e), which does get triggered when I click on the link in my HelpText document. Upon examining sender.Source, I see that it is properly set to the HtmlWebViewSource I created in the constructor. However, e.Source is set to a UrlWebViewSource object I don't recognize, but it's Url property is set to https://appdir/#namingfields which I do recognize as the target mentioned in the error message.

I then added a second event handler, WebView_BindingContextChanged(object sender, EventArgs e) which gets triggered when I launch the HelpPage view, and sender.Source is once again set to the HtmlWebViewSource I created in the constructor. Unfortunately, EventArgs is just an empty base class, and holds no interesting information, and BindingContextChangedEventArgs is not defined for MAUI applications. So, I don't know, but it is highly likely, that this event was triggered by initially setting WebView.Source.

So, at this point, I now know that I'm getting an erroneous navigation event, but I don't know where it's coming from or why.

---- Even More information ----

Upon exploring the stack trace upon triggering BindingContextChanged I now know that the triggering event was Content.BindingContext = this; and this has nothing to do with setting WebView.Source.

Upon exploring the stack trace upon triggering WebView_Navigating I was unable to find any useful information.

---- Conclusive Information ----

To close the loop on possibilities, I modified my HelpPressed code as follows:

using var stream = await FileSystem.OpenAppPackageFileAsync("HelpFile.txt");
using var reader = new StreamReader(stream);
var text = reader.ReadToEnd();
var result = Markdown.ToHtml(text);

var targetFile = "...";  
using var outputStream = File.OpenWrite(targetFile);
using var streamWriter = new StreamWriter(outputStream);
await streamWriter.WriteAsync(result);

var xyz = await Launcher.OpenAsync(new Uri(targetFile));

Instead of passing the html string into a WebView control for display, I save it in a file, then launch a browser to display it. This works just fine - all the links work as expected. So, this clearly points the finger at a bug in the WebView control, and not at Markdown or Markdig.

0

There are 0 answers