- Add CefFocusHandler::OnFocusedNodeChanged() notification (issue #379).

- Add CefDOMNode::IsFormControlElement() and CefDOMNode::GetFormControlElementType() methods (issue #379).
- Add space bar handling example to cefclient.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@318 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2011-10-14 12:40:40 +00:00
parent 06b7e9ab53
commit 9c6dcab73a
16 changed files with 267 additions and 12 deletions

View File

@ -1331,6 +1331,19 @@ public:
/*--cef()--*/
virtual bool OnSetFocus(CefRefPtr<CefBrowser> browser,
FocusSource source) { return false; }
///
// Called when a new node in the the browser gets focus. The |node| value may
// be empty if no specific node has gained focus. The node object passed to
// this method represents a snapshot of the DOM at the time this method is
// executed. DOM objects are only valid for the scope of this method. Do not
// keep references to or attempt to access any DOM objects outside the scope
// of this method.
///
/*--cef()--*/
virtual void OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node) {}
};
@ -1345,10 +1358,11 @@ public:
typedef cef_handler_keyevent_type_t KeyEventType;
///
// Called when the browser component receives a keyboard event. |type| is the
// type of keyboard event, |code| is the windows scan-code for the event,
// |modifiers| is a set of bit-flags describing any pressed modifier keys and
// |isSystemKey| is true if Windows considers this a 'system key' message (see
// Called when the browser component receives a keyboard event that has not
// been intercepted via JavaScript. |type| is the type of keyboard event,
// |code| is the windows scan-code for the event, |modifiers| is a set of bit-
// flags describing any pressed modifier keys and |isSystemKey| is true if
// Windows considers this a 'system key' message (see
// http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx). Return
// true if the keyboard event was handled or false to allow the browser
// component to handle the event.
@ -3267,6 +3281,18 @@ public:
/*--cef()--*/
virtual bool IsElement() =0;
///
// Returns true if this is a form control element node.
///
/*--cef()--*/
virtual bool IsFormControlElement() =0;
///
// Returns the type of this form control element node.
///
/*--cef()--*/
virtual CefString GetFormControlElementType() =0;
///
// Returns true if this object is pointing to the same handle as |that|
// object.

View File

@ -1138,6 +1138,18 @@ typedef struct _cef_focus_handler_t
int (CEF_CALLBACK *on_set_focus)(struct _cef_focus_handler_t* self,
struct _cef_browser_t* browser, enum cef_handler_focus_source_t source);
///
// Called when a new node in the the browser gets focus. The |node| value may
// be NULL if no specific node has gained focus. The node object passed to
// this function represents a snapshot of the DOM at the time this function is
// executed. DOM objects are only valid for the scope of this function. Do not
// keep references to or attempt to access any DOM objects outside the scope
// of this function.
///
void (CEF_CALLBACK *on_focused_node_changed)(
struct _cef_focus_handler_t* self, struct _cef_browser_t* browser,
struct _cef_frame_t* frame, struct _cef_domnode_t* node);
} cef_focus_handler_t;
@ -1151,13 +1163,14 @@ typedef struct _cef_keyboard_handler_t
cef_base_t base;
///
// Called when the browser component receives a keyboard event. |type| is the
// type of keyboard event, |code| is the windows scan-code for the event,
// |modifiers| is a set of bit-flags describing any pressed modifier keys and
// |isSystemKey| is true (1) if Windows considers this a 'system key' message
// (see http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx). Return
// true (1) if the keyboard event was handled or false (0) to allow the
// browser component to handle the event.
// Called when the browser component receives a keyboard event that has not
// been intercepted via JavaScript. |type| is the type of keyboard event,
// |code| is the windows scan-code for the event, |modifiers| is a set of bit-
// flags describing any pressed modifier keys and |isSystemKey| is true (1) if
// Windows considers this a 'system key' message (see
// http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx). Return true
// (1) if the keyboard event was handled or false (0) to allow the browser
// component to handle the event.
///
int (CEF_CALLBACK *on_key_event)(struct _cef_keyboard_handler_t* self,
struct _cef_browser_t* browser, enum cef_handler_keyevent_type_t type,
@ -3045,6 +3058,18 @@ typedef struct _cef_domnode_t
///
int (CEF_CALLBACK *is_element)(struct _cef_domnode_t* self);
///
// Returns true (1) if this is a form control element node.
///
int (CEF_CALLBACK *is_form_control_element)(struct _cef_domnode_t* self);
///
// Returns the type of this form control element node.
///
// The resulting string must be freed by calling cef_string_userfree_free().
cef_string_userfree_t (CEF_CALLBACK *get_form_control_element_type)(
struct _cef_domnode_t* self);
///
// Returns true (1) if this object is pointing to the same handle as |that|
// object.

View File

@ -17,6 +17,7 @@
#include "browser_webstoragenamespace_impl.h"
#include "browser_zoom_map.h"
#include "cef_context.h"
#include "dom_document_impl.h"
#include "request_impl.h"
#include "v8_impl.h"
@ -462,6 +463,30 @@ void BrowserWebViewDelegate::focusPrevious() {
}
}
void BrowserWebViewDelegate::focusedNodeChanged(const WebKit::WebNode& node) {
CefRefPtr<CefClient> client = browser_->GetClient();
if (client.get()) {
CefRefPtr<CefFocusHandler> handler = client->GetFocusHandler();
if (handler.get()) {
if (node.isNull()) {
handler->OnFocusedNodeChanged(browser_, browser_->GetFocusedFrame(),
NULL);
} else {
const WebKit::WebDocument& document = node.document();
if (!document.isNull()) {
WebKit::WebFrame* frame = document.frame();
CefRefPtr<CefDOMDocumentImpl> documentImpl =
new CefDOMDocumentImpl(browser_, frame);
handler->OnFocusedNodeChanged(browser_,
browser_->UIT_GetCefFrame(frame),
documentImpl->GetOrCreateNode(node));
documentImpl->Detach();
}
}
}
}
}
void BrowserWebViewDelegate::navigateBackForwardSoon(int offset) {
browser_->UIT_GetNavigationController()->GoToOffset(offset);
}

