summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_host.cc32
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc6
-rw-r--r--chrome/browser/extensions/extensions_ui.cc20
-rw-r--r--chrome/browser/notifications/balloon_host.cc18
-rw-r--r--chrome/browser/notifications/balloon_host.h5
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc4
-rw-r--r--chrome/browser/renderer_host/render_view_host.h6
-rw-r--r--chrome/browser/tab_contents/background_contents.cc192
-rw-r--r--chrome/browser/tab_contents/background_contents.h126
-rw-r--r--chrome/browser/tab_contents/render_view_host_delegate_helper.cc58
-rw-r--r--chrome/browser/tab_contents/render_view_host_delegate_helper.h35
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc2
-rw-r--r--chrome/browser/tab_contents/tab_contents_view.cc5
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/common/extensions/extension.cc2
-rw-r--r--chrome/common/extensions/extension.h1
-rw-r--r--chrome/common/extensions/extension_constants.h4
-rw-r--r--chrome/common/notification_type.h10
-rw-r--r--chrome/common/render_messages_internal.h8
-rw-r--r--chrome/common/view_types.h1
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc10
-rw-r--r--chrome/renderer/render_view.cc14
-rw-r--r--chrome/renderer/render_view.h6
23 files changed, 494 insertions, 73 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index e62f6bb..3921aa6 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/dom_ui/dom_ui_factory.h"
#include "chrome/browser/extensions/extension_message_service.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
+#include "chrome/browser/extensions/extension_tabs_module_constants.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/in_process_webkit/dom_storage_context.h"
#include "chrome/browser/in_process_webkit/webkit_context.h"
@@ -38,6 +39,7 @@
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/common/bindings_policy.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/view_types.h"
@@ -298,11 +300,8 @@ void ExtensionHost::RenderViewGone(RenderViewHost* render_view_host) {
void ExtensionHost::DidNavigate(RenderViewHost* render_view_host,
const ViewHostMsg_FrameNavigate_Params& params) {
// We only care when the outer frame changes.
- switch (params.transition) {
- case PageTransition::AUTO_SUBFRAME:
- case PageTransition::MANUAL_SUBFRAME:
- return;
- }
+ if (!PageTransition::IsMainFrame(params.transition))
+ return;
if (!params.url.SchemeIs(chrome::kExtensionScheme)) {
extension_function_dispatcher_.reset(NULL);
@@ -516,9 +515,14 @@ RendererPreferences ExtensionHost::GetRendererPrefs(Profile* profile) const {
WebPreferences ExtensionHost::GetWebkitPrefs() {
Profile* profile = render_view_host()->process()->profile();
- const bool kIsDomUI = true;
WebPreferences webkit_prefs =
- RenderViewHostDelegateHelper::GetWebkitPrefs(profile, kIsDomUI);
+ RenderViewHostDelegateHelper::GetWebkitPrefs(profile,
+ false); // is_dom_ui
+ // Extensions are trusted so we override any user preferences for disabling
+ // javascript or images.
+ webkit_prefs.loads_images_automatically = true;
+ webkit_prefs.javascript_enabled = true;
+
if (extension_host_type_ == ViewType::EXTENSION_POPUP ||
extension_host_type_ == ViewType::EXTENSION_INFOBAR)
webkit_prefs.allow_scripts_to_close_windows = true;
@@ -551,8 +555,11 @@ void ExtensionHost::CreateNewWindow(
int route_id,
WindowContainerType window_container_type) {
delegate_view_helper_.CreateNewWindow(
- route_id, render_view_host()->process()->profile(),
- site_instance(), DOMUIFactory::GetDOMUIType(url_), NULL,
+ route_id,
+ render_view_host()->process()->profile(),
+ site_instance(),
+ DOMUIFactory::GetDOMUIType(url_),
+ this,
window_container_type);
}
@@ -580,10 +587,7 @@ void ExtensionHost::ShowCreatedWindow(int route_id,
if (!browser)
return;
- // TODO(aa): It seems like this means popup windows don't work via
- // window.open() from ExtensionHost?
- browser->AddTabContents(contents, disposition, initial_pos,
- user_gesture);
+ browser->AddTabContents(contents, disposition, initial_pos, user_gesture);
}
void ExtensionHost::ShowCreatedWidget(int route_id,
@@ -713,7 +717,7 @@ void ExtensionHost::RenderViewCreated(RenderViewHost* render_view_host) {
int ExtensionHost::GetBrowserWindowID() const {
// Hosts not attached to any browser window have an id of -1. This includes
// those mentioned below, and background pages.
- int window_id = -1;
+ int window_id = extension_misc::kUnknownWindowId;
if (extension_host_type_ == ViewType::EXTENSION_TOOLSTRIP ||
extension_host_type_ == ViewType::EXTENSION_MOLE ||
extension_host_type_ == ViewType::EXTENSION_POPUP ||
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index ffaaf75..c06e931 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -289,15 +289,13 @@ void ExtensionProcessManager::Observe(NotificationType type,
// Close background hosts when the last browser is closed so that they
// have time to shutdown various objects on different threads. Our
// destructor is called too late in the shutdown sequence.
- bool app_closing_non_mac = *Details<bool>(details).ptr();
- if (app_closing_non_mac)
+ bool app_closing = *Details<bool>(details).ptr();
+ if (app_closing)
CloseBackgroundHosts();
break;
}
#elif defined(OS_MACOSX)
case NotificationType::APP_TERMINATING: {
- // Don't follow the behavior of having the last browser window closed
- // being an indication that the app should close.
CloseBackgroundHosts();
break;
}
diff --git a/chrome/browser/extensions/extensions_ui.cc b/chrome/browser/extensions/extensions_ui.cc
index 32b4976..fda3849 100644
--- a/chrome/browser/extensions/extensions_ui.cc
+++ b/chrome/browser/extensions/extensions_ui.cc
@@ -374,10 +374,16 @@ void ExtensionsDOMHandler::OnIconsLoaded(DictionaryValue* json) {
NotificationService::AllSources());
registrar_.Add(this,
NotificationType::NAV_ENTRY_COMMITTED,
- NotificationService::AllSources());
+ NotificationService::AllSources());
registrar_.Add(this,
NotificationType::RENDER_VIEW_HOST_DELETED,
- NotificationService::AllSources());
+ NotificationService::AllSources());
+ registrar_.Add(this,
+ NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
+ NotificationService::AllSources());
+ registrar_.Add(this,
+ NotificationType::BACKGROUND_CONTENTS_DELETED,
+ NotificationService::AllSources());
}
ExtensionResource ExtensionsDOMHandler::PickExtensionIcon(
@@ -692,7 +698,8 @@ void ExtensionsDOMHandler::Observe(NotificationType type,
//
// Doing it this way gets everything but causes the page to be rendered
// more than we need. It doesn't seem to result in any noticeable flicker.
- case NotificationType::RENDER_VIEW_HOST_DELETED:
+ case NotificationType::RENDER_VIEW_HOST_DELETED:
+ case NotificationType::BACKGROUND_CONTENTS_DELETED:
deleting_rvh_ = Details<RenderViewHost>(details).ptr();
case NotificationType::EXTENSION_LOADED:
case NotificationType::EXTENSION_PROCESS_CREATED:
@@ -702,11 +709,12 @@ void ExtensionsDOMHandler::Observe(NotificationType type,
case NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED:
case NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED:
case NotificationType::NAV_ENTRY_COMMITTED:
+ case NotificationType::BACKGROUND_CONTENTS_NAVIGATED:
if (!ignore_notifications_ && dom_ui_->tab_contents())
HandleRequestExtensionsData(NULL);
- deleting_rvh_ = NULL;
+ deleting_rvh_ = NULL;
break;
-
+
default:
NOTREACHED();
}
@@ -840,7 +848,7 @@ std::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension(
if (host == deleting_rvh_ ||
ViewType::EXTENSION_POPUP == host->delegate()->GetRenderViewType())
continue;
-
+
GURL url = host->delegate()->GetURL();
if (url.SchemeIs(chrome::kExtensionScheme)) {
if (url.host() != extension->id())
diff --git a/chrome/browser/notifications/balloon_host.cc b/chrome/browser/notifications/balloon_host.cc
index da819b0..9ac6455 100644
--- a/chrome/browser/notifications/balloon_host.cc
+++ b/chrome/browser/notifications/balloon_host.cc
@@ -88,8 +88,11 @@ void BalloonHost::CreateNewWindow(
int route_id,
WindowContainerType window_container_type) {
delegate_view_helper_.CreateNewWindow(
- route_id, balloon_->profile(), site_instance_.get(),
- DOMUIFactory::GetDOMUIType(balloon_->notification().content_url()), NULL,
+ route_id,
+ balloon_->profile(),
+ site_instance_.get(),
+ DOMUIFactory::GetDOMUIType(balloon_->notification().content_url()),
+ this,
window_container_type);
}
@@ -102,10 +105,13 @@ void BalloonHost::ShowCreatedWindow(int route_id,
return;
TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id);
- if (contents) {
- Browser* browser = BrowserList::GetLastActive();
- browser->AddTabContents(contents, disposition, initial_pos, user_gesture);
- }
+ if (!contents)
+ return;
+ Browser* browser = BrowserList::GetLastActiveWithProfile(balloon_->profile());
+ if (!browser)
+ return;
+
+ browser->AddTabContents(contents, disposition, initial_pos, user_gesture);
}
void BalloonHost::UpdatePreferredSize(const gfx::Size& new_size) {
diff --git a/chrome/browser/notifications/balloon_host.h b/chrome/browser/notifications/balloon_host.h
index 4aabe39..4e7a77c 100644
--- a/chrome/browser/notifications/balloon_host.h
+++ b/chrome/browser/notifications/balloon_host.h
@@ -13,6 +13,7 @@
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/site_instance.h"
#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
+#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/renderer_preferences.h"
#include "webkit/glue/webpreferences.h"
@@ -63,7 +64,9 @@ class BalloonHost : public RenderViewHostDelegate,
virtual void RenderViewGone(RenderViewHost* render_view_host);
virtual void UpdateTitle(RenderViewHost* render_view_host,
int32 page_id, const std::wstring& title) {}
- virtual int GetBrowserWindowID() const { return -1; }
+ virtual int GetBrowserWindowID() const {
+ return extension_misc::kUnknownWindowId;
+ }
virtual ViewType::Type GetRenderViewType() const {
return ViewType::NOTIFICATION;
}
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index c592b81..2dc570e 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -1263,8 +1263,8 @@ void RenderViewHost::DisassociateFromPopupCount() {
Send(new ViewMsg_DisassociateFromPopupCount(routing_id()));
}
-void RenderViewHost::PopupNotificationVisibilityChanged(bool visible) {
- Send(new ViewMsg_PopupNotificationVisibilityChanged(routing_id(), visible));
+void RenderViewHost::AllowScriptToClose(bool script_can_close) {
+ Send(new ViewMsg_AllowScriptToClose(routing_id(), script_can_close));
}
void RenderViewHost::OnMsgGoToEntryAtOffset(int offset) {
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 84dec34..0fffedd 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -376,9 +376,9 @@ class RenderViewHost : public RenderWidgetHost {
// as a popup.
void DisassociateFromPopupCount();
- // Notifies the Renderer that we've either displayed or hidden the popup
- // notification.
- void PopupNotificationVisibilityChanged(bool visible);
+ // Tells the renderer whether it should allow window.close. This is initially
+ // set to false when creating a renderer-initiated window via window.open.
+ void AllowScriptToClose(bool visible);
// Called by the AutoFillManager when the list of suggestions is ready.
void AutoFillSuggestionsReturned(
diff --git a/chrome/browser/tab_contents/background_contents.cc b/chrome/browser/tab_contents/background_contents.cc
new file mode 100644
index 0000000..c61802d
--- /dev/null
+++ b/chrome/browser/tab_contents/background_contents.cc
@@ -0,0 +1,192 @@
+// 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.
+
+#include "chrome/browser/tab_contents/background_contents.h"
+
+#include "chrome/browser/browser.h"
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/browsing_instance.h"
+#include "chrome/browser/in_process_webkit/dom_storage_context.h"
+#include "chrome/browser/in_process_webkit/webkit_context.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/renderer_host/site_instance.h"
+#include "chrome/browser/renderer_preferences_util.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/view_types.h"
+#include "chrome/common/render_messages.h"
+
+
+////////////////
+// BackgroundContents
+
+BackgroundContents::BackgroundContents(SiteInstance* site_instance,
+ int routing_id) {
+ Profile* profile = site_instance->browsing_instance()->profile();
+
+ // TODO(rafaelw): Implement correct session storage.
+ int64 session_storage_namespace_id = profile->GetWebKitContext()->
+ dom_storage_context()->AllocateSessionStorageNamespaceId();
+ render_view_host_ = new RenderViewHost(site_instance, this, routing_id,
+ session_storage_namespace_id);
+ render_view_host_->AllowScriptToClose(true);
+
+#if defined(OS_WIN) || defined(OS_LINUX)
+ registrar_.Add(this, NotificationType::BROWSER_CLOSED,
+ NotificationService::AllSources());
+#elif defined(OS_MACOSX)
+ registrar_.Add(this, NotificationType::APP_TERMINATING,
+ NotificationService::AllSources());
+#endif
+}
+
+void BackgroundContents::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ // TODO(rafaelw): Implement pagegroup ref-counting so that non-persistent
+ // background pages are closed when the last referencing frame is closed.
+ switch (type.value) {
+#if defined(OS_WIN) || defined(OS_LINUX)
+ case NotificationType::BROWSER_CLOSED: {
+ bool app_closing = *Details<bool>(details).ptr();
+ if (app_closing)
+ delete this;
+ break;
+ }
+#elif defined(OS_MACOSX)
+ case NotificationType::APP_TERMINATING: {
+ delete this;
+ break;
+ }
+#endif
+ default:
+ NOTREACHED() << "Unexpected notification sent.";
+ break;
+ }
+}
+
+BackgroundContents::~BackgroundContents() {
+ NotificationService::current()->Notify(
+ NotificationType::BACKGROUND_CONTENTS_DELETED,
+ Source<BackgroundContents>(this),
+ Details<RenderViewHost>(render_view_host_));
+ render_view_host_->Shutdown(); // deletes render_view_host
+}
+
+void BackgroundContents::DidNavigate(
+ RenderViewHost* render_view_host,
+ const ViewHostMsg_FrameNavigate_Params& params) {
+ // We only care when the outer frame changes.
+ if (!PageTransition::IsMainFrame(params.transition))
+ return;
+
+ // Note: because BackgroundContents are only available to extension apps,
+ // navigation is limited to urls within the app's extent. This is enforced in
+ // RenderView::decidePolicyForNaviation. If BackgroundContents become
+ // available as a part of the web platform, it probably makes sense to have
+ // some way to scope navigation of a background page to its opener's security
+ // origin. Note: if the first navigation is to a URL outside the app's
+ // extent a background page will be opened but will remain at about:blank.
+ url_ = params.url;
+
+ NotificationService::current()->Notify(
+ NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
+ Source<BackgroundContents>(this),
+ Details<RenderViewHost>(render_view_host_));
+}
+
+void BackgroundContents::RunJavaScriptMessage(
+ const std::wstring& message,
+ const std::wstring& default_prompt,
+ const GURL& frame_url,
+ const int flags,
+ IPC::Message* reply_msg,
+ bool* did_suppress_message) {
+ // TODO(rafaelw): Implement, The JavaScriptModalDialog needs to learn about
+ // BackgroundContents.
+ *did_suppress_message = true;
+}
+
+std::wstring BackgroundContents::GetMessageBoxTitle(const GURL& frame_url,
+ bool is_alert) {
+ NOTIMPLEMENTED();
+ return L"";
+}
+
+gfx::NativeWindow BackgroundContents::GetMessageBoxRootWindow() {
+ NOTIMPLEMENTED();
+ return NULL;
+}
+
+void BackgroundContents::OnMessageBoxClosed(IPC::Message* reply_msg,
+ bool success,
+ const std::wstring& prompt) {
+ render_view_host_->JavaScriptMessageBoxClosed(reply_msg, success, prompt);
+}
+
+void BackgroundContents::Close(RenderViewHost* render_view_host) {
+ delete this;
+}
+
+RendererPreferences BackgroundContents::GetRendererPrefs(
+ Profile* profile) const {
+ RendererPreferences preferences;
+ renderer_preferences_util::UpdateFromSystemSettings(&preferences, profile);
+ return preferences;
+}
+
+WebPreferences BackgroundContents::GetWebkitPrefs() {
+ // TODO(rafaelw): Consider enabling the webkit_prefs.dom_paste_enabled for
+ // apps.
+ Profile* profile = render_view_host_->process()->profile();
+ return RenderViewHostDelegateHelper::GetWebkitPrefs(profile,
+ false); // is_dom_ui
+}
+
+void BackgroundContents::ProcessDOMUIMessage(const std::string& message,
+ const Value* content,
+ const GURL& source_url,
+ int request_id,
+ bool has_callback) {
+ // TODO(rafaelw): It may make sense for extensions to be able to open
+ // BackgroundContents to chrome-extension://<id> pages. Consider implementing.
+ render_view_host_->BlockExtensionRequest(request_id);
+}
+
+void BackgroundContents::CreateNewWindow(
+ int route_id,
+ WindowContainerType window_container_type) {
+ delegate_view_helper_.CreateNewWindow(route_id,
+ render_view_host_->process()->profile(),
+ render_view_host_->site_instance(),
+ DOMUIFactory::GetDOMUIType(url_),
+ this,
+ window_container_type);
+}
+
+void BackgroundContents::CreateNewWidget(int route_id,
+ WebKit::WebPopupType popup_type) {
+ NOTREACHED();
+}
+
+void BackgroundContents::ShowCreatedWindow(int route_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture) {
+ TabContents* contents = delegate_view_helper_.GetCreatedWindow(route_id);
+ if (!contents)
+ return;
+ Browser* browser = BrowserList::GetLastActiveWithProfile(
+ render_view_host_->process()->profile());
+ if (!browser)
+ return;
+
+ browser->AddTabContents(contents, disposition, initial_pos, user_gesture);
+}
+
+void BackgroundContents::ShowCreatedWidget(int route_id,
+ const gfx::Rect& initial_pos) {
+ NOTIMPLEMENTED();
+}
+
diff --git a/chrome/browser/tab_contents/background_contents.h b/chrome/browser/tab_contents/background_contents.h
new file mode 100644
index 0000000..348b28a
--- /dev/null
+++ b/chrome/browser/tab_contents/background_contents.h
@@ -0,0 +1,126 @@
+// 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.
+
+#ifndef CHROME_BROWSER_TAB_CONTENTS_BACKGROUND_CONTENTS_H_
+#define CHROME_BROWSER_TAB_CONTENTS_BACKGROUND_CONTENTS_H_
+
+#include <string>
+
+#include "chrome/browser/jsmessage_box_client.h"
+#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+#include "chrome/browser/tab_contents/render_view_host_delegate_helper.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/view_types.h"
+#include "chrome/common/window_container_type.h"
+
+class RenderWidgetHost;
+class RenderWidgetHostView;
+class TabContents;
+struct WebPreferences;
+
+// This class is a peer of TabContents. It can host a renderer, but does not
+// have any visible display. Its navigation is not managed by a
+// NavigationController because is has no facility for navigating (other than
+// programatically view window.location.href) or RenderViewHostManager because
+// it is never allowed to navigate across a SiteInstance boundary.
+class BackgroundContents : public RenderViewHostDelegate,
+ public RenderViewHostDelegate::View,
+ public NotificationObserver,
+ public JavaScriptMessageBoxClient {
+ public:
+ BackgroundContents(SiteInstance* site_instance,
+ int routing_id);
+ ~BackgroundContents();
+
+ // Provide access to the RenderViewHost for the
+ // RenderViewHostDelegateViewHelper
+ RenderViewHost* render_view_host() { return render_view_host_; }
+
+ // RenderViewHostDelegate implementation.
+ virtual RenderViewHostDelegate::View* GetViewDelegate() { return this; }
+ virtual const GURL& GetURL() const { return url_; }
+ virtual ViewType::Type GetRenderViewType() const {
+ return ViewType::BACKGROUND_CONTENTS;
+ }
+ virtual int GetBrowserWindowID() const {
+ return extension_misc::kUnknownWindowId;
+ }
+ virtual void DidNavigate(RenderViewHost* render_view_host,
+ const ViewHostMsg_FrameNavigate_Params& params);
+ virtual WebPreferences GetWebkitPrefs();
+ virtual void ProcessDOMUIMessage(const std::string& message,
+ const Value* content,
+ const GURL& source_url,
+ int request_id,
+ bool has_callback);
+ virtual void RunJavaScriptMessage(const std::wstring& message,
+ const std::wstring& default_prompt,
+ const GURL& frame_url,
+ const int flags,
+ IPC::Message* reply_msg,
+ bool* did_suppress_message);
+ virtual void Close(RenderViewHost* render_view_host);
+ virtual RendererPreferences GetRendererPrefs(Profile* profile) const;
+
+ // RenderViewHostDelegate::View
+ virtual void CreateNewWindow(
+ int route_id,
+ WindowContainerType window_container_type);
+ virtual void CreateNewWidget(int route_id, WebKit::WebPopupType popup_type);
+ virtual void ShowCreatedWindow(int route_id,
+ WindowOpenDisposition disposition,
+ const gfx::Rect& initial_pos,
+ bool user_gesture);
+ virtual void ShowCreatedWidget(int route_id,
+ const gfx::Rect& initial_pos);
+ virtual void ShowContextMenu(const ContextMenuParams& params) {}
+ virtual void StartDragging(const WebDropData& drop_data,
+ WebKit::WebDragOperationsMask allowed_operations,
+ const SkBitmap& image,
+ const gfx::Point& image_offset) {}
+ virtual void UpdateDragCursor(WebKit::WebDragOperation operation) {}
+ virtual void GotFocus() {}
+ virtual void TakeFocus(bool reverse) {}
+ virtual bool PreHandleKeyboardEvent(const NativeWebKeyboardEvent& event,
+ bool* is_keyboard_shortcut) {
+ return false;
+ }
+ virtual void HandleKeyboardEvent(const NativeWebKeyboardEvent& event) {}
+ virtual void HandleMouseEvent() {}
+ virtual void HandleMouseLeave() {}
+ virtual void UpdatePreferredSize(const gfx::Size& new_size) {}
+
+ // NotificationObserver
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // JavaScriptMessageBoxClient
+ virtual std::wstring GetMessageBoxTitle(const GURL& frame_url,
+ bool is_alert);
+ virtual gfx::NativeWindow GetMessageBoxRootWindow();
+ virtual void OnMessageBoxClosed(IPC::Message* reply_msg,
+ bool success,
+ const std::wstring& prompt);
+ virtual void SetSuppressMessageBoxes(bool suppress_message_boxes) {}
+ virtual TabContents* AsTabContents() { return NULL; }
+ virtual ExtensionHost* AsExtensionHost() { return NULL; }
+
+ private:
+ // The host for our HTML content.
+ RenderViewHost* render_view_host_;
+
+ // Common implementations of some RenderViewHostDelegate::View methods.
+ RenderViewHostDelegateViewHelper delegate_view_helper_;
+
+ // The URL being hosted.
+ GURL url_;
+
+ NotificationRegistrar registrar_;
+
+ DISALLOW_COPY_AND_ASSIGN(BackgroundContents);
+};
+
+#endif // CHROME_BROWSER_TAB_CONTENTS_BACKGROUND_CONTENTS_H_
diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
index 5fe2208..a1f7f01 100644
--- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
+++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc
@@ -8,6 +8,7 @@
#include "base/string_util.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/character_encoding.h"
+#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_view_host.h"
@@ -15,26 +16,63 @@
#include "chrome/browser/renderer_host/render_widget_host.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/renderer_host/site_instance.h"
+#include "chrome/browser/tab_contents/background_contents.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
#include "chrome/browser/user_style_sheet_watcher.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
+bool RenderViewHostDelegateViewHelper::ShouldOpenBackgroundContents(
+ WindowContainerType window_container_type,
+ GURL opener_url,
+ RenderProcessHost* opener_process,
+ Profile* profile) {
+ ExtensionsService* extensions_service = profile->GetExtensionsService();
+ if (window_container_type != WINDOW_CONTAINER_TYPE_BACKGROUND ||
+ !opener_url.is_valid() ||
+ !extensions_service ||
+ !extensions_service->is_ready())
+ return false;
+
+ Extension* extension = extensions_service->GetExtensionByURL(opener_url);
+ if (!extension)
+ extension = extensions_service->GetExtensionByWebExtent(opener_url);
+ if (!extension ||
+ !extension->HasApiPermission(Extension::kBackgroundPermission))
+ return false;
+
+ ExtensionProcessManager* process_manager =
+ profile->GetExtensionProcessManager();
+ if (!opener_process || !process_manager ||
+ opener_process != process_manager->GetExtensionProcess(opener_url))
+ return false;
+
+ return true;
+}
TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow(
int route_id,
Profile* profile,
SiteInstance* site,
DOMUITypeID domui_type,
- TabContents* old_tab_contents,
+ RenderViewHostDelegate* opener,
WindowContainerType window_container_type) {
+ if (ShouldOpenBackgroundContents(window_container_type,
+ opener->GetURL(),
+ site->GetProcess(),
+ profile)) {
+ BackgroundContents* contents = new BackgroundContents(site, route_id);
+ pending_contents_[route_id] = contents->render_view_host();
+ return NULL;
+ }
+
// Create the new web contents. This will automatically create the new
// TabContentsView. In the future, we may want to create the view separately.
TabContents* new_contents =
new TabContents(profile,
site,
route_id,
- old_tab_contents);
+ opener->GetAsTabContents());
new_contents->set_opener_dom_ui_type(domui_type);
TabContentsView* new_view = new_contents->view();
@@ -43,7 +81,7 @@ TabContents* RenderViewHostDelegateViewHelper::CreateNewWindow(
new_view->CreateViewForWidget(new_contents->render_view_host());
// Save the created window associated with the route so we can show it later.
- pending_contents_[route_id] = new_contents;
+ pending_contents_[route_id] = new_contents->render_view_host();
return new_contents;
}
@@ -67,19 +105,17 @@ TabContents* RenderViewHostDelegateViewHelper::GetCreatedWindow(int route_id) {
return NULL;
}
- TabContents* new_tab_contents = iter->second;
+ RenderViewHost* new_rvh = iter->second;
pending_contents_.erase(route_id);
- if (!new_tab_contents->render_view_host()->view() ||
- !new_tab_contents->GetRenderProcessHost()->HasConnection()) {
- // The view has gone away or the renderer crashed. Nothing to do.
+ // The renderer crashed or it is a TabContents and has no view.
+ if (!new_rvh->process()->HasConnection() ||
+ (new_rvh->delegate()->GetAsTabContents() && !new_rvh->view()))
return NULL;
- }
// TODO(brettw) this seems bogus to reach into here and initialize the host.
- new_tab_contents->render_view_host()->Init();
-
- return new_tab_contents;
+ new_rvh->Init();
+ return new_rvh->delegate()->GetAsTabContents();
}
RenderWidgetHostView* RenderViewHostDelegateViewHelper::GetCreatedWidget(
diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.h b/chrome/browser/tab_contents/render_view_host_delegate_helper.h
index 351e036..084762d 100644
--- a/chrome/browser/tab_contents/render_view_host_delegate_helper.h
+++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.h
@@ -17,10 +17,12 @@
#include "webkit/glue/window_open_disposition.h"
class Browser;
+class ExtensionsService;
class PrefService;
class Profile;
class RenderProcessHost;
class RenderViewHost;
+class RenderViewHostDelegate;
class RenderWidgetHost;
class RenderWidgetHostView;
class SiteInstance;
@@ -32,24 +34,47 @@ class RenderViewHostDelegateViewHelper {
public:
RenderViewHostDelegateViewHelper() {}
+ // Creates a new renderer for window.open. This will either be a
+ // BackgroundContents (if the window_container_type ==
+ // WINDOW_CONTAINER_TYPE_BACKGROUND and permissions allow) or a TabContents.
+ // If a TabContents is created, it is returned. Otherwise NULL is returned.
virtual TabContents* CreateNewWindow(
int route_id,
Profile* profile,
SiteInstance* site,
DOMUITypeID domui_type,
- TabContents* old_tab_contents,
+ RenderViewHostDelegate* opener,
WindowContainerType window_container_type);
+
+ // Creates a new RenderWidgetHost and saves it for later retrieval by
+ // GetCreatedWidget.
virtual RenderWidgetHostView* CreateNewWidget(int route_id,
WebKit::WebPopupType popup_type,
RenderProcessHost* process);
- virtual TabContents* GetCreatedWindow(int route_id);
+
+ // Finds the new RenderWidgetHost and returns it. Note that this can only be
+ // called once as this call also removes it from the internal map.
virtual RenderWidgetHostView* GetCreatedWidget(int route_id);
+
+ // Finds the new RenderViewHost/Delegate by route_id, initializes it for
+ // for renderer-initiated creation, and returns the TabContents that needs
+ // to be shown, if there is one (i.e. not a BackgroundContents). Note that
+ // this can only be called once as this call also removes it from the internal
+ // map.
+ virtual TabContents* GetCreatedWindow(int route_id);
+
+ // Removes |host| from the internal map of pending RenderWidgets.
void RenderWidgetHostDestroyed(RenderWidgetHost* host);
private:
- // Tracks created TabContents objects that have not been shown yet. They are
- // identified by the route ID passed to CreateNewWindow.
- typedef std::map<int, TabContents*> PendingContents;
+ bool ShouldOpenBackgroundContents(WindowContainerType window_container_type,
+ GURL opener_url,
+ RenderProcessHost* opener_process,
+ Profile* profile);
+
+ // Tracks created RenderViewHost objects that have not been shown yet.
+ // They are identified by the route ID passed to CreateNewWindow.
+ typedef std::map<int, RenderViewHost*> PendingContents;
PendingContents pending_contents_;
// These maps hold on to the widgets that we created on behalf of the
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 2f3e743..9d2fd42 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -946,7 +946,7 @@ void TabContents::PopupNotificationVisibilityChanged(bool visible) {
if (is_being_destroyed_)
return;
if (!dont_notify_render_view_)
- render_view_host()->PopupNotificationVisibilityChanged(visible);
+ render_view_host()->AllowScriptToClose(!visible);
if (delegate_)
delegate_->OnContentSettingsChange(this);
}
diff --git a/chrome/browser/tab_contents/tab_contents_view.cc b/chrome/browser/tab_contents/tab_contents_view.cc
index 935b96d..0fb400e 100644
--- a/chrome/browser/tab_contents/tab_contents_view.cc
+++ b/chrome/browser/tab_contents/tab_contents_view.cc
@@ -7,6 +7,7 @@
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/renderer_host/render_widget_host.h"
+#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/renderer_host/render_widget_host_view.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_delegate.h"
@@ -28,12 +29,12 @@ void TabContentsView::RenderViewCreated(RenderViewHost* host) {
void TabContentsView::CreateNewWindow(
int route_id,
WindowContainerType window_container_type) {
- TabContents* new_contents = delegate_view_helper_.CreateNewWindow(
+ TabContents* new_contents = delegate_view_helper_.CreateNewWindow(
route_id, tab_contents_->profile(), tab_contents_->GetSiteInstance(),
DOMUIFactory::GetDOMUIType(tab_contents_->GetURL()), tab_contents_,
window_container_type);
- if (tab_contents_->delegate())
+ if (new_contents && tab_contents_->delegate())
tab_contents_->delegate()->TabContentsCreated(new_contents);
}
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 892a048..c8a0c66 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2072,6 +2072,8 @@
'browser/sync/sync_ui_util.h',
'browser/sync/sync_ui_util_mac.mm',
'browser/sync/sync_ui_util_mac.h',
+ 'browser/tab_contents/background_contents.cc',
+ 'browser/tab_contents/background_contents.h',
'browser/tab_contents/constrained_window.h',
'browser/tab_contents/infobar_delegate.cc',
'browser/tab_contents/infobar_delegate.h',
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 4c82ad1..fad9130 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -119,6 +119,7 @@ const int Extension::kIconSizes[] = {
const int Extension::kPageActionIconMaxSize = 19;
const int Extension::kBrowserActionIconMaxSize = 19;
+const char* Extension::kBackgroundPermission = "background";
const char* Extension::kBookmarkPermission = "bookmarks";
const char* Extension::kExperimentalPermission = "experimental";
const char* Extension::kGeolocationPermission = "geolocation";
@@ -128,6 +129,7 @@ const char* Extension::kTabPermission = "tabs";
const char* Extension::kUnlimitedStoragePermission = "unlimited_storage";
const char* Extension::kPermissionNames[] = {
+ Extension::kBackgroundPermission,
Extension::kBookmarkPermission,
Extension::kExperimentalPermission,
Extension::kGeolocationPermission,
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 7a1fe93..be015d2 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -87,6 +87,7 @@ class Extension {
static const int kBrowserActionIconMaxSize;
// Each permission is a module that the extension is permitted to use.
+ static const char* kBackgroundPermission;
static const char* kBookmarkPermission;
static const char* kExperimentalPermission;
static const char* kGeolocationPermission;
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index 36ba762..2353b35 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -188,4 +188,8 @@ namespace extension_filenames {
extern const char* kDecodedMessageCatalogsFilename;
}
+namespace extension_misc {
+ const int kUnknownWindowId = -1;
+} // extension_misc
+
#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_CONSTANTS_H_
diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h
index d2463a5..d8b46b4 100644
--- a/chrome/common/notification_type.h
+++ b/chrome/common/notification_type.h
@@ -467,6 +467,16 @@ class NotificationType {
// view host for the page, there are no details.
FOCUS_CHANGED_IN_PAGE,
+ // BackgroundContents ------------------------------------------------------
+
+ // The background contents navigated to a new location. The source is the
+ // BackgroundContents, and the details are contained RenderViewHost.
+ BACKGROUND_CONTENTS_NAVIGATED,
+
+ // The background contents is being deleted. The source is the
+ // BackgroundContents, and the details are the contained RendeViewHost.
+ BACKGROUND_CONTENTS_DELETED,
+
// Child Processes ---------------------------------------------------------
// This notification is sent when a child process host has connected to a
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index d575873..2bc18dd 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -654,11 +654,11 @@ IPC_BEGIN_MESSAGES(View)
int /* id of the request message */,
webkit_glue::FormData /* form data */)
- // Sent by the Browser process to alert a window about whether a blocked
- // popup notification is visible. The renderer assumes every new window is a
+ // Sent by the Browser process to alert a window about whether a it should
+ // allow a scripted window.close(). The renderer assumes every new window is a
// blocked popup until notified otherwise.
- IPC_MESSAGE_ROUTED1(ViewMsg_PopupNotificationVisibilityChanged,
- bool /* Whether it is visible */)
+ IPC_MESSAGE_ROUTED1(ViewMsg_AllowScriptToClose,
+ bool /* script_can_close */)
// Sent by AudioRendererHost to renderer to request an audio packet.
IPC_MESSAGE_ROUTED3(ViewMsg_RequestAudioPacket,
diff --git a/chrome/common/view_types.h b/chrome/common/view_types.h
index d3f1782..f74eb36 100644
--- a/chrome/common/view_types.h
+++ b/chrome/common/view_types.h
@@ -12,6 +12,7 @@ class ViewType {
public:
enum Type {
INVALID,
+ BACKGROUND_CONTENTS,
TAB_CONTENTS,
EXTENSION_TOOLSTRIP,
EXTENSION_MOLE,
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index a12ef09..0a586c4 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -15,6 +15,7 @@
#include "base/string_util.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/url_pattern.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
@@ -139,8 +140,9 @@ class ExtensionViewAccumulator : public RenderViewVisitor {
// match that of the arguments to the accumulator.
// See bug: http://crbug.com/29646
if (!(view_type_ == ViewType::EXTENSION_POPUP &&
- render_view->browser_window_id() == -1)) {
- if (browser_window_id_ != -1 &&
+ render_view->browser_window_id() ==
+ extension_misc::kUnknownWindowId)) {
+ if (browser_window_id_ != extension_misc::kUnknownWindowId &&
render_view->browser_window_id() != browser_window_id_) {
return true;
}
@@ -318,8 +320,8 @@ class ExtensionImpl : public ExtensionBase {
if (!args[0]->IsInt32() || !args[1]->IsString())
return v8::Undefined();
- // |browser_window_id| == -1 means getting views attached to any browser
- // window.
+ // |browser_window_id| == extension_misc::kUnknownWindowId means getting
+ // views attached to any browser window.
int browser_window_id = args[0]->Int32Value();
std::string view_type_string = *v8::String::Utf8Value(args[1]->ToString());
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 804df48..d76a5ac 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -379,7 +379,7 @@ RenderView::RenderView(RenderThreadBase* render_thread,
has_unload_listener_(false),
decrement_shared_popup_at_destruction_(false),
autofill_query_id_(0),
- popup_notification_visible_(false),
+ script_can_close_(true),
spelling_panel_visible_(false),
send_content_state_immediately_(false),
send_preferred_size_changes_(false),
@@ -653,8 +653,8 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
OnAutocompleteSuggestionsReturned)
IPC_MESSAGE_HANDLER(ViewMsg_AutoFillFormDataFilled,
OnAutoFillFormDataFilled)
- IPC_MESSAGE_HANDLER(ViewMsg_PopupNotificationVisibilityChanged,
- OnPopupNotificationVisibilityChanged)
+ IPC_MESSAGE_HANDLER(ViewMsg_AllowScriptToClose,
+ OnAllowScriptToClose)
IPC_MESSAGE_HANDLER(ViewMsg_MoveOrResizeStarted, OnMoveOrResizeStarted)
IPC_MESSAGE_HANDLER(ViewMsg_ExtensionResponse, OnExtensionResponse)
IPC_MESSAGE_HANDLER(ViewMsg_ExtensionMessageInvoke,
@@ -1503,8 +1503,8 @@ void RenderView::OnAutoFillFormDataFilled(int query_id,
form_manager_.FillForm(form);
}
-void RenderView::OnPopupNotificationVisibilityChanged(bool visible) {
- popup_notification_visible_ = visible;
+void RenderView::OnAllowScriptToClose(bool script_can_close) {
+ script_can_close_ = script_can_close;
}
uint32 RenderView::GetCPBrowsingContext() {
@@ -1558,7 +1558,7 @@ WebView* RenderView::createView(
// This window can't be closed from a window.close() call until we receive a
// message from the Browser process explicitly allowing it.
- popup_notification_visible_ = true;
+ script_can_close_ = false;
int32 routing_id = MSG_ROUTING_NONE;
bool user_gesture = creator->isProcessingUserGesture();
@@ -2073,7 +2073,7 @@ void RenderView::show(WebNavigationPolicy policy) {
}
void RenderView::closeWidgetSoon() {
- if (!popup_notification_visible_)
+ if (script_can_close_)
RenderWidget::closeWidgetSoon();
}
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index 1eda03e..ab2b4a4 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -771,8 +771,8 @@ class RenderView : public RenderWidget,
void OnAutoFillFormDataFilled(int query_id,
const webkit_glue::FormData& form);
- // Message that the popup notification has been shown or hidden.
- void OnPopupNotificationVisibilityChanged(bool visible);
+ // Message that script may use window.close().
+ void OnAllowScriptToClose(bool script_can_close);
// Handles messages posted from automation.
void OnMessageFromExternalHost(const std::string& message,
@@ -1086,7 +1086,7 @@ class RenderView : public RenderWidget,
// is being displayed. We instead assume that when we create a window off
// this RenderView, that it is going to be blocked until we get a message
// from the Browser process telling us otherwise.
- bool popup_notification_visible_;
+ bool script_can_close_;
// True if the browser is showing the spelling panel for us.
bool spelling_panel_visible_;