/// <summary> /// Returns the value for the preference with the specified |name|. Returns /// NULL if the preference does not exist. The returned object contains a copy /// of the underlying preference value and modifications to the returned object /// will not modify the underlying preference value. This function must be /// called on the browser process UI thread. /// </summary> public unsafe virtual CefValue GetPreference(string name) { fixed(char *s0 = name) { var cstr0 = new cef_string_t { Str = s0, Length = name != null ? name.Length : 0 }; return(SafeCall(CefValue.Wrap(CefValue.Create, NativeInstance->GetPreference(&cstr0)))); } }
// void (*)(_cef_accessibility_handler_t* self, _cef_value_t* value)* private static unsafe void OnAccessibilityLocationChangeImpl(cef_accessibility_handler_t *self, cef_value_t *value) { var instance = GetInstance((IntPtr)self) as CefAccessibilityHandler; if (instance == null || ((ICefAccessibilityHandlerPrivate)instance).AvoidOnAccessibilityLocationChange()) { ReleaseIfNonNull((cef_base_ref_counted_t *)value); return; } instance.OnAccessibilityLocationChange(CefValue.Wrap(CefValue.Create, value)); }
/// <summary> /// Sets the value at the specified key. Returns true (1) if the value was set /// successfully. If |value| represents simple data then the underlying data /// will be copied and modifications to |value| will not modify this object. If /// |value| represents complex data (binary, dictionary or list) then the /// underlying data will be referenced and modifications to |value| will modify /// this object. /// </summary> public unsafe virtual bool SetValue(string key, CefValue value) { fixed(char *s0 = key) { var cstr0 = new cef_string_t { Str = s0, Length = key != null ? key.Length : 0 }; return(SafeCall(NativeInstance->SetValue(&cstr0, (value != null) ? value.GetNativeInstance() : null) != 0)); } }
/// <summary> /// Returns the value at the specified key. For simple types the returned value /// will copy existing data and modifications to the value will not modify this /// object. For complex types (binary, dictionary and list) the returned value /// will reference existing data and modifications to the value will modify /// this object. /// </summary> public unsafe virtual CefValue GetValue(string key) { fixed(char *s0 = key) { var cstr0 = new cef_string_t { Str = s0, Length = key != null ? key.Length : 0 }; return(SafeCall(CefValue.Wrap(CefValue.Create, NativeInstance->GetValue(&cstr0)))); } }
/// <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 JSON string 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, string parameters, CancellationToken cancellationToken) { CefValue args = null; if (parameters != null) { args = CefApi.CefParseJSON(parameters, CefJsonParserOptions.AllowTrailingCommas, out string errorMessage); if (args is null) throw new ArgumentOutOfRangeException(nameof(parameters), errorMessage is null ? "An error occurred during JSON parsing." : errorMessage); } return ExecuteDevToolsMethodAsync(webview, method, args is null ? default(CefDictionaryValue) : args.GetDictionary(), cancellationToken); }
private static async Task <byte[]> ExecuteDevToolsMethodInternalAsync(IChromiumWebView webview, string method, CefDictionaryValue parameters, CancellationToken cancellationToken) { CefBrowser browser = webview.BrowserObject; if (browser is null) { throw new InvalidOperationException(); } cancellationToken.ThrowIfCancellationRequested(); CefBrowserHost browserHost = browser.Host; DevToolsProtocolClient protocolClient = GetProtocolClient(browserHost); await CefNetSynchronizationContextAwaiter.GetForThread(CefThreadId.UI); cancellationToken.ThrowIfCancellationRequested(); int messageId = browserHost.ExecuteDevToolsMethod(protocolClient.IncrementMessageId(), method, parameters); protocolClient.UpdateLastMessageId(messageId); DevToolsMethodResult r; if (cancellationToken.CanBeCanceled) { Task <DevToolsMethodResult> waitTask = protocolClient.WaitForMessageAsync(messageId); await Task.WhenAny(waitTask, Task.Delay(Timeout.Infinite, cancellationToken)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); r = waitTask.Result; } else { r = await protocolClient.WaitForMessageAsync(messageId).ConfigureAwait(false); } if (r.Success) { return(r.Result); } CefValue errorValue = CefApi.CefParseJSONBuffer(r.Result, CefJsonParserOptions.AllowTrailingCommas); if (errorValue is null) { throw new DevToolsProtocolException($"An unknown error occurred while trying to execute the '{method}' method."); } throw new DevToolsProtocolException(errorValue.GetDictionary().GetString("message")); }
/// <summary> /// Set the |value| associated with preference |name|. Returns true (1) if the /// value is set successfully and false (0) otherwise. If |value| is NULL the /// preference will be restored to its default value. If setting the preference /// fails then |error| will be populated with a detailed description of the /// problem. This function must be called on the browser process UI thread. /// </summary> public unsafe virtual bool SetPreference(string name, CefValue value, ref string error) { fixed(char *s0 = name) fixed(char *s2 = error) { var cstr0 = new cef_string_t { Str = s0, Length = name != null ? name.Length : 0 }; var cstr2 = new cef_string_t { Str = s2, Length = error != null ? error.Length : 0 }; var rv = NativeInstance->SetPreference(&cstr0, (value != null) ? value.GetNativeInstance() : null, &cstr2) != 0; error = CefString.ReadAndFree(&cstr2); GC.KeepAlive(this); return(rv); } }
/// <summary> /// Copies the V8 string into <see cref="CefValue"/> object. /// </summary> /// <param name="value">The destination <see cref="CefValue"/> object.</param> /// <returns>Returns true if the value was set successfully.</returns> public bool CopyV8StringToCefValue(CefValue value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (!IsString) { throw new InvalidOperationException(); } cef_string_userfree_t userfreeStr = NativeInstance->GetStringValue(); try { return(value.NativeInstance->SetString((cef_string_t *)userfreeStr.Base.Base) != 0); } finally { CefString.Free(userfreeStr); GC.KeepAlive(this); } }
/// <summary> /// Called after renderer process sends accessibility location changes to the /// browser process. /// </summary> public unsafe virtual void OnAccessibilityLocationChange(CefValue value) { }
/// <summary> /// Called after renderer process sends accessibility tree changes to the /// browser process. /// </summary> public unsafe virtual void OnAccessibilityTreeChange(CefValue value) { }
private static void ProcessXrayRequest(CefProcessMessageReceivedEventArgs e) { CefListValue args = e.Message.ArgumentList; CefProcessMessage message = new CefProcessMessage(XrayResponseKey); CefListValue retArgs = message.ArgumentList; retArgs.SetSize(2); retArgs.SetValue(0, args.GetValue(0)); CefValue retval = null; XrayAction queryAction = (XrayAction)args.GetInt(1); try { CefV8Context v8Context; XrayObject target = null; if (queryAction == XrayAction.GetGlobal) { v8Context = e.Frame.V8Context; } else { target = XrayHandle.FromCfxBinaryValue(args.GetBinary(2)).GetTarget(e.Frame); v8Context = target?.Context ?? e.Frame.V8Context; } if (!v8Context.IsValid) { throw new ObjectDeadException(); } if (!v8Context.Enter()) { throw new ObjectDeadException(); } try { CefV8Value rv = null; switch (queryAction) { case XrayAction.Get: long corsRid = ScriptableObjectProvider.Get(v8Context, target, args, out rv); if (corsRid != 0) { var xray = new XrayHandle(); xray.dataType = XrayDataType.CorsRedirect; xray.iRaw = corsRid; retval = new CefValue(); retval.SetBinary(xray.ToCfxBinaryValue()); retArgs.SetValue(1, retval); } break; case XrayAction.Set: ScriptableObjectProvider.Set(v8Context, target, args); break; case XrayAction.InvokeMember: rv = ScriptableObjectProvider.InvokeMember(v8Context, target, args); break; case XrayAction.Invoke: rv = ScriptableObjectProvider.Invoke(v8Context, target, args); break; case XrayAction.GetGlobal: rv = v8Context.GetGlobal(); break; default: throw new NotSupportedException(); } if (rv != null) { retval = ScriptableObjectProvider.CastCefV8ValueToCefValue(v8Context, rv, out bool isXray); if (!isXray) { rv.Dispose(); } retArgs.SetValue(1, retval); } } finally { v8Context.Exit(); } } catch (AccessViolationException) { throw; } catch (OutOfMemoryException) { throw; } catch (Exception ex) { //File.AppendAllText("G:\\outlog.txt", ex.GetType().Name + ": " + ex.Message + "\r\n" + ex.StackTrace + "\r\n"); retArgs.SetSize(4); retArgs.SetString(1, ex.Message); retArgs.SetString(2, ex.GetType().FullName); retArgs.SetString(3, ex.StackTrace); } //CfxValueType t = e.Message.ArgumentList.GetType(0); e.Frame.SendProcessMessage(CefProcessId.Browser, message); message.Dispose(); retval?.Dispose(); e.Handled = true; }
/// <summary> /// Called after renderer process sends accessibility location changes to the /// browser process. /// </summary> protected internal unsafe virtual void OnAccessibilityLocationChange(CefValue value) { }
/// <summary> /// Sets the value at the specified index. Returns true (1) if the value was /// set successfully. If |value| represents simple data then the underlying /// data will be copied and modifications to |value| will not modify this /// object. If |value| represents complex data (binary, dictionary or list) /// then the underlying data will be referenced and modifications to |value| /// will modify this object. /// </summary> public unsafe virtual bool SetValue(long index, CefValue value) { return(SafeCall(NativeInstance->SetValue(new UIntPtr((ulong)index), (value != null) ? value.GetNativeInstance() : null) != 0)); }
/// <summary> /// Returns the value at the specified index. For simple types the returned /// value will copy existing data and modifications to the value will not /// modify this object. For complex types (binary, dictionary and list) the /// returned value will reference existing data and modifications to the value /// will modify this object. /// </summary> public unsafe virtual CefValue GetValue(long index) { return(SafeCall(CefValue.Wrap(CefValue.Create, NativeInstance->GetValue(new UIntPtr((ulong)index))))); }
/// <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(CefValue that) { return(SafeCall(NativeInstance->IsSame((that != null) ? that.GetNativeInstance() : null) != 0)); }
/// <summary> /// Returns a copy of this object. The underlying data will also be copied. /// </summary> public unsafe virtual CefValue Copy() { return(SafeCall(CefValue.Wrap(CefValue.Create, NativeInstance->Copy()))); }