From 64f91d5d9b6570ecadea44b1c3842f7a6b5956d3 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 8 Dec 2011 11:44:30 +0000 Subject: [PATCH] Expose unique identifiers for frames and the ability to retrieve a frame's parent frame (issue #450). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@410 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- include/cef.h | 22 +++- include/cef_capi.h | 20 +++- libcef/browser_impl.cc | 33 ++++++ libcef/browser_impl.h | 6 ++ libcef_dll/cpptoc/frame_cpptoc.cc | 34 +++++++ libcef_dll/ctocpp/frame_ctocpp.cc | 30 ++++++ libcef_dll/ctocpp/frame_ctocpp.h | 2 + tests/unittests/navigation_unittest.cc | 136 +++++++++++++++++++++++++ tools/cef_parser.py | 3 +- 9 files changed, 281 insertions(+), 5 deletions(-) diff --git a/include/cef.h b/include/cef.h index 97e69679f..ef2d97c7f 100644 --- a/include/cef.h +++ b/include/cef.h @@ -1019,7 +1019,7 @@ public: int startLine) =0; /// - // Returns true if this is the main frame. + // Returns true if this is the main (top-level) frame. /// /*--cef()--*/ virtual bool IsMain() =0; @@ -1032,11 +1032,29 @@ public: virtual bool IsFocused() =0; /// - // Returns this frame's name. + // Returns the name for this frame. If the frame has an assigned name (for + // example, set via the iframe "name" attribute) then that value will be + // returned. Otherwise a unique name will be constructed based on the frame + // parent hierarchy. The main (top-level) frame will always have an empty name + // value. /// /*--cef()--*/ virtual CefString GetName() =0; + /// + // Returns the globally unique identifier for this frame. This method should + // only be called on the UI thread. + /// + /*--cef()--*/ + virtual long long GetIdentifier() =0; + + /// + // Returns the parent of this frame or NULL if this is the main (top-level) + // frame. This method should only be called on the UI thread. + /// + /*--cef()--*/ + virtual CefRefPtr GetParent() =0; + /// // Returns the URL currently loaded in this frame. This method should only be // called on the UI thread. diff --git a/include/cef_capi.h b/include/cef_capi.h index e0c47306e..4345f498a 100644 --- a/include/cef_capi.h +++ b/include/cef_capi.h @@ -854,7 +854,7 @@ typedef struct _cef_frame_t int startLine); /// - // Returns true (1) if this is the main frame. + // Returns true (1) if this is the main (top-level) frame. /// int (CEF_CALLBACK *is_main)(struct _cef_frame_t* self); @@ -865,11 +865,27 @@ typedef struct _cef_frame_t int (CEF_CALLBACK *is_focused)(struct _cef_frame_t* self); /// - // Returns this frame's name. + // Returns the name for this frame. If the frame has an assigned name (for + // example, set via the iframe "name" attribute) then that value will be + // returned. Otherwise a unique name will be constructed based on the frame + // parent hierarchy. The main (top-level) frame will always have an NULL name + // value. /// // The resulting string must be freed by calling cef_string_userfree_free(). cef_string_userfree_t (CEF_CALLBACK *get_name)(struct _cef_frame_t* self); + /// + // Returns the globally unique identifier for this frame. This function should + // only be called on the UI thread. + /// + long long (CEF_CALLBACK *get_identifier)(struct _cef_frame_t* self); + + /// + // Returns the parent of this frame or NULL if this is the main (top-level) + // frame. This function should only be called on the UI thread. + /// + struct _cef_frame_t* (CEF_CALLBACK *get_parent)(struct _cef_frame_t* self); + /// // Returns the URL currently loaded in this frame. This function should only // be called on the UI thread. diff --git a/libcef/browser_impl.cc b/libcef/browser_impl.cc index 64c0bf81a..5a88a93f9 100644 --- a/libcef/browser_impl.cc +++ b/libcef/browser_impl.cc @@ -609,6 +609,39 @@ void CefBrowserImpl::ExecuteJavaScript(CefRefPtr frame, startLine)); } +long long CefBrowserImpl::GetIdentifier(CefRefPtr frame) +{ + // Verify that this method is being called on the UI thread. + if (!CefThread::CurrentlyOn(CefThread::UI)) { + NOTREACHED() << "called on invalid thread"; + return 0; + } + + WebFrame* web_frame = UIT_GetWebFrame(frame); + if(web_frame) + return web_frame->identifier(); + return 0; +} + +CefRefPtr CefBrowserImpl::GetParent(CefRefPtr frame) +{ + // Verify that this method is being called on the UI thread. + if (!CefThread::CurrentlyOn(CefThread::UI)) { + NOTREACHED() << "called on invalid thread"; + return NULL; + } + + WebFrame* web_frame = UIT_GetWebFrame(frame); + if(web_frame) { + if (web_frame->parent() == NULL) { + // This is the main frame. + return NULL; + } + return UIT_GetCefFrame(web_frame->parent()); + } + return NULL; +} + CefString CefBrowserImpl::GetURL(CefRefPtr frame) { // Verify that this method is being called on the UI thread. diff --git a/libcef/browser_impl.h b/libcef/browser_impl.h index e5a1baad6..a3718a187 100644 --- a/libcef/browser_impl.h +++ b/libcef/browser_impl.h @@ -134,6 +134,8 @@ public: const CefString& jsCode, const CefString& scriptUrl, int startLine); + long long GetIdentifier(CefRefPtr frame); + CefRefPtr GetParent(CefRefPtr frame); CefString GetURL(CefRefPtr frame); // CefFrames are light-weight objects managed by the browser and loosely @@ -444,6 +446,10 @@ public: virtual bool IsMain() OVERRIDE { return name_.empty(); } virtual bool IsFocused() OVERRIDE; virtual CefString GetName() OVERRIDE { return name_; } + virtual long long GetIdentifier() OVERRIDE + { return browser_->GetIdentifier(this); } + virtual CefRefPtr GetParent() OVERRIDE + { return browser_->GetParent(this); } virtual CefString GetURL() OVERRIDE { return browser_->GetURL(this); } virtual CefRefPtr GetBrowser() OVERRIDE { return browser_.get(); } virtual void VisitDOM(CefRefPtr visitor) OVERRIDE; diff --git a/libcef_dll/cpptoc/frame_cpptoc.cc b/libcef_dll/cpptoc/frame_cpptoc.cc index 4de699a94..2ddef669e 100644 --- a/libcef_dll/cpptoc/frame_cpptoc.cc +++ b/libcef_dll/cpptoc/frame_cpptoc.cc @@ -325,6 +325,38 @@ cef_string_userfree_t CEF_CALLBACK frame_get_name(struct _cef_frame_t* self) } +long long CEF_CALLBACK frame_get_identifier(struct _cef_frame_t* self) +{ + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + + // Execute + long long _retval = CefFrameCppToC::Get(self)->GetIdentifier(); + + // Return type: simple + return _retval; +} + + +struct _cef_frame_t* CEF_CALLBACK frame_get_parent(struct _cef_frame_t* self) +{ + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = CefFrameCppToC::Get(self)->GetParent(); + + // Return type: refptr_same + return CefFrameCppToC::Wrap(_retval); +} + + cef_string_userfree_t CEF_CALLBACK frame_get_url(struct _cef_frame_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -418,6 +450,8 @@ CefFrameCppToC::CefFrameCppToC(CefFrame* cls) struct_.struct_.is_main = frame_is_main; struct_.struct_.is_focused = frame_is_focused; struct_.struct_.get_name = frame_get_name; + struct_.struct_.get_identifier = frame_get_identifier; + struct_.struct_.get_parent = frame_get_parent; struct_.struct_.get_url = frame_get_url; struct_.struct_.get_browser = frame_get_browser; struct_.struct_.visit_dom = frame_visit_dom; diff --git a/libcef_dll/ctocpp/frame_ctocpp.cc b/libcef_dll/ctocpp/frame_ctocpp.cc index ff09b1f37..8836b9876 100644 --- a/libcef_dll/ctocpp/frame_ctocpp.cc +++ b/libcef_dll/ctocpp/frame_ctocpp.cc @@ -314,6 +314,36 @@ CefString CefFrameCToCpp::GetName() } +long long CefFrameCToCpp::GetIdentifier() +{ + if (CEF_MEMBER_MISSING(struct_, get_identifier)) + return 0; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + long long _retval = struct_->get_identifier(struct_); + + // Return type: simple + return _retval; +} + + +CefRefPtr CefFrameCToCpp::GetParent() +{ + if (CEF_MEMBER_MISSING(struct_, get_parent)) + return NULL; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_frame_t* _retval = struct_->get_parent(struct_); + + // Return type: refptr_same + return CefFrameCToCpp::Wrap(_retval); +} + + CefString CefFrameCToCpp::GetURL() { if (CEF_MEMBER_MISSING(struct_, get_url)) diff --git a/libcef_dll/ctocpp/frame_ctocpp.h b/libcef_dll/ctocpp/frame_ctocpp.h index de714e869..87310be79 100644 --- a/libcef_dll/ctocpp/frame_ctocpp.h +++ b/libcef_dll/ctocpp/frame_ctocpp.h @@ -54,6 +54,8 @@ public: virtual bool IsMain() OVERRIDE; virtual bool IsFocused() OVERRIDE; virtual CefString GetName() OVERRIDE; + virtual long long GetIdentifier() OVERRIDE; + virtual CefRefPtr GetParent() OVERRIDE; virtual CefString GetURL() OVERRIDE; virtual CefRefPtr GetBrowser() OVERRIDE; virtual void VisitDOM(CefRefPtr visitor) OVERRIDE; diff --git a/tests/unittests/navigation_unittest.cc b/tests/unittests/navigation_unittest.cc index 94f2b124f..0fde4e026 100644 --- a/tests/unittests/navigation_unittest.cc +++ b/tests/unittests/navigation_unittest.cc @@ -200,3 +200,139 @@ TEST(NavigationTest, History) } } } + + +namespace { + +class FrameNameIdentNavTestHandler : public TestHandler +{ +public: + FrameNameIdentNavTestHandler() : browse_ct_(0) {} + + virtual void RunTest() OVERRIDE + { + // Add the frame resources. + std::stringstream ss; + + // Page with named frame + ss << "Nav1