Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/browser/resources/omnibox/omnibox.js

Issue 2939273002: DO NOT SUBMIT: what chrome/browser/resources/ could eventually look like with clang-format (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * Javascript for omnibox.html, served from chrome://omnibox/ 6 * Javascript for omnibox.html, served from chrome://omnibox/
7 * This is used to debug omnibox ranking. The user enters some text 7 * This is used to debug omnibox ranking. The user enters some text
8 * into a box, submits it, and then sees lots of debug information 8 * into a box, submits it, and then sees lots of debug information
9 * from the autocompleter that shows what omnibox would do with that 9 * from the autocompleter that shows what omnibox would do with that
10 * input. 10 * input.
11 * 11 *
12 * The simple object defined in this javascript file listens for 12 * The simple object defined in this javascript file listens for
13 * certain events on omnibox.html, sends (when appropriate) the 13 * certain events on omnibox.html, sends (when appropriate) the
14 * input text to C++ code to start the omnibox autcomplete controller 14 * input text to C++ code to start the omnibox autcomplete controller
15 * working, and listens from callbacks from the C++ code saying that 15 * working, and listens from callbacks from the C++ code saying that
16 * results are available. When results (possibly intermediate ones) 16 * results are available. When results (possibly intermediate ones)
17 * are available, the Javascript formats them and displays them. 17 * are available, the Javascript formats them and displays them.
18 */ 18 */
19 19
20 (function() { 20 (function() {
21 /** 21 /**
22 * Register our event handlers. 22 * Register our event handlers.
23 */ 23 */
24 function initialize() { 24 function initialize() {
25 $('omnibox-input-form').addEventListener( 25 $('omnibox-input-form').addEventListener('submit', startOmniboxQuery, false);
26 'submit', startOmniboxQuery, false); 26 $('prevent-inline-autocomplete')
27 $('prevent-inline-autocomplete').addEventListener( 27 .addEventListener('change', startOmniboxQuery);
28 'change', startOmniboxQuery); 28 $('prefer-keyword').addEventListener('change', startOmniboxQuery);
29 $('prefer-keyword').addEventListener('change', startOmniboxQuery); 29 $('page-classification').addEventListener('change', startOmniboxQuery);
30 $('page-classification').addEventListener('change', startOmniboxQuery); 30 $('show-details').addEventListener('change', refresh);
31 $('show-details').addEventListener('change', refresh); 31 $('show-incomplete-results').addEventListener('change', refresh);
32 $('show-incomplete-results').addEventListener('change', refresh); 32 $('show-all-providers').addEventListener('change', refresh);
33 $('show-all-providers').addEventListener('change', refresh); 33 }
34 } 34
35 35 /**
36 /** 36 * @type {OmniboxResultMojo} an array of all autocomplete results we've seen
37 * @type {OmniboxResultMojo} an array of all autocomplete results we've seen 37 * for this query. We append to this list once for every call to
38 * for this query. We append to this list once for every call to 38 * handleNewAutocompleteResult. See omnibox.mojom for details..
39 * handleNewAutocompleteResult. See omnibox.mojom for details.. 39 */
40 */ 40 var progressiveAutocompleteResults = [];
41 var progressiveAutocompleteResults = []; 41
42 42 /**
43 /** 43 * @type {number} the value for cursor position we sent with the most
44 * @type {number} the value for cursor position we sent with the most 44 * recent request. We need to remember this in order to display it
45 * recent request. We need to remember this in order to display it 45 * in the output; otherwise it's hard or impossible to determine
46 * in the output; otherwise it's hard or impossible to determine 46 * from screen captures or print-to-PDFs.
47 * from screen captures or print-to-PDFs. 47 */
48 */ 48 var cursorPositionUsed = -1;
49 var cursorPositionUsed = -1; 49
50 50 /**
51 /** 51 * Extracts the input text from the text field and sends it to the
52 * Extracts the input text from the text field and sends it to the 52 * C++ portion of chrome to handle. The C++ code will iteratively
53 * C++ portion of chrome to handle. The C++ code will iteratively 53 * call handleNewAutocompleteResult as results come in.
54 * call handleNewAutocompleteResult as results come in. 54 */
55 */ 55 function startOmniboxQuery(event) {
56 function startOmniboxQuery(event) { 56 // First, clear the results of past calls (if any).
57 // First, clear the results of past calls (if any). 57 progressiveAutocompleteResults = [];
58 progressiveAutocompleteResults = []; 58 // Then, call chrome with a five-element list:
59 // Then, call chrome with a five-element list: 59 // - first element: the value in the text box
60 // - first element: the value in the text box 60 // - second element: the location of the cursor in the text box
61 // - second element: the location of the cursor in the text box 61 // - third element: the value of prevent-inline-autocomplete
62 // - third element: the value of prevent-inline-autocomplete 62 // - forth element: the value of prefer-keyword
63 // - forth element: the value of prefer-keyword 63 // - fifth element: the value of page-classification
64 // - fifth element: the value of page-classification 64 cursorPositionUsed = $('input-text').selectionEnd;
65 cursorPositionUsed = $('input-text').selectionEnd; 65 browserProxy.startOmniboxQuery(
66 browserProxy.startOmniboxQuery( 66 $('input-text').value, cursorPositionUsed,
67 $('input-text').value, 67 $('prevent-inline-autocomplete').checked, $('prefer-keyword').checked,
68 cursorPositionUsed, 68 parseInt($('page-classification').value));
69 $('prevent-inline-autocomplete').checked, 69 // Cancel the submit action. i.e., don't submit the form. (We handle
70 $('prefer-keyword').checked, 70 // display the results solely with Javascript.)
71 parseInt($('page-classification').value)); 71 event.preventDefault();
72 // Cancel the submit action. i.e., don't submit the form. (We handle 72 }
73 // display the results solely with Javascript.) 73
74 event.preventDefault(); 74 /**
75 } 75 * Returns a simple object with information about how to display an
76 76 * autocomplete result data field.
77 /** 77 * @param {string} header the label for the top of the column/table.
78 * Returns a simple object with information about how to display an 78 * @param {string} urlLabelForHeader the URL that the header should point
79 * autocomplete result data field. 79 * to (if non-empty).
80 * @param {string} header the label for the top of the column/table. 80 * @param {string} propertyName the name of the property in the autocomplete
81 * @param {string} urlLabelForHeader the URL that the header should point 81 * result record that we lookup.
82 * to (if non-empty). 82 * @param {boolean} displayAlways whether the property should be displayed
83 * @param {string} propertyName the name of the property in the autocomplete 83 * regardless of whether we're in detailed more.
84 * result record that we lookup. 84 * @param {string} tooltip a description of the property that will be
85 * @param {boolean} displayAlways whether the property should be displayed 85 * presented as a tooltip when the mouse is hovered over the column title.
86 * regardless of whether we're in detailed more. 86 * @constructor
87 * @param {string} tooltip a description of the property that will be 87 */
88 * presented as a tooltip when the mouse is hovered over the column title. 88 function PresentationInfoRecord(
89 * @constructor 89 header, url, propertyName, displayAlways, tooltip) {
90 */ 90 this.header = header;
91 function PresentationInfoRecord(header, url, propertyName, displayAlways, 91 this.urlLabelForHeader = url;
92 tooltip) { 92 this.propertyName = propertyName;
93 this.header = header; 93 this.displayAlways = displayAlways;
94 this.urlLabelForHeader = url; 94 this.tooltip = tooltip;
95 this.propertyName = propertyName; 95 }
96 this.displayAlways = displayAlways; 96
97 this.tooltip = tooltip; 97 /**
98 } 98 * A constant that's used to decide what autocomplete result
99 99 * properties to output in what order. This is an array of
100 /** 100 * PresentationInfoRecord() objects; for details see that
101 * A constant that's used to decide what autocomplete result 101 * function.
102 * properties to output in what order. This is an array of 102 * @type {Array<Object>}
103 * PresentationInfoRecord() objects; for details see that 103 * @const
104 * function. 104 */
105 * @type {Array<Object>} 105 var PROPERTY_OUTPUT_ORDER = [
106 * @const 106 new PresentationInfoRecord(
107 */ 107 'Provider', '', 'providerName', true,
108 var PROPERTY_OUTPUT_ORDER = [ 108 'The AutocompleteProvider suggesting this result.'),
109 new PresentationInfoRecord('Provider', '', 'providerName', true, 109 new PresentationInfoRecord(
110 'The AutocompleteProvider suggesting this result.'), 110 'Type', '', 'type', true, 'The type of the result.'),
111 new PresentationInfoRecord('Type', '', 'type', true, 111 new PresentationInfoRecord(
112 'The type of the result.'), 112 'Relevance', '', 'relevance', true,
113 new PresentationInfoRecord('Relevance', '', 'relevance', true, 113 'The result score. Higher is more relevant.'),
114 'The result score. Higher is more relevant.'), 114 new PresentationInfoRecord(
115 new PresentationInfoRecord('Contents', '', 'contents', true, 115 'Contents', '', 'contents', true,
116 'The text that is presented identifying the result.'), 116 'The text that is presented identifying the result.'),
117 new PresentationInfoRecord( 117 new PresentationInfoRecord(
118 'Can Be Default', '', 'allowedToBeDefaultMatch', false, 118 'Can Be Default', '', 'allowedToBeDefaultMatch', false,
119 'A green checkmark indicates that the result can be the default ' + 119 'A green checkmark indicates that the result can be the default ' +
120 'match (i.e., can be the match that pressing enter in the omnibox ' + 120 'match (i.e., can be the match that pressing enter in the omnibox ' +
121 'navigates to).'), 121 'navigates to).'),
122 new PresentationInfoRecord('Starred', '', 'starred', false, 122 new PresentationInfoRecord(
123 'A green checkmark indicates that the result has been bookmarked.'), 123 'Starred', '', 'starred', false,
124 new PresentationInfoRecord('Description', '', 'description', false, 124 'A green checkmark indicates that the result has been bookmarked.'),
125 'The page title of the result.'), 125 new PresentationInfoRecord(
126 new PresentationInfoRecord('URL', '', 'destinationUrl', true, 126 'Description', '', 'description', false, 'The page title of the result.'),
127 'The URL for the result.'), 127 new PresentationInfoRecord(
128 new PresentationInfoRecord('Fill Into Edit', '', 'fillIntoEdit', false, 128 'URL', '', 'destinationUrl', true, 'The URL for the result.'),
129 'The text shown in the omnibox when the result is selected.'), 129 new PresentationInfoRecord(
130 new PresentationInfoRecord( 130 'Fill Into Edit', '', 'fillIntoEdit', false,
131 'Inline Autocompletion', '', 'inlineAutocompletion', false, 131 'The text shown in the omnibox when the result is selected.'),
132 'The text shown in the omnibox as a blue highlight selection ' + 132 new PresentationInfoRecord(
133 'following the cursor, if this match is shown inline.'), 133 'Inline Autocompletion', '', 'inlineAutocompletion', false,
134 new PresentationInfoRecord('Del', '', 'deletable', false, 134 'The text shown in the omnibox as a blue highlight selection ' +
135 'A green checkmark indicates that the result can be deleted from ' + 135 'following the cursor, if this match is shown inline.'),
136 'the visit history.'), 136 new PresentationInfoRecord(
137 new PresentationInfoRecord('Prev', '', 'fromPrevious', false, ''), 137 'Del', '', 'deletable', false,
138 new PresentationInfoRecord( 138 'A green checkmark indicates that the result can be deleted from ' +
139 'Tran', 139 'the visit history.'),
140 'http://code.google.com/codesearch#OAMlx_jo-ck/src/content/public/' + 140 new PresentationInfoRecord('Prev', '', 'fromPrevious', false, ''),
141 'common/page_transition_types.h&exact_package=chromium&l=24', 141 new PresentationInfoRecord(
142 'transition', false, 142 'Tran',
143 'How the user got to the result.'), 143 'http://code.google.com/codesearch#OAMlx_jo-ck/src/content/public/' +
144 new PresentationInfoRecord( 144 'common/page_transition_types.h&exact_package=chromium&l=24',
145 'Done', '', 'providerDone', false, 145 'transition', false, 'How the user got to the result.'),
146 'A green checkmark indicates that the provider is done looking for ' + 146 new PresentationInfoRecord(
147 'more results.'), 147 'Done', '', 'providerDone', false,
148 new PresentationInfoRecord( 148 'A green checkmark indicates that the provider is done looking for ' +
149 'Associated Keyword', '', 'associatedKeyword', false, 149 'more results.'),
150 'If non-empty, a "press tab to search" hint will be shown and will ' + 150 new PresentationInfoRecord(
151 'engage this keyword.'), 151 'Associated Keyword', '', 'associatedKeyword', false,
152 new PresentationInfoRecord( 152 'If non-empty, a "press tab to search" hint will be shown and will ' +
153 'Keyword', '', 'keyword', false, 153 'engage this keyword.'),
154 'The keyword of the search engine to be used.'), 154 new PresentationInfoRecord(
155 new PresentationInfoRecord( 155 'Keyword', '', 'keyword', false,
156 'Duplicates', '', 'duplicates', false, 156 'The keyword of the search engine to be used.'),
157 'The number of matches that have been marked as duplicates of this ' + 157 new PresentationInfoRecord(
158 'match.'), 158 'Duplicates', '', 'duplicates', false,
159 new PresentationInfoRecord( 159 'The number of matches that have been marked as duplicates of this ' +
160 'Additional Info', '', 'additionalInfo', false, 160 'match.'),
161 'Provider-specific information about the result.') 161 new PresentationInfoRecord(
162 ]; 162 'Additional Info', '', 'additionalInfo', false,
163 163 'Provider-specific information about the result.')
164 /** 164 ];
165 * Returns an HTML Element of type table row that contains the 165
166 * headers we'll use for labeling the columns. If we're in 166 /**
167 * detailedMode, we use all the headers. If not, we only use ones 167 * Returns an HTML Element of type table row that contains the
168 * marked displayAlways. 168 * headers we'll use for labeling the columns. If we're in
169 */ 169 * detailedMode, we use all the headers. If not, we only use ones
170 function createAutocompleteResultTableHeader() { 170 * marked displayAlways.
171 */
172 function createAutocompleteResultTableHeader() {
173 var row = document.createElement('tr');
174 var inDetailedMode = $('show-details').checked;
175 for (var i = 0; i < PROPERTY_OUTPUT_ORDER.length; i++) {
176 if (inDetailedMode || PROPERTY_OUTPUT_ORDER[i].displayAlways) {
177 var headerCell = document.createElement('th');
178 if (PROPERTY_OUTPUT_ORDER[i].urlLabelForHeader != '') {
179 // Wrap header text in URL.
180 var linkNode = document.createElement('a');
181 linkNode.href = PROPERTY_OUTPUT_ORDER[i].urlLabelForHeader;
182 linkNode.textContent = PROPERTY_OUTPUT_ORDER[i].header;
183 headerCell.appendChild(linkNode);
184 } else {
185 // Output header text without a URL.
186 headerCell.textContent = PROPERTY_OUTPUT_ORDER[i].header;
187 headerCell.className = 'table-header';
188 headerCell.title = PROPERTY_OUTPUT_ORDER[i].tooltip;
189 }
190 row.appendChild(headerCell);
191 }
192 }
193 return row;
194 }
195
196 /**
197 * @param {AutocompleteMatchMojo} autocompleteSuggestion the particular
198 * autocomplete suggestion we're in the process of displaying.
199 * @param {string} propertyName the particular property of the autocomplete
200 * suggestion that should go in this cell.
201 * @return {HTMLTableCellElement} that contains the value within this
202 * autocompleteSuggestion associated with propertyName.
203 */
204 function createCellForPropertyAndRemoveProperty(
205 autocompleteSuggestion, propertyName) {
206 var cell = document.createElement('td');
207 if (propertyName in autocompleteSuggestion) {
208 if (propertyName == 'additionalInfo') {
209 // |additionalInfo| embeds a two-column table of provider-specific data
210 // within this cell. |additionalInfo| is an array of
211 // AutocompleteAdditionalInfo.
212 var additionalInfoTable = document.createElement('table');
213 for (var i = 0; i < autocompleteSuggestion[propertyName].length; i++) {
214 var additionalInfo = autocompleteSuggestion[propertyName][i];
215 var additionalInfoRow = document.createElement('tr');
216
217 // Set the title (name of property) cell text.
218 var propertyCell = document.createElement('td');
219 propertyCell.textContent = additionalInfo.key + ':';
220 propertyCell.className = 'additional-info-property';
221 additionalInfoRow.appendChild(propertyCell);
222
223 // Set the value of the property cell text.
224 var valueCell = document.createElement('td');
225 valueCell.textContent = additionalInfo.value;
226 valueCell.className = 'additional-info-value';
227 additionalInfoRow.appendChild(valueCell);
228
229 additionalInfoTable.appendChild(additionalInfoRow);
230 }
231 cell.appendChild(additionalInfoTable);
232 } else if (typeof autocompleteSuggestion[propertyName] == 'boolean') {
233 // If this is a boolean, display a checkmark or an X instead of
234 // the strings true or false.
235 if (autocompleteSuggestion[propertyName]) {
236 cell.className = 'check-mark';
237 cell.textContent = '✔';
238 } else {
239 cell.className = 'x-mark';
240 cell.textContent = '✗';
241 }
242 } else {
243 var text = String(autocompleteSuggestion[propertyName]);
244 // If it's a URL wrap it in an href.
245 var re = /^(http|https|ftp|chrome|file):\/\//;
246 if (re.test(text)) {
247 var aCell = document.createElement('a');
248 aCell.textContent = text;
249 aCell.href = text;
250 cell.appendChild(aCell);
251 } else {
252 // All other data types (integer, strings, etc.) display their
253 // normal toString() output.
254 cell.textContent = autocompleteSuggestion[propertyName];
255 }
256 }
257 } // else: if propertyName is undefined, we leave the cell blank
258 return cell;
259 }
260
261 /**
262 * Appends some human-readable information about the provided
263 * autocomplete result to the HTML node with id omnibox-debug-text.
264 * The current human-readable form is a few lines about general
265 * autocomplete result statistics followed by a table with one line
266 * for each autocomplete match. The input parameter is an OmniboxResultMojo.
267 */
268 function addResultToOutput(result) {
269 var output = $('omnibox-debug-text');
270 var inDetailedMode = $('show-details').checked;
271 var showIncompleteResults = $('show-incomplete-results').checked;
272 var showPerProviderResults = $('show-all-providers').checked;
273
274 // Always output cursor position.
275 var p = document.createElement('p');
276 p.textContent = 'cursor position = ' + cursorPositionUsed;
277 output.appendChild(p);
278
279 // Output the result-level features in detailed mode and in
280 // show incomplete results mode. We do the latter because without
281 // these result-level features, one can't make sense of each
282 // batch of results.
283 if (inDetailedMode || showIncompleteResults) {
284 var p1 = document.createElement('p');
285 p1.textContent =
286 'elapsed time = ' + result.timeSinceOmniboxStartedMs + 'ms';
287 output.appendChild(p1);
288 var p2 = document.createElement('p');
289 p2.textContent = 'all providers done = ' + result.done;
290 output.appendChild(p2);
291 var p3 = document.createElement('p');
292 p3.textContent = 'host = ' + result.host;
293 if ('isTypedHost' in result) {
294 // Only output the isTypedHost information if available. (It may
295 // be missing if the history database lookup failed.)
296 p3.textContent =
297 p3.textContent + ' has isTypedHost = ' + result.isTypedHost;
298 }
299 output.appendChild(p3);
300 }
301
302 // Combined results go after the lines below.
303 var group = document.createElement('a');
304 group.className = 'group-separator';
305 group.textContent = 'Combined results.';
306 output.appendChild(group);
307
308 // Add combined/merged result table.
309 var p = document.createElement('p');
310 p.appendChild(addResultTableToOutput(result.combinedResults));
311 output.appendChild(p);
312
313 // Move forward only if you want to display per provider results.
314 if (!showPerProviderResults) {
315 return;
316 }
317
318 // Individual results go after the lines below.
319 var group = document.createElement('a');
320 group.className = 'group-separator';
321 group.textContent = 'Results for individual providers.';
322 output.appendChild(group);
323
324 // Add the per-provider result tables with labels. We do not append the
325 // combined/merged result table since we already have the per provider
326 // results.
327 for (var i = 0; i < result.resultsByProvider.length; i++) {
328 var providerResults = result.resultsByProvider[i];
329 // If we have no results we do not display anything.
330 if (providerResults.results.length == 0) {
331 continue;
332 }
333 var p = document.createElement('p');
334 p.appendChild(addResultTableToOutput(providerResults.results));
335 output.appendChild(p);
336 }
337 }
338
339 /**
340 * @param {Object} result an array of AutocompleteMatchMojos.
341 * @return {HTMLTableCellElement} that is a user-readable HTML
342 * representation of this object.
343 */
344 function addResultTableToOutput(result) {
345 var inDetailedMode = $('show-details').checked;
346 // Create a table to hold all the autocomplete items.
347 var table = document.createElement('table');
348 table.className = 'autocomplete-results-table';
349 table.appendChild(createAutocompleteResultTableHeader());
350 // Loop over every autocomplete item and add it as a row in the table.
351 for (var i = 0; i < result.length; i++) {
352 var autocompleteSuggestion = result[i];
171 var row = document.createElement('tr'); 353 var row = document.createElement('tr');
172 var inDetailedMode = $('show-details').checked; 354 // Loop over all the columns/properties and output either them
173 for (var i = 0; i < PROPERTY_OUTPUT_ORDER.length; i++) { 355 // all (if we're in detailed mode) or only the ones marked displayAlways.
174 if (inDetailedMode || PROPERTY_OUTPUT_ORDER[i].displayAlways) { 356 // Keep track of which properties we displayed.
175 var headerCell = document.createElement('th'); 357 var displayedProperties = {};
176 if (PROPERTY_OUTPUT_ORDER[i].urlLabelForHeader != '') { 358 for (var j = 0; j < PROPERTY_OUTPUT_ORDER.length; j++) {
177 // Wrap header text in URL. 359 if (inDetailedMode || PROPERTY_OUTPUT_ORDER[j].displayAlways) {
178 var linkNode = document.createElement('a'); 360 row.appendChild(createCellForPropertyAndRemoveProperty(
179 linkNode.href = PROPERTY_OUTPUT_ORDER[i].urlLabelForHeader; 361 autocompleteSuggestion, PROPERTY_OUTPUT_ORDER[j].propertyName));
180 linkNode.textContent = PROPERTY_OUTPUT_ORDER[i].header; 362 displayedProperties[PROPERTY_OUTPUT_ORDER[j].propertyName] = true;
181 headerCell.appendChild(linkNode); 363 }
182 } else { 364 }
183 // Output header text without a URL. 365
184 headerCell.textContent = PROPERTY_OUTPUT_ORDER[i].header; 366 // Now, if we're in detailed mode, add all the properties that
185 headerCell.className = 'table-header'; 367 // haven't already been output. (We know which properties have
186 headerCell.title = PROPERTY_OUTPUT_ORDER[i].tooltip; 368 // already been output because we delete the property when we output
369 // it. The only way we have properties left at this point if
370 // we're in detailed mode and we're getting back properties
371 // not listed in PROPERTY_OUTPUT_ORDER. Perhaps someone added
372 // something to the C++ code but didn't bother to update this
373 // Javascript? In any case, we want to display them.)
374 if (inDetailedMode) {
375 for (var key in autocompleteSuggestion) {
376 if (!displayedProperties[key] &&
377 typeof autocompleteSuggestion[key] != 'function') {
378 var cell = document.createElement('td');
379 cell.textContent = key + '=' + autocompleteSuggestion[key];
380 row.appendChild(cell);
187 } 381 }
188 row.appendChild(headerCell); 382 }
189 } 383 }
190 } 384
191 return row; 385 table.appendChild(row);
192 } 386 }
193 387 return table;
194 /** 388 }
195 * @param {AutocompleteMatchMojo} autocompleteSuggestion the particular 389
196 * autocomplete suggestion we're in the process of displaying. 390 /* Repaints the page based on the contents of the array
197 * @param {string} propertyName the particular property of the autocomplete 391 * progressiveAutocompleteResults, which represents consecutive
198 * suggestion that should go in this cell. 392 * autocomplete results. We only display the last (most recent)
199 * @return {HTMLTableCellElement} that contains the value within this 393 * entry unless we're asked to display incomplete results. For an
200 * autocompleteSuggestion associated with propertyName. 394 * example of the output, play with chrome://omnibox/
201 */ 395 */
202 function createCellForPropertyAndRemoveProperty(autocompleteSuggestion, 396 function refresh() {
203 propertyName) { 397 // Erase whatever is currently being displayed.
204 var cell = document.createElement('td'); 398 var output = $('omnibox-debug-text');
205 if (propertyName in autocompleteSuggestion) { 399 output.innerHTML = '';
206 if (propertyName == 'additionalInfo') { 400
207 // |additionalInfo| embeds a two-column table of provider-specific data 401 if (progressiveAutocompleteResults.length > 0) { // if we have results
208 // within this cell. |additionalInfo| is an array of 402 // Display the results.
209 // AutocompleteAdditionalInfo.
210 var additionalInfoTable = document.createElement('table');
211 for (var i = 0; i < autocompleteSuggestion[propertyName].length; i++) {
212 var additionalInfo = autocompleteSuggestion[propertyName][i];
213 var additionalInfoRow = document.createElement('tr');
214
215 // Set the title (name of property) cell text.
216 var propertyCell = document.createElement('td');
217 propertyCell.textContent = additionalInfo.key + ':';
218 propertyCell.className = 'additional-info-property';
219 additionalInfoRow.appendChild(propertyCell);
220
221 // Set the value of the property cell text.
222 var valueCell = document.createElement('td');
223 valueCell.textContent = additionalInfo.value;
224 valueCell.className = 'additional-info-value';
225 additionalInfoRow.appendChild(valueCell);
226
227 additionalInfoTable.appendChild(additionalInfoRow);
228 }
229 cell.appendChild(additionalInfoTable);
230 } else if (typeof autocompleteSuggestion[propertyName] == 'boolean') {
231 // If this is a boolean, display a checkmark or an X instead of
232 // the strings true or false.
233 if (autocompleteSuggestion[propertyName]) {
234 cell.className = 'check-mark';
235 cell.textContent = '✔';
236 } else {
237 cell.className = 'x-mark';
238 cell.textContent = '✗';
239 }
240 } else {
241 var text = String(autocompleteSuggestion[propertyName]);
242 // If it's a URL wrap it in an href.
243 var re = /^(http|https|ftp|chrome|file):\/\//;
244 if (re.test(text)) {
245 var aCell = document.createElement('a');
246 aCell.textContent = text;
247 aCell.href = text;
248 cell.appendChild(aCell);
249 } else {
250 // All other data types (integer, strings, etc.) display their
251 // normal toString() output.
252 cell.textContent = autocompleteSuggestion[propertyName];
253 }
254 }
255 } // else: if propertyName is undefined, we leave the cell blank
256 return cell;
257 }
258
259 /**
260 * Appends some human-readable information about the provided
261 * autocomplete result to the HTML node with id omnibox-debug-text.
262 * The current human-readable form is a few lines about general
263 * autocomplete result statistics followed by a table with one line
264 * for each autocomplete match. The input parameter is an OmniboxResultMojo.
265 */
266 function addResultToOutput(result) {
267 var output = $('omnibox-debug-text');
268 var inDetailedMode = $('show-details').checked;
269 var showIncompleteResults = $('show-incomplete-results').checked; 403 var showIncompleteResults = $('show-incomplete-results').checked;
270 var showPerProviderResults = $('show-all-providers').checked; 404 var startIndex =
271 405 showIncompleteResults ? 0 : progressiveAutocompleteResults.length - 1;
272 // Always output cursor position. 406 for (var i = startIndex; i < progressiveAutocompleteResults.length; i++) {
273 var p = document.createElement('p'); 407 addResultToOutput(progressiveAutocompleteResults[i]);
274 p.textContent = 'cursor position = ' + cursorPositionUsed; 408 }
275 output.appendChild(p); 409 }
276 410 }
277 // Output the result-level features in detailed mode and in 411
278 // show incomplete results mode. We do the latter because without 412 // NOTE: Need to keep a global reference to the |pageImpl| such that it is not
279 // these result-level features, one can't make sense of each 413 // garbage collected, which causes the pipe to close and future calls from C++
280 // batch of results. 414 // to JS to get dropped.
281 if (inDetailedMode || showIncompleteResults) { 415 var pageImpl = null;
282 var p1 = document.createElement('p'); 416 var browserProxy = null;
283 p1.textContent = 'elapsed time = ' + 417
284 result.timeSinceOmniboxStartedMs + 'ms'; 418 function initializeProxies() {
285 output.appendChild(p1); 419 browserProxy = new mojom.OmniboxPageHandlerPtr;
286 var p2 = document.createElement('p'); 420 Mojo.bindInterface(
287 p2.textContent = 'all providers done = ' + result.done; 421 mojom.OmniboxPageHandler.name, mojo.makeRequest(browserProxy).handle);
288 output.appendChild(p2); 422
289 var p3 = document.createElement('p'); 423 /** @constructor */
290 p3.textContent = 'host = ' + result.host; 424 var OmniboxPageImpl = function(request) {
291 if ('isTypedHost' in result) { 425 this.binding_ = new mojo.Binding(mojom.OmniboxPage, this, request);
292 // Only output the isTypedHost information if available. (It may 426 };
293 // be missing if the history database lookup failed.) 427
294 p3.textContent = p3.textContent + ' has isTypedHost = ' + 428 OmniboxPageImpl.prototype = {
295 result.isTypedHost; 429 /** @override */
296 } 430 handleNewAutocompleteResult: function(result) {
297 output.appendChild(p3); 431 progressiveAutocompleteResults.push(result);
298 } 432 refresh();
299 433 },
300 // Combined results go after the lines below. 434 };
301 var group = document.createElement('a'); 435
302 group.className = 'group-separator'; 436 var client = new mojom.OmniboxPagePtr;
303 group.textContent = 'Combined results.'; 437 pageImpl = new OmniboxPageImpl(mojo.makeRequest(client));
304 output.appendChild(group); 438 browserProxy.setClientPage(client);
305 439 }
306 // Add combined/merged result table. 440
307 var p = document.createElement('p'); 441 document.addEventListener('DOMContentLoaded', function() {
308 p.appendChild(addResultTableToOutput(result.combinedResults)); 442 initializeProxies();
309 output.appendChild(p); 443 initialize();
310 444 });
311 // Move forward only if you want to display per provider results.
312 if (!showPerProviderResults) {
313 return;
314 }
315
316 // Individual results go after the lines below.
317 var group = document.createElement('a');
318 group.className = 'group-separator';
319 group.textContent = 'Results for individual providers.';
320 output.appendChild(group);
321
322 // Add the per-provider result tables with labels. We do not append the
323 // combined/merged result table since we already have the per provider
324 // results.
325 for (var i = 0; i < result.resultsByProvider.length; i++) {
326 var providerResults = result.resultsByProvider[i];
327 // If we have no results we do not display anything.
328 if (providerResults.results.length == 0) {
329 continue;
330 }
331 var p = document.createElement('p');
332 p.appendChild(addResultTableToOutput(providerResults.results));
333 output.appendChild(p);
334 }
335 }
336
337 /**
338 * @param {Object} result an array of AutocompleteMatchMojos.
339 * @return {HTMLTableCellElement} that is a user-readable HTML
340 * representation of this object.
341 */
342 function addResultTableToOutput(result) {
343 var inDetailedMode = $('show-details').checked;
344 // Create a table to hold all the autocomplete items.
345 var table = document.createElement('table');
346 table.className = 'autocomplete-results-table';
347 table.appendChild(createAutocompleteResultTableHeader());
348 // Loop over every autocomplete item and add it as a row in the table.
349 for (var i = 0; i < result.length; i++) {
350 var autocompleteSuggestion = result[i];
351 var row = document.createElement('tr');
352 // Loop over all the columns/properties and output either them
353 // all (if we're in detailed mode) or only the ones marked displayAlways.
354 // Keep track of which properties we displayed.
355 var displayedProperties = {};
356 for (var j = 0; j < PROPERTY_OUTPUT_ORDER.length; j++) {
357 if (inDetailedMode || PROPERTY_OUTPUT_ORDER[j].displayAlways) {
358 row.appendChild(createCellForPropertyAndRemoveProperty(
359 autocompleteSuggestion, PROPERTY_OUTPUT_ORDER[j].propertyName));
360 displayedProperties[PROPERTY_OUTPUT_ORDER[j].propertyName] = true;
361 }
362 }
363
364 // Now, if we're in detailed mode, add all the properties that
365 // haven't already been output. (We know which properties have
366 // already been output because we delete the property when we output
367 // it. The only way we have properties left at this point if
368 // we're in detailed mode and we're getting back properties
369 // not listed in PROPERTY_OUTPUT_ORDER. Perhaps someone added
370 // something to the C++ code but didn't bother to update this
371 // Javascript? In any case, we want to display them.)
372 if (inDetailedMode) {
373 for (var key in autocompleteSuggestion) {
374 if (!displayedProperties[key] &&
375 typeof autocompleteSuggestion[key] != 'function') {
376 var cell = document.createElement('td');
377 cell.textContent = key + '=' + autocompleteSuggestion[key];
378 row.appendChild(cell);
379 }
380 }
381 }
382
383 table.appendChild(row);
384 }
385 return table;
386 }
387
388 /* Repaints the page based on the contents of the array
389 * progressiveAutocompleteResults, which represents consecutive
390 * autocomplete results. We only display the last (most recent)
391 * entry unless we're asked to display incomplete results. For an
392 * example of the output, play with chrome://omnibox/
393 */
394 function refresh() {
395 // Erase whatever is currently being displayed.
396 var output = $('omnibox-debug-text');
397 output.innerHTML = '';
398
399 if (progressiveAutocompleteResults.length > 0) { // if we have results
400 // Display the results.
401 var showIncompleteResults = $('show-incomplete-results').checked;
402 var startIndex = showIncompleteResults ? 0 :
403 progressiveAutocompleteResults.length - 1;
404 for (var i = startIndex; i < progressiveAutocompleteResults.length; i++) {
405 addResultToOutput(progressiveAutocompleteResults[i]);
406 }
407 }
408 }
409
410 // NOTE: Need to keep a global reference to the |pageImpl| such that it is not
411 // garbage collected, which causes the pipe to close and future calls from C++
412 // to JS to get dropped.
413 var pageImpl = null;
414 var browserProxy = null;
415
416 function initializeProxies() {
417 browserProxy = new mojom.OmniboxPageHandlerPtr;
418 Mojo.bindInterface(mojom.OmniboxPageHandler.name,
419 mojo.makeRequest(browserProxy).handle);
420
421 /** @constructor */
422 var OmniboxPageImpl = function(request) {
423 this.binding_ = new mojo.Binding(mojom.OmniboxPage, this, request);
424 };
425
426 OmniboxPageImpl.prototype = {
427 /** @override */
428 handleNewAutocompleteResult: function(result) {
429 progressiveAutocompleteResults.push(result);
430 refresh();
431 },
432 };
433
434 var client = new mojom.OmniboxPagePtr;
435 pageImpl = new OmniboxPageImpl(mojo.makeRequest(client));
436 browserProxy.setClientPage(client);
437 }
438
439 document.addEventListener('DOMContentLoaded', function() {
440 initializeProxies();
441 initialize();
442 });
443 })(); 445 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698