private void InitializeContext(CefBrowser browser, CefFrame frame, CefV8Context context) { if (_pluginContext == null) { Logger.Error("Could not locate plugin context for V8. Browser {0} Frame {1}", browser.Identifier, frame.Identifier); return; } // TODO : Put in an optimization to not create the JS Object model if the current browser is a DEV TOOLS instance var window = context.GetGlobal(); foreach (var pluginId in _pluginContext.GetPluginIds()) { var pluginPath = pluginId.Split('.'); var pluginV8HostObject = window; var clashDetected = false; for (var pluginPathSectionIndex = 0; pluginPathSectionIndex < pluginPath.Length; pluginPathSectionIndex++) { var pathSection = pluginPath[pluginPathSectionIndex]; if (pluginPathSectionIndex == 0 && pathSection == "window") { // Fully scoped path - parent should stay as the root/global object until next section continue; } if (pluginV8HostObject.HasValue(pathSection)) { pluginV8HostObject = pluginV8HostObject.GetValue(pathSection); if (!pluginV8HostObject.IsObject) { // Most likely a clash of JS paths between plugins // TODO: warn that this current plugin could not be added clashDetected = true; break; } } else { var child = CefV8Value.CreateObject(null); pluginV8HostObject.SetValue(pathSection, child, CefV8PropertyAttribute.DontEnum | CefV8PropertyAttribute.DontDelete); pluginV8HostObject = child; } } if (clashDetected) { continue; } V8PluginAdapter.Create(_pluginContext.GetPluginById(pluginId), pluginV8HostObject); } }
/// <summary> /// Create an adapter for a local (in-process) plugin. /// </summary> /// <param name="router"></param> /// <param name="pluginContext"></param> /// <param name="jsPlugin"></param> /// <returns></returns> public static V8PluginAdapter CreateLocal(IV8PluginRouter router, IPluginContext pluginContext, JavaScriptPlugin jsPlugin) { if (jsPlugin == null) { return(null); } var plugin = new LocalV8Plugin(router, pluginContext, jsPlugin); var pluginAdapter = new V8PluginAdapter(plugin); return(pluginAdapter); }
/// <summary> /// Create an adapter for a remote (out-of-process) plugin. /// </summary> /// <param name="router"></param> /// <param name="pluginContext"></param> /// <param name="descriptor"></param> /// <returns></returns> public static V8PluginAdapter CreateRemote(IV8PluginRouter router, IPluginContext pluginContext, PluginDescriptor descriptor) { V8PluginAdapter adapter; if (!RemotePluginAdapterCache.TryGetValue(descriptor.PluginId, out adapter)) { lock (RemotePluginAdapterCache) { if (!RemotePluginAdapterCache.TryGetValue(descriptor.PluginId, out adapter)) { var plugin = new RemoteV8Plugin(router, pluginContext, descriptor); adapter = new V8PluginAdapter(plugin); RemotePluginAdapterCache.Add(descriptor.PluginId, adapter); } } } return(adapter); }
protected CefV8Value ToCefV8Value(IV8PluginRouter router, object result) { if (result == null) { return(CefV8Value.CreateNull()); } // VALUES FROM REMOTE PLUGINS var remoteResult = result as ResultData; if (remoteResult != null) { switch (remoteResult.DataType) { case ResultDataType.Scalar: if (remoteResult.Items != null && remoteResult.Items.Count != 0) { return(ToCefV8Value(router, remoteResult.Items[0])); } return(CefV8Value.CreateNull()); case ResultDataType.Array: { var cefArray = CefV8Value.CreateArray(remoteResult.Items.Count); if (remoteResult.Items != null) { for (var resultIndex = 0; resultIndex < remoteResult.Items.Count; ++resultIndex) { var cefValue = ToCefV8Value(router, remoteResult.Items[resultIndex]); cefArray.SetValue(resultIndex, cefValue); } } return(cefArray); } case ResultDataType.Dictionary: { var cefObject = CefV8Value.CreateObject(null); if (remoteResult.Items != null) { foreach (var dictionaryItem in remoteResult.Items) { if (string.IsNullOrEmpty(dictionaryItem.Name)) { continue; } var cefValue = ToCefV8Value(router, dictionaryItem); cefObject.SetValue(dictionaryItem.Name, cefValue, CefV8PropertyAttribute.None); } } return(cefObject); } } } var resultItem = result as ResultItem; if (resultItem != null) { return(ToCefV8Value(router, (object)resultItem.DynamicPlugin ?? resultItem.PlainData)); } var pluginObjectDescriptor = result as PluginDescriptor; if (pluginObjectDescriptor != null) { return(V8PluginAdapter.CreateRemote(router, _plugin.PluginContext, pluginObjectDescriptor).V8Object); } // VALUES FROM REMOTE OR LOCAL PLUGINS var plainData = result as JToken; if (plainData != null) { return(CefJsonValueConverter.ToCef(plainData)); } // VALUES FROM LOCAL PLUGINS var localArray = result as object[]; if (localArray != null) { var cefArray = CefV8Value.CreateArray(localArray.Length); for (var resultIndex = 0; resultIndex < localArray.Length; ++resultIndex) { var cefValue = ToCefV8Value(router, localArray[resultIndex]); cefArray.SetValue(resultIndex, cefValue); } return(cefArray); } var localPlugin = result as JavaScriptPlugin; if (localPlugin != null) { return(V8PluginAdapter.CreateLocal(router, _plugin.PluginContext, localPlugin).V8Object); } if (JavaScriptPlugin.IsDynamicPlugin(result)) { var dynPlugin = JavaScriptPlugin.CreateFromObject(PluginProcess.Renderer, result); _plugin.PluginContext.PluginManager.AddLocalPlugin(dynPlugin); return(V8PluginAdapter.CreateLocal(router, _plugin.PluginContext, dynPlugin).V8Object); } // local C# POCO return(CefNativeValueConverter.ToCef(result)); }