View File

@ -112,6 +112,7 @@ class BrowserWebViewDelegate : public WebKit::WebViewClient,
virtual bool acceptsLoadDrops() OVERRIDE { return true; }
virtual void focusNext() OVERRIDE;
virtual void focusPrevious() OVERRIDE;
virtual void focusedNodeChanged(const WebKit::WebNode& node) OVERRIDE;
virtual void navigateBackForwardSoon(int offset) OVERRIDE;
virtual int historyBackListCount() OVERRIDE;
virtual int historyForwardListCount() OVERRIDE;

View File

@ -159,6 +159,40 @@ bool CefDOMNodeImpl::IsElement()
return node_.isElementNode();
}
bool CefDOMNodeImpl::IsFormControlElement()
{
if (!VerifyContext())
return false;
if (node_.isElementNode()) {
const WebElement& element = node_.toConst<WebElement>();
return element.isFormControlElement();
}
return false;
}
CefString CefDOMNodeImpl::GetFormControlElementType()
{
CefString str;
if (!VerifyContext())
return str;
if (node_.isElementNode()) {
const WebElement& element = node_.toConst<WebElement>();
if (element.isFormControlElement()) {
// Retrieve the type from the form control element.
const WebFormControlElement& formElement =
node_.toConst<WebFormControlElement>();
const string16& form_control_type = formElement.formControlType();
str = form_control_type;
}
}
return str;
}
bool CefDOMNodeImpl::IsSame(CefRefPtr<CefDOMNode> that)
{
if (!VerifyContext())

View File

@ -20,6 +20,8 @@ public:
virtual Type GetType() OVERRIDE;
virtual bool IsText() OVERRIDE;
virtual bool IsElement() OVERRIDE;
virtual bool IsFormControlElement() OVERRIDE;
virtual CefString GetFormControlElementType() OVERRIDE;
virtual bool IsSame(CefRefPtr<CefDOMNode> that) OVERRIDE;
virtual CefString GetName() OVERRIDE;
virtual CefString GetValue() OVERRIDE;

View File

@ -40,6 +40,9 @@ public:
// instance to the other side.
static StructName* Wrap(CefRefPtr<BaseName> c)
{
if (!c.get())
return NULL;
// Wrap our object with the CefCppToC class.
ClassName* wrapper = new ClassName(c);
// Add a reference to our wrapper object that will be released once our
@ -53,6 +56,8 @@ public:
// our wrapper structure back from the other side.
static CefRefPtr<BaseName> Unwrap(StructName* s)
{
DCHECK(s);
// Cast our structure to the wrapper structure type.
Struct* wrapperStruct = reinterpret_cast<Struct*>(s);
// Add the underlying object instance to a smart pointer.

View File

@ -46,6 +46,26 @@ int CEF_CALLBACK domnode_is_element(struct _cef_domnode_t* self)
return CefDOMNodeCppToC::Get(self)->IsElement();
}
int CEF_CALLBACK domnode_is_form_control_element(struct _cef_domnode_t* self)
{
DCHECK(self);
if (!self)
return 0;
return CefDOMNodeCppToC::Get(self)->IsFormControlElement();
}
cef_string_userfree_t CEF_CALLBACK domnode_get_form_control_element_type(
struct _cef_domnode_t* self)
{
DCHECK(self);
if (!self)
return NULL;
CefString str = CefDOMNodeCppToC::Get(self)->GetFormControlElementType();
return str.DetachToUserFree();
}
int CEF_CALLBACK domnode_is_same(struct _cef_domnode_t* self,
struct _cef_domnode_t* that)
{
@ -292,6 +312,9 @@ CefDOMNodeCppToC::CefDOMNodeCppToC(CefDOMNode* cls)
struct_.struct_.get_type = domnode_get_type;
struct_.struct_.is_text = domnode_is_text;
struct_.struct_.is_element = domnode_is_element;
struct_.struct_.is_form_control_element = domnode_is_form_control_element;
struct_.struct_.get_form_control_element_type =
domnode_get_form_control_element_type;
struct_.struct_.is_same = domnode_is_same;
struct_.struct_.get_name = domnode_get_name;
struct_.struct_.get_value = domnode_get_value;

View File

@ -12,6 +12,8 @@
#include "libcef_dll/cpptoc/focus_handler_cpptoc.h"
#include "libcef_dll/ctocpp/browser_ctocpp.h"
#include "libcef_dll/ctocpp/domnode_ctocpp.h"
#include "libcef_dll/ctocpp/frame_ctocpp.h"
// MEMBER FUNCTIONS - Body may be edited by hand.
@ -40,6 +42,21 @@ int CEF_CALLBACK focus_handler_on_set_focus(struct _cef_focus_handler_t* self,
CefBrowserCToCpp::Wrap(browser), source);
}
void CEF_CALLBACK focus_handler_on_focused_node_changed(
struct _cef_focus_handler_t* self, cef_browser_t* browser,
cef_frame_t* frame, struct _cef_domnode_t* node)
{
DCHECK(self);
DCHECK(browser);
DCHECK(frame);
if (!self || !browser || !frame)
return;
return CefFocusHandlerCppToC::Get(self)->OnFocusedNodeChanged(
CefBrowserCToCpp::Wrap(browser), CefFrameCToCpp::Wrap(frame),
CefDOMNodeCToCpp::Wrap(node));
}
// CONSTRUCTOR - Do not edit by hand.
@ -49,6 +66,8 @@ CefFocusHandlerCppToC::CefFocusHandlerCppToC(CefFocusHandler* cls)
{
struct_.struct_.on_take_focus = focus_handler_on_take_focus;
struct_.struct_.on_set_focus = focus_handler_on_set_focus;
struct_.struct_.on_focused_node_changed =
focus_handler_on_focused_node_changed;
}
#ifndef NDEBUG

View File

@ -21,6 +21,9 @@ public:
// received from the other side.
static CefRefPtr<BaseName> Wrap(StructName* s)
{
if (!s)
return NULL;
// Wrap their structure with the CefCToCpp object.
ClassName* wrapper = new ClassName(s);
// Put the wrapper object in a smart pointer.
@ -36,6 +39,8 @@ public:
// instance for return back to the other side.
static StructName* Unwrap(CefRefPtr<BaseName> c)
{
DCHECK(c.get());
// Cast the object to our wrapper class type.
ClassName* wrapper = static_cast<ClassName*>(c.get());
// Add a reference to the CefCppToC wrapper object on the other side that

View File

@ -42,6 +42,26 @@ bool CefDOMNodeCToCpp::IsElement()
return struct_->is_element(struct_) ? true : false;
}
bool CefDOMNodeCToCpp::IsFormControlElement()
{
if (CEF_MEMBER_MISSING(struct_, is_form_control_element))
return false;
return struct_->is_form_control_element(struct_) ? true : false;
}
CefString CefDOMNodeCToCpp::GetFormControlElementType()
{
CefString str;
if (CEF_MEMBER_MISSING(struct_, get_form_control_element_type))
return str;
cef_string_userfree_t strPtr =
struct_->get_form_control_element_type(struct_);
str.AttachToUserFree(strPtr);
return str;
}
bool CefDOMNodeCToCpp::IsSame(CefRefPtr<CefDOMNode> that)
{
if (CEF_MEMBER_MISSING(struct_, is_same))

View File

@ -34,6 +34,8 @@ public:
virtual Type GetType() OVERRIDE;
virtual bool IsText() OVERRIDE;
virtual bool IsElement() OVERRIDE;
virtual bool IsFormControlElement() OVERRIDE;
virtual CefString GetFormControlElementType() OVERRIDE;
virtual bool IsSame(CefRefPtr<CefDOMNode> that) OVERRIDE;
virtual CefString GetName() OVERRIDE;
virtual CefString GetValue() OVERRIDE;

View File

@ -11,6 +11,8 @@
//
#include "libcef_dll/cpptoc/browser_cpptoc.h"
#include "libcef_dll/cpptoc/domnode_cpptoc.h"
#include "libcef_dll/cpptoc/frame_cpptoc.h"
#include "libcef_dll/ctocpp/focus_handler_ctocpp.h"
@ -35,6 +37,17 @@ bool CefFocusHandlerCToCpp::OnSetFocus(CefRefPtr<CefBrowser> browser,
source) ? true : false;
}
void CefFocusHandlerCToCpp::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefDOMNode> node)
{
if (CEF_MEMBER_MISSING(struct_, on_focused_node_changed))
return;
struct_->on_focused_node_changed(struct_,
CefBrowserCppToC::Wrap(browser), CefFrameCppToC::Wrap(frame),
CefDOMNodeCppToC::Wrap(node));
}
#ifndef NDEBUG
template<> long CefCToCpp<CefFocusHandlerCToCpp, CefFocusHandler,

View File

@ -36,6 +36,8 @@ public:
virtual void OnTakeFocus(CefRefPtr<CefBrowser> browser, bool next) OVERRIDE;
virtual bool OnSetFocus(CefRefPtr<CefBrowser> browser,
FocusSource source) OVERRIDE;
virtual void OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame, CefRefPtr<CefDOMNode> node) OVERRIDE;
};
#endif // BUILDING_CEF_SHARED

