// Copyright © 2021 The CefSharp Authors. All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
using CefSharp.Internals;
using System;
using System.IO;
using System.Threading.Tasks;
namespace CefSharp
{
///
/// Extended WebBrowserExtensions
///
public static class WebBrowserExtensionsEx
{
///
/// Retrieve the current . Contains information like
/// and
///
/// The ChromiumWebBrowser instance this method extends.
///
/// that when executed returns the current or null
///
public static Task GetVisibleNavigationEntryAsync(this IChromiumWebBrowserBase browser)
{
var host = browser.GetBrowserHost();
if (host == null)
{
return Task.FromResult(null);
}
if(Cef.CurrentlyOnThread(CefThreadIds.TID_UI))
{
var entry = host.GetVisibleNavigationEntry();
return Task.FromResult(entry);
}
var tcs = new TaskCompletionSource();
Cef.UIThreadTaskFactory.StartNew(delegate
{
var entry = host.GetVisibleNavigationEntry();
tcs.TrySetResultAsync(entry);
});
return tcs.Task;
}
///
/// Downloads the specified and calls
/// when the download is complete. Makes a GET Request.
///
/// valid frame
/// url to download
/// Action to be executed when the download is complete.
public static void DownloadUrl(this IFrame frame, string url, Action completeHandler)
{
if (!frame.IsValid)
{
throw new Exception("Frame is invalid, unable to continue.");
}
//Can be created on any valid CEF Thread, here we'll use the CEF UI Thread
Cef.UIThreadTaskFactory.StartNew(delegate
{
var request = frame.CreateRequest(false);
request.Method = "GET";
request.Url = url;
var memoryStream = new MemoryStream();
var urlRequestClient = Fluent.UrlRequestClient
.Create()
.OnDownloadData((req, stream) =>
{
stream.CopyTo(memoryStream);
})
.OnRequestComplete((req) =>
{
memoryStream.Position = 0;
completeHandler?.Invoke(req, memoryStream);
})
.Build();
var urlRequest = frame.CreateUrlRequest(request, urlRequestClient);
});
}
///
/// Downloads the specified as a .
/// Makes a GET Request.
///
/// valid frame
/// url to download
/// A task that can be awaited to get the representing the Url
public static Task DownloadUrlAsync(this IFrame frame, string url)
{
if (!frame.IsValid)
{
throw new Exception("Frame is invalid, unable to continue.");
}
var taskCompletionSource = new TaskCompletionSource();
//Can be created on any valid CEF Thread, here we'll use the CEF UI Thread
Cef.UIThreadTaskFactory.StartNew(delegate
{
var request = frame.CreateRequest(false);
request.Method = "GET";
request.Url = url;
var memoryStream = new MemoryStream();
var urlRequestClient = Fluent.UrlRequestClient
.Create()
.OnDownloadData((req, stream) =>
{
stream.CopyTo(memoryStream);
})
.OnRequestComplete((req) =>
{
if (req.RequestStatus == UrlRequestStatus.Success)
{
taskCompletionSource.TrySetResultAsync(memoryStream.ToArray());
}
else
{
taskCompletionSource.TrySetExceptionAsync(new Exception("RequestStatus:" + req.RequestStatus + ";StatusCode:" + req.Response.StatusCode));
}
})
.Build();
var urlRequest = frame.CreateUrlRequest(request, urlRequestClient);
});
return taskCompletionSource.Task;
}
///
/// Toggles audio mute for the current browser.
/// If the is null or has been disposed
/// then this command will be a no-op.
///
/// The ChromiumWebBrowser instance this method extends.
public static void ToggleAudioMute(this IChromiumWebBrowserBase browser)
{
if (browser.IsDisposed || Cef.IsShutdown)
{
return;
}
_ = Cef.UIThreadTaskFactory.StartNew(delegate
{
var cefBrowser = browser.BrowserCore;
if (cefBrowser == null || cefBrowser.IsDisposed)
{
return;
}
var host = cefBrowser.GetHost();
var isAudioMuted = host.IsAudioMuted;
host.SetAudioMuted(!isAudioMuted);
});
}
}
}