Fxcop markdown preview handler (#6646)

* migrating namespace conflict

* Fixing all errors

* removing todo

* tweak wxs
This commit is contained in:
Clint Rutkas 2020-09-16 11:15:34 -07:00 committed by GitHub
parent e49900f927
commit 0a86360948
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 103 additions and 64 deletions

View File

@ -455,18 +455,18 @@
</RegistryKey>
<!-- Registry Key for Class Registration of Markdown Preview Handler -->
<RegistryKey Root="HKCR" Key="CLSID\{45769bcc-e8fd-42d0-947e-02beef77a1f5}">
<RegistryValue Type="string" Value="MarkdownPreviewHandler.MarkdownPreviewHandler" />
<RegistryValue Type="string" Value="Microsoft.PowerToys.PreviewHandler.Markdown.MarkdownPreviewHandler" />
<RegistryValue Type="string" Name="DisplayName" Value="Markdown Preview Handler" />
<RegistryValue Type="string" Name="AppID" Value="{CF142243-F059-45AF-8842-DBBE9783DB14}" />
<RegistryValue Type="string" Key="Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}" Value="" />
<RegistryValue Type="string" Key="InprocServer32" Value="mscoree.dll" />
<RegistryValue Type="string" Key="InprocServer32" Name="Assembly" Value="MarkdownPreviewHandler, Version=$(var.Version).0, Culture=neutral" />
<RegistryValue Type="string" Key="InprocServer32" Name="Class" Value="MarkdownPreviewHandler.MarkdownPreviewHandler" />
<RegistryValue Type="string" Key="InprocServer32" Name="Class" Value="Microsoft.PowerToys.PreviewHandler.Markdown.MarkdownPreviewHandler" />
<RegistryValue Type="string" Key="InprocServer32" Name="RuntimeVersion" Value="v4.0.30319" />
<RegistryValue Type="string" Key="InprocServer32" Name="ThreadingModel" Value="Both" />
<RegistryValue Type="string" Key="InprocServer32" Name="CodeBase" Value="file:///[FileExplorerPreviewInstallFolder]MarkdownPreviewHandler.dll" />
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Assembly" Value="MarkdownPreviewHandler, Version=$(var.Version).0, Culture=neutral" />
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Class" Value="MarkdownPreviewHandler.MarkdownPreviewHandler" />
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="Class" Value="Microsoft.PowerToys.PreviewHandler.Markdown.MarkdownPreviewHandler" />
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="RuntimeVersion" Value="v4.0.30319" />
<RegistryValue Type="string" Key="InprocServer32\$(var.Version).0" Name="CodeBase" Value="file:///[FileExplorerPreviewInstallFolder]MarkdownPreviewHandler.dll" />
</RegistryKey>

View File

@ -12,7 +12,7 @@ using Markdig.Renderers.Html;
using Markdig.Syntax;
using Markdig.Syntax.Inlines;
namespace MarkdownPreviewHandler
namespace Microsoft.PowerToys.PreviewHandler.Markdown
{
/// <summary>
/// Callback if extension blocks external images.
@ -33,24 +33,27 @@ namespace MarkdownPreviewHandler
/// Initializes a new instance of the <see cref="HTMLParsingExtension"/> class.
/// </summary>
/// <param name="imagesBlockedCallBack">Callback function if image is blocked by extension.</param>
/// <param name="baseUrl">Absolute path of markdown file.</param>
public HTMLParsingExtension(ImagesBlockedCallBack imagesBlockedCallBack, string baseUrl = "")
/// <param name="filePath">Absolute path of markdown file.</param>
public HTMLParsingExtension(ImagesBlockedCallBack imagesBlockedCallBack, string filePath = "")
{
this.imagesBlockedCallBack = imagesBlockedCallBack;
this.BaseUrl = baseUrl;
FilePath = filePath;
}
/// <summary>
/// Gets or sets path to directory containing markdown file.
/// </summary>
public string BaseUrl { get; set; }
public string FilePath { get; set; }
/// <inheritdoc/>
public void Setup(MarkdownPipelineBuilder pipeline)
{
// Make sure we don't have a delegate twice
pipeline.DocumentProcessed -= this.PipelineOnDocumentProcessed;
pipeline.DocumentProcessed += this.PipelineOnDocumentProcessed;
if (pipeline != null)
{
// Make sure we don't have a delegate twice
pipeline.DocumentProcessed -= PipelineOnDocumentProcessed;
pipeline.DocumentProcessed += PipelineOnDocumentProcessed;
}
}
/// <inheritdoc/>
@ -93,7 +96,7 @@ namespace MarkdownPreviewHandler
{
link.Url = "#";
link.GetAttributes().AddClass("img-fluid");
this.imagesBlockedCallBack();
imagesBlockedCallBack();
}
}
}

View File

