summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorfinnur@google.com <finnur@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-24 00:10:29 +0000
committerfinnur@google.com <finnur@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-02-24 00:10:29 +0000
commit4f3dc3751d69f9db1f8ef533a3335201b3bc78bc (patch)
treee37efecf992ddd4e901c894273cbb1e5bf4260cc /chrome/browser
parent5e7f161f73f1817b8a0c422c0e4b5eceae6954e7 (diff)
downloadchromium_src-4f3dc3751d69f9db1f8ef533a3335201b3bc78bc.zip
chromium_src-4f3dc3751d69f9db1f8ef533a3335201b3bc78bc.tar.gz
chromium_src-4f3dc3751d69f9db1f8ef533a3335201b3bc78bc.tar.bz2
The find bar should be owned and managed from the BrowserView, not the WebContentsView, since it's part of the "chrome".
Design Doc: http://dev.chromium.org/developers/design-documents/find-bar Things done: - Pulled all of the find bar stuff out of WebContentsView* since it's no longer needed. - Moved OnFindReply delegate method from RenderViewHostDelegate::View to RenderViewHostDelegate, since it's no longer implemented on the view. - Moved find control methods to WebContents. - Added recent find result state to WebContents. - Updated the UI tests to accommodate the changes in the state that is broadcast when results are discovered. - Updated the find bar layout to obtain its bounding box from the BrowserView, which knows about toolbars, bookmark bars etc. - Updated the find bar itself to handle the fact that it can be displayed for multiple different tabs. - Moved the find bar manipulation methods for testing from TabProxy to BrowserProxy, since the find bar is now a feature of the window, not the tab. - view.h: Don't lay out child views again if they have a layout manager, it already updated them. TEST=Find box should work as before. BUG=3245 Review URL: http://codereview.chromium.org/27025 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@10231 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc57
-rw-r--r--chrome/browser/browser.cc44
-rw-r--r--chrome/browser/browser.h9
-rw-r--r--chrome/browser/browser_window.h15
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.h12
-rw-r--r--chrome/browser/cocoa/browser_window_cocoa.mm4
-rw-r--r--chrome/browser/find_notification_details.h17
-rw-r--r--chrome/browser/gtk/browser_window_gtk.cc4
-rw-r--r--chrome/browser/gtk/browser_window_gtk.h1
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc7
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h15
-rw-r--r--chrome/browser/tab_contents/web_contents.cc82
-rw-r--r--chrome/browser/tab_contents/web_contents.h66
-rw-r--r--chrome/browser/tab_contents/web_contents_view.h41
-rw-r--r--chrome/browser/tab_contents/web_contents_view_win.cc74
-rw-r--r--chrome/browser/tab_contents/web_contents_view_win.h16
-rw-r--r--chrome/browser/views/find_bar_view.cc149
-rw-r--r--chrome/browser/views/find_bar_view.h41
-rw-r--r--chrome/browser/views/find_bar_win.cc427
-rw-r--r--chrome/browser/views/find_bar_win.h123
-rw-r--r--chrome/browser/views/find_bar_win_interactive_uitest.cc4
-rw-r--r--chrome/browser/views/find_bar_win_uitest.cc75
-rw-r--r--chrome/browser/views/find_bar_win_unittest.cc8
-rw-r--r--chrome/browser/views/frame/browser_view.cc82
-rw-r--r--chrome/browser/views/frame/browser_view.h26
25 files changed, 655 insertions, 744 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 013325c..926e507 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -7,7 +7,7 @@
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/thread.h"
-#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/app_modal_dialog_queue.h"
#include "chrome/browser/automation/automation_provider_list.h"
#include "chrome/browser/automation/ui_controls.h"
@@ -268,8 +268,8 @@ class NavigationNotificationObserver : public NotificationObserver {
// afer the load has started (but not after the entry was committed, as
// WaitForNavigation compares times of the last navigation).
// - when this is used with a page requiring authentication, we will not get
- // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so we need the
- // NotificationType::LOAD_START.
+ // a NotificationType::NAV_ENTRY_COMMITTED until after we authenticate, so
+ // we need the NotificationType::LOAD_START.
if (type == NotificationType::NAV_ENTRY_COMMITTED ||
type == NotificationType::LOAD_START) {
navigation_started_ = true;
@@ -360,7 +360,7 @@ class TabStripNotificationObserver : public NotificationObserver {
class TabAppendedNotificationObserver : public TabStripNotificationObserver {
public:
TabAppendedNotificationObserver(Browser* parent,
- AutomationProvider* automation, int32 routing_id,
+ AutomationProvider* automation, int32 routing_id,
IPC::Message* reply_message)
: TabStripNotificationObserver(parent, NotificationType::TAB_PARENTED,
automation, routing_id),
@@ -657,7 +657,7 @@ class AutomationInterstitialPage : public InterstitialPage {
private:
std::string contents_;
-
+
DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
};
@@ -1604,7 +1604,7 @@ void AutomationProvider::OnRedirectQueryComplete(
reply_message_->WriteInt(-1); // Negative count indicates failure.
}
- IPC::ParamTraits<std::vector<GURL>>::Write(reply_message_, redirects_gurl);
+ IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
Send(reply_message_);
redirect_query_ = NULL;
@@ -1806,14 +1806,10 @@ void AutomationProvider::HandleFindRequest(int handle,
reply_message->routing_id(),
reply_message));
- // The find in page dialog must be up for us to get the notification that the
- // find was complete.
WebContents* web_contents = tab_contents->AsWebContents();
if (web_contents) {
- NavigationController* tab = tab_tracker_->GetResource(handle);
- Browser* browser = Browser::GetBrowserForController(tab, NULL);
- web_contents->view()->FindInPage(*browser, true, request.forward);
-
+ web_contents->set_current_find_request_id(
+ FindInPageNotificationObserver::kFindInPageRequestId);
web_contents->render_view_host()->StartFinding(
FindInPageNotificationObserver::kFindInPageRequestId,
request.search_string, request.forward, request.match_case,
@@ -1823,29 +1819,33 @@ void AutomationProvider::HandleFindRequest(int handle,
void AutomationProvider::HandleOpenFindInPageRequest(
const IPC::Message& message, int handle) {
- NavigationController* tab = NULL;
- WebContents* web_contents = GetWebContentsForHandle(handle, &tab);
- if (web_contents) {
- Browser* browser = Browser::GetBrowserForController(tab, NULL);
- web_contents->view()->FindInPage(*browser, false, false);
+ if (browser_tracker_->ContainsHandle(handle)) {
+ Browser* browser = browser_tracker_->GetResource(handle);
+ browser->FindInPage(false, false);
}
}
void AutomationProvider::GetFindWindowVisibility(int handle, bool* visible) {
gfx::Point position;
*visible = false;
- WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
- if (web_contents)
- web_contents->view()->GetFindBarWindowInfo(&position, visible);
+ if (browser_tracker_->ContainsHandle(handle)) {
+ Browser* browser = browser_tracker_->GetResource(handle);
+ BrowserWindowTesting* testing =
+ browser->window()->GetBrowserWindowTesting();
+ testing->GetFindBarWindowInfo(&position, visible);
+ }
}
void AutomationProvider::HandleFindWindowLocationRequest(int handle, int* x,
int* y) {
gfx::Point position(0, 0);
bool visible = false;
- WebContents* web_contents = GetWebContentsForHandle(handle, NULL);
- if (web_contents)
- web_contents->view()->GetFindBarWindowInfo(&position, &visible);
+ if (browser_tracker_->ContainsHandle(handle)) {
+ Browser* browser = browser_tracker_->GetResource(handle);
+ BrowserWindowTesting* testing =
+ browser->window()->GetBrowserWindowTesting();
+ testing->GetFindBarWindowInfo(&position, &visible);
+ }
*x = position.x();
*y = position.y();
@@ -1926,8 +1926,8 @@ void AutomationProvider::SetFilteredInet(const IPC::Message& message,
new SetFilteredInetTask(enabled));
}
-void AutomationProvider::GetDownloadDirectory(int handle,
- std::wstring* download_directory) {
+void AutomationProvider::GetDownloadDirectory(
+ int handle, std::wstring* download_directory) {
DLOG(INFO) << "Handling download directory request";
if (tab_tracker_->ContainsHandle(handle)) {
NavigationController* tab = tab_tracker_->GetResource(handle);
@@ -2427,7 +2427,8 @@ void TestingAutomationProvider::OnBrowserRemoving(const Browser* browser) {
// want the automation provider (and hence the process) to go away when the
// last browser goes away.
if (BrowserList::size() == 1) {
- // If you change this, update Observer for NotificationType::SESSION_END below.
+ // If you change this, update Observer for NotificationType::SESSION_END
+ // below.
MessageLoop::current()->PostTask(FROM_HERE,
NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
}
@@ -2478,7 +2479,7 @@ void AutomationProvider::ClickSSLInfoBarLink(int handle,
success = true;
}
}
- }
+ }
if (!wait_for_navigation || !success)
AutomationMsg_ClickSSLInfoBarLink::WriteReplyParams(reply_message,
success);
@@ -2501,7 +2502,7 @@ void AutomationProvider::WaitForNavigation(int handle,
if (time.ToInternalValue() > last_navigation_time || !controller) {
AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
controller != NULL);
- return;
+ return;
}
AddNavigationStatusListener<bool>(controller, reply_message, true, true,
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index d91c114..9c479a6 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -845,18 +845,17 @@ void Browser::Paste() {
void Browser::Find() {
UserMetrics::RecordAction(L"Find", profile_);
- GetSelectedTabContents()->AsWebContents()->view()->FindInPage(*this, false,
- false);
+ FindInPage(false, false);
}
void Browser::FindNext() {
UserMetrics::RecordAction(L"FindNext", profile_);
- AdvanceFindSelection(true);
+ FindInPage(true, true);
}
void Browser::FindPrevious() {
UserMetrics::RecordAction(L"FindPrevious", profile_);
- AdvanceFindSelection(false);
+ FindInPage(true, false);
}
void Browser::ZoomIn() {
@@ -1238,20 +1237,6 @@ void Browser::CreateNewStripWithContents(TabContents* detached_contents,
// won't start if the page is loading.
browser->LoadingStateChanged(detached_contents);
browser->window()->Show();
-
-#if defined(OS_WIN)
- // When we detach a tab we need to make sure any associated Find window moves
- // along with it to its new home (basically we just make new_window the
- // parent of the Find window).
- // TODO(brettw) this could probably be improved, see
- // WebContentsView::ReparentFindWindow for more.
- WebContents* web_contents = detached_contents->AsWebContents();
- if (web_contents)
- web_contents->view()->ReparentFindWindow(browser);
-#else
- // TODO(port): remove the view dependency from this.
- NOTIMPLEMENTED() << "need to reparent find window";
-#endif
}
int Browser::GetDragActions() const {
@@ -1398,18 +1383,6 @@ void Browser::TabInsertedAt(TabContents* contents,
SyncHistoryWithTabs(tabstrip_model_.GetIndexOfTabContents(contents));
-#if defined(OS_WIN)
- // When a tab is dropped into a tab strip we need to make sure that the
- // associated Find window is moved along with it. We therefore change the
- // parent of the Find window (if the parent is already correctly set this
- // does nothing).
- // TODO(brettw) this could probably be improved, see
- // WebContentsView::ReparentFindWindow for more.
- WebContents* web_contents = contents->AsWebContents();
- if (web_contents)
- web_contents->view()->ReparentFindWindow(this);
-#endif
-
// Make sure the loading state is updated correctly, otherwise the throbber
// won't start if the page is loading.
LoadingStateChanged(contents);
@@ -2407,11 +2380,14 @@ GURL Browser::GetHomePage() {
}
#if defined(OS_WIN)
-void Browser::AdvanceFindSelection(bool forward_direction) {
- GetSelectedTabContents()->AsWebContents()->view()->FindInPage(
- *this, true, forward_direction);
+void Browser::FindInPage(bool find_next, bool forward_direction) {
+ window_->ShowFindBar();
+ if (find_next) {
+ GetSelectedTabContents()->AsWebContents()->StartFinding(
+ std::wstring(),
+ forward_direction);
+ }
}
-
#endif // OS_WIN
void Browser::CloseFrame() {
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index cce7bfc..828e9c6 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -508,9 +508,10 @@ class Browser : public TabStripModelDelegate,
GURL GetHomePage();
#if defined(OS_WIN)
- // Advance the find selection by one. Direction is either forward or
- // backwards depending on parameter passed in.
- void AdvanceFindSelection(bool forward_direction);
+ // Shows the Find Bar, optionally selecting the next entry that matches the
+ // existing search string for that Tab. |forward_direction| controls the
+ // search direction.
+ void FindInPage(bool find_next, bool forward_direction);
#endif
// Closes the frame.
@@ -571,7 +572,7 @@ class Browser : public TabStripModelDelegate,
private:
Browser* browser_;
- DISALLOW_EVIL_CONSTRUCTORS(BrowserToolbarModel);
+ DISALLOW_COPY_AND_ASSIGN(BrowserToolbarModel);
};
// The model for the toolbar view.
diff --git a/chrome/browser/browser_window.h b/chrome/browser/browser_window.h
index be21a1a..8a5ff21 100644
--- a/chrome/browser/browser_window.h
+++ b/chrome/browser/browser_window.h
@@ -16,6 +16,7 @@ class StatusBubble;
class TabContents;
namespace gfx {
+class Point;
class Rect;
}
@@ -123,6 +124,9 @@ class BrowserWindow {
// Shows or hides the bookmark bar depending on its current visibility.
virtual void ToggleBookmarkBar() = 0;
+ // Shows the Find Bar.
+ virtual void ShowFindBar() = 0;
+
// Shows the About Chrome dialog box.
virtual void ShowAboutChromeDialog() = 0;
@@ -182,7 +186,16 @@ class BrowserWindowTesting {
// Returns the LocationBarView.
virtual LocationBarView* GetLocationBarView() const = 0;
+
+ // 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 required.
+ //
+ // 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) const = 0;
#endif
};
-#endif // CHROME_BROWSER_BROWSER_WINDOW_H__
+#endif // CHROME_BROWSER_BROWSER_WINDOW_H_
diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h
index 1f7f59b..d4b3ffb 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.h
+++ b/chrome/browser/cocoa/browser_window_cocoa.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_WINDOW_COCOA_H_
-#define CHROME_BROWSER_WINDOW_COCOA_H_
+#ifndef CHROME_BROWSER_COCOA_BROWSER_WINDOW_COCOA_H_
+#define CHROME_BROWSER_COCOA_BROWSER_WINDOW_COCOA_H_
#include "chrome/browser/browser_window.h"
@@ -18,7 +18,7 @@ class BrowserWindowCocoa : public BrowserWindow {
public:
BrowserWindowCocoa(BrowserWindowController* controller, NSWindow* window);
virtual ~BrowserWindowCocoa();
-
+
// Overridden from BrowserWindow
virtual void Init();
virtual void Show();
@@ -46,6 +46,7 @@ class BrowserWindowCocoa : public BrowserWindow {
virtual bool IsBookmarkBarVisible() const;
virtual gfx::Rect GetRootWindowResizerRect() const;
virtual void ToggleBookmarkBar();
+ virtual void ShowFindBar();
virtual void ShowAboutChromeDialog();
virtual void ShowBookmarkManager();
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked);
@@ -58,13 +59,12 @@ class BrowserWindowCocoa : public BrowserWindow {
virtual void ShowNewProfileDialog();
virtual void ShowHTMLDialog(HtmlDialogContentsDelegate* delegate,
void* parent_window);
-
protected:
virtual void DestroyBrowser();
-
+
private:
BrowserWindowController* controller_; // weak, owns us
NSWindow* window_; // weak, owned by |controller_|
};
-#endif // CHROME_BROWSER_WINDOW_COCOA_H_
+#endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_COCOA_H_
diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm
index d54d0c7..6af331b 100644
--- a/chrome/browser/cocoa/browser_window_cocoa.mm
+++ b/chrome/browser/cocoa/browser_window_cocoa.mm
@@ -135,6 +135,10 @@ void BrowserWindowCocoa::ToggleBookmarkBar() {
NOTIMPLEMENTED();
}
+void BrowserWindowCocoa::ShowFindBar() {
+ NOTIMPLEMENTED();
+}
+
void BrowserWindowCocoa::ShowAboutChromeDialog() {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/find_notification_details.h b/chrome/browser/find_notification_details.h
index 23033ae..45dd331 100644
--- a/chrome/browser/find_notification_details.h
+++ b/chrome/browser/find_notification_details.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef CHROME_BROWSER_FIND_NOTIFICATION_DETAILS_H__
-#define CHROME_BROWSER_FIND_NOTIFICATION_DETAILS_H__
+#ifndef CHROME_BROWSER_FIND_NOTIFICATION_DETAILS_H_
+#define CHROME_BROWSER_FIND_NOTIFICATION_DETAILS_H_
#include "base/basictypes.h"
#include "base/gfx/rect.h"
@@ -21,6 +21,12 @@ class FindNotificationDetails {
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_; }
@@ -39,11 +45,6 @@ class FindNotificationDetails {
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.
-
- FindNotificationDetails() {}
-
- DISALLOW_EVIL_CONSTRUCTORS(FindNotificationDetails);
};
-#endif // CHROME_BROWSER_FIND_NOTIFICATION_DETAILS_H__
-
+#endif // CHROME_BROWSER_FIND_NOTIFICATION_DETAILS_H_
diff --git a/chrome/browser/gtk/browser_window_gtk.cc b/chrome/browser/gtk/browser_window_gtk.cc
index 06ad7af..6535539 100644
--- a/chrome/browser/gtk/browser_window_gtk.cc
+++ b/chrome/browser/gtk/browser_window_gtk.cc
@@ -290,6 +290,10 @@ void BrowserWindowGtk::ToggleBookmarkBar() {
NOTIMPLEMENTED();
}
+void BrowserWindowGtk::ShowFindBar() {
+ NOTIMPLEMENTED();
+}
+
void BrowserWindowGtk::ShowAboutChromeDialog() {
NOTIMPLEMENTED();
}
diff --git a/chrome/browser/gtk/browser_window_gtk.h b/chrome/browser/gtk/browser_window_gtk.h
index 70ed990..adc1e91 100644
--- a/chrome/browser/gtk/browser_window_gtk.h
+++ b/chrome/browser/gtk/browser_window_gtk.h
@@ -54,6 +54,7 @@ class BrowserWindowGtk : public BrowserWindow,
virtual bool IsBookmarkBarVisible() const;
virtual gfx::Rect GetRootWindowResizerRect() const;
virtual void ToggleBookmarkBar();
+ virtual void ShowFindBar();
virtual void ShowAboutChromeDialog();
virtual void ShowBookmarkManager();
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked);
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index ae84b8f..723e91e9 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -966,11 +966,8 @@ void RenderViewHost::OnMsgFindReply(int request_id,
const gfx::Rect& selection_rect,
int active_match_ordinal,
bool final_update) {
- RenderViewHostDelegate::View* view = delegate_->GetViewDelegate();
- if (!view)
- return;
- view->OnFindReply(request_id, number_of_matches, selection_rect,
- active_match_ordinal, final_update);
+ delegate_->OnFindReply(request_id, number_of_matches, selection_rect,
+ active_match_ordinal, final_update);
// Send a notification to the renderer that we are ready to receive more
// results from the scoping effort of the Find operation. The FindInPage
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index 7cfe6f9..67ac07e 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -112,13 +112,6 @@ class RenderViewHostDelegate {
// specified events. This gives an opportunity to the browser to process the
// event (used for keyboard shortcuts).
virtual void HandleKeyboardEvent(const WebKeyboardEvent& event) = 0;
-
- // A find operation in the current page completed.
- virtual void OnFindReply(int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) = 0;
};
// Interface for saving web pages.
@@ -401,7 +394,13 @@ class RenderViewHostDelegate {
// If this view can be terminated without any side effects
virtual bool CanTerminate() const { return true; }
+
+ // A find operation in the current page completed.
+ virtual void OnFindReply(int request_id,
+ int number_of_matches,
+ const gfx::Rect& selection_rect,
+ int active_match_ordinal,
+ bool final_update) { }
};
#endif // CHROME_BROWSER_RENDERER_HOST_RENDER_VIEW_HOST_DELEGATE_H_
-
diff --git a/chrome/browser/tab_contents/web_contents.cc b/chrome/browser/tab_contents/web_contents.cc
index 54b8d6e..ecf33c9 100644
--- a/chrome/browser/tab_contents/web_contents.cc
+++ b/chrome/browser/tab_contents/web_contents.cc
@@ -182,6 +182,9 @@ class WebContents::GearsCreateShortcutCallbackFunctor {
WebContents* contents_;
};
+// static
+int WebContents::find_request_id_counter_ = -1;
+
WebContents::WebContents(Profile* profile,
SiteInstance* site_instance,
RenderViewHostFactory* render_view_factory,
@@ -201,8 +204,10 @@ WebContents::WebContents(Profile* profile,
#endif
ALLOW_THIS_IN_INITIALIZER_LIST(fav_icon_helper_(this)),
suppress_javascript_messages_(false),
- load_state_(net::LOAD_STATE_IDLE) {
-
+ load_state_(net::LOAD_STATE_IDLE),
+ find_ui_active_(false),
+ find_op_aborted_(false),
+ current_find_request_id_(find_request_id_counter_++) {
pending_install_.page_id = 0;
pending_install_.callback_functor = NULL;
@@ -532,6 +537,43 @@ void WebContents::CreateShortcut() {
render_view_host()->GetApplicationInfo(pending_install_.page_id);
}
+void WebContents::StartFinding(const std::wstring& find_text,
+ bool forward_direction) {
+ // If find_text is empty, it means FindNext was pressed with a keyboard
+ // shortcut so unless we have something to search for we return early.
+ if (find_text.empty() && find_text_.empty())
+ return;
+
+ // This is a FindNext operation if we are searching for the same text again,
+ // or if the passed in search text is empty (FindNext keyboard shortcut). The
+ // exception to this is if the Find was aborted (then we don't want FindNext
+ // because the highlighting has been cleared and we need it to reappear). We
+ // therefore treat FindNext after an aborted Find operation as a full fledged
+ // Find.
+ bool find_next = (find_text_ == find_text || find_text.empty()) &&
+ !find_op_aborted_;
+ if (!find_next)
+ current_find_request_id_ = find_request_id_counter_++;
+
+ if (!find_text.empty())
+ find_text_ = find_text;
+
+ find_op_aborted_ = false;
+
+ render_view_host()->StartFinding(current_find_request_id_,
+ find_text_,
+ forward_direction,
+ false, // case sensitive
+ find_next);
+}
+
+void WebContents::StopFinding(bool clear_selection) {
+ find_ui_active_ = false;
+ find_op_aborted_ = true;
+ find_result_ = FindNotificationDetails();
+ render_view_host()->StopFinding(clear_selection);
+}
+
void WebContents::OnJavaScriptMessageBoxClosed(IPC::Message* reply_msg,
bool success,
const std::wstring& prompt) {
@@ -591,9 +633,6 @@ bool WebContents::PrintNow() {
if (showing_interstitial_page())
return false;
- // If we have a find bar it needs to hide as well.
- view_->HideFindBar(false);
-
return render_view_host()->PrintPages();
}
@@ -1356,6 +1395,33 @@ void WebContents::OnEnterOrSpace() {
#endif
}
+void WebContents::OnFindReply(int request_id,
+ int number_of_matches,
+ const gfx::Rect& selection_rect,
+ int active_match_ordinal,
+ bool final_update) {
+ // Ignore responses for requests other than the one we have most recently
+ // issued. That way we won't act on stale results when the user has
+ // already typed in another query.
+ if (request_id != current_find_request_id_)
+ return;
+
+ if (number_of_matches == -1)
+ number_of_matches = find_result_.number_of_matches();
+ if (active_match_ordinal == -1)
+ active_match_ordinal = find_result_.active_match_ordinal();
+
+ // Notify the UI, automation and any other observers that a find result was
+ // found.
+ find_result_ = FindNotificationDetails(request_id, number_of_matches,
+ selection_rect, active_match_ordinal,
+ final_update);
+ NotificationService::current()->Notify(
+ NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(this),
+ Details<FindNotificationDetails>(&find_result_));
+}
+
bool WebContents::CanTerminate() const {
if (!delegate())
return true;
@@ -1498,12 +1564,6 @@ void WebContents::DidNavigateMainFramePostCommit(
// Close constrained popups if necessary.
MaybeCloseChildWindows(details.previous_url, details.entry->url());
- // We hide the FindInPage window when the user navigates away, except on
- // reload.
- if (PageTransition::StripQualifier(params.transition) !=
- PageTransition::RELOAD)
- view_->HideFindBar(true);
-
// Update the starred state.
UpdateStarredStateForCurrentURL();
}
diff --git a/chrome/browser/tab_contents/web_contents.h b/chrome/browser/tab_contents/web_contents.h
index 52b48fe..08ac907 100644
--- a/chrome/browser/tab_contents/web_contents.h
+++ b/chrome/browser/tab_contents/web_contents.h
@@ -14,6 +14,7 @@
#include "chrome/browser/cancelable_request.h"
#include "chrome/browser/download/save_package.h"
#include "chrome/browser/fav_icon_helper.h"
+#include "chrome/browser/find_notification_details.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/render_view_host_manager.h"
@@ -171,6 +172,40 @@ class WebContents : public TabContents,
return render_manager_.interstitial_page();
}
+ // Find in Page --------------------------------------------------------------
+
+ // Starts the Find operation by calling StartFinding on the Tab. This function
+ // can be called from the outside as a result of hot-keys, so it uses the
+ // last remembered search string as specified with set_find_string(). This
+ // function does not block while a search is in progress. The controller will
+ // receive the results through the notification mechanism. See Observe(...)
+ // for details.
+ void StartFinding(const std::wstring& find_text, bool forward_direction);
+
+ // Stops the current Find operation. If |clear_selection| is true, it will
+ // also clear the selection on the focused frame.
+ void StopFinding(bool clear_selection);
+
+ // Accessors/Setters for find_ui_active_.
+ bool find_ui_active() const { return find_ui_active_; }
+ void set_find_ui_active(bool find_ui_active) {
+ find_ui_active_ = find_ui_active;
+ }
+
+ // Used _only_ by testing to set the current request ID, since it calls
+ // StartFinding on the RenderViewHost directly, rather than by using
+ // StartFinding's more limited API.
+ void set_current_find_request_id(int current_find_request_id) {
+ current_find_request_id_ = current_find_request_id;
+ }
+
+ // Accessor for find_text_. Used to determine if this WebContents has any
+ // active searches.
+ std::wstring find_text() const { return find_text_; }
+
+ // Accessor for find_result_.
+ const FindNotificationDetails& find_result() const { return find_result_; }
+
// Misc state & callbacks ----------------------------------------------------
// Set whether the contents should block javascript message boxes or not.
@@ -346,6 +381,11 @@ class WebContents : public TabContents,
int32 page_id,
const webkit_glue::WebApplicationInfo& info);
virtual void OnEnterOrSpace();
+ virtual void OnFindReply(int request_id,
+ int number_of_matches,
+ const gfx::Rect& selection_rect,
+ int active_match_ordinal,
+ bool final_update);
virtual bool CanTerminate() const;
@@ -589,6 +629,32 @@ class WebContents : public TabContents,
net::LoadState load_state_;
std::wstring load_state_host_;
+ // True if the Find UI is active for this Tab.
+ bool find_ui_active_;
+
+ // True if a Find operation was aborted. This can happen if the Find box is
+ // closed or if the search term inside the Find box is erased while a search
+ // is in progress.
+ bool find_op_aborted_;
+
+ // Each time a search request comes in we assign it an id before passing it
+ // over the IPC so that when the results come in we can evaluate whether we
+ // still care about the results of the search (in some cases we don't because
+ // the user has issued a new search).
+ static int find_request_id_counter_;
+
+ // This variable keeps track of what the most recent request id is.
+ int current_find_request_id_;
+
+ // The last string we searched for. This is used to figure out if this is a
+ // Find or a FindNext operation (FindNext should not increase the request id).
+ std::wstring find_text_;
+
+ // The last find result. This object contains details about the number of
+ // matches, the find selection rectangle, etc. The UI can access this
+ // information to build its presentation.
+ FindNotificationDetails find_result_;
+
DISALLOW_COPY_AND_ASSIGN(WebContents);
};
diff --git a/chrome/browser/tab_contents/web_contents_view.h b/chrome/browser/tab_contents/web_contents_view.h
index 4bf8dca..1a8b4f6 100644
--- a/chrome/browser/tab_contents/web_contents_view.h
+++ b/chrome/browser/tab_contents/web_contents_view.h
@@ -108,47 +108,6 @@ class WebContentsView : public RenderViewHostDelegate::View {
// RenderWidgetHost is deleted. Removes |host| from internal maps.
void RenderWidgetHostDestroyed(RenderWidgetHost* host);
- // Find in page --------------------------------------------------------------
-
- // Opens the find in page window if it isn't already open. It will advance to
- // the next match if |find_next| is set and there is a search string,
- // otherwise, the find window will merely be opened. |forward_direction|
- // indicates the direction to search when find_next is set, otherwise it is
- // ignored.
- virtual void FindInPage(const Browser& browser,
- bool find_next, bool forward_direction) = 0;
-
- // Hides the find bar if there is one shown. Does nothing otherwise. The find
- // bar will not be deleted, merely hidden. This ensures that any search terms
- // are preserved if the user subsequently opens the find bar.
- //
- // If |end_session| is true, then the find session will be ended, which
- // indicates the user requested they no longer be in find mode for that tab.
- // The find bar will not be restored when we switch back to the tab.
- // Otherwise, we assume that the find bar is being hidden because the tab is
- // being hidden, and all state like visibility and tickmarks will be restored
- // when the tab comes back.
- virtual void HideFindBar(bool end_session) = 0;
-
-#if defined(OS_WIN)
- // Called when the tab is reparented to a new browser window. On MS Windows,
- // we have to change the parent of our find bar to go with the new window.
- //
- // TODO(brettw) this seems like it could be improved. Possibly all doohickies
- // around the tab like this, the download bar etc. should be managed by the
- // BrowserView2 object.
- virtual void ReparentFindWindow(Browser* new_browser) const = 0;
-#endif
-
- // 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 required.
- //
- // 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) const = 0;
-
protected:
WebContentsView() {} // Abstract interface.
diff --git a/chrome/browser/tab_contents/web_contents_view_win.cc b/chrome/browser/tab_contents/web_contents_view_win.cc
index 9728ec8..52989e4 100644
--- a/chrome/browser/tab_contents/web_contents_view_win.cc
+++ b/chrome/browser/tab_contents/web_contents_view_win.cc
@@ -7,7 +7,7 @@
#include <windows.h>
#include "chrome/browser/bookmarks/bookmark_drag_data.h"
-#include "chrome/browser/browser.h" // TODO(beng): this dependency is awful.
+#include "chrome/browser/browser.h" // TODO(beng): this dependency is awful.
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_request_manager.h"
#include "chrome/browser/renderer_host/render_process_host.h"
@@ -20,7 +20,6 @@
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/tab_contents/web_drag_source.h"
#include "chrome/browser/tab_contents/web_drop_target.h"
-#include "chrome/browser/views/find_bar_win.h"
#include "chrome/browser/views/sad_tab_view.h"
#include "chrome/common/gfx/chrome_canvas.h"
#include "chrome/common/os_exchange_data.h"
@@ -180,10 +179,6 @@ void WebContentsViewWin::OnContentsDestroy() {
// automatically. The detached plugin windows will get cleaned up in proper
// sequence as part of the usual cleanup when the plugin instance goes away.
EnumChildWindows(GetHWND(), DetachPluginWindowsCallback, NULL);
-
- // Close the find bar if any.
- if (find_bar_.get())
- find_bar_->Close();
}
void WebContentsViewWin::OnDestroy() {
@@ -216,52 +211,6 @@ void WebContentsViewWin::SizeContents(const gfx::Size& size) {
WasSized(size);
}
-void WebContentsViewWin::FindInPage(const Browser& browser,
- bool find_next, bool forward_direction) {
- if (!find_bar_.get()) {
- // We want the Chrome top-level (Frame) window.
- HWND hwnd = reinterpret_cast<HWND>(browser.window()->GetNativeHandle());
- find_bar_.reset(new FindBarWin(this, hwnd));
- } else {
- find_bar_->Show();
- }
-
- if (find_next && !find_bar_->find_string().empty())
- find_bar_->StartFinding(forward_direction);
-}
-
-void WebContentsViewWin::HideFindBar(bool end_session) {
- if (find_bar_.get()) {
- if (end_session)
- find_bar_->EndFindSession();
- else
- find_bar_->DidBecomeUnselected();
- }
-}
-
-void WebContentsViewWin::ReparentFindWindow(Browser* new_browser) const {
- if (find_bar_.get()) {
- find_bar_->SetParent(
- reinterpret_cast<HWND>(new_browser->window()->GetNativeHandle()));
- }
-}
-
-bool WebContentsViewWin::GetFindBarWindowInfo(gfx::Point* position,
- bool* fully_visible) const {
- CRect window_rect;
- if (!find_bar_.get() ||
- !::IsWindow(find_bar_->GetHWND()) ||
- !::GetWindowRect(find_bar_->GetHWND(), &window_rect)) {
- *position = gfx::Point(0, 0);
- *fully_visible = false;
- return false;
- }
-
- *position = gfx::Point(window_rect.TopLeft().x, window_rect.TopLeft().y);
- *fully_visible = find_bar_->IsVisible() && !find_bar_->IsAnimating();
- return true;
-}
-
void WebContentsViewWin::UpdateDragCursor(bool is_drop_target) {
drop_target_->set_is_drop_target(is_drop_target);
}
@@ -326,17 +275,6 @@ void WebContentsViewWin::HandleKeyboardEvent(const WebKeyboardEvent& event) {
event.actual_message.lParam);
}
-void WebContentsViewWin::OnFindReply(int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) {
- if (find_bar_.get()) {
- find_bar_->OnFindReply(request_id, number_of_matches, selection_rect,
- active_match_ordinal, final_update);
- }
-}
-
void WebContentsViewWin::ShowContextMenu(const ContextMenuParams& params) {
RenderViewContextMenuController menu_controller(web_contents_, params);
RenderViewContextMenu menu(&menu_controller,
@@ -568,10 +506,6 @@ void WebContentsViewWin::OnWindowPosChanged(WINDOWPOS* window_pos) {
// size hasn't changed.
if (!(window_pos->flags & SWP_NOSIZE))
WasSized(gfx::Size(window_pos->cx, window_pos->cy));
-
- // If we have a FindInPage dialog, notify it that the window changed.
- if (find_bar_.get() && find_bar_->IsVisible())
- find_bar_->MoveWindowIfNecessary(gfx::Rect());
}
}
@@ -620,14 +554,10 @@ void WebContentsViewWin::ScrollCommon(UINT message, int scroll_type,
void WebContentsViewWin::WasHidden() {
web_contents_->HideContents();
- if (find_bar_.get())
- find_bar_->DidBecomeUnselected();
}
void WebContentsViewWin::WasShown() {
web_contents_->ShowContents();
- if (find_bar_.get())
- find_bar_->DidBecomeSelected();
}
void WebContentsViewWin::WasSized(const gfx::Size& size) {
@@ -635,8 +565,6 @@ void WebContentsViewWin::WasSized(const gfx::Size& size) {
web_contents_->interstitial_page()->SetSize(size);
if (web_contents_->render_widget_host_view())
web_contents_->render_widget_host_view()->SetSize(size);
- if (find_bar_.get())
- find_bar_->RespondToResize(size);
// TODO(brettw) this function can probably be moved to this class.
web_contents_->RepositionSupressedPopupsToFit(size);
diff --git a/chrome/browser/tab_contents/web_contents_view_win.h b/chrome/browser/tab_contents/web_contents_view_win.h
index a8649d7..6b891cf 100644
--- a/chrome/browser/tab_contents/web_contents_view_win.h
+++ b/chrome/browser/tab_contents/web_contents_view_win.h
@@ -10,7 +10,6 @@
#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/views/widget_win.h"
-class FindBarWin;
class SadTabView;
struct WebDropData;
class WebDropTarget;
@@ -40,12 +39,6 @@ class WebContentsViewWin : public WebContentsView,
virtual void SetPageTitle(const std::wstring& title);
virtual void Invalidate();
virtual void SizeContents(const gfx::Size& size);
- virtual void FindInPage(const Browser& browser,
- bool find_next, bool forward_direction);
- virtual void HideFindBar(bool end_session);
- virtual void ReparentFindWindow(Browser* new_browser) const;
- virtual bool GetFindBarWindowInfo(gfx::Point* position,
- bool* fully_visible) const;
// Backend implementation of RenderViewHostDelegate::View.
virtual WebContents* CreateNewWindowInternal(
@@ -63,11 +56,6 @@ class WebContentsViewWin : public WebContentsView,
virtual void UpdateDragCursor(bool is_drop_target);
virtual void TakeFocus(bool reverse);
virtual void HandleKeyboardEvent(const WebKeyboardEvent& event);
- virtual void OnFindReply(int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update);
private:
// Windows events ------------------------------------------------------------
@@ -108,10 +96,6 @@ class WebContentsViewWin : public WebContentsView,
WebContents* web_contents_;
- // For find in page. This may be NULL if there is no find bar, and if it is
- // non-NULL, it may or may not be visible.
- scoped_ptr<FindBarWin> find_bar_;
-
// A drop target object that handles drags over this WebContents.
scoped_refptr<WebDropTarget> drop_target_;
diff --git a/chrome/browser/views/find_bar_view.cc b/chrome/browser/views/find_bar_view.cc
index 862a10f..5b8c2bc 100644
--- a/chrome/browser/views/find_bar_view.cc
+++ b/chrome/browser/views/find_bar_view.cc
@@ -7,6 +7,7 @@
#include <algorithm>
#include "base/string_util.h"
+#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/views/find_bar_win.h"
#include "chrome/browser/view_ids.h"
#include "chrome/common/l10n_util.h"
@@ -22,8 +23,8 @@
static const int kWhiteSpaceAfterMatchCountLabel = 3;
// The margins around the search field and the close button.
-static const int kMarginLeftOfCloseButton = 5;
-static const int kMarginRightOfCloseButton = 5;
+static const int kMarginLeftOfCloseButton = 3;
+static const int kMarginRightOfCloseButton = 7;
static const int kMarginLeftOfFindTextField = 12;
// The margins around the match count label (We add extra space so that the
@@ -87,10 +88,9 @@ FindBarView::FindBarView(FindBarWin* container)
find_next_button_(NULL),
close_button_(NULL),
animation_offset_(0),
- toolbar_blend_(true),
- match_count_(-1),
- active_match_ordinal_(-1) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ last_reported_matchcount_(0),
+ toolbar_blend_(true) {
+ ResourceBundle& rb = ResourceBundle::GetSharedInstance();
find_text_ = new views::TextField();
find_text_->SetID(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD);
@@ -170,70 +170,70 @@ FindBarView::FindBarView(FindBarWin* container)
FindBarView::~FindBarView() {
}
-void FindBarView::ResetMatchCount() {
- match_count_text_->SetText(std::wstring());
- ResetMatchCountBackground();
+void FindBarView::SetFindText(const std::wstring& find_text) {
+ find_text_->SetText(find_text);
}
-void FindBarView::ResetMatchCountBackground() {
- match_count_text_->set_background(
- views::Background::CreateSolidBackground(kBackgroundColorMatch));
- match_count_text_->SetColor(kTextColorMatchCount);
-}
-
-void FindBarView::UpdateMatchCount(int number_of_matches,
- bool final_update) {
- if (number_of_matches < 0) // We ignore -1 sent during FindNext operations.
- return;
-
- // If we have previously recorded a match-count number we don't want to
- // overwrite it with a preliminary number of 1 (which the renderer sends when
- // it found one match and is about to start scoping to find more). This way
- // updates are smoother (as we don't flash '1' briefly after typing each
- // letter of a query).
- if (match_count_ > 0 && number_of_matches == 1 && !final_update)
- return;
-
- if (number_of_matches == 0)
- active_match_ordinal_ = 0;
-
- match_count_ = number_of_matches;
-
- if (find_text_->GetText().empty() || number_of_matches > 0) {
- ResetMatchCountBackground();
- } else {
- match_count_text_->set_background(
- views::Background::CreateSolidBackground(kBackgroundColorNoMatch));
- match_count_text_->SetColor(kTextColorNoMatch);
- MessageBeep(MB_OK);
+void FindBarView::UpdateForResult(const FindNotificationDetails& result,
+ const std::wstring& find_text) {
+ bool have_valid_range =
+ result.number_of_matches() != -1 && result.active_match_ordinal() != -1;
+
+ // 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 (result.number_of_matches() > -1) {
+ if (last_reported_matchcount_ > 0 &&
+ result.number_of_matches() == 1 &&
+ !result.final_update())
+ return; // Don't let interim result override match count.
+ last_reported_matchcount_ = result.number_of_matches();
}
-}
-void FindBarView::UpdateActiveMatchOrdinal(int ordinal) {
- if (ordinal >= 0)
- active_match_ordinal_ = ordinal;
-}
+ // If we don't have any results and something was passed in, then that means
+ // someone pressed F3 while the Find box was closed. In that case we need to
+ // repopulate the Find box with what was passed in.
+ if (find_text_->GetText().empty() && !find_text.empty()) {
+ find_text_->SetText(find_text);
+ find_text_->SelectAll();
+ }
-void FindBarView::UpdateResultLabel() {
std::wstring search_string = find_text_->GetText();
-
- if (search_string.length() > 0) {
+ if (search_string.length() > 0 && have_valid_range) {
match_count_text_->SetText(
l10n_util::GetStringF(IDS_FIND_IN_PAGE_COUNT,
- IntToWString(active_match_ordinal_),
- IntToWString(match_count_)));
+ IntToWString(result.active_match_ordinal()),
+ IntToWString(result.number_of_matches())));
} else {
- ResetMatchCount();
+ // If there was no text entered, we don't show anything in the result count
+ // area.
+ match_count_text_->SetText(std::wstring());
+ }
+
+ if (search_string.empty() || result.number_of_matches() > 0) {
+ // If there was no text entered or there were results, the match_count label
+ // should have a normal background color.
+ ResetMatchCountBackground();
+ } else if (result.final_update()) {
+ // Otherwise we show an error background behind the match_count label.
+ match_count_text_->set_background(
+ views::Background::CreateSolidBackground(kBackgroundColorNoMatch));
+ match_count_text_->SetColor(kTextColorNoMatch);
+ MessageBeep(MB_OK);
}
// Make sure Find Next and Find Previous are enabled if we found any matches.
- find_previous_button_->SetEnabled(match_count_ > 0);
- find_next_button_->SetEnabled(match_count_ > 0);
+ find_previous_button_->SetEnabled(result.number_of_matches() > 0);
+ find_next_button_->SetEnabled(result.number_of_matches() > 0);
Layout(); // The match_count label may have increased/decreased in size.
}
-void FindBarView::OnShow() {
+void FindBarView::SetFocusAndSelection() {
find_text_->RequestFocus();
find_text_->SelectAll();
}
@@ -259,11 +259,7 @@ void FindBarView::Paint(ChromeCanvas* canvas) {
const SkBitmap *bg_right =
toolbar_blend_ ? kDlgBackground_right : kDlgBackground_bb_right;
- canvas->TileImageInt(*bg_left,
- 0,
- 0,
- bg_left->width(),
- bg_left->height());
+ canvas->DrawBitmapInt(*bg_left, 0, 0);
// Stretch the middle background to cover all of the area between the two
// other images.
@@ -275,11 +271,7 @@ void FindBarView::Paint(ChromeCanvas* canvas) {
bg_right->width(),
bg_middle->height());
- canvas->TileImageInt(*bg_right,
- lb.right() - bg_right->width(),
- 0,
- bg_right->width(),
- bg_right->height());
+ canvas->DrawBitmapInt(*bg_right, lb.right() - bg_right->width(), 0);
// Then we draw the background image for the Find TextField. We start by
// calculating the position of background images for the Find text box.
@@ -386,7 +378,6 @@ void FindBarView::Layout() {
sz.width(),
sz.height());
find_text_->SetController(this);
- find_text_->RequestFocus();
// The focus forwarder view is a hidden view that should cover the area
// between the find text box and the find button so that when the user clicks
@@ -430,8 +421,9 @@ void FindBarView::ButtonPressed(views::BaseButton* sender) {
case FIND_PREVIOUS_TAG:
case FIND_NEXT_TAG:
if (find_text_->GetText().length() > 0) {
- container_->set_find_string(find_text_->GetText());
- container_->StartFinding(sender->GetTag() == FIND_NEXT_TAG);
+ container_->web_contents()->StartFinding(
+ find_text_->GetText(),
+ sender->GetTag() == FIND_NEXT_TAG);
}
break;
case CLOSE_TAG:
@@ -452,14 +444,13 @@ void FindBarView::ContentsChanged(views::TextField* sender,
// if the textbox contains something we set it as the new search string and
// initiate search (even though old searches might be in progress).
if (new_contents.length() > 0) {
- container_->set_find_string(new_contents);
- container_->StartFinding(true);
+ container_->web_contents()->StartFinding(new_contents, true);
} else {
// The textbox is empty so we reset.
- UpdateMatchCount(0, true); // true = final update.
- UpdateResultLabel();
- container_->StopFinding(true); // true = clear selection on page.
- container_->set_find_string(std::wstring());
+ container_->web_contents()->StopFinding(true); // true = clear selection on
+ // page.
+ UpdateForResult(container_->web_contents()->find_result(),
+ std::wstring());
}
}
@@ -474,15 +465,22 @@ void FindBarView::HandleKeystroke(views::TextField* sender, UINT message,
// Pressing Return/Enter starts the search (unless text box is empty).
std::wstring find_string = find_text_->GetText();
if (find_string.length() > 0) {
- container_->set_find_string(find_string);
// Search forwards for enter, backwards for shift-enter.
- container_->StartFinding(GetKeyState(VK_SHIFT) >= 0);
+ container_->web_contents()->StartFinding(
+ find_string,
+ GetKeyState(VK_SHIFT) >= 0);
}
break;
}
}
}
+void FindBarView::ResetMatchCountBackground() {
+ match_count_text_->set_background(
+ views::Background::CreateSolidBackground(kBackgroundColorMatch));
+ match_count_text_->SetColor(kTextColorMatchCount);
+}
+
bool FindBarView::FocusForwarderView::OnMousePressed(
const views::MouseEvent& event) {
if (view_to_focus_on_mousedown_) {
@@ -491,4 +489,3 @@ bool FindBarView::FocusForwarderView::OnMousePressed(
}
return true;
}
-
diff --git a/chrome/browser/views/find_bar_view.h b/chrome/browser/views/find_bar_view.h
index 146f96b..2818d6d 100644
--- a/chrome/browser/views/find_bar_view.h
+++ b/chrome/browser/views/find_bar_view.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_VIEWS_FIND_BAR_VIEW_H_
#include "base/gfx/size.h"
+#include "chrome/browser/find_notification_details.h"
#include "chrome/views/button.h"
#include "chrome/views/text_field.h"
@@ -35,31 +36,19 @@ class FindBarView : public views::View,
CLOSE_TAG, // The Close button (the 'X').
};
- FindBarView(FindBarWin* container);
+ explicit FindBarView(FindBarWin* container);
virtual ~FindBarView();
- // Updates the UI to show how many matches were found on the page/frames.
- // This function does nothing if |number_of_matches| is below 0, which can
- // happen during a FindNext operation when a scoping effort is already in
- // progress. |final_update| specifies whether this is the last update message
- // this Find operation will produce or if this is just a preliminary report.
- void UpdateMatchCount(int number_of_matches, bool final_update);
-
- // Notifies the view of the ordinal for the currently active item on the page.
- void UpdateActiveMatchOrdinal(int ordinal);
+ // Sets the text displayed in the text box.
+ void SetFindText(const std::wstring& find_text);
// Updates the label inside the Find text box that shows the ordinal of the
// active item and how many matches were found.
- void UpdateResultLabel();
-
- // Resets the UI element that shows how many matches were found.
- void ResetMatchCount();
-
- // Resets the background for the match count label.
- void ResetMatchCountBackground();
+ void UpdateForResult(const FindNotificationDetails& result,
+ const std::wstring& find_text);
- // View needs to respond to Show to set focus to the find text box
- void OnShow();
+ // Claims focus for the text field and selects its contents.
+ void SetFocusAndSelection();
// Updates the view to let it know where the controller is clipping the
// Find window (while animating the opening or closing of the window).
@@ -81,9 +70,12 @@ class FindBarView : public views::View,
TCHAR key, UINT repeat_count, UINT flags);
// Set whether or not we're attempting to blend with the toolbar.
- void SetToolbarBlend(bool toolbar_blend) {toolbar_blend_ = toolbar_blend;}
+ void set_toolbar_blend(bool toolbar_blend) { toolbar_blend_ = toolbar_blend; }
private:
+ // Resets the background for the match count label.
+ void ResetMatchCountBackground();
+
// We use a hidden view to grab mouse clicks and bring focus to the find
// text box. This is because although the find text box may look like it
// extends all the way to the find button, it only goes as far as to the
@@ -116,6 +108,9 @@ class FindBarView : public views::View,
views::Button* find_next_button_;
views::Button* close_button_;
+ // The last matchcount number we reported to the user.
+ int last_reported_matchcount_;
+
// Whether or not we're attempting to blend with the toolbar (this is
// false if the bookmarks bar is visible).
bool toolbar_blend_;
@@ -126,12 +121,6 @@ class FindBarView : public views::View,
// in the right location.
int animation_offset_;
- // How many matches were found on the page.
- int match_count_;
-
- // The ordinal of the currently active match.
- int active_match_ordinal_;
-
DISALLOW_COPY_AND_ASSIGN(FindBarView);
};
diff --git a/chrome/browser/views/find_bar_win.cc b/chrome/browser/views/find_bar_win.cc
index 671cc92..9ab7f1d 100644
--- a/chrome/browser/views/find_bar_win.cc
+++ b/chrome/browser/views/find_bar_win.cc
@@ -6,11 +6,12 @@
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/find_notification_details.h"
#include "chrome/browser/renderer_host/render_view_host.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/find_bar_view.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/web_contents.h"
#include "chrome/browser/tab_contents/web_contents_view.h"
#include "chrome/common/notification_service.h"
@@ -20,25 +21,20 @@
#include "chrome/views/view_storage.h"
#include "chrome/views/widget_win.h"
-int FindBarWin::request_id_counter_ = 0;
-
// The minimum space between the FindInPage window and the search result.
static const int kMinFindWndDistanceFromSelection = 5;
-// The amount of space we expect the window border to take up.
-static const int kWindowBorderWidth = 3;
-
////////////////////////////////////////////////////////////////////////////////
// FindBarWin, public:
-FindBarWin::FindBarWin(WebContentsView* parent_tab, HWND parent_hwnd)
- : parent_tab_(parent_tab),
- current_request_id_(request_id_counter_++),
- parent_hwnd_(parent_hwnd),
+FindBarWin::FindBarWin(BrowserView* browser_view)
+ : web_contents_(NULL),
+ browser_view_(browser_view),
find_dialog_animation_offset_(0),
- show_on_tab_selection_(false),
focus_manager_(NULL),
old_accel_target_for_esc_(NULL) {
+ HWND parent_hwnd = browser_view->GetWidget()->GetHWND();
+
// Start listening to focus changes, so we can register and unregister our
// own handler for Escape.
SetFocusChangeListener(parent_hwnd);
@@ -49,36 +45,38 @@ FindBarWin::FindBarWin(WebContentsView* parent_tab, HWND parent_hwnd)
view_ = new FindBarView(this);
- views::FocusManager* focus_manager;
- focus_manager = views::FocusManager::GetFocusManager(parent_hwnd_);
+ views::FocusManager* focus_manager = views::FocusManager::GetFocusManager(
+ parent_hwnd);
DCHECK(focus_manager);
// Stores the currently focused view, and tracks focus changes so that we can
// restore focus when the find box is closed.
focus_tracker_.reset(new views::ExternalFocusTracker(view_, focus_manager));
- // Figure out where to place the dialog, initialize and set the position.
- gfx::Rect find_dlg_rect = GetDialogPosition(gfx::Rect());
+ // Initialize the native window.
set_window_style(WS_CHILD | WS_CLIPCHILDREN);
set_window_ex_style(WS_EX_TOPMOST);
- WidgetWin::Init(parent_hwnd, find_dlg_rect, false);
+ WidgetWin::Init(parent_hwnd, gfx::Rect(), false);
SetContentsView(view_);
// Start the process of animating the opening of the window.
animation_.reset(new SlideAnimation(this));
- animation_->Show();
}
FindBarWin::~FindBarWin() {
- Close();
}
// TODO(brettw) this should not be so complicated. The view should really be in
// charge of these regions. CustomFrameWindow will do this for us. It will also
// let us set a path for the window region which will avoid some logic here.
void FindBarWin::UpdateWindowEdges(const gfx::Rect& new_pos) {
- int w = new_pos.width();
- int h = new_pos.height();
+ // |w| is used to make it easier to create the part of the polygon that curves
+ // the right side of the Find window. It essentially keeps track of the
+ // x-pixel position of the right-most background image inside the view.
+ // TODO(finnur): Let the view tell us how to draw the curves or convert
+ // this to a CustomFrameWindow.
+ int w = new_pos.width() - 6; // -6 positions us at the left edge of the
+ // rightmost background image of the view.
// This polygon array represents the outline of the background image for the
// dialog. Basically, it encompasses only the visible pixels of the
@@ -150,8 +148,8 @@ void FindBarWin::UpdateWindowEdges(const gfx::Rect& new_pos) {
//
// TODO(brettw) this constant is evil. This is the amount of room we've added
// to the window size, when we set the region, it can change the size.
- static const int kAddedWidth = 14;
- int difference = (curr_pos_relative_.right() - kAddedWidth) -
+ static const int kAddedWidth = 7;
+ int difference = (new_pos.right() - kAddedWidth) -
dialog_bounds.width() -
views::NativeScrollBar::GetVerticalScrollBarWidth() +
1;
@@ -180,26 +178,14 @@ void FindBarWin::UpdateWindowEdges(const gfx::Rect& new_pos) {
}
void FindBarWin::Show() {
- // Note: This function is called when the user presses Ctrl+F or switches back
- // to the parent tab of the Find window (assuming the Find window has been
- // opened at least once). If the Find window is already visible, we should
- // just forward the command to the view so that it will select all text and
- // grab focus. If the window is not visible, however, there are two scenarios:
- if (!IsVisible() && !animation_->IsAnimating()) {
- if (show_on_tab_selection_) {
- // The tab just got re-selected and we need to show the window again
- // (without animation). 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.
- gfx::Rect new_pos = GetDialogPosition(gfx::Rect());
- SetDialogPosition(new_pos);
- } else {
- // The Find window was dismissed and we need to start the animation again.
- animation_->Show();
- }
+ // Only show the animation if we're not already showing a find bar for the
+ // selected WebContents.
+ if (!web_contents_->find_ui_active()) {
+ web_contents_->set_find_ui_active(true);
+ animation_->Reset();
+ animation_->Show();
}
-
- view_->OnShow();
+ view_->SetFocusAndSelection();
}
bool FindBarWin::IsAnimating() {
@@ -207,122 +193,115 @@ bool FindBarWin::IsAnimating() {
}
void FindBarWin::EndFindSession() {
- if (IsVisible()) {
- show_on_tab_selection_ = false;
- animation_->Hide();
-
- // We reset the match count here so that we don't show old results when the
- // user has navigated to another page. We could alternatively achieve the
- // same effect by nulling the search string, but then the user looses the
- // last search that was entered, which can be frustrating if searching for
- // the same string on multiple pages.
- view_->ResetMatchCount();
-
- // 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
- // tick-marks and highlighting.
- StopFinding(false); // false = don't clear selection on page.
-
- // When we get dismissed we restore the focus to where it belongs.
- RestoreSavedFocus();
- }
-}
-
-void FindBarWin::Close() {
- // We may already have been destroyed if the selection resulted in a tab
- // switch which will have reactivated the browser window and closed us, so
- // we need to check to see if we're still a window before trying to destroy
- // ourself.
- if (IsWindow())
- DestroyWindow();
+ animation_->Reset(1.0);
+ animation_->Hide();
+
+ // 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.
+ web_contents_->StopFinding(false); // false = don't clear selection on
+ // page.
+ view_->UpdateForResult(web_contents_->find_result(), std::wstring());
+
+ // When we get dismissed we restore the focus to where it belongs.
+ RestoreSavedFocus();
}
-void FindBarWin::DidBecomeSelected() {
- if (!IsVisible() && show_on_tab_selection_) {
- Show();
- show_on_tab_selection_ = false;
+void FindBarWin::ChangeWebContents(WebContents* contents) {
+ if (web_contents_) {
+ NotificationService::current()->RemoveObserver(
+ this, NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(web_contents_));
+ NotificationService::current()->RemoveObserver(
+ this, NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(web_contents_->controller()));
+ if (animation_->IsAnimating())
+ animation_->End();
}
-}
-void FindBarWin::DidBecomeUnselected() {
- if (::IsWindow(GetHWND()) && IsVisible()) {
- // Finish any existing animations.
- if (animation_->IsAnimating()) {
- show_on_tab_selection_ = animation_->IsShowing();
- animation_->End();
- } else {
- show_on_tab_selection_ = true;
+ web_contents_ = contents;
+
+ if (web_contents_) {
+ if (IsVisible() && web_contents_ && !web_contents_->find_ui_active())
+ ShowWindow(SW_HIDE);
+
+ NotificationService::current()->AddObserver(
+ this, NotificationType::FIND_RESULT_AVAILABLE,
+ Source<TabContents>(web_contents_));
+ NotificationService::current()->AddObserver(
+ this, NotificationType::NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(web_contents_->controller()));
+
+ // 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.
+ view_->SetFindText(web_contents_->find_text());
+
+ if (web_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.
+ gfx::Rect new_pos = GetDialogPosition(gfx::Rect());
+ SetDialogPosition(new_pos, false);
+
+ // Only modify focus and selection if Find is active, otherwise the Find
+ // Bar will interfere with user input.
+ view_->SetFocusAndSelection();
}
- ShowWindow(SW_HIDE);
+ UpdateUIForFindResult(web_contents_->find_result(),
+ web_contents_->find_text());
}
}
-void FindBarWin::StartFinding(bool forward_direction) {
- if (find_string_.empty())
+void FindBarWin::MoveWindowIfNecessary(const gfx::Rect& selection_rect,
+ bool no_redraw) {
+ // We only move the window if one is active for the current WebContents. If we
+ // don't check this, then SetDialogPosition below will end up making the Find
+ // Bar visible.
+ if (!web_contents_ || !web_contents_->find_ui_active())
return;
- bool find_next = last_find_string_ == find_string_;
- if (!find_next)
- current_request_id_ = request_id_counter_++;
-
- last_find_string_ = find_string_;
-
- GetRenderViewHost()->StartFinding(current_request_id_,
- find_string_,
- forward_direction,
- false, // case sensitive
- find_next);
-}
-
-void FindBarWin::StopFinding(bool clear_selection) {
- last_find_string_.clear();
- GetRenderViewHost()->StopFinding(clear_selection);
-}
-
-void FindBarWin::MoveWindowIfNecessary(
- const gfx::Rect& selection_rect) {
gfx::Rect new_pos = GetDialogPosition(selection_rect);
- SetDialogPosition(new_pos);
+ SetDialogPosition(new_pos, no_redraw);
- // May need to redraw our frame to accomodate bookmark bar
- // styles.
+ // May need to redraw our frame to accommodate bookmark bar styles.
view_->SchedulePaint();
}
-void FindBarWin::RespondToResize(const gfx::Size& new_size) {
- if (!IsVisible())
- return;
-
- // We are only interested in changes to width.
- if (window_size_.width() == new_size.width())
- return;
-
- // Save the new size so we can compare later and ignore future invocations
- // of RespondToResize.
- window_size_ = new_size;
-
- gfx::Rect new_pos = GetDialogPosition(gfx::Rect());
- SetDialogPosition(new_pos);
-}
-
-void FindBarWin::SetParent(HWND new_parent) {
- DCHECK(new_parent);
- if (parent_hwnd_ != new_parent) {
- // Sync up the focus listener with the new focus manager.
- SetFocusChangeListener(new_parent);
-
- parent_hwnd_ = new_parent;
- ::SetParent(GetHWND(), new_parent);
-
- // The MSDN documentation specifies that you need to manually update the
- // UI state after changing the parent.
- ::SendMessage(new_parent,
- WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, 0), 0);
-
- // We have a new focus manager now, so start tracking with that.
- focus_tracker_.reset(new views::ExternalFocusTracker(view_,
- focus_manager_));
+////////////////////////////////////////////////////////////////////////////////
+// FindBarWin, NotificationObserver implementation:
+
+void FindBarWin::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() == web_contents_) {
+ UpdateUIForFindResult(web_contents_->find_result(),
+ web_contents_->find_text());
+ FindNotificationDetails details = web_contents_->find_result();
+ }
+ } else if (type == NotificationType::NAV_ENTRY_COMMITTED) {
+ NavigationController* source_controller =
+ Source<NavigationController>(source).ptr();
+ if (source_controller == web_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 (IsVisible() && PageTransition::StripQualifier(transition_type) !=
+ PageTransition::RELOAD) {
+ EndFindSession();
+ }
+ }
}
}
@@ -330,6 +309,9 @@ void FindBarWin::SetParent(HWND new_parent) {
// FindBarWin, views::WidgetWin implementation:
void FindBarWin::OnFinalMessage(HWND window) {
+ // TODO(beng): Destroy the RootView before destroying the Focus Manager will
+ // allow us to remove this method.
+
// We are exiting, so we no longer need to monitor focus changes.
focus_manager_->RemoveFocusChangeListener(this);
@@ -384,14 +366,15 @@ bool FindBarWin::AcceleratorPressed(const views::Accelerator& accelerator) {
void FindBarWin::AnimationProgressed(const Animation* animation) {
// First, we calculate how many pixels to slide the window.
+ gfx::Size pref_size = view_->GetPreferredSize();
find_dialog_animation_offset_ =
static_cast<int>((1.0 - animation_->GetCurrentValue()) *
- view_->height());
+ pref_size.height());
// This call makes sure it appears in the right location, the size and shape
// is correct and that it slides in the right direction.
gfx::Rect find_dlg_rect = GetDialogPosition(gfx::Rect());
- SetDialogPosition(find_dlg_rect);
+ SetDialogPosition(find_dlg_rect, false);
// Let the view know if we are animating, and at which offset to draw the
// edges.
@@ -409,125 +392,13 @@ void FindBarWin::AnimationEnded(const Animation* animation) {
}
}
-void FindBarWin::OnFindReply(int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update) {
- // Ignore responses for requests other than the one we have most recently
- // issued. That way we won't act on stale results when the user has
- // already typed in another query.
- if (view_ && request_id == current_request_id_) {
- view_->UpdateMatchCount(number_of_matches, final_update);
- view_->UpdateActiveMatchOrdinal(active_match_ordinal);
- view_->UpdateResultLabel();
-
- // We now need to check if the window is obscuring the search results.
- if (!selection_rect.IsEmpty())
- MoveWindowIfNecessary(selection_rect);
-
- // Once we find a match we no longer want to keep track of what had
- // focus. EndFindSession will then set the focus to the page content.
- if (number_of_matches > 0)
- focus_tracker_.reset(NULL);
- }
-
- // Notify all observers of this notification, such as the automation
- // providers which do UI tests for find in page.
- FindNotificationDetails detail(request_id,
- number_of_matches,
- selection_rect,
- active_match_ordinal,
- final_update);
- NotificationService::current()->Notify(
- NotificationType::FIND_RESULT_AVAILABLE,
- Source<TabContents>(parent_tab_->GetWebContents()),
- Details<FindNotificationDetails>(&detail));
-}
-
-RenderViewHost* FindBarWin::GetRenderViewHost() const {
- return parent_tab_->GetWebContents()->render_view_host();
-}
-
void FindBarWin::GetDialogBounds(gfx::Rect* bounds) {
DCHECK(bounds);
-
- // We need to find the View for the toolbar because we want to visually
- // extend it (draw our dialog slightly overlapping its border).
- views::View* root_view = views::GetRootViewForHWND(parent_hwnd_);
- views::View* toolbar = NULL;
- BookmarkBarView* bookmark_bar = NULL;
- if (root_view) {
- toolbar = root_view->GetViewByID(VIEW_ID_TOOLBAR);
- bookmark_bar = static_cast<BookmarkBarView*>(
- root_view->GetViewByID(VIEW_ID_BOOKMARK_BAR));
- }
-
- // To figure out what area we have to work with we need to know the rect for
- // the browser window and the page content area starts and get a pointer to
- // the toolbar to see where to draw the FindInPage dialog. If any of this
- // fails, we return an empty rect.
- CRect browser_client_rect, browser_window_rect, content_window_rect;
- if (!::IsWindow(parent_hwnd_) ||
- !::GetWindowRect(parent_tab_->GetContentNativeView(),
- &content_window_rect) ||
- !::GetWindowRect(parent_hwnd_, &browser_window_rect) ||
- !::GetClientRect(parent_hwnd_, &browser_client_rect) ||
- !toolbar) {
- *bounds = gfx::Rect();
- return;
- }
-
- // Start with browser's client rect, then change it below.
- *bounds = gfx::Rect(browser_client_rect);
-
- // Find the bounds of the toolbar we want to dock to.
- gfx::Rect toolbar_bounds;
- views::View* bounds_view = NULL;
- view_->SetToolbarBlend(true);
- if (bookmark_bar && !bookmark_bar->IsDetachedStyle()) {
- bounds_view = bookmark_bar;
- toolbar_bounds = bookmark_bar->GetLocalBounds(false);
- if (bookmark_bar->IsAlwaysShown())
- view_->SetToolbarBlend(false);
- } else if (toolbar) {
- bounds_view = toolbar;
- toolbar_bounds = toolbar->GetLocalBounds(false);
- }
-
- // Figure out at which y coordinate to draw the FindInPage window. If we have
- // a toolbar (chrome) we want to overlap it by one pixel so that we look like
- // we are part of the chrome (which will also draw our window on top of any
- // info-bars, if present). If there is no chrome, then we have a constrained
- // window or a Chrome application so we want to draw at the top of the page
- // content (right beneath the title bar).
- int y_pos_offset = 0;
- if (bounds_view) {
- // We have a toolbar (chrome), so overlap it by one pixel.
- gfx::Point origin;
- views::View::ConvertPointToWidget(bounds_view, &origin);
- toolbar_bounds.Offset(origin);
- y_pos_offset = toolbar_bounds.bottom() - 1;
- } else {
- // The toolbar isn't visible, so we're in fullscreen mode or this is an app
- // window. This means we draw the Find window at the top of the page content
- // window. We subtract 1 to overlap the client edge that is part of the
- // title bar (so that we don't look detached by 1 pixel).
- // TODO(pkasting): This -1 is wrong in maximized mode.
- WINDOWINFO wi;
- wi.cbSize = sizeof(WINDOWINFO);
- GetWindowInfo(parent_hwnd_, &wi);
- y_pos_offset = content_window_rect.TopLeft().y - wi.rcClient.top - 1;
- }
-
- bounds->Offset(0, y_pos_offset);
-
- // We also want to stay well within limits of the vertical scrollbar and not
- // draw on the window border (frame) itself either.
- int width = views::NativeScrollBar::GetVerticalScrollBarWidth();
- width += kWindowBorderWidth;
- bounds->set_x(bounds->x() + width);
- bounds->set_width(bounds->width() - (2 * width));
+ // The BrowserView does Layout for the components that we care about
+ // positioning relative to, so we ask it to tell us where we should go.
+ *bounds = browser_view_->GetFindBarBoundingBox();
+ view_->set_toolbar_blend(
+ !browser_view_->ShouldFindBarBlendWithBookmarksBar());
}
gfx::Rect FindBarWin::GetDialogPosition(gfx::Rect avoid_overlapping_rect) {
@@ -567,8 +438,8 @@ gfx::Rect FindBarWin::GetDialogPosition(gfx::Rect avoid_overlapping_rect) {
// for the fact that we draw the Find dialog relative to the window,
// whereas the selection rect is relative to the page.
RECT frame_rect = {0}, webcontents_rect = {0};
- ::GetWindowRect(parent_hwnd_, &frame_rect);
- ::GetWindowRect(parent_tab_->GetNativeView(), &webcontents_rect);
+ ::GetWindowRect(GetParent(), &frame_rect);
+ ::GetWindowRect(web_contents_->view()->GetNativeView(), &webcontents_rect);
avoid_overlapping_rect.Offset(0, webcontents_rect.top - frame_rect.top);
}
@@ -603,7 +474,7 @@ gfx::Rect FindBarWin::GetDialogPosition(gfx::Rect avoid_overlapping_rect) {
return new_pos;
}
-void FindBarWin::SetDialogPosition(const gfx::Rect& new_pos) {
+void FindBarWin::SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw) {
if (new_pos.IsEmpty())
return;
@@ -612,11 +483,18 @@ void FindBarWin::SetDialogPosition(const gfx::Rect& new_pos) {
// of it it doesn't look like the window crumbles into the toolbar.
UpdateWindowEdges(new_pos);
- ::SetWindowPos(GetHWND(), HWND_TOP,
- new_pos.x(), new_pos.y(), new_pos.width(), new_pos.height(),
- SWP_NOSIZE | SWP_NOOWNERZORDER | SWP_SHOWWINDOW);
+ CRect window_rect;
+ GetWindowRect(&window_rect);
+ DWORD swp_flags = SWP_NOOWNERZORDER;
+ if (!window_rect.IsRectEmpty())
+ swp_flags |= SWP_NOSIZE;
+ if (no_redraw)
+ swp_flags |= SWP_NOREDRAW;
+ if (!IsVisible())
+ swp_flags |= SWP_SHOWWINDOW;
- curr_pos_relative_ = new_pos;
+ ::SetWindowPos(GetHWND(), HWND_TOP, new_pos.x(), new_pos.y(), new_pos.width(),
+ new_pos.height(), swp_flags);
}
void FindBarWin::SetFocusChangeListener(HWND parent_hwnd) {
@@ -638,7 +516,7 @@ void FindBarWin::SetFocusChangeListener(HWND parent_hwnd) {
void FindBarWin::RestoreSavedFocus() {
if (focus_tracker_.get() == NULL) {
// TODO(brettw) Focus() should be on WebContentsView.
- parent_tab_->GetWebContents()->Focus();
+ web_contents_->Focus();
} else {
focus_tracker_->FocusLastFocusedExternalView();
}
@@ -667,3 +545,16 @@ void FindBarWin::UnregisterEscAccelerator() {
focus_manager_->RegisterAccelerator(escape, old_accel_target_for_esc_);
}
+void FindBarWin::UpdateUIForFindResult(const FindNotificationDetails& result,
+ const std::wstring& find_text) {
+ view_->UpdateForResult(result, find_text);
+
+ // We now need to check if the window is obscuring the search results.
+ if (!result.selection_rect().IsEmpty())
+ MoveWindowIfNecessary(result.selection_rect(), false);
+
+ // Once we find a match we no longer want to keep track of what had
+ // focus. EndFindSession will then set the focus to the page content.
+ if (result.number_of_matches() > 0)
+ focus_tracker_.reset(NULL);
+}
diff --git a/chrome/browser/views/find_bar_win.h b/chrome/browser/views/find_bar_win.h
index f1727de..c226ea9 100644
--- a/chrome/browser/views/find_bar_win.h
+++ b/chrome/browser/views/find_bar_win.h
@@ -6,14 +6,16 @@
#define CHROME_BROWSER_VIEWS_FIND_BAR_WIN_H_
#include "base/gfx/rect.h"
+#include "chrome/browser/find_notification_details.h"
#include "chrome/browser/renderer_host/render_view_host_delegate.h"
#include "chrome/common/animation.h"
+#include "chrome/common/notification_service.h"
#include "chrome/views/widget_win.h"
+class BrowserView;
class FindBarView;
class RenderViewHost;
class SlideAnimation;
-class WebContentsView;
namespace views {
class ExternalFocusTracker;
@@ -26,60 +28,43 @@ class View;
// functionality. It uses the FindBarWin implementation to draw its content and
// is responsible for showing, hiding, closing, and moving the window if needed,
// for example if the window is obscuring the selection results. It also
-// communicates with the parent_tab to instruct it to start searching for what
-// the user selected and receives notifications about the search results and
-// communicates that to the view.
+// receives notifications about the search results and communicates that to the
+// view.
//
-// We create one container per tab and remember each search query per tab.
+// There is one FindBarWin per BrowserView, and its state is updated whenever
+// the selected Tab is changed. The FindBarWin is created when the BrowserView
+// is attached to the frame's Widget for the first time.
//
////////////////////////////////////////////////////////////////////////////////
class FindBarWin : public views::FocusChangeListener,
public views::WidgetWin,
- public AnimationDelegate {
+ public AnimationDelegate,
+ public NotificationObserver {
public:
- FindBarWin(WebContentsView* parent_tab, HWND parent_hwnd);
+ explicit FindBarWin(BrowserView* browser_view);
virtual ~FindBarWin();
+ // Accessor for the attached WebContents.
+ WebContents* web_contents() const { return web_contents_; }
+
// Shows the find bar. Any previous search string will again be visible.
void Show();
// Ends the current session.
void EndFindSession();
- // Closes the find bar window (calls Close on the Window Container).
- void Close();
-
- // This is triggered when the parent tab of the Find dialog becomes
- // unselected, at which point the find bar should become hidden. Otherwise,
- // we leave artifacts on the chrome when other tabs are visible. However, we
- // need to show the Find dialog again when the parent tab becomes selected
- // again, so we set a flag for that and show the window if we get a
- // DidBecomeSelected call.
- void DidBecomeUnselected();
-
- // If |show_on_tab_selection_| is true, then we show the dialog and clear the
- // flag, otherwise we do nothing.
- void DidBecomeSelected();
-
- // Starts the Find operation by calling StartFinding on the Tab. This function
- // can be called from the outside as a result of hot-keys, so it uses the
- // last remembered search string as specified with set_find_string(). This
- // function does not block while a search is in progress. The controller will
- // receive the results through the notification mechanism. See Observe(...)
- // for details.
- void StartFinding(bool forward_direction);
-
- // Stops the current Find operation. If |clear_selection| is true, it will
- // also clear the selection on the focused frame.
- void StopFinding(bool clear_selection);
+ // Changes the WebContents that this FindBar is attached to. This occurs when
+ // the user switches tabs in the Browser window. |contents| can be NULL.
+ void ChangeWebContents(WebContents* contents);
// 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.
- void MoveWindowIfNecessary(const gfx::Rect& selection_rect);
+ // the web page area. If |no_redraw| is true, the window will be moved without
+ // redrawing siblings.
+ void MoveWindowIfNecessary(const gfx::Rect& selection_rect, bool no_redraw);
// Moves the window according to the new window size.
void RespondToResize(const gfx::Size& new_size);
@@ -87,11 +72,6 @@ class FindBarWin : public views::FocusChangeListener,
// Whether we are animating the position of the Find window.
bool IsAnimating();
- // Changes the parent window for the find bar. If |new_parent| is already
- // the parent of this window then no action is taken.
- // |new_parent| can not be NULL.
- void SetParent(HWND new_parent);
-
// We need to monitor focus changes so that we can register a handler for
// Escape when we get focus and unregister it when we looses focus. This
// function unregisters our old Escape accelerator (if registered) and
@@ -99,19 +79,10 @@ class FindBarWin : public views::FocusChangeListener,
// new |parent_hwnd|.
void SetFocusChangeListener(HWND parent_hwnd);
- // Accessors for specifying and retrieving the current search string.
- std::wstring find_string() { return find_string_; }
- void set_find_string(const std::wstring& find_string) {
- find_string_ = find_string;
- }
-
- // Updates the find bar with the latest results. This is called when the
- // renderer (through the RenderViewHostDelegate::View) finds more stuff.
- void OnFindReply(int request_id,
- int number_of_matches,
- const gfx::Rect& selection_rect,
- int active_match_ordinal,
- bool final_update);
+ // Overridden from NotificationObserver:
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
// Overridden from views::WidgetWin:
virtual void OnFinalMessage(HWND window);
@@ -128,9 +99,6 @@ class FindBarWin : public views::FocusChangeListener,
virtual void AnimationEnded(const Animation* animation);
private:
- // Returns the RenderViewHost associated with the current tab.
- RenderViewHost* GetRenderViewHost() const;
-
// Retrieves the boundaries that the find bar has to work with within the
// Chrome frame window. The resulting rectangle will be a rectangle that
// overlaps the bottom of the Chrome toolbar by one pixel (so we can create
@@ -159,8 +127,9 @@ class FindBarWin : public views::FocusChangeListener,
// Moves the dialog window to the provided location, moves it to top in the
// z-order (HWND_TOP, not HWND_TOPMOST) and shows the window (if hidden).
// It then calls UpdateWindowEdges to make sure we don't overwrite the Chrome
- // window border.
- void SetDialogPosition(const gfx::Rect& new_pos);
+ // window border. If |no_redraw| is set, the window is getting moved but not
+ // sized, and should not be redrawn to reduce update flicker.
+ void SetDialogPosition(const gfx::Rect& new_pos, bool no_redraw);
// The dialog needs rounded edges, so we create a polygon that corresponds to
// the background images for this window (and make the polygon only contain
@@ -182,46 +151,26 @@ class FindBarWin : public views::FocusChangeListener,
// also: SetFocusChangeListener().
void UnregisterEscAccelerator();
- // The tab we are associated with.
- WebContentsView* parent_tab_;
+ // Updates the FindBarView with the find result details contained within the
+ // specified |result|.
+ void UpdateUIForFindResult(const FindNotificationDetails& result,
+ const std::wstring& find_text);
+
+ // The WebContents we are currently associated with.
+ WebContents* web_contents_;
- // The window handle of our parent window (the main Chrome window).
- HWND parent_hwnd_;
+ // The BrowserView that created us.
+ BrowserView* browser_view_;
// Our view, which is responsible for drawing the UI.
FindBarView* view_;
- // Each time a search request comes in we assign it an id before passing it
- // over the IPC so that when the results come in we can evaluate whether we
- // still care about the results of the search (in some cases we don't because
- // the user has issued a new search).
- static int request_id_counter_;
-
- // This variable keeps track of what the most recent request id is.
- int current_request_id_;
-
- // The current string we are searching for.
- std::wstring find_string_;
-
- // The last string we searched for. This is used to figure out if this is a
- // Find or a FindNext operation (FindNext should not increase the request id).
- std::wstring last_find_string_;
-
- // The current window position (relative to parent).
- gfx::Rect curr_pos_relative_;
-
- // The current window size.
- gfx::Size window_size_;
-
// The y position pixel offset of the window while animating the Find dialog.
int find_dialog_animation_offset_;
// The animation class to use when opening the Find window.
scoped_ptr<SlideAnimation> animation_;
- // Whether to show the Find dialog when its tab becomes selected again.
- bool show_on_tab_selection_;
-
// The focus manager we register with to keep track of focus changes.
views::FocusManager* focus_manager_;
diff --git a/chrome/browser/views/find_bar_win_interactive_uitest.cc b/chrome/browser/views/find_bar_win_interactive_uitest.cc
index 9bb7d9c..e767506 100644
--- a/chrome/browser/views/find_bar_win_interactive_uitest.cc
+++ b/chrome/browser/views/find_bar_win_interactive_uitest.cc
@@ -66,13 +66,13 @@ TEST_F(FindInPageTest, CrashEscHandlers) {
scoped_ptr<TabProxy> tabA(GetActiveTab());
EXPECT_NE(AUTOMATION_MSG_NAVIGATION_ERROR, tabA->NavigateToURL(url));
- EXPECT_TRUE(tabA->OpenFindInPage());
+ EXPECT_TRUE(browser->OpenFindInPage());
// Open another tab (tab B).
EXPECT_TRUE(browser->AppendTab(url));
scoped_ptr<TabProxy> tabB(GetActiveTab());
- EXPECT_TRUE(tabB->OpenFindInPage());
+ EXPECT_TRUE(browser->OpenFindInPage());
// Select tab A.
EXPECT_TRUE(ActivateTabByClick(automation(), window.get(), 0));
diff --git a/chrome/browser/views/find_bar_win_uitest.cc b/chrome/browser/views/find_bar_win_uitest.cc
index 607aa14..21d2287 100644
--- a/chrome/browser/views/find_bar_win_uitest.cc
+++ b/chrome/browser/views/find_bar_win_uitest.cc
@@ -41,23 +41,20 @@ TEST_F(FindInPageControllerTest, FindInPageOrdinal) {
int ordinal = 0;
EXPECT_EQ(3, tab->FindInPage(L"o", FWD, IGNORE_CASE, false, &ordinal));
EXPECT_EQ(1, ordinal);
- // FindNext returns -1 for match count because it doesn't bother with
- // recounting the number of matches. We don't care about the match count
- // anyway in this case, we just want to check the ordinal.
- EXPECT_EQ(-1, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(3, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(2, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(3, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(3, ordinal);
// Go back one match.
- EXPECT_EQ(-1, tab->FindInPage(L"o", BACK, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(3, tab->FindInPage(L"o", BACK, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(2, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(3, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(3, ordinal);
// This should wrap to the top.
- EXPECT_EQ(-1, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(3, tab->FindInPage(L"o", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(1, ordinal);
// This should go back to the end.
- EXPECT_EQ(-1, tab->FindInPage(L"o", BACK, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(3, tab->FindInPage(L"o", BACK, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(3, ordinal);
}
@@ -79,31 +76,28 @@ TEST_F(FindInPageControllerTest, FindInPageMultiFramesOrdinal) {
int ordinal = 0;
EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, false, &ordinal));
EXPECT_EQ(1, ordinal);
- // FindNext returns -1 for match count because it doesn't bother with
- // recounting the number of matches. We don't care about the match count
- // anyway in this case, we just want to check the ordinal.
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(2, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(3, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(4, ordinal);
// Go back one, which should go back one frame.
- EXPECT_EQ(-1, tab->FindInPage(L"a", BACK, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", BACK, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(3, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(4, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(5, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(6, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(7, ordinal);
// Now we should wrap back to frame 1.
- EXPECT_EQ(-1, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(1, ordinal);
// Now we should wrap back to frame last frame.
- EXPECT_EQ(-1, tab->FindInPage(L"a", BACK, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(7, tab->FindInPage(L"a", BACK, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(7, ordinal);
}
@@ -124,16 +118,13 @@ TEST_F(FindInPageControllerTest, FindInPage_Issue5132) {
int ordinal = 0;
EXPECT_EQ(6, tab->FindInPage(L"goa", FWD, IGNORE_CASE, false, &ordinal));
EXPECT_EQ(1, ordinal);
- // FindNext returns -1 for match count because it doesn't bother with
- // recounting the number of matches. We don't care about the match count
- // anyway in this case, we just want to check the ordinal.
- EXPECT_EQ(-1, tab->FindInPage(L"goa", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(6, tab->FindInPage(L"goa", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(2, ordinal);
- EXPECT_EQ(-1, tab->FindInPage(L"goa", FWD, IGNORE_CASE, true, &ordinal));
+ EXPECT_EQ(6, tab->FindInPage(L"goa", FWD, IGNORE_CASE, true, &ordinal));
EXPECT_EQ(3, ordinal);
// Add space to search (should result in no matches).
EXPECT_EQ(0, tab->FindInPage(L"goa ", FWD, IGNORE_CASE, false, &ordinal));
- EXPECT_EQ(-1, ordinal);
+ EXPECT_EQ(0, ordinal);
// Remove the space, should be back to '3 out of 6')
EXPECT_EQ(6, tab->FindInPage(L"goa", FWD, IGNORE_CASE, false, &ordinal));
EXPECT_EQ(3, ordinal);
@@ -170,10 +161,7 @@ TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) {
// against the frame, otherwise an active frame pointer is set and it wont
// produce the crash.
EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, false, NULL));
- // FindNext returns -1 for match count because it doesn't bother with
- // recounting the number of matches. We don't care about the match count
- // anyway in this case, we just want to make sure it doesn't crash.
- EXPECT_EQ(-1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, true, NULL));
+ EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, true, NULL));
// This should work fine.
EXPECT_EQ(1, tab->FindInPage(L"\u0D24\u0D46", FWD, IGNORE_CASE, false, NULL));
@@ -223,12 +211,12 @@ TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), true));
// Open the Find window and wait for it to animate.
- EXPECT_TRUE(tabA->OpenFindInPage());
- EXPECT_TRUE(WaitForFindWindowVisibilityChange(tabA.get(), true));
+ EXPECT_TRUE(browser->OpenFindInPage());
+ EXPECT_TRUE(WaitForFindWindowVisibilityChange(browser.get(), true));
// Find its location.
int x = -1, y = -1;
- EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));
+ EXPECT_TRUE(browser->GetFindWindowLocation(&x, &y));
// Open another tab (tab B).
EXPECT_TRUE(browser->AppendTab(url));
@@ -239,7 +227,7 @@ TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
// See if the Find window has moved.
int new_x = -1, new_y = -1;
- EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));
+ EXPECT_TRUE(browser->GetFindWindowLocation(&new_x, &new_y));
EXPECT_EQ(x, new_x);
EXPECT_EQ(y, new_y);
@@ -249,7 +237,7 @@ TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), false));
// Bookmark bar has moved, reset our coordinates.
- EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));
+ EXPECT_TRUE(browser->GetFindWindowLocation(&x, &y));
// Open another tab (tab C).
EXPECT_TRUE(browser->AppendTab(url));
@@ -259,7 +247,7 @@ TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
EXPECT_TRUE(tabC->Close(true));
// See if the Find window has moved.
- EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));
+ EXPECT_TRUE(browser->GetFindWindowLocation(&new_x, &new_y));
EXPECT_EQ(x, new_x);
EXPECT_EQ(y, new_y);
@@ -272,6 +260,7 @@ TEST_F(FindInPageControllerTest, FindDisappearOnNavigate) {
ASSERT_TRUE(NULL != server.get());
GURL url = server->TestServerPageW(kUserSelectPage);
+ GURL url2 = server->TestServerPageW(kFramePage);
scoped_ptr<TabProxy> tab(GetActiveTab());
ASSERT_TRUE(tab->NavigateToURL(url));
WaitUntilTabCount(1);
@@ -280,14 +269,14 @@ TEST_F(FindInPageControllerTest, FindDisappearOnNavigate) {
ASSERT_TRUE(browser.get() != NULL);
// Open the Find window and wait for it to animate.
- EXPECT_TRUE(tab->OpenFindInPage());
- EXPECT_TRUE(WaitForFindWindowVisibilityChange(tab.get(), true));
+ EXPECT_TRUE(browser->OpenFindInPage());
+ EXPECT_TRUE(WaitForFindWindowVisibilityChange(browser.get(), true));
// Reload the tab and make sure Find box doesn't go away.
EXPECT_TRUE(tab->Reload());
- EXPECT_TRUE(WaitForFindWindowVisibilityChange(tab.get(), true));
+ EXPECT_TRUE(WaitForFindWindowVisibilityChange(browser.get(), true));
// Navigate and make sure the Find box goes away.
- EXPECT_TRUE(tab->NavigateToURL(url));
- EXPECT_TRUE(WaitForFindWindowVisibilityChange(tab.get(), false));
+ EXPECT_TRUE(tab->NavigateToURL(url2));
+ EXPECT_TRUE(WaitForFindWindowVisibilityChange(browser.get(), false));
}
diff --git a/chrome/browser/views/find_bar_win_unittest.cc b/chrome/browser/views/find_bar_win_unittest.cc
index c80e26d..4ef345c 100644
--- a/chrome/browser/views/find_bar_win_unittest.cc
+++ b/chrome/browser/views/find_bar_win_unittest.cc
@@ -22,7 +22,7 @@ const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html";
class FindInPageNotificationObserver : public NotificationObserver {
public:
- FindInPageNotificationObserver(TabContents* parent_tab)
+ explicit FindInPageNotificationObserver(TabContents* parent_tab)
: parent_tab_(parent_tab),
active_match_ordinal_(-1),
number_of_matches_(0) {
@@ -89,10 +89,12 @@ class FindInPageControllerTest : public InProcessBrowserTest {
WebContents* web_contents =
browser()->GetSelectedTabContents()->AsWebContents();
if (web_contents) {
- web_contents->view()->FindInPage(*browser(), true, forward == FWD);
+ web_contents->set_current_find_request_id(
+ FindInPageNotificationObserver::kFindInPageRequestId);
web_contents->render_view_host()->StartFinding(
FindInPageNotificationObserver::kFindInPageRequestId,
- search_string, forward == FWD, match_case == CASE_SENSITIVE, find_next);
+ search_string, forward == FWD, match_case == CASE_SENSITIVE,
+ find_next);
return FindInPageNotificationObserver(web_contents).number_of_matches();
}
return 0;
diff --git a/chrome/browser/views/frame/browser_view.cc b/chrome/browser/views/frame/browser_view.cc
index c0476d5..be0020f 100644
--- a/chrome/browser/views/frame/browser_view.cc
+++ b/chrome/browser/views/frame/browser_view.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/views/bug_report_view.h"
#include "chrome/browser/views/clear_browsing_data.h"
#include "chrome/browser/views/download_shelf_view.h"
+#include "chrome/browser/views/find_bar_win.h"
#include "chrome/browser/views/frame/browser_frame.h"
#include "chrome/browser/views/fullscreen_exit_bubble.h"
#include "chrome/browser/views/html_dialog_view.h"
@@ -86,6 +87,8 @@ static const int kDefaultHungPluginDetectFrequency = 2000;
static const int kDefaultPluginMessageResponseTimeout = 30000;
// The number of milliseconds between loading animation frames.
static const int kLoadingAnimationFrameTimeMs = 30;
+// The amount of space we expect the window border to take up.
+static const int kWindowBorderWidth = 5;
// If not -1, windows are shown with this state.
static int explicit_show_state = -1;
@@ -180,6 +183,8 @@ BrowserView::BrowserView(Browser* browser)
active_bookmark_bar_(NULL),
active_download_shelf_(NULL),
toolbar_(NULL),
+ infobar_container_(NULL),
+ find_bar_y_(0),
contents_container_(NULL),
initialized_(false),
fullscreen_(false),
@@ -253,6 +258,44 @@ gfx::Rect BrowserView::GetClientAreaBounds() const {
return container_bounds;
}
+bool BrowserView::ShouldFindBarBlendWithBookmarksBar() const {
+ if (bookmark_bar_view_.get())
+ return bookmark_bar_view_->IsAlwaysShown();
+ return false;
+}
+
+gfx::Rect BrowserView::GetFindBarBoundingBox() const {
+ // This function returns the area the Find Bar can be laid out within. This
+ // basically implies the "user-perceived content area" of the browser window
+ // excluding the vertical scrollbar. This is not quite so straightforward as
+ // positioning based on the TabContentsContainerView since the BookmarkBarView
+ // may be visible but not persistent (in the New Tab case) and we position
+ // the Find Bar over the top of it in that case since the BookmarkBarView is
+ // not _visually_ connected to the Toolbar.
+
+ // First determine the bounding box of the content area in Widget coordinates.
+ gfx::Rect bounding_box(contents_container_->bounds());
+
+ gfx::Point topleft;
+ views::View::ConvertPointToWidget(contents_container_, &topleft);
+ bounding_box.set_origin(topleft);
+
+ // Adjust the position and size of the bounding box by the find bar offset
+ // calculated during the last Layout.
+ int height_delta = find_bar_y_ - bounding_box.y();
+ bounding_box.set_y(find_bar_y_);
+ bounding_box.set_height(std::max(0, bounding_box.height() + height_delta));
+
+ // Finally decrease the width of the bounding box by the width of the vertical
+ // scroll bar.
+ int scrollbar_width = views::NativeScrollBar::GetVerticalScrollBarWidth();
+ bounding_box.set_width(std::max(0, bounding_box.width() - scrollbar_width));
+ if (UILayoutIsRightToLeft())
+ bounding_box.set_x(bounding_box.x() + scrollbar_width);
+
+ return bounding_box;
+}
+
int BrowserView::GetTabStripHeight() const {
return tabstrip_->GetPreferredHeight();
}
@@ -421,6 +464,8 @@ void BrowserView::Init() {
infobar_container_ = new InfoBarContainer(this);
AddChildView(infobar_container_);
+ find_bar_.reset(new FindBarWin(this));
+
contents_container_ = new TabContentsContainerView;
set_contents_view(contents_container_);
AddChildView(contents_container_);
@@ -694,6 +739,10 @@ void BrowserView::ToggleBookmarkBar() {
BookmarkBarView::ToggleWhenVisible(browser_->profile());
}
+void BrowserView::ShowFindBar() {
+ find_bar_->Show();
+}
+
void BrowserView::ShowAboutChromeDialog() {
views::Window::CreateChromeWindow(
GetWidget()->GetHWND(), gfx::Rect(),
@@ -800,6 +849,22 @@ LocationBarView* BrowserView::GetLocationBarView() const {
return toolbar_->GetLocationBarView();
}
+bool BrowserView::GetFindBarWindowInfo(gfx::Point* position,
+ bool* fully_visible) const {
+ CRect window_rect;
+ if (!find_bar_.get() ||
+ !::IsWindow(find_bar_->GetHWND()) ||
+ !::GetWindowRect(find_bar_->GetHWND(), &window_rect)) {
+ *position = gfx::Point(0, 0);
+ *fully_visible = false;
+ return false;
+ }
+
+ *position = gfx::Point(window_rect.TopLeft().x, window_rect.TopLeft().y);
+ *fully_visible = find_bar_->IsVisible() && !find_bar_->IsAnimating();
+ return true;
+}
+
///////////////////////////////////////////////////////////////////////////////
// BrowserView, NotificationObserver implementation:
@@ -828,6 +893,10 @@ void BrowserView::TabDetachedAt(TabContents* contents, int index) {
// on the selected TabContents when it is removed.
infobar_container_->ChangeTabContents(NULL);
contents_container_->SetTabContents(NULL);
+ // When dragging the last TabContents out of a window there is no selection
+ // notification that causes the find bar for that window to be un-registered
+ // for notifications from this TabContents.
+ find_bar_->ChangeWebContents(NULL);
}
}
@@ -862,6 +931,9 @@ void BrowserView::TabSelectedAt(TabContents* old_contents,
toolbar_->SetProfile(new_contents->profile());
UpdateToolbar(new_contents, true);
UpdateUIForContents(new_contents);
+
+ if (find_bar_.get() && new_contents->AsWebContents())
+ find_bar_->ChangeWebContents(new_contents->AsWebContents());
}
void BrowserView::TabStripEmpty() {
@@ -1114,6 +1186,11 @@ void BrowserView::Layout() {
top = LayoutBookmarkAndInfoBars(top);
int bottom = LayoutDownloadShelf();
LayoutTabContents(top, bottom);
+ // This must be done _after_ we lay out the TabContents since this code calls
+ // back into us to find the bounding box the find bar must be laid out within,
+ // and that code depends on the TabContentsContainer's bounds being up to
+ // date.
+ find_bar_->MoveWindowIfNecessary(gfx::Rect(), true);
LayoutStatusBubble(bottom);
#ifdef CHROME_PERSONALIZATION
if (IsPersonalizationEnabled()) {
@@ -1121,8 +1198,6 @@ void BrowserView::Layout() {
toolbar_, 0);
}
#endif
-
-
SchedulePaint();
}
@@ -1267,16 +1342,17 @@ int BrowserView::LayoutToolbar(int top) {
}
int BrowserView::LayoutBookmarkAndInfoBars(int top) {
+ find_bar_y_ = top + y() - 1;
if (bookmark_bar_view_.get()) {
// If we're showing the Bookmark bar in detached style, then we need to show
// any Info bar _above_ the Bookmark bar, since the Bookmark bar is styled
// to look like it's part of the page.
if (bookmark_bar_view_->IsDetachedStyle())
return LayoutBookmarkBar(LayoutInfoBar(top));
-
// Otherwise, Bookmark bar first, Info bar second.
top = LayoutBookmarkBar(top);
}
+ find_bar_y_ = top + y() - 1;
return LayoutInfoBar(top);
}
diff --git a/chrome/browser/views/frame/browser_view.h b/chrome/browser/views/frame/browser_view.h
index c91af8e..c228246 100644
--- a/chrome/browser/views/frame/browser_view.h
+++ b/chrome/browser/views/frame/browser_view.h
@@ -24,6 +24,7 @@ class BookmarkBarView;
class Browser;
class BrowserToolbarView;
class EncodingMenuControllerDelegate;
+class FindBarWin;
class FullscreenExitBubble;
class InfoBarContainer;
class Menu;
@@ -73,6 +74,19 @@ class BrowserView : public BrowserWindow,
// BrowserView's parent.
gfx::Rect GetClientAreaBounds() const;
+ // Returns true if the Find Bar should be rendered such that it appears to
+ // blend with the Bookmarks Bar. False if it should appear to blend with the
+ // main Toolbar. The return value will vary depending on whether or not the
+ // Bookmark Bar is always shown.
+ bool ShouldFindBarBlendWithBookmarksBar() const;
+
+ // Returns the constraining bounding box that should be used to lay out the
+ // FindBar within. This is _not_ the size of the find bar, just the bounding
+ // box it should be laid out within. The coordinate system of the returned
+ // rect is in the coordinate system of the frame, since the FindBar is a child
+ // window.
+ gfx::Rect GetFindBarBoundingBox() const;
+
// Returns the preferred height of the TabStrip. Used to position the OTR
// avatar icon.
int GetTabStripHeight() const;
@@ -181,6 +195,7 @@ class BrowserView : public BrowserWindow,
virtual bool IsBookmarkBarVisible() const;
virtual gfx::Rect GetRootWindowResizerRect() const;
virtual void ToggleBookmarkBar();
+ virtual void ShowFindBar();
virtual void ShowAboutChromeDialog();
virtual void ShowBookmarkManager();
virtual void ShowBookmarkBubble(const GURL& url, bool already_bookmarked);
@@ -193,6 +208,8 @@ class BrowserView : public BrowserWindow,
virtual void ShowNewProfileDialog();
virtual void ShowHTMLDialog(HtmlDialogContentsDelegate* delegate,
void* parent_window);
+ virtual bool GetFindBarWindowInfo(gfx::Point* position,
+ bool* fully_visible) const;
// Overridden from BrowserWindowTesting:
virtual BookmarkBarView* GetBookmarkBarView() const;
@@ -372,6 +389,13 @@ class BrowserView : public BrowserWindow,
// The InfoBarContainer that contains InfoBars for the current tab.
InfoBarContainer* infobar_container_;
+ // The Find Bar. This may be NULL if there is no Find Bar, and if it is
+ // non-NULL, it may or may not be visible.
+ scoped_ptr<FindBarWin> find_bar_;
+
+ // The distance the FindBar is from the top of the window, in pixels.
+ int find_bar_y_;
+
// The view that contains the selected TabContents.
TabContentsContainerView* contents_container_;
@@ -437,7 +461,7 @@ class BrowserView : public BrowserWindow,
bool personalization_enabled_;
#endif
- DISALLOW_EVIL_CONSTRUCTORS(BrowserView);
+ DISALLOW_COPY_AND_ASSIGN(BrowserView);
};
#endif // CHROME_BROWSER_VIEWS_FRAME_BROWSER_VIEW_H_