From eecf3aded98fabd750fa9a16dcb7abc1094f6a4f Mon Sep 17 00:00:00 2001 From: amaitland Date: Tue, 28 Mar 2017 09:43:59 +1000 Subject: [PATCH] Add IWebBrowser.CanExecuteJavascriptInMainFrame property, set to true/false when V8Context is created/released Added checks in the execute/eval javscript methods in WebBrowserExtensions Made possibly by the addition of OnContextReleased IPC message being added --- CefSharp.Core/Internals/ClientAdapter.cpp | 4 ++++ CefSharp.OffScreen/ChromiumWebBrowser.cs | 12 ++++++++++++ CefSharp.WinForms/ChromiumWebBrowser.cs | 13 +++++++++++++ CefSharp.Wpf/ChromiumWebBrowser.cs | 12 ++++++++++++ CefSharp/IWebBrowser.cs | 9 ++++++++- CefSharp/Internals/IWebBrowserInternal.cs | 1 + CefSharp/WebBrowserExtensions.cs | 16 ++++++++++++++++ 7 files changed, 66 insertions(+), 1 deletion(-) diff --git a/CefSharp.Core/Internals/ClientAdapter.cpp b/CefSharp.Core/Internals/ClientAdapter.cpp index 63bafa5257..cf6c907ca5 100644 --- a/CefSharp.Core/Internals/ClientAdapter.cpp +++ b/CefSharp.Core/Internals/ClientAdapter.cpp @@ -1091,6 +1091,8 @@ namespace CefSharp CefFrameWrapper frameWrapper(browser->GetFrame(GetInt64(argList, 0))); handler->OnContextCreated(_browserControl, browserWrapper, %frameWrapper); + + _browserControl->SetCanExecuteJavascriptOnMainFrame(true); } handled = true; @@ -1105,6 +1107,8 @@ namespace CefSharp CefFrameWrapper frameWrapper(browser->GetFrame(GetInt64(argList, 0))); handler->OnContextReleased(_browserControl, browserWrapper, %frameWrapper); + + _browserControl->SetCanExecuteJavascriptOnMainFrame(false); } handled = true; diff --git a/CefSharp.OffScreen/ChromiumWebBrowser.cs b/CefSharp.OffScreen/ChromiumWebBrowser.cs index c60bf098a2..9e5cc570b0 100644 --- a/CefSharp.OffScreen/ChromiumWebBrowser.cs +++ b/CefSharp.OffScreen/ChromiumWebBrowser.cs @@ -282,6 +282,13 @@ public class ChromiumWebBrowser : IRenderWebBrowser /// public event EventHandler NewScreenshot; + /// + /// A flag that indicates if you can execute javascript in the main frame. + /// Flag is set to true in IRenderProcessMessageHandler.OnContextCreated. + /// and false in IRenderProcessMessageHandler.OnContextReleased + /// + public bool CanExecuteJavascriptInMainFrame { get; private set; } + /// /// Top Left position of the popup. /// @@ -938,6 +945,11 @@ void IWebBrowserInternal.SetTooltipText(string tooltipText) TooltipText = tooltipText; } + void IWebBrowserInternal.SetCanExecuteJavascriptOnMainFrame(bool canExecute) + { + CanExecuteJavascriptInMainFrame = canExecute; + } + /// /// Creates a new bitmap with the dimensions of firstBitmap, then /// draws the firstBitmap, then overlays the secondBitmap diff --git a/CefSharp.WinForms/ChromiumWebBrowser.cs b/CefSharp.WinForms/ChromiumWebBrowser.cs index 76b2082921..21a0432076 100644 --- a/CefSharp.WinForms/ChromiumWebBrowser.cs +++ b/CefSharp.WinForms/ChromiumWebBrowser.cs @@ -266,6 +266,14 @@ public class ChromiumWebBrowser : Control, IWebBrowserInternal, IWinFormsWebBrow [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] public bool IsBrowserInitialized { get; private set; } + /// + /// A flag that indicates if you can execute javascript in the main frame. + /// Flag is set to true in IRenderProcessMessageHandler.OnContextCreated. + /// and false in IRenderProcessMessageHandler.OnContextReleased + /// + [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] + public bool CanExecuteJavascriptInMainFrame { get; private set; } + /// /// Initializes static members of the class. /// @@ -664,6 +672,11 @@ void IWebBrowserInternal.OnLoadError(LoadErrorEventArgs args) } } + void IWebBrowserInternal.SetCanExecuteJavascriptOnMainFrame(bool canExecute) + { + CanExecuteJavascriptInMainFrame = canExecute; + } + /// /// Gets the browser adapter. /// diff --git a/CefSharp.Wpf/ChromiumWebBrowser.cs b/CefSharp.Wpf/ChromiumWebBrowser.cs index d0d9fbdb98..0d7287ed93 100644 --- a/CefSharp.Wpf/ChromiumWebBrowser.cs +++ b/CefSharp.Wpf/ChromiumWebBrowser.cs @@ -332,6 +332,13 @@ public class ChromiumWebBrowser : ContentControl, IRenderWebBrowser, IWpfWebBrow /// The redo command. public ICommand RedoCommand { get; private set; } + /// + /// A flag that indicates if you can execute javascript in the main frame. + /// Flag is set to true in IRenderProcessMessageHandler.OnContextCreated. + /// and false in IRenderProcessMessageHandler.OnContextReleased + /// + public bool CanExecuteJavascriptInMainFrame { get; private set; } + /// /// Initializes static members of the class. /// @@ -861,6 +868,11 @@ void IWebBrowserInternal.OnLoadError(LoadErrorEventArgs args) } } + void IWebBrowserInternal.SetCanExecuteJavascriptOnMainFrame(bool canExecute) + { + CanExecuteJavascriptInMainFrame = canExecute; + } + /// /// Gets the browser adapter. /// diff --git a/CefSharp/IWebBrowser.cs b/CefSharp/IWebBrowser.cs index 9624c85a45..32cf78a7d3 100644 --- a/CefSharp/IWebBrowser.cs +++ b/CefSharp/IWebBrowser.cs @@ -237,7 +237,14 @@ public interface IWebBrowser : IDisposable string TooltipText { get; } /// - /// Attempts to give focus to the IWpfWebBrowser control. + /// A flag that indicates if you can execute javascript in the main frame. + /// Flag is set to true in IRenderProcessMessageHandler.OnContextCreated. + /// and false in IRenderProcessMessageHandler.OnContextReleased + /// + bool CanExecuteJavascriptInMainFrame { get; } + + /// + /// Attempts to give focus to the IWebBrowser control. /// /// true if keyboard focus and logical focus were set to this element; false if only logical focus /// was set to this element, or if the call to this method did not force the focus to change. diff --git a/CefSharp/Internals/IWebBrowserInternal.cs b/CefSharp/Internals/IWebBrowserInternal.cs index 9656e0ba63..ac658bdbd1 100644 --- a/CefSharp/Internals/IWebBrowserInternal.cs +++ b/CefSharp/Internals/IWebBrowserInternal.cs @@ -18,6 +18,7 @@ public interface IWebBrowserInternal : IWebBrowser void SetLoadingStateChange(LoadingStateChangedEventArgs args); void SetTitle(TitleChangedEventArgs args); void SetTooltipText(string tooltipText); + void SetCanExecuteJavascriptOnMainFrame(bool canExecute); void OnFrameLoadStart(FrameLoadStartEventArgs args); void OnFrameLoadEnd(FrameLoadEndEventArgs args); diff --git a/CefSharp/WebBrowserExtensions.cs b/CefSharp/WebBrowserExtensions.cs index 0541b1503c..2912c4c6a9 100644 --- a/CefSharp/WebBrowserExtensions.cs +++ b/CefSharp/WebBrowserExtensions.cs @@ -207,6 +207,14 @@ public static void ExecuteScriptAsync(this IWebBrowser browser, string methodNam /// The Javascript code that should be executed. public static void ExecuteScriptAsync(this IWebBrowser browser, string script) { + if (browser.CanExecuteJavascriptInMainFrame == false) + { + throw new Exception(@"Unable to execute javascript at this time, scripts can only be executed within a V8Context. + Use the IWebBrowser.CanExecuteJavascriptInMainFrame property to guard against this exception. + See https://github.com/cefsharp/CefSharp/wiki/General-Usage#when-can-i-start-executing-javascript + for more details on when you can execute javascript."); + } + using (var frame = browser.GetMainFrame()) { ThrowExceptionIfFrameNull(frame); @@ -726,6 +734,14 @@ public static Task EvaluateScriptAsync(this IWebBrowser brow throw new ArgumentOutOfRangeException("timeout", "Timeout greater than Maximum allowable value of " + UInt32.MaxValue); } + if(browser.CanExecuteJavascriptInMainFrame == false) + { + throw new Exception(@"Unable to execute javascript at this time, scripts can only be executed within a V8Context. + Use the IWebBrowser.CanExecuteJavascriptInMainFrame property to guard against this exception. + See https://github.com/cefsharp/CefSharp/wiki/General-Usage#when-can-i-start-executing-javascript + for more details on when you can execute javascript."); + } + using (var frame = browser.GetMainFrame()) { ThrowExceptionIfFrameNull(frame);