Skip to content

Commit

Permalink
Use CefParseJSON instead of V8 context for JS responses
Browse files Browse the repository at this point in the history
Nlohmann's `dump()` uses a different method of escaping characters in
strings than V8 does, resulting in `JSON.parse()` failing and the JS
commands never returning a value.

Instead, pass the Nlohmann `dump()` string directly into CEF's JSON
parser, convert it into a CefV8Value that V8 will recognise, then
forward the resulting value to the callback.

Fixes #390
  • Loading branch information
WizardCM authored and Lain-B committed Sep 23, 2023
1 parent fc57db4 commit 8407dcc
Showing 1 changed file with 53 additions and 8 deletions.
61 changes: 53 additions & 8 deletions browser-app.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,56 @@ void BrowserApp::SetDocumentVisibility(CefRefPtr<CefBrowser> browser,
}
#endif

CefRefPtr<CefV8Value> CefValueToCefV8Value(CefRefPtr<CefValue> value)
{
CefRefPtr<CefV8Value> result;
switch (value->GetType()) {
case VTYPE_INVALID:
result = CefV8Value::CreateNull();
break;
case VTYPE_NULL:
result = CefV8Value::CreateNull();
break;
case VTYPE_BOOL:
result = CefV8Value::CreateBool(value->GetBool());
break;
case VTYPE_INT:
result = CefV8Value::CreateInt(value->GetInt());
break;
case VTYPE_DOUBLE:
result = CefV8Value::CreateDouble(value->GetDouble());
break;
case VTYPE_STRING:
result = CefV8Value::CreateString(value->GetString());
break;
case VTYPE_BINARY:
result = CefV8Value::CreateNull();
break;
case VTYPE_DICTIONARY: {
result = CefV8Value::CreateObject(nullptr, nullptr);
CefRefPtr<CefDictionaryValue> dict = value->GetDictionary();
CefDictionaryValue::KeyList keys;
dict->GetKeys(keys);
for (unsigned int i = 0; i < keys.size(); i++) {
CefString key = keys[i];
result->SetValue(
key, CefValueToCefV8Value(dict->GetValue(key)),
V8_PROPERTY_ATTRIBUTE_NONE);
}
} break;
case VTYPE_LIST: {
CefRefPtr<CefListValue> list = value->GetList();
size_t size = list->GetSize();
result = CefV8Value::CreateArray((int)size);
for (int i = 0; i < size; i++) {
result->SetValue(
i, CefValueToCefV8Value(list->GetValue(i)));
}
} break;
}
return result;
}

bool BrowserApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefProcessId source_process,
Expand Down Expand Up @@ -324,25 +374,20 @@ bool BrowserApp::OnProcessMessageReceived(CefRefPtr<CefBrowser> browser,
} else if (message->GetName() == "executeCallback") {
CefRefPtr<CefV8Context> context =
browser->GetMainFrame()->GetV8Context();
CefRefPtr<CefV8Value> retval;
CefRefPtr<CefV8Exception> exception;

context->Enter();

CefRefPtr<CefListValue> arguments = message->GetArgumentList();
int callbackID = arguments->GetInt(0);
CefString jsonString = arguments->GetString(1);

std::string script;
script += "JSON.parse('";
script += arguments->GetString(1).ToString();
script += "');";
CefRefPtr<CefValue> json =
CefParseJSON(arguments->GetString(1).ToString(), {});

CefRefPtr<CefV8Value> callback = callbackMap[callbackID];
CefV8ValueList args;

context->Eval(script, browser->GetMainFrame()->GetURL(), 0,
retval, exception);
CefRefPtr<CefV8Value> retval = CefValueToCefV8Value(json);

args.push_back(retval);

Expand Down

0 comments on commit 8407dcc

Please sign in to comment.