Skip to content

Commit ae41e10

Browse files
committed
Core - Javascript Binding Configure Property Name
- Rename settings object to JavascriptBindingSettings - Validate JavascriptBindingSettings.JsBindingGlobalObjectName in setter to provide immediate feedback - Add FreezableBase which throws exception when frozen (we can reuse this for some other settings classes) - Add some basic Unit Tests (More would be better) Follow on from #3126
1 parent 6669110 commit ae41e10

19 files changed

+398
-100
lines changed

CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,17 @@ namespace CefSharp
8787
}
8888
}
8989

90-
_jsBindingPropertyName = extraInfo->GetString("JsBindingPropertyName");
91-
_jsBindingPropertyNameCamelCase = extraInfo->GetString("JsBindingPropertyNameCamelCase");
90+
if (extraInfo->HasKey("JsBindingPropertyName") || extraInfo->HasKey("JsBindingPropertyNameCamelCase"))
91+
{
92+
//TODO: Create constant for these and legacy binding strings above
93+
_jsBindingPropertyName = extraInfo->GetString("JsBindingPropertyName");
94+
_jsBindingPropertyNameCamelCase = extraInfo->GetString("JsBindingPropertyNameCamelCase");
95+
}
96+
else
97+
{
98+
_jsBindingPropertyName = "CefSharp";
99+
_jsBindingPropertyNameCamelCase = "cefSharp";
100+
}
92101
}
93102

94103
void CefAppUnmanagedWrapper::OnBrowserDestroyed(CefRefPtr<CefBrowser> browser)
@@ -134,27 +143,33 @@ namespace CefSharp
134143
auto isObjectCachedFunction = CefV8Value::CreateFunction(kIsObjectCached, new RegisterBoundObjectHandler(_javascriptObjects));
135144
auto postMessageFunction = CefV8Value::CreateFunction(kPostMessage, new JavascriptPostMessageHandler(rootObject == nullptr ? nullptr : rootObject->CallbackRegistry));
136145

