home *** CD-ROM | disk | FTP | other *** search
/ Freelog 115 / FreelogNo115-MaiJuin2013.iso / Internet / AvantBrowser / asetup.exe / _data / webkit / chrome.dll / 0 / BINDATA / 573 < prev    next >
Encoding:
Text File  |  2013-04-03  |  16.8 KB  |  421 lines

  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
  3. // found in the LICENSE file.
  4.  
  5. /**
  6.  * Javascript for omnibox.html, served from chrome://omnibox/
  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
  9.  * from the autocompleter that shows what omnibox would do with that
  10.  * input.
  11.  *
  12.  * The simple object defined in this javascript file listens for
  13.  * certain events on omnibox.html, sends (when appropriate) the
  14.  * input text to C++ code to start the omnibox autcomplete controller
  15.  * working, and listens from callbacks from the C++ code saying that
  16.  * results are available.  When results (possibly intermediate ones)
  17.  * are available, the Javascript formats them and displays them.
  18.  */
  19. cr.define('omniboxDebug', function() {
  20.   'use strict';
  21.  
  22.   /**
  23.    * Register our event handlers.
  24.    */
  25.   function initialize() {
  26.     $('omnibox-input-form').addEventListener(
  27.         'submit', startOmniboxQuery, false);
  28.     $('show-details').addEventListener('change', refresh);
  29.     $('show-incomplete-results').addEventListener('change', refresh);
  30.     $('show-all-providers').addEventListener('change', refresh);
  31.   }
  32.  
  33.   /**
  34.    * @type {Array.<Object>} an array of all autocomplete results we've seen
  35.    *     for this query.  We append to this list once for every call to
  36.    *     handleNewAutocompleteResult.  For details on the structure of
  37.    *     the object inside, see the comments by addResultToOutput.
  38.    */
  39.   var progressiveAutocompleteResults = [];
  40.  
  41.   /**
  42.    * Extracts the input text from the text field and sends it to the
  43.    * C++ portion of chrome to handle.  The C++ code will iteratively
  44.    * call handleNewAutocompleteResult as results come in.
  45.    */
  46.   function startOmniboxQuery(event) {
  47.     // First, clear the results of past calls (if any).
  48.     progressiveAutocompleteResults = [];
  49.     // Then, call chrome with a one-element list: the value in the text box.
  50.     chrome.send('startOmniboxQuery', [$('input-text').value]);
  51.     // Cancel the submit action.  i.e., don't submit the form.  (We handle
  52.     // display the results solely with Javascript.)
  53.     event.preventDefault();
  54.   }
  55.  
  56.   /**
  57.    * Returns a simple object with information about how to display an
  58.    * autocomplete result data field.
  59.    * @param {string} header the label for the top of the column/table.
  60.    * @param {string} urlLabelForHeader the URL that the header should point
  61.    *     to (if non-empty).
  62.    * @param {string} propertyName the name of the property in the autocomplete
  63.    *     result record that we lookup.
  64.    * @param {boolean} displayAlways whether the property should be displayed
  65.    *     regardless of whether we're in detailed more.
  66.    * @param {string} tooltip a description of the property that will be
  67.    *     presented as a tooltip when the mouse is hovered over the column title.
  68.    * @constructor
  69.    */
  70.   function PresentationInfoRecord(header, url, propertyName, displayAlways,
  71.                                   tooltip) {
  72.     this.header = header;
  73.     this.urlLabelForHeader = url;
  74.     this.propertyName = propertyName;
  75.     this.displayAlways = displayAlways;
  76.     this.tooltip = tooltip;
  77.   }
  78.  
  79.   /**
  80.    * A constant that's used to decide what autocomplete result
  81.    * properties to output in what order.  This is an array of
  82.    * PresentationInfoRecord() objects; for details see that
  83.    * function.
  84.    * @type {Array.<Object>}
  85.    * @const
  86.    */
  87.   var PROPERTY_OUTPUT_ORDER = [
  88.     new PresentationInfoRecord('Provider', '', 'provider_name', true,
  89.         'The AutocompleteProvider suggesting this result.'),
  90.     new PresentationInfoRecord('Type', '', 'type', true,
  91.         'The type of the result.'),
  92.     new PresentationInfoRecord('Relevance', '', 'relevance', true,
  93.         'The result score. Higher is more relevant.'),
  94.     new PresentationInfoRecord('Contents', '', 'contents', true,
  95.         'The text that is presented identifying the result.'),
  96.     new PresentationInfoRecord('Starred', '', 'starred', false,
  97.         'A green checkmark indicates that the result has been bookmarked.'),
  98.     new PresentationInfoRecord(
  99.         'HWYT', '', 'is_history_what_you_typed_match', false,
  100.         'A green checkmark indicates that the result is an History What You ' +
  101.         'Typed Match'),
  102.     new PresentationInfoRecord('Description', '', 'description', false,
  103.         'The page title of the result.'),
  104.     new PresentationInfoRecord('URL', '', 'destination_url', true,
  105.         'The URL for the result.'),
  106.     new PresentationInfoRecord('Fill Into Edit', '', 'fill_into_edit', false,
  107.         'The text shown in the omnibox when the result is selected.'),
  108.     new PresentationInfoRecord(
  109.         'IAO', '', 'inline_autocomplete_offset', false,
  110.         'The Inline Autocomplete Offset.'),
  111.     new PresentationInfoRecord('Del', '', 'deletable', false,
  112.         'A green checkmark indicates that the results can be deleted from ' +
  113.         'the visit history.'),
  114.     new PresentationInfoRecord('Prev', '', 'from_previous', false, ''),
  115.     new PresentationInfoRecord(
  116.         'Tran',
  117.         'http://code.google.com/codesearch#OAMlx_jo-ck/src/content/public/' +
  118.         'common/page_transition_types.h&exact_package=chromium&l=24',
  119.         'transition', false,
  120.         'How the user got to the result.'),
  121.     new PresentationInfoRecord(
  122.         'Done', '', 'provider_done', false,
  123.         'A green checkmark indicates that the provider is done looking for ' +
  124.         'more results.'),
  125.     new PresentationInfoRecord(
  126.         'Template URL', '', 'template_url', false, ''),
  127.     new PresentationInfoRecord(
  128.         'Associated Keyword', '', 'associated_keyword', false, ''),
  129.     new PresentationInfoRecord(
  130.         'Additional Info', '', 'additional_info', false,
  131.         'Provider-specific information about the result.')
  132.   ];
  133.  
  134.   /**
  135.    * Returns an HTML Element of type table row that contains the
  136.    * headers we'll use for labeling the columns.  If we're in
  137.    * detailed_mode, we use all the headers.  If not, we only use ones
  138.    * marked displayAlways.
  139.    */
  140.   function createAutocompleteResultTableHeader() {
  141.     var row = document.createElement('tr');
  142.     var inDetailedMode = $('show-details').checked;
  143.     for (var i = 0; i < PROPERTY_OUTPUT_ORDER.length; i++) {
  144.       if (inDetailedMode || PROPERTY_OUTPUT_ORDER[i].displayAlways) {
  145.         var headerCell = document.createElement('th');
  146.         if (PROPERTY_OUTPUT_ORDER[i].urlLabelForHeader != '') {
  147.           // Wrap header text in URL.
  148.           var linkNode = document.createElement('a');
  149.           linkNode.href = PROPERTY_OUTPUT_ORDER[i].urlLabelForHeader;
  150.           linkNode.textContent = PROPERTY_OUTPUT_ORDER[i].header;
  151.           headerCell.appendChild(linkNode);
  152.         } else {
  153.           // Output header text without a URL.
  154.           headerCell.textContent = PROPERTY_OUTPUT_ORDER[i].header;
  155.           headerCell.className = 'table-header';
  156.           headerCell.title = PROPERTY_OUTPUT_ORDER[i].tooltip;
  157.         }
  158.         row.appendChild(headerCell);
  159.       }
  160.     }
  161.     return row;
  162.   }
  163.  
  164.   /**
  165.    * @param {Object} autocompleteSuggestion the particular autocomplete
  166.    *     suggestion we're in the process of displaying.
  167.    * @param {string} propertyName the particular property of the autocomplete
  168.    *     suggestion that should go in this cell.
  169.    * @return {HTMLTableCellElement} that contains the value within this
  170.    *     autocompleteSuggestion associated with propertyName.
  171.    */
  172.   function createCellForPropertyAndRemoveProperty(autocompleteSuggestion,
  173.                                                   propertyName) {
  174.     var cell = document.createElement('td');
  175.     if (propertyName in autocompleteSuggestion) {
  176.       if (propertyName == 'additional_info') {
  177.         // |additional_info| embeds a two-column table of provider-specific data
  178.         // within this cell.
  179.         var additionalInfoTable = document.createElement('table');
  180.         for (var additionalInfoKey in autocompleteSuggestion[propertyName]) {
  181.           var additionalInfoRow = document.createElement('tr');
  182.  
  183.           // Set the title (name of property) cell text.
  184.           var propertyCell = document.createElement('td');
  185.           propertyCell.textContent = additionalInfoKey + ':';
  186.           propertyCell.className = 'additional-info-property';
  187.           additionalInfoRow.appendChild(propertyCell);
  188.  
  189.           // Set the value of the property cell text.
  190.           var valueCell = document.createElement('td');
  191.           valueCell.textContent =
  192.               autocompleteSuggestion[propertyName][additionalInfoKey];
  193.           valueCell.className = 'additional-info-value';
  194.           additionalInfoRow.appendChild(valueCell);
  195.  
  196.           additionalInfoTable.appendChild(additionalInfoRow);
  197.         }
  198.         cell.appendChild(additionalInfoTable);
  199.       } else if (typeof autocompleteSuggestion[propertyName] == 'boolean') {
  200.         // If this is a boolean, display a checkmark or an X instead of
  201.         // the strings true or false.
  202.         if (autocompleteSuggestion[propertyName]) {
  203.           cell.className = 'check-mark';
  204.           cell.textContent = 'Γ£ö';
  205.         } else {
  206.           cell.className = 'x-mark';
  207.           cell.textContent = 'Γ£ù';
  208.         }
  209.       } else {
  210.         var text = String(autocompleteSuggestion[propertyName]);
  211.         // If it's a URL wrap it in an href.
  212.         var re = /^(http|https|ftp|chrome|file):\/\//;
  213.         if (re.test(text)) {
  214.           var aCell = document.createElement('a');
  215.           aCell.textContent = text;
  216.           aCell.href = text;
  217.           cell.appendChild(aCell);
  218.         } else {
  219.           // All other data types (integer, strings, etc.) display their
  220.           // normal toString() output.
  221.           cell.textContent = autocompleteSuggestion[propertyName];
  222.         }
  223.       }
  224.     }  // else: if propertyName is undefined, we leave the cell blank
  225.     return cell;
  226.   }
  227.  
  228.   /**
  229.    * Called by C++ code when we get an update from the
  230.    * AutocompleteController.  We simply append the result to
  231.    * progressiveAutocompleteResults and refresh the page.
  232.    */
  233.   function handleNewAutocompleteResult(result) {
  234.     progressiveAutocompleteResults.push(result);
  235.     refresh();
  236.   }
  237.  
  238.   /**
  239.    * Appends some human-readable information about the provided
  240.    * autocomplete result to the HTML node with id omnibox-debug-text.
  241.    * The current human-readable form is a few lines about general
  242.    * autocomplete result statistics followed by a table with one line
  243.    * for each autocomplete match.  The input parameter result is a
  244.    * complex Object with lots of information about various
  245.    * autocomplete matches.  Here's an example of what it looks like:
  246.    * <pre>
  247.    * {@code
  248.    * {
  249.    *   'done': false,
  250.    *   'time_since_omnibox_started_ms': 15,
  251.    *   'combined_results' : {
  252.    *     'num_items': 4,
  253.    *     'item_0': {
  254.    *       'destination_url': 'http://mail.google.com',
  255.    *       'provider_name': 'HistoryURL',
  256.    *       'relevance': 1410,
  257.    *       ...
  258.    *     }
  259.    *     'item_1: {
  260.    *       ...
  261.    *     }
  262.    *     ...
  263.    *   }
  264.    *   'results_by_provider': {
  265.    *     'HistoryURL' : {
  266.    *       'num_items': 3,
  267.    *         ...
  268.    *       }
  269.    *     'Search' : {
  270.    *       'num_items': 1,
  271.    *       ...
  272.    *     }
  273.    *     ...
  274.    *   }
  275.    * }
  276.    * }
  277.    * </pre>
  278.    * For more information on how the result is packed, see the
  279.    * corresponding code in chrome/browser/ui/webui/omnibox_ui.cc
  280.    */
  281.   function addResultToOutput(result) {
  282.     var output = $('omnibox-debug-text');
  283.     var inDetailedMode = $('show-details').checked;
  284.     var showIncompleteResults = $('show-incomplete-results').checked;
  285.     var showPerProviderResults = $('show-all-providers').checked;
  286.  
  287.     // Output the result-level features in detailed mode and in
  288.     // show incomplete results mode.  We do the latter because without
  289.     // these result-level features, one can't make sense of each
  290.     // batch of results.
  291.     if (inDetailedMode || showIncompleteResults) {
  292.       var p1 = document.createElement('p');
  293.       p1.textContent = 'elapsed time = ' +
  294.           result.time_since_omnibox_started_ms + 'ms';
  295.       output.appendChild(p1);
  296.       var p2 = document.createElement('p');
  297.       p2.textContent = 'all providers done = ' + result.done;
  298.       output.appendChild(p2);
  299.     }
  300.  
  301.     // Combined results go after the lines below.
  302.     var group = document.createElement('a');
  303.     group.className = 'group-separator';
  304.     group.textContent = 'Combined results.';
  305.     output.appendChild(group);
  306.  
  307.     // Add combined/merged result table.
  308.     var p = document.createElement('p');
  309.     p.appendChild(addResultTableToOutput(result.combined_results));
  310.     output.appendChild(p);
  311.  
  312.     // Move forward only if you want to display per provider results.
  313.     if (!showPerProviderResults) {
  314.       return;
  315.     }
  316.  
  317.     // Individual results go after the lines below.
  318.     var group = document.createElement('a');
  319.     group.className = 'group-separator';
  320.     group.textContent = 'Results for individual providers.';
  321.     output.appendChild(group);
  322.  
  323.     // Add the per-provider result tables with labels. We do not append the
  324.     // combined/merged result table since we already have the per provider
  325.     // results.
  326.     for (var provider in result.results_by_provider) {
  327.       var results = result.results_by_provider[provider];
  328.       // If we have no results we do not display anything.
  329.       if (results.num_items == 0) {
  330.         continue;
  331.       }
  332.       var p = document.createElement('p');
  333.       p.appendChild(addResultTableToOutput(results));
  334.       output.appendChild(p);
  335.     }
  336.   }
  337.  
  338.   /**
  339.    * @param {Object} result either the combined_results component of
  340.    *     the structure described in the comment by addResultToOutput()
  341.    *     above or one of the per-provider results in the structure.
  342.    *     (Both have the same format).
  343.    * @return {HTMLTableCellElement} that is a user-readable HTML
  344.    *     representation of this object.
  345.    */
  346.   function addResultTableToOutput(result) {
  347.     var inDetailedMode = $('show-details').checked;
  348.     // Create a table to hold all the autocomplete items.
  349.     var table = document.createElement('table');
  350.     table.className = 'autocomplete-results-table';
  351.     table.appendChild(createAutocompleteResultTableHeader());
  352.     // Loop over every autocomplete item and add it as a row in the table.
  353.     for (var i = 0; i < result.num_items; i++) {
  354.       var autocompleteSuggestion = result['item_' + i];
  355.       var row = document.createElement('tr');
  356.       // Loop over all the columns/properties and output either them
  357.       // all (if we're in detailed mode) or only the ones marked displayAlways.
  358.       // Keep track of which properties we displayed.
  359.       var displayedProperties = {};
  360.       for (var j = 0; j < PROPERTY_OUTPUT_ORDER.length; j++) {
  361.         if (inDetailedMode || PROPERTY_OUTPUT_ORDER[j].displayAlways) {
  362.           row.appendChild(createCellForPropertyAndRemoveProperty(
  363.               autocompleteSuggestion, PROPERTY_OUTPUT_ORDER[j].propertyName));
  364.           displayedProperties[PROPERTY_OUTPUT_ORDER[j].propertyName] = true;
  365.         }
  366.       }
  367.  
  368.       // Now, if we're in detailed mode, add all the properties that
  369.       // haven't already been output.  (We know which properties have
  370.       // already been output because we delete the property when we output
  371.       // it.  The only way we have properties left at this point if
  372.       // we're in detailed mode and we're getting back properties
  373.       // not listed in PROPERTY_OUTPUT_ORDER.  Perhaps someone added
  374.       // something to the C++ code but didn't bother to update this
  375.       // Javascript?  In any case, we want to display them.)
  376.       if (inDetailedMode) {
  377.         for (var key in autocompleteSuggestion) {
  378.           if (!displayedProperties[key]) {
  379.             var cell = document.createElement('td');
  380.             cell.textContent = key + '=' + autocompleteSuggestion[key];
  381.             row.appendChild(cell);
  382.           }
  383.         }
  384.       }
  385.  
  386.       table.appendChild(row);
  387.     }
  388.     return table;
  389.   }
  390.  
  391.   /* Repaints the page based on the contents of the array
  392.    * progressiveAutocompleteResults, which represents consecutive
  393.    * autocomplete results.  We only display the last (most recent)
  394.    * entry unless we're asked to display incomplete results.  For an
  395.    * example of the output, play with chrome://omnibox/
  396.    */
  397.   function refresh() {
  398.     // Erase whatever is currently being displayed.
  399.     var output = $('omnibox-debug-text');
  400.     output.innerHTML = '';
  401.  
  402.     if (progressiveAutocompleteResults.length > 0) {  // if we have results
  403.       // Display the results.
  404.       var showIncompleteResults = $('show-incomplete-results').checked;
  405.       var startIndex = showIncompleteResults ? 0 :
  406.           progressiveAutocompleteResults.length - 1;
  407.       for (var i = startIndex; i < progressiveAutocompleteResults.length; i++) {
  408.         addResultToOutput(progressiveAutocompleteResults[i]);
  409.       }
  410.     }
  411.   }
  412.  
  413.   return {
  414.     initialize: initialize,
  415.     startOmniboxQuery: startOmniboxQuery,
  416.     handleNewAutocompleteResult: handleNewAutocompleteResult
  417.   };
  418. });
  419.  
  420. document.addEventListener('DOMContentLoaded', omniboxDebug.initialize);
  421.