Merge branch 'master' into onovotny/add-strongname
This commit is contained in:
Коммит
212304df2c
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
|
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
|
||||||
|
|
||||||
|
@ -194,6 +195,14 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
/// <see cref="WebViewControlSettings.IsScriptNotifyAllowed" />
|
/// <see cref="WebViewControlSettings.IsScriptNotifyAllowed" />
|
||||||
bool IsScriptNotifyAllowed { get; set; }
|
bool IsScriptNotifyAllowed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a partition for this process.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The partition of this process.</value>
|
||||||
|
/// <remarks>Value can be set prior to the component being initialized.</remarks>
|
||||||
|
/// <see cref="WebViewControlProcessOptions.Partition"/>
|
||||||
|
string Partition { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="WebViewControlProcess"/> that the control is hosted in.
|
/// Gets the <see cref="WebViewControlProcess"/> that the control is hosted in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -224,6 +233,12 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
/// <value>The version of EDGEHTML.DLL used by <see cref="IWebView" />.</value>
|
/// <value>The version of EDGEHTML.DLL used by <see cref="IWebView" />.</value>
|
||||||
Version Version { get; }
|
Version Version { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the script to be loaded before any others on the page.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="script">The script.</param>
|
||||||
|
void AddPreLoadedScript(string script);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes this instance.
|
/// Closes this instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -337,6 +352,23 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
/// navigation has completed.
|
/// navigation has completed.
|
||||||
void Navigate(string source);
|
void Navigate(string source);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Navigates the web view with the URI with a HTTP request and HTTP headers.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="requestUri">The Uniform Resource Identifier (URI) to send the request.</param>
|
||||||
|
/// <param name="httpMethod">The HTTP method of the request.</param>
|
||||||
|
/// <param name="content">Optional content to send with the request.</param>
|
||||||
|
/// <param name="headers">Optional headers to send with the request.</param>
|
||||||
|
/// <remarks>
|
||||||
|
/// This method only supports <see cref="HttpMethod.Get"/> and <see cref="HttpMethod.Post"/> for the <paramref name="httpMethod"/> parameter.
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="Windows.Web.UI.Interop.WebViewControl.NavigateWithHttpRequestMessage"/>
|
||||||
|
void Navigate(
|
||||||
|
Uri requestUri,
|
||||||
|
HttpMethod httpMethod,
|
||||||
|
string content = null,
|
||||||
|
IEnumerable<KeyValuePair<string, string>> headers = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the specified HTML content relative to the location of the current executable.
|
/// Loads the specified HTML content relative to the location of the current executable.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -345,6 +377,13 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
/// navigation has completed.
|
/// navigation has completed.
|
||||||
void NavigateToLocal(string relativePath);
|
void NavigateToLocal(string relativePath);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Loads local web content at the specified Uniform Resource Identifier (URI) using an <see cref="IUriToStreamResolver"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="relativePath">A path identifying the local HTML content to load.</param>
|
||||||
|
/// <param name="streamResolver">A <see cref="IUriToStreamResolver"/> instance that converts a Uniform Resource Identifier (URI) into a stream to load.</param>
|
||||||
|
void NavigateToLocalStreamUri(Uri relativePath, IUriToStreamResolver streamResolver);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Loads the specified HTML content as a new document.
|
/// Loads the specified HTML content as a new document.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -370,4 +409,4 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Stop", Justification = "Method exposed in WinRT type")]
|
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Stop", Justification = "Method exposed in WinRT type")]
|
||||||
void Stop();
|
void Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Foundation;
|
||||||
|
using Windows.Storage.Streams;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// An adapter converting <see cref="IUriToStreamResolver"/> to <see cref="Windows.Web.IUriToStreamResolver"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal sealed class GenericUriToStreamResolver : Windows.Web.IUriToStreamResolver, IUriToStreamResolver
|
||||||
|
{
|
||||||
|
private readonly IUriToStreamResolver _streamResolver;
|
||||||
|
|
||||||
|
public GenericUriToStreamResolver(IUriToStreamResolver streamResolver)
|
||||||
|
{
|
||||||
|
_streamResolver = streamResolver ?? throw new ArgumentNullException(nameof(streamResolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream UriToStream(Uri uri)
|
||||||
|
{
|
||||||
|
return _streamResolver.UriToStream(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
|
||||||
|
{
|
||||||
|
var streamOp = UriToStream(uri);
|
||||||
|
if (streamOp == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult(streamOp.AsInputStream()).AsAsyncOperation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides a method to translate a Uniform Resource I (URI) to a <see cref="Stream"/> for use by the <see cref="IWebView.NavigateToLocal(string)"/> method.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="Windows.Web.IUriToStreamResolver"/>
|
||||||
|
public interface IUriToStreamResolver
|
||||||
|
{
|
||||||
|
Stream UriToStream(Uri uri);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,63 +1,88 @@
|
||||||
// Licensed to the .NET Foundation under one or more agreements.
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||||
// The .NET Foundation licenses this file to you under the MIT license.
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Toolkit.Win32.UI.Controls.Interop.Win32;
|
using Microsoft.Toolkit.Win32.UI.Controls.Interop.Win32;
|
||||||
using Windows.Foundation;
|
|
||||||
using Windows.Storage.Streams;
|
|
||||||
using Windows.Web;
|
|
||||||
|
|
||||||
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
{
|
{
|
||||||
internal sealed class UriToLocalStreamResolver : IUriToStreamResolver
|
[Obsolete("Use NavigateToLocalStreamUri(Uri, IUriToStreamResolver) instead")]
|
||||||
|
internal class UriToLocalStreamResolver : IUriToStreamResolver
|
||||||
{
|
{
|
||||||
public IAsyncOperation<IInputStream> UriToStreamAsync(Uri uri)
|
private readonly string _path;
|
||||||
|
|
||||||
|
public UriToLocalStreamResolver()
|
||||||
|
#pragma warning disable SA1129 // Do not use default value type constructor
|
||||||
|
: this(Path.GetDirectoryName(UnsafeNativeMethods.GetModuleFileName(new HandleRef())))
|
||||||
|
#pragma warning restore SA1129 // Do not use default value type constructor
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected UriToLocalStreamResolver(string path)
|
||||||
|
{
|
||||||
|
_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Stream UriToStream(Uri uri)
|
||||||
|
{
|
||||||
|
var fullPath = ConvertToPath(uri);
|
||||||
|
|
||||||
|
// TODO: Make this proper async all the way through
|
||||||
|
#pragma warning disable SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}'
|
||||||
|
return File.Open(fullPath, FileMode.Open, FileAccess.Read);
|
||||||
|
#pragma warning restore SCS0018 // Path traversal: injection possible in {1} argument passed to '{0}'
|
||||||
|
}
|
||||||
|
|
||||||
|
private string ConvertToPath(Uri uri)
|
||||||
{
|
{
|
||||||
if (uri == null)
|
if (uri == null)
|
||||||
{
|
{
|
||||||
throw new ArgumentNullException(nameof(uri));
|
throw new ArgumentNullException(nameof(uri));
|
||||||
}
|
}
|
||||||
|
|
||||||
var path = uri.AbsolutePath;
|
// The incoming URI will be in the form of
|
||||||
return GetContentAsync(path).AsAsyncOperation();
|
// ms-local-stream://microsoft.win32webviewhost_xxxxxxxx_yyyyyyyyyyyyyy/content.htm
|
||||||
}
|
// We are only interested in the items after the application identity (x) and guid (y), e.g. "/content.htm"
|
||||||
|
// Since we must not read content from web view host
|
||||||
|
var path = UriHelper.RelativeUriToString(uri);
|
||||||
|
|
||||||
private bool IsRelative(string path)
|
if (string.IsNullOrEmpty(path))
|
||||||
{
|
|
||||||
return path != null && path[0] == '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly Lazy<string> BasePath = new Lazy<string>(() =>
|
|
||||||
#pragma warning disable SA1129 // Do not use default value type constructor
|
|
||||||
Path.GetDirectoryName(UnsafeNativeMethods.GetModuleFileName(new HandleRef())));
|
|
||||||
#pragma warning restore SA1129 // Do not use default value type constructor
|
|
||||||
|
|
||||||
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
|
|
||||||
private async Task<IInputStream> GetContentAsync(string path)
|
|
||||||
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
|
|
||||||
{
|
|
||||||
if (IsRelative(path))
|
|
||||||
{
|
{
|
||||||
// Clean up path
|
throw new ArgumentException(DesignerUI.E_WEBVIEW_INVALID_URI, nameof(uri));
|
||||||
while (path[0] == '/')
|
|
||||||
{
|
|
||||||
path = path.TrimStart('/');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translate forward slash into backslash for use in file paths
|
|
||||||
path = path.Replace(@"/", @"\");
|
|
||||||
|
|
||||||
var fullPath = Path.Combine(BasePath.Value, path);
|
|
||||||
|
|
||||||
// TODO: Make this proper async all the way through
|
|
||||||
return File.Open(fullPath, FileMode.Open, FileAccess.Read).AsInputStream();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new NotSupportedException();
|
// Clean up path
|
||||||
|
path = path.TrimStart(Path.AltDirectorySeparatorChar);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
// After stripping away the separator chars, we have nothing left
|
||||||
|
// e.g. uri was "ms-local-stream://microsoft.win32webviewhost_xxxxxxxx_yyyyyyyyyyyyyy/"
|
||||||
|
throw new ArgumentException(DesignerUI.E_WEBVIEW_INVALID_URI, nameof(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This should never be the case, but guard just in case
|
||||||
|
if (PathUtilities.IsAbsolute(path))
|
||||||
|
{
|
||||||
|
throw new ArgumentException(DesignerUI.E_WEBVIEW_INVALID_URI, nameof(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate forward slash into backslash for use in file paths
|
||||||
|
path = path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
|
||||||
|
|
||||||
|
var fullPath = Path.Combine(_path, path);
|
||||||
|
|
||||||
|
// At this point there should be no relative paths (e.g. ../../file.htm)
|
||||||
|
// This check is the last guard against potential path/directory traversal attack
|
||||||
|
if (fullPath.IndexOfAny(Path.GetInvalidPathChars()) >= 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
return fullPath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -10,7 +10,7 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
/// <seealso cref="Windows.Web.UI.Interop.WebViewControlAcceleratorKeyPressedEventArgs"/>
|
/// <seealso cref="Windows.Web.UI.Interop.WebViewControlAcceleratorKeyPressedEventArgs"/>
|
||||||
/// <summary>This class provides information for the <see cref="IWebView.AcceleratorKeyPressed"/> event.</summary>
|
/// <summary>This class provides information for the <see cref="IWebView.AcceleratorKeyPressed"/> event.</summary>
|
||||||
/// <seealso cref="System.EventArgs" />
|
/// <seealso cref="System.EventArgs" />
|
||||||
public class WebViewControlAcceleratorKeyPressedEventArgs : EventArgs
|
public sealed class WebViewControlAcceleratorKeyPressedEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
private readonly Windows.Web.UI.Interop.WebViewControlAcceleratorKeyPressedEventArgs _args;
|
private readonly Windows.Web.UI.Interop.WebViewControlAcceleratorKeyPressedEventArgs _args;
|
||||||
|
|
|
@ -8,8 +8,9 @@ using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Windows.Foundation.Metadata;
|
||||||
using Windows.Web;
|
using Windows.Web;
|
||||||
|
using Windows.Web.Http;
|
||||||
using Windows.Web.UI;
|
using Windows.Web.UI;
|
||||||
using Windows.Web.UI.Interop;
|
using Windows.Web.UI.Interop;
|
||||||
|
|
||||||
|
@ -42,6 +43,8 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
internal sealed class WebViewControlHost : IDisposable
|
internal sealed class WebViewControlHost : IDisposable
|
||||||
{
|
{
|
||||||
|
private const string LocalContentIdentifier = "LocalContent";
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
private WebViewControl _webViewControl;
|
private WebViewControl _webViewControl;
|
||||||
|
|
||||||
|
@ -80,8 +83,12 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
|
|
||||||
internal event EventHandler<WebViewControlNavigationStartingEventArgs> FrameNavigationStarting = (sender, args) => { };
|
internal event EventHandler<WebViewControlNavigationStartingEventArgs> FrameNavigationStarting = (sender, args) => { };
|
||||||
|
|
||||||
|
internal event EventHandler<object> GotFocus = (sender, args) => { };
|
||||||
|
|
||||||
internal event EventHandler<WebViewControlLongRunningScriptDetectedEventArgs> LongRunningScriptDetected = (sender, args) => { };
|
internal event EventHandler<WebViewControlLongRunningScriptDetectedEventArgs> LongRunningScriptDetected = (sender, args) => { };
|
||||||
|
|
||||||
|
internal event EventHandler<object> LostFocus = (sender, args) => { };
|
||||||
|
|
||||||
internal event EventHandler<WebViewControlMoveFocusRequestedEventArgs> MoveFocusRequested = (sender, args) => { };
|
internal event EventHandler<WebViewControlMoveFocusRequestedEventArgs> MoveFocusRequested = (sender, args) => { };
|
||||||
|
|
||||||
internal event EventHandler<WebViewControlNavigationCompletedEventArgs> NavigationCompleted = (sender, args) => { };
|
internal event EventHandler<WebViewControlNavigationCompletedEventArgs> NavigationCompleted = (sender, args) => { };
|
||||||
|
@ -282,8 +289,42 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
set;
|
set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void AddPreLoadedScript(string script)
|
||||||
|
{
|
||||||
|
if (ApiInformation.IsMethodPresent(
|
||||||
|
"Windows.Web.UI.Interop.WebViewControl",
|
||||||
|
"AddPreLoadedScript",
|
||||||
|
1))
|
||||||
|
{
|
||||||
|
_webViewControl?.AddPreLoadedScript(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal Uri BuildStream(string contentIdentifier, string relativePath)
|
internal Uri BuildStream(string contentIdentifier, string relativePath)
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(contentIdentifier))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(contentIdentifier));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(relativePath))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(relativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not passing a relative path, the method faults. No exception is thrown, the application just fails fast
|
||||||
|
// Until that issue resolved, add our own error checking
|
||||||
|
if (PathUtilities.IsAbsolute(relativePath))
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(relativePath), DesignerUI.E_WEBVIEW_INVALID_URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The content identifier is used in conjunction with the application identity to create a guid. The
|
||||||
|
// guid is appended to the win32webviewhost identity and a ms-local-stream URI is created.
|
||||||
|
// Given a relative path of "/content.htm" the following is generated:
|
||||||
|
// ms-local-stream://microsoft.win32webviewhost_xxxxxxxxxxxxx_yyyyyyyyyyyyyyyyyyyyyyyy//content.htm
|
||||||
|
// If there is relative navigation items (e.g. "..\") they are resolved. URI will ALWAYS be relative to
|
||||||
|
// the application container, e.g. "..\..\..\..\..\..\file" will resolve to "/file"
|
||||||
return _webViewControl?.BuildLocalStreamUri(contentIdentifier, relativePath);
|
return _webViewControl?.BuildLocalStreamUri(contentIdentifier, relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,16 +529,109 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
Navigate(UriHelper.StringToUri(source));
|
Navigate(UriHelper.StringToUri(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use NavigateToLocalStreamUri(Uri, IUriToStreamResolver) instead")]
|
||||||
internal void NavigateToLocal(string relativePath)
|
internal void NavigateToLocal(string relativePath)
|
||||||
{
|
{
|
||||||
var uri = BuildStream("LocalContent", relativePath);
|
var relativeUri = UriHelper.StringToRelativeUri(relativePath);
|
||||||
var resolver = new UriToLocalStreamResolver();
|
NavigateToLocalStreamUri(relativeUri, new UriToLocalStreamResolver());
|
||||||
NavigateToLocalStreamUri(uri, resolver);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void NavigateToLocalStreamUri(Uri source, IUriToStreamResolver streamResolver)
|
internal void NavigateToLocalStreamUri(Uri relativePath, IUriToStreamResolver streamResolver)
|
||||||
{
|
{
|
||||||
_webViewControl?.NavigateToLocalStreamUri(source, streamResolver);
|
if (relativePath == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(relativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relativePath.IsAbsoluteUri)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(relativePath), DesignerUI.E_WEBVIEW_INVALID_URI);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streamResolver == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(streamResolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
Windows.Web.IUriToStreamResolver AsWindowsRuntimeUriToStreamResolver(IUriToStreamResolver streamResolverInterop)
|
||||||
|
{
|
||||||
|
// Check to see if the stream resolver is actually a wrapper of a WinRT stream resolver
|
||||||
|
if (streamResolverInterop is Windows.Web.IUriToStreamResolver streamResolverAdapter)
|
||||||
|
{
|
||||||
|
return streamResolverAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (streamResolverInterop is GenericUriToStreamResolver genericAdapter)
|
||||||
|
{
|
||||||
|
return genericAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We have an unwrapped stream resolver
|
||||||
|
return new GenericUriToStreamResolver(streamResolver);
|
||||||
|
}
|
||||||
|
|
||||||
|
var uri = BuildStream(LocalContentIdentifier, UriHelper.UriToString(relativePath));
|
||||||
|
_webViewControl?.NavigateToLocalStreamUri(uri, AsWindowsRuntimeUriToStreamResolver(streamResolver));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Navigate(
|
||||||
|
Uri requestUri,
|
||||||
|
System.Net.Http.HttpMethod method,
|
||||||
|
string content = null,
|
||||||
|
IEnumerable<KeyValuePair<string, string>> headers = null)
|
||||||
|
{
|
||||||
|
if (requestUri == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(requestUri));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(method));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a System.Net.Http.HttpMethod to Windows.Web.Http.HttpMethod
|
||||||
|
HttpMethod ToHttpMethod(System.Net.Http.HttpMethod httpMethod)
|
||||||
|
{
|
||||||
|
if (System.Net.Http.HttpMethod.Get.Equals(httpMethod))
|
||||||
|
{
|
||||||
|
return HttpMethod.Get;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (System.Net.Http.HttpMethod.Post.Equals(httpMethod))
|
||||||
|
{
|
||||||
|
return HttpMethod.Post;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For compatabilty with WebView.NavigateWithHttpRequestMessage, this only supports POST and GET
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(httpMethod));
|
||||||
|
}
|
||||||
|
|
||||||
|
var requestMessage = new HttpRequestMessage
|
||||||
|
{
|
||||||
|
RequestUri = requestUri,
|
||||||
|
Method = ToHttpMethod(method)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (content != null)
|
||||||
|
{
|
||||||
|
requestMessage.Content = new HttpStringContent(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers != null)
|
||||||
|
{
|
||||||
|
foreach (var header in headers)
|
||||||
|
{
|
||||||
|
requestMessage.Headers.Add(header);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavigateWithHttpRequestMessage(requestMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void NavigateWithHttpRequestMessage(HttpRequestMessage requestMessage)
|
||||||
|
{
|
||||||
|
_webViewControl?.NavigateWithHttpRequestMessage(requestMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <exception cref="ArgumentNullException"><paramref name="text"/> is <see langword="null"/></exception>
|
/// <exception cref="ArgumentNullException"><paramref name="text"/> is <see langword="null"/></exception>
|
||||||
|
@ -678,8 +812,19 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGotFocus(object args)
|
||||||
|
{
|
||||||
|
var handler = GotFocus;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void OnFrameNavigationStarting(IWebViewControl sender, Windows.Web.UI.WebViewControlNavigationStartingEventArgs args) => OnFrameNavigationStarting(args);
|
private void OnFrameNavigationStarting(IWebViewControl sender, Windows.Web.UI.WebViewControlNavigationStartingEventArgs args) => OnFrameNavigationStarting(args);
|
||||||
|
|
||||||
|
private void OnGotFocus(IWebViewControl sender, object args) => OnGotFocus(args);
|
||||||
|
|
||||||
private void OnLongRunningScriptDetected(WebViewControlLongRunningScriptDetectedEventArgs args)
|
private void OnLongRunningScriptDetected(WebViewControlLongRunningScriptDetectedEventArgs args)
|
||||||
{
|
{
|
||||||
var handler = LongRunningScriptDetected;
|
var handler = LongRunningScriptDetected;
|
||||||
|
@ -691,6 +836,17 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
|
|
||||||
private void OnLongRunningScriptDetected(IWebViewControl sender, Windows.Web.UI.WebViewControlLongRunningScriptDetectedEventArgs args) => OnLongRunningScriptDetected(args);
|
private void OnLongRunningScriptDetected(IWebViewControl sender, Windows.Web.UI.WebViewControlLongRunningScriptDetectedEventArgs args) => OnLongRunningScriptDetected(args);
|
||||||
|
|
||||||
|
private void OnLostFocus(object args)
|
||||||
|
{
|
||||||
|
var handler = LostFocus;
|
||||||
|
if (handler != null)
|
||||||
|
{
|
||||||
|
handler(this, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnLostFocus(IWebViewControl sender, object args) => OnLostFocus(args);
|
||||||
|
|
||||||
private void OnMoveFocusRequested(WebViewControlMoveFocusRequestedEventArgs args)
|
private void OnMoveFocusRequested(WebViewControlMoveFocusRequestedEventArgs args)
|
||||||
{
|
{
|
||||||
var handler = MoveFocusRequested;
|
var handler = MoveFocusRequested;
|
||||||
|
@ -910,6 +1066,16 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
_webViewControl.UnsafeContentWarningDisplaying += OnUnsafeContentWarningDisplaying;
|
_webViewControl.UnsafeContentWarningDisplaying += OnUnsafeContentWarningDisplaying;
|
||||||
_webViewControl.UnsupportedUriSchemeIdentified += OnUnsupportedUriSchemeIdentified;
|
_webViewControl.UnsupportedUriSchemeIdentified += OnUnsupportedUriSchemeIdentified;
|
||||||
_webViewControl.UnviewableContentIdentified += OnUnviewableContentIdentified;
|
_webViewControl.UnviewableContentIdentified += OnUnviewableContentIdentified;
|
||||||
|
|
||||||
|
if (ApiInformation.IsEventPresent("Windows.Web.UI.Interop", "GotFocus"))
|
||||||
|
{
|
||||||
|
_webViewControl.GotFocus += OnGotFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ApiInformation.IsEventPresent("Windows.Web.UI.Interop", "LostFocus"))
|
||||||
|
{
|
||||||
|
_webViewControl.LostFocus += OnLostFocus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
|
@ -948,6 +1114,16 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
_webViewControl.UnsafeContentWarningDisplaying -= OnUnsafeContentWarningDisplaying;
|
_webViewControl.UnsafeContentWarningDisplaying -= OnUnsafeContentWarningDisplaying;
|
||||||
_webViewControl.UnsupportedUriSchemeIdentified -= OnUnsupportedUriSchemeIdentified;
|
_webViewControl.UnsupportedUriSchemeIdentified -= OnUnsupportedUriSchemeIdentified;
|
||||||
_webViewControl.UnviewableContentIdentified -= OnUnviewableContentIdentified;
|
_webViewControl.UnviewableContentIdentified -= OnUnviewableContentIdentified;
|
||||||
|
|
||||||
|
if (ApiInformation.IsEventPresent("Windows.Web.UI.Interop", "GotFocus"))
|
||||||
|
{
|
||||||
|
_webViewControl.GotFocus -= OnGotFocus;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ApiInformation.IsEventPresent("Windows.Web.UI.Interop", "LostFocus"))
|
||||||
|
{
|
||||||
|
_webViewControl.LostFocus -= OnLostFocus;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnsubscribeProcessExited()
|
private void UnsubscribeProcessExited()
|
||||||
|
|
|
@ -7,6 +7,7 @@ using System.Security;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
using Windows.Foundation;
|
using Windows.Foundation;
|
||||||
|
using Windows.Foundation.Metadata;
|
||||||
using Windows.Web.UI.Interop;
|
using Windows.Web.UI.Interop;
|
||||||
|
|
||||||
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
|
@ -14,7 +15,7 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A proxy for <see cref="Windows.Web.UI.Interop.WebViewControlProcess"/>.
|
/// A proxy for <see cref="Windows.Web.UI.Interop.WebViewControlProcess"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class WebViewControlProcess
|
public sealed class WebViewControlProcess
|
||||||
{
|
{
|
||||||
[SecurityCritical]
|
[SecurityCritical]
|
||||||
private readonly Windows.Web.UI.Interop.WebViewControlProcess _process;
|
private readonly Windows.Web.UI.Interop.WebViewControlProcess _process;
|
||||||
|
@ -60,12 +61,50 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
/// <value><c>true</c> if this instance can access the private network; otherwise, <c>false</c>.</value>
|
/// <value><c>true</c> if this instance can access the private network; otherwise, <c>false</c>.</value>
|
||||||
public bool IsPrivateNetworkClientServerCapabilityEnabled => _process.IsPrivateNetworkClientServerCapabilityEnabled;
|
public bool IsPrivateNetworkClientServerCapabilityEnabled => _process.IsPrivateNetworkClientServerCapabilityEnabled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating the partition of the web view.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The partition.</value>
|
||||||
|
public string Partition
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (ApiInformation.IsPropertyPresent(
|
||||||
|
"Windows.Web.UI.Interop.WebViewControlProcessOptions",
|
||||||
|
"Partition"))
|
||||||
|
{
|
||||||
|
return _process.Partition;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the process identifier (PID) of the underlying WWAHost.
|
/// Gets the process identifier (PID) of the underlying WWAHost.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The process identifier (PID).</value>
|
/// <value>The process identifier (PID).</value>
|
||||||
public uint ProcessId => _process.ProcessId;
|
public uint ProcessId => _process.ProcessId;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the user agent of the underlying web view
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The user agent.</value>
|
||||||
|
public string UserAgent
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (ApiInformation.IsPropertyPresent(
|
||||||
|
"Windows.Web.UI.Interop.WebViewControlProcessOptions",
|
||||||
|
"UserAgent"))
|
||||||
|
{
|
||||||
|
return _process.UserAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Performs an implicit conversion from <see cref="Windows.Web.UI.Interop.WebViewControlProcess"/> to <see cref="WebViewControlProcess"/>.
|
/// Performs an implicit conversion from <see cref="Windows.Web.UI.Interop.WebViewControlProcess"/> to <see cref="WebViewControlProcess"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using Windows.Foundation.Metadata;
|
||||||
|
|
||||||
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
{
|
{
|
||||||
|
@ -13,7 +14,7 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
/// Copy from <see cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> to avoid requirement to link Windows.winmd.
|
/// Copy from <see cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> to avoid requirement to link Windows.winmd.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <seealso cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/>
|
/// <seealso cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/>
|
||||||
public class WebViewControlProcessOptions
|
public sealed class WebViewControlProcessOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the enterprise identifier for apps that are WIP-enabled.
|
/// Gets or sets the enterprise identifier for apps that are WIP-enabled.
|
||||||
|
@ -21,37 +22,83 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
/// <value>The enterprise identifier.</value>
|
/// <value>The enterprise identifier.</value>
|
||||||
public string EnterpriseId { get; set; }
|
public string EnterpriseId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the partition for the web view.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The partition.</value>
|
||||||
|
public string Partition { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the private network client server capability.
|
/// Gets or sets the private network client server capability.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <value>The private network client server capability.</value>
|
/// <value>The private network client server capability.</value>
|
||||||
public WebViewControlProcessCapabilityState PrivateNetworkClientServerCapability { get; set; }
|
public WebViewControlProcessCapabilityState PrivateNetworkClientServerCapability { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the user agent.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The user agent.</value>
|
||||||
|
public string UserAgent { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="WebViewControlProcessOptions"/> class.
|
/// Initializes a new instance of the <see cref="WebViewControlProcessOptions"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public WebViewControlProcessOptions()
|
public WebViewControlProcessOptions()
|
||||||
{
|
{
|
||||||
EnterpriseId = string.Empty;
|
EnterpriseId = string.Empty;
|
||||||
|
Partition = string.Empty;
|
||||||
|
UserAgent = string.Empty;
|
||||||
PrivateNetworkClientServerCapability = WebViewControlProcessCapabilityState.Default;
|
PrivateNetworkClientServerCapability = WebViewControlProcessCapabilityState.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs an implicit conversion from <see cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> to <see cref="WebViewControlProcessOptions"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The options.</param>
|
||||||
|
/// <returns>The result of the conversion.</returns>
|
||||||
|
public static implicit operator WebViewControlProcessOptions(Windows.Web.UI.Interop.WebViewControlProcessOptions options) => ToWinRtWebViewControlProcessOptions(options);
|
||||||
|
|
||||||
|
public static Windows.Web.UI.Interop.WebViewControlProcessOptions ToWinRtWebViewControlProcessOptions(WebViewControlProcessOptions options)
|
||||||
|
{
|
||||||
|
var retval = new Windows.Web.UI.Interop.WebViewControlProcessOptions();
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(options?.EnterpriseId) && !StringComparer.InvariantCulture.Equals(retval.EnterpriseId, options?.EnterpriseId))
|
||||||
|
{
|
||||||
|
retval.EnterpriseId = options.EnterpriseId;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ApiInformation.IsPropertyPresent(
|
||||||
|
"Windows.Web.UI.Interop.WebViewControlProcessOptions",
|
||||||
|
"Partition"))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(options?.Partition))
|
||||||
|
{
|
||||||
|
retval.Partition = options.Partition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
retval.PrivateNetworkClientServerCapability = (Windows.Web.UI.Interop.WebViewControlProcessCapabilityState)options?.PrivateNetworkClientServerCapability;
|
||||||
|
|
||||||
|
if (ApiInformation.IsPropertyPresent(
|
||||||
|
"Windows.Web.UI.Interop.WebViewControlProcessOptions",
|
||||||
|
"UserAgent"))
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(options?.UserAgent))
|
||||||
|
{
|
||||||
|
retval.UserAgent = options.UserAgent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts this instance to a <seealso cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> instance.
|
/// Converts this instance to a <seealso cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>A <seealso cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> instance.</returns>
|
/// <returns>A <seealso cref="Windows.Web.UI.Interop.WebViewControlProcessOptions"/> instance.</returns>
|
||||||
internal Windows.Web.UI.Interop.WebViewControlProcessOptions ToWinRtWebViewControlProcessOptions()
|
internal Windows.Web.UI.Interop.WebViewControlProcessOptions ToWinRtWebViewControlProcessOptions()
|
||||||
{
|
{
|
||||||
var retval = new Windows.Web.UI.Interop.WebViewControlProcessOptions();
|
return ToWinRtWebViewControlProcessOptions(this);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(EnterpriseId) && !StringComparer.InvariantCulture.Equals(retval.EnterpriseId, EnterpriseId))
|
|
||||||
{
|
|
||||||
retval.EnterpriseId = EnterpriseId;
|
|
||||||
}
|
|
||||||
|
|
||||||
retval.PrivateNetworkClientServerCapability = (Windows.Web.UI.Interop.WebViewControlProcessCapabilityState)PrivateNetworkClientServerCapability;
|
|
||||||
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -14,6 +14,7 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT
|
||||||
public const bool IsJavaScriptEnabled = true;
|
public const bool IsJavaScriptEnabled = true;
|
||||||
public const bool IsPrivateNetworkEnabled = false;
|
public const bool IsPrivateNetworkEnabled = false;
|
||||||
public const bool IsScriptNotifyEnabled = false;
|
public const bool IsScriptNotifyEnabled = false;
|
||||||
|
public const string Partition = "";
|
||||||
public static readonly Uri AboutBlankUri = new Uri(AboutBlank);
|
public static readonly Uri AboutBlankUri = new Uri(AboutBlank);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,9 +13,18 @@
|
||||||
|
|
||||||
<!-- Need Metadata contract 6.0 or later -->
|
<!-- Need Metadata contract 6.0 or later -->
|
||||||
<!-- First introduced in 17110: Insider Preview (Fast) -->
|
<!-- First introduced in 17110: Insider Preview (Fast) -->
|
||||||
<TargetPlatformMinVersion>10.0.17110.0</TargetPlatformMinVersion>
|
<!-- Most people will have RTM 17134: April 2018 Update -->
|
||||||
<!-- Most people will have RTM 17134: Insider Preview (Fast), Spring Creators (RS4) -->
|
<TargetPlatformMinVersion>10.0.17134.0</TargetPlatformMinVersion>
|
||||||
<TargetPlatformVersion>10.0.17134.0</TargetPlatformVersion>
|
<!--
|
||||||
|
When changing this value, ensure the SDK is installed with the build process.
|
||||||
|
Need to check several files:
|
||||||
|
- /.vsts-ci.yml
|
||||||
|
- /.vsts-pr.yml
|
||||||
|
|
||||||
|
This also needs to be installed on your local machine. Can do this with PowerShell:
|
||||||
|
./build/Install-WindowsSDKISO.ps1 17704
|
||||||
|
-->
|
||||||
|
<TargetPlatformVersion>10.0.17704.0</TargetPlatformVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
@ -32,6 +41,7 @@
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Xaml" />
|
<Reference Include="System.Xaml" />
|
||||||
<Reference Include="WindowsBase" />
|
<Reference Include="WindowsBase" />
|
||||||
|
<PackageReference Include="System.Net.Http" Version="4.0.0" />
|
||||||
<PackageReference Include="System.Runtime.WindowsRuntime" PrivateAssets="All">
|
<PackageReference Include="System.Runtime.WindowsRuntime" PrivateAssets="All">
|
||||||
<Version>4.0.0</Version>
|
<Version>4.0.0</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
|
{
|
||||||
|
// Contains path parsing utilities
|
||||||
|
internal static class PathUtilities
|
||||||
|
{
|
||||||
|
// true if the character is the platform directory separator character or the alternate directory separator
|
||||||
|
public static bool IsDirectorySeparator(char c) => c == Path.DirectorySeparatorChar || c == Path.AltDirectorySeparatorChar;
|
||||||
|
|
||||||
|
public static bool IsAbsolute(string path)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(path))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "C:\"
|
||||||
|
if (IsDriveRootedAbsolutePath(path))
|
||||||
|
{
|
||||||
|
// Including invalid paths (e.g. "*:\")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "\\machine\share"
|
||||||
|
// Including invalid/incomplete UNC paths (e.g. "\\foo")
|
||||||
|
return path.Length >= 2 &&
|
||||||
|
IsDirectorySeparator(path[0]) &&
|
||||||
|
IsDirectorySeparator(path[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// true if given path is absolute and starts with a drive specification (e.g. "C:\"); otherwise, false.
|
||||||
|
private static bool IsDriveRootedAbsolutePath(string path)
|
||||||
|
{
|
||||||
|
return path.Length >= 3 && path[1] == Path.VolumeSeparatorChar && IsDirectorySeparator(path[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,6 +36,20 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
MAX_URL_LENGTH).ToString();
|
MAX_URL_LENGTH).ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static string RelativeUriToString(Uri uri)
|
||||||
|
{
|
||||||
|
if (uri == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new StringBuilder(
|
||||||
|
uri.GetComponents(
|
||||||
|
UriComponents.PathAndQuery,
|
||||||
|
UriFormat.SafeUnescaped),
|
||||||
|
MAX_URL_LENGTH).ToString();
|
||||||
|
}
|
||||||
|
|
||||||
internal static Uri StringToUri(string source)
|
internal static Uri StringToUri(string source)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(source))
|
if (string.IsNullOrEmpty(source))
|
||||||
|
@ -51,5 +65,21 @@ namespace Microsoft.Toolkit.Win32.UI.Controls
|
||||||
// Unrecognized URI
|
// Unrecognized URI
|
||||||
throw new ArgumentException(DesignerUI.E_WEBVIEW_INVALID_URI);
|
throw new ArgumentException(DesignerUI.E_WEBVIEW_INVALID_URI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static Uri StringToRelativeUri(string source)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(source))
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException(nameof(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Uri.TryCreate(source, UriKind.Relative, out Uri result))
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unrecognized URI
|
||||||
|
throw new ArgumentException(DesignerUI.E_WEBVIEW_INVALID_URI);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@ using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
@ -90,6 +91,12 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
typeof(WebView),
|
typeof(WebView),
|
||||||
new PropertyMetadata(WebViewDefaults.AboutBlankUri, PropertyChangedCallback));
|
new PropertyMetadata(WebViewDefaults.AboutBlankUri, PropertyChangedCallback));
|
||||||
|
|
||||||
|
private static readonly DependencyProperty PartitionProperty = DependencyProperty.Register(
|
||||||
|
nameof(Partition),
|
||||||
|
typeof(string),
|
||||||
|
typeof(WebView),
|
||||||
|
new PropertyMetadata(WebViewDefaults.Partition, PropertyChangedCallback));
|
||||||
|
|
||||||
private WebViewControlProcess _process;
|
private WebViewControlProcess _process;
|
||||||
|
|
||||||
private volatile WebViewControlHost _webViewControl;
|
private volatile WebViewControlHost _webViewControl;
|
||||||
|
@ -424,6 +431,15 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[StringResourceCategory(Constants.CategoryBehavior)]
|
||||||
|
[DefaultValue(WebViewDefaults.Partition)]
|
||||||
|
public string Partition
|
||||||
|
{
|
||||||
|
get => (string)GetValue(PartitionProperty);
|
||||||
|
set => SetValue(PartitionProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[Browsable(false)]
|
[Browsable(false)]
|
||||||
public WebViewControlProcess Process
|
public WebViewControlProcess Process
|
||||||
|
@ -475,6 +491,14 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="IWebView.AddPreLoadedScript" />
|
||||||
|
public void AddPreLoadedScript(string script)
|
||||||
|
{
|
||||||
|
VerifyAccess();
|
||||||
|
Verify.IsNotNull(_webViewControl);
|
||||||
|
_webViewControl?.AddPreLoadedScript(script);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IWebView.Close" />
|
/// <inheritdoc cref="IWebView.Close" />
|
||||||
public override void Close()
|
public override void Close()
|
||||||
{
|
{
|
||||||
|
@ -583,6 +607,26 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
|
public void Navigate(
|
||||||
|
Uri requestUri,
|
||||||
|
HttpMethod httpMethod,
|
||||||
|
string content = null,
|
||||||
|
IEnumerable<KeyValuePair<string, string>> headers = null)
|
||||||
|
{
|
||||||
|
VerifyAccess();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dispatcher.CurrentDispatcher.DoEvents();
|
||||||
|
}
|
||||||
|
while (!_initializationComplete.WaitOne(InitializationBlockingTime));
|
||||||
|
|
||||||
|
Verify.IsNotNull(_webViewControl);
|
||||||
|
_webViewControl.Navigate(requestUri, httpMethod, content, headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[Obsolete("Use NavigateToLocalStreamUri(Uri, IUriToStreamResolver) instead")]
|
||||||
public void NavigateToLocal(string relativePath)
|
public void NavigateToLocal(string relativePath)
|
||||||
{
|
{
|
||||||
VerifyAccess();
|
VerifyAccess();
|
||||||
|
@ -597,6 +641,21 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
_webViewControl.NavigateToLocal(relativePath);
|
_webViewControl.NavigateToLocal(relativePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void NavigateToLocalStreamUri(Uri relativePath, IUriToStreamResolver streamResolver)
|
||||||
|
{
|
||||||
|
VerifyAccess();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dispatcher.CurrentDispatcher.DoEvents();
|
||||||
|
}
|
||||||
|
while (!_initializationComplete.WaitOne(InitializationBlockingTime));
|
||||||
|
|
||||||
|
Verify.IsNotNull(_webViewControl);
|
||||||
|
_webViewControl.NavigateToLocalStreamUri(relativePath, streamResolver);
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void NavigateToString(string text)
|
public void NavigateToString(string text)
|
||||||
{
|
{
|
||||||
|
@ -645,13 +704,17 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
var enterpriseId = !Dispatcher.CheckAccess()
|
var enterpriseId = !Dispatcher.CheckAccess()
|
||||||
? Dispatcher.Invoke(() => EnterpriseId)
|
? Dispatcher.Invoke(() => EnterpriseId)
|
||||||
: EnterpriseId;
|
: EnterpriseId;
|
||||||
|
var partition = !Dispatcher.CheckAccess()
|
||||||
|
? Dispatcher.Invoke(() => Partition)
|
||||||
|
: Partition;
|
||||||
|
|
||||||
_process = new WebViewControlProcess(new WebViewControlProcessOptions
|
_process = new WebViewControlProcess(new WebViewControlProcessOptions
|
||||||
{
|
{
|
||||||
PrivateNetworkClientServerCapability = privateNetworkEnabled
|
PrivateNetworkClientServerCapability = privateNetworkEnabled
|
||||||
? WebViewControlProcessCapabilityState.Enabled
|
? WebViewControlProcessCapabilityState.Enabled
|
||||||
: WebViewControlProcessCapabilityState.Disabled,
|
: WebViewControlProcessCapabilityState.Disabled,
|
||||||
EnterpriseId = enterpriseId
|
EnterpriseId = enterpriseId,
|
||||||
|
Partition = partition
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,7 +733,14 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
|
|
||||||
Verify.IsNotNull(_webViewControl);
|
Verify.IsNotNull(_webViewControl);
|
||||||
|
|
||||||
UpdateSize(RenderSize);
|
if (!Dispatcher.CheckAccess())
|
||||||
|
{
|
||||||
|
Dispatcher.Invoke(() => UpdateSize(RenderSize));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateSize(RenderSize);
|
||||||
|
}
|
||||||
|
|
||||||
DestroyWindowCore(ChildWindow);
|
DestroyWindowCore(ChildWindow);
|
||||||
|
|
||||||
|
@ -825,6 +895,14 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
throw new InvalidOperationException(DesignerUI.E_CANNOT_CHANGE_AFTER_INIT);
|
throw new InvalidOperationException(DesignerUI.E_CANNOT_CHANGE_AFTER_INIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (dependencyPropertyChangedEventArgs.Property.Name == nameof(Partition))
|
||||||
|
{
|
||||||
|
Verify.IsFalse(wv.WebViewControlInitialized);
|
||||||
|
if (wv.WebViewControlInitialized)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(DesignerUI.E_CANNOT_CHANGE_AFTER_INIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -900,6 +978,11 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGotFocus(object sender, object args)
|
||||||
|
{
|
||||||
|
OnGotFocus(new RoutedEventArgs(GotFocusEvent));
|
||||||
|
}
|
||||||
|
|
||||||
private void OnLongRunningScriptDetected(object sender, WebViewControlLongRunningScriptDetectedEventArgs args)
|
private void OnLongRunningScriptDetected(object sender, WebViewControlLongRunningScriptDetectedEventArgs args)
|
||||||
{
|
{
|
||||||
var handler = LongRunningScriptDetected;
|
var handler = LongRunningScriptDetected;
|
||||||
|
@ -909,6 +992,11 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnLostFocus(object sender, object args)
|
||||||
|
{
|
||||||
|
OnLostFocus(new RoutedEventArgs(GotFocusEvent));
|
||||||
|
}
|
||||||
|
|
||||||
private void OnMoveFocusRequested(object sender, WebViewControlMoveFocusRequestedEventArgs args)
|
private void OnMoveFocusRequested(object sender, WebViewControlMoveFocusRequestedEventArgs args)
|
||||||
{
|
{
|
||||||
var handler = MoveFocusRequested;
|
var handler = MoveFocusRequested;
|
||||||
|
@ -1012,7 +1100,9 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
_webViewControl.FrameDOMContentLoaded += OnFrameDOMContentLoaded;
|
_webViewControl.FrameDOMContentLoaded += OnFrameDOMContentLoaded;
|
||||||
_webViewControl.FrameNavigationCompleted += OnFrameNavigationCompleted;
|
_webViewControl.FrameNavigationCompleted += OnFrameNavigationCompleted;
|
||||||
_webViewControl.FrameNavigationStarting += OnFrameNavigationStarting;
|
_webViewControl.FrameNavigationStarting += OnFrameNavigationStarting;
|
||||||
|
_webViewControl.GotFocus += OnGotFocus;
|
||||||
_webViewControl.LongRunningScriptDetected += OnLongRunningScriptDetected;
|
_webViewControl.LongRunningScriptDetected += OnLongRunningScriptDetected;
|
||||||
|
_webViewControl.LostFocus += OnLostFocus;
|
||||||
_webViewControl.MoveFocusRequested += OnMoveFocusRequested;
|
_webViewControl.MoveFocusRequested += OnMoveFocusRequested;
|
||||||
_webViewControl.NavigationCompleted += OnNavigationCompleted;
|
_webViewControl.NavigationCompleted += OnNavigationCompleted;
|
||||||
_webViewControl.NavigationStarting += OnNavigationStarting;
|
_webViewControl.NavigationStarting += OnNavigationStarting;
|
||||||
|
@ -1040,7 +1130,9 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WPF
|
||||||
_webViewControl.FrameDOMContentLoaded -= OnFrameDOMContentLoaded;
|
_webViewControl.FrameDOMContentLoaded -= OnFrameDOMContentLoaded;
|
||||||
_webViewControl.FrameNavigationCompleted -= OnFrameNavigationCompleted;
|
_webViewControl.FrameNavigationCompleted -= OnFrameNavigationCompleted;
|
||||||
_webViewControl.FrameNavigationStarting -= OnFrameNavigationStarting;
|
_webViewControl.FrameNavigationStarting -= OnFrameNavigationStarting;
|
||||||
|
_webViewControl.GotFocus -= OnGotFocus;
|
||||||
_webViewControl.LongRunningScriptDetected -= OnLongRunningScriptDetected;
|
_webViewControl.LongRunningScriptDetected -= OnLongRunningScriptDetected;
|
||||||
|
_webViewControl.LostFocus -= OnLostFocus;
|
||||||
_webViewControl.MoveFocusRequested -= OnMoveFocusRequested;
|
_webViewControl.MoveFocusRequested -= OnMoveFocusRequested;
|
||||||
_webViewControl.NavigationCompleted -= OnNavigationCompleted;
|
_webViewControl.NavigationCompleted -= OnNavigationCompleted;
|
||||||
_webViewControl.NavigationStarting -= OnNavigationStarting;
|
_webViewControl.NavigationStarting -= OnNavigationStarting;
|
||||||
|
|
|
@ -239,6 +239,11 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnGotFocus(object sender, object args)
|
||||||
|
{
|
||||||
|
OnGotFocus(EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnLongRunningScriptDetected(object sender, WebViewControlLongRunningScriptDetectedEventArgs args)
|
private void OnLongRunningScriptDetected(object sender, WebViewControlLongRunningScriptDetectedEventArgs args)
|
||||||
{
|
{
|
||||||
var handler = LongRunningScriptDetected;
|
var handler = LongRunningScriptDetected;
|
||||||
|
@ -248,6 +253,11 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnLostFocus(object sender, object args)
|
||||||
|
{
|
||||||
|
OnLostFocus(EventArgs.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
private void OnMoveFocusRequested(object sender, WebViewControlMoveFocusRequestedEventArgs args)
|
private void OnMoveFocusRequested(object sender, WebViewControlMoveFocusRequestedEventArgs args)
|
||||||
{
|
{
|
||||||
var handler = MoveFocusRequested;
|
var handler = MoveFocusRequested;
|
||||||
|
|
|
@ -124,7 +124,8 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
PrivateNetworkClientServerCapability = _delayedPrivateNetworkEnabled
|
PrivateNetworkClientServerCapability = _delayedPrivateNetworkEnabled
|
||||||
? WebViewControlProcessCapabilityState.Enabled
|
? WebViewControlProcessCapabilityState.Enabled
|
||||||
: WebViewControlProcessCapabilityState.Disabled,
|
: WebViewControlProcessCapabilityState.Disabled,
|
||||||
EnterpriseId = _delayedEnterpriseId
|
EnterpriseId = _delayedEnterpriseId,
|
||||||
|
Partition = _delayedPartition
|
||||||
});
|
});
|
||||||
_webViewControl = Process.CreateWebViewControlHost(Handle, ClientRectangle);
|
_webViewControl = Process.CreateWebViewControlHost(Handle, ClientRectangle);
|
||||||
SubscribeEvents();
|
SubscribeEvents();
|
||||||
|
@ -164,7 +165,9 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
_webViewControl.FrameDOMContentLoaded += OnFrameDOMContentLoaded;
|
_webViewControl.FrameDOMContentLoaded += OnFrameDOMContentLoaded;
|
||||||
_webViewControl.FrameNavigationCompleted += OnFrameNavigationCompleted;
|
_webViewControl.FrameNavigationCompleted += OnFrameNavigationCompleted;
|
||||||
_webViewControl.FrameNavigationStarting += OnFrameNavigationStarting;
|
_webViewControl.FrameNavigationStarting += OnFrameNavigationStarting;
|
||||||
|
_webViewControl.GotFocus += OnGotFocus;
|
||||||
_webViewControl.LongRunningScriptDetected += OnLongRunningScriptDetected;
|
_webViewControl.LongRunningScriptDetected += OnLongRunningScriptDetected;
|
||||||
|
_webViewControl.LostFocus += OnLostFocus;
|
||||||
_webViewControl.MoveFocusRequested += OnMoveFocusRequested;
|
_webViewControl.MoveFocusRequested += OnMoveFocusRequested;
|
||||||
_webViewControl.NavigationCompleted += OnNavigationCompleted;
|
_webViewControl.NavigationCompleted += OnNavigationCompleted;
|
||||||
_webViewControl.NavigationStarting += OnNavigationStarting;
|
_webViewControl.NavigationStarting += OnNavigationStarting;
|
||||||
|
@ -191,7 +194,9 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
_webViewControl.FrameDOMContentLoaded -= OnFrameDOMContentLoaded;
|
_webViewControl.FrameDOMContentLoaded -= OnFrameDOMContentLoaded;
|
||||||
_webViewControl.FrameNavigationCompleted -= OnFrameNavigationCompleted;
|
_webViewControl.FrameNavigationCompleted -= OnFrameNavigationCompleted;
|
||||||
_webViewControl.FrameNavigationStarting -= OnFrameNavigationStarting;
|
_webViewControl.FrameNavigationStarting -= OnFrameNavigationStarting;
|
||||||
|
_webViewControl.GotFocus -= OnGotFocus;
|
||||||
_webViewControl.LongRunningScriptDetected -= OnLongRunningScriptDetected;
|
_webViewControl.LongRunningScriptDetected -= OnLongRunningScriptDetected;
|
||||||
|
_webViewControl.LostFocus -= OnLostFocus;
|
||||||
_webViewControl.MoveFocusRequested -= OnMoveFocusRequested;
|
_webViewControl.MoveFocusRequested -= OnMoveFocusRequested;
|
||||||
_webViewControl.NavigationCompleted -= OnNavigationCompleted;
|
_webViewControl.NavigationCompleted -= OnNavigationCompleted;
|
||||||
_webViewControl.NavigationStarting -= OnNavigationStarting;
|
_webViewControl.NavigationStarting -= OnNavigationStarting;
|
||||||
|
|
|
@ -3,7 +3,10 @@
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Net.Http;
|
||||||
|
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
|
||||||
|
|
||||||
namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
{
|
{
|
||||||
|
@ -95,5 +98,34 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Navigate(Uri source) => _webViewControl?.Navigate(source);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Navigate(string source)
|
||||||
|
{
|
||||||
|
Verify.IsFalse(IsDisposed);
|
||||||
|
Verify.IsNotNull(_webViewControl);
|
||||||
|
_webViewControl?.Navigate(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[Obsolete("Use NavigateToLocalStreamUri(Uri, IUriToStreamResolver) instead")]
|
||||||
|
public void NavigateToLocal(string relativePath) => _webViewControl?.NavigateToLocal(relativePath);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void NavigateToString(string text) => _webViewControl?.NavigateToString(text);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void NavigateToLocalStreamUri(Uri relativePath, IUriToStreamResolver streamResolver) => _webViewControl?.NavigateToLocalStreamUri(relativePath, streamResolver);
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void Navigate(
|
||||||
|
Uri requestUri,
|
||||||
|
HttpMethod httpMethod,
|
||||||
|
string content = null,
|
||||||
|
IEnumerable<KeyValuePair<string, string>> headers = null) =>
|
||||||
|
_webViewControl.Navigate(requestUri, httpMethod, content, headers);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -41,6 +41,7 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
private bool _delayedIsIndexDbEnabled = WebViewDefaults.IsIndexedDBEnabled;
|
private bool _delayedIsIndexDbEnabled = WebViewDefaults.IsIndexedDBEnabled;
|
||||||
private bool _delayedIsJavaScriptEnabled = WebViewDefaults.IsJavaScriptEnabled;
|
private bool _delayedIsJavaScriptEnabled = WebViewDefaults.IsJavaScriptEnabled;
|
||||||
private bool _delayedIsScriptNotifyAllowed = WebViewDefaults.IsScriptNotifyEnabled;
|
private bool _delayedIsScriptNotifyAllowed = WebViewDefaults.IsScriptNotifyEnabled;
|
||||||
|
private string _delayedPartition = WebViewDefaults.Partition;
|
||||||
private bool _delayedPrivateNetworkEnabled = WebViewDefaults.IsPrivateNetworkEnabled;
|
private bool _delayedPrivateNetworkEnabled = WebViewDefaults.IsPrivateNetworkEnabled;
|
||||||
private Uri _delayedSource;
|
private Uri _delayedSource;
|
||||||
private WebViewControlHost _webViewControl;
|
private WebViewControlHost _webViewControl;
|
||||||
|
@ -55,6 +56,8 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
Layout += OnWebViewLayout;
|
Layout += OnWebViewLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal WebViewControlHost Host => _webViewControl;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a value indicating whether <see cref="WebView"/> is supported in this environment.
|
/// Gets a value indicating whether <see cref="WebView"/> is supported in this environment.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -291,6 +294,37 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[StringResourceCategory(Constants.CategoryBehavior)]
|
||||||
|
[DefaultValue(WebViewDefaults.Partition)]
|
||||||
|
public string Partition
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
Verify.IsFalse(IsDisposed);
|
||||||
|
Verify.Implies(Initializing, !Initialized);
|
||||||
|
Verify.Implies(Initialized, WebViewControlInitialized);
|
||||||
|
return WebViewControlInitialized
|
||||||
|
? _webViewControl.Process.Partition
|
||||||
|
: _delayedPartition;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Verify.IsFalse(IsDisposed);
|
||||||
|
_delayedPartition = value;
|
||||||
|
if (!DesignMode)
|
||||||
|
{
|
||||||
|
EnsureInitialized();
|
||||||
|
if (WebViewControlInitialized
|
||||||
|
&& !string.Equals(_delayedPartition, _webViewControl.Process.Partition, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException(DesignerUI.E_CANNOT_CHANGE_AFTER_INIT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a <see cref="WebViewControlProcess" /> object that the control is hosted in.
|
/// Gets a <see cref="WebViewControlProcess" /> object that the control is hosted in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -369,6 +403,15 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||||
public Version Version => _webViewControl?.Version;
|
public Version Version => _webViewControl?.Version;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public void AddPreLoadedScript(string script)
|
||||||
|
{
|
||||||
|
Verify.IsFalse(IsDisposed);
|
||||||
|
Verify.Implies(Initializing, !Initialized);
|
||||||
|
Verify.Implies(Initialized, WebViewControlInitialized);
|
||||||
|
_webViewControl?.AddPreLoadedScript(script);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Closes this control.
|
/// Closes this control.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -420,23 +463,6 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.WinForms
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void MoveFocus(WebViewControlMoveFocusReason reason) => _webViewControl?.MoveFocus(reason);
|
public void MoveFocus(WebViewControlMoveFocusReason reason) => _webViewControl?.MoveFocus(reason);
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Navigate(Uri source) => _webViewControl?.Navigate(source);
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void Navigate(string source)
|
|
||||||
{
|
|
||||||
Verify.IsFalse(IsDisposed);
|
|
||||||
Verify.IsNotNull(_webViewControl);
|
|
||||||
_webViewControl?.Navigate(source);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void NavigateToLocal(string relativePath) => _webViewControl?.NavigateToLocal(relativePath);
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void NavigateToString(string text) => _webViewControl?.NavigateToString(text);
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Releases the unmanaged resources used by the <see cref="T:System.Windows.Forms.Control" /> and its child controls and optionally releases the managed resources.
|
/// Releases the unmanaged resources used by the <see cref="T:System.Windows.Forms.Control" /> and its child controls and optionally releases the managed resources.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -19,6 +19,9 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WebView.Shared
|
||||||
|
|
||||||
// Local navigation: when using a null value for Source the uri is about:blank
|
// Local navigation: when using a null value for Source the uri is about:blank
|
||||||
public static readonly Uri AboutBlank = new Uri("about:blank");
|
public static readonly Uri AboutBlank = new Uri("about:blank");
|
||||||
|
|
||||||
|
// A simple HTTP Request & Response Service
|
||||||
|
public static readonly Uri HttpBin = new Uri("http://httpbin.org", UriKind.Absolute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Should;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTests.NavigateToLocalStreamUri
|
||||||
|
{
|
||||||
|
public abstract class BuildStreamContextSpecification : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
public Uri Actual { get; set; }
|
||||||
|
public Uri Expected { get; set; }
|
||||||
|
public string RelativePath { get; set; }
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
Actual = WebView.Host.BuildStream("Test", RelativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public virtual void GeneratedStreamUriIsExpectedValue()
|
||||||
|
{
|
||||||
|
Actual.ShouldEqual(Expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_two_ancestors : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/foo.htm");
|
||||||
|
RelativePath = @"..\..\foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_sibling : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/foo.htm");
|
||||||
|
RelativePath = @"foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_sibling_backslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374//foo.htm");
|
||||||
|
RelativePath = @"\foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_sibling_dotbackslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/foo.htm");
|
||||||
|
RelativePath = @".\foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_sibling_frontslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/foo.htm");
|
||||||
|
RelativePath = @"/foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_sibling_dotfrontslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/foo.htm");
|
||||||
|
RelativePath = @"./foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_descendant : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/bar/foo.htm");
|
||||||
|
RelativePath = @"bar/foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_descendant_backslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374//bar/foo.htm");
|
||||||
|
RelativePath = @"\bar\foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_descendant_dotbackslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/bar/foo.htm");
|
||||||
|
RelativePath = @".\bar\foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_descendant_frontslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/bar/foo.htm");
|
||||||
|
RelativePath = @"/bar/foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_a_relative_path_referencing_descendant_dotfrontslash : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
Expected = new Uri("ms-local-stream://microsoft.win32webviewhost_cw5n1h2txyewy_54657374/bar/foo.htm");
|
||||||
|
RelativePath = @"./bar/foo.htm";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_an_absolute_path_referencing_two_ancestors : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
|
||||||
|
RelativePath = @"C:\foo.htm";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
// Intentionally blank
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||||
|
public override void GeneratedStreamUriIsExpectedValue()
|
||||||
|
{
|
||||||
|
// The error actually occurs in the BuildStream(String, String) method
|
||||||
|
base.When();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Given_an_UNC_path_referencing_two_ancestors : BuildStreamContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
|
||||||
|
RelativePath = @"\\machine\share\foo.htm";
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
// Intentionally blank
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||||
|
public override void GeneratedStreamUriIsExpectedValue()
|
||||||
|
{
|
||||||
|
// The error actually occurs in the BuildStream(String, String) method
|
||||||
|
base.When();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.Toolkit.Win32.UI.Controls.Test.WebView.Shared;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Should;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTests.NavigateToLocalStreamUri
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
[TestCategory(TestConstants.Categories.Nav)]
|
||||||
|
[DeploymentItem("FunctionalTests\\NavigateToLocalStreamUri\\async.htm")]
|
||||||
|
public class Given_a_local_htm_file : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _success;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_success = e.IsSuccess;
|
||||||
|
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
NavigateToLocalAndWaitForFormClose(new Uri("async.htm", UriKind.Relative), new TestStreamResolver());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LocalNavigationCompleted()
|
||||||
|
{
|
||||||
|
_success.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[TestCategory(TestConstants.Categories.Nav)]
|
||||||
|
[DeploymentItem("FunctionalTests\\NavigateToLocalStreamUri\\async.htm")]
|
||||||
|
public class Given_a_local_htm_file_with_async_XHR_for_local_content : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private string _scriptNotifyResult;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.IsJavaScriptEnabled = true;
|
||||||
|
WebView.IsScriptNotifyAllowed = true;
|
||||||
|
|
||||||
|
|
||||||
|
WebView.ScriptNotify += (o, e) =>
|
||||||
|
{
|
||||||
|
_scriptNotifyResult = e.Value;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
NavigateToLocalAndWaitForFormClose(new Uri("async.htm", UriKind.Relative), new TestStreamResolver());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LocalNavigationCompleted()
|
||||||
|
{
|
||||||
|
_scriptNotifyResult.ShouldEqual("Success");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[TestCategory(TestConstants.Categories.Nav)]
|
||||||
|
[DeploymentItem("FunctionalTests\\NavigateToLocalStreamUri\\sync.htm")]
|
||||||
|
public class Given_a_local_htm_file_with_sync_XHR_for_local_content : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private string _scriptNotifyResult;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.IsJavaScriptEnabled = true;
|
||||||
|
WebView.IsScriptNotifyAllowed = true;
|
||||||
|
|
||||||
|
|
||||||
|
WebView.ScriptNotify += (o, e) =>
|
||||||
|
{
|
||||||
|
_scriptNotifyResult = e.Value;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
NavigateToLocalAndWaitForFormClose(new Uri("sync.htm", UriKind.Relative), new TestStreamResolver());
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void LocalNavigationCompleted()
|
||||||
|
{
|
||||||
|
_scriptNotifyResult.ShouldEqual("Success");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTests.NavigateToLocalStreamUri
|
||||||
|
{
|
||||||
|
internal class TestStreamResolver : UriToLocalStreamResolver
|
||||||
|
{
|
||||||
|
public TestStreamResolver()
|
||||||
|
:base(Path.GetDirectoryName(typeof(TestStreamResolver).Assembly.Location))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Async XHR Test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span id="progress">Loading...</span>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Set timeout to show the page before causing the deadlock
|
||||||
|
setTimeout(function () {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '/async.htm', /* async */ true);
|
||||||
|
xhr.onload = function () {
|
||||||
|
/* this will never be called... */
|
||||||
|
document.getElementById('progress').textContent = 'Success';
|
||||||
|
window.external.notify('Success');
|
||||||
|
};
|
||||||
|
xhr.onerror = function () {
|
||||||
|
/* this will never be called... */
|
||||||
|
document.getElementById('progress').textContent = 'Error';
|
||||||
|
window.external.notify('Error');
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}, 1);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Sync XHR Test</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<span id="progress">Loading...</span>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Set timeout to show the page before causing the deadlock
|
||||||
|
setTimeout(function () {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.open('GET', '/sync.htm', /* async */ false);
|
||||||
|
xhr.onload = function () {
|
||||||
|
/* this will never be called... */
|
||||||
|
document.getElementById('progress').textContent = 'Success';
|
||||||
|
window.external.notify('Success');
|
||||||
|
};
|
||||||
|
xhr.onerror = function () {
|
||||||
|
/* this will never be called... */
|
||||||
|
document.getElementById('progress').textContent = 'Error';
|
||||||
|
window.external.notify('Error');
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}, 1);
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -3,7 +3,10 @@
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
using Microsoft.Toolkit.Win32.UI.Controls.Test.WebView.Shared;
|
using Microsoft.Toolkit.Win32.UI.Controls.Test.WebView.Shared;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Should;
|
using Should;
|
||||||
|
@ -83,4 +86,185 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class Navigate2Tests : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navigationCompleted;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navigationCompleted = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
WebView.Navigate(TestConstants.Uris.HttpBin, HttpMethod.Get);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Explict_HTTP_GET_succeeds()
|
||||||
|
{
|
||||||
|
_navigationCompleted.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class NavigateGetWithHeaders : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navigationCompleted;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navigationCompleted = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
WebView.Navigate(
|
||||||
|
TestConstants.Uris.HttpBin,
|
||||||
|
HttpMethod.Get,
|
||||||
|
null,
|
||||||
|
new[] { new KeyValuePair<string, string>("pragma", "no-cache") });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Explict_HTTP_GET_with_HEADERS_succeeds()
|
||||||
|
{
|
||||||
|
_navigationCompleted.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class NavigateGetWithBasicAuth : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navigationCompleted;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navigationCompleted = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
const string user = "usr";
|
||||||
|
const string password = "pwd";
|
||||||
|
const string header = "Authorization";
|
||||||
|
|
||||||
|
var authInfo = Convert.ToBase64String(Encoding.Default.GetBytes($"{user}:{password}"));
|
||||||
|
|
||||||
|
WebView.Navigate(
|
||||||
|
new Uri(TestConstants.Uris.HttpBin, new Uri($"/basic-auth/{user}/{password}", UriKind.Relative)),
|
||||||
|
HttpMethod.Get,
|
||||||
|
null,
|
||||||
|
new[] { new KeyValuePair<string, string>(header, $"Basic {authInfo}") });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Explict_HTTP_GET_with_AUTH_BASIC_succeeds()
|
||||||
|
{
|
||||||
|
_navigationCompleted.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class NavigateOption : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navigationCompleted;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navigationCompleted = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
WebView.Navigate(
|
||||||
|
TestConstants.Uris.ExampleCom,
|
||||||
|
HttpMethod.Options
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(ArgumentOutOfRangeException))]
|
||||||
|
[Ignore("Pops UI that stalls test")]
|
||||||
|
public void Explict_HTTP_OPTION_fails()
|
||||||
|
{
|
||||||
|
_navigationCompleted.ShouldBeFalse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class NavigatePostWithContent : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navigationCompleted;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navigationCompleted = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
string Foo()
|
||||||
|
{
|
||||||
|
var c = new FormUrlEncodedContent(new[] { new KeyValuePair<string, string>("Foo", "Bar"), });
|
||||||
|
return c.ReadAsStringAsync().Result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebView.Navigate(
|
||||||
|
new Uri(TestConstants.Uris.HttpBin, "/post"),
|
||||||
|
HttpMethod.Post,
|
||||||
|
Foo()
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Explict_HTTP_POST_with_data_succeeds()
|
||||||
|
{
|
||||||
|
_navigationCompleted.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using Microsoft.Toolkit.Win32.UI.Controls.Test.WebView.Shared;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Should;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTests.PreLoad
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class NullPreLoadScript : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.IsJavaScriptEnabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[ExpectedException(typeof(ArgumentNullException))]
|
||||||
|
public void CannotPassNullForPreLoadScript()
|
||||||
|
{
|
||||||
|
WebView.AddPreLoadedScript(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class EmptyPreLoadScript : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navSuccess;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.IsJavaScriptEnabled = true;
|
||||||
|
WebView.AddPreLoadedScript(string.Empty);
|
||||||
|
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navSuccess = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
NavigateAndWaitForFormClose(TestConstants.Uris.ExampleCom);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NavigationCompletesForEmptyPreLoadScript()
|
||||||
|
{
|
||||||
|
_navSuccess.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
public class NonExistentPreLoadScript : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _navSuccess;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.IsJavaScriptEnabled = true;
|
||||||
|
WebView.AddPreLoadedScript($"./non-exist.js");
|
||||||
|
|
||||||
|
WebView.NavigationCompleted += (o, e) =>
|
||||||
|
{
|
||||||
|
_navSuccess = e.IsSuccess;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
NavigateAndWaitForFormClose(TestConstants.Uris.ExampleCom);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void NavigateCompletesWithoutError()
|
||||||
|
{
|
||||||
|
_navSuccess.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestClass]
|
||||||
|
[DeploymentItem("FunctionalTests/PreLoad/preload.js")]
|
||||||
|
public class RelativePreLoadScript : HostFormWebViewContextSpecification
|
||||||
|
{
|
||||||
|
private bool _scriptNotifyCalled;
|
||||||
|
|
||||||
|
protected override void Given()
|
||||||
|
{
|
||||||
|
base.Given();
|
||||||
|
WebView.IsScriptNotifyAllowed = true;
|
||||||
|
WebView.IsJavaScriptEnabled = true;
|
||||||
|
|
||||||
|
// Not sure how to get this to execute
|
||||||
|
WebView.AddPreLoadedScript(Path.Combine(TestContext.TestDeploymentDir, "preload.js"));
|
||||||
|
|
||||||
|
// Set up the event handler
|
||||||
|
WebView.ScriptNotify += (o, e) =>
|
||||||
|
{
|
||||||
|
_scriptNotifyCalled = true;
|
||||||
|
Form.Close();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void When()
|
||||||
|
{
|
||||||
|
NavigateAndWaitForFormClose(TestConstants.Uris.ExampleCom);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
[Timeout(TestConstants.Timeouts.Longest)]
|
||||||
|
public void ScriptNotifyRaised()
|
||||||
|
{
|
||||||
|
_scriptNotifyCalled.ShouldBeTrue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
window.external.notify('preload');
|
|
@ -5,6 +5,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
|
||||||
using Should;
|
using Should;
|
||||||
|
|
||||||
namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTests
|
namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTests
|
||||||
|
@ -110,6 +111,22 @@ namespace Microsoft.Toolkit.Win32.UI.Controls.Test.WinForms.WebView.FunctionalTe
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void NavigateToLocalAndWaitForFormClose(string relativePath)
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
WriteLine("Navigating WebView:");
|
||||||
|
WebView.NavigateToLocal(relativePath);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void NavigateToLocalAndWaitForFormClose(Uri relativePath, IUriToStreamResolver streamResolver)
|
||||||
|
{
|
||||||
|
PerformActionAndWaitForFormClose(() =>
|
||||||
|
{
|
||||||
|
WriteLine("Navigating WebView");
|
||||||
|
WebView.NavigateToLocalStreamUri(relativePath, streamResolver);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,10 +55,14 @@
|
||||||
<Compile Include="FunctionalTests\Ctor\WebViewControlProcessCreateWebViewAsyncTests.cs" />
|
<Compile Include="FunctionalTests\Ctor\WebViewControlProcessCreateWebViewAsyncTests.cs" />
|
||||||
<Compile Include="FunctionalTests\DocumentTitle\DocumentTitleTests.cs" />
|
<Compile Include="FunctionalTests\DocumentTitle\DocumentTitleTests.cs" />
|
||||||
<Compile Include="FunctionalTests\FullScreen\FullScreenTests.cs" />
|
<Compile Include="FunctionalTests\FullScreen\FullScreenTests.cs" />
|
||||||
|
<Compile Include="FunctionalTests\NavigateToLocalStreamUri\BuildStreamTests.cs" />
|
||||||
|
<Compile Include="FunctionalTests\NavigateToLocalStreamUri\NavigateToLocalStreamUriTests.cs" />
|
||||||
|
<Compile Include="FunctionalTests\NavigateToLocalStreamUri\TestStreamResolver.cs" />
|
||||||
<Compile Include="FunctionalTests\Navigation\NavigateTests.cs" />
|
<Compile Include="FunctionalTests\Navigation\NavigateTests.cs" />
|
||||||
<Compile Include="FunctionalTests\Navigation\StopTests.cs" />
|
<Compile Include="FunctionalTests\Navigation\StopTests.cs" />
|
||||||
<Compile Include="FunctionalTests\NewWindow\NewWindowTests.cs" />
|
<Compile Include="FunctionalTests\NewWindow\NewWindowTests.cs" />
|
||||||
<Compile Include="FunctionalTests\PartialTrust\PartialTrustTests.cs" />
|
<Compile Include="FunctionalTests\PartialTrust\PartialTrustTests.cs" />
|
||||||
|
<Compile Include="FunctionalTests\PreLoad\PreLoadTests.cs" />
|
||||||
<Compile Include="FunctionalTests\Termination\TerminationTests.cs" />
|
<Compile Include="FunctionalTests\Termination\TerminationTests.cs" />
|
||||||
<Compile Include="FunctionalTests\TestHostForm.cs">
|
<Compile Include="FunctionalTests\TestHostForm.cs">
|
||||||
<SubType>Form</SubType>
|
<SubType>Form</SubType>
|
||||||
|
@ -114,6 +118,17 @@
|
||||||
<Version>1.1.20</Version>
|
<Version>1.1.20</Version>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="FunctionalTests\NavigateToLocalStreamUri\sync.htm">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="FunctionalTests\NavigateToLocalStreamUri\async.htm">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="FunctionalTests\PreLoad\preload.js">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<Target Name="Pack">
|
<Target Name="Pack">
|
||||||
|
|
Загрузка…
Ссылка в новой задаче