Skip to content

Commit efd719c

Browse files
authored
Merge 96aea4b into b86a3ac
2 parents b86a3ac + 96aea4b commit efd719c

File tree

8 files changed

+122
-13
lines changed

8 files changed

+122
-13
lines changed

CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ namespace CefSharp
8686
}
8787
}
8888
}
89+
90+
_jsBindingPropertyName = extraInfo->GetString("JsBindingPropertyName");
91+
_jsBindingPropertyNameCamelCase = extraInfo->GetString("JsBindingPropertyNameCamelCase");
8992
}
9093

9194
void CefAppUnmanagedWrapper::OnBrowserDestroyed(CefRefPtr<CefBrowser> browser)
@@ -123,13 +126,6 @@ namespace CefSharp
123126
auto global = context->GetGlobal();
124127
auto browserWrapper = FindBrowserWrapper(browser->GetIdentifier());
125128

126-
auto cefSharpObj = CefV8Value::CreateObject(NULL, NULL);
127-
global->SetValue("CefSharp", cefSharpObj, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
128-
129-
//We'll support both CefSharp and cefSharp, for those who prefer the JS style
130-
auto cefSharpObjCamelCase = CefV8Value::CreateObject(NULL, NULL);
131-
global->SetValue("cefSharp", cefSharpObjCamelCase, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
132-
133129
//TODO: JSB: Split functions into their own classes
134130
//Browser wrapper is only used for BindObjectAsync
135131
auto bindObjAsyncFunction = CefV8Value::CreateFunction(kBindObjectAsync, new BindObjectAsyncHandler(_registerBoundObjectRegistry, _javascriptObjects, browserWrapper));
@@ -138,11 +134,21 @@ namespace CefSharp
138134
auto isObjectCachedFunction = CefV8Value::CreateFunction(kIsObjectCached, new RegisterBoundObjectHandler(_javascriptObjects));
139135
auto postMessageFunction = CefV8Value::CreateFunction(kPostMessage, new JavascriptPostMessageHandler(rootObject == nullptr ? nullptr : rootObject->CallbackRegistry));
140136

141-
cefSharpObj->SetValue(kBindObjectAsync, bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
142-
cefSharpObj->SetValue(kDeleteBoundObject, unBindObjFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
143-
cefSharpObj->SetValue(kRemoveObjectFromCache, removeObjectFromCacheFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
144-
cefSharpObj->SetValue(kIsObjectCached, isObjectCachedFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
145-
cefSharpObj->SetValue(kPostMessage, postMessageFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
137+
if (!_jsBindingPropertyName.empty())
138+
{
139+
auto cefSharpObj = CefV8Value::CreateObject(NULL, NULL);
140+
global->SetValue(_jsBindingPropertyName, cefSharpObj, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
141+
142+
cefSharpObj->SetValue(kBindObjectAsync, bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
143+
cefSharpObj->SetValue(kDeleteBoundObject, unBindObjFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
144+
cefSharpObj->SetValue(kRemoveObjectFromCache, removeObjectFromCacheFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
145+
cefSharpObj->SetValue(kIsObjectCached, isObjectCachedFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
146+
cefSharpObj->SetValue(kPostMessage, postMessageFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
147+
}
148+
149+
//We'll support both CefSharp and cefSharp, for those who prefer the JS style
150+
auto cefSharpObjCamelCase = CefV8Value::CreateObject(NULL, NULL);
151+
global->SetValue(_jsBindingPropertyNameCamelCase, cefSharpObjCamelCase, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
146152

147153
cefSharpObjCamelCase->SetValue(kBindObjectAsyncCamelCase, bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
148154
cefSharpObjCamelCase->SetValue(kDeleteBoundObjectCamelCase, unBindObjFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);

CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ namespace CefSharp
2828
bool _focusedNodeChangedEnabled;
2929
bool _legacyBindingEnabled;
3030

31+
// The property names used to call binded objects
32+
CefString _jsBindingPropertyName;
33+
CefString _jsBindingPropertyNameCamelCase;
34+
3135
// The serialized registered object data waiting to be used.
3236
gcroot<Dictionary<String^, JavascriptObject^>^> _javascriptObjects;
3337

CefSharp.Core/ManagedCefBrowserAdapter.cpp

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void ManagedCefBrowserAdapter::CreateBrowser(IWindowInfo^ windowInfo, BrowserSet
4848

4949
legacyBindingEnabled = objectRepository->HasBoundObjects;
5050

51-
//For legacy binding we only add values if we have bond objects
51+
//For legacy binding we only add values if we have bond objects.
5252
if (legacyBindingEnabled)
5353
{
5454
auto listValue = CefListValue::Create();
@@ -61,6 +61,26 @@ void ManagedCefBrowserAdapter::CreateBrowser(IWindowInfo^ windowInfo, BrowserSet
6161

6262
extraInfo->SetBool("LegacyBindingEnabled", legacyBindingEnabled);
6363

64+
// Retrieve the configurable binding property names, throw exception if empty or illegal characters
65+
auto jsBindingPropertyName = _javaScriptObjectRepository->Settings->WindowPropertyName;
66+
if (!StringCheck::EnsureLettersAndNumbers(jsBindingPropertyName))
67+
{
68+
throw gcnew InvalidOperationException("CefBrowserHost::CreateBrowser invalid or illegal characters used for binding property names. Alphanumeric and underscores characters only.");
69+
}
70+
71+
if (_javaScriptObjectRepository->Settings->IsWindowPropertyNameCamelCase())
72+
{
73+
extraInfo->SetString("JsBindingPropertyNameCamelCase", StringUtils::ToNative(jsBindingPropertyName));
74+
}
75+
else
76+
{
77+
extraInfo->SetString("JsBindingPropertyName", StringUtils::ToNative(jsBindingPropertyName));
78+
79+
// Convert to camelCase
80+
auto camelCasePropertyName = _javaScriptObjectRepository->ConvertStringToCamelCase(jsBindingPropertyName);
81+
extraInfo->SetString("JsBindingPropertyNameCamelCase", StringUtils::ToNative(camelCasePropertyName));
82+
}
83+
6484
if (!CefBrowserHost::CreateBrowser(*cefWindowInfoWrapper->GetWindowInfo(), _clientAdapter.get(), addressNative,
6585
*browserSettings->_browserSettings, extraInfo, static_cast<CefRefPtr<CefRequestContext>>(requestContext)))
6686
{

CefSharp/CefSharp.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
<Compile Include="DefaultApp.cs" />
105105
<Compile Include="Enums\SchemeOptions.cs" />
106106
<Compile Include="Internals\IBrowserRefCounter.cs" />
107+
<Compile Include="Internals\JavascriptObjectRepositorySettings.cs" />
107108
<Compile Include="Internals\MimeTypeMapping.cs" />
108109
<Compile Include="Internals\NoOpBrowserRefCounter.cs" />
109110
<Compile Include="Internals\PathCheck.cs" />
@@ -112,6 +113,7 @@
112113
<Compile Include="Internals\CookieManagerDecorator.cs" />
113114
<Compile Include="Internals\ParentProcessMonitor.cs" />
114115
<Compile Include="Internals\HeaderNameValueCollection.cs" />
116+
<Compile Include="Internals\StringCheck.cs" />
115117
<Compile Include="Internals\TaskScheduler\LimitedConcurrencyLevelTaskScheduler.cs" />
116118
<Compile Include="IUrlRequest.cs" />
117119
<Compile Include="IUrlRequestClient.cs" />

CefSharp/IJavascriptObjectRepository.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
using System;
66
using CefSharp.Event;
7+
using CefSharp.Internals;
78

89
namespace CefSharp
910
{
@@ -13,6 +14,7 @@ namespace CefSharp
1314
/// </summary>
1415
public interface IJavascriptObjectRepository : IDisposable
1516
{
17+
JavascriptObjectRepositorySettings Settings { get; }
1618
/// <summary>
1719
/// Register an object for binding in Javascript. You can either
1820
/// register an object in advance or as part of the <see cref="ResolveObject"/>

CefSharp/Internals/JavascriptObjectRepository.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,16 @@ public bool HasBoundObjects
6464
get { return objects.Count > 0; }
6565
}
6666

67+
/// <summary>
68+
/// Configurable settings for this repository, such as setting the property name CefSharp injects into the window.
69+
/// </summary>
70+
public JavascriptObjectRepositorySettings Settings { get; }
71+
72+
public JavascriptObjectRepository()
73+
{
74+
Settings = new JavascriptObjectRepositorySettings();
75+
}
76+
6777
public bool IsBound(string name)
6878
{
6979
return objects.Values.Any(x => x.Name == name);
@@ -540,6 +550,11 @@ private static string GetJavascriptName(string str, bool camelCaseJavascriptName
540550
return str;
541551
}
542552

553+
return ConvertStringToCamelCase(str);
554+
}
555+
556+
public static string ConvertStringToCamelCase(string str)
557+
{
543558
if (string.IsNullOrEmpty(str))
544559
{
545560
return string.Empty;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright © 2020 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+
namespace CefSharp.Internals
6+
{
7+
public class JavascriptObjectRepositorySettings
8+
{
9+
public string WindowPropertyName { get; set; }
10+
11+
public JavascriptObjectRepositorySettings()
12+
{
13+
WindowPropertyName = "CefSharp";
14+
}
15+
16+
public bool IsWindowPropertyNameCamelCase()
17+
{
18+
return StringCheck.IsFirstCharacterLowercase(WindowPropertyName);
19+
}
20+
}
21+
}

CefSharp/Internals/StringCheck.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright © 2020 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.Text.RegularExpressions;
6+
7+
namespace CefSharp.Internals
8+
{
9+
public static class StringCheck
10+
{
11+
/// <summary>
12+
/// Regex check to ensure string contains only letters, numbers and underscores.
13+
/// </summary>
14+
/// <param name="stringToCheck"></param>
15+
/// <returns></returns>
16+
public static bool EnsureLettersAndNumbers(string stringToCheck)
17+
{
18+
if (!string.IsNullOrWhiteSpace(stringToCheck))
19+
{
20+
return Regex.IsMatch(stringToCheck, @"^\w+$");
21+
}
22+
23+
return false;
24+
}
25+
26+
public static bool IsFirstCharacterLowercase(string str)
27+
{
28+
if (!string.IsNullOrEmpty(str))
29+
{
30+
if (char.IsLetter(str[0]))
31+
{
32+
return char.IsLower(str[0]);
33+
}
34+
}
35+
36+
return false;
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)