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

Side by Side Diff: chrome/browser/resources/shared/js/cr/ui/list.js

Issue 9288017: WebUI TaskManager: Use the specified height of row on refleshing. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge with master Created 8 years, 10 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 | « no previous file | chrome/browser/resources/task_manager/main.js » ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 // require: array_data_model.js 5 // require: array_data_model.js
6 // require: list_selection_model.js 6 // require: list_selection_model.js
7 // require: list_selection_controller.js 7 // require: list_selection_controller.js
8 // require: list_item.js 8 // require: list_item.js
9 9
10 /** 10 /**
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 this.boundHandleDataModelPermuted_); 126 this.boundHandleDataModelPermuted_);
127 this.dataModel_.removeEventListener('change', 127 this.dataModel_.removeEventListener('change',
128 this.boundHandleDataModelChange_); 128 this.boundHandleDataModelChange_);
129 this.dataModel_.removeEventListener('splice', 129 this.dataModel_.removeEventListener('splice',
130 this.boundHandleDataModelChange_); 130 this.boundHandleDataModelChange_);
131 } 131 }
132 132
133 this.dataModel_ = dataModel; 133 this.dataModel_ = dataModel;
134 134
135 this.cachedItems_ = {}; 135 this.cachedItems_ = {};
136 this.cachedItemSizes_ = {}; 136 this.cachedItemHeights_ = {};
137 this.selectionModel.clear(); 137 this.selectionModel.clear();
138 if (dataModel) 138 if (dataModel)
139 this.selectionModel.adjustLength(dataModel.length); 139 this.selectionModel.adjustLength(dataModel.length);
140 140
141 if (this.dataModel_) { 141 if (this.dataModel_) {
142 this.dataModel_.addEventListener( 142 this.dataModel_.addEventListener(
143 'permuted', 143 'permuted',
144 this.boundHandleDataModelPermuted_); 144 this.boundHandleDataModelPermuted_);
145 this.dataModel_.addEventListener('change', 145 this.dataModel_.addEventListener('change',
146 this.boundHandleDataModelChange_); 146 this.boundHandleDataModelChange_);
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 this.addEventListener('blur', this.handleElementBlur_, true); 324 this.addEventListener('blur', this.handleElementBlur_, true);
325 this.addEventListener('scroll', this.handleScroll.bind(this)); 325 this.addEventListener('scroll', this.handleScroll.bind(this));
326 this.setAttribute('role', 'listbox'); 326 this.setAttribute('role', 'listbox');
327 327
328 // Make list focusable 328 // Make list focusable
329 if (!this.hasAttribute('tabindex')) 329 if (!this.hasAttribute('tabindex'))
330 this.tabIndex = 0; 330 this.tabIndex = 0;
331 }, 331 },
332 332
333 /** 333 /**
334 * @param {ListItem=} item The list item to measure.
335 * @return {number} The height of the given item. If the fixed height on CSS
336 * is set by 'px', uses that value as height. Otherwise, measures the size.
337 * @private
338 */
339 measureItemHeight_: function(item) {
340 var height = item.style.height;
341 // Use the fixed height if set it on CSS, to save a time of layout
342 // calculation.
343 if (height && height.substr(-2) == 'px')
344 return parseInt(height.substr(0, height.length - 2));
345
346 return this.measureItem(item).height;
347 },
348
349 /**
334 * @return {number} The height of default item, measuring it if necessary. 350 * @return {number} The height of default item, measuring it if necessary.
335 * @private 351 * @private
336 */ 352 */
337 getDefaultItemHeight_: function() { 353 getDefaultItemHeight_: function() {
338 return this.getDefaultItemSize_().height; 354 return this.getDefaultItemSize_().height;
339 }, 355 },
340 356
341 /** 357 /**
342 * @param {number} index The index of the item. 358 * @param {number} index The index of the item.
343 * @return {number} The height of the item. 359 * @return {number} The height of the item, measuring it if necessary.
344 */ 360 */
345 getItemHeightByIndex_: function(index) { 361 getItemHeightByIndex_: function(index) {
346 // If |this.fixedHeight_| is true, all the rows have same default height. 362 // If |this.fixedHeight_| is true, all the rows have same default height.
347 if (this.fixedHeight_) 363 if (this.fixedHeight_)
348 return this.getDefaultItemHeight_(); 364 return this.getDefaultItemHeight_();
349 365
350 if (this.cachedItemSizes_[index]) 366 if (this.cachedItemHeights_[index])
351 return this.cachedItemSizes_[index].height; 367 return this.cachedItemHeights_[index];
352 368
353 var item = this.getListItemByIndex(index); 369 var item = this.getListItemByIndex(index);
354 if (item) 370 if (item)
355 return this.getItemSize_(item).height; 371 return this.measureItemHeight_(item);
356 372
357 return this.getDefaultItemHeight_(); 373 return this.getDefaultItemHeight_();
358 }, 374 },
359 375
360 /** 376 /**
361 * @return {number} The width of default item, measuring it if necessary.
362 * @private
363 */
364 getDefaultItemWidth_: function() {
365 return this.getDefaultItemSize_().width;
366 },
367
368 /**
369 * @return {{height: number, width: number}} The height and width 377 * @return {{height: number, width: number}} The height and width
370 * of default item, measuring it if necessary. 378 * of default item, measuring it if necessary.
371 * @private 379 * @private
372 */ 380 */
373 getDefaultItemSize_: function() { 381 getDefaultItemSize_: function() {
374 if (!this.measured_ || !this.measured_.height) { 382 if (!this.measured_ || !this.measured_.height) {
375 this.measured_ = this.measureItem(); 383 this.measured_ = this.measureItem();
376 } 384 }
377 return this.measured_; 385 return this.measured_;
378 }, 386 },
379 387
380 /** 388 /**
381 * @return {{height: number, width: number}} The height and width
382 * of an item, measuring it if necessary.
383 * @private
384 */
385 getItemSize_: function(item) {
386 if (this.cachedItemSizes_[item.listIndex])
387 return this.cachedItemSizes_[item.listIndex];
388
389 var size = this.measureItem(item);
390 if (!isNaN(size.height) && !isNaN(size.weight))
391 this.cachedItemSizes_[item.listIndex] = size;
392
393 return size;
394 },
395
396 /**
397 * Creates an item (dataModel.item(0)) and measures its height. The item is 389 * Creates an item (dataModel.item(0)) and measures its height. The item is
398 * cached instead of creating a new one every time.. 390 * cached instead of creating a new one every time..
399 * @param {ListItem=} opt_item The list item to use to do the measuring. If 391 * @param {ListItem=} opt_item The list item to use to do the measuring. If
400 * this is not provided an item will be created based on the first value 392 * this is not provided an item will be created based on the first value
401 * in the model. 393 * in the model.
402 * @return {{height: number, marginTop: number, marginBottom:number, 394 * @return {{height: number, marginTop: number, marginBottom:number,
403 * width: number, marginLeft: number, marginRight:number}} 395 * width: number, marginLeft: number, marginRight:number}}
404 * The height and width of the item, taking 396 * The height and width of the item, taking
405 * margins into account, and the top, bottom, left and right margins 397 * margins into account, and the top, bottom, left and right margins
406 * themselves. 398 * themselves.
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 var newCachedItems = {}; 620 var newCachedItems = {};
629 for (var index in this.cachedItems_) { 621 for (var index in this.cachedItems_) {
630 if (e.permutation[index] != -1) { 622 if (e.permutation[index] != -1) {
631 var newIndex = e.permutation[index]; 623 var newIndex = e.permutation[index];
632 newCachedItems[newIndex] = this.cachedItems_[index]; 624 newCachedItems[newIndex] = this.cachedItems_[index];
633 newCachedItems[newIndex].listIndex = newIndex; 625 newCachedItems[newIndex].listIndex = newIndex;
634 } 626 }
635 } 627 }
636 this.cachedItems_ = newCachedItems; 628 this.cachedItems_ = newCachedItems;
637 629
638 var newCachedItemSizes = {}; 630 var newCachedItemHeights = {};
639 for (var index in this.cachedItemSizes_) { 631 for (var index in this.cachedItemHeights_) {
640 if (e.permutation[index] != -1) { 632 if (e.permutation[index] != -1) {
641 newCachedItemSizes[e.permutation[index]] = 633 newCachedItemHeights[e.permutation[index]] =
642 this.cachedItemSizes_[index]; 634 this.cachedItemHeights_[index];
643 } 635 }
644 } 636 }
645 this.cachedItemSizes_ = newCachedItemSizes; 637 this.cachedItemHeights_ = newCachedItemHeights;
646 638
647 this.startBatchUpdates(); 639 this.startBatchUpdates();
648 640
649 var sm = this.selectionModel; 641 var sm = this.selectionModel;
650 sm.adjustLength(e.newLength); 642 sm.adjustLength(e.newLength);
651 sm.adjustToReordering(e.permutation); 643 sm.adjustToReordering(e.permutation);
652 644
653 this.endBatchUpdates(); 645 this.endBatchUpdates();
654 }, 646 },
655 647
656 handleDataModelChange_: function(e) { 648 handleDataModelChange_: function(e) {
657 delete this.cachedItems_[e.index]; 649 delete this.cachedItems_[e.index];
658 delete this.cachedItemSizes_[e.index]; 650 delete this.cachedItemHeights_[e.index];
659 this.cachedMeasuredItem_ = null; 651 this.cachedMeasuredItem_ = null;
660 652
661 if (e.index >= this.firstIndex_ && 653 if (e.index >= this.firstIndex_ &&
662 (e.index < this.lastIndex_ || this.remainingSpace_)) { 654 (e.index < this.lastIndex_ || this.remainingSpace_)) {
663 this.redraw(); 655 this.redraw();
664 } 656 }
665 }, 657 },
666 658
667 /** 659 /**
668 * @param {number} index The index of the item. 660 * @param {number} index The index of the item.
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 while (currentIndex < lastIndex) 976 while (currentIndex < lastIndex)
985 insert(this); 977 insert(this);
986 }, 978 },
987 979
988 /** 980 /**
989 * Ensures that all the item sizes in the list have been already cached. 981 * Ensures that all the item sizes in the list have been already cached.
990 */ 982 */
991 ensureAllItemSizesInCache: function() { 983 ensureAllItemSizesInCache: function() {
992 var measuringIndexes = []; 984 var measuringIndexes = [];
993 for (var y = 0; y < this.dataModel.length; y++) { 985 for (var y = 0; y < this.dataModel.length; y++) {
994 if (!this.cachedItemSizes_[y]) 986 if (!this.cachedItemHeights_[y])
995 measuringIndexes.push(y); 987 measuringIndexes.push(y);
996 } 988 }
997 989
998 var measuringItems = []; 990 var measuringItems = [];
999 // Adds temporary elements. 991 // Adds temporary elements.
1000 for (var y = 0; y < measuringIndexes.length; y++) { 992 for (var y = 0; y < measuringIndexes.length; y++) {
1001 var index = measuringIndexes[y]; 993 var index = measuringIndexes[y];
1002 var dataItem = this.dataModel.item(index); 994 var dataItem = this.dataModel.item(index);
1003 var listItem = this.cachedItems_[index] || this.createItem(dataItem); 995 var listItem = this.cachedItems_[index] || this.createItem(dataItem);
1004 listItem.listIndex = index; 996 listItem.listIndex = index;
1005 this.appendChild(listItem); 997 this.appendChild(listItem);
1006 this.cachedItems_[index] = listItem; 998 this.cachedItems_[index] = listItem;
1007 measuringItems.push(listItem); 999 measuringItems.push(listItem);
1008 } 1000 }
1009 1001
1010 // All mesurings must be placed after adding all the elements, to prevent 1002 // All mesurings must be placed after adding all the elements, to prevent
1011 // performance reducing. 1003 // performance reducing.
1012 for (var y = 0; y < measuringIndexes.length; y++) { 1004 for (var y = 0; y < measuringIndexes.length; y++) {
1013 var index = measuringIndexes[y]; 1005 var index = measuringIndexes[y];
1014 this.cachedItemSizes_[index] = this.measureItem(measuringItems[y]); 1006 this.cachedItemHeights_[index] =
1007 this.measureItemHeight_(measuringItems[y]);
1015 } 1008 }
1016 1009
1017 // Removes all the temprary elements. 1010 // Removes all the temprary elements.
1018 for (var y = 0; y < measuringIndexes.length; y++) { 1011 for (var y = 0; y < measuringIndexes.length; y++) {
1019 this.removeChild(measuringItems[y]); 1012 this.removeChild(measuringItems[y]);
1020 } 1013 }
1021 }, 1014 },
1022 1015
1023 /** 1016 /**
1024 * Returns the height of after filler in the list. 1017 * Returns the height of after filler in the list.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 1055
1063 // We cache the list items since creating the DOM nodes is the most 1056 // We cache the list items since creating the DOM nodes is the most
1064 // expensive part of redrawing. 1057 // expensive part of redrawing.
1065 var cachedItems = this.cachedItems_ || {}; 1058 var cachedItems = this.cachedItems_ || {};
1066 var newCachedItems = {}; 1059 var newCachedItems = {};
1067 1060
1068 var autoExpands = this.autoExpands_; 1061 var autoExpands = this.autoExpands_;
1069 var scrollTop = this.scrollTop; 1062 var scrollTop = this.scrollTop;
1070 var clientHeight = this.clientHeight; 1063 var clientHeight = this.clientHeight;
1071 1064
1072 var lastItemHeights = this.getHeightsForIndex_(dataModel.length - 1);
1073 var desiredScrollHeight = lastItemHeights.top + lastItemHeights.height;
1074
1075 var itemsInViewPort = this.getItemsInViewPort(scrollTop, clientHeight); 1065 var itemsInViewPort = this.getItemsInViewPort(scrollTop, clientHeight);
1076 // Draws the hidden rows just above/below the viewport to prevent 1066 // Draws the hidden rows just above/below the viewport to prevent
1077 // flashing in scroll. 1067 // flashing in scroll.
1078 var firstIndex = Math.max(0, itemsInViewPort.first - 1); 1068 var firstIndex = Math.max(0, itemsInViewPort.first - 1);
1079 var lastIndex = Math.min(itemsInViewPort.last + 1, dataModel.length); 1069 var lastIndex = Math.min(itemsInViewPort.last + 1, dataModel.length);
1080 1070
1081 var beforeFillerHeight = 1071 var beforeFillerHeight =
1082 this.autoExpands ? 0 : this.getItemTop(firstIndex); 1072 this.autoExpands ? 0 : this.getItemTop(firstIndex);
1083 var afterFillerHeight = 1073 var afterFillerHeight =
1084 this.autoExpands ? 0 : this.getAfterFillerHeight(lastIndex); 1074 this.autoExpands ? 0 : this.getAfterFillerHeight(lastIndex);
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 this.firstIndex_ = firstIndex; 1110 this.firstIndex_ = firstIndex;
1121 this.lastIndex_ = lastIndex; 1111 this.lastIndex_ = lastIndex;
1122 1112
1123 this.remainingSpace_ = itemsInViewPort.last > dataModel.length; 1113 this.remainingSpace_ = itemsInViewPort.last > dataModel.length;
1124 this.cachedItems_ = newCachedItems; 1114 this.cachedItems_ = newCachedItems;
1125 1115
1126 // Mesurings must be placed after adding all the elements, to prevent 1116 // Mesurings must be placed after adding all the elements, to prevent
1127 // performance reducing. 1117 // performance reducing.
1128 if (!this.fixedHeight_) { 1118 if (!this.fixedHeight_) {
1129 for (var y = firstIndex; y < lastIndex; y++) 1119 for (var y = firstIndex; y < lastIndex; y++)
1130 this.cachedItemSizes_[y] = this.measureItem(newCachedItems[y]); 1120 this.cachedItemHeights_[y] =
1121 this.measureItemHeight_(newCachedItems[y]);
1131 } 1122 }
1132 1123
1133 // Measure again in case the item height has changed due to a page zoom. 1124 // Measure again in case the item height has changed due to a page zoom.
1134 // 1125 //
1135 // The measure above is only done the first time but this measure is done 1126 // The measure above is only done the first time but this measure is done
1136 // after every redraw. It is done in a timeout so it will not trigger 1127 // after every redraw. It is done in a timeout so it will not trigger
1137 // a reflow (which made the redraw speed 3 times slower on my system). 1128 // a reflow (which made the redraw speed 3 times slower on my system).
1138 // By using a timeout the measuring will happen later when there is no 1129 // By using a timeout the measuring will happen later when there is no
1139 // need for a reflow. 1130 // need for a reflow.
1140 if (listItem && this.fixedHeight_) { 1131 if (listItem && this.fixedHeight_) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 * because list items can contain controls that can be focused, and for some 1174 * because list items can contain controls that can be focused, and for some
1184 * purposes (e.g., styling), the list can still be conceptually focused at 1175 * purposes (e.g., styling), the list can still be conceptually focused at
1185 * that point even though it doesn't actually have the page focus. 1176 * that point even though it doesn't actually have the page focus.
1186 */ 1177 */
1187 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR); 1178 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR);
1188 1179
1189 return { 1180 return {
1190 List: List 1181 List: List
1191 } 1182 }
1192 }); 1183 });
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/resources/task_manager/main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698