summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ui')
-rw-r--r--chrome/browser/ui/browser.cc4
-rw-r--r--chrome/browser/ui/cocoa/find_bar_bridge.h2
-rw-r--r--chrome/browser/ui/cocoa/find_bar_bridge_unittest.mm2
-rw-r--r--chrome/browser/ui/cocoa/find_bar_cocoa_controller.mm2
-rw-r--r--chrome/browser/ui/cocoa/find_bar_cocoa_controller_unittest.mm2
-rw-r--r--chrome/browser/ui/cocoa/tab_strip_controller.mm4
-rw-r--r--chrome/browser/ui/find_bar/find_backend_unittest.cc76
-rw-r--r--chrome/browser/ui/find_bar/find_bar.h98
-rw-r--r--chrome/browser/ui/find_bar/find_bar_controller.cc225
-rw-r--r--chrome/browser/ui/find_bar/find_bar_controller.h89
-rw-r--r--chrome/browser/ui/find_bar/find_bar_host_browsertest.cc1085
-rw-r--r--chrome/browser/ui/find_bar/find_bar_state.cc20
-rw-r--r--chrome/browser/ui/find_bar/find_bar_state.h41
-rw-r--r--chrome/browser/ui/find_bar/find_notification_details.h51
-rw-r--r--chrome/browser/ui/views/dropdown_bar_host_win.cc2
-rw-r--r--chrome/browser/ui/views/find_bar_host.cc2
-rw-r--r--chrome/browser/ui/views/find_bar_host.h2
-rw-r--r--chrome/browser/ui/views/find_bar_host_gtk.cc2
-rw-r--r--chrome/browser/ui/views/find_bar_host_interactive_uitest.cc2
-rw-r--r--chrome/browser/ui/views/find_bar_host_win.cc2
-rw-r--r--chrome/browser/ui/views/find_bar_view.cc4
-rw-r--r--chrome/browser/ui/views/find_bar_view.h2
-rw-r--r--chrome/browser/ui/views/frame/browser_view_layout.cc4
23 files changed, 1704 insertions, 19 deletions
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index a0be08a..d792d430 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -53,8 +53,6 @@
#include "chrome/browser/extensions/extension_prefs.h"
#include "chrome/browser/extensions/extension_tabs_module.h"
#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/find_bar.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/first_run/first_run.h"
#include "chrome/browser/google/google_url_tracker.h"
#include "chrome/browser/google/google_util.h"
@@ -87,6 +85,8 @@
#include "chrome/browser/tab_menu_model.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/upgrade_detector.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/window_sizer.h"
diff --git a/chrome/browser/ui/cocoa/find_bar_bridge.h b/chrome/browser/ui/cocoa/find_bar_bridge.h
index 3a9c197..3bafa66 100644
--- a/chrome/browser/ui/cocoa/find_bar_bridge.h
+++ b/chrome/browser/ui/cocoa/find_bar_bridge.h
@@ -7,7 +7,7 @@
#pragma once
#include "base/logging.h"
-#include "chrome/browser/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
class BrowserWindowCocoa;
class FindBarController;
diff --git a/chrome/browser/ui/cocoa/find_bar_bridge_unittest.mm b/chrome/browser/ui/cocoa/find_bar_bridge_unittest.mm
index 81679fdb..421cb80 100644
--- a/chrome/browser/ui/cocoa/find_bar_bridge_unittest.mm
+++ b/chrome/browser/ui/cocoa/find_bar_bridge_unittest.mm
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#include "chrome/browser/ui/cocoa/find_bar_bridge.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
namespace {
diff --git a/chrome/browser/ui/cocoa/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar_cocoa_controller.mm
index f50d6db..05e5397 100644
--- a/chrome/browser/ui/cocoa/find_bar_cocoa_controller.mm
+++ b/chrome/browser/ui/cocoa/find_bar_cocoa_controller.mm
@@ -6,7 +6,6 @@
#include "base/mac_util.h"
#include "base/sys_string_conversions.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/ui/cocoa/browser_window_cocoa.h"
@@ -17,6 +16,7 @@
#import "chrome/browser/ui/cocoa/find_pasteboard.h"
#import "chrome/browser/ui/cocoa/focus_tracker.h"
#import "chrome/browser/ui/cocoa/tab_strip_controller.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h"
namespace {
diff --git a/chrome/browser/ui/cocoa/find_bar_cocoa_controller_unittest.mm b/chrome/browser/ui/cocoa/find_bar_cocoa_controller_unittest.mm
index ca85dd2..d7869c2 100644
--- a/chrome/browser/ui/cocoa/find_bar_cocoa_controller_unittest.mm
+++ b/chrome/browser/ui/cocoa/find_bar_cocoa_controller_unittest.mm
@@ -5,11 +5,11 @@
#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#include "chrome/browser/browser_window.h"
-#include "chrome/browser/find_notification_details.h"
#import "chrome/browser/ui/cocoa/cocoa_test_helper.h"
#import "chrome/browser/ui/cocoa/find_bar_cocoa_controller.h"
#import "chrome/browser/ui/cocoa/find_pasteboard.h"
#import "chrome/browser/ui/cocoa/find_bar_text_field.h"
+#include "chrome/browser/ui/find_bar/find_notification_details.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
diff --git a/chrome/browser/ui/cocoa/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tab_strip_controller.mm
index 7a34c58..46b7395 100644
--- a/chrome/browser/ui/cocoa/tab_strip_controller.mm
+++ b/chrome/browser/ui/cocoa/tab_strip_controller.mm
@@ -15,8 +15,6 @@
#include "base/nsimage_cache_mac.h"
#include "base/sys_string_conversions.h"
#include "chrome/app/chrome_command_ids.h"
-#include "chrome/browser/find_bar.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/metrics/user_metrics.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/debugger/devtools_window.h"
@@ -40,6 +38,8 @@
#import "chrome/browser/ui/cocoa/tab_strip_model_observer_bridge.h"
#import "chrome/browser/ui/cocoa/tab_view.h"
#import "chrome/browser/ui/cocoa/throbber_view.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "grit/app_resources.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
diff --git a/chrome/browser/ui/find_bar/find_backend_unittest.cc b/chrome/browser/ui/find_bar/find_backend_unittest.cc
new file mode 100644
index 0000000..c4ec58b
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_backend_unittest.cc
@@ -0,0 +1,76 @@
+// Copyright (c) 2009 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 "base/string16.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/renderer_host/test/test_render_view_host.h"
+#include "chrome/browser/tab_contents/test_tab_contents.h"
+#include "chrome/browser/ui/find_bar/find_bar_state.h"
+#include "chrome/common/url_constants.h"
+#include "chrome/test/testing_profile.h"
+
+typedef RenderViewHostTestHarness FindBackendTest;
+
+namespace {
+
+string16 FindPrepopulateText(TabContents* contents) {
+ return FindBarState::GetLastPrepopulateText(contents->profile());
+}
+
+} // end namespace
+
+// This test takes two TabContents objects, searches in both of them and
+// tests the internal state for find_text and find_prepopulate_text.
+TEST_F(FindBackendTest, InternalState) {
+ // Initial state for the TabContents is blank strings.
+ EXPECT_EQ(string16(), FindPrepopulateText(contents()));
+ EXPECT_EQ(string16(), contents()->find_text());
+
+ // Get another TabContents object ready.
+ TestTabContents contents2(profile_.get(), NULL);
+
+ // No search has still been issued, strings should be blank.
+ EXPECT_EQ(string16(), FindPrepopulateText(contents()));
+ EXPECT_EQ(string16(), contents()->find_text());
+ EXPECT_EQ(string16(), FindPrepopulateText(&contents2));
+ EXPECT_EQ(string16(), contents2.find_text());
+
+ string16 search_term1 = ASCIIToUTF16(" I had a 401K ");
+ string16 search_term2 = ASCIIToUTF16(" but the economy ");
+ string16 search_term3 = ASCIIToUTF16(" eated it. ");
+
+ // Start searching in the first TabContents, searching forwards but not case
+ // sensitive (as indicated by the last two params).
+ contents()->StartFinding(search_term1, true, false);
+
+ // Pre-populate string should always match between the two, but find_text
+ // should not.
+ EXPECT_EQ(search_term1, FindPrepopulateText(contents()));
+ EXPECT_EQ(search_term1, contents()->find_text());
+ EXPECT_EQ(search_term1, FindPrepopulateText(&contents2));
+ EXPECT_EQ(string16(), contents2.find_text());
+
+ // Now search in the other TabContents, searching forwards but not case
+ // sensitive (as indicated by the last two params).
+ contents2.StartFinding(search_term2, true, false);
+
+ // Again, pre-populate string should always match between the two, but
+ // find_text should not.
+ EXPECT_EQ(search_term2, FindPrepopulateText(contents()));
+ EXPECT_EQ(search_term1, contents()->find_text());
+ EXPECT_EQ(search_term2, FindPrepopulateText(&contents2));
+ EXPECT_EQ(search_term2, contents2.find_text());
+
+ // Search again in the first TabContents, searching forwards but not case
+ // sensitive (as indicated by the last two params).
+ contents()->StartFinding(search_term3, true, false);
+
+ // Once more, pre-populate string should always match between the two, but
+ // find_text should not.
+ EXPECT_EQ(search_term3, FindPrepopulateText(contents()));
+ EXPECT_EQ(search_term3, contents()->find_text());
+ EXPECT_EQ(search_term3, FindPrepopulateText(&contents2));
+ EXPECT_EQ(search_term2, contents2.find_text());
+}
diff --git a/chrome/browser/ui/find_bar/find_bar.h b/chrome/browser/ui/find_bar/find_bar.h
new file mode 100644
index 0000000..350682d
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_bar.h
@@ -0,0 +1,98 @@
+// 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.
+//
+// This is an interface for the platform specific FindBar. It is responsible
+// for drawing the FindBar bar on the platform and is owned by the
+// FindBarController.
+
+#ifndef CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_H_
+#define CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_H_
+#pragma once
+
+#include "base/string16.h"
+#include "gfx/rect.h"
+
+class FindBarController;
+class FindBarTesting;
+class FindNotificationDetails;
+
+class FindBar {
+ public:
+ virtual ~FindBar() { }
+
+ // Accessor and setter for the FindBarController.
+ virtual FindBarController* GetFindBarController() const = 0;
+ virtual void SetFindBarController(
+ FindBarController* find_bar_controller) = 0;
+
+ // Shows the find bar. Any previous search string will again be visible.
+ // If |animate| is true, we try to slide the find bar in.
+ virtual void Show(bool animate) = 0;
+
+ // Hide the find bar. If |animate| is true, we try to slide the find bar
+ // away.
+ virtual void Hide(bool animate) = 0;
+
+ // Restore the selected text in the find box and focus it.
+ virtual void SetFocusAndSelection() = 0;
+
+ // Clear the text in the find box.
+ virtual void ClearResults(const FindNotificationDetails& results) = 0;
+
+ // Stop the animation.
+ virtual void StopAnimation() = 0;
+
+ // If the find bar obscures the search results we need to move the window. To
+ // do that we need to know what is selected on the page. We simply calculate
+ // where it would be if we place it on the left of the selection and if it
+ // doesn't fit on the screen we try the right side. The parameter
+ // |selection_rect| is expected to have coordinates relative to the top of
+ // the web page area. If |no_redraw| is true, the window will be moved without
+ // redrawing siblings.
+ virtual void MoveWindowIfNecessary(const gfx::Rect& selection_rect,
+ bool no_redraw) = 0;
+
+ // Set the text in the find box.
+ virtual void SetFindText(const string16& find_text) = 0;
+
+ // Updates the FindBar with the find result details contained within the
+ // specified |result|.
+ virtual void UpdateUIForFindResult(const FindNotificationDetails& result,
+ const string16& find_text) = 0;
+
+ // No match was found; play an audible alert.
+ virtual void AudibleAlert() = 0;
+
+ virtual bool IsFindBarVisible() = 0;
+
+ // Upon dismissing the window, restore focus to the last focused view which is
+ // not FindBarView or any of its children.
+ virtual void RestoreSavedFocus() = 0;
+
+ // Returns a pointer to the testing interface to the FindBar, or NULL
+ // if there is none.
+ virtual FindBarTesting* GetFindBarTesting() = 0;
+};
+
+class FindBarTesting {
+ public:
+ virtual ~FindBarTesting() { }
+
+ // Computes the location of the find bar and whether it is fully visible in
+ // its parent window. The return value indicates if the window is visible at
+ // all. Both out arguments are optional.
+ //
+ // This is used for UI tests of the find bar. If the find bar is not currently
+ // shown (return value of false), the out params will be {(0, 0), false}.
+ virtual bool GetFindBarWindowInfo(gfx::Point* position,
+ bool* fully_visible) = 0;
+
+ // Gets the search string currently visible in the Find box.
+ virtual string16 GetFindText() = 0;
+
+ // Gets the match count text (ie. 1 of 3) visible in the Find box.
+ virtual string16 GetMatchCountText() = 0;
+};
+
+#endif // CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_H_
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.cc b/chrome/browser/ui/find_bar/find_bar_controller.cc
new file mode 100644
index 0000000..ce7c2a5
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_bar_controller.cc
@@ -0,0 +1,225 @@
+// 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/ui/find_bar/find_bar_controller.h"
+
+#include "base/i18n/rtl.h"
+#include "build/build_config.h"
+#include "chrome/browser/tab_contents/navigation_entry.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar_state.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "gfx/rect.h"
+
+// The minimum space between the FindInPage window and the search result.
+static const int kMinFindWndDistanceFromSelection = 5;
+
+FindBarController::FindBarController(FindBar* find_bar)
+ : find_bar_(find_bar),
+ tab_contents_(NULL),
+ last_reported_matchcount_(0) {
+}
+
+FindBarController::~FindBarController() {
+ DCHECK(!tab_contents_);
+}
+
+void FindBarController::Show() {
+ // Only show the animation if we're not already showing a find bar for the
+ // selected TabContents.
+ if (!tab_contents_->find_ui_active()) {
+ MaybeSetPrepopulateText();
+
+ tab_contents_->set_find_ui_active(true);
+ find_bar_->Show(true);
+ }
+ find_bar_->SetFocusAndSelection();
+}
+
+void FindBarController::EndFindSession(SelectionAction action) {
+ find_bar_->Hide(true);
+
+ // |tab_contents_| can be NULL for a number of reasons, for example when the
+ // tab is closing. We must guard against that case. See issue 8030.
+ if (tab_contents_) {
+ // When we hide the window, we need to notify the renderer that we are done
+ // for now, so that we can abort the scoping effort and clear all the
+ // tickmarks and highlighting.
+ tab_contents_->StopFinding(action);
+
+ if (action != kKeepSelection)
+ find_bar_->ClearResults(tab_contents_->find_result());
+
+ // When we get dismissed we restore the focus to where it belongs.
+ find_bar_->RestoreSavedFocus();
+ }
+}
+
+void FindBarController::ChangeTabContents(TabContents* contents) {
+ if (tab_contents_) {
+ registrar_.RemoveAll();
+ find_bar_->StopAnimation();
+ }
+
+ tab_contents_ = contents;
+
+ // Hide any visible find window from the previous tab if NULL |tab_contents|
+ // is passed in or if the find UI is not active in the new tab.
+ if (find_bar_->IsFindBarVisible() &&
+ (!tab_contents_ || !tab_contents_->find_ui_active())) {
+ find_bar_->Hide(false);
+ }
+
+ if (!tab_contents_)
+ return;
+
+ registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(tab_contents_));
+ registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(&tab_contents_->controller()));
+
+ MaybeSetPrepopulateText();
+
+ if (tab_contents_->find_ui_active()) {
+ // A tab with a visible find bar just got selected and we need to show the
+ // find bar but without animation since it was already animated into its
+ // visible state. We also want to reset the window location so that
+ // we don't surprise the user by popping up to the left for no apparent
+ // reason.
+ find_bar_->Show(false);
+ }
+
+ UpdateFindBarForCurrentResult();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// FindBarHost, NotificationObserver implementation:
+
+void FindBarController::Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ if (type == NotificationType::FIND_RESULT_AVAILABLE) {
+ // Don't update for notifications from TabContentses other than the one we
+ // are actively tracking.
+ if (Source<TabContents>(source).ptr() == tab_contents_) {
+ UpdateFindBarForCurrentResult();
+ if (tab_contents_->find_result().final_update() &&
+ tab_contents_->find_result().number_of_matches() == 0) {
+ const string16& last_search = tab_contents_->previous_find_text();
+ const string16& current_search = tab_contents_->find_text();
+ if (last_search.find(current_search) != 0)
+ find_bar_->AudibleAlert();
+ }
+ }
+ } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
+ NavigationController* source_controller =
+ Source<NavigationController>(source).ptr();
+ if (source_controller == &tab_contents_->controller()) {
+ NavigationController::LoadCommittedDetails* commit_details =
+ Details<NavigationController::LoadCommittedDetails>(details).ptr();
+ PageTransition::Type transition_type =
+ commit_details->entry->transition_type();
+ // We hide the FindInPage window when the user navigates away, except on
+ // reload.
+ if (find_bar_->IsFindBarVisible()) {
+ if (PageTransition::StripQualifier(transition_type) !=
+ PageTransition::RELOAD) {
+ EndFindSession(kKeepSelection);
+ } else {
+ // On Reload we want to make sure FindNext is converted to a full Find
+ // to make sure highlights for inactive matches are repainted.
+ tab_contents_->set_find_op_aborted(true);
+ }
+ }
+ }
+ }
+}
+
+// static
+gfx::Rect FindBarController::GetLocationForFindbarView(
+ gfx::Rect view_location,
+ const gfx::Rect& dialog_bounds,
+ const gfx::Rect& avoid_overlapping_rect) {
+ if (base::i18n::IsRTL()) {
+ int boundary = dialog_bounds.width() - view_location.width();
+ view_location.set_x(std::min(view_location.x(), boundary));
+ } else {
+ view_location.set_x(std::max(view_location.x(), dialog_bounds.x()));
+ }
+
+ gfx::Rect new_pos = view_location;
+
+ // If the selection rectangle intersects the current position on screen then
+ // we try to move our dialog to the left (right for RTL) of the selection
+ // rectangle.
+ if (!avoid_overlapping_rect.IsEmpty() &&
+ avoid_overlapping_rect.Intersects(new_pos)) {
+ if (base::i18n::IsRTL()) {
+ new_pos.set_x(avoid_overlapping_rect.x() +
+ avoid_overlapping_rect.width() +
+ (2 * kMinFindWndDistanceFromSelection));
+
+ // If we moved it off-screen to the right, we won't move it at all.
+ if (new_pos.x() + new_pos.width() > dialog_bounds.width())
+ new_pos = view_location; // Reset.
+ } else {
+ new_pos.set_x(avoid_overlapping_rect.x() - new_pos.width() -
+ kMinFindWndDistanceFromSelection);
+
+ // If we moved it off-screen to the left, we won't move it at all.
+ if (new_pos.x() < 0)
+ new_pos = view_location; // Reset.
+ }
+ }
+
+ return new_pos;
+}
+
+void FindBarController::UpdateFindBarForCurrentResult() {
+ const FindNotificationDetails& find_result = tab_contents_->find_result();
+
+ // Avoid bug 894389: When a new search starts (and finds something) it reports
+ // an interim match count result of 1 before the scoping effort starts. This
+ // is to provide feedback as early as possible that we will find something.
+ // As you add letters to the search term, this creates a flashing effect when
+ // we briefly show "1 of 1" matches because there is a slight delay until
+ // the scoping effort starts updating the match count. We avoid this flash by
+ // ignoring interim results of 1 if we already have a positive number.
+ if (find_result.number_of_matches() > -1) {
+ if (last_reported_matchcount_ > 0 &&
+ find_result.number_of_matches() == 1 &&
+ !find_result.final_update())
+ return; // Don't let interim result override match count.
+ last_reported_matchcount_ = find_result.number_of_matches();
+ }
+
+ find_bar_->UpdateUIForFindResult(find_result, tab_contents_->find_text());
+}
+
+void FindBarController::MaybeSetPrepopulateText() {
+#if !defined(OS_MACOSX)
+ // Find out what we should show in the find text box. Usually, this will be
+ // the last search in this tab, but if no search has been issued in this tab
+ // we use the last search string (from any tab).
+ string16 find_string = tab_contents_->find_text();
+ if (find_string.empty())
+ find_string = tab_contents_->previous_find_text();
+ if (find_string.empty()) {
+ find_string =
+ FindBarState::GetLastPrepopulateText(tab_contents_->profile());
+ }
+
+ // Update the find bar with existing results and search text, regardless of
+ // whether or not the find bar is visible, so that if it's subsequently
+ // shown it is showing the right state for this tab. We update the find text
+ // _first_ since the FindBarView checks its emptiness to see if it should
+ // clear the result count display when there's nothing in the box.
+ find_bar_->SetFindText(find_string);
+#else
+ // Having a per-tab find_string is not compatible with OS X's find pasteboard,
+ // so we always have the same find text in all find bars. This is done through
+ // the find pasteboard mechanism, so don't set the text here.
+#endif
+}
diff --git a/chrome/browser/ui/find_bar/find_bar_controller.h b/chrome/browser/ui/find_bar/find_bar_controller.h
new file mode 100644
index 0000000..1c3a1d6
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_bar_controller.h
@@ -0,0 +1,89 @@
+// 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_UI_FIND_BAR_FIND_BAR_CONTROLLER_H_
+#define CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_CONTROLLER_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+
+namespace gfx {
+class Rect;
+}
+
+class FindBar;
+class TabContents;
+
+class FindBarController : public NotificationObserver {
+ public:
+ // An enum listing the possible actions to take on a find-in-page selection.
+ enum SelectionAction {
+ kKeepSelection, // Translate the find selection into a normal selection.
+ kClearSelection, // Clear the find selection.
+ kActivateSelection // Focus and click the selected node (for links).
+ };
+
+ // FindBar takes ownership of |find_bar_view|.
+ explicit FindBarController(FindBar* find_bar);
+
+ virtual ~FindBarController();
+
+ // Shows the find bar. Any previous search string will again be visible.
+ void Show();
+
+ // Ends the current session.
+ void EndFindSession(SelectionAction action);
+
+ // Accessor for the attached TabContents.
+ TabContents* tab_contents() const { return tab_contents_; }
+
+ // Changes the TabContents that this FindBar is attached to. This occurs when
+ // the user switches tabs in the Browser window. |contents| can be NULL.
+ void ChangeTabContents(TabContents* contents);
+
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ FindBar* find_bar() const { return find_bar_.get(); }
+
+ // Reposition |view_location| such that it avoids |avoid_overlapping_rect|,
+ // and return the new location.
+ static gfx::Rect GetLocationForFindbarView(
+ gfx::Rect view_location,
+ const gfx::Rect& dialog_bounds,
+ const gfx::Rect& avoid_overlapping_rect);
+
+ private:
+ // Sents an update to the find bar with the tab contents' current result. The
+ // tab_contents_ must be non-NULL before this call. Theis handles
+ // de-flickering in addition to just calling the update function.
+ void UpdateFindBarForCurrentResult();
+
+ // For Windows and Linux this function sets the prepopulate text for the
+ // Find text box. The propopulate value is the last value the user searched
+ // for in the current tab, or (if blank) the last value searched for in any
+ // tab. Mac has a global value for search, so this function does nothing on
+ // Mac.
+ void MaybeSetPrepopulateText();
+
+ NotificationRegistrar registrar_;
+
+ scoped_ptr<FindBar> find_bar_;
+
+ // The TabContents we are currently associated with. Can be NULL.
+ TabContents* tab_contents_;
+
+ // The last match count we reported to the user. This is used by
+ // UpdateFindBarForCurrentResult to avoid flickering.
+ int last_reported_matchcount_;
+
+ DISALLOW_COPY_AND_ASSIGN(FindBarController);
+};
+
+#endif // CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_CONTROLLER_H_
diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
new file mode 100644
index 0000000..e37e43a
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc
@@ -0,0 +1,1085 @@
+// 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 "app/keyboard_codes.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/renderer_host/render_view_host.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_navigator.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
+#include "chrome/browser/ui/find_bar/find_notification_details.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/test/in_process_browser_test.h"
+#include "chrome/test/ui_test_utils.h"
+#include "net/test/test_server.h"
+
+#if defined(TOOLKIT_VIEWS)
+#include "chrome/browser/views/find_bar_host.h"
+#include "views/focus/focus_manager.h"
+#elif defined(TOOLKIT_GTK)
+#include "chrome/browser/gtk/slide_animator_gtk.h"
+#elif defined(OS_MACOSX)
+#include "chrome/browser/ui/cocoa/find_bar_bridge.h"
+#endif
+
+const std::string kSimplePage = "404_is_enough_for_us.html";
+const std::string kFramePage = "files/find_in_page/frames.html";
+const std::string kFrameData = "files/find_in_page/framedata_general.html";
+const std::string kUserSelectPage = "files/find_in_page/user-select.html";
+const std::string kCrashPage = "files/find_in_page/crash_1341577.html";
+const std::string kTooFewMatchesPage = "files/find_in_page/bug_1155639.html";
+const std::string kEndState = "files/find_in_page/end_state.html";
+const std::string kPrematureEnd = "files/find_in_page/premature_end.html";
+const std::string kMoveIfOver = "files/find_in_page/move_if_obscuring.html";
+const std::string kBitstackCrash = "files/find_in_page/crash_14491.html";
+const std::string kSelectChangesOrdinal =
+ "files/find_in_page/select_changes_ordinal.html";
+const std::string kSimple = "files/find_in_page/simple.html";
+const std::string kLinkPage = "files/find_in_page/link.html";
+
+const bool kBack = false;
+const bool kFwd = true;
+
+const bool kIgnoreCase = false;
+const bool kCaseSensitive = true;
+
+const int kMoveIterations = 30;
+
+class FindInPageControllerTest : public InProcessBrowserTest {
+ public:
+ FindInPageControllerTest() {
+ EnableDOMAutomation();
+
+#if defined(TOOLKIT_VIEWS)
+ DropdownBarHost::disable_animations_during_testing_ = true;
+#elif defined(TOOLKIT_GTK)
+ SlideAnimatorGtk::SetAnimationsForTesting(false);
+#elif defined(OS_MACOSX)
+ FindBarBridge::disable_animations_during_testing_ = true;
+#endif
+ }
+
+ protected:
+ bool GetFindBarWindowInfoForBrowser(
+ Browser* browser, gfx::Point* position, bool* fully_visible) {
+ FindBarTesting* find_bar =
+ browser->GetFindBarController()->find_bar()->GetFindBarTesting();
+ return find_bar->GetFindBarWindowInfo(position, fully_visible);
+ }
+
+ bool GetFindBarWindowInfo(gfx::Point* position, bool* fully_visible) {
+ return GetFindBarWindowInfoForBrowser(browser(), position, fully_visible);
+ }
+
+ string16 GetFindBarTextForBrowser(Browser* browser) {
+ FindBarTesting* find_bar =
+ browser->GetFindBarController()->find_bar()->GetFindBarTesting();
+ return find_bar->GetFindText();
+ }
+
+ string16 GetFindBarText() {
+ return GetFindBarTextForBrowser(browser());
+ }
+
+ string16 GetFindBarMatchCountTextForBrowser(Browser* browser) {
+ FindBarTesting* find_bar =
+ browser->GetFindBarController()->find_bar()->GetFindBarTesting();
+ return find_bar->GetMatchCountText();
+ }
+
+ string16 GetMatchCountText() {
+ return GetFindBarMatchCountTextForBrowser(browser());
+ }
+
+ void EnsureFindBoxOpenForBrowser(Browser* browser) {
+ browser->ShowFindBar();
+ gfx::Point position;
+ bool fully_visible = false;
+ EXPECT_TRUE(GetFindBarWindowInfoForBrowser(
+ browser, &position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+ }
+
+ void EnsureFindBoxOpen() {
+ EnsureFindBoxOpenForBrowser(browser());
+ }
+};
+
+// Platform independent FindInPage that takes |const wchar_t*|
+// as an input.
+int FindInPageWchar(TabContents* tab,
+ const wchar_t* search_str,
+ bool forward,
+ bool case_sensitive,
+ int* ordinal) {
+ return ui_test_utils::FindInPage(
+ tab, WideToUTF16(std::wstring(search_str)),
+ forward, case_sensitive, ordinal);
+}
+
+// This test loads a page with frames and starts FindInPage requests.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our frames page.
+ GURL url = test_server()->GetURL(kFramePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Try incremental search (mimicking user typing in).
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ EXPECT_EQ(18, FindInPageWchar(tab, L"g",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(11, FindInPageWchar(tab, L"go",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(04, FindInPageWchar(tab, L"goo",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(03, FindInPageWchar(tab, L"goog",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(02, FindInPageWchar(tab, L"googl",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(01, FindInPageWchar(tab, L"google",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(00, FindInPageWchar(tab, L"google!",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+
+ // Negative test (no matches should be found).
+ EXPECT_EQ(0, FindInPageWchar(tab, L"Non-existing string",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+
+ // 'horse' only exists in the three right frames.
+ EXPECT_EQ(3, FindInPageWchar(tab, L"horse",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // 'cat' only exists in the first frame.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"cat",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Try searching again, should still come up with 1 match.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"cat",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Try searching backwards, ignoring case, should still come up with 1 match.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"CAT",
+ kBack, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Try case sensitive, should NOT find it.
+ EXPECT_EQ(0, FindInPageWchar(tab, L"CAT",
+ kFwd, kCaseSensitive, &ordinal));
+ EXPECT_EQ(0, ordinal);
+
+ // Try again case sensitive, but this time with right case.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"dog",
+ kFwd, kCaseSensitive, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame).
+ EXPECT_EQ(1, FindInPageWchar(tab, L"Hreggvi\u00F0ur",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(1, FindInPageWchar(tab, L"Hreggvi\u00F0ur",
+ kFwd, kCaseSensitive, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(0, FindInPageWchar(tab, L"hreggvi\u00F0ur",
+ kFwd, kCaseSensitive, &ordinal));
+ EXPECT_EQ(0, ordinal);
+}
+
+// Specifying a prototype so that we can add the WARN_UNUSED_RESULT attribute.
+bool FocusedOnPage(TabContents* tab_contents, std::string* result)
+ WARN_UNUSED_RESULT;
+
+bool FocusedOnPage(TabContents* tab_contents, std::string* result) {
+ return ui_test_utils::ExecuteJavaScriptAndExtractString(
+ tab_contents->render_view_host(),
+ L"",
+ L"window.domAutomationController.send(getFocusedElement());",
+ result);
+}
+
+// This tests the FindInPage end-state, in other words: what is focused when you
+// close the Find box (ie. if you find within a link the link should be
+// focused).
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageEndState) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our special focus tracking page.
+ GURL url = test_server()->GetURL(kEndState);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ TabContents* tab_contents = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(NULL != tab_contents);
+
+ // Verify that nothing has focus.
+ std::string result;
+ ASSERT_TRUE(FocusedOnPage(tab_contents, &result));
+ ASSERT_STREQ("{nothing focused}", result.c_str());
+
+ // Search for a text that exists within a link on the page.
+ int ordinal = 0;
+ EXPECT_EQ(1, FindInPageWchar(tab_contents, L"nk",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // End the find session, which should set focus to the link.
+ tab_contents->StopFinding(FindBarController::kKeepSelection);
+
+ // Verify that the link is focused.
+ ASSERT_TRUE(FocusedOnPage(tab_contents, &result));
+ EXPECT_STREQ("link1", result.c_str());
+
+ // Search for a text that exists within a link on the page.
+ EXPECT_EQ(1, FindInPageWchar(tab_contents, L"Google",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Move the selection to link 1, after searching.
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ tab_contents->render_view_host(),
+ L"",
+ L"window.domAutomationController.send(selectLink1());",
+ &result));
+
+ // End the find session.
+ tab_contents->StopFinding(FindBarController::kKeepSelection);
+
+ // Verify that link2 is not focused.
+ ASSERT_TRUE(FocusedOnPage(tab_contents, &result));
+ EXPECT_STREQ("", result.c_str());
+}
+
+// This test loads a single-frame page and makes sure the ordinal returned makes
+// sense as we FindNext over all the items.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageOrdinal) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kFrameData);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for 'o', which should make the first item active and return
+ // '1 in 3' (1st ordinal of a total of 3 matches).
+ TabContents* tab = browser()->GetSelectedTabContents();
+ int ordinal = 0;
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(2, ordinal);
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+ // Go back one match.
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kBack, kIgnoreCase, &ordinal));
+ EXPECT_EQ(2, ordinal);
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+ // This should wrap to the top.
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ // This should go back to the end.
+ EXPECT_EQ(3, FindInPageWchar(tab, L"o",
+ kBack, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+}
+
+// This tests that the ordinal is correctly adjusted after a selection
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
+ SelectChangesOrdinal_Issue20883) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our test content.
+ GURL url = test_server()->GetURL(kSelectChangesOrdinal);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ TabContents* tab_contents = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(NULL != tab_contents);
+
+ // Search for a text that exists within a link on the page.
+ TabContents* tab = browser()->GetSelectedTabContents();
+ int ordinal = 0;
+ EXPECT_EQ(4, FindInPageWchar(tab_contents,
+ L"google",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Move the selection to link 1, after searching.
+ std::string result;
+ ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString(
+ tab_contents->render_view_host(),
+ L"",
+ L"window.domAutomationController.send(selectLink1());",
+ &result));
+
+ // Do a find-next after the selection. This should move forward
+ // from there to the 3rd instance of 'google'.
+ EXPECT_EQ(4, FindInPageWchar(tab,
+ L"google",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+
+ // End the find session.
+ tab_contents->StopFinding(FindBarController::kKeepSelection);
+}
+
+// This test loads a page with frames and makes sure the ordinal returned makes
+// sense.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageMultiFramesOrdinal) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kFramePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for 'a', which should make the first item active and return
+ // '1 in 7' (1st ordinal of a total of 7 matches).
+ TabContents* tab = browser()->GetSelectedTabContents();
+ int ordinal = 0;
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(2, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(4, ordinal);
+ // Go back one, which should go back one frame.
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kBack, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(4, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(5, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(6, ordinal);
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(7, ordinal);
+ // Now we should wrap back to frame 1.
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ // Now we should wrap back to frame last frame.
+ EXPECT_EQ(7,
+ FindInPageWchar(tab, L"a", kBack, kIgnoreCase, &ordinal));
+ EXPECT_EQ(7, ordinal);
+}
+
+// We could get ordinals out of whack when restarting search in subframes.
+// See http://crbug.com/5132.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPage_Issue5132) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kFramePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for 'goa' three times (6 matches on page).
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ EXPECT_EQ(6, FindInPageWchar(tab, L"goa",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(6, FindInPageWchar(tab, L"goa",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(2, ordinal);
+ EXPECT_EQ(6, FindInPageWchar(tab, L"goa",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+ // Add space to search (should result in no matches).
+ EXPECT_EQ(0, FindInPageWchar(tab, L"goa ",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+ // Remove the space, should be back to '3 out of 6')
+ EXPECT_EQ(6, FindInPageWchar(tab, L"goa",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(3, ordinal);
+}
+
+// Load a page with no selectable text and make sure we don't crash.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindUnSelectableText) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kUserSelectPage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ // The search string is present but doesn't qualify to be found
+ EXPECT_EQ(0, FindInPageWchar(tab, L"text",
+ kFwd, kIgnoreCase, &ordinal));
+ // With zero results there should be no current selection.
+ EXPECT_EQ(0, ordinal);
+}
+
+// Try to reproduce the crash seen in issue 1341577.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kCrashPage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // This would crash the tab. These must be the first two find requests issued
+ // against the frame, otherwise an active frame pointer is set and it wont
+ // produce the crash.
+ // We used to check the return value and |ordinal|. With ICU 4.2, FiP does
+ // not find a stand-alone dependent vowel sign of Indic scripts. So, the
+ // exptected values are all 0. To make this test pass regardless of
+ // ICU version, we just call FiP and see if there's any crash.
+ // TODO(jungshik): According to a native Malayalam speaker, it's ok not
+ // to find U+0D4C. Still need to investigate further this issue.
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ FindInPageWchar(tab, L"\u0D4C", kFwd, kIgnoreCase, &ordinal);
+ FindInPageWchar(tab, L"\u0D4C", kFwd, kIgnoreCase, &ordinal);
+
+ // This should work fine.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"\u0D24\u0D46",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+ EXPECT_EQ(0, FindInPageWchar(tab, L"nostring",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+}
+
+// Try to reproduce the crash seen in http://crbug.com/14491, where an assert
+// hits in the BitStack size comparison in WebKit.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindCrash_Issue14491) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kBitstackCrash);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // This used to crash the tab.
+ int ordinal = 0;
+ EXPECT_EQ(0, FindInPageWchar(browser()->GetSelectedTabContents(),
+ L"s", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+}
+
+// Test to make sure Find does the right thing when restarting from a timeout.
+// We used to have a problem where we'd stop finding matches when all of the
+// following conditions were true:
+// 1) The page has a lot of text to search.
+// 2) The page contains more than one match.
+// 3) It takes longer than the time-slice given to each Find operation (100
+// ms) to find one or more of those matches (so Find times out and has to try
+// again from where it left off).
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindRestarts_Issue1155639) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our page.
+ GURL url = test_server()->GetURL(kTooFewMatchesPage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // This string appears 5 times at the bottom of a long page. If Find restarts
+ // properly after a timeout, it will find 5 matches, not just 1.
+ int ordinal = 0;
+ EXPECT_EQ(5, FindInPageWchar(browser()->GetSelectedTabContents(),
+ L"008.xml",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+}
+
+// This tests bug 11761: FindInPage terminates search prematurely.
+// This test is not expected to pass until bug 11761 is fixed.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
+ DISABLED_FindInPagePrematureEnd) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our special focus tracking page.
+ GURL url = test_server()->GetURL(kPrematureEnd);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ TabContents* tab_contents = browser()->GetSelectedTabContents();
+ ASSERT_TRUE(NULL != tab_contents);
+
+ // Search for a text that exists within a link on the page.
+ int ordinal = 0;
+ EXPECT_EQ(2, FindInPageWchar(tab_contents, L"html ",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+}
+
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindDisappearOnNavigate) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our special focus tracking page.
+ GURL url = test_server()->GetURL(kSimplePage);
+ GURL url2 = test_server()->GetURL(kFramePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ browser()->ShowFindBar();
+
+ gfx::Point position;
+ bool fully_visible = false;
+
+ // Make sure it is open.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ // Reload the tab and make sure Find window doesn't go away.
+ browser()->Reload(CURRENT_TAB);
+ ui_test_utils::WaitForNavigationInCurrentTab(browser());
+
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ // Navigate and make sure the Find window goes away.
+ ui_test_utils::NavigateToURL(browser(), url2);
+
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_FALSE(fully_visible);
+}
+
+#if defined(OS_MACOSX)
+// FindDisappearOnNewTabAndHistory is flaky, at least on Mac.
+// See http://crbug.com/43072
+#define FindDisappearOnNewTabAndHistory FLAKY_FindDisappearOnNewTabAndHistory
+#endif
+
+// Make sure Find box disappears when History/Downloads page is opened, and
+// when a New Tab is opened.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
+ FindDisappearOnNewTabAndHistory) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our special focus tracking page.
+ GURL url = test_server()->GetURL(kSimplePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ browser()->ShowFindBar();
+
+ gfx::Point position;
+ bool fully_visible = false;
+
+ // Make sure it is open.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ // Open another tab (tab B).
+ browser()->NewTab();
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Make sure Find box is closed.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_FALSE(fully_visible);
+
+ // Close tab B.
+ browser()->CloseTab();
+
+ // Make sure Find window appears again.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ browser()->ShowHistoryTab();
+
+ // Make sure Find box is closed.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_FALSE(fully_visible);
+}
+
+// TODO(rohitrao): The FindMovesWhenObscuring test does not pass on mac.
+// http://crbug.com/22036
+#if defined(OS_MACOSX)
+#define MAYBE_FindMovesWhenObscuring FAILS_FindMovesWhenObscuring
+#else
+#define MAYBE_FindMovesWhenObscuring FindMovesWhenObscuring
+#endif
+
+// Make sure Find box moves out of the way if it is obscuring the active match.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_FindMovesWhenObscuring) {
+ ASSERT_TRUE(test_server()->Start());
+
+ GURL url = test_server()->GetURL(kMoveIfOver);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ browser()->ShowFindBar();
+
+ // This is needed on GTK because the reposition operation is asynchronous.
+ MessageLoop::current()->RunAllPending();
+
+ gfx::Point start_position;
+ gfx::Point position;
+ bool fully_visible = false;
+
+ // Make sure it is open.
+ EXPECT_TRUE(GetFindBarWindowInfo(&start_position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ // Search for 'Chromium' which the Find box is obscuring.
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ int index = 0;
+ for (; index < kMoveIterations; ++index) {
+ EXPECT_EQ(kMoveIterations, FindInPageWchar(tab, L"Chromium",
+ kFwd, kIgnoreCase, &ordinal));
+
+ // Check the position.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ // If the Find box has moved then we are done.
+ if (position.x() != start_position.x())
+ break;
+ }
+
+ // We should not have reached the end.
+ ASSERT_GT(kMoveIterations, index);
+
+ // Search for something guaranteed not to be obscured by the Find box.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"Done",
+ kFwd, kIgnoreCase, &ordinal));
+ // Check the position.
+ EXPECT_TRUE(GetFindBarWindowInfo(&position, &fully_visible));
+ EXPECT_TRUE(fully_visible);
+
+ // Make sure Find box has moved back to its original location.
+ EXPECT_EQ(position.x(), start_position.x());
+}
+
+#if defined(OS_MACOSX)
+// FindNextInNewTabUsesPrepopulate times-out, at least on Mac.
+// See http://crbug.com/43070
+#define FindNextInNewTabUsesPrepopulate DISABLED_FindNextInNewTabUsesPrepopulate
+#endif
+
+// Make sure F3 in a new tab works if Find has previous string to search for.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
+ FindNextInNewTabUsesPrepopulate) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimplePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for 'no_match'. No matches should be found.
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ EXPECT_EQ(0, FindInPageWchar(tab, L"no_match",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+
+ // Open another tab (tab B).
+ browser()->NewTab();
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Simulate what happens when you press F3 for FindNext. We should get a
+ // response here (a hang means search was aborted).
+ EXPECT_EQ(0, ui_test_utils::FindInPage(tab, string16(),
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+
+ // Open another tab (tab C).
+ browser()->NewTab();
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Simulate what happens when you press F3 for FindNext. We should get a
+ // response here (a hang means search was aborted).
+ EXPECT_EQ(0, ui_test_utils::FindInPage(tab, string16(),
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(0, ordinal);
+}
+
+#if defined(TOOLKIT_VIEWS)
+// Make sure Find box grabs the Esc accelerator and restores it again.
+#if defined(OS_LINUX)
+// TODO(oshima): On Gtk/Linux, a focus out event is asynchronous and
+// hiding a find bar does not immediately update the target
+// accelerator. The last condition fails in most cases due to this
+// behavior. See http://crbug.com/26870.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest,
+ DISABLED_AcceleratorRestoring) {
+#else
+ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, AcceleratorRestoring) {
+#endif
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimplePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ views::FocusManager* focus_manager =
+ views::FocusManager::GetFocusManagerForNativeWindow(
+ browser()->window()->GetNativeHandle());
+
+ // See where Escape is registered.
+ views::Accelerator escape(app::VKEY_ESCAPE, false, false, false);
+ views::AcceleratorTarget* old_target =
+ focus_manager->GetCurrentTargetForAccelerator(escape);
+ EXPECT_TRUE(old_target != NULL);
+
+ browser()->ShowFindBar();
+
+ // Our Find bar should be the new target.
+ views::AcceleratorTarget* new_target =
+ focus_manager->GetCurrentTargetForAccelerator(escape);
+
+ EXPECT_TRUE(new_target != NULL);
+ EXPECT_NE(new_target, old_target);
+
+ // Close the Find box.
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // The accelerator for Escape should be back to what it was before.
+ EXPECT_EQ(old_target,
+ focus_manager->GetCurrentTargetForAccelerator(escape));
+}
+#endif // TOOLKIT_VIEWS
+
+// Make sure Find box does not become UI-inactive when no text is in the box as
+// we switch to a tab contents with an empty find string. See issue 13570.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, StayActive) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimplePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ browser()->ShowFindBar();
+
+ // Simulate a user clearing the search string. Ideally, we should be
+ // simulating keypresses here for searching for something and pressing
+ // backspace, but that's been proven flaky in the past, so we go straight to
+ // tab_contents.
+ TabContents* tab_contents = browser()->GetSelectedTabContents();
+ // Stop the (non-existing) find operation, and clear the selection (which
+ // signals the UI is still active).
+ tab_contents->StopFinding(FindBarController::kClearSelection);
+ // Make sure the Find UI flag hasn't been cleared, it must be so that the UI
+ // still responds to browser window resizing.
+ ASSERT_TRUE(tab_contents->find_ui_active());
+}
+
+// Make sure F3 works after you FindNext a couple of times and end the Find
+// session. See issue http://crbug.com/28306.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, RestartSearchFromF3) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to a simple page.
+ GURL url = test_server()->GetURL(kSimple);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for 'page'. Should have 1 match.
+ int ordinal = 0;
+ TabContents* tab = browser()->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(tab, L"page", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // Simulate what happens when you press F3 for FindNext. Still should show
+ // one match. This cleared the pre-populate string at one point (see bug).
+ EXPECT_EQ(1, ui_test_utils::FindInPage(tab, string16(),
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+
+ // End the Find session, thereby making the next F3 start afresh.
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // Simulate F3 while Find box is closed. Should have 1 match.
+ EXPECT_EQ(1, FindInPageWchar(tab, L"", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(1, ordinal);
+}
+
+// When re-opening the find bar with F3, the find bar should be re-populated
+// with the last search from the same tab rather than the last overall search.
+// http://crbug.com/30006
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PreferPreviousSearch) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimplePage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Find "Default".
+ int ordinal = 0;
+ TabContents* tab1 = browser()->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(tab1, L"Default", kFwd, kIgnoreCase, &ordinal));
+
+ // Create a second tab.
+ // For some reason we can't use AddSelectedTabWithURL here on ChromeOS. It
+ // could be some delicate assumption about the tab starting off unselected or
+ // something relating to user gesture.
+ browser::NavigateParams params(browser(), url, PageTransition::TYPED);
+ params.disposition = NEW_BACKGROUND_TAB;
+ params.tabstrip_add_types = TabStripModel::ADD_NONE;
+ browser::Navigate(&params);
+ browser()->SelectTabContentsAt(1, false);
+ TabContents* tab2 = browser()->GetSelectedTabContents();
+ EXPECT_NE(tab1, tab2);
+
+ // Find "given".
+ FindInPageWchar(tab2, L"given", kFwd, kIgnoreCase, &ordinal);
+
+ // Switch back to first tab.
+ browser()->SelectTabContentsAt(0, false);
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+ // Simulate F3.
+ ui_test_utils::FindInPage(tab1, string16(), kFwd, kIgnoreCase, &ordinal);
+ EXPECT_EQ(tab1->find_text(), WideToUTF16(L"Default"));
+}
+
+// This tests that whenever you close and reopen the Find bar, it should show
+// the last search entered in that tab. http://crbug.com/40121.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulateSameTab) {
+#if defined(OS_MACOSX)
+ // FindInPage on Mac doesn't use prepopulated values. Search there is global.
+ return;
+#endif
+
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimple);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for the word "page".
+ int ordinal = 0;
+ TabContents* tab1 = browser()->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal));
+
+ // Open the Find box.
+ EnsureFindBoxOpen();
+
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
+ EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
+
+ // Close the Find box.
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // Open the Find box again.
+ EnsureFindBoxOpen();
+
+ // After the Find box has been reopened, it should have been prepopulated with
+ // the word "page" again.
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
+ EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
+}
+
+// This tests that whenever you open Find in a new tab it should prepopulate
+// with a previous search term (in any tab), if a search has not been issued in
+// this tab before.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulateInNewTab) {
+#if defined(OS_MACOSX)
+ // FindInPage on Mac doesn't use prepopulated values. Search there is global.
+ return;
+#endif
+
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimple);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for the word "page".
+ int ordinal = 0;
+ TabContents* tab1 = browser()->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText());
+
+ // Now create a second tab and load the same page.
+ browser()->AddSelectedTabWithURL(url, PageTransition::TYPED);
+ TabContents* tab2 = browser()->GetSelectedTabContents();
+ EXPECT_NE(tab1, tab2);
+
+ // Open the Find box.
+ EnsureFindBoxOpen();
+
+ // The new tab should have "page" prepopulated, since that was the last search
+ // in the first tab.
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
+ // But it should not seem like a search has been issued.
+ EXPECT_EQ(ASCIIToUTF16(""), GetMatchCountText());
+}
+
+// This makes sure that we can search for A in tabA, then for B in tabB and
+// when we come back to tabA we should still see A (because that was the last
+// search in that tab).
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulatePreserveLast) {
+#if defined(OS_MACOSX)
+ // FindInPage on Mac doesn't use prepopulated values. Search there is global.
+ return;
+#endif
+
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to any page.
+ GURL url = test_server()->GetURL(kSimple);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for the word "page".
+ int ordinal = 0;
+ TabContents* tab1 = browser()->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal));
+
+ // Open the Find box.
+ EnsureFindBoxOpen();
+
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
+
+ // Close the Find box.
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // Now create a second tab and load the same page.
+ browser::NavigateParams params(browser(), url, PageTransition::TYPED);
+ params.disposition = NEW_BACKGROUND_TAB;
+ params.tabstrip_add_types = TabStripModel::ADD_NONE;
+ browser::Navigate(&params);
+ browser()->SelectTabContentsAt(1, false);
+ TabContents* tab2 = browser()->GetSelectedTabContents();
+ EXPECT_NE(tab1, tab2);
+
+ // Search for the word "text".
+ FindInPageWchar(tab2, L"text", kFwd, kIgnoreCase, &ordinal);
+
+ // Go back to the first tab and make sure we have NOT switched the prepopulate
+ // text to "text".
+ browser()->SelectTabContentsAt(0, false);
+
+ // Open the Find box.
+ EnsureFindBoxOpen();
+
+ // After the Find box has been reopened, it should have been prepopulated with
+ // the word "page" again, since that was the last search in that tab.
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
+
+ // Close the Find box.
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // Re-open the Find box.
+ // This is a special case: previous search in TabContents used to get cleared
+ // if you opened and closed the FindBox, which would cause the global
+ // prepopulate value to show instead of last search in this tab.
+ EnsureFindBoxOpen();
+
+ // After the Find box has been reopened, it should have been prepopulated with
+ // the word "page" again, since that was the last search in that tab.
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarText());
+}
+
+// TODO(rohitrao): Searching in incognito tabs does not work in browser tests in
+// Linux views. Investigate and fix. http://crbug.com/40948
+#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
+#define MAYBE_NoIncognitoPrepopulate DISABLED_NoIncognitoPrepopulate
+#else
+#define MAYBE_NoIncognitoPrepopulate NoIncognitoPrepopulate
+#endif
+
+// This tests that search terms entered into an incognito find bar are not used
+// as prepopulate terms for non-incognito windows.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_NoIncognitoPrepopulate) {
+#if defined(OS_MACOSX)
+ // FindInPage on Mac doesn't use prepopulated values. Search there is global.
+ return;
+#endif
+
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to the "simple" test page.
+ GURL url = test_server()->GetURL(kSimple);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ // Search for the word "page" in the normal browser tab.
+ int ordinal = 0;
+ TabContents* tab1 = browser()->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal));
+
+ // Open the Find box.
+ EnsureFindBoxOpenForBrowser(browser());
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(browser()));
+
+ // Close the Find box.
+ browser()->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // Open a new incognito window and navigate to the same page.
+ Profile* incognito_profile = browser()->profile()->GetOffTheRecordProfile();
+ Browser* incognito_browser = Browser::Create(incognito_profile);
+ incognito_browser->AddSelectedTabWithURL(url, PageTransition::START_PAGE);
+ ui_test_utils::WaitForNavigation(
+ &incognito_browser->GetSelectedTabContents()->controller());
+ incognito_browser->window()->Show();
+
+ // Open the find box and make sure that it is prepopulated with "page".
+ EnsureFindBoxOpenForBrowser(incognito_browser);
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(incognito_browser));
+
+ // Search for the word "text" in the incognito tab.
+ TabContents* incognito_tab = incognito_browser->GetSelectedTabContents();
+ EXPECT_EQ(1, FindInPageWchar(incognito_tab, L"text",
+ kFwd, kIgnoreCase, &ordinal));
+ EXPECT_EQ(ASCIIToUTF16("text"), GetFindBarTextForBrowser(incognito_browser));
+
+ // Close the Find box.
+ incognito_browser->GetFindBarController()->EndFindSession(
+ FindBarController::kKeepSelection);
+
+ // Now open a new tab in the original (non-incognito) browser.
+ browser()->AddSelectedTabWithURL(url, PageTransition::TYPED);
+ TabContents* tab2 = browser()->GetSelectedTabContents();
+ EXPECT_NE(tab1, tab2);
+
+ // Open the Find box and make sure it is prepopulated with the search term
+ // from the original browser, not the search term from the incognito window.
+ EnsureFindBoxOpenForBrowser(browser());
+ EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(browser()));
+}
+
+// This makes sure that dismissing the find bar with kActivateSelection works.
+IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, ActivateLinkNavigatesPage) {
+ ASSERT_TRUE(test_server()->Start());
+
+ // First we navigate to our test content.
+ GURL url = test_server()->GetURL(kLinkPage);
+ ui_test_utils::NavigateToURL(browser(), url);
+
+ TabContents* tab = browser()->GetSelectedTabContents();
+ int ordinal = 0;
+ FindInPageWchar(tab, L"link", kFwd, kIgnoreCase, &ordinal);
+ EXPECT_EQ(ordinal, 1);
+
+ // End the find session, click on the link.
+ tab->StopFinding(FindBarController::kActivateSelection);
+ EXPECT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser()));
+}
diff --git a/chrome/browser/ui/find_bar/find_bar_state.cc b/chrome/browser/ui/find_bar/find_bar_state.cc
new file mode 100644
index 0000000..667ac53
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_bar_state.cc
@@ -0,0 +1,20 @@
+// 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/profile.h"
+#include "chrome/browser/ui/find_bar/find_bar_state.h"
+
+// static
+string16 FindBarState::GetLastPrepopulateText(Profile* p) {
+ FindBarState* state = p->GetFindBarState();
+ string16 text = state->last_prepopulate_text();
+
+ if (text.empty() && p->IsOffTheRecord()) {
+ // Fall back to the original profile.
+ state = p->GetOriginalProfile()->GetFindBarState();
+ text = state->last_prepopulate_text();
+ }
+
+ return text;
+}
diff --git a/chrome/browser/ui/find_bar/find_bar_state.h b/chrome/browser/ui/find_bar/find_bar_state.h
new file mode 100644
index 0000000..57f2d2e
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_bar_state.h
@@ -0,0 +1,41 @@
+// 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.
+
+// Stores per-profile state needed for find in page. This includes the most
+// recently searched for term.
+
+#ifndef CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_STATE_H_
+#define CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_STATE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+
+class Profile;
+
+class FindBarState {
+ public:
+ FindBarState() {}
+ ~FindBarState() {}
+
+ string16 last_prepopulate_text() const {
+ return last_prepopulate_text_;
+ }
+
+ void set_last_prepopulate_text(const string16& text) {
+ last_prepopulate_text_ = text;
+ }
+
+ // Retrieves the last prepopulate text for a given Profile. If the profile is
+ // off the record and has an empty prepopulate text, falls back to the
+ // prepopulate text from the normal profile.
+ static string16 GetLastPrepopulateText(Profile* profile);
+
+ private:
+ string16 last_prepopulate_text_;
+
+ DISALLOW_COPY_AND_ASSIGN(FindBarState);
+};
+
+#endif // CHROME_BROWSER_UI_FIND_BAR_FIND_BAR_STATE_H_
diff --git a/chrome/browser/ui/find_bar/find_notification_details.h b/chrome/browser/ui/find_bar/find_notification_details.h
new file mode 100644
index 0000000..d553782
--- /dev/null
+++ b/chrome/browser/ui/find_bar/find_notification_details.h
@@ -0,0 +1,51 @@
+// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_FIND_BAR_FIND_NOTIFICATION_DETAILS_H_
+#define CHROME_BROWSER_UI_FIND_BAR_FIND_NOTIFICATION_DETAILS_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "gfx/rect.h"
+
+class FindNotificationDetails {
+ public:
+ FindNotificationDetails(int request_id,
+ int number_of_matches,
+ const gfx::Rect& selection_rect,
+ int active_match_ordinal,
+ bool final_update)
+ : request_id_(request_id),
+ number_of_matches_(number_of_matches),
+ selection_rect_(selection_rect),
+ active_match_ordinal_(active_match_ordinal),
+ final_update_(final_update) {}
+
+ FindNotificationDetails()
+ : request_id_(0),
+ number_of_matches_(-1),
+ active_match_ordinal_(-1),
+ final_update_(false) {}
+
+ ~FindNotificationDetails() {}
+
+ int request_id() const { return request_id_; }
+
+ int number_of_matches() const { return number_of_matches_; }
+
+ gfx::Rect selection_rect() const { return selection_rect_; }
+
+ int active_match_ordinal() const { return active_match_ordinal_; }
+
+ bool final_update() const { return final_update_; }
+
+ private:
+ int request_id_; // The find-in-page request whose results we're returning.
+ int number_of_matches_; // How many matches were found.
+ gfx::Rect selection_rect_; // Where selection occurred (screen coordinate).
+ int active_match_ordinal_; // The ordinal of the currently selected match.
+ bool final_update_; // Whether this is the last Find Result update.
+};
+
+#endif // CHROME_BROWSER_UI_FIND_BAR_FIND_NOTIFICATION_DETAILS_H_
diff --git a/chrome/browser/ui/views/dropdown_bar_host_win.cc b/chrome/browser/ui/views/dropdown_bar_host_win.cc
index c14fb21..e3d27c8 100644
--- a/chrome/browser/ui/views/dropdown_bar_host_win.cc
+++ b/chrome/browser/ui/views/dropdown_bar_host_win.cc
@@ -4,10 +4,10 @@
#include "chrome/browser/views/dropdown_bar_host.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "views/controls/scrollbar/native_scroll_bar.h"
#include "views/widget/widget_win.h"
diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc
index 6dbea33..44cb187 100644
--- a/chrome/browser/ui/views/find_bar_host.cc
+++ b/chrome/browser/ui/views/find_bar_host.cc
@@ -6,9 +6,9 @@
#include "app/keyboard_codes.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/find_bar_view.h"
#include "chrome/browser/views/frame/browser_view.h"
diff --git a/chrome/browser/ui/views/find_bar_host.h b/chrome/browser/ui/views/find_bar_host.h
index 130b876..496cef0 100644
--- a/chrome/browser/ui/views/find_bar_host.h
+++ b/chrome/browser/ui/views/find_bar_host.h
@@ -6,8 +6,8 @@
#define CHROME_BROWSER_UI_VIEWS_FIND_BAR_HOST_H_
#pragma once
-#include "chrome/browser/find_bar.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
#include "chrome/browser/views/dropdown_bar_host.h"
#include "gfx/native_widget_types.h"
#include "gfx/rect.h"
diff --git a/chrome/browser/ui/views/find_bar_host_gtk.cc b/chrome/browser/ui/views/find_bar_host_gtk.cc
index d9f8986..e17c6d0 100644
--- a/chrome/browser/ui/views/find_bar_host_gtk.cc
+++ b/chrome/browser/ui/views/find_bar_host_gtk.cc
@@ -4,8 +4,8 @@
#include "chrome/browser/views/find_bar_host.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/views/tab_contents/tab_contents_view_gtk.h"
#include "views/widget/widget_gtk.h"
diff --git a/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc
index 8feecb8..361faa0 100644
--- a/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc
+++ b/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc
@@ -7,10 +7,10 @@
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tabs/tab_strip_model.h"
#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/views/find_bar_host.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "chrome/browser/view_ids.h"
diff --git a/chrome/browser/ui/views/find_bar_host_win.cc b/chrome/browser/ui/views/find_bar_host_win.cc
index e1e5a50..0133f60 100644
--- a/chrome/browser/ui/views/find_bar_host_win.cc
+++ b/chrome/browser/ui/views/find_bar_host_win.cc
@@ -4,10 +4,10 @@
#include "chrome/browser/views/find_bar_host.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/tab_contents/tab_contents_view.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/views/frame/browser_view.h"
#include "views/controls/scrollbar/native_scroll_bar.h"
#include "views/widget/widget_win.h"
diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc
index 94d46ad..12dbd4c 100644
--- a/chrome/browser/ui/views/find_bar_view.cc
+++ b/chrome/browser/ui/views/find_bar_view.cc
@@ -11,11 +11,11 @@
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/find_bar_controller.h"
-#include "chrome/browser/find_bar_state.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/browser/themes/browser_theme_provider.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
+#include "chrome/browser/ui/find_bar/find_bar_state.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/find_bar_host.h"
#include "chrome/browser/views/frame/browser_view.h"
diff --git a/chrome/browser/ui/views/find_bar_view.h b/chrome/browser/ui/views/find_bar_view.h
index f8197fe..92ab262 100644
--- a/chrome/browser/ui/views/find_bar_view.h
+++ b/chrome/browser/ui/views/find_bar_view.h
@@ -7,7 +7,7 @@
#pragma once
#include "base/string16.h"
-#include "chrome/browser/find_notification_details.h"
+#include "chrome/browser/ui/find_bar/find_notification_details.h"
#include "chrome/browser/views/dropdown_bar_view.h"
#include "gfx/size.h"
#include "views/controls/button/button.h"
diff --git a/chrome/browser/ui/views/frame/browser_view_layout.cc b/chrome/browser/ui/views/frame/browser_view_layout.cc
index 5b7dc66..6fa2b67 100644
--- a/chrome/browser/ui/views/frame/browser_view_layout.cc
+++ b/chrome/browser/ui/views/frame/browser_view_layout.cc
@@ -4,9 +4,9 @@
#include "chrome/browser/views/frame/browser_view_layout.h"
-#include "chrome/browser/find_bar.h"
-#include "chrome/browser/find_bar_controller.h"
#include "chrome/browser/sidebar/sidebar_manager.h"
+#include "chrome/browser/ui/find_bar/find_bar.h"
+#include "chrome/browser/ui/find_bar/find_bar_controller.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/download_shelf_view.h"