OLD | NEW |
1 /* Copyright 2015 The Chromium Authors. All rights reserved. | 1 /* Copyright 2015 The Chromium Authors. All rights reserved. |
2 * Use of this source code is governed by a BSD-style license that can be | 2 * Use of this source code is governed by a BSD-style license that can be |
3 * found in the LICENSE file. */ | 3 * found in the LICENSE file. */ |
4 | 4 |
5 // Single iframe for NTP tiles. | 5 // Single iframe for NTP tiles. |
6 (function() { | 6 (function() { |
7 'use strict'; | 7 'use strict'; |
8 | 8 |
9 | 9 |
10 /** | 10 /** |
11 * The different types of events that are logged from the NTP. This enum is | 11 * The different types of events that are logged from the NTP. This enum is |
12 * used to transfer information from the NTP JavaScript to the renderer and is | 12 * used to transfer information from the NTP JavaScript to the renderer and is |
13 * not used as a UMA enum histogram's logged value. | 13 * not used as a UMA enum histogram's logged value. |
14 * Note: Keep in sync with common/ntp_logging_events.h | 14 * Note: Keep in sync with common/ntp_logging_events.h |
15 * @enum {number} | 15 * @enum {number} |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 chrome.embeddedSearch.newTabPage.logEvent(eventType); | 110 chrome.embeddedSearch.newTabPage.logEvent(eventType); |
111 }; | 111 }; |
112 | 112 |
113 /** | 113 /** |
114 * Log impression of an NTP tile. | 114 * Log impression of an NTP tile. |
115 * @param {number} tileIndex Position of the tile, >= 0 and < NUMBER_OF_TILES. | 115 * @param {number} tileIndex Position of the tile, >= 0 and < NUMBER_OF_TILES. |
116 * @param {number} tileSource The source from TileSource. | 116 * @param {number} tileSource The source from TileSource. |
117 * @param {number} tileType The type from TileVisualType. | 117 * @param {number} tileType The type from TileVisualType. |
118 */ | 118 */ |
119 function logMostVisitedImpression(tileIndex, tileSource, tileType) { | 119 function logMostVisitedImpression(tileIndex, tileSource, tileType) { |
120 chrome.embeddedSearch.newTabPage.logMostVisitedImpression(tileIndex, | 120 chrome.embeddedSearch.newTabPage.logMostVisitedImpression( |
121 tileSource, | 121 tileIndex, tileSource, tileType); |
122 tileType); | |
123 } | 122 } |
124 | 123 |
125 /** | 124 /** |
126 * Log click on an NTP tile. | 125 * Log click on an NTP tile. |
127 * @param {number} tileIndex Position of the tile, >= 0 and < NUMBER_OF_TILES. | 126 * @param {number} tileIndex Position of the tile, >= 0 and < NUMBER_OF_TILES. |
128 * @param {number} tileSource The source from TileSource. | 127 * @param {number} tileSource The source from TileSource. |
129 * @param {number} tileType The type from TileVisualType. | 128 * @param {number} tileType The type from TileVisualType. |
130 */ | 129 */ |
131 function logMostVisitedNavigation(tileIndex, tileSource, tileType) { | 130 function logMostVisitedNavigation(tileIndex, tileSource, tileType) { |
132 chrome.embeddedSearch.newTabPage.logMostVisitedNavigation(tileIndex, | 131 chrome.embeddedSearch.newTabPage.logMostVisitedNavigation( |
133 tileSource, | 132 tileIndex, tileSource, tileType); |
134 tileType); | |
135 } | 133 } |
136 | 134 |
137 /** | 135 /** |
138 * Down counts the DOM elements that we are waiting for the page to load. | 136 * Down counts the DOM elements that we are waiting for the page to load. |
139 * When we get to 0, we send a message to the parent window. | 137 * When we get to 0, we send a message to the parent window. |
140 * This is usually used as an EventListener of onload/onerror. | 138 * This is usually used as an EventListener of onload/onerror. |
141 */ | 139 */ |
142 var countLoad = function() { | 140 var countLoad = function() { |
143 loadedCounter -= 1; | 141 loadedCounter -= 1; |
144 if (loadedCounter <= 0) { | 142 if (loadedCounter <= 0) { |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 | 198 |
201 | 199 |
202 /** | 200 /** |
203 * Handler for the 'updateTheme' message from the host page. | 201 * Handler for the 'updateTheme' message from the host page. |
204 * @param {object} info Data received in the message. | 202 * @param {object} info Data received in the message. |
205 */ | 203 */ |
206 var updateTheme = function(info) { | 204 var updateTheme = function(info) { |
207 var themeStyle = []; | 205 var themeStyle = []; |
208 | 206 |
209 if (info.tileBorderColor) { | 207 if (info.tileBorderColor) { |
210 themeStyle.push('.mv-tile {' + | 208 themeStyle.push( |
| 209 '.mv-tile {' + |
211 'border: 1px solid ' + info.tileBorderColor + '; }'); | 210 'border: 1px solid ' + info.tileBorderColor + '; }'); |
212 } | 211 } |
213 if (info.tileHoverBorderColor) { | 212 if (info.tileHoverBorderColor) { |
214 themeStyle.push('.mv-tile:hover {' + | 213 themeStyle.push( |
| 214 '.mv-tile:hover {' + |
215 'border-color: ' + info.tileHoverBorderColor + '; }'); | 215 'border-color: ' + info.tileHoverBorderColor + '; }'); |
216 } | 216 } |
217 if (info.isThemeDark) { | 217 if (info.isThemeDark) { |
218 themeStyle.push('.mv-tile, .mv-empty-tile { ' + | 218 themeStyle.push( |
| 219 '.mv-tile, .mv-empty-tile { ' + |
219 'background: rgb(51,51,51); }'); | 220 'background: rgb(51,51,51); }'); |
220 themeStyle.push('.mv-thumb.failed-img { ' + | 221 themeStyle.push( |
| 222 '.mv-thumb.failed-img { ' + |
221 'background-color: #555; }'); | 223 'background-color: #555; }'); |
222 themeStyle.push('.mv-thumb.failed-img::after { ' + | 224 themeStyle.push( |
| 225 '.mv-thumb.failed-img::after { ' + |
223 'border-color: #333; }'); | 226 'border-color: #333; }'); |
224 themeStyle.push('.mv-x { ' + | 227 themeStyle.push( |
| 228 '.mv-x { ' + |
225 'background: linear-gradient(to left, ' + | 229 'background: linear-gradient(to left, ' + |
226 'rgb(51,51,51) 60%, transparent); }'); | 230 'rgb(51,51,51) 60%, transparent); }'); |
227 themeStyle.push('html[dir=rtl] .mv-x { ' + | 231 themeStyle.push( |
| 232 'html[dir=rtl] .mv-x { ' + |
228 'background: linear-gradient(to right, ' + | 233 'background: linear-gradient(to right, ' + |
229 'rgb(51,51,51) 60%, transparent); }'); | 234 'rgb(51,51,51) 60%, transparent); }'); |
230 themeStyle.push('.mv-x::after { ' + | 235 themeStyle.push( |
| 236 '.mv-x::after { ' + |
231 'background-color: rgba(255,255,255,0.7); }'); | 237 'background-color: rgba(255,255,255,0.7); }'); |
232 themeStyle.push('.mv-x:hover::after { ' + | 238 themeStyle.push( |
| 239 '.mv-x:hover::after { ' + |
233 'background-color: #fff; }'); | 240 'background-color: #fff; }'); |
234 themeStyle.push('.mv-x:active::after { ' + | 241 themeStyle.push( |
| 242 '.mv-x:active::after { ' + |
235 'background-color: rgba(255,255,255,0.5); }'); | 243 'background-color: rgba(255,255,255,0.5); }'); |
236 } | 244 } |
237 if (info.tileTitleColor) { | 245 if (info.tileTitleColor) { |
238 themeStyle.push('body { color: ' + info.tileTitleColor + '; }'); | 246 themeStyle.push('body { color: ' + info.tileTitleColor + '; }'); |
239 } | 247 } |
240 | 248 |
241 document.querySelector('#custom-theme').textContent = themeStyle.join('\n'); | 249 document.querySelector('#custom-theme').textContent = themeStyle.join('\n'); |
242 }; | 250 }; |
243 | 251 |
244 | 252 |
245 /** | 253 /** |
246 * Hides extra tiles that don't fit on screen. Called in response to the 'show' | 254 * Hides extra tiles that don't fit on screen. Called in response to the 'show' |
247 * and 'tilesVisible' messages from the host page. | 255 * and 'tilesVisible' messages from the host page. |
248 */ | 256 */ |
249 var hideOverflowTiles = function(data) { | 257 var hideOverflowTiles = function(data) { |
250 var tileAndEmptyTileList = document.querySelectorAll( | 258 var tileAndEmptyTileList = |
251 '#mv-tiles .mv-tile,#mv-tiles .mv-empty-tile'); | 259 document.querySelectorAll('#mv-tiles .mv-tile,#mv-tiles .mv-empty-tile'); |
252 for (var i = 0; i < tileAndEmptyTileList.length; ++i) { | 260 for (var i = 0; i < tileAndEmptyTileList.length; ++i) { |
253 tileAndEmptyTileList[i].classList.toggle('hidden', i >= data.maxVisible); | 261 tileAndEmptyTileList[i].classList.toggle('hidden', i >= data.maxVisible); |
254 } | 262 } |
255 }; | 263 }; |
256 | 264 |
257 | 265 |
258 /** | 266 /** |
259 * Removes all old instances of #mv-tiles that are pending for deletion. | 267 * Removes all old instances of #mv-tiles that are pending for deletion. |
260 */ | 268 */ |
261 var removeAllOldTiles = function() { | 269 var removeAllOldTiles = function() { |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
351 | 359 |
352 /** | 360 /** |
353 * Called when the user decided to add a tile to the blacklist. | 361 * Called when the user decided to add a tile to the blacklist. |
354 * It sets off the animation for the blacklist and sends the blacklisted id | 362 * It sets off the animation for the blacklist and sends the blacklisted id |
355 * to the host page. | 363 * to the host page. |
356 * @param {Element} tile DOM node of the tile we want to remove. | 364 * @param {Element} tile DOM node of the tile we want to remove. |
357 */ | 365 */ |
358 var blacklistTile = function(tile) { | 366 var blacklistTile = function(tile) { |
359 tile.classList.add('blacklisted'); | 367 tile.classList.add('blacklisted'); |
360 tile.addEventListener('transitionend', function(ev) { | 368 tile.addEventListener('transitionend', function(ev) { |
361 if (ev.propertyName != 'width') return; | 369 if (ev.propertyName != 'width') |
| 370 return; |
362 | 371 |
363 window.parent.postMessage({cmd: 'tileBlacklisted', | 372 window.parent.postMessage( |
364 tid: Number(tile.getAttribute('data-tid'))}, | 373 {cmd: 'tileBlacklisted', tid: Number(tile.getAttribute('data-tid'))}, |
365 DOMAIN_ORIGIN); | 374 DOMAIN_ORIGIN); |
366 }); | 375 }); |
367 }; | 376 }; |
368 | 377 |
369 | 378 |
370 /** | 379 /** |
371 * Returns whether the given URL has a known, safe scheme. | 380 * Returns whether the given URL has a known, safe scheme. |
372 * @param {string} url URL to check. | 381 * @param {string} url URL to check. |
373 */ | 382 */ |
374 var isSchemeAllowed = function(url) { | 383 var isSchemeAllowed = function(url) { |
375 return url.startsWith('http://') || url.startsWith('https://') || | 384 return url.startsWith('http://') || url.startsWith('https://') || |
376 url.startsWith('ftp://') || url.startsWith('chrome-extension://'); | 385 url.startsWith('ftp://') || url.startsWith('chrome-extension://'); |
377 }; | 386 }; |
378 | 387 |
379 | 388 |
380 /** | 389 /** |
381 * Renders a MostVisited tile to the DOM. | 390 * Renders a MostVisited tile to the DOM. |
382 * @param {object} data Object containing rid, url, title, favicon, thumbnail. | 391 * @param {object} data Object containing rid, url, title, favicon, thumbnail. |
383 * data is null if you want to construct an empty tile. | 392 * data is null if you want to construct an empty tile. |
384 */ | 393 */ |
385 var renderTile = function(data) { | 394 var renderTile = function(data) { |
386 var tile = document.createElement('a'); | 395 var tile = document.createElement('a'); |
(...skipping 27 matching lines...) Expand all Loading... |
414 tile.addEventListener('click', function(ev) { | 423 tile.addEventListener('click', function(ev) { |
415 logMostVisitedNavigation(position, data.tileSource, tileType); | 424 logMostVisitedNavigation(position, data.tileSource, tileType); |
416 }); | 425 }); |
417 | 426 |
418 tile.addEventListener('keydown', function(event) { | 427 tile.addEventListener('keydown', function(event) { |
419 if (event.keyCode == 46 /* DELETE */ || | 428 if (event.keyCode == 46 /* DELETE */ || |
420 event.keyCode == 8 /* BACKSPACE */) { | 429 event.keyCode == 8 /* BACKSPACE */) { |
421 event.preventDefault(); | 430 event.preventDefault(); |
422 event.stopPropagation(); | 431 event.stopPropagation(); |
423 blacklistTile(this); | 432 blacklistTile(this); |
424 } else if (event.keyCode == 13 /* ENTER */ || | 433 } else if ( |
425 event.keyCode == 32 /* SPACE */) { | 434 event.keyCode == 13 /* ENTER */ || event.keyCode == 32 /* SPACE */) { |
426 event.preventDefault(); | 435 event.preventDefault(); |
427 this.click(); | 436 this.click(); |
428 } else if (event.keyCode >= 37 && event.keyCode <= 40 /* ARROWS */) { | 437 } else if (event.keyCode >= 37 && event.keyCode <= 40 /* ARROWS */) { |
429 // specify the direction of movement | 438 // specify the direction of movement |
430 var inArrowDirection = function(origin, target) { | 439 var inArrowDirection = function(origin, target) { |
431 return (event.keyCode == 37 /* LEFT */ && | 440 return (event.keyCode == 37 /* LEFT */ && |
432 origin.offsetTop == target.offsetTop && | 441 origin.offsetTop == target.offsetTop && |
433 origin.offsetLeft > target.offsetLeft) || | 442 origin.offsetLeft > target.offsetLeft) || |
434 (event.keyCode == 38 /* UP */ && | 443 (event.keyCode == 38 /* UP */ && |
435 origin.offsetTop > target.offsetTop && | 444 origin.offsetTop > target.offsetTop && |
436 origin.offsetLeft == target.offsetLeft) || | 445 origin.offsetLeft == target.offsetLeft) || |
437 (event.keyCode == 39 /* RIGHT */ && | 446 (event.keyCode == 39 /* RIGHT */ && |
438 origin.offsetTop == target.offsetTop && | 447 origin.offsetTop == target.offsetTop && |
439 origin.offsetLeft < target.offsetLeft) || | 448 origin.offsetLeft < target.offsetLeft) || |
440 (event.keyCode == 40 /* DOWN */ && | 449 (event.keyCode == 40 /* DOWN */ && |
441 origin.offsetTop < target.offsetTop && | 450 origin.offsetTop < target.offsetTop && |
442 origin.offsetLeft == target.offsetLeft); | 451 origin.offsetLeft == target.offsetLeft); |
443 }; | 452 }; |
444 | 453 |
445 var nonEmptyTiles = document.querySelectorAll('#mv-tiles .mv-tile'); | 454 var nonEmptyTiles = document.querySelectorAll('#mv-tiles .mv-tile'); |
446 var nextTile = null; | 455 var nextTile = null; |
447 // Find the closest tile in the appropriate direction. | 456 // Find the closest tile in the appropriate direction. |
448 for (var i = 0; i < nonEmptyTiles.length; i++) { | 457 for (var i = 0; i < nonEmptyTiles.length; i++) { |
449 if (inArrowDirection(this, nonEmptyTiles[i]) && | 458 if (inArrowDirection(this, nonEmptyTiles[i]) && |
450 (!nextTile || inArrowDirection(nonEmptyTiles[i], nextTile))) { | 459 (!nextTile || inArrowDirection(nonEmptyTiles[i], nextTile))) { |
451 nextTile = nonEmptyTiles[i]; | 460 nextTile = nonEmptyTiles[i]; |
452 } | 461 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
526 // one-by-one via addTile, and the whole thing will be inserted into the page | 535 // one-by-one via addTile, and the whole thing will be inserted into the page |
527 // in swapInNewTiles, after the parent has sent us the 'show' message, and all | 536 // in swapInNewTiles, after the parent has sent us the 'show' message, and all |
528 // thumbnails and favicons have loaded. | 537 // thumbnails and favicons have loaded. |
529 tiles = document.createElement('div'); | 538 tiles = document.createElement('div'); |
530 | 539 |
531 // Parse query arguments. | 540 // Parse query arguments. |
532 var query = window.location.search.substring(1).split('&'); | 541 var query = window.location.search.substring(1).split('&'); |
533 queryArgs = {}; | 542 queryArgs = {}; |
534 for (var i = 0; i < query.length; ++i) { | 543 for (var i = 0; i < query.length; ++i) { |
535 var val = query[i].split('='); | 544 var val = query[i].split('='); |
536 if (val[0] == '') continue; | 545 if (val[0] == '') |
| 546 continue; |
537 queryArgs[decodeURIComponent(val[0])] = decodeURIComponent(val[1]); | 547 queryArgs[decodeURIComponent(val[0])] = decodeURIComponent(val[1]); |
538 } | 548 } |
539 | 549 |
540 if ('ntl' in queryArgs) { | 550 if ('ntl' in queryArgs) { |
541 var ntl = parseInt(queryArgs['ntl'], 10); | 551 var ntl = parseInt(queryArgs['ntl'], 10); |
542 if (isFinite(ntl)) | 552 if (isFinite(ntl)) |
543 NUM_TITLE_LINES = ntl; | 553 NUM_TITLE_LINES = ntl; |
544 } | 554 } |
545 | 555 |
546 // Enable RTL. | 556 // Enable RTL. |
547 if (queryArgs['rtl'] == '1') { | 557 if (queryArgs['rtl'] == '1') { |
548 var html = document.querySelector('html'); | 558 var html = document.querySelector('html'); |
549 html.dir = 'rtl'; | 559 html.dir = 'rtl'; |
550 } | 560 } |
551 | 561 |
552 window.addEventListener('message', handlePostMessage); | 562 window.addEventListener('message', handlePostMessage); |
553 }; | 563 }; |
554 | 564 |
555 | 565 |
556 window.addEventListener('DOMContentLoaded', init); | 566 window.addEventListener('DOMContentLoaded', init); |
557 })(); | 567 })(); |
OLD | NEW |