mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-17 04:30:46 +01:00
cefclient:
- Add tests for CefBrowser::GetText() and CefBrowser::GetSource(). - Do not execute calls to CefBrowser::GetText() and CefBrowser::GetSource() on the main application UI thread when running in multi-threaded message loop mode because those calls will block resulting in potential deadlock (issue #79). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@76 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
parent
698f146e4c
commit
02fa65cefe
1
cef.gyp
1
cef.gyp
@ -46,6 +46,7 @@
|
|||||||
'tests/cefclient/scheme_test.h',
|
'tests/cefclient/scheme_test.h',
|
||||||
'tests/cefclient/string_util.cpp',
|
'tests/cefclient/string_util.cpp',
|
||||||
'tests/cefclient/string_util.h',
|
'tests/cefclient/string_util.h',
|
||||||
|
'tests/cefclient/thread_util.h',
|
||||||
'tests/cefclient/uiplugin.cpp',
|
'tests/cefclient/uiplugin.cpp',
|
||||||
'tests/cefclient/uiplugin.h',
|
'tests/cefclient/uiplugin.h',
|
||||||
'tests/cefclient/uiplugin_test.cpp',
|
'tests/cefclient/uiplugin_test.cpp',
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2008-2009 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -9,6 +9,7 @@
|
|||||||
#include "resource_util.h"
|
#include "resource_util.h"
|
||||||
#include "scheme_test.h"
|
#include "scheme_test.h"
|
||||||
#include "string_util.h"
|
#include "string_util.h"
|
||||||
|
#include "thread_util.h"
|
||||||
#include "uiplugin_test.h"
|
#include "uiplugin_test.h"
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -594,6 +595,29 @@ HWND AppGetMainHwnd()
|
|||||||
return g_handler->GetMainHwnd();
|
return g_handler->GetMainHwnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Retrieve the current page source and display.
|
||||||
|
static void RunGetSourceTest(CefRefPtr<CefFrame> frame)
|
||||||
|
{
|
||||||
|
std::wstring source = frame->GetSource();
|
||||||
|
source = StringReplace(source, L"<", L"<");
|
||||||
|
source = StringReplace(source, L">", L">");
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << L"<html><body>Source:" << L"<pre>" << source
|
||||||
|
<< L"</pre></body></html>";
|
||||||
|
frame->LoadString(ss.str(), L"http://tests/getsource");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the current page text and display.
|
||||||
|
static void RunGetTextTest(CefRefPtr<CefFrame> frame)
|
||||||
|
{
|
||||||
|
std::wstring text = frame->GetText();
|
||||||
|
text = StringReplace(text, L"<", L"<");
|
||||||
|
text = StringReplace(text, L">", L">");
|
||||||
|
std::wstringstream ss;
|
||||||
|
ss << L"<html><body>Text:" << L"<pre>" << text
|
||||||
|
<< L"</pre></body></html>";
|
||||||
|
frame->LoadString(ss.str(), L"http://tests/gettext");
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
|
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
|
||||||
@ -757,6 +781,56 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
if(browser.get())
|
if(browser.get())
|
||||||
browser->StopLoad();
|
browser->StopLoad();
|
||||||
return 0;
|
return 0;
|
||||||
|
case ID_TESTS_GETSOURCE: // Test the GetSource function
|
||||||
|
if(browser.get()) {
|
||||||
|
#ifdef TEST_SINGLE_THREADED_MESSAGE_LOOP
|
||||||
|
RunGetSourceTest(browser->GetMainFrame());
|
||||||
|
#else // !TEST_SINGLE_THREADED_MESSAGE_LOOP
|
||||||
|
// Execute the GetSource() call on a new worker thread to avoid
|
||||||
|
// blocking the UI thread when using a multi-threaded message loop
|
||||||
|
// (issue #79).
|
||||||
|
class ExecHandler : public Thread::Handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExecHandler(CefRefPtr<CefFrame> frame) : m_Frame(frame) {}
|
||||||
|
virtual DWORD Run()
|
||||||
|
{
|
||||||
|
RunGetSourceTest(m_Frame);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual void Destroy() { delete this; }
|
||||||
|
private:
|
||||||
|
CefRefPtr<CefFrame> m_Frame;
|
||||||
|
};
|
||||||
|
Thread::Execute(new ExecHandler(browser->GetMainFrame()));
|
||||||
|
#endif // !TEST_SINGLE_THREADED_MESSAGE_LOOP
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
case ID_TESTS_GETTEXT: // Test the GetText function
|
||||||
|
if(browser.get()) {
|
||||||
|
#ifdef TEST_SINGLE_THREADED_MESSAGE_LOOP
|
||||||
|
RunGetTextTest(browser->GetMainFrame());
|
||||||
|
#else // !TEST_SINGLE_THREADED_MESSAGE_LOOP
|
||||||
|
// Execute the GetText() call on a new worker thread to avoid
|
||||||
|
// blocking the UI thread when using a multi-threaded message loop
|
||||||
|
// (issue #79).
|
||||||
|
class ExecHandler : public Thread::Handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExecHandler(CefRefPtr<CefFrame> frame) : m_Frame(frame) {}
|
||||||
|
virtual DWORD Run()
|
||||||
|
{
|
||||||
|
RunGetTextTest(m_Frame);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
virtual void Destroy() { delete this; }
|
||||||
|
private:
|
||||||
|
CefRefPtr<CefFrame> m_Frame;
|
||||||
|
};
|
||||||
|
Thread::Execute(new ExecHandler(browser->GetMainFrame()));
|
||||||
|
#endif // !TEST_SINGLE_THREADED_MESSAGE_LOOP
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
case ID_TESTS_JAVASCRIPT_HANDLER: // Test the V8 extension handler
|
case ID_TESTS_JAVASCRIPT_HANDLER: // Test the V8 extension handler
|
||||||
if(browser.get())
|
if(browser.get())
|
||||||
RunExtensionTest(browser);
|
RunExtensionTest(browser);
|
||||||
|
@ -59,6 +59,8 @@ BEGIN
|
|||||||
END
|
END
|
||||||
POPUP "Tests"
|
POPUP "Tests"
|
||||||
BEGIN
|
BEGIN
|
||||||
|
MENUITEM "Get Source", ID_TESTS_GETSOURCE
|
||||||
|
MENUITEM "Get Text", ID_TESTS_GETTEXT
|
||||||
MENUITEM "JavaScript Extension Handler",ID_TESTS_JAVASCRIPT_HANDLER
|
MENUITEM "JavaScript Extension Handler",ID_TESTS_JAVASCRIPT_HANDLER
|
||||||
MENUITEM "JavaScript Execute", ID_TESTS_JAVASCRIPT_EXECUTE
|
MENUITEM "JavaScript Execute", ID_TESTS_JAVASCRIPT_EXECUTE
|
||||||
MENUITEM "Plugin", ID_TESTS_PLUGIN
|
MENUITEM "Plugin", ID_TESTS_PLUGIN
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2008 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -21,6 +21,8 @@
|
|||||||
#define IDC_NAV_FORWARD 201
|
#define IDC_NAV_FORWARD 201
|
||||||
#define IDC_NAV_RELOAD 202
|
#define IDC_NAV_RELOAD 202
|
||||||
#define IDC_NAV_STOP 203
|
#define IDC_NAV_STOP 203
|
||||||
|
#define ID_TESTS_GETSOURCE 32769
|
||||||
|
#define ID_TESTS_GETTEXT 32770
|
||||||
#define ID_TESTS_JAVASCRIPT_HANDLER 32771
|
#define ID_TESTS_JAVASCRIPT_HANDLER 32771
|
||||||
#define ID_TESTS_JAVASCRIPT_EXECUTE 32772
|
#define ID_TESTS_JAVASCRIPT_EXECUTE 32772
|
||||||
#define ID_TESTS_PLUGIN 32773
|
#define ID_TESTS_PLUGIN 32773
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -81,3 +81,20 @@ void DumpRequestContents(CefRefPtr<CefRequest> request, std::wstring& str)
|
|||||||
|
|
||||||
str = ss.str();
|
str = ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::wstring StringReplace(const std::wstring& str, const std::wstring& from,
|
||||||
|
const std::wstring& to)
|
||||||
|
{
|
||||||
|
std::wstring result = str;
|
||||||
|
std::wstring::size_type pos = 0;
|
||||||
|
std::wstring::size_type from_len = from.length();
|
||||||
|
std::wstring::size_type to_len = to.length();
|
||||||
|
do {
|
||||||
|
pos = result.find(from, pos);
|
||||||
|
if(pos != std::wstring::npos) {
|
||||||
|
result.replace(pos, from_len, to);
|
||||||
|
pos += to_len;
|
||||||
|
}
|
||||||
|
} while(pos != std::wstring::npos);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) 2009 The Chromium Embedded Framework Authors. All rights
|
// Copyright (c) 2010 The Chromium Embedded Framework Authors. All rights
|
||||||
// reserved. Use of this source code is governed by a BSD-style license that
|
// reserved. Use of this source code is governed by a BSD-style license that
|
||||||
// can be found in the LICENSE file.
|
// can be found in the LICENSE file.
|
||||||
|
|
||||||
@ -16,3 +16,7 @@ std::string WStringToString(const std::wstring& s);
|
|||||||
|
|
||||||
// Dump the contents of the request into a string.
|
// Dump the contents of the request into a string.
|
||||||
void DumpRequestContents(CefRefPtr<CefRequest> request, std::wstring& str);
|
void DumpRequestContents(CefRefPtr<CefRequest> request, std::wstring& str);
|
||||||
|
|
||||||
|
// Replace all instances of |from| with |to| in |str|.
|
||||||
|
std::wstring StringReplace(const std::wstring& str, const std::wstring& from,
|
||||||
|
const std::wstring& to);
|
58
tests/cefclient/thread_util.h
Normal file
58
tests/cefclient/thread_util.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (c) 2010 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 <windows.h>
|
||||||
|
|
||||||
|
class Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Interface for thread execution.
|
||||||
|
class Handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual DWORD Run() =0;
|
||||||
|
virtual void Destroy() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create and execute a new thread for the specified handler.
|
||||||
|
static HANDLE Execute(Handler* pHandler)
|
||||||
|
{
|
||||||
|
if (!pHandler)
|
||||||
|
return 0;
|
||||||
|
Thread* pThread = new Thread(pHandler);
|
||||||
|
return pThread->Execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Thread(Handler* pHandler) : m_hThread(NULL), m_pHandler(pHandler) {}
|
||||||
|
~Thread()
|
||||||
|
{
|
||||||
|
if (m_hThread)
|
||||||
|
CloseHandle(m_hThread);
|
||||||
|
m_pHandler->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE Execute()
|
||||||
|
{
|
||||||
|
m_hThread = CreateThread(NULL, 4096, ThreadHandler,
|
||||||
|
reinterpret_cast<LPVOID>(this), 0, NULL);
|
||||||
|
if (m_hThread == NULL) {
|
||||||
|
delete this;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return m_hThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DWORD WINAPI ThreadHandler(LPVOID lpThreadParameter)
|
||||||
|
{
|
||||||
|
Thread* pThread = reinterpret_cast<Thread*>(lpThreadParameter);
|
||||||
|
DWORD ret = pThread->m_pHandler->Run();
|
||||||
|
delete pThread;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler* m_pHandler;
|
||||||
|
HANDLE m_hThread;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user