⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 243242 in webkit


Ignore:
Timestamp:
Mar 20, 2019, 2:49:13 PM (7 years ago)
Author:
Devin Rousso
Message:

Web Inspector: Debugger: virtualize the list of variables in the Scope sidebar
https://bugs.webkit.org/show_bug.cgi?id=192648
<rdar://problem/46800949>

Reviewed by Joseph Pecoraro.

Source/WebInspectorUI:

  • UserInterface/Views/ScopeChainDetailsSidebarPanel.js:

(WI.ScopeChainDetailsSidebarPanel.prototype._generateCallFramesSection):

  • UserInterface/Views/TreeElement.js:

(WI.TreeElement.prototype.set hidden):
(WI.TreeElement.prototype._attach):
(WI.TreeElement.prototype._detach):
(WI.TreeElement.prototype.collapse):
(WI.TreeElement.prototype.expand):
Move updateVirtualizedElements calls to the owner WI.TreeOutline to ensure that they get
called. Make the remaining calls use rAF debouncing to better coalesce updates.

  • UserInterface/Views/TreeOutline.js:

(WI.TreeOutline.prototype._rememberTreeElement):
(WI.TreeOutline.prototype._forgetTreeElement):
(WI.TreeOutline.prototype.registerScrollVirtualizer):
(WI.TreeOutline.prototype._updateVirtualizedElements.calculateOffsetFromContainer): Added.
(WI.TreeOutline.prototype._updateVirtualizedElements):
(WI.TreeOutline.prototype._calculateVirtualizedValues): Deleted.
Calculate the WI.TreeOutline's top offset within the scroll container so that it will only
update when it's within the visual area.

  • UserInterface/Views/Utilities.js:

(Array.prototype.remove):
Return whether the item was actually removed from the array.

LayoutTests:

  • inspector/unit-tests/array-utilities.html:
  • inspector/unit-tests/array-utilities-expected.txt:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r243241 r243242  
     12019-03-20  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Debugger: virtualize the list of variables in the Scope sidebar
     4        https://bugs.webkit.org/show_bug.cgi?id=192648
     5        <rdar://problem/46800949>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/unit-tests/array-utilities.html:
     10        * inspector/unit-tests/array-utilities-expected.txt:
     11
    1122019-03-20  Dean Jackson  <dino@apple.com>
    213
  • trunk/LayoutTests/inspector/unit-tests/array-utilities-expected.txt

    r240559 r243242  
    9797
    9898-- Running test case: Array.prototype.remove
     99PASS: remove should return true when removing a value that exists.
    99100PASS: remove should only remove the first matching value.
     101PASS: remove should return true when removing a value that exists.
     102PASS: remove should return false when removing a value that does not exist.
    100103PASS: remove should only remove values that strictly match.
     104PASS: remove should return false when removing a value that does not exist.
     105PASS: remove should return false when removing a value that does not exist.
     106PASS: remove should not affect the array if the value does not exist.
    101107
    102108-- Running test case: Array.prototype.removeAll
  • trunk/LayoutTests/inspector/unit-tests/array-utilities.html

    r240559 r243242  
    214214        test() {
    215215            let arr1 = [1, 2, 3, 1];
    216             arr1.remove(1);
     216            InspectorTest.expectThat(arr1.remove(1), "remove should return true when removing a value that exists.");
    217217            InspectorTest.expectShallowEqual(arr1, [2, 3, 1], "remove should only remove the first matching value.");
    218218
    219219            let arr2 = ["1", "2", 3, 1];
    220             arr2.remove("1");
    221             arr2.remove(2);
     220            InspectorTest.expectThat(arr2.remove("1"), "remove should return true when removing a value that exists.");
     221            InspectorTest.expectFalse(arr2.remove(2), "remove should return false when removing a value that does not exist.");
    222222            InspectorTest.expectShallowEqual(arr2, ["2", 3, 1], "remove should only remove values that strictly match.");
    223223
    224             return true;
     224            let arr3 = [1, 2, 3];
     225            InspectorTest.expectFalse(arr3.remove("1"), "remove should return false when removing a value that does not exist.");
     226            InspectorTest.expectFalse(arr3.remove(4), "remove should return false when removing a value that does not exist.");
     227            InspectorTest.expectShallowEqual(arr3, [1, 2, 3], "remove should not affect the array if the value does not exist.");
    225228        }
    226229    });
  • trunk/Source/WebInspectorUI/ChangeLog

    r243238 r243242  
     12019-03-20  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: Debugger: virtualize the list of variables in the Scope sidebar
     4        https://bugs.webkit.org/show_bug.cgi?id=192648
     5        <rdar://problem/46800949>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
     10        (WI.ScopeChainDetailsSidebarPanel.prototype._generateCallFramesSection):
     11
     12        * UserInterface/Views/TreeElement.js:
     13        (WI.TreeElement.prototype.set hidden):
     14        (WI.TreeElement.prototype._attach):
     15        (WI.TreeElement.prototype._detach):
     16        (WI.TreeElement.prototype.collapse):
     17        (WI.TreeElement.prototype.expand):
     18        Move `updateVirtualizedElements` calls to the owner `WI.TreeOutline` to ensure that they get
     19        called. Make the remaining calls use rAF debouncing to better coalesce updates.
     20
     21        * UserInterface/Views/TreeOutline.js:
     22        (WI.TreeOutline.prototype._rememberTreeElement):
     23        (WI.TreeOutline.prototype._forgetTreeElement):
     24        (WI.TreeOutline.prototype.registerScrollVirtualizer):
     25        (WI.TreeOutline.prototype._updateVirtualizedElements.calculateOffsetFromContainer): Added.
     26        (WI.TreeOutline.prototype._updateVirtualizedElements):
     27        (WI.TreeOutline.prototype._calculateVirtualizedValues): Deleted.
     28        Calculate the `WI.TreeOutline`'s top offset within the scroll container so that it will only
     29        update when it's within the visual area.
     30
     31        * UserInterface/Views/Utilities.js:
     32        (Array.prototype.remove):
     33        Return whether the item was actually removed from the array.
     34
    1352019-03-20  Joseph Pecoraro  <pecoraro@apple.com>
    236
  • trunk/Source/WebInspectorUI/UserInterface/Base/Utilities.js

    r242562 r243242  
    586586            if (this[i] === value) {
    587587                this.splice(i, 1);
    588                 return;
     588                return true;
    589589            }
    590590        }
     591        return false;
    591592    }
    592593});
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js

    r238005 r243242  
    262262
    263263                let treeOutline = objectTree.treeOutline;
     264                treeOutline.registerScrollVirtualizer(this.contentView.element, 16);
    264265                treeOutline.addEventListener(WI.TreeOutline.Event.ElementAdded, this._treeElementAdded.bind(this, detailsSectionIdentifier), this);
    265266                treeOutline.addEventListener(WI.TreeOutline.Event.ElementDisclosureDidChanged, this._treeElementDisclosureDidChange.bind(this, detailsSectionIdentifier), this);
  • trunk/Source/WebInspectorUI/UserInterface/Views/TreeElement.js

    r242017 r243242  
    166166
    167167        if (this.treeOutline) {
    168             if (this.treeOutline.virtualized) {
    169                 let focusedTreeElement = null;
    170                 if (!this._hidden && this.selected)
    171                     focusedTreeElement = this;
    172                 this.treeOutline.updateVirtualizedElementsDebouncer.delayForTime(0, focusedTreeElement);
    173             }
     168            if (this.treeOutline.virtualized)
     169                this.treeOutline.updateVirtualizedElementsDebouncer.delayForFrame();
    174170
    175171            this.treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementVisibilityDidChange, {element: this});
     
    270266        }
    271267
    272         if (this.treeOutline && this.treeOutline.virtualized)
    273             this.treeOutline.updateVirtualizedElementsDebouncer.delayForTime(0);
    274 
    275268        if (this.selected)
    276269            this.select();
     
    287280        if (this._childrenListNode && this._childrenListNode.parentNode)
    288281            this._childrenListNode.parentNode.removeChild(this._childrenListNode);
    289 
    290         if (this.treeOutline && this.treeOutline.virtualized)
    291             this.treeOutline.updateVirtualizedElementsDebouncer.delayForTime(0);
    292282    }
    293283
     
    355345            this.oncollapse(this);
    356346
    357         if (this.treeOutline && this.treeOutline.virtualized) {
    358             this.treeOutline.updateVirtualizedElementsDebouncer.delayForTime(0, this);
     347        if (this.treeOutline) {
     348            if (this.treeOutline.virtualized)
     349                this.treeOutline.updateVirtualizedElementsDebouncer.delayForFrame();
    359350
    360351            this.treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementDisclosureDidChanged, {element: this});
     
    422413            this.onexpand(this);
    423414
    424         if (this.treeOutline && this.treeOutline.virtualized) {
    425             this.treeOutline.updateVirtualizedElementsDebouncer.delayForTime(0, this);
     415        if (this.treeOutline) {
     416            if (this.treeOutline.virtualized)
     417                this.treeOutline.updateVirtualizedElementsDebouncer.delayForFrame();
    426418
    427419            this.treeOutline.dispatchEventToListeners(WI.TreeOutline.Event.ElementDisclosureDidChanged, {element: this});
  • trunk/Source/WebInspectorUI/UserInterface/Views/TreeOutline.js

    r242897 r243242  
    443443            this._knownTreeElements[element.identifier] = [];
    444444
    445         // check if the element is already known
    446445        var elements = this._knownTreeElements[element.identifier];
    447         if (elements.indexOf(element) !== -1)
    448             return;
    449 
    450         // add the element
    451         elements.push(element);
    452         this._cachedNumberOfDescendents++;
     446        if (!elements.includes(element)) {
     447            elements.push(element);
     448            this._cachedNumberOfDescendents++;
     449        }
     450
     451        if (this.virtualized)
     452            this._virtualizedDebouncer.delayForFrame();
    453453    }
    454454
     
    459459            this.selectedTreeElement = null;
    460460        }
     461
    461462        if (this._knownTreeElements[element.identifier]) {
    462             this._knownTreeElements[element.identifier].remove(element, true);
    463             this._cachedNumberOfDescendents--;
    464         }
     463            if (this._knownTreeElements[element.identifier].remove(element))
     464                this._cachedNumberOfDescendents--;
     465        }
     466
     467        if (this.virtualized)
     468            this._virtualizedDebouncer.delayForFrame();
    465469    }
    466470
     
    728732    registerScrollVirtualizer(scrollContainer, treeItemHeight)
    729733    {
     734        console.assert(scrollContainer);
    730735        console.assert(!isNaN(treeItemHeight));
     736        console.assert(!this.virtualized);
    731737
    732738        let boundUpdateVirtualizedElements = (focusedTreeElement) => {
     
    746752            throttler.fire();
    747753        });
     754
     755        this._updateVirtualizedElements();
    748756    }
    749757
     
    964972    }
    965973
    966     _calculateVirtualizedValues()
    967     {
    968         let numberVisible = Math.ceil(this._virtualizedScrollContainer.offsetHeight / this._virtualizedTreeItemHeight);
    969         let extraRows = Math.max(numberVisible * 5, 50);
    970         let firstItem = Math.floor(this._virtualizedScrollContainer.scrollTop / this._virtualizedTreeItemHeight) - extraRows;
    971         let lastItem = firstItem + numberVisible + (extraRows * 2);
    972         return {
    973             numberVisible,
    974             extraRows,
    975             firstItem,
    976             lastItem,
    977         };
    978     }
    979 
    980974    _updateVirtualizedElements(focusedTreeElement)
    981975    {
    982976        console.assert(this.virtualized);
     977
     978        this._virtualizedDebouncer.cancel();
    983979
    984980        function walk(parent, callback, count = 0) {
     
    1003999        }
    10041000
    1005         let {numberVisible, extraRows, firstItem, lastItem} = this._calculateVirtualizedValues();
     1001        function calculateOffsetFromContainer(node, target) {
     1002            let top = 0;
     1003            while (node !== target) {
     1004                top += node.offsetTop;
     1005                node = node.offsetParent;
     1006                if (!node)
     1007                    return 0;
     1008            }
     1009            return top;
     1010        }
     1011
     1012        let offsetFromContainer = calculateOffsetFromContainer(this._virtualizedTopSpacer.parentNode ? this._virtualizedTopSpacer : this.element, this._virtualizedScrollContainer);
     1013        let numberVisible = Math.ceil(Math.max(0, this._virtualizedScrollContainer.offsetHeight - offsetFromContainer) / this._virtualizedTreeItemHeight);
     1014        let extraRows = Math.max(numberVisible * 5, 50);
     1015        let firstItem = Math.floor((this._virtualizedScrollContainer.scrollTop - offsetFromContainer) / this._virtualizedTreeItemHeight) - extraRows;
     1016        let lastItem = firstItem + numberVisible + (extraRows * 2);
    10061017
    10071018        let shouldScroll = false;
     
    10311042                if (count >= firstItem + extraRows && count <= lastItem - extraRows)
    10321043                    visibleTreeElements.add(treeElement);
    1033             } else if (treeElement.element.parentNode)
     1044            } else if (treeElement._listItemNode.parentNode)
    10341045                treeElementsToDetach.add(treeElement);
    10351046
     
    10511062
    10521063        for (let treeElement of treeElementsToDetach)
    1053             treeElement.element.remove();
     1064            treeElement._listItemNode.remove();
    10541065
    10551066        for (let treeElement of treeElementsToAttach) {
    1056             treeElement.parent._childrenListNode.appendChild(treeElement.element);
     1067            treeElement.parent._childrenListNode.appendChild(treeElement._listItemNode);
    10571068            if (treeElement._childrenListNode)
    10581069                treeElement.parent._childrenListNode.appendChild(treeElement._childrenListNode);
    10591070        }
    10601071
    1061         this._virtualizedTopSpacer.style.height = (Math.max(firstItem, 0) * this._virtualizedTreeItemHeight) + "px";
     1072        this._virtualizedTopSpacer.style.height = (Number.constrain(firstItem, 0, totalItems) * this._virtualizedTreeItemHeight) + "px";
    10621073        if (this.element.previousElementSibling !== this._virtualizedTopSpacer)
    10631074            this.element.parentNode.insertBefore(this._virtualizedTopSpacer, this.element);
    10641075
    1065         this._virtualizedBottomSpacer.style.height = (Math.max(totalItems - lastItem, 0) * this._virtualizedTreeItemHeight) + "px";
     1076        this._virtualizedBottomSpacer.style.height = (Number.constrain(totalItems - lastItem, 0, totalItems) * this._virtualizedTreeItemHeight) + "px";
    10661077        if (this.element.nextElementSibling !== this._virtualizedBottomSpacer)
    10671078            this.element.parentNode.insertBefore(this._virtualizedBottomSpacer, this.element.nextElementSibling);
    10681079
    10691080        if (shouldScroll)
    1070             this._virtualizedScrollContainer.scrollTop = (firstItem + extraRows) * this._virtualizedTreeItemHeight;
     1081            this._virtualizedScrollContainer.scrollTop = offsetFromContainer + ((firstItem + extraRows) * this._virtualizedTreeItemHeight);
    10711082    }
    10721083
Note: See TracChangeset for help on using the changeset viewer.