View File

@ -20,7 +20,8 @@ ClientHandler::ClientHandler()
m_BackHwnd(NULL),
m_ForwardHwnd(NULL),
m_StopHwnd(NULL),
m_ReloadHwnd(NULL)
m_ReloadHwnd(NULL),
m_bFormElementHasFocus(false)
{
}
@ -201,6 +202,37 @@ bool ClientHandler::OnConsoleMessage(CefRefPtr<CefBrowser> browser,
return false;
}
void ClientHandler::OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node)
{
REQUIRE_UI_THREAD();
// Set to true if a form element has focus.
m_bFormElementHasFocus = (node.get() && node->IsFormControlElement());
}
bool ClientHandler::OnKeyEvent(CefRefPtr<CefBrowser> browser,
KeyEventType type,
int code,
int modifiers,
bool isSystemKey)
{
REQUIRE_UI_THREAD();
if (!m_bFormElementHasFocus && code == 0x20) {
// Special handling for the space character if a form element does not have
// focus.
if (type == KEYEVENT_RAWKEYDOWN) {
browser->GetMainFrame()->ExecuteJavaScript(
"alert('You pressed the space bar!');", "", 0);
}
return true;
}
return false;
}
bool ClientHandler::GetPrintHeaderFooter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
const CefPrintInfo& printInfo,