137-
if (!_jsBindingPropertyName.empty())
146+
//By default We'll support both CefSharp and cefSharp, for those who prefer the JS style
147+
auto createCefSharpObj = !_jsBindingPropertyName.empty();
148+
auto createCefSharpObjCamelCase = !_jsBindingPropertyNameCamelCase.empty();
149+
150+
if (createCefSharpObj)
138151
{
139152
auto cefSharpObj = CefV8Value::CreateObject(NULL, NULL);
140-
global->SetValue(_jsBindingPropertyName, cefSharpObj, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
141-
142153
cefSharpObj->SetValue(kBindObjectAsync, bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
143154
cefSharpObj->SetValue(kDeleteBoundObject, unBindObjFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
144155
cefSharpObj->SetValue(kRemoveObjectFromCache, removeObjectFromCacheFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
145156
cefSharpObj->SetValue(kIsObjectCached, isObjectCachedFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
146157
cefSharpObj->SetValue(kPostMessage, postMessageFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
147-
}
148158

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);
159+
global->SetValue(_jsBindingPropertyName, cefSharpObj, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
160+
}
152161

153-
cefSharpObjCamelCase->SetValue(kBindObjectAsyncCamelCase, bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
154-
cefSharpObjCamelCase->SetValue(kDeleteBoundObjectCamelCase, unBindObjFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
155-
cefSharpObjCamelCase->SetValue(kRemoveObjectFromCacheCamelCase, removeObjectFromCacheFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
156-
cefSharpObjCamelCase->SetValue(kIsObjectCachedCamelCase, isObjectCachedFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
157-
cefSharpObjCamelCase->SetValue(kPostMessageCamelCase, postMessageFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
162+
if (createCefSharpObjCamelCase)
163+
{
164+
auto cefSharpObjCamelCase = CefV8Value::CreateObject(NULL, NULL);
165+
cefSharpObjCamelCase->SetValue(kBindObjectAsyncCamelCase, bindObjAsyncFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
166+
cefSharpObjCamelCase->SetValue(kDeleteBoundObjectCamelCase, unBindObjFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
167+
cefSharpObjCamelCase->SetValue(kRemoveObjectFromCacheCamelCase, removeObjectFromCacheFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
168+
cefSharpObjCamelCase->SetValue(kIsObjectCachedCamelCase, isObjectCachedFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
169+
cefSharpObjCamelCase->SetValue(kPostMessageCamelCase, postMessageFunction, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_NONE);
170+
171+
global->SetValue(_jsBindingPropertyNameCamelCase, cefSharpObjCamelCase, CefV8Value::PropertyAttribute::V8_PROPERTY_ATTRIBUTE_READONLY);
172+
}
158173

159174
//Send a message to the browser processing signaling that OnContextCreated has been called
160175
//only param is the FrameId. Previous sent only for main frame, now sent for all frames

CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace CefSharp
2828
bool _focusedNodeChangedEnabled;
2929
bool _legacyBindingEnabled;
3030

31-
// The property names used to call binded objects
31+
// The property names used to call bound objects
3232
CefString _jsBindingPropertyName;
3333
CefString _jsBindingPropertyNameCamelCase;
3434

CefSharp.Core/ManagedCefBrowserAdapter.cpp

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,24 +66,18 @@ void ManagedCefBrowserAdapter::CreateBrowser(IWindowInfo^ windowInfo, BrowserSet
6666

6767
extraInfo->SetBool("LegacyBindingEnabled", legacyBindingEnabled);
6868

69-
// Retrieve the configurable binding property names, throw exception if empty or illegal characters
70-
auto jsBindingPropertyName = _javaScriptObjectRepository->Settings->WindowPropertyName;
71-
if (!StringCheck::EnsureLettersAndNumbers(jsBindingPropertyName))
69+
if (!String::IsNullOrEmpty(objectRepository->Settings->JavascriptBindingApiGlobalObjectName))
7270
{
73-
throw gcnew InvalidOperationException("CefBrowserHost::CreateBrowser invalid or illegal characters used for binding property names. Alphanumeric and underscores characters only.");
74-
}
75-
76-
if (_javaScriptObjectRepository->Settings->IsWindowPropertyNameCamelCase())
77-
{
78-
extraInfo->SetString("JsBindingPropertyNameCamelCase", StringUtils::ToNative(jsBindingPropertyName));
79-
}
80-
else
81-
{
82-
extraInfo->SetString("JsBindingPropertyName", StringUtils::ToNative(jsBindingPropertyName));
71+
auto globalObjName = objectRepository->Settings->JavascriptBindingApiGlobalObjectName;
8372

84-
// Convert to camelCase
85-
auto camelCasePropertyName = _javaScriptObjectRepository->ConvertStringToCamelCase(jsBindingPropertyName);
86-
extraInfo->SetString("JsBindingPropertyNameCamelCase", StringUtils::ToNative(camelCasePropertyName));
73+
if (StringCheck::IsFirstCharacterLowercase(globalObjName))
74+
{
75+
extraInfo->SetString("JsBindingPropertyNameCamelCase", StringUtils::ToNative(globalObjName));
76+
}
77+
else
78+
{
79+
extraInfo->SetString("JsBindingPropertyName", StringUtils::ToNative(globalObjName));
80+
}
8781
}
8882

8983
if (!CefBrowserHost::CreateBrowser(*cefWindowInfoWrapper->GetWindowInfo(), _clientAdapter.get(), addressNative,

CefSharp.Example/CefExample.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ public static class CefExample
1616
{
1717
//TODO: Revert after https://bitbucket.org/chromiumembedded/cef/issues/2685/networkservice-custom-scheme-unable-to
1818
//has been fixed.
19-
public const string BaseUrl = "https://cefsharp.example";
19+
public const string ExampleDomain = "cefsharp.example";
20+
public const string BaseUrl = "https://" + ExampleDomain;
2021
public const string DefaultUrl = BaseUrl + "/home.html";
2122
public const string BindingTestUrl = BaseUrl + "/BindingTest.html";
2223
public const string BindingTestSingleUrl = BaseUrl + "/BindingTestSingle.html";
@@ -32,6 +33,7 @@ public static class CefExample
3233
public const string DragDropCursorsTestUrl = BaseUrl + "/DragDropCursorsTest.html";
3334
public const string CssAnimationTestUrl = BaseUrl + "/CssAnimationTest.html";
3435
public const string CdmSupportTestUrl = BaseUrl + "/CdmSupportTest.html";
36+
public const string BindingApiCustomObjectNameTestUrl = BaseUrl + "/BindingApiCustomObjectNameTest.html";
3537
public const string TestResourceUrl = "http://test/resource/load";
3638
public const string RenderProcessCrashedUrl = "http://processcrashed";
3739
public const string TestUnicodeResourceUrl = "http://test/resource/loadUnicode";
@@ -171,7 +173,7 @@ public static void Init(CefSettingsBase settings, IBrowserProcessHandler browser
171173
{
172174
SchemeName = "https",
173175
SchemeHandlerFactory = new CefSharpSchemeHandlerFactory(),
174-
DomainName = "cefsharp.example"
176+
DomainName = ExampleDomain
175177
});
176178

177179
settings.RegisterScheme(new CefCustomScheme

CefSharp.Example/CefSharp.Example.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
<None Include="Resources\assets\js\shBrushJScript.js" />
151151
<Content Include="Resources\assets\js\shCore.js" />
152152
<Content Include="Resources\BindingTestsAsyncTask.html" />
153+
<Content Include="Resources\BindingApiCustomObjectNameTest.html" />
153154
<Content Include="Resources\BindingTestSingle.html" />
154155
<Content Include="Resources\DragDropCursorsTest.html" />
155156
<Content Include="Resources\JavascriptCallbackTest.html" />

CefSharp.Example/CefSharpSchemeHandlerFactory.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ static CefSharpSchemeHandlerFactory()
5555
{ "/UnicodeExampleGreaterThan32kb.html", Resources.UnicodeExampleGreaterThan32kb },
5656
{ "/UnocodeExampleEqualTo32kb.html", Resources.UnocodeExampleEqualTo32kb },
5757
{ "/JavascriptCallbackTest.html", Resources.JavascriptCallbackTest },
58-
{ "/BindingTestsAsyncTask.html", Resources.BindingTestsAsyncTask }
58+
{ "/BindingTestsAsyncTask.html", Resources.BindingTestsAsyncTask },
59+
{ "/BindingApiCustomObjectNameTest.html", Resources.BindingApiCustomObjectNameTest }
5960
};
6061
}
6162

CefSharp.Example/Properties/Resources.Designer.cs

Lines changed: 58 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CefSharp.Example/Properties/Resources.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,4 +223,7 @@
223223
<data name="PostMessageTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
224224
<value>..\Resources\PostMessageTest.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
225225
</data>
226+
<data name="BindingApiCustomObjectNameTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
227+
<value>..\Resources\BindingApiCustomObjectNameTest.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
228+
</data>
226229
</root>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<title>QUnit Javascript Binding API Object Name</title>
6+
<link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.10.0.css">
7+
<script>
8+
if (!window.bindingApiObject)
9+
{
10+
window.bindingApiObject = cefSharp;
11+
}
12+
</script>
13+
</head>
14+
<body>
15+
<div id="qunit"></div>
16+
<div id="qunit-fixture"></div>
17+
<script src="https://code.jquery.com/qunit/qunit-2.10.0.js"></script>
18+
<script>
19+
QUnit.test("Test if can execute a method on our object", function (assert)
20+
{
21+
assert.notOk(bindingApiObject.isObjectCached("fakeExample"), "We expect false");
22+
});
23+
</script>
24+
</body>
25+
</html>

CefSharp.Example/Resources/BindingTest.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,11 @@
649649
});
650650
});
651651
});
652+
653+
QUnit.done(function (details)
654+
{
655+
CefSharp.PostMessage({ "Type" : "QUnitExecutionComplete", "Details" : details });
656+
});
652657
</script>
653658

654659
</body>

0 commit comments

Comments
 (0)