mirror of
https://github.com/QL-Win/QuickLook.git
synced 2025-09-11 09:49:07 +00:00
Revert "Go back from Webkit to IE render engine"
This reverts commit f58ef0dcb6
.
This commit is contained in:
Binary file not shown.
Binary file not shown.
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/cef.pak
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/cef.pak
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/icudtl.dat
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/icudtl.dat
Normal file
Binary file not shown.
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/libEGL.dll
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/libEGL.dll
Normal file
Binary file not shown.
Binary file not shown.
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/libcef.dll
Normal file
BIN
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/libcef.dll
Normal file
Binary file not shown.
Binary file not shown.
14203
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/natives_blob.bin
Normal file
14203
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/CefSharp/natives_blob.bin
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -1,50 +0,0 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
internal static class Helper
|
||||
{
|
||||
public static string FilePathToFileUrl(string filePath)
|
||||
{
|
||||
var uri = new StringBuilder();
|
||||
foreach (var v in filePath)
|
||||
if (v >= 'a' && v <= 'z' || v >= 'A' && v <= 'Z' || v >= '0' && v <= '9' ||
|
||||
v == '+' || v == '/' || v == ':' || v == '.' || v == '-' || v == '_' || v == '~' ||
|
||||
v > '\xFF')
|
||||
uri.Append(v);
|
||||
else if (v == Path.DirectorySeparatorChar || v == Path.AltDirectorySeparatorChar)
|
||||
uri.Append('/');
|
||||
else
|
||||
uri.Append($"%{(int) v:X2}");
|
||||
if (uri.Length >= 2 && uri[0] == '/' && uri[1] == '/') // UNC path
|
||||
uri.Insert(0, "file:");
|
||||
else
|
||||
uri.Insert(0, "file:///");
|
||||
return uri.ToString();
|
||||
}
|
||||
|
||||
public static void SetBrowserFeatureControl()
|
||||
{
|
||||
var exeName = Path.GetFileName(App.AppFullPath);
|
||||
|
||||
// use latest engine
|
||||
SetBrowserFeatureControlKey("FEATURE_BROWSER_EMULATION", exeName, 0);
|
||||
//
|
||||
SetBrowserFeatureControlKey("FEATURE_GPU_RENDERING", exeName, 0);
|
||||
// turn on hi-dpi mode
|
||||
SetBrowserFeatureControlKey("FEATURE_96DPI_PIXEL", exeName, 1);
|
||||
}
|
||||
|
||||
private static void SetBrowserFeatureControlKey(string feature, string appName, uint value)
|
||||
{
|
||||
using (var key = Registry.CurrentUser.CreateSubKey(
|
||||
string.Concat(@"Software\Microsoft\Internet Explorer\Main\FeatureControl\", feature),
|
||||
RegistryKeyPermissionCheck.ReadWriteSubTree))
|
||||
{
|
||||
key?.SetValue(appName, value, RegistryValueKind.DWord);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
// Copyright © 2010-2017 The CefSharp Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
using CefSharp;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
public class JsDialogHandler : IJsDialogHandler
|
||||
{
|
||||
public bool OnJSDialog(IWebBrowser browserControl, IBrowser browser, string originUrl,
|
||||
CefJsDialogType dialogType, string messageText, string defaultPromptText, IJsDialogCallback callback,
|
||||
ref bool suppressMessage)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool OnJSBeforeUnload(IWebBrowser browserControl, IBrowser browser, string message, bool isReload,
|
||||
IJsDialogCallback callback)
|
||||
{
|
||||
//NOTE: No need to execute the callback if you return false
|
||||
// callback.Continue(true);
|
||||
|
||||
//NOTE: Returning false will trigger the default behaviour, you need to return true to handle yourself.
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnResetDialogState(IWebBrowser browserControl, IBrowser browser)
|
||||
{
|
||||
}
|
||||
|
||||
public void OnDialogClosed(IWebBrowser browserControl, IBrowser browser)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
35
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/MenuHandler.cs
Normal file
35
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/MenuHandler.cs
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright © 2010-2017 The CefSharp Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
using CefSharp;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
internal class MenuHandler : IContextMenuHandler
|
||||
{
|
||||
public void OnBeforeContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IContextMenuParams parameters,
|
||||
IMenuModel model)
|
||||
{
|
||||
}
|
||||
|
||||
public bool OnContextMenuCommand(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IContextMenuParams parameters,
|
||||
CefMenuCommand commandId, CefEventFlags eventFlags)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnContextMenuDismissed(IWebBrowser browserControl, IBrowser browser, IFrame frame)
|
||||
{
|
||||
}
|
||||
|
||||
public bool RunContextMenu(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IContextMenuParams parameters,
|
||||
IMenuModel model, IRunContextMenuCallback callback)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,16 +1,15 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
public class Plugin : IViewer
|
||||
{
|
||||
private WebpagePanel _panel;
|
||||
private WebkitPanel _panel;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => false;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
@@ -37,12 +36,12 @@ namespace QuickLook.Plugin.HtmlViewer
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
{
|
||||
_panel = new WebpagePanel();
|
||||
_panel = new WebkitPanel();
|
||||
context.ViewerContent = _panel;
|
||||
context.Title = Path.IsPathRooted(path) ? Path.GetFileName(path) : path;
|
||||
|
||||
_panel.Navigate(path);
|
||||
_panel.Dispatcher.Invoke(() => { context.IsBusy = false; }, DispatcherPriority.Loaded);
|
||||
context.IsBusy = false;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
|
@@ -35,10 +35,20 @@
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="CefSharp, Version=57.0.0.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\CefSharp.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CefSharp.Core, Version=57.0.0.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\CefSharp.Core.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="CefSharp.Wpf, Version=57.0.0.0, Culture=neutral, PublicKeyToken=40c4b6fc221f4138, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>References\CefSharp.Wpf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xaml">
|
||||
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||
</Reference>
|
||||
@@ -47,18 +57,20 @@
|
||||
<Reference Include="PresentationFramework" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="WpfBrowserWrapper.cs" />
|
||||
<Page Include="WebpagePanel.xaml">
|
||||
<Page Include="WebkitPanel.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Compile Include="..\..\GitVersion.cs">
|
||||
<Link>Properties\GitVersion.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="JsDialogHandler.cs" />
|
||||
<Compile Include="MenuHandler.cs" />
|
||||
<Compile Include="Plugin.cs" />
|
||||
<Compile Include="Helper.cs" />
|
||||
<Compile Include="WebpagePanel.xaml.cs">
|
||||
<DependentUpon>WebpagePanel.xaml</DependentUpon>
|
||||
<Compile Include="RequestHandler.cs" />
|
||||
<Compile Include="UrlHelper.cs" />
|
||||
<Compile Include="WebkitPanel.xaml.cs">
|
||||
<DependentUpon>WebkitPanel.xaml</DependentUpon>
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
@@ -66,6 +78,38 @@
|
||||
<Compile Include="Properties\AssemblyInfo.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<ContentWithTargetPath Include="CefSharp\cef.pak">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>cef.pak</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\cef_100_percent.pak">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>cef_100_percent.pak</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\cef_200_percent.pak">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>cef_200_percent.pak</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\cef_extensions.pak">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>cef_extensions.pak</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\icudtl.dat">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>icudtl.dat</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\locales\en-US.pak">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>locales\en-US.pak</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\natives_blob.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>natives_blob.bin</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\snapshot_blob.bin">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>snapshot_blob.bin</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\QuickLook\QuickLook.csproj">
|
||||
@@ -75,15 +119,38 @@
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="SHDocVw">
|
||||
<Guid>{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}</Guid>
|
||||
<VersionMajor>1</VersionMajor>
|
||||
<VersionMinor>1</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>tlbimp</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>True</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<ContentWithTargetPath Include="CefSharp\CefSharp.BrowserSubprocess.Core.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>CefSharp.BrowserSubprocess.Core.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\CefSharp.BrowserSubprocess.exe">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>CefSharp.BrowserSubprocess.exe</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\chrome_elf.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>chrome_elf.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\d3dcompiler_47.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>d3dcompiler_47.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\libcef.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>libcef.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\libEGL.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>libEGL.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\libGLESv2.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>libGLESv2.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
<ContentWithTargetPath Include="CefSharp\widevinecdmadapter.dll">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<TargetPath>widevinecdmadapter.dll</TargetPath>
|
||||
</ContentWithTargetPath>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
113
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/RequestHandler.cs
Normal file
113
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/RequestHandler.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright © 2010-2017 The CefSharp Authors. All rights reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using CefSharp;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
public class RequestHandler : IRequestHandler
|
||||
{
|
||||
bool IRequestHandler.OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IRequest request, bool isRedirect)
|
||||
{
|
||||
return request.TransitionType != TransitionType.Explicit;
|
||||
}
|
||||
|
||||
bool IRequestHandler.OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
|
||||
{
|
||||
return OnOpenUrlFromTab(browserControl, browser, frame, targetUrl, targetDisposition, userGesture);
|
||||
}
|
||||
|
||||
bool IRequestHandler.OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode,
|
||||
string requestUrl, ISslInfo sslInfo, IRequestCallback callback)
|
||||
{
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
void IRequestHandler.OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath)
|
||||
{
|
||||
}
|
||||
|
||||
CefReturnValue IRequestHandler.OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IRequest request, IRequestCallback callback)
|
||||
{
|
||||
return CefReturnValue.Continue;
|
||||
}
|
||||
|
||||
bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback)
|
||||
{
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IRequestHandler.OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy,
|
||||
string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
|
||||
{
|
||||
//NOTE: If you do not wish to implement this method returning false is the default behaviour
|
||||
// We also suggest you explicitly Dispose of the callback as it wraps an unmanaged resource.
|
||||
|
||||
return OnSelectClientCertificate(browserControl, browser, isProxy, host, port, certificates, callback);
|
||||
}
|
||||
|
||||
void IRequestHandler.OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser,
|
||||
CefTerminationStatus status)
|
||||
{
|
||||
}
|
||||
|
||||
bool IRequestHandler.OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl,
|
||||
long newSize, IRequestCallback callback)
|
||||
{
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
|
||||
void IRequestHandler.OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IRequest request, IResponse response, ref string newUrl)
|
||||
{
|
||||
}
|
||||
|
||||
bool IRequestHandler.OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void IRequestHandler.OnRenderViewReady(IWebBrowser browserControl, IBrowser browser)
|
||||
{
|
||||
}
|
||||
|
||||
bool IRequestHandler.OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IRequest request, IResponse response)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser,
|
||||
IFrame frame, IRequest request, IResponse response)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
void IRequestHandler.OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength)
|
||||
{
|
||||
}
|
||||
|
||||
protected virtual bool OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame,
|
||||
string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy,
|
||||
string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback)
|
||||
{
|
||||
callback.Dispose();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
27
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/UrlHelper.cs
Normal file
27
QuickLook.Plugin/QuickLook.Plugin.HtmlViewer/UrlHelper.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
internal static class UrlHelper
|
||||
{
|
||||
internal static string FilePathToFileUrl(string filePath)
|
||||
{
|
||||
var uri = new StringBuilder();
|
||||
foreach (var v in filePath)
|
||||
if (v >= 'a' && v <= 'z' || v >= 'A' && v <= 'Z' || v >= '0' && v <= '9' ||
|
||||
v == '+' || v == '/' || v == ':' || v == '.' || v == '-' || v == '_' || v == '~' ||
|
||||
v > '\xFF')
|
||||
uri.Append(v);
|
||||
else if (v == Path.DirectorySeparatorChar || v == Path.AltDirectorySeparatorChar)
|
||||
uri.Append('/');
|
||||
else
|
||||
uri.Append($"%{(int) v:X2}");
|
||||
if (uri.Length >= 2 && uri[0] == '/' && uri[1] == '/') // UNC path
|
||||
uri.Insert(0, "file:");
|
||||
else
|
||||
uri.Insert(0, "file:///");
|
||||
return uri.ToString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +1,13 @@
|
||||
<UserControl x:Class="QuickLook.Plugin.HtmlViewer.WebpagePanel"
|
||||
<UserControl x:Class="QuickLook.Plugin.HtmlViewer.WebkitPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:QuickLook.Plugin.HtmlViewer"
|
||||
xmlns:cef="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="300" d:DesignWidth="300">
|
||||
<Grid>
|
||||
<local:WpfWebBrowserWrapper x:Name="browser" Zoom="200" />
|
||||
<cef:ChromiumWebBrowser x:Name="browser" />
|
||||
</Grid>
|
||||
</UserControl>
|
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using CefSharp;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for UserControl1.xaml
|
||||
/// </summary>
|
||||
public partial class WebkitPanel : UserControl, IDisposable
|
||||
{
|
||||
private readonly string _cefPath =
|
||||
Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location));
|
||||
|
||||
public WebkitPanel()
|
||||
{
|
||||
var libraryLoader = new CefLibraryHandle(Path.Combine(_cefPath, "libcef.dll"));
|
||||
|
||||
if (!Cef.IsInitialized)
|
||||
Cef.Initialize(new CefSettings
|
||||
{
|
||||
BrowserSubprocessPath = Path.Combine(_cefPath, "CefSharp.BrowserSubprocess.exe"),
|
||||
LocalesDirPath = Path.Combine(_cefPath, "locales"),
|
||||
ResourcesDirPath = _cefPath,
|
||||
LogSeverity = LogSeverity.Disable,
|
||||
CefCommandLineArgs = {new KeyValuePair<string, string>("disable-gpu", "1")}
|
||||
});
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Application.Current.Exit += (sender, e) => Cef.Shutdown();
|
||||
|
||||
browser.RequestHandler = new RequestHandler();
|
||||
browser.MenuHandler = new MenuHandler();
|
||||
browser.JsDialogHandler = new JsDialogHandler();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
browser?.Dispose();
|
||||
}
|
||||
|
||||
public void Navigate(string path)
|
||||
{
|
||||
if (Path.IsPathRooted(path))
|
||||
path = UrlHelper.FilePathToFileUrl(path);
|
||||
|
||||
browser.IsBrowserInitializedChanged += (sender, e) => browser.Load(path);
|
||||
}
|
||||
|
||||
public void LoadHtml(string html, string path)
|
||||
{
|
||||
if (Path.IsPathRooted(path))
|
||||
path = UrlHelper.FilePathToFileUrl(path);
|
||||
|
||||
browser.IsBrowserInitializedChanged += (sender, e) => browser.LoadHtml(html, path);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,42 +0,0 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for UserControl1.xaml
|
||||
/// </summary>
|
||||
public partial class WebpagePanel : UserControl, IDisposable
|
||||
{
|
||||
public WebpagePanel()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
Helper.SetBrowserFeatureControl();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
browser?.Dispose();
|
||||
browser = null;
|
||||
}
|
||||
|
||||
public void Navigate(string path)
|
||||
{
|
||||
if (Path.IsPathRooted(path))
|
||||
path = Helper.FilePathToFileUrl(path);
|
||||
|
||||
browser.Dispatcher.Invoke(() => { browser.Navigate(path); }, DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
public void LoadHtml(string html)
|
||||
{
|
||||
var s = new MemoryStream(Encoding.UTF8.GetBytes(html ?? ""));
|
||||
|
||||
browser.Dispatcher.Invoke(() => { browser.Navigate(s); }, DispatcherPriority.Loaded);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,230 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Navigation;
|
||||
using SHDocVw;
|
||||
using HorizontalAlignment = System.Windows.HorizontalAlignment;
|
||||
using WebBrowser = System.Windows.Controls.WebBrowser;
|
||||
|
||||
namespace QuickLook.Plugin.HtmlViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Class wraps a Browser (which itself is a bad designed WPF control) and presents itself as
|
||||
/// a better designed WPF control. For example provides a bindable source property or commands.
|
||||
/// </summary>
|
||||
public class WpfWebBrowserWrapper : ContentControl, IDisposable
|
||||
{
|
||||
private static readonly Guid SidSWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
|
||||
|
||||
private WebBrowser _innerBrowser;
|
||||
private bool _loaded;
|
||||
private int _zoom;
|
||||
|
||||
public WpfWebBrowserWrapper()
|
||||
{
|
||||
_innerBrowser = new WebBrowser
|
||||
{
|
||||
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||
VerticalAlignment = VerticalAlignment.Stretch
|
||||
};
|
||||
|
||||
Content = _innerBrowser;
|
||||
_innerBrowser.Navigated += InnerBrowserNavigated;
|
||||
_innerBrowser.Navigating += InnerBrowserNavigating;
|
||||
_innerBrowser.LoadCompleted += InnerBrowserLoadCompleted;
|
||||
_innerBrowser.Loaded += InnerBrowserLoaded;
|
||||
_innerBrowser.SizeChanged += InnerBrowserSizeChanged;
|
||||
}
|
||||
|
||||
public string Url { get; private set; }
|
||||
|
||||
public int Zoom
|
||||
{
|
||||
get => _zoom;
|
||||
set
|
||||
{
|
||||
_zoom = value;
|
||||
ApplyZoom();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// gets the browser control's underlying activeXcontrol. Ready only from within Loaded-event but before loaded Document!
|
||||
// do not use prior loaded event.
|
||||
public InternetExplorer ActiveXControl
|
||||
{
|
||||
get
|
||||
{
|
||||
// this is a brilliant way to access the WebBrowserObject prior to displaying the actual document (eg. Document property)
|
||||
var fiComWebBrowser =
|
||||
typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (fiComWebBrowser == null) return null;
|
||||
var objComWebBrowser = fiComWebBrowser.GetValue(_innerBrowser);
|
||||
return objComWebBrowser as InternetExplorer;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_innerBrowser.Source = null;
|
||||
_innerBrowser.Dispose();
|
||||
_innerBrowser = null;
|
||||
Content = null;
|
||||
}
|
||||
|
||||
private void InnerBrowserSizeChanged(object sender, SizeChangedEventArgs e)
|
||||
{
|
||||
ApplyZoom();
|
||||
}
|
||||
|
||||
private void InnerBrowserLoaded(object sender, EventArgs e)
|
||||
{
|
||||
// make browser control not silent: allow HTTP-Auth-dialogs. Requery command availability
|
||||
var ie = ActiveXControl;
|
||||
ie.Silent = true;
|
||||
}
|
||||
|
||||
// called when the loading of a web page is done
|
||||
private void InnerBrowserLoadCompleted(object sender, NavigationEventArgs e)
|
||||
{
|
||||
ApplyZoom(); // apply later and not only at changed event, since only works if browser is rendered.
|
||||
}
|
||||
|
||||
// called when the browser started to load and retrieve data.
|
||||
private void InnerBrowserNavigating(object sender, NavigatingCancelEventArgs e)
|
||||
{
|
||||
if (_loaded)
|
||||
e.Cancel = true;
|
||||
_loaded = true;
|
||||
}
|
||||
|
||||
// re query the commands once done navigating.
|
||||
private void InnerBrowserNavigated(object sender, NavigationEventArgs e)
|
||||
{
|
||||
RegisterWindowErrorHanlder_();
|
||||
}
|
||||
|
||||
public void Navigate(string uri)
|
||||
{
|
||||
Url = uri;
|
||||
|
||||
if (_innerBrowser == null)
|
||||
return;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(uri) && Uri.IsWellFormedUriString(uri, UriKind.Absolute))
|
||||
try
|
||||
{
|
||||
_innerBrowser.Source = new Uri(uri);
|
||||
}
|
||||
catch (UriFormatException)
|
||||
{
|
||||
// just don't crash because of a malformed url
|
||||
}
|
||||
else
|
||||
_innerBrowser.Source = null;
|
||||
}
|
||||
|
||||
public void Navigate(Stream stream)
|
||||
{
|
||||
if (_innerBrowser == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
_innerBrowser.NavigateToStream(stream);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
// register script errors handler on DOM - document.window
|
||||
private void RegisterWindowErrorHanlder_()
|
||||
{
|
||||
object parwin = ((dynamic) _innerBrowser.Document).parentWindow;
|
||||
var cookie = new AxHost.ConnectionPointCookie(parwin, new HtmlWindowEvents2Impl(this),
|
||||
typeof(IIntHTMLWindowEvents2));
|
||||
// MemoryLEAK? No: cookie has a Finalize() to Disconnect istelf. We'll rely on that. If disconnected too early,
|
||||
// though (eg. in LoadCompleted-event) scripts continue to run and can cause error messages to appear again.
|
||||
// --> forget cookie and be happy.
|
||||
}
|
||||
|
||||
private void ApplyZoom()
|
||||
{
|
||||
if (_innerBrowser == null || !_innerBrowser.IsLoaded)
|
||||
return;
|
||||
|
||||
// grab a handle to the underlying ActiveX object
|
||||
IServiceProvider serviceProvider = null;
|
||||
if (_innerBrowser.Document != null)
|
||||
serviceProvider = (IServiceProvider) _innerBrowser.Document;
|
||||
if (serviceProvider == null)
|
||||
return;
|
||||
|
||||
var serviceGuid = SidSWebBrowserApp;
|
||||
var iid = typeof(IWebBrowser2).GUID;
|
||||
var browserInst =
|
||||
(IWebBrowser2) serviceProvider.QueryService(ref serviceGuid, ref iid);
|
||||
|
||||
try
|
||||
{
|
||||
object zoomPercObj = _zoom;
|
||||
// send the zoom command to the ActiveX object
|
||||
browserInst.ExecWB(OLECMDID.OLECMDID_OPTICAL_ZOOM,
|
||||
OLECMDEXECOPT.OLECMDEXECOPT_DONTPROMPTUSER,
|
||||
ref zoomPercObj,
|
||||
IntPtr.Zero);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore this dynamic call if it fails.
|
||||
}
|
||||
}
|
||||
|
||||
// needed to implement the Event for script errors
|
||||
[Guid("3050f625-98b5-11cf-bb82-00aa00bdce0b")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
|
||||
[TypeLibType(TypeLibTypeFlags.FHidden)]
|
||||
[ComImport]
|
||||
private interface IIntHTMLWindowEvents2
|
||||
{
|
||||
[DispId(1002)]
|
||||
bool onerror(string description, string url, int line);
|
||||
}
|
||||
|
||||
// needed to implement the Event for script errors
|
||||
private class HtmlWindowEvents2Impl : IIntHTMLWindowEvents2
|
||||
{
|
||||
private readonly WpfWebBrowserWrapper _control;
|
||||
|
||||
public HtmlWindowEvents2Impl(WpfWebBrowserWrapper control)
|
||||
{
|
||||
_control = control;
|
||||
}
|
||||
|
||||
// implementation of the onerror Javascript error. Return true to indicate a "Handled" state.
|
||||
public bool onerror(string description, string urlString, int line)
|
||||
{
|
||||
Debug.WriteLine(description + "@" + urlString + ": " + line);
|
||||
// Handled:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Needed to expose the WebBrowser's underlying ActiveX control for zoom functionality
|
||||
[ComImport]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
|
||||
internal interface IServiceProvider
|
||||
{
|
||||
[return: MarshalAs(UnmanagedType.IUnknown)]
|
||||
object QueryService(ref Guid guidService, ref Guid riid);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,17 +1,16 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
using QuickLook.Plugin.HtmlViewer;
|
||||
|
||||
namespace QuickLook.Plugin.MarkdownViewer
|
||||
{
|
||||
public class Plugin : IViewer
|
||||
{
|
||||
private WebpagePanel _panel;
|
||||
private WebkitPanel _panel;
|
||||
|
||||
public int Priority => int.MaxValue;
|
||||
public bool AllowsTransparency => false;
|
||||
public bool AllowsTransparency => true;
|
||||
|
||||
public bool CanHandle(string path)
|
||||
{
|
||||
@@ -21,7 +20,6 @@ namespace QuickLook.Plugin.MarkdownViewer
|
||||
switch (Path.GetExtension(path).ToLower())
|
||||
{
|
||||
case ".md":
|
||||
case ".rmd":
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -38,12 +36,13 @@ namespace QuickLook.Plugin.MarkdownViewer
|
||||
|
||||
public void View(string path, ContextObject context)
|
||||
{
|
||||
_panel = new WebpagePanel();
|
||||
_panel = new WebkitPanel();
|
||||
context.ViewerContent = _panel;
|
||||
context.Title = Path.GetFileName(path);
|
||||
|
||||
_panel.LoadHtml(GenerateMarkdownHtml(path));
|
||||
_panel.Dispatcher.Invoke(() => { context.IsBusy = false; }, DispatcherPriority.Loaded);
|
||||
_panel.LoadHtml(GenerateMarkdownHtml(path), path);
|
||||
|
||||
context.IsBusy = false;
|
||||
}
|
||||
|
||||
public void Cleanup()
|
||||
|
Reference in New Issue
Block a user