blob: efa0c95b54de15ded2834873b323433dd725fb15 [file] [log] [blame]
[email protected]9e790bd2011-01-10 23:48:541// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]4bdde602010-06-16 03:17:355#include "chrome/browser/external_tab_container_win.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]4c540ee2009-07-07 17:15:557#include <string>
8
[email protected]58580352010-10-26 04:07:509#include "base/debug/trace_event.h"
[email protected]7cf1b6ce2010-03-20 06:37:0110#include "base/i18n/rtl.h"
initial.commit09911bf2008-07-26 23:55:2911#include "base/logging.h"
[email protected]1f1e7cb2011-10-07 22:55:4712#include "base/memory/scoped_ptr.h"
[email protected]944b4212010-12-14 00:00:3313#include "base/utf_string_conversions.h"
[email protected]a8e20582010-12-31 17:18:5014#include "base/win/win_util.h"
[email protected]1a3aba82010-11-08 23:52:5415#include "chrome/app/chrome_command_ids.h"
[email protected]0f8df8672010-11-09 00:36:3216#include "chrome/app/chrome_dll_resource.h"
[email protected]b3841c502011-03-09 01:21:3117#include "chrome/browser/automation/automation_provider.h"
[email protected]dce502762011-07-20 08:53:4918#include "chrome/browser/debugger/devtools_toggle_action.h"
19#include "chrome/browser/debugger/devtools_window.h"
[email protected]91a79232010-11-10 18:15:0820#include "chrome/browser/google/google_util.h"
[email protected]ec0b6c42010-08-26 03:16:5821#include "chrome/browser/history/history_types.h"
[email protected]105bb0f2011-05-24 17:12:1422#include "chrome/browser/history/history_tab_helper.h"
[email protected]7e204122011-09-01 18:56:2123#include "chrome/browser/infobars/infobar_tab_helper.h"
[email protected]8ecad5e2010-12-02 21:18:3324#include "chrome/browser/profiles/profile.h"
[email protected]3ab9cb82011-06-03 18:02:0725#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]7fbd1e92011-06-02 19:33:0026#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]a8c229cc2011-01-13 22:31:5827#include "chrome/browser/ui/browser.h"
[email protected]00070c732011-04-09 15:31:3328#include "chrome/browser/ui/browser_window.h"
[email protected]7b8d4a22011-02-10 20:57:5429#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9e790bd2011-01-10 23:48:5430#include "chrome/browser/ui/views/browser_dialogs.h"
[email protected]6c6614f12011-03-31 18:51:4231#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
[email protected]9e790bd2011-01-10 23:48:5432#include "chrome/browser/ui/views/page_info_bubble_view.h"
33#include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h"
34#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
[email protected]a8ba6362010-11-10 20:02:2535#include "chrome/common/automation_messages.h"
initial.commit09911bf2008-07-26 23:55:2936#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:2737#include "chrome/common/chrome_notification_types.h"
[email protected]15b2c6a2011-05-16 23:54:4038#include "chrome/common/render_messages.h"
[email protected]91a79232010-11-10 18:15:0839#include "chrome/common/url_constants.h"
[email protected]35e251d2011-05-24 21:01:0440#include "content/browser/load_notification_details.h"
[email protected]5de634712011-03-02 00:20:1941#include "content/browser/renderer_host/render_process_host.h"
42#include "content/browser/renderer_host/render_view_host.h"
43#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
[email protected]8286f51a2011-05-31 17:39:1344#include "content/browser/tab_contents/navigation_details.h"
[email protected]299425b2011-03-02 07:45:2045#include "content/browser/tab_contents/provisional_load_details.h"
[email protected]ad50def52011-10-19 23:17:0746#include "content/public/browser/notification_service.h"
[email protected]216813952011-05-19 22:21:2647#include "content/common/page_zoom.h"
[email protected]0aed2f52011-03-23 18:06:3648#include "content/common/view_messages.h"
[email protected]8bc38d22011-10-14 20:39:2049#include "content/public/browser/native_web_keyboard_event.h"
[email protected]e091df82011-10-11 18:13:2150#include "content/public/common/bindings_policy.h"
[email protected]2905f742011-10-13 03:51:5851#include "content/public/common/page_transition_types.h"
[email protected]e943d6662009-06-12 03:50:3952#include "grit/generated_resources.h"
[email protected]0b7a012d2010-10-19 23:49:2653#include "grit/locale_settings.h"
[email protected]c051a1b2011-01-21 23:30:1754#include "ui/base/l10n/l10n_util.h"
[email protected]9ac174e92011-04-16 00:58:5655#include "ui/base/resource/resource_bundle.h"
[email protected]9dd7e3d72011-01-20 18:27:0656#include "ui/base/view_prop.h"
[email protected]b516e2d2011-07-12 16:54:1257#include "ui/base/models/menu_model.h"
[email protected]9ef7d4b2011-01-27 02:17:2158#include "views/layout/grid_layout.h"
[email protected]e943d6662009-06-12 03:50:3959
[email protected]9dd7e3d72011-01-20 18:27:0660using ui::ViewProp;
[email protected]3b8a7f8e2010-11-21 22:44:2161
62static const char kWindowObjectKey[] = "ChromeWindowObject";
initial.commit09911bf2008-07-26 23:55:2963
[email protected]b516e2d2011-07-12 16:54:1264namespace {
65
66// Convert ui::MenuModel into a serializable form for Chrome Frame
67ContextMenuModel* ConvertMenuModel(const ui::MenuModel* ui_model) {
68 ContextMenuModel* new_model = new ContextMenuModel;
69
70 const int index_base = ui_model->GetFirstItemIndex(NULL);
71 const int item_count = ui_model->GetItemCount();
72 new_model->items.reserve(item_count);
73 for (int i = 0; i < item_count; ++i) {
74 const int index = index_base + i;
75 if (ui_model->IsVisibleAt(index)) {
76 ContextMenuModel::Item item;
77 item.type = ui_model->GetTypeAt(index);
78 item.item_id = ui_model->GetCommandIdAt(index);
79 item.label = ui_model->GetLabelAt(index);
80 item.checked = ui_model->IsItemCheckedAt(index);
81 item.enabled = ui_model->IsEnabledAt(index);
82 if (item.type == ui::MenuModel::TYPE_SUBMENU)
83 item.submenu = ConvertMenuModel(ui_model->GetSubmenuModelAt(index));
84
85 new_model->items.push_back(item);
86 }
87 }
88
89 return new_model;
90}
91
92} // namespace
93
[email protected]5168c72c2011-04-25 17:30:2394// This class overrides the LinkClicked function in the PageInfoBubbleView
[email protected]0b7a012d2010-10-19 23:49:2695// class and routes the help center link navigation to the host browser.
96class ExternalTabPageInfoBubbleView : public PageInfoBubbleView {
97 public:
98 ExternalTabPageInfoBubbleView(ExternalTabContainer* container,
99 gfx::NativeWindow parent_window,
100 Profile* profile,
101 const GURL& url,
102 const NavigationEntry::SSLStatus& ssl,
103 bool show_history)
104 : PageInfoBubbleView(parent_window, profile, url, ssl, show_history),
105 container_(container) {
[email protected]5044da82010-10-27 01:09:16106 DVLOG(1) << __FUNCTION__;
[email protected]0b7a012d2010-10-19 23:49:26107 }
108 virtual ~ExternalTabPageInfoBubbleView() {
[email protected]5044da82010-10-27 01:09:16109 DVLOG(1) << __FUNCTION__;
[email protected]0b7a012d2010-10-19 23:49:26110 }
[email protected]5168c72c2011-04-25 17:30:23111 // LinkListener methods:
112 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE {
[email protected]91a79232010-11-10 18:15:08113 GURL url = google_util::AppendGoogleLocaleParam(
114 GURL(chrome::kPageInfoHelpCenterURL));
[email protected]0b7a012d2010-10-19 23:49:26115 container_->OpenURLFromTab(container_->tab_contents(), url, GURL(),
[email protected]2905f742011-10-13 03:51:58116 NEW_FOREGROUND_TAB,
117 content::PAGE_TRANSITION_LINK);
[email protected]0b7a012d2010-10-19 23:49:26118 }
119 private:
120 scoped_refptr<ExternalTabContainer> container_;
121};
122
[email protected]d0ed50d2010-06-22 01:01:32123base::LazyInstance<ExternalTabContainer::PendingTabs>
124 ExternalTabContainer::pending_tabs_(base::LINKER_INITIALIZED);
125
initial.commit09911bf2008-07-26 23:55:29126ExternalTabContainer::ExternalTabContainer(
[email protected]2e4633c2009-07-09 16:58:06127 AutomationProvider* automation, AutomationResourceMessageFilter* filter)
[email protected]2fc66722011-05-19 14:43:12128 : views::NativeWidgetWin(new views::Widget),
[email protected]9a56a0d2011-05-13 19:03:31129 automation_(automation),
[email protected]2e39d2e2009-02-19 18:41:31130 tab_contents_container_(NULL),
[email protected]eac83f02009-05-08 18:44:44131 tab_handle_(0),
[email protected]2e4633c2009-07-09 16:58:06132 ignore_next_load_notification_(false),
133 automation_resource_message_filter_(filter),
[email protected]a50a4902009-08-14 22:39:01134 load_requests_via_automation_(false),
[email protected]24f98bba2009-10-14 18:47:49135 handle_top_level_requests_(false),
[email protected]4cfc1d922009-11-08 14:02:58136 external_method_factory_(this),
[email protected]f7019302010-03-26 19:58:32137 pending_(false),
[email protected]ba67fd82010-07-09 18:30:31138 focus_manager_(NULL),
[email protected]1f71d5882010-07-15 20:39:07139 external_tab_view_(NULL),
[email protected]9eeb35e2010-09-30 21:38:50140 unload_reply_message_(NULL),
[email protected]326d3b72011-03-29 20:38:24141 route_all_top_level_navigations_(false),
142 is_popup_window_(false) {
initial.commit09911bf2008-07-26 23:55:29143}
144
145ExternalTabContainer::~ExternalTabContainer() {
[email protected]632fbb12009-09-06 15:27:14146 Uninitialize();
initial.commit09911bf2008-07-26 23:55:29147}
148
[email protected]7b8d4a22011-02-10 20:57:54149TabContents* ExternalTabContainer::tab_contents() const {
150 return tab_contents_.get() ? tab_contents_->tab_contents() : NULL;
151}
152
[email protected]9095e982009-05-27 17:28:24153bool ExternalTabContainer::Init(Profile* profile,
154 HWND parent,
155 const gfx::Rect& bounds,
[email protected]95c3c592009-07-14 22:09:03156 DWORD style,
[email protected]5f450e52009-07-28 13:28:11157 bool load_requests_via_automation,
[email protected]a50a4902009-08-14 22:39:01158 bool handle_top_level_requests,
[email protected]7b8d4a22011-02-10 20:57:54159 TabContentsWrapper* existing_contents,
[email protected]7de487c2009-12-18 21:07:53160 const GURL& initial_url,
[email protected]f7019302010-03-26 19:58:32161 const GURL& referrer,
[email protected]9eeb35e2010-09-30 21:38:50162 bool infobars_enabled,
163 bool route_all_top_level_navigations) {
initial.commit09911bf2008-07-26 23:55:29164 if (IsWindow()) {
165 NOTREACHED();
166 return false;
167 }
[email protected]0498f7f82009-02-24 03:04:12168
[email protected]95c3c592009-07-14 22:09:03169 load_requests_via_automation_ = load_requests_via_automation;
[email protected]a50a4902009-08-14 22:39:01170 handle_top_level_requests_ = handle_top_level_requests;
[email protected]9eeb35e2010-09-30 21:38:50171 route_all_top_level_navigations_ = route_all_top_level_navigations;
[email protected]95c3c592009-07-14 22:09:03172
[email protected]6603fe92009-08-05 17:05:57173 set_window_style(WS_POPUP | WS_CLIPCHILDREN);
[email protected]af1fde02011-04-26 17:43:05174
[email protected]243d16c2011-04-26 19:31:24175 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
[email protected]af1fde02011-04-26 17:43:05176 params.bounds = bounds;
[email protected]9a56a0d2011-05-13 19:03:31177 params.native_widget = this;
[email protected]af1fde02011-04-26 17:43:05178 GetWidget()->Init(params);
[email protected]08ed00a2009-05-28 20:48:14179 if (!IsWindow()) {
180 NOTREACHED();
181 return false;
182 }
[email protected]f5cde2b2009-09-11 22:33:58183
[email protected]82166b62009-06-30 18:48:00184 // TODO(jcampan): limit focus traversal to contents.
initial.commit09911bf2008-07-26 23:55:29185
[email protected]3b8a7f8e2010-11-21 22:44:21186 prop_.reset(new ViewProp(GetNativeView(), kWindowObjectKey, this));
initial.commit09911bf2008-07-26 23:55:29187
[email protected]632fbb12009-09-06 15:27:14188 if (existing_contents) {
[email protected]7b8d4a22011-02-10 20:57:54189 tab_contents_.reset(existing_contents);
[email protected]3d7474ff2011-07-27 17:47:37190 tab_contents_->controller().set_browser_context(profile);
[email protected]632fbb12009-09-06 15:27:14191 } else {
[email protected]7b8d4a22011-02-10 20:57:54192 TabContents* new_contents = new TabContents(profile, NULL, MSG_ROUTING_NONE,
193 NULL, NULL);
194 tab_contents_.reset(new TabContentsWrapper(new_contents));
[email protected]632fbb12009-09-06 15:27:14195 }
[email protected]a50a4902009-08-14 22:39:01196
[email protected]7abc95292011-05-18 00:18:09197 if (!infobars_enabled)
[email protected]7e204122011-09-01 18:56:21198 tab_contents_->infobar_tab_helper()->set_infobars_enabled(false);
[email protected]7abc95292011-05-18 00:18:09199
[email protected]7b8d4a22011-02-10 20:57:54200 tab_contents_->tab_contents()->set_delegate(this);
[email protected]632fbb12009-09-06 15:27:14201
[email protected]7b8d4a22011-02-10 20:57:54202 tab_contents_->tab_contents()->
203 GetMutableRendererPrefs()->browser_handles_top_level_requests =
204 handle_top_level_requests;
[email protected]a50a4902009-08-14 22:39:01205
206 if (!existing_contents) {
207 tab_contents_->render_view_host()->AllowBindings(
[email protected]e091df82011-10-11 18:13:21208 content::BINDINGS_POLICY_EXTERNAL_HOST);
[email protected]a50a4902009-08-14 22:39:01209 }
[email protected]18cb2572008-08-21 20:34:45210
[email protected]ce3fa3c2009-04-20 19:55:57211 NavigationController* controller = &tab_contents_->controller();
[email protected]432115822011-07-10 15:52:27212 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:53213 content::Source<NavigationController>(controller));
[email protected]432115822011-07-10 15:52:27214 registrar_.Add(this, content::NOTIFICATION_FAIL_PROVISIONAL_LOAD_WITH_ERROR,
[email protected]6c2381d2011-10-19 02:52:53215 content::Source<NavigationController>(controller));
[email protected]432115822011-07-10 15:52:27216 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53217 content::Source<NavigationController>(controller));
[email protected]432115822011-07-10 15:52:27218 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB,
[email protected]6c2381d2011-10-19 02:52:53219 content::Source<TabContents>(tab_contents_->tab_contents()));
[email protected]432115822011-07-10 15:52:27220 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_DELETED,
[email protected]ad50def52011-10-19 23:17:07221 content::NotificationService::AllSources());
[email protected]2e4633c2009-07-09 16:58:06222
[email protected]23bf92962011-06-03 21:04:22223 TabContentsObserver::Observe(tab_contents_->tab_contents());
[email protected]15b2c6a2011-05-16 23:54:40224
[email protected]f5cde2b2009-09-11 22:33:58225 // Start loading initial URL
226 if (!initial_url.is_empty()) {
227 // Navigate out of context since we don't have a 'tab_handle_' yet.
[email protected]24f98bba2009-10-14 18:47:49228 MessageLoop::current()->PostTask(
229 FROM_HERE,
230 external_method_factory_.NewRunnableMethod(
[email protected]7de487c2009-12-18 21:07:53231 &ExternalTabContainer::Navigate, initial_url, referrer));
[email protected]f5cde2b2009-09-11 22:33:58232 }
233
[email protected]0498f7f82009-02-24 03:04:12234 // We need WS_POPUP to be on the window during initialization, but
235 // once initialized we apply the requested style which may or may not
236 // include the popup bit.
237 // Note that it's important to do this before we call SetParent since
238 // during the SetParent call we will otherwise get a WA_ACTIVATE call
239 // that causes us to steal the current focus.
[email protected]9095e982009-05-27 17:28:24240 SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style);
[email protected]0498f7f82009-02-24 03:04:12241
[email protected]31fb110522009-01-28 21:50:39242 // Now apply the parenting and style
243 if (parent)
[email protected]9095e982009-05-27 17:28:24244 SetParent(GetNativeView(), parent);
[email protected]7e503122009-02-04 21:52:48245
[email protected]7b8d4a22011-02-10 20:57:54246 ::ShowWindow(tab_contents_->tab_contents()->GetNativeView(), SW_SHOWNA);
[email protected]e943d6662009-06-12 03:50:39247
[email protected]3f70c1e12010-01-12 20:38:49248 LoadAccelerators();
[email protected]ab861b42010-02-05 19:13:44249 SetupExternalTabView();
[email protected]7fbd1e92011-06-02 19:33:00250 tab_contents_->blocked_content_tab_helper()->set_delegate(this);
initial.commit09911bf2008-07-26 23:55:29251 return true;
252}
253
[email protected]632fbb12009-09-06 15:27:14254void ExternalTabContainer::Uninitialize() {
255 registrar_.RemoveAll();
[email protected]7b8d4a22011-02-10 20:57:54256 if (tab_contents_.get()) {
[email protected]39ec12f2011-03-25 23:02:28257 UnregisterRenderViewHost(tab_contents_->render_view_host());
[email protected]52933842009-09-29 03:44:06258
[email protected]9a56a0d2011-05-13 19:03:31259 if (GetWidget()->GetRootView())
260 GetWidget()->GetRootView()->RemoveAllChildViews(true);
[email protected]482a2d92011-02-10 00:34:28261
[email protected]ad50def52011-10-19 23:17:07262 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27263 chrome::NOTIFICATION_EXTERNAL_TAB_CLOSED,
[email protected]6c2381d2011-10-19 02:52:53264 content::Source<NavigationController>(&tab_contents_->controller()),
265 content::Details<ExternalTabContainer>(this));
[email protected]632fbb12009-09-06 15:27:14266
[email protected]7b8d4a22011-02-10 20:57:54267 tab_contents_.reset(NULL);
[email protected]632fbb12009-09-06 15:27:14268 }
[email protected]1a98a932009-11-17 00:12:52269
[email protected]93685472010-04-23 00:57:50270 if (focus_manager_) {
271 focus_manager_->UnregisterAccelerators(this);
[email protected]f1c74ec2010-05-21 22:20:37272 focus_manager_ = NULL;
[email protected]3f70c1e12010-01-12 20:38:49273 }
274
[email protected]ba67fd82010-07-09 18:30:31275 external_tab_view_ = NULL;
[email protected]13c30922009-11-19 03:43:19276 request_context_ = NULL;
[email protected]ab861b42010-02-05 19:13:44277 tab_contents_container_ = NULL;
[email protected]632fbb12009-09-06 15:27:14278}
279
280bool ExternalTabContainer::Reinitialize(
281 AutomationProvider* automation_provider,
[email protected]6e47f2f2010-07-12 17:30:58282 AutomationResourceMessageFilter* filter,
283 gfx::NativeWindow parent_window) {
[email protected]632fbb12009-09-06 15:27:14284 if (!automation_provider || !filter) {
285 NOTREACHED();
286 return false;
287 }
288
289 automation_ = automation_provider;
290 automation_resource_message_filter_ = filter;
[email protected]6c2e45b2010-05-07 00:55:25291 // Wait for the automation channel to be initialized before resuming pending
292 // render views and sending in the navigation state.
[email protected]24f98bba2009-10-14 18:47:49293 MessageLoop::current()->PostTask(
294 FROM_HERE,
295 external_method_factory_.NewRunnableMethod(
[email protected]18290eb2010-01-30 00:47:06296 &ExternalTabContainer::OnReinitialize));
[email protected]6e47f2f2010-07-12 17:30:58297
298 if (parent_window)
299 SetParent(GetNativeView(), parent_window);
[email protected]632fbb12009-09-06 15:27:14300 return true;
301}
302
[email protected]1a98a932009-11-17 00:12:52303void ExternalTabContainer::SetTabHandle(int handle) {
304 tab_handle_ = handle;
[email protected]1a98a932009-11-17 00:12:52305}
306
[email protected]9095e982009-05-27 17:28:24307void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
[email protected]0b5781a2011-10-18 21:29:00308 NativeWebKeyboardEvent keyboard_event(msg);
[email protected]3f70c1e12010-01-12 20:38:49309 unhandled_keyboard_event_handler_.HandleKeyboardEvent(keyboard_event,
[email protected]93685472010-04-23 00:57:50310 focus_manager_);
[email protected]9095e982009-05-27 17:28:24311}
312
[email protected]1fd45692010-04-19 21:01:18313void ExternalTabContainer::FocusThroughTabTraversal(
314 bool reverse, bool restore_focus_to_view) {
[email protected]7b8d4a22011-02-10 20:57:54315 DCHECK(tab_contents_.get());
316 if (tab_contents_.get())
317 tab_contents_->tab_contents()->Focus();
[email protected]6331e0b2010-02-23 19:36:10318
319 // The tab_contents_ member can get destroyed in the context of the call to
[email protected]7e2cef52011-04-11 21:47:23320 // TabContentsViewViews::Focus() above. This method eventually calls SetFocus
[email protected]6331e0b2010-02-23 19:36:10321 // on the native window, which could end up dispatching messages like
322 // WM_DESTROY for the external tab.
[email protected]7b8d4a22011-02-10 20:57:54323 if (tab_contents_.get() && restore_focus_to_view)
324 tab_contents_->tab_contents()->FocusThroughTabTraversal(reverse);
initial.commit09911bf2008-07-26 23:55:29325}
326
[email protected]9095e982009-05-27 17:28:24327// static
328bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
[email protected]3b8a7f8e2010-11-21 22:44:21329 return ViewProp::GetValue(window, kWindowObjectKey) != NULL;
initial.commit09911bf2008-07-26 23:55:29330}
331
[email protected]9095e982009-05-27 17:28:24332// static
333ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
334 HWND tab_window) {
335 HWND parent_window = ::GetParent(tab_window);
336 if (!::IsWindow(parent_window)) {
337 return NULL;
initial.commit09911bf2008-07-26 23:55:29338 }
[email protected]9095e982009-05-27 17:28:24339 if (!IsExternalTabContainer(parent_window)) {
340 return NULL;
341 }
342 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
[email protected]3b8a7f8e2010-11-21 22:44:21343 ViewProp::GetValue(parent_window, kWindowObjectKey));
[email protected]9095e982009-05-27 17:28:24344 return container;
initial.commit09911bf2008-07-26 23:55:29345}
346
[email protected]2b19e2fe2010-02-16 02:24:18347// static
348ExternalTabContainer*
349 ExternalTabContainer::GetExternalContainerFromNativeWindow(
350 gfx::NativeView native_window) {
351 ExternalTabContainer* tab_container = NULL;
352 if (native_window) {
[email protected]3b8a7f8e2010-11-21 22:44:21353 tab_container = reinterpret_cast<ExternalTabContainer*>(
354 ViewProp::GetValue(native_window, kWindowObjectKey));
[email protected]2b19e2fe2010-02-16 02:24:18355 }
356 return tab_container;
357}
[email protected]9095e982009-05-27 17:28:24358////////////////////////////////////////////////////////////////////////////////
359// ExternalTabContainer, TabContentsDelegate implementation:
[email protected]72baf6762009-05-06 18:45:33360
[email protected]00c37fc2011-08-02 00:22:50361// TODO(adriansc): Remove this method once refactoring changed all call sites.
[email protected]992e4542011-07-20 23:09:25362TabContents* ExternalTabContainer::OpenURLFromTab(
363 TabContents* source,
364 const GURL& url,
365 const GURL& referrer,
366 WindowOpenDisposition disposition,
[email protected]2905f742011-10-13 03:51:58367 content::PageTransition transition) {
[email protected]00c37fc2011-08-02 00:22:50368 return OpenURLFromTab(source,
[email protected]e47ae9472011-10-13 19:48:34369 OpenURLParams(url, referrer, disposition, transition,
370 false));
[email protected]00c37fc2011-08-02 00:22:50371}
[email protected]18290eb2010-01-30 00:47:06372
[email protected]00c37fc2011-08-02 00:22:50373TabContents* ExternalTabContainer::OpenURLFromTab(TabContents* source,
374 const OpenURLParams& params) {
375 if (pending()) {
376 pending_open_url_requests_.push_back(params);
[email protected]992e4542011-07-20 23:09:25377 return NULL;
[email protected]18290eb2010-01-30 00:47:06378 }
379
[email protected]00c37fc2011-08-02 00:22:50380 switch (params.disposition) {
initial.commit09911bf2008-07-26 23:55:29381 case CURRENT_TAB:
[email protected]fba16f52009-04-02 22:30:35382 case SINGLETON_TAB:
initial.commit09911bf2008-07-26 23:55:29383 case NEW_FOREGROUND_TAB:
384 case NEW_BACKGROUND_TAB:
[email protected]5f450e52009-07-28 13:28:11385 case NEW_POPUP:
initial.commit09911bf2008-07-26 23:55:29386 case NEW_WINDOW:
[email protected]5f450e52009-07-28 13:28:11387 case SAVE_TO_DISK:
initial.commit09911bf2008-07-26 23:55:29388 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34389 automation_->Send(new AutomationMsg_OpenURL(tab_handle_,
[email protected]00c37fc2011-08-02 00:22:50390 params.url,
391 params.referrer,
392 params.disposition));
[email protected]898f59212010-07-22 00:35:26393 // TODO(ananta)
394 // We should populate other fields in the
395 // ViewHostMsg_FrameNavigate_Params structure. Another option could be
396 // to refactor the UpdateHistoryForNavigation function in TabContents.
[email protected]00c37fc2011-08-02 00:22:50397 ViewHostMsg_FrameNavigate_Params nav_params;
398 nav_params.referrer = params.referrer;
399 nav_params.url = params.url;
400 nav_params.page_id = -1;
[email protected]2905f742011-10-13 03:51:58401 nav_params.transition = content::PAGE_TRANSITION_LINK;
[email protected]898f59212010-07-22 00:35:26402
[email protected]8286f51a2011-05-31 17:39:13403 content::LoadCommittedDetails details;
[email protected]898f59212010-07-22 00:35:26404 details.did_replace_entry = false;
405
[email protected]ec0b6c42010-08-26 03:16:58406 scoped_refptr<history::HistoryAddPageArgs> add_page_args(
[email protected]105bb0f2011-05-24 17:12:14407 tab_contents_->history_tab_helper()->
[email protected]00c37fc2011-08-02 00:22:50408 CreateHistoryAddPageArgs(params.url, details, nav_params));
[email protected]105bb0f2011-05-24 17:12:14409 tab_contents_->history_tab_helper()->
[email protected]7b8d4a22011-02-10 20:57:54410 UpdateHistoryForNavigation(add_page_args);
[email protected]992e4542011-07-20 23:09:25411
412 return tab_contents_->tab_contents();
initial.commit09911bf2008-07-26 23:55:29413 }
414 break;
415 default:
[email protected]5f450e52009-07-28 13:28:11416 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29417 break;
[email protected]6dfed102009-04-28 03:09:53418 }
[email protected]992e4542011-07-20 23:09:25419
420 return NULL;
initial.commit09911bf2008-07-26 23:55:29421}
422
423void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
[email protected]b9d227492009-02-10 15:20:27424 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:29425 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34426 NavigationInfo nav_info;
[email protected]610cbb82011-10-18 16:35:08427 if (InitNavigationInfo(&nav_info, content::NAVIGATION_TYPE_NAV_IGNORE, 0))
[email protected]6c908bb2009-08-21 19:03:50428 automation_->Send(new AutomationMsg_NavigationStateChanged(
[email protected]f5494d42010-12-23 22:15:34429 tab_handle_, changed_flags, nav_info));
initial.commit09911bf2008-07-26 23:55:29430 }
431}
432
initial.commit09911bf2008-07-26 23:55:29433void ExternalTabContainer::AddNewContents(TabContents* source,
434 TabContents* new_contents,
435 WindowOpenDisposition disposition,
436 const gfx::Rect& initial_pos,
437 bool user_gesture) {
[email protected]e478e212010-07-17 00:31:29438 if (!automation_) {
439 DCHECK(pending_);
440 LOG(ERROR) << "Invalid automation provider. Dropping new contents notify";
441 delete new_contents;
442 return;
443 }
[email protected]a50a4902009-08-14 22:39:01444
[email protected]9eeb35e2010-09-30 21:38:50445 scoped_refptr<ExternalTabContainer> new_container;
446 // If the host is a browser like IE8, then the URL being navigated to in the
447 // new tab contents could potentially navigate back to Chrome from a new
448 // IE process. We support full tab mode only for IE and hence we use that as
449 // a determining factor in whether the new ExternalTabContainer instance is
450 // created as pending or not.
451 if (!route_all_top_level_navigations_) {
452 new_container = new ExternalTabContainer(NULL, NULL);
453 } else {
454 // Reuse the same tab handle here as the new container instance is a dummy
455 // instance which does not have an automation client connected at the other
456 // end.
457 new_container = new TemporaryPopupExternalTabContainer(
458 automation_, automation_resource_message_filter_.get());
459 new_container->SetTabHandle(tab_handle_);
460 }
[email protected]a50a4902009-08-14 22:39:01461
[email protected]6f526082010-01-28 19:36:58462 // Make sure that ExternalTabContainer instance is initialized with
463 // an unwrapped Profile.
[email protected]7b8d4a22011-02-10 20:57:54464 scoped_ptr<TabContentsWrapper> wrapper(new TabContentsWrapper(new_contents));
[email protected]6f526082010-01-28 19:36:58465 bool result = new_container->Init(
[email protected]e7013f4c2011-08-01 16:04:12466 wrapper->profile()->GetOriginalProfile(),
[email protected]6f526082010-01-28 19:36:58467 NULL,
468 initial_pos,
469 WS_CHILD,
470 load_requests_via_automation_,
471 handle_top_level_requests_,
[email protected]7b8d4a22011-02-10 20:57:54472 wrapper.get(),
[email protected]6f526082010-01-28 19:36:58473 GURL(),
[email protected]f7019302010-03-26 19:58:32474 GURL(),
[email protected]9eeb35e2010-09-30 21:38:50475 true,
476 route_all_top_level_navigations_);
[email protected]a50a4902009-08-14 22:39:01477
[email protected]6f526082010-01-28 19:36:58478 if (result) {
[email protected]e7013f4c2011-08-01 16:04:12479 Profile* profile = wrapper->profile();
[email protected]7b8d4a22011-02-10 20:57:54480 wrapper.release(); // Ownership has been transferred.
[email protected]9eeb35e2010-09-30 21:38:50481 if (route_all_top_level_navigations_) {
482 return;
483 }
[email protected]b1c55638612010-03-08 16:26:11484 uintptr_t cookie = reinterpret_cast<uintptr_t>(new_container.get());
[email protected]d0ed50d2010-06-22 01:01:32485 pending_tabs_.Get()[cookie] = new_container;
[email protected]18290eb2010-01-30 00:47:06486 new_container->set_pending(true);
[email protected]326d3b72011-03-29 20:38:24487 new_container->set_is_popup_window(disposition == NEW_POPUP);
[email protected]f5494d42010-12-23 22:15:34488 AttachExternalTabParams attach_params_;
[email protected]b1c55638612010-03-08 16:26:11489 attach_params_.cookie = static_cast<uint64>(cookie);
490 attach_params_.dimensions = initial_pos;
491 attach_params_.user_gesture = user_gesture;
492 attach_params_.disposition = disposition;
[email protected]8103c7f2010-09-08 22:36:09493 attach_params_.profile_name = WideToUTF8(
[email protected]e7013f4c2011-08-01 16:04:12494 profile->GetPath().DirName().BaseName().value());
[email protected]f5494d42010-12-23 22:15:34495 automation_->Send(new AutomationMsg_AttachExternalTab(
[email protected]b1c55638612010-03-08 16:26:11496 tab_handle_, attach_params_));
[email protected]6f526082010-01-28 19:36:58497 } else {
498 NOTREACHED();
[email protected]9f5b80a2009-04-08 01:26:07499 }
initial.commit09911bf2008-07-26 23:55:29500}
501
[email protected]5951b5c12010-02-22 18:15:34502void ExternalTabContainer::TabContentsCreated(TabContents* new_contents) {
503 RenderViewHost* rvh = new_contents->render_view_host();
504 DCHECK(rvh != NULL);
[email protected]fd571bb2010-03-19 01:23:54505
506 // Register this render view as a pending render view, i.e. any network
507 // requests initiated by this render view would be serviced when the
508 // external host connects to the new external tab instance.
509 RegisterRenderViewHostForAutomation(rvh, true);
[email protected]5951b5c12010-02-22 18:15:34510}
511
initial.commit09911bf2008-07-26 23:55:29512void ExternalTabContainer::CloseContents(TabContents* source) {
[email protected]d9d8f0c2010-09-17 21:47:16513 if (!automation_)
514 return;
[email protected]e56e96f82010-02-03 21:38:08515
[email protected]d9d8f0c2010-09-17 21:47:16516 if (unload_reply_message_) {
517 AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_,
518 true);
519 automation_->Send(unload_reply_message_);
520 unload_reply_message_ = NULL;
[email protected]e16dd1672010-06-07 21:40:29521 } else {
[email protected]f5494d42010-12-23 22:15:34522 automation_->Send(new AutomationMsg_CloseExternalTab(tab_handle_));
[email protected]085d9cf2010-01-27 01:11:02523 }
initial.commit09911bf2008-07-26 23:55:29524}
525
[email protected]b9d227492009-02-10 15:20:27526void ExternalTabContainer::MoveContents(TabContents* source,
527 const gfx::Rect& pos) {
[email protected]326d3b72011-03-29 20:38:24528 if (automation_ && is_popup_window_)
529 automation_->Send(new AutomationMsg_MoveWindow(tab_handle_, pos));
530}
531
[email protected]7fbd1e92011-06-02 19:33:00532TabContentsWrapper* ExternalTabContainer::GetConstrainingContentsWrapper(
533 TabContentsWrapper* source) {
534 return source;
535}
536
[email protected]326d3b72011-03-29 20:38:24537bool ExternalTabContainer::IsPopup(const TabContents* source) const {
538 return is_popup_window_;
initial.commit09911bf2008-07-26 23:55:29539}
540
initial.commit09911bf2008-07-26 23:55:29541void ExternalTabContainer::UpdateTargetURL(TabContents* source,
[email protected]d952a052011-09-06 18:42:45542 int32 page_id,
initial.commit09911bf2008-07-26 23:55:29543 const GURL& url) {
[email protected]d952a052011-09-06 18:42:45544 Browser::UpdateTargetURLHelper(source, page_id, url);
initial.commit09911bf2008-07-26 23:55:29545 if (automation_) {
546 std::wstring url_string = CA2W(url.spec().c_str());
547 automation_->Send(
[email protected]f5494d42010-12-23 22:15:34548 new AutomationMsg_UpdateTargetUrl(tab_handle_, url_string));
initial.commit09911bf2008-07-26 23:55:29549 }
550}
551
552void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
553}
554
[email protected]a95631cb2009-12-10 01:59:11555gfx::NativeWindow ExternalTabContainer::GetFrameNativeWindow() {
556 return hwnd();
557}
558
[email protected]1e0a02d62009-04-23 22:55:56559bool ExternalTabContainer::TakeFocus(bool reverse) {
560 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34561 automation_->Send(new AutomationMsg_TabbedOut(tab_handle_,
[email protected]a8e20582010-12-31 17:18:50562 base::win::IsShiftPressed()));
[email protected]1e0a02d62009-04-23 22:55:56563 }
564
565 return true;
566}
567
[email protected]686493142011-07-15 21:47:22568bool ExternalTabContainer::CanDownload(TabContents* source, int request_id) {
569 if (load_requests_via_automation_) {
570 if (automation_) {
571 // In case the host needs to show UI that needs to take the focus.
572 ::AllowSetForegroundWindow(ASFW_ANY);
573
574 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
575 NewRunnableMethod(automation_resource_message_filter_.get(),
576 &AutomationResourceMessageFilter::SendDownloadRequestToHost,
577 0, tab_handle_, request_id));
578 }
579 } else {
580 DLOG(WARNING) << "Downloads are only supported with host browser network "
581 "stack enabled.";
582 }
583
584 // Never allow downloads.
585 return false;
586}
587
[email protected]21e302e2009-09-12 23:10:41588void ExternalTabContainer::ShowPageInfo(Profile* profile,
589 const GURL& url,
590 const NavigationEntry::SSLStatus& ssl,
591 bool show_history) {
[email protected]0b7a012d2010-10-19 23:49:26592 POINT cursor_pos = {0};
593 GetCursorPos(&cursor_pos);
594
595 gfx::Rect bounds;
596 bounds.set_origin(gfx::Point(cursor_pos));
597
598 PageInfoBubbleView* page_info_bubble =
599 new ExternalTabPageInfoBubbleView(this, NULL, profile, url,
600 ssl, show_history);
[email protected]05a3a862011-08-24 19:50:30601 Bubble* bubble = Bubble::Show(GetWidget(), bounds,
602 views::BubbleBorder::TOP_LEFT,
[email protected]cb7f12f2011-04-14 15:10:23603 page_info_bubble, page_info_bubble);
604 page_info_bubble->set_bubble(bubble);
[email protected]21e302e2009-09-12 23:10:41605}
606
[email protected]fd571bb2010-03-19 01:23:54607void ExternalTabContainer::RegisterRenderViewHostForAutomation(
608 RenderViewHost* render_view_host, bool pending_view) {
609 if (render_view_host) {
610 AutomationResourceMessageFilter::RegisterRenderView(
611 render_view_host->process()->id(),
612 render_view_host->routing_id(),
613 tab_handle(),
614 automation_resource_message_filter_,
615 pending_view);
616 }
617}
618
[email protected]fd571bb2010-03-19 01:23:54619void ExternalTabContainer::RegisterRenderViewHost(
620 RenderViewHost* render_view_host) {
621 // RenderViewHost instances that are to be associated with this
622 // ExternalTabContainer should share the same resource request automation
623 // settings.
624 RegisterRenderViewHostForAutomation(
625 render_view_host,
626 false); // Network requests should not be handled later.
627}
628
629void ExternalTabContainer::UnregisterRenderViewHost(
630 RenderViewHost* render_view_host) {
631 // Undo the resource automation registration performed in
632 // ExternalTabContainer::RegisterRenderViewHost.
633 if (render_view_host) {
634 AutomationResourceMessageFilter::UnRegisterRenderView(
635 render_view_host->process()->id(),
636 render_view_host->routing_id());
637 }
638}
639
[email protected]3ab9cb82011-06-03 18:02:07640content::JavaScriptDialogCreator*
641ExternalTabContainer::GetJavaScriptDialogCreator() {
642 return GetJavaScriptDialogCreatorInstance();
643}
644
[email protected]e943d6662009-06-12 03:50:39645bool ExternalTabContainer::HandleContextMenu(const ContextMenuParams& params) {
646 if (!automation_) {
647 NOTREACHED();
648 return false;
649 }
[email protected]e943d6662009-06-12 03:50:39650 external_context_menu_.reset(
[email protected]14831ef2010-05-11 23:51:20651 new RenderViewContextMenuViews(tab_contents(), params));
652 external_context_menu_->SetExternal();
[email protected]e943d6662009-06-12 03:50:39653 external_context_menu_->Init();
[email protected]a5e04ea2010-06-08 13:37:08654 external_context_menu_->UpdateMenuItemStates();
[email protected]e943d6662009-06-12 03:50:39655
[email protected]b516e2d2011-07-12 16:54:12656 scoped_ptr<ContextMenuModel> context_menu_model(
657 ConvertMenuModel(&external_context_menu_->menu_model()));
658
[email protected]e943d6662009-06-12 03:50:39659 POINT screen_pt = { params.x, params.y };
660 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
661
[email protected]f5494d42010-12-23 22:15:34662 MiniContextMenuParams ipc_params(
[email protected]0f1afed2010-12-15 17:22:28663 screen_pt.x,
664 screen_pt.y,
665 params.link_url,
666 params.unfiltered_link_url,
667 params.src_url,
668 params.page_url,
[email protected]747f1c52011-07-01 01:55:49669 params.keyword_url,
[email protected]0f1afed2010-12-15 17:22:28670 params.frame_url);
[email protected]35f13ab2009-12-16 23:59:17671
[email protected]7cf1b6ce2010-03-20 06:37:01672 bool rtl = base::i18n::IsRTL();
[email protected]e943d6662009-06-12 03:50:39673 automation_->Send(
[email protected]f5494d42010-12-23 22:15:34674 new AutomationMsg_ForwardContextMenuToExternalHost(tab_handle_,
[email protected]b516e2d2011-07-12 16:54:12675 *context_menu_model,
[email protected]35f13ab2009-12-16 23:59:17676 rtl ? TPM_RIGHTALIGN : TPM_LEFTALIGN, ipc_params));
[email protected]e943d6662009-06-12 03:50:39677
678 return true;
679}
680
681bool ExternalTabContainer::ExecuteContextMenuCommand(int command) {
682 if (!external_context_menu_.get()) {
683 NOTREACHED();
684 return false;
685 }
686
[email protected]35f13ab2009-12-16 23:59:17687 switch (command) {
688 case IDS_CONTENT_CONTEXT_SAVEAUDIOAS:
689 case IDS_CONTENT_CONTEXT_SAVEVIDEOAS:
690 case IDS_CONTENT_CONTEXT_SAVEIMAGEAS:
691 case IDS_CONTENT_CONTEXT_SAVELINKAS: {
692 NOTREACHED(); // Should be handled in host.
693 break;
694 }
695 }
696
[email protected]e943d6662009-06-12 03:50:39697 external_context_menu_->ExecuteCommand(command);
698 return true;
699}
700
[email protected]867125a02009-12-10 06:01:48701bool ExternalTabContainer::PreHandleKeyboardEvent(
702 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
703 return false;
704}
705
706void ExternalTabContainer::HandleKeyboardEvent(
[email protected]334a105b2009-07-14 03:42:55707 const NativeWebKeyboardEvent& event) {
[email protected]867125a02009-12-10 06:01:48708 ProcessUnhandledKeyStroke(event.os_event.hwnd, event.os_event.message,
709 event.os_event.wParam, event.os_event.lParam);
[email protected]334a105b2009-07-14 03:42:55710}
711
[email protected]d9d8f0c2010-09-17 21:47:16712void ExternalTabContainer::BeforeUnloadFired(TabContents* tab,
713 bool proceed,
714 bool* proceed_to_fire_unload) {
[email protected]d9d8f0c2010-09-17 21:47:16715 *proceed_to_fire_unload = true;
716
717 if (!automation_) {
718 delete unload_reply_message_;
719 unload_reply_message_ = NULL;
720 return;
721 }
722
[email protected]b5e0a192011-03-22 19:15:32723 if (!unload_reply_message_) {
724 NOTREACHED() << "**** NULL unload reply message pointer.";
725 return;
726 }
727
[email protected]d9d8f0c2010-09-17 21:47:16728 if (!proceed) {
729 AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_,
730 false);
731 automation_->Send(unload_reply_message_);
732 unload_reply_message_ = NULL;
733 *proceed_to_fire_unload = false;
734 }
735}
736
[email protected]2fc22d12010-12-02 23:08:16737void ExternalTabContainer::ShowRepostFormWarningDialog(
738 TabContents* tab_contents) {
739 browser::ShowRepostFormWarningDialog(GetNativeView(), tab_contents);
740}
741
[email protected]3a29a6e2011-08-24 18:26:21742void ExternalTabContainer::RunFileChooser(
743 TabContents* tab, const ViewHostMsg_RunFileChooser_Params& params) {
744 Browser::RunFileChooserHelper(tab, params);
745}
746
747void ExternalTabContainer::EnumerateDirectory(TabContents* tab, int request_id,
748 const FilePath& path) {
749 Browser::EnumerateDirectoryHelper(tab, request_id, path);
750}
751
[email protected]7d189022011-08-25 22:54:20752void ExternalTabContainer::JSOutOfMemory(TabContents* tab) {
753 Browser::JSOutOfMemoryHelper(tab);
754}
755
756void ExternalTabContainer::RegisterProtocolHandler(TabContents* tab,
757 const std::string& protocol,
758 const GURL& url,
759 const string16& title) {
760 Browser::RegisterProtocolHandlerHelper(tab, protocol, url, title);
761}
762
763void ExternalTabContainer::RegisterIntentHandler(TabContents* tab,
764 const string16& action,
765 const string16& type,
766 const string16& href,
767 const string16& title) {
768 Browser::RegisterIntentHandlerHelper(tab, action, type, href, title);
769}
770
[email protected]ce9751942011-09-21 01:57:24771void ExternalTabContainer::WebIntentDispatch(
772 TabContents* tab,
773 int routing_id,
774 const webkit_glue::WebIntentData& intent,
775 int intent_id) {
[email protected]828e61af2011-09-14 19:45:06776 // TODO(binji) How do we want to display the WebIntentPicker bubble if there
777 // is no BrowserWindow?
[email protected]7d189022011-08-25 22:54:20778}
779
[email protected]b888919c2011-09-02 00:32:16780void ExternalTabContainer::FindReply(TabContents* tab,
781 int request_id,
782 int number_of_matches,
783 const gfx::Rect& selection_rect,
784 int active_match_ordinal,
785 bool final_update) {
786 Browser::FindReplyHelper(tab, request_id, number_of_matches, selection_rect,
787 active_match_ordinal, final_update);
788}
789
[email protected]d952a052011-09-06 18:42:45790void ExternalTabContainer::CrashedPlugin(TabContents* tab,
791 const FilePath& plugin_path) {
792 Browser::CrashedPluginHelper(tab, plugin_path);
793}
794
[email protected]15b2c6a2011-05-16 23:54:40795bool ExternalTabContainer::OnMessageReceived(const IPC::Message& message) {
796 bool handled = true;
797 IPC_BEGIN_MESSAGE_MAP(ExternalTabContainer, message)
[email protected]2ccf45c2011-08-19 23:35:50798 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ForwardMessageToExternalHost,
[email protected]15b2c6a2011-05-16 23:54:40799 OnForwardMessageToExternalHost)
800 IPC_MESSAGE_UNHANDLED(handled = false)
801 IPC_END_MESSAGE_MAP()
802 return handled;
803}
804
805void ExternalTabContainer::OnForwardMessageToExternalHost(
806 const std::string& message,
807 const std::string& origin,
808 const std::string& target) {
809 if (automation_) {
810 automation_->Send(new AutomationMsg_ForwardMessageToExternalHost(
811 tab_handle_, message, origin, target));
812 }
813}
814
[email protected]9095e982009-05-27 17:28:24815////////////////////////////////////////////////////////////////////////////////
816// ExternalTabContainer, NotificationObserver implementation:
817
[email protected]432115822011-07-10 15:52:27818void ExternalTabContainer::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53819 const content::NotificationSource& source,
820 const content::NotificationDetails& details) {
[email protected]33ee8da2009-04-16 17:45:37821 if (!automation_)
822 return;
823
[email protected]2e39d2e2009-02-19 18:41:31824 static const int kHttpClientErrorStart = 400;
825 static const int kHttpServerErrorEnd = 510;
826
[email protected]432115822011-07-10 15:52:27827 switch (type) {
828 case content::NOTIFICATION_LOAD_STOP: {
[email protected]33ee8da2009-04-16 17:45:37829 const LoadNotificationDetails* load =
[email protected]6c2381d2011-10-19 02:52:53830 content::Details<LoadNotificationDetails>(details).ptr();
[email protected]2905f742011-10-13 03:51:58831 if (load != NULL &&
832 content::PageTransitionIsMainFrame(load->origin())) {
[email protected]366ae242011-05-10 02:23:58833 TRACE_EVENT_END_ETW("ExternalTabContainer::Navigate", 0,
834 load->url().spec());
[email protected]f5494d42010-12-23 22:15:34835 automation_->Send(new AutomationMsg_TabLoaded(tab_handle_,
[email protected]eac83f02009-05-08 18:44:44836 load->url()));
[email protected]33ee8da2009-04-16 17:45:37837 }
838 break;
[email protected]2e39d2e2009-02-19 18:41:31839 }
[email protected]432115822011-07-10 15:52:27840 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
[email protected]33ee8da2009-04-16 17:45:37841 if (ignore_next_load_notification_) {
842 ignore_next_load_notification_ = false;
843 return;
844 }
[email protected]2e39d2e2009-02-19 18:41:31845
[email protected]8286f51a2011-05-31 17:39:13846 const content::LoadCommittedDetails* commit =
[email protected]6c2381d2011-10-19 02:52:53847 content::Details<content::LoadCommittedDetails>(details).ptr();
[email protected]0e8db942008-09-24 21:21:48848
[email protected]f0a51fb52009-03-05 12:46:38849 if (commit->http_status_code >= kHttpClientErrorStart &&
[email protected]2e39d2e2009-02-19 18:41:31850 commit->http_status_code <= kHttpServerErrorEnd) {
851 automation_->Send(new AutomationMsg_NavigationFailed(
[email protected]f5494d42010-12-23 22:15:34852 tab_handle_, commit->http_status_code, commit->entry->url()));
[email protected]2e39d2e2009-02-19 18:41:31853
854 ignore_next_load_notification_ = true;
855 } else {
[email protected]f5494d42010-12-23 22:15:34856 NavigationInfo navigation_info;
[email protected]2e39d2e2009-02-19 18:41:31857 // When the previous entry index is invalid, it will be -1, which
858 // will still make the computation come out right (navigating to the
859 // 0th entry will be +1).
[email protected]6c908bb2009-08-21 19:03:50860 if (InitNavigationInfo(&navigation_info, commit->type,
861 commit->previous_entry_index -
862 tab_contents_->controller().last_committed_entry_index()))
[email protected]f5494d42010-12-23 22:15:34863 automation_->Send(new AutomationMsg_DidNavigate(tab_handle_,
[email protected]6c908bb2009-08-21 19:03:50864 navigation_info));
[email protected]2e39d2e2009-02-19 18:41:31865 }
[email protected]33ee8da2009-04-16 17:45:37866 break;
[email protected]0e8db942008-09-24 21:21:48867 }
[email protected]432115822011-07-10 15:52:27868 case content::NOTIFICATION_FAIL_PROVISIONAL_LOAD_WITH_ERROR: {
[email protected]33ee8da2009-04-16 17:45:37869 const ProvisionalLoadDetails* load_details =
[email protected]6c2381d2011-10-19 02:52:53870 content::Details<ProvisionalLoadDetails>(details).ptr();
[email protected]33ee8da2009-04-16 17:45:37871 automation_->Send(new AutomationMsg_NavigationFailed(
[email protected]f5494d42010-12-23 22:15:34872 tab_handle_, load_details->error_code(), load_details->url()));
[email protected]2e39d2e2009-02-19 18:41:31873
[email protected]33ee8da2009-04-16 17:45:37874 ignore_next_load_notification_ = true;
[email protected]2e39d2e2009-02-19 18:41:31875 break;
876 }
[email protected]432115822011-07-10 15:52:27877 case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB: {
[email protected]2e4633c2009-07-09 16:58:06878 if (load_requests_via_automation_) {
[email protected]6c2381d2011-10-19 02:52:53879 RenderViewHost* rvh = content::Details<RenderViewHost>(details).ptr();
[email protected]fd571bb2010-03-19 01:23:54880 RegisterRenderViewHostForAutomation(rvh, false);
[email protected]2e4633c2009-07-09 16:58:06881 }
882 break;
883 }
[email protected]432115822011-07-10 15:52:27884 case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: {
[email protected]2e4633c2009-07-09 16:58:06885 if (load_requests_via_automation_) {
[email protected]6c2381d2011-10-19 02:52:53886 RenderViewHost* rvh = content::Source<RenderViewHost>(source).ptr();
[email protected]fd571bb2010-03-19 01:23:54887 UnregisterRenderViewHost(rvh);
[email protected]2e4633c2009-07-09 16:58:06888 }
889 break;
890 }
[email protected]0e8db942008-09-24 21:21:48891 default:
892 NOTREACHED();
893 }
initial.commit09911bf2008-07-26 23:55:29894}
895
[email protected]9095e982009-05-27 17:28:24896////////////////////////////////////////////////////////////////////////////////
[email protected]2fc66722011-05-19 14:43:12897// ExternalTabContainer, views::NativeWidgetWin overrides:
[email protected]9095e982009-05-27 17:28:24898
[email protected]632fbb12009-09-06 15:27:14899LRESULT ExternalTabContainer::OnCreate(LPCREATESTRUCT create_struct) {
[email protected]2fc66722011-05-19 14:43:12900 LRESULT result = views::NativeWidgetWin::OnCreate(create_struct);
[email protected]632fbb12009-09-06 15:27:14901 if (result == 0) {
902 // Grab a reference here which will be released in OnFinalMessage
903 AddRef();
904 }
905 return result;
906}
907
[email protected]9095e982009-05-27 17:28:24908void ExternalTabContainer::OnDestroy() {
[email protected]7c9d8292010-11-01 16:57:13909 prop_.reset();
[email protected]632fbb12009-09-06 15:27:14910 Uninitialize();
[email protected]2fc66722011-05-19 14:43:12911 NativeWidgetWin::OnDestroy();
initial.commit09911bf2008-07-26 23:55:29912}
913
[email protected]632fbb12009-09-06 15:27:14914void ExternalTabContainer::OnFinalMessage(HWND window) {
915 // Release the reference which we grabbed in WM_CREATE.
916 Release();
[email protected]334a105b2009-07-14 03:42:55917}
918
[email protected]d9d8f0c2010-09-17 21:47:16919void ExternalTabContainer::RunUnloadHandlers(IPC::Message* reply_message) {
920 if (!automation_) {
921 delete reply_message;
922 return;
[email protected]1f71d5882010-07-15 20:39:07923 }
[email protected]d9d8f0c2010-09-17 21:47:16924
925 // If we have a pending unload message, then just respond back to this
926 // request and continue processing the previous unload message.
927 if (unload_reply_message_) {
928 AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true);
929 automation_->Send(reply_message);
930 return;
931 }
[email protected]b5e0a192011-03-22 19:15:32932
933 unload_reply_message_ = reply_message;
934 bool wait_for_unload_handlers =
935 tab_contents_.get() &&
936 Browser::RunUnloadEventsHelper(tab_contents_->tab_contents());
937 if (!wait_for_unload_handlers) {
[email protected]d9d8f0c2010-09-17 21:47:16938 AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true);
939 automation_->Send(reply_message);
[email protected]b5e0a192011-03-22 19:15:32940 unload_reply_message_ = NULL;
[email protected]1f71d5882010-07-15 20:39:07941 }
942}
943
[email protected]632fbb12009-09-06 15:27:14944////////////////////////////////////////////////////////////////////////////////
945// ExternalTabContainer, private:
[email protected]334a105b2009-07-14 03:42:55946bool ExternalTabContainer::ProcessUnhandledKeyStroke(HWND window,
947 UINT message,
948 WPARAM wparam,
949 LPARAM lparam) {
initial.commit09911bf2008-07-26 23:55:29950 if (!automation_) {
951 return false;
952 }
[email protected]a8e20582010-12-31 17:18:50953 if ((wparam == VK_TAB) && !base::win::IsCtrlPressed()) {
initial.commit09911bf2008-07-26 23:55:29954 // Tabs are handled separately (except if this is Ctrl-Tab or
955 // Ctrl-Shift-Tab)
956 return false;
957 }
[email protected]060254c2009-05-02 16:45:27958
[email protected]01dba672010-02-12 21:55:48959 // Send this keystroke to the external host as it could be processed as an
960 // accelerator there. If the host does not handle this accelerator, it will
961 // reflect the accelerator back to us via the ProcessUnhandledAccelerator
962 // method.
963 MSG msg = {0};
964 msg.hwnd = window;
965 msg.message = message;
966 msg.wParam = wparam;
967 msg.lParam = lparam;
[email protected]f5494d42010-12-23 22:15:34968 automation_->Send(new AutomationMsg_HandleAccelerator(tab_handle_, msg));
[email protected]01dba672010-02-12 21:55:48969 return true;
initial.commit09911bf2008-07-26 23:55:29970}
[email protected]4150ef02009-08-19 23:14:26971
[email protected]f5494d42010-12-23 22:15:34972bool ExternalTabContainer::InitNavigationInfo(NavigationInfo* nav_info,
[email protected]610cbb82011-10-18 16:35:08973 content::NavigationType nav_type,
[email protected]4150ef02009-08-19 23:14:26974 int relative_offset) {
[email protected]4150ef02009-08-19 23:14:26975 DCHECK(nav_info);
[email protected]6c908bb2009-08-21 19:03:50976 NavigationEntry* entry = tab_contents_->controller().GetActiveEntry();
977 // If this is very early in the game then we may not have an entry.
978 if (!entry)
979 return false;
[email protected]4150ef02009-08-19 23:14:26980
981 nav_info->navigation_type = nav_type;
982 nav_info->relative_offset = relative_offset;
983 nav_info->navigation_index =
984 tab_contents_->controller().GetCurrentEntryIndex();
[email protected]4150ef02009-08-19 23:14:26985 nav_info->url = entry->url();
[email protected]a1955adf2010-08-02 17:59:39986 nav_info->referrer = entry->referrer();
[email protected]6b2f7a82011-04-25 19:30:51987 nav_info->title = UTF16ToWideHack(entry->title());
[email protected]24f98bba2009-10-14 18:47:49988 if (nav_info->title.empty())
989 nav_info->title = UTF8ToWide(nav_info->url.spec());
990
[email protected]f5cde2b2009-09-11 22:33:58991 nav_info->security_style = entry->ssl().security_style();
[email protected]b4e75c12010-05-18 18:28:48992 nav_info->displayed_insecure_content =
993 entry->ssl().displayed_insecure_content();
994 nav_info->ran_insecure_content = entry->ssl().ran_insecure_content();
[email protected]6c908bb2009-08-21 19:03:50995 return true;
[email protected]4150ef02009-08-19 23:14:26996}
997
[email protected]cd0dec62010-02-11 02:33:18998scoped_refptr<ExternalTabContainer> ExternalTabContainer::RemovePendingTab(
[email protected]b1c55638612010-03-08 16:26:11999 uintptr_t cookie) {
[email protected]d0ed50d2010-06-22 01:01:321000 ExternalTabContainer::PendingTabs& pending_tabs = pending_tabs_.Get();
1001 PendingTabs::iterator index = pending_tabs.find(cookie);
1002 if (index != pending_tabs.end()) {
[email protected]632fbb12009-09-06 15:27:141003 scoped_refptr<ExternalTabContainer> container = (*index).second;
[email protected]d0ed50d2010-06-22 01:01:321004 pending_tabs.erase(index);
[email protected]cd0dec62010-02-11 02:33:181005 return container;
[email protected]632fbb12009-09-06 15:27:141006 }
1007
1008 NOTREACHED() << "Failed to find ExternalTabContainer for cookie: "
1009 << cookie;
1010 return NULL;
1011}
1012
[email protected]9ac174e92011-04-16 00:58:561013SkColor ExternalTabContainer::GetInfoBarSeparatorColor() const {
1014 return ResourceBundle::toolbar_separator_color;
1015}
1016
[email protected]4f2d40d2011-05-05 01:33:301017void ExternalTabContainer::InfoBarContainerStateChanged(bool is_animating) {
[email protected]f4f50ef2011-01-21 19:01:191018 if (external_tab_view_)
[email protected]ba67fd82010-07-09 18:30:311019 external_tab_view_->Layout();
[email protected]ab861b42010-02-05 19:13:441020}
1021
[email protected]ee120872011-04-15 01:37:061022bool ExternalTabContainer::DrawInfoBarArrows(int* x) const {
1023 return false;
1024}
1025
[email protected]3f70c1e12010-01-12 20:38:491026bool ExternalTabContainer::AcceleratorPressed(
1027 const views::Accelerator& accelerator) {
1028 std::map<views::Accelerator, int>::const_iterator iter =
1029 accelerator_table_.find(accelerator);
1030 DCHECK(iter != accelerator_table_.end());
1031
[email protected]7b8d4a22011-02-10 20:57:541032 if (!tab_contents_.get() || !tab_contents_->render_view_host()) {
[email protected]3f70c1e12010-01-12 20:38:491033 NOTREACHED();
1034 return false;
1035 }
1036
[email protected]216813952011-05-19 22:21:261037 RenderViewHost* host = tab_contents_->render_view_host();
[email protected]3f70c1e12010-01-12 20:38:491038 int command_id = iter->second;
1039 switch (command_id) {
1040 case IDC_ZOOM_PLUS:
[email protected]6a64e8a2011-09-19 22:59:571041 host->Zoom(PageZoom::ZOOM_IN);
[email protected]3f70c1e12010-01-12 20:38:491042 break;
1043 case IDC_ZOOM_NORMAL:
[email protected]6a64e8a2011-09-19 22:59:571044 host->Zoom(PageZoom::RESET);
[email protected]3f70c1e12010-01-12 20:38:491045 break;
1046 case IDC_ZOOM_MINUS:
[email protected]6a64e8a2011-09-19 22:59:571047 host->Zoom(PageZoom::ZOOM_OUT);
[email protected]3f70c1e12010-01-12 20:38:491048 break;
1049 case IDC_DEV_TOOLS:
[email protected]aebdd072011-07-07 12:36:591050 DevToolsWindow::ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:481051 tab_contents_->render_view_host(), DEVTOOLS_TOGGLE_ACTION_NONE);
[email protected]3f70c1e12010-01-12 20:38:491052 break;
1053 case IDC_DEV_TOOLS_CONSOLE:
[email protected]aebdd072011-07-07 12:36:591054 DevToolsWindow::ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:481055 tab_contents_->render_view_host(),
1056 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
1057 break;
1058 case IDC_DEV_TOOLS_INSPECT:
[email protected]aebdd072011-07-07 12:36:591059 DevToolsWindow::ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:481060 tab_contents_->render_view_host(),
1061 DEVTOOLS_TOGGLE_ACTION_INSPECT);
[email protected]3f70c1e12010-01-12 20:38:491062 break;
1063 default:
1064 NOTREACHED() << "Unsupported accelerator: " << command_id;
1065 return false;
1066 }
1067 return true;
1068}
1069
[email protected]f5cde2b2009-09-11 22:33:581070void ExternalTabContainer::Navigate(const GURL& url, const GURL& referrer) {
[email protected]7b8d4a22011-02-10 20:57:541071 if (!tab_contents_.get()) {
[email protected]f5cde2b2009-09-11 22:33:581072 NOTREACHED();
1073 return;
1074 }
1075
[email protected]366ae242011-05-10 02:23:581076 TRACE_EVENT_BEGIN_ETW("ExternalTabContainer::Navigate", 0, url.spec());
[email protected]a872ea1f2010-08-11 04:45:331077
[email protected]f5cde2b2009-09-11 22:33:581078 tab_contents_->controller().LoadURL(url, referrer,
[email protected]2905f742011-10-13 03:51:581079 content::PAGE_TRANSITION_START_PAGE,
[email protected]79046fd2011-09-10 05:48:331080 std::string());
[email protected]f5cde2b2009-09-11 22:33:581081}
[email protected]f9cc4c452009-10-13 14:56:381082
1083bool ExternalTabContainer::OnGoToEntryOffset(int offset) {
1084 if (load_requests_via_automation_) {
1085 automation_->Send(new AutomationMsg_RequestGoToHistoryEntryOffset(
[email protected]f5494d42010-12-23 22:15:341086 tab_handle_, offset));
[email protected]f9cc4c452009-10-13 14:56:381087 return false;
1088 }
1089
1090 return true;
1091}
[email protected]1a98a932009-11-17 00:12:521092
[email protected]3f70c1e12010-01-12 20:38:491093void ExternalTabContainer::LoadAccelerators() {
1094 HACCEL accelerator_table = AtlLoadAccelerators(IDR_CHROMEFRAME);
1095 DCHECK(accelerator_table);
1096
1097 // We have to copy the table to access its contents.
1098 int count = CopyAcceleratorTable(accelerator_table, 0, 0);
1099 if (count == 0) {
1100 // Nothing to do in that case.
1101 return;
1102 }
1103
[email protected]1f1e7cb2011-10-07 22:55:471104 scoped_array<ACCEL> scoped_accelerators(new ACCEL[count]);
[email protected]3f70c1e12010-01-12 20:38:491105 ACCEL* accelerators = scoped_accelerators.get();
1106 DCHECK(accelerators != NULL);
1107
1108 CopyAcceleratorTable(accelerator_table, accelerators, count);
1109
[email protected]9a56a0d2011-05-13 19:03:311110 focus_manager_ = GetWidget()->GetFocusManager();
[email protected]93685472010-04-23 00:57:501111 DCHECK(focus_manager_);
[email protected]3f70c1e12010-01-12 20:38:491112
1113 // Let's fill our own accelerator table.
1114 for (int i = 0; i < count; ++i) {
1115 bool alt_down = (accelerators[i].fVirt & FALT) == FALT;
1116 bool ctrl_down = (accelerators[i].fVirt & FCONTROL) == FCONTROL;
1117 bool shift_down = (accelerators[i].fVirt & FSHIFT) == FSHIFT;
1118 views::Accelerator accelerator(
[email protected]b6d81262011-01-13 17:36:091119 static_cast<ui::KeyboardCode>(accelerators[i].key),
[email protected]3f70c1e12010-01-12 20:38:491120 shift_down, ctrl_down, alt_down);
1121 accelerator_table_[accelerator] = accelerators[i].cmd;
1122
1123 // Also register with the focus manager.
[email protected]93685472010-04-23 00:57:501124 if (focus_manager_)
1125 focus_manager_->RegisterAccelerator(accelerator, this);
[email protected]3f70c1e12010-01-12 20:38:491126 }
1127}
[email protected]18290eb2010-01-30 00:47:061128
1129void ExternalTabContainer::OnReinitialize() {
[email protected]6c2e45b2010-05-07 00:55:251130 if (load_requests_via_automation_) {
[email protected]6c2e45b2010-05-07 00:55:251131 RenderViewHost* rvh = tab_contents_->render_view_host();
1132 if (rvh) {
1133 AutomationResourceMessageFilter::ResumePendingRenderView(
1134 rvh->process()->id(), rvh->routing_id(),
1135 tab_handle_, automation_resource_message_filter_);
1136 }
1137 }
1138
[email protected]7b8d4a22011-02-10 20:57:541139 NavigationStateChanged(tab_contents(), 0);
[email protected]18290eb2010-01-30 00:47:061140 ServicePendingOpenURLRequests();
1141}
1142
1143void ExternalTabContainer::ServicePendingOpenURLRequests() {
1144 DCHECK(pending());
1145
1146 set_pending(false);
1147
1148 for (size_t index = 0; index < pending_open_url_requests_.size();
[email protected]7b8d4a22011-02-10 20:57:541149 ++index) {
[email protected]00c37fc2011-08-02 00:22:501150 const OpenURLParams& url_request = pending_open_url_requests_[index];
1151 OpenURLFromTab(tab_contents(), url_request);
[email protected]18290eb2010-01-30 00:47:061152 }
1153 pending_open_url_requests_.clear();
1154}
1155
[email protected]ab861b42010-02-05 19:13:441156void ExternalTabContainer::SetupExternalTabView() {
1157 // Create a TabContentsContainer to handle focus cycling using Tab and
1158 // Shift-Tab.
1159 tab_contents_container_ = new TabContentsContainer;
1160
1161 // The views created here will be destroyed when the ExternalTabContainer
1162 // widget is torn down.
[email protected]ba67fd82010-07-09 18:30:311163 external_tab_view_ = new views::View();
[email protected]ab861b42010-02-05 19:13:441164
[email protected]6c6614f12011-03-31 18:51:421165 InfoBarContainerView* info_bar_container = new InfoBarContainerView(this);
[email protected]95a33ed62011-09-30 15:07:081166 info_bar_container->ChangeTabContents(tab_contents_->infobar_tab_helper());
[email protected]ab861b42010-02-05 19:13:441167
[email protected]ba67fd82010-07-09 18:30:311168 views::GridLayout* layout = new views::GridLayout(external_tab_view_);
1169 // Give this column an identifier of 0.
1170 views::ColumnSet* columns = layout->AddColumnSet(0);
[email protected]ab861b42010-02-05 19:13:441171 columns->AddColumn(views::GridLayout::FILL,
1172 views::GridLayout::FILL,
1173 1,
1174 views::GridLayout::USE_PREF,
1175 0,
1176 0);
1177
[email protected]ba67fd82010-07-09 18:30:311178 external_tab_view_->SetLayoutManager(layout);
[email protected]ab861b42010-02-05 19:13:441179
1180 layout->StartRow(0, 0);
1181 layout->AddView(info_bar_container);
1182 layout->StartRow(1, 0);
1183 layout->AddView(tab_contents_container_);
[email protected]9a56a0d2011-05-13 19:03:311184 GetWidget()->SetContentsView(external_tab_view_);
[email protected]ab861b42010-02-05 19:13:441185 // Note that SetTabContents must be called after AddChildView is called
[email protected]7b8d4a22011-02-10 20:57:541186 tab_contents_container_->ChangeTabContents(tab_contents());
[email protected]ab861b42010-02-05 19:13:441187}
[email protected]9eeb35e2010-09-30 21:38:501188
1189TemporaryPopupExternalTabContainer::TemporaryPopupExternalTabContainer(
1190 AutomationProvider* automation,
1191 AutomationResourceMessageFilter* filter)
1192 : ExternalTabContainer(automation, filter) {
1193}
1194
1195TemporaryPopupExternalTabContainer::~TemporaryPopupExternalTabContainer() {
[email protected]8e96e502010-10-21 20:57:121196 DVLOG(1) << __FUNCTION__;
[email protected]9eeb35e2010-09-30 21:38:501197}
1198
[email protected]992e4542011-07-20 23:09:251199TabContents* TemporaryPopupExternalTabContainer::OpenURLFromTab(
[email protected]9eeb35e2010-09-30 21:38:501200 TabContents* source, const GURL& url, const GURL& referrer,
[email protected]2905f742011-10-13 03:51:581201 WindowOpenDisposition disposition, content::PageTransition transition) {
[email protected]00c37fc2011-08-02 00:22:501202 return OpenURLFromTab(source,
[email protected]e47ae9472011-10-13 19:48:341203 OpenURLParams(url, referrer, disposition, transition,
1204 false));
[email protected]00c37fc2011-08-02 00:22:501205}
1206
1207TabContents* TemporaryPopupExternalTabContainer::OpenURLFromTab(
1208 TabContents* source,
1209 const OpenURLParams& params) {
[email protected]9eeb35e2010-09-30 21:38:501210 if (!automation_)
[email protected]992e4542011-07-20 23:09:251211 return NULL;
[email protected]9eeb35e2010-09-30 21:38:501212
[email protected]00c37fc2011-08-02 00:22:501213 OpenURLParams forward_params = params;
1214 if (params.disposition == CURRENT_TAB) {
[email protected]9eeb35e2010-09-30 21:38:501215 DCHECK(route_all_top_level_navigations_);
[email protected]00c37fc2011-08-02 00:22:501216 forward_params.disposition = NEW_FOREGROUND_TAB;
[email protected]9eeb35e2010-09-30 21:38:501217 }
[email protected]992e4542011-07-20 23:09:251218 TabContents* new_contents =
[email protected]00c37fc2011-08-02 00:22:501219 ExternalTabContainer::OpenURLFromTab(source, forward_params);
[email protected]9eeb35e2010-09-30 21:38:501220 // support only one navigation for a dummy tab before it is killed.
1221 ::DestroyWindow(GetNativeView());
[email protected]992e4542011-07-20 23:09:251222 return new_contents;
[email protected]9eeb35e2010-09-30 21:38:501223}