Skip to content

Commit

Permalink
Core - Rename WaitForBrowserInitialLoadAsync to WaitForInitialLoadAsy…
Browse files Browse the repository at this point in the history
…nc and simplify

- Initial intention was to have a reusable method that could be used CefSharp.Wpf.HwndHost,
  upon further deliberation I've decided to build the functionality into the ChromiumWebBrowser.Partial.cs
  and will need to duplicate the functionality in CefSharp.Wpf.HwndHost. This guarantees that the
  Task will be resolved in all cases. The previous implementation there was a theoretical change we'd
  miss subscribing to the relevant events
- Remove CancellationToken as it's not possible to cancel

Issue #3842
  • Loading branch information
amaitland committed Oct 28, 2021
1 parent 3221c4b commit e8e6eb8
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 206 deletions.
139 changes: 0 additions & 139 deletions CefSharp.Core/WebBrowserExtensionsEx.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,145 +51,6 @@ public static Task<NavigationEntry> GetVisibleNavigationEntryAsync(this IWebBrow
return tcs.Task;
}

/// <summary>
/// See <see cref="IWebBrowser.WaitForBrowserInitialLoadAsync()"/> for details
/// </summary>
/// <param name="chromiumWebBrowser">ChromiumWebBrowser instance (cannot be null)</param>
/// <param name="cancellationToken">cancellation token</param>
/// <returns>See <see cref="IWebBrowser.WaitForBrowserInitialLoadAsync()"/> for details</returns>
public static Task<LoadUrlAsyncResponse> WaitForBrowserInitialLoadAsync(IWebBrowser chromiumWebBrowser, CancellationToken? cancellationToken = null)
{
var tcs = new TaskCompletionSource<LoadUrlAsyncResponse>();

if (cancellationToken?.IsCancellationRequested ?? false)
{
tcs.TrySetCanceled();

return tcs.Task;
}

if (chromiumWebBrowser.IsDisposed)
{
var ex = new ObjectDisposedException(nameof(chromiumWebBrowser));

tcs.TrySetException(ex);

return tcs.Task;
}

//If the browser has already initialized then we
//should check if the page has already loaded
if (chromiumWebBrowser.IsBrowserInitialized)
{
var browser = chromiumWebBrowser.GetBrowser();

if (!browser.IsLoading)
{
chromiumWebBrowser.GetVisibleNavigationEntryAsync().ContinueWith(x =>
{
if (cancellationToken?.IsCancellationRequested ?? false)
{
tcs.TrySetCanceledAsync();
return;
}
var navEntry = x.Result;
int statusCode = navEntry?.HttpStatusCode ?? -1;
//By default 0 is some sort of error, we map that to -1
//so that it's clearer that something failed.
if (statusCode == 0)
{
statusCode = -1;
}
var response = new LoadUrlAsyncResponse(CefErrorCode.None, statusCode);
tcs.TrySetResultAsync(response);
}, TaskScheduler.Default);

return tcs.Task;
}
}

EventHandler<LoadErrorEventArgs> loadErrorHandler = null;
EventHandler<LoadingStateChangedEventArgs> loadingStateChangeHandler = null;

loadErrorHandler = (sender, args) =>
{
//Ignore Aborted
if (args.ErrorCode == CefErrorCode.Aborted)
{
return;
}
//If LoadError was called then we'll remove both our handlers
//as we won't need to capture LoadingStateChanged, we know there
//was an error
chromiumWebBrowser.LoadError -= loadErrorHandler;
chromiumWebBrowser.LoadingStateChanged -= loadingStateChangeHandler;
if (cancellationToken?.IsCancellationRequested ?? false)
{
tcs.TrySetCanceledAsync();
return;
}
//Ensure our continuation is executed on the ThreadPool
//For the .Net Core implementation we could use
//TaskCreationOptions.RunContinuationsAsynchronously
tcs.TrySetResultAsync(new LoadUrlAsyncResponse(args.ErrorCode, -1));
};

loadingStateChangeHandler = (sender, args) =>
{
//Wait for IsLoading = false
if (!args.IsLoading)
{
//If LoadingStateChanged was called then we'll remove both our handlers
//as LoadError won't be called, our site has loaded with a valid HttpStatusCode
//HttpStatusCodes can still be for example 404, this is considered a successful request,
//the server responded, it just didn't have the page you were after.
chromiumWebBrowser.LoadError -= loadErrorHandler;
chromiumWebBrowser.LoadingStateChanged -= loadingStateChangeHandler;
if (cancellationToken?.IsCancellationRequested ?? false)
{
tcs.TrySetCanceledAsync();
return;
}
var host = args.Browser.GetHost();
var navEntry = host?.GetVisibleNavigationEntry();
int statusCode = navEntry?.HttpStatusCode ?? -1;
//By default 0 is some sort of error, we map that to -1
//so that it's clearer that something failed.
if (statusCode == 0)
{
statusCode = -1;
}
//Ensure our continuation is executed on the ThreadPool
//For the .Net Core implementation we could use
//TaskCreationOptions.RunContinuationsAsynchronously
tcs.TrySetResultAsync(new LoadUrlAsyncResponse(CefErrorCode.None, statusCode));
}
};

chromiumWebBrowser.LoadError += loadErrorHandler;
chromiumWebBrowser.LoadingStateChanged += loadingStateChangeHandler;

return tcs.Task;
}

