Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / resources / suggestions_internals / suggestions_internals.js
blob35988303db0ea5b6c9ac4df73b8fcbfd7c8409f7
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.
5 /**
6  * Javascript for suggestions_internals.html, served from
7  * chrome://suggestions-internals/. This is used to debug suggestions ranking.
8  * When loaded, the page will show the current set of suggestions, along with a
9  * large set of information (e.g. all the signals that were taken into
10  * consideration for deciding which pages were selected to be shown to the user)
11  * that will aid in debugging and optimizing the algorithms.
12  */
13 cr.define('suggestionsInternals', function() {
14   'use strict';
16   /**
17    * Register our event handlers.
18    */
19   function initialize() {
20     $('suggestions-form').addEventListener('submit', onRefreshClicked);
21     $('show-discarded').addEventListener('change', refresh);
22     refresh();
23   }
25   /**
26    * Called when the 'Refresh' button is clicked. Reloads the suggestions data.
27    */
28   function onRefreshClicked(event) {
29     refresh();
30     event.preventDefault();
31   }
33   /**
34    * Reloads the suggestions data by sending a 'getSuggestions' message to
35    * Chrome. The C++ code is then expected to call 'setSuggestions' when there
36    * are suggestions ready.
37    */
38   function refresh() {
39     chrome.send('getSuggestions');
40   }
42   /**
43    * A list of columns that we do not want to display.
44    * @type {Array.<string>}
45    * @const
46    */
47   var IGNORED_COLUMNS = [
48     'direction'
49   ];
51   /**
52    * A list specifying the name of the first columns to be displayed. If
53    * present, they will be displayed in this order, followed by the remaining
54    * columns.
55    * @type {Array.<string>}
56    * @const
57    */
58   var PREFERRED_COLUMN_ORDER = [
59     'title',
60     'url',
61     'score'
62   ];
64   function setBooleanColumn(column, value) {
65     if (value) {
66       column.innerText = 'Y';
67       column.classList.add('boolean-property-true');
68     } else {
69       column.innerText = 'N';
70       column.classList.add('boolean-property-false');
71     }
72   }
74   /**
75    * Called by Chrome code, with a ranked list of suggestions. The columns
76    * to be displayed are calculated automatically from the properties of the
77    * elements in the list, such that all properties have a column.
78    */
79   function setSuggestions(list) {
80     // Build a list of all the columns that will be displayed.
81     var columns = [];
82     list.forEach(function(entry) {
83       for (var column in entry) {
84         if (typeof entry[column] == 'object') {
85           // Expand one level deep
86           for (var subColumn in entry[column]) {
87             var path = column + '.' + subColumn;
88             if (columns.indexOf(path) < 0)
89               columns.push(path);
90           }
91         } else if (columns.indexOf(column) < 0) {
92           columns.push(column);
93         }
94       }
95     });
97     // Remove columns that we don't want to display.
98     columns = columns.filter(function(column) {
99       return IGNORED_COLUMNS.indexOf(column) < 0;
100     });
102     // Move the preferred columns to the start of the column list.
103     for (var i = PREFERRED_COLUMN_ORDER.length - 1; i >= 0; i--) {
104       var index = columns.indexOf(PREFERRED_COLUMN_ORDER[i]);
105       if (index >= 0)
106         columns.unshift(columns.splice(index, 1)[0]);
107     }
109     // Special columns.
110     columns.unshift('favicon');
111     columns.unshift('screenshot');
112     columns.unshift('rank');
114     // Erase whatever is currently being displayed.
115     var output = $('suggestions-debug-text');
116     output.innerHTML = '';
118     // Create the container table and add the header row.
119     var table = document.createElement('table');
120     table.className = 'suggestions-debug-table';
121     var header = document.createElement('tr');
122     columns.forEach(function(entry) {
123       var column = document.createElement('th');
124       column.innerText = entry;
125       header.appendChild(column);
126     });
127     table.appendChild(header);
129     // Add all the suggestions to the table.
130     var rank = 1;
131     list.forEach(function(entry) {
132       var row = document.createElement('tr');
133       columns.forEach(function(columnName) {
134         var column = document.createElement('td');
135         // Expand the path and find the data if it's there.
136         var path = columnName.split('.');
137         var data = entry;
138         for (var i = 0; i < path.length; ++i) {
139           if (data && data.hasOwnProperty(path[i]))
140             data = data[path[i]];
141           else
142             data = undefined;
143         }
144         // Only add the column if the current suggestion has this property
145         // (otherwise, leave the cell empty).
146         if (typeof(data) != 'undefined') {
147           if (typeof(data) == 'boolean') {
148             setBooleanColumn(column, data);
149           } else if (/^https?:\/\/.+$/.test(data)) {
150             // If the text is a URL, make it an anchor element.
151             var anchor = document.createElement('a');
152             anchor.href = data;
153             anchor.innerText = data;
154             column.appendChild(anchor);
155           } else {
156             column.innerText = data;
157           }
158         } else if (columnName == 'rank') {
159           column.innerText = rank++;
160         } else if (columnName == 'screenshot') {
161           var thumbnailUrl = 'chrome://thumb/' + entry.url;
162           var img = document.createElement('img');
163           img.onload = function() { setBooleanColumn(column, true); }
164           img.onerror = function() { setBooleanColumn(column, false); }
165           img.src = thumbnailUrl;
166         } else if (columnName == 'favicon') {
167           var faviconUrl = 'chrome://favicon/size/16@1x/' + entry.url;
168           column.style.backgroundImage = url(faviconUrl);
169           column.style.backgroundRepeat = 'no-repeat';
170           column.style.backgroundPosition = 'center center';
171         }
172         row.appendChild(column);
173       });
174       table.appendChild(row);
175     });
177     output.appendChild(table);
178   }
180   return {
181     initialize: initialize,
182     setSuggestions: setSuggestions
183   };
186 document.addEventListener('DOMContentLoaded', suggestionsInternals.initialize);