From 766a7086b0ac46dd7a7bd676da47813e5a1790bf Mon Sep 17 00:00:00 2001 From: "jam@chromium.org" Date: Fri, 3 Feb 2012 23:39:15 +0000 Subject: Move DOMAutomationController code from chrome to content. This is needed by interstitial pages which are in content, and also browser tests in content. In followup changes, I'll make interstitial pages not have to derive from a concrete class, and instead implement some sort of delegate interface like we did with WebUI. BUG=98716 Review URL: https://chromiumcodereview.appspot.com/9310094 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@120441 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/automation/automation_provider.cc | 1 - .../automation/automation_provider_observers.cc | 9 +- .../automation_tab_helper_browsertest.cc | 8 +- chrome/browser/browser_keyevents_browsertest.cc | 9 +- chrome/browser/chrome_content_browser_client.cc | 1 - .../browser/dom_operation_notification_details.h | 28 -- .../browser/geolocation/geolocation_browsertest.cc | 15 +- .../chrome_render_view_host_observer.cc | 12 - .../chrome_render_view_host_observer.h | 3 - .../safe_browsing/safe_browsing_blocking_page.cc | 1 - chrome/browser/ssl/ssl_blocking_page.cc | 1 - .../tab_contents/chrome_interstitial_page.cc | 21 -- .../tab_contents/chrome_interstitial_page.h | 9 - chrome/chrome_browser.gypi | 1 - chrome/chrome_dll.gypi | 1 + chrome/chrome_renderer.gypi | 2 - chrome/chrome_tests.gypi | 6 + chrome/common/chrome_content_client.cc | 12 - chrome/common/chrome_content_client.h | 1 - chrome/common/chrome_notification_types.h | 4 - chrome/common/chrome_switches.cc | 10 - chrome/common/chrome_switches.h | 1 - chrome/common/render_messages.h | 9 - .../automation/dom_automation_controller.cc | 144 ------- .../automation/dom_automation_controller.h | 113 ------ chrome/renderer/chrome_content_renderer_client.cc | 6 - chrome/renderer/chrome_render_view_observer.cc | 21 -- chrome/renderer/chrome_render_view_observer.h | 9 - chrome/renderer/renderer_resources.grd | 1 - chrome/renderer/resources/dom_automation.js | 418 --------------------- chrome/test/base/ui_test_utils.cc | 13 +- .../renderer_host/render_process_host_impl.cc | 1 + content/browser/renderer_host/render_view_host.cc | 13 + content/browser/renderer_host/render_view_host.h | 3 +- content/browser/tab_contents/interstitial_page.cc | 12 + content/browser/tab_contents/interstitial_page.h | 3 + content/common/swapped_out_messages.cc | 5 +- content/common/view_messages.h | 9 + content/content.gyp | 1 + content/content_browser.gypi | 1 + content/content_renderer.gypi | 2 + content/content_resources.grd | 9 +- .../browser/dom_operation_notification_details.h | 26 ++ content/public/browser/notification_types.h | 5 + content/public/common/content_client.h | 4 - content/public/common/content_switches.cc | 10 + content/public/common/content_switches.h | 1 + content/public/renderer/render_view.h | 1 - content/renderer/dom_automation.js | 418 +++++++++++++++++++++ content/renderer/dom_automation_controller.cc | 140 +++++++ content/renderer/dom_automation_controller.h | 113 ++++++ content/renderer/render_thread_impl.cc | 9 + content/renderer/render_view_impl.cc | 19 +- content/renderer/render_view_impl.h | 6 +- content/shell/shell_content_client.cc | 4 - content/shell/shell_content_client.h | 1 - content/test/test_content_client.cc | 5 - content/test/test_content_client.h | 1 - 58 files changed, 825 insertions(+), 887 deletions(-) delete mode 100644 chrome/browser/dom_operation_notification_details.h delete mode 100644 chrome/renderer/automation/dom_automation_controller.cc delete mode 100644 chrome/renderer/automation/dom_automation_controller.h delete mode 100644 chrome/renderer/resources/dom_automation.js create mode 100644 content/public/browser/dom_operation_notification_details.h create mode 100644 content/renderer/dom_automation.js create mode 100644 content/renderer/dom_automation_controller.cc create mode 100644 content/renderer/dom_automation_controller.h diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 352fa92..5f2dabd 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -41,7 +41,6 @@ #include "chrome/browser/browsing_data_remover.h" #include "chrome/browser/character_encoding.h" #include "chrome/browser/content_settings/host_content_settings_map.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_browser_event_router.h" #include "chrome/browser/extensions/extension_host.h" diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index 0201144..ef8664b 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -29,7 +29,6 @@ #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/extension_host.h" #include "chrome/browser/extensions/extension_process_manager.h" @@ -76,6 +75,7 @@ #include "chrome/common/content_settings_types.h" #include "chrome/common/extensions/extension.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/render_process_host.h" @@ -87,6 +87,7 @@ #include "ui/gfx/rect.h" using content::BrowserThread; +using content::DomOperationNotificationDetails; using content::DownloadItem; using content::DownloadManager; using content::NavigationController; @@ -1206,7 +1207,7 @@ void FindInPageNotificationObserver::Observe( const int FindInPageNotificationObserver::kFindInPageRequestId = -1; DomOperationObserver::DomOperationObserver() { - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::NotificationService::AllSources()); registrar_.Add(this, chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN, content::NotificationService::AllSources()); @@ -1219,9 +1220,9 @@ DomOperationObserver::~DomOperationObserver() {} void DomOperationObserver::Observe( int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - if (type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE) { + if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) { content::Details dom_op_details(details); - OnDomOperationCompleted(dom_op_details->json()); + OnDomOperationCompleted(dom_op_details->json); } else if (type == chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN) { OnModalDialogShown(); } else if (type == chrome::NOTIFICATION_WEB_CONTENT_SETTINGS_CHANGED) { diff --git a/chrome/browser/automation/automation_tab_helper_browsertest.cc b/chrome/browser/automation/automation_tab_helper_browsertest.cc index 388d4df..e320c12 100644 --- a/chrome/browser/automation/automation_tab_helper_browsertest.cc +++ b/chrome/browser/automation/automation_tab_helper_browsertest.cc @@ -69,14 +69,14 @@ class AutomationTabHelperBrowserTest : public InProcessBrowserTest { MockTabEventObserver* mock_tab_observer, MockNotificationObserver* mock_notification_observer) { mock_notification_observer->Register( - chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::NotificationService::AllSources()); testing::InSequence expect_in_sequence; EXPECT_CALL(*mock_tab_observer, OnFirstPendingLoad(_)); EXPECT_CALL(*mock_notification_observer, Observe( testing::Eq( - static_cast(chrome::NOTIFICATION_DOM_OPERATION_RESPONSE)), + static_cast(content::NOTIFICATION_DOM_OPERATION_RESPONSE)), _, _)); EXPECT_CALL(*mock_tab_observer, OnNoMorePendingLoads(_)) .WillOnce(testing::InvokeWithoutArgs( @@ -185,7 +185,7 @@ IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, LoadStopComesAfterOnLoad) { MockNotificationObserver mock_notification_observer; mock_notification_observer.Register( - chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::NotificationService::AllSources()); MockTabEventObserver mock_tab_observer(tab_helper()); @@ -194,7 +194,7 @@ IN_PROC_BROWSER_TEST_F(AutomationTabHelperBrowserTest, testing::InSequence expect_in_sequence; EXPECT_CALL(mock_notification_observer, Observe( testing::Eq( - static_cast(chrome::NOTIFICATION_DOM_OPERATION_RESPONSE)), + static_cast(content::NOTIFICATION_DOM_OPERATION_RESPONSE)), _, _)); EXPECT_CALL(mock_tab_observer, OnNoMorePendingLoads(_)); } diff --git a/chrome/browser/browser_keyevents_browsertest.cc b/chrome/browser/browser_keyevents_browsertest.cc index 6ba0dcd..df3145a 100644 --- a/chrome/browser/browser_keyevents_browsertest.cc +++ b/chrome/browser/browser_keyevents_browsertest.cc @@ -10,7 +10,6 @@ #include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" @@ -18,6 +17,7 @@ #include "chrome/test/base/ui_test_utils.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/renderer_host/render_widget_host_view.h" +#include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/web_contents.h" @@ -25,6 +25,7 @@ #include "net/test/test_server.h" #include "ui/base/keycodes/keyboard_codes.h" +using content::DomOperationNotificationDetails; using content::NavigationController; namespace { @@ -88,7 +89,7 @@ class TestFinishObserver : public content::NotificationObserver { public: explicit TestFinishObserver(RenderViewHost* render_view_host) : finished_(false), waiting_(false) { - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::Source(render_view_host)); } @@ -104,11 +105,11 @@ class TestFinishObserver : public content::NotificationObserver { virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) { - DCHECK(type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE); + DCHECK(type == content::NOTIFICATION_DOM_OPERATION_RESPONSE); content::Details dom_op_details(details); // We might receive responses for other script execution, but we only // care about the test finished message. - if (dom_op_details->json() == "\"FINISHED\"") { + if (dom_op_details->json == "\"FINISHED\"") { finished_ = true; if (waiting_) MessageLoopForUI::current()->Quit(); diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 2c91df3..86ef1e2 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -636,7 +636,6 @@ void ChromeContentBrowserClient::AppendExtraCommandLineSwitches( switches::kAppsGalleryURL, switches::kCloudPrintServiceURL, switches::kDebugPrint, - switches::kDomAutomationController, switches::kDumpHistogramsOnExit, switches::kEnableBenchmarking, switches::kEnableCrxlessWebApps, diff --git a/chrome/browser/dom_operation_notification_details.h b/chrome/browser/dom_operation_notification_details.h deleted file mode 100644 index fc56394..0000000 --- a/chrome/browser/dom_operation_notification_details.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -// -// A class to hold the parameters we get back from the -// ViewHostMsg_DomOperationResponse IPC call. This is used when passing -// parameters through the notification service. - -#ifndef CHROME_BROWSER_DOM_OPERATION_NOTIFICATION_DETAILS_H__ -#define CHROME_BROWSER_DOM_OPERATION_NOTIFICATION_DETAILS_H__ -#pragma once - -class DomOperationNotificationDetails { - public: - DomOperationNotificationDetails(const std::string& json, int automation_id) - : json_(json), automation_id_(automation_id) { } - - ~DomOperationNotificationDetails() { } - - std::string json() const { return json_; } - int automation_id() const { return automation_id_; } - - private: - std::string json_; - int automation_id_; -}; - -#endif // CHROME_BROWSER_DOM_OPERATION_NOTIFICATION_DETAILS_H__ diff --git a/chrome/browser/geolocation/geolocation_browsertest.cc b/chrome/browser/geolocation/geolocation_browsertest.cc index c9c8141..3d8d924 100644 --- a/chrome/browser/geolocation/geolocation_browsertest.cc +++ b/chrome/browser/geolocation/geolocation_browsertest.cc @@ -10,7 +10,6 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/geolocation/geolocation_settings_state.h" #include "chrome/browser/infobars/infobar.h" #include "chrome/browser/infobars/infobar_tab_helper.h" @@ -25,6 +24,7 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_details.h" @@ -33,6 +33,7 @@ #include "net/base/net_util.h" #include "net/test/test_server.h" +using content::DomOperationNotificationDetails; using content::NavigationController; using content::WebContents; @@ -51,7 +52,7 @@ class IFrameLoader : public content::NotificationObserver { &browser->GetSelectedWebContents()->GetController(); registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, content::Source(controller)); - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::NotificationService::AllSources()); std::string script = base::StringPrintf( "window.domAutomationController.setAutomationId(0);" @@ -81,9 +82,9 @@ class IFrameLoader : public content::NotificationObserver { const content::NotificationDetails& details) { if (type == content::NOTIFICATION_LOAD_STOP) { navigation_completed_ = true; - } else if (type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE) { + } else if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) { content::Details dom_op_details(details); - javascript_response_ = dom_op_details->json(); + javascript_response_ = dom_op_details->json; javascript_completed_ = true; } if (javascript_completed_ && navigation_completed_) @@ -117,7 +118,7 @@ class GeolocationNotificationObserver : public content::NotificationObserver { infobar_(NULL), navigation_started_(false), navigation_completed_(false) { - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::NotificationService::AllSources()); if (wait_for_infobar) { registrar_.Add(this, chrome::NOTIFICATION_TAB_CONTENTS_INFOBAR_ADDED, @@ -159,9 +160,9 @@ class GeolocationNotificationObserver : public content::NotificationObserver { infobar_ = content::Details(details).ptr(); ASSERT_TRUE(infobar_->GetIcon()); ASSERT_TRUE(infobar_->AsConfirmInfoBarDelegate()); - } else if (type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE) { + } else if (type == content::NOTIFICATION_DOM_OPERATION_RESPONSE) { content::Details dom_op_details(details); - javascript_response_ = dom_op_details->json(); + javascript_response_ = dom_op_details->json; LOG(WARNING) << "javascript_response " << javascript_response_; } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED || type == content::NOTIFICATION_LOAD_START) { diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc index 26cd431..4618346 100644 --- a/chrome/browser/renderer_host/chrome_render_view_host_observer.cc +++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.cc @@ -5,7 +5,6 @@ #include "chrome/browser/renderer_host/chrome_render_view_host_observer.h" #include "base/command_line.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/profiles/profile.h" @@ -59,8 +58,6 @@ bool ChromeRenderViewHostObserver::OnMessageReceived( const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(ChromeRenderViewHostObserver, message) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_DomOperationResponse, - OnDomOperationResponse) IPC_MESSAGE_HANDLER(ChromeViewHostMsg_FocusedEditableNodeTouched, OnFocusedEditableNodeTouched) IPC_MESSAGE_UNHANDLED(handled = false) @@ -164,15 +161,6 @@ void ChromeRenderViewHostObserver::RemoveRenderViewHostForExtensions( process_manager->UnregisterRenderViewHost(rvh); } -void ChromeRenderViewHostObserver::OnDomOperationResponse( - const std::string& json_string, int automation_id) { - DomOperationNotificationDetails details(json_string, automation_id); - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, - content::Source(render_view_host()), - content::Details(&details)); -} - void ChromeRenderViewHostObserver::OnFocusedEditableNodeTouched() { content::NotificationService::current()->Notify( chrome::NOTIFICATION_FOCUSED_EDITABLE_NODE_TOUCHED, diff --git a/chrome/browser/renderer_host/chrome_render_view_host_observer.h b/chrome/browser/renderer_host/chrome_render_view_host_observer.h index 5a933e0..a7ab2d6 100644 --- a/chrome/browser/renderer_host/chrome_render_view_host_observer.h +++ b/chrome/browser/renderer_host/chrome_render_view_host_observer.h @@ -40,9 +40,6 @@ class ChromeRenderViewHostObserver : public content::RenderViewHostObserver { const Extension* GetExtension(); // Cleans up when a RenderViewHost is removed, or on destruction. void RemoveRenderViewHostForExtensions(RenderViewHost* rvh); - - void OnDomOperationResponse(const std::string& json_string, - int automation_id); void OnFocusedEditableNodeTouched(); Profile* profile_; diff --git a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc index 89c2dd2..ea1c2ee 100644 --- a/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc +++ b/chrome/browser/safe_browsing/safe_browsing_blocking_page.cc @@ -17,7 +17,6 @@ #include "base/utf_string_conversions.h" #include "base/values.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/google/google_util.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc index 23c0cfa..3d96c05 100644 --- a/chrome/browser/ssl/ssl_blocking_page.cc +++ b/chrome/browser/ssl/ssl_blocking_page.cc @@ -9,7 +9,6 @@ #include "base/string_piece.h" #include "base/utf_string_conversions.h" #include "base/values.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/ssl/ssl_error_info.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/common/jstemplate_builder.h" diff --git a/chrome/browser/tab_contents/chrome_interstitial_page.cc b/chrome/browser/tab_contents/chrome_interstitial_page.cc index ef1c194..8b5f1b7 100644 --- a/chrome/browser/tab_contents/chrome_interstitial_page.cc +++ b/chrome/browser/tab_contents/chrome_interstitial_page.cc @@ -4,14 +4,10 @@ #include "chrome/browser/tab_contents/chrome_interstitial_page.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_preferences_util.h" -#include "chrome/common/chrome_notification_types.h" #include "chrome/common/render_messages.h" #include "content/browser/renderer_host/render_view_host.h" -#include "content/public/browser/notification_details.h" -#include "content/public/browser/notification_source.h" #include "content/public/browser/web_contents.h" using content::WebContents; @@ -32,23 +28,6 @@ ChromeInterstitialPage::~ChromeInterstitialPage() { void ChromeInterstitialPage::Show() { InterstitialPage::Show(); - notification_registrar_.Add( - this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, - content::Source(render_view_host())); render_view_host()->Send( new ChromeViewMsg_SetAsInterstitial(render_view_host()->routing_id())); } - -void ChromeInterstitialPage::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - if (chrome::NOTIFICATION_DOM_OPERATION_RESPONSE == type) { - if (enabled()) { - content::Details dom_op_details(details); - CommandReceived(dom_op_details->json()); - } - return; - } - InterstitialPage::Observe(type, source, details); -} diff --git a/chrome/browser/tab_contents/chrome_interstitial_page.h b/chrome/browser/tab_contents/chrome_interstitial_page.h index 2fdd646..0692e56 100644 --- a/chrome/browser/tab_contents/chrome_interstitial_page.h +++ b/chrome/browser/tab_contents/chrome_interstitial_page.h @@ -25,15 +25,6 @@ class ChromeInterstitialPage : public InterstitialPage { // Shows the interstitial page in the tab. virtual void Show() OVERRIDE; - protected: - // content::NotificationObserver method: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) OVERRIDE; - - // Invoked when the page sent a command through DOMAutomation. - virtual void CommandReceived(const std::string& command) {} - private: DISALLOW_COPY_AND_ASSIGN(ChromeInterstitialPage); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index afaae77..78f03cc 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -915,7 +915,6 @@ 'browser/diagnostics/recon_diagnostics.h', 'browser/diagnostics/sqlite_diagnostics.cc', 'browser/diagnostics/sqlite_diagnostics.h', - 'browser/dom_operation_notification_details.h', 'browser/download/chrome_download_manager_delegate.cc', 'browser/download/chrome_download_manager_delegate.h', 'browser/download/download_crx_util.cc', diff --git a/chrome/chrome_dll.gypi b/chrome/chrome_dll.gypi index 7964ed5..b234e04 100644 --- a/chrome/chrome_dll.gypi +++ b/chrome/chrome_dll.gypi @@ -100,6 +100,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/renderer_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/gfx/gfx_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 030233e..ca2cd03 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -56,8 +56,6 @@ 'renderer/autofill/password_autofill_manager.h', 'renderer/automation/automation_renderer_helper.cc', 'renderer/automation/automation_renderer_helper.h', - 'renderer/automation/dom_automation_controller.cc', - 'renderer/automation/dom_automation_controller.h', 'renderer/benchmarking_extension.cc', 'renderer/benchmarking_extension.h', 'renderer/extensions/app_bindings.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 0ed1ff8..b4bcac5 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -703,6 +703,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_version/other_version.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', @@ -2344,6 +2345,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_version/other_version.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', @@ -2967,6 +2969,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_version/other_version.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', @@ -3220,6 +3223,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_version/other_version.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', @@ -3353,6 +3357,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_version/other_version.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', @@ -4071,6 +4076,7 @@ '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome/theme_resources_standard.rc', '<(SHARED_INTERMEDIATE_DIR)/chrome_version/other_version.rc', + '<(SHARED_INTERMEDIATE_DIR)/content/content_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/net/net_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources/ui_resources.rc', '<(SHARED_INTERMEDIATE_DIR)/ui/ui_resources_standard/ui_resources_standard.rc', diff --git a/chrome/common/chrome_content_client.cc b/chrome/common/chrome_content_client.cc index 1a0c7c8..9478cd1 100644 --- a/chrome/common/chrome_content_client.cc +++ b/chrome/common/chrome_content_client.cc @@ -317,18 +317,6 @@ void ChromeContentClient::AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) { } -bool ChromeContentClient::CanSendWhileSwappedOut(const IPC::Message* msg) { - // Any Chrome-specific messages that must be allowed to be sent from swapped - // out renderers. - switch (msg->type()) { - case ChromeViewHostMsg_DomOperationResponse::ID: - return true; - default: - break; - } - return false; -} - bool ChromeContentClient::CanHandleWhileSwappedOut( const IPC::Message& msg) { // Any Chrome-specific messages (apart from those listed in diff --git a/chrome/common/chrome_content_client.h b/chrome/common/chrome_content_client.h index d925c34..deb2d8e 100644 --- a/chrome/common/chrome_content_client.h +++ b/chrome/common/chrome_content_client.h @@ -23,7 +23,6 @@ class ChromeContentClient : public content::ContentClient { std::vector* plugins) OVERRIDE; virtual void AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) OVERRIDE; - virtual bool CanSendWhileSwappedOut(const IPC::Message* msg) OVERRIDE; virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE; virtual std::string GetUserAgent(bool* overriding) const OVERRIDE; virtual string16 GetLocalizedString(int message_id) const OVERRIDE; diff --git a/chrome/common/chrome_notification_types.h b/chrome/common/chrome_notification_types.h index d63d0b9..625b72c 100644 --- a/chrome/common/chrome_notification_types.h +++ b/chrome/common/chrome_notification_types.h @@ -137,10 +137,6 @@ enum NotificationType { // Stuff inside the tabs --------------------------------------------------- - // Notification from TabContents that we have received a response from the - // renderer in response to a dom automation controller action. - NOTIFICATION_DOM_OPERATION_RESPONSE, - // Sent when the bookmark bubble hides. The source is the profile, the // details unused. NOTIFICATION_BOOKMARK_BUBBLE_HIDDEN, diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 808877e..66bdf5d 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -434,16 +434,6 @@ const char kDnsPrefetchDisable[] = "dns-prefetch-disable"; // Use the specified DNS server for raw DNS resolution. const char kDnsServer[] = "dns-server"; -// Specifies if the |DOMAutomationController| needs to be bound in the -// renderer. This binding happens on per-frame basis and hence can potentially -// be a performance bottleneck. One should only enable it when automating dom -// based tests. Also enables sending/receiving renderer automation messages -// through the |AutomationRenderViewHelper|. -// -// TODO(kkania): Rename this to enable-renderer-automation after moving the -// |DOMAutomationController| to the |AutomationRenderViewHelper|. -const char kDomAutomationController[] = "dom-automation"; - // Replaces the download shelf with a new experimental UI. const char kDownloadsNewUI[] = "downloads-new-ui"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 1760ed1..cf38de6 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -128,7 +128,6 @@ extern const char kDiskCacheSize[]; extern const char kDnsLogDetails[]; extern const char kDnsPrefetchDisable[]; extern const char kDnsServer[]; -extern const char kDomAutomationController[]; extern const char kDownloadsNewUI[]; extern const char kDumpHistogramsOnExit[]; extern const char kEnableAeroPeekTabs[]; diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 4792706..327f2f5 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -476,15 +476,6 @@ IPC_MESSAGE_ROUTED3(ChromeViewHostMsg_Thumbnail, IPC_MESSAGE_ROUTED1(ChromeViewHostMsg_Snapshot, SkBitmap /* bitmap */) -// Following message is used to communicate the values received by the -// callback binding the JS to Cpp. -// An instance of browser that has an automation host listening to it can -// have a javascript send a native value (string, number, boolean) to the -// listener in Cpp. (DomAutomationController) -IPC_MESSAGE_ROUTED2(ChromeViewHostMsg_DomOperationResponse, - std::string /* json_string */, - int /* automation_id */) - // A message for an external host. IPC_MESSAGE_ROUTED3(ChromeViewHostMsg_ForwardMessageToExternalHost, std::string /* message */, diff --git a/chrome/renderer/automation/dom_automation_controller.cc b/chrome/renderer/automation/dom_automation_controller.cc deleted file mode 100644 index 81b2be6..0000000 --- a/chrome/renderer/automation/dom_automation_controller.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/renderer/automation/dom_automation_controller.h" - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/json/json_value_serializer.h" -#include "base/string_util.h" -#include "chrome/common/render_messages.h" - -DomAutomationController::DomAutomationController() - : sender_(NULL), - routing_id_(MSG_ROUTING_NONE), - automation_id_(MSG_ROUTING_NONE) { - BindCallback("send", base::Bind(&DomAutomationController::Send, - base::Unretained(this))); - BindCallback("setAutomationId", - base::Bind(&DomAutomationController::SetAutomationId, - base::Unretained(this))); - BindCallback("sendJSON", base::Bind(&DomAutomationController::SendJSON, - base::Unretained(this))); -} - -void DomAutomationController::Send(const CppArgumentList& args, - CppVariant* result) { - if (args.size() != 1) { - result->SetNull(); - return; - } - - if (automation_id_ == MSG_ROUTING_NONE) { - result->SetNull(); - return; - } - - if (!sender_) { - NOTREACHED(); - result->SetNull(); - return; - } - - std::string json; - JSONStringValueSerializer serializer(&json); - scoped_ptr value; - - // Warning: note that JSON officially requires the root-level object to be - // an object (e.g. {foo:3}) or an array, while here we're serializing - // strings, bools, etc. to "JSON". This only works because (a) the JSON - // writer is lenient, and (b) on the receiving side we wrap the JSON string - // in square brackets, converting it to an array, then parsing it and - // grabbing the 0th element to get the value out. - switch (args[0].type) { - case NPVariantType_String: { - value.reset(Value::CreateStringValue(args[0].ToString())); - break; - } - case NPVariantType_Bool: { - value.reset(Value::CreateBooleanValue(args[0].ToBoolean())); - break; - } - case NPVariantType_Int32: { - value.reset(Value::CreateIntegerValue(args[0].ToInt32())); - break; - } - case NPVariantType_Double: { - // The value that is sent back is an integer while it is treated - // as a double in this binding. The reason being that KJS treats - // any number value as a double. Refer for more details, - // chrome/third_party/webkit/src/JavaScriptCore/bindings/c/c_utility.cpp - value.reset(Value::CreateIntegerValue(args[0].ToInt32())); - break; - } - default: { - result->SetNull(); - return; - } - } - - if (!serializer.Serialize(*value)) { - result->SetNull(); - return; - } - - bool succeeded = sender_->Send( - new ChromeViewHostMsg_DomOperationResponse(routing_id_, - json, - automation_id_)); - result->Set(succeeded); - - automation_id_ = MSG_ROUTING_NONE; - -} - -void DomAutomationController::SendJSON(const CppArgumentList& args, - CppVariant* result) { - if (args.size() != 1) { - result->SetNull(); - return; - } - - if (automation_id_ == MSG_ROUTING_NONE) { - result->SetNull(); - return; - } - - if (!sender_) { - NOTREACHED(); - result->SetNull(); - return; - } - - if (args[0].type != NPVariantType_String) { - result->SetNull(); - return; - } - - std::string json = args[0].ToString(); - result->Set(sender_->Send( - new ChromeViewHostMsg_DomOperationResponse(routing_id_, - json, - automation_id_))); - - automation_id_ = MSG_ROUTING_NONE; -} - -void DomAutomationController::SetAutomationId( - const CppArgumentList& args, CppVariant* result) { - if (args.size() != 1) { - result->SetNull(); - return; - } - - // The check here is for NumberType and not Int32 as - // KJS::JSType only defines a NumberType (no Int32) - if (!args[0].isNumber()) { - result->SetNull(); - return; - } - - automation_id_ = args[0].ToInt32(); - result->Set(true); -} diff --git a/chrome/renderer/automation/dom_automation_controller.h b/chrome/renderer/automation/dom_automation_controller.h deleted file mode 100644 index d6cb8f3..0000000 --- a/chrome/renderer/automation/dom_automation_controller.h +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_RENDERER_AUTOMATION_DOM_AUTOMATION_CONTROLLER_H__ -#define CHROME_RENDERER_AUTOMATION_DOM_AUTOMATION_CONTROLLER_H__ -#pragma once - -#include "ipc/ipc_message.h" -#include "webkit/glue/cpp_bound_class.h" - -/* DomAutomationController class: - Bound to Javascript window.domAutomationController object. - At the very basic, this object makes any native value (string, numbers, - boolean) from javascript available to the automation host in Cpp. - Any renderer implementation that is built with this binding will allow the - above facility. - The intended use of this object is to expose the DOM Objects and their - attributes to the automation host. - - A typical usage would be like following (JS code): - - var object = document.getElementById('some_id'); - window.domAutomationController.send(object.nodeName); // get the tag name - - For the exact mode of usage, - refer AutomationProxyTest.*DomAutomationController tests. - - The class provides a single send method that can send variety of native - javascript values. (NPString, Number(double), Boolean) - - The actual communication occurs in the following manner: - - TEST MASTER RENDERER - (1) (3) - |AProxy| ----->|AProvider|----->|RenderView|------| - /\ | | | - | | | | - |(6) |(2) |(0) |(4) - | | \/ | - | |-------->|DAController|<----| - | | - | |(5) - |---------|TabContents|<----------| - - - Legends: - - AProxy = AutomationProxy - - AProvider = AutomationProvider - - DAController = DomAutomationController - - (0) Initialization step where DAController is bound to the renderer - and the view_id of the renderer is supplied to the DAController for - routing message in (5). (routing_id_) - (1) A 'javascript:' url is sent from the test process to master as an IPC - message. A unique routing id is generated at this stage (automation_id_) - (2) The automation_id_ of step (1) is supplied to DAController by calling - the bound method setAutomationId(). This is required for routing message - in (6). - (3) The 'javascript:' url is sent for execution by calling into - Browser::LoadURL() - (4) A callback is generated as a result of domAutomationController.send() - into Cpp. The supplied value is received as a result of this callback. - (5) The value received in (4) is sent to the master along with the - stored automation_id_ as an IPC message. routing_id_ is used to route - the message. (IPC messages, ViewHostMsg_*DomAutomation* ) - (6) The value and the automation_id_ is extracted out of the message received - in (5). This value is relayed to AProxy using another IPC message. - automation_id_ is used to route the message. - (IPC messages, AutomationMsg_Dom*Response) - -*/ - -// TODO(vibhor): Add another method-pair like sendLater() and sendNow() -// sendLater() should keep building a json serializer -// sendNow() should send the above serializer as a string. -class DomAutomationController : public CppBoundClass { - public: - DomAutomationController(); - - // Makes the renderer send a javascript value to the app. - // The value to be sent can be either of type NPString, - // Number (double casted to int32) or boolean. - // The function returns true/false based on the result of actual send over - // IPC. It sets the return value to null on unexpected errors or arguments. - void Send(const CppArgumentList& args, CppVariant* result); - - // Makes the renderer send a javascript value to the app. - // The value must be a NPString and should be properly formed JSON. - // This function does not modify/escape the returned string in any way. - void SendJSON(const CppArgumentList& args, CppVariant* result); - - void SetAutomationId(const CppArgumentList& args, CppVariant* result); - - // TODO(vibhor): Implement later - // static CppBindingObjectMethod sendLater; - // static CppBindingObjectMethod sendNow; - - void set_routing_id(int routing_id) { routing_id_ = routing_id; } - - void set_message_sender(IPC::Message::Sender* sender) { - sender_ = sender; - } - - private: - IPC::Message::Sender* sender_; - - // Refer to the comments at the top of the file for more details. - int routing_id_; // routing id to be used by first channel. - int automation_id_; // routing id to be used by the next channel. -}; - -#endif // CHROME_RENDERER_AUTOMATION_DOM_AUTOMATION_CONTROLLER_H__ diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index e260d4e..e565ee4 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -191,12 +191,6 @@ void ChromeContentRendererClient::RenderThreadStarted() { thread->RegisterExtension(search_extension); if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDomAutomationController)) { - thread->RegisterExtension(new ChromeV8Extension( - "dom_automation.js", IDR_DOM_AUTOMATION_JS, NULL)); - } - - if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableBenchmarking)) thread->RegisterExtension(extensions_v8::BenchmarkingExtension::Get()); diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc index 9f29c66..9db1c9c 100644 --- a/chrome/renderer/chrome_render_view_observer.cc +++ b/chrome/renderer/chrome_render_view_observer.cc @@ -18,7 +18,6 @@ #include "chrome/common/thumbnail_score.h" #include "chrome/common/url_constants.h" #include "chrome/renderer/about_handler.h" -#include "chrome/renderer/automation/dom_automation_controller.h" #include "chrome/renderer/chrome_render_process_observer.h" #include "chrome/renderer/content_settings_observer.h" #include "chrome/renderer/extensions/extension_dispatcher.h" @@ -232,11 +231,6 @@ ChromeRenderViewObserver::ChromeRenderViewObserver( allow_running_insecure_content_(false), ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kDomAutomationController)) { - int old_bindings = render_view->GetEnabledBindings(); - render_view->SetEnabledBindings( - old_bindings |= content::BINDINGS_POLICY_DOM_AUTOMATION); - } render_view->GetWebView()->setPermissionClient(this); if (!command_line.HasSwitch(switches::kDisableClientSidePhishingDetection)) OnSetClientSidePhishingDetection(true); @@ -728,11 +722,6 @@ void ChromeRenderViewObserver::DidCommitProvisionalLoad( void ChromeRenderViewObserver::DidClearWindowObject(WebFrame* frame) { if (render_view()->GetEnabledBindings() & - content::BINDINGS_POLICY_DOM_AUTOMATION) { - BindDOMAutomationController(frame); - } - - if (render_view()->GetEnabledBindings() & content::BINDINGS_POLICY_EXTERNAL_HOST) { GetExternalHostBindings()->BindToJavascript(frame, "externalHost"); } @@ -1011,16 +1000,6 @@ bool ChromeRenderViewObserver::CaptureSnapshot(WebView* view, return true; } -void ChromeRenderViewObserver::BindDOMAutomationController(WebFrame* frame) { - if (!dom_automation_controller_.get()) { - dom_automation_controller_.reset(new DomAutomationController()); - } - dom_automation_controller_->set_message_sender(this); - dom_automation_controller_->set_routing_id(routing_id()); - dom_automation_controller_->BindToJavascript(frame, - "domAutomationController"); -} - ExternalHostBindings* ChromeRenderViewObserver::GetExternalHostBindings() { if (!external_host_bindings_.get()) { external_host_bindings_.reset(new ExternalHostBindings( diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h index fe97f5d..877ac1b 100644 --- a/chrome/renderer/chrome_render_view_observer.h +++ b/chrome/renderer/chrome_render_view_observer.h @@ -19,7 +19,6 @@ class ChromeRenderProcessObserver; class ContentSettingsObserver; -class DomAutomationController; class ExtensionDispatcher; class ExternalHostBindings; class SkBitmap; @@ -161,10 +160,6 @@ class ChromeRenderViewObserver : public content::RenderViewObserver, // to get a snapshot of a tab using chrome.tabs.captureVisibleTab(). bool CaptureSnapshot(WebKit::WebView* view, SkBitmap* snapshot); - // Exposes the DOMAutomationController object that allows JS to send - // information to the browser process. - void BindDOMAutomationController(WebKit::WebFrame* webframe); - ExternalHostBindings* GetExternalHostBindings(); // This callback is triggered when DownloadFavicon completes, either @@ -213,10 +208,6 @@ class ChromeRenderViewObserver : public content::RenderViewObserver, bool allow_running_insecure_content_; std::set strict_security_hosts_; - // Allows JS to access DOM automation. The JS object is only exposed when the - // DOM automation bindings are enabled. - scoped_ptr dom_automation_controller_; - // External host exposed through automation controller. scoped_ptr external_host_bindings_; diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd index 533ea8c..18d5fde 100644 --- a/chrome/renderer/renderer_resources.grd +++ b/chrome/renderer/renderer_resources.grd @@ -14,7 +14,6 @@ without changes to the corresponding grd file. fb9 --> - diff --git a/chrome/renderer/resources/dom_automation.js b/chrome/renderer/resources/dom_automation.js deleted file mode 100644 index 0af645b..0000000 --- a/chrome/renderer/resources/dom_automation.js +++ /dev/null @@ -1,418 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// dom_automation.js -// Methods for performing common DOM operations. Used in Chrome testing -// involving the DomAutomationController. - -var domAutomation = domAutomation || {}; - -(function() { - // |objects| is used to track objects which are sent back to the - // DomAutomationController. Since JavaScript does not have a map type, - // |objects| is simply an object in which the property name and - // property value serve as the key-value pair. The key is the handle number - // and the value is the tracked object. - domAutomation.objects = {}; - - // The next object handle to use. - domAutomation.nextHandle = 1; - - // The current call ID for which a response is awaited. Each asynchronous - // function is given a call ID. When the function has a result to return, - // it must supply that call ID. If a result has not yet been received for - // that call ID, a response containing the result will be sent to the - // domAutomationController. - domAutomation.currentCallId = 1; - - // The current timeout for an asynchronous JavaScript evaluation. Can be given - // to window.clearTimeout. - domAutomation.currentTimeout = null; - - // Returns |value| after converting it to an acceptable type for return, if - // necessary. - function getConvertedValue(value) { - if (typeof value == "undefined" || !value) { - return ""; - } - if (value instanceof Array) { - var result = []; - for (var i = 0; i < value.length; i++) { - result.push(getConvertedValue(value[i])); - } - return result; - } - if (typeof(value) == "object") { - var handle = getHandleForObject(value); - if (handle == -1) { - // Track this object. - var handle = domAutomation.nextHandle++; - domAutomation.objects[handle] = value; - } - return handle; - } - return value; - } - - // Returns the handle for |obj|, or -1 if no handle exists. - function getHandleForObject(obj) { - for (var property in domAutomation.objects) { - if (domAutomation.objects[property] == obj) - return parseInt(property); - } - return -1; - } - - // Sends a completed response back to the domAutomationController with a - // return value, which can be of any type. - function sendCompletedResponse(returnValue) { - var result = [true, "", getConvertedValue(returnValue)]; - domAutomationController.sendJSON(JSON.stringify(result)); - } - - // Sends a error response back to the domAutomationController. |exception| - // should be a string or an exception. - function sendErrorResponse(exception) { - var message = exception.message; - if (typeof message == "undefined") - message = exception; - if (typeof message != "string") - message = JSON.stringify(message); - var result = [false, message, exception]; - domAutomationController.sendJSON(JSON.stringify(result)); - } - - // Safely evaluates |javascript| and sends a response back via the - // DomAutomationController. See javascript_execution_controller.cc - // for more details. - domAutomation.evaluateJavaScript = function(javascript) { - try { - sendCompletedResponse(eval(javascript)); - } - catch (exception) { - sendErrorResponse(exception); - } - } - - // Called by a function when it has completed successfully. Any value, - // including undefined, is acceptable for |returnValue|. This should only - // be used by functions with an asynchronous response. - function onAsyncJavaScriptComplete(callId, returnValue) { - if (domAutomation.currentCallId != callId) { - // We are not waiting for a response for this call anymore, - // because it already responded. - return; - } - domAutomation.currentCallId++; - window.clearTimeout(domAutomation.currentTimeout); - sendCompletedResponse(returnValue); - } - - // Calld by a function when it has an error preventing its successful - // execution. |exception| should be an exception or a string. - function onAsyncJavaScriptError(callId, exception) { - if (domAutomation.currentCallId != callId) { - // We are not waiting for a response for this call anymore, - // because it already responded. - return; - } - domAutomation.currentCallId++; - window.clearTimeout(domAutomation.currentTimeout); - sendErrorResponse(exception); - } - - // Returns whether the call with the given ID has already finished. If true, - // this means that the call timed out or that it already gave a response. - function didCallFinish(callId) { - return domAutomation.currentCallId != callId; - } - - // Safely evaluates |javascript|. The JavaScript is expected to return - // a response via either onAsyncJavaScriptComplete or - // onAsyncJavaScriptError. The script should respond within the |timeoutMs|. - domAutomation.evaluateAsyncJavaScript = function(javascript, timeoutMs) { - try { - eval(javascript); - } - catch (exception) { - onAsyncJavaScriptError(domAutomation.currentCallId, exception); - return; - } - domAutomation.currentTimeout = window.setTimeout( - onAsyncJavaScriptError, timeoutMs, domAutomation.currentCallId, - "JavaScript timed out waiting for response."); - } - - // Stops tracking the object associated with |handle|. - domAutomation.removeObject = function(handle) { - delete domAutomation.objects[handle]; - } - - // Stops tracking all objects. - domAutomation.removeAll = function() { - domAutomation.objects = {}; - domAutomation.nextHandle = 1; - } - - // Gets the object associated with this |handle|. - domAutomation.getObject = function(handle) { - var obj = domAutomation.objects[handle] - if (typeof obj == "undefined") { - throw "Object with handle " + handle + " does not exist." - } - return domAutomation.objects[handle]; - } - - // Gets the ID for this asynchronous call. - domAutomation.getCallId = function() { - return domAutomation.currentCallId; - } - - // Converts an indexable list with a length property to an array. - function getArray(list) { - var arr = []; - for (var i = 0; i < list.length; i++) { - arr.push(list[i]); - } - return arr; - } - - // Removes whitespace at the beginning and end of |text|. - function trim(text) { - return text.replace(/^\s+|\s+$/g, ""); - } - - // Returns the window (which is a sub window of |win|) which - // directly contains |doc|. May return null. - function findWindowForDocument(win, doc) { - if (win.document == doc) - return win; - for (var i = 0; i < win.frames.length; i++) { - if (findWindowForDocument(win.frames[i], doc)) - return win.frames[i]; - } - return null; - } - - // Returns |element|'s text. This includes all descendants' text. - // For textareas and inputs, the text is the element's value. For Text, - // it is the textContent. - function getText(element) { - if (element instanceof Text) { - return trim(element.textContent); - } else if (element instanceof HTMLTextAreaElement || - element instanceof HTMLInputElement) { - return element.value || ""; - } - var childrenText = ""; - for (var i = 0; i < element.childNodes.length; i++) { - childrenText += getText(element.childNodes[i]); - } - return childrenText; - } - - // Returns whether |element| is visible. - function isVisible(element) { - while (element.style) { - if (element.style.display == 'none' || - element.style.visibility == 'hidden' || - element.style.visibility == 'collapse') { - return false; - } - element = element.parentNode; - } - return true; - } - - // Returns an array of the visible elements found in the |elements| array. - function getVisibleElements(elements) { - var visibleElements = []; - for (var i = 0; i < elements.length; i++) { - if (isVisible(elements[i])) - visibleElements.push(elements[i]); - } - return visibleElements; - } - - // Finds all the elements which satisfy the xpath query using the context - // node |context|. This function may throw an exception. - function findByXPath(context, xpath) { - var xpathResult = - document.evaluate(xpath, context, null, - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); - var elements = []; - for (var i = 0; i < xpathResult.snapshotLength; i++) { - elements.push(xpathResult.snapshotItem(i)); - } - return elements; - } - - // Finds the first element which satisfies the xpath query using the context - // node |context|. This function may throw an exception. - function find1ByXPath(context, xpath) { - var xpathResult = - document.evaluate(xpath, context, null, - XPathResult.FIRST_ORDERED_NODE_TYPE, null); - return xpathResult.singleNodeValue; - } - - // Finds all the elements which satisfy the selectors query using the context - // node |context|. This function may throw an exception. - function findBySelectors(context, selectors) { - return getArray(context.querySelectorAll(selectors)); - } - - // Finds the first element which satisfies the selectors query using the - // context node |context|. This function may throw an exception. - function find1BySelectors(context, selectors) { - return context.querySelector(selectors); - } - - // Finds all the elements which contain |text| using the context - // node |context|. See getText for details about what constitutes the text - // of an element. This function may throw an exception. - function findByText(context, text) { - // Find all elements containing this text and all inputs containing - // this text. - var xpath = ".//*[contains(text(), '" + text + "')] | " + - ".//input[contains(@value, '" + text + "')]"; - var elements = findByXPath(context, xpath); - - // Limit to what is visible. - return getVisibleElements(elements); - } - - // Finds the first element which contains |text| using the context - // node |context|. See getText for details about what constitutes the text - // of an element. This function may throw an exception. - function find1ByText(context, text) { - var elements = findByText(context, text); - if (elements.length > 0) - return findByText(context, text)[0]; - return null; - } - - //// DOM Element automation methods - //// See dom_element_proxy.h for method details. - - domAutomation.getDocumentFromFrame = function(element, frameNames) { - // Find the window this element is in. - var containingDocument = element.ownerDocument || element; - var frame = findWindowForDocument(window, containingDocument); - - for (var i = 0; i < frameNames.length; i++) { - frame = frame.frames[frameNames[i]]; - if (typeof frame == "undefined" || !frame) { - return null; - } - } - return frame.document; - } - - domAutomation.findElement = function(context, query) { - var type = query.type; - var queryString = query.queryString; - if (type == "xpath") { - return find1ByXPath(context, queryString); - } else if (type == "selectors") { - return find1BySelectors(context, queryString); - } else if (type == "text") { - return find1ByText(context, queryString); - } - } - - domAutomation.findElements = function(context, query) { - var type = query.type; - var queryString = query.queryString; - if (type == "xpath") { - return findByXPath(context, queryString); - } else if (type == "selectors") { - return findBySelectors(context, queryString); - } else if (type == "text") { - return findByText(context, queryString); - } - } - - domAutomation.waitForVisibleElementCount = function(context, query, count, - callId) { - (function waitHelper() { - try { - var elements = domAutomation.findElements(context, query); - var visibleElements = getVisibleElements(elements); - if (visibleElements.length == count) - onAsyncJavaScriptComplete(callId, visibleElements); - else if (!didCallFinish(callId)) - window.setTimeout(waitHelper, 500); - } - catch (exception) { - onAsyncJavaScriptError(callId, exception); - } - })(); - } - - domAutomation.click = function(element) { - var evt = document.createEvent('MouseEvents'); - evt.initMouseEvent('click', true, true, window, - 0, 0, 0, 0, 0, false, false, - false, false, 0, null); - while (element) { - element.dispatchEvent(evt); - element = element.parentNode; - } - } - - domAutomation.type = function(element, text) { - if (element instanceof HTMLTextAreaElement || - (element instanceof HTMLInputElement && element.type == "text")) { - element.value += text; - return true; - } - return false; - } - - domAutomation.setText = function(element, text) { - if (element instanceof HTMLTextAreaElement || - (element instanceof HTMLInputElement && element.type == "text")) { - element.value = text; - return true; - } - return false; - } - - domAutomation.getProperty = function(element, property) { - return element[property]; - } - - domAutomation.getAttribute = function(element, attribute) { - return element.getAttribute(attribute); - } - - domAutomation.getValue = function(element, type) { - if (type == "text") { - return getText(element); - } else if (type == "innerhtml") { - return trim(element.innerHTML); - } else if (type == "visibility") { - return isVisible(element); - } else if (type == "id") { - return element.id; - } else if (type == "contentdocument") { - return element.contentDocument; - } - } - - domAutomation.waitForAttribute = function(element, attribute, value, callId) { - (function waitForAttributeHelper() { - try { - if (element.getAttribute(attribute) == value) - onAsyncJavaScriptComplete(callId); - else if (!didCallFinish(callId)) - window.setTimeout(waitForAttributeHelper, 200); - } - catch (exception) { - onAsyncJavaScriptError(callId, exception); - } - })(); - } -})(); diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index 999c5f4..dc68764 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc @@ -26,7 +26,6 @@ #include "chrome/browser/automation/ui_controls.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser_process.h" -#include "chrome/browser/dom_operation_notification_details.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/search_engines/template_url_service.h" #include "chrome/browser/search_engines/template_url_service_test_util.h" @@ -44,6 +43,7 @@ #include "chrome/test/automation/javascript_execution_controller.h" #include "chrome/test/base/bookmark_load_observer.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/download_item.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/navigation_controller.h" @@ -69,6 +69,7 @@ #include "ui/aura/root_window.h" #endif +using content::DomOperationNotificationDetails; using content::NavigationController; using content::NavigationEntry; using content::OpenURLParams; @@ -88,7 +89,7 @@ class DOMOperationObserver : public content::NotificationObserver, : content::WebContentsObserver( render_view_host->delegate()->GetAsWebContents()), did_respond_(false) { - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::Source(render_view_host)); ui_test_utils::RunMessageLoop(); } @@ -96,9 +97,9 @@ class DOMOperationObserver : public content::NotificationObserver, virtual void Observe(int type, const content::NotificationSource& source, const content::NotificationDetails& details) OVERRIDE { - DCHECK(type == chrome::NOTIFICATION_DOM_OPERATION_RESPONSE); + DCHECK(type == content::NOTIFICATION_DOM_OPERATION_RESPONSE); content::Details dom_op_details(details); - response_ = dom_op_details->json(); + response_ = dom_op_details->json; did_respond_ = true; MessageLoopForUI::current()->Quit(); } @@ -998,7 +999,7 @@ void TitleWatcher::Observe(int type, } DOMMessageQueue::DOMMessageQueue() { - registrar_.Add(this, chrome::NOTIFICATION_DOM_OPERATION_RESPONSE, + registrar_.Add(this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, content::NotificationService::AllSources()); } @@ -1009,7 +1010,7 @@ void DOMMessageQueue::Observe(int type, const content::NotificationDetails& details) { content::Details dom_op_details(details); content::Source sender(source); - message_queue_.push(dom_op_details->json()); + message_queue_.push(dom_op_details->json); if (waiting_for_message_) { waiting_for_message_ = false; MessageLoopForUI::current()->Quit(); diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 0ed84fb..7e32b8d 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -652,6 +652,7 @@ void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( switches::kDisableSpeechInput, switches::kDisableWebAudio, switches::kDisableWebSockets, + switches::kDomAutomationController, switches::kEnableAccessibilityLogging, switches::kEnableDCHECK, switches::kEnableGamepad, diff --git a/content/browser/renderer_host/render_view_host.cc b/content/browser/renderer_host/render_view_host.cc index d0d5720..9ae93a4 100644 --- a/content/browser/renderer_host/render_view_host.cc +++ b/content/browser/renderer_host/render_view_host.cc @@ -35,6 +35,7 @@ #include "content/public/browser/browser_context.h" #include "content/public/browser/browser_message_filter.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/notification_details.h" #include "content/public/browser/notification_service.h" @@ -58,6 +59,7 @@ using base::TimeDelta; using content::BrowserMessageFilter; using content::BrowserThread; +using content::DomOperationNotificationDetails; using content::RenderViewHostDelegate; using content::SiteInstance; using content::UserMetricsAction; @@ -782,6 +784,8 @@ bool RenderViewHost::OnMessageReceived(const IPC::Message& msg) { #endif IPC_MESSAGE_HANDLER(ViewHostMsg_RunFileChooser, OnRunFileChooser) IPC_MESSAGE_HANDLER(ViewHostMsg_WebUISend, OnWebUISend) + IPC_MESSAGE_HANDLER(ViewHostMsg_DomOperationResponse, + OnDomOperationResponse) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(handled = RenderWidgetHost::OnMessageReceived(msg)) IPC_END_MESSAGE_MAP_EX() @@ -1559,6 +1563,15 @@ void RenderViewHost::OnWebUISend(const GURL& source_url, delegate_->WebUISend(this, source_url, name, args); } +void RenderViewHost::OnDomOperationResponse( + const std::string& json_string, int automation_id) { + DomOperationNotificationDetails details(json_string, automation_id); + content::NotificationService::current()->Notify( + content::NOTIFICATION_DOM_OPERATION_RESPONSE, + content::Source(this), + content::Details(&details)); +} + void RenderViewHost::ClearPowerSaveBlockers() { STLDeleteValues(&power_save_blockers_); } diff --git a/content/browser/renderer_host/render_view_host.h b/content/browser/renderer_host/render_view_host.h index aa12e85..f979d40 100644 --- a/content/browser/renderer_host/render_view_host.h +++ b/content/browser/renderer_host/render_view_host.h @@ -596,9 +596,10 @@ class CONTENT_EXPORT RenderViewHost : public RenderWidgetHost { const content::ShowDesktopNotificationHostMsgParams& params); void OnCancelDesktopNotification(int notification_id); void OnRunFileChooser(const content::FileChooserParams& params); - void OnWebUISend(const GURL& source_url, const std::string& name, const base::ListValue& args); + void OnDomOperationResponse(const std::string& json_string, + int automation_id); #if defined(OS_MACOSX) void OnMsgShowPopup(const ViewHostMsg_ShowPopup_Params& params); diff --git a/content/browser/tab_contents/interstitial_page.cc b/content/browser/tab_contents/interstitial_page.cc index 19f1643..676522c 100644 --- a/content/browser/tab_contents/interstitial_page.cc +++ b/content/browser/tab_contents/interstitial_page.cc @@ -24,6 +24,7 @@ #include "content/common/view_messages.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" +#include "content/public/browser/dom_operation_notification_details.h" #include "content/public/browser/invalidate_type.h" #include "content/public/browser/notification_service.h" #include "content/public/browser/notification_source.h" @@ -35,6 +36,7 @@ #include "net/url_request/url_request_context_getter.h" using content::BrowserThread; +using content::DomOperationNotificationDetails; using content::NavigationController; using content::NavigationEntry; using content::NavigationEntryImpl; @@ -219,6 +221,9 @@ void InterstitialPage::Show() { content::Source(&tab_->GetController())); notification_registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_PENDING, content::Source(&tab_->GetController())); + notification_registrar_.Add( + this, content::NOTIFICATION_DOM_OPERATION_RESPONSE, + content::Source(render_view_host_)); } void InterstitialPage::Hide() { @@ -302,6 +307,13 @@ void InterstitialPage::Observe(int type, // WARNING: we are now deleted! } break; + case content::NOTIFICATION_DOM_OPERATION_RESPONSE: + if (enabled()) { + content::Details dom_op_details( + details); + CommandReceived(dom_op_details->json); + } + break; default: NOTREACHED(); } diff --git a/content/browser/tab_contents/interstitial_page.h b/content/browser/tab_contents/interstitial_page.h index bd047100..fcbc6f2 100644 --- a/content/browser/tab_contents/interstitial_page.h +++ b/content/browser/tab_contents/interstitial_page.h @@ -80,6 +80,9 @@ class CONTENT_EXPORT InterstitialPage : public content::NotificationObserver, // Sub-classes should return the HTML that should be displayed in the page. virtual std::string GetHTMLContents(); + // Invoked when the page sent a command through DOMAutomation. + virtual void CommandReceived(const std::string& command) {} + // Reverts to the page showing before the interstitial. // Sub-classes should call this method when the user has chosen NOT to proceed // to the target URL. diff --git a/content/common/swapped_out_messages.cc b/content/common/swapped_out_messages.cc index 16c58e1..c350bc3 100644 --- a/content/common/swapped_out_messages.cc +++ b/content/common/swapped_out_messages.cc @@ -23,14 +23,13 @@ bool SwappedOutMessages::CanSendWhileSwappedOut(const IPC::Message* msg) { case ViewHostMsg_ShouldClose_ACK::ID: case ViewHostMsg_SwapOut_ACK::ID: case ViewHostMsg_ClosePage_ACK::ID: + case ViewHostMsg_DomOperationResponse::ID: return true; default: break; } - // Check with the embedder as well. - ContentClient* client = GetContentClient(); - return client->CanSendWhileSwappedOut(msg); + return false; } bool SwappedOutMessages::CanHandleWhileSwappedOut( diff --git a/content/common/view_messages.h b/content/common/view_messages.h index 248c18c..e5625da 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -2003,3 +2003,12 @@ IPC_MESSAGE_ROUTED0(ViewHostMsg_LockMouse) // whenever the mouse is unlocked (which may or may not be caused by // ViewHostMsg_UnlockMouse). IPC_MESSAGE_ROUTED0(ViewHostMsg_UnlockMouse) + +// Following message is used to communicate the values received by the +// callback binding the JS to Cpp. +// An instance of browser that has an automation host listening to it can +// have a javascript send a native value (string, number, boolean) to the +// listener in Cpp. (DomAutomationController) +IPC_MESSAGE_ROUTED2(ViewHostMsg_DomOperationResponse, + std::string /* json_string */, + int /* automation_id */) diff --git a/content/content.gyp b/content/content.gyp index 1973d1f..d2f1c16 100644 --- a/content/content.gyp +++ b/content/content.gyp @@ -106,6 +106,7 @@ ], 'dependencies': [ 'content_common', + 'content_resources.gyp:content_resources', ], }, {'target_name': 'content_utility', diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 380a09e..5fde4f3 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -50,6 +50,7 @@ 'public/browser/devtools_http_handler.h', 'public/browser/devtools_http_handler_delegate.h', 'public/browser/devtools_manager.h', + 'public/browser/dom_operation_notification_details.h', 'public/browser/download_item.h', 'public/browser/download_manager.h', 'public/browser/download_manager_delegate.cc', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index b79234f..95e4977 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -50,6 +50,8 @@ 'renderer/devtools_agent_filter.h', 'renderer/devtools_client.cc', 'renderer/devtools_client.h', + 'renderer/dom_automation_controller.cc', + 'renderer/dom_automation_controller.h', 'renderer/external_popup_menu.cc', 'renderer/external_popup_menu.h', 'renderer/gamepad_shared_memory_reader.cc', diff --git a/content/content_resources.grd b/content/content_resources.grd index c60c3a7..44c4e1c 100644 --- a/content/content_resources.grd +++ b/content/content_resources.grd @@ -1,13 +1,5 @@ - - @@ -19,6 +11,7 @@ content_resources.rc file to the respective targets. + diff --git a/content/public/browser/dom_operation_notification_details.h b/content/public/browser/dom_operation_notification_details.h new file mode 100644 index 0000000..13626a1 --- /dev/null +++ b/content/public/browser/dom_operation_notification_details.h @@ -0,0 +1,26 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// A class to hold the parameters we get back from the +// ViewHostMsg_DomOperationResponse IPC call. This is used when passing +// parameters through the notification service. + +#ifndef CONTENT_PUBLIC_BROWSER_DOM_OPERATION_NOTIFICATION_DETAILS_H_ +#define CONTENT_PUBLIC_BROWSER_DOM_OPERATION_NOTIFICATION_DETAILS_H_ +#pragma once + +namespace content { + +struct DomOperationNotificationDetails { + public: + DomOperationNotificationDetails(const std::string& json, int automation_id) + : json(json), automation_id(automation_id) { } + + std::string json; + int automation_id; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_BROWSER_DOM_OPERATION_NOTIFICATION_DETAILS_H_ diff --git a/content/public/browser/notification_types.h b/content/public/browser/notification_types.h index bb8f64a..057e190 100644 --- a/content/public/browser/notification_types.h +++ b/content/public/browser/notification_types.h @@ -364,6 +364,11 @@ enum NotificationType { // V8HeapStatsDetails object. NOTIFICATION_RENDERER_V8_HEAP_STATS_COMPUTED, + // Notification from WebContents that we have received a response from the + // renderer in response to a dom automation controller action. The source is + // the RenderViewHost, and hte details is a DomOperationNotificationDetails. + NOTIFICATION_DOM_OPERATION_RESPONSE, + // Child Processes --------------------------------------------------------- // This notification is sent when a child process host has connected to a diff --git a/content/public/common/content_client.h b/content/public/common/content_client.h index 5721265..4e6612d 100644 --- a/content/public/common/content_client.h +++ b/content/public/common/content_client.h @@ -94,10 +94,6 @@ class CONTENT_EXPORT ContentClient { virtual void AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) = 0; - // Returns whether the given message should be allowed to be sent from a - // swapped out renderer. - virtual bool CanSendWhileSwappedOut(const IPC::Message* msg) = 0; - // Returns whether the given message should be processed in the browser on // behalf of a swapped out renderer. virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) = 0; diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index ea8f680..f84eeec 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc @@ -174,6 +174,16 @@ const char kDisableWebAudio[] = "disable-webaudio"; // Disable Web Sockets support. const char kDisableWebSockets[] = "disable-web-sockets"; +// Specifies if the |DOMAutomationController| needs to be bound in the +// renderer. This binding happens on per-frame basis and hence can potentially +// be a performance bottleneck. One should only enable it when automating dom +// based tests. Also enables sending/receiving renderer automation messages +// through the |AutomationRenderViewHelper|. +// +// TODO(kkania): Rename this to enable-renderer-automation after moving the +// |DOMAutomationController| to the |AutomationRenderViewHelper|. +const char kDomAutomationController[] = "dom-automation"; + // Enable gpu-accelerated 2d canvas. const char kEnableAccelerated2dCanvas[] = "enable-accelerated-2d-canvas"; diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index cc631ee..9fcaad6 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -65,6 +65,7 @@ CONTENT_EXPORT extern const char kDisableSpeechInput[]; extern const char kDisableSpellcheckAPI[]; CONTENT_EXPORT extern const char kDisableWebAudio[]; extern const char kDisableWebSockets[]; +CONTENT_EXPORT extern const char kDomAutomationController[]; extern const char kEnableAccelerated2dCanvas[]; CONTENT_EXPORT extern const char kEnableAcceleratedPainting[]; CONTENT_EXPORT extern const char kEnableAcceleratedFilters[]; diff --git a/content/public/renderer/render_view.h b/content/public/renderer/render_view.h index 764e837..14020aeb 100644 --- a/content/public/renderer/render_view.h +++ b/content/public/renderer/render_view.h @@ -101,7 +101,6 @@ class CONTENT_EXPORT RenderView : public IPC::Message::Sender { // Bitwise-ORed set of extra bindings that have been enabled. See // BindingsPolicy for details. virtual int GetEnabledBindings() = 0; - virtual void SetEnabledBindings(int enabled_bindings) = 0; // Whether content state (such as form state, scroll position and page // contents) should be sent to the browser immediately. This is normally diff --git a/content/renderer/dom_automation.js b/content/renderer/dom_automation.js new file mode 100644 index 0000000..0af645b --- /dev/null +++ b/content/renderer/dom_automation.js @@ -0,0 +1,418 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// dom_automation.js +// Methods for performing common DOM operations. Used in Chrome testing +// involving the DomAutomationController. + +var domAutomation = domAutomation || {}; + +(function() { + // |objects| is used to track objects which are sent back to the + // DomAutomationController. Since JavaScript does not have a map type, + // |objects| is simply an object in which the property name and + // property value serve as the key-value pair. The key is the handle number + // and the value is the tracked object. + domAutomation.objects = {}; + + // The next object handle to use. + domAutomation.nextHandle = 1; + + // The current call ID for which a response is awaited. Each asynchronous + // function is given a call ID. When the function has a result to return, + // it must supply that call ID. If a result has not yet been received for + // that call ID, a response containing the result will be sent to the + // domAutomationController. + domAutomation.currentCallId = 1; + + // The current timeout for an asynchronous JavaScript evaluation. Can be given + // to window.clearTimeout. + domAutomation.currentTimeout = null; + + // Returns |value| after converting it to an acceptable type for return, if + // necessary. + function getConvertedValue(value) { + if (typeof value == "undefined" || !value) { + return ""; + } + if (value instanceof Array) { + var result = []; + for (var i = 0; i < value.length; i++) { + result.push(getConvertedValue(value[i])); + } + return result; + } + if (typeof(value) == "object") { + var handle = getHandleForObject(value); + if (handle == -1) { + // Track this object. + var handle = domAutomation.nextHandle++; + domAutomation.objects[handle] = value; + } + return handle; + } + return value; + } + + // Returns the handle for |obj|, or -1 if no handle exists. + function getHandleForObject(obj) { + for (var property in domAutomation.objects) { + if (domAutomation.objects[property] == obj) + return parseInt(property); + } + return -1; + } + + // Sends a completed response back to the domAutomationController with a + // return value, which can be of any type. + function sendCompletedResponse(returnValue) { + var result = [true, "", getConvertedValue(returnValue)]; + domAutomationController.sendJSON(JSON.stringify(result)); + } + + // Sends a error response back to the domAutomationController. |exception| + // should be a string or an exception. + function sendErrorResponse(exception) { + var message = exception.message; + if (typeof message == "undefined") + message = exception; + if (typeof message != "string") + message = JSON.stringify(message); + var result = [false, message, exception]; + domAutomationController.sendJSON(JSON.stringify(result)); + } + + // Safely evaluates |javascript| and sends a response back via the + // DomAutomationController. See javascript_execution_controller.cc + // for more details. + domAutomation.evaluateJavaScript = function(javascript) { + try { + sendCompletedResponse(eval(javascript)); + } + catch (exception) { + sendErrorResponse(exception); + } + } + + // Called by a function when it has completed successfully. Any value, + // including undefined, is acceptable for |returnValue|. This should only + // be used by functions with an asynchronous response. + function onAsyncJavaScriptComplete(callId, returnValue) { + if (domAutomation.currentCallId != callId) { + // We are not waiting for a response for this call anymore, + // because it already responded. + return; + } + domAutomation.currentCallId++; + window.clearTimeout(domAutomation.currentTimeout); + sendCompletedResponse(returnValue); + } + + // Calld by a function when it has an error preventing its successful + // execution. |exception| should be an exception or a string. + function onAsyncJavaScriptError(callId, exception) { + if (domAutomation.currentCallId != callId) { + // We are not waiting for a response for this call anymore, + // because it already responded. + return; + } + domAutomation.currentCallId++; + window.clearTimeout(domAutomation.currentTimeout); + sendErrorResponse(exception); + } + + // Returns whether the call with the given ID has already finished. If true, + // this means that the call timed out or that it already gave a response. + function didCallFinish(callId) { + return domAutomation.currentCallId != callId; + } + + // Safely evaluates |javascript|. The JavaScript is expected to return + // a response via either onAsyncJavaScriptComplete or + // onAsyncJavaScriptError. The script should respond within the |timeoutMs|. + domAutomation.evaluateAsyncJavaScript = function(javascript, timeoutMs) { + try { + eval(javascript); + } + catch (exception) { + onAsyncJavaScriptError(domAutomation.currentCallId, exception); + return; + } + domAutomation.currentTimeout = window.setTimeout( + onAsyncJavaScriptError, timeoutMs, domAutomation.currentCallId, + "JavaScript timed out waiting for response."); + } + + // Stops tracking the object associated with |handle|. + domAutomation.removeObject = function(handle) { + delete domAutomation.objects[handle]; + } + + // Stops tracking all objects. + domAutomation.removeAll = function() { + domAutomation.objects = {}; + domAutomation.nextHandle = 1; + } + + // Gets the object associated with this |handle|. + domAutomation.getObject = function(handle) { + var obj = domAutomation.objects[handle] + if (typeof obj == "undefined") { + throw "Object with handle " + handle + " does not exist." + } + return domAutomation.objects[handle]; + } + + // Gets the ID for this asynchronous call. + domAutomation.getCallId = function() { + return domAutomation.currentCallId; + } + + // Converts an indexable list with a length property to an array. + function getArray(list) { + var arr = []; + for (var i = 0; i < list.length; i++) { + arr.push(list[i]); + } + return arr; + } + + // Removes whitespace at the beginning and end of |text|. + function trim(text) { + return text.replace(/^\s+|\s+$/g, ""); + } + + // Returns the window (which is a sub window of |win|) which + // directly contains |doc|. May return null. + function findWindowForDocument(win, doc) { + if (win.document == doc) + return win; + for (var i = 0; i < win.frames.length; i++) { + if (findWindowForDocument(win.frames[i], doc)) + return win.frames[i]; + } + return null; + } + + // Returns |element|'s text. This includes all descendants' text. + // For textareas and inputs, the text is the element's value. For Text, + // it is the textContent. + function getText(element) { + if (element instanceof Text) { + return trim(element.textContent); + } else if (element instanceof HTMLTextAreaElement || + element instanceof HTMLInputElement) { + return element.value || ""; + } + var childrenText = ""; + for (var i = 0; i < element.childNodes.length; i++) { + childrenText += getText(element.childNodes[i]); + } + return childrenText; + } + + // Returns whether |element| is visible. + function isVisible(element) { + while (element.style) { + if (element.style.display == 'none' || + element.style.visibility == 'hidden' || + element.style.visibility == 'collapse') { + return false; + } + element = element.parentNode; + } + return true; + } + + // Returns an array of the visible elements found in the |elements| array. + function getVisibleElements(elements) { + var visibleElements = []; + for (var i = 0; i < elements.length; i++) { + if (isVisible(elements[i])) + visibleElements.push(elements[i]); + } + return visibleElements; + } + + // Finds all the elements which satisfy the xpath query using the context + // node |context|. This function may throw an exception. + function findByXPath(context, xpath) { + var xpathResult = + document.evaluate(xpath, context, null, + XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + var elements = []; + for (var i = 0; i < xpathResult.snapshotLength; i++) { + elements.push(xpathResult.snapshotItem(i)); + } + return elements; + } + + // Finds the first element which satisfies the xpath query using the context + // node |context|. This function may throw an exception. + function find1ByXPath(context, xpath) { + var xpathResult = + document.evaluate(xpath, context, null, + XPathResult.FIRST_ORDERED_NODE_TYPE, null); + return xpathResult.singleNodeValue; + } + + // Finds all the elements which satisfy the selectors query using the context + // node |context|. This function may throw an exception. + function findBySelectors(context, selectors) { + return getArray(context.querySelectorAll(selectors)); + } + + // Finds the first element which satisfies the selectors query using the + // context node |context|. This function may throw an exception. + function find1BySelectors(context, selectors) { + return context.querySelector(selectors); + } + + // Finds all the elements which contain |text| using the context + // node |context|. See getText for details about what constitutes the text + // of an element. This function may throw an exception. + function findByText(context, text) { + // Find all elements containing this text and all inputs containing + // this text. + var xpath = ".//*[contains(text(), '" + text + "')] | " + + ".//input[contains(@value, '" + text + "')]"; + var elements = findByXPath(context, xpath); + + // Limit to what is visible. + return getVisibleElements(elements); + } + + // Finds the first element which contains |text| using the context + // node |context|. See getText for details about what constitutes the text + // of an element. This function may throw an exception. + function find1ByText(context, text) { + var elements = findByText(context, text); + if (elements.length > 0) + return findByText(context, text)[0]; + return null; + } + + //// DOM Element automation methods + //// See dom_element_proxy.h for method details. + + domAutomation.getDocumentFromFrame = function(element, frameNames) { + // Find the window this element is in. + var containingDocument = element.ownerDocument || element; + var frame = findWindowForDocument(window, containingDocument); + + for (var i = 0; i < frameNames.length; i++) { + frame = frame.frames[frameNames[i]]; + if (typeof frame == "undefined" || !frame) { + return null; + } + } + return frame.document; + } + + domAutomation.findElement = function(context, query) { + var type = query.type; + var queryString = query.queryString; + if (type == "xpath") { + return find1ByXPath(context, queryString); + } else if (type == "selectors") { + return find1BySelectors(context, queryString); + } else if (type == "text") { + return find1ByText(context, queryString); + } + } + + domAutomation.findElements = function(context, query) { + var type = query.type; + var queryString = query.queryString; + if (type == "xpath") { + return findByXPath(context, queryString); + } else if (type == "selectors") { + return findBySelectors(context, queryString); + } else if (type == "text") { + return findByText(context, queryString); + } + } + + domAutomation.waitForVisibleElementCount = function(context, query, count, + callId) { + (function waitHelper() { + try { + var elements = domAutomation.findElements(context, query); + var visibleElements = getVisibleElements(elements); + if (visibleElements.length == count) + onAsyncJavaScriptComplete(callId, visibleElements); + else if (!didCallFinish(callId)) + window.setTimeout(waitHelper, 500); + } + catch (exception) { + onAsyncJavaScriptError(callId, exception); + } + })(); + } + + domAutomation.click = function(element) { + var evt = document.createEvent('MouseEvents'); + evt.initMouseEvent('click', true, true, window, + 0, 0, 0, 0, 0, false, false, + false, false, 0, null); + while (element) { + element.dispatchEvent(evt); + element = element.parentNode; + } + } + + domAutomation.type = function(element, text) { + if (element instanceof HTMLTextAreaElement || + (element instanceof HTMLInputElement && element.type == "text")) { + element.value += text; + return true; + } + return false; + } + + domAutomation.setText = function(element, text) { + if (element instanceof HTMLTextAreaElement || + (element instanceof HTMLInputElement && element.type == "text")) { + element.value = text; + return true; + } + return false; + } + + domAutomation.getProperty = function(element, property) { + return element[property]; + } + + domAutomation.getAttribute = function(element, attribute) { + return element.getAttribute(attribute); + } + + domAutomation.getValue = function(element, type) { + if (type == "text") { + return getText(element); + } else if (type == "innerhtml") { + return trim(element.innerHTML); + } else if (type == "visibility") { + return isVisible(element); + } else if (type == "id") { + return element.id; + } else if (type == "contentdocument") { + return element.contentDocument; + } + } + + domAutomation.waitForAttribute = function(element, attribute, value, callId) { + (function waitForAttributeHelper() { + try { + if (element.getAttribute(attribute) == value) + onAsyncJavaScriptComplete(callId); + else if (!didCallFinish(callId)) + window.setTimeout(waitForAttributeHelper, 200); + } + catch (exception) { + onAsyncJavaScriptError(callId, exception); + } + })(); + } +})(); diff --git a/content/renderer/dom_automation_controller.cc b/content/renderer/dom_automation_controller.cc new file mode 100644 index 0000000..b1c4fee --- /dev/null +++ b/content/renderer/dom_automation_controller.cc @@ -0,0 +1,140 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/renderer/dom_automation_controller.h" + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/json/json_value_serializer.h" +#include "base/string_util.h" +#include "content/common/view_messages.h" + +DomAutomationController::DomAutomationController() + : sender_(NULL), + routing_id_(MSG_ROUTING_NONE), + automation_id_(MSG_ROUTING_NONE) { + BindCallback("send", base::Bind(&DomAutomationController::Send, + base::Unretained(this))); + BindCallback("setAutomationId", + base::Bind(&DomAutomationController::SetAutomationId, + base::Unretained(this))); + BindCallback("sendJSON", base::Bind(&DomAutomationController::SendJSON, + base::Unretained(this))); +} + +void DomAutomationController::Send(const CppArgumentList& args, + CppVariant* result) { + if (args.size() != 1) { + result->SetNull(); + return; + } + + if (automation_id_ == MSG_ROUTING_NONE) { + result->SetNull(); + return; + } + + if (!sender_) { + NOTREACHED(); + result->SetNull(); + return; + } + + std::string json; + JSONStringValueSerializer serializer(&json); + scoped_ptr value; + + // Warning: note that JSON officially requires the root-level object to be + // an object (e.g. {foo:3}) or an array, while here we're serializing + // strings, bools, etc. to "JSON". This only works because (a) the JSON + // writer is lenient, and (b) on the receiving side we wrap the JSON string + // in square brackets, converting it to an array, then parsing it and + // grabbing the 0th element to get the value out. + switch (args[0].type) { + case NPVariantType_String: { + value.reset(Value::CreateStringValue(args[0].ToString())); + break; + } + case NPVariantType_Bool: { + value.reset(Value::CreateBooleanValue(args[0].ToBoolean())); + break; + } + case NPVariantType_Int32: { + value.reset(Value::CreateIntegerValue(args[0].ToInt32())); + break; + } + case NPVariantType_Double: { + // The value that is sent back is an integer while it is treated + // as a double in this binding. The reason being that KJS treats + // any number value as a double. Refer for more details, + // chrome/third_party/webkit/src/JavaScriptCore/bindings/c/c_utility.cpp + value.reset(Value::CreateIntegerValue(args[0].ToInt32())); + break; + } + default: { + result->SetNull(); + return; + } + } + + if (!serializer.Serialize(*value)) { + result->SetNull(); + return; + } + + bool succeeded = sender_->Send( + new ViewHostMsg_DomOperationResponse(routing_id_, json, automation_id_)); + result->Set(succeeded); + + automation_id_ = MSG_ROUTING_NONE; + +} + +void DomAutomationController::SendJSON(const CppArgumentList& args, + CppVariant* result) { + if (args.size() != 1) { + result->SetNull(); + return; + } + + if (automation_id_ == MSG_ROUTING_NONE) { + result->SetNull(); + return; + } + + if (!sender_) { + NOTREACHED(); + result->SetNull(); + return; + } + + if (args[0].type != NPVariantType_String) { + result->SetNull(); + return; + } + + std::string json = args[0].ToString(); + result->Set(sender_->Send( + new ViewHostMsg_DomOperationResponse(routing_id_, json, automation_id_))); + + automation_id_ = MSG_ROUTING_NONE; +} + +void DomAutomationController::SetAutomationId( + const CppArgumentList& args, CppVariant* result) { + if (args.size() != 1) { + result->SetNull(); + return; + } + + // The check here is for NumberType and not Int32 as + // KJS::JSType only defines a NumberType (no Int32) + if (!args[0].isNumber()) { + result->SetNull(); + return; + } + + automation_id_ = args[0].ToInt32(); + result->Set(true); +} diff --git a/content/renderer/dom_automation_controller.h b/content/renderer/dom_automation_controller.h new file mode 100644 index 0000000..576e09d --- /dev/null +++ b/content/renderer/dom_automation_controller.h @@ -0,0 +1,113 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_ +#define CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_ +#pragma once + +#include "ipc/ipc_message.h" +#include "webkit/glue/cpp_bound_class.h" + +/* DomAutomationController class: + Bound to Javascript window.domAutomationController object. + At the very basic, this object makes any native value (string, numbers, + boolean) from javascript available to the automation host in Cpp. + Any renderer implementation that is built with this binding will allow the + above facility. + The intended use of this object is to expose the DOM Objects and their + attributes to the automation host. + + A typical usage would be like following (JS code): + + var object = document.getElementById('some_id'); + window.domAutomationController.send(object.nodeName); // get the tag name + + For the exact mode of usage, + refer AutomationProxyTest.*DomAutomationController tests. + + The class provides a single send method that can send variety of native + javascript values. (NPString, Number(double), Boolean) + + The actual communication occurs in the following manner: + + TEST MASTER RENDERER + (1) (3) + |AProxy| ----->|AProvider|----->|RenderView|------| + /\ | | | + | | | | + |(6) |(2) |(0) |(4) + | | \/ | + | |-------->|DAController|<----| + | | + | |(5) + |---------|TabContents|<----------| + + + Legends: + - AProxy = AutomationProxy + - AProvider = AutomationProvider + - DAController = DomAutomationController + + (0) Initialization step where DAController is bound to the renderer + and the view_id of the renderer is supplied to the DAController for + routing message in (5). (routing_id_) + (1) A 'javascript:' url is sent from the test process to master as an IPC + message. A unique routing id is generated at this stage (automation_id_) + (2) The automation_id_ of step (1) is supplied to DAController by calling + the bound method setAutomationId(). This is required for routing message + in (6). + (3) The 'javascript:' url is sent for execution by calling into + Browser::LoadURL() + (4) A callback is generated as a result of domAutomationController.send() + into Cpp. The supplied value is received as a result of this callback. + (5) The value received in (4) is sent to the master along with the + stored automation_id_ as an IPC message. routing_id_ is used to route + the message. (IPC messages, ViewHostMsg_*DomAutomation* ) + (6) The value and the automation_id_ is extracted out of the message received + in (5). This value is relayed to AProxy using another IPC message. + automation_id_ is used to route the message. + (IPC messages, AutomationMsg_Dom*Response) + +*/ + +// TODO(vibhor): Add another method-pair like sendLater() and sendNow() +// sendLater() should keep building a json serializer +// sendNow() should send the above serializer as a string. +class DomAutomationController : public CppBoundClass { + public: + DomAutomationController(); + + // Makes the renderer send a javascript value to the app. + // The value to be sent can be either of type NPString, + // Number (double casted to int32) or boolean. + // The function returns true/false based on the result of actual send over + // IPC. It sets the return value to null on unexpected errors or arguments. + void Send(const CppArgumentList& args, CppVariant* result); + + // Makes the renderer send a javascript value to the app. + // The value must be a NPString and should be properly formed JSON. + // This function does not modify/escape the returned string in any way. + void SendJSON(const CppArgumentList& args, CppVariant* result); + + void SetAutomationId(const CppArgumentList& args, CppVariant* result); + + // TODO(vibhor): Implement later + // static CppBindingObjectMethod sendLater; + // static CppBindingObjectMethod sendNow; + + void set_routing_id(int routing_id) { routing_id_ = routing_id; } + + void set_message_sender(IPC::Message::Sender* sender) { + sender_ = sender; + } + + private: + IPC::Message::Sender* sender_; + + // Refer to the comments at the top of the file for more details. + int routing_id_; // routing id to be used by first channel. + int automation_id_; // routing id to be used by the next channel. +}; + +#endif // CONTENT_RENDERER_DOM_AUTOMATION_CONTROLLER_H_ diff --git a/content/renderer/render_thread_impl.cc b/content/renderer/render_thread_impl.cc index 00c405f..578d6aa 100644 --- a/content/renderer/render_thread_impl.cc +++ b/content/renderer/render_thread_impl.cc @@ -52,6 +52,7 @@ #include "content/renderer/render_process_impl.h" #include "content/renderer/render_view_impl.h" #include "content/renderer/renderer_webkitplatformsupport_impl.h" +#include "grit/content_resources.h" #include "ipc/ipc_channel_handle.h" #include "ipc/ipc_platform_file.h" #include "net/base/net_errors.h" @@ -475,6 +476,14 @@ void RenderThreadImpl::EnsureWebKitInitialized() { RegisterExtension(extensions_v8::PlaybackExtension::Get()); } + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDomAutomationController)) { + base::StringPiece extension = content::GetContentClient()->GetDataResource( + IDR_DOM_AUTOMATION_JS); + RegisterExtension(new v8::Extension( + "dom_automation.js", extension.data(), 0, NULL, extension.size())); + } + web_database_observer_impl_.reset(new WebDatabaseObserverImpl(Get())); WebKit::WebDatabase::setObserver(web_database_observer_impl_.get()); diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index 767523e..2b9c197 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -50,6 +50,7 @@ #include "content/public/renderer/render_view_visitor.h" #include "content/renderer/device_orientation_dispatcher.h" #include "content/renderer/devtools_agent.h" +#include "content/renderer/dom_automation_controller.h" #include "content/renderer/external_popup_menu.h" #include "content/renderer/geolocation_dispatcher.h" #include "content/renderer/gpu/webgraphicscontext3d_command_buffer_impl.h" @@ -496,6 +497,10 @@ RenderViewImpl::RenderViewImpl( new IdleUserDetector(this); + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kDomAutomationController)) + enabled_bindings_ |= content::BINDINGS_POLICY_DOM_AUTOMATION; + content::GetContentClient()->renderer()->RenderViewCreated(this); } @@ -2746,6 +2751,16 @@ void RenderViewImpl::didClearWindowObject(WebFrame* frame) { frame_url.SchemeIs(chrome::kDataScheme))) { GetWebUIBindings()->BindToJavascript(frame, "chrome"); } + + if (enabled_bindings_ & content::BINDINGS_POLICY_DOM_AUTOMATION) { + if (!dom_automation_controller_.get()) + dom_automation_controller_.reset(new DomAutomationController()); + dom_automation_controller_->set_message_sender( + static_cast(this)); + dom_automation_controller_->set_routing_id(routing_id()); + dom_automation_controller_->BindToJavascript(frame, + "domAutomationController"); + } } void RenderViewImpl::didCreateDocumentElement(WebFrame* frame) { @@ -3397,10 +3412,6 @@ int RenderViewImpl::GetEnabledBindings() { return enabled_bindings_; } -void RenderViewImpl::SetEnabledBindings(int enabled_bindings) { - enabled_bindings_ = enabled_bindings; -} - bool RenderViewImpl::GetContentStateImmediately() { return send_content_state_immediately_; } diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index b892a80..1d9963a 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -60,6 +60,7 @@ class DeviceOrientationDispatcher; class DevToolsAgent; +class DomAutomationController; class ExternalPopupMenu; class GeolocationDispatcher; class GURL; @@ -588,7 +589,6 @@ class RenderViewImpl : public RenderWidget, bool notify_result) OVERRIDE; virtual bool ShouldDisplayScrollbars(int width, int height) const OVERRIDE; virtual int GetEnabledBindings() OVERRIDE; - virtual void SetEnabledBindings(int enabled_bindings) OVERRIDE; virtual bool GetContentStateImmediately() OVERRIDE; virtual float GetFilteredTimePerFrame() OVERRIDE; virtual void ShowContextMenu(WebKit::WebFrame* frame, @@ -1250,6 +1250,10 @@ class RenderViewImpl : public RenderWidget, int focused_plugin_id_; #endif + // Allows JS to access DOM automation. The JS object is only exposed when the + // DOM automation bindings are enabled. + scoped_ptr dom_automation_controller_; + // NOTE: pepper_delegate_ should be last member because its constructor calls // AddObservers method of RenderViewImpl from c-tor. PepperPluginDelegateImpl pepper_delegate_; diff --git a/content/shell/shell_content_client.cc b/content/shell/shell_content_client.cc index 145a7fe..5870451 100644 --- a/content/shell/shell_content_client.cc +++ b/content/shell/shell_content_client.cc @@ -27,10 +27,6 @@ void ShellContentClient::AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) { } -bool ShellContentClient::CanSendWhileSwappedOut(const IPC::Message* msg) { - return false; -} - bool ShellContentClient::CanHandleWhileSwappedOut(const IPC::Message& msg) { return false; } diff --git a/content/shell/shell_content_client.h b/content/shell/shell_content_client.h index a4ef244..21ea340 100644 --- a/content/shell/shell_content_client.h +++ b/content/shell/shell_content_client.h @@ -21,7 +21,6 @@ class ShellContentClient : public ContentClient { std::vector* plugins) OVERRIDE; virtual void AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) OVERRIDE; - virtual bool CanSendWhileSwappedOut(const IPC::Message* msg) OVERRIDE; virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE; virtual std::string GetUserAgent(bool* overriding) const OVERRIDE; virtual string16 GetLocalizedString(int message_id) const OVERRIDE; diff --git a/content/test/test_content_client.cc b/content/test/test_content_client.cc index 954958f..fb572ce 100644 --- a/content/test/test_content_client.cc +++ b/content/test/test_content_client.cc @@ -35,11 +35,6 @@ void TestContentClient::AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) { } -bool TestContentClient::CanSendWhileSwappedOut(const IPC::Message* msg) { - // TestContentClient does not need to send any additional messages. - return false; -} - bool TestContentClient::CanHandleWhileSwappedOut(const IPC::Message& msg) { // TestContentClient does not need to handle any additional messages. return false; diff --git a/content/test/test_content_client.h b/content/test/test_content_client.h index 44399a7..0ff830f 100644 --- a/content/test/test_content_client.h +++ b/content/test/test_content_client.h @@ -22,7 +22,6 @@ class TestContentClient : public content::ContentClient { std::vector* plugins) OVERRIDE; virtual void AddNPAPIPlugins( webkit::npapi::PluginList* plugin_list) OVERRIDE; - virtual bool CanSendWhileSwappedOut(const IPC::Message* msg) OVERRIDE; virtual bool CanHandleWhileSwappedOut(const IPC::Message& msg) OVERRIDE; virtual std::string GetUserAgent(bool* overriding) const OVERRIDE; virtual string16 GetLocalizedString(int message_id) const OVERRIDE; -- cgit v1.1