Add CefFrame::GetV8Context() method for retrieving the V8 context of a frame (issue #344).

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@345 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2011-10-28 20:30:19 +00:00
parent 5147a4c7a0
commit 0ec9541b78
13 changed files with 154 additions and 16 deletions

View File

@ -1022,6 +1022,13 @@ public:
///
/*--cef()--*/
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) =0;
///
// Get the V8 context associated with the frame. This method should only be
// called on the UI thread.
///
/*--cef()--*/
virtual CefRefPtr<CefV8Context> GetV8Context() =0;
};

View File

@ -854,6 +854,13 @@ typedef struct _cef_frame_t
void (CEF_CALLBACK *visit_dom)(struct _cef_frame_t* self,
struct _cef_domvisitor_t* visitor);
///
// Get the V8 context associated with the frame. This function should only be
// called on the UI thread.
///
struct _cef_v8context_t* (CEF_CALLBACK *get_v8context)(
struct _cef_frame_t* self);
} cef_frame_t;

View File

@ -11,6 +11,7 @@
#include "dom_document_impl.h"
#include "request_impl.h"
#include "stream_impl.h"
#include "v8_impl.h"
#include "base/file_path.h"
#include "base/path_service.h"
@ -110,13 +111,13 @@ bool CefBrowser::CreateBrowser(CefWindowInfo& windowInfo,
{
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED();
NOTREACHED() << "context not valid";
return false;
}
// Verify that the settings structure is a valid size.
if (settings.size != sizeof(cef_browser_settings_t)) {
NOTREACHED();
NOTREACHED() << "invalid CefBrowserSettings structure size";
return false;
}
@ -135,19 +136,19 @@ CefRefPtr<CefBrowser> CefBrowser::CreateBrowserSync(
{
// Verify that the context is in a valid state.
if (!CONTEXT_STATE_VALID()) {
NOTREACHED();
NOTREACHED() << "context not valid";
return NULL;
}
// Verify that the settings structure is a valid size.
if (settings.size != sizeof(cef_browser_settings_t)) {
NOTREACHED();
NOTREACHED() << "invalid CefBrowserSettings structure size";
return NULL;
}
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return NULL;
}
@ -243,7 +244,7 @@ CefRefPtr<CefFrame> CefBrowserImpl::GetFocusedFrame()
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return NULL;
}
@ -255,7 +256,7 @@ CefRefPtr<CefFrame> CefBrowserImpl::GetFrame(const CefString& name)
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return NULL;
}
@ -273,7 +274,7 @@ void CefBrowserImpl::GetFrameNames(std::vector<CefString>& names)
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return;
}
@ -356,7 +357,7 @@ void CefBrowserImpl::CloseDevTools()
bool CefBrowserImpl::GetSize(PaintElementType type, int& width, int& height)
{
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return false;
}
@ -389,7 +390,7 @@ void CefBrowserImpl::SetSize(PaintElementType type, int width, int height)
bool CefBrowserImpl::IsPopupVisible()
{
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return false;
}
@ -416,7 +417,7 @@ bool CefBrowserImpl::GetImage(PaintElementType type, int width, int height,
void* buffer)
{
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return false;
}
@ -543,7 +544,7 @@ CefString CefBrowserImpl::GetSource(CefRefPtr<CefFrame> frame)
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return CefString();
}
@ -558,7 +559,7 @@ CefString CefBrowserImpl::GetText(CefRefPtr<CefFrame> frame)
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return CefString();
}
@ -615,7 +616,7 @@ CefString CefBrowserImpl::GetURL(CefRefPtr<CefFrame> frame)
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return CefString();
}
@ -1607,7 +1608,7 @@ bool CefFrameImpl::IsFocused()
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED();
NOTREACHED() << "called on invalid thread";
return false;
}
@ -1619,10 +1620,27 @@ bool CefFrameImpl::IsFocused()
void CefFrameImpl::VisitDOM(CefRefPtr<CefDOMVisitor> visitor)
{
if(!visitor.get()) {
NOTREACHED();
NOTREACHED() << "invalid parameter";
return;
}
CefRefPtr<CefFrame> framePtr(this);
CefThread::PostTask(CefThread::UI, FROM_HERE, NewRunnableMethod(
browser_.get(), &CefBrowserImpl::UIT_VisitDOM, framePtr, visitor));
}
CefRefPtr<CefV8Context> CefFrameImpl::GetV8Context()
{
// Verify that this method is being called on the UI thread.
if (!CefThread::CurrentlyOn(CefThread::UI)) {
NOTREACHED() << "called on invalid thread";
return NULL;
}
WebKit::WebFrame* frame = browser_->UIT_GetWebFrame(this);
if (frame) {
v8::HandleScope handle_scope;
return new CefV8ContextImpl(webkit_glue::GetV8Context(frame));
} else {
return NULL;
}
}