@ -7,7 +7,7 @@ using System.Runtime.InteropServices;
using Common;
using Microsoft.PowerToys.Telemetry;
namespace MarkdownPreviewHandler
namespace Microsoft.PowerToys.PreviewHandler.Markdown
{
/// <summary>
/// Implementation of preview handler for markdown files.
@ -15,22 +15,51 @@ namespace MarkdownPreviewHandler
[Guid("45769bcc-e8fd-42d0-947e-02beef77a1f5")]
[ClassInterface(ClassInterfaceType.None)]
[ComVisible(true)]
public class MarkdownPreviewHandler : FileBasedPreviewHandler
public class MarkdownPreviewHandler : FileBasedPreviewHandler, IDisposable
{
private MarkdownPreviewHandlerControl markdownPreviewHandlerControl;
private MarkdownPreviewHandlerControl _markdownPreviewHandlerControl;
private bool disposedValue;
/// <inheritdoc />
public override void DoPreview()
{
this.markdownPreviewHandlerControl.DoPreview(this.FilePath);
_markdownPreviewHandlerControl.DoPreview(FilePath);
}
/// <inheritdoc />
protected override IPreviewHandlerControl CreatePreviewHandlerControl()
{
PowerToysTelemetry.Log.WriteEvent(new Telemetry.Events.MarkdownFileHandlerLoaded());
this.markdownPreviewHandlerControl = new MarkdownPreviewHandlerControl();
return this.markdownPreviewHandlerControl;
_markdownPreviewHandlerControl = new MarkdownPreviewHandlerControl();
return _markdownPreviewHandlerControl;
}
/// <summary>
/// Disposes objects
/// </summary>
/// <param name="disposing">Is Disposing</param>
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_markdownPreviewHandlerControl.Dispose();
}
// TODO: free unmanaged resources (unmanaged objects) and override finalizer
// TODO: set large fields to null
disposedValue = true;
}
}
/// <inheritdoc />
public void Dispose()
{
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@ -44,7 +44,7 @@
<ProjectGuid>{6A71162E-FC4C-4A2C-B90F-3CF94F59A9BB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MarkdownPreviewHandler</RootNamespace>
<RootNamespace>Microsoft.PowerToys.PreviewHandler.Markdown</RootNamespace>
<AssemblyName>MarkdownPreviewHandler</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
@ -127,6 +127,11 @@
<PackageReference Include="Markdig.Signed">
<Version>0.20.0</Version>
</PackageReference>
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers">
<Version>3.3.0</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="StyleCop.Analyzers">
<Version>1.1.118</Version>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>

View File

@ -9,12 +9,12 @@ using System.Text.RegularExpressions;
using System.Windows.Forms;
using Common;
using Markdig;
using MarkdownPreviewHandler.Properties;
using MarkdownPreviewHandler.Telemetry.Events;
using Microsoft.PowerToys.PreviewHandler.Markdown.Properties;
using Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events;
using Microsoft.PowerToys.Telemetry;
using PreviewHandlerCommon;
namespace MarkdownPreviewHandler
namespace Microsoft.PowerToys.PreviewHandler.Markdown
{
/// <summary>
/// Win Form Implementation for Markdown Preview Handler.
@ -24,12 +24,12 @@ namespace MarkdownPreviewHandler
/// <summary>
/// Extension to modify markdown AST.
/// </summary>
private readonly HTMLParsingExtension extension;
private readonly HTMLParsingExtension _extension;
/// <summary>
/// Markdig Pipeline builder.
/// </summary>
private readonly MarkdownPipelineBuilder pipelineBuilder;
private readonly MarkdownPipelineBuilder _pipelineBuilder;
/// <summary>
/// Markdown HTML header.
@ -44,26 +44,26 @@ namespace MarkdownPreviewHandler
/// <summary>
/// RichTextBox control to display if external images are blocked.
/// </summary>
private RichTextBox infoBar;
private RichTextBox _infoBar;
/// <summary>
/// Extended Browser Control to display markdown html.
/// </summary>
private WebBrowserExt browser;
private WebBrowserExt _browser;
/// <summary>
/// True if external image is blocked, false otherwise.
/// </summary>
private bool infoBarDisplayed = false;
private bool _infoBarDisplayed;
/// <summary>
/// Initializes a new instance of the <see cref="MarkdownPreviewHandlerControl"/> class.
/// </summary>
public MarkdownPreviewHandlerControl()
{
this.extension = new HTMLParsingExtension(this.ImagesBlockedCallBack);
this.pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley();
this.pipelineBuilder.Extensions.Add(this.extension);
_extension = new HTMLParsingExtension(ImagesBlockedCallBack);
_pipelineBuilder = new MarkdownPipelineBuilder().UseAdvancedExtensions().UseEmojiAndSmiley();
_pipelineBuilder.Extensions.Add(_extension);
}
/// <summary>
@ -72,7 +72,7 @@ namespace MarkdownPreviewHandler
/// <param name="dataSource">Path to the file.</param>
public override void DoPreview<T>(T dataSource)
{
this.infoBarDisplayed = false;
_infoBarDisplayed = false;
try
{
@ -85,17 +85,17 @@ namespace MarkdownPreviewHandler
Regex imageTagRegex = new Regex(@"<[ ]*img.*>");
if (imageTagRegex.IsMatch(fileText))
{
this.infoBarDisplayed = true;
_infoBarDisplayed = true;
}
this.extension.BaseUrl = Path.GetDirectoryName(filePath);
MarkdownPipeline pipeline = this.pipelineBuilder.Build();
string parsedMarkdown = Markdown.ToHtml(fileText, pipeline);
string markdownHTML = $"{this.htmlHeader}{parsedMarkdown}{this.htmlFooter}";
_extension.FilePath = Path.GetDirectoryName(filePath);
MarkdownPipeline pipeline = _pipelineBuilder.Build();
string parsedMarkdown = Markdig.Markdown.ToHtml(fileText, pipeline);
string markdownHTML = $"{htmlHeader}{parsedMarkdown}{htmlFooter}";
this.InvokeOnControlThread(() =>
InvokeOnControlThread(() =>
{
this.browser = new WebBrowserExt
_browser = new WebBrowserExt
{
DocumentText = markdownHTML,
Dock = DockStyle.Fill,
@ -104,29 +104,31 @@ namespace MarkdownPreviewHandler
ScrollBarsEnabled = true,
AllowNavigation = false,
};
this.Controls.Add(this.browser);
Controls.Add(_browser);
if (this.infoBarDisplayed)
if (_infoBarDisplayed)
{
this.infoBar = this.GetTextBoxControl(Resources.BlockedImageInfoText);
this.Resize += this.FormResized;
this.Controls.Add(this.infoBar);
_infoBar = GetTextBoxControl(Resources.BlockedImageInfoText);
Resize += FormResized;
Controls.Add(_infoBar);
}
});
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewed());
}
catch (Exception e)
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewError { Message = e.Message });
PowerToysTelemetry.Log.WriteEvent(new MarkdownFilePreviewError { Message = ex.Message });
this.InvokeOnControlThread(() =>
InvokeOnControlThread(() =>
{
this.Controls.Clear();
this.infoBarDisplayed = true;
this.infoBar = this.GetTextBoxControl(Resources.MarkdownNotPreviewedError);
this.Resize += this.FormResized;
this.Controls.Add(this.infoBar);
Controls.Clear();
_infoBarDisplayed = true;
_infoBar = GetTextBoxControl(Resources.MarkdownNotPreviewedError);
Resize += FormResized;
Controls.Add(_infoBar);
});
}
finally
@ -150,7 +152,7 @@ namespace MarkdownPreviewHandler
Dock = DockStyle.Top,
ReadOnly = true,
};
richTextBox.ContentsResized += this.RTBContentsResized;
richTextBox.ContentsResized += RTBContentsResized;
richTextBox.ScrollBars = RichTextBoxScrollBars.None;
richTextBox.BorderStyle = BorderStyle.None;
@ -175,9 +177,9 @@ namespace MarkdownPreviewHandler
/// <param name="e">Provides data for the event.</param>
private void FormResized(object sender, EventArgs e)
{
if (this.infoBarDisplayed)
if (_infoBarDisplayed)
{
this.infoBar.Width = this.Width;
_infoBar.Width = Width;
}
}
@ -186,7 +188,7 @@ namespace MarkdownPreviewHandler
/// </summary>
private void ImagesBlockedCallBack()
{
this.infoBarDisplayed = true;
_infoBarDisplayed = true;
}
}
}

