// 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); }); } } }