View File

@ -447,6 +447,7 @@ public:
virtual CefString GetURL() OVERRIDE { return browser_->GetURL(this); }
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE { return browser_.get(); }
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) OVERRIDE;
virtual CefRefPtr<CefV8Context> GetV8Context() OVERRIDE;
private:
CefRefPtr<CefBrowserImpl> browser_;

View File

@ -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/v8context_cpptoc.h"
#include "libcef_dll/ctocpp/domvisitor_ctocpp.h"
@ -237,6 +238,21 @@ void CEF_CALLBACK frame_visit_dom(struct _cef_frame_t* self,
CefFrameCppToC::Get(self)->VisitDOM(CefDOMVisitorCToCpp::Wrap(visitor));
}
struct _cef_v8context_t* CEF_CALLBACK frame_get_v8context(
struct _cef_frame_t* self)
{
DCHECK(self);
if (!self)
return NULL;
CefRefPtr<CefFrame> framePtr = CefFrameCppToC::Get(self);
CefRefPtr<CefV8Context> v8ContextPtr = framePtr->GetV8Context();
if (v8ContextPtr.get())
return CefV8ContextCppToC::Wrap(v8ContextPtr);
return NULL;
}
// CONSTRUCTOR - Do not edit by hand.
@ -265,6 +281,7 @@ CefFrameCppToC::CefFrameCppToC(CefFrame* cls)
struct_.struct_.get_url = frame_get_url;
struct_.struct_.get_browser = frame_get_browser;
struct_.struct_.visit_dom = frame_visit_dom;
struct_.struct_.get_v8context = frame_get_v8context;
}
#ifndef NDEBUG

View File

@ -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/v8context_ctocpp.h"
// VIRTUAL METHODS - Body may be edited by hand.
@ -216,6 +217,18 @@ void CefFrameCToCpp::VisitDOM(CefRefPtr<CefDOMVisitor> visitor)
struct_->visit_dom(struct_, CefDOMVisitorCppToC::Wrap(visitor));
}
CefRefPtr<CefV8Context> CefFrameCToCpp::GetV8Context()
{
if (CEF_MEMBER_MISSING(struct_, get_v8context))
return NULL;
cef_v8context_t* v8ContextStruct = struct_->get_v8context(struct_);
if (v8ContextStruct)
return CefV8ContextCToCpp::Wrap(v8ContextStruct);
return NULL;
}
#ifndef NDEBUG
template<> long CefCToCpp<CefFrameCToCpp, CefFrame, cef_frame_t>::DebugObjCt =

View File

@ -56,6 +56,7 @@ public:
virtual CefString GetURL() OVERRIDE;
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) OVERRIDE;
virtual CefRefPtr<CefV8Context> GetV8Context() OVERRIDE;
};
#endif // USING_CEF_SHARED

View File