View File

@ -8,7 +8,7 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace MarkdownPreviewHandler.Properties {
namespace Microsoft.PowerToys.PreviewHandler.Markdown.Properties {
using System;
@ -39,7 +39,7 @@ namespace MarkdownPreviewHandler.Properties {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("MarkdownPreviewHandler.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.PowerToys.PreviewHandler.Markdown.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;

View File

@ -8,11 +8,11 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace MarkdownPreviewHandler.Properties {
namespace Microsoft.PowerToys.PreviewHandler.Markdown.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.4.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.7.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));

View File

@ -6,7 +6,7 @@ using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
namespace MarkdownPreviewHandler.Telemetry.Events
namespace Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events
{
/// <summary>
/// A telemetry event that is triggered when a markdown file is viewed in the preview pane.

View File

@ -5,7 +5,7 @@
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
namespace MarkdownPreviewHandler.Telemetry.Events
namespace Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events
{
/// <summary>
/// A telemetry event that is triggered when an error occurs while attempting to view a markdown file in the preview pane.

View File

@ -6,7 +6,7 @@ using System.Diagnostics.Tracing;
using Microsoft.PowerToys.Telemetry;
using Microsoft.PowerToys.Telemetry.Events;
namespace MarkdownPreviewHandler.Telemetry.Events
namespace Microsoft.PowerToys.PreviewHandler.Markdown.Telemetry.Events
{
/// <summary>
/// A telemetry event that is triggered when a markdown file is viewed in the preview pane.

View File

@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using Markdig;
using MarkdownPreviewHandler;
using Microsoft.PowerToys.PreviewHandler.Markdown;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace PreviewPaneUnitTests

View File

@ -4,7 +4,7 @@
using System.Drawing;
using System.Windows.Forms;
using MarkdownPreviewHandler;
using Microsoft.PowerToys.PreviewHandler.Markdown;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using PreviewHandlerCommon;