diff --git a/bazaar/ChromiumBrowser/ChromiumBrowser.h b/bazaar/ChromiumBrowser/ChromiumBrowser.h index 1a09a81b8..174a50943 100644 --- a/bazaar/ChromiumBrowser/ChromiumBrowser.h +++ b/bazaar/ChromiumBrowser/ChromiumBrowser.h @@ -30,11 +30,11 @@ public: ChromiumBrowser(); ~ChromiumBrowser(); - Callback1 WhenUrlChange; - Callback1 WhenMessage; - Callback WhenTakeFocus; - Callback1 WhenKeyboard; - Callback3 WhenConsoleMessage; + Callback1 WhenUrlChange; + Callback2 > > WhenMessage; + Callback WhenTakeFocus; + Callback1 WhenKeyboard; + Callback3 WhenConsoleMessage; static void ChildProcess(); static bool IsChildProcess(); diff --git a/bazaar/ChromiumBrowser/ClientApp.cpp b/bazaar/ChromiumBrowser/ClientApp.cpp index 110de67e9..b4e508977 100644 --- a/bazaar/ChromiumBrowser/ClientApp.cpp +++ b/bazaar/ChromiumBrowser/ClientApp.cpp @@ -1,10 +1,13 @@ #include "ClientApp.h" +static const char * const func_names[]={ + "JSExample1" +}; + + ClientApp::ClientApp() { - //Add our own JS functions to the list - functions.Add("JSExample1", Upp::callback(this, &ClientApp::JSExample1)); } @@ -20,9 +23,9 @@ void ClientApp::OnContextCreated(CefRefPtr browser, CefRefPtr object = context->GetGlobal(); - for(int f = 0; f < functions.GetCount(); f++){ - CefRefPtr func = CefV8Value::CreateFunction(~functions.GetKey(f), this); - object->SetValue(~functions.GetKey(f), func, V8_PROPERTY_ATTRIBUTE_NONE); + for(int f = 0; f < __countof(func_names); f++){ + CefRefPtr func = CefV8Value::CreateFunction(func_names[f], this); + object->SetValue(func_names[f], func, V8_PROPERTY_ATTRIBUTE_NONE); } } @@ -36,19 +39,26 @@ void ClientApp::OnFocusedNodeChanged(CefRefPtr browser, CefRefPtr object, const CefV8ValueList& arguments, CefRefPtr& retval, CefString& exception) { - int f = functions.Find(name.ToString()); - if (f >= 0){ - functions[f].Execute(arguments, retval, exception); - return true; - }else{ - RLOG(Upp::String("ERROR: Unknown native function: ") + name.ToString()); - } - - return false; + CefRefPtr message = CefProcessMessage::Create(name); + CefRefPtr par = message->GetArgumentList(); + V8ValueListToCefListValue(arguments, par); + CefRefPtr browser = CefV8Context::GetCurrentContext()->GetBrowser(); + if (browser) browser->SendProcessMessage(PID_BROWSER, message); + return true; } -void ClientApp::JSExample1(const CefV8ValueList& args, CefRefPtr& retval, CefString& exc) +void ClientApp::V8ValueListToCefListValue(const CefV8ValueList& src, CefRefPtr & dst) { - retval = CefV8Value::CreateString("Function that returns some string"); + for (unsigned i = 0; i < src.size(); i++) + { + if (!src[i]->IsValid()) { dst->SetString(dst->GetSize(),"Invalid V8Value"); continue;} + if (src[i]->IsUndefined() || src[i]->IsNull()) { dst->SetNull(dst->GetSize()); continue;} + if (src[i]->IsBool()) { dst->SetBool(dst->GetSize(), src[i]->GetBoolValue()); continue;} + if (src[i]->IsInt()) { dst->SetInt(dst->GetSize(), src[i]->GetIntValue()); continue;} + if (src[i]->IsDouble()) { dst->SetDouble(dst->GetSize(),src[i]->GetDoubleValue()); continue;} + if (src[i]->IsString()) { dst->SetString(dst->GetSize(),src[i]->GetStringValue()); continue;} + + dst->SetString(dst->GetSize(), "Unimplemented V8Value conversion"); + } } diff --git a/bazaar/ChromiumBrowser/ClientApp.h b/bazaar/ChromiumBrowser/ClientApp.h index e45150cbc..b53891534 100644 --- a/bazaar/ChromiumBrowser/ClientApp.h +++ b/bazaar/ChromiumBrowser/ClientApp.h @@ -25,9 +25,7 @@ class ClientApp: public CefApp, private: CefRefPtr GetRenderProcessHandler() { return this; } - - Upp::VectorMap&, CefString&> > functions; - void JSExample1(const CefV8ValueList&, CefRefPtr&, CefString&); + void V8ValueListToCefListValue(const CefV8ValueList& src, CefRefPtr & dst); public: typedef ClientApp CLASSNAME; diff --git a/bazaar/ChromiumBrowser/ClientHandler.cpp b/bazaar/ChromiumBrowser/ClientHandler.cpp index 2ec3ad509..1e7a63ad3 100644 --- a/bazaar/ChromiumBrowser/ClientHandler.cpp +++ b/bazaar/ChromiumBrowser/ClientHandler.cpp @@ -66,11 +66,45 @@ void ClientHandler::OnLoadError(CefRefPtr browser, bool ClientHandler::OnProcessMessageReceived(CefRefPtr browser, CefProcessId source_process, CefRefPtr message) { if (message->GetName().ToString() == "show_keyboard"){ + PostCallback(callback1(WhenKeyboard, true)); + }else if (message->GetName().ToString() == "hide_keyboard"){ + PostCallback(callback1(WhenKeyboard, false)); + }else{ - PostCallback(callback1(WhenMessage, message->GetName().ToString())); + + CefRefPtr args = message->GetArgumentList(); + Upp::Vector par; + + for (unsigned i = 0; i < args->GetSize(); i++){ + CefValueType type = args->GetType(i); + switch(type){ + + case VTYPE_BOOL: + par.Add(args->GetBool(i)); + break; + + case VTYPE_DOUBLE: + par.Add(args->GetDouble(i)); + break; + + case VTYPE_INT: + par.Add(args->GetInt(i)); + break; + + case VTYPE_STRING: + par.Add(args->GetString(i).ToString().c_str()); + break; + + default: + par.Add("OnProcessMessageReceived: unsupported parameter type"); + break; + } + } + + PostCallback(callback2(WhenMessage, message->GetName().ToString(), par)); } return true; } @@ -87,8 +121,10 @@ void ClientHandler::OnBeforeContextMenu(CefRefPtr browser, CefRefPtr params, CefRefPtr model) { +#ifndef _DEBUG //Empty context menu model->Clear(); +#endif } diff --git a/bazaar/ChromiumBrowser/ClientHandler.h b/bazaar/ChromiumBrowser/ClientHandler.h index eb4515e60..8f0579f0d 100644 --- a/bazaar/ChromiumBrowser/ClientHandler.h +++ b/bazaar/ChromiumBrowser/ClientHandler.h @@ -23,7 +23,7 @@ class ClientHandler : public CefClient, public CefLifeSpanHandler, public CefDis public: ClientHandler( Upp::Callback1 & wuc, - Upp::Callback1 & wm, + Upp::Callback2 > > & wm, Upp::Callback & tf, Upp::Callback1 & wk, Upp::Callback3 & wcm): @@ -33,7 +33,7 @@ public: ~ClientHandler() { } Upp::Callback1 & WhenUrlChange; - Upp::Callback1 & WhenMessage; + Upp::Callback2 > > & WhenMessage; Upp::Callback & WhenTakeFocus; Upp::Callback1 & WhenKeyboard; Upp::Callback3 & WhenConsoleMessage; diff --git a/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.h b/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.h index b72d3ded8..c60a0c94a 100644 --- a/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.h +++ b/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.h @@ -14,11 +14,13 @@ class ChromiumBrowserExample : public WithChromiumBrowserExampleLayout > par); + void OnJSTests(); public: typedef ChromiumBrowserExample CLASSNAME; diff --git a/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.lay b/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.lay index c79c884a0..ae126e2b5 100644 --- a/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.lay +++ b/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.lay @@ -1,10 +1,11 @@ -LAYOUT(ChromiumBrowserExampleLayout, 388, 260) +LAYOUT(ChromiumBrowserExampleLayout, 504, 260) ITEM(Button, Back, Tip(t_("Go back")).LeftPosZ(4, 48).TopPosZ(4, 44)) ITEM(Button, Forward, Tip(t_("Go forward")).LeftPosZ(56, 48).TopPosZ(4, 44)) ITEM(Button, Refresh, Tip(t_("Refresh current page")).LeftPosZ(108, 48).TopPosZ(4, 44)) - ITEM(EditString, Url, SetFont(StdFontZ(32)).HSizePosZ(160, 108).TopPosZ(4, 44)) - ITEM(Button, Go, Tip(t_("Go")).RightPosZ(56, 48).TopPosZ(4, 44)) - ITEM(Button, Stop, Tip(t_("Stop")).RightPosZ(4, 48).TopPosZ(4, 44)) + ITEM(EditString, Url, SetFont(StdFontZ(32)).HSizePosZ(160, 160).TopPosZ(4, 44)) + ITEM(Button, Go, Tip(t_("Go")).RightPosZ(108, 48).TopPosZ(4, 44)) + ITEM(Button, JSTests, SetLabel(t_("JS Test")).Tip(t_("Stop")).RightPosZ(4, 48).TopPosZ(4, 44)) ITEM(ChromiumBrowser, Browser, StartPage("http://ultimatepp.org").HSizePosZ(0, 0).VSizePosZ(52, 0)) + ITEM(Button, Stop, Tip(t_("Stop")).RightPosZ(56, 48).TopPosZ(4, 44)) END_LAYOUT diff --git a/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.upp b/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.upp index 27b26b145..e23586aeb 100644 --- a/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.upp +++ b/bazaar/ChromiumBrowserExample/ChromiumBrowserExample.upp @@ -13,6 +13,8 @@ options(GCC) -std=c++11; link(GCC) "-Wl,-rpath ."; file + html/test_page.html, + files.brc, Utils readonly separator, Utils.h, Utils.cpp, diff --git a/bazaar/ChromiumBrowserExample/files.brc b/bazaar/ChromiumBrowserExample/files.brc new file mode 100644 index 000000000..49ef6f0e5 --- /dev/null +++ b/bazaar/ChromiumBrowserExample/files.brc @@ -0,0 +1,2 @@ +BINARY(test_page, "html/test_page.html") + diff --git a/bazaar/ChromiumBrowserExample/html/test_page.html b/bazaar/ChromiumBrowserExample/html/test_page.html new file mode 100644 index 000000000..4b2d431a2 --- /dev/null +++ b/bazaar/ChromiumBrowserExample/html/test_page.html @@ -0,0 +1,29 @@ + + + + + + + + +

