diff --git a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp index 95d1ae2f7e..91b45bf450 100644 --- a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp +++ b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp @@ -62,7 +62,11 @@ namespace CefSharp _onBrowserCreated->Invoke(wrapper); //Multiple CefBrowserWrappers created when opening popups - _browserWrappers->TryAdd(browser->GetIdentifier(), wrapper); + auto browserId = browser->GetIdentifier(); + _browserWrappers->TryAdd(browserId, wrapper); + + auto javascriptBindingSettings = gcnew JavascriptBindingSettings(); + _browserJavascriptBindingSettings->TryAdd(browserId, javascriptBindingSettings); if (!extraInfo.get()) { @@ -103,19 +107,19 @@ namespace CefSharp if (extraInfo->HasKey("JavascriptBindingApiEnabled")) { - wrapper->JavascriptBindingApiEnabled = extraInfo->GetBool("JavascriptBindingApiEnabled"); + javascriptBindingSettings->JavascriptBindingApiEnabled = extraInfo->GetBool("JavascriptBindingApiEnabled"); } if (extraInfo->HasKey("JavascriptBindingApiHasAllowOrigins")) { - wrapper->JavascriptBindingApiHasAllowOrigins = extraInfo->GetBool("JavascriptBindingApiHasAllowOrigins"); + javascriptBindingSettings->JavascriptBindingApiHasAllowOrigins = extraInfo->GetBool("JavascriptBindingApiHasAllowOrigins"); - if (wrapper->JavascriptBindingApiHasAllowOrigins) + if (javascriptBindingSettings->JavascriptBindingApiHasAllowOrigins) { auto allowOrigins = extraInfo->GetList("JavascriptBindingApiAllowOrigins"); if (allowOrigins.get() && allowOrigins->IsValid()) { - wrapper->JavascriptBindingApiAllowOrigins = allowOrigins->Copy(); + javascriptBindingSettings->JavascriptBindingApiAllowOrigins = allowOrigins->Copy(); } } } @@ -136,6 +140,9 @@ namespace CefSharp _onBrowserDestroyed->Invoke(wrapper); delete wrapper; } + + // Don't remove javascript settings because cef is unreliable in calling OnBrowserCreated/OnBrowserDestroyed consistently: + // https://github.com/cefsharp/CefSharp/issues/5228 }; void CefAppUnmanagedWrapper::OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context) @@ -165,9 +172,10 @@ namespace CefSharp } } - auto browserWrapper = FindBrowserWrapper(browser->GetIdentifier()); + JavascriptBindingSettings^ javascriptBindingSettings = nullptr; + _browserJavascriptBindingSettings->TryGetValue(browser->GetIdentifier(), javascriptBindingSettings); - if (browserWrapper != nullptr && browserWrapper->JavascriptBindingApiEnabled && IsJavascriptBindingApiAllowed(browserWrapper, frame)) + if (IsJavascriptBindingApiAllowed(javascriptBindingSettings, frame)) { //TODO: Look at adding some sort of javascript mapping layer to reduce the code duplication auto global = context->GetGlobal(); @@ -347,14 +355,24 @@ namespace CefSharp return rootObject; } - bool CefAppUnmanagedWrapper::IsJavascriptBindingApiAllowed(CefBrowserWrapper^ browserWrapper, CefRefPtr frame) + bool CefAppUnmanagedWrapper::IsJavascriptBindingApiAllowed(JavascriptBindingSettings^ javascriptBindingSettings, CefRefPtr frame) { - if (browserWrapper == nullptr || !browserWrapper->JavascriptBindingApiHasAllowOrigins) + if (javascriptBindingSettings == nullptr) + { + return false; + } + + if (!javascriptBindingSettings->JavascriptBindingApiEnabled) + { + return false; + } + + if (!javascriptBindingSettings->JavascriptBindingApiHasAllowOrigins) { return true; } - auto allowOrigins = browserWrapper->JavascriptBindingApiAllowOrigins; + auto allowOrigins = javascriptBindingSettings->JavascriptBindingApiAllowOrigins; if (!allowOrigins.get()) { return false; diff --git a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h index 680a48791b..d0e3506d3a 100644 --- a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h +++ b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h @@ -9,6 +9,7 @@ #include "SubProcessApp.h" #include "CefBrowserWrapper.h" +#include "JavascriptBindingSettings.h" #include "RegisterBoundObjectRegistry.h" using namespace System::Collections::Generic; @@ -26,6 +27,7 @@ namespace CefSharp gcroot^> _onBrowserCreated; gcroot^> _onBrowserDestroyed; gcroot^> _browserWrappers; + gcroot^> _browserJavascriptBindingSettings; gcroot^> _jsRootObjectWrappersByFrameId; bool _focusedNodeChangedEnabled; bool _legacyBindingEnabled; @@ -38,7 +40,7 @@ namespace CefSharp gcroot^> _javascriptObjects; gcroot _registerBoundObjectRegistry; - bool IsJavascriptBindingApiAllowed(CefBrowserWrapper^ browserWrapper, CefRefPtr frame); + bool IsJavascriptBindingApiAllowed(JavascriptBindingSettings^ javascriptBindingSettings, CefRefPtr frame); public: static const CefString kPromiseCreatorScript; @@ -49,6 +51,7 @@ namespace CefSharp _onBrowserCreated = onBrowserCreated; _onBrowserDestroyed = onBrowserDestroyed; _browserWrappers = gcnew ConcurrentDictionary(); + _browserJavascriptBindingSettings = gcnew ConcurrentDictionary(); _jsRootObjectWrappersByFrameId = gcnew ConcurrentDictionary(); _focusedNodeChangedEnabled = enableFocusedNodeChanged; _javascriptObjects = gcnew Dictionary(); @@ -62,7 +65,7 @@ namespace CefSharp { if (!Object::ReferenceEquals(_browserWrappers, nullptr)) { - for each (CefBrowserWrapper ^ browser in Enumerable::OfType(_browserWrappers)) + for each (CefBrowserWrapper ^ browser in _browserWrappers->Values) { delete browser; } @@ -70,9 +73,19 @@ namespace CefSharp _browserWrappers = nullptr; } + if (!Object::ReferenceEquals(_browserJavascriptBindingSettings, nullptr)) + { + for each (JavascriptBindingSettings ^ javascriptBindingSettings in _browserJavascriptBindingSettings->Values) + { + delete javascriptBindingSettings; + } + + _browserJavascriptBindingSettings = nullptr; + } + if (!Object::ReferenceEquals(_jsRootObjectWrappersByFrameId, nullptr)) { - for each (JavascriptRootObjectWrapper^ rootObject in Enumerable::OfType(_jsRootObjectWrappersByFrameId)) + for each (JavascriptRootObjectWrapper^ rootObject in _jsRootObjectWrappersByFrameId->Values) { delete rootObject; } diff --git a/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h b/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h index 50b9e304a8..934725eaeb 100644 --- a/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h +++ b/CefSharp.BrowserSubprocess.Core/CefBrowserWrapper.h @@ -28,7 +28,6 @@ namespace CefSharp { private: MCefRefPtr _cefBrowser; - MCefRefPtr _javascriptBindingApiAllowOrigins; public: CefBrowserWrapper(const CefRefPtr &cefBrowser) @@ -36,17 +35,11 @@ namespace CefSharp _cefBrowser = cefBrowser.get(); BrowserId = cefBrowser->GetIdentifier(); IsPopup = cefBrowser->IsPopup(); - - JavascriptBindingApiEnabled = true; - JavascriptBindingApiHasAllowOrigins = false; - JavascriptBindingApiAllowOrigins = nullptr; } !CefBrowserWrapper() { _cefBrowser = nullptr; - - _javascriptBindingApiAllowOrigins = nullptr; } ~CefBrowserWrapper() @@ -56,13 +49,6 @@ namespace CefSharp property int BrowserId; property bool IsPopup; - property bool JavascriptBindingApiEnabled; - property bool JavascriptBindingApiHasAllowOrigins; - property CefRefPtr JavascriptBindingApiAllowOrigins - { - CefRefPtr get() { return _javascriptBindingApiAllowOrigins.get(); } - void set(CefRefPtr value) { _javascriptBindingApiAllowOrigins = value.get(); } - } #ifndef NETCOREAPP // This allows us to create the WCF proxies back to our parent process. diff --git a/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj b/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj index 7dfe15f578..1c77a92143 100644 --- a/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj +++ b/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.netcore.vcxproj @@ -278,6 +278,7 @@ + diff --git a/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj b/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj index 188d45921a..60f3493bbc 100644 --- a/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj +++ b/CefSharp.BrowserSubprocess.Core/CefSharp.BrowserSubprocess.Core.vcxproj @@ -188,6 +188,7 @@ + diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptBindingSettings.h b/CefSharp.BrowserSubprocess.Core/JavascriptBindingSettings.h new file mode 100644 index 0000000000..8ef2f888bb --- /dev/null +++ b/CefSharp.BrowserSubprocess.Core/JavascriptBindingSettings.h @@ -0,0 +1,47 @@ +// Copyright © 2013 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. + +#pragma once + +#include "include/cef_v8.h" + +#include "Stdafx.h" + +namespace CefSharp +{ + namespace BrowserSubprocess + { + private ref class JavascriptBindingSettings + { + private: + MCefRefPtr _javascriptBindingApiAllowOrigins; + + public: + JavascriptBindingSettings() + { + JavascriptBindingApiEnabled = true; + JavascriptBindingApiHasAllowOrigins = false; + JavascriptBindingApiAllowOrigins = nullptr; + } + + !JavascriptBindingSettings() + { + _javascriptBindingApiAllowOrigins = nullptr; + } + + ~JavascriptBindingSettings() + { + this->!JavascriptBindingSettings(); + } + + property bool JavascriptBindingApiEnabled; + property bool JavascriptBindingApiHasAllowOrigins; + property CefRefPtr JavascriptBindingApiAllowOrigins + { + CefRefPtr get() { return _javascriptBindingApiAllowOrigins.get(); } + void set(CefRefPtr value) { _javascriptBindingApiAllowOrigins = value.get(); } + } + }; + } +}