Source/WebInspectorUI/ChangeLog

 12018-10-12 Devin Rousso <drousso@apple.com>
 2
 3 Web Inspector: Canvas Recording loading goes significantly slower when "Frame" tree element is expanded
 4 https://bugs.webkit.org/show_bug.cgi?id=190497
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 Save the `WI.TreeElement` that are in the DOM, and compare that with any `WI.TreeElement`
 9 that would be added to the DOM. If all of the following are true, don't edit the DOM:
 10 - no focused `WI.TreeElement` that isn't currently visible (we would scroll otherwise)
 11 - the set of previously visible `WI.TreeElement`s (e.g. not used for scroll padding) has at
 12 least one of the `WI.TreeElement`s that would be added from this update
 13 - this means that the user hasn't scrolled beyond the padding `WI.TreeElement`
 14 - there are no `WI.TreeElement`s that would be added from this update that were NOT added
 15 in a previous update
 16 - this covers the case that a `WI.TreeElement` is inserted in the visible area
 17
 18 * UserInterface/Base/Utilities.js:
 19
 20 * UserInterface/Views/TreeOutline.js:
 21 (WI.TreeOutline):
 22 (WI.TreeOutline.prototype.registerScrollVirtualizer):
 23 (WI.TreeOutline.prototype.updateVirtualizedElements.walk):
 24 (WI.TreeOutline.prototype.updateVirtualizedElements):
 25
1262018-10-11 Devin Rousso <drousso@apple.com>
227
328 Web Inspector: Network: detail view reverts to "Response" when new requests are added

Source/WebInspectorUI/UserInterface/Base/Utilities.js

@@Object.defineProperty(Map.prototype, "take",
118118 }
119119});
120120
 121Object.defineProperty(Set.prototype, "intersects",
 122{
 123 value(other)
 124 {
 125 if (!this.size || !other.size)
 126 return false;
 127
 128 for (let item of this) {
 129 if (other.has(item))
 130 return true;
 131 }
 132
 133 return false;
 134 },
 135});
 136
 137Object.defineProperty(Set.prototype, "contains",
 138{
 139 value(other)
 140 {
 141 if (!this.size || !other.size)
 142 return false;
 143
 144 for (let item of other) {
 145 if (!this.has(item))
 146 return false;
 147 }
 148
 149 return true;
 150 },
 151});
 152
