summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/views/dom_view.cc15
-rw-r--r--chrome/browser/views/dom_view.h2
-rw-r--r--chrome/browser/views/dom_view_browsertest.cc93
-rw-r--r--chrome/chrome_tests.gypi2
4 files changed, 111 insertions, 1 deletions
diff --git a/chrome/browser/views/dom_view.cc b/chrome/browser/views/dom_view.cc
index 4725cf9..9c42201 100644
--- a/chrome/browser/views/dom_view.cc
+++ b/chrome/browser/views/dom_view.cc
@@ -23,7 +23,9 @@ bool DOMView::Init(Profile* profile, SiteInstance* instance) {
initialized_ = true;
tab_contents_.reset(CreateTabContents(profile, instance));
- views::NativeViewHost::Attach(tab_contents_->GetNativeView());
+ // Attach the native_view now if the view is already added to Widget.
+ if (GetWidget())
+ Attach(tab_contents_->GetNativeView());
return true;
}
@@ -47,3 +49,14 @@ bool DOMView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) {
void DOMView::Focus() {
tab_contents_->Focus();
}
+
+void DOMView::ViewHierarchyChanged(bool is_add, views::View* parent,
+ views::View* child) {
+ // Attach the native_view when this is added to Widget if
+ // the native view has not been attached yet and tab_contents_ exists.
+ views::NativeViewHost::ViewHierarchyChanged(is_add, parent, child);
+ if (is_add && GetWidget() && !native_view() && tab_contents_.get())
+ Attach(tab_contents_->GetNativeView());
+ else if (!is_add && child == this && native_view())
+ Detach();
+}
diff --git a/chrome/browser/views/dom_view.h b/chrome/browser/views/dom_view.h
index 09d8b2a..4a804f8 100644
--- a/chrome/browser/views/dom_view.h
+++ b/chrome/browser/views/dom_view.h
@@ -40,6 +40,8 @@ class DOMView : public views::NativeViewHost {
// Overridden from View.
virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
virtual void Focus();
+ virtual void ViewHierarchyChanged(bool is_add, views::View* parent,
+ views::View* child);
// Returns new allocated TabContents instance, caller is responsible deleting.
// Override in derived classes to replace TabContents with derivative.
diff --git a/chrome/browser/views/dom_view_browsertest.cc b/chrome/browser/views/dom_view_browsertest.cc
new file mode 100644
index 0000000..8aa51b6
--- /dev/null
+++ b/chrome/browser/views/dom_view_browsertest.cc
@@ -0,0 +1,93 @@
+// 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/browser.h"
+#include "chrome/browser/views/dom_view.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "views/widget/root_view.h"
+#include "views/widget/widget.h"
+
+using namespace views;
+
+class DOMViewTest : public InProcessBrowserTest {
+ public:
+ Widget* CreatePopupWindow() {
+ Widget* window =
+ Widget::CreatePopupWidget(Widget::NotTransparent,
+ Widget::AcceptEvents,
+ Widget::DeleteOnDestroy,
+ Widget::DontMirrorOriginInRTL);
+ window->Init(NULL, gfx::Rect(0, 0, 400, 400));
+ return window;
+ }
+};
+
+// Tests if creating and deleting dom_view
+// does not crash and leak memory.
+IN_PROC_BROWSER_TEST_F(DOMViewTest, TestShowAndHide) {
+ Widget* one = CreatePopupWindow();
+
+ DOMView* dom_view = new DOMView();
+ one->GetRootView()->AddChildView(dom_view);
+
+ dom_view->Init(browser()->profile(), NULL);
+ dom_view->LoadURL(GURL("http://www.google.com"));
+ ui_test_utils::WaitForNotification(NotificationType::LOAD_STOP);
+ one->Show();
+
+ ui_test_utils::RunAllPendingInMessageLoop();
+
+ one->Hide();
+}
+
+// Tests if removing from tree then deleting dom_view
+// does not crash and leak memory.
+IN_PROC_BROWSER_TEST_F(DOMViewTest, TestRemoveAndDelete) {
+ Widget* one = CreatePopupWindow();
+
+ DOMView* dom_view = new DOMView();
+ one->GetRootView()->AddChildView(dom_view);
+
+ dom_view->Init(browser()->profile(), NULL);
+ dom_view->LoadURL(GURL("http://www.google.com"));
+ ui_test_utils::WaitForNotification(NotificationType::LOAD_STOP);
+ one->Show();
+
+ ui_test_utils::RunAllPendingInMessageLoop();
+
+ one->GetRootView()->RemoveChildView(dom_view);
+
+ delete dom_view;
+
+ one->Hide();
+}
+
+// Tests if reparenting dom_view does not crash and does not leak
+// memory.
+IN_PROC_BROWSER_TEST_F(DOMViewTest, TestReparent) {
+ Widget* one = CreatePopupWindow();
+
+ DOMView* dom_view = new DOMView();
+ one->GetRootView()->AddChildView(dom_view);
+
+ dom_view->Init(browser()->profile(), NULL);
+ dom_view->LoadURL(GURL("http://www.google.com"));
+ ui_test_utils::WaitForNotification(NotificationType::LOAD_STOP);
+ one->Show();
+
+ ui_test_utils::RunAllPendingInMessageLoop();
+
+ one->GetRootView()->RemoveChildView(dom_view);
+ one->Hide();
+
+ // Re-attach to another Widget.
+ Widget* two = CreatePopupWindow();
+ two->GetRootView()->AddChildView(dom_view);
+ two->Show();
+
+ ui_test_utils::RunAllPendingInMessageLoop();
+
+ two->Hide();
+}
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index e6d4854..320dda0 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1764,6 +1764,7 @@
'browser/ssl/ssl_browser_tests.cc',
'browser/task_manager_browsertest.cc',
'browser/views/browser_actions_container_browsertest.cc',
+ 'browser/views/dom_view_browsertest.cc',
'browser/views/html_dialog_view_browsertest.cc',
'renderer/form_autocomplete_browsertest.cc',
'renderer/form_manager_browsertest.cc',
@@ -1903,6 +1904,7 @@
'sources!': [
'browser/extensions/browser_action_test_util_views.cc',
'browser/views/browser_actions_container_browsertest.cc',
+ 'browser/views/dom_view_browsertest.cc',
'browser/views/html_dialog_view_browsertest.cc',
],
}],