public CreateWindowEventArgs( CefFrame frame, string targetUrl, string targetFrameName, CefWindowOpenDisposition targetDisposition, bool userGesture, CefPopupFeatures popupFeatures, CefWindowInfo windowInfo, CefClient client, CefBrowserSettings settings, CefDictionaryValue extraInfo, bool noJavascriptAccess) { this.Frame = frame; this.TargetUrl = targetUrl; this.TargetFrameName = targetFrameName; this.TargetDisposition = targetDisposition; this.UserGesture = userGesture; this.PopupFeatures = popupFeatures; this.Settings = settings; this.WindowInfo = windowInfo; this.Client = client; this.ExtraInfo = extraInfo; this.NoJavaScriptAccess = noJavascriptAccess; }
/// <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(); } }
/// <summary> /// Sets the value at the specified key as type dict. Returns true (1) if the /// value was set successfully. If |value| is currently owned by another object /// then the value will be copied and the |value| reference will not change. /// Otherwise, ownership will be transferred to this object and the |value| /// reference will be invalidated. /// </summary> public unsafe virtual bool SetDictionary(string key, CefDictionaryValue value) { fixed(char *s0 = key) { var cstr0 = new cef_string_t { Str = s0, Length = key != null ? key.Length : 0 }; return(SafeCall(NativeInstance->SetDictionary(&cstr0, (value != null) ? value.GetNativeInstance() : null) != 0)); } }
/// <summary> /// Returns the value at the specified key as type dictionary. The returned /// value will reference existing data and modifications to the value will /// modify this object. /// </summary> public unsafe virtual CefDictionaryValue GetDictionary(string key) { fixed(char *s0 = key) { var cstr0 = new cef_string_t { Str = s0, Length = key != null ? key.Length : 0 }; return(SafeCall(CefDictionaryValue.Wrap(CefDictionaryValue.Create, NativeInstance->GetDictionary(&cstr0)))); } }
/// <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> /// Enables touch on platforms which do not support them. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="enabled">True whether the touch event emulation should be enabled.</param> /// <param name="maxTouchPoints">Maximum touch points supported. Defaults to one.</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 SetTouchEmulationEnabledAsync(this IChromiumWebView webview, bool enabled, int? maxTouchPoints, CancellationToken cancellationToken) { if (webview is null) throw new ArgumentNullException(nameof(webview)); var args = new CefDictionaryValue(); args.SetBool("enabled", enabled); if (maxTouchPoints is not null) { if (maxTouchPoints.Value < 1 || maxTouchPoints.Value > 16) throw new ArgumentOutOfRangeException(nameof(maxTouchPoints), "Touch points must be between 1 and 16."); args.SetInt("maxTouchPoints", maxTouchPoints.Value); } ThrowIfNotEmptyResponse(await ExecuteDevToolsMethodInternalAsync(webview, "Emulation.setTouchEmulationEnabled", 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)); }
public WindowlessWebView(string url, CefBrowserSettings settings, CefDictionaryValue extraInfo, CefRequestContext requestContext) { CefWindowInfo windowInfo = null; try { windowInfo = new CefWindowInfo(); Initialize(windowInfo); if (!CefApi.CreateBrowser(windowInfo, ViewGlue.Client, url ?? "about:blank", settings ?? DefaultBrowserSettings, extraInfo, requestContext)) { throw new InvalidOperationException(); } } finally { windowInfo?.Dispose(); } }
/// <summary> /// Sets the value at the specified index as type dict. Returns true (1) if the /// value was set successfully. If |value| is currently owned by another object /// then the value will be copied and the |value| reference will not change. /// Otherwise, ownership will be transferred to this object and the |value| /// reference will be invalidated. /// </summary> public unsafe virtual bool SetDictionary(long index, CefDictionaryValue value) { return(SafeCall(NativeInstance->SetDictionary(new UIntPtr((ulong)index), (value != null) ? value.GetNativeInstance() : null) != 0)); }
/// <summary> /// Returns the value at the specified index as type dictionary. The returned /// value will reference existing data and modifications to the value will /// modify this object. /// </summary> public unsafe virtual CefDictionaryValue GetDictionary(long index) { return(SafeCall(CefDictionaryValue.Wrap(CefDictionaryValue.Create, NativeInstance->GetDictionary(new UIntPtr((ulong)index))))); }
/// <summary> /// Called on the UI thread before a new popup browser is created. The /// |browser| and |frame| values represent the source of the popup request. The /// |target_url| and |target_frame_name| values indicate where the popup /// browser should navigate and may be NULL if not specified with the request. /// The |target_disposition| value indicates where the user intended to open /// the popup (e.g. current tab, new tab, etc). The |user_gesture| value will /// be true (1) if the popup was opened via explicit user gesture (e.g. /// clicking a link) or false (0) if the popup opened automatically (e.g. via /// the DomContentLoaded event). The |popupFeatures| structure contains /// additional information about the requested popup window. To allow creation /// of the popup browser optionally modify |windowInfo|, |client|, |settings| /// and |no_javascript_access| and return false (0). To cancel creation of the /// popup browser return true (1). The |client| and |settings| values will /// default to the source browser's values. If the |no_javascript_access| value /// is set to false (0) the new browser will not be scriptable and may not be /// hosted in the same renderer process as the source browser. Any /// modifications to |windowInfo| will be ignored if the parent browser is /// wrapped in a cef_browser_view_t. Popup browser creation will be canceled if /// the parent browser is destroyed before the popup browser creation completes /// (indicated by a call to OnAfterCreated for the popup browser). The /// |extra_info| parameter provides an opportunity to specify extra information /// specific to the created popup browser that will be passed to /// cef_render_process_handler_t::on_browser_created() in the render process. /// </summary> protected internal unsafe virtual bool OnBeforePopup(CefBrowser browser, CefFrame frame, string targetUrl, string targetFrameName, CefWindowOpenDisposition targetDisposition, bool userGesture, CefPopupFeatures popupFeatures, CefWindowInfo windowInfo, ref CefClient client, CefBrowserSettings settings, ref CefDictionaryValue extraInfo, ref int noJavascriptAccess) { return(default);
/// <summary> /// Sets the underlying value as type dict. Returns true (1) if the value was /// set successfully. This object keeps a reference to |value| and ownership of /// the underlying data remains unchanged. /// </summary> public unsafe virtual bool SetDictionary(CefDictionaryValue value) { return(SafeCall(NativeInstance->SetDictionary((value != null) ? value.GetNativeInstance() : null) != 0)); }
/// <summary> /// Returns the underlying value as type dictionary. The returned reference may /// become invalid if the value is owned by another object or if ownership is /// transferred to another object in the future. To maintain a reference to the /// value after assigning ownership to a dictionary or list pass this object to /// the set_value() function instead of passing the returned reference to /// set_dictionary(). /// </summary> public unsafe virtual CefDictionaryValue GetDictionary() { return(SafeCall(CefDictionaryValue.Wrap(CefDictionaryValue.Create, NativeInstance->GetDictionary()))); }
/// <summary> /// Called after a browser has been created. /// </summary> /// <param name="browser">The browser instance.</param> /// <param name="extraInfo">A read-only value originating from the browser creator or null.</param> protected internal virtual void OnBrowserCreated(CefBrowser browser, CefDictionaryValue extraInfo) { Interlocked.Increment(ref _browsersCount); }
/// <summary> /// Executes a method call over the DevTools protocol. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="method">The method name.</param> /// <param name="parameters"> /// The dictionaly with method parameters. May be null. /// See the <see href="https://chromedevtools.github.io/devtools-protocol/"> /// DevTools Protocol documentation</see> for details of supported methods /// and the expected parameters. /// </param> /// <returns> /// The JSON string with the response. Structure of the response varies depending /// on the method name and is defined by the 'RETURN OBJECT' section of /// the Chrome DevTools Protocol command description. /// </returns> /// <remarks> /// Usage of the ExecuteDevToolsMethodAsync function does not require an active /// DevTools front-end or remote-debugging session. Other active DevTools sessions /// will continue to function independently. However, any modification of global /// browser state by one session may not be reflected in the UI of other sessions. /// <para/> /// Communication with the DevTools front-end (when displayed) can be logged /// for development purposes by passing the `--devtools-protocol-log- /// file=<path>` command-line flag. /// </remarks> public static Task <string> ExecuteDevToolsMethodAsync(this IChromiumWebView webview, string method, CefDictionaryValue parameters) { return(ExecuteDevToolsMethodAsync(webview, method, parameters, CancellationToken.None)); }
/// <summary> /// Returns a writable copy of this object. If |exclude_NULL_children| is true /// (1) any NULL dictionaries or lists will be excluded from the copy. /// </summary> public unsafe virtual CefDictionaryValue Copy(bool excludeEmptyChildren) { return(SafeCall(CefDictionaryValue.Wrap(CefDictionaryValue.Create, NativeInstance->Copy(excludeEmptyChildren ? 1 : 0)))); }
/// <summary> /// Called after a browser has been created. When browsing cross-origin a new /// browser will be created before the old browser with the same identifier is /// destroyed. |extra_info| is a read-only value originating from /// cef_browser_host_t::cef_browser_host_create_browser(), /// cef_browser_host_t::cef_browser_host_create_browser_sync(), /// cef_life_span_handler_t::on_before_popup() or /// cef_browser_view_t::cef_browser_view_create(). /// </summary> public unsafe virtual void OnBrowserCreated(CefBrowser browser, CefDictionaryValue extraInfo) { }
/// <summary> /// Executes a method call over the DevTools protocol. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="method">The method name.</param> /// <param name="parameters"> /// The dictionaly with method parameters. May be null. /// See the <see href="https://chromedevtools.github.io/devtools-protocol/"> /// DevTools Protocol documentation</see> for details of supported methods /// and the expected parameters. /// </param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns> /// The JSON string with the response. Structure of the response varies depending /// on the method name and is defined by the 'RETURN OBJECT' section of /// the Chrome DevTools Protocol command description. /// </returns> /// <remarks> /// Usage of the ExecuteDevToolsMethodAsync function does not require an active /// DevTools front-end or remote-debugging session. Other active DevTools sessions /// will continue to function independently. However, any modification of global /// browser state by one session may not be reflected in the UI of other sessions. /// <para/> /// Communication with the DevTools front-end (when displayed) can be logged /// for development purposes by passing the `--devtools-protocol-log- /// file=<path>` command-line flag. /// </remarks> public static Task<string> ExecuteDevToolsMethodAsync(this IChromiumWebView webview, string method, CefDictionaryValue parameters, CancellationToken cancellationToken) { if (webview is null) throw new ArgumentNullException(nameof(webview)); if (method is null) throw new ArgumentNullException(nameof(method)); method = method.Trim(); if (method.Length == 0) throw new ArgumentOutOfRangeException(nameof(method)); return ExecuteDevToolsMethodInternalAsync(webview, method, parameters, cancellationToken); }
/// <summary> /// Execute a function call over the DevTools protocol. This is a more /// structured version of SendDevToolsMessage. |message_id| is an incremental /// number that uniquely identifies the message (pass 0 to have the next number /// assigned automatically based on previous values). |function| is the /// function name. |params| are the function parameters, which may be NULL. See /// the DevTools protocol documentation (linked above) for details of supported /// functions and the expected |params| dictionary contents. This function will /// return the assigned message ID if called on the UI thread and the message /// was successfully submitted for validation, otherwise 0. See the /// SendDevToolsMessage documentation for additional usage information. /// </summary> public unsafe virtual int ExecuteDevToolsMethod(int messageId, string method, CefDictionaryValue @params) { fixed(char *s1 = method) { var cstr1 = new cef_string_t { Str = s1, Length = method != null ? method.Length : 0 }; return(SafeCall(NativeInstance->ExecuteDevToolsMethod(messageId, &cstr1, (@params != null) ? @params.GetNativeInstance() : null))); } }
/// <summary> /// Executes a method call over the DevTools protocol. /// </summary> /// <typeparam name="T">The type of object to return.</typeparam> /// <param name="webview">The WebView control.</param> /// <param name="method">The method name.</param> /// <param name="parameters"> /// The dictionaly with method parameters. May be null. /// See the <see href="https://chromedevtools.github.io/devtools-protocol/"> /// DevTools Protocol documentation</see> for details of supported methods /// and the expected parameters. /// </param> /// <param name="convert"> /// A callback function that converts the result content into an object of type <see cref="T"/>. /// If null, a byte array containing a UTF-8-encoded copy of the content is returned. /// </param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns> /// The JSON string with the response. Structure of the response varies depending /// on the method name and is defined by the 'RETURN OBJECT' section of /// the Chrome DevTools Protocol command description. /// </returns> /// <remarks> /// Usage of the ExecuteDevToolsMethodAsync function does not require an active /// DevTools front-end or remote-debugging session. Other active DevTools sessions /// will continue to function independently. However, any modification of global /// browser state by one session may not be reflected in the UI of other sessions. /// <para/> /// Communication with the DevTools front-end (when displayed) can be logged /// for development purposes by passing the `--devtools-protocol-log- /// file=<path>` command-line flag. /// </remarks> public static async Task<T> ExecuteDevToolsMethodAsync<T>(this IChromiumWebView webview, string method, CefDictionaryValue parameters, ConvertUtf8BufferToTypeDelegate<T> convert, CancellationToken cancellationToken) where T : class { if (webview is null) throw new ArgumentNullException(nameof(webview)); if (method is null) throw new ArgumentNullException(nameof(method)); method = method.Trim(); if (method.Length == 0) throw new ArgumentOutOfRangeException(nameof(method)); object result = await ExecuteDevToolsMethodInternalAsync(webview, method, parameters, (buffer, size) => convert(buffer, size), cancellationToken).ConfigureAwait(false); return (T)result; }
/// <summary> /// Executes a method call over the DevTools protocol. /// </summary> /// <param name="webview">The WebView control.</param> /// <param name="method">The method name.</param> /// <param name="parameters"> /// The dictionaly with method parameters. May be null. /// See the <see href="https://chromedevtools.github.io/devtools-protocol/"> /// DevTools Protocol documentation</see> for details of supported methods /// and the expected parameters. /// </param> /// <param name="cancellationToken">The token to monitor for cancellation requests.</param> /// <returns> /// The JSON string with the response. Structure of the response varies depending /// on the method name and is defined by the 'RETURN OBJECT' section of /// the Chrome DevTools Protocol command description. /// </returns> /// <remarks> /// Usage of the ExecuteDevToolsMethodAsync function does not require an active /// DevTools front-end or remote-debugging session. Other active DevTools sessions /// will continue to function independently. However, any modification of global /// browser state by one session may not be reflected in the UI of other sessions. /// <para/> /// Communication with the DevTools front-end (when displayed) can be logged /// for development purposes by passing the `--devtools-protocol-log- /// file=<path>` command-line flag. /// </remarks> public static async Task <string> ExecuteDevToolsMethodAsync(this IChromiumWebView webview, string method, CefDictionaryValue parameters, CancellationToken cancellationToken) { if (webview is null) { throw new ArgumentNullException(nameof(webview)); } if (method is null) { throw new ArgumentNullException(nameof(method)); } method = method.Trim(); if (method.Length == 0) { throw new ArgumentOutOfRangeException(nameof(method)); } byte[] rv = await ExecuteDevToolsMethodInternalAsync(webview, method, parameters, cancellationToken).ConfigureAwait(false); return(rv is null ? null : Encoding.UTF8.GetString(rv)); }
/// <summary> /// Returns true (1) if this object and |that| object have the same underlying /// data. If true (1) modifications to this object will also affect |that| /// object and vice-versa. /// </summary> public unsafe virtual bool IsSame(CefDictionaryValue that) { return(SafeCall(NativeInstance->IsSame((that != null) ? that.GetNativeInstance() : null) != 0)); }