diff --git a/include/capi/cef_dom_capi.h b/include/capi/cef_dom_capi.h index 5bb42d3d5..9579c8f55 100644 --- a/include/capi/cef_dom_capi.h +++ b/include/capi/cef_dom_capi.h @@ -331,6 +331,11 @@ typedef struct _cef_domnode_t { // The resulting string must be freed by calling cef_string_userfree_free(). cef_string_userfree_t (CEF_CALLBACK *get_element_inner_text)( struct _cef_domnode_t* self); + + /// + // Returns the bounds of the element. + /// + cef_rect_t (CEF_CALLBACK *get_element_bounds)(struct _cef_domnode_t* self); } cef_domnode_t; diff --git a/include/cef_dom.h b/include/cef_dom.h index 9f9a3d5ae..65933b758 100644 --- a/include/cef_dom.h +++ b/include/cef_dom.h @@ -323,6 +323,12 @@ class CefDOMNode : public virtual CefBase { /// /*--cef()--*/ virtual CefString GetElementInnerText() =0; + + /// + // Returns the bounds of the element. + /// + /*--cef()--*/ + virtual CefRect GetElementBounds() =0; }; #endif // CEF_INCLUDE_CEF_DOM_H_ diff --git a/libcef/renderer/dom_node_impl.cc b/libcef/renderer/dom_node_impl.cc index e5ae1df94..1095b0c34 100644 --- a/libcef/renderer/dom_node_impl.cc +++ b/libcef/renderer/dom_node_impl.cc @@ -378,6 +378,23 @@ CefString CefDOMNodeImpl::GetElementInnerText() { return str; } +CefRect CefDOMNodeImpl::GetElementBounds() { + CefRect rect; + if (!VerifyContext()) + return rect; + + if (!node_.isElementNode()) { + NOTREACHED(); + return rect; + } + + WebElement element = node_.to(); + blink::WebRect rc = element.boundsInViewport(); + rect.Set(rc.x, rc.y, rc.width, rc.height); + + return rect; +} + void CefDOMNodeImpl::Detach() { document_ = NULL; node_.assign(WebNode()); diff --git a/libcef/renderer/dom_node_impl.h b/libcef/renderer/dom_node_impl.h index d2d33ef2a..62f8835b7 100644 --- a/libcef/renderer/dom_node_impl.h +++ b/libcef/renderer/dom_node_impl.h @@ -44,6 +44,7 @@ class CefDOMNodeImpl : public CefDOMNode { bool SetElementAttribute(const CefString& attrName, const CefString& value) override; CefString GetElementInnerText() override; + CefRect GetElementBounds() override; // Will be called from CefDOMDocumentImpl::Detach(). void Detach(); diff --git a/libcef_dll/cpptoc/domnode_cpptoc.cc b/libcef_dll/cpptoc/domnode_cpptoc.cc index ed9a33cd8..ab7932f0a 100644 --- a/libcef_dll/cpptoc/domnode_cpptoc.cc +++ b/libcef_dll/cpptoc/domnode_cpptoc.cc @@ -429,6 +429,21 @@ cef_string_userfree_t CEF_CALLBACK domnode_get_element_inner_text( return _retval.DetachToUserFree(); } +cef_rect_t CEF_CALLBACK domnode_get_element_bounds( + struct _cef_domnode_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return CefRect(); + + // Execute + cef_rect_t _retval = CefDOMNodeCppToC::Get(self)->GetElementBounds(); + + // Return type: simple + return _retval; +} + } // namespace @@ -461,6 +476,7 @@ CefDOMNodeCppToC::CefDOMNodeCppToC() { GetStruct()->get_element_attributes = domnode_get_element_attributes; GetStruct()->set_element_attribute = domnode_set_element_attribute; GetStruct()->get_element_inner_text = domnode_get_element_inner_text; + GetStruct()->get_element_bounds = domnode_get_element_bounds; } template<> CefRefPtr CefCppToCget_element_bounds(_struct); + + // Return type: simple + return _retval; +} + // CONSTRUCTOR - Do not edit by hand. diff --git a/libcef_dll/ctocpp/domnode_ctocpp.h b/libcef_dll/ctocpp/domnode_ctocpp.h index 6321c9209..6e204c2a5 100644 --- a/libcef_dll/ctocpp/domnode_ctocpp.h +++ b/libcef_dll/ctocpp/domnode_ctocpp.h @@ -56,6 +56,7 @@ class CefDOMNodeCToCpp bool SetElementAttribute(const CefString& attrName, const CefString& value) OVERRIDE; CefString GetElementInnerText() OVERRIDE; + CefRect GetElementBounds() OVERRIDE; }; #endif // USING_CEF_SHARED diff --git a/tests/unittests/dom_unittest.cc b/tests/unittests/dom_unittest.cc index dfa816bd0..7f1c41da8 100644 --- a/tests/unittests/dom_unittest.cc +++ b/tests/unittests/dom_unittest.cc @@ -78,7 +78,7 @@ class TestDOMVisitor : public CefDOMVisitor { EXPECT_EQ(h1Node->GetName(), "H1"); EXPECT_EQ(h1Node->GetElementTagName(), "H1"); - EXPECT_FALSE(h1Node->GetNextSibling().get()); + EXPECT_TRUE(h1Node->GetNextSibling().get()); EXPECT_FALSE(h1Node->GetPreviousSibling().get()); EXPECT_TRUE(h1Node->HasChildren()); EXPECT_FALSE(h1Node->HasElementAttributes()); @@ -130,6 +130,17 @@ class TestDOMVisitor : public CefDOMVisitor { EXPECT_FALSE(textNode->GetNextSibling().get()); EXPECT_FALSE(textNode->HasChildren()); + + CefRefPtr divNode = h1Node->GetNextSibling(); + EXPECT_TRUE(divNode.get()); + EXPECT_TRUE(divNode->IsElement()); + EXPECT_FALSE(divNode->IsText()); + CefRect divRect = divNode->GetElementBounds(); + EXPECT_EQ(divRect.width, 50); + EXPECT_EQ(divRect.height, 25); + EXPECT_EQ(divRect.x, 150); + EXPECT_EQ(divRect.y, 100); + EXPECT_FALSE(divNode->GetNextSibling().get()); } // Test document structure by iterating through the DOM tree. @@ -264,6 +275,7 @@ class TestDOMHandler : public TestHandler { "" "

Hello From
" "Main Frame

" + "
" "" "";