Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 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. | |
|
Dan Beam
2013/03/22 19:32:50
can you add a namespace here? this shouldn't all
jeremycho
2013/03/22 21:33:30
Done.
| |
| 4 | |
| 5 /** | |
| 6 * The element used to vertically position the most visited section on | |
| 7 * window resize. | |
| 8 * @type {Element} | |
| 9 */ | |
| 10 var topMarginElement; | |
| 11 | |
| 12 /** | |
| 13 * The container for the tile elements. | |
| 14 * @type {Element} | |
| 15 */ | |
| 16 var tilesContainer; | |
| 17 | |
| 18 /** | |
| 19 * The notification displayed when a page is blacklisted. | |
| 20 * @type {Element} | |
| 21 */ | |
| 22 var notification; | |
| 23 | |
| 24 /** | |
| 25 * The handle for the timer used to hide the notification. | |
| 26 * @type {?number} | |
| 27 */ | |
| 28 var notificationTimer = null; | |
| 29 | |
| 30 /** | |
| 31 * The array of rendered tiles, ordered by appearance. | |
| 32 * @type {Array.<Tile>} | |
| 33 */ | |
| 34 var tiles = []; | |
| 35 | |
| 36 /** | |
| 37 * The last blacklisted tile if any, which by definition should not be filler. | |
| 38 * @type {?Tile} | |
| 39 */ | |
| 40 var lastBlacklistedTile = null; | |
| 41 | |
| 42 /** | |
| 43 * The index of the last blacklisted tile, if any. Used to determine where to | |
| 44 * re-insert a tile on undo. | |
| 45 * @type {number} | |
| 46 */ | |
| 47 var lastBlacklistedIndex = -1; | |
| 48 | |
| 49 /** | |
| 50 * True if a page has been blacklisted and we're waiting on the | |
| 51 * onmostvisitedchange callback. See onMostVisitedChange() for how this | |
| 52 * is used. | |
| 53 * @type {boolean} | |
| 54 */ | |
| 55 var isBlacklisting = false; | |
| 56 | |
| 57 /** | |
| 58 * True if a blacklist has been undone and we're waiting on the | |
| 59 * onmostvisitedchange callback. See onMostVisitedChange() for how this | |
| 60 * is used. | |
| 61 * @type {boolean} | |
| 62 */ | |
| 63 var isUndoing = false; | |
| 64 | |
| 65 /** | |
| 66 * Current number of tiles shown based on the window width, including filler. | |
| 67 * @type {number} | |
| 68 */ | |
| 69 var numTilesShown = 0; | |
| 70 | |
| 71 /** | |
| 72 * The browser embeddedSearch.newTabPage object. | |
| 73 * @type {Object} | |
| 74 */ | |
| 75 var apiHandle; | |
| 76 | |
| 77 /** | |
| 78 * Possible background-colors of a non-custom theme. Used to determine whether | |
| 79 * the homepage should be updated to support custom or non-custom themes. | |
| 80 * @type {Array.<string>} | |
|
Dan Beam
2013/03/22 19:32:50
nit: !Array
jeremycho
2013/03/22 21:33:30
Done.
| |
| 81 * @const | |
| 82 */ | |
| 83 var WHITE = ['rgba(255,255,255,1)', 'rgba(0,0,0,0)']; | |
| 84 | |
| 85 /** | |
| 86 * Should be equal to mv-tile's -webkit-margin-start + width. | |
| 87 * @type {number} | |
| 88 * @const | |
| 89 */ | |
| 90 var TILE_WIDTH = 160; | |
| 91 | |
| 92 /** | |
| 93 * The height of the most visited section. | |
| 94 * @type {number} | |
| 95 * @const | |
| 96 */ | |
| 97 var MOST_VISITED_HEIGHT = 156; | |
| 98 | |
| 99 /** @type {number} @const */ | |
| 100 var MAX_NUM_TILES_TO_SHOW = 4; | |
| 101 | |
| 102 /** @type {number} @const */ | |
| 103 var MIN_NUM_TILES_TO_SHOW = 2; | |
| 104 | |
| 105 /** | |
| 106 * Minimum total padding to give to the left and right of the most visited | |
| 107 * section. Used to determine how many tiles to show. | |
| 108 * @type {number} | |
| 109 * @const | |
| 110 */ | |
| 111 var MIN_TOTAL_HORIZONTAL_PADDING = 188; | |
| 112 | |
| 113 /** | |
| 114 * Enum for classnames. | |
| 115 * @enum {string} | |
| 116 * @const | |
| 117 */ | |
| 118 var CLASSES = { | |
| 119 TOP_MARGIN: 'mv-top-margin', | |
| 120 TILES: 'mv-tiles', | |
| 121 TILE: 'mv-tile', | |
| 122 PAGE: 'mv-page', // page tiles | |
| 123 TITLE: 'mv-title', | |
| 124 THUMBNAIL: 'mv-thumb', | |
| 125 DOMAIN: 'mv-domain', | |
| 126 BLACKLIST_BUTTON: 'mv-x', | |
| 127 FAVICON: 'mv-favicon', | |
| 128 FILLER: 'mv-filler', // filler tiles | |
| 129 NOTIFICATION: 'mv-notice', | |
| 130 BLACKLIST: 'mv-blacklist', // triggers tile blacklist animation | |
| 131 HIDE_TILE: 'mv-tile-hide', // hides tiles on small browser width | |
| 132 HIDE_BLACKLIST_BUTTON: 'mv-x-hide', // hides blacklist button during animation | |
| 133 HIDE_NOTIFICATION: 'mv-notice-hide' | |
|
Dan Beam
2013/03/22 19:32:50
nit: alpha
jeremycho
2013/03/22 21:33:30
Sorry, not sure what you mean.
| |
| 134 }; | |
| 135 | |
| 136 /** | |
| 137 * Time (in milliseconds) to show the notification. | |
| 138 * @type {number} | |
| 139 * @const | |
| 140 */ | |
| 141 var NOTIFICATION_TIMEOUT = 10000; | |
| 142 | |
| 143 /** | |
| 144 * A Tile is either a rendering of a Most Visited page or "filler" used to | |
| 145 * pad out the section when not enough pages exist. | |
| 146 * | |
| 147 * @param {Element} elem The element for rendering the tile. | |
| 148 * @param {number=} opt_rid The RID for the corresponding Most Visited page. | |
| 149 * Should only be left unspecified when creating a filler tile. | |
| 150 * @constructor | |
| 151 */ | |
| 152 function Tile(elem, opt_rid) { | |
| 153 /** @type {Element} */ | |
| 154 this.elem = elem; | |
| 155 | |
| 156 /** @type {number|undefined} */ | |
| 157 this.rid = opt_rid; | |
| 158 } | |
| 159 | |
| 160 /** | |
| 161 * Updates the NTP based on the current theme. | |
| 162 * @private | |
| 163 */ | |
| 164 function onThemeChange() { | |
| 165 var info = apiHandle.themeBackgroundInfo; | |
| 166 if (!info) | |
| 167 return; | |
| 168 var background = [info.colorRgba, | |
| 169 info.imageUrl, | |
| 170 info.imageTiling, | |
| 171 info.imageHorizontalAlignment, | |
| 172 info.imageVerticalAlignment].join(' ').trim(); | |
| 173 document.body.style.background = background; | |
| 174 var isCustom = !!background && WHITE.indexOf(background) == -1; | |
| 175 enable(document.body, 'custom-theme', isCustom); | |
| 176 } | |
| 177 | |
| 178 /** | |
| 179 * Handles a new set of Most Visited page data. | |
| 180 */ | |
| 181 function onMostVisitedChange() { | |
| 182 var pages = apiHandle.mostVisited; | |
| 183 | |
| 184 // If this was called as a result of a blacklist, add a new replacement | |
| 185 // (possibly filler) tile at the end and trigger the blacklist animation. | |
| 186 if (isBlacklisting) { | |
| 187 var replacementTile = createTile(pages[MAX_NUM_TILES_TO_SHOW - 1]); | |
| 188 | |
| 189 tiles.push(replacementTile); | |
| 190 tilesContainer.appendChild(replacementTile.elem); | |
| 191 | |
| 192 var lastBlacklistedTileElement = lastBlacklistedTile.elem; | |
| 193 lastBlacklistedTileElement.addEventListener( | |
| 194 'webkitTransitionEnd', blacklistAnimationDone); | |
| 195 lastBlacklistedTileElement.classList.add(CLASSES.BLACKLIST); | |
| 196 // In order to animate the replacement tile sliding into place, it must | |
| 197 // be made visible. | |
| 198 updateTileVisibility(numTilesShown + 1); | |
| 199 | |
| 200 // If this was called as a result of an undo, re-insert the last blacklisted | |
| 201 // tile in its old location and trigger the undo animation. | |
|
Dan Beam
2013/03/22 19:32:50
^ indent off
jeremycho
2013/03/22 21:33:30
Done.
jeremycho
2013/03/22 21:33:30
Done.
| |
| 202 } else if (isUndoing) { | |
| 203 tiles.splice( | |
| 204 lastBlacklistedIndex, 0, lastBlacklistedTile); | |
| 205 var lastBlacklistedTileElement = lastBlacklistedTile.elem; | |
| 206 tilesContainer.insertBefore( | |
| 207 lastBlacklistedTileElement, | |
| 208 tilesContainer.childNodes[lastBlacklistedIndex]); | |
| 209 lastBlacklistedTileElement.addEventListener( | |
| 210 'webkitTransitionEnd', undoAnimationDone); | |
| 211 // Yield to ensure the tile is added to the DOM before removing the class. | |
| 212 // Without this, the webkit transition doesn't reliably trigger. | |
| 213 window.setTimeout(function() { | |
| 214 lastBlacklistedTileElement.classList.remove(CLASSES.BLACKLIST); | |
|
Dan Beam
2013/03/22 19:32:50
just putting
lastBlacklistedTileElement.scrollT
jeremycho
2013/03/22 21:33:30
Neat! Done.
| |
| 215 }, 0); | |
| 216 // Otherwise render the tiles using the new data without animation. | |
| 217 } else { | |
| 218 tiles = []; | |
| 219 for (var i = 0; i < MAX_NUM_TILES_TO_SHOW; ++i) { | |
| 220 tiles.push(createTile(pages[i])); | |
| 221 } | |
| 222 renderTiles(); | |
| 223 } | |
| 224 } | |
| 225 | |
| 226 /** | |
| 227 * Renders the current set of tiles without animation. | |
| 228 */ | |
| 229 function renderTiles() { | |
| 230 removeChildren(tilesContainer); | |
| 231 for (var i = 0, length = tiles.length; i < length; ++i) { | |
| 232 tilesContainer.appendChild(tiles[i].elem); | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 /** | |
| 237 * Creates a Tile with the specified page data. If no data is provided, a | |
| 238 * filler Tile is created. | |
| 239 * @param {Object} page The page data. | |
| 240 * @return {Tile} The new Tile_. | |
|
Dan Beam
2013/03/22 19:32:50
why Tile_?
jeremycho
2013/03/22 21:33:30
Done.
| |
| 241 */ | |
| 242 function createTile(page) { | |
| 243 var tileElement = document.createElement('div'); | |
| 244 tileElement.classList.add(CLASSES.TILE); | |
| 245 | |
| 246 if (page) { | |
| 247 var rid = page.rid; | |
| 248 tileElement.classList.add(CLASSES.PAGE); | |
| 249 | |
| 250 // The click handler for navigating to the page identified by the RID. | |
| 251 tileElement.addEventListener('click', function() { | |
| 252 apiHandle.navigateContentWindow(rid); | |
| 253 }); | |
| 254 | |
| 255 // The shadow DOM which renders the page title. | |
| 256 var titleElement = page.titleElement; | |
| 257 if (titleElement) { | |
| 258 titleElement.classList.add(CLASSES.TITLE); | |
| 259 tileElement.appendChild(titleElement); | |
| 260 } | |
| 261 | |
| 262 // Render the thumbnail if present. Otherwise, fall back to a shadow DOM | |
| 263 // which renders the domain. | |
| 264 var thumbnailUrl = page.thumbnailUrl; | |
| 265 | |
| 266 var showDomainElement = function() { | |
| 267 var domainElement = page.domainElement; | |
| 268 if (domainElement) { | |
| 269 domainElement.classList.add(CLASSES.DOMAIN); | |
| 270 tileElement.appendChild(domainElement); | |
| 271 } | |
| 272 }; | |
| 273 if (thumbnailUrl) { | |
| 274 var image = new Image(); | |
| 275 image.onload = function() { | |
| 276 var thumbnailElement = createAndAppendElement( | |
| 277 tileElement, 'div', CLASSES.THUMBNAIL); | |
| 278 thumbnailElement.style['background-image'] = | |
|
Dan Beam
2013/03/22 19:32:50
thumbnailElement.style.backgroundImage =
jeremycho
2013/03/22 21:33:30
Done.
| |
| 279 'url(' + thumbnailUrl + ')'; | |
| 280 }; | |
| 281 | |
| 282 image.onerror = showDomainElement; | |
| 283 image.src = thumbnailUrl; | |
| 284 } else { | |
| 285 showDomainElement(); | |
| 286 } | |
| 287 | |
| 288 // The button used to blacklist this page. | |
| 289 var blacklistButton = createAndAppendElement( | |
| 290 tileElement, 'div', CLASSES.BLACKLIST_BUTTON); | |
| 291 blacklistButton.addEventListener('click', generateBlacklistFunction(rid)); | |
| 292 // TODO(jeremycho): i18n. | |
| 293 blacklistButton.title = "Don't show on this page"; | |
|
Dan Beam
2013/03/22 19:32:50
^ when will this happen?
jeremycho
2013/03/22 21:33:30
Added the tracking bug.
| |
| 294 | |
| 295 // The page favicon, if any. | |
| 296 var faviconUrl = page.faviconUrl; | |
| 297 if (faviconUrl) { | |
| 298 var favicon = createAndAppendElement( | |
| 299 tileElement, 'div', CLASSES.FAVICON); | |
| 300 favicon.style['background-image'] = 'url(' + faviconUrl + ')'; | |
| 301 } | |
| 302 return new Tile(tileElement, rid); | |
| 303 } else { | |
| 304 tileElement.classList.add(CLASSES.FILLER); | |
| 305 return new Tile(tileElement); | |
| 306 } | |
| 307 } | |
| 308 | |
| 309 /** | |
| 310 * Generates a function to be called when the page with the corresponding RID | |
| 311 * is blacklisted. | |
| 312 * @param {number} rid The RID of the page being blacklisted. | |
| 313 * @return {function(Event)} A function which handles the blacklisting of the | |
| 314 * page by displaying the notification, updating state variables, and | |
| 315 * notifying Chrome. | |
| 316 */ | |
| 317 function generateBlacklistFunction(rid) { | |
| 318 return function(e) { | |
| 319 // Prevent navigation when the page is being blacklisted. | |
| 320 e.stopPropagation(); | |
| 321 | |
| 322 showNotification(); | |
| 323 isBlacklisting = true; | |
| 324 tilesContainer.classList.add(CLASSES.HIDE_BLACKLIST_BUTTON); | |
| 325 lastBlacklistedTile = getTileByRid(rid); | |
| 326 lastBlacklistedIndex = tiles.indexOf(lastBlacklistedTile); | |
| 327 apiHandle.deleteMostVisitedItem(rid); | |
| 328 }; | |
| 329 } | |
| 330 | |
| 331 /** | |
| 332 * Shows the blacklist notification and refreshes the timer to hide it. | |
| 333 */ | |
| 334 function showNotification() { | |
| 335 notification.classList.remove(CLASSES.HIDE_NOTIFICATION); | |
| 336 if (notificationTimer) | |
| 337 window.clearTimeout(notificationTimer); | |
| 338 notificationTimer = window.setTimeout( | |
| 339 hideNotification, NOTIFICATION_TIMEOUT); | |
| 340 } | |
| 341 | |
|
Dan Beam
2013/03/22 19:32:50
\n\n or \n between methods -- be consistent (closu
jeremycho
2013/03/22 21:33:30
Done.
| |
| 342 | |
| 343 /** | |
| 344 * Hides the blacklist notification. | |
| 345 */ | |
| 346 function hideNotification() { | |
| 347 notification.classList.add(CLASSES.HIDE_NOTIFICATION); | |
| 348 } | |
| 349 | |
| 350 /** | |
| 351 * Handles the end of the blacklist animation by removing the blacklisted tile. | |
| 352 */ | |
| 353 function blacklistAnimationDone() { | |
| 354 tiles.splice(lastBlacklistedIndex, 1); | |
| 355 removeNode(lastBlacklistedTile.elem); | |
| 356 updateTileVisibility(numTilesShown); | |
| 357 isBlacklisting = false; | |
| 358 tilesContainer.classList.remove(CLASSES.HIDE_BLACKLIST_BUTTON); | |
| 359 lastBlacklistedTile.elem.removeEventListener( | |
| 360 'webkitTransitionEnd', blacklistAnimationDone); | |
| 361 } | |
| 362 | |
| 363 /** | |
| 364 * Handles a click on the notification undo link by hiding the notification and | |
| 365 * informing Chrome. | |
| 366 */ | |
| 367 function onUndo() { | |
| 368 hideNotification(); | |
| 369 var lastBlacklistedRID = lastBlacklistedTile.rid; | |
| 370 if (lastBlacklistedRID != null) { | |
|
Dan Beam
2013/03/22 19:32:50
can rid ever be 0? if not, then just
if (lastB
jeremycho
2013/03/22 21:33:30
Using undefined just to be safe.
On 2013/03/22 19
| |
| 371 isUndoing = true; | |
| 372 apiHandle.undoMostVisitedDeletion(lastBlacklistedRID); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 /** | |
| 377 * Handles the end of the undo animation by removing the extraneous end tile. | |
| 378 */ | |
| 379 function undoAnimationDone() { | |
| 380 isUndoing = false; | |
| 381 tiles.splice(tiles.length - 1, 1); | |
| 382 removeNode(tilesContainer.lastElementChild); | |
| 383 updateTileVisibility(numTilesShown); | |
| 384 lastBlacklistedTile.elem.removeEventListener( | |
| 385 'webkitTransitionEnd', undoAnimationDone); | |
| 386 } | |
| 387 | |
| 388 /** | |
| 389 * Handles a click on the restore all notification link by hiding the | |
| 390 * notification and informing Chrome. | |
| 391 */ | |
| 392 function onRestoreAll() { | |
| 393 hideNotification(); | |
| 394 apiHandle.undoAllMostVisitedDeletions(); | |
| 395 } | |
| 396 | |
| 397 /** | |
| 398 * Handles a resize by vertically centering the most visited section | |
| 399 * and triggering the tile show/hide animation if necessary. | |
| 400 */ | |
| 401 function onResize() { | |
| 402 var clientHeight = document.documentElement.clientHeight; | |
| 403 topMarginElement.style['margin-top'] = | |
|
Dan Beam
2013/03/22 19:32:50
topMarginElement.style.marginTop
jeremycho
2013/03/22 21:33:30
Done.
| |
| 404 Math.max(0, (clientHeight - MOST_VISITED_HEIGHT) / 2) + 'px'; | |
| 405 | |
| 406 var clientWidth = document.documentElement.clientWidth; | |
| 407 var numTilesToShow = Math.floor( | |
| 408 (clientWidth - MIN_TOTAL_HORIZONTAL_PADDING) / TILE_WIDTH); | |
| 409 numTilesToShow = Math.max(MIN_NUM_TILES_TO_SHOW, numTilesToShow); | |
| 410 if (numTilesToShow != numTilesShown) { | |
| 411 updateTileVisibility(numTilesToShow); | |
| 412 numTilesShown = numTilesToShow; | |
| 413 } | |
| 414 } | |
| 415 | |
|
Dan Beam
2013/03/22 19:32:50
\n\n or \n
jeremycho
2013/03/22 21:33:30
Done.
| |
| 416 | |
| 417 /** | |
| 418 * Triggers an animation to show the first numTilesToShow tiles and hide the | |
| 419 * remaining. | |
| 420 * @param {number} numTilesToShow The number of tiles to show. | |
| 421 */ | |
| 422 function updateTileVisibility(numTilesToShow) { | |
| 423 for (var i = 0, length = tiles.length; i < length; ++i) { | |
| 424 enable(tiles[i].elem, CLASSES.HIDE_TILE, i >= numTilesToShow); | |
| 425 } | |
| 426 } | |
| 427 | |
| 428 /** | |
| 429 * Returns the tile corresponding to the specified page RID. | |
| 430 * @param {number} rid The page RID being looked up. | |
| 431 * @return {Tile} The corresponding tile. | |
| 432 */ | |
| 433 function getTileByRid(rid) { | |
| 434 for (var i = 0, length = tiles.length; i < length; ++i) { | |
| 435 var tile = tiles[i]; | |
| 436 if (tile.rid == rid) | |
| 437 return tile; | |
| 438 } | |
| 439 return null; | |
| 440 } | |
| 441 | |
| 442 /** | |
| 443 * Utility function which creates an element with an optional classname and | |
| 444 * appends it to the specified parent. | |
| 445 * @param {Element} parent The parent to append the new element. | |
| 446 * @param {string} name The name of the new element. | |
| 447 * @param {string=} opt_class The optional classname of the new element. | |
| 448 * @return {Element} The new element. | |
| 449 */ | |
| 450 function createAndAppendElement(parent, name, opt_class) { | |
| 451 var child = document.createElement(name); | |
| 452 if (opt_class) | |
| 453 child.classList.add(opt_class); | |
| 454 parent.appendChild(child); | |
| 455 return child; | |
| 456 } | |
| 457 | |
| 458 /** | |
| 459 * Removes a node from its parent. | |
| 460 * @param {Node} node The node to remove. | |
| 461 */ | |
| 462 function removeNode(node) { | |
| 463 node && node.parentNode && node.parentNode.removeChild(node); | |
| 464 } | |
| 465 | |
| 466 /** | |
| 467 * Removes all the child nodes on a DOM node. | |
| 468 * @param {Node} node Node to remove children from. | |
| 469 */ | |
| 470 function removeChildren(node) { | |
|
Dan Beam
2013/03/22 19:32:50
node.innerHTML = '';
jeremycho
2013/03/22 21:33:30
Done.
| |
| 471 var child; | |
| 472 while ((child = node.firstChild)) { | |
| 473 node.removeChild(child); | |
| 474 } | |
| 475 } | |
| 476 | |
| 477 /** | |
| 478 * Adds or removes a class depending on the enabled argument. | |
| 479 * @param {Element} element DOM node to add or remove the class on. | |
| 480 * @param {string} className Class name to add or remove. | |
| 481 * @param {boolean} enabled Whether to add or remove the class (true adds, | |
| 482 * false removes). | |
| 483 */ | |
| 484 function enable(element, className, enabled) { | |
|
Dan Beam
2013/03/22 19:32:50
element.classList.toggle(className, enabled);
jeremycho
2013/03/22 21:33:30
Done.
| |
| 485 if (enabled) | |
| 486 element.classList.add(className); | |
| 487 else | |
| 488 element.classList.remove(className); | |
| 489 } | |
| 490 | |
| 491 /** | |
| 492 * @return {Object} the handle to the embeddedSearch API. | |
| 493 */ | |
| 494 function getEmbeddedSearchApiHandle() { | |
| 495 if (window.cideb) | |
| 496 return window.cideb; | |
| 497 if (window.navigator && window.navigator.embeddedSearch) | |
|
Dan Beam
2013/03/22 19:32:50
when will navigator not be there?
jeremycho
2013/03/22 21:33:30
Isn't currently supported, but hopefully someday.
| |
| 498 return window.navigator.embeddedSearch; | |
| 499 if (window.chrome && window.chrome.embeddedSearch) | |
|
Dan Beam
2013/03/22 19:32:50
when will chrome not be there?
jeremycho
2013/03/22 21:33:30
This shouldn't happen. If it does, other things w
| |
| 500 return window.chrome.embeddedSearch; | |
| 501 return null; | |
| 502 } | |
| 503 | |
| 504 /** | |
| 505 * Prepares the New Tab Page by adding listeners, rendering the current | |
| 506 * theme, and the most visited pages section. | |
| 507 */ | |
| 508 function init() { | |
| 509 topMarginElement = document.getElementById(CLASSES.TOP_MARGIN); | |
|
Dan Beam
2013/03/22 19:32:50
^ uh, what? getElementById('class')? also, why are
jeremycho
2013/03/22 21:33:30
AFAIK, because we're in chrome-search://, we can't
| |
| 510 tilesContainer = document.getElementById(CLASSES.TILES); | |
| 511 notification = document.getElementById(CLASSES.NOTIFICATION); | |
| 512 | |
| 513 // TODO(jeremycho): i18n. | |
| 514 var notificationMessage = document.getElementById('mv-msg'); | |
| 515 notificationMessage.innerText = 'Thumbnail removed.'; | |
| 516 var undoLink = document.getElementById('mv-undo'); | |
| 517 undoLink.addEventListener('click', onUndo); | |
| 518 undoLink.innerText = 'Undo'; | |
| 519 var restoreAllLink = document.getElementById('mv-restore'); | |
| 520 restoreAllLink.addEventListener('click', onRestoreAll); | |
| 521 restoreAllLink.innerText = 'Restore all'; | |
| 522 var notificationCloseButton = document.getElementById('mv-notice-x'); | |
| 523 notificationCloseButton.addEventListener('click', hideNotification); | |
| 524 | |
| 525 window.addEventListener('resize', onResize); | |
| 526 onResize(); | |
| 527 | |
| 528 var topLevelHandle = getEmbeddedSearchApiHandle(); | |
| 529 // This is to inform Chrome that the NTP is instant-extended capable. | |
| 530 topLevelHandle.searchBox.onsubmit = function() {}; | |
|
Dan Beam
2013/03/22 19:32:50
^ er, what is this doing?
jeremycho
2013/03/22 21:33:30
See comment. Without this, Chrome doesn't fire ev
| |
| 531 | |
| 532 apiHandle = topLevelHandle.newTabPage; | |
| 533 apiHandle.onthemechange = onThemeChange; | |
| 534 apiHandle.onmostvisitedchange = onMostVisitedChange; | |
| 535 | |
| 536 onThemeChange(); | |
| 537 onMostVisitedChange(); | |
| 538 } | |
| 539 | |
| 540 document.addEventListener('DOMContentLoaded', init); | |
| OLD | NEW |