View File

@ -21,6 +21,8 @@ class ClientHandler : public CefClient,
public CefLoadHandler,
public CefRequestHandler,
public CefDisplayHandler,
public CefFocusHandler,
public CefKeyboardHandler,
public CefPrintHandler,
public CefJSBindingHandler,
public CefDragHandler,
@ -39,6 +41,10 @@ public:
{ return this; }
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefFocusHandler> GetFocusHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefKeyboardHandler> GetKeyboardHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefPrintHandler> GetPrintHandler() OVERRIDE
{ return this; }
virtual CefRefPtr<CefJSBindingHandler> GetJSBindingHandler() OVERRIDE
@ -97,6 +103,18 @@ public:
const CefString& source,
int line) OVERRIDE;
// CefFocusHandler methods.
virtual void OnFocusedNodeChanged(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefDOMNode> node) OVERRIDE;
// CefKeyboardHandler methods.
virtual bool OnKeyEvent(CefRefPtr<CefBrowser> browser,
KeyEventType type,
int code,
int modifiers,
bool isSystemKey) OVERRIDE;
// CefPrintHandler methods.
virtual bool GetPrintHeaderFooter(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
@ -192,6 +210,9 @@ protected:
typedef std::map<std::string, CefRefPtr<CefDOMVisitor> > DOMVisitorMap;
DOMVisitorMap m_DOMVisitors;
// True if a form element currently has focus
bool m_bFormElementHasFocus;
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(ClientHandler);
// Include the default locking implementation.