/* * 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(); } } }