121153Object.defineProperty(Node.prototype, "enclosingNodeOrSelfWithClass",
122154{
123155 value(className)

Source/WebInspectorUI/UserInterface/Views/TreeOutline.js

@@WI.TreeOutline = class TreeOutline extends WI.Object
5555 this._customIndent = false;
5656 this._selectable = selectable;
5757
58  this._virtualizedCurrentMiddleItem = NaN;
 58 this._virtualizedVisibleTreeElements = null;
 59 this._virtualizedAttachedTreeElements = null;
5960 this._virtualizedScrollContainer = null;
6061 this._virtualizedTreeItemHeight = NaN;
6162 this._virtualizedTopSpacer = null;

@@WI.TreeOutline = class TreeOutline extends WI.Object
654655 {
655656 console.assert(!isNaN(treeItemHeight));
656657
 658 this._virtualizedVisibleTreeElements = new Set;
 659 this._virtualizedAttachedTreeElements = new Set;
657660 this._virtualizedScrollContainer = scrollContainer;
658661 this._virtualizedTreeItemHeight = treeItemHeight;
659662 this._virtualizedTopSpacer = document.createElement("div");
660663 this._virtualizedBottomSpacer = document.createElement("div");
661664
 665 let throttler = this.throttle(1000 / 16);
662666 this._virtualizedScrollContainer.addEventListener("scroll", (event) => {
663  let {numberVisible, extraRows, firstItem} = this._calculateVirtualizedValues();
664 
665  if (Math.abs(firstItem + (numberVisible / 2) - this._virtualizedCurrentMiddleItem) >= extraRows)
666  this.updateVirtualizedElements();
 667 throttler.updateVirtualizedElements();
667668 });
668669 }
669670

@@WI.TreeOutline = class TreeOutline extends WI.Object
678679 if (!child.revealed(false))
679680 continue;
680681
681  shouldReturn = callback({
682  parent,
683  treeElement: child,
684  count,
685  });
 682 shouldReturn = callback(child, count);
686683 if (shouldReturn)
687684 break;
688685

@@WI.TreeOutline = class TreeOutline extends WI.Object
701698
702699 let shouldScroll = false;
703700 if (focusedTreeElement && focusedTreeElement.revealed(false)) {
704  let index = walk(this, ({treeElement}) => treeElement === focusedTreeElement).count;
 701 let index = walk(this, (treeElement) => treeElement === focusedTreeElement).count;
705702 if (index < firstItem) {
706703 firstItem = index - extraRows;
707704 lastItem = index + numberVisible + extraRows;

@@WI.TreeOutline = class TreeOutline extends WI.Object
715712 shouldScroll = (index < firstItem + extraRows) || (index > lastItem - extraRows);
716713 }
717714
718  let totalItems = walk(this, ({parent, treeElement, count}) => {
 715 console.assert(firstItem < lastItem);
 716
 717 let visibleTreeElements = new Set;
 718 let treeElementsToAttach = new Set;
 719 let treeElementsToDetach = new Set;
 720 let totalItems = walk(this, (treeElement, count) => {
719721 if (count >= firstItem && count <= lastItem) {
720  parent._childrenListNode.appendChild(treeElement.element);
721  if (treeElement._childrenListNode)
722  parent._childrenListNode.appendChild(treeElement._childrenListNode);
723  } else
724  treeElement.element.remove();
 722 treeElementsToAttach.add(treeElement);
 723 if (count >= firstItem + extraRows && count <= lastItem - extraRows)
 724 visibleTreeElements.add(treeElement);
 725 } else if (treeElement.element.parentNode)
 726 treeElementsToDetach.add(treeElement);
725727
726728 return false;
727729 }).count;
728730
 731 // Redraw if we are about to scroll.
 732 if (!shouldScroll) {
 733 // Redraw if all of the previously centered `WI.TreeElement` are no longer centered.
 734 if (this._virtualizedVisibleTreeElements.intersects(visibleTreeElements)) {
 735 // Redraw if there is a `WI.TreeElement` that should be shown that isn't attached.
 736 if (this._virtualizedAttachedTreeElements.contains(visibleTreeElements))
 737 return;
 738 }
 739 }
 740
 741 this._virtualizedVisibleTreeElements = visibleTreeElements;
 742 this._virtualizedAttachedTreeElements = treeElementsToAttach;
 743
 744 for (let treeElement of treeElementsToDetach)
 745 treeElement.element.remove();
 746
 747 for (let treeElement of treeElementsToAttach) {
 748 treeElement.parent._childrenListNode.appendChild(treeElement.element);
 749 if (treeElement._childrenListNode)
 750 treeElement.parent._childrenListNode.appendChild(treeElement._childrenListNode);
 751 }
 752
729753 this._virtualizedTopSpacer.style.height = (Math.max(firstItem, 0) * this._virtualizedTreeItemHeight) + "px";
730  this.element.parentNode.insertBefore(this._virtualizedTopSpacer, this.element);
 754 if (this.element.previousElementSibling !== this._virtualizedTopSpacer)
 755 this.element.parentNode.insertBefore(this._virtualizedTopSpacer, this.element);
731756
732757 this._virtualizedBottomSpacer.style.height = (Math.max(totalItems - lastItem, 0) * this._virtualizedTreeItemHeight) + "px";
733  this.element.parentNode.insertBefore(this._virtualizedBottomSpacer, this.element.nextElementSibling);
 758 if (this.element.nextElementSibling !== this._virtualizedBottomSpacer)
 759 this.element.parentNode.insertBefore(this._virtualizedBottomSpacer, this.element.nextElementSibling);
734760
735761 if (shouldScroll)
736762 this._virtualizedScrollContainer.scrollTop = (firstItem + extraRows) * this._virtualizedTreeItemHeight;
737 
738  this._virtualizedCurrentMiddleItem = firstItem + (numberVisible / 2);
739763 }
740764
741765 // Protected

LayoutTests/ChangeLog

 12018-10-12 Devin Rousso <drousso@apple.com>
 2
 3 Web Inspector: Canvas Recording loading goes significantly slower when "Frame" tree element is expanded
 4 https://bugs.webkit.org/show_bug.cgi?id=190497
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * inspector/unit-tests/set-utilities-expected.txt: Added.
 9 * inspector/unit-tests/set-utilities.html: Added.
 10
1112018-10-08 Yusuke Suzuki <yusukesuzuki@slowstart.org>
212
313 [JSC] JSC should have "parseFunction" to optimize Function constructor

LayoutTests/inspector/unit-tests/set-utilities-expected.txt

 1
 2== Running test suite: SetUtilities
 3-- Running test case: Set.prototype.intersects
 4PASS: empy sets should not intersect.
 5PASS: sets with the same values should intersect.
 6PASS: sets with the different values should not intersect.
 7PASS: sets with same and different values should intersect.
 8
 9-- Running test case: Set.prototype.contains
 10PASS: an empy sets should not contain another empty set.
 11PASS: a set should contain another set with the same values.
 12PASS: a set should not contain another set with different values.
 13PASS: a set should not contain another set with same and different values.
 14

LayoutTests/inspector/unit-tests/set-utilities.html

 1<!DOCTYPE html>
 2<html>
 3<head>
 4<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
 5<script>
 6function test()
 7{
 8 let suite = InspectorTest.createSyncSuite("SetUtilities");
 9
 10 suite.addTestCase({
 11 name: "Set.prototype.intersects",
 12 test() {
 13 function testTrue(a, b, message) {
 14 InspectorTest.expectThat((new Set(a)).intersects(new Set(b)), message);
 15 }
 16
 17 function testFalse(a, b, message) {
 18 InspectorTest.expectFalse((new Set(a)).intersects(new Set(b)), message);
 19 }
 20
 21 const object1 = {a: 1};
 22 const object2 = {b: 2};
 23 const object3 = {c: 3};
 24
 25 testFalse([], [], "empy sets should not intersect.");
 26 testTrue([1, "a", object1], [1, "a", object1], "sets with the same values should intersect.");
 27 testFalse([1, "a", object1], [2, "b", object2], "sets with the different values should not intersect.");
 28 testTrue([1, 2, "a", "b", object1, object2], [1, 3, "a", "c", object1, object3], "sets with same and different values should intersect.");
 29
 30 return true;
 31 }
 32 });
 33
 34 suite.addTestCase({
 35 name: "Set.prototype.contains",
 36 test() {
 37 function testTrue(a, b, message) {
 38 InspectorTest.expectThat((new Set(a)).contains(new Set(b)), message);
 39 }
 40
 41 function testFalse(a, b, message) {
 42 InspectorTest.expectFalse((new Set(a)).contains(new Set(b)), message);
 43 }
 44
 45 const object1 = {a: 1};
 46 const object2 = {b: 2};
 47 const object3 = {c: 3};
 48
 49 testFalse([], [], "an empy sets should not contain another empty set.");
 50 testTrue([1, "a", object1], [1, "a", object1], "a set should contain another set with the same values.");
 51 testFalse([1, "a", object1], [2, "b", object2], "a set should not contain another set with different values.");
 52 testFalse([1, 2, "a", "b", object1, object2], [1, 3, "a", "c", object1, object3], "a set should not contain another set with same and different values.");
 53
 54 return true;
 55 }
 56 });
 57
 58 suite.runTestCasesAndFinish();
 59}
 60</script>
 61</head>
 62<body onLoad="runTest()">
 63</body>
 64</html>