From e8cc5669f0264809c300aa26eaca4ae40767a53b Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Tue, 31 Aug 2010 17:52:34 +0000 Subject: [PATCH] - Fix bug in CefV8Value handling of weak references. (issue #72) - Reintroduce support for CefHandler::HandleJSBinding(). (issue #72) git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@100 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- cef.gyp | 2 + include/cef.h | 12 +- include/cef_capi.h | 11 +- libcef/browser_webkit_glue.cc | 7 ++ libcef/browser_webkit_glue.h | 3 + libcef/browser_webview_delegate.cc | 16 +++ libcef/browser_webview_delegate.h | 1 + libcef/v8_impl.cc | 3 +- libcef_dll/cpptoc/handler_cpptoc.cc | 18 +++ libcef_dll/ctocpp/handler_ctocpp.cc | 12 ++ libcef_dll/ctocpp/handler_ctocpp.h | 2 + tests/cefclient/binding_test.cpp | 173 ++++++++++++++++++++++++++++ tests/cefclient/binding_test.h | 14 +++ tests/cefclient/cefclient.cpp | 19 ++- tests/cefclient/cefclient.rc | 3 +- tests/cefclient/resource.h | 15 +-- tests/unittests/test_handler.h | 7 ++ tests/unittests/v8_unittest.cc | 81 ++++++++++++- 18 files changed, 381 insertions(+), 18 deletions(-) create mode 100644 tests/cefclient/binding_test.cpp create mode 100644 tests/cefclient/binding_test.h diff --git a/cef.gyp b/cef.gyp index 58c1fb146..20ae0248e 100644 --- a/cef.gyp +++ b/cef.gyp @@ -25,6 +25,8 @@ ], 'sources': [ 'tests/cefclient/Resource.h', + 'tests/cefclient/binding_test.cpp', + 'tests/cefclient/binding_test.h', 'tests/cefclient/cefclient.cpp', 'tests/cefclient/cefclient.h', 'tests/cefclient/cefclient.ico', diff --git a/include/cef.h b/include/cef.h index a78c83d60..488f0f6da 100644 --- a/include/cef.h +++ b/include/cef.h @@ -699,6 +699,13 @@ public: bool& retval, std::wstring& result) =0; + // Event called for adding values to a frame's JavaScript 'window' object. The + // return value is currently ignored. + /*--cef()--*/ + virtual RetVal HandleJSBinding(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) =0; + // Called just before a window is closed. The return value is currently // ignored. /*--cef()--*/ @@ -1025,8 +1032,9 @@ class CefV8Value : public CefBase { public: // Create a new CefV8Value object of the specified type. These methods - // should only be called from within the JavaScript context in a - // CefV8Handler::Execute() callback. + // should only be called from within the JavaScript context -- either in a + // CefV8Handler::Execute() callback or a CefHandler::HandleJSBinding() + // callback. /*--cef()--*/ static CefRefPtr CreateUndefined(); /*--cef()--*/ diff --git a/include/cef_capi.h b/include/cef_capi.h index d0a4d426f..18ffc9695 100644 --- a/include/cef_capi.h +++ b/include/cef_capi.h @@ -511,6 +511,12 @@ typedef struct _cef_handler_t const wchar_t* message, const wchar_t* defaultValue, int* retval, cef_string_t* result); + // Event called for adding values to a frame's JavaScript 'window' object. The + // return value is currently ignored. + enum cef_retval_t (CEF_CALLBACK *handle_jsbinding)( + struct _cef_handler_t* self, struct _cef_browser_t* browser, + struct _cef_frame_t* frame, struct _cef_v8value_t* object); + // Called just before a window is closed. The return value is currently // ignored. enum cef_retval_t (CEF_CALLBACK *handle_before_window_close)( @@ -906,8 +912,9 @@ typedef struct _cef_v8value_t // Create a new cef_v8value_t object of the specified type. These functions -// should only be called from within the JavaScript context in a -// cef_v8handler_t::execute() callback. +// should only be called from within the JavaScript context -- either in a +// cef_v8handler_t::execute() callback or a cef_handler_t::handle_jsbinding() +// callback. CEF_EXPORT cef_v8value_t* cef_v8value_create_undefined(); CEF_EXPORT cef_v8value_t* cef_v8value_create_null(); CEF_EXPORT cef_v8value_t* cef_v8value_create_bool(int value); diff --git a/libcef/browser_webkit_glue.cc b/libcef/browser_webkit_glue.cc index d31dfd20f..3e3d0484a 100644 --- a/libcef/browser_webkit_glue.cc +++ b/libcef/browser_webkit_glue.cc @@ -81,6 +81,13 @@ void InitializeTextEncoding() { WebCore::UTF8Encoding(); } +v8::Handle GetV8Context(WebKit::WebFrame* frame) +{ + WebFrameImpl* webFrameImpl = static_cast(frame); + WebCore::Frame* core_frame = webFrameImpl->frame(); + return WebCore::V8Proxy::context(core_frame); +} + void CloseIdleConnections() { // Used in benchmarking, Ignored for CEF. } diff --git a/libcef/browser_webkit_glue.h b/libcef/browser_webkit_glue.h index 23ba2d5ee..e1e34d77a 100644 --- a/libcef/browser_webkit_glue.h +++ b/libcef/browser_webkit_glue.h @@ -33,6 +33,9 @@ void InitializeTextEncoding(); // This is called indirectly by the network layer to access resources. base::StringPiece NetResourceProvider(int key); +// Retrieve the V8 context associated with the frame. +v8::Handle GetV8Context(WebKit::WebFrame* frame); + // Clear all cached data. void ClearCache(); diff --git a/libcef/browser_webview_delegate.cc b/libcef/browser_webview_delegate.cc index 207d1cfed..cb0d52c29 100644 --- a/libcef/browser_webview_delegate.cc +++ b/libcef/browser_webview_delegate.cc @@ -700,6 +700,22 @@ void BrowserWebViewDelegate::didCommitProvisionalLoad( } } +void BrowserWebViewDelegate::didClearWindowObject(WebFrame* frame) { + CefRefPtr handler = browser_->GetHandler(); + if(handler.get()) { + v8::HandleScope handle_scope; + v8::Handle context = webkit_glue::GetV8Context(frame); + if(context.IsEmpty()) + return; + + v8::Context::Scope scope(context); + + CefRefPtr cframe(browser_->GetCefFrame(frame)); + CefRefPtr object = new CefV8ValueImpl(context->Global()); + handler->HandleJSBinding(browser_, cframe, object); + } +} + void BrowserWebViewDelegate::didReceiveTitle( WebFrame* frame, const WebString& title) { std::wstring wtitle = UTF16ToWideHack(title); diff --git a/libcef/browser_webview_delegate.h b/libcef/browser_webview_delegate.h index 1f49fd0f8..ff2af4987 100644 --- a/libcef/browser_webview_delegate.h +++ b/libcef/browser_webview_delegate.h @@ -152,6 +152,7 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient, WebKit::WebFrame*, const WebKit::WebURLError&); virtual void didCommitProvisionalLoad( WebKit::WebFrame*, bool is_new_navigation); + virtual void didClearWindowObject(WebKit::WebFrame*); virtual void didReceiveTitle( WebKit::WebFrame*, const WebKit::WebString& title); virtual void didFailLoad( diff --git a/libcef/v8_impl.cc b/libcef/v8_impl.cc index 912c6be59..5d8b42237 100644 --- a/libcef/v8_impl.cc +++ b/libcef/v8_impl.cc @@ -50,6 +50,8 @@ static void TrackDestructor(v8::Persistent object, { if(parameter) TrackDelete(static_cast(parameter)); + object.Dispose(); + object.Clear(); } @@ -305,7 +307,6 @@ void CefV8ValueImpl::Detach() if(tracker_) TrackAdd(tracker_); v8_value_.MakeWeak(tracker_, TrackDestructor); - v8_value_.Clear(); tracker_ = NULL; Unlock(); } diff --git a/libcef_dll/cpptoc/handler_cpptoc.cc b/libcef_dll/cpptoc/handler_cpptoc.cc index b4e85eb99..a2af92001 100644 --- a/libcef_dll/cpptoc/handler_cpptoc.cc +++ b/libcef_dll/cpptoc/handler_cpptoc.cc @@ -15,6 +15,7 @@ #include "libcef_dll/ctocpp/frame_ctocpp.h" #include "libcef_dll/ctocpp/request_ctocpp.h" #include "libcef_dll/ctocpp/stream_reader_ctocpp.h" +#include "libcef_dll/ctocpp/v8value_ctocpp.h" #include "libcef_dll/transfer_util.h" @@ -419,6 +420,22 @@ enum cef_retval_t CEF_CALLBACK handler_handle_jsprompt( return rv; } +enum cef_retval_t CEF_CALLBACK handler_handle_jsbinding( + struct _cef_handler_t* self, cef_browser_t* browser, cef_frame_t* frame, + struct _cef_v8value_t* object) +{ + DCHECK(self); + DCHECK(browser); + DCHECK(frame); + DCHECK(object); + if(!self || !browser || !frame || !object) + return RV_CONTINUE; + + return CefHandlerCppToC::Get(self)->HandleJSBinding( + CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame), + CefV8ValueCToCpp::Wrap(object)); +} + enum cef_retval_t CEF_CALLBACK handler_handle_before_window_close( struct _cef_handler_t* self, cef_browser_t* browser) { @@ -551,6 +568,7 @@ CefHandlerCppToC::CefHandlerCppToC(CefHandler* cls) struct_.struct_.handle_jsalert = handler_handle_jsalert; struct_.struct_.handle_jsconfirm = handler_handle_jsconfirm; struct_.struct_.handle_jsprompt = handler_handle_jsprompt; + struct_.struct_.handle_jsbinding = handler_handle_jsbinding; struct_.struct_.handle_before_window_close = handler_handle_before_window_close; struct_.struct_.handle_take_focus = handler_handle_take_focus; diff --git a/libcef_dll/ctocpp/handler_ctocpp.cc b/libcef_dll/ctocpp/handler_ctocpp.cc index 292623960..de7faf6b2 100644 --- a/libcef_dll/ctocpp/handler_ctocpp.cc +++ b/libcef_dll/ctocpp/handler_ctocpp.cc @@ -14,6 +14,7 @@ #include "libcef_dll/cpptoc/frame_cpptoc.h" #include "libcef_dll/cpptoc/request_cpptoc.h" #include "libcef_dll/cpptoc/stream_reader_cpptoc.h" +#include "libcef_dll/cpptoc/v8value_cpptoc.h" #include "libcef_dll/ctocpp/handler_ctocpp.h" #include "libcef_dll/transfer_util.h" @@ -317,6 +318,17 @@ CefHandler::RetVal CefHandlerCToCpp::HandleJSPrompt( return rv; } +CefHandler::RetVal CefHandlerCToCpp::HandleJSBinding( + CefRefPtr browser, CefRefPtr frame, + CefRefPtr object) +{ + if(CEF_MEMBER_MISSING(struct_, handle_jsbinding)) + return RV_CONTINUE; + + return struct_->handle_jsbinding(struct_, CefBrowserCppToC::Wrap(browser), + CefFrameCppToC::Wrap(frame), CefV8ValueCppToC::Wrap(object)); +} + CefHandler::RetVal CefHandlerCToCpp::HandleBeforeWindowClose( CefRefPtr browser) { diff --git a/libcef_dll/ctocpp/handler_ctocpp.h b/libcef_dll/ctocpp/handler_ctocpp.h index d5c14a1ed..16c5d4ff2 100644 --- a/libcef_dll/ctocpp/handler_ctocpp.h +++ b/libcef_dll/ctocpp/handler_ctocpp.h @@ -73,6 +73,8 @@ public: virtual RetVal HandleJSPrompt(CefRefPtr browser, CefRefPtr frame, const std::wstring& message, const std::wstring& defaultValue, bool& retval, std::wstring& result); + virtual RetVal HandleJSBinding(CefRefPtr browser, + CefRefPtr frame, CefRefPtr object); virtual RetVal HandleBeforeWindowClose(CefRefPtr browser); virtual RetVal HandleTakeFocus(CefRefPtr browser, bool reverse); virtual RetVal HandleSetFocus(CefRefPtr browser, bool isWidget); diff --git a/tests/cefclient/binding_test.cpp b/tests/cefclient/binding_test.cpp new file mode 100644 index 000000000..647638920 --- /dev/null +++ b/tests/cefclient/binding_test.cpp @@ -0,0 +1,173 @@ +// Copyright (c) 2008-2009 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#include "binding_test.h" +#include + + +// Implementation of the V8 handler class for the "window.cef_test.Dump" +// function. +class ClientV8FunctionHandler : public CefThreadSafeBase +{ +public: + ClientV8FunctionHandler() {} + virtual ~ClientV8FunctionHandler() {} + + // Execute with the specified argument list and return value. Return true if + // the method was handled. + virtual bool Execute(const std::wstring& name, + CefRefPtr object, + const CefV8ValueList& arguments, + CefRefPtr& retval, + std::wstring& exception) + { + if(name == L"Dump") + { + // The "Dump" function will return a human-readable dump of the input + // arguments. + std::wstringstream stream; + size_t i; + + for(i = 0; i < arguments.size(); ++i) + { + stream << L"arg[" << i << L"] = "; + PrintValue(arguments[i], stream, 0); + stream << L"\n"; + } + + retval = CefV8Value::CreateString(stream.str()); + return true; + } + else if(name == L"Call") + { + // The "Call" function will execute a function to get an object and then + // return the result of calling a function belonging to that object. The + // first arument is the function that will return an object and the second + // argument is the function that will be called on that returned object. + int argSize = arguments.size(); + if(argSize < 2 || !arguments[0]->IsFunction() + || !arguments[1]->IsString()) + return false; + + CefV8ValueList argList; + + // Execute the function stored in the first argument to retrieve an + // object. + CefRefPtr objectPtr; + if(!arguments[0]->ExecuteFunction(object, argList, objectPtr, exception)) + return false; + // Verify that the returned value is an object. + if(!objectPtr.get() || !objectPtr->IsObject()) + return false; + + // Retrieve the member function specified by name in the second argument + // from the object. + CefRefPtr funcPtr = + objectPtr->GetValue(arguments[1]->GetStringValue()); + // Verify that the returned value is a function. + if(!funcPtr.get() || !funcPtr->IsFunction()) + return false; + + // Pass any additional arguments on to the member function. + for(int i = 2; i < argSize; ++i) + argList.push_back(arguments[i]); + + // Execute the member function. + return funcPtr->ExecuteFunction(arguments[0], argList, retval, exception); + } + return false; + } + + // Simple function for formatted output of a V8 value. + void PrintValue(CefRefPtr value, std::wstringstream &stream, + int indent) + { + std::wstringstream indent_stream; + for(int i = 0; i < indent; ++i) + indent_stream << L" "; + std::wstring indent_str = indent_stream.str(); + + if(value->IsUndefined()) + stream << L"(undefined)"; + else if(value->IsNull()) + stream << L"(null)"; + else if(value->IsBool()) + stream << L"(bool) " << (value->GetBoolValue() ? L"true" : L"false"); + else if(value->IsInt()) + stream << L"(int) " << value->GetIntValue(); + else if(value->IsDouble()) + stream << L"(double) " << value->GetDoubleValue(); + else if(value->IsString()) + stream << L"(string) " << value->GetStringValue().c_str(); + else if(value->IsFunction()) + stream << L"(function) " << value->GetFunctionName().c_str(); + else if(value->IsArray()) { + stream << L"(array) ["; + int len = value->GetArrayLength(); + for(int i = 0; i < len; ++i) { + stream << L"\n " << indent_str.c_str() << i << L" = "; + PrintValue(value->GetValue(i), stream, indent+1); + } + stream << L"\n" << indent_str.c_str() << L"]"; + } else if(value->IsObject()) { + stream << L"(object) ["; + std::vector keys; + if(value->GetKeys(keys)) { + for(size_t i = 0; i < keys.size(); ++i) { + stream << L"\n " << indent_str.c_str() << keys[i].c_str() << L" = "; + PrintValue(value->GetValue(keys[i]), stream, indent+1); + } + } + stream << L"\n" << indent_str.c_str() << L"]"; + } + } +}; + + +void InitBindingTest(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) +{ + // Create the new V8 object. + CefRefPtr testObjPtr = CefV8Value::CreateObject(NULL); + // Add the new V8 object to the global window object with the name + // "cef_test". + object->SetValue(L"cef_test", testObjPtr); + + // Create an instance of ClientV8FunctionHandler as the V8 handler. + CefRefPtr handlerPtr = new ClientV8FunctionHandler(); + + // Add a new V8 function to the cef_test object with the name "Dump". + testObjPtr->SetValue(L"Dump", + CefV8Value::CreateFunction(L"Dump", handlerPtr)); + // Add a new V8 function to the cef_test object with the name "Call". + testObjPtr->SetValue(L"Call", + CefV8Value::CreateFunction(L"Call", handlerPtr)); +} + +void RunBindingTest(CefRefPtr browser) +{ + std::wstring html = + L"ClientV8FunctionHandler says:
"
+    L""
+    L"
"; + browser->GetMainFrame()->LoadString(html, L"about:blank"); +} diff --git a/tests/cefclient/binding_test.h b/tests/cefclient/binding_test.h new file mode 100644 index 000000000..f760ffab3 --- /dev/null +++ b/tests/cefclient/binding_test.h @@ -0,0 +1,14 @@ +// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. + +#pragma once +#include "include/cef.h" + +// Add the V8 bindings. +void InitBindingTest(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object); + +// Run the test. +void RunBindingTest(CefRefPtr browser); diff --git a/tests/cefclient/cefclient.cpp b/tests/cefclient/cefclient.cpp index cb673f7d2..f4d13ed04 100644 --- a/tests/cefclient/cefclient.cpp +++ b/tests/cefclient/cefclient.cpp @@ -4,6 +4,7 @@ #include "include/cef.h" #include "cefclient.h" +#include "binding_test.h" #include "extension_test.h" #include "plugin_test.h" #include "resource_util.h" @@ -505,6 +506,18 @@ public: return RV_CONTINUE; } + // Event called for binding to a frame's JavaScript global object. The + // return value is currently ignored. + virtual RetVal HandleJSBinding(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) + { + // Add the V8 bindings. + InitBindingTest(browser, frame, object); + + return RV_HANDLED; + } + // Called just before a window is closed. The return value is currently // ignored. virtual RetVal HandleBeforeWindowClose(CefRefPtr browser) @@ -1013,7 +1026,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) #endif // !TEST_SINGLE_THREADED_MESSAGE_LOOP } return 0; - case ID_TESTS_JAVASCRIPT_HANDLER: // Test the V8 extension handler + case ID_TESTS_JAVASCRIPT_BINDING: // Test the V8 binding handler + if(browser.get()) + RunBindingTest(browser); + return 0; + case ID_TESTS_JAVASCRIPT_EXTENSION: // Test the V8 extension handler if(browser.get()) RunExtensionTest(browser); return 0; diff --git a/tests/cefclient/cefclient.rc b/tests/cefclient/cefclient.rc index 57a7aa9b1..0f8d49376 100644 --- a/tests/cefclient/cefclient.rc +++ b/tests/cefclient/cefclient.rc @@ -65,7 +65,8 @@ BEGIN BEGIN MENUITEM "Get Source", ID_TESTS_GETSOURCE MENUITEM "Get Text", ID_TESTS_GETTEXT - MENUITEM "JavaScript Extension Handler",ID_TESTS_JAVASCRIPT_HANDLER + MENUITEM "JavaScript Binding Handler", ID_TESTS_JAVASCRIPT_BINDING + MENUITEM "JavaScript Extension Handler",ID_TESTS_JAVASCRIPT_EXTENSION MENUITEM "JavaScript Execute", ID_TESTS_JAVASCRIPT_EXECUTE MENUITEM "Plugin", ID_TESTS_PLUGIN MENUITEM "Popup Window", ID_TESTS_POPUP diff --git a/tests/cefclient/resource.h b/tests/cefclient/resource.h index a8c53328d..ea53c5d78 100644 --- a/tests/cefclient/resource.h +++ b/tests/cefclient/resource.h @@ -26,13 +26,14 @@ #define ID_PRINT 32002 #define ID_TESTS_GETSOURCE 32769 #define ID_TESTS_GETTEXT 32770 -#define ID_TESTS_JAVASCRIPT_HANDLER 32771 -#define ID_TESTS_JAVASCRIPT_EXECUTE 32772 -#define ID_TESTS_PLUGIN 32773 -#define ID_TESTS_POPUP 32774 -#define ID_TESTS_REQUEST 32775 -#define ID_TESTS_SCHEME_HANDLER 32776 -#define ID_TESTS_UIAPP 32777 +#define ID_TESTS_JAVASCRIPT_BINDING 32771 +#define ID_TESTS_JAVASCRIPT_EXTENSION 32772 +#define ID_TESTS_JAVASCRIPT_EXECUTE 32773 +#define ID_TESTS_PLUGIN 32774 +#define ID_TESTS_POPUP 32775 +#define ID_TESTS_REQUEST 32776 +#define ID_TESTS_SCHEME_HANDLER 32777 +#define ID_TESTS_UIAPP 32778 #define IDC_STATIC -1 #define IDS_LOGO 1000 #define IDS_UIPLUGIN 1001 diff --git a/tests/unittests/test_handler.h b/tests/unittests/test_handler.h index eb549e86d..5e888db5d 100644 --- a/tests/unittests/test_handler.h +++ b/tests/unittests/test_handler.h @@ -175,6 +175,13 @@ public: return RV_CONTINUE; } + virtual RetVal HandleJSBinding(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) + { + return RV_CONTINUE; + } + virtual RetVal HandleBeforeWindowClose(CefRefPtr browser) { Lock(); diff --git a/tests/unittests/v8_unittest.cc b/tests/unittests/v8_unittest.cc index 7a02f34a8..fc31f993d 100644 --- a/tests/unittests/v8_unittest.cc +++ b/tests/unittests/v8_unittest.cc @@ -215,12 +215,18 @@ public: class V8TestHandler : public TestHandler { public: - V8TestHandler() {} + V8TestHandler(bool bindingTest) { binding_test_ = bindingTest; } virtual void RunTest() { - // extension uses a global object - std::string object = "test"; + std::string object; + if(binding_test_) { + // binding uses the window object + object = "window.test"; + } else { + // extension uses a global object + object = "test"; + } std::stringstream testHtml; testHtml << @@ -247,8 +253,75 @@ public: DestroyTest(); return RV_CONTINUE; } + + virtual RetVal HandleJSBinding(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) + { + if(binding_test_) { + TestHandleJSBinding(browser, frame, object); + return RV_HANDLED; + } + return RV_CONTINUE; + } + + void TestHandleJSBinding(CefRefPtr browser, + CefRefPtr frame, + CefRefPtr object) + { + // Create the new V8 object + CefRefPtr testObj = CefV8Value::CreateObject(NULL); + ASSERT_TRUE(testObj.get() != NULL); + ASSERT_TRUE(object->SetValue(L"test", testObj)); + + // Create an instance of V8ExecuteV8Handler + CefRefPtr testHandler(new V8TestV8Handler(true)); + ASSERT_TRUE(testHandler.get() != NULL); + + // Add the functions + CefRefPtr testFunc; + testFunc = CefV8Value::CreateFunction(L"execute", testHandler); + ASSERT_TRUE(testFunc.get() != NULL); + ASSERT_TRUE(testObj->SetValue(L"execute", testFunc)); + testFunc = CefV8Value::CreateFunction(L"execute2", testHandler); + ASSERT_TRUE(testFunc.get() != NULL); + ASSERT_TRUE(testObj->SetValue(L"execute2", testFunc)); + + // Add the values + ASSERT_TRUE(testObj->SetValue(L"intVal", + CefV8Value::CreateInt(12))); + ASSERT_TRUE(testObj->SetValue(L"doubleVal", + CefV8Value::CreateDouble(5.432))); + ASSERT_TRUE(testObj->SetValue(L"boolVal", + CefV8Value::CreateBool(true))); + ASSERT_TRUE(testObj->SetValue(L"stringVal", + CefV8Value::CreateString(L"the string"))); + + CefRefPtr testArray(CefV8Value::CreateArray()); + ASSERT_TRUE(testArray.get() != NULL); + ASSERT_TRUE(testObj->SetValue(L"arrayVal", testArray)); + ASSERT_TRUE(testArray->SetValue(0, CefV8Value::CreateInt(4))); + ASSERT_TRUE(testArray->SetValue(1, CefV8Value::CreateDouble(120.43))); + ASSERT_TRUE(testArray->SetValue(2, CefV8Value::CreateBool(true))); + ASSERT_TRUE(testArray->SetValue(3, CefV8Value::CreateString(L"a string"))); + } + + bool binding_test_; }; +// Verify window binding +TEST(V8Test, Binding) +{ + g_V8TestV8HandlerExecuteCalled = false; + g_V8TestV8HandlerExecute2Called = false; + + CefRefPtr handler = new V8TestHandler(true); + handler->ExecuteTest(); + + ASSERT_TRUE(g_V8TestV8HandlerExecuteCalled); + ASSERT_TRUE(g_V8TestV8HandlerExecute2Called); +} + // Verify extensions TEST(V8Test, Extension) { @@ -271,7 +344,7 @@ TEST(V8Test, Extension) L"})();"; CefRegisterExtension(L"v8/test", extensionCode, new V8TestV8Handler(false)); - CefRefPtr handler = new V8TestHandler(); + CefRefPtr handler = new V8TestHandler(false); handler->ExecuteTest(); ASSERT_TRUE(g_V8TestV8HandlerExecuteCalled);