diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /devtools/client/debugger/src/components/Editor/HighlightLine.js | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/debugger/src/components/Editor/HighlightLine.js')
-rw-r--r-- | devtools/client/debugger/src/components/Editor/HighlightLine.js | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/Editor/HighlightLine.js b/devtools/client/debugger/src/components/Editor/HighlightLine.js new file mode 100644 index 0000000000..0b66d499b1 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/HighlightLine.js @@ -0,0 +1,195 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ + +// @flow +import { Component } from "react"; +import { toEditorLine, endOperation, startOperation } from "../../utils/editor"; +import { getDocument, hasDocument } from "../../utils/editor/source-documents"; + +import { connect } from "../../utils/connect"; +import { + getVisibleSelectedFrame, + getSelectedLocation, + getSelectedSourceWithContent, + getPauseCommand, + getCurrentThread, +} from "../../selectors"; + +import type { + SourceLocation, + SourceWithContent, + SourceDocuments, +} from "../../types"; +import type { Command } from "../../reducers/types"; + +type HighlightFrame = { + location: SourceLocation, +}; + +type OwnProps = {||}; +type Props = { + pauseCommand: Command, + selectedFrame: ?HighlightFrame, + selectedLocation: SourceLocation, + selectedSource: ?SourceWithContent, +}; + +function isDebugLine( + selectedFrame: ?HighlightFrame, + selectedLocation: SourceLocation +) { + if (!selectedFrame) { + return; + } + + return ( + selectedFrame.location.sourceId == selectedLocation.sourceId && + selectedFrame.location.line == selectedLocation.line + ); +} + +function isDocumentReady(selectedSource: ?SourceWithContent, selectedLocation) { + return ( + selectedLocation && + selectedSource && + selectedSource.content && + hasDocument(selectedLocation.sourceId) + ); +} + +export class HighlightLine extends Component<Props> { + isStepping: boolean = false; + previousEditorLine: ?number = null; + + shouldComponentUpdate(nextProps: Props) { + const { selectedLocation, selectedSource } = nextProps; + return this.shouldSetHighlightLine(selectedLocation, selectedSource); + } + + componentDidUpdate(prevProps: Props) { + this.completeHighlightLine(prevProps); + } + + componentDidMount() { + this.completeHighlightLine(null); + } + + shouldSetHighlightLine( + selectedLocation: SourceLocation, + selectedSource: ?SourceWithContent + ) { + const { sourceId, line } = selectedLocation; + const editorLine = toEditorLine(sourceId, line); + + if (!isDocumentReady(selectedSource, selectedLocation)) { + return false; + } + + if (this.isStepping && editorLine === this.previousEditorLine) { + return false; + } + + return true; + } + + completeHighlightLine(prevProps: Props | null) { + const { + pauseCommand, + selectedLocation, + selectedFrame, + selectedSource, + } = this.props; + if (pauseCommand) { + this.isStepping = true; + } + + startOperation(); + if (prevProps) { + this.clearHighlightLine( + prevProps.selectedLocation, + prevProps.selectedSource + ); + } + this.setHighlightLine(selectedLocation, selectedFrame, selectedSource); + endOperation(); + } + + setHighlightLine( + selectedLocation: SourceLocation, + selectedFrame: ?HighlightFrame, + selectedSource: ?SourceWithContent + ) { + const { sourceId, line } = selectedLocation; + if (!this.shouldSetHighlightLine(selectedLocation, selectedSource)) { + return; + } + + this.isStepping = false; + const editorLine = toEditorLine(sourceId, line); + this.previousEditorLine = editorLine; + + if (!line || isDebugLine(selectedFrame, selectedLocation)) { + return; + } + + const doc = getDocument(sourceId); + doc.addLineClass(editorLine, "wrapClass", "highlight-line"); + this.resetHighlightLine(doc, editorLine); + } + + resetHighlightLine(doc: SourceDocuments, editorLine: number) { + const editorWrapper: HTMLElement | null = document.querySelector( + ".editor-wrapper" + ); + + if (editorWrapper === null) { + return; + } + + const duration = parseInt( + getComputedStyle(editorWrapper).getPropertyValue( + "--highlight-line-duration" + ), + 10 + ); + + setTimeout( + () => + doc && doc.removeLineClass(editorLine, "wrapClass", "highlight-line"), + duration + ); + } + + clearHighlightLine( + selectedLocation: SourceLocation, + selectedSource: ?SourceWithContent + ) { + if (!isDocumentReady(selectedSource, selectedLocation)) { + return; + } + + const { line, sourceId } = selectedLocation; + const editorLine = toEditorLine(sourceId, line); + const doc = getDocument(sourceId); + doc.removeLineClass(editorLine, "wrapClass", "highlight-line"); + } + + render() { + return null; + } +} + +export default connect<Props, OwnProps, _, _, _, _>(state => { + const selectedLocation = getSelectedLocation(state); + + if (!selectedLocation) { + throw new Error("must have selected location"); + } + return { + pauseCommand: getPauseCommand(state, getCurrentThread(state)), + selectedFrame: getVisibleSelectedFrame(state), + selectedLocation, + selectedSource: getSelectedSourceWithContent(state), + }; +})(HighlightLine); |