@ -14,6 +14,54 @@
#include <stdio.h>
#include <string>
namespace {
void UIT_InvokeScript(CefRefPtr<CefBrowser> browser)
{
REQUIRE_UI_THREAD();
CefRefPtr<CefFrame> frame = browser->GetMainFrame();
CefRefPtr<CefV8Context> v8Context = frame->GetV8Context();
CefString url = frame->GetURL();
if (!v8Context.get()) {
frame->ExecuteJavaScript("alert('Failed to get V8 context!');", url, 0);
} else if (v8Context->Enter()) {
CefRefPtr<CefV8Value> globalObj = v8Context->GetGlobal();
CefRefPtr<CefV8Value> evalFunc = globalObj->GetValue("eval");
CefRefPtr<CefV8Value> arg0 = CefV8Value::CreateString("1+2");
CefV8ValueList args;
args.push_back(arg0);
CefRefPtr<CefV8Value> retVal;
CefString exception;
if (evalFunc->ExecuteFunctionWithContext(v8Context, globalObj, args, retVal,
exception)) {
if (retVal.get()) {
frame->ExecuteJavaScript(
std::string("alert('InvokeScript returns ") +
retVal->GetStringValue().ToString() + "!');",
url, 0);
} else {
frame->ExecuteJavaScript(
std::string("alert('InvokeScript returns exception: ") +
exception.ToString() + "!');",
url, 0);
}
} else {
frame->ExecuteJavaScript("alert('Failed to execute function!');", url, 0);
}
v8Context->Exit();
} else {
frame->ExecuteJavaScript("alert('Failed to enter into V8 context!');",
url, 0);
}
}
} // namespace
CefRefPtr<ClientHandler> g_handler;
@ -102,6 +150,16 @@ void RunJavaScriptExecuteTest(CefRefPtr<CefBrowser> browser)
"alert('JavaScript execute works!');", "about:blank", 0);
}
void RunJavaScriptInvokeTest(CefRefPtr<CefBrowser> browser)
{
if (CefCurrentlyOn(TID_UI)) {
UIT_InvokeScript(browser);
} else {
// Execute on the UI thread.
CefPostTask(TID_UI, NewCefRunnableFunction(&UIT_InvokeScript, browser));
}
}
void RunPopupTest(CefRefPtr<CefBrowser> browser)
{
browser->GetMainFrame()->ExecuteJavaScript(

View File

@ -21,6 +21,7 @@ void RunGetSourceTest(CefRefPtr<CefBrowser> browser);
void RunGetTextTest(CefRefPtr<CefBrowser> browser);
void RunRequestTest(CefRefPtr<CefBrowser> browser);
void RunJavaScriptExecuteTest(CefRefPtr<CefBrowser> browser);
void RunJavaScriptInvokeTest(CefRefPtr<CefBrowser> browser);
void RunPopupTest(CefRefPtr<CefBrowser> browser);
void RunLocalStorageTest(CefRefPtr<CefBrowser> browser);
void RunAccelerated2DCanvasTest(CefRefPtr<CefBrowser> browser);

View File

@ -77,6 +77,7 @@ BEGIN
MENUITEM "JavaScript Extension Handler",ID_TESTS_JAVASCRIPT_EXTENSION
MENUITEM "JavaScript Extension Performance",ID_TESTS_JAVASCRIPT_PERFORMANCE
MENUITEM "JavaScript Execute", ID_TESTS_JAVASCRIPT_EXECUTE
MENUITEM "JavaScript Invoke", ID_TESTS_JAVASCRIPT_INVOKE
MENUITEM "Plugin", ID_TESTS_PLUGIN
MENUITEM "Popup Window", ID_TESTS_POPUP
MENUITEM "Transparent Popup Window", ID_TESTS_TRANSPARENT_POPUP

View File

@ -190,6 +190,7 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
- (IBAction)testJSExtension:(id)sender;
- (IBAction)testJSExtensionPerf:(id)sender;
- (IBAction)testJSExecute:(id)sender;
- (IBAction)testJSInvoke:(id)sender;
- (IBAction)testRequest:(id)sender;
- (IBAction)testLocalStorage:(id)sender;
- (IBAction)testXMLHttpRequest:(id)sender;
@ -243,6 +244,9 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
[testMenu addItemWithTitle:@"JavaScript Execute"
action:@selector(testJSExecute:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"JavaScript Invoke"
action:@selector(testJSInvoke:)
keyEquivalent:@""];
[testMenu addItemWithTitle:@"Popup Window"
action:@selector(testPopupWindow:)
keyEquivalent:@""];
@ -411,6 +415,11 @@ NSButton* MakeButton(NSRect* rect, NSString* title, NSView* parent) {
RunJavaScriptExecuteTest(g_handler->GetBrowser());
}
- (IBAction)testJSInvoke:(id)sender {
if(g_handler.get() && g_handler->GetBrowserHwnd())
RunJavaScriptInvokeTest(g_handler->GetBrowser());
}
- (IBAction)testRequest:(id)sender {
if(g_handler.get() && g_handler->GetBrowserHwnd())
RunRequestTest(g_handler->GetBrowser());

View File

@ -487,6 +487,10 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
if(browser.get())
RunJavaScriptExecuteTest(browser);
return 0;
case ID_TESTS_JAVASCRIPT_INVOKE:
if(browser.get())
RunJavaScriptInvokeTest(browser);
return 0;
case ID_TESTS_PLUGIN: // Test the custom plugin
if(browser.get())
RunPluginTest(browser);

View File

@ -55,6 +55,7 @@
#define ID_TESTS_JAVASCRIPT_PERFORMANCE 32795
#define ID_TESTS_TRANSPARENT_POPUP 32796
#define ID_TESTS_TRANSPARENT_OSRAPP 32797
#define ID_TESTS_JAVASCRIPT_INVOKE 32798
#define IDC_STATIC -1
#define IDS_LOGO 1000
#define IDS_UIPLUGIN 1001