From d15f6abc3ac18a6bdf221e764609d16103d6f974 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Sat, 11 Oct 2014 00:12:01 +0000 Subject: [PATCH] Add support for DevTools inspect element via a new |inspect_element_at| parameter added to CefBrowserHost::ShowDevTools (issue #586). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1870 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- include/capi/cef_browser_capi.h | 6 ++-- include/cef_browser.h | 8 +++-- include/internal/cef_types.h | 8 +++++ include/internal/cef_types_wrappers.h | 41 ++++++++++++++++++++++++ libcef/browser/browser_host_impl.cc | 17 ++++++---- libcef/browser/browser_host_impl.h | 3 +- libcef/browser/devtools_frontend.cc | 12 +++++-- libcef/browser/devtools_frontend.h | 3 +- libcef_dll/cpptoc/browser_host_cpptoc.cc | 10 ++++-- libcef_dll/ctocpp/browser_host_ctocpp.cc | 7 ++-- libcef_dll/ctocpp/browser_host_ctocpp.h | 4 +-- tests/cefclient/client_handler.cpp | 14 ++++++-- tests/cefclient/client_handler.h | 3 +- tests/unittests/v8_unittest.cc | 3 +- tools/cef_parser.py | 1 + 15 files changed, 113 insertions(+), 27 deletions(-) diff --git a/include/capi/cef_browser_capi.h b/include/capi/cef_browser_capi.h index 6ecc0cdea..46a19d89d 100644 --- a/include/capi/cef_browser_capi.h +++ b/include/capi/cef_browser_capi.h @@ -333,12 +333,14 @@ typedef struct _cef_browser_host_t { int clearSelection); /// - // Open developer tools in its own window. + // Open developer tools in its own window. If |inspect_element_at| is non- + // NULL the element at the specified (x,y) location will be inspected. /// void (CEF_CALLBACK *show_dev_tools)(struct _cef_browser_host_t* self, const struct _cef_window_info_t* windowInfo, struct _cef_client_t* client, - const struct _cef_browser_settings_t* settings); + const struct _cef_browser_settings_t* settings, + const cef_point_t* inspect_element_at); /// // Explicitly close the developer tools window if one exists for this browser diff --git a/include/cef_browser.h b/include/cef_browser.h index b16cce8be..d1f3a3c9f 100644 --- a/include/cef_browser.h +++ b/include/cef_browser.h @@ -378,12 +378,14 @@ class CefBrowserHost : public virtual CefBase { virtual void StopFinding(bool clearSelection) =0; /// - // Open developer tools in its own window. + // Open developer tools in its own window. If |inspect_element_at| is non- + // empty the element at the specified (x,y) location will be inspected. /// - /*--cef()--*/ + /*--cef(optional_param=inspect_element_at)--*/ virtual void ShowDevTools(const CefWindowInfo& windowInfo, CefRefPtr client, - const CefBrowserSettings& settings) =0; + const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) =0; /// // Explicitly close the developer tools window if one exists for this browser diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index cd0c11291..d478764f7 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -1102,6 +1102,14 @@ typedef enum { UR_FAILED, } cef_urlrequest_status_t; +/// +// Structure representing a point. +/// +typedef struct _cef_point_t { + int x; + int y; +} cef_point_t; + /// // Structure representing a rectangle. /// diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index 1f1779fe6..f7bc56840 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -134,6 +134,47 @@ class CefStructBase : public traits::struct_type { }; +struct CefPointTraits { + typedef cef_point_t struct_type; + + static inline void init(struct_type* s) {} + static inline void clear(struct_type* s) {} + + static inline void set(const struct_type* src, struct_type* target, + bool copy) { + *target = *src; + } +}; + +/// +// Class representing a point. +/// +class CefPoint : public CefStructBase { + public: + typedef CefStructBase parent; + + CefPoint() : parent() {} + CefPoint(const cef_point_t& r) : parent(r) {} // NOLINT(runtime/explicit) + CefPoint(const CefPoint& r) : parent(r) {} // NOLINT(runtime/explicit) + CefPoint(int x, int y) : parent() { + Set(x, y); + } + + bool IsEmpty() const { return x <= 0 || x <= 0; } + void Set(int x, int y) { + this->x = x, this->y = y; + } +}; + +inline bool operator==(const CefPoint& a, const CefPoint& b) { + return a.x == b.x && a.y == b.y; +} + +inline bool operator!=(const CefPoint& a, const CefPoint& b) { + return !(a == b); +} + + struct CefRectTraits { typedef cef_rect_t struct_type; diff --git a/libcef/browser/browser_host_impl.cc b/libcef/browser/browser_host_impl.cc index 7567b809f..7d0fd3c8e 100644 --- a/libcef/browser/browser_host_impl.cc +++ b/libcef/browser/browser_host_impl.cc @@ -98,21 +98,24 @@ class ShowDevToolsHelper { ShowDevToolsHelper(CefRefPtr browser, const CefWindowInfo& windowInfo, CefRefPtr client, - const CefBrowserSettings& settings) + const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) : browser_(browser), window_info_(windowInfo), client_(client), - settings_(settings) {} + settings_(settings), + inspect_element_at_(inspect_element_at) {} CefRefPtr browser_; CefWindowInfo window_info_; CefRefPtr client_; CefBrowserSettings settings_; + CefPoint inspect_element_at_; }; void ShowDevToolsWithHelper(ShowDevToolsHelper* helper) { helper->browser_->ShowDevTools(helper->window_info_, helper->client_, - helper->settings_); + helper->settings_, helper->inspect_element_at_); delete helper; } @@ -812,7 +815,8 @@ void CefBrowserHostImpl::StopFinding(bool clearSelection) { void CefBrowserHostImpl::ShowDevTools( const CefWindowInfo& windowInfo, CefRefPtr client, - const CefBrowserSettings& settings) { + const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) { if (CEF_CURRENTLY_ON_UIT()) { if (!web_contents_) return; @@ -823,12 +827,13 @@ void CefBrowserHostImpl::ShowDevTools( } devtools_frontend_ = CefDevToolsFrontend::Show( - this, windowInfo, client, settings); + this, windowInfo, client, settings, inspect_element_at); devtools_observer_.reset(new DevToolsWebContentsObserver( this, devtools_frontend_->frontend_browser()->web_contents())); } else { ShowDevToolsHelper* helper = - new ShowDevToolsHelper(this, windowInfo, client, settings); + new ShowDevToolsHelper(this, windowInfo, client, settings, + inspect_element_at); CEF_POST_TASK(CEF_UIT, base::Bind(ShowDevToolsWithHelper, helper)); } } diff --git a/libcef/browser/browser_host_impl.h b/libcef/browser/browser_host_impl.h index cc621f709..6bce5ecb6 100644 --- a/libcef/browser/browser_host_impl.h +++ b/libcef/browser/browser_host_impl.h @@ -153,7 +153,8 @@ class CefBrowserHostImpl : public CefBrowserHost, virtual void StopFinding(bool clearSelection) OVERRIDE; virtual void ShowDevTools(const CefWindowInfo& windowInfo, CefRefPtr client, - const CefBrowserSettings& settings) OVERRIDE; + const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) OVERRIDE; virtual void CloseDevTools() OVERRIDE; virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE; virtual bool IsMouseCursorChangeDisabled() OVERRIDE; diff --git a/libcef/browser/devtools_frontend.cc b/libcef/browser/devtools_frontend.cc index 7f37cccd7..6ce309ab3 100644 --- a/libcef/browser/devtools_frontend.cc +++ b/libcef/browser/devtools_frontend.cc @@ -26,7 +26,8 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show( CefRefPtr inspected_browser, const CefWindowInfo& windowInfo, CefRefPtr client, - const CefBrowserSettings& settings) { + const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) { CefBrowserSettings new_settings = settings; if (CefColorGetA(new_settings.background_color) == 0) { // Use white as the default background color for DevTools instead of the @@ -40,12 +41,17 @@ CefDevToolsFrontend* CefDevToolsFrontend::Show( inspected_browser->GetWindowHandle(), true, inspected_browser->GetRequestContext()); + scoped_refptr agent_host = + content::DevToolsAgentHost::GetOrCreateFor( + inspected_browser->GetWebContents()); + if (!inspect_element_at.IsEmpty()) + agent_host->InspectElement(inspect_element_at.x, inspect_element_at.y); + // CefDevToolsFrontend will delete itself when the frontend WebContents is // destroyed. CefDevToolsFrontend* devtools_frontend = new CefDevToolsFrontend( static_cast(frontend_browser.get()), - content::DevToolsAgentHost::GetOrCreateFor( - inspected_browser->GetWebContents()).get()); + agent_host.get()); // Need to load the URL after creating the DevTools objects. CefDevToolsDelegate* delegate = diff --git a/libcef/browser/devtools_frontend.h b/libcef/browser/devtools_frontend.h index 7bd3bf149..a8451db03 100644 --- a/libcef/browser/devtools_frontend.h +++ b/libcef/browser/devtools_frontend.h @@ -28,7 +28,8 @@ class CefDevToolsFrontend : public content::WebContentsObserver, CefRefPtr inspected_browser, const CefWindowInfo& windowInfo, CefRefPtr client, - const CefBrowserSettings& settings); + const CefBrowserSettings& settings, + const CefPoint& inspect_element_at); void Activate(); void Focus(); diff --git a/libcef_dll/cpptoc/browser_host_cpptoc.cc b/libcef_dll/cpptoc/browser_host_cpptoc.cc index f897e5233..54eff0fb4 100644 --- a/libcef_dll/cpptoc/browser_host_cpptoc.cc +++ b/libcef_dll/cpptoc/browser_host_cpptoc.cc @@ -336,7 +336,8 @@ void CEF_CALLBACK browser_host_stop_finding(struct _cef_browser_host_t* self, void CEF_CALLBACK browser_host_show_dev_tools(struct _cef_browser_host_t* self, const cef_window_info_t* windowInfo, struct _cef_client_t* client, - const struct _cef_browser_settings_t* settings) { + const struct _cef_browser_settings_t* settings, + const cef_point_t* inspect_element_at) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING DCHECK(self); @@ -354,6 +355,7 @@ void CEF_CALLBACK browser_host_show_dev_tools(struct _cef_browser_host_t* self, DCHECK(settings); if (!settings) return; + // Unverified params: inspect_element_at // Translate param: windowInfo; type: struct_byref_const CefWindowInfo windowInfoObj; @@ -363,12 +365,16 @@ void CEF_CALLBACK browser_host_show_dev_tools(struct _cef_browser_host_t* self, CefBrowserSettings settingsObj; if (settings) settingsObj.Set(*settings, false); + // Translate param: inspect_element_at; type: simple_byref_const + CefPoint inspect_element_atVal = + inspect_element_at?*inspect_element_at:CefPoint(); // Execute CefBrowserHostCppToC::Get(self)->ShowDevTools( windowInfoObj, CefClientCToCpp::Wrap(client), - settingsObj); + settingsObj, + inspect_element_atVal); } void CEF_CALLBACK browser_host_close_dev_tools( diff --git a/libcef_dll/ctocpp/browser_host_ctocpp.cc b/libcef_dll/ctocpp/browser_host_ctocpp.cc index 56737dbce..77245666f 100644 --- a/libcef_dll/ctocpp/browser_host_ctocpp.cc +++ b/libcef_dll/ctocpp/browser_host_ctocpp.cc @@ -279,7 +279,8 @@ void CefBrowserHostCToCpp::StopFinding(bool clearSelection) { } void CefBrowserHostCToCpp::ShowDevTools(const CefWindowInfo& windowInfo, - CefRefPtr client, const CefBrowserSettings& settings) { + CefRefPtr client, const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) { if (CEF_MEMBER_MISSING(struct_, show_dev_tools)) return; @@ -289,12 +290,14 @@ void CefBrowserHostCToCpp::ShowDevTools(const CefWindowInfo& windowInfo, DCHECK(client.get()); if (!client.get()) return; + // Unverified params: inspect_element_at // Execute struct_->show_dev_tools(struct_, &windowInfo, CefClientCppToC::Wrap(client), - &settings); + &settings, + &inspect_element_at); } void CefBrowserHostCToCpp::CloseDevTools() { diff --git a/libcef_dll/ctocpp/browser_host_ctocpp.h b/libcef_dll/ctocpp/browser_host_ctocpp.h index c4857cc59..f4dada2b1 100644 --- a/libcef_dll/ctocpp/browser_host_ctocpp.h +++ b/libcef_dll/ctocpp/browser_host_ctocpp.h @@ -57,8 +57,8 @@ class CefBrowserHostCToCpp bool matchCase, bool findNext) OVERRIDE; virtual void StopFinding(bool clearSelection) OVERRIDE; virtual void ShowDevTools(const CefWindowInfo& windowInfo, - CefRefPtr client, - const CefBrowserSettings& settings) OVERRIDE; + CefRefPtr client, const CefBrowserSettings& settings, + const CefPoint& inspect_element_at) OVERRIDE; virtual void CloseDevTools() OVERRIDE; virtual void SetMouseCursorChangeDisabled(bool disabled) OVERRIDE; virtual bool IsMouseCursorChangeDisabled() OVERRIDE; diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index e8b869e22..b30c7f846 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -34,6 +34,7 @@ namespace { enum client_menu_ids { CLIENT_ID_SHOW_DEVTOOLS = MENU_ID_USER_FIRST, CLIENT_ID_CLOSE_DEVTOOLS, + CLIENT_ID_INSPECT_ELEMENT, CLIENT_ID_TESTMENU_SUBMENU, CLIENT_ID_TESTMENU_CHECKITEM, CLIENT_ID_TESTMENU_RADIOITEM1, @@ -158,6 +159,8 @@ void ClientHandler::OnBeforeContextMenu( // Add DevTools items to all context menus. model->AddItem(CLIENT_ID_SHOW_DEVTOOLS, "&Show DevTools"); model->AddItem(CLIENT_ID_CLOSE_DEVTOOLS, "Close DevTools"); + model->AddSeparator(); + model->AddItem(CLIENT_ID_INSPECT_ELEMENT, "Inspect Element"); // Test context menu features. BuildTestMenu(model); @@ -174,11 +177,14 @@ bool ClientHandler::OnContextMenuCommand( switch (command_id) { case CLIENT_ID_SHOW_DEVTOOLS: - ShowDevTools(browser); + ShowDevTools(browser, CefPoint()); return true; case CLIENT_ID_CLOSE_DEVTOOLS: CloseDevTools(browser); return true; + case CLIENT_ID_INSPECT_ELEMENT: + ShowDevTools(browser, CefPoint(params->GetXCoord(), params->GetYCoord())); + return true; default: // Allow default handling, if any. return ExecuteTestMenu(command_id); } @@ -779,7 +785,8 @@ std::string ClientHandler::GetLastDownloadFile() const { return last_download_file_; } -void ClientHandler::ShowDevTools(CefRefPtr browser) { +void ClientHandler::ShowDevTools(CefRefPtr browser, + const CefPoint& inspect_element_at) { CefWindowInfo windowInfo; CefBrowserSettings settings; @@ -787,7 +794,8 @@ void ClientHandler::ShowDevTools(CefRefPtr browser) { windowInfo.SetAsPopup(browser->GetHost()->GetWindowHandle(), "DevTools"); #endif - browser->GetHost()->ShowDevTools(windowInfo, this, settings); + browser->GetHost()->ShowDevTools(windowInfo, this, settings, + inspect_element_at); } void ClientHandler::CloseDevTools(CefRefPtr browser) { diff --git a/tests/cefclient/client_handler.h b/tests/cefclient/client_handler.h index d975cd109..36bc4b702 100644 --- a/tests/cefclient/client_handler.h +++ b/tests/cefclient/client_handler.h @@ -282,7 +282,8 @@ class ClientHandler : public CefClient, }; void SendNotification(NotificationType type); - void ShowDevTools(CefRefPtr browser); + void ShowDevTools(CefRefPtr browser, + const CefPoint& inspect_element_at); void CloseDevTools(CefRefPtr browser); // Returns the startup URL. diff --git a/tests/unittests/v8_unittest.cc b/tests/unittests/v8_unittest.cc index c054eb693..4c0524834 100644 --- a/tests/unittests/v8_unittest.cc +++ b/tests/unittests/v8_unittest.cc @@ -2051,7 +2051,8 @@ class V8TestHandler : public TestHandler { windowInfo.SetAsPopup(browser->GetHost()->GetWindowHandle(), "DevTools"); #endif - browser->GetHost()->ShowDevTools(windowInfo, this, settings); + browser->GetHost()->ShowDevTools(windowInfo, this, settings, + CefPoint()); } return; } diff --git a/tools/cef_parser.py b/tools/cef_parser.py index 44b1a9587..80c83fcc9 100644 --- a/tools/cef_parser.py +++ b/tools/cef_parser.py @@ -381,6 +381,7 @@ _simpletypes = { 'CefEventHandle' : ['cef_event_handle_t', 'kNullEventHandle'], 'CefWindowHandle' : ['cef_window_handle_t', 'kNullWindowHandle'], 'CefTextInputContext' : ['cef_text_input_context_t' ,'NULL'], + 'CefPoint' : ['cef_point_t', 'CefPoint()'], 'CefRect' : ['cef_rect_t', 'CefRect()'], 'CefSize' : ['cef_size_t', 'CefSize()'], 'CefPageRange' : ['cef_page_range_t', 'CefPageRange()'],