Skip to content

Commit

Permalink
Merge pull request #1644 from ChrisBardsley/master
Browse files Browse the repository at this point in the history
Add paramArray support to Javascript Binding
  • Loading branch information
amaitland committed Apr 5, 2016
2 parents 81e909d + d3d6907 commit 7cf5f17
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 5 deletions.
21 changes: 21 additions & 0 deletions CefSharp.Example/BoundObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

using System;
using System.Linq;
using System.Threading.Tasks;

namespace CefSharp.Example
Expand Down Expand Up @@ -270,5 +271,25 @@ public SubBoundObject GetSubObject()
{
return SubObject;
}

/// <summary>
/// Demonstrates the use of params as an argument in a bound object
/// </summary>
/// <param name="name">Dummy Argument</param>
/// <param name="args">Params Argument</param>
public string MethodWithParams(string name, params object[] args)
{
return String.Join(", ", args.ToArray());
}

public string MethodWithoutParams(string name, string arg2)
{
return String.Format("{0}, {1}", name, arg2);
}

public string methodWithoutAnything()
{
return "Method without anything called and returned successfully.";
}
}
}
29 changes: 29 additions & 0 deletions CefSharp.Example/Resources/BindingTest.html
Original file line number Diff line number Diff line change
Expand Up @@ -237,5 +237,34 @@
}
</script>
</ul>
<p>
Javascript function sending variable number of parameters to Bound Object. (ParamArray Test)
<script type="text/javascript">
function invokeParamArrayMethod(func) {
var result = func();
document.getElementById('paramArrayResults').innerHTML = result;
}
</script>
<ul>
<li style="list-style:none;display:inline-block;">
<button onclick="invokeParamArrayMethod(function(){return bound.methodWithParams('test', 'hello-world')})">With 1 Params</button>
</li>
<li style="list-style:none;display:inline-block;">
<button onclick="invokeParamArrayMethod(function(){return bound.methodWithParams('test', 'hello-world', 'chris was here')})">With 2 Params</button>
</li>
<li style="list-style:none;display:inline-block;">
<button onclick="invokeParamArrayMethod(function(){return bound.methodWithParams('test')})">With no Params</button>
</li>
<li style="list-style:none;display:inline-block;">
<button onclick="invokeParamArrayMethod(function(){return bound.methodWithoutParams('test', 'hello')})">Normal Method</button>
</li>
<li style="list-style:none;display:inline-block;">
<button onclick="invokeParamArrayMethod(function(){return bound.methodWithoutAnything()})">Normal Method No Params</button>
</li>
</ul>
<span>ParamArray Results</span>
<br />
<span id="paramArrayResults"></span>
</p>
</body>
</html>
1 change: 1 addition & 0 deletions CefSharp.Example/ScriptedMethodsBoundObject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
using System;
using System.Linq;

namespace CefSharp.Example
{
Expand Down
1 change: 1 addition & 0 deletions CefSharp/CefSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
<Compile Include="IDomNode.cs" />
<Compile Include="IFindHandler.cs" />
<Compile Include="Internals\CommandLineArgsParser.cs" />
<Compile Include="Internals\MethodParameter.cs" />
<Compile Include="IPluginHandler.cs" />
<Compile Include="IPopupFeatures.cs" />
<Compile Include="IRenderProcessMessageHandler.cs" />
Expand Down
3 changes: 3 additions & 0 deletions CefSharp/Internals/JavascriptMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;

namespace CefSharp.Internals
Expand Down Expand Up @@ -33,6 +34,8 @@ public class JavascriptMethod
[DataMember]
public string JavascriptName { get; set; }

public List<MethodParameter> MethodParameters { get; set; }

/// <summary>
/// Number of Params this function exepects
/// </summary>
Expand Down
43 changes: 38 additions & 5 deletions CefSharp/Internals/JavascriptObjectRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,42 @@ public bool TryCallMethod(long objectId, string name, object[] parameters, out o

try
{
// Do we have enough arguments? Add Type.Missing for any that we don't have incase of optional params
//Added param array support. Current implementation support param Object only. 04/04/2016
var missingParams = method.ParameterCount - parameters.Length;
if (missingParams > 0)
//CONDITION #1 : Check for parameter count missmatch between the parameters on the javascript function and the
// number of parameters on the bound object method.
//CONDITION #2 : Check if the bound object method contains a ParamArray as the last parameter on the method signature.
if (missingParams > 0 || method.MethodParameters.LastOrDefault(t => t.IsParamArray) != null)
{
var paramList = new List<object>(parameters);
var paramList = new List<object>(method.MethodParameters.Count);

for (var i = 0; i < missingParams; i++)
//Loop through all of the method parameters on the bound object.
for (var i = 0; i < method.MethodParameters.Count; i++)
{
paramList.Add(Type.Missing);
//Attempt to get the javascript function param at the current bound object parameter index.
//If the javascript function param is missing IE: NULL, then add Type.Missing.
//This will allow for default bound object parameters. IE: (string someParameter = "someValue")
object jsParam = parameters.ElementAtOrDefault(i);
if (jsParam == null && !method.MethodParameters[i].IsParamArray)
{
paramList.Add(Type.Missing);
}
//If the method parameter is a paramArray IE: (params Object[] someParameter)
//grab the parameters from the javascript function starting at the current bound object parameter index
//and add create an array that will be passed in as the last bound object method parameter.
else if (method.MethodParameters[i].IsParamArray)
{
List<object> convertedParams = new List<object>();
for (var s = i; s < parameters.Length; s++)
{
convertedParams.Add(parameters[s]);
}
paramList.Add(convertedParams.ToArray());
}
else
{
paramList.Add(jsParam);
}
}

parameters = paramList.ToArray();
Expand Down Expand Up @@ -287,6 +314,12 @@ private static JavascriptMethod CreateJavaScriptMethod(MethodInfo methodInfo, bo
jsMethod.JavascriptName = GetJavascriptName(methodInfo.Name, camelCaseJavascriptNames);
jsMethod.Function = methodInfo.Invoke;
jsMethod.ParameterCount = methodInfo.GetParameters().Length;
jsMethod.MethodParameters = methodInfo.GetParameters()
.Select(t => new MethodParameter()
{
IsParamArray = t.GetCustomAttributes(typeof(ParamArrayAttribute), false).Length > 0
}).ToList();


return jsMethod;
}
Expand Down
12 changes: 12 additions & 0 deletions CefSharp/Internals/MethodParameter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright © 2010-2016 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.
using System;

namespace CefSharp.Internals
{
public class MethodParameter
{
public Boolean IsParamArray { get; set; }
}
}
4 changes: 4 additions & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,9 @@
</activePackageSource>
<packageSources>
<add key="cefsharp-myget" value="https://www.myget.org/F/cefsharp/" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
</packageSources>
<disabledPackageSources>
<add key="nuget.org" value="true" />
</disabledPackageSources>
</configuration>

0 comments on commit 7cf5f17

Please sign in to comment.