/* * CEF JS调用C#组装类 * * 使用方法(CefGlue为例): * public class BrowserRenderProcessHandler : CefRenderProcessHandler { * //自定义Handler private TestBrowserHandler _testHandler = null; * * protected override void OnWebKitInitialized() * { * _testHandler = new TestBrowserHandler(); * CefRuntime.RegisterExtension(_testHandler.GetType().Name, _testHandler.Javascript.Create(), _testHandler); * } * } * * /// <summary> /// 测试Handler /// </summary> public class TestBrowserHandler : CefV8Handler { public GenerateJavascriptFull Javascript = null; * * public TestBrowserHandler() { Javascript = new GenerateJavascriptFull("plugins", "test"); * // getHello的参数数量,可进一步封装。表示接受一个参数 Javascript.AddMethod("gethello", "arg0"); * // getHello的参数数量,可进一步封装。表示接受二个参数 Javascript.AddMethod("sethello", "arg0","arg1"); * //表示无参 * Javascript.AddMethod("sethello"); Javascript.AddGetProperty("hello", "gethello"); Javascript.AddSetProperty("hello", "sethello", "arg0"); Javascript.AddMethod("start", "arg0"); Javascript.AddMethod("stop"); * * //这里表示浏览器JS增加了: window.plugins.test 对象 * // window.plugins.test.gethello() * // window.plugins.test.sethello("123") * //断点在 Execute(**)中 } * * protected override bool Execute(string name, CefV8Value obj, CefV8Value[] arguments, out CefV8Value returnValue, out string exception) { try { returnValue = CefV8Value.CreateNull(); switch (name) { case "gethello": //returnValue = CefV8Value.CreateString(GetHello()); if (arguments.Length == 1 && arguments[0].IsFunction) { CefV8Value[] args = new CefV8Value[1]; args[0] = CefV8Value.CreateString(GetHello()); returnValue = arguments[0].ExecuteFunction(null, args); } break; case "sethello": returnValue = CefV8Value.CreateBool(SetHello(arguments[0].GetStringValue())); break; case "start": if (arguments.Length == 1 && arguments[0].IsFunction) { CefV8Context context = CefV8Context.GetCurrentContext(); //这里定义异步调用方式 new Thread(new ThreadStart(delegate() { while (isStart) { System.Threading.Thread.Sleep(1000); string timer = DateTime.Now.ToString(); * //TestTimerTask继承CefTask CefRuntime.PostTask(CefThreadId.Renderer, new TestTimerTask(context as CefV8Context, arguments[0], new object[] { timer })); } })).Start(); returnValue = CefV8Value.CreateBool(true); } break; case "stop": isStart = false; returnValue = CefV8Value.CreateBool(true); break; } exception = null; return true; } catch (Exception e) { returnValue = null; exception = e.Message; return false; } } * } * * * * * */ using System; using System.Collections.Generic; using System.Text; namespace G.DeskCommon { /// <summary> /// 组装JS /// </summary> public class GenerateJavascriptFull { string _extensionName = string.Empty; string _functionName = string.Empty; Dictionary<string, string[]> _methodName = new Dictionary<string, string[]>(); // Dictionary<string, string> _getterPropertyName = new Dictionary<string, string>(); // 保存setter 名称 和参数。 与 _setterPropertyArgs 成对出现。 Dictionary<string, string> _setterPropertyName = new Dictionary<string, string>(); Dictionary<string, string[]> _setterPropertyArgs = new Dictionary<string, string[]>(); //自定义javascript代码 List<string> _customJavascript = new List<string>(); /// <summary> /// /// </summary> /// <param name="extensionName"> /// 插件方法作用域 /// e.g: window.plugin.test /// 其中 plugin 为作用域. 如不设置,添加的js方法在window下. /// </param> /// <param name="functionName"> /// /// </param> public GenerateJavascriptFull(string extensionName, string functionName) { _extensionName = extensionName; _functionName = functionName; } /// <summary> /// 增加方法 /// </summary> /// <param name="methodName">方法名称</param> /// <param name="args">参数名:arg0,arg1,...arg20 (固定写死)</param> public void AddMethod(string methodName, params string[] args) { //检测是否存在改方法 if (_methodName.ContainsKey(methodName)) return; _methodName.Add(methodName, args); } /// <summary> /// 增加Getter属性 /// </summary> /// <param name="propertyName">属性名称</param> /// <param name="executeName">执行名称,CEF handler中execute的Name参数同名</param> public void AddGetProperty(string propertyName, string executeName) { if (_getterPropertyName.ContainsKey(propertyName)) return; _getterPropertyName.Add(propertyName, executeName); } /// <summary> /// 增加Setter属性 /// </summary> /// <param name="propertyName">属性名称</param> /// <param name="executeName">执行名称,CEF handler中execute的Name参数同名</param> /// <param name="args">参数名:arg0,arg1,...arg20 (固定写死)</param> public void AddSetProperty(string propertyName, string executeName, params string[] args) { if (_setterPropertyName.ContainsKey(propertyName) || _setterPropertyArgs.ContainsKey(propertyName)) return; _setterPropertyName.Add(propertyName, executeName); _setterPropertyArgs.Add(propertyName, args); } /// <summary> /// 增加自定义的javascript代码。 /// </summary> /// <param name="javascriptCode">注意:functionName一定要大写。 /// 例如: TEST.__defineSetter__(‘hello‘, function(b) { /// native function sethello();sethello(b);});</param> public void AddCustomJavascript(string javascriptCode) { _customJavascript.Add(javascriptCode); } /// <summary> /// 组装本地JS的一个过程 /// </summary> /// <returns>返回CEF识别的javascript</returns> public string Create() { //System.Threading.Thread.Sleep(3000); if (string.IsNullOrEmpty(_functionName)) throw new Exception("JavascriptFull函数名不能为空!"); StringBuilder sb = new StringBuilder(); //头部 if (!string.IsNullOrEmpty(_extensionName)) { sb.Append(string.Format("if (!{0}) var {0} = {{ }}; ", _extensionName)); } if (!string.IsNullOrEmpty(_functionName)) { sb.Append(string.Format("var {0} = function () {{ }}; ", _functionName.ToUpper())); if (!string.IsNullOrEmpty(_extensionName)) sb.Append(string.Format("if (!{0}.{1}) {0}.{1} = {2};", _extensionName, _functionName, _functionName.ToUpper())); else sb.Append(string.Format("if (!{0}) var {0} = {1};", _functionName, _functionName.ToUpper())); } //开始 sb.Append("(function () {"); //方法 foreach (KeyValuePair<string, string[]> item in _methodName) { sb.Append(string.Format("{0}.{1} = function ({2}) {{", _functionName.ToUpper(), item.Key, string.Join(",", item.Value))); sb.Append(string.Format("native function {0}({1}); return {0}({1});", item.Key, string.Join(",", item.Value))); sb.Append("};"); } //GET属性 foreach (KeyValuePair<string, string> item in _getterPropertyName) { sb.Append(string.Format("{0}.__defineGetter__(‘{1}‘, function () {{", _functionName.ToUpper(), item.Key)); sb.Append(string.Format("native function {0}(); return {0}();", item.Value)); sb.Append("});"); } //SET属性 if (_setterPropertyArgs.Count == _setterPropertyName.Count) { foreach (KeyValuePair<string, string> item in _setterPropertyName) { sb.Append(string.Format("{0}.__defineSetter__(‘{1}‘, function ({2}) {{", _functionName.ToUpper(), item.Key, string.Join(",", _setterPropertyArgs[item.Key]))); sb.Append(string.Format("native function {0}({1}); return {0}({1});", item.Value, string.Join(",", _setterPropertyArgs[item.Key]))); sb.Append("});"); } } //自定义javascript for (int i = 0; i < _customJavascript.Count; i++) { sb.Append(_customJavascript[i]); } //结尾 sb.Append("})();"); return sb.ToString(); } } }