Created
May 14, 2019 19:26
-
-
Save jasonLaster/cbeca56d95addc3e5d09636442d87b2f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 1f59911c3c9ef0a717f3f2366f908ed154d39577 | |
Author: Jason Laster <jlaster@mozilla.com> | |
Date: Tue May 14 15:08:36 2019 -0400 | |
foo | |
diff --git a/devtools/client/debugger/src/actions/preview.js b/devtools/client/debugger/src/actions/preview.js | |
index 019b63a10ab8..cf1436fc633e 100644 | |
--- a/devtools/client/debugger/src/actions/preview.js | |
+++ b/devtools/client/debugger/src/actions/preview.js | |
@@ -13,7 +13,6 @@ import { isOriginal } from "../utils/source"; | |
import { | |
getPreview, | |
getPreviewTarget, | |
- getPreviewHovered, | |
isLineInScope, | |
isSelectedFrameVisible, | |
getSelectedSource, | |
@@ -46,34 +45,6 @@ function findExpressionMatch(state, codeMirror, tokenPos) { | |
return match; | |
} | |
-export function tryUpdatingPreview( | |
- cx: Context, | |
- target: HTMLElement, | |
- tokenPos: Object, | |
- codeMirror: any | |
-) { | |
- return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => { | |
- return setTimeout(function() { | |
- // Check the displayed preview's target, if there is one | |
- let displayedPreviewTarget = undefined; | |
- try { | |
- displayedPreviewTarget = getPreviewTarget(getState()); | |
- } catch (e) { | |
- displayedPreviewTarget = undefined; | |
- } | |
- | |
- // To avoid re-rendering the same token unnecessarily, this makes sure | |
- // that the current token isn't the same one that is already rendered | |
- if (target === displayedPreviewTarget) { | |
- return; | |
- } | |
- | |
- dispatch(updatePreview(cx, target, tokenPos, editor.codeMirror)); | |
- }, 500); | |
- } | |
-} | |
- | |
- | |
export function updatePreview( | |
cx: Context, | |
target: HTMLElement, | |
@@ -168,6 +139,12 @@ export function setPreview( | |
}; | |
const properties = await client.loadObjectProperties(root); | |
+ // Bail if the user has moused off of the target | |
+ // before we have had a chance to get the preview value | |
+ if (!target.matches(":hover")) { | |
+ return; | |
+ } | |
+ | |
return { | |
expression, | |
result, | |
@@ -180,18 +157,6 @@ export function setPreview( | |
}; | |
})() | |
}); | |
- // After dispatching setPreview, clear the timeout reference | |
- clearScheduledPreview(); | |
- }; | |
-} | |
- | |
-export function clearExistingScheduledPreview() { | |
- return ({ dispatch, getState}: ThunkArgs) => { | |
- const scheduledPreviewTimeoutID = getScheduledPreviewTimeoutID(getState()); | |
- if (scheduledPreviewTimeoutID) { | |
- clearTimeout(scheduledPreviewTimeoutID); | |
- dispatch(clearScheduledPreview()); | |
- } | |
}; | |
} | |
@@ -210,47 +175,3 @@ export function clearPreview(cx: Context) { | |
); | |
}; | |
} | |
- | |
-export function schedulePreview(timeoutID: Number) { | |
- return ({ dispatch }: ThunkArgs) => { | |
- return dispatch({type: "SCHEDULE_PREVIEW", timeoutID}); | |
- }; | |
-} | |
- | |
-export function clearScheduledPreview() { | |
- return ({ dispatch }: ThunkArgs) => { | |
- return dispatch({type: "CLEAR_SCHEDULED_PREVIEW"}: Action); | |
- }; | |
-} | |
- | |
-export function onPreviewMouseEnter(timeoutID: Number) { | |
- return ({ dispatch }: ThunkArgs) => { | |
- return dispatch({type: "ON_PREVIEW_MOUSE_ENTER"}); | |
- }; | |
-} | |
- | |
-export function onPreviewMouseLeave(timeoutID: Number) { | |
- return ({ dispatch }: ThunkArgs) => { | |
- const a = dispatch({type: "ON_PREVIEW_MOUSE_LEAVE"}); | |
- return a; | |
- }; | |
-} | |
- | |
-export function startClearPreviewInterval(cx) { | |
- return ({ dispatch, getState }: ThunkArgs) => { | |
- let intervalID = setInterval(function() { | |
- // Don't clear the current preview if mouse is hovered on | |
- // the current preview's element (target) or the popup element | |
- const currentTarget = getPreviewTarget(getState()); | |
- const previewHovered = getPreviewHovered(getState()); | |
- if (currentTarget.matches(":hover") || previewHovered) { | |
- return; | |
- } | |
- | |
- // Clear the interval and the preview if it is not hovered | |
- // on the current preview's element or the popup element | |
- clearInterval(intervalID); | |
- return dispatch(clearPreview(cx)); | |
- }, 500); | |
- } | |
-} | |
\ No newline at end of file | |
diff --git a/devtools/client/debugger/src/components/Editor/Preview/Popup.js b/devtools/client/debugger/src/components/Editor/Preview/Popup.js | |
index 267318acddfb..64f28c9b4655 100644 | |
--- a/devtools/client/debugger/src/components/Editor/Preview/Popup.js | |
+++ b/devtools/client/debugger/src/components/Editor/Preview/Popup.js | |
@@ -44,49 +44,56 @@ type Props = { | |
openElementInInspector: typeof actions.openElementInInspectorCommand, | |
highlightDomElement: typeof actions.highlightDomElement, | |
unHighlightDomElement: typeof actions.unHighlightDomElement, | |
+ clearPreview: typeof actions.clearPreview | |
}; | |
type State = { | |
- top: number, | |
- firstRender: boolean | |
+ top: number | |
}; | |
-function inPreview(event) { | |
- const relatedTarget: Element = (event.relatedTarget: any); | |
- | |
- if ( | |
- !relatedTarget || | |
- (relatedTarget.classList && | |
- relatedTarget.classList.contains("preview-expression")) | |
- ) { | |
- return true; | |
- } | |
- | |
- // $FlowIgnore | |
- const inPreviewSelection = document | |
- .elementsFromPoint(event.clientX, event.clientY) | |
- .some(el => el.classList.contains("preview-selection")); | |
- | |
- return inPreviewSelection; | |
-} | |
- | |
export class Popup extends Component<Props, State> { | |
marker: any; | |
pos: any; | |
+ timerId = null; | |
+ popup = null; | |
constructor(props: Props) { | |
super(props); | |
this.state = { | |
- top: 0, | |
- firstRender: true | |
+ top: 0 | |
}; | |
} | |
componentDidMount() { | |
- const { cx, startClearPreviewInterval } = this.props; | |
- startClearPreviewInterval(cx); | |
+ this.startTimer(); | |
+ } | |
+ | |
+ componentWillUnmount() { | |
+ if (this.timerId) { | |
+ // this.clearTimer(); | |
+ } | |
+ } | |
+ | |
+ startTimer() { | |
+ this.timerId = setInterval(this.onInterval, 500); | |
} | |
+ onInterval = () => { | |
+ const { preview, clearPreview, cx } = this.props; | |
+ | |
+ // Don't clear the current preview if mouse is hovered on | |
+ // the current preview's element (target) or the popup element | |
+ const currentTarget = preview.target; | |
+ if (currentTarget.matches(":hover") || this.popup.matches(":hover")) { | |
+ return; | |
+ } | |
+ | |
+ // Clear the interval and the preview if it is not hovered | |
+ // on the current preview's element or the popup element | |
+ clearInterval(this.timerId); | |
+ return clearPreview(cx); | |
+ }; | |
+ | |
calculateMaxHeight = () => { | |
const { editorRef } = this.props; | |
if (!editorRef) { | |
@@ -99,16 +106,13 @@ export class Popup extends Component<Props, State> { | |
const { | |
cx, | |
selectSourceURL, | |
- preview: { result }, | |
- onPreviewMouseEnter, | |
- onPreviewMouseLeave | |
+ preview: { result } | |
} = this.props; | |
return ( | |
<div | |
className="preview-popup" | |
- onMouseEnter={onPreviewMouseEnter} | |
- onMouseLeave={onPreviewMouseLeave} | |
+ ref="popup" | |
onClick={() => | |
selectSourceURL(cx, result.location.url, { | |
line: result.location.line | |
@@ -126,17 +130,14 @@ export class Popup extends Component<Props, State> { | |
openLink, | |
openElementInInspector, | |
highlightDomElement, | |
- unHighlightDomElement, | |
- onPreviewMouseEnter, | |
- onPreviewMouseLeave | |
+ unHighlightDomElement | |
} = this.props; | |
return ( | |
<div | |
className="preview-popup" | |
style={{ maxHeight: this.calculateMaxHeight() }} | |
- onMouseEnter={onPreviewMouseEnter} | |
- onMouseLeave={onPreviewMouseLeave} | |
+ ref="popup" | |
> | |
<ObjectInspector | |
roots={properties} | |
@@ -157,16 +158,10 @@ export class Popup extends Component<Props, State> { | |
renderSimplePreview() { | |
const { | |
openLink, | |
- preview: { result }, | |
- onPreviewMouseEnter, | |
- onPreviewMouseLeave | |
+ preview: { result } | |
} = this.props; | |
return ( | |
- <div | |
- className="preview-popup" | |
- onMouseEnter={onPreviewMouseEnter} | |
- onMouseLeave={onPreviewMouseLeave} | |
- > | |
+ <div className="preview-popup" ref="popup"> | |
{Rep({ | |
object: result, | |
mode: MODE.LONG, | |
@@ -222,16 +217,6 @@ export class Popup extends Component<Props, State> { | |
return null; | |
} | |
- // The first time a popup is rendered, the mouse should be hovered | |
- // on the token. If it happens to be hovered on whitespace, it should | |
- // not render anything | |
- if (this.state.firstRender) { | |
- if (!target.matches(":hover")) { | |
- return null; | |
- } | |
- this.setState({firstRender: false}); | |
- } | |
- | |
return ( | |
<Popover | |
targetPosition={cursorPos} | |
@@ -257,10 +242,7 @@ const { | |
openElementInInspectorCommand, | |
highlightDomElement, | |
unHighlightDomElement, | |
- clearPreview, | |
- onPreviewMouseEnter, | |
- onPreviewMouseLeave, | |
- startClearPreviewInterval | |
+ clearPreview | |
} = actions; | |
const mapDispatchToProps = { | |
@@ -270,10 +252,7 @@ const mapDispatchToProps = { | |
openElementInInspector: openElementInInspectorCommand, | |
highlightDomElement, | |
unHighlightDomElement, | |
- clearPreview, | |
- onPreviewMouseEnter, | |
- onPreviewMouseLeave, | |
- startClearPreviewInterval | |
+ clearPreview | |
}; | |
export default connect( | |
diff --git a/devtools/client/debugger/src/components/Editor/Preview/index.js b/devtools/client/debugger/src/components/Editor/Preview/index.js | |
index 0858417690ab..16ca31172900 100644 | |
--- a/devtools/client/debugger/src/components/Editor/Preview/index.js | |
+++ b/devtools/client/debugger/src/components/Editor/Preview/index.js | |
@@ -9,7 +9,11 @@ import { connect } from "../../../utils/connect"; | |
import Popup from "./Popup"; | |
-import { getPreview, getThreadContext, getScheduledPreviewTimeoutID } from "../../../selectors"; | |
+import { | |
+ getPreview, | |
+ getThreadContext, | |
+ getScheduledPreviewTimeoutID | |
+} from "../../../selectors"; | |
import actions from "../../../actions"; | |
import type { ThreadContext } from "../../../types"; | |
@@ -96,39 +100,22 @@ class Preview extends PureComponent<Props, State> { | |
target && target.classList.add("preview-selection"); | |
} | |
- if (prevProps.preview && !prevProps.preview.updating && prevProps.preview !== preview) { | |
+ if ( | |
+ prevProps.preview && | |
+ !prevProps.preview.updating && | |
+ prevProps.preview !== preview | |
+ ) { | |
const target = getElementFromPos(prevProps.preview.cursorPos); | |
target && target.classList.remove("preview-selection"); | |
} | |
} | |
onTokenEnter = ({ target, tokenPos }) => { | |
- const { | |
- cx, | |
- schedulePreview, | |
- clearScheduledPreview, | |
- editor, | |
- scheduledPreviewTimeoutID, | |
- tryUpdatingPreview | |
- } = this.props; | |
+ const { cx, editor, updatePreview } = this.props; | |
if (cx.isPaused) { | |
- // Check for already scheduled preview | |
- if (scheduledPreviewTimeoutID) { | |
- clearTimeout(scheduledPreviewTimeoutID); | |
- clearScheduledPreview(); | |
- } | |
- | |
// Schedule an updatePreview for this token's preview | |
- const previewTimeoutID = tryUpdatingPreview( | |
- cx, | |
- target, | |
- tokenPos, | |
- editor.codeMirror | |
- ); | |
- | |
- // Keep track in the Redux store that there is a preview scheduled | |
- schedulePreview(previewTimeoutID); | |
+ updatePreview(cx, target, tokenPos, editor.codeMirror); | |
} | |
}; | |
@@ -153,7 +140,7 @@ class Preview extends PureComponent<Props, State> { | |
}; | |
render() { | |
- const { preview } = this.props; | |
+ const { preview, clearPreview } = this.props; | |
if (!preview || preview.updating || this.state.selecting) { | |
return null; | |
} | |
diff --git a/devtools/client/debugger/src/reducers/ast.js b/devtools/client/debugger/src/reducers/ast.js | |
index 9e93dcc69fad..4e0440bd9c4d 100644 | |
--- a/devtools/client/debugger/src/reducers/ast.js | |
+++ b/devtools/client/debugger/src/reducers/ast.js | |
@@ -39,7 +39,8 @@ export type PreviewValue = {| | |
location: AstLocation, | |
cursorPos: any, | |
tokenPos: AstLocation, | |
- updating: false | |
+ updating: false, | |
+ target: HTMLElement | |
|}; | |
export type ASTState = { | |
@@ -105,22 +106,6 @@ function update(state: ASTState = initialASTState(), action: Action): ASTState { | |
return state; | |
} | |
- case "SCHEDULE_PREVIEW": { | |
- return { ...state, scheduledPreviewTimeoutID: action.timeoutID }; | |
- } | |
- | |
- case "CLEAR_SCHEDULED_PREVIEW": { | |
- return { ...state, scheduledPreviewTimeoutID: null }; | |
- } | |
- | |
- case "ON_PREVIEW_MOUSE_ENTER": { | |
- return { ...state, previewHovered: true }; | |
- } | |
- | |
- case "ON_PREVIEW_MOUSE_LEAVE": { | |
- return { ...state, previewHovered: false }; | |
- } | |
- | |
case "RESUME": { | |
return { ...state, outOfScopeLocations: null }; | |
} | |
@@ -181,14 +166,6 @@ export function getPreview(state: OuterState) { | |
return state.ast.preview; | |
} | |
-export function getPreviewTarget(state: OuterState) { | |
- return state.ast.preview.target; | |
-} | |
- | |
-export function getPreviewHovered(state: OuterState) { | |
- return state.ast.previewHovered; | |
-} | |
- | |
export function getInScopeLines(state: OuterState) { | |
return state.ast.inScopeLines; | |
} | |
@@ -198,8 +175,4 @@ export function isLineInScope(state: OuterState, line: number) { | |
return linesInScope && linesInScope.includes(line); | |
} | |
-export function getScheduledPreviewTimeoutID(state: OuterState) { | |
- return state.ast.scheduledPreviewTimeoutID; | |
-} | |
- | |
export default update; | |
diff --git a/devtools/client/debugger/test/mochitest/helpers.js b/devtools/client/debugger/test/mochitest/helpers.js | |
index 40dd62c43474..b3fee54e530b 100644 | |
--- a/devtools/client/debugger/test/mochitest/helpers.js | |
+++ b/devtools/client/debugger/test/mochitest/helpers.js | |
@@ -1060,8 +1060,8 @@ const keyMappings = { | |
fileSearchPrev: { code: "g", modifiers: cmdShift }, | |
Enter: { code: "VK_RETURN" }, | |
ShiftEnter: { code: "VK_RETURN", modifiers: shiftOrAlt }, | |
- AltEnter: { | |
- code: "VK_RETURN", | |
+ AltEnter: { | |
+ code: "VK_RETURN", | |
modifiers: { altKey: true } | |
}, | |
Up: { code: "VK_UP" }, | |
@@ -1501,10 +1501,13 @@ async function hoverAtPos(dbg, { line, ch }) { | |
const { left, top } = coords; | |
+ mouseOver(dbg, left, top); | |
+} | |
+ | |
+function mouseOver(dbg, left, top) { | |
// Adds a vertical offset due to increased line height | |
// https://github.com/firefox-devtools/debugger/pull/7934 | |
const lineHeightOffset = 3; | |
- | |
const tokenEl = dbg.win.document.elementFromPoint( | |
left, | |
top + lineHeightOffset | |
@@ -1514,7 +1517,11 @@ async function hoverAtPos(dbg, { line, ch }) { | |
return false; | |
} | |
- tokenEl.dispatchEvent( | |
+ mouseOverEl(dbg, el); | |
+} | |
+ | |
+function mouseOverEl(dbg, el) { | |
+ el.dispatchEvent( | |
new MouseEvent("mouseover", { | |
bubbles: true, | |
cancelable: true, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment