| Index: chrome/browser/resources/new_new_tab.js
|
| ===================================================================
|
| --- chrome/browser/resources/new_new_tab.js (revision 21075)
|
| +++ chrome/browser/resources/new_new_tab.js (working copy)
|
| @@ -94,29 +94,82 @@
|
|
|
| // We should only show complete downloads.
|
| data = data.filter(function(d) {
|
| + d.type = 'download';
|
| + d.timestamp = d.started;
|
| return d.state == 'COMPLETE';
|
| });
|
| - data.length = Math.min(data.length, 5);
|
| - processData('#download-items', data);
|
| +
|
| + gotRecentItems(data, 'download');
|
| }
|
|
|
| function recentlyClosedTabs(data) {
|
| logEvent('received recently closed tabs');
|
| - data.length = Math.min(data.length, 5);
|
| - processData('#tab-items', data);
|
| +
|
| + // We handle timestamp 0 as now
|
| + data.forEach(function(d) {
|
| + if (d.timestamp == 0) {
|
| + d.timestamp = Date.now();
|
| + }
|
| + });
|
| +
|
| + gotRecentItems(data);
|
| }
|
|
|
| +var recentItems = [];
|
| +var recentItemKeys = {};
|
| +
|
| +function getRecentItemKey(d) {
|
| + // type == window does not have a URL
|
| + return d.type + (d.url || d.sessionId) + d.timestamp;
|
| +}
|
| +
|
| +function gotRecentItems(data) {
|
| + // Add new items
|
| + for (var i = 0; i < data.length; i++) {
|
| + var d = data[i];
|
| + var key = getRecentItemKey(d);
|
| + if (!(key in recentItemKeys)) {
|
| + recentItems.push(d);
|
| + recentItemKeys[key] = true;
|
| + }
|
| + }
|
| +
|
| + recentItems.sort(function(d1, d2) {
|
| + return d2.timestamp - d1.timestamp;
|
| + });
|
| +
|
| + renderRecentItems();
|
| +}
|
| +
|
| +function renderRecentItems() {
|
| + // When tips are shown we only show 10 items
|
| + var desiredCount = shownSections & Section.TIPS ? 10 : 20;
|
| + desiredCount -= 2; // Show all downloads and all history uses two rows.
|
| +
|
| + processData('#recent-activities > .item-container',
|
| + recentItems.slice(0, desiredCount));
|
| +}
|
| +
|
| function onShownSections(mask) {
|
| logEvent('received shown sections');
|
| if (mask != shownSections) {
|
| + var oldShownSections = shownSections;
|
| + shownSections = mask;
|
|
|
| // Only invalidate most visited if needed.
|
| - if ((mask & Section.THUMB) != (shownSections & Section.THUMB) ||
|
| - (mask & Section.LIST) != (shownSections & Section.LIST)) {
|
| + if ((mask & Section.THUMB) != (oldShownSections & Section.THUMB) ||
|
| + (mask & Section.LIST) != (oldShownSections & Section.LIST)) {
|
| mostVisited.invalidate();
|
| }
|
|
|
| - shownSections = mask;
|
| + if ((mask & Section.RECENT) != (oldShownSections & Section.RECENT)) {
|
| + notifyLowerSectionForChange(Section.RECENT);
|
| + }
|
| +
|
| + if ((mask & Section.TIPS) != (oldShownSections & Section.TIPS)) {
|
| + notifyLowerSectionForChange(Section.TIPS);
|
| + }
|
| +
|
| mostVisited.updateDisplayMode();
|
| layoutLowerSections();
|
| updateOptionMenu();
|
| @@ -136,10 +189,6 @@
|
| processData('#tip-items', data);
|
| }
|
|
|
| -// This global variable is used to skip parts of the DOM tree for the global
|
| -// jst processing done by the i18n.
|
| -var processing = false;
|
| -
|
| function processData(selector, data) {
|
| var output = document.querySelector(selector);
|
|
|
| @@ -152,9 +201,7 @@
|
| } else {
|
| var d0 = Date.now();
|
| var input = new JsEvalContext(data);
|
| - processing = true;
|
| jstProcess(input, output);
|
| - processing = false;
|
| logEvent('processData: ' + selector + ', ' + (Date.now() - d0));
|
| }
|
| }
|
| @@ -272,7 +319,7 @@
|
| shownSections &= ~Section.THUMB;
|
| mostVisited.invalidate();
|
| } else {
|
| - notifyLowerSectionForChange(section, false);
|
| + notifyLowerSectionForChange(section);
|
| layoutLowerSections();
|
| }
|
|
|
| @@ -290,8 +337,8 @@
|
| mostVisited.invalidate();
|
| }
|
|
|
| - if (section & Section.RECENT|| section & Section.TIPS) {
|
| - notifyLowerSectionForChange(section, true);
|
| + if (section & Section.RECENT || section & Section.TIPS) {
|
| + notifyLowerSectionForChange(section);
|
| layoutLowerSections();
|
| }
|
|
|
| @@ -301,16 +348,15 @@
|
| }
|
| }
|
|
|
| -function notifyLowerSectionForChange(section, large) {
|
| +function notifyLowerSectionForChange(section) {
|
| // Notify recent and tips if they need to display more data.
|
| if (section == Section.RECENT || section == Section.TIPS) {
|
| - // we are hiding one of them so if the other one is visible it is now
|
| - // {@code large}.
|
| if (shownSections & Section.RECENT) {
|
| - recentChangedSize(large);
|
| - } else if (shownSections & Section.TIPS) {
|
| - tipsChangedSize(large);
|
| + recentChangedSize(!(shownSections & Section.TIPS));
|
| }
|
| + if (shownSections & Section.TIPS) {
|
| + tipsChangedSize(!(shownSections & Section.RECENT));
|
| + }
|
| }
|
| }
|
|
|
| @@ -563,7 +609,13 @@
|
| };
|
|
|
| function recentChangedSize(large) {
|
| - // TODO(arv): Implement
|
| + if (large) {
|
| + addClass($('recent-activities'), 'large');
|
| + } else {
|
| + removeClass($('recent-activities'), 'large');
|
| + }
|
| +
|
| + renderRecentItems();
|
| }
|
|
|
| function tipsChangedSize(large) {
|
| @@ -924,9 +976,6 @@
|
| };
|
| }
|
|
|
| -$('downloads').addEventListener('click', maybeOpenFile);
|
| -$('downloads').addEventListener('keydown', handleIfEnterKey(maybeOpenFile));
|
| -
|
| function maybeOpenFile(e) {
|
| var el = findAncestor(e.target, function(el) {
|
| return el.fileId !== undefined;
|
| @@ -937,10 +986,6 @@
|
| }
|
| }
|
|
|
| -var recentTabs = $('recent-tabs');
|
| -recentTabs.addEventListener('click', maybeReopenTab);
|
| -recentTabs.addEventListener('keydown', handleIfEnterKey(maybeReopenTab));
|
| -
|
| function maybeReopenTab(e) {
|
| var el = findAncestor(e.target, function(el) {
|
| return el.sessionId !== undefined;
|
| @@ -951,19 +996,30 @@
|
| }
|
| }
|
|
|
| -recentTabs.addEventListener('mouseover', maybeShowWindowMenu);
|
| -recentTabs.addEventListener('focus', maybeShowWindowMenu, true);
|
| -
|
| -
|
| function maybeShowWindowMenu(e) {
|
| - var el = findAncestor(e.target, function(el) {
|
| + var f = function(el) {
|
| return el.tabItems !== undefined;
|
| - });
|
| - if (el) {
|
| + };
|
| + var el = findAncestor(e.target, f);
|
| + var relatedEl = findAncestor(e.relatedTarget, f);
|
| + if (el && el != relatedEl) {
|
| windowMenu.show(e, el, el.tabItems);
|
| }
|
| }
|
|
|
| +
|
| +var recentActivitiesElement = $('recent-activities');
|
| +recentActivitiesElement.addEventListener('click', maybeOpenFile);
|
| +recentActivitiesElement.addEventListener('keydown',
|
| + handleIfEnterKey(maybeOpenFile));
|
| +
|
| +recentActivitiesElement.addEventListener('click', maybeReopenTab);
|
| +recentActivitiesElement.addEventListener('keydown',
|
| + handleIfEnterKey(maybeReopenTab));
|
| +
|
| +recentActivitiesElement.addEventListener('mouseover', maybeShowWindowMenu);
|
| +recentActivitiesElement.addEventListener('focus', maybeShowWindowMenu, true);
|
| +
|
| /**
|
| * This object represents a window/tooltip representing a closed window. It is
|
| * shown when hovering over a closed window item or when the item is focused. It
|
| @@ -972,13 +1028,11 @@
|
| * @constructor
|
| */
|
| function WindowMenu(menuEl) {
|
| + // TODO(arv): Rename WindowTooltip and make it behave even more like a
|
| + // tooltip.
|
| this.menuEl = menuEl;
|
| - var self = this;
|
| this.boundHide_ = bind(this.hide, this);
|
| - menuEl.onmouseover = function() {
|
| - clearTimeout(self.timer);
|
| - };
|
| - menuEl.onmouseout = this.boundHide_;
|
| + this.boundHandleMouseOut_ = bind(this.handleMouseOut, this);
|
| }
|
|
|
| WindowMenu.prototype = {
|
| @@ -993,18 +1047,37 @@
|
| var rtl = document.documentElement.dir == 'rtl';
|
|
|
| this.menuEl.style.display = 'block';
|
| - this.menuEl.style.left = (rtl ?
|
| - rect.left + bodyRect.left + rect.width - this.menuEl.offsetWidth :
|
| - rect.left + bodyRect.left) + 'px';
|
| - this.menuEl.style.top = rect.top + bodyRect.top + rect.height + 'px';
|
| + // When focused show below, like a drop down menu.
|
| + if (e.type == 'focus') {
|
| + this.menuEl.style.left = (rtl ?
|
| + rect.left + bodyRect.left + rect.width - this.menuEl.offsetWidth :
|
| + rect.left + bodyRect.left) + 'px';
|
| + this.menuEl.style.top = rect.top + bodyRect.top + rect.height + 'px';
|
| + } else {
|
| + this.menuEl.style.left = bodyRect.left + (rtl ?
|
| + e.clientX - this.menuEl.offsetWidth :
|
| + e.clientX) + 'px';
|
| + this.menuEl.style.top = e.clientY + bodyRect.top + 'px';
|
| + }
|
|
|
| if (e.type == 'focus') {
|
| linkEl.onblur = this.boundHide_;
|
| } else { // mouseover
|
| - linkEl.onmouseout = this.boundHide_;
|
| + linkEl.onmouseout = this.boundHandleMouseOut_;
|
| }
|
| },
|
| - hide: function() {
|
| + handleMouseOut: function(e) {
|
| + // Don't hide when move to another item in the link.
|
| + var f = function(el) {
|
| + return el.tabItems !== undefined;
|
| + };
|
| + var el = findAncestor(e.target, f);
|
| + var relatedEl = findAncestor(e.relatedTarget, f);
|
| + if (el && el != relatedEl) {
|
| + this.hide();
|
| + }
|
| + },
|
| + hide: function(e) {
|
| // Delay before hiding.
|
| var self = this;
|
| this.timer = setTimeout(function() {
|
|
|