Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alzollin/markdown features #588

Merged
merged 5 commits into from
Nov 25, 2024
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!-- 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. -->
<!-- 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. -->
<Page x:Class="MarkdownTextBlockExperiment.Samples.MarkdownTextBlockCustomSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Expand All @@ -25,7 +25,8 @@
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<controls:MarkdownTextBlock Grid.Column="0"
<controls:MarkdownTextBlock x:Name="MarkdownTextBlock1"
Grid.Column="0"
Config="{x:Bind LiveMarkdownConfig, Mode=OneTime}"
Text="{x:Bind MarkdownTextBox.Text, Mode=OneWay}" />
<TextBox x:Name="MarkdownTextBox"
Expand All @@ -37,7 +38,8 @@
FontSize="16"
FontWeight="Bold"
Text="Built-in Sample" />
<controls:MarkdownTextBlock Grid.Row="3"
<controls:MarkdownTextBlock x:Name="MarkdownTextBlock2"
Grid.Row="3"
Config="{x:Bind MarkdownConfig, Mode=OneTime}"
Text="{x:Bind Text, Mode=OneTime}" />
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,5 +607,12 @@ public MarkdownTextBlockCustomSample()
_liveConfig = new MarkdownConfig();
_text = _markdown;
MarkdownTextBox.Text = "# Hello World\n\n";
MarkdownTextBlock1.OnLinkClicked += MarkdownTextBlock_OnLinkClicked;
MarkdownTextBlock2.OnLinkClicked += MarkdownTextBlock_OnLinkClicked;
}

private void MarkdownTextBlock_OnLinkClicked(object? sender, LinkClickedEventArgs e)
{
Debug.WriteLine($"Link Clicked: {e.Uri}");
}
}
14 changes: 12 additions & 2 deletions components/MarkdownTextBlock/src/HtmlWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,21 @@ public static void WriteHtml(WinUIRenderer renderer, HtmlNodeCollection nodes)
IAddChild hyperLink;
if (node.ChildNodes.Any(n => n.Name != "#text"))
{
hyperLink = new MyHyperlinkButton(node, renderer.Config.BaseUrl);
var myHyperlinkButton = new MyHyperlinkButton(node, renderer.Config.BaseUrl);
myHyperlinkButton.ClickEvent += (sender, e) =>
{
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(((HyperlinkButton)sender).NavigateUri);
};
hyperLink = myHyperlinkButton;
}
else
{
hyperLink = new MyHyperlink(node, renderer.Config.BaseUrl);
var myHyperlink = new MyHyperlink(node, renderer.Config.BaseUrl);
myHyperlink.ClickEvent += (sender, e) =>
{
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri);
};
hyperLink = myHyperlink;
}
renderer.Push(hyperLink);
WriteHtml(renderer, node.ChildNodes);
Expand Down
15 changes: 15 additions & 0 deletions components/MarkdownTextBlock/src/LinkClickedEventArgs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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.

namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock;

public class LinkClickedEventArgs : EventArgs
{
public Uri Uri { get; }

public LinkClickedEventArgs(Uri uri)
{
this.Uri = uri;
}
}
6 changes: 5 additions & 1 deletion components/MarkdownTextBlock/src/MarkdownTextBlock.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public string Text
set => SetValue(TextProperty, value);
}

public event EventHandler<LinkClickedEventArgs>? OnLinkClicked;

internal void RaiseLinkClickedEvent(Uri uri) => OnLinkClicked?.Invoke(this, new LinkClickedEventArgs(uri));

private static void OnConfigChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is MarkdownTextBlock self && e.NewValue != null)
Expand Down Expand Up @@ -110,7 +114,7 @@ private void Build()
{
if (_renderer == null)
{
_renderer = new WinUIRenderer(_document, Config);
_renderer = new WinUIRenderer(_document, Config, this);
}
_pipeline.Setup(_renderer);
ApplyText(false);
Expand Down
8 changes: 8 additions & 0 deletions components/MarkdownTextBlock/src/MarkdownThemes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,15 @@ public sealed class MarkdownThemes : DependencyObject

public FontWeight H6FontWeight { get; set; } = FontWeights.Normal;

public Thickness H1Margin { get; set; } = new(0);
public Thickness H2Margin { get; set; } = new(0);
public Thickness H3Margin { get; set; } = new(0);
public Thickness H4Margin { get; set; } = new(0);
public Thickness H5Margin { get; set; } = new(0);
public Thickness H6Margin { get; set; } = new(0);

public Brush InlineCodeBackground { get; set; } = (Brush)Application.Current.Resources["ExpanderHeaderBackground"];
public Brush InlineCodeForeground { get; set; } = (Brush)Application.Current.Resources["TextFillColorPrimaryBrush"];

public Brush InlineCodeBorderBrush { get; set; } = new SolidColorBrush(Colors.Gray);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ protected override void Write(WinUIRenderer renderer, AutolinkInline link)
}

