1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian 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/extensions/extension_omnibox_api.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/json/json_writer.h" 821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/lazy_instance.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h" 10201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "base/utf_string_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h" 12731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "chrome/browser/extensions/extension_event_router.h" 1321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h" 1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h" 15201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/search_engines/template_url.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace events { 194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kOnInputStarted[] = "omnibox.onInputStarted"; 204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kOnInputChanged[] = "omnibox.onInputChanged"; 214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kOnInputEntered[] = "omnibox.onInputEntered"; 224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kOnInputCancelled[] = "omnibox.onInputCancelled"; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // namespace events 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kDescriptionStylesOrderError[] = 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Suggestion descriptionStyles must be in increasing non-overlapping order."; 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst char kDescriptionStylesLengthError[] = 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch "Suggestion descriptionStyles contains an offset longer than the" 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch " description text"; 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kSuggestionContent[] = "content"; 333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kSuggestionDescription[] = "description"; 343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kSuggestionDescriptionStyles[] = "descriptionStyles"; 353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kDescriptionStylesType[] = "type"; 363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst char kDescriptionStylesOffset[] = "offset"; 374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochconst char kDescriptionStylesLength[] = "length"; 38201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenstatic base::LazyInstance<PropertyAccessor<ExtensionOmniboxSuggestion> > 4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen g_extension_omnibox_suggestion_property_accessor(base::LINKER_INITIALIZED); 4121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochPropertyAccessor<ExtensionOmniboxSuggestion>& GetPropertyAccessor() { 4321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return g_extension_omnibox_suggestion_property_accessor.Get(); 44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Returns the suggestion object set by the extension via the 47201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// omnibox.setDefaultSuggestion call, or NULL if it was never set. 48201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochconst ExtensionOmniboxSuggestion* GetDefaultSuggestionForExtension( 49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Profile* profile, const std::string& extension_id) { 50201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const Extension* extension = 5121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen profile->GetExtensionService()->GetExtensionById(extension_id, false); 52201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!extension) 53201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return NULL; 54201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return GetPropertyAccessor().GetProperty( 5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen profile->GetExtensionService()->GetPropertyBag(extension)); 56201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 57201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; // namespace 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionOmniboxEventRouter::OnInputStarted( 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, const std::string& extension_id) { 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick profile->GetExtensionEventRouter()->DispatchEventToExtension( 643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extension_id, events::kOnInputStarted, "[]", profile, GURL()); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool ExtensionOmniboxEventRouter::OnInputChanged( 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, const std::string& extension_id, 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& input, int suggest_id) { 71731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!profile->GetExtensionEventRouter()->ExtensionHasEventListener( 72731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick extension_id, events::kOnInputChanged)) 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue args; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args.Set(0, Value::CreateStringValue(input)); 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args.Set(1, Value::CreateIntegerValue(suggest_id)); 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string json_args; 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::JSONWriter::Write(&args, false, &json_args); 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 81731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick profile->GetExtensionEventRouter()->DispatchEventToExtension( 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extension_id, events::kOnInputChanged, json_args, profile, GURL()); 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionOmniboxEventRouter::OnInputEntered( 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, const std::string& extension_id, 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& input) { 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue args; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch args.Set(0, Value::CreateStringValue(input)); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string json_args; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::JSONWriter::Write(&args, false, &json_args); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick profile->GetExtensionEventRouter()->DispatchEventToExtension( 963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extension_id, events::kOnInputEntered, json_args, profile, GURL()); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_OMNIBOX_INPUT_ENTERED, 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile), NotificationService::NoDetails()); 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionOmniboxEventRouter::OnInputCancelled( 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Profile* profile, const std::string& extension_id) { 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick profile->GetExtensionEventRouter()->DispatchEventToExtension( 1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick extension_id, events::kOnInputCancelled, "[]", profile, GURL()); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool OmniboxSendSuggestionsFunction::RunImpl() { 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionOmniboxSuggestions suggestions; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* suggestions_value; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &suggestions.request_id)); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &suggestions_value)); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suggestions.suggestions.resize(suggestions_value->GetSize()); 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (size_t i = 0; i < suggestions_value->GetSize(); ++i) { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ExtensionOmniboxSuggestion& suggestion = suggestions.suggestions[i]; 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* suggestion_value; 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE(suggestions_value->GetDictionary( 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch i, &suggestion_value)); 1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXTENSION_FUNCTION_VALIDATE(suggestion_value->GetString( 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSuggestionContent, &suggestion.content)); 1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick EXTENSION_FUNCTION_VALIDATE(suggestion_value->GetString( 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch kSuggestionDescription, &suggestion.description)); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (suggestion_value->HasKey(kSuggestionDescriptionStyles)) { 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ListValue* styles; 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch EXTENSION_FUNCTION_VALIDATE( 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suggestion_value->GetList(kSuggestionDescriptionStyles, &styles)); 1314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch EXTENSION_FUNCTION_VALIDATE(suggestion.ReadStylesFromValue(*styles)); 1324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } else { 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch suggestion.description_styles.clear(); 1344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch suggestion.description_styles.push_back( 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ACMatchClassification(0, ACMatchClassification::NONE)); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::EXTENSION_OMNIBOX_SUGGESTIONS_READY, 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<Profile>(profile_), 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Details<ExtensionOmniboxSuggestions>(&suggestions)); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return true; 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 147201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochbool OmniboxSetDefaultSuggestionFunction::RunImpl() { 148201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ExtensionOmniboxSuggestion suggestion; 149201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DictionaryValue* suggestion_value; 150201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &suggestion_value)); 151201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXTENSION_FUNCTION_VALIDATE(suggestion_value->GetString( 152201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch kSuggestionDescription, &suggestion.description)); 153201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 154201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (suggestion_value->HasKey(kSuggestionDescriptionStyles)) { 155201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ListValue* styles; 156201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXTENSION_FUNCTION_VALIDATE( 157201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch suggestion_value->GetList(kSuggestionDescriptionStyles, &styles)); 158201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch EXTENSION_FUNCTION_VALIDATE(suggestion.ReadStylesFromValue(*styles)); 159201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } else { 160201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch suggestion.description_styles.clear(); 161201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch suggestion.description_styles.push_back( 162201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ACMatchClassification(0, ACMatchClassification::NONE)); 163201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 164201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 165201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Store the suggestion in the extension's runtime data. 166201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch GetPropertyAccessor().SetProperty( 16721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen profile_->GetExtensionService()->GetPropertyBag(GetExtension()), 168201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch suggestion); 169201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 170201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationService::current()->Notify( 171201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationType::EXTENSION_OMNIBOX_DEFAULT_SUGGESTION_CHANGED, 172201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Source<Profile>(profile_), 173201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch NotificationService::NoDetails()); 174201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 175201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return true; 176201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 177201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 178731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionOmniboxSuggestion::ExtensionOmniboxSuggestion() {} 179731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 180731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionOmniboxSuggestion::~ExtensionOmniboxSuggestion() {} 181731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 1824a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochbool ExtensionOmniboxSuggestion::ReadStylesFromValue( 1834a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch const ListValue& styles_value) { 1844a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch description_styles.clear(); 1854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1864a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch // Step 1: Build a vector of styles, 1 per character of description text. 1874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::vector<int> styles; 1884a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch styles.resize(description.length()); // sets all styles to 0 1894a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 1904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 0; i < styles_value.GetSize(); ++i) { 1914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch DictionaryValue* style; 1924a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch std::string type; 1934a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int offset; 1944a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int length; 1954a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!styles_value.GetDictionary(i, &style)) 1964a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 1974a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!style->GetString(kDescriptionStylesType, &type)) 1984a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 1994a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!style->GetInteger(kDescriptionStylesOffset, &offset)) 2004a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 2014a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (!style->GetInteger(kDescriptionStylesLength, &length) || length < 0) 2024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch length = description.length(); 2034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (offset < 0) 2054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch offset = std::max(0, static_cast<int>(description.length()) + offset); 2064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2074a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch int type_class = 2084a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch (type == "url") ? ACMatchClassification::URL : 2094a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch (type == "match") ? ACMatchClassification::MATCH : 2104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch (type == "dim") ? ACMatchClassification::DIM : -1; 2114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (type_class == -1) 2124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return false; 2134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (int j = offset; 2154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch j < offset + length && j < static_cast<int>(styles.size()); ++j) 2164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch styles[j] |= type_class; 2174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 219201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Step 2: Convert the vector into continuous runs of common styles. 2204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch for (size_t i = 0; i < styles.size(); ++i) { 2214a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch if (i == 0 || styles[i] != styles[i-1]) 2224a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch description_styles.push_back(ACMatchClassification(i, styles[i])); 2234a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch } 2244a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 2254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch return true; 2264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch} 2274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch 228513209b27ff55e2841eac0e4120199c23acce758Ben MurdochExtensionOmniboxSuggestions::ExtensionOmniboxSuggestions() : request_id(0) {} 229731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick 230731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickExtensionOmniboxSuggestions::~ExtensionOmniboxSuggestions() {} 231201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 232201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid ApplyDefaultSuggestionForExtensionKeyword( 233201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch Profile* profile, 234201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const TemplateURL* keyword, 235201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const string16& remaining_input, 236201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch AutocompleteMatch* match) { 237201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch DCHECK(keyword->IsExtensionKeyword()); 238201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const ExtensionOmniboxSuggestion* suggestion = 239201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch GetDefaultSuggestionForExtension(profile, keyword->GetExtensionId()); 240201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!suggestion) 241201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; // fall back to the universal default 242201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 243201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const string16 kPlaceholderText(ASCIIToUTF16("%s")); 244201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch const string16 kReplacementText(ASCIIToUTF16("<input>")); 245201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 246201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 description = suggestion->description; 247201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch ACMatchClassifications& description_styles = match->contents_class; 248201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch description_styles = suggestion->description_styles; 249201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 250201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // Replace "%s" with the user's input and adjust the style offsets to the 251201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch // new length of the description. 252201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch size_t placeholder(suggestion->description.find(kPlaceholderText, 0)); 253201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (placeholder != string16::npos) { 254201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch string16 replacement = 255201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch remaining_input.empty() ? kReplacementText : remaining_input; 256201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch description.replace(placeholder, kPlaceholderText.length(), replacement); 257201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 258201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch for (size_t i = 0; i < description_styles.size(); ++i) { 259201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (description_styles[i].offset > placeholder) 260201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch description_styles[i].offset += replacement.length() - 2; 261201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 262201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 263201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen match->contents.assign(description); 265201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 266