1 // Copyright 2013 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.
7 * @fileoverview Utilities for rendering most visited thumbnails and titles.
10 <include src="instant_iframe_validation.js">
13 * The different types of events that are logged from the NTP. This enum is
14 * used to transfer information from the NTP javascript to the renderer and is
15 * not used as a UMA enum histogram's logged value.
16 * Note: Keep in sync with common/ntp_logging_events.h
20 var NTP_LOGGING_EVENT_TYPE = {
21 // The suggestion is coming from the server.
22 NTP_SERVER_SIDE_SUGGESTION: 0,
23 // The suggestion is coming from the client.
24 NTP_CLIENT_SIDE_SUGGESTION: 1,
25 // Indicates a tile was rendered, no matter if it's a thumbnail, a gray tile
26 // or an external tile.
28 // The tile uses a local thumbnail image.
29 NTP_THUMBNAIL_TILE: 3,
30 // Used when no thumbnail is specified and a gray tile with the domain is used
33 // The visuals of that tile are handled externally by the page itself.
35 // There was an error in loading both the thumbnail image and the fallback
36 // (if it was provided), resulting in a grey tile.
37 NTP_THUMBNAIL_ERROR: 6,
38 // Used a gray tile with the domain as the fallback for a failed thumbnail.
39 NTP_GRAY_TILE_FALLBACK: 7,
40 // The visuals of that tile's fallback are handled externally.
41 NTP_EXTERNAL_TILE_FALLBACK: 8,
42 // The user moused over an NTP tile or title.
47 * Type of the impression provider for a generic client-provided suggestion.
51 var CLIENT_PROVIDER_NAME = 'client';
54 * Type of the impression provider for a generic server-provided suggestion.
58 var SERVER_PROVIDER_NAME = 'server';
61 * Parses query parameters from Location.
62 * @param {string} location The URL to generate the CSS url for.
63 * @return {Object} Dictionary containing name value pairs for URL.
65 function parseQueryParams(location) {
66 var params = Object.create(null);
67 var query = location.search.substring(1);
68 var vars = query.split('&');
69 for (var i = 0; i < vars.length; i++) {
70 var pair = vars[i].split('=');
71 var k = decodeURIComponent(pair[0]);
73 // Duplicate parameters are not allowed to prevent attackers who can
74 // append things to |location| from getting their parameter values to
75 // override legitimate ones.
76 return Object.create(null);
78 params[k] = decodeURIComponent(pair[1]);
86 * Creates a new most visited link element.
87 * @param {Object} params URL parameters containing styles for the link.
88 * @param {string} href The destination for the link.
89 * @param {string} title The title for the link.
90 * @param {string|undefined} text The text for the link or none.
91 * @param {string|undefined} ping If specified, a location relative to the
92 * referrer of this iframe, to ping when the link is clicked. Only works if
93 * the referrer is HTTPS.
94 * @param {string|undefined} provider A provider name (max 8 alphanumeric
95 * characters) used for logging. Undefined if suggestion is not coming from
97 * @return {HTMLAnchorElement} A new link element.
99 function createMostVisitedLink(params, href, title, text, ping, provider) {
100 var styles = getMostVisitedStyles(params, !!text);
101 var link = document.createElement('a');
102 link.style.color = styles.color;
103 link.style.fontSize = styles.fontSize + 'px';
104 if (styles.fontFamily)
105 link.style.fontFamily = styles.fontFamily;
107 if ('pos' in params && isFinite(params.pos)) {
108 link.ping = '/log.html?pos=' + params.pos;
110 link.ping += '&pr=' + provider;
111 // If a ping parameter was specified, add it to the list of pings, relative
112 // to the referrer of this iframe, which is the default search provider.
114 var parentUrl = document.createElement('a');
115 parentUrl.href = document.referrer;
116 if (parentUrl.protocol == 'https:') {
117 link.ping += ' ' + parentUrl.origin + '/' + ping;
122 link.target = '_top';
123 // Exclude links from the tab order. The tabIndex is added to the thumbnail
124 // parent container instead.
125 link.tabIndex = '-1';
127 link.textContent = text;
128 link.addEventListener('mouseover', function() {
129 var ntpApiHandle = chrome.embeddedSearch.newTabPage;
130 ntpApiHandle.logEvent(NTP_LOGGING_EVENT_TYPE.NTP_MOUSEOVER);
137 * Decodes most visited styles from URL parameters.
139 * - fs: font-size as a number in pixels.
140 * - c: A hexadecimal number interpreted as a hex color code.
141 * @param {Object.<string, string>} params URL parameters specifying style.
142 * @param {boolean} isTitle if the style is for the Most Visited Title.
143 * @return {Object} Styles suitable for CSS interpolation.
145 function getMostVisitedStyles(params, isTitle) {
151 var apiHandle = chrome.embeddedSearch.newTabPage;
152 var themeInfo = apiHandle.themeBackgroundInfo;
153 if (isTitle && themeInfo && !themeInfo.usingDefaultTheme) {
154 styles.color = convertArrayToRGBAColor(themeInfo.textColorRgba) ||
156 } else if ('c' in params) {
157 styles.color = convertToHexColor(parseInt(params.c, 16)) || styles.color;
159 if ('f' in params && /^[-0-9a-zA-Z ,]+$/.test(params.f))
160 styles.fontFamily = params.f;
161 if ('fs' in params && isFinite(parseInt(params.fs, 10)))
162 styles.fontSize = parseInt(params.fs, 10);
168 * @param {string} location A location containing URL parameters.
169 * @param {function(Object, Object)} fill A function called with styles and
172 function fillMostVisited(location, fill) {
173 var params = parseQueryParams(document.location);
174 params.rid = parseInt(params.rid, 10);
175 if (!isFinite(params.rid) && !params.url)
177 // Log whether the suggestion was obtained from the server or the client.
178 chrome.embeddedSearch.newTabPage.logEvent(params.url ?
179 NTP_LOGGING_EVENT_TYPE.NTP_SERVER_SIDE_SUGGESTION :
180 NTP_LOGGING_EVENT_TYPE.NTP_CLIENT_SIDE_SUGGESTION);
183 // Means that the suggestion data comes from the server. Create data object.
184 data.url = params.url;
185 data.thumbnailUrl = params.tu || '';
186 data.title = params.ti || '';
187 data.direction = params.di || '';
188 data.domain = params.dom || '';
189 data.ping = params.ping || '';
190 data.provider = params.pr || SERVER_PROVIDER_NAME;
192 // Log the fact that suggestion was obtained from the server.
193 var ntpApiHandle = chrome.embeddedSearch.newTabPage;
194 ntpApiHandle.logEvent(NTP_LOGGING_EVENT_TYPE.NTP_SERVER_SIDE_SUGGESTION);
196 var apiHandle = chrome.embeddedSearch.searchBox;
197 data = apiHandle.getMostVisitedItemData(params.rid);
200 data.provider = CLIENT_PROVIDER_NAME;
203 if (/^javascript:/i.test(data.url) ||
204 /^javascript:/i.test(data.thumbnailUrl) ||
205 !/^[a-z0-9]{0,8}$/i.test(data.provider))
208 document.body.dir = data.direction;