Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / search / search_terms_tracker.cc
bloba0d9d2fb90aeef9a00e02ccb9cc45ee08c9bd269
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/search/search_terms_tracker.h"
7 #include "chrome/browser/profiles/profile.h"
8 #include "chrome/browser/search_engines/template_url.h"
9 #include "chrome/browser/search_engines/template_url_service.h"
10 #include "chrome/browser/search_engines/template_url_service_factory.h"
11 #include "content/public/browser/navigation_controller.h"
12 #include "content/public/browser/navigation_entry.h"
13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_source.h"
16 #include "content/public/browser/notification_types.h"
17 #include "content/public/browser/web_contents.h"
19 namespace chrome {
21 SearchTermsTracker::SearchTermsTracker() {
22 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
23 content::NotificationService::AllSources());
24 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_CHANGED,
25 content::NotificationService::AllSources());
26 registrar_.Add(this, content::NOTIFICATION_WEB_CONTENTS_DESTROYED,
27 content::NotificationService::AllSources());
30 SearchTermsTracker::~SearchTermsTracker() {
33 bool SearchTermsTracker::GetSearchTerms(
34 const content::WebContents* contents,
35 base::string16* search_terms,
36 int* navigation_index) const {
37 if (contents) {
38 TabState::const_iterator it = tabs_.find(contents);
39 if (it != tabs_.end() && !it->second.search_terms.empty()) {
40 if (search_terms)
41 *search_terms = it->second.search_terms;
42 if (navigation_index)
43 *navigation_index = it->second.srp_navigation_index;
44 return true;
47 return false;
50 void SearchTermsTracker::Observe(
51 int type,
52 const content::NotificationSource& source,
53 const content::NotificationDetails& details) {
54 switch (type) {
55 case content::NOTIFICATION_NAV_ENTRY_COMMITTED:
56 case content::NOTIFICATION_NAV_ENTRY_CHANGED: {
57 content::NavigationController* controller =
58 content::Source<content::NavigationController>(source).ptr();
59 TabData search;
60 if (FindMostRecentSearch(controller, &search))
61 tabs_[controller->GetWebContents()] = search;
62 else
63 RemoveTabData(controller->GetWebContents());
64 break;
67 case content::NOTIFICATION_WEB_CONTENTS_DESTROYED: {
68 RemoveTabData(content::Source<content::WebContents>(source).ptr());
69 break;
72 default:
73 NOTREACHED();
74 return;
78 bool SearchTermsTracker::FindMostRecentSearch(
79 const content::NavigationController* controller,
80 SearchTermsTracker::TabData* tab_data) {
81 Profile* profile =
82 Profile::FromBrowserContext(controller->GetBrowserContext());
83 DCHECK(profile);
84 if (!profile)
85 return false;
87 TemplateURL* template_url =
88 TemplateURLServiceFactory::GetForProfile(profile)->
89 GetDefaultSearchProvider();
91 for (int i = controller->GetCurrentEntryIndex(); i >= 0; --i) {
92 content::NavigationEntry* entry = controller->GetEntryAtIndex(i);
93 if (entry->GetPageType() == content::PAGE_TYPE_NORMAL) {
94 if (template_url->IsSearchURL(entry->GetURL())) {
95 // This entry is a search results page. Extract the terms only if this
96 // isn't the last (i.e. most recent/current) entry as we don't want to
97 // record the search terms when we're on an SRP.
98 if (i != controller->GetCurrentEntryIndex()) {
99 tab_data->srp_navigation_index = i;
100 template_url->ExtractSearchTermsFromURL(entry->GetURL(),
101 &tab_data->search_terms);
102 return true;
105 // We've found an SRP - stop searching (even if we did not record the
106 // search terms, as anything before this entry will be unrelated).
107 break;
111 // Do not consider any navigations that precede a non-web-triggerable
112 // navigation as they are not related to those terms.
113 if (!content::PageTransitionIsWebTriggerable(
114 entry->GetTransitionType())) {
115 break;
119 return false;
122 void SearchTermsTracker::RemoveTabData(
123 const content::WebContents* contents) {
124 TabState::iterator it = tabs_.find(contents);
125 if (it != tabs_.end()) {
126 tabs_.erase(it);
130 } // namespace chrome