+

+ + + + + diff --git a/bazaar/ChromiumBrowserExample/main.cpp b/bazaar/ChromiumBrowserExample/main.cpp index dbf82ab00..9b5ba7828 100644 --- a/bazaar/ChromiumBrowserExample/main.cpp +++ b/bazaar/ChromiumBrowserExample/main.cpp @@ -6,6 +6,7 @@ using namespace Upp; #define IMAGEFILE #include +#include "files.brc" ChromiumBrowserExample::ChromiumBrowserExample() { @@ -23,6 +24,7 @@ ChromiumBrowserExample::ChromiumBrowserExample() Browser.WhenTakeFocus = THISBACK(OnTakeFocus); Browser.WhenKeyboard = STDBACK(::ShowKeyboard); Browser.WhenConsoleMessage = THISBACK(OnConsoleMessage); + Browser.WhenMessage = THISBACK(OnMessage); Back.WhenAction = callback(&Browser, &ChromiumBrowser::GoBack); Forward.WhenAction = callback(&Browser, &ChromiumBrowser::GoForward); @@ -30,6 +32,7 @@ ChromiumBrowserExample::ChromiumBrowserExample() Url.WhenEnter = THISBACK(OnBrowse); Go.WhenAction = THISBACK(OnBrowse); Stop.WhenAction = callback(&Browser, &ChromiumBrowser::Stop); + JSTests.WhenAction = THISBACK(OnJSTests); #ifdef PLATFORM_WIN32 Maximize(); @@ -40,6 +43,27 @@ ChromiumBrowserExample::ChromiumBrowserExample() } + +void ChromiumBrowserExample::OnJSTests() +{ + Browser.ShowHTML(String(test_page, test_page_length)); +} + + +void ChromiumBrowserExample::OnMessage(String name, WithDeepCopy > par) +{ + String tmp = "Native function executed by JS:&[* " + name + "("; + for (int i = 0; i < par.GetCount(); i++){ + if (i > 0) tmp += ','; + tmp += DeQtfLf(par[i].ToString()); + } + tmp += ") ]&&After you press OK javascript function will be executed by native code"; + PromptOK(tmp); + + Browser.ExecuteJavaScript(Format("CallbackExample(%d);", (int)Random())); +} + + GUI_APP_MAIN { StdLogSetup(LOG_FILE | LOG_CERR | LOG_TIMESTAMP | LOG_APPEND);