| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -77,20 +77,7 @@ namespace CefSharp | |||
| 77 | 77 | { | |
| 78 | 78 | auto javascriptObjects = DeserializeJsObjects(objects, 0); | |
| 79 | 79 | ||
| 80 | - for each (JavascriptObject ^ obj in Enumerable::OfType<JavascriptObject^>(javascriptObjects)) | ||
| 81 | - { | ||
| 82 | - //Using LegacyBinding with multiple ChromiumWebBrowser instances that share the same | ||
| 83 | - //render process and using LegacyBinding will cause problems for the limited caching implementation | ||
| 84 | - //that exists at the moment, for now we'll remove an object if already exists, same behaviour | ||
| 85 | - //as the new binding method. | ||
| 86 | - //TODO: This should be removed when https://github.com/cefsharp/CefSharp/issues/2306 | ||
| 87 | - //Is complete as objects will be stored at the browser level | ||
| 88 | - if (_javascriptObjects->ContainsKey(obj->JavascriptName)) | ||
| 89 | - { | ||
| 90 | - _javascriptObjects->Remove(obj->JavascriptName); | ||
| 91 | - } | ||
| 92 | - _javascriptObjects->Add(obj->JavascriptName, obj); | ||
| 93 | - } | ||
| 80 | + _javascriptObjectCache->InsertOrUpdate(browser->GetIdentifier(), javascriptObjects); | ||
| 94 | 81 | } | |
| 95 | 82 | } | |
| 96 | 83 | ||
@@ -113,6 +100,8 @@ namespace CefSharp | |||
| 113 | 100 | _onBrowserDestroyed->Invoke(wrapper); | |
| 114 | 101 | delete wrapper; | |
| 115 | 102 | } | |
| 103 | + | ||
| 104 | + _javascriptObjectCache->ClearCache(browser->GetIdentifier()); | ||
| 116 | 105 | }; | |
| 117 | 106 | ||
| 118 | 107 | void CefAppUnmanagedWrapper::OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context) | |
@@ -130,9 +119,11 @@ namespace CefSharp | |||
| 130 | 119 | ||
| 131 | 120 | if (_legacyBindingEnabled) | |
| 132 | 121 | { | |
| 133 | - if (_javascriptObjects->Count > 0 && rootObject != nullptr) | ||
| 122 | + auto values = _javascriptObjectCache->GetCacheValues(browser->GetIdentifier()); | ||
| 123 | + | ||
| 124 | + if (values->Count > 0 && rootObject != nullptr) | ||
| 134 | 125 | { | |
| 135 | - rootObject->Bind(_javascriptObjects->Values, context->GetGlobal()); | ||
| 126 | + rootObject->Bind(values, context->GetGlobal()); | ||
| 136 | 127 | } | |
| 137 | 128 | } | |
| 138 | 129 | ||
@@ -142,13 +133,14 @@ namespace CefSharp | |||
| 142 | 133 | auto global = context->GetGlobal(); | |
| 143 | 134 | auto browserWrapper = FindBrowserWrapper(browser->GetIdentifier()); | |
| 144 | 135 | auto processId = System::Diagnostics::Process::GetCurrentProcess()->Id; | |
| 136 | + auto objectCache = _javascriptObjectCache->GetCache(browser->GetIdentifier()); | ||
| 145 | 137 | ||
| 146 | 138 | //TODO: JSB: Split functions into their own classes | |
| 147 | 139 | //Browser wrapper is only used for BindObjectAsync | |
| 148 | - auto bindObjAsyncFunction = CefV8Value::CreateFunction(kBindObjectAsync, new BindObjectAsyncHandler(_registerBoundObjectRegistry, _javascriptObjects, browserWrapper)); | ||
| 149 | - auto unBindObjFunction = CefV8Value::CreateFunction(kDeleteBoundObject, new RegisterBoundObjectHandler(_javascriptObjects)); | ||
| 150 | - auto removeObjectFromCacheFunction = CefV8Value::CreateFunction(kRemoveObjectFromCache, new RegisterBoundObjectHandler(_javascriptObjects)); | ||
| 151 | - auto isObjectCachedFunction = CefV8Value::CreateFunction(kIsObjectCached, new RegisterBoundObjectHandler(_javascriptObjects)); | ||
| 140 | + auto bindObjAsyncFunction = CefV8Value::CreateFunction(kBindObjectAsync, new BindObjectAsyncHandler(_registerBoundObjectRegistry, objectCache, browserWrapper)); | ||
| 141 | + auto unBindObjFunction = CefV8Value::CreateFunction(kDeleteBoundObject, new RegisterBoundObjectHandler(objectCache)); | ||
| 142 | + auto removeObjectFromCacheFunction = CefV8Value::CreateFunction(kRemoveObjectFromCache, new RegisterBoundObjectHandler(objectCache)); | ||
| 143 | + auto isObjectCachedFunction = CefV8Value::CreateFunction(kIsObjectCached, new RegisterBoundObjectHandler(objectCache)); | ||
| 152 | 144 | auto postMessageFunction = CefV8Value::CreateFunction(kPostMessage, new JavascriptPostMessageHandler(rootObject == nullptr ? nullptr : rootObject->CallbackRegistry)); | |
| 153 | 145 | auto promiseHandlerFunction = CefV8Value::CreateFunction(kSendEvalScriptResponse, new JavascriptPromiseHandler()); | |
| 154 | 146 | ||
@@ -621,15 +613,7 @@ namespace CefSharp | |||
| 621 | 613 | auto javascriptObjects = DeserializeJsObjects(argList, 1); | |
| 622 | 614 | ||
| 623 | 615 | //Caching of JavascriptObjects | |
| 624 | - //TODO: JSB Should caching be configurable? On a per object basis? | ||
| 625 | - for each (JavascriptObject ^ obj in Enumerable::OfType<JavascriptObject^>(javascriptObjects)) | ||
| 626 | - { | ||
| 627 | - if (_javascriptObjects->ContainsKey(obj->JavascriptName)) | ||
| 628 | - { | ||
| 629 | - _javascriptObjects->Remove(obj->JavascriptName); | ||
| 630 | - } | ||
| 631 | - _javascriptObjects->Add(obj->JavascriptName, obj); | ||
| 632 | - } | ||
| 616 | + _javascriptObjectCache->InsertOrUpdate(browser->GetIdentifier(), javascriptObjects); | ||
| 633 | 617 | ||
| 634 | 618 | auto rootObject = GetJsRootObjectWrapper(browser->GetIdentifier(), frame->GetIdentifier()); | |
| 635 | 619 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -35,25 +35,33 @@ namespace CefSharp | |||
| 35 | 35 | CefString _jsBindingPropertyNameCamelCase; | |
| 36 | 36 | ||
| 37 | 37 | // The serialized registered object data waiting to be used. | |
| 38 | - gcroot<Dictionary<String^, JavascriptObject^>^> _javascriptObjects; | ||
| 38 | + gcroot<IJavaScriptObjectCache^> _javascriptObjectCache; | ||
| 39 | 39 | ||
| 40 | 40 | gcroot<RegisterBoundObjectRegistry^> _registerBoundObjectRegistry; | |
| 41 | 41 | ||
| 42 | 42 | public: | |
| 43 | 43 | static const CefString kPromiseCreatorScript; | |
| 44 | 44 | ||
| 45 | - CefAppUnmanagedWrapper(IRenderProcessHandler^ handler, List<CefCustomScheme^>^ schemes, bool enableFocusedNodeChanged, Action<CefBrowserWrapper^>^ onBrowserCreated, Action<CefBrowserWrapper^>^ onBrowserDestroyed) : SubProcessApp(schemes) | ||
| 45 | + CefAppUnmanagedWrapper(IRenderProcessHandler^ handler, List<CefCustomScheme^>^ schemes, bool jsbCachePerBrowser, bool enableFocusedNodeChanged, Action<CefBrowserWrapper^>^ onBrowserCreated, Action<CefBrowserWrapper^>^ onBrowserDestroyed) : SubProcessApp(schemes) | ||
| 46 | 46 | { | |
| 47 | 47 | _handler = handler; | |
| 48 | 48 | _onBrowserCreated = onBrowserCreated; | |
| 49 | 49 | _onBrowserDestroyed = onBrowserDestroyed; | |
| 50 | 50 | _browserWrappers = gcnew ConcurrentDictionary<int, CefBrowserWrapper^>(); | |
| 51 | 51 | _focusedNodeChangedEnabled = enableFocusedNodeChanged; | |
| 52 | - _javascriptObjects = gcnew Dictionary<String^, JavascriptObject^>(); | ||
| 53 | 52 | _registerBoundObjectRegistry = gcnew RegisterBoundObjectRegistry(); | |
| 54 | 53 | _legacyBindingEnabled = false; | |
| 55 | 54 | _jsBindingPropertyName = "CefSharp"; | |
| 56 | 55 | _jsBindingPropertyNameCamelCase = "cefSharp"; | |
| 56 | + | ||
| 57 | + if (jsbCachePerBrowser) | ||
| 58 | + { | ||
| 59 | + _javascriptObjectCache = gcnew PerBrowserJavaScriptObjectCache(); | ||
| 60 | + } | ||
| 61 | + else | ||
| 62 | + { | ||
| 63 | + _javascriptObjectCache = gcnew LegacyJavaScriptObjectCache(); | ||
| 64 | + } | ||
| 57 | 65 | } | |
| 58 | 66 | ||
| 59 | 67 | ~CefAppUnmanagedWrapper() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -33,9 +33,10 @@ namespace CefSharp | |||
| 33 | 33 | auto onBrowserCreated = gcnew Action<CefBrowserWrapper^>(this, &SubProcess::OnBrowserCreated); | |
| 34 | 34 | auto onBrowserDestroyed = gcnew Action<CefBrowserWrapper^>(this, &SubProcess::OnBrowserDestroyed); | |
| 35 | 35 | auto schemes = CefCustomScheme::ParseCommandLineArguments(args); | |
| 36 | + auto jsbCachePerBrowser = CommandLineArgsParser::HasArgument(args, CefSharpArguments::PerBrowserJavaScriptObjectCache); | ||
| 36 | 37 | auto enableFocusedNodeChanged = CommandLineArgsParser::HasArgument(args, CefSharpArguments::FocusedNodeChangedEnabledArgument); | |
| 37 | 38 | ||
| 38 | - _cefApp = new CefAppUnmanagedWrapper(handler, schemes, enableFocusedNodeChanged, onBrowserCreated, onBrowserDestroyed); | ||
| 39 | + _cefApp = new CefAppUnmanagedWrapper(handler, schemes, jsbCachePerBrowser, enableFocusedNodeChanged, onBrowserCreated, onBrowserDestroyed); | ||
| 39 | 40 | } | |
| 40 | 41 | ||
| 41 | 42 | !SubProcess() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ public static class CefSharpArguments | |||
| 10 | 10 | public const string HostProcessIdArgument = "--host-process-id"; | |
| 11 | 11 | public const string CustomSchemeArgument = "--custom-scheme"; | |
| 12 | 12 | public const string FocusedNodeChangedEnabledArgument = "--focused-node-enabled"; | |
| 13 | + public const string PerBrowserJavaScriptObjectCache = "--jsb-cache-perbrowser"; | ||
| 13 | 14 | public const string SubProcessTypeArgument = "--type"; | |
| 14 | 15 | public const string ExitIfParentProcessClosed = "--cefsharpexitsub"; | |
| 15 | 16 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,42 @@ | |||
| 1 | + // Copyright © 2023 The CefSharp Authors. All rights reserved. | ||
| 2 | + // | ||
| 3 | + // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. | ||
| 4 | + | ||
| 5 | + using System.Collections.Generic; | ||
| 6 | + | ||
| 7 | + namespace CefSharp.Internals | ||
| 8 | + { | ||
| 9 | + /// <summary> | ||
| 10 | + /// Render Process JavaScript Binding (JSB) object cache | ||
| 11 | + /// </summary> | ||
| 12 | + public interface IJavaScriptObjectCache | ||
| 13 | + { | ||
| 14 | + /// <summary> | ||
| 15 | + /// Remove the Browser specific Cache | ||
| 16 | + /// </summary> | ||
| 17 | + /// <param name="browserId">browser Id</param> | ||
| 18 | + void ClearCache(int browserId); | ||
| 19 | + /// <summary> | ||
| 20 | + /// Gets the browser specific cache (dictionary) based on it's Id | ||
| 21 | + /// </summary> | ||
| 22 | + /// <param name="browserId">browser Id</param> | ||
| 23 | + /// <returns>Dictionary of cache <see cref="JavascriptObject"/>'s.</returns> | ||
| 24 | + /// <exception cref="InvalidOperationException"></exception> | ||
| 25 | + Dictionary<string, JavascriptObject> GetCache(int browserId); | ||
| 26 | + /// <summary> | ||
| 27 | + /// Gets a collection of <see cref="JavascriptObject"/>s | ||
| 28 | + /// for the given <paramref name="browserId"/> | ||
| 29 | + /// </summary> | ||
| 30 | + /// <param name="browserId">browser Id</param> | ||
| 31 | + /// <returns>Collection of current bound objects for the browser</returns> | ||
| 32 | + /// <exception cref="InvalidOperationException"></exception> | ||
| 33 | + ICollection<JavascriptObject> GetCacheValues(int browserId); | ||
| 34 | + /// <summary> | ||
| 35 | + /// Insert or Update the <paramref name="javascriptObject"/> within the Cache | ||
| 36 | + /// </summary> | ||
| 37 | + /// <param name="browserId">browser id</param> | ||
| 38 | + /// <param name="javascriptObject">JavaScript object</param> | ||
| 39 | + /// <exception cref="InvalidOperationException"></exception> | ||
| 40 | + void InsertOrUpdate(int browserId, IList<JavascriptObject> javascriptObjects); | ||
| 41 | + } | ||
| 42 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,45 @@ | |||
| 1 | + // Copyright © 2023 The CefSharp Authors. All rights reserved. | ||
| 2 | + // | ||
| 3 | + // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. | ||
| 4 | + | ||
| 5 | + using System.Collections.Generic; | ||
| 6 | + | ||
| 7 | + namespace CefSharp.Internals | ||
| 8 | + { | ||
| 9 | + /// <summary> | ||
| 10 | + /// Render Process JavaScript Binding (JSB) object cache | ||
| 11 | + /// Legacy Behaviour, objects are cache per process. | ||
| 12 | + /// </summary> | ||
| 13 | + public class LegacyJavaScriptObjectCache : IJavaScriptObjectCache | ||
| 14 | + { | ||
| 15 | + private readonly Dictionary<string, JavascriptObject> cache | ||
| 16 | + = new Dictionary<string, JavascriptObject>(); | ||
| 17 | + | ||
| 18 | + /// <inheritdoc/> | ||
| 19 | + public void ClearCache(int browserId) | ||
| 20 | + { | ||
| 21 | + // NO OP | ||
| 22 | + } | ||
| 23 | + | ||
| 24 | + /// <inheritdoc/> | ||
| 25 | + public void InsertOrUpdate(int browserId, IList<JavascriptObject> javascriptObjects) | ||
| 26 | + { | ||
| 27 | + foreach (var obj in javascriptObjects) | ||
| 28 | + { | ||
| 29 | + cache[obj.Name] = obj; | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + /// <inheritdoc/> | ||
| 34 | + public ICollection<JavascriptObject> GetCacheValues(int browserId) | ||
| 35 | + { | ||
| 36 | + return cache.Values; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /// <inheritdoc/> | ||
| 40 | + public Dictionary<string, JavascriptObject> GetCache(int browserId) | ||
| 41 | + { | ||
| 42 | + return cache; | ||
| 43 | + } | ||
| 44 | + } | ||
| 45 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,69 @@ | |||
| 1 | + // Copyright © 2023 The CefSharp Authors. All rights reserved. | ||
| 2 | + // | ||
| 3 | + // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. | ||
| 4 | + | ||
| 5 | + using System; | ||
| 6 | + using System.Collections.Generic; | ||
| 7 | + | ||
| 8 | + namespace CefSharp.Internals | ||
| 9 | + { | ||
| 10 | + /// <summary> | ||
| 11 | + /// Render Process JavaScript Binding (JSB) object cache | ||
| 12 | + /// Stores bound objects per CefBrowser. | ||
| 13 | + /// </summary> | ||
| 14 | + public class PerBrowserJavaScriptObjectCache : IJavaScriptObjectCache | ||
| 15 | + { | ||
| 16 | + private readonly Dictionary<int, Dictionary<string, JavascriptObject>> cache | ||
| 17 | + = new Dictionary<int, Dictionary<string, JavascriptObject>>(); | ||
| 18 | + | ||
| 19 | + /// <inheritdoc/> | ||
| 20 | + public void ClearCache(int browserId) | ||
| 21 | + { | ||
| 22 | + cache.Remove(browserId); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + /// <inheritdoc/> | ||
| 26 | + public void InsertOrUpdate(int browserId, IList<JavascriptObject> javascriptObjects) | ||
| 27 | + { | ||
| 28 | + var dict = GetCacheInternal(browserId); | ||
| 29 | + | ||
| 30 | + foreach (var obj in javascriptObjects) | ||
| 31 | + { | ||
| 32 | + dict[obj.Name] = obj; | ||
| 33 | + } | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + /// <inheritdoc/> | ||
| 37 | + public ICollection<JavascriptObject> GetCacheValues(int browserId) | ||
| 38 | + { | ||
| 39 | + if (cache.TryGetValue(browserId, out var dict)) | ||
| 40 | + { | ||
| 41 | + return dict.Values; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + return new List<JavascriptObject>(); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + /// <inheritdoc/> | ||
| 48 | + public Dictionary<string, JavascriptObject> GetCache(int browserId) | ||
| 49 | + { | ||
| 50 | + var dict = GetCacheInternal(browserId); | ||
| 51 | + | ||
| 52 | + return dict; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + private Dictionary<string, JavascriptObject> GetCacheInternal(int browserId) | ||
| 56 | + { | ||
| 57 | + Dictionary<string, JavascriptObject> dict; | ||
| 58 | + | ||
| 59 | + if (!cache.TryGetValue(browserId, out dict)) | ||
| 60 | + { | ||
| 61 | + dict = new Dictionary<string, JavascriptObject>(); | ||
| 62 | + | ||
| 63 | + cache.Add(browserId, dict); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + return dict; | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + } | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments