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.
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.
13 cr
.define('suggestionsInternals', function() {
17 * Register our event handlers.
19 function initialize() {
20 $('suggestions-form').addEventListener('submit', onRefreshClicked
);
21 $('show-discarded').addEventListener('change', refresh
);
26 * Called when the 'Refresh' button is clicked. Reloads the suggestions data.
28 function onRefreshClicked(event
) {
30 event
.preventDefault();
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.
39 chrome
.send('getSuggestions');
43 * A list of columns that we do not want to display.
44 * @type {Array<string>}
47 var IGNORED_COLUMNS
= [
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
55 * @type {Array<string>}
58 var PREFERRED_COLUMN_ORDER
= [
64 function setBooleanColumn(column
, value
) {
66 column
.innerText
= 'Y';
67 column
.classList
.add('boolean-property-true');
69 column
.innerText
= 'N';
70 column
.classList
.add('boolean-property-false');
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.
79 function setSuggestions(list
) {
80 // Build a list of all the columns that will be displayed.
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)
91 } else if (columns
.indexOf(column
) < 0) {
97 // Remove columns that we don't want to display.
98 columns
= columns
.filter(function(column
) {
99 return IGNORED_COLUMNS
.indexOf(column
) < 0;
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
]);
106 columns
.unshift(columns
.splice(index
, 1)[0]);
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
);
127 table
.appendChild(header
);
129 // Add all the suggestions to the table.
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('.');
138 for (var i
= 0; i
< path
.length
; ++i
) {
139 if (data
&& data
.hasOwnProperty(path
[i
]))
140 data
= data
[path
[i
]];
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');
153 anchor
.innerText
= data
;
154 column
.appendChild(anchor
);
156 column
.innerText
= data
;
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';
172 row
.appendChild(column
);
174 table
.appendChild(row
);
177 output
.appendChild(table
);
181 initialize
: initialize
,
182 setSuggestions
: setSuggestions
186 document
.addEventListener('DOMContentLoaded', suggestionsInternals
.initialize
);