Enhance chrome://omnibox Presentation

Added ability of providers to append arbitrary information to be presented in the omnibox metrics window.
Adjust formatting somewhat.

BUG=None
TEST=Observe
Review URL: https://chromiumcodereview.appspot.com/10692075

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@148905 0039d316-1c4b-4281-b951-d872f2087c98
parent 7913d649
......@@ -4,9 +4,14 @@
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "base/i18n/time_formatting.h"
#include "base/logging.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "base/string16.h"
#include "base/stringprintf.h"
#include "base/time.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/autocomplete/autocomplete_provider.h"
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_service.h"
......@@ -75,7 +80,8 @@ AutocompleteMatch::AutocompleteMatch(const AutocompleteMatch& match)
from_previous(match.from_previous),
search_terms_args(match.search_terms_args.get() ?
new TemplateURLRef::SearchTermsArgs(*match.search_terms_args) :
NULL) {
NULL),
additional_info(match.additional_info) {
}
AutocompleteMatch::~AutocompleteMatch() {
......@@ -108,6 +114,7 @@ AutocompleteMatch& AutocompleteMatch::operator=(
from_previous = match.from_previous;
search_terms_args.reset(match.search_terms_args.get() ?
new TemplateURLRef::SearchTermsArgs(*match.search_terms_args) : NULL);
additional_info = match.additional_info;
return *this;
}
......@@ -319,6 +326,24 @@ TemplateURL* AutocompleteMatch::GetTemplateURL(Profile* profile) const {
GetTemplateURLForKeyword(keyword);
}
void AutocompleteMatch::RecordAdditionalInfo(const std::string& property,
const std::string& value) {
DCHECK(property.size());
DCHECK(value.size());
additional_info[property] = value;
}
void AutocompleteMatch::RecordAdditionalInfo(const std::string& property,
int value) {
RecordAdditionalInfo(property, StringPrintf("%d", value));
}
void AutocompleteMatch::RecordAdditionalInfo(const std::string& property,
const base::Time& value) {
RecordAdditionalInfo(property,
UTF16ToUTF8(base::TimeFormatShortDateAndTime(value)));
}
#ifndef NDEBUG
void AutocompleteMatch::Validate() const {
ValidateClassifications(contents, contents_class);
......
......@@ -5,6 +5,7 @@
#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_MATCH_H_
#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_MATCH_H_
#include <map>
#include <string>
#include <vector>
......@@ -17,6 +18,10 @@ class AutocompleteProvider;
class Profile;
class TemplateURL;
namespace base {
class Time;
} // namespace base
// AutocompleteMatch ----------------------------------------------------------
// A single result line with classified spans. The autocomplete popup displays
......@@ -64,6 +69,10 @@ struct AutocompleteMatch {
typedef std::vector<ACMatchClassification> ACMatchClassifications;
// Type used by providers to attach additional, optional information to
// an AutocompleteMatch.
typedef std::map<std::string, std::string> AdditionalInfo;
// The type of this match.
enum Type {
URL_WHAT_YOU_TYPED = 0, // The input as a URL.
......@@ -189,6 +198,13 @@ struct AutocompleteMatch {
// TemplateURL. See comments on |keyword| below.
TemplateURL* GetTemplateURL(Profile* profile) const;
// Adds optional information to the |additional_info| dictionary.
void RecordAdditionalInfo(const std::string& property,
const std::string& value);
void RecordAdditionalInfo(const std::string& property, int value);
void RecordAdditionalInfo(const std::string& property,
const base::Time& value);
// The provider of this match, used to remember which provider the user had
// selected when the input changes. This may be NULL, in which case there is
// no provider (or memory of the user's selection).
......@@ -283,6 +299,10 @@ struct AutocompleteMatch {
// AutocompleteController to do no additional transformations.
scoped_ptr<TemplateURLRef::SearchTermsArgs> search_terms_args;
// Information dictionary into which each provider can optionally record a
// property and associated value and which is presented in chrome://omnibox.
AdditionalInfo additional_info;
#ifndef NDEBUG
// Does a data integrity check on this match.
void Validate() const;
......
......@@ -245,6 +245,10 @@ AutocompleteMatch HistoryQuickProvider::QuickMatchToACMatch(
match.description_class = SpansFromTermMatch(
history_match.title_matches, match.description.length(), false);
match.RecordAdditionalInfo("typed count", info.typed_count());
match.RecordAdditionalInfo("visit count", info.visit_count());
match.RecordAdditionalInfo("last visit", info.last_visit());
return match;
}
......
......@@ -936,5 +936,9 @@ AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch(
ACMatchClassification::NONE,
&match.description_class);
match.RecordAdditionalInfo("typed count", info.typed_count());
match.RecordAdditionalInfo("visit count", info.visit_count());
match.RecordAdditionalInfo("last visit", info.last_visit());
return match;
}
......@@ -40,3 +40,8 @@ p {
.table-header {
white-space: nowrap;
}
.additional-info-property,
.additional-info-value {
white-space: nowrap;
}
......@@ -63,13 +63,17 @@ cr.define('omniboxDebug', function() {
* result record that we lookup.
* @param {boolean} displayAlways whether the property should be displayed
* regardless of whether we're in detailed more.
* @param {string} tooltip a description of the property that will be
* presented as a tooltip when the mouse is hovered over the column title.
* @constructor
*/
function PresentationInfoRecord(header, url, propertyName, displayAlways) {
function PresentationInfoRecord(header, url, propertyName, displayAlways,
tooltip) {
this.header = header;
this.urlLabelForHeader = url;
this.propertyName = propertyName;
this.displayAlways = displayAlways;
this.tooltip = tooltip;
}
/**
......@@ -81,32 +85,50 @@ cr.define('omniboxDebug', function() {
* @const
*/
var PROPERTY_OUTPUT_ORDER = [
new PresentationInfoRecord('Provider', '', 'provider_name', true),
new PresentationInfoRecord('Type', '', 'type', true),
new PresentationInfoRecord('Relevance', '', 'relevance', true),
new PresentationInfoRecord('Contents', '', 'contents', true),
new PresentationInfoRecord('Starred', '', 'starred', false),
new PresentationInfoRecord('Provider', '', 'provider_name', true,
'The AutocompleteProvider suggesting this result.'),
new PresentationInfoRecord('Type', '', 'type', true,
'The type of the result.'),
new PresentationInfoRecord('Relevance', '', 'relevance', true,
'The result score. Higher is more relevant.'),
new PresentationInfoRecord('Contents', '', 'contents', true,
'The text that is presented identifying the result.'),
new PresentationInfoRecord('Starred', '', 'starred', false,
'A green checkmark indicates that the result has been bookmarked.'),
new PresentationInfoRecord(
'Is History What You Typed Match', '',
'is_history_what_you_typed_match', false),
new PresentationInfoRecord('Description', '', 'description', false),
new PresentationInfoRecord('URL', '', 'destination_url', true),
new PresentationInfoRecord('Fill Into Edit', '', 'fill_into_edit', false),
'HWYT', '', 'is_history_what_you_typed_match', false,
'A green checkmark indicates that the result is an History What You ' +
'Typed Match'),
new PresentationInfoRecord('Description', '', 'description', false,
'The page title of the result.'),
new PresentationInfoRecord('URL', '', 'destination_url', true,
'The URL for the result.'),
new PresentationInfoRecord('Fill Into Edit', '', 'fill_into_edit', false,
'The text shown in the omnibox when the result is selected.'),
new PresentationInfoRecord(
'Inline Autocomplete Offset', '', 'inline_autocomplete_offset', false),
new PresentationInfoRecord('Deletable', '', 'deletable', false),
new PresentationInfoRecord('From Previous', '', 'from_previous', false),
'IAO', '', 'inline_autocomplete_offset', false,
'The Inline Autocomplete Offset.'),
new PresentationInfoRecord('Del', '', 'deletable', false,
'A green checkmark indicates that the results can be deleted from ' +
'the visit history.'),
new PresentationInfoRecord('Prev', '', 'from_previous', false, ''),
new PresentationInfoRecord(
'Transition Type',
'Tran',
'http://code.google.com/codesearch#OAMlx_jo-ck/src/content/public/' +
'common/page_transition_types.h&exact_package=chromium&l=24',
'transition', false),
'transition', false,
'How the user got to the result.'),
new PresentationInfoRecord(
'Is This Provider Done', '', 'provider_done', false),
'Done', '', 'provider_done', false,
'A green checkmark indicates that the provider is done looking for ' +
'more results.'),
new PresentationInfoRecord(
'Template URL', '', 'template_url', false),
'Template URL', '', 'template_url', false, ''),
new PresentationInfoRecord(
'Associated Keyword', '', 'associated_keyword', false)
'Associated Keyword', '', 'associated_keyword', false, ''),
new PresentationInfoRecord(
'Additional Info', '', 'additional_info', false,
'Provider-specific information about the result.')
];
/**
......@@ -131,6 +153,7 @@ cr.define('omniboxDebug', function() {
// Output header text without a URL.
headerCell.textContent = PROPERTY_OUTPUT_ORDER[i].header;
headerCell.className = 'table-header';
headerCell.title = PROPERTY_OUTPUT_ORDER[i].tooltip;
}
row.appendChild(headerCell);
}
......@@ -150,7 +173,30 @@ cr.define('omniboxDebug', function() {
propertyName) {
var cell = document.createElement('td');
if (propertyName in autocompleteSuggestion) {
if (typeof autocompleteSuggestion[propertyName] == 'boolean') {
if (propertyName == 'additional_info') {
// |additional_info| embeds a two-column table of provider-specific data
// within this cell.
var additionalInfoTable = document.createElement('table');
for (var additionalInfoKey in autocompleteSuggestion[propertyName]) {
var additionalInfoRow = document.createElement('tr');
// Set the title (name of property) cell text.
var propertyCell = document.createElement('td');
propertyCell.textContent = additionalInfoKey + ':';
propertyCell.className = 'additional-info-property';
additionalInfoRow.appendChild(propertyCell);
// Set the value of the property cell text.
var valueCell = document.createElement('td');
valueCell.textContent =
autocompleteSuggestion[propertyName][additionalInfoKey];
valueCell.className = 'additional-info-value';
additionalInfoRow.appendChild(valueCell);
additionalInfoTable.appendChild(additionalInfoRow);
}
cell.appendChild(additionalInfoTable);
} else if (typeof autocompleteSuggestion[propertyName] == 'boolean') {
// If this is a boolean, display a checkmark or an X instead of
// the strings true or false.
if (autocompleteSuggestion[propertyName]) {
......
......@@ -125,6 +125,11 @@ void OmniboxUIHandler::AddResultToDictionary(const std::string& prefix,
output->SetString(item_prefix + ".keyword", it->keyword);
output->SetBoolean(item_prefix + ".starred", it->starred);
output->SetBoolean(item_prefix + ".from_previous", it->from_previous);
for (AutocompleteMatch::AdditionalInfo::const_iterator j =
it->additional_info.begin(); j != it->additional_info.end(); ++j) {
output->SetString(item_prefix + ".additional_info." + j->first,
j->second);
}
}
output->SetInteger(prefix + ".num_items", i);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment