Bug 1574623 - When switching to Messages panel with many messages, the table isn't scrolled down. r=Honza
authortanhengyeow <E0032242@u.nus.edu>
Wed, 21 Aug 2019 11:15:39 +0000
changeset 489166 d486a73f335879d316a5daf9d77da8fe693e7f85
parent 489165 4e11ff3ee0e72b60cea6f1c886e8dcd0ffdceaa9
child 489167 8769925846c8e0a10d79fa3c2a9372aeb7190f12
push id36465
push userdvarga@mozilla.com
push dateWed, 21 Aug 2019 16:47:43 +0000
treeherdermozilla-central@4ab60925635c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersHonza
bugs1574623
milestone70.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1574623 - When switching to Messages panel with many messages, the table isn't scrolled down. r=Honza Handle more cases for scroll to bottom. Differential Revision: https://phabricator.services.mozilla.com/D42482
devtools/client/netmonitor/src/assets/styles/websockets.css
devtools/client/netmonitor/src/components/websockets/FrameListContent.js
devtools/client/netmonitor/src/components/websockets/WebSocketsPanel.js
--- a/devtools/client/netmonitor/src/assets/styles/websockets.css
+++ b/devtools/client/netmonitor/src/assets/styles/websockets.css
@@ -140,8 +140,12 @@
   background-repeat: no-repeat;
   -moz-context-properties: fill;
   fill: inherit;
 }
 
 #messages-panel .truncation-checkbox {
   margin-right: 5px;
 }
+
+#messages-panel .truncated-message {
+  font-variant-numeric: tabular-nums;
+}
--- a/devtools/client/netmonitor/src/components/websockets/FrameListContent.js
+++ b/devtools/client/netmonitor/src/components/websockets/FrameListContent.js
@@ -43,58 +43,88 @@ class FrameListContent extends Component
   static get propTypes() {
     return {
       connector: PropTypes.object.isRequired,
       startPanelContainer: PropTypes.object,
       frames: PropTypes.array,
       selectedFrame: PropTypes.object,
       selectFrame: PropTypes.func.isRequired,
       columns: PropTypes.object.isRequired,
+      channelId: PropTypes.number,
     };
   }
 
   constructor(props) {
     super(props);
 
     this.framesLimit = Services.prefs.getIntPref(
       "devtools.netmonitor.ws.displayed-frames.limit"
     );
     this.currentTruncatedNum = 0;
     this.state = {
       checked: false,
     };
     this.pinnedToBottom = false;
     this.initIntersectionObserver = false;
+    this.intersectionObserver = null;
   }
 
-  componentDidUpdate() {
+  componentDidMount() {
     const { startPanelContainer } = this.props;
     const scrollAnchor = this.refs.scrollAnchor;
 
+    if (scrollAnchor) {
+      // Always scroll to anchor when FrameListContent component first mounts.
+      scrollAnchor.scrollIntoView();
+    }
+    this.setupScrollToBottom(startPanelContainer, scrollAnchor);
+  }
+
+  componentDidUpdate(prevProps) {
+    const { startPanelContainer, channelId } = this.props;
+    const scrollAnchor = this.refs.scrollAnchor;
+
     // When frames are cleared, the previous scrollAnchor would be destroyed, so we need to reset this boolean.
     if (!scrollAnchor) {
       this.initIntersectionObserver = false;
     }
 
+    // If a new WebSocket connection is selected, scroll to anchor.
+    if (channelId !== prevProps.channelId && scrollAnchor) {
+      scrollAnchor.scrollIntoView();
+    }
+
+    this.setupScrollToBottom(startPanelContainer, scrollAnchor);
+  }
+
+  componentWillUnmount() {
+    // Reset observables and boolean values.
+    const scrollAnchor = this.refs.scrollAnchor;
+    this.intersectionObserver.unobserve(scrollAnchor);
+    this.initIntersectionObserver = false;
+    this.pinnedToBottom = false;
+  }
+
+  setupScrollToBottom(startPanelContainer, scrollAnchor) {
     if (startPanelContainer && scrollAnchor) {
       // Initialize intersection observer.
       if (!this.initIntersectionObserver) {
-        const observer = new IntersectionObserver(
+        this.intersectionObserver = new IntersectionObserver(
           () => {
             // When scrollAnchor first comes into view, this.pinnedToBottom is set to true.
             // When the anchor goes out of view, this callback function triggers again and toggles this.pinnedToBottom.
             // Subsequent scroll into/out of view will toggle this.pinnedToBottom.
             this.pinnedToBottom = !this.pinnedToBottom;
           },
           {
             root: startPanelContainer,
             threshold: 0.1,
           }
         );
-        observer.observe(scrollAnchor);
+        this.intersectionObserver.observe(scrollAnchor);
         this.initIntersectionObserver = true;
       }
 
       if (this.pinnedToBottom) {
         scrollAnchor.scrollIntoView();
       }
     }
   }
--- a/devtools/client/netmonitor/src/components/websockets/WebSocketsPanel.js
+++ b/devtools/client/netmonitor/src/components/websockets/WebSocketsPanel.js
@@ -102,17 +102,22 @@ class WebSocketsPanel extends Component 
   // Reset the filter text
   clearFilterText() {
     if (this.searchboxRef) {
       this.searchboxRef.current.onClearButtonClick();
     }
   }
 
   render() {
-    const { frameDetailsOpen, connector, selectedFrame } = this.props;
+    const {
+      frameDetailsOpen,
+      connector,
+      selectedFrame,
+      channelId,
+    } = this.props;
 
     const searchboxRef = this.searchboxRef;
     const startPanelContainer = this.state.startPanelContainer;
 
     const initialHeight = Services.prefs.getIntPref(
       "devtools.netmonitor.ws.payload-preview-height"
     );
 
@@ -126,16 +131,17 @@ class WebSocketsPanel extends Component 
         initialHeight: initialHeight,
         minSize: "50px",
         maxSize: "80%",
         splitterSize: frameDetailsOpen ? 1 : 0,
         onSelectContainerElement: this.handleContainerElement,
         startPanel: FrameListContent({
           connector,
           startPanelContainer,
+          channelId,
         }),
         endPanel:
           frameDetailsOpen &&
           FramePayload({
             ref: "endPanel",
             connector,
             selectedFrame,
           }),