From fd5264240c1f2c7570dbf67d2ba7aabae900f1bd Mon Sep 17 00:00:00 2001 From: WrinklyNinja Date: Sun, 8 Jun 2014 17:01:48 +0100 Subject: [PATCH] First implementation of C++<->JS comms. The Help menu item now opens the readme in the default browser. --- resources/report/js/script.js | 11 ++++++++- resources/report/testdata.js | 1 - src/gui/app.cpp | 18 ++++++++++++++- src/gui/app.h | 13 +++++++++-- src/gui/handler.cpp | 43 +++++++++++++++++++++++++++++++++++ src/gui/handler.h | 22 ++++++++++++++++++ 6 files changed, 103 insertions(+), 5 deletions(-) diff --git a/resources/report/js/script.js b/resources/report/js/script.js index 092cf600..3d2c1517 100644 --- a/resources/report/js/script.js +++ b/resources/report/js/script.js @@ -193,6 +193,15 @@ function openLogLocation(evt) { } function openReadme(evt) { + // Create and send a new query. + var request_id = window.cefQuery({ + request: 'openReadme', + persistent: false, + onSuccess: function(response) {}, + onFailure: function(error_code, error_message) { + alert(error_code + error_message); + } + }); } function updateMasterlist(evt) { @@ -575,7 +584,7 @@ function processURLParams() { var activePluginNo = 0; var dirtyPluginNo = 0; /* Fill report with data. */ - document.getElementById('LOOTVersion').textContent = data.lootVersion; + document.getElementById('LOOTVersion').textContent = loot.version; document.getElementById('masterlistRevision').textContent = data.masterlist.revision.substr(0, 9); document.getElementById('masterlistDate').textContent = data.masterlist.date; var generalMessagesList = document.getElementById('generalMessages').getElementsByTagName('ul')[0]; diff --git a/resources/report/testdata.js b/resources/report/testdata.js index b7ecdf4a..83e64a88 100644 --- a/resources/report/testdata.js +++ b/resources/report/testdata.js @@ -1,5 +1,4 @@ var data = { - "lootVersion": "0.5.0", "masterlist": { "revision": "f66688fbe946396bc8fa1d5dadb7c8211c189cee", "date": "2014-05-10" diff --git a/src/gui/app.cpp b/src/gui/app.cpp index 092f6ca4..dce6142d 100644 --- a/src/gui/app.cpp +++ b/src/gui/app.cpp @@ -68,11 +68,28 @@ namespace loot { CefBrowserHost::CreateBrowser(window_info, handler.get(), url, browser_settings, NULL); } + void LootApp::OnWebKitInitialized() { + // Create the renderer-side router for query handling. + CefMessageRouterConfig config; + message_router_ = CefMessageRouterRendererSide::Create(config); + } + + bool LootApp::OnProcessMessageReceived( + CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) { + // Handle IPC messages from the browser process... + return message_router_->OnProcessMessageReceived(browser, source_process, message); + } + void LootApp::OnContextCreated(CefRefPtr browser, CefRefPtr frame, CefRefPtr context) { + // Register javascript functions. + message_router_->OnContextCreated(browser, frame, context); + // Retrieve the context's window object. CefRefPtr object = context->GetGlobal(); @@ -85,7 +102,6 @@ namespace loot { lootObj->SetValue("version", CefV8Value::CreateString(IntToString(g_version_major) + "." + IntToString(g_version_minor) + "." + IntToString(g_version_patch)), V8_PROPERTY_ATTRIBUTE_NONE); - // Add the string to the window object as "window.myval". See the "JS Objects" section below. object->SetValue("loot", lootObj, V8_PROPERTY_ATTRIBUTE_NONE); } } \ No newline at end of file diff --git a/src/gui/app.h b/src/gui/app.h index f2943274..ab054599 100644 --- a/src/gui/app.h +++ b/src/gui/app.h @@ -26,6 +26,7 @@ #define __LOOT_GUI_APP__ #include +#include #include @@ -43,10 +44,18 @@ namespace loot { // Override CefBrowserProcessHandler methods. virtual void OnContextInitialized() OVERRIDE; + virtual void OnWebKitInitialized() OVERRIDE; + + // Override CefRenderProcessHandler methods. + virtual bool OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) OVERRIDE; private: + CefRefPtr message_router_; + virtual void OnContextCreated(CefRefPtr browser, - CefRefPtr frame, - CefRefPtr context) OVERRIDE; + CefRefPtr frame, + CefRefPtr context) OVERRIDE; IMPLEMENT_REFCOUNTING(LootApp); }; diff --git a/src/gui/handler.cpp b/src/gui/handler.cpp index db1b511c..76c7fba2 100644 --- a/src/gui/handler.cpp +++ b/src/gui/handler.cpp @@ -39,6 +39,34 @@ namespace loot { LootHandler * g_instance = NULL; } + // Handler methods + //---------------- + + Handler::Handler() {} + + // Called due to cefQuery execution in binding.html. + bool Handler::OnQuery(CefRefPtr browser, + CefRefPtr frame, + int64 query_id, + const CefString& request, + bool persistent, + CefRefPtr callback) { + + const std::string& message_name = request; + if (message_name.find("openReadme") == 0) { + // Open readme in default application. + std::string url = ToFileURL(g_path_readme); + int len = MultiByteToWideChar(CP_UTF8, 0, url.c_str(), url.length() + 1, 0, 0); + std::wstring wurl(len, NULL); + MultiByteToWideChar(CP_UTF8, 0, url.c_str(), url.length() + 1, &(wurl[0]), len); + ShellExecute(0, NULL, wurl.c_str(), NULL, NULL, SW_SHOWNORMAL); + callback->Success(request); + return true; + } + + return false; + } + LootHandler::LootHandler() : is_closing_(false) { assert(!g_instance); g_instance = this; @@ -67,6 +95,12 @@ namespace loot { return this; } + bool LootHandler::OnProcessMessageReceived( CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) { + return browser_side_router_->OnProcessMessageReceived(browser, source_process, message); + } + // CefDisplayHandler methods //-------------------------- @@ -95,6 +129,12 @@ namespace loot { // Add to the list of existing browsers. browser_list_.push_back(browser); + + // Create a message router. + CefMessageRouterConfig config; + browser_side_router_ = CefMessageRouterBrowserSide::Create(config); + + browser_side_router_->AddHandler(new Handler(), false); } bool LootHandler::DoClose(CefRefPtr browser) { @@ -116,6 +156,9 @@ namespace loot { void LootHandler::OnBeforeClose(CefRefPtr browser) { assert(CefCurrentlyOn(TID_UI)); + // Cancel any javascript callbacks. + browser_side_router_->OnBeforeClose(browser); + // Remove from the list of existing browsers. for (BrowserList::iterator bit = browser_list_.begin(); bit != browser_list_.end(); ++bit) { if ((*bit)->IsSame(browser)) { diff --git a/src/gui/handler.h b/src/gui/handler.h index dc029f8e..17874814 100644 --- a/src/gui/handler.h +++ b/src/gui/handler.h @@ -25,12 +25,29 @@ #ifndef __LOOT_GUI_HANDLER__ #define __LOOT_GUI_HANDLER__ +#include "../backend/globals.h" +#include "../backend/helpers.h" + #include +#include #include namespace loot { + class Handler : public CefMessageRouterBrowserSide::Handler { + public: + Handler(); + + // Called due to cefQuery execution in binding.html. + virtual bool OnQuery(CefRefPtr browser, + CefRefPtr frame, + int64 query_id, + const CefString& request, + bool persistent, + CefRefPtr callback) OVERRIDE; + }; + class LootHandler : public CefClient, public CefDisplayHandler, public CefLifeSpanHandler, @@ -48,6 +65,10 @@ namespace loot { virtual CefRefPtr GetLifeSpanHandler() OVERRIDE; virtual CefRefPtr GetLoadHandler() OVERRIDE; + virtual bool OnProcessMessageReceived(CefRefPtr browser, + CefProcessId source_process, + CefRefPtr message) OVERRIDE; + // CefDisplayHandler methods //-------------------------- virtual void OnTitleChange(CefRefPtr browser, @@ -76,6 +97,7 @@ namespace loot { // List of existing browser windows. Only accessed on the CEF UI thread. typedef std::list > BrowserList; BrowserList browser_list_; + CefRefPtr browser_side_router_; bool is_closing_;