breakpointAtLocation.js (3518B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 import { getSelectedSource, getBreakpointPositionsForLine } from "./sources"; 6 import { getBreakpointsList } from "./breakpoints"; 7 8 function getColumn(column, selectedSource) { 9 if (column) { 10 return column; 11 } 12 13 return !selectedSource.isOriginal ? undefined : 0; 14 } 15 16 function getLocation(bp, selectedSource) { 17 return !selectedSource.isOriginal 18 ? bp.generatedLocation || bp.location 19 : bp.location; 20 } 21 22 function getBreakpointsForSource(state, selectedSource) { 23 const breakpoints = getBreakpointsList(state); 24 25 return breakpoints.filter(bp => { 26 const location = getLocation(bp, selectedSource); 27 return location.source.id === selectedSource.id; 28 }); 29 } 30 31 function findBreakpointAtLocation( 32 breakpoints, 33 selectedSource, 34 { line, column } 35 ) { 36 return breakpoints.find(breakpoint => { 37 const location = getLocation(breakpoint, selectedSource); 38 const sameLine = location.line === line; 39 if (!sameLine) { 40 return false; 41 } 42 43 if (column === undefined) { 44 return true; 45 } 46 47 return location.column === getColumn(column, selectedSource); 48 }); 49 } 50 51 // returns the closest active column breakpoint 52 function findClosestBreakpoint(breakpoints, column) { 53 if (!breakpoints || !breakpoints.length) { 54 return null; 55 } 56 57 const firstBreakpoint = breakpoints[0]; 58 return breakpoints.reduce((closestBp, currentBp) => { 59 const currentColumn = currentBp.generatedLocation.column; 60 const closestColumn = closestBp.generatedLocation.column; 61 // check that breakpoint has a column. 62 if (column && currentColumn && closestColumn) { 63 const currentDistance = Math.abs(currentColumn - column); 64 const closestDistance = Math.abs(closestColumn - column); 65 66 return currentDistance < closestDistance ? currentBp : closestBp; 67 } 68 return closestBp; 69 }, firstBreakpoint); 70 } 71 72 /* 73 * Finds a breakpoint at a location (line, column) of the 74 * selected source. 75 * 76 * This is useful for finding a breakpoint when the 77 * user clicks in the gutter or on a token. 78 */ 79 export function getBreakpointAtLocation(state, location) { 80 const selectedSource = getSelectedSource(state); 81 if (!selectedSource) { 82 throw new Error("no selectedSource"); 83 } 84 const breakpoints = getBreakpointsForSource(state, selectedSource); 85 86 return findBreakpointAtLocation(breakpoints, selectedSource, location); 87 } 88 89 export function getBreakpointsAtLine(state, line) { 90 const selectedSource = getSelectedSource(state); 91 if (!selectedSource) { 92 throw new Error("no selectedSource"); 93 } 94 const breakpoints = getBreakpointsForSource(state, selectedSource); 95 96 return breakpoints.filter( 97 breakpoint => getLocation(breakpoint, selectedSource).line === line 98 ); 99 } 100 101 export function getClosestBreakpoint(state, position) { 102 const columnBreakpoints = getBreakpointsAtLine(state, position.line); 103 const breakpoint = findClosestBreakpoint(columnBreakpoints, position.column); 104 return breakpoint; 105 } 106 107 export function getClosestBreakpointPosition(state, position) { 108 const selectedSource = getSelectedSource(state); 109 if (!selectedSource) { 110 throw new Error("no selectedSource"); 111 } 112 113 const columnBreakpoints = getBreakpointPositionsForLine( 114 state, 115 selectedSource.id, 116 position.line 117 ); 118 119 return findClosestBreakpoint(columnBreakpoints, position.column); 120 }