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

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

Issue 3363001: Different approach to NTP layout (Closed)
Patch Set: cleanup Created 10 years, 3 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
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | chrome/browser/resources/new_tab_theme.css » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 // To avoid creating tons of unnecessary nodes. We assume we cannot fit more 5 // To avoid creating tons of unnecessary nodes. We assume we cannot fit more
6 // than this many items in the miniview. 6 // than this many items in the miniview.
7 var MAX_MINIVIEW_ITEMS = 15; 7 var MAX_MINIVIEW_ITEMS = 15;
8 8
9 // Extra spacing at the top of the layout. 9 // Extra spacing at the top of the layout.
10 var LAYOUT_SPACING_TOP = 5; 10 var LAYOUT_SPACING_TOP = 25;
11 11
12 var loading = true; 12 var loading = true;
13 13
14 function updateSimpleSection(id, section) { 14 function updateSimpleSection(id, section) {
15 if (shownSections & section) 15 var elm = $(id);
16 var maxiview = getSectionMaxiview(elm);
17 if (shownSections & section) {
16 $(id).classList.remove('hidden'); 18 $(id).classList.remove('hidden');
17 else 19 if (maxiview)
20 maxiview.classList.remove('hidden');
21 } else {
18 $(id).classList.add('hidden'); 22 $(id).classList.add('hidden');
23 if (maxiview)
24 maxiview.classList.add('hidden');
25 }
19 } 26 }
20 27
21 function recentlyClosedTabs(data) { 28 function recentlyClosedTabs(data) {
22 logEvent('received recently closed tabs'); 29 logEvent('received recently closed tabs');
23 // We need to store the recent items so we can update the layout on a resize. 30 // We need to store the recent items so we can update the layout on a resize.
24 recentItems = data; 31 recentItems = data;
25 renderRecentlyClosed(); 32 renderRecentlyClosed();
26 layoutSections(); 33 layoutSections();
27 } 34 }
28 35
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 101
95 layoutSections(); 102 layoutSections();
96 } 103 }
97 104
98 // Stores some information about each section necessary to layout. A new 105 // Stores some information about each section necessary to layout. A new
99 // instance is constructed for each section on each layout. 106 // instance is constructed for each section on each layout.
100 function SectionLayoutInfo(section) { 107 function SectionLayoutInfo(section) {
101 this.section = section; 108 this.section = section;
102 this.header = section.getElementsByTagName('h2')[0]; 109 this.header = section.getElementsByTagName('h2')[0];
103 this.miniview = section.getElementsByClassName('miniview')[0]; 110 this.miniview = section.getElementsByClassName('miniview')[0];
104 this.maxiview = section.getElementsByClassName('maxiview')[0]; 111 this.maxiview = getSectionMaxiview(section);
105 this.expanded = !section.classList.contains('hidden'); 112 this.expanded = this.maxiview && !section.classList.contains('hidden');
106 this.fixedHeight = this.header.offsetHeight; 113 this.fixedHeight = this.section.offsetHeight;
107 this.scrollingHeight = 0; 114 this.scrollingHeight = 0;
108 115
109 if (this.expanded) { 116 if (this.expanded)
110 this.scrollingHeight = this.maxiview.offsetHeight; 117 this.scrollingHeight = this.maxiview.offsetHeight;
111 } else if (this.miniview) {
112 this.fixedHeight += this.miniview.offsetHeight;
113 }
114 } 118 }
115 119
116 // Get all sections to be layed out. 120 // Get all sections to be layed out.
117 SectionLayoutInfo.getAll = function() { 121 SectionLayoutInfo.getAll = function() {
118 var sections = document.querySelectorAll('.section:not(.disabled)'); 122 var sections = document.querySelectorAll('.section:not(.disabled)');
119 var result = []; 123 var result = [];
120 for (var i = 0, section; section = sections[i]; i++) { 124 for (var i = 0, section; section = sections[i]; i++) {
121 result.push(new SectionLayoutInfo(section)); 125 result.push(new SectionLayoutInfo(section));
122 } 126 }
123 return result; 127 return result;
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 'px'; 206 'px';
203 } else { 207 } else {
204 expandedSectionHeight = expandedSection.scrollingHeight; 208 expandedSectionHeight = expandedSection.scrollingHeight;
205 document.body.style.height = ''; 209 document.body.style.height = '';
206 } 210 }
207 } 211 }
208 212
209 // Now position all the elements. 213 // Now position all the elements.
210 var y = LAYOUT_SPACING_TOP; 214 var y = LAYOUT_SPACING_TOP;
211 for (i = 0, section; section = sections[i]; i++) { 215 for (i = 0, section; section = sections[i]; i++) {
212 section.header.style.top = y + 'px'; 216 section.section.style.top = y + 'px';
213 y += section.header.offsetHeight; 217 y += section.fixedHeight;
214
215 if (section.miniview) {
216 section.miniview.style.top = y + 'px';
217 if (section != expandedSection) {
218 y += section.miniview.offsetHeight;
219 }
220 }
221 218
222 if (section.maxiview) { 219 if (section.maxiview) {
223 section.maxiview.style.top = y + 'px'; 220 section.maxiview.style.top = y + 'px';
224 if (section == expandedSection) { 221
225 y += expandedSectionHeight; 222 if (section == expandedSection)
226 } 223 updateMask(section.maxiview, expandedSectionHeight);
227 } 224 }
225
226 if (section == expandedSection)
227 y += expandedSectionHeight;
228 } 228 }
229 } 229 }
230 230
231 function updateMask(maxiview, visibleHeightPx) {
232 // We want to end up with 10px gradients at the top and bottom of
233 // visibleHeight, but webkit-mask only supports expression in terms of
234 // percentages.
235
236 // We might not have enough room to do 10px gradients on each side. To get the
237 // right effect, we don't want to make the gradients smaller, but make them
238 // appear to mush into each other.
239 var gradientHeightPx = Math.min(10, Math.floor(visibleHeightPx / 2));
240 var gradientDestination = "rgba(0,0,0," + (gradientHeightPx / 10) + ")";
arv (Not doing code reviews) 2010/09/03 00:24:22 s/"/'/
241
242 var bottomSpacing = 15;
243 var first = parseFloat(maxiview.style.top) / window.innerHeight;
244 var second = first + gradientHeightPx / window.innerHeight;
245 var fourth = first + (visibleHeightPx - bottomSpacing) / window.innerHeight;
246 var third = fourth - gradientHeightPx / window.innerHeight;
247
248 var gradientArguments = [
249 "linear",
250 "0 0",
251 "0 100%",
252 "from(transparent)",
253 getColorStopString(first, "transparent"),
254 getColorStopString(second, gradientDestination),
255 getColorStopString(third, gradientDestination),
256 getColorStopString(fourth, "transparent"),
257 "to(transparent)"
258 ];
259
260 var gradient = '-webkit-gradient(' + gradientArguments.join(', ') + ')';
261 console.log(gradient);
arv (Not doing code reviews) 2010/09/03 00:24:22 can you remove this log?
262 maxiview.style.WebkitMaskImage = gradient;
263 }
264
265 function getColorStopString(height, color) {
266 return "color-stop(" + height + ", " + color + ")";
267 }
268
231 window.addEventListener('resize', handleWindowResize); 269 window.addEventListener('resize', handleWindowResize);
232 270
233 var sectionToElementMap; 271 var sectionToElementMap;
234 function getSectionElement(section) { 272 function getSectionElement(section) {
235 if (!sectionToElementMap) { 273 if (!sectionToElementMap) {
236 sectionToElementMap = {}; 274 sectionToElementMap = {};
237 for (var key in Section) { 275 for (var key in Section) {
238 sectionToElementMap[Section[key]] = 276 sectionToElementMap[Section[key]] =
239 document.querySelector('.section[section=' + key + ']'); 277 document.querySelector('.section[section=' + key + ']');
240 } 278 }
241 } 279 }
242 return sectionToElementMap[section]; 280 return sectionToElementMap[section];
243 } 281 }
244 282
283 function getSectionMaxiview(section) {
284 return $(section.id + '-maxiview');
285 }
286
245 function showSection(section) { 287 function showSection(section) {
246 if (!(section & shownSections)) { 288 if (!(section & shownSections)) {
247 shownSections |= section; 289 shownSections |= section;
248 var el = getSectionElement(section); 290 var el = getSectionElement(section);
249 if (el) 291 if (el) {
250 el.classList.remove('hidden'); 292 el.classList.remove('hidden');
251 293
294 var maxiview = getSectionMaxiview(el);
295 if (maxiview)
296 maxiview.classList.remove('hidden');
297 }
298
252 switch (section) { 299 switch (section) {
253 case Section.THUMB: 300 case Section.THUMB:
254 mostVisited.visible = true; 301 mostVisited.visible = true;
255 mostVisited.layout(); 302 mostVisited.layout();
256 break; 303 break;
257 } 304 }
258 } 305 }
259 } 306 }
260 307
261 function hideSection(section) { 308 function hideSection(section) {
262 if (section & shownSections) { 309 if (section & shownSections) {
263 shownSections &= ~section; 310 shownSections &= ~section;
264 311
265 switch (section) { 312 switch (section) {
266 case Section.THUMB: 313 case Section.THUMB:
267 mostVisited.visible = false; 314 mostVisited.visible = false;
268 mostVisited.layout(); 315 mostVisited.layout();
269 break; 316 break;
270 } 317 }
271 318
272 var el = getSectionElement(section); 319 var el = getSectionElement(section);
273 if (el) 320 if (el) {
274 el.classList.add('hidden'); 321 el.classList.add('hidden');
322
323 var maxiview = getSectionMaxiview(el);
324 if (maxiview)
325 maxiview.classList.add('hidden');
326 }
275 } 327 }
276 } 328 }
277 329
278 /** 330 /**
279 * Callback when the shown sections changes in another NTP. 331 * Callback when the shown sections changes in another NTP.
280 * @param {number} newShownSections Bitmask of the shown sections. 332 * @param {number} newShownSections Bitmask of the shown sections.
281 */ 333 */
282 function setShownSections(newShownSections) { 334 function setShownSections(newShownSections) {
283 for (var key in Section) { 335 for (var key in Section) {
284 if (newShownSections & Section[key]) 336 if (newShownSections & Section[key])
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 * linkisvisible is true). 385 * linkisvisible is true).
334 * linkurlisset: true if an URL should be set as the href for the link and false 386 * linkurlisset: true if an URL should be set as the href for the link and false
335 * otherwise. If this field is false, then clicking on the link 387 * otherwise. If this field is false, then clicking on the link
336 * will result in sending a message to the backend (see 388 * will result in sending a message to the backend (see
337 * 'SyncLinkClicked'). 389 * 'SyncLinkClicked').
338 * linkurl: the URL to use as the element's href (only used if linkurlisset is 390 * linkurl: the URL to use as the element's href (only used if linkurlisset is
339 * true). 391 * true).
340 */ 392 */
341 function syncMessageChanged(newMessage) { 393 function syncMessageChanged(newMessage) {
342 var syncStatusElement = $('sync-status'); 394 var syncStatusElement = $('sync-status');
343 var style = syncStatusElement.style;
344 395
345 // Hide the section if the message is emtpy. 396 // Hide the section if the message is emtpy.
346 if (!newMessage['syncsectionisvisible']) { 397 if (!newMessage['syncsectionisvisible']) {
347 style.display = 'none'; 398 syncStatusElement.classList.add('disabled');
348 return; 399 return;
349 } 400 }
350 style.display = 'block'; 401
402 syncStatusElement.classList.remove('disabled');
403
404 var content = syncStatusElement.children[0];
351 405
352 // Set the sync section background color based on the state. 406 // Set the sync section background color based on the state.
353 if (newMessage.msgtype == 'error') { 407 if (newMessage.msgtype == 'error') {
354 style.backgroundColor = 'tomato'; 408 content.style.backgroundColor = 'tomato';
355 } else { 409 } else {
356 style.backgroundColor = ''; 410 content.style.backgroundColor = '';
357 } 411 }
358 412
359 // Set the text for the header and sync message. 413 // Set the text for the header and sync message.
360 var titleElement = syncStatusElement.firstElementChild; 414 var titleElement = content.firstElementChild;
361 titleElement.textContent = newMessage.title; 415 titleElement.textContent = newMessage.title;
362 var messageElement = titleElement.nextElementSibling; 416 var messageElement = titleElement.nextElementSibling;
363 messageElement.textContent = newMessage.msg; 417 messageElement.textContent = newMessage.msg;
364 418
365 // Remove what comes after the message 419 // Remove what comes after the message
366 while (messageElement.nextSibling) { 420 while (messageElement.nextSibling) {
367 syncStatusElement.removeChild(messageElement.nextSibling); 421 content.removeChild(messageElement.nextSibling);
368 } 422 }
369 423
370 if (newMessage.linkisvisible) { 424 if (newMessage.linkisvisible) {
371 var el; 425 var el;
372 if (newMessage.linkurlisset) { 426 if (newMessage.linkurlisset) {
373 // Use a link 427 // Use a link
374 el = document.createElement('a'); 428 el = document.createElement('a');
375 el.href = newMessage.linkurl; 429 el.href = newMessage.linkurl;
376 } else { 430 } else {
377 el = document.createElement('button'); 431 el = document.createElement('button');
378 el.className = 'link'; 432 el.className = 'link';
379 el.addEventListener('click', syncSectionLinkClicked); 433 el.addEventListener('click', syncSectionLinkClicked);
380 } 434 }
381 el.textContent = newMessage.linktext; 435 el.textContent = newMessage.linktext;
382 syncStatusElement.appendChild(el); 436 content.appendChild(el);
383 fixLinkUnderline(el); 437 fixLinkUnderline(el);
384 } 438 }
439
440 layoutSections();
385 } 441 }
386 442
387 /** 443 /**
388 * Invoked when the link in the sync status section is clicked. 444 * Invoked when the link in the sync status section is clicked.
389 */ 445 */
390 function syncSectionLinkClicked(e) { 446 function syncSectionLinkClicked(e) {
391 chrome.send('SyncLinkClicked'); 447 chrome.send('SyncLinkClicked');
392 e.preventDefault(); 448 e.preventDefault();
393 } 449 }
394 450
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 var command = item.getAttribute('command'); 769 var command = item.getAttribute('command');
714 if (command in this.commands) { 770 if (command in this.commands) {
715 this.commands[command].call(this, item); 771 this.commands[command].call(this, item);
716 } 772 }
717 773
718 this.hide(); 774 this.hide();
719 } 775 }
720 }; 776 };
721 777
722 var optionMenu = new OptionMenu( 778 var optionMenu = new OptionMenu(
723 document.querySelector('#most-visited-section h2 .settings-wrapper'), 779 document.querySelector('#most-visited h2 .settings-wrapper'),
724 $('option-menu')); 780 $('option-menu'));
725 optionMenu.commands = { 781 optionMenu.commands = {
726 'clear-all-blacklisted' : function() { 782 'clear-all-blacklisted' : function() {
727 mostVisited.clearAllBlacklisted(); 783 mostVisited.clearAllBlacklisted();
728 chrome.send('getMostVisited'); 784 chrome.send('getMostVisited');
729 } 785 }
730 }; 786 };
731 787
732 $('main').addEventListener('click', function(e) { 788 $('main').addEventListener('click', function(e) {
733 var p = e.target; 789 var p = e.target;
734 while (p && p.tagName != 'H2') { 790 while (p && p.tagName != 'H2') {
735 p = p.parentNode; 791 p = p.parentNode;
736 } 792 }
737 793
738 if (!p) { 794 if (!p) {
739 return; 795 return;
740 } 796 }
741 797
742 p = p.parentNode; 798 p = p.parentNode;
743 if (p.hasAttribute('noexpand')) { 799 if (!getSectionMaxiview(p)) {
744 return; 800 return;
745 } 801 }
746 802
747 var section = p.getAttribute('section'); 803 var section = p.getAttribute('section');
748 if (section) { 804 if (section) {
749 if (shownSections & Section[section]) { 805 if (shownSections & Section[section]) {
750 hideSection(Section[section]); 806 hideSection(Section[section]);
751 } else { 807 } else {
752 for (var p in Section) { 808 for (var p in Section) {
753 if (p == section) 809 if (p == section)
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 span.className = 'link-color'; 1052 span.className = 'link-color';
997 while (el.hasChildNodes()) { 1053 while (el.hasChildNodes()) {
998 span.appendChild(el.firstChild); 1054 span.appendChild(el.firstChild);
999 } 1055 }
1000 el.appendChild(span); 1056 el.appendChild(span);
1001 } 1057 }
1002 1058
1003 updateAttribution(); 1059 updateAttribution();
1004 1060
1005 var mostVisited = new MostVisited( 1061 var mostVisited = new MostVisited(
1006 $('most-visited'), 1062 $('most-visited-maxiview'),
1007 document.querySelector('#most-visited-section .miniview'), 1063 document.querySelector('#most-visited .miniview'),
1008 useSmallGrid(), 1064 useSmallGrid(),
1009 shownSections & Section.THUMB); 1065 shownSections & Section.THUMB);
1010 1066
1011 function mostVisitedPages(data, firstRun) { 1067 function mostVisitedPages(data, firstRun) {
1012 logEvent('received most visited pages'); 1068 logEvent('received most visited pages');
1013 1069
1014 mostVisited.data = data; 1070 mostVisited.data = data;
1015 mostVisited.layout(); 1071 mostVisited.layout();
1016 layoutSections(); 1072 layoutSections();
1017 1073
1018 loading = false; 1074 loading = false;
1019 1075
1020 // Remove class name in a timeout so that changes done in this JS thread are 1076 // Remove class name in a timeout so that changes done in this JS thread are
1021 // not animated. 1077 // not animated.
1022 window.setTimeout(function() { 1078 window.setTimeout(function() {
1023 mostVisited.ensureSmallGridCorrect(); 1079 mostVisited.ensureSmallGridCorrect();
1024 document.body.classList.remove('loading'); 1080 document.body.classList.remove('loading');
1025 }, 1); 1081 }, 1);
1026 1082
1027 // Only show the first run notification if first run. 1083 // Only show the first run notification if first run.
1028 if (firstRun) { 1084 if (firstRun) {
1029 showFirstRunNotification(); 1085 showFirstRunNotification();
1030 } 1086 }
1031 } 1087 }
OLDNEW
« no previous file with comments | « chrome/browser/resources/new_new_tab.html ('k') | chrome/browser/resources/new_tab_theme.css » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698