Changeset 220180 in webkit
- Timestamp:
- Aug 2, 2017 9:21:32 PM (7 years ago)
- Location:
- trunk/Source/WebInspectorUI
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebInspectorUI/ChangeLog
r220119 r220180 1 2017-08-02 Devin Rousso <drousso@apple.com> 2 3 Web Inspector: add TreeElement virtualization for the Recording tab 4 https://bugs.webkit.org/show_bug.cgi?id=174968 5 6 Reviewed by Joseph Pecoraro. 7 8 * UserInterface/Views/RecordingNavigationSidebarPanel.js: 9 (WI.RecordingNavigationSidebarPanel): 10 11 * UserInterface/Views/TreeOutline.js: 12 (WI.TreeOutline): 13 (WI.TreeOutline.prototype.get virtualized): 14 (WI.TreeOutline.prototype.registerScrollVirtualizer): 15 (WI.TreeOutline.prototype.updateVirtualizedElements.walk): 16 (WI.TreeOutline.prototype.updateVirtualizedElements): 17 Add spacer elements before and after the TreeOutline element that will size to ensure that 18 the TreeOutline node still takes up the same amount of space after some of the TreeElements 19 are removed. Whenever the scroll of the container view changes, recalculate the visible area 20 and add/remove TreeElements based on whether they would be in that. This is only possible if 21 every TreeElement has the same vertical height, which is given when setting up the scroll 22 listener on the container view. 23 24 * UserInterface/Views/TreeElement.js: 25 (WI.TreeElement.prototype.set hidden): 26 (WI.TreeElement.prototype._attach): 27 (WI.TreeElement.prototype.collapse): 28 (WI.TreeElement.prototype.expand): 29 (WI.TreeElement.prototype.reveal): 30 If the TreeOutline is being virtualized, don't add each TreeElement's node to the DOM. They 31 will be added at the end of the frame (via setTimeout) if they are within the visible + padding 32 area of the TreeOutline. 33 1 34 2017-08-01 Devin Rousso <drousso@apple.com> 2 35 -
trunk/Source/WebInspectorUI/UserInterface/Views/RecordingNavigationSidebarPanel.js
r220119 r220180 31 31 32 32 this.contentTreeOutline.customIndent = true; 33 this.contentTreeOutline.registerScrollVirtualizer(this.contentView.element, 20); 33 34 34 35 this.filterBar.placeholder = WI.UIString("Filter Actions"); -
trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js
r220119 r220180 166 166 this._childrenListNode.hidden = this._hidden; 167 167 168 if (this.treeOutline) 168 if (this.treeOutline) { 169 this.treeOutline.soon.updateVirtualizedElements(this); 170 169 171 this.treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementVisibilityDidChange, {element: this}); 172 } 170 173 } 171 174 … … 245 248 if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode) 246 249 nextSibling = this.nextSibling._listItemNode; 247 this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling); 248 if (this._childrenListNode) 249 this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling); 250 251 if (!this.treeOutline || !this.treeOutline.virtualized) { 252 this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling); 253 if (this._childrenListNode) 254 this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling); 255 } 256 257 if (this.treeOutline) 258 this.treeOutline.soon.updateVirtualizedElements(); 259 250 260 if (this.selected) 251 261 this.select(); … … 335 345 this.oncollapse(this); 336 346 337 if (this.treeOutline) 347 if (this.treeOutline) { 348 this.treeOutline.soon.updateVirtualizedElements(this); 349 338 350 this.treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementDisclosureDidChanged, {element: this}); 351 } 339 352 } 340 353 … … 399 412 this.onexpand(this); 400 413 401 if (this.treeOutline) 414 if (this.treeOutline) { 415 this.treeOutline.soon.updateVirtualizedElements(this); 416 402 417 this.treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementDisclosureDidChanged, {element: this}); 418 } 403 419 } 404 420 … … 446 462 currentAncestor = currentAncestor.parent; 447 463 } 464 465 // This must be called before onreveal, as some subclasses will scrollIntoViewIfNeeded and 466 // we should update the visible elements before attempting to scroll. 467 if (this.treeOutline) 468 this.treeOutline.updateVirtualizedElements(this); 448 469 449 470 if (this.onreveal) -
trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js
r220119 r220180 54 54 this._disclosureButtons = true; 55 55 this._customIndent = false; 56 57 this._virtualizedScrollContainer = null; 58 this._virtualizedTreeItemHeight = NaN; 59 this._virtualizedTopSpacer = null; 60 this._virtualizedBottomSpacer = null; 56 61 57 62 this._childrenListNode.tabIndex = 0; … … 634 639 } 635 640 641 get virtualized() 642 { 643 return this._virtualizedScrollContainer && !isNaN(this._virtualizedTreeItemHeight); 644 } 645 646 registerScrollVirtualizer(scrollContainer, treeItemHeight) 647 { 648 console.assert(!isNaN(treeItemHeight)); 649 650 this._virtualizedScrollContainer = scrollContainer; 651 this._virtualizedTreeItemHeight = treeItemHeight; 652 this._virtualizedTopSpacer = document.createElement("div"); 653 this._virtualizedBottomSpacer = document.createElement("div"); 654 655 this._virtualizedScrollContainer.addEventListener("scroll", (event) => { 656 this.updateVirtualizedElements(); 657 }); 658 } 659 660 updateVirtualizedElements(focusedTreeElement) 661 { 662 if (!this.virtualized) 663 return; 664 665 function walk(parent, callback) { 666 let count = 0; 667 let shouldReturn = false; 668 for (let i = 0; i < parent.children.length; ++i) { 669 if (!parent.children[i].revealed(false)) 670 continue; 671 672 shouldReturn = callback({ 673 parent, 674 treeElement: parent.children[i], 675 count, 676 }); 677 if (shouldReturn) 678 break; 679 680 ++count; 681 if (parent.children[i].expanded) { 682 let result = walk(parent.children[i], callback); 683 count += result.count; 684 if (result.shouldReturn) 685 break; 686 } 687 } 688 return {count, shouldReturn}; 689 } 690 691 let numberVisible = Math.ceil(this._virtualizedScrollContainer.offsetHeight / this._virtualizedTreeItemHeight); 692 let extraRows = Math.max(numberVisible * 5, 50); 693 let firstItem = Math.floor(this._virtualizedScrollContainer.scrollTop / this._virtualizedTreeItemHeight) - extraRows; 694 let lastItem = firstItem + numberVisible + (extraRows * 2); 695 696 if (focusedTreeElement && focusedTreeElement.revealed(false)) { 697 let index = walk(this, ({treeElement}) => treeElement === focusedTreeElement).count; 698 if (index < firstItem) { 699 firstItem = index - extraRows; 700 lastItem = index + numberVisible + extraRows; 701 } else if (index > lastItem) { 702 firstItem = index - numberVisible - extraRows; 703 lastItem = index + extraRows; 704 } 705 } 706 707 let totalItems = walk(this, ({parent, treeElement, count}) => { 708 if (count < firstItem || count > lastItem) 709 treeElement.element.remove(); 710 else { 711 parent._childrenListNode.appendChild(treeElement.element); 712 if (treeElement._childrenListNode) 713 parent._childrenListNode.appendChild(treeElement._childrenListNode); 714 } 715 return false; 716 }).count; 717 718 this._virtualizedTopSpacer.style.height = (Math.max(firstItem, 0) * this._virtualizedTreeItemHeight) + "px"; 719 this.element.parentNode.insertBefore(this._virtualizedTopSpacer, this.element); 720 721 this._virtualizedBottomSpacer.style.height = (Math.max(totalItems - lastItem, 0) * this._virtualizedTreeItemHeight) + "px"; 722 this.element.parentNode.insertBefore(this._virtualizedBottomSpacer, this.element.nextElementSibling); 723 724 if (focusedTreeElement) 725 this._virtualizedScrollContainer.scrollTop = (firstItem + extraRows) * this._virtualizedTreeItemHeight; 726 } 727 636 728 // Protected 637 729
Note: See TracChangeset
for help on using the changeset viewer.