mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
commit
18a982b872
@ -149,11 +149,13 @@ DebuggerPanel.prototype = {
|
||||
},
|
||||
|
||||
selectSourceURL(url, line, column) {
|
||||
return this._actions.selectSourceURL(url, { line, column });
|
||||
const cx = this._selectors.getContext(this._getState());
|
||||
return this._actions.selectSourceURL(cx, url, { line, column });
|
||||
},
|
||||
|
||||
selectSource(sourceId, line, column) {
|
||||
return this._actions.selectSource(sourceId, { line, column });
|
||||
const cx = this._selectors.getContext(this._getState());
|
||||
return this._actions.selectSource(cx, sourceId, { line, column });
|
||||
},
|
||||
|
||||
getSourceByActorId(sourceId) {
|
||||
|
@ -12,9 +12,10 @@ import * as parser from "../workers/parser";
|
||||
|
||||
import { isLoaded } from "../utils/source";
|
||||
|
||||
import type { Context } from "../types";
|
||||
import type { ThunkArgs, Action } from "./types";
|
||||
|
||||
export function setOutOfScopeLocations() {
|
||||
export function setOutOfScopeLocations(cx: Context) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const location = getSelectedLocation(getState());
|
||||
if (!location) {
|
||||
@ -38,9 +39,10 @@ export function setOutOfScopeLocations() {
|
||||
dispatch(
|
||||
({
|
||||
type: "OUT_OF_SCOPE_LOCATIONS",
|
||||
cx,
|
||||
locations
|
||||
}: Action)
|
||||
);
|
||||
dispatch(setInScopeLines());
|
||||
dispatch(setInScopeLines(cx));
|
||||
};
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import { range, flatMap, uniq, without } from "lodash";
|
||||
|
||||
import type { AstLocation } from "../../workers/parser";
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type { Context } from "../../types";
|
||||
|
||||
function getOutOfScopeLines(outOfScopeLocations: ?(AstLocation[])) {
|
||||
if (!outOfScopeLocations) {
|
||||
@ -24,7 +25,7 @@ function getOutOfScopeLines(outOfScopeLocations: ?(AstLocation[])) {
|
||||
);
|
||||
}
|
||||
|
||||
export function setInScopeLines() {
|
||||
export function setInScopeLines(cx: Context) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const source = getSelectedSource(getState());
|
||||
const outOfScopeLocations = getOutOfScopeLocations(getState());
|
||||
@ -44,6 +45,7 @@ export function setInScopeLines() {
|
||||
|
||||
dispatch({
|
||||
type: "IN_SCOPE_LINES",
|
||||
cx,
|
||||
lines: inScopeLines
|
||||
});
|
||||
};
|
||||
|
@ -17,7 +17,8 @@ import {
|
||||
import type {
|
||||
MappedLocation,
|
||||
SourceLocation,
|
||||
BreakpointPositions
|
||||
BreakpointPositions,
|
||||
Context
|
||||
} from "../../types";
|
||||
import { makeBreakpointId } from "../../utils/breakpoint";
|
||||
import {
|
||||
@ -72,7 +73,7 @@ function convertToList(results, source) {
|
||||
return positions;
|
||||
}
|
||||
|
||||
async function _setBreakpointPositions(sourceId, thunkArgs) {
|
||||
async function _setBreakpointPositions(cx, sourceId, thunkArgs) {
|
||||
const { client, dispatch, getState, sourceMaps } = thunkArgs;
|
||||
let generatedSource = getSource(getState(), sourceId);
|
||||
if (!generatedSource) {
|
||||
@ -124,6 +125,7 @@ async function _setBreakpointPositions(sourceId, thunkArgs) {
|
||||
|
||||
dispatch({
|
||||
type: "ADD_BREAKPOINT_POSITIONS",
|
||||
cx,
|
||||
source: source,
|
||||
positions
|
||||
});
|
||||
@ -132,7 +134,7 @@ async function _setBreakpointPositions(sourceId, thunkArgs) {
|
||||
}
|
||||
|
||||
export const setBreakpointPositions: MemoizedAction<
|
||||
{ sourceId: string },
|
||||
{ cx: Context, sourceId: string },
|
||||
?BreakpointPositions
|
||||
> = memoizeableAction("setBreakpointPositions", {
|
||||
hasValue: ({ sourceId }, { getState }) =>
|
||||
@ -149,6 +151,6 @@ export const setBreakpointPositions: MemoizedAction<
|
||||
: [];
|
||||
return [sourceId, ...actors].join(":");
|
||||
},
|
||||
action: ({ sourceId }, thunkArgs) =>
|
||||
_setBreakpointPositions(sourceId, thunkArgs)
|
||||
action: ({ cx, sourceId }, thunkArgs) =>
|
||||
_setBreakpointPositions(cx, sourceId, thunkArgs)
|
||||
});
|
||||
|
@ -37,16 +37,17 @@ import type {
|
||||
Breakpoint,
|
||||
Source,
|
||||
SourceLocation,
|
||||
XHRBreakpoint
|
||||
XHRBreakpoint,
|
||||
Context
|
||||
} from "../../types";
|
||||
|
||||
export * from "./breakpointPositions";
|
||||
export * from "./modify";
|
||||
export * from "./syncBreakpoint";
|
||||
|
||||
export function addHiddenBreakpoint(location: SourceLocation) {
|
||||
export function addHiddenBreakpoint(cx: Context, location: SourceLocation) {
|
||||
return ({ dispatch }: ThunkArgs) => {
|
||||
return dispatch(addBreakpoint(location, { hidden: true }));
|
||||
return dispatch(addBreakpoint(cx, location, { hidden: true }));
|
||||
};
|
||||
}
|
||||
|
||||
@ -56,12 +57,12 @@ export function addHiddenBreakpoint(location: SourceLocation) {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function disableBreakpointsInSource(source: Source) {
|
||||
export function disableBreakpointsInSource(cx: Context, source: Source) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoints = getBreakpointsForSource(getState(), source.id);
|
||||
for (const breakpoint of breakpoints) {
|
||||
if (!breakpoint.disabled) {
|
||||
dispatch(disableBreakpoint(breakpoint));
|
||||
dispatch(disableBreakpoint(cx, breakpoint));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -73,12 +74,12 @@ export function disableBreakpointsInSource(source: Source) {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function enableBreakpointsInSource(source: Source) {
|
||||
export function enableBreakpointsInSource(cx: Context, source: Source) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoints = getBreakpointsForSource(getState(), source.id);
|
||||
for (const breakpoint of breakpoints) {
|
||||
if (breakpoint.disabled) {
|
||||
dispatch(enableBreakpoint(breakpoint));
|
||||
dispatch(enableBreakpoint(cx, breakpoint));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -90,15 +91,18 @@ export function enableBreakpointsInSource(source: Source) {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function toggleAllBreakpoints(shouldDisableBreakpoints: boolean) {
|
||||
export function toggleAllBreakpoints(
|
||||
cx: Context,
|
||||
shouldDisableBreakpoints: boolean
|
||||
) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoints = getBreakpointsList(getState());
|
||||
|
||||
for (const breakpoint of breakpoints) {
|
||||
if (shouldDisableBreakpoints) {
|
||||
dispatch(disableBreakpoint(breakpoint));
|
||||
dispatch(disableBreakpoint(cx, breakpoint));
|
||||
} else {
|
||||
dispatch(enableBreakpoint(breakpoint));
|
||||
dispatch(enableBreakpoint(cx, breakpoint));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -111,6 +115,7 @@ export function toggleAllBreakpoints(shouldDisableBreakpoints: boolean) {
|
||||
* @static
|
||||
*/
|
||||
export function toggleBreakpoints(
|
||||
cx: Context,
|
||||
shouldDisableBreakpoints: boolean,
|
||||
breakpoints: Breakpoint[]
|
||||
) {
|
||||
@ -118,8 +123,8 @@ export function toggleBreakpoints(
|
||||
const promises = breakpoints.map(
|
||||
breakpoint =>
|
||||
shouldDisableBreakpoints
|
||||
? dispatch(disableBreakpoint(breakpoint))
|
||||
: dispatch(enableBreakpoint(breakpoint))
|
||||
? dispatch(disableBreakpoint(cx, breakpoint))
|
||||
: dispatch(enableBreakpoint(cx, breakpoint))
|
||||
);
|
||||
|
||||
await Promise.all(promises);
|
||||
@ -127,12 +132,15 @@ export function toggleBreakpoints(
|
||||
}
|
||||
|
||||
export function toggleBreakpointsAtLine(
|
||||
cx: Context,
|
||||
shouldDisableBreakpoints: boolean,
|
||||
line: number
|
||||
) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const breakpoints = await getBreakpointsAtLine(getState(), line);
|
||||
return dispatch(toggleBreakpoints(shouldDisableBreakpoints, breakpoints));
|
||||
const breakpoints = getBreakpointsAtLine(getState(), line);
|
||||
return dispatch(
|
||||
toggleBreakpoints(cx, shouldDisableBreakpoints, breakpoints)
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -142,11 +150,11 @@ export function toggleBreakpointsAtLine(
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeAllBreakpoints() {
|
||||
export function removeAllBreakpoints(cx: Context) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const breakpointList = getBreakpointsList(getState());
|
||||
return Promise.all(
|
||||
breakpointList.map(bp => dispatch(removeBreakpoint(bp)))
|
||||
breakpointList.map(bp => dispatch(removeBreakpoint(cx, bp)))
|
||||
);
|
||||
};
|
||||
}
|
||||
@ -157,9 +165,11 @@ export function removeAllBreakpoints() {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeBreakpoints(breakpoints: Breakpoint[]) {
|
||||
export function removeBreakpoints(cx: Context, breakpoints: Breakpoint[]) {
|
||||
return async ({ dispatch }: ThunkArgs) => {
|
||||
return Promise.all(breakpoints.map(bp => dispatch(removeBreakpoint(bp))));
|
||||
return Promise.all(
|
||||
breakpoints.map(bp => dispatch(removeBreakpoint(cx, bp)))
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -169,16 +179,16 @@ export function removeBreakpoints(breakpoints: Breakpoint[]) {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeBreakpointsInSource(source: Source) {
|
||||
export function removeBreakpointsInSource(cx: Context, source: Source) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoints = getBreakpointsForSource(getState(), source.id);
|
||||
for (const breakpoint of breakpoints) {
|
||||
dispatch(removeBreakpoint(breakpoint));
|
||||
dispatch(removeBreakpoint(cx, breakpoint));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function remapBreakpoints(sourceId: string) {
|
||||
export function remapBreakpoints(cx: Context, sourceId: string) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
const breakpoints = getBreakpointsForSource(getState(), sourceId);
|
||||
const newBreakpoints = await remapLocations(
|
||||
@ -192,16 +202,16 @@ export function remapBreakpoints(sourceId: string) {
|
||||
// have different locations than the new ones. Manually remove the
|
||||
// old breakpoints before adding the new ones.
|
||||
for (const bp of breakpoints) {
|
||||
dispatch(removeBreakpoint(bp));
|
||||
dispatch(removeBreakpoint(cx, bp));
|
||||
}
|
||||
|
||||
for (const bp of newBreakpoints) {
|
||||
await dispatch(addBreakpoint(bp.location, bp.options, bp.disabled));
|
||||
await dispatch(addBreakpoint(cx, bp.location, bp.options, bp.disabled));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleBreakpointAtLine(line: number) {
|
||||
export function toggleBreakpointAtLine(cx: Context, line: number) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const state = getState();
|
||||
const selectedSource = getSelectedSource(state);
|
||||
@ -222,10 +232,10 @@ export function toggleBreakpointAtLine(line: number) {
|
||||
}
|
||||
|
||||
if (bp) {
|
||||
return dispatch(removeBreakpoint(bp));
|
||||
return dispatch(removeBreakpoint(cx, bp));
|
||||
}
|
||||
return dispatch(
|
||||
addBreakpoint({
|
||||
addBreakpoint(cx, {
|
||||
sourceId: selectedSource.id,
|
||||
sourceUrl: selectedSource.url,
|
||||
line: line
|
||||
@ -234,7 +244,7 @@ export function toggleBreakpointAtLine(line: number) {
|
||||
};
|
||||
}
|
||||
|
||||
export function addBreakpointAtLine(line: number) {
|
||||
export function addBreakpointAtLine(cx: Context, line: number) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const state = getState();
|
||||
const source = getSelectedSource(state);
|
||||
@ -244,7 +254,7 @@ export function addBreakpointAtLine(line: number) {
|
||||
}
|
||||
|
||||
return dispatch(
|
||||
addBreakpoint({
|
||||
addBreakpoint(cx, {
|
||||
sourceId: source.id,
|
||||
sourceUrl: source.url,
|
||||
column: undefined,
|
||||
@ -254,45 +264,57 @@ export function addBreakpointAtLine(line: number) {
|
||||
};
|
||||
}
|
||||
|
||||
export function removeBreakpointsAtLine(sourceId: string, line: number) {
|
||||
export function removeBreakpointsAtLine(
|
||||
cx: Context,
|
||||
sourceId: string,
|
||||
line: number
|
||||
) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const breakpointsAtLine = getBreakpointsForSource(
|
||||
getState(),
|
||||
sourceId,
|
||||
line
|
||||
);
|
||||
return dispatch(removeBreakpoints(breakpointsAtLine));
|
||||
return dispatch(removeBreakpoints(cx, breakpointsAtLine));
|
||||
};
|
||||
}
|
||||
|
||||
export function disableBreakpointsAtLine(sourceId: string, line: number) {
|
||||
export function disableBreakpointsAtLine(
|
||||
cx: Context,
|
||||
sourceId: string,
|
||||
line: number
|
||||
) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const breakpointsAtLine = getBreakpointsForSource(
|
||||
getState(),
|
||||
sourceId,
|
||||
line
|
||||
);
|
||||
return dispatch(toggleBreakpoints(true, breakpointsAtLine));
|
||||
return dispatch(toggleBreakpoints(cx, true, breakpointsAtLine));
|
||||
};
|
||||
}
|
||||
|
||||
export function enableBreakpointsAtLine(sourceId: string, line: number) {
|
||||
export function enableBreakpointsAtLine(
|
||||
cx: Context,
|
||||
sourceId: string,
|
||||
line: number
|
||||
) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const breakpointsAtLine = getBreakpointsForSource(
|
||||
getState(),
|
||||
sourceId,
|
||||
line
|
||||
);
|
||||
return dispatch(toggleBreakpoints(false, breakpointsAtLine));
|
||||
return dispatch(toggleBreakpoints(cx, false, breakpointsAtLine));
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleDisabledBreakpoint(breakpoint: Breakpoint) {
|
||||
export function toggleDisabledBreakpoint(cx: Context, breakpoint: Breakpoint) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
if (!breakpoint.disabled) {
|
||||
return dispatch(disableBreakpoint(breakpoint));
|
||||
return dispatch(disableBreakpoint(cx, breakpoint));
|
||||
}
|
||||
return dispatch(enableBreakpoint(breakpoint));
|
||||
return dispatch(enableBreakpoint(cx, breakpoint));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,8 @@ import type {
|
||||
Breakpoint,
|
||||
BreakpointOptions,
|
||||
BreakpointPosition,
|
||||
SourceLocation
|
||||
SourceLocation,
|
||||
Context
|
||||
} from "../../types";
|
||||
|
||||
// This file has the primitive operations used to modify individual breakpoints
|
||||
@ -78,7 +79,7 @@ function clientRemoveBreakpoint(generatedLocation: SourceLocation) {
|
||||
};
|
||||
}
|
||||
|
||||
export function enableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
export function enableBreakpoint(cx: Context, initialBreakpoint: Breakpoint) {
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const breakpoint = getBreakpoint(getState(), initialBreakpoint.location);
|
||||
if (!breakpoint || !breakpoint.disabled) {
|
||||
@ -87,6 +88,7 @@ export function enableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
cx,
|
||||
breakpoint: { ...breakpoint, disabled: false }
|
||||
});
|
||||
|
||||
@ -95,6 +97,7 @@ export function enableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
}
|
||||
|
||||
export function addBreakpoint(
|
||||
cx: Context,
|
||||
initialLocation: SourceLocation,
|
||||
options: BreakpointOptions = {},
|
||||
disabled: boolean = false,
|
||||
@ -105,7 +108,7 @@ export function addBreakpoint(
|
||||
|
||||
const { sourceId, column } = initialLocation;
|
||||
|
||||
await dispatch(setBreakpointPositions({ sourceId }));
|
||||
await dispatch(setBreakpointPositions({ cx, sourceId }));
|
||||
|
||||
const position: ?BreakpointPosition = column
|
||||
? getBreakpointPositionsForLocation(getState(), initialLocation)
|
||||
@ -146,7 +149,7 @@ export function addBreakpoint(
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({ type: "SET_BREAKPOINT", breakpoint });
|
||||
dispatch({ type: "SET_BREAKPOINT", cx, breakpoint });
|
||||
|
||||
if (disabled) {
|
||||
// If we just clobbered an enabled breakpoint with a disabled one, we need
|
||||
@ -164,7 +167,7 @@ export function addBreakpoint(
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
export function removeBreakpoint(cx: Context, initialBreakpoint: Breakpoint) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
recordEvent("remove_breakpoint");
|
||||
|
||||
@ -175,6 +178,7 @@ export function removeBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
|
||||
dispatch({
|
||||
type: "REMOVE_BREAKPOINT",
|
||||
cx,
|
||||
location: breakpoint.location
|
||||
});
|
||||
|
||||
@ -194,7 +198,10 @@ export function removeBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function removeBreakpointAtGeneratedLocation(target: SourceLocation) {
|
||||
export function removeBreakpointAtGeneratedLocation(
|
||||
cx: Context,
|
||||
target: SourceLocation
|
||||
) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
// Remove any breakpoints matching the generated location.
|
||||
const breakpoints = getBreakpointsList(getState());
|
||||
@ -205,6 +212,7 @@ export function removeBreakpointAtGeneratedLocation(target: SourceLocation) {
|
||||
) {
|
||||
dispatch({
|
||||
type: "REMOVE_BREAKPOINT",
|
||||
cx,
|
||||
location
|
||||
});
|
||||
}
|
||||
@ -219,6 +227,7 @@ export function removeBreakpointAtGeneratedLocation(target: SourceLocation) {
|
||||
) {
|
||||
dispatch({
|
||||
type: "REMOVE_PENDING_BREAKPOINT",
|
||||
cx,
|
||||
location
|
||||
});
|
||||
}
|
||||
@ -235,7 +244,7 @@ export function removeBreakpointAtGeneratedLocation(target: SourceLocation) {
|
||||
* @memberof actions/breakpoints
|
||||
* @static
|
||||
*/
|
||||
export function disableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
export function disableBreakpoint(cx: Context, initialBreakpoint: Breakpoint) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const breakpoint = getBreakpoint(getState(), initialBreakpoint.location);
|
||||
if (!breakpoint || breakpoint.disabled) {
|
||||
@ -244,6 +253,7 @@ export function disableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
cx,
|
||||
breakpoint: { ...breakpoint, disabled: true }
|
||||
});
|
||||
|
||||
@ -263,13 +273,14 @@ export function disableBreakpoint(initialBreakpoint: Breakpoint) {
|
||||
* Any options to set on the breakpoint
|
||||
*/
|
||||
export function setBreakpointOptions(
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
options: BreakpointOptions = {}
|
||||
) {
|
||||
return ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
let breakpoint = getBreakpoint(getState(), location);
|
||||
if (!breakpoint) {
|
||||
return dispatch(addBreakpoint(location, options));
|
||||
return dispatch(addBreakpoint(cx, location, options));
|
||||
}
|
||||
|
||||
// Note: setting a breakpoint's options implicitly enables it.
|
||||
@ -277,6 +288,7 @@ export function setBreakpointOptions(
|
||||
|
||||
dispatch({
|
||||
type: "SET_BREAKPOINT",
|
||||
cx,
|
||||
breakpoint
|
||||
});
|
||||
|
||||
|
@ -27,15 +27,17 @@ import type {
|
||||
ASTLocation,
|
||||
PendingBreakpoint,
|
||||
SourceId,
|
||||
BreakpointPositions
|
||||
BreakpointPositions,
|
||||
Context
|
||||
} from "../../types";
|
||||
|
||||
async function findBreakpointPosition(
|
||||
cx: Context,
|
||||
{ getState, dispatch },
|
||||
location: SourceLocation
|
||||
) {
|
||||
const positions: BreakpointPositions = await dispatch(
|
||||
setBreakpointPositions({ sourceId: location.sourceId })
|
||||
setBreakpointPositions({ cx, sourceId: location.sourceId })
|
||||
);
|
||||
|
||||
const position = findPosition(positions, location);
|
||||
@ -43,13 +45,14 @@ async function findBreakpointPosition(
|
||||
}
|
||||
|
||||
async function findNewLocation(
|
||||
cx: Context,
|
||||
{ name, offset, index }: ASTLocation,
|
||||
location: SourceLocation,
|
||||
source,
|
||||
thunkArgs
|
||||
) {
|
||||
const symbols: LoadedSymbols = await thunkArgs.dispatch(
|
||||
setSymbols({ source })
|
||||
setSymbols({ cx, source })
|
||||
);
|
||||
const func = findFunctionByName(symbols, name, index);
|
||||
|
||||
@ -85,6 +88,7 @@ async function findNewLocation(
|
||||
// to the reducer for the new location corresponding to the original location
|
||||
// in the pending breakpoint.
|
||||
export function syncBreakpoint(
|
||||
cx: Context,
|
||||
sourceId: SourceId,
|
||||
pendingBreakpoint: PendingBreakpoint
|
||||
) {
|
||||
@ -124,6 +128,7 @@ export function syncBreakpoint(
|
||||
);
|
||||
return dispatch(
|
||||
addBreakpoint(
|
||||
cx,
|
||||
sourceGeneratedLocation,
|
||||
pendingBreakpoint.options,
|
||||
pendingBreakpoint.disabled,
|
||||
@ -135,6 +140,7 @@ export function syncBreakpoint(
|
||||
const previousLocation = { ...location, sourceId };
|
||||
|
||||
const newLocation = await findNewLocation(
|
||||
cx,
|
||||
astLocation,
|
||||
previousLocation,
|
||||
source,
|
||||
@ -142,6 +148,7 @@ export function syncBreakpoint(
|
||||
);
|
||||
|
||||
const newGeneratedLocation = await findBreakpointPosition(
|
||||
cx,
|
||||
thunkArgs,
|
||||
newLocation
|
||||
);
|
||||
@ -152,7 +159,9 @@ export function syncBreakpoint(
|
||||
// breakpoint moved. If the old generated location still maps to an
|
||||
// original location then we don't want to add a breakpoint for it.
|
||||
if (location.sourceUrl != generatedLocation.sourceUrl) {
|
||||
dispatch(removeBreakpointAtGeneratedLocation(sourceGeneratedLocation));
|
||||
dispatch(
|
||||
removeBreakpointAtGeneratedLocation(cx, sourceGeneratedLocation)
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -166,11 +175,14 @@ export function syncBreakpoint(
|
||||
// breakpoint, remove any breakpoint associated with the old generated
|
||||
// location.
|
||||
if (!isSameLocation) {
|
||||
dispatch(removeBreakpointAtGeneratedLocation(sourceGeneratedLocation));
|
||||
dispatch(
|
||||
removeBreakpointAtGeneratedLocation(cx, sourceGeneratedLocation)
|
||||
);
|
||||
}
|
||||
|
||||
return dispatch(
|
||||
addBreakpoint(
|
||||
cx,
|
||||
newLocation,
|
||||
pendingBreakpoint.options,
|
||||
pendingBreakpoint.disabled
|
||||
|
@ -18,10 +18,10 @@ describe("breakpointPositions", () => {
|
||||
getBreakpointPositions: async () => ({ "9": [1] })
|
||||
});
|
||||
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
await dispatch(actions.newSource(makeSource("foo")));
|
||||
|
||||
dispatch(actions.setBreakpointPositions({ sourceId: "foo" }));
|
||||
dispatch(actions.setBreakpointPositions({ cx, sourceId: "foo" }));
|
||||
|
||||
await waitForState(store, state =>
|
||||
selectors.hasBreakpointPositions(state, "foo")
|
||||
@ -58,11 +58,11 @@ describe("breakpointPositions", () => {
|
||||
})
|
||||
});
|
||||
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
await dispatch(actions.newSource(makeSource("foo")));
|
||||
|
||||
dispatch(actions.setBreakpointPositions({ sourceId: "foo" }));
|
||||
dispatch(actions.setBreakpointPositions({ sourceId: "foo" }));
|
||||
dispatch(actions.setBreakpointPositions({ cx, sourceId: "foo" }));
|
||||
dispatch(actions.setBreakpointPositions({ cx, sourceId: "foo" }));
|
||||
|
||||
resolve({ "9": [1] });
|
||||
await waitForState(store, state =>
|
||||
|
@ -23,7 +23,7 @@ function mockClient(positionsResponse = {}) {
|
||||
|
||||
describe("breakpoints", () => {
|
||||
it("should add a breakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "2": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "2": [1] }));
|
||||
const loc1 = {
|
||||
sourceId: "a",
|
||||
line: 2,
|
||||
@ -33,16 +33,16 @@ describe("breakpoints", () => {
|
||||
|
||||
const source = makeSource("a");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
await dispatch(
|
||||
actions.setSelectedLocation(source, {
|
||||
actions.setSelectedLocation(cx, source, {
|
||||
line: 1,
|
||||
column: 1,
|
||||
sourceId: source.id
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
@ -54,7 +54,7 @@ describe("breakpoints", () => {
|
||||
});
|
||||
|
||||
it("should not show a breakpoint that does not have text", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
const loc1 = {
|
||||
sourceId: "a",
|
||||
line: 5,
|
||||
@ -63,16 +63,16 @@ describe("breakpoints", () => {
|
||||
};
|
||||
const source = makeSource("a");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
await dispatch(
|
||||
actions.setSelectedLocation(source, {
|
||||
actions.setSelectedLocation(cx, source, {
|
||||
line: 1,
|
||||
column: 1,
|
||||
sourceId: source.id
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
@ -81,7 +81,7 @@ describe("breakpoints", () => {
|
||||
});
|
||||
|
||||
it("should show a disabled breakpoint that does not have text", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
const loc1 = {
|
||||
sourceId: "a",
|
||||
line: 5,
|
||||
@ -90,22 +90,22 @@ describe("breakpoints", () => {
|
||||
};
|
||||
const source = makeSource("a");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
await dispatch(
|
||||
actions.setSelectedLocation(source, {
|
||||
actions.setSelectedLocation(cx, source, {
|
||||
line: 1,
|
||||
column: 1,
|
||||
sourceId: source.id
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
const breakpoint = selectors.getBreakpoint(getState(), loc1);
|
||||
if (!breakpoint) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(breakpoint));
|
||||
await dispatch(actions.disableBreakpoint(cx, breakpoint));
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
@ -114,7 +114,7 @@ describe("breakpoints", () => {
|
||||
});
|
||||
|
||||
it("should not re-add a breakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
const loc1 = {
|
||||
sourceId: "a",
|
||||
line: 5,
|
||||
@ -124,26 +124,26 @@ describe("breakpoints", () => {
|
||||
|
||||
const source = makeSource("a");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
await dispatch(
|
||||
actions.setSelectedLocation(source, {
|
||||
actions.setSelectedLocation(cx, source, {
|
||||
line: 1,
|
||||
column: 1,
|
||||
sourceId: source.id
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
expect(bp && bp.location).toEqual(loc1);
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
});
|
||||
|
||||
it("should remove a breakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [1], "6": [2] })
|
||||
);
|
||||
|
||||
@ -163,34 +163,34 @@ describe("breakpoints", () => {
|
||||
|
||||
const aSource = makeSource("a");
|
||||
await dispatch(actions.newSource(aSource));
|
||||
await dispatch(actions.loadSourceText({ source: aSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: aSource }));
|
||||
|
||||
const bSource = makeSource("b");
|
||||
await dispatch(actions.newSource(bSource));
|
||||
await dispatch(actions.loadSourceText({ source: bSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: bSource }));
|
||||
|
||||
await dispatch(
|
||||
actions.setSelectedLocation(aSource, {
|
||||
actions.setSelectedLocation(cx, aSource, {
|
||||
line: 1,
|
||||
column: 1,
|
||||
sourceId: aSource.id
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(loc2));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc2));
|
||||
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
if (!bp) {
|
||||
throw new Error("no bp");
|
||||
}
|
||||
await dispatch(actions.removeBreakpoint(bp));
|
||||
await dispatch(actions.removeBreakpoint(cx, bp));
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
});
|
||||
|
||||
it("should disable a breakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [1], "6": [2] })
|
||||
);
|
||||
|
||||
@ -210,28 +210,28 @@ describe("breakpoints", () => {
|
||||
|
||||
const aSource = makeSource("a");
|
||||
await dispatch(actions.newSource(aSource));
|
||||
await dispatch(actions.loadSourceText({ source: aSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: aSource }));
|
||||
|
||||
const bSource = makeSource("b");
|
||||
await dispatch(actions.newSource(bSource));
|
||||
await dispatch(actions.loadSourceText({ source: bSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: bSource }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(loc2));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc2));
|
||||
|
||||
const breakpoint = selectors.getBreakpoint(getState(), loc1);
|
||||
if (!breakpoint) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(breakpoint));
|
||||
await dispatch(actions.disableBreakpoint(cx, breakpoint));
|
||||
|
||||
const bp = selectors.getBreakpoint(getState(), loc1);
|
||||
expect(bp && bp.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it("should enable breakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [1], "6": [2] })
|
||||
);
|
||||
const loc = {
|
||||
@ -243,15 +243,15 @@ describe("breakpoints", () => {
|
||||
|
||||
const aSource = makeSource("a");
|
||||
await dispatch(actions.newSource(aSource));
|
||||
await dispatch(actions.loadSourceText({ source: aSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: aSource }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc));
|
||||
await dispatch(actions.addBreakpoint(cx, loc));
|
||||
let bp = selectors.getBreakpoint(getState(), loc);
|
||||
if (!bp) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(bp));
|
||||
await dispatch(actions.disableBreakpoint(cx, bp));
|
||||
|
||||
bp = selectors.getBreakpoint(getState(), loc);
|
||||
if (!bp) {
|
||||
@ -260,14 +260,14 @@ describe("breakpoints", () => {
|
||||
|
||||
expect(bp && bp.disabled).toBe(true);
|
||||
|
||||
await dispatch(actions.enableBreakpoint(bp));
|
||||
await dispatch(actions.enableBreakpoint(cx, bp));
|
||||
|
||||
bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && !bp.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it("should toggle all the breakpoints", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [1], "6": [2] })
|
||||
);
|
||||
|
||||
@ -287,16 +287,16 @@ describe("breakpoints", () => {
|
||||
|
||||
const aSource = makeSource("a");
|
||||
await dispatch(actions.newSource(aSource));
|
||||
await dispatch(actions.loadSourceText({ source: aSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: aSource }));
|
||||
|
||||
const bSource = makeSource("b");
|
||||
await dispatch(actions.newSource(bSource));
|
||||
await dispatch(actions.loadSourceText({ source: bSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: bSource }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc1));
|
||||
await dispatch(actions.addBreakpoint(loc2));
|
||||
await dispatch(actions.addBreakpoint(cx, loc1));
|
||||
await dispatch(actions.addBreakpoint(cx, loc2));
|
||||
|
||||
await dispatch(actions.toggleAllBreakpoints(true));
|
||||
await dispatch(actions.toggleAllBreakpoints(cx, true));
|
||||
|
||||
let bp1 = selectors.getBreakpoint(getState(), loc1);
|
||||
let bp2 = selectors.getBreakpoint(getState(), loc2);
|
||||
@ -304,7 +304,7 @@ describe("breakpoints", () => {
|
||||
expect(bp1 && bp1.disabled).toBe(true);
|
||||
expect(bp2 && bp2.disabled).toBe(true);
|
||||
|
||||
await dispatch(actions.toggleAllBreakpoints(false));
|
||||
await dispatch(actions.toggleAllBreakpoints(cx, false));
|
||||
|
||||
bp1 = selectors.getBreakpoint(getState(), loc1);
|
||||
bp2 = selectors.getBreakpoint(getState(), loc2);
|
||||
@ -316,19 +316,19 @@ describe("breakpoints", () => {
|
||||
const loc = { sourceId: "foo1", line: 5, column: 1 };
|
||||
const getBp = () => selectors.getBreakpoint(getState(), loc);
|
||||
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
|
||||
const source = makeSource("foo1");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.selectLocation(loc));
|
||||
await dispatch(actions.selectLocation(cx, loc));
|
||||
|
||||
await dispatch(actions.toggleBreakpointAtLine(5));
|
||||
await dispatch(actions.toggleBreakpointAtLine(cx, 5));
|
||||
const bp = getBp();
|
||||
expect(bp && !bp.disabled).toBe(true);
|
||||
|
||||
await dispatch(actions.toggleBreakpointAtLine(5));
|
||||
await dispatch(actions.toggleBreakpointAtLine(cx, 5));
|
||||
expect(getBp()).toBe(undefined);
|
||||
});
|
||||
|
||||
@ -336,28 +336,28 @@ describe("breakpoints", () => {
|
||||
const location = { sourceId: "foo1", line: 5, column: 1 };
|
||||
const getBp = () => selectors.getBreakpoint(getState(), location);
|
||||
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
|
||||
const source = makeSource("foo1");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo1", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo1", line: 1 }));
|
||||
|
||||
await dispatch(actions.toggleBreakpointAtLine(5));
|
||||
await dispatch(actions.toggleBreakpointAtLine(cx, 5));
|
||||
let bp = getBp();
|
||||
expect(bp && !bp.disabled).toBe(true);
|
||||
bp = getBp();
|
||||
if (!bp) {
|
||||
throw new Error("no bp");
|
||||
}
|
||||
await dispatch(actions.toggleDisabledBreakpoint(bp));
|
||||
await dispatch(actions.toggleDisabledBreakpoint(cx, bp));
|
||||
bp = getBp();
|
||||
expect(bp && bp.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it("should set the breakpoint condition", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
|
||||
const loc = {
|
||||
sourceId: "a",
|
||||
@ -368,15 +368,15 @@ describe("breakpoints", () => {
|
||||
|
||||
const source = makeSource("a");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc));
|
||||
await dispatch(actions.addBreakpoint(cx, loc));
|
||||
|
||||
let bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && bp.options.condition).toBe(undefined);
|
||||
|
||||
await dispatch(
|
||||
actions.setBreakpointOptions(loc, {
|
||||
actions.setBreakpointOptions(cx, loc, {
|
||||
condition: "const foo = 0",
|
||||
getTextForLine: () => {}
|
||||
})
|
||||
@ -387,7 +387,7 @@ describe("breakpoints", () => {
|
||||
});
|
||||
|
||||
it("should set the condition and enable a breakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "5": [1] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "5": [1] }));
|
||||
|
||||
const loc = {
|
||||
sourceId: "a",
|
||||
@ -398,21 +398,21 @@ describe("breakpoints", () => {
|
||||
|
||||
const source = makeSource("a");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc));
|
||||
await dispatch(actions.addBreakpoint(cx, loc));
|
||||
let bp = selectors.getBreakpoint(getState(), loc);
|
||||
if (!bp) {
|
||||
throw new Error("no breakpoint");
|
||||
}
|
||||
|
||||
await dispatch(actions.disableBreakpoint(bp));
|
||||
await dispatch(actions.disableBreakpoint(cx, bp));
|
||||
|
||||
bp = selectors.getBreakpoint(getState(), loc);
|
||||
expect(bp && bp.options.condition).toBe(undefined);
|
||||
|
||||
await dispatch(
|
||||
actions.setBreakpointOptions(loc, {
|
||||
actions.setBreakpointOptions(cx, loc, {
|
||||
condition: "const foo = 0",
|
||||
getTextForLine: () => {}
|
||||
})
|
||||
@ -425,7 +425,7 @@ describe("breakpoints", () => {
|
||||
});
|
||||
|
||||
it("should remap breakpoints on pretty print", async () => {
|
||||
const { dispatch, getState } = createStore(mockClient({ "1": [0] }));
|
||||
const { dispatch, getState, cx } = createStore(mockClient({ "1": [0] }));
|
||||
|
||||
const loc = {
|
||||
sourceId: "a.js",
|
||||
@ -436,10 +436,10 @@ describe("breakpoints", () => {
|
||||
|
||||
const source = makeSource("a.js");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(loc));
|
||||
await dispatch(actions.togglePrettyPrint("a.js"));
|
||||
await dispatch(actions.addBreakpoint(cx, loc));
|
||||
await dispatch(actions.togglePrettyPrint(cx, "a.js"));
|
||||
|
||||
const breakpoint = selectors.getBreakpointsList(getState())[0];
|
||||
|
||||
|
@ -6,10 +6,13 @@
|
||||
|
||||
import type { Action, ThunkArgs } from "./types";
|
||||
|
||||
import { getContext } from "../selectors";
|
||||
|
||||
export function updateWorkers() {
|
||||
return async function({ dispatch, getState, client }: ThunkArgs) {
|
||||
const cx = getContext(getState());
|
||||
const workers = await client.fetchWorkers();
|
||||
const mainThread = client.getMainThread();
|
||||
dispatch(({ type: "SET_WORKERS", workers, mainThread }: Action));
|
||||
dispatch(({ type: "SET_WORKERS", cx, workers, mainThread }: Action));
|
||||
};
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ import { features } from "../utils/prefs";
|
||||
import { isOriginal } from "../utils/source";
|
||||
|
||||
import * as parser from "../workers/parser";
|
||||
import type { Expression } from "../types";
|
||||
import type { Expression, ThreadContext } from "../types";
|
||||
import type { ThunkArgs } from "./types";
|
||||
|
||||
/**
|
||||
@ -33,7 +33,7 @@ import type { ThunkArgs } from "./types";
|
||||
* @memberof actions/pause
|
||||
* @static
|
||||
*/
|
||||
export function addExpression(input: string) {
|
||||
export function addExpression(cx: ThreadContext, input: string) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
if (!input) {
|
||||
return;
|
||||
@ -43,27 +43,26 @@ export function addExpression(input: string) {
|
||||
|
||||
const expression = getExpression(getState(), input);
|
||||
if (expression) {
|
||||
return dispatch(evaluateExpression(expression));
|
||||
return dispatch(evaluateExpression(cx, expression));
|
||||
}
|
||||
|
||||
dispatch({ type: "ADD_EXPRESSION", input, expressionError });
|
||||
dispatch({ type: "ADD_EXPRESSION", cx, input, expressionError });
|
||||
|
||||
const newExpression = getExpression(getState(), input);
|
||||
if (newExpression) {
|
||||
return dispatch(evaluateExpression(newExpression));
|
||||
return dispatch(evaluateExpression(cx, newExpression));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function autocomplete(input: string, cursor: number) {
|
||||
export function autocomplete(cx: ThreadContext, input: string, cursor: number) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
if (!input) {
|
||||
return;
|
||||
}
|
||||
const thread = getCurrentThread(getState());
|
||||
const frameId = getSelectedFrameId(getState(), thread);
|
||||
const frameId = getSelectedFrameId(getState(), cx.thread);
|
||||
const result = await client.autocomplete(input, cursor, frameId);
|
||||
await dispatch({ type: "AUTOCOMPLETE", input, result });
|
||||
await dispatch({ type: "AUTOCOMPLETE", cx, input, result });
|
||||
};
|
||||
}
|
||||
|
||||
@ -75,7 +74,11 @@ export function clearExpressionError() {
|
||||
return { type: "CLEAR_EXPRESSION_ERROR" };
|
||||
}
|
||||
|
||||
export function updateExpression(input: string, expression: Expression) {
|
||||
export function updateExpression(
|
||||
cx: ThreadContext,
|
||||
input: string,
|
||||
expression: Expression
|
||||
) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
if (!input) {
|
||||
return;
|
||||
@ -84,12 +87,13 @@ export function updateExpression(input: string, expression: Expression) {
|
||||
const expressionError = await parser.hasSyntaxError(input);
|
||||
dispatch({
|
||||
type: "UPDATE_EXPRESSION",
|
||||
cx,
|
||||
expression,
|
||||
input: expressionError ? expression.input : input,
|
||||
expressionError
|
||||
});
|
||||
|
||||
dispatch(evaluateExpressions());
|
||||
dispatch(evaluateExpressions(cx));
|
||||
};
|
||||
}
|
||||
|
||||
@ -115,21 +119,20 @@ export function deleteExpression(expression: Expression) {
|
||||
* @param {number} selectedFrameId
|
||||
* @static
|
||||
*/
|
||||
export function evaluateExpressions() {
|
||||
export function evaluateExpressions(cx: ThreadContext) {
|
||||
return async function({ dispatch, getState, client }: ThunkArgs) {
|
||||
const expressions = getExpressions(getState()).toJS();
|
||||
const inputs = expressions.map(({ input }) => input);
|
||||
const thread = getCurrentThread(getState());
|
||||
const frameId = getSelectedFrameId(getState(), thread);
|
||||
const frameId = getSelectedFrameId(getState(), cx.thread);
|
||||
const results = await client.evaluateExpressions(inputs, {
|
||||
frameId,
|
||||
thread
|
||||
thread: cx.thread
|
||||
});
|
||||
dispatch({ type: "EVALUATE_EXPRESSIONS", inputs, results });
|
||||
dispatch({ type: "EVALUATE_EXPRESSIONS", cx, inputs, results });
|
||||
};
|
||||
}
|
||||
|
||||
function evaluateExpression(expression: Expression) {
|
||||
function evaluateExpression(cx: ThreadContext, expression: Expression) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
if (!expression.input) {
|
||||
console.warn("Expressions should not be empty");
|
||||
@ -137,8 +140,7 @@ function evaluateExpression(expression: Expression) {
|
||||
}
|
||||
|
||||
let input = expression.input;
|
||||
const thread = getCurrentThread(getState());
|
||||
const frame = getSelectedFrame(getState(), thread);
|
||||
const frame = getSelectedFrame(getState(), cx.thread);
|
||||
|
||||
if (frame) {
|
||||
const { location } = frame;
|
||||
@ -154,15 +156,16 @@ function evaluateExpression(expression: Expression) {
|
||||
}
|
||||
}
|
||||
|
||||
const frameId = getSelectedFrameId(getState(), thread);
|
||||
const frameId = getSelectedFrameId(getState(), cx.thread);
|
||||
|
||||
return dispatch({
|
||||
type: "EVALUATE_EXPRESSION",
|
||||
thread,
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
input: expression.input,
|
||||
[PROMISE]: client.evaluateInFrame(wrapExpression(input), {
|
||||
frameId,
|
||||
thread
|
||||
thread: cx.thread
|
||||
})
|
||||
});
|
||||
};
|
||||
|
@ -15,7 +15,7 @@ import {
|
||||
import { isWasm, renderWasmText } from "../utils/wasm";
|
||||
import { getMatches } from "../workers/search";
|
||||
import type { Action, FileTextSearchModifier, ThunkArgs } from "./types";
|
||||
import type { WasmSource } from "../types";
|
||||
import type { WasmSource, Context } from "../types";
|
||||
|
||||
import {
|
||||
getSelectedSource,
|
||||
@ -32,15 +32,15 @@ import {
|
||||
type Editor = Object;
|
||||
type Match = Object;
|
||||
|
||||
export function doSearch(query: string, editor: Editor) {
|
||||
export function doSearch(cx: Context, query: string, editor: Editor) {
|
||||
return ({ getState, dispatch }: ThunkArgs) => {
|
||||
const selectedSource = getSelectedSource(getState());
|
||||
if (!selectedSource || !selectedSource.text) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(setFileSearchQuery(query));
|
||||
dispatch(searchContents(query, editor));
|
||||
dispatch(setFileSearchQuery(cx, query));
|
||||
dispatch(searchContents(cx, query, editor));
|
||||
};
|
||||
}
|
||||
|
||||
@ -59,20 +59,23 @@ export function doSearchForHighlight(
|
||||
};
|
||||
}
|
||||
|
||||
export function setFileSearchQuery(query: string): Action {
|
||||
export function setFileSearchQuery(cx: Context, query: string): Action {
|
||||
return {
|
||||
type: "UPDATE_FILE_SEARCH_QUERY",
|
||||
cx,
|
||||
query
|
||||
};
|
||||
}
|
||||
|
||||
export function toggleFileSearchModifier(
|
||||
cx: Context,
|
||||
modifier: FileTextSearchModifier
|
||||
): Action {
|
||||
return { type: "TOGGLE_FILE_SEARCH_MODIFIER", modifier };
|
||||
return { type: "TOGGLE_FILE_SEARCH_MODIFIER", cx, modifier };
|
||||
}
|
||||
|
||||
export function updateSearchResults(
|
||||
cx: Context,
|
||||
characterIndex: number,
|
||||
line: number,
|
||||
matches: Match[]
|
||||
@ -83,6 +86,7 @@ export function updateSearchResults(
|
||||
|
||||
return {
|
||||
type: "UPDATE_SEARCH_RESULTS",
|
||||
cx,
|
||||
results: {
|
||||
matches,
|
||||
matchIndex,
|
||||
@ -92,7 +96,7 @@ export function updateSearchResults(
|
||||
};
|
||||
}
|
||||
|
||||
export function searchContents(query: string, editor: Object) {
|
||||
export function searchContents(cx: Context, query: string, editor: Object) {
|
||||
return async ({ getState, dispatch }: ThunkArgs) => {
|
||||
const modifiers = getFileSearchModifiers(getState());
|
||||
const selectedSource = getSelectedSource(getState());
|
||||
@ -124,7 +128,7 @@ export function searchContents(query: string, editor: Object) {
|
||||
|
||||
const { ch, line } = res;
|
||||
|
||||
dispatch(updateSearchResults(ch, line, matches));
|
||||
dispatch(updateSearchResults(cx, ch, line, matches));
|
||||
};
|
||||
}
|
||||
|
||||
@ -155,7 +159,7 @@ export function searchContentsForHighlight(
|
||||
};
|
||||
}
|
||||
|
||||
export function traverseResults(rev: boolean, editor: Editor) {
|
||||
export function traverseResults(cx: Context, rev: boolean, editor: Editor) {
|
||||
return async ({ getState, dispatch }: ThunkArgs) => {
|
||||
if (!editor) {
|
||||
return;
|
||||
@ -180,12 +184,12 @@ export function traverseResults(rev: boolean, editor: Editor) {
|
||||
return;
|
||||
}
|
||||
const { ch, line } = results;
|
||||
dispatch(updateSearchResults(ch, line, matchedLocations));
|
||||
dispatch(updateSearchResults(cx, ch, line, matchedLocations));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function closeFileSearch(editor: Editor) {
|
||||
export function closeFileSearch(cx: Context, editor: Editor) {
|
||||
return ({ getState, dispatch }: ThunkArgs) => {
|
||||
if (editor) {
|
||||
const query = getFileSearchQuery(getState());
|
||||
@ -193,7 +197,7 @@ export function closeFileSearch(editor: Editor) {
|
||||
removeOverlay(ctx, query);
|
||||
}
|
||||
|
||||
dispatch(setFileSearchQuery(""));
|
||||
dispatch(setFileSearchQuery(cx, ""));
|
||||
dispatch(closeActiveSearch());
|
||||
dispatch(clearHighlightLineRange());
|
||||
};
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import { getCurrentThread } from "../../selectors";
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type { ThreadContext } from "../../types";
|
||||
|
||||
/**
|
||||
* Debugger breakOnNext command.
|
||||
@ -15,10 +15,9 @@ import type { ThunkArgs } from "../types";
|
||||
* @memberof actions/pause
|
||||
* @static
|
||||
*/
|
||||
export function breakOnNext() {
|
||||
export function breakOnNext(cx: ThreadContext) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
await client.breakOnNext(thread);
|
||||
return dispatch({ type: "BREAK_ON_NEXT", thread });
|
||||
await client.breakOnNext(cx.thread);
|
||||
return dispatch({ type: "BREAK_ON_NEXT", thread: cx.thread });
|
||||
};
|
||||
}
|
||||
|
@ -6,32 +6,39 @@
|
||||
// @flow
|
||||
|
||||
import {
|
||||
getIsPaused,
|
||||
getCurrentThread,
|
||||
getSource,
|
||||
getTopFrame,
|
||||
getSelectedFrame
|
||||
getSelectedFrame,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import { getNextStep } from "../../workers/parser";
|
||||
import { addHiddenBreakpoint } from "../breakpoints";
|
||||
import { evaluateExpressions } from "../expressions";
|
||||
import { selectLocation } from "../sources";
|
||||
import { fetchScopes } from "./fetchScopes";
|
||||
import { features } from "../../utils/prefs";
|
||||
import { recordEvent } from "../../utils/telemetry";
|
||||
import assert from "../../utils/assert";
|
||||
|
||||
import type { Source, ThreadId } from "../../types";
|
||||
import type { Source, ThreadId, Context, ThreadContext } from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type { Command } from "../../reducers/types";
|
||||
|
||||
export function selectThread(thread: ThreadId) {
|
||||
export function selectThread(cx: Context, thread: ThreadId) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
await dispatch({ type: "SELECT_THREAD", thread });
|
||||
dispatch(evaluateExpressions());
|
||||
await dispatch({ cx, type: "SELECT_THREAD", thread });
|
||||
|
||||
// Get a new context now that the current thread has changed.
|
||||
const threadcx = getThreadContext(getState());
|
||||
assert(threadcx.thread == thread, "Thread mismatch");
|
||||
|
||||
dispatch(evaluateExpressions(threadcx));
|
||||
|
||||
const frame = getSelectedFrame(getState(), thread);
|
||||
if (frame) {
|
||||
dispatch(selectLocation(frame.location));
|
||||
dispatch(selectLocation(threadcx, frame.location));
|
||||
dispatch(fetchScopes(threadcx));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -43,14 +50,15 @@ export function selectThread(thread: ThreadId) {
|
||||
* @memberof actions/pause
|
||||
* @static
|
||||
*/
|
||||
export function command(thread: ThreadId, type: Command) {
|
||||
export function command(cx: ThreadContext, type: Command) {
|
||||
return async ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
if (type) {
|
||||
return dispatch({
|
||||
type: "COMMAND",
|
||||
command: type,
|
||||
thread,
|
||||
[PROMISE]: client[type](thread)
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
[PROMISE]: client[type](cx.thread)
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -62,11 +70,10 @@ export function command(thread: ThreadId, type: Command) {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function stepIn() {
|
||||
export function stepIn(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(command(thread, "stepIn"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(command(cx, "stepIn"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -77,11 +84,10 @@ export function stepIn() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function stepOver() {
|
||||
export function stepOver(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(astCommand(thread, "stepOver"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(astCommand(cx, "stepOver"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -92,11 +98,10 @@ export function stepOver() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function stepOut() {
|
||||
export function stepOut(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(command(thread, "stepOut"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(command(cx, "stepOut"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -107,12 +112,11 @@ export function stepOut() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function resume() {
|
||||
export function resume(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
if (cx.isPaused) {
|
||||
recordEvent("continue");
|
||||
return dispatch(command(thread, "resume"));
|
||||
return dispatch(command(cx, "resume"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -123,11 +127,10 @@ export function resume() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function rewind() {
|
||||
export function rewind(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(command(thread, "rewind"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(command(cx, "rewind"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -138,11 +141,10 @@ export function rewind() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function reverseStepIn() {
|
||||
export function reverseStepIn(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(command(thread, "reverseStepIn"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(command(cx, "reverseStepIn"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -153,11 +155,10 @@ export function reverseStepIn() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function reverseStepOver() {
|
||||
export function reverseStepOver(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(astCommand(thread, "reverseStepOver"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(astCommand(cx, "reverseStepOver"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -168,11 +169,10 @@ export function reverseStepOver() {
|
||||
* @static
|
||||
* @returns {Function} {@link command}
|
||||
*/
|
||||
export function reverseStepOut() {
|
||||
export function reverseStepOut(cx: ThreadContext) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getIsPaused(getState(), thread)) {
|
||||
return dispatch(command(thread, "reverseStepOut"));
|
||||
if (cx.isPaused) {
|
||||
return dispatch(command(cx, "reverseStepOut"));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -205,26 +205,26 @@ function hasAwait(source: Source, pauseLocation) {
|
||||
* @param stepType
|
||||
* @returns {function(ThunkArgs)}
|
||||
*/
|
||||
export function astCommand(thread: ThreadId, stepType: Command) {
|
||||
export function astCommand(cx: ThreadContext, stepType: Command) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
if (!features.asyncStepping) {
|
||||
return dispatch(command(thread, stepType));
|
||||
return dispatch(command(cx, stepType));
|
||||
}
|
||||
|
||||
if (stepType == "stepOver") {
|
||||
// This type definition is ambiguous:
|
||||
const frame: any = getTopFrame(getState(), thread);
|
||||
const frame: any = getTopFrame(getState(), cx.thread);
|
||||
const source = getSource(getState(), frame.location.sourceId);
|
||||
|
||||
if (source && hasAwait(source, frame.location)) {
|
||||
const nextLocation = await getNextStep(source.id, frame.location);
|
||||
if (nextLocation) {
|
||||
await dispatch(addHiddenBreakpoint(nextLocation));
|
||||
return dispatch(command(thread, "resume"));
|
||||
await dispatch(addHiddenBreakpoint(cx, nextLocation));
|
||||
return dispatch(command(cx, "resume"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dispatch(command(thread, stepType));
|
||||
return dispatch(command(cx, stepType));
|
||||
};
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
// @flow
|
||||
|
||||
import {
|
||||
getCurrentThread,
|
||||
getSelectedSource,
|
||||
getSelectedFrame,
|
||||
getCanRewind
|
||||
@ -14,12 +13,16 @@ import { addHiddenBreakpoint } from "../breakpoints";
|
||||
import { resume, rewind } from "./commands";
|
||||
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type { ThreadContext } from "../../types";
|
||||
|
||||
export function continueToHere(line: number, column?: number) {
|
||||
export function continueToHere(
|
||||
cx: ThreadContext,
|
||||
line: number,
|
||||
column?: number
|
||||
) {
|
||||
return async function({ dispatch, getState }: ThunkArgs) {
|
||||
const thread = getCurrentThread(getState());
|
||||
const selectedSource = getSelectedSource(getState());
|
||||
const selectedFrame = getSelectedFrame(getState(), thread);
|
||||
const selectedFrame = getSelectedFrame(getState(), cx.thread);
|
||||
|
||||
if (!selectedFrame || !selectedSource) {
|
||||
return;
|
||||
@ -34,13 +37,13 @@ export function continueToHere(line: number, column?: number) {
|
||||
getCanRewind(getState()) && line < debugLine ? rewind : resume;
|
||||
|
||||
await dispatch(
|
||||
addHiddenBreakpoint({
|
||||
addHiddenBreakpoint(cx, {
|
||||
line,
|
||||
column: column,
|
||||
sourceId: selectedSource.id
|
||||
})
|
||||
);
|
||||
|
||||
dispatch(action());
|
||||
dispatch(action(cx));
|
||||
};
|
||||
}
|
||||
|
@ -7,23 +7,24 @@
|
||||
import { getSelectedFrame, getGeneratedFrameScope } from "../../selectors";
|
||||
import { mapScopes } from "./mapScopes";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import type { ThreadId } from "../../types";
|
||||
import type { ThreadContext } from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
export function fetchScopes(thread: ThreadId) {
|
||||
export function fetchScopes(cx: ThreadContext) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
const frame = getSelectedFrame(getState(), thread);
|
||||
const frame = getSelectedFrame(getState(), cx.thread);
|
||||
if (!frame || getGeneratedFrameScope(getState(), frame.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scopes = dispatch({
|
||||
type: "ADD_SCOPES",
|
||||
thread,
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
frame,
|
||||
[PROMISE]: client.getFrameScopes(frame)
|
||||
});
|
||||
|
||||
await dispatch(mapScopes(scopes, frame));
|
||||
await dispatch(mapScopes(cx, scopes, frame));
|
||||
};
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import assert from "../../utils/assert";
|
||||
import { findClosestFunction } from "../../utils/ast";
|
||||
import { setSymbols } from "../sources/symbols";
|
||||
|
||||
import type { Frame, ThreadId } from "../../types";
|
||||
import type { Frame, ThreadContext } from "../../types";
|
||||
import type { State } from "../../reducers/types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
@ -155,11 +155,11 @@ async function expandFrames(
|
||||
return result;
|
||||
}
|
||||
|
||||
async function updateFrameSymbols(frames, { dispatch, getState }) {
|
||||
async function updateFrameSymbols(cx, frames, { dispatch, getState }) {
|
||||
await Promise.all(
|
||||
frames.map(frame => {
|
||||
const source = getSourceFromId(getState(), frame.location.sourceId);
|
||||
return dispatch(setSymbols({ source }));
|
||||
return dispatch(setSymbols({ cx, source }));
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -173,28 +173,29 @@ async function updateFrameSymbols(frames, { dispatch, getState }) {
|
||||
* @memberof actions/pause
|
||||
* @static
|
||||
*/
|
||||
export function mapFrames(thread: ThreadId) {
|
||||
export function mapFrames(cx: ThreadContext) {
|
||||
return async function(thunkArgs: ThunkArgs) {
|
||||
const { dispatch, getState, sourceMaps } = thunkArgs;
|
||||
const frames = getFrames(getState(), thread);
|
||||
const frames = getFrames(getState(), cx.thread);
|
||||
if (!frames) {
|
||||
return;
|
||||
}
|
||||
|
||||
let mappedFrames = await updateFrameLocations(frames, sourceMaps);
|
||||
await updateFrameSymbols(mappedFrames, thunkArgs);
|
||||
await updateFrameSymbols(cx, mappedFrames, thunkArgs);
|
||||
|
||||
mappedFrames = await expandFrames(mappedFrames, sourceMaps, getState);
|
||||
mappedFrames = mapDisplayNames(mappedFrames, getState);
|
||||
|
||||
const selectedFrameId = getSelectedFrameId(
|
||||
getState(),
|
||||
thread,
|
||||
cx.thread,
|
||||
mappedFrames
|
||||
);
|
||||
dispatch({
|
||||
type: "MAP_FRAMES",
|
||||
thread,
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
frames: mappedFrames,
|
||||
selectedFrameId
|
||||
});
|
||||
|
@ -10,15 +10,16 @@ import {
|
||||
getSelectedFrame,
|
||||
getSelectedGeneratedScope,
|
||||
getSelectedOriginalScope,
|
||||
getCurrentThread
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
import { loadSourceText } from "../sources/loadSourceText";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
import assert from "../../utils/assert";
|
||||
|
||||
import { features } from "../../utils/prefs";
|
||||
import { log } from "../../utils/log";
|
||||
import { isGenerated, isOriginal } from "../../utils/source";
|
||||
import type { Frame, Scope } from "../../types";
|
||||
import type { Frame, Scope, ThreadContext } from "../../types";
|
||||
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
@ -32,23 +33,30 @@ export function toggleMapScopes() {
|
||||
|
||||
dispatch({ type: "TOGGLE_MAP_SCOPES", mapScopes: true });
|
||||
|
||||
const thread = getCurrentThread(getState());
|
||||
if (getSelectedOriginalScope(getState(), thread)) {
|
||||
const cx = getThreadContext(getState());
|
||||
|
||||
if (getSelectedOriginalScope(getState(), cx.thread)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scopes = getSelectedGeneratedScope(getState(), thread);
|
||||
const frame = getSelectedFrame(getState(), thread);
|
||||
const scopes = getSelectedGeneratedScope(getState(), cx.thread);
|
||||
const frame = getSelectedFrame(getState(), cx.thread);
|
||||
if (!scopes || !frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(mapScopes(Promise.resolve(scopes.scope), frame));
|
||||
dispatch(mapScopes(cx, Promise.resolve(scopes.scope), frame));
|
||||
};
|
||||
}
|
||||
|
||||
export function mapScopes(scopes: Promise<Scope>, frame: Frame) {
|
||||
export function mapScopes(
|
||||
cx: ThreadContext,
|
||||
scopes: Promise<Scope>,
|
||||
frame: Frame
|
||||
) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
assert(cx.thread == frame.thread, "Thread mismatch");
|
||||
|
||||
const generatedSource = getSource(
|
||||
getState(),
|
||||
frame.generatedLocation.sourceId
|
||||
@ -58,7 +66,8 @@ export function mapScopes(scopes: Promise<Scope>, frame: Frame) {
|
||||
|
||||
await dispatch({
|
||||
type: "MAP_SCOPES",
|
||||
thread: frame.thread,
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
frame,
|
||||
[PROMISE]: (async function() {
|
||||
if (
|
||||
@ -72,9 +81,9 @@ export function mapScopes(scopes: Promise<Scope>, frame: Frame) {
|
||||
return null;
|
||||
}
|
||||
|
||||
await dispatch(loadSourceText({ source }));
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
if (isOriginal(source)) {
|
||||
await dispatch(loadSourceText({ source: generatedSource }));
|
||||
await dispatch(loadSourceText({ cx, source: generatedSource }));
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -7,7 +7,8 @@ import {
|
||||
getHiddenBreakpoint,
|
||||
isEvaluatingExpression,
|
||||
getSelectedFrame,
|
||||
wasStepping
|
||||
wasStepping,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
|
||||
import { mapFrames } from ".";
|
||||
@ -15,6 +16,7 @@ import { removeBreakpoint } from "../breakpoints";
|
||||
import { evaluateExpressions } from "../expressions";
|
||||
import { selectLocation } from "../sources";
|
||||
import { togglePaneCollapse } from "../ui";
|
||||
import assert from "../../utils/assert";
|
||||
|
||||
import { fetchScopes } from "./fetchScopes";
|
||||
|
||||
@ -42,29 +44,33 @@ export function paused(pauseInfo: Pause) {
|
||||
loadedObjects: loadedObjects || []
|
||||
});
|
||||
|
||||
// Get a context capturing the newly paused and selected thread.
|
||||
const cx = getThreadContext(getState());
|
||||
assert(cx.thread == thread, "Thread mismatch");
|
||||
|
||||
const hiddenBreakpoint = getHiddenBreakpoint(getState());
|
||||
if (hiddenBreakpoint) {
|
||||
dispatch(removeBreakpoint(hiddenBreakpoint));
|
||||
dispatch(removeBreakpoint(cx, hiddenBreakpoint));
|
||||
}
|
||||
|
||||
await dispatch(mapFrames(thread));
|
||||
await dispatch(mapFrames(cx));
|
||||
|
||||
const selectedFrame = getSelectedFrame(getState(), thread);
|
||||
if (selectedFrame) {
|
||||
await dispatch(selectLocation(selectedFrame.location));
|
||||
await dispatch(selectLocation(cx, selectedFrame.location));
|
||||
}
|
||||
|
||||
if (!wasStepping(getState(), thread)) {
|
||||
dispatch(togglePaneCollapse("end", false));
|
||||
}
|
||||
|
||||
await dispatch(fetchScopes(thread));
|
||||
await dispatch(fetchScopes(cx));
|
||||
|
||||
// Run after fetching scoping data so that it may make use of the sourcemap
|
||||
// expression mappings for local variables.
|
||||
const atException = why.type == "exception";
|
||||
if (!atException || !isEvaluatingExpression(getState(), thread)) {
|
||||
await dispatch(evaluateExpressions());
|
||||
await dispatch(evaluateExpressions(cx));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import { isStepping, getPauseReason } from "../../selectors";
|
||||
import { isStepping, getPauseReason, getThreadContext } from "../../selectors";
|
||||
import { evaluateExpressions } from "../expressions";
|
||||
import { inDebuggerEval } from "../../utils/pause";
|
||||
|
||||
@ -26,8 +26,9 @@ export function resumed(packet: ResumedPacket) {
|
||||
|
||||
dispatch({ type: "RESUME", thread, wasStepping });
|
||||
|
||||
if (!wasStepping && !wasPausedInEval) {
|
||||
await dispatch(evaluateExpressions());
|
||||
const cx = getThreadContext(getState());
|
||||
if (!wasStepping && !wasPausedInEval && cx.thread == thread) {
|
||||
await dispatch(evaluateExpressions(cx));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -7,25 +7,29 @@
|
||||
import { selectLocation } from "../sources";
|
||||
import { evaluateExpressions } from "../expressions";
|
||||
import { fetchScopes } from "./fetchScopes";
|
||||
import assert from "../../utils/assert";
|
||||
|
||||
import type { Frame } from "../../types";
|
||||
import type { Frame, ThreadContext } from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
/**
|
||||
* @memberof actions/pause
|
||||
* @static
|
||||
*/
|
||||
export function selectFrame(frame: Frame) {
|
||||
export function selectFrame(cx: ThreadContext, frame: Frame) {
|
||||
return async ({ dispatch, client, getState, sourceMaps }: ThunkArgs) => {
|
||||
assert(cx.thread == frame.thread, "Thread mismatch");
|
||||
|
||||
dispatch({
|
||||
type: "SELECT_FRAME",
|
||||
thread: frame.thread,
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
frame
|
||||
});
|
||||
|
||||
dispatch(selectLocation(frame.location));
|
||||
dispatch(selectLocation(cx, frame.location));
|
||||
|
||||
dispatch(evaluateExpressions());
|
||||
dispatch(fetchScopes(frame.thread));
|
||||
dispatch(evaluateExpressions(cx));
|
||||
dispatch(fetchScopes(cx));
|
||||
};
|
||||
}
|
||||
|
@ -4,25 +4,30 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import { getPopupObjectProperties, getCurrentThread } from "../../selectors";
|
||||
import { getPopupObjectProperties } from "../../selectors";
|
||||
import type { ThunkArgs } from "../types";
|
||||
import type { ThreadContext } from "../../types";
|
||||
|
||||
/**
|
||||
* @memberof actions/pause
|
||||
* @static
|
||||
*/
|
||||
export function setPopupObjectProperties(object: any, properties: Object) {
|
||||
export function setPopupObjectProperties(
|
||||
cx: ThreadContext,
|
||||
object: any,
|
||||
properties: Object
|
||||
) {
|
||||
return ({ dispatch, client, getState }: ThunkArgs) => {
|
||||
const objectId = object.actor || object.objectId;
|
||||
const thread = getCurrentThread(getState());
|
||||
|
||||
if (getPopupObjectProperties(getState(), thread, object.actor)) {
|
||||
if (getPopupObjectProperties(getState(), cx.thread, object.actor)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: "SET_POPUP_OBJECT_PROPERTIES",
|
||||
thread,
|
||||
cx,
|
||||
thread: cx.thread,
|
||||
objectId,
|
||||
properties
|
||||
});
|
||||
|
@ -109,7 +109,8 @@ describe("pause", () => {
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
const stepped = dispatch(actions.stepIn());
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
const stepped = dispatch(actions.stepIn(cx));
|
||||
expect(isStepping(getState(), "FakeThread")).toBeTruthy();
|
||||
if (!stepInResolve) {
|
||||
throw new Error("no stepInResolve");
|
||||
@ -121,9 +122,9 @@ describe("pause", () => {
|
||||
|
||||
it("should only step when paused", async () => {
|
||||
const client = { stepIn: jest.fn() };
|
||||
const { dispatch } = createStore(client);
|
||||
const { dispatch, cx } = createStore(client);
|
||||
|
||||
dispatch(actions.stepIn());
|
||||
dispatch(actions.stepIn(cx));
|
||||
expect(client.stepIn.mock.calls).toHaveLength(0);
|
||||
});
|
||||
|
||||
@ -133,7 +134,8 @@ describe("pause", () => {
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
dispatch(actions.stepIn());
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
dispatch(actions.stepIn(cx));
|
||||
expect(isStepping(getState(), "FakeThread")).toBeTruthy();
|
||||
});
|
||||
|
||||
@ -144,15 +146,16 @@ describe("pause", () => {
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
const getNextStepSpy = jest.spyOn(parser, "getNextStep");
|
||||
dispatch(actions.stepOver());
|
||||
dispatch(actions.stepOver(cx));
|
||||
expect(getNextStepSpy).not.toBeCalled();
|
||||
expect(isStepping(getState(), "FakeThread")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("should step over when paused before an await", async () => {
|
||||
const store = createStore(mockThreadClient);
|
||||
const { dispatch } = store;
|
||||
const { dispatch, getState } = store;
|
||||
const mockPauseInfo = createPauseInfo({
|
||||
sourceId: "await",
|
||||
line: 2,
|
||||
@ -163,15 +166,16 @@ describe("pause", () => {
|
||||
await dispatch(actions.newSource(source));
|
||||
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
const getNextStepSpy = jest.spyOn(parser, "getNextStep");
|
||||
dispatch(actions.stepOver());
|
||||
dispatch(actions.stepOver(cx));
|
||||
expect(getNextStepSpy).toBeCalled();
|
||||
getNextStepSpy.mockRestore();
|
||||
});
|
||||
|
||||
it("should step over when paused after an await", async () => {
|
||||
const store = createStore(mockThreadClient);
|
||||
const { dispatch } = store;
|
||||
const { dispatch, getState } = store;
|
||||
const mockPauseInfo = createPauseInfo({
|
||||
sourceId: "await",
|
||||
line: 2,
|
||||
@ -182,8 +186,9 @@ describe("pause", () => {
|
||||
await dispatch(actions.newSource(source));
|
||||
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
const getNextStepSpy = jest.spyOn(parser, "getNextStep");
|
||||
dispatch(actions.stepOver());
|
||||
dispatch(actions.stepOver(cx));
|
||||
expect(getNextStepSpy).toBeCalled();
|
||||
getNextStepSpy.mockRestore();
|
||||
});
|
||||
@ -367,22 +372,27 @@ describe("pause", () => {
|
||||
|
||||
describe("resumed", () => {
|
||||
it("should not evaluate expression while stepping", async () => {
|
||||
const client = { evaluateExpressions: jest.fn() };
|
||||
const { dispatch } = createStore(client);
|
||||
const client = { ...mockThreadClient, evaluateExpressions: jest.fn() };
|
||||
const { dispatch, getState } = createStore(client);
|
||||
const mockPauseInfo = createPauseInfo();
|
||||
|
||||
dispatch(actions.stepIn());
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.paused(mockPauseInfo));
|
||||
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
dispatch(actions.stepIn(cx));
|
||||
await dispatch(actions.resumed(resumedPacket()));
|
||||
expect(client.evaluateExpressions.mock.calls).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("resuming - will re-evaluate watch expressions", async () => {
|
||||
const store = createStore(mockThreadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
const mockPauseInfo = createPauseInfo();
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.newSource(makeSource("foo")));
|
||||
dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
await waitForState(store, state => selectors.getExpression(state, "foo"));
|
||||
|
||||
mockThreadClient.evaluateExpressions = () => new Promise(r => r(["YAY"]));
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
import { getMappedExpression } from "./expressions";
|
||||
|
||||
import type { Action, ThunkArgs } from "./types";
|
||||
import type { Position } from "../types";
|
||||
import type { Position, Context } from "../types";
|
||||
import type { AstLocation } from "../workers/parser";
|
||||
|
||||
function findExpressionMatch(state, codeMirror, tokenPos) {
|
||||
@ -43,6 +43,7 @@ function findExpressionMatch(state, codeMirror, tokenPos) {
|
||||
}
|
||||
|
||||
export function updatePreview(
|
||||
cx: Context,
|
||||
target: HTMLElement,
|
||||
tokenPos: Object,
|
||||
codeMirror: any
|
||||
@ -68,11 +69,12 @@ export function updatePreview(
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(setPreview(expression, location, tokenPos, cursorPos));
|
||||
dispatch(setPreview(cx, expression, location, tokenPos, cursorPos));
|
||||
};
|
||||
}
|
||||
|
||||
export function setPreview(
|
||||
cx: Context,
|
||||
expression: string,
|
||||
location: AstLocation,
|
||||
tokenPos: Position,
|
||||
@ -81,6 +83,7 @@ export function setPreview(
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
await dispatch({
|
||||
type: "SET_PREVIEW",
|
||||
cx,
|
||||
[PROMISE]: (async function() {
|
||||
const source = getSelectedSource(getState());
|
||||
if (!source) {
|
||||
@ -126,7 +129,7 @@ export function setPreview(
|
||||
};
|
||||
}
|
||||
|
||||
export function clearPreview() {
|
||||
export function clearPreview(cx: Context) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const currentSelection = getPreview(getState());
|
||||
if (!currentSelection) {
|
||||
@ -135,7 +138,8 @@ export function clearPreview() {
|
||||
|
||||
return dispatch(
|
||||
({
|
||||
type: "CLEAR_SELECTION"
|
||||
type: "CLEAR_SELECTION",
|
||||
cx
|
||||
}: Action)
|
||||
);
|
||||
};
|
||||
|
@ -20,67 +20,73 @@ import {
|
||||
} from "../reducers/project-text-search";
|
||||
|
||||
import type { Action, ThunkArgs } from "./types";
|
||||
import type { Context } from "../types";
|
||||
import type { SearchOperation } from "../reducers/project-text-search";
|
||||
|
||||
export function addSearchQuery(query: string): Action {
|
||||
return { type: "ADD_QUERY", query };
|
||||
export function addSearchQuery(cx: Context, query: string): Action {
|
||||
return { type: "ADD_QUERY", cx, query };
|
||||
}
|
||||
|
||||
export function addOngoingSearch(ongoingSearch: SearchOperation): Action {
|
||||
return { type: "ADD_ONGOING_SEARCH", ongoingSearch };
|
||||
export function addOngoingSearch(
|
||||
cx: Context,
|
||||
ongoingSearch: SearchOperation
|
||||
): Action {
|
||||
return { type: "ADD_ONGOING_SEARCH", cx, ongoingSearch };
|
||||
}
|
||||
|
||||
export function addSearchResult(
|
||||
cx: Context,
|
||||
sourceId: string,
|
||||
filepath: string,
|
||||
matches: Object[]
|
||||
): Action {
|
||||
return {
|
||||
type: "ADD_SEARCH_RESULT",
|
||||
cx,
|
||||
result: { sourceId, filepath, matches }
|
||||
};
|
||||
}
|
||||
|
||||
export function clearSearchResults(): Action {
|
||||
return { type: "CLEAR_SEARCH_RESULTS" };
|
||||
export function clearSearchResults(cx: Context): Action {
|
||||
return { type: "CLEAR_SEARCH_RESULTS", cx };
|
||||
}
|
||||
|
||||
export function clearSearch(): Action {
|
||||
return { type: "CLEAR_SEARCH" };
|
||||
export function clearSearch(cx: Context): Action {
|
||||
return { type: "CLEAR_SEARCH", cx };
|
||||
}
|
||||
|
||||
export function updateSearchStatus(status: string): Action {
|
||||
return { type: "UPDATE_STATUS", status };
|
||||
export function updateSearchStatus(cx: Context, status: string): Action {
|
||||
return { type: "UPDATE_STATUS", cx, status };
|
||||
}
|
||||
|
||||
export function closeProjectSearch() {
|
||||
export function closeProjectSearch(cx: Context) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
dispatch(stopOngoingSearch());
|
||||
dispatch(stopOngoingSearch(cx));
|
||||
dispatch({ type: "CLOSE_PROJECT_SEARCH" });
|
||||
};
|
||||
}
|
||||
|
||||
export function stopOngoingSearch() {
|
||||
export function stopOngoingSearch(cx: Context) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const state = getState();
|
||||
const ongoingSearch = getTextSearchOperation(state);
|
||||
const status = getTextSearchStatus(state);
|
||||
if (ongoingSearch && status !== statusType.done) {
|
||||
ongoingSearch.cancel();
|
||||
dispatch(updateSearchStatus(statusType.cancelled));
|
||||
dispatch(updateSearchStatus(cx, statusType.cancelled));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function searchSources(query: string) {
|
||||
export function searchSources(cx: Context, query: string) {
|
||||
let cancelled = false;
|
||||
|
||||
const search = async ({ dispatch, getState }: ThunkArgs) => {
|
||||
dispatch(stopOngoingSearch());
|
||||
await dispatch(addOngoingSearch(search));
|
||||
await dispatch(clearSearchResults());
|
||||
await dispatch(addSearchQuery(query));
|
||||
dispatch(updateSearchStatus(statusType.fetching));
|
||||
dispatch(stopOngoingSearch(cx));
|
||||
await dispatch(addOngoingSearch(cx, search));
|
||||
await dispatch(clearSearchResults(cx));
|
||||
await dispatch(addSearchQuery(cx, query));
|
||||
dispatch(updateSearchStatus(cx, statusType.fetching));
|
||||
const validSources = getSourceList(getState()).filter(
|
||||
source => !hasPrettySource(getState(), source.id) && !isThirdParty(source)
|
||||
);
|
||||
@ -88,10 +94,10 @@ export function searchSources(query: string) {
|
||||
if (cancelled) {
|
||||
return;
|
||||
}
|
||||
await dispatch(loadSourceText({ source }));
|
||||
await dispatch(searchSource(source.id, query));
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
await dispatch(searchSource(cx, source.id, query));
|
||||
}
|
||||
dispatch(updateSearchStatus(statusType.done));
|
||||
dispatch(updateSearchStatus(cx, statusType.done));
|
||||
};
|
||||
|
||||
search.cancel = () => {
|
||||
@ -101,7 +107,7 @@ export function searchSources(query: string) {
|
||||
return search;
|
||||
}
|
||||
|
||||
export function searchSource(sourceId: string, query: string) {
|
||||
export function searchSource(cx: Context, sourceId: string, query: string) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const source = getSource(getState(), sourceId);
|
||||
if (!source) {
|
||||
@ -112,6 +118,6 @@ export function searchSource(sourceId: string, query: string) {
|
||||
if (!matches.length) {
|
||||
return;
|
||||
}
|
||||
dispatch(addSearchResult(source.id, source.url, matches));
|
||||
dispatch(addSearchResult(cx, source.id, source.url, matches));
|
||||
};
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
// @flow
|
||||
|
||||
import type { Action, FocusItem, ThunkArgs } from "./types";
|
||||
import type { Context } from "../types";
|
||||
|
||||
export function setExpandedState(thread: string, expanded: Set<string>) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
@ -17,10 +18,11 @@ export function setExpandedState(thread: string, expanded: Set<string>) {
|
||||
};
|
||||
}
|
||||
|
||||
export function focusItem(item: FocusItem) {
|
||||
export function focusItem(cx: Context, item: FocusItem) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
dispatch({
|
||||
type: "SET_FOCUSED_SOURCE_ITEM",
|
||||
cx,
|
||||
item
|
||||
});
|
||||
};
|
||||
|
@ -16,7 +16,7 @@ import { getSourceFromId } from "../../selectors";
|
||||
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
async function blackboxActors(state, client, sourceId, isBlackBoxed, range?) {
|
||||
@ -27,7 +27,7 @@ async function blackboxActors(state, client, sourceId, isBlackBoxed, range?) {
|
||||
return { isBlackBoxed: !isBlackBoxed };
|
||||
}
|
||||
|
||||
export function toggleBlackBox(source: Source) {
|
||||
export function toggleBlackBox(cx: Context, source: Source) {
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const { isBlackBoxed } = source;
|
||||
|
||||
@ -45,6 +45,7 @@ export function toggleBlackBox(source: Source) {
|
||||
|
||||
return dispatch({
|
||||
type: "BLACKBOX",
|
||||
cx,
|
||||
source,
|
||||
[PROMISE]: blackboxActors(
|
||||
getState(),
|
||||
|
@ -27,7 +27,7 @@ import { Telemetry } from "devtools-modules";
|
||||
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
// Measures the time it takes for a source to load
|
||||
const loadSourceHistogram = "DEVTOOLS_DEBUGGER_LOAD_SOURCE_MS";
|
||||
@ -73,6 +73,7 @@ async function loadSource(
|
||||
}
|
||||
|
||||
async function loadSourceTextPromise(
|
||||
cx: Context,
|
||||
source: Source,
|
||||
{ dispatch, getState, client, sourceMaps }: ThunkArgs
|
||||
): Promise<?Source> {
|
||||
@ -92,27 +93,27 @@ async function loadSourceTextPromise(
|
||||
|
||||
if (!newSource.isWasm && isLoaded(newSource)) {
|
||||
parser.setSource(newSource);
|
||||
dispatch(setBreakpointPositions({ sourceId: newSource.id }));
|
||||
dispatch(setBreakpointPositions({ cx, sourceId: newSource.id }));
|
||||
|
||||
// Update the text in any breakpoints for this source by re-adding them.
|
||||
const breakpoints = getBreakpointsForSource(getState(), source.id);
|
||||
for (const { location, options, disabled } of breakpoints) {
|
||||
await dispatch(addBreakpoint(location, options, disabled));
|
||||
await dispatch(addBreakpoint(cx, location, options, disabled));
|
||||
}
|
||||
}
|
||||
|
||||
return newSource;
|
||||
}
|
||||
|
||||
export function loadSourceById(sourceId: string) {
|
||||
export function loadSourceById(cx: Context, sourceId: string) {
|
||||
return ({ getState, dispatch }: ThunkArgs) => {
|
||||
const source = getSourceFromId(getState(), sourceId);
|
||||
return dispatch(loadSourceText({ source }));
|
||||
return dispatch(loadSourceText({ cx, source }));
|
||||
};
|
||||
}
|
||||
|
||||
export const loadSourceText: MemoizedAction<
|
||||
{ source: Source },
|
||||
{ cx: Context, source: Source },
|
||||
?Source
|
||||
> = memoizeableAction("loadSourceText", {
|
||||
exitEarly: ({ source }) => !source,
|
||||
@ -122,5 +123,6 @@ export const loadSourceText: MemoizedAction<
|
||||
const epoch = getSourcesEpoch(getState());
|
||||
return `${epoch}:${source.id}`;
|
||||
},
|
||||
action: ({ source }, thunkArgs) => loadSourceTextPromise(source, thunkArgs)
|
||||
action: ({ cx, source }, thunkArgs) =>
|
||||
loadSourceTextPromise(cx, source, thunkArgs)
|
||||
});
|
||||
|
@ -28,13 +28,14 @@ import {
|
||||
getSource,
|
||||
getPendingSelectedLocation,
|
||||
getPendingBreakpointsForSource,
|
||||
hasBreakpointPositions
|
||||
hasBreakpointPositions,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
|
||||
import { prefs } from "../../utils/prefs";
|
||||
import sourceQueue from "../../utils/source-queue";
|
||||
|
||||
import type { Source, SourceId } from "../../types";
|
||||
import type { Source, SourceId, Context } from "../../types";
|
||||
import type { Action, ThunkArgs } from "../types";
|
||||
|
||||
function createOriginalSource(
|
||||
@ -57,14 +58,14 @@ function createOriginalSource(
|
||||
};
|
||||
}
|
||||
|
||||
function loadSourceMaps(sources: Source[]) {
|
||||
function loadSourceMaps(cx: Context, sources: Source[]) {
|
||||
return async function({
|
||||
dispatch,
|
||||
sourceMaps
|
||||
}: ThunkArgs): Promise<Promise<Source>[]> {
|
||||
const sourceList = await Promise.all(
|
||||
sources.map(async ({ id }) => {
|
||||
const originalSources = await dispatch(loadSourceMap(id));
|
||||
const originalSources = await dispatch(loadSourceMap(cx, id));
|
||||
sourceQueue.queueSources(originalSources);
|
||||
return originalSources;
|
||||
})
|
||||
@ -76,7 +77,7 @@ function loadSourceMaps(sources: Source[]) {
|
||||
// loading source maps as sometimes generated and original
|
||||
// files share the same paths.
|
||||
for (const source of sources) {
|
||||
dispatch(checkPendingBreakpoints(source.id));
|
||||
dispatch(checkPendingBreakpoints(cx, source.id));
|
||||
}
|
||||
|
||||
return flatten(sourceList);
|
||||
@ -87,7 +88,7 @@ function loadSourceMaps(sources: Source[]) {
|
||||
* @memberof actions/sources
|
||||
* @static
|
||||
*/
|
||||
function loadSourceMap(sourceId: SourceId) {
|
||||
function loadSourceMap(cx: Context, sourceId: SourceId) {
|
||||
return async function({
|
||||
dispatch,
|
||||
getState,
|
||||
@ -131,6 +132,7 @@ function loadSourceMap(sourceId: SourceId) {
|
||||
dispatch(
|
||||
({
|
||||
type: "UPDATE_SOURCE",
|
||||
cx,
|
||||
// NOTE: Flow https://github.com/facebook/flow/issues/6342 issue
|
||||
source: (({ ...currentSource, sourceMapURL: "" }: any): Source)
|
||||
}: Action)
|
||||
@ -144,7 +146,7 @@ function loadSourceMap(sourceId: SourceId) {
|
||||
|
||||
// If a request has been made to show this source, go ahead and
|
||||
// select it.
|
||||
function checkSelectedSource(sourceId: string) {
|
||||
function checkSelectedSource(cx: Context, sourceId: string) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const source = getSource(getState(), sourceId);
|
||||
const pendingLocation = getPendingSelectedLocation(getState());
|
||||
@ -158,12 +160,12 @@ function checkSelectedSource(sourceId: string) {
|
||||
|
||||
if (rawPendingUrl === source.url) {
|
||||
if (isPrettyURL(pendingUrl)) {
|
||||
const prettySource = await dispatch(togglePrettyPrint(source.id));
|
||||
return dispatch(checkPendingBreakpoints(prettySource.id));
|
||||
const prettySource = await dispatch(togglePrettyPrint(cx, source.id));
|
||||
return dispatch(checkPendingBreakpoints(cx, prettySource.id));
|
||||
}
|
||||
|
||||
await dispatch(
|
||||
selectLocation({
|
||||
selectLocation(cx, {
|
||||
sourceId: source.id,
|
||||
line:
|
||||
typeof pendingLocation.line === "number" ? pendingLocation.line : 0,
|
||||
@ -174,7 +176,7 @@ function checkSelectedSource(sourceId: string) {
|
||||
};
|
||||
}
|
||||
|
||||
function checkPendingBreakpoints(sourceId: string) {
|
||||
function checkPendingBreakpoints(cx: Context, sourceId: string) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
// source may have been modified by selectLocation
|
||||
const source = getSource(getState(), sourceId);
|
||||
@ -192,17 +194,17 @@ function checkPendingBreakpoints(sourceId: string) {
|
||||
}
|
||||
|
||||
// load the source text if there is a pending breakpoint for it
|
||||
await dispatch(loadSourceText({ source }));
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
|
||||
await Promise.all(
|
||||
pendingBreakpoints.map(bp => {
|
||||
return dispatch(syncBreakpoint(sourceId, bp));
|
||||
return dispatch(syncBreakpoint(cx, sourceId, bp));
|
||||
})
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
function restoreBlackBoxedSources(sources: Source[]) {
|
||||
function restoreBlackBoxedSources(cx: Context, sources: Source[]) {
|
||||
return async ({ dispatch }: ThunkArgs) => {
|
||||
const tabs = getBlackBoxList();
|
||||
if (tabs.length == 0) {
|
||||
@ -210,7 +212,7 @@ function restoreBlackBoxedSources(sources: Source[]) {
|
||||
}
|
||||
for (const source of sources) {
|
||||
if (tabs.includes(source.url) && !source.isBlackBoxed) {
|
||||
dispatch(toggleBlackBox(source));
|
||||
dispatch(toggleBlackBox(cx, source));
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -229,6 +231,8 @@ export function newSource(source: Source) {
|
||||
|
||||
export function newSources(sources: Source[]) {
|
||||
return async ({ dispatch, getState }: ThunkArgs) => {
|
||||
const cx = getContext(getState());
|
||||
|
||||
const _newSources = sources.filter(
|
||||
source => !getSource(getState(), source.id) || isInlineScript(source)
|
||||
);
|
||||
@ -237,10 +241,10 @@ export function newSources(sources: Source[]) {
|
||||
hasBreakpointPositions(getState(), source.id)
|
||||
);
|
||||
|
||||
dispatch({ type: "ADD_SOURCES", sources });
|
||||
dispatch({ type: "ADD_SOURCES", cx, sources });
|
||||
|
||||
for (const source of _newSources) {
|
||||
dispatch(checkSelectedSource(source.id));
|
||||
dispatch(checkSelectedSource(cx, source.id));
|
||||
}
|
||||
|
||||
// Adding new sources may have cleared this file's breakpoint positions
|
||||
@ -248,11 +252,11 @@ export function newSources(sources: Source[]) {
|
||||
// re-request new breakpoint positions.
|
||||
for (const source of sourcesNeedingPositions) {
|
||||
if (!hasBreakpointPositions(getState(), source.id)) {
|
||||
dispatch(setBreakpointPositions({ sourceId: source.id }));
|
||||
dispatch(setBreakpointPositions({ cx, sourceId: source.id }));
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(restoreBlackBoxedSources(_newSources));
|
||||
dispatch(loadSourceMaps(_newSources));
|
||||
dispatch(restoreBlackBoxedSources(cx, _newSources));
|
||||
dispatch(loadSourceMaps(cx, _newSources));
|
||||
};
|
||||
}
|
||||
|
@ -18,14 +18,14 @@ import { selectSpecificLocation } from "../sources";
|
||||
import {
|
||||
getSource,
|
||||
getSourceFromId,
|
||||
getSourceThreads,
|
||||
getSourceByURL,
|
||||
getSelectedLocation
|
||||
getSelectedLocation,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
|
||||
import type { Action, ThunkArgs } from "../types";
|
||||
import { selectSource } from "./select";
|
||||
import type { JsSource, Source } from "../../types";
|
||||
import type { JsSource, Source, Context } from "../../types";
|
||||
|
||||
export async function prettyPrintSource(
|
||||
sourceMaps: any,
|
||||
@ -51,7 +51,7 @@ export async function prettyPrintSource(
|
||||
};
|
||||
}
|
||||
|
||||
export function createPrettySource(sourceId: string) {
|
||||
export function createPrettySource(cx: Context, sourceId: string) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
const source = getSourceFromId(getState(), sourceId);
|
||||
const url = getPrettySourceURL(source.url);
|
||||
@ -72,25 +72,25 @@ export function createPrettySource(sourceId: string) {
|
||||
actors: []
|
||||
};
|
||||
|
||||
dispatch(({ type: "ADD_SOURCE", source: prettySource }: Action));
|
||||
await dispatch(selectSource(prettySource.id));
|
||||
dispatch(({ type: "ADD_SOURCE", cx, source: prettySource }: Action));
|
||||
await dispatch(selectSource(cx, prettySource.id));
|
||||
|
||||
return prettySource;
|
||||
};
|
||||
}
|
||||
|
||||
function selectPrettyLocation(prettySource: Source) {
|
||||
function selectPrettyLocation(cx: Context, prettySource: Source) {
|
||||
return async ({ dispatch, sourceMaps, getState }: ThunkArgs) => {
|
||||
let location = getSelectedLocation(getState());
|
||||
|
||||
if (location) {
|
||||
location = await sourceMaps.getOriginalLocation(location);
|
||||
return dispatch(
|
||||
selectSpecificLocation({ ...location, sourceId: prettySource.id })
|
||||
selectSpecificLocation(cx, { ...location, sourceId: prettySource.id })
|
||||
);
|
||||
}
|
||||
|
||||
return dispatch(selectSource(prettySource.id));
|
||||
return dispatch(selectSource(cx, prettySource.id));
|
||||
};
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ function selectPrettyLocation(prettySource: Source) {
|
||||
* A promise that resolves to [aSource, prettyText] or rejects to
|
||||
* [aSource, error].
|
||||
*/
|
||||
export function togglePrettyPrint(sourceId: string) {
|
||||
export function togglePrettyPrint(cx: Context, sourceId: string) {
|
||||
return async ({ dispatch, getState, client, sourceMaps }: ThunkArgs) => {
|
||||
const source = getSource(getState(), sourceId);
|
||||
if (!source) {
|
||||
@ -118,7 +118,7 @@ export function togglePrettyPrint(sourceId: string) {
|
||||
}
|
||||
|
||||
if (!isLoaded(source)) {
|
||||
await dispatch(loadSourceText({ source }));
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
}
|
||||
|
||||
assert(
|
||||
@ -130,18 +130,18 @@ export function togglePrettyPrint(sourceId: string) {
|
||||
const prettySource = getSourceByURL(getState(), url);
|
||||
|
||||
if (prettySource) {
|
||||
return dispatch(selectPrettyLocation(prettySource));
|
||||
return dispatch(selectPrettyLocation(cx, prettySource));
|
||||
}
|
||||
|
||||
const newPrettySource = await dispatch(createPrettySource(sourceId));
|
||||
await dispatch(selectPrettyLocation(newPrettySource));
|
||||
const newPrettySource = await dispatch(createPrettySource(cx, sourceId));
|
||||
await dispatch(selectPrettyLocation(cx, newPrettySource));
|
||||
|
||||
const threads = getSourceThreads(getState(), source);
|
||||
await Promise.all(threads.map(thread => dispatch(mapFrames(thread))));
|
||||
const threadcx = getThreadContext(getState());
|
||||
await dispatch(mapFrames(threadcx));
|
||||
|
||||
await dispatch(setSymbols({ source: newPrettySource }));
|
||||
await dispatch(setSymbols({ cx, source: newPrettySource }));
|
||||
|
||||
await dispatch(remapBreakpoints(sourceId));
|
||||
await dispatch(remapBreakpoints(cx, sourceId));
|
||||
|
||||
return newPrettySource;
|
||||
};
|
||||
|
@ -35,26 +35,39 @@ import {
|
||||
getSelectedSource
|
||||
} from "../../selectors";
|
||||
|
||||
import type { SourceLocation, PartialPosition, Source } from "../../types";
|
||||
import type {
|
||||
SourceLocation,
|
||||
PartialPosition,
|
||||
Source,
|
||||
Context
|
||||
} from "../../types";
|
||||
import type { ThunkArgs } from "../types";
|
||||
|
||||
export const setSelectedLocation = (
|
||||
cx: Context,
|
||||
source: Source,
|
||||
location: SourceLocation
|
||||
) => ({
|
||||
type: "SET_SELECTED_LOCATION",
|
||||
cx,
|
||||
source,
|
||||
location
|
||||
});
|
||||
|
||||
export const setPendingSelectedLocation = (url: string, options: Object) => ({
|
||||
export const setPendingSelectedLocation = (
|
||||
cx: Context,
|
||||
url: string,
|
||||
options: Object
|
||||
) => ({
|
||||
type: "SET_PENDING_SELECTED_LOCATION",
|
||||
cx,
|
||||
url: url,
|
||||
line: options.location ? options.location.line : null
|
||||
});
|
||||
|
||||
export const clearSelectedLocation = () => ({
|
||||
type: "CLEAR_SELECTED_LOCATION"
|
||||
export const clearSelectedLocation = (cx: Context) => ({
|
||||
type: "CLEAR_SELECTED_LOCATION",
|
||||
cx
|
||||
});
|
||||
|
||||
/**
|
||||
@ -69,18 +82,19 @@ export const clearSelectedLocation = () => ({
|
||||
* @static
|
||||
*/
|
||||
export function selectSourceURL(
|
||||
cx: Context,
|
||||
url: string,
|
||||
options: PartialPosition = { line: 1 }
|
||||
) {
|
||||
return async ({ dispatch, getState, sourceMaps }: ThunkArgs) => {
|
||||
const source = getSourceByURL(getState(), url);
|
||||
if (!source) {
|
||||
return dispatch(setPendingSelectedLocation(url, options));
|
||||
return dispatch(setPendingSelectedLocation(cx, url, options));
|
||||
}
|
||||
|
||||
const sourceId = source.id;
|
||||
const location = createLocation({ ...options, sourceId });
|
||||
return dispatch(selectLocation(location));
|
||||
return dispatch(selectLocation(cx, location));
|
||||
};
|
||||
}
|
||||
|
||||
@ -89,12 +103,13 @@ export function selectSourceURL(
|
||||
* @static
|
||||
*/
|
||||
export function selectSource(
|
||||
cx: Context,
|
||||
sourceId: string,
|
||||
options: PartialPosition = { line: 1 }
|
||||
) {
|
||||
return async ({ dispatch }: ThunkArgs) => {
|
||||
const location = createLocation({ ...options, sourceId });
|
||||
return dispatch(selectSpecificLocation(location));
|
||||
return dispatch(selectSpecificLocation(cx, location));
|
||||
};
|
||||
}
|
||||
|
||||
@ -103,6 +118,7 @@ export function selectSource(
|
||||
* @static
|
||||
*/
|
||||
export function selectLocation(
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
{ keepContext = true }: Object = {}
|
||||
) {
|
||||
@ -118,7 +134,7 @@ export function selectLocation(
|
||||
let source = getSource(getState(), location.sourceId);
|
||||
if (!source) {
|
||||
// If there is no source we deselect the current selected source
|
||||
return dispatch(clearSelectedLocation());
|
||||
return dispatch(clearSelectedLocation(cx));
|
||||
}
|
||||
|
||||
const activeSearch = getActiveSearch(getState());
|
||||
@ -143,9 +159,9 @@ export function selectLocation(
|
||||
dispatch(addTab(source));
|
||||
}
|
||||
|
||||
dispatch(setSelectedLocation(source, location));
|
||||
dispatch(setSelectedLocation(cx, source, location));
|
||||
|
||||
await dispatch(loadSourceText({ source }));
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
const loadedSource = getSource(getState(), source.id);
|
||||
|
||||
if (!loadedSource) {
|
||||
@ -160,17 +176,17 @@ export function selectLocation(
|
||||
shouldPrettyPrint(loadedSource) &&
|
||||
isMinified(loadedSource)
|
||||
) {
|
||||
await dispatch(togglePrettyPrint(loadedSource.id));
|
||||
dispatch(closeTab(loadedSource));
|
||||
await dispatch(togglePrettyPrint(cx, loadedSource.id));
|
||||
dispatch(closeTab(cx, loadedSource));
|
||||
}
|
||||
|
||||
dispatch(setSymbols({ source: loadedSource }));
|
||||
dispatch(setOutOfScopeLocations());
|
||||
dispatch(setSymbols({ cx, source: loadedSource }));
|
||||
dispatch(setOutOfScopeLocations(cx));
|
||||
|
||||
// If a new source is selected update the file search results
|
||||
const newSource = getSelectedSource(getState());
|
||||
if (currentSource && currentSource !== newSource) {
|
||||
dispatch(updateActiveFileSearch());
|
||||
dispatch(updateActiveFileSearch(cx));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -179,15 +195,15 @@ export function selectLocation(
|
||||
* @memberof actions/sources
|
||||
* @static
|
||||
*/
|
||||
export function selectSpecificLocation(location: SourceLocation) {
|
||||
return selectLocation(location, { keepContext: false });
|
||||
export function selectSpecificLocation(cx: Context, location: SourceLocation) {
|
||||
return selectLocation(cx, location, { keepContext: false });
|
||||
}
|
||||
|
||||
/**
|
||||
* @memberof actions/sources
|
||||
* @static
|
||||
*/
|
||||
export function jumpToMappedLocation(location: SourceLocation) {
|
||||
export function jumpToMappedLocation(cx: Context, location: SourceLocation) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
if (!client) {
|
||||
return;
|
||||
@ -195,17 +211,17 @@ export function jumpToMappedLocation(location: SourceLocation) {
|
||||
|
||||
const pairedLocation = await mapLocation(getState(), sourceMaps, location);
|
||||
|
||||
return dispatch(selectSpecificLocation({ ...pairedLocation }));
|
||||
return dispatch(selectSpecificLocation(cx, { ...pairedLocation }));
|
||||
};
|
||||
}
|
||||
|
||||
export function jumpToMappedSelectedLocation() {
|
||||
export function jumpToMappedSelectedLocation(cx: Context) {
|
||||
return async function({ dispatch, getState }: ThunkArgs) {
|
||||
const location = getSelectedLocation(getState());
|
||||
if (!location) {
|
||||
return;
|
||||
}
|
||||
|
||||
await dispatch(jumpToMappedLocation(location));
|
||||
await dispatch(jumpToMappedLocation(cx, location));
|
||||
};
|
||||
}
|
||||
|
@ -18,18 +18,19 @@ import {
|
||||
type MemoizedAction
|
||||
} from "../../utils/memoizableAction";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
import type { Symbols } from "../../reducers/types";
|
||||
|
||||
async function doSetSymbols(source, { dispatch, getState }) {
|
||||
async function doSetSymbols(cx, source, { dispatch, getState }) {
|
||||
const sourceId = source.id;
|
||||
|
||||
if (!isLoaded(source)) {
|
||||
await dispatch(loadSourceText({ source }));
|
||||
await dispatch(loadSourceText({ cx, source }));
|
||||
}
|
||||
|
||||
await dispatch({
|
||||
type: "SET_SYMBOLS",
|
||||
cx,
|
||||
sourceId,
|
||||
[PROMISE]: parser.getSymbols(sourceId)
|
||||
});
|
||||
@ -42,7 +43,7 @@ async function doSetSymbols(source, { dispatch, getState }) {
|
||||
return symbols;
|
||||
}
|
||||
|
||||
type Args = { source: Source };
|
||||
type Args = { cx: Context, source: Source };
|
||||
|
||||
export const setSymbols: MemoizedAction<Args, ?Symbols> = memoizeableAction(
|
||||
"setSymbols",
|
||||
@ -51,6 +52,6 @@ export const setSymbols: MemoizedAction<Args, ?Symbols> = memoizeableAction(
|
||||
hasValue: ({ source }, { getState }) => hasSymbols(getState(), source),
|
||||
getValue: ({ source }, { getState }) => getSymbols(getState(), source),
|
||||
createKey: ({ source }) => source.id,
|
||||
action: ({ source }, thunkArgs) => doSetSymbols(source, thunkArgs)
|
||||
action: ({ cx, source }, thunkArgs) => doSetSymbols(cx, source, thunkArgs)
|
||||
}
|
||||
);
|
||||
|
@ -14,11 +14,11 @@ import {
|
||||
describe("blackbox", () => {
|
||||
it("should blackbox a source", async () => {
|
||||
const store = createStore({ blackBox: async () => true });
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
|
||||
const foo1Source = makeSource("foo1");
|
||||
await dispatch(actions.newSource(foo1Source));
|
||||
await dispatch(actions.toggleBlackBox(foo1Source));
|
||||
await dispatch(actions.toggleBlackBox(cx, foo1Source));
|
||||
|
||||
const fooSource = selectors.getSource(getState(), "foo1");
|
||||
|
||||
|
@ -21,11 +21,11 @@ import { getBreakpointsList } from "../../../selectors";
|
||||
describe("loadSourceText", () => {
|
||||
it("should load source text", async () => {
|
||||
const store = createStore(sourceThreadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
|
||||
const foo1Source = makeSource("foo1");
|
||||
await dispatch(actions.newSource(foo1Source));
|
||||
await dispatch(actions.loadSourceText({ source: foo1Source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: foo1Source }));
|
||||
const fooSource = selectors.getSource(getState(), "foo1");
|
||||
|
||||
if (!fooSource || typeof fooSource.text != "string") {
|
||||
@ -35,7 +35,7 @@ describe("loadSourceText", () => {
|
||||
|
||||
const baseFoo2Source = makeSource("foo2");
|
||||
await dispatch(actions.newSource(baseFoo2Source));
|
||||
await dispatch(actions.loadSourceText({ source: baseFoo2Source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: baseFoo2Source }));
|
||||
const foo2Source = selectors.getSource(getState(), "foo2");
|
||||
|
||||
if (!foo2Source || typeof foo2Source.text != "string") {
|
||||
@ -73,7 +73,7 @@ describe("loadSourceText", () => {
|
||||
})
|
||||
}
|
||||
);
|
||||
const { dispatch, getState } = store;
|
||||
const { cx, dispatch, getState } = store;
|
||||
|
||||
await dispatch(actions.newSource(fooOrigSource));
|
||||
await dispatch(actions.newSource(fooGenSource));
|
||||
@ -83,20 +83,20 @@ describe("loadSourceText", () => {
|
||||
line: 1,
|
||||
column: 0
|
||||
};
|
||||
await dispatch(actions.addBreakpoint(location, {}));
|
||||
await dispatch(actions.addBreakpoint(cx, location, {}));
|
||||
|
||||
const breakpoint = getBreakpointsList(getState())[0];
|
||||
|
||||
expect(breakpoint.text).toBe("");
|
||||
expect(breakpoint.originalText).toBe("");
|
||||
|
||||
await dispatch(actions.loadSourceText({ source: fooOrigSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: fooOrigSource }));
|
||||
|
||||
const breakpoint1 = getBreakpointsList(getState())[0];
|
||||
expect(breakpoint1.text).toBe("");
|
||||
expect(breakpoint1.originalText).toBe("var fooOrig = 42;");
|
||||
|
||||
await dispatch(actions.loadSourceText({ source: fooGenSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: fooGenSource }));
|
||||
|
||||
const breakpoint2 = getBreakpointsList(getState())[0];
|
||||
expect(breakpoint2.text).toBe("var fooGen = 42;");
|
||||
@ -106,7 +106,7 @@ describe("loadSourceText", () => {
|
||||
it("loads two sources w/ one request", async () => {
|
||||
let resolve;
|
||||
let count = 0;
|
||||
const { dispatch, getState } = createStore({
|
||||
const { dispatch, getState, cx } = createStore({
|
||||
sourceContents: () =>
|
||||
new Promise(r => {
|
||||
count++;
|
||||
@ -120,10 +120,10 @@ describe("loadSourceText", () => {
|
||||
await dispatch(actions.newSource(baseSource));
|
||||
|
||||
let source = selectors.getSourceFromId(getState(), id);
|
||||
dispatch(actions.loadSourceText({ source }));
|
||||
dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
source = selectors.getSourceFromId(getState(), id);
|
||||
const loading = dispatch(actions.loadSourceText({ source }));
|
||||
const loading = dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
if (!resolve) {
|
||||
throw new Error("no resolve");
|
||||
@ -139,7 +139,7 @@ describe("loadSourceText", () => {
|
||||
it("doesn't re-load loaded sources", async () => {
|
||||
let resolve;
|
||||
let count = 0;
|
||||
const { dispatch, getState } = createStore({
|
||||
const { dispatch, getState, cx } = createStore({
|
||||
sourceContents: () =>
|
||||
new Promise(r => {
|
||||
count++;
|
||||
@ -152,7 +152,7 @@ describe("loadSourceText", () => {
|
||||
|
||||
await dispatch(actions.newSource(baseSource));
|
||||
let source = selectors.getSourceFromId(getState(), id);
|
||||
const loading = dispatch(actions.loadSourceText({ source }));
|
||||
const loading = dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
if (!resolve) {
|
||||
throw new Error("no resolve");
|
||||
@ -161,7 +161,7 @@ describe("loadSourceText", () => {
|
||||
await loading;
|
||||
|
||||
source = selectors.getSourceFromId(getState(), id);
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
expect(count).toEqual(1);
|
||||
|
||||
source = selectors.getSource(getState(), id);
|
||||
@ -169,14 +169,14 @@ describe("loadSourceText", () => {
|
||||
});
|
||||
|
||||
it("should cache subsequent source text loads", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
|
||||
const source = makeSource("foo1");
|
||||
dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
const prevSource = selectors.getSourceFromId(getState(), "foo1");
|
||||
|
||||
await dispatch(actions.loadSourceText({ source: prevSource }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: prevSource }));
|
||||
const curSource = selectors.getSource(getState(), "foo1");
|
||||
|
||||
expect(prevSource === curSource).toBeTruthy();
|
||||
@ -184,7 +184,7 @@ describe("loadSourceText", () => {
|
||||
|
||||
it("should indicate a loading source", async () => {
|
||||
const store = createStore(sourceThreadClient);
|
||||
const { dispatch } = store;
|
||||
const { dispatch, cx } = store;
|
||||
|
||||
const source = makeSource("foo2");
|
||||
await dispatch(actions.newSource(source));
|
||||
@ -194,17 +194,17 @@ describe("loadSourceText", () => {
|
||||
return fooSource && fooSource.loadedState === "loading";
|
||||
});
|
||||
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
expect(wasLoading()).toBe(true);
|
||||
});
|
||||
|
||||
it("should indicate an errored source text", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
|
||||
const source = makeSource("bad-id");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
const badSource = selectors.getSource(getState(), "bad-id");
|
||||
|
||||
if (!badSource || !badSource.error) {
|
||||
|
@ -45,9 +45,9 @@ describe("sources - new sources", () => {
|
||||
});
|
||||
|
||||
it("should automatically select a pending source", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
const baseSource = makeSource("base.js");
|
||||
await dispatch(actions.selectSourceURL(baseSource.url));
|
||||
await dispatch(actions.selectSourceURL(cx, baseSource.url));
|
||||
|
||||
expect(getSelectedSource(getState())).toBe(undefined);
|
||||
await dispatch(actions.newSource(baseSource));
|
||||
|
@ -14,13 +14,13 @@ import { createPrettySource } from "../prettyPrint";
|
||||
import { sourceThreadClient } from "../../tests/helpers/threadClient.js";
|
||||
|
||||
describe("sources - pretty print", () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
|
||||
it("returns a pretty source for a minified file", async () => {
|
||||
const url = "base.js";
|
||||
const source = makeSource(url);
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(createPrettySource(source.id));
|
||||
await dispatch(createPrettySource(cx, source.id));
|
||||
|
||||
const prettyURL = `${source.url}:formatted`;
|
||||
const pretty = selectors.getSourceByURL(getState(), prettyURL);
|
||||
@ -31,15 +31,15 @@ describe("sources - pretty print", () => {
|
||||
|
||||
it("should create a source when first toggling pretty print", async () => {
|
||||
const source = makeSource("foobar.js", { loadedState: "loaded" });
|
||||
await dispatch(actions.togglePrettyPrint(source.id));
|
||||
await dispatch(actions.togglePrettyPrint(cx, source.id));
|
||||
expect(selectors.getSourceCount(getState())).toEqual(2);
|
||||
});
|
||||
|
||||
it("should not make a second source when toggling pretty print", async () => {
|
||||
const source = makeSource("foobar.js", { loadedState: "loaded" });
|
||||
await dispatch(actions.togglePrettyPrint(source.id));
|
||||
await dispatch(actions.togglePrettyPrint(cx, source.id));
|
||||
expect(selectors.getSourceCount(getState())).toEqual(2);
|
||||
await dispatch(actions.togglePrettyPrint(source.id));
|
||||
await dispatch(actions.togglePrettyPrint(cx, source.id));
|
||||
expect(selectors.getSourceCount(getState())).toEqual(2);
|
||||
});
|
||||
});
|
||||
|
@ -50,8 +50,9 @@ describe("sources", () => {
|
||||
})
|
||||
);
|
||||
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
await dispatch(
|
||||
actions.selectLocation({ sourceId: "foo1", line: 1, column: 5 })
|
||||
actions.selectLocation(cx, { sourceId: "foo1", line: 1, column: 5 })
|
||||
);
|
||||
|
||||
const selectedSource = getSelectedSource(getState());
|
||||
@ -72,7 +73,7 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
it("should select next tab on tab closed if no previous tab", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
|
||||
const fooSource = makeSource("foo.js");
|
||||
|
||||
@ -81,19 +82,19 @@ describe("sources", () => {
|
||||
await dispatch(actions.newSource(makeSource("baz.js")));
|
||||
|
||||
// 3rd tab
|
||||
await dispatch(actions.selectLocation(initialLocation("foo.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
|
||||
// 2nd tab
|
||||
await dispatch(actions.selectLocation(initialLocation("bar.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("bar.js")));
|
||||
|
||||
// 1st tab
|
||||
await dispatch(actions.selectLocation(initialLocation("baz.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("baz.js")));
|
||||
|
||||
// 3rd tab is reselected
|
||||
await dispatch(actions.selectLocation(initialLocation("foo.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
|
||||
// closes the 1st tab, which should have no previous tab
|
||||
await dispatch(actions.closeTab(fooSource));
|
||||
await dispatch(actions.closeTab(cx, fooSource));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("bar.js");
|
||||
@ -101,9 +102,9 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
it("should open a tab for the source", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
dispatch(actions.selectLocation(initialLocation("foo.js")));
|
||||
dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
|
||||
const tabs = getSourceTabs(getState());
|
||||
expect(tabs).toHaveLength(1);
|
||||
@ -111,17 +112,17 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
it("should select previous tab on tab closed", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
|
||||
const bazSource = makeSource("baz.js");
|
||||
await dispatch(actions.newSource(bazSource));
|
||||
|
||||
await dispatch(actions.selectLocation(initialLocation("foo.js")));
|
||||
await dispatch(actions.selectLocation(initialLocation("bar.js")));
|
||||
await dispatch(actions.selectLocation(initialLocation("baz.js")));
|
||||
await dispatch(actions.closeTab(bazSource));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("bar.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("baz.js")));
|
||||
await dispatch(actions.closeTab(cx, bazSource));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("bar.js");
|
||||
@ -129,7 +130,7 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
it("should keep the selected source when other tab closed", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
|
||||
const bazSource = makeSource("baz.js");
|
||||
|
||||
@ -138,17 +139,17 @@ describe("sources", () => {
|
||||
await dispatch(actions.newSource(bazSource));
|
||||
|
||||
// 3rd tab
|
||||
await dispatch(actions.selectLocation(initialLocation("foo.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
|
||||
// 2nd tab
|
||||
await dispatch(actions.selectLocation(initialLocation("bar.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("bar.js")));
|
||||
|
||||
// 1st tab
|
||||
await dispatch(actions.selectLocation(initialLocation("baz.js")));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("baz.js")));
|
||||
|
||||
// 3rd tab is reselected
|
||||
await dispatch(actions.selectLocation(initialLocation("foo.js")));
|
||||
await dispatch(actions.closeTab(bazSource));
|
||||
await dispatch(actions.selectLocation(cx, initialLocation("foo.js")));
|
||||
await dispatch(actions.closeTab(cx, bazSource));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("foo.js");
|
||||
@ -168,29 +169,29 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
it("sets and clears selected location correctly", () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
const source = makeSource("testSource");
|
||||
const location = ({ test: "testLocation" }: any);
|
||||
|
||||
// set value
|
||||
dispatch(actions.setSelectedLocation(source, location));
|
||||
dispatch(actions.setSelectedLocation(cx, source, location));
|
||||
expect(getSelectedLocation(getState())).toEqual({
|
||||
sourceId: source.id,
|
||||
...location
|
||||
});
|
||||
|
||||
// clear value
|
||||
dispatch(actions.clearSelectedLocation());
|
||||
dispatch(actions.clearSelectedLocation(cx));
|
||||
expect(getSelectedLocation(getState())).toEqual(null);
|
||||
});
|
||||
|
||||
it("sets and clears pending selected location correctly", () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
const url = "testURL";
|
||||
const options = { location: { line: "testLine" } };
|
||||
|
||||
// set value
|
||||
dispatch(actions.setPendingSelectedLocation(url, options));
|
||||
dispatch(actions.setPendingSelectedLocation(cx, url, options));
|
||||
const setResult = getState().sources.pendingSelectedLocation;
|
||||
expect(setResult).toEqual({
|
||||
url,
|
||||
@ -198,19 +199,19 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
// clear value
|
||||
dispatch(actions.clearSelectedLocation());
|
||||
dispatch(actions.clearSelectedLocation(cx));
|
||||
const clearResult = getState().sources.pendingSelectedLocation;
|
||||
expect(clearResult).toEqual({ url: "" });
|
||||
});
|
||||
|
||||
it("should keep the generated the viewing context", async () => {
|
||||
const store = createStore(sourceThreadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
const baseSource = makeSource("base.js");
|
||||
await dispatch(actions.newSource(baseSource));
|
||||
|
||||
await dispatch(
|
||||
actions.selectLocation({ sourceId: baseSource.id, line: 1 })
|
||||
actions.selectLocation(cx, { sourceId: baseSource.id, line: 1 })
|
||||
);
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
@ -219,7 +220,7 @@ describe("sources", () => {
|
||||
});
|
||||
|
||||
it("should keep the original the viewing context", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
sourceThreadClient,
|
||||
{},
|
||||
{
|
||||
@ -237,18 +238,20 @@ describe("sources", () => {
|
||||
const originalBaseSource = makeOriginalSource("base.js");
|
||||
await dispatch(actions.newSource(originalBaseSource));
|
||||
|
||||
await dispatch(actions.selectSource(originalBaseSource.id));
|
||||
await dispatch(actions.selectSource(cx, originalBaseSource.id));
|
||||
|
||||
const fooSource = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(fooSource));
|
||||
await dispatch(actions.selectLocation({ sourceId: fooSource.id, line: 1 }));
|
||||
await dispatch(
|
||||
actions.selectLocation(cx, { sourceId: fooSource.id, line: 1 })
|
||||
);
|
||||
|
||||
const selected = getSelectedLocation(getState());
|
||||
expect(selected && selected.line).toBe(12);
|
||||
});
|
||||
|
||||
it("should change the original the viewing context", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
sourceThreadClient,
|
||||
{},
|
||||
{
|
||||
@ -263,10 +266,10 @@ describe("sources", () => {
|
||||
const baseSource = makeOriginalSource("base.js");
|
||||
|
||||
await dispatch(actions.newSource(baseSource));
|
||||
await dispatch(actions.selectSource(baseSource.id));
|
||||
await dispatch(actions.selectSource(cx, baseSource.id));
|
||||
|
||||
await dispatch(
|
||||
actions.selectSpecificLocation({
|
||||
actions.selectSpecificLocation(cx, {
|
||||
sourceId: baseSource.id,
|
||||
line: 1
|
||||
})
|
||||
@ -278,9 +281,9 @@ describe("sources", () => {
|
||||
|
||||
describe("selectSourceURL", () => {
|
||||
it("should automatically select a pending source", async () => {
|
||||
const { dispatch, getState } = createStore(sourceThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(sourceThreadClient);
|
||||
const baseSource = makeSource("base.js");
|
||||
await dispatch(actions.selectSourceURL(baseSource.url));
|
||||
await dispatch(actions.selectSourceURL(cx, baseSource.url));
|
||||
|
||||
expect(getSelectedSource(getState())).toBe(undefined);
|
||||
await dispatch(actions.newSource(baseSource));
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
} from "../selectors";
|
||||
|
||||
import type { Action, ThunkArgs } from "./types";
|
||||
import type { Source } from "../types";
|
||||
import type { Source, Context } from "../types";
|
||||
|
||||
export function updateTab(source: Source, framework: string): Action {
|
||||
const { url, id: sourceId } = source;
|
||||
@ -62,7 +62,7 @@ export function moveTab(url: string, tabIndex: number): Action {
|
||||
* @memberof actions/tabs
|
||||
* @static
|
||||
*/
|
||||
export function closeTab(source: Source) {
|
||||
export function closeTab(cx: Context, source: Source) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const { id, url } = source;
|
||||
|
||||
@ -71,7 +71,7 @@ export function closeTab(source: Source) {
|
||||
const tabs = removeSourceFromTabList(getSourceTabs(getState()), source);
|
||||
const sourceId = getNewSelectedSourceId(getState(), tabs);
|
||||
dispatch(({ type: "CLOSE_TAB", url, tabs }: Action));
|
||||
dispatch(selectSource(sourceId));
|
||||
dispatch(selectSource(cx, sourceId));
|
||||
};
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ export function closeTab(source: Source) {
|
||||
* @memberof actions/tabs
|
||||
* @static
|
||||
*/
|
||||
export function closeTabs(urls: string[]) {
|
||||
export function closeTabs(cx: Context, urls: string[]) {
|
||||
return ({ dispatch, getState, client }: ThunkArgs) => {
|
||||
const sources = urls
|
||||
.map(url => getSourceByURL(getState(), url))
|
||||
@ -90,6 +90,6 @@ export function closeTabs(urls: string[]) {
|
||||
dispatch(({ type: "CLOSE_TABS", sources, tabs }: Action));
|
||||
|
||||
const sourceId = getNewSelectedSourceId(getState(), tabs);
|
||||
dispatch(selectSource(sourceId));
|
||||
dispatch(selectSource(cx, sourceId));
|
||||
};
|
||||
}
|
||||
|
@ -66,13 +66,13 @@ describe("ast", () => {
|
||||
describe("when the source is loaded", () => {
|
||||
it("should be able to set symbols", async () => {
|
||||
const store = createStore(threadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
const base = makeSource("base.js");
|
||||
await dispatch(actions.newSource(base));
|
||||
await dispatch(actions.loadSourceText({ source: base }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: base }));
|
||||
|
||||
const loadedSource = selectors.getSourceFromId(getState(), base.id);
|
||||
await dispatch(actions.setSymbols({ source: loadedSource }));
|
||||
await dispatch(actions.setSymbols({ cx, source: loadedSource }));
|
||||
await waitForState(store, state => !isSymbolsLoading(state, base));
|
||||
|
||||
const baseSymbols = getSymbols(getState(), base);
|
||||
@ -102,27 +102,27 @@ describe("ast", () => {
|
||||
describe("frameworks", () => {
|
||||
it("should detect react components", async () => {
|
||||
const store = createStore(threadClient, {}, sourceMaps);
|
||||
const { dispatch, getState } = store;
|
||||
const { cx, dispatch, getState } = store;
|
||||
const source = makeOriginalSource("reactComponent.js");
|
||||
|
||||
await dispatch(actions.newSource(makeSource("reactComponent.js")));
|
||||
|
||||
await dispatch(actions.newSource(source));
|
||||
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
const loadedSource = selectors.getSourceFromId(getState(), source.id);
|
||||
await dispatch(actions.setSymbols({ source: loadedSource }));
|
||||
await dispatch(actions.setSymbols({ cx, source: loadedSource }));
|
||||
|
||||
expect(getFramework(getState(), source)).toBe("React");
|
||||
});
|
||||
|
||||
it("should not give false positive on non react components", async () => {
|
||||
const store = createStore(threadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const { cx, dispatch, getState } = store;
|
||||
const base = makeSource("base.js");
|
||||
await dispatch(actions.newSource(base));
|
||||
await dispatch(actions.loadSourceText({ source: base }));
|
||||
await dispatch(actions.setSymbols({ source: base }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: base }));
|
||||
await dispatch(actions.setSymbols({ cx, source: base }));
|
||||
|
||||
expect(getFramework(getState(), base)).toBe(undefined);
|
||||
});
|
||||
@ -136,14 +136,20 @@ describe("ast", () => {
|
||||
|
||||
it("with selected line", async () => {
|
||||
const store = createStore(threadClient);
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
const source = makeSource("scopes.js");
|
||||
await dispatch(actions.newSource(source));
|
||||
|
||||
await dispatch(
|
||||
actions.selectLocation({ sourceId: "scopes.js", line: 5 })
|
||||
actions.selectLocation(cx, { sourceId: "scopes.js", line: 5 })
|
||||
);
|
||||
|
||||
// Make sure the state has finished updating before pausing.
|
||||
await waitForState(store, state => {
|
||||
const symbols = getSymbols(state, source);
|
||||
return symbols && !symbols.loading && getOutOfScopeLocations(state);
|
||||
});
|
||||
|
||||
const frame = makeFrame({ id: "1", sourceId: "scopes.js" });
|
||||
await dispatch(
|
||||
actions.paused({
|
||||
@ -154,7 +160,8 @@ describe("ast", () => {
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.setOutOfScopeLocations());
|
||||
const ncx = selectors.getThreadContext(getState());
|
||||
await dispatch(actions.setOutOfScopeLocations(ncx));
|
||||
|
||||
await waitForState(store, state => getOutOfScopeLocations(state));
|
||||
|
||||
@ -166,10 +173,10 @@ describe("ast", () => {
|
||||
});
|
||||
|
||||
it("without a selected line", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
const base = makeSource("base.js");
|
||||
await dispatch(actions.newSource(base));
|
||||
await dispatch(actions.selectSource("base.js"));
|
||||
await dispatch(actions.selectSource(cx, "base.js"));
|
||||
|
||||
const locations = getOutOfScopeLocations(getState());
|
||||
// const lines = getInScopeLines(getState());
|
||||
|
@ -51,52 +51,52 @@ const mockThreadClient = {
|
||||
|
||||
describe("expressions", () => {
|
||||
it("should add an expression", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
|
||||
await dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
expect(selectors.getExpressions(getState()).size).toBe(1);
|
||||
});
|
||||
|
||||
it("should not add empty expressions", () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
|
||||
dispatch(actions.addExpression((undefined: any)));
|
||||
dispatch(actions.addExpression(""));
|
||||
dispatch(actions.addExpression(cx, (undefined: any)));
|
||||
dispatch(actions.addExpression(cx, ""));
|
||||
expect(selectors.getExpressions(getState()).size).toBe(0);
|
||||
});
|
||||
|
||||
it("should not add invalid expressions", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
await dispatch(actions.addExpression("foo#"));
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
await dispatch(actions.addExpression(cx, "foo#"));
|
||||
const state = getState();
|
||||
expect(selectors.getExpressions(state).size).toBe(0);
|
||||
expect(selectors.getExpressionError(state)).toBe(true);
|
||||
});
|
||||
|
||||
it("should update an expression", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
|
||||
await dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
const expression = selectors.getExpression(getState(), "foo");
|
||||
await dispatch(actions.updateExpression("bar", expression));
|
||||
await dispatch(actions.updateExpression(cx, "bar", expression));
|
||||
|
||||
expect(selectors.getExpression(getState(), "bar").input).toBe("bar");
|
||||
});
|
||||
|
||||
it("should not update an expression w/ invalid code", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
|
||||
await dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
const expression = selectors.getExpression(getState(), "foo");
|
||||
await dispatch(actions.updateExpression("#bar", expression));
|
||||
await dispatch(actions.updateExpression(cx, "#bar", expression));
|
||||
expect(selectors.getExpression(getState(), "bar")).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should delete an expression", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
|
||||
await dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression("bar"));
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
await dispatch(actions.addExpression(cx, "bar"));
|
||||
expect(selectors.getExpressions(getState()).size).toBe(2);
|
||||
|
||||
const expression = selectors.getExpression(getState(), "foo");
|
||||
@ -106,54 +106,57 @@ describe("expressions", () => {
|
||||
});
|
||||
|
||||
it("should evaluate expressions global scope", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
|
||||
await dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression("bar"));
|
||||
const { dispatch, getState, cx } = createStore(mockThreadClient);
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
await dispatch(actions.addExpression(cx, "bar"));
|
||||
expect(selectors.getExpression(getState(), "foo").value).toBe("bla");
|
||||
expect(selectors.getExpression(getState(), "bar").value).toBe("bla");
|
||||
|
||||
await dispatch(actions.evaluateExpressions());
|
||||
await dispatch(actions.evaluateExpressions(cx));
|
||||
expect(selectors.getExpression(getState(), "foo").value).toBe("bla");
|
||||
expect(selectors.getExpression(getState(), "bar").value).toBe("bla");
|
||||
});
|
||||
|
||||
it("should evaluate expressions in specific scope", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
await createFrames(dispatch);
|
||||
await createFrames(getState, dispatch);
|
||||
|
||||
const cx = selectors.getThreadContext(getState());
|
||||
await dispatch(actions.newSource(makeSource("source")));
|
||||
await dispatch(actions.addExpression("foo"));
|
||||
await dispatch(actions.addExpression("bar"));
|
||||
await dispatch(actions.addExpression(cx, "foo"));
|
||||
await dispatch(actions.addExpression(cx, "bar"));
|
||||
|
||||
expect(selectors.getExpression(getState(), "foo").value).toBe("boo");
|
||||
expect(selectors.getExpression(getState(), "bar").value).toBe("boo");
|
||||
|
||||
await dispatch(actions.evaluateExpressions());
|
||||
await dispatch(actions.evaluateExpressions(cx));
|
||||
|
||||
expect(selectors.getExpression(getState(), "foo").value).toBe("boo");
|
||||
expect(selectors.getExpression(getState(), "bar").value).toBe("boo");
|
||||
});
|
||||
|
||||
it("should get the autocomplete matches for the input", async () => {
|
||||
const { dispatch, getState } = createStore(mockThreadClient);
|
||||
await dispatch(actions.autocomplete("to", 2));
|
||||
const { cx, dispatch, getState } = createStore(mockThreadClient);
|
||||
await dispatch(actions.autocomplete(cx, "to", 2));
|
||||
expect(selectors.getAutocompleteMatchset(getState())).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
async function createFrames(dispatch) {
|
||||
async function createFrames(getState, dispatch) {
|
||||
const frame = makeMockFrame();
|
||||
await dispatch(actions.newSource(makeSource("example.js")));
|
||||
await dispatch(actions.newSource(makeSource("source")));
|
||||
|
||||
await dispatch(
|
||||
actions.paused({
|
||||
thread: "UnknownThread",
|
||||
thread: "FakeThread",
|
||||
frame,
|
||||
frames: [frame],
|
||||
why: { type: "just because" }
|
||||
})
|
||||
);
|
||||
|
||||
await dispatch(actions.selectFrame(frame));
|
||||
await dispatch(
|
||||
actions.selectFrame(selectors.getThreadContext(getState()), frame)
|
||||
);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ const {
|
||||
|
||||
describe("file text search", () => {
|
||||
it("should update search results", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
expect(getFileSearchResults(getState())).toEqual({
|
||||
matches: [],
|
||||
matchIndex: -1,
|
||||
@ -23,7 +23,7 @@ describe("file text search", () => {
|
||||
});
|
||||
|
||||
const matches = [{ line: 1, ch: 3 }, { line: 3, ch: 2 }];
|
||||
dispatch(actions.updateSearchResults(2, 3, matches));
|
||||
dispatch(actions.updateSearchResults(cx, 2, 3, matches));
|
||||
|
||||
expect(getFileSearchResults(getState())).toEqual({
|
||||
count: 2,
|
||||
@ -34,29 +34,29 @@ describe("file text search", () => {
|
||||
});
|
||||
|
||||
it("should update the file search query", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
let fileSearchQueryState = getFileSearchQuery(getState());
|
||||
expect(fileSearchQueryState).toBe("");
|
||||
dispatch(actions.setFileSearchQuery("foobar"));
|
||||
dispatch(actions.setFileSearchQuery(cx, "foobar"));
|
||||
fileSearchQueryState = getFileSearchQuery(getState());
|
||||
expect(fileSearchQueryState).toBe("foobar");
|
||||
});
|
||||
|
||||
it("should toggle a file search modifier", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
let fileSearchModState = getFileSearchModifiers(getState());
|
||||
expect(fileSearchModState.get("caseSensitive")).toBe(false);
|
||||
dispatch(actions.toggleFileSearchModifier("caseSensitive"));
|
||||
dispatch(actions.toggleFileSearchModifier(cx, "caseSensitive"));
|
||||
fileSearchModState = getFileSearchModifiers(getState());
|
||||
expect(fileSearchModState.get("caseSensitive")).toBe(true);
|
||||
});
|
||||
|
||||
it("should toggle a file search query cleaning", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setFileSearchQuery("foobar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setFileSearchQuery(cx, "foobar"));
|
||||
let fileSearchQueryState = getFileSearchQuery(getState());
|
||||
expect(fileSearchQueryState).toBe("foobar");
|
||||
dispatch(actions.setFileSearchQuery(""));
|
||||
dispatch(actions.setFileSearchQuery(cx, ""));
|
||||
fileSearchQueryState = getFileSearchQuery(getState());
|
||||
expect(fileSearchQueryState).toBe("");
|
||||
});
|
||||
|
@ -48,11 +48,11 @@ describe("navigation", () => {
|
||||
});
|
||||
|
||||
it("navigation closes project-search", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
const mockQuery = "foo";
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.searchSources(mockQuery));
|
||||
await dispatch(actions.searchSources(cx, mockQuery));
|
||||
|
||||
let results = getTextSearchResults(getState());
|
||||
expect(results).toHaveLength(1);
|
||||
@ -77,9 +77,9 @@ describe("navigation", () => {
|
||||
});
|
||||
|
||||
it("navigation clears the file-search query", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
dispatch(actions.setFileSearchQuery("foobar"));
|
||||
dispatch(actions.setFileSearchQuery(cx, "foobar"));
|
||||
expect(getFileSearchQuery(getState())).toBe("foobar");
|
||||
|
||||
await dispatch(actions.willNavigate("will-navigate"));
|
||||
@ -88,10 +88,10 @@ describe("navigation", () => {
|
||||
});
|
||||
|
||||
it("navigation clears the file-search results", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const searchResults = [{ line: 1, ch: 3 }, { line: 3, ch: 2 }];
|
||||
dispatch(actions.updateSearchResults(2, 3, searchResults));
|
||||
dispatch(actions.updateSearchResults(cx, 2, 3, searchResults));
|
||||
expect(getFileSearchResults(getState())).toEqual({
|
||||
count: 2,
|
||||
index: 2,
|
||||
|
@ -69,7 +69,7 @@ function mockSourceMaps() {
|
||||
|
||||
describe("when adding breakpoints", () => {
|
||||
it("a corresponding pending breakpoint should be added", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [1] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -78,12 +78,12 @@ describe("when adding breakpoints", () => {
|
||||
const source = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
const bp = generateBreakpoint("foo.js", 5, 1);
|
||||
const id = makePendingLocationId(bp.location);
|
||||
|
||||
await dispatch(actions.addBreakpoint(bp.location));
|
||||
await dispatch(actions.addBreakpoint(cx, bp.location));
|
||||
const pendingBps = selectors.getPendingBreakpoints(getState());
|
||||
|
||||
expect(selectors.getPendingBreakpointList(getState())).toHaveLength(2);
|
||||
@ -104,7 +104,7 @@ describe("when adding breakpoints", () => {
|
||||
});
|
||||
|
||||
it("add a corresponding pendingBreakpoint for each addition", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -119,11 +119,11 @@ describe("when adding breakpoints", () => {
|
||||
await dispatch(actions.newSource(source1));
|
||||
await dispatch(actions.newSource(source2));
|
||||
|
||||
await dispatch(actions.loadSourceText({ source: source1 }));
|
||||
await dispatch(actions.loadSourceText({ source: source2 }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: source1 }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: source2 }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(breakpoint1.location));
|
||||
await dispatch(actions.addBreakpoint(breakpoint2.location));
|
||||
await dispatch(actions.addBreakpoint(cx, breakpoint1.location));
|
||||
await dispatch(actions.addBreakpoint(cx, breakpoint2.location));
|
||||
|
||||
const pendingBps = selectors.getPendingBreakpoints(getState());
|
||||
|
||||
@ -135,7 +135,7 @@ describe("when adding breakpoints", () => {
|
||||
});
|
||||
|
||||
it("hidden breakponts do not create pending bps", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -144,10 +144,10 @@ describe("when adding breakpoints", () => {
|
||||
const source = makeSource("foo");
|
||||
await dispatch(actions.newSource(makeSource("foo")));
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(
|
||||
actions.addBreakpoint(breakpoint1.location, { hidden: true })
|
||||
actions.addBreakpoint(cx, breakpoint1.location, { hidden: true })
|
||||
);
|
||||
const pendingBps = selectors.getPendingBreakpoints(getState());
|
||||
|
||||
@ -155,7 +155,7 @@ describe("when adding breakpoints", () => {
|
||||
});
|
||||
|
||||
it("remove a corresponding pending breakpoint when deleting", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -170,12 +170,12 @@ describe("when adding breakpoints", () => {
|
||||
await dispatch(actions.newSource(source1));
|
||||
await dispatch(actions.newSource(source2));
|
||||
|
||||
await dispatch(actions.loadSourceText({ source: source1 }));
|
||||
await dispatch(actions.loadSourceText({ source: source2 }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: source1 }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: source2 }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(breakpoint1.location));
|
||||
await dispatch(actions.addBreakpoint(breakpoint2.location));
|
||||
await dispatch(actions.removeBreakpoint(breakpoint1));
|
||||
await dispatch(actions.addBreakpoint(cx, breakpoint1.location));
|
||||
await dispatch(actions.addBreakpoint(cx, breakpoint2.location));
|
||||
await dispatch(actions.removeBreakpoint(cx, breakpoint1));
|
||||
|
||||
const pendingBps = selectors.getPendingBreakpoints(getState());
|
||||
expect(pendingBps.hasOwnProperty(breakpointLocationId1)).toBe(false);
|
||||
@ -186,7 +186,7 @@ describe("when adding breakpoints", () => {
|
||||
|
||||
describe("when changing an existing breakpoint", () => {
|
||||
it("updates corresponding pendingBreakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -197,11 +197,11 @@ describe("when changing an existing breakpoint", () => {
|
||||
const source = makeSource("foo");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.newSource(makeSource("foo")));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(bp.location));
|
||||
await dispatch(actions.addBreakpoint(cx, bp.location));
|
||||
await dispatch(
|
||||
actions.setBreakpointOptions(bp.location, { condition: "2" })
|
||||
actions.setBreakpointOptions(cx, bp.location, { condition: "2" })
|
||||
);
|
||||
const bps = selectors.getPendingBreakpoints(getState());
|
||||
const breakpoint = bps[id];
|
||||
@ -209,7 +209,7 @@ describe("when changing an existing breakpoint", () => {
|
||||
});
|
||||
|
||||
it("if disabled, updates corresponding pendingBreakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -221,17 +221,17 @@ describe("when changing an existing breakpoint", () => {
|
||||
|
||||
const source = makeSource("foo");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(bp.location));
|
||||
await dispatch(actions.disableBreakpoint(bp));
|
||||
await dispatch(actions.addBreakpoint(cx, bp.location));
|
||||
await dispatch(actions.disableBreakpoint(cx, bp));
|
||||
const bps = selectors.getPendingBreakpoints(getState());
|
||||
const breakpoint = bps[id];
|
||||
expect(breakpoint.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it("does not delete the pre-existing pendingBreakpoint", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -241,13 +241,13 @@ describe("when changing an existing breakpoint", () => {
|
||||
const source = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
const id = makePendingLocationId(bp.location);
|
||||
|
||||
await dispatch(actions.addBreakpoint(bp.location));
|
||||
await dispatch(actions.addBreakpoint(cx, bp.location));
|
||||
await dispatch(
|
||||
actions.setBreakpointOptions(bp.location, { condition: "2" })
|
||||
actions.setBreakpointOptions(cx, bp.location, { condition: "2" })
|
||||
);
|
||||
const bps = selectors.getPendingBreakpoints(getState());
|
||||
const breakpoint = bps[id];
|
||||
@ -267,7 +267,7 @@ describe("initializing when pending breakpoints exist in prefs", () => {
|
||||
});
|
||||
|
||||
it("re-adding breakpoints update existing pending breakpoints", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [1, 2] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -278,15 +278,15 @@ describe("initializing when pending breakpoints exist in prefs", () => {
|
||||
|
||||
const source = makeSource("bar.js");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.addBreakpoint(bar.location));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
await dispatch(actions.addBreakpoint(cx, bar.location));
|
||||
|
||||
const bps = selectors.getPendingBreakpointList(getState());
|
||||
expect(bps).toHaveLength(2);
|
||||
});
|
||||
|
||||
it("adding bps doesn't remove existing pending breakpoints", async () => {
|
||||
const { dispatch, getState } = createStore(
|
||||
const { dispatch, getState, cx } = createStore(
|
||||
mockClient({ "5": [0] }),
|
||||
loadInitialState(),
|
||||
mockSourceMaps()
|
||||
@ -296,9 +296,9 @@ describe("initializing when pending breakpoints exist in prefs", () => {
|
||||
const source = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await dispatch(actions.addBreakpoint(bp.location));
|
||||
await dispatch(actions.addBreakpoint(cx, bp.location));
|
||||
|
||||
const bps = selectors.getPendingBreakpointList(getState());
|
||||
expect(bps).toHaveLength(2);
|
||||
@ -313,12 +313,12 @@ describe("initializing with disabled pending breakpoints in prefs", () => {
|
||||
mockSourceMaps()
|
||||
);
|
||||
|
||||
const { getState, dispatch } = store;
|
||||
const { getState, dispatch, cx } = store;
|
||||
const source = makeSource("bar.js");
|
||||
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await waitForState(store, state => {
|
||||
const bps = selectors.getBreakpointsForSource(state, source.id);
|
||||
@ -346,7 +346,7 @@ describe("adding sources", () => {
|
||||
loadInitialState({ disabled: true }),
|
||||
mockSourceMaps()
|
||||
);
|
||||
const { getState, dispatch } = store;
|
||||
const { getState, dispatch, cx } = store;
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(0);
|
||||
|
||||
@ -354,7 +354,7 @@ describe("adding sources", () => {
|
||||
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
await waitForState(store, state => selectors.getBreakpointCount(state) > 0);
|
||||
|
||||
@ -396,7 +396,7 @@ describe("adding sources", () => {
|
||||
loadInitialState({ disabled: true }),
|
||||
mockSourceMaps()
|
||||
);
|
||||
const { getState, dispatch } = store;
|
||||
const { getState, dispatch, cx } = store;
|
||||
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(0);
|
||||
|
||||
@ -405,8 +405,8 @@ describe("adding sources", () => {
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.newSources([source1, source2]));
|
||||
await dispatch(actions.loadSourceText({ source: source1 }));
|
||||
await dispatch(actions.loadSourceText({ source: source2 }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: source1 }));
|
||||
await dispatch(actions.loadSourceText({ cx, source: source2 }));
|
||||
|
||||
await waitForState(store, state => selectors.getBreakpointCount(state) > 0);
|
||||
expect(selectors.getBreakpointCount(getState())).toEqual(1);
|
||||
|
@ -44,16 +44,16 @@ const threadClient = {
|
||||
|
||||
describe("project text search", () => {
|
||||
it("should add a project text search query", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
const mockQuery = "foo";
|
||||
|
||||
dispatch(actions.addSearchQuery(mockQuery));
|
||||
dispatch(actions.addSearchQuery(cx, mockQuery));
|
||||
|
||||
expect(getTextSearchQuery(getState())).toEqual(mockQuery);
|
||||
});
|
||||
|
||||
it("should search all the loaded sources based on the query", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
const mockQuery = "foo";
|
||||
const source1 = makeSource("foo1");
|
||||
const source2 = makeSource("foo2");
|
||||
@ -61,7 +61,7 @@ describe("project text search", () => {
|
||||
await dispatch(actions.newSource(source1));
|
||||
await dispatch(actions.newSource(source2));
|
||||
|
||||
await dispatch(actions.searchSources(mockQuery));
|
||||
await dispatch(actions.searchSources(cx, mockQuery));
|
||||
|
||||
const results = getTextSearchResults(getState());
|
||||
expect(results).toMatchSnapshot();
|
||||
@ -87,26 +87,26 @@ describe("project text search", () => {
|
||||
getOriginalLocations: async items => items
|
||||
};
|
||||
|
||||
const { dispatch, getState } = createStore(threadClient, {}, mockMaps);
|
||||
const { dispatch, getState, cx } = createStore(threadClient, {}, mockMaps);
|
||||
const mockQuery = "bla";
|
||||
|
||||
await dispatch(actions.newSource(source1));
|
||||
await dispatch(actions.newSource(source2));
|
||||
|
||||
await dispatch(actions.searchSources(mockQuery));
|
||||
await dispatch(actions.searchSources(cx, mockQuery));
|
||||
|
||||
const results = getTextSearchResults(getState());
|
||||
expect(results).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should search a specific source", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const source = makeSource("bar");
|
||||
await dispatch(actions.newSource(source));
|
||||
await dispatch(actions.loadSourceText({ source }));
|
||||
await dispatch(actions.loadSourceText({ cx, source }));
|
||||
|
||||
dispatch(actions.addSearchQuery("bla"));
|
||||
dispatch(actions.addSearchQuery(cx, "bla"));
|
||||
|
||||
const barSource = getSource(getState(), "bar");
|
||||
if (!barSource) {
|
||||
@ -114,7 +114,7 @@ describe("project text search", () => {
|
||||
}
|
||||
const sourceId = barSource.id;
|
||||
|
||||
await dispatch(actions.searchSource(sourceId, "bla"), "bla");
|
||||
await dispatch(actions.searchSource(cx, sourceId, "bla"), "bla");
|
||||
|
||||
const results = getTextSearchResults(getState());
|
||||
|
||||
@ -123,36 +123,36 @@ describe("project text search", () => {
|
||||
});
|
||||
|
||||
it("should clear all the search results", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
const mockQuery = "foo";
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.searchSources(mockQuery));
|
||||
await dispatch(actions.searchSources(cx, mockQuery));
|
||||
|
||||
expect(getTextSearchResults(getState())).toMatchSnapshot();
|
||||
|
||||
await dispatch(actions.clearSearchResults());
|
||||
await dispatch(actions.clearSearchResults(cx));
|
||||
|
||||
expect(getTextSearchResults(getState())).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it("should set the status properly", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
const mockStatus = "Fetching";
|
||||
dispatch(actions.updateSearchStatus(mockStatus));
|
||||
dispatch(actions.updateSearchStatus(cx, mockStatus));
|
||||
expect(getTextSearchStatus(getState())).toEqual(mockStatus);
|
||||
});
|
||||
|
||||
it("should close project search", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
const mockQuery = "foo";
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo1")));
|
||||
await dispatch(actions.searchSources(mockQuery));
|
||||
await dispatch(actions.searchSources(cx, mockQuery));
|
||||
|
||||
expect(getTextSearchResults(getState())).toMatchSnapshot();
|
||||
|
||||
dispatch(actions.closeProjectSearch());
|
||||
dispatch(actions.closeProjectSearch(cx));
|
||||
|
||||
expect(getTextSearchQuery(getState())).toEqual("");
|
||||
|
||||
|
@ -17,39 +17,39 @@ const { getProjectDirectoryRoot, getDisplayedSources } = selectors;
|
||||
|
||||
describe("setProjectDirectoryRoot", () => {
|
||||
it("should set domain directory as root", async () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("example.com"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "example.com"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("example.com");
|
||||
});
|
||||
|
||||
it("should set a directory as root directory", async () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/foo"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/foo"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("/example.com/foo");
|
||||
});
|
||||
|
||||
it("should add to the directory ", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/foo"));
|
||||
dispatch(actions.setProjectDirectoryRoot("/foo/bar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/foo"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/foo/bar"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("/example.com/foo/bar");
|
||||
});
|
||||
|
||||
it("should update the directory ", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/foo"));
|
||||
dispatch(actions.clearProjectDirectoryRoot());
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/bar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/foo"));
|
||||
dispatch(actions.clearProjectDirectoryRoot(cx));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/bar"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("/example.com/bar");
|
||||
});
|
||||
|
||||
it("should filter sources", async () => {
|
||||
const store = createStore({});
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
await dispatch(actions.newSource(makeSource("js/scopes.js")));
|
||||
await dispatch(actions.newSource(makeSource("lib/vendor.js")));
|
||||
|
||||
dispatch(actions.setProjectDirectoryRoot("localhost:8000/examples/js"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "localhost:8000/examples/js"));
|
||||
|
||||
const filteredSourcesByThread = getDisplayedSources(getState());
|
||||
const filteredSources = Object.values(filteredSourcesByThread)[0];
|
||||
@ -63,16 +63,16 @@ describe("setProjectDirectoryRoot", () => {
|
||||
});
|
||||
|
||||
it("should update the child directory ", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("example.com"));
|
||||
dispatch(actions.setProjectDirectoryRoot("example.com/foo/bar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "example.com"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "example.com/foo/bar"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("example.com/foo/bar");
|
||||
});
|
||||
|
||||
it("should update the child directory when domain name is Webpack://", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("webpack://"));
|
||||
dispatch(actions.setProjectDirectoryRoot("webpack:///app"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "webpack://"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "webpack:///app"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("webpack:///app");
|
||||
});
|
||||
});
|
||||
|
@ -16,26 +16,26 @@ import { sourceThreadClient as threadClient } from "./helpers/threadClient.js";
|
||||
|
||||
describe("closing tabs", () => {
|
||||
it("closing a tab", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const fooSource = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(fooSource));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
dispatch(actions.closeTab(fooSource));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
dispatch(actions.closeTab(cx, fooSource));
|
||||
|
||||
expect(getSelectedSource(getState())).toBe(undefined);
|
||||
expect(getSourceTabs(getState())).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("closing the inactive tab", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const fooSource = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(fooSource));
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bar.js", line: 1 }));
|
||||
dispatch(actions.closeTab(fooSource));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "bar.js", line: 1 }));
|
||||
dispatch(actions.closeTab(cx, fooSource));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("bar.js");
|
||||
@ -43,26 +43,26 @@ describe("closing tabs", () => {
|
||||
});
|
||||
|
||||
it("closing the only tab", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const fooSource = makeSource("foo.js");
|
||||
await dispatch(actions.newSource(fooSource));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
dispatch(actions.closeTab(fooSource));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
dispatch(actions.closeTab(cx, fooSource));
|
||||
|
||||
expect(getSelectedSource(getState())).toBe(undefined);
|
||||
expect(getSourceTabs(getState())).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("closing the active tab", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const barSource = makeSource("bar.js");
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.newSource(barSource));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(actions.closeTab(barSource));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(actions.closeTab(cx, barSource));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("foo.js");
|
||||
@ -70,22 +70,24 @@ describe("closing tabs", () => {
|
||||
});
|
||||
|
||||
it("closing many inactive tabs", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
const fooSource = makeSource("foo.js");
|
||||
const barSource = makeSource("bar.js");
|
||||
await dispatch(actions.newSource(fooSource));
|
||||
await dispatch(actions.newSource(barSource));
|
||||
await dispatch(actions.newSource(makeSource("bazz.js")));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bazz.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(
|
||||
actions.selectLocation(cx, { sourceId: "bazz.js", line: 1 })
|
||||
);
|
||||
|
||||
const tabs = [
|
||||
"http://localhost:8000/examples/foo.js",
|
||||
"http://localhost:8000/examples/bar.js"
|
||||
];
|
||||
dispatch(actions.closeTabs(tabs));
|
||||
dispatch(actions.closeTabs(cx, tabs));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("bazz.js");
|
||||
@ -93,19 +95,21 @@ describe("closing tabs", () => {
|
||||
});
|
||||
|
||||
it("closing many tabs including the active tab", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
await dispatch(actions.newSource(makeSource("bazz.js")));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bazz.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(
|
||||
actions.selectLocation(cx, { sourceId: "bazz.js", line: 1 })
|
||||
);
|
||||
const tabs = [
|
||||
"http://localhost:8000/examples/bar.js",
|
||||
"http://localhost:8000/examples/bazz.js"
|
||||
];
|
||||
await dispatch(actions.closeTabs(tabs));
|
||||
await dispatch(actions.closeTabs(cx, tabs));
|
||||
|
||||
const selected = getSelectedSource(getState());
|
||||
expect(selected && selected.id).toBe("foo.js");
|
||||
@ -113,14 +117,14 @@ describe("closing tabs", () => {
|
||||
});
|
||||
|
||||
it("closing all the tabs", async () => {
|
||||
const { dispatch, getState } = createStore(threadClient);
|
||||
const { dispatch, getState, cx } = createStore(threadClient);
|
||||
|
||||
await dispatch(actions.newSource(makeSource("foo.js")));
|
||||
await dispatch(actions.newSource(makeSource("bar.js")));
|
||||
await dispatch(actions.selectLocation({ sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation({ sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "foo.js", line: 1 }));
|
||||
await dispatch(actions.selectLocation(cx, { sourceId: "bar.js", line: 1 }));
|
||||
await dispatch(
|
||||
actions.closeTabs([
|
||||
actions.closeTabs(cx, [
|
||||
"http://localhost:8000/examples/foo.js",
|
||||
"http://localhost:8000/examples/bar.js"
|
||||
])
|
||||
|
@ -85,39 +85,39 @@ describe("ui", () => {
|
||||
|
||||
describe("setProjectDirectoryRoot", () => {
|
||||
it("should set domain directory as root", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("example.com"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "example.com"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("example.com");
|
||||
});
|
||||
|
||||
it("should set a directory as root directory", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/foo"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/foo"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("/example.com/foo");
|
||||
});
|
||||
|
||||
it("should add to the directory ", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/foo"));
|
||||
dispatch(actions.setProjectDirectoryRoot("/foo/bar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/foo"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/foo/bar"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("/example.com/foo/bar");
|
||||
});
|
||||
|
||||
it("should update the directory ", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/foo"));
|
||||
dispatch(actions.clearProjectDirectoryRoot());
|
||||
dispatch(actions.setProjectDirectoryRoot("/example.com/bar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/foo"));
|
||||
dispatch(actions.clearProjectDirectoryRoot(cx));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "/example.com/bar"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("/example.com/bar");
|
||||
});
|
||||
|
||||
it("should filter sources", async () => {
|
||||
const store = createStore({});
|
||||
const { dispatch, getState } = store;
|
||||
const { dispatch, getState, cx } = store;
|
||||
await dispatch(actions.newSource(makeSource("js/scopes.js")));
|
||||
await dispatch(actions.newSource(makeSource("lib/vendor.js")));
|
||||
|
||||
dispatch(actions.setProjectDirectoryRoot("localhost:8000/examples/js"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "localhost:8000/examples/js"));
|
||||
|
||||
const filteredSourcesByThread = getDisplayedSources(getState());
|
||||
const filteredSources = Object.values(filteredSourcesByThread)[0];
|
||||
@ -131,16 +131,16 @@ describe("setProjectDirectoryRoot", () => {
|
||||
});
|
||||
|
||||
it("should update the child directory ", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("example.com"));
|
||||
dispatch(actions.setProjectDirectoryRoot("example.com/foo/bar"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "example.com"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "example.com/foo/bar"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("example.com/foo/bar");
|
||||
});
|
||||
|
||||
it("should update the child directory when domain name is Webpack://", () => {
|
||||
const { dispatch, getState } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot("webpack://"));
|
||||
dispatch(actions.setProjectDirectoryRoot("webpack:///app"));
|
||||
const { dispatch, getState, cx } = createStore();
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "webpack://"));
|
||||
dispatch(actions.setProjectDirectoryRoot(cx, "webpack:///app"));
|
||||
expect(getProjectDirectoryRoot(getState())).toBe("webpack:///app");
|
||||
});
|
||||
});
|
||||
|
@ -6,26 +6,31 @@
|
||||
|
||||
import type { SymbolDeclarations, AstLocation } from "../../workers/parser";
|
||||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
import type { Context } from "../../types";
|
||||
|
||||
export type ASTAction =
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "SET_SYMBOLS",
|
||||
+cx: Context,
|
||||
+sourceId: string
|
||||
|},
|
||||
SymbolDeclarations
|
||||
>
|
||||
| {|
|
||||
+type: "OUT_OF_SCOPE_LOCATIONS",
|
||||
+cx: Context,
|
||||
+locations: ?(AstLocation[])
|
||||
|}
|
||||
| {|
|
||||
+type: "IN_SCOPE_LINES",
|
||||
+cx: Context,
|
||||
+lines: number[]
|
||||
|}
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "SET_PREVIEW"
|
||||
+type: "SET_PREVIEW",
|
||||
+cx: Context
|
||||
|},
|
||||
{
|
||||
expression: string,
|
||||
@ -36,5 +41,6 @@ export type ASTAction =
|
||||
}
|
||||
>
|
||||
| {|
|
||||
+type: "CLEAR_SELECTION"
|
||||
+type: "CLEAR_SELECTION",
|
||||
+cx: Context
|
||||
|};
|
||||
|
@ -10,7 +10,8 @@ import type {
|
||||
XHRBreakpoint,
|
||||
Source,
|
||||
BreakpointPositions,
|
||||
PendingLocation
|
||||
PendingLocation,
|
||||
Context
|
||||
} from "../../types";
|
||||
|
||||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
@ -42,18 +43,22 @@ export type BreakpointAction =
|
||||
|}>
|
||||
| {|
|
||||
+type: "SET_BREAKPOINT",
|
||||
+cx: Context,
|
||||
+breakpoint: Breakpoint
|
||||
|}
|
||||
| {|
|
||||
+type: "REMOVE_BREAKPOINT",
|
||||
+cx: Context,
|
||||
+location: SourceLocation
|
||||
|}
|
||||
| {|
|
||||
+type: "REMOVE_PENDING_BREAKPOINT",
|
||||
+cx: Context,
|
||||
+location: PendingLocation
|
||||
|}
|
||||
| {|
|
||||
type: "ADD_BREAKPOINT_POSITIONS",
|
||||
+cx: Context,
|
||||
positions: BreakpointPositions,
|
||||
source: Source
|
||||
|};
|
||||
|
@ -5,23 +5,33 @@
|
||||
// @flow
|
||||
|
||||
import type { Command } from "../../reducers/types";
|
||||
import type { Expression, LoadedObject, Frame, Scope, Why } from "../../types";
|
||||
import type {
|
||||
Expression,
|
||||
LoadedObject,
|
||||
Frame,
|
||||
Scope,
|
||||
Why,
|
||||
ThreadContext
|
||||
} from "../../types";
|
||||
|
||||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
|
||||
export type PauseAction =
|
||||
| {|
|
||||
+type: "BREAK_ON_NEXT",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+value: boolean
|
||||
|}
|
||||
| {|
|
||||
// Note: Do not include cx, as this action is triggered by the server.
|
||||
+type: "RESUME",
|
||||
+thread: string,
|
||||
+value: void,
|
||||
+wasStepping: boolean
|
||||
|}
|
||||
| {|
|
||||
// Note: Do not include cx, as this action is triggered by the server.
|
||||
+type: "PAUSED",
|
||||
+thread: string,
|
||||
+why: Why,
|
||||
@ -37,11 +47,13 @@ export type PauseAction =
|
||||
|}
|
||||
| PromiseAction<{|
|
||||
+type: "COMMAND",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+command: Command
|
||||
|}>
|
||||
| {|
|
||||
+type: "SELECT_FRAME",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+frame: Frame
|
||||
|}
|
||||
@ -52,12 +64,14 @@ export type PauseAction =
|
||||
|}
|
||||
| {|
|
||||
+type: "SET_POPUP_OBJECT_PROPERTIES",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+objectId: string,
|
||||
+properties: Object
|
||||
|}
|
||||
| {|
|
||||
+type: "ADD_EXPRESSION",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+id: number,
|
||||
+input: string,
|
||||
@ -67,6 +81,7 @@ export type PauseAction =
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "EVALUATE_EXPRESSION",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+input: string
|
||||
|},
|
||||
@ -74,11 +89,13 @@ export type PauseAction =
|
||||
>
|
||||
| PromiseAction<{|
|
||||
+type: "EVALUATE_EXPRESSIONS",
|
||||
+cx: ThreadContext,
|
||||
+results: Expression[],
|
||||
+inputs: string[]
|
||||
|}>
|
||||
| {|
|
||||
+type: "UPDATE_EXPRESSION",
|
||||
+cx: ThreadContext,
|
||||
+expression: Expression,
|
||||
+input: string,
|
||||
+expressionError: ?string
|
||||
@ -95,12 +112,14 @@ export type PauseAction =
|
||||
|}
|
||||
| {|
|
||||
+type: "AUTOCOMPLETE",
|
||||
+cx: ThreadContext,
|
||||
+input: string,
|
||||
+result: Object
|
||||
|}
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "MAP_SCOPES",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+frame: Frame
|
||||
|},
|
||||
@ -113,6 +132,7 @@ export type PauseAction =
|
||||
>
|
||||
| {|
|
||||
+type: "MAP_FRAMES",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+frames: Frame[],
|
||||
+selectedFrameId: string
|
||||
@ -120,6 +140,7 @@ export type PauseAction =
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "ADD_SCOPES",
|
||||
+cx: ThreadContext,
|
||||
+thread: string,
|
||||
+frame: Frame
|
||||
|},
|
||||
|
@ -4,12 +4,13 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import type { Source, SourceLocation } from "../../types";
|
||||
import type { Source, SourceLocation, Context } from "../../types";
|
||||
import type { PromiseAction } from "../utils/middleware/promise";
|
||||
|
||||
export type LoadSourceAction = PromiseAction<
|
||||
{|
|
||||
+type: "LOAD_SOURCE_TEXT",
|
||||
+cx: Context,
|
||||
+sourceId: string,
|
||||
+epoch: number
|
||||
|},
|
||||
@ -19,31 +20,37 @@ export type SourceAction =
|
||||
| LoadSourceAction
|
||||
| {|
|
||||
+type: "ADD_SOURCE",
|
||||
+cx: Context,
|
||||
+source: Source
|
||||
|}
|
||||
| {|
|
||||
+type: "ADD_SOURCES",
|
||||
+cx: Context,
|
||||
+sources: Array<Source>
|
||||
|}
|
||||
| {|
|
||||
+type: "UPDATE_SOURCE",
|
||||
+cx: Context,
|
||||
+source: Source
|
||||
|}
|
||||
| {|
|
||||
+type: "SET_SELECTED_LOCATION",
|
||||
+cx: Context,
|
||||
+source: Source,
|
||||
+location?: SourceLocation
|
||||
|}
|
||||
| {|
|
||||
+type: "SET_PENDING_SELECTED_LOCATION",
|
||||
+cx: Context,
|
||||
+url: string,
|
||||
+line?: number,
|
||||
+column?: number
|
||||
|}
|
||||
| {| type: "CLEAR_SELECTED_LOCATION" |}
|
||||
| {| type: "CLEAR_SELECTED_LOCATION", +cx: Context |}
|
||||
| PromiseAction<
|
||||
{|
|
||||
+type: "BLACKBOX",
|
||||
+cx: Context,
|
||||
+source: Source
|
||||
|},
|
||||
{|
|
||||
|
@ -4,7 +4,12 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import type { Source, PartialRange, SourceLocation } from "../../types";
|
||||
import type {
|
||||
Source,
|
||||
PartialRange,
|
||||
SourceLocation,
|
||||
Context
|
||||
} from "../../types";
|
||||
|
||||
import type {
|
||||
ActiveSearchType,
|
||||
@ -64,6 +69,7 @@ export type UIAction =
|
||||
|}
|
||||
| {|
|
||||
+type: "SET_PROJECT_DIRECTORY_ROOT",
|
||||
+cx: Context,
|
||||
+url: string
|
||||
|}
|
||||
| {|
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
// @flow
|
||||
|
||||
import type { WorkerList, MainThread } from "../../types";
|
||||
import type { WorkerList, MainThread, Context } from "../../types";
|
||||
import type { State } from "../../reducers/types";
|
||||
import type { MatchedLocations } from "../../reducers/file-search";
|
||||
import type { TreeNode } from "../../utils/sources-tree/types";
|
||||
@ -75,18 +75,23 @@ export type FocusItem = {
|
||||
|
||||
export type SourceTreeAction =
|
||||
| {| +type: "SET_EXPANDED_STATE", +thread: string, +expanded: any |}
|
||||
| {| +type: "SET_FOCUSED_SOURCE_ITEM", item: FocusItem |};
|
||||
| {| +type: "SET_FOCUSED_SOURCE_ITEM", +cx: Context, item: FocusItem |};
|
||||
|
||||
export type ProjectTextSearchAction =
|
||||
| {| +type: "ADD_QUERY", +query: string |}
|
||||
| {| +type: "ADD_QUERY", +cx: Context, +query: string |}
|
||||
| {|
|
||||
+type: "ADD_SEARCH_RESULT",
|
||||
+cx: Context,
|
||||
+result: ProjectTextSearchResult
|
||||
|}
|
||||
| {| +type: "UPDATE_STATUS", +status: string |}
|
||||
| {| +type: "CLEAR_SEARCH_RESULTS" |}
|
||||
| {| +type: "ADD_ONGOING_SEARCH", +ongoingSearch: SearchOperation |}
|
||||
| {| +type: "CLEAR_SEARCH" |};
|
||||
| {| +type: "UPDATE_STATUS", +cx: Context, +status: string |}
|
||||
| {| +type: "CLEAR_SEARCH_RESULTS", +cx: Context |}
|
||||
| {|
|
||||
+type: "ADD_ONGOING_SEARCH",
|
||||
+cx: Context,
|
||||
+ongoingSearch: SearchOperation
|
||||
|}
|
||||
| {| +type: "CLEAR_SEARCH", +cx: Context |};
|
||||
|
||||
export type FileTextSearchModifier =
|
||||
| "caseSensitive"
|
||||
@ -96,14 +101,17 @@ export type FileTextSearchModifier =
|
||||
export type FileTextSearchAction =
|
||||
| {|
|
||||
+type: "TOGGLE_FILE_SEARCH_MODIFIER",
|
||||
+cx: Context,
|
||||
+modifier: FileTextSearchModifier
|
||||
|}
|
||||
| {|
|
||||
+type: "UPDATE_FILE_SEARCH_QUERY",
|
||||
+cx: Context,
|
||||
+query: string
|
||||
|}
|
||||
| {|
|
||||
+type: "UPDATE_SEARCH_RESULTS",
|
||||
+cx: Context,
|
||||
+results: {
|
||||
matches: MatchedLocations[],
|
||||
matchIndex: number,
|
||||
@ -117,14 +125,16 @@ export type QuickOpenAction =
|
||||
| {| +type: "OPEN_QUICK_OPEN", +query?: string |}
|
||||
| {| +type: "CLOSE_QUICK_OPEN" |};
|
||||
|
||||
export type DebugeeAction =
|
||||
export type DebuggeeAction =
|
||||
| {|
|
||||
+type: "SET_WORKERS",
|
||||
+cx: Context,
|
||||
+workers: WorkerList,
|
||||
+mainThread: string
|
||||
|}
|
||||
| {|
|
||||
+type: "SELECT_THREAD",
|
||||
+cx: Context,
|
||||
+thread: string
|
||||
|};
|
||||
|
||||
@ -156,5 +166,5 @@ export type Action =
|
||||
| QuickOpenAction
|
||||
| FileTextSearchAction
|
||||
| ProjectTextSearchAction
|
||||
| DebugeeAction
|
||||
| DebuggeeAction
|
||||
| SourceTreeAction;
|
||||
|
@ -17,7 +17,7 @@ import type { ThunkArgs, panelPositionType } from "./types";
|
||||
import { getEditor, getLocationsInViewport } from "../utils/editor";
|
||||
import { searchContents } from "./file-search";
|
||||
|
||||
import type { SourceLocation } from "../types";
|
||||
import type { SourceLocation, Context } from "../types";
|
||||
import type {
|
||||
ActiveSearchType,
|
||||
OrientationType,
|
||||
@ -53,13 +53,13 @@ export function setActiveSearch(activeSearch?: ActiveSearchType) {
|
||||
};
|
||||
}
|
||||
|
||||
export function updateActiveFileSearch() {
|
||||
export function updateActiveFileSearch(cx: Context) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const isFileSearchOpen = getActiveSearch(getState()) === "file";
|
||||
const fileSearchQuery = getFileSearchQuery(getState());
|
||||
if (isFileSearchOpen && fileSearchQuery) {
|
||||
const editor = getEditor();
|
||||
dispatch(searchContents(fileSearchQuery, editor));
|
||||
dispatch(searchContents(cx, fileSearchQuery, editor));
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -73,7 +73,7 @@ export function toggleFrameworkGrouping(toggleValue: boolean) {
|
||||
};
|
||||
}
|
||||
|
||||
export function showSource(sourceId: string) {
|
||||
export function showSource(cx: Context, sourceId: string) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const source = getSource(getState(), sourceId);
|
||||
if (!source) {
|
||||
@ -91,7 +91,7 @@ export function showSource(sourceId: string) {
|
||||
dispatch(setPrimaryPaneTab("sources"));
|
||||
|
||||
dispatch({ type: "SHOW_SOURCE", source: null });
|
||||
dispatch(selectSource(source.id));
|
||||
dispatch(selectSource(cx, source.id));
|
||||
dispatch({ type: "SHOW_SOURCE", source });
|
||||
};
|
||||
}
|
||||
@ -171,14 +171,15 @@ export function closeConditionalPanel() {
|
||||
};
|
||||
}
|
||||
|
||||
export function clearProjectDirectoryRoot() {
|
||||
export function clearProjectDirectoryRoot(cx: Context) {
|
||||
return {
|
||||
type: "SET_PROJECT_DIRECTORY_ROOT",
|
||||
cx,
|
||||
url: ""
|
||||
};
|
||||
}
|
||||
|
||||
export function setProjectDirectoryRoot(newRoot: string) {
|
||||
export function setProjectDirectoryRoot(cx: Context, newRoot: string) {
|
||||
return ({ dispatch, getState }: ThunkArgs) => {
|
||||
const curRoot = getProjectDirectoryRoot(getState());
|
||||
if (newRoot && curRoot) {
|
||||
@ -195,6 +196,7 @@ export function setProjectDirectoryRoot(newRoot: string) {
|
||||
|
||||
dispatch({
|
||||
type: "SET_PROJECT_DIRECTORY_ROOT",
|
||||
cx,
|
||||
url: newRoot
|
||||
});
|
||||
};
|
||||
|
@ -18,6 +18,7 @@ import { history } from "./middleware/history";
|
||||
import { promise } from "./middleware/promise";
|
||||
import { thunk } from "./middleware/thunk";
|
||||
import { timing } from "./middleware/timing";
|
||||
import { context } from "./middleware/context";
|
||||
|
||||
/**
|
||||
* @memberof utils/create-store
|
||||
@ -47,6 +48,7 @@ type ReduxStoreOptions = {
|
||||
const configureStore = (opts: ReduxStoreOptions = {}) => {
|
||||
const middleware = [
|
||||
thunk(opts.makeThunkArgs),
|
||||
context,
|
||||
promise,
|
||||
|
||||
// Order is important: services must go last as they always
|
||||
|
@ -0,0 +1,37 @@
|
||||
/* 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 {
|
||||
validateNavigateContext,
|
||||
validateContext
|
||||
} from "../../../utils/context";
|
||||
|
||||
import type { ThunkArgs } from "../../types";
|
||||
|
||||
function validateActionContext(getState, action) {
|
||||
if (action.type == "COMMAND" && action.status == "done") {
|
||||
// The thread will have resumed execution since the action was initiated,
|
||||
// so just make sure we haven't navigated.
|
||||
validateNavigateContext(getState(), action.cx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate using all available information in the context.
|
||||
validateContext(getState(), action.cx);
|
||||
}
|
||||
|
||||
// Middleware which looks for actions that have a cx property and ignores
|
||||
// them if the context is no longer valid.
|
||||
function context({ dispatch, getState }: ThunkArgs) {
|
||||
return (next: Function) => (action: Object) => {
|
||||
if ("cx" in action) {
|
||||
validateActionContext(getState, action);
|
||||
}
|
||||
return next(action);
|
||||
};
|
||||
}
|
||||
|
||||
export { context };
|
@ -8,6 +8,7 @@ DIRS += [
|
||||
]
|
||||
|
||||
CompiledModules(
|
||||
'context.js',
|
||||
'history.js',
|
||||
'log.js',
|
||||
'promise.js',
|
||||
|
@ -15,13 +15,18 @@ import { breakpointItems } from "./menus/breakpoints";
|
||||
import type { BreakpointItemActions } from "./menus/breakpoints";
|
||||
import type { EditorItemActions } from "./menus/editor";
|
||||
|
||||
import type { Source, Breakpoint as BreakpointType } from "../../types";
|
||||
import type {
|
||||
Source,
|
||||
Breakpoint as BreakpointType,
|
||||
ThreadContext
|
||||
} from "../../types";
|
||||
|
||||
const breakpointSvg = document.createElement("div");
|
||||
breakpointSvg.innerHTML =
|
||||
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 15" width="60" height="15"><path d="M53.07.5H1.5c-.54 0-1 .46-1 1v12c0 .54.46 1 1 1h51.57c.58 0 1.15-.26 1.53-.7l4.7-6.3-4.7-6.3c-.38-.44-.95-.7-1.53-.7z"/></svg>';
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
breakpoint: BreakpointType,
|
||||
selectedSource: Source,
|
||||
editor: Object,
|
||||
@ -61,6 +66,7 @@ class Breakpoint extends PureComponent<Props> {
|
||||
|
||||
onClick = (event: MouseEvent) => {
|
||||
const {
|
||||
cx,
|
||||
breakpointActions,
|
||||
editorActions,
|
||||
breakpoint,
|
||||
@ -77,31 +83,33 @@ class Breakpoint extends PureComponent<Props> {
|
||||
|
||||
const selectedLocation = getSelectedLocation(breakpoint, selectedSource);
|
||||
if (event.metaKey) {
|
||||
return editorActions.continueToHere(selectedLocation.line);
|
||||
return editorActions.continueToHere(cx, selectedLocation.line);
|
||||
}
|
||||
|
||||
if (event.shiftKey) {
|
||||
if (features.columnBreakpoints) {
|
||||
return breakpointActions.toggleBreakpointsAtLine(
|
||||
cx,
|
||||
!breakpoint.disabled,
|
||||
selectedLocation.line
|
||||
);
|
||||
}
|
||||
|
||||
return breakpointActions.toggleDisabledBreakpoint(breakpoint);
|
||||
return breakpointActions.toggleDisabledBreakpoint(cx, breakpoint);
|
||||
}
|
||||
|
||||
return breakpointActions.removeBreakpointsAtLine(
|
||||
cx,
|
||||
selectedLocation.sourceId,
|
||||
selectedLocation.line
|
||||
);
|
||||
};
|
||||
|
||||
onContextMenu = (event: MouseEvent) => {
|
||||
const { breakpoint, breakpointActions } = this.props;
|
||||
const { cx, breakpoint, breakpointActions } = this.props;
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
showMenu(event, breakpointItems(breakpoint, breakpointActions));
|
||||
showMenu(event, breakpointItems(cx, breakpoint, breakpointActions));
|
||||
};
|
||||
|
||||
addBreakpoint(props: Props) {
|
||||
|
@ -14,9 +14,14 @@ import { editorItemActions } from "./menus/editor";
|
||||
|
||||
import type { BreakpointItemActions } from "./menus/breakpoints";
|
||||
import type { EditorItemActions } from "./menus/editor";
|
||||
import type { Breakpoint as BreakpointType, Source } from "../../types";
|
||||
import type {
|
||||
Breakpoint as BreakpointType,
|
||||
Source,
|
||||
ThreadContext
|
||||
} from "../../types";
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
selectedSource: Source,
|
||||
breakpoints: BreakpointType[],
|
||||
editor: Object,
|
||||
@ -27,6 +32,7 @@ type Props = {
|
||||
class Breakpoints extends Component<Props> {
|
||||
render() {
|
||||
const {
|
||||
cx,
|
||||
breakpoints,
|
||||
selectedSource,
|
||||
editor,
|
||||
@ -43,6 +49,7 @@ class Breakpoints extends Component<Props> {
|
||||
{breakpoints.map(bp => {
|
||||
return (
|
||||
<Breakpoint
|
||||
cx={cx}
|
||||
key={makeBreakpointId(bp.location)}
|
||||
breakpoint={bp}
|
||||
selectedSource={selectedSource}
|
||||
|
@ -13,13 +13,14 @@ import { breakpointItems, createBreakpointItems } from "./menus/breakpoints";
|
||||
// eslint-disable-next-line max-len
|
||||
import type { ColumnBreakpoint as ColumnBreakpointType } from "../../selectors/visibleColumnBreakpoints";
|
||||
import type { BreakpointItemActions } from "./menus/breakpoints";
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
type Bookmark = {
|
||||
clear: Function
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
editor: Object,
|
||||
source: Source,
|
||||
columnBreakpoint: ColumnBreakpointType,
|
||||
@ -88,11 +89,11 @@ export default class ColumnBreakpoint extends PureComponent<Props> {
|
||||
onClick = (event: MouseEvent) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const { columnBreakpoint, breakpointActions } = this.props;
|
||||
const { cx, columnBreakpoint, breakpointActions } = this.props;
|
||||
if (columnBreakpoint.breakpoint) {
|
||||
breakpointActions.removeBreakpoint(columnBreakpoint.breakpoint);
|
||||
breakpointActions.removeBreakpoint(cx, columnBreakpoint.breakpoint);
|
||||
} else {
|
||||
breakpointActions.addBreakpoint(columnBreakpoint.location);
|
||||
breakpointActions.addBreakpoint(cx, columnBreakpoint.location);
|
||||
}
|
||||
};
|
||||
|
||||
@ -100,13 +101,14 @@ export default class ColumnBreakpoint extends PureComponent<Props> {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
const {
|
||||
cx,
|
||||
columnBreakpoint: { breakpoint, location },
|
||||
breakpointActions
|
||||
} = this.props;
|
||||
|
||||
const items = breakpoint
|
||||
? breakpointItems(breakpoint, breakpointActions)
|
||||
: createBreakpointItems(location, breakpointActions);
|
||||
? breakpointItems(cx, breakpoint, breakpointActions)
|
||||
: createBreakpointItems(cx, location, breakpointActions);
|
||||
|
||||
showMenu(event, items);
|
||||
};
|
||||
|
@ -8,17 +8,22 @@ import React, { Component } from "react";
|
||||
|
||||
import ColumnBreakpoint from "./ColumnBreakpoint";
|
||||
|
||||
import { getSelectedSource, visibleColumnBreakpoints } from "../../selectors";
|
||||
import {
|
||||
getSelectedSource,
|
||||
visibleColumnBreakpoints,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
import { connect } from "../../utils/connect";
|
||||
import { makeBreakpointId } from "../../utils/breakpoint";
|
||||
import { breakpointItemActions } from "./menus/breakpoints";
|
||||
import type { BreakpointItemActions } from "./menus/breakpoints";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
// eslint-disable-next-line max-len
|
||||
import type { ColumnBreakpoint as ColumnBreakpointType } from "../../selectors/visibleColumnBreakpoints";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
editor: Object,
|
||||
selectedSource: Source,
|
||||
columnBreakpoints: ColumnBreakpointType[],
|
||||
@ -30,6 +35,7 @@ class ColumnBreakpoints extends Component<Props> {
|
||||
|
||||
render() {
|
||||
const {
|
||||
cx,
|
||||
editor,
|
||||
columnBreakpoints,
|
||||
selectedSource,
|
||||
@ -44,6 +50,7 @@ class ColumnBreakpoints extends Component<Props> {
|
||||
editor.codeMirror.operation(() => {
|
||||
breakpoints = columnBreakpoints.map(breakpoint => (
|
||||
<ColumnBreakpoint
|
||||
cx={cx}
|
||||
key={makeBreakpointId(breakpoint.location)}
|
||||
columnBreakpoint={breakpoint}
|
||||
editor={editor}
|
||||
@ -58,6 +65,7 @@ class ColumnBreakpoints extends Component<Props> {
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
cx: getContext(state),
|
||||
selectedSource: getSelectedSource(state),
|
||||
columnBreakpoints: visibleColumnBreakpoints(state)
|
||||
};
|
||||
|
@ -14,14 +14,16 @@ import actions from "../../actions";
|
||||
import {
|
||||
getBreakpointForLocation,
|
||||
getConditionalPanelLocation,
|
||||
getLogPointStatus
|
||||
getLogPointStatus,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
|
||||
import type { SourceLocation } from "../../types";
|
||||
import type { SourceLocation, Context } from "../../types";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
breakpoint: ?Object,
|
||||
setBreakpointOptions: Function,
|
||||
setBreakpointOptions: typeof actions.setBreakpointOptions,
|
||||
location: SourceLocation,
|
||||
log: boolean,
|
||||
editor: Object,
|
||||
@ -63,10 +65,10 @@ export class ConditionalPanel extends PureComponent<Props> {
|
||||
};
|
||||
|
||||
setBreakpoint(value: string) {
|
||||
const { location, log, breakpoint } = this.props;
|
||||
const { cx, location, log, breakpoint } = this.props;
|
||||
const options = breakpoint ? breakpoint.options : {};
|
||||
const type = log ? "logValue" : "condition";
|
||||
return this.props.setBreakpointOptions(location, {
|
||||
return this.props.setBreakpointOptions(cx, location, {
|
||||
...options,
|
||||
[type]: value
|
||||
});
|
||||
@ -199,6 +201,7 @@ const mapStateToProps = state => {
|
||||
const location = getConditionalPanelLocation(state);
|
||||
const log = getLogPointStatus(state);
|
||||
return {
|
||||
cx: getContext(state),
|
||||
breakpoint: getBreakpointForLocation(state, location),
|
||||
location,
|
||||
log
|
||||
|
@ -12,16 +12,18 @@ import { getSourceLocationFromMouseEvent } from "../../utils/editor";
|
||||
import {
|
||||
getPrettySource,
|
||||
getIsPaused,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
|
||||
import { editorMenuItems, editorItemActions } from "./menus/editor";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, ThreadContext } from "../../types";
|
||||
import type { EditorItemActions } from "./menus/editor";
|
||||
import type SourceEditor from "../../utils/editor/source-editor";
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
contextMenu: ?MouseEvent,
|
||||
editorActions: EditorItemActions,
|
||||
clearContextMenu: () => void,
|
||||
@ -43,6 +45,7 @@ class EditorMenu extends Component<Props> {
|
||||
|
||||
showMenu(props) {
|
||||
const {
|
||||
cx,
|
||||
editor,
|
||||
selectedSource,
|
||||
editorActions,
|
||||
@ -61,6 +64,7 @@ class EditorMenu extends Component<Props> {
|
||||
showMenu(
|
||||
event,
|
||||
editorMenuItems({
|
||||
cx,
|
||||
editorActions,
|
||||
selectedSource,
|
||||
hasPrettySource,
|
||||
@ -78,6 +82,7 @@ class EditorMenu extends Component<Props> {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props) => ({
|
||||
cx: getThreadContext(state),
|
||||
isPaused: getIsPaused(state, getCurrentThread(state)),
|
||||
hasPrettySource: !!getPrettySource(state, props.selectedSource.id)
|
||||
});
|
||||
|
@ -10,7 +10,8 @@ import actions from "../../actions";
|
||||
import {
|
||||
getSelectedSource,
|
||||
getPrettySource,
|
||||
getPaneCollapse
|
||||
getPaneCollapse,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
|
||||
import {
|
||||
@ -27,7 +28,7 @@ import { shouldShowPrettyPrint } from "../../utils/editor";
|
||||
import { PaneToggleButton } from "../shared/Button";
|
||||
import AccessibleImage from "../shared/AccessibleImage";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
import "./Footer.css";
|
||||
|
||||
@ -37,6 +38,7 @@ type CursorPosition = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
selectedSource: Source,
|
||||
mappedSource: Source,
|
||||
endPanelCollapsed: boolean,
|
||||
@ -83,7 +85,7 @@ class SourceFooter extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
prettyPrintButton() {
|
||||
const { selectedSource, togglePrettyPrint } = this.props;
|
||||
const { cx, selectedSource, togglePrettyPrint } = this.props;
|
||||
|
||||
if (!selectedSource) {
|
||||
return;
|
||||
@ -107,7 +109,7 @@ class SourceFooter extends PureComponent<Props, State> {
|
||||
const type = "prettyPrint";
|
||||
return (
|
||||
<button
|
||||
onClick={() => togglePrettyPrint(selectedSource.id)}
|
||||
onClick={() => togglePrettyPrint(cx, selectedSource.id)}
|
||||
className={classnames("action", type, {
|
||||
active: sourceLoaded,
|
||||
pretty: isPretty(selectedSource)
|
||||
@ -122,7 +124,7 @@ class SourceFooter extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
blackBoxButton() {
|
||||
const { selectedSource, toggleBlackBox } = this.props;
|
||||
const { cx, selectedSource, toggleBlackBox } = this.props;
|
||||
const sourceLoaded = selectedSource && isLoaded(selectedSource);
|
||||
|
||||
if (!selectedSource) {
|
||||
@ -143,7 +145,7 @@ class SourceFooter extends PureComponent<Props, State> {
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={() => toggleBlackBox(selectedSource)}
|
||||
onClick={() => toggleBlackBox(cx, selectedSource)}
|
||||
className={classnames("action", type, {
|
||||
active: sourceLoaded,
|
||||
blackboxed: blackboxed
|
||||
@ -182,7 +184,12 @@ class SourceFooter extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
renderSourceSummary() {
|
||||
const { mappedSource, jumpToMappedLocation, selectedSource } = this.props;
|
||||
const {
|
||||
cx,
|
||||
mappedSource,
|
||||
jumpToMappedLocation,
|
||||
selectedSource
|
||||
} = this.props;
|
||||
|
||||
if (!mappedSource || !isOriginal(selectedSource)) {
|
||||
return null;
|
||||
@ -202,7 +209,7 @@ class SourceFooter extends PureComponent<Props, State> {
|
||||
return (
|
||||
<button
|
||||
className="mapped-source"
|
||||
onClick={() => jumpToMappedLocation(mappedSourceLocation)}
|
||||
onClick={() => jumpToMappedLocation(cx, mappedSourceLocation)}
|
||||
title={tooltip}
|
||||
>
|
||||
<span>{title}</span>
|
||||
@ -255,6 +262,7 @@ const mapStateToProps = state => {
|
||||
const selectedSource = getSelectedSource(state);
|
||||
|
||||
return {
|
||||
cx: getContext(state),
|
||||
selectedSource,
|
||||
mappedSource: getGeneratedSource(state, selectedSource),
|
||||
prettySource: getPrettySource(
|
||||
|
@ -24,7 +24,8 @@ const {
|
||||
import actions from "../../../actions";
|
||||
import {
|
||||
getAllPopupObjectProperties,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getThreadContext
|
||||
} from "../../../selectors";
|
||||
import Popover from "../../shared/Popover";
|
||||
import PreviewFunction from "../../shared/PreviewFunction";
|
||||
@ -36,9 +37,11 @@ import "./Popup.css";
|
||||
|
||||
import type { EditorRange } from "../../../utils/editor/types";
|
||||
import type { Coords } from "../../shared/Popover";
|
||||
import type { ThreadContext } from "../../../types";
|
||||
|
||||
type PopupValue = Object | null;
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
popupObjectProperties: Object,
|
||||
popoverPos: Object,
|
||||
value: PopupValue,
|
||||
@ -92,6 +95,7 @@ export class Popup extends Component<Props, State> {
|
||||
|
||||
async componentWillMount() {
|
||||
const {
|
||||
cx,
|
||||
value,
|
||||
setPopupObjectProperties,
|
||||
popupObjectProperties
|
||||
@ -108,7 +112,7 @@ export class Popup extends Component<Props, State> {
|
||||
const onLoadItemProperties = loadItemProperties(root, createObjectClient);
|
||||
if (onLoadItemProperties !== null) {
|
||||
const properties = await onLoadItemProperties;
|
||||
setPopupObjectProperties(root.contents.value, properties);
|
||||
setPopupObjectProperties(cx, root.contents.value, properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,7 +185,7 @@ export class Popup extends Component<Props, State> {
|
||||
};
|
||||
|
||||
renderFunctionPreview() {
|
||||
const { selectSourceURL, value } = this.props;
|
||||
const { cx, selectSourceURL, value } = this.props;
|
||||
|
||||
if (!value) {
|
||||
return null;
|
||||
@ -191,7 +195,9 @@ export class Popup extends Component<Props, State> {
|
||||
return (
|
||||
<div
|
||||
className="preview-popup"
|
||||
onClick={() => selectSourceURL(location.url, { line: location.line })}
|
||||
onClick={() =>
|
||||
selectSourceURL(cx, location.url, { line: location.line })
|
||||
}
|
||||
>
|
||||
<PreviewFunction func={value} />
|
||||
</div>
|
||||
@ -330,6 +336,7 @@ export class Popup extends Component<Props, State> {
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getThreadContext(state),
|
||||
popupObjectProperties: getAllPopupObjectProperties(
|
||||
state,
|
||||
getCurrentThread(state)
|
||||
|
@ -12,22 +12,21 @@ import Popup from "./Popup";
|
||||
import {
|
||||
getPreview,
|
||||
getSelectedSource,
|
||||
getIsPaused,
|
||||
getCurrentThread
|
||||
getThreadContext
|
||||
} from "../../../selectors";
|
||||
import actions from "../../../actions";
|
||||
import { toEditorRange } from "../../../utils/editor";
|
||||
|
||||
import type { Source } from "../../../types";
|
||||
import type { Source, ThreadContext } from "../../../types";
|
||||
|
||||
import type { Preview as PreviewType } from "../../../reducers/ast";
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
editor: any,
|
||||
editorRef: ?HTMLDivElement,
|
||||
selectedSource: Source,
|
||||
preview: PreviewType,
|
||||
isPaused: boolean,
|
||||
clearPreview: typeof actions.clearPreview,
|
||||
setPopupObjectProperties: typeof actions.setPopupObjectProperties,
|
||||
addExpression: typeof actions.addExpression,
|
||||
@ -113,40 +112,41 @@ class Preview extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
onTokenEnter = ({ target, tokenPos }) => {
|
||||
if (this.props.isPaused) {
|
||||
this.props.updatePreview(target, tokenPos, this.props.editor.codeMirror);
|
||||
const { cx, updatePreview, editor } = this.props;
|
||||
if (cx.isPaused) {
|
||||
updatePreview(cx, target, tokenPos, editor.codeMirror);
|
||||
}
|
||||
};
|
||||
|
||||
onTokenLeave = e => {
|
||||
if (this.props.isPaused && !inPopup(e)) {
|
||||
this.props.clearPreview();
|
||||
if (this.props.cx.isPaused && !inPopup(e)) {
|
||||
this.props.clearPreview(this.props.cx);
|
||||
}
|
||||
};
|
||||
|
||||
onMouseUp = () => {
|
||||
if (this.props.isPaused) {
|
||||
if (this.props.cx.isPaused) {
|
||||
this.setState({ selecting: false });
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
onMouseDown = () => {
|
||||
if (this.props.isPaused) {
|
||||
if (this.props.cx.isPaused) {
|
||||
this.setState({ selecting: true });
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
onScroll = () => {
|
||||
if (this.props.isPaused) {
|
||||
this.props.clearPreview();
|
||||
if (this.props.cx.isPaused) {
|
||||
this.props.clearPreview(this.props.cx);
|
||||
}
|
||||
};
|
||||
|
||||
onClose = e => {
|
||||
if (this.props.isPaused) {
|
||||
this.props.clearPreview();
|
||||
if (this.props.cx.isPaused) {
|
||||
this.props.clearPreview(this.props.cx);
|
||||
}
|
||||
};
|
||||
|
||||
@ -183,8 +183,8 @@ class Preview extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getThreadContext(state),
|
||||
preview: getPreview(state),
|
||||
isPaused: getIsPaused(state, getCurrentThread(state)),
|
||||
selectedSource: getSelectedSource(state)
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,8 @@ import {
|
||||
getFileSearchQuery,
|
||||
getFileSearchModifiers,
|
||||
getFileSearchResults,
|
||||
getHighlightedLineRange
|
||||
getHighlightedLineRange,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
|
||||
import { removeOverlay } from "../../utils/editor";
|
||||
@ -25,7 +26,7 @@ import { removeOverlay } from "../../utils/editor";
|
||||
import { scrollList } from "../../utils/result-list";
|
||||
import classnames from "classnames";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
import type { Modifiers, SearchResults } from "../../reducers/file-search";
|
||||
|
||||
import SearchInput from "../shared/SearchInput";
|
||||
@ -55,6 +56,7 @@ type State = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
editor: SourceEditor,
|
||||
selectedSource?: Source,
|
||||
searchOn: boolean,
|
||||
@ -137,10 +139,10 @@ class SearchBar extends Component<Props, State> {
|
||||
};
|
||||
|
||||
closeSearch = (e: SyntheticEvent<HTMLElement>) => {
|
||||
const { closeFileSearch, editor, searchOn } = this.props;
|
||||
const { cx, closeFileSearch, editor, searchOn } = this.props;
|
||||
if (editor && searchOn) {
|
||||
this.clearSearch();
|
||||
closeFileSearch(editor);
|
||||
closeFileSearch(cx, editor);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
@ -169,12 +171,12 @@ class SearchBar extends Component<Props, State> {
|
||||
};
|
||||
|
||||
doSearch = (query: string) => {
|
||||
const { selectedSource } = this.props;
|
||||
const { cx, selectedSource } = this.props;
|
||||
if (!selectedSource || !selectedSource.text) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.doSearch(query, this.props.editor);
|
||||
this.props.doSearch(cx, query, this.props.editor);
|
||||
};
|
||||
|
||||
traverseResults = (e: SyntheticEvent<HTMLElement>, rev: boolean) => {
|
||||
@ -185,7 +187,7 @@ class SearchBar extends Component<Props, State> {
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
this.props.traverseResults(rev, editor);
|
||||
this.props.traverseResults(this.props.cx, rev, editor);
|
||||
};
|
||||
|
||||
// Handlers
|
||||
@ -242,7 +244,7 @@ class SearchBar extends Component<Props, State> {
|
||||
}
|
||||
|
||||
renderSearchModifiers = () => {
|
||||
const { modifiers, toggleFileSearchModifier, query } = this.props;
|
||||
const { cx, modifiers, toggleFileSearchModifier, query } = this.props;
|
||||
const { doSearch } = this;
|
||||
|
||||
function SearchModBtn({ modVal, className, svgName, tooltip }) {
|
||||
@ -253,12 +255,12 @@ class SearchBar extends Component<Props, State> {
|
||||
<button
|
||||
className={preppedClass}
|
||||
onMouseDown={() => {
|
||||
toggleFileSearchModifier(modVal);
|
||||
toggleFileSearchModifier(cx, modVal);
|
||||
doSearch(query);
|
||||
}}
|
||||
onKeyDown={(e: any) => {
|
||||
if (e.key === "Enter") {
|
||||
toggleFileSearchModifier(modVal);
|
||||
toggleFileSearchModifier(cx, modVal);
|
||||
doSearch(query);
|
||||
}
|
||||
}}
|
||||
@ -357,6 +359,7 @@ SearchBar.contextTypes = {
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getContext(state),
|
||||
searchOn: getActiveSearch(state) === "file",
|
||||
selectedSource: getSelectedSource(state),
|
||||
selectedLocation: getSelectedLocation(state),
|
||||
|
@ -13,7 +13,7 @@ import SourceIcon from "../shared/SourceIcon";
|
||||
import { CloseButton } from "../shared/Button";
|
||||
|
||||
import type { List } from "immutable";
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
import actions from "../../actions";
|
||||
|
||||
@ -33,7 +33,8 @@ import {
|
||||
getSelectedSource,
|
||||
getActiveSearch,
|
||||
getSourcesForTabs,
|
||||
getHasSiblingOfSameName
|
||||
getHasSiblingOfSameName,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
import type { ActiveSearchType } from "../../selectors";
|
||||
|
||||
@ -42,6 +43,7 @@ import classnames from "classnames";
|
||||
type SourcesList = List<Source>;
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
tabSources: SourcesList,
|
||||
selectedSource: Source,
|
||||
source: Source,
|
||||
@ -63,6 +65,7 @@ class Tab extends PureComponent<Props> {
|
||||
|
||||
showContextMenu(e, tab: string) {
|
||||
const {
|
||||
cx,
|
||||
closeTab,
|
||||
closeTabs,
|
||||
tabSources,
|
||||
@ -88,13 +91,13 @@ class Tab extends PureComponent<Props> {
|
||||
{
|
||||
item: {
|
||||
...tabMenuItems.closeTab,
|
||||
click: () => closeTab(sourceTab)
|
||||
click: () => closeTab(cx, sourceTab)
|
||||
}
|
||||
},
|
||||
{
|
||||
item: {
|
||||
...tabMenuItems.closeOtherTabs,
|
||||
click: () => closeTabs(otherTabURLs),
|
||||
click: () => closeTabs(cx, otherTabURLs),
|
||||
disabled: otherTabURLs.length === 0
|
||||
}
|
||||
},
|
||||
@ -103,7 +106,7 @@ class Tab extends PureComponent<Props> {
|
||||
...tabMenuItems.closeTabsToEnd,
|
||||
click: () => {
|
||||
const tabIndex = tabSources.findIndex(t => t.id == tab);
|
||||
closeTabs(tabURLs.filter((t, i) => i > tabIndex));
|
||||
closeTabs(cx, tabURLs.filter((t, i) => i > tabIndex));
|
||||
},
|
||||
disabled:
|
||||
tabCount === 1 ||
|
||||
@ -111,7 +114,10 @@ class Tab extends PureComponent<Props> {
|
||||
}
|
||||
},
|
||||
{
|
||||
item: { ...tabMenuItems.closeAllTabs, click: () => closeTabs(tabURLs) }
|
||||
item: {
|
||||
...tabMenuItems.closeAllTabs,
|
||||
click: () => closeTabs(cx, tabURLs)
|
||||
}
|
||||
},
|
||||
{ item: { type: "separator" } },
|
||||
{
|
||||
@ -132,7 +138,7 @@ class Tab extends PureComponent<Props> {
|
||||
item: {
|
||||
...tabMenuItems.showSource,
|
||||
disabled: !selectedSource.url,
|
||||
click: () => showSource(tab)
|
||||
click: () => showSource(cx, tab)
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -142,13 +148,13 @@ class Tab extends PureComponent<Props> {
|
||||
? L10N.getStr("sourceFooter.unblackbox")
|
||||
: L10N.getStr("sourceFooter.blackbox"),
|
||||
disabled: !shouldBlackbox(source),
|
||||
click: () => toggleBlackBox(source)
|
||||
click: () => toggleBlackBox(cx, source)
|
||||
}
|
||||
},
|
||||
{
|
||||
item: {
|
||||
...tabMenuItems.prettyPrint,
|
||||
click: () => togglePrettyPrint(tab),
|
||||
click: () => togglePrettyPrint(cx, tab),
|
||||
disabled: isPretty(sourceTab)
|
||||
}
|
||||
}
|
||||
@ -167,6 +173,7 @@ class Tab extends PureComponent<Props> {
|
||||
|
||||
render() {
|
||||
const {
|
||||
cx,
|
||||
selectedSource,
|
||||
selectSource,
|
||||
closeTab,
|
||||
@ -183,13 +190,13 @@ class Tab extends PureComponent<Props> {
|
||||
|
||||
function onClickClose(e) {
|
||||
e.stopPropagation();
|
||||
closeTab(source);
|
||||
closeTab(cx, source);
|
||||
}
|
||||
|
||||
function handleTabClick(e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
return selectSource(sourceId);
|
||||
return selectSource(cx, sourceId);
|
||||
}
|
||||
|
||||
const className = classnames("source-tab", {
|
||||
@ -206,7 +213,7 @@ class Tab extends PureComponent<Props> {
|
||||
key={sourceId}
|
||||
onClick={handleTabClick}
|
||||
// Accommodate middle click to close tab
|
||||
onMouseUp={e => e.button === 1 && closeTab(source)}
|
||||
onMouseUp={e => e.button === 1 && closeTab(cx, source)}
|
||||
onContextMenu={e => this.onTabContextMenu(e, sourceId)}
|
||||
title={getFileURL(source, false)}
|
||||
>
|
||||
@ -231,6 +238,7 @@ const mapStateToProps = (state, { source }) => {
|
||||
const selectedSource = getSelectedSource(state);
|
||||
|
||||
return {
|
||||
cx: getContext(state),
|
||||
tabSources: getSourcesForTabs(state),
|
||||
selectedSource: selectedSource,
|
||||
activeSearch: getActiveSearch(state),
|
||||
|
@ -11,7 +11,8 @@ import {
|
||||
getSelectedSource,
|
||||
getSourcesForTabs,
|
||||
getIsPaused,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
import { isVisible } from "../../utils/ui";
|
||||
|
||||
@ -28,11 +29,12 @@ import Dropdown from "../shared/Dropdown";
|
||||
import AccessibleImage from "../shared/AccessibleImage";
|
||||
import CommandBar from "../SecondaryPanes/CommandBar";
|
||||
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
type SourcesList = Source[];
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
tabSources: SourcesList,
|
||||
selectedSource: ?Source,
|
||||
horizontal: boolean,
|
||||
@ -136,10 +138,10 @@ class Tabs extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
renderDropdownSource = (source: Source) => {
|
||||
const { selectSource } = this.props;
|
||||
const { cx, selectSource } = this.props;
|
||||
const filename = getFilename(source);
|
||||
|
||||
const onClick = () => selectSource(source.id);
|
||||
const onClick = () => selectSource(cx, source.id);
|
||||
return (
|
||||
<li key={source.id} onClick={onClick}>
|
||||
<AccessibleImage
|
||||
@ -226,6 +228,7 @@ class Tabs extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getContext(state),
|
||||
selectedSource: getSelectedSource(state),
|
||||
tabSources: getSourcesForTabs(state),
|
||||
isPaused: getIsPaused(state, getCurrentThread(state))
|
||||
|
@ -35,7 +35,8 @@ import {
|
||||
getConditionalPanelLocation,
|
||||
getSymbols,
|
||||
getIsPaused,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
|
||||
// Redux actions
|
||||
@ -79,13 +80,14 @@ import "./Highlight.css";
|
||||
|
||||
import type SourceEditor from "../../utils/editor/source-editor";
|
||||
import type { SymbolDeclarations } from "../../workers/parser";
|
||||
import type { SourceLocation, Source } from "../../types";
|
||||
import type { SourceLocation, Source, ThreadContext } from "../../types";
|
||||
|
||||
const cssVars = {
|
||||
searchbarHeight: "var(--editor-searchbar-height)"
|
||||
};
|
||||
|
||||
export type Props = {
|
||||
cx: ThreadContext,
|
||||
selectedLocation: ?SourceLocation,
|
||||
selectedSource: ?Source,
|
||||
searchOn: boolean,
|
||||
@ -224,11 +226,11 @@ class Editor extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
onClosePress = (key, e: KeyboardEvent) => {
|
||||
const { selectedSource } = this.props;
|
||||
const { cx, selectedSource } = this.props;
|
||||
if (selectedSource) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.closeTab(selectedSource);
|
||||
this.props.closeTab(cx, selectedSource);
|
||||
}
|
||||
};
|
||||
|
||||
@ -272,7 +274,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
return;
|
||||
}
|
||||
|
||||
this.props.toggleBreakpointAtLine(line);
|
||||
this.props.toggleBreakpointAtLine(this.props.cx, line);
|
||||
};
|
||||
|
||||
onToggleConditionalPanel = (key, e: KeyboardEvent) => {
|
||||
@ -326,7 +328,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
onSearchAgain = (_, e: KeyboardEvent) => {
|
||||
this.props.traverseResults(e.shiftKey, this.state.editor);
|
||||
this.props.traverseResults(this.props.cx, e.shiftKey, this.state.editor);
|
||||
};
|
||||
|
||||
openMenu(event: MouseEvent) {
|
||||
@ -334,6 +336,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
event.preventDefault();
|
||||
|
||||
const {
|
||||
cx,
|
||||
selectedSource,
|
||||
breakpointActions,
|
||||
editorActions,
|
||||
@ -356,9 +359,9 @@ class Editor extends PureComponent<Props, State> {
|
||||
|
||||
if (target.classList.contains("CodeMirror-linenumber")) {
|
||||
return showMenu(event, [
|
||||
...createBreakpointItems(location, breakpointActions),
|
||||
...createBreakpointItems(cx, location, breakpointActions),
|
||||
{ type: "separator" },
|
||||
continueToHereItem(location, isPaused, editorActions)
|
||||
continueToHereItem(cx, location, isPaused, editorActions)
|
||||
]);
|
||||
}
|
||||
|
||||
@ -380,6 +383,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
ev: MouseEvent
|
||||
) => {
|
||||
const {
|
||||
cx,
|
||||
selectedSource,
|
||||
conditionalPanelLocation,
|
||||
closeConditionalPanel,
|
||||
@ -411,10 +415,10 @@ class Editor extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
if (ev.metaKey) {
|
||||
return continueToHere(sourceLine);
|
||||
return continueToHere(cx, sourceLine);
|
||||
}
|
||||
|
||||
return addBreakpointAtLine(sourceLine);
|
||||
return addBreakpointAtLine(cx, sourceLine);
|
||||
};
|
||||
|
||||
onGutterContextMenu = (event: MouseEvent) => {
|
||||
@ -422,7 +426,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
};
|
||||
|
||||
onClick(e: MouseEvent) {
|
||||
const { selectedSource, jumpToMappedLocation } = this.props;
|
||||
const { cx, selectedSource, jumpToMappedLocation } = this.props;
|
||||
|
||||
if (selectedSource && e.metaKey && e.altKey) {
|
||||
const sourceLocation = getSourceLocationFromMouseEvent(
|
||||
@ -430,7 +434,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
selectedSource,
|
||||
e
|
||||
);
|
||||
jumpToMappedLocation(sourceLocation);
|
||||
jumpToMappedLocation(cx, sourceLocation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,7 +572,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
}
|
||||
|
||||
renderItems() {
|
||||
const { selectedSource, conditionalPanelLocation } = this.props;
|
||||
const { cx, selectedSource, conditionalPanelLocation } = this.props;
|
||||
const { editor, contextMenu } = this.state;
|
||||
|
||||
if (!selectedSource || !editor || !getDocument(selectedSource.id)) {
|
||||
@ -580,7 +584,7 @@ class Editor extends PureComponent<Props, State> {
|
||||
<DebugLine editor={editor} />
|
||||
<HighlightLine />
|
||||
<EmptyLines editor={editor} />
|
||||
<Breakpoints editor={editor} />
|
||||
<Breakpoints editor={editor} cx={cx} />
|
||||
<Preview editor={editor} editorRef={this.$editorWrapper} />
|
||||
<HighlightLines editor={editor} />
|
||||
{
|
||||
@ -637,6 +641,7 @@ const mapStateToProps = state => {
|
||||
const selectedSource = getSelectedSource(state);
|
||||
|
||||
return {
|
||||
cx: getThreadContext(state),
|
||||
selectedLocation: getSelectedLocation(state),
|
||||
selectedSource,
|
||||
searchOn: getActiveSearch(state) === "file",
|
||||
|
@ -6,10 +6,11 @@
|
||||
|
||||
import actions from "../../../actions";
|
||||
import { bindActionCreators } from "redux";
|
||||
import type { SourceLocation, Breakpoint } from "../../../types";
|
||||
import type { SourceLocation, Breakpoint, Context } from "../../../types";
|
||||
import { features } from "../../../utils/prefs";
|
||||
|
||||
export const addBreakpointItem = (
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) => ({
|
||||
@ -17,11 +18,12 @@ export const addBreakpointItem = (
|
||||
label: L10N.getStr("editor.addBreakpoint"),
|
||||
accesskey: L10N.getStr("shortcuts.toggleBreakpoint.accesskey"),
|
||||
disabled: false,
|
||||
click: () => breakpointActions.addBreakpoint(location),
|
||||
click: () => breakpointActions.addBreakpoint(cx, location),
|
||||
accelerator: L10N.getStr("toggleBreakpoint.key")
|
||||
});
|
||||
|
||||
export const removeBreakpointItem = (
|
||||
cx: Context,
|
||||
breakpoint: Breakpoint,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) => ({
|
||||
@ -29,7 +31,7 @@ export const removeBreakpointItem = (
|
||||
label: L10N.getStr("editor.removeBreakpoint"),
|
||||
accesskey: L10N.getStr("shortcuts.toggleBreakpoint.accesskey"),
|
||||
disabled: false,
|
||||
click: () => breakpointActions.removeBreakpoint(breakpoint),
|
||||
click: () => breakpointActions.removeBreakpoint(cx, breakpoint),
|
||||
accelerator: L10N.getStr("toggleBreakpoint.key")
|
||||
});
|
||||
|
||||
@ -108,13 +110,14 @@ export const logPointItem = (
|
||||
};
|
||||
|
||||
export const toggleDisabledBreakpointItem = (
|
||||
cx: Context,
|
||||
breakpoint: Breakpoint,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) => {
|
||||
return {
|
||||
accesskey: L10N.getStr("editor.disableBreakpoint.accesskey"),
|
||||
disabled: false,
|
||||
click: () => breakpointActions.toggleDisabledBreakpoint(breakpoint),
|
||||
click: () => breakpointActions.toggleDisabledBreakpoint(cx, breakpoint),
|
||||
...(breakpoint.disabled
|
||||
? {
|
||||
id: "node-menu-enable-breakpoint",
|
||||
@ -128,21 +131,30 @@ export const toggleDisabledBreakpointItem = (
|
||||
};
|
||||
|
||||
export function breakpointItems(
|
||||
cx: Context,
|
||||
breakpoint: Breakpoint,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) {
|
||||
const items = [
|
||||
removeBreakpointItem(breakpoint, breakpointActions),
|
||||
toggleDisabledBreakpointItem(breakpoint, breakpointActions)
|
||||
removeBreakpointItem(cx, breakpoint, breakpointActions),
|
||||
toggleDisabledBreakpointItem(cx, breakpoint, breakpointActions)
|
||||
];
|
||||
|
||||
if (features.columnBreakpoints) {
|
||||
items.push(
|
||||
{ type: "separator" },
|
||||
removeBreakpointsOnLineItem(breakpoint.location, breakpointActions),
|
||||
removeBreakpointsOnLineItem(cx, breakpoint.location, breakpointActions),
|
||||
breakpoint.disabled
|
||||
? enableBreakpointsOnLineItem(breakpoint.location, breakpointActions)
|
||||
: disableBreakpointsOnLineItem(breakpoint.location, breakpointActions),
|
||||
? enableBreakpointsOnLineItem(
|
||||
cx,
|
||||
breakpoint.location,
|
||||
breakpointActions
|
||||
)
|
||||
: disableBreakpointsOnLineItem(
|
||||
cx,
|
||||
breakpoint.location,
|
||||
breakpointActions
|
||||
),
|
||||
{ type: "separator" }
|
||||
);
|
||||
}
|
||||
@ -157,11 +169,12 @@ export function breakpointItems(
|
||||
}
|
||||
|
||||
export function createBreakpointItems(
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) {
|
||||
const items = [
|
||||
addBreakpointItem(location, breakpointActions),
|
||||
addBreakpointItem(cx, location, breakpointActions),
|
||||
addConditionalBreakpointItem(location, breakpointActions)
|
||||
];
|
||||
|
||||
@ -173,6 +186,7 @@ export function createBreakpointItems(
|
||||
|
||||
// ToDo: Only enable if there are more than one breakpoints on a line?
|
||||
export const removeBreakpointsOnLineItem = (
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) => ({
|
||||
@ -181,10 +195,15 @@ export const removeBreakpointsOnLineItem = (
|
||||
accesskey: L10N.getStr("breakpointMenuItem.removeAllAtLine.accesskey"),
|
||||
disabled: false,
|
||||
click: () =>
|
||||
breakpointActions.removeBreakpointsAtLine(location.sourceId, location.line)
|
||||
breakpointActions.removeBreakpointsAtLine(
|
||||
cx,
|
||||
location.sourceId,
|
||||
location.line
|
||||
)
|
||||
});
|
||||
|
||||
export const enableBreakpointsOnLineItem = (
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) => ({
|
||||
@ -193,10 +212,15 @@ export const enableBreakpointsOnLineItem = (
|
||||
accesskey: L10N.getStr("breakpointMenuItem.enableAllAtLine.accesskey"),
|
||||
disabled: false,
|
||||
click: () =>
|
||||
breakpointActions.enableBreakpointsAtLine(location.sourceId, location.line)
|
||||
breakpointActions.enableBreakpointsAtLine(
|
||||
cx,
|
||||
location.sourceId,
|
||||
location.line
|
||||
)
|
||||
});
|
||||
|
||||
export const disableBreakpointsOnLineItem = (
|
||||
cx: Context,
|
||||
location: SourceLocation,
|
||||
breakpointActions: BreakpointItemActions
|
||||
) => ({
|
||||
@ -205,7 +229,11 @@ export const disableBreakpointsOnLineItem = (
|
||||
accesskey: L10N.getStr("breakpointMenuItem.disableAllAtLine.accesskey"),
|
||||
disabled: false,
|
||||
click: () =>
|
||||
breakpointActions.disableBreakpointsAtLine(location.sourceId, location.line)
|
||||
breakpointActions.disableBreakpointsAtLine(
|
||||
cx,
|
||||
location.sourceId,
|
||||
location.line
|
||||
)
|
||||
});
|
||||
|
||||
export type BreakpointItemActions = {
|
||||
|
@ -19,20 +19,26 @@ import { downloadFile } from "../../../utils/utils";
|
||||
|
||||
import actions from "../../../actions";
|
||||
|
||||
import type { Source, SourceLocation } from "../../../types";
|
||||
import type {
|
||||
Source,
|
||||
SourceLocation,
|
||||
Context,
|
||||
ThreadContext
|
||||
} from "../../../types";
|
||||
|
||||
function isMapped(selectedSource) {
|
||||
return isOriginalId(selectedSource.id) || !!selectedSource.sourceMapURL;
|
||||
}
|
||||
|
||||
export const continueToHereItem = (
|
||||
cx: ThreadContext,
|
||||
location: SourceLocation,
|
||||
isPaused: boolean,
|
||||
editorActions: EditorItemActions
|
||||
) => ({
|
||||
accesskey: L10N.getStr("editor.continueToHere.accesskey"),
|
||||
disabled: !isPaused,
|
||||
click: () => editorActions.continueToHere(location.line, location.column),
|
||||
click: () => editorActions.continueToHere(cx, location.line, location.column),
|
||||
id: "node-menu-continue-to-here",
|
||||
label: L10N.getStr("editor.continueToHere.label")
|
||||
});
|
||||
@ -85,6 +91,7 @@ const copySourceUri2Item = (
|
||||
});
|
||||
|
||||
const jumpToMappedLocationItem = (
|
||||
cx: Context,
|
||||
selectedSource: Source,
|
||||
location: SourceLocation,
|
||||
hasPrettySource: boolean,
|
||||
@ -100,10 +107,11 @@ const jumpToMappedLocationItem = (
|
||||
accesskey: L10N.getStr("editor.jumpToMappedLocation1.accesskey"),
|
||||
disabled:
|
||||
(!isMapped(selectedSource) && !isPretty(selectedSource)) || hasPrettySource,
|
||||
click: () => editorActions.jumpToMappedLocation(location)
|
||||
click: () => editorActions.jumpToMappedLocation(cx, location)
|
||||
});
|
||||
|
||||
const showSourceMenuItem = (
|
||||
cx: Context,
|
||||
selectedSource: Source,
|
||||
editorActions: EditorItemActions
|
||||
) => ({
|
||||
@ -111,10 +119,11 @@ const showSourceMenuItem = (
|
||||
label: L10N.getStr("sourceTabs.revealInTree"),
|
||||
accesskey: L10N.getStr("sourceTabs.revealInTree.accesskey"),
|
||||
disabled: !selectedSource.url,
|
||||
click: () => editorActions.showSource(selectedSource.id)
|
||||
click: () => editorActions.showSource(cx, selectedSource.id)
|
||||
});
|
||||
|
||||
const blackBoxMenuItem = (
|
||||
cx: Context,
|
||||
selectedSource: Source,
|
||||
editorActions: EditorItemActions
|
||||
) => ({
|
||||
@ -124,10 +133,11 @@ const blackBoxMenuItem = (
|
||||
: L10N.getStr("sourceFooter.blackbox"),
|
||||
accesskey: L10N.getStr("sourceFooter.blackbox.accesskey"),
|
||||
disabled: !shouldBlackbox(selectedSource),
|
||||
click: () => editorActions.toggleBlackBox(selectedSource)
|
||||
click: () => editorActions.toggleBlackBox(cx, selectedSource)
|
||||
});
|
||||
|
||||
const watchExpressionItem = (
|
||||
cx: ThreadContext,
|
||||
selectedSource: Source,
|
||||
selectionText: string,
|
||||
editorActions: EditorItemActions
|
||||
@ -135,7 +145,7 @@ const watchExpressionItem = (
|
||||
id: "node-menu-add-watch-expression",
|
||||
label: L10N.getStr("expressions.label"),
|
||||
accesskey: L10N.getStr("expressions.accesskey"),
|
||||
click: () => editorActions.addExpression(selectionText)
|
||||
click: () => editorActions.addExpression(cx, selectionText)
|
||||
});
|
||||
|
||||
const evaluateInConsoleItem = (
|
||||
@ -161,6 +171,7 @@ const downloadFileItem = (
|
||||
};
|
||||
|
||||
export function editorMenuItems({
|
||||
cx,
|
||||
editorActions,
|
||||
selectedSource,
|
||||
location,
|
||||
@ -169,6 +180,7 @@ export function editorMenuItems({
|
||||
isTextSelected,
|
||||
isPaused
|
||||
}: {
|
||||
cx: ThreadContext,
|
||||
editorActions: EditorItemActions,
|
||||
selectedSource: Source,
|
||||
location: SourceLocation,
|
||||
@ -181,26 +193,27 @@ export function editorMenuItems({
|
||||
|
||||
items.push(
|
||||
jumpToMappedLocationItem(
|
||||
cx,
|
||||
selectedSource,
|
||||
location,
|
||||
hasPrettySource,
|
||||
editorActions
|
||||
),
|
||||
continueToHereItem(location, isPaused, editorActions),
|
||||
continueToHereItem(cx, location, isPaused, editorActions),
|
||||
{ type: "separator" },
|
||||
copyToClipboardItem(selectedSource, editorActions),
|
||||
copySourceItem(selectedSource, selectionText, editorActions),
|
||||
copySourceUri2Item(selectedSource, editorActions),
|
||||
downloadFileItem(selectedSource, editorActions),
|
||||
{ type: "separator" },
|
||||
showSourceMenuItem(selectedSource, editorActions),
|
||||
blackBoxMenuItem(selectedSource, editorActions)
|
||||
showSourceMenuItem(cx, selectedSource, editorActions),
|
||||
blackBoxMenuItem(cx, selectedSource, editorActions)
|
||||
);
|
||||
|
||||
if (isTextSelected) {
|
||||
items.push(
|
||||
{ type: "separator" },
|
||||
watchExpressionItem(selectedSource, selectionText, editorActions),
|
||||
watchExpressionItem(cx, selectedSource, selectionText, editorActions),
|
||||
evaluateInConsoleItem(selectedSource, selectionText, editorActions)
|
||||
);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ describe("doSearch", () => {
|
||||
.find("SearchInput")
|
||||
.simulate("change", { target: { value: "query" } });
|
||||
|
||||
const doSearchArgs = props.doSearch.mock.calls[0][0];
|
||||
const doSearchArgs = props.doSearch.mock.calls[0][1];
|
||||
expect(doSearchArgs).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
@ -16,7 +16,8 @@ import actions from "../../actions";
|
||||
import {
|
||||
getSelectedSource,
|
||||
getSymbols,
|
||||
getSelectedLocation
|
||||
getSelectedLocation,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
|
||||
import OutlineFilter from "./OutlineFilter";
|
||||
@ -30,9 +31,10 @@ import type {
|
||||
SymbolDeclaration,
|
||||
FunctionDeclaration
|
||||
} from "../../workers/parser";
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
symbols: SymbolDeclarations,
|
||||
selectedSource: ?Source,
|
||||
alphabetizeOutline: boolean,
|
||||
@ -72,12 +74,12 @@ export class Outline extends Component<Props, State> {
|
||||
}
|
||||
|
||||
selectItem(location: AstLocation) {
|
||||
const { selectedSource, selectLocation } = this.props;
|
||||
const { cx, selectedSource, selectLocation } = this.props;
|
||||
if (!selectedSource) {
|
||||
return;
|
||||
}
|
||||
|
||||
selectLocation({
|
||||
selectLocation(cx, {
|
||||
sourceId: selectedSource.id,
|
||||
line: location.start.line,
|
||||
column: location.start.column
|
||||
@ -264,6 +266,7 @@ const mapStateToProps = state => {
|
||||
const symbols = selectedSource ? getSymbols(state, selectedSource) : null;
|
||||
|
||||
return {
|
||||
cx: getContext(state),
|
||||
symbols,
|
||||
selectedSource,
|
||||
selectedLocation: getSelectedLocation(state),
|
||||
|
@ -19,7 +19,8 @@ import {
|
||||
getDisplayedSourcesForThread,
|
||||
getFocusedSourceItem,
|
||||
getWorkerByThread,
|
||||
getWorkerCount
|
||||
getWorkerCount,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
|
||||
import { getGeneratedSourceByURL } from "../../reducers/sources";
|
||||
@ -51,11 +52,12 @@ import type {
|
||||
TreeDirectory,
|
||||
ParentMap
|
||||
} from "../../utils/sources-tree/types";
|
||||
import type { Worker, Source } from "../../types";
|
||||
import type { Worker, Source, Context } from "../../types";
|
||||
import type { SourcesMap, State as AppState } from "../../reducers/types";
|
||||
import type { Item } from "../shared/ManagedTree";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
thread: string,
|
||||
worker: Worker,
|
||||
sources: SourcesMap,
|
||||
@ -156,12 +158,12 @@ class SourcesTree extends Component<Props, State> {
|
||||
|
||||
selectItem = (item: TreeNode) => {
|
||||
if (item.type == "source" && !Array.isArray(item.contents)) {
|
||||
this.props.selectSource(item.contents.id);
|
||||
this.props.selectSource(this.props.cx, item.contents.id);
|
||||
}
|
||||
};
|
||||
|
||||
onFocus = (item: TreeNode) => {
|
||||
this.props.focusItem({ thread: this.props.thread, item });
|
||||
this.props.focusItem(this.props.cx, { thread: this.props.thread, item });
|
||||
};
|
||||
|
||||
onActivate = (item: TreeNode) => {
|
||||
@ -371,6 +373,7 @@ const mapStateToProps = (state, props) => {
|
||||
const displayedSources = getDisplayedSourcesForThread(state, thread);
|
||||
|
||||
return {
|
||||
cx: getContext(state),
|
||||
shownSource: getSourceForTree(state, displayedSources, shownSource, thread),
|
||||
selectedSource: getSourceForTree(
|
||||
state,
|
||||
|
@ -15,7 +15,8 @@ import AccessibleImage from "../shared/AccessibleImage";
|
||||
import {
|
||||
getGeneratedSourceByURL,
|
||||
getHasSiblingOfSameName,
|
||||
hasPrettySource as checkHasPrettySource
|
||||
hasPrettySource as checkHasPrettySource,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
import actions from "../../actions";
|
||||
|
||||
@ -30,9 +31,10 @@ import { copyToTheClipboard } from "../../utils/clipboard";
|
||||
import { features } from "../../utils/prefs";
|
||||
|
||||
import type { TreeNode } from "../../utils/sources-tree/types";
|
||||
import type { Source } from "../../types";
|
||||
import type { Source, Context } from "../../types";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
debuggeeUrl: string,
|
||||
projectRoot: string,
|
||||
source: ?Source,
|
||||
@ -134,7 +136,7 @@ class SourceTreeItem extends Component<Props, State> {
|
||||
click: () => copyToTheClipboard(contents.url)
|
||||
};
|
||||
|
||||
const { source } = this.props;
|
||||
const { cx, source } = this.props;
|
||||
if (source) {
|
||||
const blackBoxMenuItem = {
|
||||
id: "node-menu-blackbox",
|
||||
@ -143,7 +145,7 @@ class SourceTreeItem extends Component<Props, State> {
|
||||
: L10N.getStr("sourceFooter.blackbox"),
|
||||
accesskey: L10N.getStr("sourceFooter.blackbox.accesskey"),
|
||||
disabled: !shouldBlackbox(source),
|
||||
click: () => this.props.toggleBlackBox(source)
|
||||
click: () => this.props.toggleBlackBox(cx, source)
|
||||
};
|
||||
menuOptions.push(copySourceUri2, blackBoxMenuItem);
|
||||
}
|
||||
@ -155,14 +157,14 @@ class SourceTreeItem extends Component<Props, State> {
|
||||
|
||||
if (features.root) {
|
||||
const { path } = item;
|
||||
const { projectRoot } = this.props;
|
||||
const { cx, projectRoot } = this.props;
|
||||
|
||||
if (projectRoot.endsWith(path)) {
|
||||
menuOptions.push({
|
||||
id: "node-remove-directory-root",
|
||||
label: removeDirectoryRootLabel,
|
||||
disabled: false,
|
||||
click: () => this.props.clearProjectDirectoryRoot()
|
||||
click: () => this.props.clearProjectDirectoryRoot(cx)
|
||||
});
|
||||
} else {
|
||||
menuOptions.push({
|
||||
@ -170,7 +172,7 @@ class SourceTreeItem extends Component<Props, State> {
|
||||
label: setDirectoryRootLabel,
|
||||
accesskey: setDirectoryRootKey,
|
||||
disabled: false,
|
||||
click: () => this.props.setProjectDirectoryRoot(path)
|
||||
click: () => this.props.setProjectDirectoryRoot(cx, path)
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -273,6 +275,7 @@ function getHasMatchingGeneratedSource(state, source: ?Source) {
|
||||
const mapStateToProps = (state, props) => {
|
||||
const { source } = props;
|
||||
return {
|
||||
cx: getContext(state),
|
||||
hasMatchingGeneratedSource: getHasMatchingGeneratedSource(state, source),
|
||||
hasSiblingOfSameName: getHasSiblingOfSameName(state, source),
|
||||
hasPrettySource: source ? checkHasPrettySource(state, source.id) : false
|
||||
|
@ -14,7 +14,8 @@ import {
|
||||
getActiveSearch,
|
||||
getProjectDirectoryRoot,
|
||||
getSelectedPrimaryPaneTab,
|
||||
getThreads
|
||||
getThreads,
|
||||
getContext
|
||||
} from "../../selectors";
|
||||
import { features, prefs } from "../../utils/prefs";
|
||||
import { connect } from "../../utils/connect";
|
||||
@ -26,7 +27,7 @@ import AccessibleImage from "../shared/AccessibleImage";
|
||||
|
||||
import type { SourcesMapByThread } from "../../reducers/types";
|
||||
import type { SelectedPrimaryPaneTabType } from "../../selectors";
|
||||
import type { Thread } from "../../types";
|
||||
import type { Thread, Context } from "../../types";
|
||||
|
||||
import "./Sources.css";
|
||||
|
||||
@ -35,6 +36,7 @@ type State = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
selectedTab: SelectedPrimaryPaneTabType,
|
||||
sources: SourcesMapByThread,
|
||||
horizontal: boolean,
|
||||
@ -101,7 +103,7 @@ class PrimaryPanes extends Component<Props, State> {
|
||||
}
|
||||
|
||||
renderProjectRootHeader() {
|
||||
const { projectRoot } = this.props;
|
||||
const { cx, projectRoot } = this.props;
|
||||
|
||||
if (!projectRoot) {
|
||||
return null;
|
||||
@ -113,7 +115,7 @@ class PrimaryPanes extends Component<Props, State> {
|
||||
<div key="root" className="sources-clear-root-container">
|
||||
<button
|
||||
className="sources-clear-root"
|
||||
onClick={() => this.props.clearProjectDirectoryRoot()}
|
||||
onClick={() => this.props.clearProjectDirectoryRoot(cx)}
|
||||
title={L10N.getStr("removeDirectoryRoot.label")}
|
||||
>
|
||||
<AccessibleImage className="home" />
|
||||
@ -164,6 +166,7 @@ class PrimaryPanes extends Component<Props, State> {
|
||||
}
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getContext(state),
|
||||
selectedTab: getSelectedPrimaryPaneTab(state),
|
||||
sources: getDisplayedSources(state),
|
||||
sourceSearchOn: getActiveSearch(state) === "source",
|
||||
|
@ -9,7 +9,7 @@ import { shallow } from "enzyme";
|
||||
import { showMenu } from "devtools-contextmenu";
|
||||
|
||||
import SourcesTree from "../SourcesTree";
|
||||
import { makeMockSource } from "../../../utils/test-mockup";
|
||||
import { makeMockSource, mockcx } from "../../../utils/test-mockup";
|
||||
import { copyToTheClipboard } from "../../../utils/clipboard";
|
||||
|
||||
jest.mock("devtools-contextmenu", () => ({ showMenu: jest.fn() }));
|
||||
@ -194,6 +194,7 @@ describe("SourcesTree", () => {
|
||||
instance.onActivate(item);
|
||||
expect(spy).toHaveBeenCalledWith(item);
|
||||
expect(props.selectSource).toHaveBeenCalledWith(
|
||||
mockcx,
|
||||
"server1.conn13.child1/39"
|
||||
);
|
||||
});
|
||||
@ -204,6 +205,7 @@ describe("SourcesTree", () => {
|
||||
const { instance, props } = render();
|
||||
instance.selectItem(createMockItem());
|
||||
expect(props.selectSource).toHaveBeenCalledWith(
|
||||
mockcx,
|
||||
"server1.conn13.child1/39"
|
||||
);
|
||||
});
|
||||
@ -357,6 +359,7 @@ function generateDefaults(overrides: Object) {
|
||||
)
|
||||
};
|
||||
return {
|
||||
cx: mockcx,
|
||||
thread: "FakeThread",
|
||||
autoExpandAll: true,
|
||||
selectSource: jest.fn(),
|
||||
|
@ -19,7 +19,8 @@ import {
|
||||
getActiveSearch,
|
||||
getTextSearchResults,
|
||||
getTextSearchStatus,
|
||||
getTextSearchQuery
|
||||
getTextSearchQuery,
|
||||
getContext
|
||||
} from "../selectors";
|
||||
|
||||
import ManagedTree from "./shared/ManagedTree";
|
||||
@ -29,6 +30,7 @@ import AccessibleImage from "./shared/AccessibleImage";
|
||||
import type { List } from "immutable";
|
||||
import type { ActiveSearchType } from "../reducers/types";
|
||||
import type { StatusType } from "../reducers/project-text-search";
|
||||
import type { Context } from "../types";
|
||||
|
||||
import "./ProjectSearch.css";
|
||||
|
||||
@ -59,6 +61,7 @@ type State = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
query: string,
|
||||
results: List<Result>,
|
||||
status: StatusType,
|
||||
@ -119,17 +122,17 @@ export class ProjectSearch extends Component<Props, State> {
|
||||
}
|
||||
|
||||
doSearch(searchTerm: string) {
|
||||
this.props.searchSources(searchTerm);
|
||||
this.props.searchSources(this.props.cx, searchTerm);
|
||||
}
|
||||
|
||||
toggleProjectTextSearch = (key: string, e: KeyboardEvent) => {
|
||||
const { closeProjectSearch, setActiveSearch } = this.props;
|
||||
const { cx, closeProjectSearch, setActiveSearch } = this.props;
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
if (this.isProjectSearchEnabled()) {
|
||||
return closeProjectSearch();
|
||||
return closeProjectSearch(cx);
|
||||
}
|
||||
|
||||
return setActiveSearch("project");
|
||||
@ -138,7 +141,7 @@ export class ProjectSearch extends Component<Props, State> {
|
||||
isProjectSearchEnabled = () => this.props.activeSearch === "project";
|
||||
|
||||
selectMatchItem = (matchItem: Match) => {
|
||||
this.props.selectSpecificLocation({
|
||||
this.props.selectSpecificLocation(this.props.cx, {
|
||||
sourceId: matchItem.sourceId,
|
||||
line: matchItem.line,
|
||||
column: matchItem.column
|
||||
@ -196,10 +199,10 @@ export class ProjectSearch extends Component<Props, State> {
|
||||
|
||||
inputOnChange = (e: SyntheticInputEvent<HTMLInputElement>) => {
|
||||
const inputValue = e.target.value;
|
||||
const { clearSearch } = this.props;
|
||||
const { cx, clearSearch } = this.props;
|
||||
this.setState({ inputValue });
|
||||
if (inputValue === "") {
|
||||
clearSearch();
|
||||
clearSearch(cx);
|
||||
}
|
||||
};
|
||||
|
||||
@ -331,6 +334,7 @@ ProjectSearch.contextTypes = {
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getContext(state),
|
||||
activeSearch: getActiveSearch(state),
|
||||
results: getTextSearchResults(state),
|
||||
query: getTextSearchQuery(state),
|
||||
|
@ -17,7 +17,8 @@ import {
|
||||
getSelectedSource,
|
||||
getSymbols,
|
||||
getTabs,
|
||||
isSymbolsLoading
|
||||
isSymbolsLoading,
|
||||
getContext
|
||||
} from "../selectors";
|
||||
import { scrollList } from "../utils/result-list";
|
||||
import {
|
||||
@ -35,13 +36,14 @@ import type {
|
||||
QuickOpenResult
|
||||
} from "../utils/quick-open";
|
||||
|
||||
import type { Source } from "../types";
|
||||
import type { Source, Context } from "../types";
|
||||
import type { QuickOpenType } from "../reducers/quick-open";
|
||||
import type { Tab } from "../reducers/tabs";
|
||||
|
||||
import "./QuickOpenModal.css";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
enabled: boolean,
|
||||
sources: Array<Object>,
|
||||
selectedSource?: Source,
|
||||
@ -245,11 +247,11 @@ export class QuickOpenModal extends Component<Props, State> {
|
||||
};
|
||||
|
||||
gotoLocation = (location: ?GotoLocationType) => {
|
||||
const { selectSpecificLocation, selectedSource } = this.props;
|
||||
const { cx, selectSpecificLocation, selectedSource } = this.props;
|
||||
const selectedSourceId = selectedSource ? selectedSource.id : "";
|
||||
if (location != null) {
|
||||
const sourceId = location.sourceId ? location.sourceId : selectedSourceId;
|
||||
selectSpecificLocation({
|
||||
selectSpecificLocation(cx, {
|
||||
sourceId,
|
||||
line: location.line,
|
||||
column: location.column
|
||||
@ -419,6 +421,7 @@ function mapStateToProps(state) {
|
||||
const selectedSource = getSelectedSource(state);
|
||||
|
||||
return {
|
||||
cx: getContext(state),
|
||||
enabled: getQuickOpenEnabled(state),
|
||||
sources: formatSources(getDisplayedSourcesList(state), getTabs(state)),
|
||||
selectedSource,
|
||||
|
@ -27,7 +27,8 @@ import type {
|
||||
Breakpoint as BreakpointType,
|
||||
Frame,
|
||||
Source,
|
||||
SourceLocation
|
||||
SourceLocation,
|
||||
Context
|
||||
} from "../../../types";
|
||||
|
||||
type FormattedFrame = Frame & {
|
||||
@ -38,10 +39,12 @@ import {
|
||||
getBreakpointsList,
|
||||
getSelectedFrame,
|
||||
getSelectedSource,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getContext
|
||||
} from "../../../selectors";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
breakpoint: BreakpointType,
|
||||
breakpoints: BreakpointType[],
|
||||
selectedSource: Source,
|
||||
@ -79,22 +82,22 @@ class Breakpoint extends PureComponent<Props> {
|
||||
|
||||
selectBreakpoint = event => {
|
||||
event.preventDefault();
|
||||
const { selectSpecificLocation } = this.props;
|
||||
selectSpecificLocation(this.selectedLocation);
|
||||
const { cx, selectSpecificLocation } = this.props;
|
||||
selectSpecificLocation(cx, this.selectedLocation);
|
||||
};
|
||||
|
||||
removeBreakpoint = event => {
|
||||
const { removeBreakpoint, breakpoint } = this.props;
|
||||
const { cx, removeBreakpoint, breakpoint } = this.props;
|
||||
event.stopPropagation();
|
||||
removeBreakpoint(breakpoint);
|
||||
removeBreakpoint(cx, breakpoint);
|
||||
};
|
||||
|
||||
handleBreakpointCheckbox = () => {
|
||||
const { breakpoint, enableBreakpoint, disableBreakpoint } = this.props;
|
||||
const { cx, breakpoint, enableBreakpoint, disableBreakpoint } = this.props;
|
||||
if (breakpoint.disabled) {
|
||||
enableBreakpoint(breakpoint);
|
||||
enableBreakpoint(cx, breakpoint);
|
||||
} else {
|
||||
disableBreakpoint(breakpoint);
|
||||
disableBreakpoint(cx, breakpoint);
|
||||
}
|
||||
};
|
||||
|
||||
@ -211,6 +214,7 @@ const getFormattedFrame = createSelector(
|
||||
);
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getContext(state),
|
||||
breakpoints: getBreakpointsList(state),
|
||||
frame: getFormattedFrame(state, getCurrentThread(state))
|
||||
});
|
||||
|
@ -14,15 +14,17 @@ import {
|
||||
} from "../../../utils/source";
|
||||
import {
|
||||
getHasSiblingOfSameName,
|
||||
getBreakpointsForSource
|
||||
getBreakpointsForSource,
|
||||
getContext
|
||||
} from "../../../selectors";
|
||||
|
||||
import SourceIcon from "../../shared/SourceIcon";
|
||||
|
||||
import type { Source, Breakpoint } from "../../../types";
|
||||
import type { Source, Breakpoint, Context } from "../../../types";
|
||||
import showContextMenu from "./BreakpointHeadingsContextMenu";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
sources: Source[],
|
||||
source: Source,
|
||||
hasSiblingOfSameName: boolean,
|
||||
@ -39,7 +41,13 @@ class BreakpointHeading extends PureComponent<Props> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { sources, source, hasSiblingOfSameName, selectSource } = this.props;
|
||||
const {
|
||||
cx,
|
||||
sources,
|
||||
source,
|
||||
hasSiblingOfSameName,
|
||||
selectSource
|
||||
} = this.props;
|
||||
|
||||
const path = getDisplayPath(source, sources);
|
||||
const query = hasSiblingOfSameName ? getSourceQueryString(source) : "";
|
||||
@ -48,7 +56,7 @@ class BreakpointHeading extends PureComponent<Props> {
|
||||
<div
|
||||
className="breakpoint-heading"
|
||||
title={getFileURL(source, false)}
|
||||
onClick={() => selectSource(source.id)}
|
||||
onClick={() => selectSource(cx, source.id)}
|
||||
onContextMenu={this.onContextMenu}
|
||||
>
|
||||
<SourceIcon
|
||||
@ -65,6 +73,7 @@ class BreakpointHeading extends PureComponent<Props> {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, { source }) => ({
|
||||
cx: getContext(state),
|
||||
hasSiblingOfSameName: getHasSiblingOfSameName(state, source),
|
||||
breakpointsForSource: getBreakpointsForSource(state, source.id)
|
||||
});
|
||||
|
@ -7,9 +7,10 @@
|
||||
import { buildMenu, showMenu } from "devtools-contextmenu";
|
||||
|
||||
import actions from "../../../actions";
|
||||
import type { Breakpoint, Source } from "../../../types";
|
||||
import type { Breakpoint, Source, Context } from "../../../types";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
source: Source,
|
||||
breakpointsForSource: Breakpoint[],
|
||||
disableBreakpointsInSource: typeof actions.disableBreakpointsInSource,
|
||||
@ -20,6 +21,7 @@ type Props = {
|
||||
|
||||
export default function showContextMenu(props: Props) {
|
||||
const {
|
||||
cx,
|
||||
source,
|
||||
breakpointsForSource,
|
||||
disableBreakpointsInSource,
|
||||
@ -54,7 +56,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: disableInSourceLabel,
|
||||
accesskey: disableInSourceKey,
|
||||
disabled: false,
|
||||
click: () => disableBreakpointsInSource(source)
|
||||
click: () => disableBreakpointsInSource(cx, source)
|
||||
};
|
||||
|
||||
const enableInSourceItem = {
|
||||
@ -62,7 +64,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: enableInSourceLabel,
|
||||
accesskey: enableInSourceKey,
|
||||
disabled: false,
|
||||
click: () => enableBreakpointsInSource(source)
|
||||
click: () => enableBreakpointsInSource(cx, source)
|
||||
};
|
||||
|
||||
const removeInSourceItem = {
|
||||
@ -70,7 +72,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: removeInSourceLabel,
|
||||
accesskey: removeInSourceKey,
|
||||
disabled: false,
|
||||
click: () => removeBreakpointsInSource(source)
|
||||
click: () => removeBreakpointsInSource(cx, source)
|
||||
};
|
||||
|
||||
const hideDisableInSourceItem = breakpointsForSource.every(
|
||||
|
@ -9,9 +9,10 @@ import { getSelectedLocation } from "../../../utils/source-maps";
|
||||
import actions from "../../../actions";
|
||||
import { features } from "../../../utils/prefs";
|
||||
|
||||
import type { Breakpoint, Source } from "../../../types";
|
||||
import type { Breakpoint, Source, Context } from "../../../types";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
breakpoint: Breakpoint,
|
||||
breakpoints: Breakpoint[],
|
||||
selectedSource: Source,
|
||||
@ -29,6 +30,7 @@ type Props = {
|
||||
|
||||
export default function showContextMenu(props: Props) {
|
||||
const {
|
||||
cx,
|
||||
breakpoint,
|
||||
breakpoints,
|
||||
selectedSource,
|
||||
@ -115,7 +117,7 @@ export default function showContextMenu(props: Props) {
|
||||
accesskey: deleteSelfKey,
|
||||
disabled: false,
|
||||
click: () => {
|
||||
removeBreakpoint(breakpoint);
|
||||
removeBreakpoint(cx, breakpoint);
|
||||
}
|
||||
};
|
||||
|
||||
@ -124,7 +126,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: deleteAllLabel,
|
||||
accesskey: deleteAllKey,
|
||||
disabled: false,
|
||||
click: () => removeAllBreakpoints()
|
||||
click: () => removeAllBreakpoints(cx)
|
||||
};
|
||||
|
||||
const deleteOthersItem = {
|
||||
@ -132,7 +134,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: deleteOthersLabel,
|
||||
accesskey: deleteOthersKey,
|
||||
disabled: false,
|
||||
click: () => removeBreakpoints(otherBreakpoints)
|
||||
click: () => removeBreakpoints(cx, otherBreakpoints)
|
||||
};
|
||||
|
||||
const enableSelfItem = {
|
||||
@ -141,7 +143,7 @@ export default function showContextMenu(props: Props) {
|
||||
accesskey: enableSelfKey,
|
||||
disabled: false,
|
||||
click: () => {
|
||||
toggleDisabledBreakpoint(breakpoint);
|
||||
toggleDisabledBreakpoint(cx, breakpoint);
|
||||
}
|
||||
};
|
||||
|
||||
@ -150,7 +152,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: enableAllLabel,
|
||||
accesskey: enableAllKey,
|
||||
disabled: false,
|
||||
click: () => toggleAllBreakpoints(false)
|
||||
click: () => toggleAllBreakpoints(cx, false)
|
||||
};
|
||||
|
||||
const enableOthersItem = {
|
||||
@ -158,7 +160,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: enableOthersLabel,
|
||||
accesskey: enableOthersKey,
|
||||
disabled: false,
|
||||
click: () => toggleBreakpoints(false, otherDisabledBreakpoints)
|
||||
click: () => toggleBreakpoints(cx, false, otherDisabledBreakpoints)
|
||||
};
|
||||
|
||||
const disableSelfItem = {
|
||||
@ -167,7 +169,7 @@ export default function showContextMenu(props: Props) {
|
||||
accesskey: disableSelfKey,
|
||||
disabled: false,
|
||||
click: () => {
|
||||
toggleDisabledBreakpoint(breakpoint);
|
||||
toggleDisabledBreakpoint(cx, breakpoint);
|
||||
}
|
||||
};
|
||||
|
||||
@ -176,14 +178,14 @@ export default function showContextMenu(props: Props) {
|
||||
label: disableAllLabel,
|
||||
accesskey: disableAllKey,
|
||||
disabled: false,
|
||||
click: () => toggleAllBreakpoints(true)
|
||||
click: () => toggleAllBreakpoints(cx, true)
|
||||
};
|
||||
|
||||
const disableOthersItem = {
|
||||
id: "node-menu-disable-others",
|
||||
label: disableOthersLabel,
|
||||
accesskey: disableOthersKey,
|
||||
click: () => toggleBreakpoints(true, otherEnabledBreakpoints)
|
||||
click: () => toggleBreakpoints(cx, true, otherEnabledBreakpoints)
|
||||
};
|
||||
|
||||
const removeConditionItem = {
|
||||
@ -192,7 +194,7 @@ export default function showContextMenu(props: Props) {
|
||||
accesskey: removeConditionKey,
|
||||
disabled: false,
|
||||
click: () =>
|
||||
setBreakpointOptions(selectedLocation, {
|
||||
setBreakpointOptions(cx, selectedLocation, {
|
||||
...breakpoint.options,
|
||||
condition: null
|
||||
})
|
||||
@ -203,7 +205,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: addConditionLabel,
|
||||
accesskey: addConditionKey,
|
||||
click: () => {
|
||||
selectSpecificLocation(selectedLocation);
|
||||
selectSpecificLocation(cx, selectedLocation);
|
||||
openConditionalPanel(selectedLocation);
|
||||
},
|
||||
accelerator: L10N.getStr("toggleCondPanel.breakpoint.key")
|
||||
@ -214,7 +216,7 @@ export default function showContextMenu(props: Props) {
|
||||
label: editConditionLabel,
|
||||
accesskey: editConditionKey,
|
||||
click: () => {
|
||||
selectSpecificLocation(selectedLocation);
|
||||
selectSpecificLocation(cx, selectedLocation);
|
||||
openConditionalPanel(selectedLocation);
|
||||
},
|
||||
accelerator: L10N.getStr("toggleCondPanel.breakpoint.key")
|
||||
@ -244,7 +246,7 @@ export default function showContextMenu(props: Props) {
|
||||
accesskey: L10N.getStr("editor.removeLogPoint.accesskey"),
|
||||
disabled: false,
|
||||
click: () =>
|
||||
setBreakpointOptions(selectedLocation, {
|
||||
setBreakpointOptions(cx, selectedLocation, {
|
||||
...breakpoint.options,
|
||||
logValue: null
|
||||
})
|
||||
|
@ -12,7 +12,8 @@ import { buildMenu } from "devtools-contextmenu";
|
||||
|
||||
import {
|
||||
makeMockBreakpoint,
|
||||
makeMockSource
|
||||
makeMockSource,
|
||||
mockcx
|
||||
} from "../../../../utils/test-mockup";
|
||||
|
||||
jest.mock("devtools-contextmenu");
|
||||
@ -55,6 +56,7 @@ function generateDefaults(disabled) {
|
||||
];
|
||||
|
||||
const props = {
|
||||
cx: mockcx,
|
||||
breakpoints,
|
||||
breakpoint: breakpoints[0],
|
||||
removeBreakpoint: jest.fn(),
|
||||
@ -90,7 +92,7 @@ describe("BreakpointsContextMenu", () => {
|
||||
expect(props.removeBreakpoints).toHaveBeenCalled();
|
||||
|
||||
const otherBreakpoints = [props.breakpoints[1], props.breakpoints[2]];
|
||||
expect(props.removeBreakpoints.mock.calls[0][0]).toEqual(
|
||||
expect(props.removeBreakpoints.mock.calls[0][1]).toEqual(
|
||||
otherBreakpoints
|
||||
);
|
||||
});
|
||||
@ -105,10 +107,10 @@ describe("BreakpointsContextMenu", () => {
|
||||
|
||||
expect(props.toggleBreakpoints).toHaveBeenCalled();
|
||||
|
||||
expect(props.toggleBreakpoints.mock.calls[0][0]).toBe(false);
|
||||
expect(props.toggleBreakpoints.mock.calls[0][1]).toBe(false);
|
||||
|
||||
const otherBreakpoints = [props.breakpoints[1], props.breakpoints[2]];
|
||||
expect(props.toggleBreakpoints.mock.calls[0][1]).toEqual(
|
||||
expect(props.toggleBreakpoints.mock.calls[0][2]).toEqual(
|
||||
otherBreakpoints
|
||||
);
|
||||
});
|
||||
@ -122,10 +124,10 @@ describe("BreakpointsContextMenu", () => {
|
||||
disableOthers.item.click();
|
||||
|
||||
expect(props.toggleBreakpoints).toHaveBeenCalled();
|
||||
expect(props.toggleBreakpoints.mock.calls[0][0]).toBe(true);
|
||||
expect(props.toggleBreakpoints.mock.calls[0][1]).toBe(true);
|
||||
|
||||
const otherBreakpoints = [props.breakpoints[1], props.breakpoints[2]];
|
||||
expect(props.toggleBreakpoints.mock.calls[0][1]).toEqual(
|
||||
expect(props.toggleBreakpoints.mock.calls[0][2]).toEqual(
|
||||
otherBreakpoints
|
||||
);
|
||||
});
|
||||
|
@ -12,11 +12,11 @@ import { connect } from "../../utils/connect";
|
||||
import classnames from "classnames";
|
||||
import { features } from "../../utils/prefs";
|
||||
import {
|
||||
getIsPaused,
|
||||
getIsWaitingOnBreak,
|
||||
getCanRewind,
|
||||
getSkipPausing,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
import { formatKeyShortcut } from "../../utils/text";
|
||||
import actions from "../../actions";
|
||||
@ -25,6 +25,7 @@ import AccessibleImage from "../shared/AccessibleImage";
|
||||
import "./CommandBar.css";
|
||||
|
||||
import { appinfo } from "devtools-services";
|
||||
import type { ThreadContext } from "../../types";
|
||||
|
||||
const isMacOS = appinfo.OS === "Darwin";
|
||||
|
||||
@ -75,7 +76,7 @@ function formatKey(action) {
|
||||
}
|
||||
|
||||
type Props = {
|
||||
isPaused: boolean,
|
||||
cx: ThreadContext,
|
||||
isWaitingOnBreak: boolean,
|
||||
horizontal: boolean,
|
||||
canRewind: boolean,
|
||||
@ -121,41 +122,44 @@ class CommandBar extends Component<Props> {
|
||||
}
|
||||
|
||||
handleEvent(e, action) {
|
||||
const { cx } = this.props;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (action === "resume") {
|
||||
this.props.isPaused ? this.props.resume() : this.props.breakOnNext();
|
||||
this.props.cx.isPaused
|
||||
? this.props.resume(cx)
|
||||
: this.props.breakOnNext(cx);
|
||||
} else {
|
||||
this.props[action]();
|
||||
this.props[action](cx);
|
||||
}
|
||||
}
|
||||
|
||||
renderStepButtons() {
|
||||
const { isPaused, canRewind } = this.props;
|
||||
const className = isPaused ? "active" : "disabled";
|
||||
const isDisabled = !isPaused;
|
||||
const { cx, canRewind } = this.props;
|
||||
const className = cx.isPaused ? "active" : "disabled";
|
||||
const isDisabled = !cx.isPaused;
|
||||
|
||||
if (canRewind || (!isPaused && features.removeCommandBarOptions)) {
|
||||
if (canRewind || (!cx.isPaused && features.removeCommandBarOptions)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [
|
||||
debugBtn(
|
||||
this.props.stepOver,
|
||||
() => this.props.stepOver(cx),
|
||||
"stepOver",
|
||||
className,
|
||||
L10N.getFormatStr("stepOverTooltip", formatKey("stepOver")),
|
||||
isDisabled
|
||||
),
|
||||
debugBtn(
|
||||
this.props.stepIn,
|
||||
() => this.props.stepIn(cx),
|
||||
"stepIn",
|
||||
className,
|
||||
L10N.getFormatStr("stepInTooltip", formatKey("stepIn")),
|
||||
isDisabled
|
||||
),
|
||||
debugBtn(
|
||||
this.props.stepOut,
|
||||
() => this.props.stepOut(cx),
|
||||
"stepOut",
|
||||
className,
|
||||
L10N.getFormatStr("stepOutTooltip", formatKey("stepOut")),
|
||||
@ -165,13 +169,13 @@ class CommandBar extends Component<Props> {
|
||||
}
|
||||
|
||||
resume() {
|
||||
this.props.resume();
|
||||
this.props.resume(this.props.cx);
|
||||
}
|
||||
|
||||
renderPauseButton() {
|
||||
const { isPaused, breakOnNext, isWaitingOnBreak, canRewind } = this.props;
|
||||
const { cx, breakOnNext, isWaitingOnBreak, canRewind } = this.props;
|
||||
|
||||
if (isPaused) {
|
||||
if (cx.isPaused) {
|
||||
if (canRewind) {
|
||||
return null;
|
||||
}
|
||||
@ -198,7 +202,7 @@ class CommandBar extends Component<Props> {
|
||||
}
|
||||
|
||||
return debugBtn(
|
||||
breakOnNext,
|
||||
() => breakOnNext(cx),
|
||||
"pause",
|
||||
"active",
|
||||
L10N.getFormatStr("pauseButtonTooltip", formatKey("resume"))
|
||||
@ -206,32 +210,37 @@ class CommandBar extends Component<Props> {
|
||||
}
|
||||
|
||||
renderTimeTravelButtons() {
|
||||
const { isPaused, canRewind } = this.props;
|
||||
const { cx, canRewind } = this.props;
|
||||
|
||||
if (!canRewind || !isPaused) {
|
||||
if (!canRewind || !cx.isPaused) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const isDisabled = !isPaused;
|
||||
const isDisabled = !cx.isPaused;
|
||||
|
||||
return [
|
||||
debugBtn(this.props.rewind, "rewind", "active", "Rewind Execution"),
|
||||
debugBtn(
|
||||
() => this.props.rewind(cx),
|
||||
"rewind",
|
||||
"active",
|
||||
"Rewind Execution"
|
||||
),
|
||||
|
||||
debugBtn(
|
||||
this.props.resume,
|
||||
() => this.props.resume(cx),
|
||||
"resume",
|
||||
"active",
|
||||
L10N.getFormatStr("resumeButtonTooltip", formatKey("resume"))
|
||||
),
|
||||
<div key="divider-1" className="divider" />,
|
||||
debugBtn(
|
||||
this.props.reverseStepOver,
|
||||
() => this.props.reverseStepOver(cx),
|
||||
"reverseStepOver",
|
||||
"active",
|
||||
"Reverse step over"
|
||||
),
|
||||
debugBtn(
|
||||
this.props.stepOver,
|
||||
() => this.props.stepOver(cx),
|
||||
"stepOver",
|
||||
"active",
|
||||
L10N.getFormatStr("stepOverTooltip", formatKey("stepOver")),
|
||||
@ -239,7 +248,7 @@ class CommandBar extends Component<Props> {
|
||||
),
|
||||
<div key="divider-2" className="divider" />,
|
||||
debugBtn(
|
||||
this.props.stepOut,
|
||||
() => this.props.stepOut(cx),
|
||||
"stepOut",
|
||||
"active",
|
||||
L10N.getFormatStr("stepOutTooltip", formatKey("stepOut")),
|
||||
@ -247,7 +256,7 @@ class CommandBar extends Component<Props> {
|
||||
),
|
||||
|
||||
debugBtn(
|
||||
this.props.stepIn,
|
||||
() => this.props.stepIn(cx),
|
||||
"stepIn",
|
||||
"active",
|
||||
L10N.getFormatStr("stepInTooltip", formatKey("stepIn")),
|
||||
@ -303,7 +312,7 @@ CommandBar.contextTypes = {
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
isPaused: getIsPaused(state, getCurrentThread(state)),
|
||||
cx: getThreadContext(state),
|
||||
isWaitingOnBreak: getIsWaitingOnBreak(state, getCurrentThread(state)),
|
||||
canRewind: getCanRewind(state),
|
||||
skipPausing: getSkipPausing(state)
|
||||
|
@ -13,7 +13,8 @@ import actions from "../../actions";
|
||||
import {
|
||||
getExpressions,
|
||||
getExpressionError,
|
||||
getAutocompleteMatchset
|
||||
getAutocompleteMatchset,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
import { getValue } from "../../utils/expressions";
|
||||
import { createObjectClient } from "../../client/firefox";
|
||||
@ -22,7 +23,7 @@ import { CloseButton } from "../shared/Button";
|
||||
import { debounce } from "lodash";
|
||||
|
||||
import type { List } from "immutable";
|
||||
import type { Expression } from "../../types";
|
||||
import type { Expression, ThreadContext } from "../../types";
|
||||
|
||||
import "./Expressions.css";
|
||||
|
||||
@ -36,6 +37,7 @@ type State = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
expressions: List<Expression>,
|
||||
expressionError: boolean,
|
||||
showInput: boolean,
|
||||
@ -73,10 +75,10 @@ class Expressions extends Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { expressions, evaluateExpressions, showInput } = this.props;
|
||||
const { cx, expressions, evaluateExpressions, showInput } = this.props;
|
||||
|
||||
if (expressions.size > 0) {
|
||||
evaluateExpressions();
|
||||
evaluateExpressions(cx);
|
||||
}
|
||||
|
||||
// Ensures that the input is focused when the "+"
|
||||
@ -161,7 +163,7 @@ class Expressions extends Component<Props, State> {
|
||||
|
||||
findAutocompleteMatches = debounce((value, selectionStart) => {
|
||||
const { autocomplete } = this.props;
|
||||
autocomplete(value, selectionStart);
|
||||
autocomplete(this.props.cx, value, selectionStart);
|
||||
}, 250);
|
||||
|
||||
handleKeyDown = (e: SyntheticKeyboardEvent<HTMLInputElement>) => {
|
||||
@ -192,7 +194,11 @@ class Expressions extends Component<Props, State> {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.props.updateExpression(this.state.inputValue, expression);
|
||||
this.props.updateExpression(
|
||||
this.props.cx,
|
||||
this.state.inputValue,
|
||||
expression
|
||||
);
|
||||
this.hideInput();
|
||||
};
|
||||
|
||||
@ -202,7 +208,7 @@ class Expressions extends Component<Props, State> {
|
||||
e.stopPropagation();
|
||||
|
||||
this.props.clearExpressionError();
|
||||
await this.props.addExpression(this.state.inputValue);
|
||||
await this.props.addExpression(this.props.cx, this.state.inputValue);
|
||||
this.setState({
|
||||
editing: false,
|
||||
editIndex: -1,
|
||||
@ -377,6 +383,7 @@ class Expressions extends Component<Props, State> {
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
cx: getThreadContext(state),
|
||||
autocompleteMatches: getAutocompleteMatchset(state),
|
||||
expressions: getExpressions(state),
|
||||
expressionError: getExpressionError(state)
|
||||
|
@ -13,8 +13,9 @@ import { formatDisplayName } from "../../../utils/pause/frames";
|
||||
import { getFilename, getFileURL } from "../../../utils/source";
|
||||
import FrameMenu from "./FrameMenu";
|
||||
import FrameIndent from "./FrameIndent";
|
||||
import actions from "../../../actions";
|
||||
|
||||
import type { Frame } from "../../../types";
|
||||
import type { Frame, ThreadContext } from "../../../types";
|
||||
|
||||
type FrameTitleProps = {
|
||||
frame: Frame,
|
||||
@ -61,11 +62,12 @@ function FrameLocation({ frame, displayFullUrl = false }: FrameLocationProps) {
|
||||
FrameLocation.displayName = "FrameLocation";
|
||||
|
||||
type FrameComponentProps = {
|
||||
cx: ThreadContext,
|
||||
frame: Frame,
|
||||
selectedFrame: Frame,
|
||||
copyStackTrace: Function,
|
||||
toggleFrameworkGrouping: Function,
|
||||
selectFrame: Function,
|
||||
selectFrame: typeof actions.selectFrame,
|
||||
frameworkGroupingOn: boolean,
|
||||
hideLocation: boolean,
|
||||
shouldMapDisplayName: boolean,
|
||||
@ -107,7 +109,7 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
if (e.button !== 0) {
|
||||
return;
|
||||
}
|
||||
this.props.selectFrame(frame);
|
||||
this.props.selectFrame(this.props.cx, frame);
|
||||
}
|
||||
|
||||
onKeyUp(
|
||||
@ -118,7 +120,7 @@ export default class FrameComponent extends Component<FrameComponentProps> {
|
||||
if (event.key != "Enter") {
|
||||
return;
|
||||
}
|
||||
this.props.selectFrame(frame);
|
||||
this.props.selectFrame(this.props.cx, frame);
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -15,7 +15,8 @@ import FrameComponent from "./Frame";
|
||||
|
||||
import "./Group.css";
|
||||
|
||||
import type { Frame } from "../../../types";
|
||||
import actions from "../../../actions";
|
||||
import type { Frame, ThreadContext } from "../../../types";
|
||||
import Badge from "../../shared/Badge";
|
||||
import FrameIndent from "./FrameIndent";
|
||||
|
||||
@ -39,9 +40,10 @@ function FrameLocation({ frame, expanded }: FrameLocationProps) {
|
||||
FrameLocation.displayName = "FrameLocation";
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
group: Frame[],
|
||||
selectedFrame: Frame,
|
||||
selectFrame: Function,
|
||||
selectFrame: typeof actions.selectFrame,
|
||||
toggleFrameworkGrouping: Function,
|
||||
copyStackTrace: Function,
|
||||
toggleBlackBox: Function,
|
||||
@ -88,6 +90,7 @@ export default class Group extends Component<Props, State> {
|
||||
|
||||
renderFrames() {
|
||||
const {
|
||||
cx,
|
||||
group,
|
||||
selectFrame,
|
||||
selectedFrame,
|
||||
@ -114,6 +117,7 @@ export default class Group extends Component<Props, State> {
|
||||
}
|
||||
return acc.concat(
|
||||
<FrameComponent
|
||||
cx={cx}
|
||||
copyStackTrace={copyStackTrace}
|
||||
frame={frame}
|
||||
frameworkGroupingOn={frameworkGroupingOn}
|
||||
|
@ -8,7 +8,7 @@ import React, { Component } from "react";
|
||||
import { connect } from "../../../utils/connect";
|
||||
import PropTypes from "prop-types";
|
||||
|
||||
import type { Frame, Why } from "../../../types";
|
||||
import type { Frame, Why, ThreadContext } from "../../../types";
|
||||
|
||||
import FrameComponent from "./Frame";
|
||||
import Group from "./Group";
|
||||
@ -24,7 +24,8 @@ import {
|
||||
getSelectedFrame,
|
||||
getCallStackFrames,
|
||||
getPauseReason,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getThreadContext
|
||||
} from "../../../selectors";
|
||||
|
||||
import "./Frames.css";
|
||||
@ -32,11 +33,12 @@ import "./Frames.css";
|
||||
const NUM_FRAMES_SHOWN = 7;
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
frames: Array<Frame>,
|
||||
frameworkGroupingOn: boolean,
|
||||
selectedFrame: Object,
|
||||
why: Why,
|
||||
selectFrame: Function,
|
||||
selectFrame: typeof actions.selectFrame,
|
||||
toggleBlackBox: Function,
|
||||
toggleFrameworkGrouping: Function,
|
||||
disableFrameTruncate: boolean,
|
||||
@ -114,6 +116,7 @@ class Frames extends Component<Props, State> {
|
||||
|
||||
renderFrames(frames: Frame[]) {
|
||||
const {
|
||||
cx,
|
||||
selectFrame,
|
||||
selectedFrame,
|
||||
toggleBlackBox,
|
||||
@ -136,6 +139,7 @@ class Frames extends Component<Props, State> {
|
||||
(frameOrGroup: FrameOrGroup) =>
|
||||
frameOrGroup.id ? (
|
||||
<FrameComponent
|
||||
cx={cx}
|
||||
frame={(frameOrGroup: any)}
|
||||
toggleFrameworkGrouping={this.toggleFrameworkGrouping}
|
||||
copyStackTrace={this.copyStackTrace}
|
||||
@ -151,6 +155,7 @@ class Frames extends Component<Props, State> {
|
||||
/>
|
||||
) : (
|
||||
<Group
|
||||
cx={cx}
|
||||
group={(frameOrGroup: any)}
|
||||
toggleFrameworkGrouping={this.toggleFrameworkGrouping}
|
||||
copyStackTrace={this.copyStackTrace}
|
||||
@ -216,6 +221,7 @@ class Frames extends Component<Props, State> {
|
||||
Frames.contextTypes = { l10n: PropTypes.object };
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
cx: getThreadContext(state),
|
||||
frames: getCallStackFrames(state),
|
||||
why: getPauseReason(state, getCurrentThread(state)),
|
||||
frameworkGroupingOn: getFrameworkGroupingState(state),
|
||||
|
@ -7,13 +7,18 @@
|
||||
import React from "react";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import Frame from "../Frame.js";
|
||||
import { makeMockFrame, makeMockSource } from "../../../../utils/test-mockup";
|
||||
import {
|
||||
makeMockFrame,
|
||||
makeMockSource,
|
||||
mockthreadcx
|
||||
} from "../../../../utils/test-mockup";
|
||||
|
||||
import FrameMenu from "../FrameMenu";
|
||||
jest.mock("../FrameMenu", () => jest.fn());
|
||||
|
||||
function frameProperties(frame, selectedFrame: any, overrides = {}) {
|
||||
return {
|
||||
cx: mockthreadcx,
|
||||
frame,
|
||||
selectedFrame,
|
||||
copyStackTrace: jest.fn(),
|
||||
|
@ -7,7 +7,11 @@
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import Group from "../Group.js";
|
||||
import { makeMockFrame, makeMockSource } from "../../../../utils/test-mockup";
|
||||
import {
|
||||
makeMockFrame,
|
||||
makeMockSource,
|
||||
mockthreadcx
|
||||
} from "../../../../utils/test-mockup";
|
||||
|
||||
import FrameMenu from "../FrameMenu";
|
||||
jest.mock("../FrameMenu", () => jest.fn());
|
||||
@ -15,6 +19,7 @@ jest.mock("../FrameMenu", () => jest.fn());
|
||||
function render(overrides = {}) {
|
||||
const frame = { ...makeMockFrame(), displayName: "foo", library: "Back" };
|
||||
const defaultProps = {
|
||||
cx: mockthreadcx,
|
||||
group: [frame],
|
||||
selectedFrame: frame,
|
||||
frameworkGroupingOn: true,
|
||||
|
@ -155,6 +155,14 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
/>
|
||||
<Frame
|
||||
copyStackTrace={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"isPaused": false,
|
||||
"navigateCounter": 0,
|
||||
"pauseCounter": 0,
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
}
|
||||
disableContextMenu={false}
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
@ -258,6 +266,14 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
/>
|
||||
<Frame
|
||||
copyStackTrace={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"isPaused": false,
|
||||
"navigateCounter": 0,
|
||||
"pauseCounter": 0,
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
}
|
||||
disableContextMenu={false}
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
@ -361,6 +377,14 @@ exports[`Group passes the getFrameTitle prop to the Frame components 1`] = `
|
||||
/>
|
||||
<Frame
|
||||
copyStackTrace={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"isPaused": false,
|
||||
"navigateCounter": 0,
|
||||
"pauseCounter": 0,
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
}
|
||||
disableContextMenu={false}
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
@ -618,6 +642,14 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
/>
|
||||
<Frame
|
||||
copyStackTrace={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"isPaused": false,
|
||||
"navigateCounter": 0,
|
||||
"pauseCounter": 0,
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
}
|
||||
disableContextMenu={false}
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
@ -720,6 +752,14 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
/>
|
||||
<Frame
|
||||
copyStackTrace={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"isPaused": false,
|
||||
"navigateCounter": 0,
|
||||
"pauseCounter": 0,
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
}
|
||||
disableContextMenu={false}
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
@ -822,6 +862,14 @@ exports[`Group renders group with anonymous functions 2`] = `
|
||||
/>
|
||||
<Frame
|
||||
copyStackTrace={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"isPaused": false,
|
||||
"navigateCounter": 0,
|
||||
"pauseCounter": 0,
|
||||
"thread": "FakeThread",
|
||||
}
|
||||
}
|
||||
disableContextMenu={false}
|
||||
displayFullUrl={false}
|
||||
frame={
|
||||
|
@ -9,13 +9,14 @@ import { connect } from "../../utils/connect";
|
||||
import classnames from "classnames";
|
||||
|
||||
import actions from "../../actions";
|
||||
import { getCurrentThread, getIsPaused } from "../../selectors";
|
||||
import { getCurrentThread, getIsPaused, getContext } from "../../selectors";
|
||||
import { getDisplayName, isWorker } from "../../utils/workers";
|
||||
import AccessibleImage from "../shared/AccessibleImage";
|
||||
|
||||
import type { Thread } from "../../types";
|
||||
import type { Context, Thread } from "../../types";
|
||||
|
||||
type Props = {
|
||||
cx: Context,
|
||||
selectThread: typeof actions.selectThread,
|
||||
isPaused: boolean,
|
||||
thread: Thread,
|
||||
@ -25,7 +26,7 @@ type Props = {
|
||||
export class Worker extends Component<Props> {
|
||||
onSelectThread = () => {
|
||||
const { thread } = this.props;
|
||||
this.props.selectThread(thread.actor);
|
||||
this.props.selectThread(this.props.cx, thread.actor);
|
||||
};
|
||||
|
||||
render() {
|
||||
@ -57,6 +58,7 @@ export class Worker extends Component<Props> {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state, props: Props) => ({
|
||||
cx: getContext(state),
|
||||
currentThread: getCurrentThread(state),
|
||||
isPaused: getIsPaused(state, props.thread.actor)
|
||||
});
|
||||
|
@ -21,7 +21,8 @@ import {
|
||||
getShouldPauseOnExceptions,
|
||||
getShouldPauseOnCaughtExceptions,
|
||||
getWorkers,
|
||||
getCurrentThread
|
||||
getCurrentThread,
|
||||
getThreadContext
|
||||
} from "../../selectors";
|
||||
|
||||
import AccessibleImage from "../shared/AccessibleImage";
|
||||
@ -42,7 +43,7 @@ import Scopes from "./Scopes";
|
||||
|
||||
import "./SecondaryPanes.css";
|
||||
|
||||
import type { Expression, Frame, WorkerList } from "../../types";
|
||||
import type { Expression, Frame, WorkerList, ThreadContext } from "../../types";
|
||||
|
||||
type AccordionPaneItem = {
|
||||
header: string,
|
||||
@ -72,6 +73,7 @@ type State = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
cx: ThreadContext,
|
||||
expressions: List<Expression>,
|
||||
hasFrames: boolean,
|
||||
horizontal: boolean,
|
||||
@ -114,6 +116,7 @@ class SecondaryPanes extends Component<Props, State> {
|
||||
|
||||
renderBreakpointsToggle() {
|
||||
const {
|
||||
cx,
|
||||
toggleAllBreakpoints,
|
||||
breakpoints,
|
||||
breakpointsDisabled
|
||||
@ -135,7 +138,7 @@ class SecondaryPanes extends Component<Props, State> {
|
||||
key: "breakpoints-toggle",
|
||||
onChange: e => {
|
||||
e.stopPropagation();
|
||||
toggleAllBreakpoints(!breakpointsDisabled);
|
||||
toggleAllBreakpoints(cx, !breakpointsDisabled);
|
||||
},
|
||||
onClick: e => e.stopPropagation(),
|
||||
checked: !breakpointsDisabled && !isIndeterminate,
|
||||
@ -162,7 +165,7 @@ class SecondaryPanes extends Component<Props, State> {
|
||||
debugBtn(
|
||||
evt => {
|
||||
evt.stopPropagation();
|
||||
this.props.evaluateExpressions();
|
||||
this.props.evaluateExpressions(this.props.cx);
|
||||
},
|
||||
"refresh",
|
||||
"refresh",
|
||||
@ -462,6 +465,7 @@ const mapStateToProps = state => {
|
||||
const thread = getCurrentThread(state);
|
||||
|
||||
return {
|
||||
cx: getThreadContext(state),
|
||||
expressions: getExpressions(state),
|
||||
hasFrames: !!getTopFrame(state, thread),
|
||||
breakpoints: getBreakpointsList(state),
|
||||
|
@ -7,10 +7,12 @@
|
||||
import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import CommandBar from "../CommandBar";
|
||||
import { mockthreadcx } from "../../../utils/test-mockup";
|
||||
|
||||
describe("CommandBar", () => {
|
||||
it("f8 key command calls props.breakOnNext when not in paused state", () => {
|
||||
const props = {
|
||||
cx: mockthreadcx,
|
||||
breakOnNext: jest.fn(),
|
||||
resume: jest.fn(),
|
||||
isPaused: false
|
||||
@ -43,6 +45,7 @@ describe("CommandBar", () => {
|
||||
|
||||
it("f8 key command calls props.resume when in paused state", () => {
|
||||
const props = {
|
||||
cx: { ...mockthreadcx, isPaused: true },
|
||||
breakOnNext: jest.fn(),
|
||||
resume: jest.fn(),
|
||||
isPaused: true
|
||||
|
@ -8,6 +8,7 @@ import React from "react";
|
||||
import { shallow } from "enzyme";
|
||||
import Outline from "../../components/PrimaryPanes/Outline";
|
||||
import { makeSymbolDeclaration } from "../../utils/test-head";
|
||||
import { mockcx } from "../../utils/test-mockup";
|
||||
import { showMenu } from "devtools-contextmenu";
|
||||
import { copyToTheClipboard } from "../../utils/clipboard";
|
||||
|
||||
@ -19,6 +20,7 @@ const mockFunctionText = "mock function text";
|
||||
|
||||
function generateDefaults(overrides) {
|
||||
return {
|
||||
cx: mockcx,
|
||||
selectLocation: jest.fn(),
|
||||
selectedSource: { id: sourceId },
|
||||
getFunctionText: jest.fn().mockReturnValue(mockFunctionText),
|
||||
@ -70,7 +72,10 @@ describe("Outline", () => {
|
||||
const { selectLocation } = props;
|
||||
const listItem = component.find("li").first();
|
||||
listItem.simulate("click");
|
||||
expect(selectLocation).toHaveBeenCalledWith({ line: startLine, sourceId });
|
||||
expect(selectLocation).toHaveBeenCalledWith(mockcx, {
|
||||
line: startLine,
|
||||
sourceId
|
||||
});
|
||||
});
|
||||
|
||||
describe("renders outline", () => {
|
||||
@ -210,7 +215,7 @@ describe("Outline", () => {
|
||||
|
||||
await component.find("h2").simulate("click", {});
|
||||
|
||||
expect(props.selectLocation).toHaveBeenCalledWith({
|
||||
expect(props.selectLocation).toHaveBeenCalledWith(mockcx, {
|
||||
line: 24,
|
||||
sourceId: sourceId
|
||||
});
|
||||
|
@ -8,6 +8,7 @@ import React from "react";
|
||||
import { mount, shallow } from "enzyme";
|
||||
import { ProjectSearch } from "../ProjectSearch";
|
||||
import { statusType } from "../../reducers/project-text-search";
|
||||
import { mockcx } from "../../utils/test-mockup";
|
||||
|
||||
const hooks = { on: [], off: [] };
|
||||
const shortcuts = {
|
||||
@ -75,6 +76,7 @@ const testMatch = {
|
||||
|
||||
function render(overrides = {}, mounted = false) {
|
||||
const props = {
|
||||
cx: mockcx,
|
||||
status: "DONE",
|
||||
sources: {},
|
||||
results: [],
|
||||
@ -187,7 +189,7 @@ describe("ProjectSearch", () => {
|
||||
component
|
||||
.find("SearchInput input")
|
||||
.simulate("keydown", { key: "Enter", stopPropagation: jest.fn() });
|
||||
expect(searchSources).toHaveBeenCalledWith("foo");
|
||||
expect(searchSources).toHaveBeenCalledWith(mockcx, "foo");
|
||||
});
|
||||
|
||||
it("onEnterPress shortcut no match or setExpanded", () => {
|
||||
@ -215,7 +217,7 @@ describe("ProjectSearch", () => {
|
||||
);
|
||||
component.instance().state.focusedItem = { ...testMatch };
|
||||
shortcuts.dispatch("Enter");
|
||||
expect(selectSpecificLocation).toHaveBeenCalledWith({
|
||||
expect(selectSpecificLocation).toHaveBeenCalledWith(mockcx, {
|
||||
sourceId: "some-target/source42",
|
||||
line: 3,
|
||||
column: 30
|
||||
|
@ -8,6 +8,7 @@
|
||||
import React from "react";
|
||||
import { shallow, mount } from "enzyme";
|
||||
import { QuickOpenModal } from "../QuickOpenModal";
|
||||
import { mockcx } from "../../utils/test-mockup";
|
||||
|
||||
jest.mock("fuzzaldrin-plus");
|
||||
|
||||
@ -15,6 +16,7 @@ import { filter } from "fuzzaldrin-plus";
|
||||
|
||||
function generateModal(propOverrides, renderType = "shallow") {
|
||||
const props = {
|
||||
cx: mockcx,
|
||||
enabled: false,
|
||||
query: "",
|
||||
searchType: "sources",
|
||||
@ -314,7 +316,7 @@ describe("QuickOpenModal", () => {
|
||||
key: "Enter"
|
||||
};
|
||||
wrapper.find("SearchInput").simulate("keydown", event);
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith({
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith(mockcx, {
|
||||
column: 12,
|
||||
line: 34,
|
||||
sourceId: ""
|
||||
@ -336,7 +338,7 @@ describe("QuickOpenModal", () => {
|
||||
key: "Enter"
|
||||
};
|
||||
wrapper.find("SearchInput").simulate("keydown", event);
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith({
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith(mockcx, {
|
||||
column: 12,
|
||||
line: 34,
|
||||
sourceId: sourceId
|
||||
@ -447,7 +449,7 @@ describe("QuickOpenModal", () => {
|
||||
key: "Enter"
|
||||
};
|
||||
wrapper.find("SearchInput").simulate("keydown", event);
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith({
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith(mockcx, {
|
||||
column: undefined,
|
||||
sourceId: id,
|
||||
line: 0
|
||||
@ -477,7 +479,7 @@ describe("QuickOpenModal", () => {
|
||||
key: "Enter"
|
||||
};
|
||||
wrapper.find("SearchInput").simulate("keydown", event);
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith({
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith(mockcx, {
|
||||
column: undefined,
|
||||
line: 0,
|
||||
sourceId: ""
|
||||
@ -507,7 +509,7 @@ describe("QuickOpenModal", () => {
|
||||
key: "Enter"
|
||||
};
|
||||
wrapper.find("SearchInput").simulate("keydown", event);
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith({
|
||||
expect(props.selectSpecificLocation).toHaveBeenCalledWith(mockcx, {
|
||||
column: 4,
|
||||
line: 3,
|
||||
sourceId: id
|
||||
|
@ -44,6 +44,11 @@ exports[`ProjectSearch found search results 1`] = `
|
||||
activeSearch="project"
|
||||
clearSearch={[MockFunction]}
|
||||
closeProjectSearch={[MockFunction]}
|
||||
cx={
|
||||
Object {
|
||||
"navigateCounter": 0,
|
||||
}
|
||||
}
|
||||
doSearchForHighlight={[MockFunction]}
|
||||
query="match"
|
||||
results={
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user