From ecd011094d18e84b4318d3076a5748b7a29c2e03 Mon Sep 17 00:00:00 2001 From: Nick Reiley Date: Thu, 7 May 2020 08:24:32 +0500 Subject: [PATCH 1/5] allow to continue dragging --- .../views/Profiler/SnapshotCommitList.js | 33 +---------- .../views/Profiler/SnapshotCommitListItem.js | 57 ++++++++++++++++++- 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js index 54b5370991e93..ed60208258f12 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js @@ -8,7 +8,7 @@ */ import * as React from 'react'; -import {useCallback, useEffect, useMemo, useRef, useState} from 'react'; +import {useEffect, useMemo, useRef} from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; import {FixedSizeList} from 'react-window'; import SnapshotCommitListItem from './SnapshotCommitListItem'; @@ -20,7 +20,6 @@ export type ItemData = {| commitDurations: Array, commitTimes: Array, filteredCommitIndices: Array, - isMouseDown: boolean, maxDuration: number, selectedCommitIndex: number | null, selectedFilteredCommitIndex: number | null, @@ -97,28 +96,6 @@ function List({ } }, [listRef, selectedFilteredCommitIndex]); - // When the mouse is down, dragging over a commit should auto-select it. - // This provides a nice way for users to swipe across a range of commits to compare them. - const [isMouseDown, setIsMouseDown] = useState(false); - const handleMouseDown = useCallback(() => { - setIsMouseDown(true); - }, []); - const handleMouseUp = useCallback(() => { - setIsMouseDown(false); - }, []); - useEffect(() => { - if (divRef.current === null) { - return () => {}; - } - - // It's important to listen to the ownerDocument to support the browser extension. - // Here we use portals to render individual tabs (e.g. Profiler), - // and the root document might belong to a different window. - const ownerDocument = divRef.current.ownerDocument; - ownerDocument.addEventListener('mouseup', handleMouseUp); - return () => ownerDocument.removeEventListener('mouseup', handleMouseUp); - }, [divRef, handleMouseUp]); - const itemSize = useMemo( () => Math.max(minBarWidth, width / filteredCommitIndices.length), [filteredCommitIndices, width], @@ -134,7 +111,6 @@ function List({ commitDurations, commitTimes, filteredCommitIndices, - isMouseDown, maxDuration, selectedCommitIndex, selectedFilteredCommitIndex, @@ -144,7 +120,6 @@ function List({ commitDurations, commitTimes, filteredCommitIndices, - isMouseDown, maxDuration, selectedCommitIndex, selectedFilteredCommitIndex, @@ -153,11 +128,7 @@ function List({ ); return ( -
+
{ + if (e.buttons === 0) { + document.removeEventListener('mousemove', handleDrag); + const iframe = document.querySelector('iframe'); + if (iframe) iframe.style.pointerEvents = 'auto'; + dragStartCommit = null; + return; + } + if (dragStartCommit === null) return; + + let newCommitIndex = index; + let newCommitRectLeft = dragStartCommit.rectLeft; + + if (e.pageX < dragStartCommit.rectLeft) { + while (e.pageX < newCommitRectLeft) { + newCommitRectLeft = newCommitRectLeft - 1 - width; + newCommitIndex -= 1; + } + } else { + let newCommitRectRight = newCommitRectLeft + 1 + width; + while (e.pageX > newCommitRectRight) { + newCommitRectRight = newCommitRectRight + 1 + width; + newCommitIndex += 1; + } + } + + if (newCommitIndex < 0) { + newCommitIndex = 0; + } else if (newCommitIndex > maxCommitIndex) { + newCommitIndex = maxCommitIndex; + } + selectCommitIndex(newCommitIndex); + }; + + const handleMouseDown = (e: any) => { + handleClick(); + document.addEventListener('mousemove', handleDrag); + const iframe = document.querySelector('iframe'); + if (iframe) iframe.style.pointerEvents = 'none'; + const rect = e.target.getBoundingClientRect(); + dragStartCommit = { + dragStartCommitIndex: index, + rectLeft: rect.left, + }; + }; + // Guard against commits with duration 0 const percentage = Math.min(1, Math.max(0, commitDuration / maxDuration)) || 0; @@ -56,7 +109,7 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) {
Date: Fri, 8 May 2020 15:45:46 +0500 Subject: [PATCH 2/5] move dragging logic to parent --- .../views/Profiler/SnapshotCommitList.js | 98 ++++++++++++++++++- .../views/Profiler/SnapshotCommitListItem.js | 74 +++----------- 2 files changed, 112 insertions(+), 60 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js index ed60208258f12..1827eb074baed 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js @@ -8,7 +8,7 @@ */ import * as React from 'react'; -import {useEffect, useMemo, useRef} from 'react'; +import {useEffect, useMemo, useRef, useState} from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; import {FixedSizeList} from 'react-window'; import SnapshotCommitListItem from './SnapshotCommitListItem'; @@ -24,6 +24,13 @@ export type ItemData = {| selectedCommitIndex: number | null, selectedFilteredCommitIndex: number | null, selectCommitIndex: (index: number) => void, + startCommitDrag: (newDragStartCommit: DragStartCommit) => void, +|}; + +type State = {| + dragCommitStarted: boolean, + dragStartCommit: DragStartCommit | null, + modifiedIframes: Map | null, |}; type Props = {| @@ -72,6 +79,12 @@ type ListProps = {| width: number, |}; +type DragStartCommit = { + dragStartCommitIndex: number, + rectLeft: number, + width: number, +}; + function List({ commitDurations, selectedCommitIndex, @@ -105,6 +118,87 @@ function List({ [commitDurations], ); + const maxCommitIndex = filteredCommitIndices.length - 1; + + const [state, setState] = useState({ + dragCommitStarted: false, + dragStartCommit: null, + modifiedIframes: null, + }); + + const startCommitDrag = (newDragStartCommit: DragStartCommit) => { + const element = divRef.current; + if (element !== null) { + const iframes = element.ownerDocument.querySelectorAll('iframe'); + if (iframes.length > 0) { + const modifiedIframesMap = new Map(); + for (let i = 0; i < iframes.length; i++) { + if (iframes[i].style.pointerEvents !== 'none') { + modifiedIframesMap.set(iframes[i], iframes[i].style.pointerEvents); + iframes[i].style.pointerEvents = 'none'; + } + } + setState({ + dragCommitStarted: true, + dragStartCommit: newDragStartCommit, + modifiedIframes: modifiedIframesMap, + }); + } + } + }; + + const handleDragCommit = (e: any) => { + const {dragCommitStarted, dragStartCommit, modifiedIframes} = state; + if (dragCommitStarted === false || dragStartCommit === null) return; + if (e.buttons === 0) { + if (modifiedIframes !== null) { + modifiedIframes.forEach((value, iframe) => { + iframe.style.pointerEvents = value; + }); + } + setState({ + dragCommitStarted: false, + dragStartCommit: null, + modifiedIframes: null, + }); + return; + } + + let newCommitIndex = dragStartCommit.dragStartCommitIndex; + let newCommitRectLeft = dragStartCommit.rectLeft; + + if (e.pageX < dragStartCommit.rectLeft) { + while (e.pageX < newCommitRectLeft) { + newCommitRectLeft = newCommitRectLeft - 1 - dragStartCommit.width; + newCommitIndex -= 1; + } + } else { + let newCommitRectRight = newCommitRectLeft + dragStartCommit.width; + while (e.pageX > newCommitRectRight) { + newCommitRectRight = newCommitRectRight + 1 + dragStartCommit.width; + newCommitIndex += 1; + } + } + + if (newCommitIndex < 0) { + newCommitIndex = 0; + } else if (newCommitIndex > maxCommitIndex) { + newCommitIndex = maxCommitIndex; + } + selectCommitIndex(newCommitIndex); + }; + + useEffect(() => { + const element = divRef.current; + if (element !== null) { + const ownerDocument = element.ownerDocument; + ownerDocument.addEventListener('mousemove', handleDragCommit); + return () => { + ownerDocument.removeEventListener('mousemove', handleDragCommit); + }; + } + }, [state]); + // Pass required contextual data down to the ListItem renderer. const itemData = useMemo( () => ({ @@ -115,6 +209,7 @@ function List({ selectedCommitIndex, selectedFilteredCommitIndex, selectCommitIndex, + startCommitDrag, }), [ commitDurations, @@ -124,6 +219,7 @@ function List({ selectedCommitIndex, selectedFilteredCommitIndex, selectCommitIndex, + startCommitDrag, ], ); diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js index 32e186f13bc80..c6d639912f82a 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js @@ -23,11 +23,6 @@ type Props = { ... }; -type DragStartCommit = { - dragStartCommitIndex: number, - rectLeft: number, -}; - function SnapshotCommitListItem({data: itemData, index, style}: Props) { const { commitDurations, @@ -36,6 +31,7 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) { maxDuration, selectedCommitIndex, selectCommitIndex, + startCommitDrag, } = itemData; index = filteredCommitIndices[index]; @@ -43,59 +39,10 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) { const commitDuration = commitDurations[index]; const commitTime = commitTimes[index]; - const handleClick = useCallback(() => selectCommitIndex(index), [ - index, - selectCommitIndex, - ]); - - let dragStartCommit: DragStartCommit | null = null; - const maxCommitIndex = filteredCommitIndices.length - 1; - - const handleDrag = (e: any) => { - if (e.buttons === 0) { - document.removeEventListener('mousemove', handleDrag); - const iframe = document.querySelector('iframe'); - if (iframe) iframe.style.pointerEvents = 'auto'; - dragStartCommit = null; - return; - } - if (dragStartCommit === null) return; - - let newCommitIndex = index; - let newCommitRectLeft = dragStartCommit.rectLeft; - - if (e.pageX < dragStartCommit.rectLeft) { - while (e.pageX < newCommitRectLeft) { - newCommitRectLeft = newCommitRectLeft - 1 - width; - newCommitIndex -= 1; - } - } else { - let newCommitRectRight = newCommitRectLeft + 1 + width; - while (e.pageX > newCommitRectRight) { - newCommitRectRight = newCommitRectRight + 1 + width; - newCommitIndex += 1; - } - } - - if (newCommitIndex < 0) { - newCommitIndex = 0; - } else if (newCommitIndex > maxCommitIndex) { - newCommitIndex = maxCommitIndex; - } - selectCommitIndex(newCommitIndex); - }; - - const handleMouseDown = (e: any) => { - handleClick(); - document.addEventListener('mousemove', handleDrag); - const iframe = document.querySelector('iframe'); - if (iframe) iframe.style.pointerEvents = 'none'; - const rect = e.target.getBoundingClientRect(); - dragStartCommit = { - dragStartCommitIndex: index, - rectLeft: rect.left, - }; - }; + const memoizedSelectCommitIndex = useCallback( + () => selectCommitIndex(index), + [index, selectCommitIndex], + ); // Guard against commits with duration 0 const percentage = @@ -105,10 +52,19 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) { // Leave a 1px gap between snapshots const width = parseFloat(style.width) - 1; + const handleMouseDown = (e: any) => { + memoizedSelectCommitIndex(); + const rect = e.target.getBoundingClientRect(); + startCommitDrag({ + dragStartCommitIndex: index, + rectLeft: rect.left, + width, + }); + }; + return (
Date: Fri, 8 May 2020 10:45:16 -0700 Subject: [PATCH 3/5] Update SnapshotCommitList.js --- .../views/Profiler/SnapshotCommitList.js | 108 ++++++------------ 1 file changed, 37 insertions(+), 71 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js index 1827eb074baed..0d309f700644b 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitList.js @@ -24,13 +24,7 @@ export type ItemData = {| selectedCommitIndex: number | null, selectedFilteredCommitIndex: number | null, selectCommitIndex: (index: number) => void, - startCommitDrag: (newDragStartCommit: DragStartCommit) => void, -|}; - -type State = {| - dragCommitStarted: boolean, - dragStartCommit: DragStartCommit | null, - modifiedIframes: Map | null, + startCommitDrag: (newDragState: DragState) => void, |}; type Props = {| @@ -79,10 +73,10 @@ type ListProps = {| width: number, |}; -type DragStartCommit = { - dragStartCommitIndex: number, - rectLeft: number, - width: number, +type DragState = { + commitIndex: number, + left: number, + sizeIncrement: number, }; function List({ @@ -120,75 +114,48 @@ function List({ const maxCommitIndex = filteredCommitIndices.length - 1; - const [state, setState] = useState({ - dragCommitStarted: false, - dragStartCommit: null, - modifiedIframes: null, - }); - - const startCommitDrag = (newDragStartCommit: DragStartCommit) => { - const element = divRef.current; - if (element !== null) { - const iframes = element.ownerDocument.querySelectorAll('iframe'); - if (iframes.length > 0) { - const modifiedIframesMap = new Map(); - for (let i = 0; i < iframes.length; i++) { - if (iframes[i].style.pointerEvents !== 'none') { - modifiedIframesMap.set(iframes[i], iframes[i].style.pointerEvents); - iframes[i].style.pointerEvents = 'none'; - } - } - setState({ - dragCommitStarted: true, - dragStartCommit: newDragStartCommit, - modifiedIframes: modifiedIframesMap, - }); - } - } - }; + const [dragState, setDragState] = useState(null); - const handleDragCommit = (e: any) => { - const {dragCommitStarted, dragStartCommit, modifiedIframes} = state; - if (dragCommitStarted === false || dragStartCommit === null) return; - if (e.buttons === 0) { - if (modifiedIframes !== null) { - modifiedIframes.forEach((value, iframe) => { - iframe.style.pointerEvents = value; - }); - } - setState({ - dragCommitStarted: false, - dragStartCommit: null, - modifiedIframes: null, - }); + const handleDragCommit = ({buttons, pageX}: any) => { + if (buttons === 0) { + setDragState(null); return; } - let newCommitIndex = dragStartCommit.dragStartCommitIndex; - let newCommitRectLeft = dragStartCommit.rectLeft; + if (dragState !== null) { + const {commitIndex, left, sizeIncrement} = dragState; + + let newCommitIndex = commitIndex; + let newCommitLeft = left; - if (e.pageX < dragStartCommit.rectLeft) { - while (e.pageX < newCommitRectLeft) { - newCommitRectLeft = newCommitRectLeft - 1 - dragStartCommit.width; - newCommitIndex -= 1; + if (pageX < newCommitLeft) { + while (pageX < newCommitLeft) { + newCommitLeft -= sizeIncrement; + newCommitIndex -= 1; + } + } else { + let newCommitRectRight = newCommitLeft + sizeIncrement; + while (pageX > newCommitRectRight) { + newCommitRectRight += sizeIncrement; + newCommitIndex += 1; + } } - } else { - let newCommitRectRight = newCommitRectLeft + dragStartCommit.width; - while (e.pageX > newCommitRectRight) { - newCommitRectRight = newCommitRectRight + 1 + dragStartCommit.width; - newCommitIndex += 1; + + if (newCommitIndex < 0) { + newCommitIndex = 0; + } else if (newCommitIndex > maxCommitIndex) { + newCommitIndex = maxCommitIndex; } - } - if (newCommitIndex < 0) { - newCommitIndex = 0; - } else if (newCommitIndex > maxCommitIndex) { - newCommitIndex = maxCommitIndex; + selectCommitIndex(newCommitIndex); } - selectCommitIndex(newCommitIndex); }; useEffect(() => { + if (dragState === null) { + return; + } + const element = divRef.current; if (element !== null) { const ownerDocument = element.ownerDocument; @@ -197,7 +164,7 @@ function List({ ownerDocument.removeEventListener('mousemove', handleDragCommit); }; } - }, [state]); + }, [dragState]); // Pass required contextual data down to the ListItem renderer. const itemData = useMemo( @@ -209,7 +176,7 @@ function List({ selectedCommitIndex, selectedFilteredCommitIndex, selectCommitIndex, - startCommitDrag, + startCommitDrag: setDragState, }), [ commitDurations, @@ -219,7 +186,6 @@ function List({ selectedCommitIndex, selectedFilteredCommitIndex, selectCommitIndex, - startCommitDrag, ], ); From d498186cb778ac5dd0af89c6ac5d957c052eff00 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Fri, 8 May 2020 10:45:27 -0700 Subject: [PATCH 4/5] Update SnapshotCommitListItem.js --- .../views/Profiler/SnapshotCommitListItem.js | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js index c6d639912f82a..977196782726e 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js @@ -8,7 +8,7 @@ */ import * as React from 'react'; -import {memo, useCallback} from 'react'; +import {memo} from 'react'; import {areEqual} from 'react-window'; import {getGradientColor, formatDuration, formatTime} from './utils'; @@ -39,11 +39,6 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) { const commitDuration = commitDurations[index]; const commitTime = commitTimes[index]; - const memoizedSelectCommitIndex = useCallback( - () => selectCommitIndex(index), - [index, selectCommitIndex], - ); - // Guard against commits with duration 0 const percentage = Math.min(1, Math.max(0, commitDuration / maxDuration)) || 0; @@ -52,14 +47,17 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) { // Leave a 1px gap between snapshots const width = parseFloat(style.width) - 1; - const handleMouseDown = (e: any) => { - memoizedSelectCommitIndex(); - const rect = e.target.getBoundingClientRect(); - startCommitDrag({ - dragStartCommitIndex: index, - rectLeft: rect.left, - width, - }); + const handleMouseDown = ({buttons, target}: any) => { + if (buttons === 1) { + selectCommitIndex(index); + + // TODO Count for border/margin + startCommitDrag({ + commitIndex: index, + left: target.getBoundingClientRect().left, + sizeIncrement: parseFloat(style.width), + }); + } }; return ( From 12e2bdea46b17810c8b626fd5b36384840817316 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Fri, 8 May 2020 10:46:37 -0700 Subject: [PATCH 5/5] Update SnapshotCommitListItem.js --- .../src/devtools/views/Profiler/SnapshotCommitListItem.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js index 977196782726e..e8399a09bb37d 100644 --- a/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js +++ b/packages/react-devtools-shared/src/devtools/views/Profiler/SnapshotCommitListItem.js @@ -50,8 +50,6 @@ function SnapshotCommitListItem({data: itemData, index, style}: Props) { const handleMouseDown = ({buttons, target}: any) => { if (buttons === 1) { selectCommitIndex(index); - - // TODO Count for border/margin startCommitDrag({ commitIndex: index, left: target.getBoundingClientRect().left,