/// <summary> /// Create a new V8 plugin adapter. /// </summary> /// <param name="pluginObject"> /// The local or remote native plugin to adapt to V8. /// </param> /// <param name="v8HostObject"> /// Optional - if supplied, the adapter will add the native methods and events to this /// existing object instead of creating a new one with a property accessor. /// </param> private V8PluginAdapter(IV8Plugin pluginObject, CefV8Value v8HostObject = null) { Plugin = pluginObject; V8Object = v8HostObject; if (V8Object == null) { V8Object = CefV8Value.CreateObject(new PluginV8Accessor()); V8Object.SetUserData(this); } // Create a single method handler configured to handle all methods on the plugin var methodHandler = new PluginMethodV8Handler(Plugin); foreach (var methodDescriptor in Plugin.Descriptor.Methods) { V8Object.SetValue(methodDescriptor.MethodName, CefV8Value.CreateFunction(methodDescriptor.MethodName, methodHandler), CefV8PropertyAttribute.None); } foreach (var eventName in Plugin.Descriptor.Events) { // For each event, create a child object exposed as a property named after the event // The child object is a syntactic placeholder for the addListener/removeListener/hasListener/hasListeners methods var eventObject = CefV8Value.CreateObject(null); var eventHandler = new PluginEventV8Handler(Plugin, eventName); eventObject.SetValue(PluginEventV8Handler.MethodNameAddListener, CefV8Value.CreateFunction(PluginEventV8Handler.MethodNameAddListener, eventHandler), CefV8PropertyAttribute.None); eventObject.SetValue(PluginEventV8Handler.MethodNameRemoveListener, CefV8Value.CreateFunction(PluginEventV8Handler.MethodNameRemoveListener, eventHandler), CefV8PropertyAttribute.None); eventObject.SetValue(PluginEventV8Handler.MethodNameHasListener, CefV8Value.CreateFunction(PluginEventV8Handler.MethodNameHasListener, eventHandler), CefV8PropertyAttribute.None); eventObject.SetValue(PluginEventV8Handler.MethodNameHasListeners, CefV8Value.CreateFunction(PluginEventV8Handler.MethodNameHasListeners, eventHandler), CefV8PropertyAttribute.None); V8Object.SetValue(eventName, eventObject, CefV8PropertyAttribute.None); } }
/// <summary> /// 绑定数据并注册对象 /// 说明:已经过滤特殊名称,即不含系统自动生成的属性、方法 /// </summary> /// <param name="name">对象名称</param> /// <param name="obj">需要绑定的对象</param> /// <param name="window">用于注册的V8 JS引擎对象,类似于整个程序的窗口句柄</param> public static void Bind(string name, object obj, CefV8Value window) { var unmanagedWrapper = new UnmanagedWrapper(obj); var propertyAccessor = new PropertyAccessor(); //javascript对象包 CefV8Value javascriptWrapper = CefV8Value.CreateObject(propertyAccessor); //将非托管对象放到javascript对象包 javascriptWrapper.SetUserData(unmanagedWrapper); var handler = new BindingHandler(); unmanagedWrapper.Properties = GetProperties(obj.GetType()); CreateJavascriptProperties(javascriptWrapper, unmanagedWrapper.Properties); IList <string> methodNames = GetMethodNames(obj.GetType(), unmanagedWrapper.Properties); CreateJavascriptMethods(handler, javascriptWrapper, methodNames); window.SetValue(name, javascriptWrapper, CefV8PropertyAttribute.None); }