From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../src/selectors/visibleColumnBreakpoints.js | 185 +++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 devtools/client/debugger/src/selectors/visibleColumnBreakpoints.js (limited to 'devtools/client/debugger/src/selectors/visibleColumnBreakpoints.js') diff --git a/devtools/client/debugger/src/selectors/visibleColumnBreakpoints.js b/devtools/client/debugger/src/selectors/visibleColumnBreakpoints.js new file mode 100644 index 0000000000..5ed391c7e4 --- /dev/null +++ b/devtools/client/debugger/src/selectors/visibleColumnBreakpoints.js @@ -0,0 +1,185 @@ +/* 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 . */ + +import { createSelector } from "reselect"; + +import { + getViewport, + getSelectedSource, + getSelectedSourceTextContent, + getBreakpointPositionsForSource, +} from "./index"; +import { getVisibleBreakpoints } from "./visibleBreakpoints"; +import { getSelectedLocation } from "../utils/selected-location"; +import { sortSelectedLocations } from "../utils/location"; +import { getLineText } from "../utils/source"; + +function contains(location, range) { + return ( + location.line >= range.start.line && + location.line <= range.end.line && + (!location.column || + (location.column >= range.start.column && + location.column <= range.end.column)) + ); +} + +function groupBreakpoints(breakpoints, selectedSource) { + const breakpointsMap = {}; + if (!breakpoints) { + return breakpointsMap; + } + + for (const breakpoint of breakpoints) { + if (breakpoint.options.hidden) { + continue; + } + const location = getSelectedLocation(breakpoint, selectedSource); + const { line, column } = location; + + if (!breakpointsMap[line]) { + breakpointsMap[line] = {}; + } + + if (!breakpointsMap[line][column]) { + breakpointsMap[line][column] = []; + } + + breakpointsMap[line][column].push(breakpoint); + } + + return breakpointsMap; +} + +function findBreakpoint(location, breakpointMap) { + const { line, column } = location; + const breakpoints = breakpointMap[line]?.[column]; + + if (!breakpoints) { + return null; + } + return breakpoints[0]; +} + +function filterByLineCount(positions, selectedSource) { + const lineCount = {}; + + for (const breakpoint of positions) { + const { line } = getSelectedLocation(breakpoint, selectedSource); + if (!lineCount[line]) { + lineCount[line] = 0; + } + lineCount[line] = lineCount[line] + 1; + } + + return positions.filter( + breakpoint => + lineCount[getSelectedLocation(breakpoint, selectedSource).line] > 1 + ); +} + +function filterVisible(positions, selectedSource, viewport) { + return positions.filter(columnBreakpoint => { + const location = getSelectedLocation(columnBreakpoint, selectedSource); + return viewport && contains(location, viewport); + }); +} + +function filterByBreakpoints(positions, selectedSource, breakpointMap) { + return positions.filter(position => { + const location = getSelectedLocation(position, selectedSource); + return breakpointMap[location.line]; + }); +} + +// Filters out breakpoints to the right of the line. (bug 1552039) +function filterInLine(positions, selectedSource, selectedContent) { + return positions.filter(position => { + const location = getSelectedLocation(position, selectedSource); + const lineText = getLineText( + selectedSource.id, + selectedContent, + location.line + ); + + return lineText.length >= (location.column || 0); + }); +} + +function formatPositions(positions, selectedSource, breakpointMap) { + return positions.map(position => { + const location = getSelectedLocation(position, selectedSource); + return { + location, + breakpoint: findBreakpoint(location, breakpointMap), + }; + }); +} + +function convertToList(breakpointPositions) { + return [].concat(...Object.values(breakpointPositions)); +} + +export function getColumnBreakpoints( + positions, + breakpoints, + viewport, + selectedSource, + selectedSourceTextContent +) { + if (!positions || !selectedSource) { + return []; + } + + // We only want to show a column breakpoint if several conditions are matched + // - it is the first breakpoint to appear at an the original location + // - the position is in the current viewport + // - there is atleast one other breakpoint on that line + // - there is a breakpoint on that line + const breakpointMap = groupBreakpoints(breakpoints, selectedSource); + positions = filterByLineCount(positions, selectedSource); + positions = filterVisible(positions, selectedSource, viewport); + positions = filterInLine( + positions, + selectedSource, + selectedSourceTextContent + ); + positions = filterByBreakpoints(positions, selectedSource, breakpointMap); + + return formatPositions(positions, selectedSource, breakpointMap); +} + +const getVisibleBreakpointPositions = createSelector( + state => { + const source = getSelectedSource(state); + if (!source) { + return null; + } + return getBreakpointPositionsForSource(state, source.id); + }, + sourcePositions => { + return convertToList(sourcePositions || []); + } +); + +export const visibleColumnBreakpoints = createSelector( + getVisibleBreakpointPositions, + getVisibleBreakpoints, + getViewport, + getSelectedSource, + getSelectedSourceTextContent, + getColumnBreakpoints +); + +export function getFirstBreakpointPosition(state, location) { + const positions = getBreakpointPositionsForSource(state, location.sourceId); + if (!positions) { + return null; + } + + return sortSelectedLocations(convertToList(positions), location.source).find( + position => + getSelectedLocation(position, location.source).line == location.line + ); +} -- cgit v1.2.3