nim_duilib/ui_components/cef_control/app/client_app_render.cpp
jiajia_deng ad9a6b3edc Modified the namespace of the UI component
Signed-off-by: jiajia_deng <2894220@gmail.com>
2019-09-22 11:08:20 +08:00

155 lines
4.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "stdafx.h"
#include "client_app.h"
#include <string>
#include "include/cef_cookie.h"
#include "include/cef_process_message.h"
#include "include/cef_task.h"
#include "include/cef_v8.h"
#include "cef_control/util/util.h"
#include "cef_control/app/js_handler.h"
#include "cef_control/app/ipc_string_define.h"
#include "cef_control/app/cef_js_bridge.h"
namespace nim_comp
{
//////////////////////////////////////////////////////////////////////////////////////////
// CefRenderProcessHandler methods.
void ClientApp::OnRenderThreadCreated(CefRefPtr<CefListValue> extra_info)
{
}
void ClientApp::OnWebKitInitialized()
{
/**
* JavaScript 扩展代码,这里定义一个 NimCefWebFunction 对象提供 call 方法来让 Web 端触发 native 的 CefV8Handler 处理代码
* param[in] functionName 要调用的 C++ 方法名称
* param[in] params 调用该方法传递的参数,在前端指定的是一个 Object但转到 Native 的时候转为了字符串
* param[in] callback 执行该方法后的回调函数
* 前端调用示例
* NimCefWebHelper.call('showMessage', { message: 'Hello C++' }, (arguments) => {
* console.log(arguments)
* })
*/
std::string extensionCode = R"(
var NimCefWebInstance = {};
(() => {
NimCefWebInstance.call = (functionName, arg1, arg2) => {
if (typeof arg1 === 'function') {
native function call(functionName, arg1);
return call(functionName, arg1);
} else {
const jsonString = JSON.stringify(arg1);
native function call(functionName, jsonString, arg2);
return call(functionName, jsonString, arg2);
}
};
NimCefWebInstance.register = (functionName, callback) => {
native function register(functionName, callback);
return register(functionName, callback);
};
})();
)";
CefRefPtr<CefJSHandler> handler = new CefJSHandler();
if (!render_js_bridge_.get())
render_js_bridge_.reset(new CefJSBridge);
handler->AttachJSBridge(render_js_bridge_);
CefRegisterExtension("v8/extern", extensionCode, handler);
}
void ClientApp::OnBrowserCreated(CefRefPtr<CefBrowser> browser)
{
if (!render_js_bridge_.get())
render_js_bridge_.reset(new CefJSBridge);
}
void ClientApp::OnBrowserDestroyed(CefRefPtr<CefBrowser> browser)
{
}
CefRefPtr<CefLoadHandler> ClientApp::GetLoadHandler()
{
return NULL;
}
bool ClientApp::OnBeforeNavigation(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
NavigationType navigation_type,
bool is_redirect)
{
return false;
}
void ClientApp::OnContextCreated(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
{
}
void ClientApp::OnContextReleased(CefRefPtr<CefBrowser> browser, CefRefPtr<CefFrame> frame, CefRefPtr<CefV8Context> context)
{
render_js_bridge_->RemoveCallbackFuncWithFrame(frame);
render_js_bridge_->UnRegisterJSFuncWithFrame(frame);
}
void ClientApp::OnUncaughtException(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context,
CefRefPtr<CefV8Exception> exception,
CefRefPtr<CefV8StackTrace> stackTrace)
{
}
void ClientApp::OnFocusedNodeChanged(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node)
{
bool is_editable = (node.get() && node->IsEditable());
if (is_editable != last_node_is_editable_)
{
// Notify the browser of the change in focused element type.
last_node_is_editable_ = is_editable;
CefRefPtr<CefProcessMessage> message = CefProcessMessage::Create(kFocusedNodeChangedMessage);
message->GetArgumentList()->SetBool(0, is_editable);
browser->SendProcessMessage(PID_BROWSER, message);
}
}
bool ClientApp::OnProcessMessageReceived(
CefRefPtr<CefBrowser> browser,
CefProcessId source_process,
CefRefPtr<CefProcessMessage> message)
{
ASSERT(source_process == PID_BROWSER);
// 收到 browser 的消息回复
const CefString& message_name = message->GetName();
if (message_name == kExecuteJsCallbackMessage)
{
int callback_id = message->GetArgumentList()->GetInt(0);
bool has_error = message->GetArgumentList()->GetBool(1);
CefString json_string = message->GetArgumentList()->GetString(2);
// 将收到的参数通过管理器传递给调用时传递的回调函数
render_js_bridge_->ExecuteJSCallbackFunc(callback_id, has_error, json_string);
}
else if (message_name == kCallJsFunctionMessage)
{
CefString function_name = message->GetArgumentList()->GetString(0);
CefString json_string = message->GetArgumentList()->GetString(1);
int cpp_callback_id = message->GetArgumentList()->GetInt(2);
int64 frame_id = message->GetArgumentList()->GetInt(3);
// 通过 C++ 执行一个已经注册过的 JS 方法
// frame_id 小于 0 则可能是 browser 进程的 browser 是无效的,所以这里为了避免出现错误就获取一个顶层 frame 执行代码
render_js_bridge_->ExecuteJSFunc(function_name, json_string, frame_id < 0 ? browser->GetMainFrame() : browser->GetFrame(frame_id), cpp_callback_id);
}
return false;
}
}