var autolink = new MyAutolinkInline(link);
autolink.ClickEvent += (sender, e) =>
{
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri);
};

renderer.Push(autolink);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,20 @@ protected override void Write(WinUIRenderer renderer, LinkInline link)
{
if (link.FirstChild is LinkInline linkInlineChild && linkInlineChild.IsImage)
{
renderer.Push(new MyHyperlinkButton(link, renderer.Config.BaseUrl));
var myHyperlinkButton = new MyHyperlinkButton(link, renderer.Config.BaseUrl);
myHyperlinkButton.ClickEvent += (sender, e) =>
{
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(((HyperlinkButton)sender).NavigateUri);
};
renderer.Push(myHyperlinkButton);
}
else
{
var hyperlink = new MyHyperlink(link, renderer.Config.BaseUrl);
hyperlink.ClickEvent += (sender, e) =>
{
renderer.MarkdownTextBlock.RaiseLinkClickedEvent(sender.NavigateUri);
};

renderer.Push(hyperlink);
}
Expand Down
4 changes: 3 additions & 1 deletion components/MarkdownTextBlock/src/Renderers/WinUIRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ public MarkdownConfig Config
get => _config;
set => _config = value;
}
public MarkdownTextBlock MarkdownTextBlock { get; }

public WinUIRenderer(MyFlowDocument document, MarkdownConfig config)
public WinUIRenderer(MyFlowDocument document, MarkdownConfig config, MarkdownTextBlock markdownTextBlock)
{
_buffer = new char[1024];
Config = config;
MarkdownTextBlock = markdownTextBlock;
FlowDocument = document;
// set style
_stack.Push(FlowDocument);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@ internal class MyAutolinkInline : IAddChild

public TextElement TextElement { get; private set; }

public event TypedEventHandler<Hyperlink, HyperlinkClickEventArgs>? ClickEvent
{
add
{
((Hyperlink)TextElement).Click += value;
}
remove
{
((Hyperlink)TextElement).Click -= value;
}
}

public MyAutolinkInline(AutolinkInline autoLinkInline)
{
_autoLinkInline = autoLinkInline;
Expand All @@ -21,7 +33,6 @@ public MyAutolinkInline(AutolinkInline autoLinkInline)
};
}


public void AddChild(IAddChild child)
{
try
Expand Down
36 changes: 15 additions & 21 deletions components/MarkdownTextBlock/src/TextElements/MyHeading.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,26 +27,7 @@ public MyHeading(HeadingBlock headingBlock, MarkdownConfig config)
_paragraph = new Paragraph();
_config = config;

var level = headingBlock.Level;
_paragraph.FontSize = level switch
{
1 => _config.Themes.H1FontSize,
2 => _config.Themes.H2FontSize,
3 => _config.Themes.H3FontSize,
4 => _config.Themes.H4FontSize,
5 => _config.Themes.H5FontSize,
_ => _config.Themes.H6FontSize,
};
_paragraph.Foreground = _config.Themes.HeadingForeground;
_paragraph.FontWeight = level switch
{
1 => _config.Themes.H1FontWeight,
2 => _config.Themes.H2FontWeight,
3 => _config.Themes.H3FontWeight,
4 => _config.Themes.H4FontWeight,
5 => _config.Themes.H5FontWeight,
_ => _config.Themes.H6FontWeight,
};
SetHProperties(headingBlock.Level);
}

public MyHeading(HtmlNode htmlNode, MarkdownConfig config)
Expand All @@ -65,7 +46,11 @@ public MyHeading(HtmlNode htmlNode, MarkdownConfig config)
_ => TextAlignment.Left,
};

var level = int.Parse(htmlNode.Name.Substring(1));
SetHProperties(int.Parse(htmlNode.Name.Substring(1)));
}

