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
This commit is contained in:
Marshall Greenblatt 2011-12-08 11:44:30 +00:00
parent ef64033467
commit 64f91d5d9b
9 changed files with 281 additions and 5 deletions

View File

@ -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<CefFrame> GetParent() =0;
///
// Returns the URL currently loaded in this frame. This method should only be
// called on the UI thread.

View File

@ -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.

View File

@ -609,6 +609,39 @@ void CefBrowserImpl::ExecuteJavaScript(CefRefPtr<CefFrame> frame,
startLine));
}
long long CefBrowserImpl::GetIdentifier(CefRefPtr<CefFrame> 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<CefFrame> CefBrowserImpl::GetParent(CefRefPtr<CefFrame> 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<CefFrame> frame)
{
// Verify that this method is being called on the UI thread.

View File

@ -134,6 +134,8 @@ public:
const CefString& jsCode,
const CefString& scriptUrl,
int startLine);
long long GetIdentifier(CefRefPtr<CefFrame> frame);
CefRefPtr<CefFrame> GetParent(CefRefPtr<CefFrame> frame);
CefString GetURL(CefRefPtr<CefFrame> 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<CefFrame> GetParent() OVERRIDE
{ return browser_->GetParent(this); }
virtual CefString GetURL() OVERRIDE { return browser_->GetURL(this); }
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE { return browser_.get(); }
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) OVERRIDE;

View File

@ -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<CefFrame> _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;

View File

@ -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<CefFrame> 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))

View File

@ -54,6 +54,8 @@ public:
virtual bool IsMain() OVERRIDE;
virtual bool IsFocused() OVERRIDE;
virtual CefString GetName() OVERRIDE;
virtual long long GetIdentifier() OVERRIDE;
virtual CefRefPtr<CefFrame> GetParent() OVERRIDE;
virtual CefString GetURL() OVERRIDE;
virtual CefRefPtr<CefBrowser> GetBrowser() OVERRIDE;
virtual void VisitDOM(CefRefPtr<CefDOMVisitor> visitor) OVERRIDE;

View File

@ -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 << "<html>Nav1<iframe src=\"" << kNav2 << "\" name=\"nav2\"></html>";
AddResource(kNav1, ss.str(), "text/html");
ss.str("");
// Page with unnamed frame
ss << "<html>Nav2<iframe src=\"" << kNav3 << "\"></html>";
AddResource(kNav2, ss.str(), "text/html");
ss.str("");
AddResource(kNav3, "<html>Nav3</html>", "text/html");
// Create the browser.
CreateBrowser(kNav1);
}
virtual bool OnBeforeBrowse(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
NavType navType,
bool isRedirect) OVERRIDE
{
std::string url = request->GetURL();
std::string name = frame->GetName();
CefRefPtr<CefFrame> parent = frame->GetParent();
if (url == kNav1) {
frame1_ident_ = frame->GetIdentifier();
if (name == "")
got_frame1_name_.yes();
if (!parent.get())
got_frame1_ident_parent_before_.yes();
} else if (url == kNav2) {
frame2_ident_ = frame->GetIdentifier();
if (name == "nav2")
got_frame2_name_.yes();
if (parent.get() && frame1_ident_ == parent->GetIdentifier())
got_frame2_ident_parent_before_.yes();
} else if (url == kNav3) {
frame3_ident_ = frame->GetIdentifier();
if (name == "<!--framePath //nav2/<!--frame0-->-->")
got_frame3_name_.yes();
if (parent.get() && frame2_ident_ == parent->GetIdentifier())
got_frame3_ident_parent_before_.yes();
}
return false;
}
virtual void OnLoadEnd(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
int httpStatusCode) OVERRIDE
{
std::string url = frame->GetURL();
CefRefPtr<CefFrame> parent = frame->GetParent();
if (url == kNav1) {
if (frame1_ident_ == frame->GetIdentifier())
got_frame1_ident_.yes();
if (!parent.get())
got_frame1_ident_parent_after_.yes();
} else if (url == kNav2) {
if (frame2_ident_ == frame->GetIdentifier())
got_frame2_ident_.yes();
if (parent.get() && frame1_ident_ == parent->GetIdentifier())
got_frame2_ident_parent_after_.yes();
} else if (url == kNav3) {
if (frame3_ident_ == frame->GetIdentifier())
got_frame3_ident_.yes();
if (parent.get() && frame2_ident_ == parent->GetIdentifier())
got_frame3_ident_parent_after_.yes();
}
if (++browse_ct_ == 3)
DestroyTest();
}
int browse_ct_;
long long frame1_ident_;
long long frame2_ident_;
long long frame3_ident_;
TrackCallback got_frame1_name_;
TrackCallback got_frame2_name_;
TrackCallback got_frame3_name_;
TrackCallback got_frame1_ident_;
TrackCallback got_frame2_ident_;
TrackCallback got_frame3_ident_;
TrackCallback got_frame1_ident_parent_before_;
TrackCallback got_frame2_ident_parent_before_;
TrackCallback got_frame3_ident_parent_before_;
TrackCallback got_frame1_ident_parent_after_;
TrackCallback got_frame2_ident_parent_after_;
TrackCallback got_frame3_ident_parent_after_;
};
} // namespace
// Verify frame names and identifiers.
TEST(NavigationTest, FrameNameIdent)
{
CefRefPtr<FrameNameIdentNavTestHandler> handler =
new FrameNameIdentNavTestHandler();
handler->ExecuteTest();
ASSERT_GT(handler->frame1_ident_, 0);
ASSERT_GT(handler->frame2_ident_, 0);
ASSERT_GT(handler->frame3_ident_, 0);
ASSERT_TRUE(handler->got_frame1_name_);
ASSERT_TRUE(handler->got_frame2_name_);
ASSERT_TRUE(handler->got_frame3_name_);
ASSERT_TRUE(handler->got_frame1_ident_);
ASSERT_TRUE(handler->got_frame2_ident_);
ASSERT_TRUE(handler->got_frame3_ident_);
ASSERT_TRUE(handler->got_frame1_ident_parent_before_);
ASSERT_TRUE(handler->got_frame2_ident_parent_before_);
ASSERT_TRUE(handler->got_frame3_ident_parent_before_);
ASSERT_TRUE(handler->got_frame1_ident_parent_after_);
ASSERT_TRUE(handler->got_frame2_ident_parent_after_);
ASSERT_TRUE(handler->got_frame3_ident_parent_after_);
}

View File

@ -1074,7 +1074,7 @@ class obj_argument:
parts = string.split(val, ':')
if len(parts) != 2:
raise Exception("Invalid 'count_func' attribute value for "+ \
this.parent.get_qualified_name()+': '+val)
self.parent.get_qualified_name()+': '+val)
if string.strip(parts[0]) == name:
return string.strip(parts[1])
return None
@ -1392,6 +1392,7 @@ class obj_analysis:
'double' : ['double', '0'],
'long' : ['long', '0'],
'unsigned long' : ['unsigned long', '0'],
'long long' : ['long long', '0'],
'size_t' : ['size_t', '0'],
'time_t' : ['time_t', '0'],
'bool' : ['int', '0'],