/// <summary> /// Overrides user agent with the given string. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="userAgent">User agent to use.</param> /// <param name="acceptLanguage">Browser langugage to emulate.</param> /// <param name="platform">The platform navigator.platform should return.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>The task object representing the asynchronous operation.</returns> public static async Task SetUserAgentOverrideAsync(this IChromiumWebView webview, string userAgent, string acceptLanguage, string platform, CancellationToken cancellationToken) { if (webview is null) throw new ArgumentNullException(nameof(webview)); var args = new CefDictionaryValue(); args.SetString("userAgent", userAgent); if (acceptLanguage is not null) args.SetString("acceptLanguage", acceptLanguage); if (platform is not null) args.SetString("platform", platform); ThrowIfNotEmptyResponse(await ExecuteDevToolsMethodInternalAsync(webview, "Emulation.setUserAgentOverride", args, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Emulates the given media type or media feature for CSS media queries. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="media">Media type to emulate. Empty string disables the override.</param> /// <param name="features">Media features to emulate.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>The task object representing the asynchronous operation.</returns> public static async Task SetEmulatedMediaAsync(this IChromiumWebView webview, string media, IDictionary<string, string> features, CancellationToken cancellationToken) { if (webview is null) throw new ArgumentNullException(nameof(webview)); var args = new CefDictionaryValue(); args.SetString("media", media); if (features is not null) { foreach (KeyValuePair<string, string> feature in features) { if (string.IsNullOrWhiteSpace(feature.Key)) throw new ArgumentOutOfRangeException(nameof(features), "Key may not be empty."); args.SetString(feature.Key, feature.Value); } } ThrowIfNotEmptyResponse(await ExecuteDevToolsMethodInternalAsync(webview, "Emulation.setEmulatedMedia", args, cancellationToken).ConfigureAwait(false)); }
/// <summary> /// Captures page screenshot. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="settings">The capture settings or null.</param> /// <param name="targetStream">A stream to save the captured image to.</param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns>The task object representing the asynchronous operation.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="webview"/> or <paramref name="targetStream"/> is null. /// </exception> /// <exception cref="DevToolsProtocolException"> /// An error occurred while trying to execute a DevTools Protocol method. /// </exception> /// <exception cref="InvalidOperationException">Other error occurred.</exception> public static async Task CaptureScreenshotAsync(this IChromiumWebView webview, PageCaptureSettings settings, Stream targetStream, CancellationToken cancellationToken) { if (webview is null) throw new ArgumentNullException(nameof(webview)); if (targetStream is null) throw new ArgumentNullException(nameof(targetStream)); CefDictionaryValue args; if (settings is null) { args = null; } else { args = new CefDictionaryValue(); if (settings.Format == ImageCompressionFormat.Jpeg) { args.SetString("format", "jpeg"); if (settings.Quality.HasValue) args.SetInt("quality", settings.Quality.Value); } if (!settings.FromSurface) args.SetBool("fromSurface", false); if (settings.Viewport != null) { PageViewport viewport = settings.Viewport; var viewportDict = new CefDictionaryValue(); viewportDict.SetDouble("x", viewport.X); viewportDict.SetDouble("y", viewport.Y); viewportDict.SetDouble("width", viewport.Width); viewportDict.SetDouble("height", viewport.Height); viewportDict.SetDouble("scale", viewport.Scale); args.SetDictionary("clip", viewportDict); } if (settings.CaptureBeyondViewport) args.SetBool("captureBeyondViewport", true); } byte[] rv = (byte[])await ExecuteDevToolsMethodInternalAsync(webview, "Page.captureScreenshot", args, null, cancellationToken).ConfigureAwait(false); if (rv != null && rv.Length > 11 && rv[rv.Length - 1] == '}' && rv[rv.Length - 2] == '"' && "{\"data\":\"".Equals(Encoding.ASCII.GetString(rv, 0, 9), StringComparison.Ordinal)) { using (var input = new MemoryStream(rv, 9, rv.Length - 11)) using (var base64Transform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces)) using (var cryptoStream = new CryptoStream(input, base64Transform, CryptoStreamMode.Read)) { await cryptoStream.CopyToAsync(targetStream, 4096, cancellationToken).ConfigureAwait(false); await targetStream.FlushAsync(cancellationToken).ConfigureAwait(false); } } else { throw new InvalidOperationException(); } }