OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // Helpers | 5 var loading = true; |
6 | 6 |
7 function findAncestorByClass(el, className) { | 7 function updateSimpleSection(id, section) { |
8 return findAncestor(el, function(el) { | 8 if (shownSections & section) |
9 return hasClass(el, className); | 9 $(id).classList.remove('hidden'); |
10 }); | 10 else |
| 11 $(id).classList.add('hidden'); |
11 } | 12 } |
12 | 13 |
13 /** | |
14 * Return the first ancestor for which the {@code predicate} returns true. | |
15 * @param {Node} node The node to check. | |
16 * @param {function(Node) : boolean} predicate The function that tests the | |
17 * nodes. | |
18 * @return {Node} The found ancestor or null if not found. | |
19 */ | |
20 function findAncestor(node, predicate) { | |
21 var last = false; | |
22 while (node != null && !(last = predicate(node))) { | |
23 node = node.parentNode; | |
24 } | |
25 return last ? node : null; | |
26 } | |
27 | |
28 // WebKit does not have Node.prototype.swapNode | |
29 // https://bugs.webkit.org/show_bug.cgi?id=26525 | |
30 function swapDomNodes(a, b) { | |
31 var afterA = a.nextSibling; | |
32 if (afterA == b) { | |
33 swapDomNodes(b, a); | |
34 return; | |
35 } | |
36 var aParent = a.parentNode; | |
37 b.parentNode.replaceChild(a, b); | |
38 aParent.insertBefore(b, afterA); | |
39 } | |
40 | |
41 function bind(fn, selfObj, var_args) { | |
42 var boundArgs = Array.prototype.slice.call(arguments, 2); | |
43 return function() { | |
44 var args = Array.prototype.slice.call(arguments); | |
45 args.unshift.apply(args, boundArgs); | |
46 return fn.apply(selfObj, args); | |
47 } | |
48 } | |
49 | |
50 const IS_MAC = /$Mac/.test(navigator.platform); | |
51 | |
52 var loading = true; | |
53 | |
54 function getAppsCallback(data) { | 14 function getAppsCallback(data) { |
| 15 logEvent('recieved apps'); |
55 var appsSection = $('apps-section'); | 16 var appsSection = $('apps-section'); |
56 var debugSection = $('debug'); | 17 var debugSection = $('debug'); |
57 appsSection.innerHTML = ''; | 18 appsSection.innerHTML = ''; |
58 | 19 |
59 data.forEach(function(app) { | 20 data.forEach(function(app) { |
60 appsSection.appendChild(apps.createElement(app)); | 21 appsSection.appendChild(apps.createElement(app)); |
61 }); | 22 }); |
62 | 23 |
63 // TODO(aa): Figure out what to do with the debug mode when we turn apps on | 24 // TODO(aa): Figure out what to do with the debug mode when we turn apps on |
64 // for everyone. | 25 // for everyone. |
65 if (data.length) { | 26 if (data.length) { |
66 removeClass(appsSection, 'disabled'); | 27 appsSection.classList.remove('disabled'); |
67 removeClass(debugSection, 'disabled'); | 28 debugSection.classList.remove('disabled'); |
68 } else { | 29 } else { |
69 addClass(appsSection, 'disabled'); | 30 appsSection.classList.add('disabled'); |
70 addClass(debugSection, 'disabled'); | 31 debugSection.classList.add('disabled'); |
71 } | 32 } |
72 } | 33 } |
73 | 34 |
74 var apps = { | 35 var apps = { |
75 /** | 36 /** |
76 * @this {!HTMLAnchorElement} | 37 * @this {!HTMLAnchorElement} |
77 */ | 38 */ |
78 handleClick_: function() { | 39 handleClick_: function() { |
79 var launchType = ''; | 40 var launchType = ''; |
80 var inputElements = document.querySelectorAll( | 41 var inputElements = document.querySelectorAll( |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 el.dir = data.direction; | 150 el.dir = data.direction; |
190 el.textContent = data.title; | 151 el.textContent = data.title; |
191 } | 152 } |
192 el.sessionId = data.sessionId; | 153 el.sessionId = data.sessionId; |
193 el.xtitle = data.title; | 154 el.xtitle = data.title; |
194 var wrapperEl = document.createElement('span'); | 155 var wrapperEl = document.createElement('span'); |
195 wrapperEl.appendChild(el); | 156 wrapperEl.appendChild(el); |
196 return wrapperEl; | 157 return wrapperEl; |
197 } | 158 } |
198 | 159 |
199 function onShownSections(mask) { | |
200 logEvent('received shown sections'); | |
201 if (mask != shownSections) { | |
202 var oldShownSections = shownSections; | |
203 shownSections = mask; | |
204 | |
205 // Only invalidate most visited if needed. | |
206 if ((mask & Section.THUMB) != (oldShownSections & Section.THUMB)) { | |
207 mostVisited.invalidate(); | |
208 } | |
209 | |
210 mostVisited.updateDisplayMode(); | |
211 renderRecentlyClosed(); | |
212 } | |
213 } | |
214 | |
215 function saveShownSections() { | 160 function saveShownSections() { |
216 chrome.send('setShownSections', [String(shownSections)]); | 161 chrome.send('setShownSections', [String(shownSections)]); |
217 } | 162 } |
218 | 163 |
219 function url(s) { | |
220 // http://www.w3.org/TR/css3-values/#uris | |
221 // Parentheses, commas, whitespace characters, single quotes (') and double | |
222 // quotes (") appearing in a URI must be escaped with a backslash | |
223 var s2 = s.replace(/(\(|\)|\,|\s|\'|\"|\\)/g, '\\$1'); | |
224 // WebKit has a bug when it comes to URLs that end with \ | |
225 // https://bugs.webkit.org/show_bug.cgi?id=28885 | |
226 if (/\\\\$/.test(s2)) { | |
227 // Add a space to work around the WebKit bug. | |
228 s2 += ' '; | |
229 } | |
230 return 'url("' + s2 + '")'; | |
231 } | |
232 | |
233 /** | |
234 * Calls chrome.send with a callback and restores the original afterwards. | |
235 */ | |
236 function chromeSend(name, params, callbackName, callback) { | |
237 var old = global[callbackName]; | |
238 global[callbackName] = function() { | |
239 // restore | |
240 global[callbackName] = old; | |
241 | |
242 var args = Array.prototype.slice.call(arguments); | |
243 return callback.apply(global, args); | |
244 }; | |
245 chrome.send(name, params); | |
246 } | |
247 | |
248 var LayoutMode = { | 164 var LayoutMode = { |
249 SMALL: 1, | 165 SMALL: 1, |
250 NORMAL: 2 | 166 NORMAL: 2 |
251 }; | 167 }; |
252 | 168 |
253 var layoutMode = useSmallGrid() ? LayoutMode.SMALL : LayoutMode.NORMAL; | 169 var layoutMode = useSmallGrid() ? LayoutMode.SMALL : LayoutMode.NORMAL; |
254 | 170 |
255 function handleWindowResize() { | 171 function handleWindowResize() { |
256 if (window.innerWidth < 10) { | 172 if (window.innerWidth < 10) { |
257 // We're probably a background tab, so don't do anything. | 173 // We're probably a background tab, so don't do anything. |
258 return; | 174 return; |
259 } | 175 } |
260 | 176 |
261 var oldLayoutMode = layoutMode; | 177 var oldLayoutMode = layoutMode; |
262 layoutMode = useSmallGrid() ? LayoutMode.SMALL : LayoutMode.NORMAL | 178 var b = useSmallGrid(); |
| 179 layoutMode = b ? LayoutMode.SMALL : LayoutMode.NORMAL |
263 | 180 |
264 if (layoutMode != oldLayoutMode){ | 181 if (layoutMode != oldLayoutMode){ |
265 mostVisited.invalidate(); | 182 mostVisited.useSmallGrid = b; |
266 mostVisited.layout(); | 183 mostVisited.layout(); |
267 renderRecentlyClosed(); | 184 renderRecentlyClosed(); |
268 } | 185 } |
269 } | 186 } |
270 | 187 |
| 188 window.addEventListener('resize', handleWindowResize); |
| 189 |
| 190 var sectionToElementMap; |
| 191 function getSectionElement(section) { |
| 192 if (!sectionToElementMap) { |
| 193 sectionToElementMap = {}; |
| 194 for (var key in Section) { |
| 195 sectionToElementMap[Section[key]] = |
| 196 document.querySelector('.section[section=' + key + ']'); |
| 197 } |
| 198 } |
| 199 return sectionToElementMap[section]; |
| 200 } |
| 201 |
271 function showSection(section) { | 202 function showSection(section) { |
272 if (!(section & shownSections)) { | 203 if (!(section & shownSections)) { |
273 shownSections |= section; | 204 shownSections |= section; |
274 | 205 |
275 switch (section) { | 206 switch (section) { |
276 case Section.THUMB: | 207 case Section.THUMB: |
277 mostVisited.invalidate(); | 208 mostVisited.visible = true; |
278 mostVisited.updateDisplayMode(); | |
279 mostVisited.layout(); | 209 mostVisited.layout(); |
280 break; | 210 break; |
281 case Section.RECENT: | 211 case Section.RECENT: |
282 renderRecentlyClosed(); | 212 renderRecentlyClosed(); |
283 break; | 213 break; |
284 case Section.TIPS: | |
285 removeClass($('tip-line'), 'hidden'); | |
286 break; | |
287 case Section.DEBUG: | |
288 removeClass($('debug'), 'hidden'); | |
289 break; | |
290 } | 214 } |
| 215 |
| 216 getSectionElement(section).classList.remove('hidden'); |
291 } | 217 } |
292 } | 218 } |
293 | 219 |
294 function hideSection(section) { | 220 function hideSection(section) { |
295 if (section & shownSections) { | 221 if (section & shownSections) { |
296 shownSections &= ~section; | 222 shownSections &= ~section; |
297 | 223 |
298 switch (section) { | 224 switch (section) { |
299 case Section.THUMB: | 225 case Section.THUMB: |
300 mostVisited.invalidate(); | 226 mostVisited.visible = false; |
301 mostVisited.updateDisplayMode(); | |
302 mostVisited.layout(); | 227 mostVisited.layout(); |
303 break; | 228 break; |
304 case Section.RECENT: | 229 case Section.RECENT: |
305 renderRecentlyClosed(); | 230 renderRecentlyClosed(); |
306 break; | 231 break; |
307 case Section.TIPS: | |
308 addClass($('tip-line'), 'hidden'); | |
309 break; | |
310 case Section.DEBUG: | |
311 addClass($('debug'), 'hidden'); | |
312 break; | |
313 } | 232 } |
| 233 |
| 234 getSectionElement(section).classList.add('hidden'); |
314 } | 235 } |
315 } | 236 } |
316 | 237 |
317 // Recently closed | 238 // Recently closed |
318 | 239 |
319 function layoutRecentlyClosed() { | 240 function layoutRecentlyClosed() { |
320 var recentShown = shownSections & Section.RECENT; | 241 var recentShown = shownSections & Section.RECENT; |
321 updateSimpleSection('recently-closed', Section.RECENT); | |
322 | 242 |
323 if (recentShown) { | 243 if (recentShown) { |
324 var recentElement = $('recently-closed'); | 244 var recentElement = $('recently-closed'); |
325 var style = recentElement.style; | 245 var style = recentElement.style; |
326 // We cannot use clientWidth here since the width has a transition. | 246 // We cannot use clientWidth here since the width has a transition. |
327 var spacing = 20; | 247 var spacing = 20; |
328 var headerEl = recentElement.firstElementChild; | 248 var headerEl = recentElement.firstElementChild; |
329 var navEl = recentElement.lastElementChild.lastElementChild; | 249 var navEl = recentElement.lastElementChild.lastElementChild; |
330 var navWidth = navEl.offsetWidth; | 250 var navWidth = navEl.offsetWidth; |
331 // Subtract 10 for the padding | 251 // Subtract 10 for the padding |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 * Returns the text used for a recently closed window. | 354 * Returns the text used for a recently closed window. |
435 * @param {number} numTabs Number of tabs in the window. | 355 * @param {number} numTabs Number of tabs in the window. |
436 * @return {string} The text to use. | 356 * @return {string} The text to use. |
437 */ | 357 */ |
438 function formatTabsText(numTabs) { | 358 function formatTabsText(numTabs) { |
439 if (numTabs == 1) | 359 if (numTabs == 1) |
440 return localStrings.getString('closedwindowsingle'); | 360 return localStrings.getString('closedwindowsingle'); |
441 return localStrings.getStringF('closedwindowmultiple', numTabs); | 361 return localStrings.getStringF('closedwindowmultiple', numTabs); |
442 } | 362 } |
443 | 363 |
444 /** | |
445 * We need both most visited and the shown sections to be considered loaded. | |
446 * @return {boolean} | |
447 */ | |
448 function onDataLoaded() { | |
449 if (gotMostVisited) { | |
450 mostVisited.layout(); | |
451 loading = false; | |
452 // Remove class name in a timeout so that changes done in this JS thread are | |
453 // not animated. | |
454 window.setTimeout(function() { | |
455 ensureSmallGridCorrect(); | |
456 removeClass(document.body, 'loading'); | |
457 }, 1); | |
458 } | |
459 } | |
460 | |
461 // Theme related | 364 // Theme related |
462 | 365 |
463 function themeChanged() { | 366 function themeChanged() { |
464 $('themecss').href = 'chrome://theme/css/newtab.css?' + Date.now(); | 367 $('themecss').href = 'chrome://theme/css/newtab.css?' + Date.now(); |
465 updateAttribution(); | 368 updateAttribution(); |
466 } | 369 } |
467 | 370 |
468 function updateAttribution() { | 371 function updateAttribution() { |
469 $('attribution-img').src = 'chrome://theme/theme_ntp_attribution?' + | 372 $('attribution-img').src = 'chrome://theme/theme_ntp_attribution?' + |
470 Date.now(); | 373 Date.now(); |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 | 431 |
529 var notificationTimeout; | 432 var notificationTimeout; |
530 | 433 |
531 function showNotification(text, actionText, opt_f, opt_delay) { | 434 function showNotification(text, actionText, opt_f, opt_delay) { |
532 var notificationElement = $('notification'); | 435 var notificationElement = $('notification'); |
533 var f = opt_f || function() {}; | 436 var f = opt_f || function() {}; |
534 var delay = opt_delay || 10000; | 437 var delay = opt_delay || 10000; |
535 | 438 |
536 function show() { | 439 function show() { |
537 window.clearTimeout(notificationTimeout); | 440 window.clearTimeout(notificationTimeout); |
538 addClass(notificationElement, 'show'); | 441 notificationElement.classList.add('show'); |
539 addClass(document.body, 'notification-shown'); | 442 document.body.classList.add('notification-shown'); |
540 } | 443 } |
541 | 444 |
542 function delayedHide() { | 445 function delayedHide() { |
543 notificationTimeout = window.setTimeout(hideNotification, delay); | 446 notificationTimeout = window.setTimeout(hideNotification, delay); |
544 } | 447 } |
545 | 448 |
546 function doAction() { | 449 function doAction() { |
547 f(); | 450 f(); |
548 hideNotification(); | 451 hideNotification(); |
549 } | 452 } |
550 | 453 |
551 // Remove any possible first-run trails. | 454 // Remove any possible first-run trails. |
552 removeClass(notification, 'first-run'); | 455 notification.classList.remove('first-run'); |
553 | 456 |
554 var actionLink = notificationElement.querySelector('.link-color'); | 457 var actionLink = notificationElement.querySelector('.link-color'); |
555 notificationElement.firstElementChild.textContent = text; | 458 notificationElement.firstElementChild.textContent = text; |
556 actionLink.textContent = actionText; | 459 actionLink.textContent = actionText; |
557 | 460 |
558 actionLink.onclick = doAction; | 461 actionLink.onclick = doAction; |
559 actionLink.onkeydown = handleIfEnterKey(doAction); | 462 actionLink.onkeydown = handleIfEnterKey(doAction); |
560 notificationElement.onmouseover = show; | 463 notificationElement.onmouseover = show; |
561 notificationElement.onmouseout = delayedHide; | 464 notificationElement.onmouseout = delayedHide; |
562 actionLink.onfocus = show; | 465 actionLink.onfocus = show; |
563 actionLink.onblur = delayedHide; | 466 actionLink.onblur = delayedHide; |
564 // Enable tabbing to the link now that it is shown. | 467 // Enable tabbing to the link now that it is shown. |
565 actionLink.tabIndex = 0; | 468 actionLink.tabIndex = 0; |
566 | 469 |
567 show(); | 470 show(); |
568 delayedHide(); | 471 delayedHide(); |
569 } | 472 } |
570 | 473 |
571 /** | 474 /** |
572 * Hides the notifier. | 475 * Hides the notifier. |
573 */ | 476 */ |
574 function hideNotification() { | 477 function hideNotification() { |
575 var notificationElement = $('notification'); | 478 var notificationElement = $('notification'); |
576 removeClass(notificationElement, 'show'); | 479 notificationElement.classList.remove('show'); |
577 removeClass(document.body, 'notification-shown'); | 480 document.body.classList.remove('notification-shown'); |
578 var actionLink = notificationElement.querySelector('.link-color'); | 481 var actionLink = notificationElement.querySelector('.link-color'); |
579 // Prevent tabbing to the hidden link. | 482 // Prevent tabbing to the hidden link. |
580 actionLink.tabIndex = -1; | 483 actionLink.tabIndex = -1; |
581 // Setting tabIndex to -1 only prevents future tabbing to it. If, however, the | 484 // Setting tabIndex to -1 only prevents future tabbing to it. If, however, the |
582 // user switches window or a tab and then moves back to this tab the element | 485 // user switches window or a tab and then moves back to this tab the element |
583 // may gain focus. We therefore make sure that we blur the element so that the | 486 // may gain focus. We therefore make sure that we blur the element so that the |
584 // element focus is not restored when coming back to this window. | 487 // element focus is not restored when coming back to this window. |
585 actionLink.blur(); | 488 actionLink.blur(); |
586 } | 489 } |
587 | 490 |
588 function showFirstRunNotification() { | 491 function showFirstRunNotification() { |
589 showNotification(localStrings.getString('firstrunnotification'), | 492 showNotification(localStrings.getString('firstrunnotification'), |
590 localStrings.getString('closefirstrunnotification'), | 493 localStrings.getString('closefirstrunnotification'), |
591 null, 30000); | 494 null, 30000); |
592 var notificationElement = $('notification'); | 495 var notificationElement = $('notification'); |
593 addClass(notification, 'first-run'); | 496 notification.classList.add('first-run'); |
594 } | 497 } |
595 | 498 |
596 /** | 499 /** |
597 * This handles the option menu. | 500 * This handles the option menu. |
598 * @param {Element} button The button element. | 501 * @param {Element} button The button element. |
599 * @param {Element} menu The menu element. | 502 * @param {Element} menu The menu element. |
600 * @constructor | 503 * @constructor |
601 */ | 504 */ |
602 function OptionMenu(button, menu) { | 505 function OptionMenu(button, menu) { |
603 this.button = button; | 506 this.button = button; |
604 this.menu = menu; | 507 this.menu = menu; |
605 this.button.onmousedown = bind(this.handleMouseDown, this); | 508 this.button.onmousedown = bind(this.handleMouseDown, this); |
606 this.button.onkeydown = bind(this.handleKeyDown, this); | 509 this.button.onkeydown = bind(this.handleKeyDown, this); |
607 this.boundHideMenu_ = bind(this.hide, this); | 510 this.boundHideMenu_ = bind(this.hide, this); |
608 this.boundMaybeHide_ = bind(this.maybeHide_, this); | 511 this.boundMaybeHide_ = bind(this.maybeHide_, this); |
609 this.menu.onmouseover = bind(this.handleMouseOver, this); | 512 this.menu.onmouseover = bind(this.handleMouseOver, this); |
610 this.menu.onmouseout = bind(this.handleMouseOut, this); | 513 this.menu.onmouseout = bind(this.handleMouseOut, this); |
611 this.menu.onmouseup = bind(this.handleMouseUp, this); | 514 this.menu.onmouseup = bind(this.handleMouseUp, this); |
612 } | 515 } |
613 | 516 |
614 OptionMenu.prototype = { | 517 OptionMenu.prototype = { |
615 show: function() { | 518 show: function() { |
616 updateOptionMenu(); | 519 updateOptionMenu(); |
617 this.positionMenu_(); | 520 this.positionMenu_(); |
618 this.menu.style.display = 'block'; | 521 this.menu.style.display = 'block'; |
619 addClass(this.button, 'open'); | 522 this.button.classList.add('open'); |
620 this.button.focus(); | 523 this.button.focus(); |
621 | 524 |
622 // Listen to document and window events so that we hide the menu when the | 525 // Listen to document and window events so that we hide the menu when the |
623 // user clicks outside the menu or tabs away or the whole window is blurred. | 526 // user clicks outside the menu or tabs away or the whole window is blurred. |
624 document.addEventListener('focus', this.boundMaybeHide_, true); | 527 document.addEventListener('focus', this.boundMaybeHide_, true); |
625 document.addEventListener('mousedown', this.boundMaybeHide_, true); | 528 document.addEventListener('mousedown', this.boundMaybeHide_, true); |
626 }, | 529 }, |
627 | 530 |
628 positionMenu_: function() { | 531 positionMenu_: function() { |
629 this.menu.style.top = this.button.getBoundingClientRect().bottom + 'px'; | 532 this.menu.style.top = this.button.getBoundingClientRect().bottom + 'px'; |
630 }, | 533 }, |
631 | 534 |
632 hide: function() { | 535 hide: function() { |
633 this.menu.style.display = 'none'; | 536 this.menu.style.display = 'none'; |
634 removeClass(this.button, 'open'); | 537 this.button.classList.remove('open'); |
635 this.setSelectedIndex(-1); | 538 this.setSelectedIndex(-1); |
636 | 539 |
637 document.removeEventListener('focus', this.boundMaybeHide_, true); | 540 document.removeEventListener('focus', this.boundMaybeHide_, true); |
638 document.removeEventListener('mousedown', this.boundMaybeHide_, true); | 541 document.removeEventListener('mousedown', this.boundMaybeHide_, true); |
639 }, | 542 }, |
640 | 543 |
641 isShown: function() { | 544 isShown: function() { |
642 return this.menu.style.display == 'block'; | 545 return this.menu.style.display == 'block'; |
643 }, | 546 }, |
644 | 547 |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
960 span.textContent = tab.title; | 863 span.textContent = tab.title; |
961 tooltip.appendChild(span); | 864 tooltip.appendChild(span); |
962 }); | 865 }); |
963 } | 866 } |
964 }; | 867 }; |
965 | 868 |
966 var windowTooltip = new WindowTooltip($('window-tooltip')); | 869 var windowTooltip = new WindowTooltip($('window-tooltip')); |
967 | 870 |
968 window.addEventListener('load', bind(logEvent, global, 'Tab.NewTabOnload', | 871 window.addEventListener('load', bind(logEvent, global, 'Tab.NewTabOnload', |
969 true)); | 872 true)); |
970 window.addEventListener('load', onDataLoaded); | |
971 | 873 |
972 window.addEventListener('resize', handleWindowResize); | 874 window.addEventListener('resize', handleWindowResize); |
973 document.addEventListener('DOMContentLoaded', | 875 document.addEventListener('DOMContentLoaded', |
974 bind(logEvent, global, 'Tab.NewTabDOMContentLoaded', true)); | 876 bind(logEvent, global, 'Tab.NewTabDOMContentLoaded', true)); |
975 | 877 |
976 // Whether or not we should send the initial 'GetSyncMessage' to the backend | 878 // Whether or not we should send the initial 'GetSyncMessage' to the backend |
977 // depends on the value of the attribue 'syncispresent' which the backend sets | 879 // depends on the value of the attribue 'syncispresent' which the backend sets |
978 // to indicate if there is code in the backend which is capable of processing | 880 // to indicate if there is code in the backend which is capable of processing |
979 // this message. This attribute is loaded by the JSTemplate and therefore we | 881 // this message. This attribute is loaded by the JSTemplate and therefore we |
980 // must make sure we check the attribute after the DOM is loaded. | 882 // must make sure we check the attribute after the DOM is loaded. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1014 window.addEventListener('keydown', function(e) { | 916 window.addEventListener('keydown', function(e) { |
1015 if (e.keyIdentifier == 'Alt' || e.keyIdentifier == 'Meta') { | 917 if (e.keyIdentifier == 'Alt' || e.keyIdentifier == 'Meta') { |
1016 hideAllMenus(); | 918 hideAllMenus(); |
1017 } | 919 } |
1018 }, true); | 920 }, true); |
1019 | 921 |
1020 // Tooltip for elements that have text that overflows. | 922 // Tooltip for elements that have text that overflows. |
1021 document.addEventListener('mouseover', function(e) { | 923 document.addEventListener('mouseover', function(e) { |
1022 // We don't want to do this while we are dragging because it makes things very | 924 // We don't want to do this while we are dragging because it makes things very |
1023 // janky | 925 // janky |
1024 if (dnd.dragItem) { | 926 if (mostVisited.isDragging()) { |
1025 return; | 927 return; |
1026 } | 928 } |
1027 | 929 |
1028 var el = findAncestor(e.target, function(el) { | 930 var el = findAncestor(e.target, function(el) { |
1029 return el.xtitle; | 931 return el.xtitle; |
1030 }); | 932 }); |
1031 if (el && el.xtitle != el.title) { | 933 if (el && el.xtitle != el.title) { |
1032 if (el.scrollWidth > el.clientWidth) { | 934 if (el.scrollWidth > el.clientWidth) { |
1033 el.title = el.xtitle; | 935 el.title = el.xtitle; |
1034 } else { | 936 } else { |
(...skipping 21 matching lines...) Expand all Loading... |
1056 while (el.hasChildNodes()) { | 958 while (el.hasChildNodes()) { |
1057 span.appendChild(el.firstChild); | 959 span.appendChild(el.firstChild); |
1058 } | 960 } |
1059 el.appendChild(span); | 961 el.appendChild(span); |
1060 } | 962 } |
1061 | 963 |
1062 updateAttribution(); | 964 updateAttribution(); |
1063 | 965 |
1064 // Closes the promo line when close button is clicked. | 966 // Closes the promo line when close button is clicked. |
1065 $('promo-close').onclick = function (e) { | 967 $('promo-close').onclick = function (e) { |
1066 addClass($('promo-line'), 'hidden'); | 968 $('promo-line').classList.add('hidden'); |
1067 chrome.send('stopPromoLineMessage'); | 969 chrome.send('stopPromoLineMessage'); |
1068 e.preventDefault(); | 970 e.preventDefault(); |
1069 }; | 971 }; |
1070 | 972 |
1071 // Set bookmark sync button to start bookmark sync process on click; also set | 973 // Set bookmark sync button to start bookmark sync process on click; also set |
1072 // link underline colors correctly. | 974 // link underline colors correctly. |
1073 function setUpPromoMessage() { | 975 function setUpPromoMessage() { |
1074 var syncButton = document.querySelector('#promo-message button'); | 976 var syncButton = document.querySelector('#promo-message button'); |
1075 syncButton.className = 'sync-button link'; | 977 syncButton.className = 'sync-button link'; |
1076 syncButton.onclick = syncSectionLinkClicked; | 978 syncButton.onclick = syncSectionLinkClicked; |
1077 fixLinkUnderlines($('promo-message')); | 979 fixLinkUnderlines($('promo-message')); |
1078 } | 980 } |
| 981 |
| 982 var mostVisited = new MostVisited($('most-visited'), |
| 983 useSmallGrid(), |
| 984 shownSections & Section.THUMB); |
| 985 |
| 986 function mostVisitedPages(data, firstRun) { |
| 987 logEvent('received most visited pages'); |
| 988 |
| 989 mostVisited.data = data; |
| 990 mostVisited.layout(); |
| 991 |
| 992 loading = false; |
| 993 |
| 994 // Remove class name in a timeout so that changes done in this JS thread are |
| 995 // not animated. |
| 996 window.setTimeout(function() { |
| 997 mostVisited.ensureSmallGridCorrect(); |
| 998 document.body.classList.remove('loading'); |
| 999 }, 1); |
| 1000 |
| 1001 // Only show the first run notification if first run. |
| 1002 if (firstRun) { |
| 1003 showFirstRunNotification(); |
| 1004 } |
| 1005 } |
| 1006 |
| 1007 |
OLD | NEW |