private void SetHProperties(int level)
{
_paragraph.FontSize = level switch
{
1 => _config.Themes.H1FontSize,
Expand All @@ -85,6 +70,15 @@ public MyHeading(HtmlNode htmlNode, MarkdownConfig config)
5 => _config.Themes.H5FontWeight,
_ => _config.Themes.H6FontWeight,
};
_paragraph.Margin = level switch
{
1 => _config.Themes.H1Margin,
2 => _config.Themes.H2Margin,
3 => _config.Themes.H3Margin,
4 => _config.Themes.H4Margin,
5 => _config.Themes.H5Margin,
_ => _config.Themes.H6Margin,
};
}

public void AddChild(IAddChild child)
Expand Down
12 changes: 12 additions & 0 deletions components/MarkdownTextBlock/src/TextElements/MyHyperlink.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ internal class MyHyperlink : IAddChild
private HtmlNode? _htmlNode;
private string? _baseUrl;

public event TypedEventHandler<Hyperlink, HyperlinkClickEventArgs> ClickEvent
{
add
{
_hyperlink.Click += value;
}
remove
{
_hyperlink.Click -= value;
}
}

public bool IsHtml => _htmlNode != null;

public TextElement TextElement
Expand Down
43 changes: 26 additions & 17 deletions components/MarkdownTextBlock/src/TextElements/MyHyperlinkButton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,24 @@ namespace CommunityToolkit.Labs.WinUI.MarkdownTextBlock.TextElements;

internal class MyHyperlinkButton : IAddChild
{
private HyperlinkButton? _hyperLinkButton;
private HyperlinkButton _hyperLinkButton;
private InlineUIContainer _inlineUIContainer = new InlineUIContainer();
private MyFlowDocument? _flowDoc;
private MyFlowDocument _flowDoc;
private string? _baseUrl;
private LinkInline? _linkInline;
private HtmlNode? _htmlNode;

public event RoutedEventHandler? ClickEvent
{
add
{
_hyperLinkButton.Click += value;
}
remove
{
_hyperLinkButton.Click -= value;
}
}

public bool IsHtml => _htmlNode != null;

Expand All @@ -24,43 +36,40 @@ public TextElement TextElement
}

public MyHyperlinkButton(LinkInline linkInline, string? baseUrl)
: this(linkInline.GetDynamicUrl != null ? linkInline.GetDynamicUrl() ?? linkInline.Url : linkInline.Url, baseUrl, null, linkInline)
{
_baseUrl = baseUrl;
var url = linkInline.GetDynamicUrl != null ? linkInline.GetDynamicUrl() ?? linkInline.Url : linkInline.Url;
_linkInline = linkInline;
Init(url, baseUrl);
}

public MyHyperlinkButton(HtmlNode htmlNode, string? baseUrl)
: this(htmlNode.GetAttribute("href", "#"), baseUrl, htmlNode, null)
{
_baseUrl = baseUrl;
_htmlNode = htmlNode;
var url = htmlNode.GetAttribute("href", "#");
Init(url, baseUrl);
}

private void Init(string? url, string? baseUrl)
private MyHyperlinkButton(string? url, string? baseUrl, HtmlNode? htmlNode, LinkInline? linkInline)
{
_hyperLinkButton = new HyperlinkButton()
_baseUrl = baseUrl;
_htmlNode = htmlNode;
_linkInline = linkInline;
_hyperLinkButton = new HyperlinkButton
{
NavigateUri = Extensions.GetUri(url, baseUrl),
};
_hyperLinkButton.Padding = new Thickness(0);
_hyperLinkButton.Margin = new Thickness(0);
if (IsHtml && _htmlNode != null)
if (_htmlNode != null)
{
_flowDoc = new MyFlowDocument(_htmlNode);
}
else if (_linkInline != null)
else
{
_flowDoc = new MyFlowDocument(_linkInline);
_flowDoc = new MyFlowDocument(_linkInline!);
}
_inlineUIContainer.Child = _hyperLinkButton;
_hyperLinkButton.Content = _flowDoc?.RichTextBlock;
_hyperLinkButton.Content = _flowDoc.RichTextBlock;
}

public void AddChild(IAddChild child)
{
_flowDoc?.AddChild(child);
_flowDoc.AddChild(child);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public MyInlineCode(CodeInline codeInline, MarkdownConfig config)
border.Transform3D = transform;
var textBlock = new TextBlock();
textBlock.FontSize = _config.Themes.InlineCodeFontSize;
textBlock.Foreground = _config.Themes.InlineCodeForeground;
textBlock.FontWeight = _config.Themes.InlineCodeFontWeight;
textBlock.Text = codeInline.Content.ToString();
border.Child = textBlock;
Expand Down
Loading