15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_controller.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_state.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_bar_state_factory.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_tab_helper.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_details.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The minimum space between the FindInPage window and the search result.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMinFindWndDistanceFromSelection = 5;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindBarController::FindBarController(FindBar* find_bar)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : find_bar_(find_bar),
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_(NULL),
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_reported_matchcount_(0) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FindBarController::~FindBarController() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!web_contents_);
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarController::Show() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindTabHelper* find_tab_helper =
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FindTabHelper::FromWebContents(web_contents_);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Only show the animation if we're not already showing a find bar for the
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // selected WebContents.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!find_tab_helper->find_ui_active()) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MaybeSetPrepopulateText();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_tab_helper->set_find_ui_active(true);
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_bar_->Show(true);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  find_bar_->SetFocusAndSelection();
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarController::EndFindSession(SelectionAction selection_action,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       ResultAction result_action) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  find_bar_->Hide(true);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |web_contents_| can be NULL for a number of reasons, for example when the
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tab is closing. We must guard against that case. See issue 8030.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_) {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FindTabHelper* find_tab_helper =
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FindTabHelper::FromWebContents(web_contents_);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When we hide the window, we need to notify the renderer that we are done
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // for now, so that we can abort the scoping effort and clear all the
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // tickmarks and highlighting.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_tab_helper->StopFinding(selection_action);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (result_action == kClearResultsInFindBox)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      find_bar_->ClearResults(find_tab_helper->find_result());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // When we get dismissed we restore the focus to where it belongs.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_bar_->RestoreSavedFocus();
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarController::ChangeWebContents(WebContents* contents) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (web_contents_) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.RemoveAll();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_bar_->StopAnimation();
834e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    FindTabHelper* find_tab_helper =
854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        FindTabHelper::FromWebContents(web_contents_);
864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    if (find_tab_helper)
874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      find_tab_helper->set_selected_range(find_bar_->GetSelectedRange());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents_ = contents;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindTabHelper* find_tab_helper =
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_ ? FindTabHelper::FromWebContents(web_contents_)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    : NULL;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hide any visible find window from the previous tab if a NULL tab contents
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is passed in or if the find UI is not active in the new tab.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (find_bar_->IsFindBarVisible() &&
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (!find_tab_helper || !find_tab_helper->find_ui_active())) {
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_bar_->Hide(false);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_contents_)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(this,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 content::Source<WebContents>(web_contents_));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar_.Add(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      this,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NOTIFICATION_NAV_ENTRY_COMMITTED,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(&web_contents_->GetController()));
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MaybeSetPrepopulateText();
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (find_tab_helper && find_tab_helper->find_ui_active()) {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // A tab with a visible find bar just got selected and we need to show the
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // find bar but without animation since it was already animated into its
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // visible state. We also want to reset the window location so that
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we don't surprise the user by popping up to the left for no apparent
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // reason.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_bar_->Show(false);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateFindBarForCurrentResult();
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  find_bar_->UpdateFindBarForChangedWebContents();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FindBarHost, content::NotificationObserver implementation:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarController::Observe(int type,
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const content::NotificationSource& source,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const content::NotificationDetails& details) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindTabHelper* find_tab_helper =
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FindTabHelper::FromWebContents(web_contents_);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == chrome::NOTIFICATION_FIND_RESULT_AVAILABLE) {
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Don't update for notifications from WebContentses other than the one we
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // are actively tracking.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (content::Source<WebContents>(source).ptr() == web_contents_) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UpdateFindBarForCurrentResult();
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (find_tab_helper->find_result().final_update() &&
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          find_tab_helper->find_result().number_of_matches() == 0) {
143a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const base::string16& last_search =
144a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            find_tab_helper->previous_find_text();
145a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        const base::string16& current_search = find_tab_helper->find_text();
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (last_search.find(current_search) != 0)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          find_bar_->AudibleAlert();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationController* source_controller =
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::Source<NavigationController>(source).ptr();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (source_controller == &web_contents_->GetController()) {
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::LoadCommittedDetails* commit_details =
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::Details<content::LoadCommittedDetails>(details).ptr();
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::PageTransition transition_type =
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          commit_details->entry->GetTransitionType();
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // Hide the find bar on reload or navigation.
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      if (find_bar_->IsFindBarVisible() &&
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          (ui::PageTransitionStripQualifier(transition_type) ==
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci               ui::PAGE_TRANSITION_RELOAD ||
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci           commit_details->is_navigation_to_different_page()))
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        EndFindSession(kKeepSelectionOnPage, kClearResultsInFindBox);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect FindBarController::GetLocationForFindbarView(
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Rect view_location,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& dialog_bounds,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& avoid_overlapping_rect) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::i18n::IsRTL()) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int boundary = dialog_bounds.width() - view_location.width();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_location.set_x(std::min(view_location.x(), boundary));
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view_location.set_x(std::max(view_location.x(), dialog_bounds.x()));
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect new_pos = view_location;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the selection rectangle intersects the current position on screen then
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we try to move our dialog to the left (right for RTL) of the selection
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // rectangle.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!avoid_overlapping_rect.IsEmpty() &&
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      avoid_overlapping_rect.Intersects(new_pos)) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (base::i18n::IsRTL()) {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_pos.set_x(avoid_overlapping_rect.x() +
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    avoid_overlapping_rect.width() +
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    (2 * kMinFindWndDistanceFromSelection));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we moved it off-screen to the right, we won't move it at all.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (new_pos.x() + new_pos.width() > dialog_bounds.width())
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new_pos = view_location;  // Reset.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new_pos.set_x(avoid_overlapping_rect.x() - new_pos.width() -
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kMinFindWndDistanceFromSelection);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // If we moved it off-screen to the left, we won't move it at all.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (new_pos.x() < 0)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        new_pos = view_location;  // Reset.
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new_pos;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarController::UpdateFindBarForCurrentResult() {
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindTabHelper* find_tab_helper =
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FindTabHelper::FromWebContents(web_contents_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const FindNotificationDetails& find_result = find_tab_helper->find_result();
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Avoid bug 894389: When a new search starts (and finds something) it reports
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an interim match count result of 1 before the scoping effort starts. This
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is to provide feedback as early as possible that we will find something.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // As you add letters to the search term, this creates a flashing effect when
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we briefly show "1 of 1" matches because there is a slight delay until
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the scoping effort starts updating the match count. We avoid this flash by
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ignoring interim results of 1 if we already have a positive number.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (find_result.number_of_matches() > -1) {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (last_reported_matchcount_ > 0 &&
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        find_result.number_of_matches() == 1 &&
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !find_result.final_update())
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;  // Don't let interim result override match count.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    last_reported_matchcount_ = find_result.number_of_matches();
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  find_bar_->UpdateUIForFindResult(find_result, find_tab_helper->find_text());
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FindBarController::MaybeSetPrepopulateText() {
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Having a per-tab find_string is not compatible with a global find
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // pasteboard, so we always have the same find text in all find bars. This is
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // done through the find pasteboard mechanism, so don't set the text here.
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (find_bar_->HasGlobalFindPasteboard())
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find out what we should show in the find text box. Usually, this will be
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the last search in this tab, but if no search has been issued in this tab
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we use the last search string (from any tab).
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindTabHelper* find_tab_helper =
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FindTabHelper::FromWebContents(web_contents_);
243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 find_string = find_tab_helper->find_text();
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (find_string.empty())
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_string = find_tab_helper->previous_find_text();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (find_string.empty()) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile =
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Profile::FromBrowserContext(web_contents_->GetBrowserContext());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    find_string = FindBarStateFactory::GetLastPrepopulateText(profile);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Update the find bar with existing results and search text, regardless of
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // whether or not the find bar is visible, so that if it's subsequently
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shown it is showing the right state for this tab. We update the find text
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // _first_ since the FindBarView checks its emptiness to see if it should
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // clear the result count display when there's nothing in the box.
2574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  find_bar_->SetFindTextAndSelectedRange(find_string,
2584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                         find_tab_helper->selected_range());
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
260