OLD | NEW |
| (Empty) |
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 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'; | |
15 | |
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 } | |
24 | |
25 /** | |
26 * Called when the 'Refresh' button is clicked. Reloads the suggestions data. | |
27 */ | |
28 function onRefreshClicked(event) { | |
29 refresh(); | |
30 event.preventDefault(); | |
31 } | |
32 | |
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 } | |
41 | |
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 ]; | |
50 | |
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 ]; | |
63 | |
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 } | |
73 | |
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 }); | |
96 | |
97 // Remove columns that we don't want to display. | |
98 columns = columns.filter(function(column) { | |
99 return IGNORED_COLUMNS.indexOf(column) < 0; | |
100 }); | |
101 | |
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 } | |
108 | |
109 // Special columns. | |
110 columns.unshift('favicon'); | |
111 columns.unshift('screenshot'); | |
112 columns.unshift('rank'); | |
113 | |
114 // Erase whatever is currently being displayed. | |
115 var output = $('suggestions-debug-text'); | |
116 output.innerHTML = ''; | |
117 | |
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); | |
128 | |
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 }); | |
176 | |
177 output.appendChild(table); | |
178 } | |
179 | |
180 return { | |
181 initialize: initialize, | |
182 setSuggestions: setSuggestions | |
183 }; | |
184 }); | |
185 | |
186 document.addEventListener('DOMContentLoaded', suggestionsInternals.initialize); | |
OLD | NEW |