/// <summary>
/// Downloads the specified <paramref name="url"/> and calls <paramref name="completeHandler"/>
/// when the download is complete. Makes a GET Request.
Expand Down
4 changes: 1 addition & 3 deletions CefSharp.OffScreen/ChromiumWebBrowser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -756,13 +756,11 @@ void IWebBrowserInternal.SetAddress(AddressChangedEventArgs args)
/// Sets the loading state change.
/// </summary>
/// <param name="args">The <see cref="LoadingStateChangedEventArgs"/> instance containing the event data.</param>
void IWebBrowserInternal.SetLoadingStateChange(LoadingStateChangedEventArgs args)
partial void SetLoadingStateChange(LoadingStateChangedEventArgs args)
{
CanGoBack = args.CanGoBack;
CanGoForward = args.CanGoForward;
IsLoading = args.IsLoading;

LoadingStateChanged?.Invoke(this, args);
}

/// <summary>
Expand Down
16 changes: 8 additions & 8 deletions CefSharp.Test/DevTools/DevToolsClientFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public async Task CanCaptureScreenshot()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand Down Expand Up @@ -83,7 +83,7 @@ public async Task CanGetDevToolsProtocolVersion()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand All @@ -104,7 +104,7 @@ public async Task CanEmulationCanEmulate()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand All @@ -120,7 +120,7 @@ public async Task CanGetPageNavigationHistory()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand All @@ -143,7 +143,7 @@ public async Task CanSetCookieForDomain(string name, string value, string domain
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand All @@ -159,7 +159,7 @@ public async Task CanUseMultipleDevToolsClientInstancesPerBrowser()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand Down Expand Up @@ -192,7 +192,7 @@ public async Task CanSetUserAgentOverride()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand Down Expand Up @@ -309,7 +309,7 @@ public async Task ExecuteDevToolsMethodThrowsExceptionWithInvalidMethod()
{
using (var browser = new ChromiumWebBrowser("www.google.com"))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

using (var devToolsClient = browser.GetDevToolsClient())
{
Expand Down
12 changes: 6 additions & 6 deletions CefSharp.Test/JavascriptBinding/IntegrationTestFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public async Task IsObjectCachedWithInvalidObjectNameReturnsFalse()
{
using (var browser = new ChromiumWebBrowser(CefExample.BindingApiCustomObjectNameTestUrl))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

//We'll execute twice using the different cased (camelcase naming and standard)
var response = await browser.EvaluateScriptAsync("CefSharp.IsObjectCached('doesntexist')");
Expand All @@ -186,7 +186,7 @@ public async Task JsBindingGlobalObjectNameCustomValueExecuteIsObjectCachedSucce
//To modify the settings we need to defer browser creation slightly
browser.CreateBrowser();

await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

var result = await browser.EvaluateScriptAsync("bindingApiObject.isObjectCached('doesntexist') === false");

Expand All @@ -205,7 +205,7 @@ public async Task JsBindingGlobalApiDisabled()
//To modify the settings we need to defer browser creation slightly
browser.CreateBrowser();

var loadResponse = await browser.WaitForBrowserInitialLoadAsync();
var loadResponse = await browser.WaitForInitialLoadAsync();

Assert.True(loadResponse.Success);

Expand All @@ -231,7 +231,7 @@ public async Task JsBindingGlobalApiEnabled()
//To modify the settings we need to defer browser creation slightly
browser.CreateBrowser();

await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

var response1 = await browser.EvaluateScriptAsync("typeof window.cefSharp === 'undefined'");
var response2 = await browser.EvaluateScriptAsync("typeof window.CefSharp === 'undefined'");
Expand All @@ -251,7 +251,7 @@ public async Task JsBindingRenderProcessId(string script)
{
using (var browser = new ChromiumWebBrowser(CefExample.BindingApiCustomObjectNameTestUrl))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

var result = await browser.EvaluateScriptAsync(script);

Expand All @@ -271,7 +271,7 @@ public async Task CanCallCefSharpBindObjectAsyncWithoutParams()
{
using (var browser = new ChromiumWebBrowser(CefExample.HelloWorldUrl))
{
await browser.WaitForBrowserInitialLoadAsync();
await browser.WaitForInitialLoadAsync();

//TODO: See if we can avoid GetAwaiter().GetResult()
var evt = Assert.Raises<JavascriptBindingEventArgs>(
Expand Down

0 comments on commit e8e6eb8

Please sign in to comment.