172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/icu_string_conversions.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/utf_string_conversions.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/metrics/user_metrics.h" 13513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch#include "chrome/browser/search_engines/search_engine_type.h" 143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/search_engines/search_terms_data.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/search_engines/template_url_model.h" 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h" 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/installer/util/google_update_settings.h" 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/escape.h" 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/favicon_size.h" 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// TODO(pastarmovj): Remove google_update_settings and user_metrics when the 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// CollectRLZMetrics function is not needed anymore. 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The TemplateURLRef has any number of terms that need to be replaced. Each of 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// the terms is enclosed in braces. If the character preceeding the final 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// brace is a ?, it indicates the term is optional and can be replaced with 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// an empty string. 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kStartParameter = '{'; 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kEndParameter = '}'; 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kOptional = '?'; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Known parameters found in the URL. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kSearchTermsParameter[] = "searchTerms"; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kSearchTermsParameterFull[] = "{searchTerms}"; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kCountParameter[] = "count"; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kStartIndexParameter[] = "startIndex"; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kStartPageParameter[] = "startPage"; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kLanguageParameter[] = "language"; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kInputEncodingParameter[] = "inputEncoding"; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kOutputEncodingParameter[] = "outputEncoding"; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleAcceptedSuggestionParameter[] = 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "google:acceptedSuggestion"; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Host/Domain Google searches are relative to. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleBaseURLParameter[] = "google:baseURL"; 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleBaseURLParameterFull[] = "{google:baseURL}"; 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Like google:baseURL, but for the Search Suggest capability. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleBaseSuggestURLParameter[] = 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "google:baseSuggestURL"; 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleBaseSuggestURLParameterFull[] = 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "{google:baseSuggestURL}"; 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleOriginalQueryForSuggestionParameter[] = 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "google:originalQueryForSuggestion"; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleRLZParameter[] = "google:RLZ"; 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Same as kSearchTermsParameter, with no escaping. 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleUnescapedSearchTermsParameter[] = 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "google:unescapedSearchTerms"; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kGoogleUnescapedSearchTermsParameterFull[] = 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "{google:unescapedSearchTerms}"; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Display value for kSearchTermsParameter. 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kDisplaySearchTerms[] = "%s"; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Display value for kGoogleUnescapedSearchTermsParameter. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kDisplayUnescapedSearchTerms[] = "%S"; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used if the count parameter is not optional. Indicates we want 10 search 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// results. 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kDefaultCount[] = "10"; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Used if the parameter kOutputEncodingParameter is required. 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const char kOutputEncodingType[] = "UTF-8"; 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTemplateURLRef::TemplateURLRef() { 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Set(std::string(), 0, 0); 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTemplateURLRef::TemplateURLRef(const std::string& url, 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int index_offset, 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int page_offset) 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : url_(url), 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick index_offset_(index_offset), 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick page_offset_(page_offset), 843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick parsed_(false), 853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick valid_(false), 863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick supports_replacements_(false) { 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLRef::Set(const std::string& url, 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index_offset, 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int page_offset) { 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_ = url; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch index_offset_ = index_offset; 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch page_offset_ = page_offset; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InvalidateCachedValues(); 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 983345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTemplateURLRef::~TemplateURLRef() { 993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLRef::ParseParameter(size_t start, 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t end, 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* url, 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Replacements* replacements) const { 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(start != std::string::npos && 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch end != std::string::npos && end > start); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t length = end - start - 1; 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool optional = false; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((*url)[end - 1] == kOptional) { 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch optional = true; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch length--; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string parameter(url->substr(start + 1, length)); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string full_parameter(url->substr(start, end - start + 1)); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Remove the parameter from the string. 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url->erase(start, end - start + 1); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (parameter == kSearchTermsParameter) { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(SEARCH_TERMS, start)); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kCountParameter) { 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!optional) 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url->insert(start, kDefaultCount); 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kStartIndexParameter) { 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!optional) { 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url->insert(start, base::IntToString(index_offset_)); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kStartPageParameter) { 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!optional) { 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url->insert(start, base::IntToString(page_offset_)); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kLanguageParameter) { 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(LANGUAGE, start)); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kInputEncodingParameter) { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(ENCODING, start)); 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kOutputEncodingParameter) { 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!optional) 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url->insert(start, kOutputEncodingType); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kGoogleAcceptedSuggestionParameter) { 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(GOOGLE_ACCEPTED_SUGGESTION, start)); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kGoogleBaseURLParameter) { 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(GOOGLE_BASE_URL, start)); 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kGoogleBaseSuggestURLParameter) { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(GOOGLE_BASE_SUGGEST_URL, start)); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kGoogleOriginalQueryForSuggestionParameter) { 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION, 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch start)); 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kGoogleRLZParameter) { 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(GOOGLE_RLZ, start)); 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (parameter == kGoogleUnescapedSearchTermsParameter) { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements->push_back(Replacement(GOOGLE_UNESCAPED_SEARCH_TERMS, start)); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It can be some garbage but can also be a javascript block. Put it back. 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url->insert(start, full_parameter); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string TemplateURLRef::ParseURL(const std::string& url, 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Replacements* replacements, 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool* valid) const { 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *valid = false; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string parsed_url = url; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t last = 0; last != std::string::npos; ) { 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last = parsed_url.find(kStartParameter, last); 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (last != std::string::npos) { 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t template_end = parsed_url.find(kEndParameter, last); 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (template_end != std::string::npos) { 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Since we allow Javascript in the URL, {} pairs could be nested. Match 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // only leaf pairs with supported parameters. 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t next_template_start = parsed_url.find(kStartParameter, last + 1); 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (next_template_start == std::string::npos || 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch next_template_start > template_end) { 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If successful, ParseParameter erases from the string as such no 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // need to update |last|. If failed, move |last| to the end of pair. 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!ParseParameter(last, template_end, &parsed_url, replacements)) { 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // |template_end| + 1 may be beyond the end of the string. 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last = template_end; 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch last = next_template_start; 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Open brace without a closing brace, return. 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(); 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch *valid = true; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return parsed_url; 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLRef::ParseIfNecessary() const { 1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ParseIfNecessaryUsingTermsData(search_terms_data); 1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLRef::ParseIfNecessaryUsingTermsData( 1983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) const { 199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!parsed_) { 200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parsed_ = true; 201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch parsed_url_ = ParseURL(url_, &replacements_, &valid_); 202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch supports_replacements_ = false; 203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (valid_) { 204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool has_only_one_search_term = false; 205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (Replacements::const_iterator i = replacements_.begin(); 206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != replacements_.end(); ++i) { 207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((i->type == SEARCH_TERMS) || 208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (i->type == GOOGLE_UNESCAPED_SEARCH_TERMS)) { 209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_only_one_search_term) { 210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_only_one_search_term = false; 211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch has_only_one_search_term = true; 214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch supports_replacements_ = true; 215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Only parse the host/key if there is one search term. Technically there 218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // could be more than one term, but it's uncommon; so we punt. 219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (has_only_one_search_term) 2203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ParseHostAndSearchTermKey(search_terms_data); 221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLRef::ParseHostAndSearchTermKey( 2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) const { 227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url_string = url_; 228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReplaceSubstringsAfterOffset(&url_string, 0, 229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kGoogleBaseURLParameterFull, 2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick search_terms_data.GoogleBaseURLValue()); 231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReplaceSubstringsAfterOffset(&url_string, 0, 232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kGoogleBaseSuggestURLParameterFull, 2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick search_terms_data.GoogleBaseSuggestURLValue()); 234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL url(url_string); 236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!url.is_valid()) 237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string query_string = url.query(); 240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (query_string.empty()) 241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_parse::Component query, key, value; 244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch query.len = static_cast<int>(query_string.size()); 245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch while (url_parse::ExtractQueryKeyValue(query_string.c_str(), &query, &key, 246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &value)) { 247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (key.is_nonempty() && value.is_nonempty()) { 248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string value_string = query_string.substr(value.begin, value.len); 249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (value_string.find(kSearchTermsParameterFull, 0) != 250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string::npos || 251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch value_string.find(kGoogleUnescapedSearchTermsParameterFull, 0) != 252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string::npos) { 253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch search_term_key_ = query_string.substr(key.begin, key.len); 254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_ = url.host(); 255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch path_ = url.path(); 256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 2633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURLRef::SetGoogleBaseURL(std::string* google_base_url) { 2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData::SetGoogleBaseURL(google_base_url); 2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string TemplateURLRef::ReplaceSearchTerms( 268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const TemplateURL& host, 26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& terms, 270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int accepted_suggestion, 27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& original_query_for_suggestion) const { 2723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 2733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return ReplaceSearchTermsUsingTermsData(host, 2743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick terms, 2753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick accepted_suggestion, 2763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick original_query_for_suggestion, 2773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick search_terms_data); 2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 2793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickstd::string TemplateURLRef::ReplaceSearchTermsUsingTermsData( 2813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL& host, 28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& terms, 2833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick int accepted_suggestion, 28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& original_query_for_suggestion, 2853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) const { 2863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ParseIfNecessaryUsingTermsData(search_terms_data); 287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!valid_) 288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return std::string(); 289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (replacements_.empty()) 291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return parsed_url_; 292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Determine if the search terms are in the query or before. We're escaping 294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // space as '+' in the former case and as '%20' in the latter case. 295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool is_in_query = true; 296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (Replacements::iterator i = replacements_.begin(); 297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != replacements_.end(); ++i) { 298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (i->type == SEARCH_TERMS) { 29972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16::size_type query_start = parsed_url_.find('?'); 30072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen is_in_query = query_start != string16::npos && 30172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen (static_cast<string16::size_type>(i->index) > query_start); 302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 encoded_terms; 307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 encoded_original_query; 308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string input_encoding; 309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // If the search terms are in query - escape them respecting the encoding. 310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (is_in_query) { 311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Encode the search terms so that we know the encoding. 312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<std::string>& encodings = host.input_encodings(); 313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < encodings.size(); ++i) { 31472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (EscapeQueryParamValue(terms, 315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encodings[i].c_str(), true, 316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &encoded_terms)) { 317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!original_query_for_suggestion.empty()) { 31872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EscapeQueryParamValue(original_query_for_suggestion, 319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encodings[i].c_str(), 320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch true, 321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &encoded_original_query); 322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_encoding = encodings[i]; 324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (input_encoding.empty()) { 32872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen encoded_terms = EscapeQueryParamValueUTF8(terms, true); 329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!original_query_for_suggestion.empty()) { 330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch encoded_original_query = 33172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen EscapeQueryParamValueUTF8(original_query_for_suggestion, true); 332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_encoding = "UTF-8"; 334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 33672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen encoded_terms = UTF8ToUTF16(EscapePath(UTF16ToUTF8(terms))); 337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch input_encoding = "UTF-8"; 338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string url = parsed_url_; 341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // replacements_ is ordered in ascending order, as such we need to iterate 343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // from the back. 344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (Replacements::reverse_iterator i = replacements_.rbegin(); 345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != replacements_.rend(); ++i) { 346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (i->type) { 347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case ENCODING: 348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.insert(i->index, input_encoding); 349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GOOGLE_ACCEPTED_SUGGESTION: 352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (accepted_suggestion == NO_SUGGESTION_CHOSEN) 353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.insert(i->index, "aq=f&"); 354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (accepted_suggestion != NO_SUGGESTIONS_AVAILABLE) 355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.insert(i->index, StringPrintf("aq=%d&", accepted_suggestion)); 356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GOOGLE_BASE_URL: 3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url.insert(i->index, search_terms_data.GoogleBaseURLValue()); 360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GOOGLE_BASE_SUGGEST_URL: 3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url.insert(i->index, search_terms_data.GoogleBaseSuggestURLValue()); 364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: 367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (accepted_suggestion >= 0) 368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.insert(i->index, "oq=" + UTF16ToUTF8(encoded_original_query) + 369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "&"); 370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GOOGLE_RLZ: { 373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // On platforms that don't have RLZ, we still want this branch 374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // to happen so that we replace the RLZ template with the 375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // empty string. (If we don't handle this case, we hit a 376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // NOTREACHED below.) 3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) 37872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 rlz_string = search_terms_data.GetRlzParameterValue(); 379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!rlz_string.empty()) { 380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rlz_string = L"rlz=" + rlz_string + L"&"; 38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen url.insert(i->index, UTF16ToUTF8(rlz_string)); 382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case GOOGLE_UNESCAPED_SEARCH_TERMS: { 388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string unescaped_terms; 38972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::UTF16ToCodepage(terms, input_encoding.c_str(), 39072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::OnStringConversionError::SKIP, 39172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &unescaped_terms); 392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.insert(i->index, std::string(unescaped_terms.begin(), 393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch unescaped_terms.end())); 394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case LANGUAGE: 3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick url.insert(i->index, search_terms_data.GetApplicationLocale()); 399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch case SEARCH_TERMS: 402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url.insert(i->index, UTF16ToUTF8(encoded_terms)); 403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NOTREACHED(); 407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return url; 412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLRef::SupportsReplacement() const { 4153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 4163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return SupportsReplacementUsingTermsData(search_terms_data); 4173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TemplateURLRef::SupportsReplacementUsingTermsData( 4203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) const { 4213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ParseIfNecessaryUsingTermsData(search_terms_data); 422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return valid_ && supports_replacements_; 423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLRef::IsValid() const { 4263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return IsValidUsingTermsData(search_terms_data); 4283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 4293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TemplateURLRef::IsValidUsingTermsData( 4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) const { 4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ParseIfNecessaryUsingTermsData(search_terms_data); 433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return valid_; 434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURLRef::DisplayURL() const { 437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParseIfNecessary(); 438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!valid_ || replacements_.empty()) 43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return UTF8ToUTF16(url_); 440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch string16 result = UTF8ToUTF16(url_); 442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReplaceSubstringsAfterOffset(&result, 0, 443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kSearchTermsParameterFull), 444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kDisplaySearchTerms)); 445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReplaceSubstringsAfterOffset( 447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &result, 0, 448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kGoogleUnescapedSearchTermsParameterFull), 449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kDisplayUnescapedSearchTerms)); 450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 45172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return result; 452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string TemplateURLRef::DisplayURLToURLRef( 45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const string16& display_url) { 45772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 result = display_url; 458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReplaceSubstringsAfterOffset(&result, 0, ASCIIToUTF16(kDisplaySearchTerms), 459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kSearchTermsParameterFull)); 460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ReplaceSubstringsAfterOffset( 461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch &result, 0, 462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kDisplayUnescapedSearchTerms), 463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ASCIIToUTF16(kGoogleUnescapedSearchTermsParameterFull)); 464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return UTF16ToUTF8(result); 465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst std::string& TemplateURLRef::GetHost() const { 468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParseIfNecessary(); 469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return host_; 470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst std::string& TemplateURLRef::GetPath() const { 473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParseIfNecessary(); 474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return path_; 475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst std::string& TemplateURLRef::GetSearchTermKey() const { 478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParseIfNecessary(); 479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return search_term_key_; 480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 48272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURLRef::SearchTermToString16(const TemplateURL& host, 483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& term) const { 484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::vector<std::string>& encodings = host.input_encodings(); 48572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 result; 486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string unescaped = 488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnescapeURLComponent(term, UnescapeRule::REPLACE_PLUS_WITH_SPACE | 489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UnescapeRule::URL_SPECIAL_CHARS); 490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < encodings.size(); ++i) { 49172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (base::CodepageToUTF16(unescaped, encodings[i].c_str(), 49272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::OnStringConversionError::FAIL, &result)) 493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Always fall back on UTF-8 if it works. 49772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (base::CodepageToUTF16(unescaped, base::kCodepageUTF8, 49872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::OnStringConversionError::FAIL, &result)) 499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // When nothing worked, just use the escaped text. We have no idea what the 502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // encoding is. We need to substitute spaces for pluses ourselves since we're 503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // not sending it through an unescaper. 50472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen result = UTF8ToUTF16(term); 505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::replace(result.begin(), result.end(), '+', ' '); 506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return result; 507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURLRef::HasGoogleBaseURLs() const { 510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ParseIfNecessary(); 511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < replacements_.size(); ++i) { 512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if ((replacements_[i].type == GOOGLE_BASE_URL) || 513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch (replacements_[i].type == GOOGLE_BASE_SUGGEST_URL)) 514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 519731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// static 520731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickbool TemplateURLRef::SameUrlRefs(const TemplateURLRef* ref1, 521731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const TemplateURLRef* ref2) { 522731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return ref1 == ref2 || (ref1 && ref2 && ref1->url() == ref2->url()); 523731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 524731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TemplateURLRef::CollectRLZMetrics() const { 52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(OS_WIN) && defined(GOOGLE_CHROME_BUILD) 52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ParseIfNecessary(); 52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen for (size_t i = 0; i < replacements_.size(); ++i) { 52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We are interesed in searches that were supposed to send the RLZ token. 53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (replacements_[i].type == GOOGLE_RLZ) { 53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 brand; 53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We only have RLZ tocken on a branded browser version. 53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (GoogleUpdateSettings::GetBrand(&brand) && !brand.empty() && 53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen !GoogleUpdateSettings::IsOrganic(brand)) { 53572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Now we know we should have had RLZ token check if there was one. 53672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (url().find("rlz=") != std::string::npos) 53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UserMetrics::RecordAction(UserMetricsAction("SearchWithRLZ")); 53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen else 53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen UserMetrics::RecordAction(UserMetricsAction("SearchWithoutRLZ")); 54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 54172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return; 54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 54472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 54572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 54672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURLRef::InvalidateCachedValues() const { 548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch supports_replacements_ = valid_ = parsed_ = false; 549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch host_.clear(); 550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch path_.clear(); 551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch search_term_key_.clear(); 552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch replacements_.clear(); 553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// TemplateURL ---------------------------------------------------------------- 556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 558c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochGURL TemplateURL::GenerateFaviconURL(const GURL& url) { 559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(url.is_valid()); 560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch GURL::Replacements rep; 561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char favicon_path[] = "/favicon.ico"; 563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int favicon_path_len = arraysize(favicon_path) - 1; 564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.SetPath(favicon_path, url_parse::Component(0, favicon_path_len)); 566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearUsername(); 567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearPassword(); 568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearQuery(); 569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch rep.ClearRef(); 570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return url.ReplaceComponents(rep); 571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURL::SupportsReplacement(const TemplateURL* turl) { 5753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick UIThreadSearchTermsData search_terms_data; 5763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return SupportsReplacementUsingTermsData(turl, search_terms_data); 5773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// static 5803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool TemplateURL::SupportsReplacementUsingTermsData( 5813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const TemplateURL* turl, 5823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const SearchTermsData& search_terms_data) { 5833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return turl && turl->url() && 5843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick turl->url()->SupportsReplacementUsingTermsData(search_terms_data); 5853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 5863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 5873345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTemplateURL::TemplateURL() 5883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick : autogenerate_keyword_(false), 5893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick keyword_generated_(false), 5903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick show_in_default_list_(false), 5913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick safe_for_autoreplace_(false), 5923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick id_(0), 5933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick date_created_(base::Time::Now()), 5943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick created_by_policy_(false), 5953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick usage_count_(0), 596513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch search_engine_type_(SEARCH_ENGINE_OTHER), 597513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch logo_id_(kNoSearchEngineLogo), 5983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick prepopulate_id_(0) { 5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6013345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickTemplateURL::~TemplateURL() { 602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURL::AdjustedShortNameForLocaleDirection() const { 60572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen string16 bidi_safe_short_name = short_name_; 606201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch base::i18n::AdjustStringForLocaleDirection(&bidi_safe_short_name); 607201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return bidi_safe_short_name; 608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURL::SetSuggestionsURL(const std::string& suggestions_url, 611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index_offset, 612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int page_offset) { 613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suggestions_url_.Set(suggestions_url, index_offset, page_offset); 614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURL::SetURL(const std::string& url, 617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int index_offset, 618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int page_offset) { 619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_.Set(url, index_offset, page_offset); 620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 622731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid TemplateURL::SetInstantURL(const std::string& url, 623731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int index_offset, 624731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick int page_offset) { 625731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick instant_url_.Set(url, index_offset, page_offset); 626731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick} 627731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 62872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TemplateURL::set_keyword(const string16& keyword) { 629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Case sensitive keyword matching is confusing. As such, we force all 630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // keywords to be lower case. 63172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen keyword_ = l10n_util::ToLower(keyword); 632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch autogenerate_keyword_ = false; 633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstring16 TemplateURL::keyword() const { 6363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EnsureKeyword(); 6373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return keyword_; 6383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 6393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TemplateURL::EnsureKeyword() const { 641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autogenerate_keyword_ && !keyword_generated_) { 642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Generate a keyword and cache it. 643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_ = TemplateURLModel::GenerateKeyword( 644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch TemplateURLModel::GenerateSearchURL(this).GetWithEmptyPath(), true); 645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_generated_ = true; 646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURL::ShowInDefaultList() const { 650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return show_in_default_list() && url() && url()->SupportsReplacement(); 651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 653ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TemplateURL::SetFaviconURL(const GURL& url) { 654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<ImageRef>::iterator i = image_refs_.begin(); 655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != image_refs_.end(); ++i) { 65672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (i->type == "image/x-icon" && 657ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen i->width == kFaviconSize && i->height == kFaviconSize) { 658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!url.is_valid()) 659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch image_refs_.erase(i); 660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i->url = url; 662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Don't have one yet, add it. 666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (url.is_valid()) { 667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch add_image_ref( 668ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TemplateURL::ImageRef("image/x-icon", kFaviconSize, 669ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kFaviconSize, url)); 670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 673ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenGURL TemplateURL::GetFaviconURL() const { 674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (std::vector<ImageRef>::const_iterator i = image_refs_.begin(); 675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i != image_refs_.end(); ++i) { 67672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if ((i->type == "image/x-icon" || i->type == "image/vnd.microsoft.icon") 677ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen && i->width == kFaviconSize && i->height == kFaviconSize) { 678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return i->url; 679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(); 682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TemplateURL::InvalidateCachedValues() const { 685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch url_.InvalidateCachedValues(); 686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suggestions_url_.InvalidateCachedValues(); 687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (autogenerate_keyword_) { 688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_.clear(); 689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch keyword_generated_ = false; 690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string TemplateURL::GetExtensionId() const { 694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(IsExtensionKeyword()); 695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(url_.url()).host(); 696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool TemplateURL::IsExtensionKeyword() const { 699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return GURL(url_.url()).SchemeIs(chrome::kExtensionScheme); 700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 701