Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(292)

Side by Side Diff: chrome/browser/resources/new_new_tab.js

Issue 155865: NNTP: Merge the recent activities into one list and show more items... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 // Helpers 2 // Helpers
3 3
4 function $(id) { 4 function $(id) {
5 return document.getElementById(id); 5 return document.getElementById(id);
6 } 6 }
7 7
8 // TODO(arv): Remove these when classList is available in HTML5. 8 // TODO(arv): Remove these when classList is available in HTML5.
9 // https://bugs.webkit.org/show_bug.cgi?id=20709 9 // https://bugs.webkit.org/show_bug.cgi?id=20709
10 function hasClass(el, name) { 10 function hasClass(el, name) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 87
88 gotMostVisited = true; 88 gotMostVisited = true;
89 onDataLoaded(); 89 onDataLoaded();
90 } 90 }
91 91
92 function downloadsList(data) { 92 function downloadsList(data) {
93 logEvent('received downloads'); 93 logEvent('received downloads');
94 94
95 // We should only show complete downloads. 95 // We should only show complete downloads.
96 data = data.filter(function(d) { 96 data = data.filter(function(d) {
97 d.type = 'download';
98 d.timestamp = d.started;
97 return d.state == 'COMPLETE'; 99 return d.state == 'COMPLETE';
98 }); 100 });
99 data.length = Math.min(data.length, 5); 101
100 processData('#download-items', data); 102 gotRecentItems(data, 'download');
101 } 103 }
102 104
103 function recentlyClosedTabs(data) { 105 function recentlyClosedTabs(data) {
104 logEvent('received recently closed tabs'); 106 logEvent('received recently closed tabs');
105 data.length = Math.min(data.length, 5); 107
106 processData('#tab-items', data); 108 // We handle timestamp 0 as now
109 data.forEach(function(d) {
110 if (d.timestamp == 0) {
111 d.timestamp = Date.now();
112 }
113 });
114
115 gotRecentItems(data);
116 }
117
118 var recentItems = [];
119 var recentItemKeys = {};
120
121 function getRecentItemKey(d) {
122 // type == window does not have a URL
123 return d.type + (d.url || d.sessionId) + d.timestamp;
124 }
125
126 function gotRecentItems(data) {
127 // Add new items
128 for (var i = 0; i < data.length; i++) {
129 var d = data[i];
130 var key = getRecentItemKey(d);
131 if (!(key in recentItemKeys)) {
132 recentItems.push(d);
133 recentItemKeys[key] = true;
134 }
135 }
136
137 recentItems.sort(function(d1, d2) {
138 return d2.timestamp - d1.timestamp;
139 });
140
141 renderRecentItems();
142 }
143
144 function renderRecentItems() {
145 // When tips are shown we only show 10 items
146 var desiredCount = shownSections & Section.TIPS ? 10 : 20;
147 desiredCount -= 2; // Show all downloads and all history uses two rows.
148
149 processData('#recent-activities > .item-container',
150 recentItems.slice(0, desiredCount));
107 } 151 }
108 152
109 function onShownSections(mask) { 153 function onShownSections(mask) {
110 logEvent('received shown sections'); 154 logEvent('received shown sections');
111 if (mask != shownSections) { 155 if (mask != shownSections) {
156 var oldShownSections = shownSections;
157 shownSections = mask;
112 158
113 // Only invalidate most visited if needed. 159 // Only invalidate most visited if needed.
114 if ((mask & Section.THUMB) != (shownSections & Section.THUMB) || 160 if ((mask & Section.THUMB) != (oldShownSections & Section.THUMB) ||
115 (mask & Section.LIST) != (shownSections & Section.LIST)) { 161 (mask & Section.LIST) != (oldShownSections & Section.LIST)) {
116 mostVisited.invalidate(); 162 mostVisited.invalidate();
117 } 163 }
118 164
119 shownSections = mask; 165 if ((mask & Section.RECENT) != (oldShownSections & Section.RECENT)) {
166 notifyLowerSectionForChange(Section.RECENT);
167 }
168
169 if ((mask & Section.TIPS) != (oldShownSections & Section.TIPS)) {
170 notifyLowerSectionForChange(Section.TIPS);
171 }
172
120 mostVisited.updateDisplayMode(); 173 mostVisited.updateDisplayMode();
121 layoutLowerSections(); 174 layoutLowerSections();
122 updateOptionMenu(); 175 updateOptionMenu();
123 } 176 }
124 177
125 gotShownSections = true; 178 gotShownSections = true;
126 onDataLoaded(); 179 onDataLoaded();
127 } 180 }
128 181
129 function saveShownSections() { 182 function saveShownSections() {
130 chrome.send('setShownSections', [String(shownSections)]); 183 chrome.send('setShownSections', [String(shownSections)]);
131 } 184 }
132 185
133 function tips(data) { 186 function tips(data) {
134 logEvent('received tips data'); 187 logEvent('received tips data');
135 data.length = Math.min(data.length, 5); 188 data.length = Math.min(data.length, 5);
136 processData('#tip-items', data); 189 processData('#tip-items', data);
137 } 190 }
138 191
139 // This global variable is used to skip parts of the DOM tree for the global
140 // jst processing done by the i18n.
141 var processing = false;
142
143 function processData(selector, data) { 192 function processData(selector, data) {
144 var output = document.querySelector(selector); 193 var output = document.querySelector(selector);
145 194
146 // Wait until ready 195 // Wait until ready
147 if (typeof JsEvalContext !== 'function' || !output) { 196 if (typeof JsEvalContext !== 'function' || !output) {
148 logEvent('JsEvalContext is not yet available, ' + selector); 197 logEvent('JsEvalContext is not yet available, ' + selector);
149 document.addEventListener('DOMContentLoaded', function() { 198 document.addEventListener('DOMContentLoaded', function() {
150 processData(selector, data); 199 processData(selector, data);
151 }); 200 });
152 } else { 201 } else {
153 var d0 = Date.now(); 202 var d0 = Date.now();
154 var input = new JsEvalContext(data); 203 var input = new JsEvalContext(data);
155 processing = true;
156 jstProcess(input, output); 204 jstProcess(input, output);
157 processing = false;
158 logEvent('processData: ' + selector + ', ' + (Date.now() - d0)); 205 logEvent('processData: ' + selector + ', ' + (Date.now() - d0));
159 } 206 }
160 } 207 }
161 208
162 function getThumbnailClassName(data) { 209 function getThumbnailClassName(data) {
163 return 'thumbnail-container' + 210 return 'thumbnail-container' +
164 (data.pinned ? ' pinned' : '') + 211 (data.pinned ? ' pinned' : '') +
165 (data.filler ? ' filler' : ''); 212 (data.filler ? ' filler' : '');
166 } 213 }
167 214
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 // THUMBS and LIST are mutually exclusive. 312 // THUMBS and LIST are mutually exclusive.
266 if (section == Section.THUMB) { 313 if (section == Section.THUMB) {
267 // hide LIST 314 // hide LIST
268 shownSections &= ~Section.LIST; 315 shownSections &= ~Section.LIST;
269 mostVisited.invalidate(); 316 mostVisited.invalidate();
270 } else if (section == Section.LIST) { 317 } else if (section == Section.LIST) {
271 // hide THUMB 318 // hide THUMB
272 shownSections &= ~Section.THUMB; 319 shownSections &= ~Section.THUMB;
273 mostVisited.invalidate(); 320 mostVisited.invalidate();
274 } else { 321 } else {
275 notifyLowerSectionForChange(section, false); 322 notifyLowerSectionForChange(section);
276 layoutLowerSections(); 323 layoutLowerSections();
277 } 324 }
278 325
279 updateOptionMenu(); 326 updateOptionMenu();
280 mostVisited.updateDisplayMode(); 327 mostVisited.updateDisplayMode();
281 mostVisited.layout(); 328 mostVisited.layout();
282 } 329 }
283 } 330 }
284 331
285 function hideSection(section) { 332 function hideSection(section) {
286 if (section & shownSections) { 333 if (section & shownSections) {
287 shownSections &= ~section; 334 shownSections &= ~section;
288 335
289 if (section & Section.THUMB || section & Section.LIST) { 336 if (section & Section.THUMB || section & Section.LIST) {
290 mostVisited.invalidate(); 337 mostVisited.invalidate();
291 } 338 }
292 339
293 if (section & Section.RECENT|| section & Section.TIPS) { 340 if (section & Section.RECENT || section & Section.TIPS) {
294 notifyLowerSectionForChange(section, true); 341 notifyLowerSectionForChange(section);
295 layoutLowerSections(); 342 layoutLowerSections();
296 } 343 }
297 344
298 updateOptionMenu(); 345 updateOptionMenu();
299 mostVisited.updateDisplayMode(); 346 mostVisited.updateDisplayMode();
300 mostVisited.layout(); 347 mostVisited.layout();
301 } 348 }
302 } 349 }
303 350
304 function notifyLowerSectionForChange(section, large) { 351 function notifyLowerSectionForChange(section) {
305 // Notify recent and tips if they need to display more data. 352 // Notify recent and tips if they need to display more data.
306 if (section == Section.RECENT || section == Section.TIPS) { 353 if (section == Section.RECENT || section == Section.TIPS) {
307 // we are hiding one of them so if the other one is visible it is now
308 // {@code large}.
309 if (shownSections & Section.RECENT) { 354 if (shownSections & Section.RECENT) {
310 recentChangedSize(large); 355 recentChangedSize(!(shownSections & Section.TIPS));
311 } else if (shownSections & Section.TIPS) { 356 }
312 tipsChangedSize(large); 357 if (shownSections & Section.TIPS) {
358 tipsChangedSize(!(shownSections & Section.RECENT));
313 } 359 }
314 } 360 }
315 } 361 }
316 362
317 var mostVisited = { 363 var mostVisited = {
318 getItem: function(el) { 364 getItem: function(el) {
319 return findAncestorByClass(el, 'thumbnail-container'); 365 return findAncestorByClass(el, 'thumbnail-container');
320 }, 366 },
321 367
322 getHref: function(el) { 368 getHref: function(el) {
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 } 602 }
557 }); 603 });
558 604
559 this.dirty_ = false; 605 this.dirty_ = false;
560 606
561 logEvent('mostVisited.layout: ' + (Date.now() - d0)); 607 logEvent('mostVisited.layout: ' + (Date.now() - d0));
562 } 608 }
563 }; 609 };
564 610
565 function recentChangedSize(large) { 611 function recentChangedSize(large) {
566 // TODO(arv): Implement 612 if (large) {
613 addClass($('recent-activities'), 'large');
614 } else {
615 removeClass($('recent-activities'), 'large');
616 }
617
618 renderRecentItems();
567 } 619 }
568 620
569 function tipsChangedSize(large) { 621 function tipsChangedSize(large) {
570 // TODO(arv): Implement 622 // TODO(arv): Implement
571 } 623 }
572 624
573 // Recent activities 625 // Recent activities
574 626
575 function layoutLowerSections() { 627 function layoutLowerSections() {
576 // This lower sections are inline blocks so all we need to do is to set the 628 // This lower sections are inline blocks so all we need to do is to set the
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 }); 969 });
918 970
919 function handleIfEnterKey(f) { 971 function handleIfEnterKey(f) {
920 return function(e) { 972 return function(e) {
921 if (e.keyIdentifier == 'Enter') { 973 if (e.keyIdentifier == 'Enter') {
922 f(e); 974 f(e);
923 } 975 }
924 }; 976 };
925 } 977 }
926 978
927 $('downloads').addEventListener('click', maybeOpenFile);
928 $('downloads').addEventListener('keydown', handleIfEnterKey(maybeOpenFile));
929
930 function maybeOpenFile(e) { 979 function maybeOpenFile(e) {
931 var el = findAncestor(e.target, function(el) { 980 var el = findAncestor(e.target, function(el) {
932 return el.fileId !== undefined; 981 return el.fileId !== undefined;
933 }); 982 });
934 if (el) { 983 if (el) {
935 chrome.send('openFile', [String(el.fileId)]); 984 chrome.send('openFile', [String(el.fileId)]);
936 e.preventDefault(); 985 e.preventDefault();
937 } 986 }
938 } 987 }
939 988
940 var recentTabs = $('recent-tabs');
941 recentTabs.addEventListener('click', maybeReopenTab);
942 recentTabs.addEventListener('keydown', handleIfEnterKey(maybeReopenTab));
943
944 function maybeReopenTab(e) { 989 function maybeReopenTab(e) {
945 var el = findAncestor(e.target, function(el) { 990 var el = findAncestor(e.target, function(el) {
946 return el.sessionId !== undefined; 991 return el.sessionId !== undefined;
947 }); 992 });
948 if (el) { 993 if (el) {
949 chrome.send('reopenTab', [String(el.sessionId)]); 994 chrome.send('reopenTab', [String(el.sessionId)]);
950 e.preventDefault(); 995 e.preventDefault();
951 } 996 }
952 } 997 }
953 998
954 recentTabs.addEventListener('mouseover', maybeShowWindowMenu);
955 recentTabs.addEventListener('focus', maybeShowWindowMenu, true);
956
957
958 function maybeShowWindowMenu(e) { 999 function maybeShowWindowMenu(e) {
959 var el = findAncestor(e.target, function(el) { 1000 var f = function(el) {
960 return el.tabItems !== undefined; 1001 return el.tabItems !== undefined;
961 }); 1002 };
962 if (el) { 1003 var el = findAncestor(e.target, f);
1004 var relatedEl = findAncestor(e.relatedTarget, f);
1005 if (el && el != relatedEl) {
963 windowMenu.show(e, el, el.tabItems); 1006 windowMenu.show(e, el, el.tabItems);
964 } 1007 }
965 } 1008 }
966 1009
1010
1011 var recentActivitiesElement = $('recent-activities');
1012 recentActivitiesElement.addEventListener('click', maybeOpenFile);
1013 recentActivitiesElement.addEventListener('keydown',
1014 handleIfEnterKey(maybeOpenFile));
1015
1016 recentActivitiesElement.addEventListener('click', maybeReopenTab);
1017 recentActivitiesElement.addEventListener('keydown',
1018 handleIfEnterKey(maybeReopenTab));
1019
1020 recentActivitiesElement.addEventListener('mouseover', maybeShowWindowMenu);
1021 recentActivitiesElement.addEventListener('focus', maybeShowWindowMenu, true);
1022
967 /** 1023 /**
968 * This object represents a window/tooltip representing a closed window. It is 1024 * This object represents a window/tooltip representing a closed window. It is
969 * shown when hovering over a closed window item or when the item is focused. It 1025 * shown when hovering over a closed window item or when the item is focused. It
970 * gets hidden when blurred or when mousing out of the menu or the item. 1026 * gets hidden when blurred or when mousing out of the menu or the item.
971 * @param {Element} menuEl The element to use as the menu. 1027 * @param {Element} menuEl The element to use as the menu.
972 * @constructor 1028 * @constructor
973 */ 1029 */
974 function WindowMenu(menuEl) { 1030 function WindowMenu(menuEl) {
1031 // TODO(arv): Rename WindowTooltip and make it behave even more like a
1032 // tooltip.
975 this.menuEl = menuEl; 1033 this.menuEl = menuEl;
976 var self = this;
977 this.boundHide_ = bind(this.hide, this); 1034 this.boundHide_ = bind(this.hide, this);
978 menuEl.onmouseover = function() { 1035 this.boundHandleMouseOut_ = bind(this.handleMouseOut, this);
979 clearTimeout(self.timer);
980 };
981 menuEl.onmouseout = this.boundHide_;
982 } 1036 }
983 1037
984 WindowMenu.prototype = { 1038 WindowMenu.prototype = {
985 timer: 0, 1039 timer: 0,
986 show: function(e, linkEl, tabs) { 1040 show: function(e, linkEl, tabs) {
987 optionMenu.hide(); 1041 optionMenu.hide();
988 1042
989 clearTimeout(this.timer); 1043 clearTimeout(this.timer);
990 processData('#window-menu', tabs); 1044 processData('#window-menu', tabs);
991 var rect = linkEl.getBoundingClientRect(); 1045 var rect = linkEl.getBoundingClientRect();
992 var bodyRect = document.body.getBoundingClientRect() 1046 var bodyRect = document.body.getBoundingClientRect()
993 var rtl = document.documentElement.dir == 'rtl'; 1047 var rtl = document.documentElement.dir == 'rtl';
994 1048
995 this.menuEl.style.display = 'block'; 1049 this.menuEl.style.display = 'block';
996 this.menuEl.style.left = (rtl ? 1050 // When focused show below, like a drop down menu.
997 rect.left + bodyRect.left + rect.width - this.menuEl.offsetWidth : 1051 if (e.type == 'focus') {
998 rect.left + bodyRect.left) + 'px'; 1052 this.menuEl.style.left = (rtl ?
999 this.menuEl.style.top = rect.top + bodyRect.top + rect.height + 'px'; 1053 rect.left + bodyRect.left + rect.width - this.menuEl.offsetWidth :
1054 rect.left + bodyRect.left) + 'px';
1055 this.menuEl.style.top = rect.top + bodyRect.top + rect.height + 'px';
1056 } else {
1057 this.menuEl.style.left = bodyRect.left + (rtl ?
1058 e.clientX - this.menuEl.offsetWidth :
1059 e.clientX) + 'px';
1060 this.menuEl.style.top = e.clientY + bodyRect.top + 'px';
1061 }
1000 1062
1001 if (e.type == 'focus') { 1063 if (e.type == 'focus') {
1002 linkEl.onblur = this.boundHide_; 1064 linkEl.onblur = this.boundHide_;
1003 } else { // mouseover 1065 } else { // mouseover
1004 linkEl.onmouseout = this.boundHide_; 1066 linkEl.onmouseout = this.boundHandleMouseOut_;
1005 } 1067 }
1006 }, 1068 },
1007 hide: function() { 1069 handleMouseOut: function(e) {
1070 // Don't hide when move to another item in the link.
1071 var f = function(el) {
1072 return el.tabItems !== undefined;
1073 };
1074 var el = findAncestor(e.target, f);
1075 var relatedEl = findAncestor(e.relatedTarget, f);
1076 if (el && el != relatedEl) {
1077 this.hide();
1078 }
1079 },
1080 hide: function(e) {
1008 // Delay before hiding. 1081 // Delay before hiding.
1009 var self = this; 1082 var self = this;
1010 this.timer = setTimeout(function() { 1083 this.timer = setTimeout(function() {
1011 self.menuEl.style.display = 'none'; 1084 self.menuEl.style.display = 'none';
1012 }, 100); 1085 }, 100);
1013 } 1086 }
1014 }; 1087 };
1015 1088
1016 var windowMenu = new WindowMenu($('window-menu')); 1089 var windowMenu = new WindowMenu($('window-menu'));
1017 1090
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
1203 el.addEventListener('dragover', bind(this.handleDragOver, this)); 1276 el.addEventListener('dragover', bind(this.handleDragOver, this));
1204 el.addEventListener('dragleave', bind(this.handleDragLeave, this)); 1277 el.addEventListener('dragleave', bind(this.handleDragLeave, this));
1205 el.addEventListener('drop', bind(this.handleDrop, this)); 1278 el.addEventListener('drop', bind(this.handleDrop, this));
1206 el.addEventListener('dragend', bind(this.handleDragEnd, this)); 1279 el.addEventListener('dragend', bind(this.handleDragEnd, this));
1207 el.addEventListener('drag', bind(this.handleDrag, this)); 1280 el.addEventListener('drag', bind(this.handleDrag, this));
1208 el.addEventListener('mousedown', bind(this.handleMouseDown, this)); 1281 el.addEventListener('mousedown', bind(this.handleMouseDown, this));
1209 } 1282 }
1210 }; 1283 };
1211 1284
1212 dnd.init(); 1285 dnd.init();
OLDNEW
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698