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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/console/ConsoleViewport.js

Issue 2799043006: DevTools: make console viewport less error prone by always defining cumulativeHeights (Closed)
Patch Set: Created 3 years, 8 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 this.element.addEventListener('scroll', this._onScroll.bind(this), false); 55 this.element.addEventListener('scroll', this._onScroll.bind(this), false);
56 this.element.addEventListener('copy', this._onCopy.bind(this), false); 56 this.element.addEventListener('copy', this._onCopy.bind(this), false);
57 this.element.addEventListener('dragstart', this._onDragStart.bind(this), fal se); 57 this.element.addEventListener('dragstart', this._onDragStart.bind(this), fal se);
58 58
59 this._firstActiveIndex = 0; 59 this._firstActiveIndex = 0;
60 this._lastActiveIndex = -1; 60 this._lastActiveIndex = -1;
61 this._renderedItems = []; 61 this._renderedItems = [];
62 this._anchorSelection = null; 62 this._anchorSelection = null;
63 this._headSelection = null; 63 this._headSelection = null;
64 this._itemCount = 0; 64 this._itemCount = 0;
65 this._cumulativeHeights = new Int32Array(0);
65 66
66 // Listen for any changes to descendants and trigger a refresh. This ensures 67 // Listen for any changes to descendants and trigger a refresh. This ensures
67 // that items updated asynchronously will not break stick-to-bottom behavior 68 // that items updated asynchronously will not break stick-to-bottom behavior
68 // if they change the scroll height. 69 // if they change the scroll height.
69 this._observer = new MutationObserver(this.refresh.bind(this)); 70 this._observer = new MutationObserver(this.refresh.bind(this));
70 this._observerConfig = {childList: true, subtree: true}; 71 this._observerConfig = {childList: true, subtree: true};
71 } 72 }
72 73
73 /** 74 /**
74 * @return {boolean} 75 * @return {boolean}
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 } 114 }
114 115
115 /** 116 /**
116 * @return {!Element} 117 * @return {!Element}
117 */ 118 */
118 contentElement() { 119 contentElement() {
119 return this._contentElement; 120 return this._contentElement;
120 } 121 }
121 122
122 invalidate() { 123 invalidate() {
123 delete this._cumulativeHeights;
124 delete this._cachedProviderElements; 124 delete this._cachedProviderElements;
125 this._itemCount = this._provider.itemCount(); 125 this._itemCount = this._provider.itemCount();
126 this._rebuildCumulativeHeights();
126 this.refresh(); 127 this.refresh();
127 } 128 }
128 129
129 /** 130 /**
130 * @param {number} index 131 * @param {number} index
131 * @return {?Console.ConsoleViewportElement} 132 * @return {?Console.ConsoleViewportElement}
132 */ 133 */
133 _providerElement(index) { 134 _providerElement(index) {
134 if (!this._cachedProviderElements) 135 if (!this._cachedProviderElements)
135 this._cachedProviderElements = new Array(this._itemCount); 136 this._cachedProviderElements = new Array(this._itemCount);
136 var element = this._cachedProviderElements[index]; 137 var element = this._cachedProviderElements[index];
137 if (!element) { 138 if (!element) {
138 element = this._provider.itemElement(index); 139 element = this._provider.itemElement(index);
139 this._cachedProviderElements[index] = element; 140 this._cachedProviderElements[index] = element;
140 } 141 }
141 return element; 142 return element;
142 } 143 }
143 144
144 _rebuildCumulativeHeightsIfNeeded() { 145 _rebuildCumulativeHeights() {
145 if (this._cumulativeHeights) 146 if (!this._itemCount) {
dgozman 2017/04/07 20:31:44 I think this special-casing is not needed anymore.
luoe 2017/04/07 22:09:54 Done.
147 this._cumulativeHeights = new Int32Array(0);
146 return; 148 return;
147 if (!this._itemCount) 149 }
148 return;
149 var firstActiveIndex = this._firstActiveIndex; 150 var firstActiveIndex = this._firstActiveIndex;
150 var lastActiveIndex = this._lastActiveIndex; 151 var lastActiveIndex = this._lastActiveIndex;
151 var height = 0; 152 var height = 0;
152 this._cumulativeHeights = new Int32Array(this._itemCount); 153 this._cumulativeHeights = new Int32Array(this._itemCount);
153 for (var i = 0; i < this._itemCount; ++i) { 154 for (var i = 0; i < this._itemCount; ++i) {
154 if (firstActiveIndex <= i && i <= lastActiveIndex) 155 if (firstActiveIndex <= i && i <= lastActiveIndex)
155 height += this._renderedItems[i - firstActiveIndex].element().offsetHeig ht; 156 height += this._renderedItems[i - firstActiveIndex].element().offsetHeig ht;
156 else 157 else
157 height += this._provider.fastHeight(i); 158 height += this._provider.fastHeight(i);
158 this._cumulativeHeights[i] = height; 159 this._cumulativeHeights[i] = height;
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 } 318 }
318 319
319 var selection = this.element.getComponentSelection(); 320 var selection = this.element.getComponentSelection();
320 var shouldRestoreSelection = this._updateSelectionModel(selection); 321 var shouldRestoreSelection = this._updateSelectionModel(selection);
321 322
322 var visibleFrom = this.element.scrollTop; 323 var visibleFrom = this.element.scrollTop;
323 var visibleHeight = this._visibleHeight(); 324 var visibleHeight = this._visibleHeight();
324 325
325 for (var i = 0; i < this._renderedItems.length; ++i) { 326 for (var i = 0; i < this._renderedItems.length; ++i) {
326 // Tolerate 1-pixel error due to double-to-integer rounding errors. 327 // Tolerate 1-pixel error due to double-to-integer rounding errors.
327 if (this._cumulativeHeights && 328 var cachedItemHeight = this._cachedItemHeight(this._firstActiveIndex + i);
328 Math.abs(this._cachedItemHeight(this._firstActiveIndex + i) - this._re nderedItems[i].element().offsetHeight) > 329 if (Math.abs(cachedItemHeight - this._renderedItems[i].element().offsetHei ght) > 1) {
329 1) 330 this._rebuildCumulativeHeights();
330 delete this._cumulativeHeights; 331 break;
332 }
331 } 333 }
332 this._rebuildCumulativeHeightsIfNeeded();
333 var activeHeight = visibleHeight * 2; 334 var activeHeight = visibleHeight * 2;
334 // When the viewport is scrolled to the bottom, using the cumulative heights estimate is not 335 // When the viewport is scrolled to the bottom, using the cumulative heights estimate is not
335 // precise enough to determine next visible indices. This stickToBottom chec k avoids extra 336 // precise enough to determine next visible indices. This stickToBottom chec k avoids extra
336 // calls to refresh in those cases. 337 // calls to refresh in those cases.
337 if (this._stickToBottom) { 338 if (this._stickToBottom) {
338 this._firstActiveIndex = 339 this._firstActiveIndex =
339 Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.min imumRowHeight()), 0); 340 Math.max(this._itemCount - Math.ceil(activeHeight / this._provider.min imumRowHeight()), 0);
340 this._lastActiveIndex = this._itemCount - 1; 341 this._lastActiveIndex = this._itemCount - 1;
341 } else { 342 } else {
342 this._firstActiveIndex = Math.max( 343 this._firstActiveIndex = Math.max(
343 Array.prototype.lowerBound.call( 344 Int32Array.prototype.lowerBound.call(
344 this._cumulativeHeights, visibleFrom + 1 - (activeHeight - visible Height) / 2), 345 this._cumulativeHeights, visibleFrom + 1 - (activeHeight - visible Height) / 2),
345 0); 346 0);
346 // Proactively render more rows in case some of them will be collapsed wit hout triggering refresh. @see crbug.com/390169 347 // Proactively render more rows in case some of them will be collapsed wit hout triggering refresh. @see crbug.com/390169
347 this._lastActiveIndex = this._firstActiveIndex + Math.ceil(activeHeight / this._provider.minimumRowHeight()) - 1; 348 this._lastActiveIndex = this._firstActiveIndex + Math.ceil(activeHeight / this._provider.minimumRowHeight()) - 1;
348 this._lastActiveIndex = Math.min(this._lastActiveIndex, this._itemCount - 1); 349 this._lastActiveIndex = Math.min(this._lastActiveIndex, this._itemCount - 1);
349 } 350 }
350 351
351 var topGapHeight = this._cumulativeHeights[this._firstActiveIndex - 1] || 0; 352 var topGapHeight = this._cumulativeHeights[this._firstActiveIndex - 1] || 0;
352 var bottomGapHeight = 353 var bottomGapHeight =
353 this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumu lativeHeights[this._lastActiveIndex]; 354 this._cumulativeHeights[this._cumulativeHeights.length - 1] - this._cumu lativeHeights[this._lastActiveIndex];
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
468 */ 469 */
469 _onScroll(event) { 470 _onScroll(event) {
470 this.refresh(); 471 this.refresh();
471 } 472 }
472 473
473 /** 474 /**
474 * @return {number} 475 * @return {number}
475 */ 476 */
476 firstVisibleIndex() { 477 firstVisibleIndex() {
477 var firstVisibleIndex = 478 var firstVisibleIndex =
478 Math.max(Array.prototype.lowerBound.call(this._cumulativeHeights, this.e lement.scrollTop + 1), 0); 479 Math.max(Int32Array.prototype.lowerBound.call(this._cumulativeHeights, t his.element.scrollTop + 1), 0);
479 return Math.max(firstVisibleIndex, this._firstActiveIndex); 480 return Math.max(firstVisibleIndex, this._firstActiveIndex);
480 } 481 }
481 482
482 /** 483 /**
483 * @return {number} 484 * @return {number}
484 */ 485 */
485 lastVisibleIndex() { 486 lastVisibleIndex() {
486 var lastVisibleIndex; 487 var lastVisibleIndex;
487 if (this._stickToBottom) { 488 if (this._stickToBottom) {
488 lastVisibleIndex = this._itemCount - 1; 489 lastVisibleIndex = this._itemCount - 1;
(...skipping 30 matching lines...) Expand all
519 this.forceScrollItemToBeFirst(index); 520 this.forceScrollItemToBeFirst(index);
520 else if (index >= lastVisibleIndex) 521 else if (index >= lastVisibleIndex)
521 this.forceScrollItemToBeLast(index); 522 this.forceScrollItemToBeLast(index);
522 } 523 }
523 524
524 /** 525 /**
525 * @param {number} index 526 * @param {number} index
526 */ 527 */
527 forceScrollItemToBeFirst(index) { 528 forceScrollItemToBeFirst(index) {
528 this.setStickToBottom(false); 529 this.setStickToBottom(false);
529 this._rebuildCumulativeHeightsIfNeeded();
530 this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0; 530 this.element.scrollTop = index > 0 ? this._cumulativeHeights[index - 1] : 0;
531 if (this.element.isScrolledToBottom()) 531 if (this.element.isScrolledToBottom())
532 this.setStickToBottom(true); 532 this.setStickToBottom(true);
533 this.refresh(); 533 this.refresh();
534 } 534 }
535 535
536 /** 536 /**
537 * @param {number} index 537 * @param {number} index
538 */ 538 */
539 forceScrollItemToBeLast(index) { 539 forceScrollItemToBeLast(index) {
540 this.setStickToBottom(false); 540 this.setStickToBottom(false);
541 this._rebuildCumulativeHeightsIfNeeded();
luoe 2017/04/07 01:19:38 By default, CH is an empty typed array if there ar
542 this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeigh t(); 541 this.element.scrollTop = this._cumulativeHeights[index] - this._visibleHeigh t();
543 if (this.element.isScrolledToBottom()) 542 if (this.element.isScrolledToBottom())
544 this.setStickToBottom(true); 543 this.setStickToBottom(true);
545 this.refresh(); 544 this.refresh();
546 } 545 }
547 546
548 /** 547 /**
549 * @return {number} 548 * @return {number}
550 */ 549 */
551 _visibleHeight() { 550 _visibleHeight() {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 Console.ConsoleViewportElement.prototype = { 597 Console.ConsoleViewportElement.prototype = {
599 willHide() {}, 598 willHide() {},
600 599
601 wasShown() {}, 600 wasShown() {},
602 601
603 /** 602 /**
604 * @return {!Element} 603 * @return {!Element}
605 */ 604 */
606 element() {}, 605 element() {},
607 }; 606 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698