Index: chrome/browser/extensions/extension_omnibox_api.cc |
diff --git a/chrome/browser/extensions/extension_omnibox_api.cc b/chrome/browser/extensions/extension_omnibox_api.cc |
index 705771f8e02b90141dd8c071adeaf6a57587ac31..4e161ae11a8a96272643c3d274114d641c63a6d6 100644 |
--- a/chrome/browser/extensions/extension_omnibox_api.cc |
+++ b/chrome/browser/extensions/extension_omnibox_api.cc |
@@ -126,11 +126,11 @@ ExtensionOmniboxSuggestion::~ExtensionOmniboxSuggestion() {} |
bool ExtensionOmniboxSuggestion::ReadStylesFromValue( |
const ListValue& styles_value) { |
- // Start with a NONE style covering the entire range. As we iterate over the |
- // styles, bisect or overwrite the running style list with each new style. |
description_styles.clear(); |
- description_styles.push_back( |
- ACMatchClassification(0, ACMatchClassification::NONE)); |
+ |
+ // Step 1: Build a vector of styles, 1 per character of description text. |
+ std::vector<int> styles; |
+ styles.resize(description.length()); // sets all styles to 0 |
for (size_t i = 0; i < styles_value.GetSize(); ++i) { |
DictionaryValue* style; |
@@ -143,8 +143,11 @@ bool ExtensionOmniboxSuggestion::ReadStylesFromValue( |
return false; |
if (!style->GetInteger(kDescriptionStylesOffset, &offset)) |
return false; |
- if (!style->GetInteger(kDescriptionStylesLength, &length)) |
- return false; |
+ if (!style->GetInteger(kDescriptionStylesLength, &length) || length < 0) |
+ length = description.length(); |
+ |
+ if (offset < 0) |
+ offset = std::max(0, static_cast<int>(description.length()) + offset); |
int type_class = |
(type == "url") ? ACMatchClassification::URL : |
@@ -153,52 +156,18 @@ bool ExtensionOmniboxSuggestion::ReadStylesFromValue( |
if (type_class == -1) |
return false; |
- InsertNewStyle(type_class, offset, length); |
- } |
- |
- return true; |
-} |
- |
-void ExtensionOmniboxSuggestion::InsertNewStyle(int type, |
- size_t offset, |
- size_t length) { |
- // Find the first and last existing styles that this new style overlaps. Those |
- // will have to be removed (if they completely overlap), or bisected. |
- size_t start = 0, end = 0; |
- while (end < description_styles.size()) { |
- if (start < description_styles.size() && |
- description_styles[start].offset < offset) |
- ++start; |
- if (description_styles[end].offset <= offset + length) { |
- ++end; |
- } else { |
- break; |
- } |
+ for (int j = offset; |
+ j < offset + length && j < static_cast<int>(styles.size()); ++j) |
+ styles[j] |= type_class; |
} |
- DCHECK_GT(end, 0u); |
- DCHECK(start == description_styles.size() || |
- description_styles[start].offset >= offset); |
- DCHECK(end == description_styles.size() || |
- description_styles[end].offset > offset + length); |
- |
- // The last style in the overlapping range will come after our new style. |
- int last_style = description_styles[end - 1].style; |
- |
- // Remove all overlapping styles. |
- if (start < end) { |
- description_styles.erase(description_styles.begin() + start, |
- description_styles.begin() + end); |
+ // Step 2: Convert the vector into continous runs of common styles. |
+ for (size_t i = 0; i < styles.size(); ++i) { |
+ if (i == 0 || styles[i] != styles[i-1]) |
+ description_styles.push_back(ACMatchClassification(i, styles[i])); |
} |
- // Insert our new style. |
- description_styles.insert(description_styles.begin() + start, |
- ACMatchClassification(offset, type)); |
- if (offset + length < description.length()) { |
- description_styles.insert(description_styles.begin() + start + 1, |
- ACMatchClassification(offset + length, |
- last_style)); |
- } |
+ return true; |
} |
ExtensionOmniboxSuggestions::ExtensionOmniboxSuggestions() : request_id(0) {} |