diff options
author | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-01 16:24:09 +0000 |
---|---|---|
committer | avi@chromium.org <avi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-01 16:24:09 +0000 |
commit | fdfb032b5ba7f106ee7e44580bbda1580af15dbb (patch) | |
tree | 835b3086386b5c5e0abde993e6f082496a105443 | |
parent | c80580c78a15a2436cce54088921d88540a962e1 (diff) | |
download | chromium_src-fdfb032b5ba7f106ee7e44580bbda1580af15dbb.zip chromium_src-fdfb032b5ba7f106ee7e44580bbda1580af15dbb.tar.gz chromium_src-fdfb032b5ba7f106ee7e44580bbda1580af15dbb.tar.bz2 |
Move find-in-page from TabContents to TabContentsWrapper.
BUG=71097
TEST=Hammer on find-in-page on all platforms. Nothing should crash, break, or have any user-visible change.
Review URL: http://codereview.chromium.org/6378014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@73294 0039d316-1c4b-4281-b951-d872f2087c98
31 files changed, 553 insertions, 349 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm index c2841f4..236a21e 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm @@ -18,6 +18,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/ui/cocoa/event_utils.h" #include "chrome/browser/ui/toolbar/toolbar_model.h" +#include "gfx/rect.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" #include "net/base/escape.h" diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc index 294ba39..2a8f6b1 100644 --- a/chrome/browser/automation/automation_provider.cc +++ b/chrome/browser/automation/automation_provider.cc @@ -78,9 +78,11 @@ #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_manager.h" #include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/login/login_prompt.h" #include "chrome/browser/ui/omnibox/location_bar.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/automation_constants.h" #include "chrome/common/automation_messages.h" #include "chrome/common/chrome_constants.h" @@ -529,7 +531,10 @@ void AutomationProvider::SendFindRequest( if (!with_json) { find_in_page_observer_.reset(observer); } - tab_contents->set_current_find_request_id(request_id); + TabContentsWrapper** wrapper = + TabContentsWrapper::property_accessor()->GetProperty( + tab_contents->property_bag()); + (*wrapper)->GetFindManager()->set_current_find_request_id(request_id); tab_contents->render_view_host()->StartFinding( FindInPageNotificationObserver::kFindInPageRequestId, search_string, diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index f496a7a..1560946 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -50,6 +50,7 @@ #include "chrome/browser/translate/page_translated_details.h" #include "chrome/browser/translate/translate_infobar_delegate.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/login/login_prompt.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/automation_constants.h" diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc index 75a6304..f46b176 100644 --- a/chrome/browser/browser_focus_uitest.cc +++ b/chrome/browser/browser_focus_uitest.cc @@ -343,7 +343,7 @@ IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_TabsRememberFocusFindInPage) { ui_test_utils::NavigateToURL(browser(), url); browser()->Find(); - ui_test_utils::FindInPage(browser()->GetSelectedTabContents(), + ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(), ASCIIToUTF16("a"), true, false, NULL); ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 9c1b81d..3e0e8d6 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -34,6 +34,7 @@ class RenderViewHostDelegate; class SessionStorageNamespace; class SiteInstance; class SkBitmap; +class TabContents; class ViewMsg_Navigate; struct ContentSettings; struct ContextMenuParams; diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 8a941cd..0c8e6de 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -80,7 +80,6 @@ #include "chrome/browser/tab_contents/thumbnail_generator.h" #include "chrome/browser/translate/page_translated_details.h" #include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" -#include "chrome/browser/ui/find_bar/find_bar_state.h" #include "chrome/common/bindings_policy.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/content_restriction.h" @@ -254,10 +253,6 @@ void MakeNavigateParams(const NavigationEntry& entry, // TabContents ---------------------------------------------------------------- -// static -int TabContents::find_request_id_counter_ = -1; - - TabContents::TabContents(Profile* profile, SiteInstance* site_instance, int routing_id, @@ -298,11 +293,6 @@ TabContents::TabContents(Profile* profile, dont_notify_render_view_(false), displayed_insecure_content_(false), infobar_delegates_(), - find_ui_active_(false), - find_op_aborted_(false), - current_find_request_id_(find_request_id_counter_++), - last_search_case_sensitive_(false), - last_search_result_(), extension_app_(NULL), capturing_contents_(false), is_being_destroyed_(false), @@ -538,7 +528,6 @@ bool TabContents::OnMessageReceived(const IPC::Message& message) { OnUpdateContentRestrictions) IPC_MESSAGE_HANDLER(ViewHostMsg_PDFHasUnsupportedFeature, OnPDFHasUnsupportedFeature) - IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply) IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset) IPC_MESSAGE_HANDLER(ViewHostMsg_DidGetApplicationInfo, OnDidGetApplicationInfo) @@ -1281,74 +1270,6 @@ void TabContents::DidMoveOrResize(ConstrainedWindow* window) { #endif } -void TabContents::StartFinding(string16 search_string, - bool forward_direction, - bool case_sensitive) { - // If search_string is empty, it means FindNext was pressed with a keyboard - // shortcut so unless we have something to search for we return early. - if (search_string.empty() && find_text_.empty()) { - string16 last_search_prepopulate_text = - FindBarState::GetLastPrepopulateText(profile()); - - // Try the last thing we searched for on this tab, then the last thing - // searched for on any tab. - if (!previous_find_text_.empty()) - search_string = previous_find_text_; - else if (!last_search_prepopulate_text.empty()) - search_string = last_search_prepopulate_text; - else - return; - } - - // Keep track of the previous search. - previous_find_text_ = find_text_; - - // 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_ == search_string || search_string.empty()) && - (last_search_case_sensitive_ == case_sensitive) && - !find_op_aborted_; - if (!find_next) - current_find_request_id_ = find_request_id_counter_++; - - if (!search_string.empty()) - find_text_ = search_string; - last_search_case_sensitive_ = case_sensitive; - - find_op_aborted_ = false; - - // Keep track of what the last search was across the tabs. - FindBarState* find_bar_state = profile()->GetFindBarState(); - find_bar_state->set_last_prepopulate_text(find_text_); - render_view_host()->StartFinding(current_find_request_id_, - find_text_, - forward_direction, - case_sensitive, - find_next); -} - -void TabContents::StopFinding( - FindBarController::SelectionAction selection_action) { - if (selection_action == FindBarController::kClearSelection) { - // kClearSelection means the find string has been cleared by the user, but - // the UI has not been dismissed. In that case we want to clear the - // previously remembered search (http://crbug.com/42639). - previous_find_text_ = string16(); - } else { - find_ui_active_ = false; - if (!find_text_.empty()) - previous_find_text_ = find_text_; - } - find_text_.clear(); - find_op_aborted_ = true; - last_search_result_ = FindNotificationDetails(); - render_view_host()->StopFinding(selection_action); -} - void TabContents::OnSavePage() { // If we can not save the page, try to download it. if (!SavePackage::IsSavableContents(contents_mime_type())) { @@ -2171,46 +2092,6 @@ void TabContents::GenerateKeywordIfNecessary( url_model->Add(new_url); } -void TabContents::OnFindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - // Ignore responses for requests that have been aborted. - // 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 (!find_op_aborted_ && request_id == current_find_request_id_) { - if (number_of_matches == -1) - number_of_matches = last_search_result_.number_of_matches(); - if (active_match_ordinal == -1) - active_match_ordinal = last_search_result_.active_match_ordinal(); - - gfx::Rect selection = selection_rect; - if (selection.IsEmpty()) - selection = last_search_result_.selection_rect(); - - // Notify the UI, automation and any other observers that a find result was - // found. - last_search_result_ = FindNotificationDetails( - request_id, number_of_matches, selection, active_match_ordinal, - final_update); - NotificationService::current()->Notify( - NotificationType::FIND_RESULT_AVAILABLE, - Source<TabContents>(this), - Details<FindNotificationDetails>(&last_search_result_)); - } - - // Send a notification to the renderer that we are ready to receive more - // results from the scoping effort of the Find operation. The FindInPage - // scoping is asynchronous and periodically sends results back up to the - // browser using IPC. In an effort to not spam the browser we have the - // browser send an ACK for each FindReply message and have the renderer - // queue up the latest status message while waiting for this ACK. - render_view_host()->Send(new ViewMsg_FindReplyACK( - render_view_host()->routing_id())); -} - void TabContents::OnGoToEntryAtOffset(int offset) { if (!delegate_ || delegate_->OnGoToEntryOffset(offset)) { NavigationEntry* entry = controller_.GetEntryAtOffset(offset); diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index fa7a6a5..e24e030 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -29,8 +29,6 @@ #include "chrome/browser/tab_contents/render_view_host_manager.h" #include "chrome/browser/tab_contents/tab_specific_content_settings.h" #include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h" -#include "chrome/browser/ui/find_bar/find_bar_controller.h" -#include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/property_bag.h" #include "chrome/common/renderer_preferences.h" @@ -538,50 +536,6 @@ class TabContents : public PageNavigator, 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(string16 search_string, - bool forward_direction, - bool case_sensitive); - - // Stops the current Find operation. - void StopFinding(FindBarController::SelectionAction selection_action); - - // 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; - } - - // Setter for find_op_aborted_. - void set_find_op_aborted(bool find_op_aborted) { - find_op_aborted_ = find_op_aborted; - } - - // Used _only_ by testing to get or set the current request ID. - int current_find_request_id() { return current_find_request_id_; } - 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 TabContents has any - // active searches. - string16 find_text() const { return find_text_; } - - // Accessor for the previous search we issued. - string16 previous_find_text() const { return previous_find_text_; } - - // Accessor for find_result_. - const FindNotificationDetails& find_result() const { - return last_search_result_; - } - // Misc state & callbacks ---------------------------------------------------- // Set whether the contents should block javascript message boxes or not. @@ -814,11 +768,6 @@ class TabContents : public PageNavigator, void OnUpdateContentRestrictions(int restrictions); void OnPDFHasUnsupportedFeature(); - void OnFindReply(int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update); void OnGoToEntryAtOffset(int offset); void OnDidGetApplicationInfo(int32 page_id, const WebApplicationInfo& info); void OnInstallApplication(const WebApplicationInfo& info); @@ -1212,45 +1161,6 @@ class TabContents : public PageNavigator, // Delegates for InfoBars associated with this TabContents. std::vector<InfoBarDelegate*> infobar_delegates_; - // Data for find in page ----------------------------------------------------- - - // TODO(brettw) this should be separated into a helper class. - - // 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_; - - // 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. This can also be set if a page has been reloaded, and will - // on FindNext result in a full Find operation so that the highlighting for - // inactive matches can be repainted. - bool find_op_aborted_; - - // This variable keeps track of what the most recent request id is. - int current_find_request_id_; - - // The current string we are/just finished searching for. This is used to - // figure out if this is a Find or a FindNext operation (FindNext should not - // increase the request id). - string16 find_text_; - - // The string we searched for before |find_text_|. - string16 previous_find_text_; - - // Whether the last search was case sensitive or not. - bool last_search_case_sensitive_; - - // 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 last_search_result_; - // Data for app extensions --------------------------------------------------- // If non-null this tab is an app tab and this is the extension the tab was diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index d395497..05fd143 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -81,6 +81,7 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_manager.h" #include "chrome/browser/ui/omnibox/location_bar.h" #include "chrome/browser/ui/options/options_window.h" #include "chrome/browser/ui/status_bubble.h" @@ -449,7 +450,7 @@ FindBarController* Browser::GetFindBarController() { FindBar* find_bar = BrowserWindow::CreateFindBar(this); find_bar_controller_.reset(new FindBarController(find_bar)); find_bar->SetFindBarController(find_bar_controller_.get()); - find_bar_controller_->ChangeTabContents(GetSelectedTabContents()); + find_bar_controller_->ChangeTabContents(GetSelectedTabContentsWrapper()); find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true); } return find_bar_controller_.get(); @@ -2698,7 +2699,7 @@ void Browser::TabSelectedAt(TabContentsWrapper* old_contents, } if (HasFindBarController()) { - find_bar_controller_->ChangeTabContents(new_contents->tab_contents()); + find_bar_controller_->ChangeTabContents(new_contents); find_bar_controller_->find_bar()->MoveWindowIfNecessary(gfx::Rect(), true); } @@ -4114,9 +4115,10 @@ void Browser::FindInPage(bool find_next, bool forward_direction) { // We always want to search for the contents of the find pasteboard on OS X. find_text = GetFindPboardText(); #endif - GetSelectedTabContents()->StartFinding(find_text, - forward_direction, - false); // Not case sensitive. + GetSelectedTabContentsWrapper()-> + GetFindManager()->StartFinding(find_text, + forward_direction, + false); // Not case sensitive. } } diff --git a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm index b51607d..b6bb951 100644 --- a/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm +++ b/chrome/browser/ui/cocoa/find_bar/find_bar_cocoa_controller.mm @@ -17,6 +17,8 @@ #import "chrome/browser/ui/cocoa/focus_tracker.h" #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" namespace { @@ -81,17 +83,23 @@ const float kFindBarCloseDuration = 0.15; } - (IBAction)previousResult:(id)sender { - if (findBarBridge_) - findBarBridge_->GetFindBarController()->tab_contents()->StartFinding( + if (findBarBridge_) { + FindManager* find_manager = findBarBridge_-> + GetFindBarController()->tab_contents()->GetFindManager(); + find_manager->StartFinding( base::SysNSStringToUTF16([findText_ stringValue]), false, false); + } } - (IBAction)nextResult:(id)sender { - if (findBarBridge_) - findBarBridge_->GetFindBarController()->tab_contents()->StartFinding( + if (findBarBridge_) { + FindManager* find_manager = findBarBridge_-> + GetFindBarController()->tab_contents()->GetFindManager(); + find_manager->StartFinding( base::SysNSStringToUTF16([findText_ stringValue]), true, false); + } } - (void)findPboardUpdated:(NSNotification*)notification { @@ -122,10 +130,11 @@ const float kFindBarCloseDuration = 0.15; if (!findBarBridge_) return; - TabContents* tab_contents = + TabContentsWrapper* tab_contents = findBarBridge_->GetFindBarController()->tab_contents(); if (!tab_contents) return; + FindManager* find_manager = tab_contents->GetFindManager(); NSString* findText = [findText_ stringValue]; suppressPboardUpdateActions_ = YES; @@ -133,11 +142,11 @@ const float kFindBarCloseDuration = 0.15; suppressPboardUpdateActions_ = NO; if ([findText length] > 0) { - tab_contents->StartFinding(base::SysNSStringToUTF16(findText), true, false); + find_manager->StartFinding(base::SysNSStringToUTF16(findText), true, false); } else { // The textbox is empty so we reset. - tab_contents->StopFinding(FindBarController::kClearSelection); - [self updateUIForFindResult:tab_contents->find_result() + find_manager->StopFinding(FindBarController::kClearSelection); + [self updateUIForFindResult:find_manager->find_result() withText:string16()]; } } @@ -173,7 +182,7 @@ const float kFindBarCloseDuration = 0.15; command == @selector(scrollToEndOfDocument:) || command == @selector(moveUp:) || command == @selector(moveDown:)) { - TabContents* contents = + TabContentsWrapper* contents = findBarBridge_->GetFindBarController()->tab_contents(); if (!contents) return NO; @@ -238,7 +247,8 @@ const float kFindBarCloseDuration = 0.15; if (!(focusTracker_.get() && [focusTracker_ restoreFocusInWindow:[findBarView_ window]])) { // Fall back to giving focus to the tab contents. - findBarBridge_->GetFindBarController()->tab_contents()->Focus(); + findBarBridge_-> + GetFindBarController()->tab_contents()->tab_contents()->Focus(); } focusTracker_.reset(nil); } @@ -367,11 +377,12 @@ const float kFindBarCloseDuration = 0.15; // End the find session, hide the "x of y" text and disable the // buttons, but do not close the find bar or raise the window here. if (stopSearch && findBarBridge_) { - TabContents* contents = + TabContentsWrapper* contents = findBarBridge_->GetFindBarController()->tab_contents(); if (contents) { - contents->StopFinding(FindBarController::kClearSelection); - findBarBridge_->ClearResults(contents->find_result()); + FindManager* find_manager = contents->GetFindManager(); + find_manager->StopFinding(FindBarController::kClearSelection); + findBarBridge_->ClearResults(find_manager->find_result()); } } diff --git a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm index 1b40a00..3c8a5c3 100644 --- a/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm +++ b/chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm @@ -29,6 +29,7 @@ #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_navigator.h" +#include "chrome/browser/ui/find_bar/find_manager.h" #import "chrome/browser/ui/cocoa/browser_window_controller.h" #import "chrome/browser/ui/cocoa/constrained_window_mac.h" #import "chrome/browser/ui/cocoa/new_tab_button.h" @@ -1069,7 +1070,7 @@ private: newContents->tab_contents()->DidBecomeSelected(); newContents->view()->RestoreFocus(); - if (newContents->tab_contents()->find_ui_active()) + if (newContents->GetFindManager()->find_ui_active()) browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); } } diff --git a/chrome/browser/ui/find_bar/find_backend_unittest.cc b/chrome/browser/ui/find_bar/find_backend_unittest.cc index c4ec58b..d40a968 100644 --- a/chrome/browser/ui/find_bar/find_backend_unittest.cc +++ b/chrome/browser/ui/find_bar/find_backend_unittest.cc @@ -5,13 +5,15 @@ #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "chrome/browser/renderer_host/test/test_render_view_host.h" #include "chrome/browser/tab_contents/test_tab_contents.h" #include "chrome/browser/ui/find_bar/find_bar_state.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h" #include "chrome/common/url_constants.h" #include "chrome/test/testing_profile.h" -typedef RenderViewHostTestHarness FindBackendTest; +typedef TabContentsWrapperTestHarness FindBackendTest; namespace { @@ -24,18 +26,21 @@ string16 FindPrepopulateText(TabContents* contents) { // This test takes two TabContents objects, searches in both of them and // tests the internal state for find_text and find_prepopulate_text. TEST_F(FindBackendTest, InternalState) { + FindManager* find_manager = contents_wrapper()->GetFindManager(); // Initial state for the TabContents is blank strings. EXPECT_EQ(string16(), FindPrepopulateText(contents())); - EXPECT_EQ(string16(), contents()->find_text()); + EXPECT_EQ(string16(), find_manager->find_text()); // Get another TabContents object ready. - TestTabContents contents2(profile_.get(), NULL); + TestTabContents* contents2 = new TestTabContents(profile_.get(), NULL); + TabContentsWrapper wrapper2(contents2); + FindManager* find_manager2 = wrapper2.GetFindManager(); // No search has still been issued, strings should be blank. EXPECT_EQ(string16(), FindPrepopulateText(contents())); - EXPECT_EQ(string16(), contents()->find_text()); - EXPECT_EQ(string16(), FindPrepopulateText(&contents2)); - EXPECT_EQ(string16(), contents2.find_text()); + EXPECT_EQ(string16(), find_manager->find_text()); + EXPECT_EQ(string16(), FindPrepopulateText(contents2)); + EXPECT_EQ(string16(), find_manager2->find_text()); string16 search_term1 = ASCIIToUTF16(" I had a 401K "); string16 search_term2 = ASCIIToUTF16(" but the economy "); @@ -43,34 +48,34 @@ TEST_F(FindBackendTest, InternalState) { // Start searching in the first TabContents, searching forwards but not case // sensitive (as indicated by the last two params). - contents()->StartFinding(search_term1, true, false); + find_manager->StartFinding(search_term1, true, false); // Pre-populate string should always match between the two, but find_text // should not. EXPECT_EQ(search_term1, FindPrepopulateText(contents())); - EXPECT_EQ(search_term1, contents()->find_text()); - EXPECT_EQ(search_term1, FindPrepopulateText(&contents2)); - EXPECT_EQ(string16(), contents2.find_text()); + EXPECT_EQ(search_term1, find_manager->find_text()); + EXPECT_EQ(search_term1, FindPrepopulateText(contents2)); + EXPECT_EQ(string16(), find_manager2->find_text()); // Now search in the other TabContents, searching forwards but not case // sensitive (as indicated by the last two params). - contents2.StartFinding(search_term2, true, false); + find_manager2->StartFinding(search_term2, true, false); // Again, pre-populate string should always match between the two, but // find_text should not. EXPECT_EQ(search_term2, FindPrepopulateText(contents())); - EXPECT_EQ(search_term1, contents()->find_text()); - EXPECT_EQ(search_term2, FindPrepopulateText(&contents2)); - EXPECT_EQ(search_term2, contents2.find_text()); + EXPECT_EQ(search_term1, find_manager->find_text()); + EXPECT_EQ(search_term2, FindPrepopulateText(contents2)); + EXPECT_EQ(search_term2, find_manager2->find_text()); // Search again in the first TabContents, searching forwards but not case // sensitive (as indicated by the last two params). - contents()->StartFinding(search_term3, true, false); + find_manager->StartFinding(search_term3, true, false); // Once more, pre-populate string should always match between the two, but // find_text should not. EXPECT_EQ(search_term3, FindPrepopulateText(contents())); - EXPECT_EQ(search_term3, contents()->find_text()); - EXPECT_EQ(search_term3, FindPrepopulateText(&contents2)); - EXPECT_EQ(search_term2, contents2.find_text()); + EXPECT_EQ(search_term3, find_manager->find_text()); + EXPECT_EQ(search_term3, FindPrepopulateText(contents2)); + EXPECT_EQ(search_term2, find_manager2->find_text()); } diff --git a/chrome/browser/ui/find_bar/find_bar_controller.cc b/chrome/browser/ui/find_bar/find_bar_controller.cc index 4f637e8..53dfe00 100644 --- a/chrome/browser/ui/find_bar/find_bar_controller.cc +++ b/chrome/browser/ui/find_bar/find_bar_controller.cc @@ -11,7 +11,8 @@ #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_state.h" -#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" #include "gfx/rect.h" @@ -30,12 +31,14 @@ FindBarController::~FindBarController() { } void FindBarController::Show() { + FindManager* find_manager = tab_contents_->GetFindManager(); + // Only show the animation if we're not already showing a find bar for the // selected TabContents. - if (!tab_contents_->find_ui_active()) { + if (!find_manager->find_ui_active()) { MaybeSetPrepopulateText(); - tab_contents_->set_find_ui_active(true); + find_manager->set_find_ui_active(true); find_bar_->Show(true); } find_bar_->SetFocusAndSelection(); @@ -47,20 +50,22 @@ void FindBarController::EndFindSession(SelectionAction action) { // |tab_contents_| can be NULL for a number of reasons, for example when the // tab is closing. We must guard against that case. See issue 8030. if (tab_contents_) { + FindManager* find_manager = tab_contents_->GetFindManager(); + // When we hide the window, we need to notify the renderer that we are done // for now, so that we can abort the scoping effort and clear all the // tickmarks and highlighting. - tab_contents_->StopFinding(action); + find_manager->StopFinding(action); if (action != kKeepSelection) - find_bar_->ClearResults(tab_contents_->find_result()); + find_bar_->ClearResults(find_manager->find_result()); // When we get dismissed we restore the focus to where it belongs. find_bar_->RestoreSavedFocus(); } } -void FindBarController::ChangeTabContents(TabContents* contents) { +void FindBarController::ChangeTabContents(TabContentsWrapper* contents) { if (tab_contents_) { registrar_.RemoveAll(); find_bar_->StopAnimation(); @@ -71,7 +76,7 @@ void FindBarController::ChangeTabContents(TabContents* contents) { // Hide any visible find window from the previous tab if NULL |tab_contents| // is passed in or if the find UI is not active in the new tab. if (find_bar_->IsFindBarVisible() && - (!tab_contents_ || !tab_contents_->find_ui_active())) { + (!tab_contents_ || !tab_contents_->GetFindManager()->find_ui_active())) { find_bar_->Hide(false); } @@ -79,13 +84,13 @@ void FindBarController::ChangeTabContents(TabContents* contents) { return; registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE, - Source<TabContents>(tab_contents_)); + Source<TabContents>(tab_contents_->tab_contents())); registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, Source<NavigationController>(&tab_contents_->controller())); MaybeSetPrepopulateText(); - if (tab_contents_->find_ui_active()) { + if (tab_contents_->GetFindManager()->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 @@ -103,15 +108,16 @@ void FindBarController::ChangeTabContents(TabContents* contents) { void FindBarController::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { + FindManager* find_manager = tab_contents_->GetFindManager(); if (type == NotificationType::FIND_RESULT_AVAILABLE) { // Don't update for notifications from TabContentses other than the one we // are actively tracking. - if (Source<TabContents>(source).ptr() == tab_contents_) { + if (Source<TabContents>(source).ptr() == tab_contents_->tab_contents()) { UpdateFindBarForCurrentResult(); - if (tab_contents_->find_result().final_update() && - tab_contents_->find_result().number_of_matches() == 0) { - const string16& last_search = tab_contents_->previous_find_text(); - const string16& current_search = tab_contents_->find_text(); + if (find_manager->find_result().final_update() && + find_manager->find_result().number_of_matches() == 0) { + const string16& last_search = find_manager->previous_find_text(); + const string16& current_search = find_manager->find_text(); if (last_search.find(current_search) != 0) find_bar_->AudibleAlert(); } @@ -133,7 +139,7 @@ void FindBarController::Observe(NotificationType type, } else { // On Reload we want to make sure FindNext is converted to a full Find // to make sure highlights for inactive matches are repainted. - tab_contents_->set_find_op_aborted(true); + find_manager->set_find_op_aborted(true); } } } @@ -181,7 +187,8 @@ gfx::Rect FindBarController::GetLocationForFindbarView( } void FindBarController::UpdateFindBarForCurrentResult() { - const FindNotificationDetails& find_result = tab_contents_->find_result(); + FindManager* find_manager = tab_contents_->GetFindManager(); + const FindNotificationDetails& find_result = find_manager->find_result(); // Avoid bug 894389: When a new search starts (and finds something) it reports // an interim match count result of 1 before the scoping effort starts. This @@ -198,7 +205,7 @@ void FindBarController::UpdateFindBarForCurrentResult() { last_reported_matchcount_ = find_result.number_of_matches(); } - find_bar_->UpdateUIForFindResult(find_result, tab_contents_->find_text()); + find_bar_->UpdateUIForFindResult(find_result, find_manager->find_text()); } void FindBarController::MaybeSetPrepopulateText() { @@ -206,9 +213,10 @@ void FindBarController::MaybeSetPrepopulateText() { // Find out what we should show in the find text box. Usually, this will be // the last search in this tab, but if no search has been issued in this tab // we use the last search string (from any tab). - string16 find_string = tab_contents_->find_text(); + FindManager* find_manager = tab_contents_->GetFindManager(); + string16 find_string = find_manager->find_text(); if (find_string.empty()) - find_string = tab_contents_->previous_find_text(); + find_string = find_manager->previous_find_text(); if (find_string.empty()) { find_string = FindBarState::GetLastPrepopulateText(tab_contents_->profile()); diff --git a/chrome/browser/ui/find_bar/find_bar_controller.h b/chrome/browser/ui/find_bar/find_bar_controller.h index 1c3a1d6..75dce1f 100644 --- a/chrome/browser/ui/find_bar/find_bar_controller.h +++ b/chrome/browser/ui/find_bar/find_bar_controller.h @@ -16,7 +16,7 @@ class Rect; } class FindBar; -class TabContents; +class TabContentsWrapper; class FindBarController : public NotificationObserver { public: @@ -38,12 +38,12 @@ class FindBarController : public NotificationObserver { // Ends the current session. void EndFindSession(SelectionAction action); - // Accessor for the attached TabContents. - TabContents* tab_contents() const { return tab_contents_; } + // Accessor for the attached TabContentsWrapper. + TabContentsWrapper* tab_contents() const { return tab_contents_; } // Changes the TabContents that this FindBar is attached to. This occurs when // the user switches tabs in the Browser window. |contents| can be NULL. - void ChangeTabContents(TabContents* contents); + void ChangeTabContents(TabContentsWrapper* contents); // Overridden from NotificationObserver: virtual void Observe(NotificationType type, @@ -76,8 +76,8 @@ class FindBarController : public NotificationObserver { scoped_ptr<FindBar> find_bar_; - // The TabContents we are currently associated with. Can be NULL. - TabContents* tab_contents_; + // The TabContentsWrapper we are currently associated with. Can be NULL. + TabContentsWrapper* tab_contents_; // The last match count we reported to the user. This is used by // UpdateFindBarForCurrentResult to avoid flickering. diff --git a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc index 5b2f1c9..a96b9c4 100644 --- a/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc +++ b/chrome/browser/ui/find_bar/find_bar_host_browsertest.cc @@ -15,7 +15,9 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_manager.h" #include "chrome/browser/ui/find_bar/find_notification_details.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/test/in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" #include "net/test/test_server.h" @@ -115,7 +117,7 @@ class FindInPageControllerTest : public InProcessBrowserTest { // Platform independent FindInPage that takes |const wchar_t*| // as an input. -int FindInPageWchar(TabContents* tab, +int FindInPageWchar(TabContentsWrapper* tab, const wchar_t* search_str, bool forward, bool case_sensitive, @@ -135,7 +137,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageFrames) { // Try incremental search (mimicking user typing in). int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(18, FindInPageWchar(tab, L"g", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(1, ordinal); @@ -227,12 +229,12 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageEndState) { GURL url = test_server()->GetURL(kEndState); ui_test_utils::NavigateToURL(browser(), url); - TabContents* tab_contents = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab_contents = browser()->GetSelectedTabContentsWrapper(); ASSERT_TRUE(NULL != tab_contents); // Verify that nothing has focus. std::string result; - ASSERT_TRUE(FocusedOnPage(tab_contents, &result)); + ASSERT_TRUE(FocusedOnPage(tab_contents->tab_contents(), &result)); ASSERT_STREQ("{nothing focused}", result.c_str()); // Search for a text that exists within a link on the page. @@ -242,10 +244,11 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageEndState) { EXPECT_EQ(1, ordinal); // End the find session, which should set focus to the link. - tab_contents->StopFinding(FindBarController::kKeepSelection); + tab_contents-> + GetFindManager()->StopFinding(FindBarController::kKeepSelection); // Verify that the link is focused. - ASSERT_TRUE(FocusedOnPage(tab_contents, &result)); + ASSERT_TRUE(FocusedOnPage(tab_contents->tab_contents(), &result)); EXPECT_STREQ("link1", result.c_str()); // Search for a text that exists within a link on the page. @@ -261,10 +264,11 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageEndState) { &result)); // End the find session. - tab_contents->StopFinding(FindBarController::kKeepSelection); + tab_contents-> + GetFindManager()->StopFinding(FindBarController::kKeepSelection); // Verify that link2 is not focused. - ASSERT_TRUE(FocusedOnPage(tab_contents, &result)); + ASSERT_TRUE(FocusedOnPage(tab_contents->tab_contents(), &result)); EXPECT_STREQ("", result.c_str()); } @@ -279,7 +283,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageOrdinal) { // Search for 'o', which should make the first item active and return // '1 in 3' (1st ordinal of a total of 3 matches). - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); int ordinal = 0; EXPECT_EQ(3, FindInPageWchar(tab, L"o", kFwd, kIgnoreCase, &ordinal)); @@ -316,13 +320,11 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, GURL url = test_server()->GetURL(kSelectChangesOrdinal); ui_test_utils::NavigateToURL(browser(), url); - TabContents* tab_contents = browser()->GetSelectedTabContents(); - ASSERT_TRUE(NULL != tab_contents); - // Search for a text that exists within a link on the page. - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); + ASSERT_TRUE(NULL != tab); int ordinal = 0; - EXPECT_EQ(4, FindInPageWchar(tab_contents, + EXPECT_EQ(4, FindInPageWchar(tab, L"google", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(1, ordinal); @@ -330,7 +332,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, // Move the selection to link 1, after searching. std::string result; ASSERT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractString( - tab_contents->render_view_host(), + tab->render_view_host(), L"", L"window.domAutomationController.send(selectLink1());", &result)); @@ -343,7 +345,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, EXPECT_EQ(3, ordinal); // End the find session. - tab_contents->StopFinding(FindBarController::kKeepSelection); + tab->GetFindManager()->StopFinding(FindBarController::kKeepSelection); } // This test loads a page with frames and makes sure the ordinal returned makes @@ -357,7 +359,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPageMultiFramesOrdinal) { // Search for 'a', which should make the first item active and return // '1 in 7' (1st ordinal of a total of 7 matches). - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); int ordinal = 0; EXPECT_EQ(7, FindInPageWchar(tab, L"a", kFwd, kIgnoreCase, &ordinal)); @@ -408,7 +410,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindInPage_Issue5132) { // Search for 'goa' three times (6 matches on page). int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(6, FindInPageWchar(tab, L"goa", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(1, ordinal); @@ -437,7 +439,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindUnselectableText) { ui_test_utils::NavigateToURL(browser(), url); int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab, L"text", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(1, ordinal); } @@ -460,7 +462,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) { // TODO(jungshik): According to a native Malayalam speaker, it's ok not // to find U+0D4C. Still need to investigate further this issue. int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); FindInPageWchar(tab, L"\u0D4C", kFwd, kIgnoreCase, &ordinal); FindInPageWchar(tab, L"\u0D4C", kFwd, kIgnoreCase, &ordinal); @@ -484,7 +486,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindCrash_Issue14491) { // This used to crash the tab. int ordinal = 0; - EXPECT_EQ(0, FindInPageWchar(browser()->GetSelectedTabContents(), + EXPECT_EQ(0, FindInPageWchar(browser()->GetSelectedTabContentsWrapper(), L"s", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(0, ordinal); } @@ -507,7 +509,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, FindRestarts_Issue1155639) { // This string appears 5 times at the bottom of a long page. If Find restarts // properly after a timeout, it will find 5 matches, not just 1. int ordinal = 0; - EXPECT_EQ(5, FindInPageWchar(browser()->GetSelectedTabContents(), + EXPECT_EQ(5, FindInPageWchar(browser()->GetSelectedTabContentsWrapper(), L"008.xml", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(1, ordinal); @@ -523,7 +525,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, GURL url = test_server()->GetURL(kPrematureEnd); ui_test_utils::NavigateToURL(browser(), url); - TabContents* tab_contents = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab_contents = browser()->GetSelectedTabContentsWrapper(); ASSERT_TRUE(NULL != tab_contents); // Search for a text that exists within a link on the page. @@ -641,7 +643,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_FindMovesWhenObscuring) { // Search for 'Chromium' which the Find box is obscuring. int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); int index = 0; for (; index < kMoveIterations; ++index) { EXPECT_EQ(kMoveIterations, FindInPageWchar(tab, L"Chromium", @@ -687,7 +689,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, // Search for 'no_match'. No matches should be found. int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(0, FindInPageWchar(tab, L"no_match", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(0, ordinal); @@ -775,13 +777,14 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, StayActive) { // simulating keypresses here for searching for something and pressing // backspace, but that's been proven flaky in the past, so we go straight to // tab_contents. - TabContents* tab_contents = browser()->GetSelectedTabContents(); + FindManager* find_manager = + browser()->GetSelectedTabContentsWrapper()->GetFindManager(); // Stop the (non-existing) find operation, and clear the selection (which // signals the UI is still active). - tab_contents->StopFinding(FindBarController::kClearSelection); + find_manager->StopFinding(FindBarController::kClearSelection); // Make sure the Find UI flag hasn't been cleared, it must be so that the UI // still responds to browser window resizing. - ASSERT_TRUE(tab_contents->find_ui_active()); + ASSERT_TRUE(find_manager->find_ui_active()); } // Make sure F3 works after you FindNext a couple of times and end the Find @@ -795,7 +798,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, RestartSearchFromF3) { // Search for 'page'. Should have 1 match. int ordinal = 0; - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab, L"page", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(1, ordinal); @@ -826,7 +829,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PreferPreviousSearch) { // Find "Default". int ordinal = 0; - TabContents* tab1 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab1 = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab1, L"Default", kFwd, kIgnoreCase, &ordinal)); // Create a second tab. @@ -838,7 +841,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PreferPreviousSearch) { params.tabstrip_add_types = TabStripModel::ADD_NONE; browser::Navigate(¶ms); browser()->SelectTabContentsAt(1, false); - TabContents* tab2 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab2 = browser()->GetSelectedTabContentsWrapper(); EXPECT_NE(tab1, tab2); // Find "given". @@ -850,7 +853,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PreferPreviousSearch) { FindBarController::kKeepSelection); // Simulate F3. ui_test_utils::FindInPage(tab1, string16(), kFwd, kIgnoreCase, &ordinal); - EXPECT_EQ(tab1->find_text(), WideToUTF16(L"Default")); + EXPECT_EQ(tab1->GetFindManager()->find_text(), WideToUTF16(L"Default")); } // This tests that whenever you close and reopen the Find bar, it should show @@ -869,7 +872,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulateSameTab) { // Search for the word "page". int ordinal = 0; - TabContents* tab1 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab1 = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal)); // Open the Find box. @@ -908,13 +911,13 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulateInNewTab) { // Search for the word "page". int ordinal = 0; - TabContents* tab1 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab1 = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(ASCIIToUTF16("1 of 1"), GetMatchCountText()); // Now create a second tab and load the same page. browser()->AddSelectedTabWithURL(url, PageTransition::TYPED); - TabContents* tab2 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab2 = browser()->GetSelectedTabContentsWrapper(); EXPECT_NE(tab1, tab2); // Open the Find box. @@ -944,7 +947,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulatePreserveLast) { // Search for the word "page". int ordinal = 0; - TabContents* tab1 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab1 = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal)); // Open the Find box. @@ -962,7 +965,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, PrepopulatePreserveLast) { params.tabstrip_add_types = TabStripModel::ADD_NONE; browser::Navigate(¶ms); browser()->SelectTabContentsAt(1, false); - TabContents* tab2 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab2 = browser()->GetSelectedTabContentsWrapper(); EXPECT_NE(tab1, tab2); // Search for the word "text". @@ -1018,7 +1021,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_NoIncognitoPrepopulate) { // Search for the word "page" in the normal browser tab. int ordinal = 0; - TabContents* tab1 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab1 = browser()->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(tab1, L"page", kFwd, kIgnoreCase, &ordinal)); // Open the Find box. @@ -1042,7 +1045,8 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_NoIncognitoPrepopulate) { EXPECT_EQ(ASCIIToUTF16("page"), GetFindBarTextForBrowser(incognito_browser)); // Search for the word "text" in the incognito tab. - TabContents* incognito_tab = incognito_browser->GetSelectedTabContents(); + TabContentsWrapper* incognito_tab = + incognito_browser->GetSelectedTabContentsWrapper(); EXPECT_EQ(1, FindInPageWchar(incognito_tab, L"text", kFwd, kIgnoreCase, &ordinal)); EXPECT_EQ(ASCIIToUTF16("text"), GetFindBarTextForBrowser(incognito_browser)); @@ -1053,7 +1057,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, MAYBE_NoIncognitoPrepopulate) { // Now open a new tab in the original (non-incognito) browser. browser()->AddSelectedTabWithURL(url, PageTransition::TYPED); - TabContents* tab2 = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab2 = browser()->GetSelectedTabContentsWrapper(); EXPECT_NE(tab1, tab2); // Open the Find box and make sure it is prepopulated with the search term @@ -1070,12 +1074,12 @@ IN_PROC_BROWSER_TEST_F(FindInPageControllerTest, ActivateLinkNavigatesPage) { GURL url = test_server()->GetURL(kLinkPage); ui_test_utils::NavigateToURL(browser(), url); - TabContents* tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* tab = browser()->GetSelectedTabContentsWrapper(); int ordinal = 0; FindInPageWchar(tab, L"link", kFwd, kIgnoreCase, &ordinal); EXPECT_EQ(ordinal, 1); // End the find session, click on the link. - tab->StopFinding(FindBarController::kActivateSelection); + tab->GetFindManager()->StopFinding(FindBarController::kActivateSelection); EXPECT_TRUE(ui_test_utils::WaitForNavigationInCurrentTab(browser())); } diff --git a/chrome/browser/ui/find_bar/find_manager.cc b/chrome/browser/ui/find_bar/find_manager.cc new file mode 100644 index 0000000..b02bad6 --- /dev/null +++ b/chrome/browser/ui/find_bar/find_manager.cc @@ -0,0 +1,147 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/find_bar/find_manager.h" + +#include <vector> + +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/ui/find_bar/find_bar_state.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/render_messages.h" + +// static +int FindManager::find_request_id_counter_ = -1; + +FindManager::FindManager(TabContentsWrapper* tab_contents) + : tab_contents_(tab_contents), + find_ui_active_(false), + find_op_aborted_(false), + current_find_request_id_(find_request_id_counter_++), + last_search_case_sensitive_(false), + last_search_result_() { + DCHECK(tab_contents_); +} + +FindManager::~FindManager() { +} + +void FindManager::StartFinding(string16 search_string, + bool forward_direction, + bool case_sensitive) { + // If search_string is empty, it means FindNext was pressed with a keyboard + // shortcut so unless we have something to search for we return early. + if (search_string.empty() && find_text_.empty()) { + string16 last_search_prepopulate_text = + FindBarState::GetLastPrepopulateText(tab_contents_->profile()); + + // Try the last thing we searched for on this tab, then the last thing + // searched for on any tab. + if (!previous_find_text_.empty()) + search_string = previous_find_text_; + else if (!last_search_prepopulate_text.empty()) + search_string = last_search_prepopulate_text; + else + return; + } + + // Keep track of the previous search. + previous_find_text_ = find_text_; + + // 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_ == search_string || search_string.empty()) && + (last_search_case_sensitive_ == case_sensitive) && + !find_op_aborted_; + if (!find_next) + current_find_request_id_ = find_request_id_counter_++; + + if (!search_string.empty()) + find_text_ = search_string; + last_search_case_sensitive_ = case_sensitive; + + find_op_aborted_ = false; + + // Keep track of what the last search was across the tabs. + FindBarState* find_bar_state = tab_contents_->profile()->GetFindBarState(); + find_bar_state->set_last_prepopulate_text(find_text_); + tab_contents_->render_view_host()->StartFinding(current_find_request_id_, + find_text_, + forward_direction, + case_sensitive, + find_next); +} + +void FindManager::StopFinding( + FindBarController::SelectionAction selection_action) { + if (selection_action == FindBarController::kClearSelection) { + // kClearSelection means the find string has been cleared by the user, but + // the UI has not been dismissed. In that case we want to clear the + // previously remembered search (http://crbug.com/42639). + previous_find_text_ = string16(); + } else { + find_ui_active_ = false; + if (!find_text_.empty()) + previous_find_text_ = find_text_; + } + find_text_.clear(); + find_op_aborted_ = true; + last_search_result_ = FindNotificationDetails(); + tab_contents_->render_view_host()->StopFinding(selection_action); +} + +bool FindManager::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(FindManager, message) + IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnFindReply) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void FindManager::OnFindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update) { + // Ignore responses for requests that have been aborted. + // 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 (!find_op_aborted_ && request_id == current_find_request_id_) { + if (number_of_matches == -1) + number_of_matches = last_search_result_.number_of_matches(); + if (active_match_ordinal == -1) + active_match_ordinal = last_search_result_.active_match_ordinal(); + + gfx::Rect selection = selection_rect; + if (selection.IsEmpty()) + selection = last_search_result_.selection_rect(); + + // Notify the UI, automation and any other observers that a find result was + // found. + last_search_result_ = FindNotificationDetails( + request_id, number_of_matches, selection, active_match_ordinal, + final_update); + NotificationService::current()->Notify( + NotificationType::FIND_RESULT_AVAILABLE, + Source<TabContents>(tab_contents_->tab_contents()), + Details<FindNotificationDetails>(&last_search_result_)); + } + + // Send a notification to the renderer that we are ready to receive more + // results from the scoping effort of the Find operation. The FindInPage + // scoping is asynchronous and periodically sends results back up to the + // browser using IPC. In an effort to not spam the browser we have the + // browser send an ACK for each FindReply message and have the renderer + // queue up the latest status message while waiting for this ACK. + tab_contents_->render_view_host()->Send(new ViewMsg_FindReplyACK( + tab_contents_->render_view_host()->routing_id())); +} diff --git a/chrome/browser/ui/find_bar/find_manager.h b/chrome/browser/ui/find_bar/find_manager.h new file mode 100644 index 0000000..2a210f3 --- /dev/null +++ b/chrome/browser/ui/find_bar/find_manager.h @@ -0,0 +1,113 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_FIND_BAR_FIND_MANAGER_H_ +#define CHROME_BROWSER_UI_FIND_BAR_FIND_MANAGER_H_ +#pragma once + +#include "chrome/browser/tab_contents/tab_contents_observer.h" +#include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_notification_details.h" + +class TabContentsWrapper; + +// Per-tab find manager. Handles dealing with the life cycle of find sessions. +class FindManager : public TabContentsObserver { + public: + explicit FindManager(TabContentsWrapper* tab_contents); + virtual ~FindManager(); + + // 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(string16 search_string, + bool forward_direction, + bool case_sensitive); + + // Stops the current Find operation. + void StopFinding(FindBarController::SelectionAction selection_action); + + // 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; + } + + // Setter for find_op_aborted_. + void set_find_op_aborted(bool find_op_aborted) { + find_op_aborted_ = find_op_aborted; + } + + // Used _only_ by testing to get or set the current request ID. + int current_find_request_id() { return current_find_request_id_; } + 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 TabContents has any + // active searches. + string16 find_text() const { return find_text_; } + + // Accessor for the previous search we issued. + string16 previous_find_text() const { return previous_find_text_; } + + // Accessor for find_result_. + const FindNotificationDetails& find_result() const { + return last_search_result_; + } + + // TabContentsObserver overrides. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + + void OnFindReply(int request_id, + int number_of_matches, + const gfx::Rect& selection_rect, + int active_match_ordinal, + bool final_update); + + private: + TabContentsWrapper* tab_contents_; + + // 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_; + + // 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. This can also be set if a page has been reloaded, and will + // on FindNext result in a full Find operation so that the highlighting for + // inactive matches can be repainted. + bool find_op_aborted_; + + // This variable keeps track of what the most recent request id is. + int current_find_request_id_; + + // The current string we are/just finished searching for. This is used to + // figure out if this is a Find or a FindNext operation (FindNext should not + // increase the request id). + string16 find_text_; + + // The string we searched for before |find_text_|. + string16 previous_find_text_; + + // Whether the last search was case sensitive or not. + bool last_search_case_sensitive_; + + // 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 last_search_result_; + + DISALLOW_COPY_AND_ASSIGN(FindManager); +}; + +#endif // CHROME_BROWSER_UI_FIND_BAR_FIND_MANAGER_H_ diff --git a/chrome/browser/ui/gtk/browser_window_gtk.cc b/chrome/browser/ui/gtk/browser_window_gtk.cc index 79781b9..d0c21c6 100644 --- a/chrome/browser/ui/gtk/browser_window_gtk.cc +++ b/chrome/browser/ui/gtk/browser_window_gtk.cc @@ -37,6 +37,7 @@ #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_manager.h" #include "chrome/browser/ui/gtk/about_chrome_dialog.h" #include "chrome/browser/ui/gtk/accelerators_gtk.h" #include "chrome/browser/ui/gtk/bookmark_bar_gtk.h" @@ -1182,7 +1183,7 @@ void BrowserWindowGtk::TabSelectedAt(TabContentsWrapper* old_contents, // we are the active browser before calling RestoreFocus(). if (!browser_->tabstrip_model()->closing_all()) { new_contents->view()->RestoreFocus(); - if (new_contents->tab_contents()->find_ui_active()) + if (new_contents->GetFindManager()->find_ui_active()) browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); } diff --git a/chrome/browser/ui/gtk/find_bar_gtk.cc b/chrome/browser/ui/gtk/find_bar_gtk.cc index 55b30b0..f8136e8 100644 --- a/chrome/browser/ui/gtk/find_bar_gtk.cc +++ b/chrome/browser/ui/gtk/find_bar_gtk.cc @@ -20,6 +20,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/find_bar/find_bar_state.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/find_bar/find_notification_details.h" #include "chrome/browser/ui/gtk/browser_window_gtk.h" #include "chrome/browser/ui/gtk/cairo_cached_surface.h" #include "chrome/browser/ui/gtk/custom_button.h" @@ -31,6 +33,7 @@ #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" #include "chrome/browser/ui/gtk/tabs/tab_strip_gtk.h" #include "chrome/browser/ui/gtk/view_id_util.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/native_web_keyboard_event.h" #include "chrome/common/notification_service.h" #include "grit/generated_resources.h" @@ -449,7 +452,7 @@ void FindBarGtk::RestoreSavedFocus() { if (focus_store_.widget()) gtk_widget_grab_focus(focus_store_.widget()); else - find_bar_controller_->tab_contents()->Focus(); + find_bar_controller_->tab_contents()->tab_contents()->Focus(); } FindBarTesting* FindBarGtk::GetFindBarTesting() { @@ -574,20 +577,20 @@ string16 FindBarGtk::GetMatchCountText() { } void FindBarGtk::FindEntryTextInContents(bool forward_search) { - TabContents* tab_contents = find_bar_controller_->tab_contents(); + TabContentsWrapper* tab_contents = find_bar_controller_->tab_contents(); if (!tab_contents) return; + FindManager* find_manager = tab_contents->GetFindManager(); std::string new_contents(gtk_entry_get_text(GTK_ENTRY(text_entry_))); if (new_contents.length() > 0) { - tab_contents->StartFinding(UTF8ToUTF16(new_contents), forward_search, + find_manager->StartFinding(UTF8ToUTF16(new_contents), forward_search, false); // Not case sensitive. } else { // The textbox is empty so we reset. - tab_contents->StopFinding(FindBarController::kClearSelection); - UpdateUIForFindResult(find_bar_controller_->tab_contents()->find_result(), - string16()); + find_manager->StopFinding(FindBarController::kClearSelection); + UpdateUIForFindResult(find_manager->find_result(), string16()); // Clearing the text box should also clear the prepopulate state so that // when we close and reopen the Find box it doesn't show the search we @@ -657,7 +660,7 @@ bool FindBarGtk::MaybeForwardKeyEventToRenderer(GdkEventKey* event) { return false; } - TabContents* contents = find_bar_controller_->tab_contents(); + TabContentsWrapper* contents = find_bar_controller_->tab_contents(); if (!contents) return false; diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc index 43f4c49..cb44d61 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc @@ -8,6 +8,7 @@ #include "chrome/browser/password_manager/password_manager.h" #include "chrome/browser/password_manager_delegate_impl.h" #include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/ui/find_bar/find_manager.h" static base::LazyInstance<PropertyAccessor<TabContentsWrapper*> > g_tab_contents_wrapper_property_accessor(base::LINKER_INITIALIZED); @@ -57,6 +58,15 @@ PasswordManager* TabContentsWrapper::GetPasswordManager() { return password_manager_.get(); } +FindManager* TabContentsWrapper::GetFindManager() { + if (!find_manager_.get()) { + find_manager_.reset(new FindManager(this)); + // Register the manager to receive navigation notifications. + tab_contents()->AddObserver(find_manager_.get()); + } + return find_manager_.get(); +} + //////////////////////////////////////////////////////////////////////////////// // TabContentsWrapper, TabContentsObserver implementation: diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h index 430008f..8172b9a 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h @@ -12,6 +12,7 @@ #include "chrome/browser/tab_contents/tab_contents_observer.h" class Extension; +class FindManager; class NavigationController; class PasswordManager; class PasswordManagerDelegate; @@ -62,6 +63,9 @@ class TabContentsWrapper : public TabContentsObserver { // Returns the PasswordManager, creating it if necessary. PasswordManager* GetPasswordManager(); + // Returns the FindManager, creating it if necessary. + FindManager* GetFindManager(); + // TabContentsObserver overrides: virtual void NavigateToPendingEntry() OVERRIDE; @@ -71,6 +75,9 @@ class TabContentsWrapper : public TabContentsObserver { scoped_ptr<PasswordManagerDelegate> password_manager_delegate_; scoped_ptr<PasswordManager> password_manager_; + // FindManager, lazily created. + scoped_ptr<FindManager> find_manager_; + // The supporting objects need to outlive the TabContents dtor (as they may // be called upon during its execution). As a result, this must come last // in the list. diff --git a/chrome/browser/ui/tab_contents/test_tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/test_tab_contents_wrapper.cc new file mode 100644 index 0000000..10b8a6b --- /dev/null +++ b/chrome/browser/ui/tab_contents/test_tab_contents_wrapper.cc @@ -0,0 +1,40 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h" + +#include "chrome/browser/tab_contents/test_tab_contents.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" +#include "chrome/test/testing_profile.h" + +TabContentsWrapperTestHarness::TabContentsWrapperTestHarness() + : RenderViewHostTestHarness() { +} + +TabContentsWrapperTestHarness::~TabContentsWrapperTestHarness() { +} + +TestTabContents* TabContentsWrapperTestHarness::contents() { + return static_cast<TestTabContents*>(contents_wrapper_.get()->tab_contents()); +} + +TabContentsWrapper* TabContentsWrapperTestHarness::contents_wrapper() { + return contents_wrapper_.get(); +} + +void TabContentsWrapperTestHarness::SetUp() { + contents_wrapper_.reset(new TabContentsWrapper(CreateTestTabContents())); +} + +void TabContentsWrapperTestHarness::TearDown() { + contents_wrapper_.reset(); + + // Make sure that we flush any messages related to TabContents destruction + // before we destroy the profile. + MessageLoop::current()->RunAllPending(); + + // Release the profile on the UI thread. + message_loop_.DeleteSoon(FROM_HERE, profile_.release()); + message_loop_.RunAllPending(); +} diff --git a/chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h new file mode 100644 index 0000000..9c60c12 --- /dev/null +++ b/chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h @@ -0,0 +1,32 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_TAB_CONTENTS_TEST_TAB_CONTENTS_WRAPPER_H_ +#define CHROME_BROWSER_UI_TAB_CONTENTS_TEST_TAB_CONTENTS_WRAPPER_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "chrome/browser/renderer_host/test/test_render_view_host.h" + +class TabContentsWrapper; + +class TabContentsWrapperTestHarness : public RenderViewHostTestHarness { + public: + TabContentsWrapperTestHarness(); + virtual ~TabContentsWrapperTestHarness(); + + TestTabContents* contents(); + TabContentsWrapper* contents_wrapper(); + + protected: + // testing::Test + virtual void SetUp() OVERRIDE; + virtual void TearDown() OVERRIDE; + + scoped_ptr<TabContentsWrapper> contents_wrapper_; + + DISALLOW_COPY_AND_ASSIGN(TabContentsWrapperTestHarness); +}; + +#endif // CHROME_BROWSER_UI_TAB_CONTENTS_TEST_TAB_CONTENTS_WRAPPER_H_ diff --git a/chrome/browser/ui/views/find_bar_host.cc b/chrome/browser/ui/views/find_bar_host.cc index 4adb96f..a253f8f 100644 --- a/chrome/browser/ui/views/find_bar_host.cc +++ b/chrome/browser/ui/views/find_bar_host.cc @@ -10,6 +10,8 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/find_bar_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -62,7 +64,7 @@ bool FindBarHost::MaybeForwardKeyEventToWebpage( return false; } - TabContents* contents = find_bar_controller_->tab_contents(); + TabContentsWrapper* contents = find_bar_controller_->tab_contents(); if (!contents) return false; @@ -71,7 +73,8 @@ bool FindBarHost::MaybeForwardKeyEventToWebpage( // Make sure we don't have a text field element interfering with keyboard // input. Otherwise Up and Down arrow key strokes get eaten. "Nom Nom Nom". render_view_host->ClearFocusedNode(); - NativeWebKeyboardEvent event = GetKeyboardEvent(contents, key_event); + NativeWebKeyboardEvent event = GetKeyboardEvent(contents->tab_contents(), + key_event); render_view_host->ForwardKeyboardEvent(event); return true; } @@ -110,7 +113,8 @@ void FindBarHost::MoveWindowIfNecessary(const gfx::Rect& selection_rect, // don't check this, then SetWidgetPosition below will end up making the Find // Bar visible. if (!find_bar_controller_->tab_contents() || - !find_bar_controller_->tab_contents()->find_ui_active()) { + !find_bar_controller_-> + tab_contents()->GetFindManager()->find_ui_active()) { return; } @@ -151,7 +155,7 @@ bool FindBarHost::IsFindBarVisible() { void FindBarHost::RestoreSavedFocus() { if (focus_tracker() == NULL) { // TODO(brettw) Focus() should be on TabContentsView. - find_bar_controller_->tab_contents()->Focus(); + find_bar_controller_->tab_contents()->tab_contents()->Focus(); } else { focus_tracker()->FocusLastFocusedExternalView(); } diff --git a/chrome/browser/ui/views/find_bar_host_gtk.cc b/chrome/browser/ui/views/find_bar_host_gtk.cc index 4240579..bacb9d8 100644 --- a/chrome/browser/ui/views/find_bar_host_gtk.cc +++ b/chrome/browser/ui/views/find_bar_host_gtk.cc @@ -7,6 +7,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "views/widget/widget_gtk.h" diff --git a/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc b/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc index 8103085..816ead2 100644 --- a/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc +++ b/chrome/browser/ui/views/find_bar_host_interactive_uitest.cc @@ -100,7 +100,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestore) { browser()->Find(); EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); - ui_test_utils::FindInPage(browser()->GetSelectedTabContents(), + ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(), ASCIIToUTF16("a"), true, false, NULL); browser()->GetFindBarController()->EndFindSession( FindBarController::kKeepSelection); @@ -135,7 +135,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestoreOnTabSwitch) { browser()->GetFindBarController()->find_bar()->GetFindBarTesting(); // Search for 'a'. - ui_test_utils::FindInPage(browser()->GetSelectedTabContents(), + ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(), ASCIIToUTF16("a"), true, false, NULL); EXPECT_TRUE(ASCIIToUTF16("a") == find_bar->GetFindSelectedText()); @@ -149,7 +149,7 @@ IN_PROC_BROWSER_TEST_F(FindInPageTest, FocusRestoreOnTabSwitch) { VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); // Search for 'b'. - ui_test_utils::FindInPage(browser()->GetSelectedTabContents(), + ui_test_utils::FindInPage(browser()->GetSelectedTabContentsWrapper(), ASCIIToUTF16("b"), true, false, NULL); EXPECT_TRUE(ASCIIToUTF16("b") == find_bar->GetFindSelectedText()); diff --git a/chrome/browser/ui/views/find_bar_host_win.cc b/chrome/browser/ui/views/find_bar_host_win.cc index fb341c0..051f54c 100644 --- a/chrome/browser/ui/views/find_bar_host_win.cc +++ b/chrome/browser/ui/views/find_bar_host_win.cc @@ -8,6 +8,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/tab_contents_view.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "views/controls/scrollbar/native_scroll_bar.h" #include "views/widget/widget_win.h" @@ -21,7 +22,8 @@ void FindBarHost::GetWidgetPositionNative(gfx::Rect* avoid_overlapping_rect) { ::GetWindowRect( static_cast<views::WidgetWin*>(host())->GetParent(), &frame_rect); ::GetWindowRect( - find_bar_controller_->tab_contents()->view()->GetNativeView(), + find_bar_controller_-> + tab_contents()->tab_contents()->view()->GetNativeView(), &webcontents_rect); avoid_overlapping_rect->Offset(0, webcontents_rect.top - frame_rect.top); } diff --git a/chrome/browser/ui/views/find_bar_view.cc b/chrome/browser/ui/views/find_bar_view.cc index d28481e..818efda 100644 --- a/chrome/browser/ui/views/find_bar_view.cc +++ b/chrome/browser/ui/views/find_bar_view.cc @@ -14,6 +14,8 @@ #include "chrome/browser/themes/browser_theme_provider.h" #include "chrome/browser/ui/find_bar/find_bar_controller.h" #include "chrome/browser/ui/find_bar/find_bar_state.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/view_ids.h" #include "chrome/browser/ui/views/find_bar_host.h" #include "chrome/browser/ui/views/frame/browser_view.h" @@ -439,9 +441,9 @@ void FindBarView::ButtonPressed( case FIND_NEXT_TAG: if (!find_text_->text().empty()) { find_bar_host()->GetFindBarController()->tab_contents()-> - StartFinding(find_text_->text(), - sender->tag() == FIND_NEXT_TAG, - false); // Not case sensitive. + GetFindManager()->StartFinding(find_text_->text(), + sender->tag() == FIND_NEXT_TAG, + false); // Not case sensitive. } if (event.IsMouseEvent()) { // If mouse event, we move the focus back to the text-field, so that the @@ -480,16 +482,17 @@ void FindBarView::ContentsChanged(views::Textfield* sender, // can lead to crashes, as exposed by automation testing in issue 8048. if (!controller->tab_contents()) return; + FindManager* find_manager = controller->tab_contents()->GetFindManager(); // When the user changes something in the text box we check the contents and // 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.empty()) { // The last two params here are forward (true) and case sensitive (false). - controller->tab_contents()->StartFinding(new_contents, true, false); + find_manager->StartFinding(new_contents, true, false); } else { - controller->tab_contents()->StopFinding(FindBarController::kClearSelection); - UpdateForResult(controller->tab_contents()->find_result(), string16()); + find_manager->StopFinding(FindBarController::kClearSelection); + UpdateForResult(find_manager->find_result(), string16()); // Clearing the text box should clear the prepopulate state so that when // we close and reopen the Find box it doesn't show the search we just @@ -515,11 +518,12 @@ bool FindBarView::HandleKeyEvent(views::Textfield* sender, // Pressing Return/Enter starts the search (unless text box is empty). string16 find_string = find_text_->text(); if (!find_string.empty()) { + FindBarController* controller = find_bar_host()->GetFindBarController(); + FindManager* find_manager = controller->tab_contents()->GetFindManager(); // Search forwards for enter, backwards for shift-enter. - find_bar_host()->GetFindBarController()->tab_contents()->StartFinding( - find_string, - !key_event.IsShiftDown(), - false); // Not case sensitive. + find_manager->StartFinding(find_string, + !key_event.IsShiftDown(), + false); // Not case sensitive. } } diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7c33c93..d7f0979 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2861,6 +2861,8 @@ 'browser/ui/find_bar/find_bar_controller.h', 'browser/ui/find_bar/find_bar_state.cc', 'browser/ui/find_bar/find_bar_state.h', + 'browser/ui/find_bar/find_manager.h', + 'browser/ui/find_bar/find_manager.cc', 'browser/ui/find_bar/find_notification_details.h', 'browser/ui/gtk/about_chrome_dialog.cc', 'browser/ui/gtk/about_chrome_dialog.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index cdd303c..48924f0 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -86,6 +86,8 @@ 'browser/sync/profile_sync_service_mock.h', 'browser/ui/browser.h', 'browser/ui/cocoa/browser_test_helper.h', + 'browser/ui/tab_contents/test_tab_contents_wrapper.cc', + 'browser/ui/tab_contents/test_tab_contents_wrapper.h', 'common/net/test_url_fetcher_factory.cc', 'common/net/test_url_fetcher_factory.h', 'common/notification_observer_mock.cc', diff --git a/chrome/test/ui_test_utils.cc b/chrome/test/ui_test_utils.cc index 0dd2504..407458d 100644 --- a/chrome/test/ui_test_utils.cc +++ b/chrome/test/ui_test_utils.cc @@ -31,6 +31,9 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/tab_contents/thumbnail_generator.h" #include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/find_bar/find_manager.h" +#include "chrome/browser/ui/find_bar/find_notification_details.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/extensions/extension_action.h" #include "chrome/common/notification_type.h" @@ -223,13 +226,14 @@ class DownloadsCompleteObserver : public DownloadManager::Observer, class FindInPageNotificationObserver : public NotificationObserver { public: - explicit FindInPageNotificationObserver(TabContents* parent_tab) + explicit FindInPageNotificationObserver(TabContentsWrapper* parent_tab) : parent_tab_(parent_tab), active_match_ordinal_(-1), number_of_matches_(0) { - current_find_request_id_ = parent_tab->current_find_request_id(); + current_find_request_id_ = + parent_tab->GetFindManager()->current_find_request_id(); registrar_.Add(this, NotificationType::FIND_RESULT_AVAILABLE, - Source<TabContents>(parent_tab_)); + Source<TabContents>(parent_tab_->tab_contents())); ui_test_utils::RunMessageLoop(); } @@ -260,7 +264,7 @@ class FindInPageNotificationObserver : public NotificationObserver { private: NotificationRegistrar registrar_; - TabContents* parent_tab_; + TabContentsWrapper* parent_tab_; // We will at some point (before final update) be notified of the ordinal and // we need to preserve it so we can send it later. int active_match_ordinal_; @@ -624,9 +628,10 @@ void WaitForFocusInBrowser(Browser* browser) { Source<Browser>(browser)); } -int FindInPage(TabContents* tab_contents, const string16& search_string, +int FindInPage(TabContentsWrapper* tab_contents, const string16& search_string, bool forward, bool match_case, int* ordinal) { - tab_contents->StartFinding(search_string, forward, match_case); + tab_contents-> + GetFindManager()->StartFinding(search_string, forward, match_case); FindInPageNotificationObserver observer(tab_contents); if (ordinal) *ordinal = observer.active_match_ordinal(); diff --git a/chrome/test/ui_test_utils.h b/chrome/test/ui_test_utils.h index d6a7cd6..89dd676 100644 --- a/chrome/test/ui_test_utils.h +++ b/chrome/test/ui_test_utils.h @@ -44,6 +44,7 @@ class RenderWidgetHost; class ScopedTempDir; class SkBitmap; class TabContents; +class TabContentsWrapper; class Value; namespace gfx { @@ -209,7 +210,7 @@ void WaitForFocusInBrowser(Browser* browser); // Performs a find in the page of the specified tab. Returns the number of // matches found. |ordinal| is an optional parameter which is set to the index // of the current match. -int FindInPage(TabContents* tab, +int FindInPage(TabContentsWrapper* tab, const string16& search_string, bool forward, bool case_sensitive, |