зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1532162 - Map Scopes should be opt-in. r=loganfsmyth
Differential Revision: https://phabricator.services.mozilla.com/D21870 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
17ca504ef6
Коммит
fb790261c6
|
@ -4017,6 +4017,42 @@ html[dir="rtl"] .event-listeners-content .arrow.expanded {
|
|||
* 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/>. */
|
||||
|
||||
|
||||
|
||||
.scopes-content .toggle-map-scopes {
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
margin-bottom: 3px;
|
||||
margin-left: 10px;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes input {
|
||||
padding-inline-start: 2px;
|
||||
margin-inline-start: 0;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes-label {
|
||||
padding-inline-start: 2px;
|
||||
padding-inline-end: 8px;
|
||||
cursor: default;
|
||||
flex-grow: 1;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes a.mdn {
|
||||
padding-inline-end: 10px;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes .img.shortcuts {
|
||||
background: var(--theme-comment);
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.object-node.default-property {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
|
|
@ -30,3 +30,4 @@ export { setPopupObjectProperties } from "./setPopupObjectProperties";
|
|||
export { pauseOnExceptions } from "./pauseOnExceptions";
|
||||
export { selectFrame } from "./selectFrame";
|
||||
export { toggleSkipPausing } from "./skipPausing";
|
||||
export { toggleMapScopes } from "./mapScopes";
|
||||
|
|
|
@ -4,7 +4,14 @@
|
|||
|
||||
// @flow
|
||||
|
||||
import { getCurrentThread, getSource } from "../../selectors";
|
||||
import {
|
||||
getCurrentThread,
|
||||
getSource,
|
||||
getMapScopes,
|
||||
getSelectedFrame,
|
||||
getSelectedGeneratedScope,
|
||||
getSelectedOriginalScope
|
||||
} from "../../selectors";
|
||||
import { loadSourceText } from "../sources/loadSourceText";
|
||||
import { PROMISE } from "../utils/middleware/promise";
|
||||
|
||||
|
@ -17,6 +24,28 @@ import type { ThunkArgs } from "../types";
|
|||
|
||||
import { buildMappedScopes } from "../../utils/pause/mapScopes";
|
||||
|
||||
export function toggleMapScopes() {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
if (getMapScopes(getState())) {
|
||||
return dispatch({ type: "TOGGLE_MAP_SCOPES", mapScopes: false });
|
||||
}
|
||||
|
||||
dispatch({ type: "TOGGLE_MAP_SCOPES", mapScopes: true });
|
||||
|
||||
if (getSelectedOriginalScope(getState())) {
|
||||
return;
|
||||
}
|
||||
|
||||
const scopes = getSelectedGeneratedScope(getState());
|
||||
const frame = getSelectedFrame(getState());
|
||||
if (!scopes || !frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(mapScopes(Promise.resolve(scopes.scope), frame));
|
||||
};
|
||||
}
|
||||
|
||||
export function mapScopes(scopes: Promise<Scope>, frame: Frame) {
|
||||
return async function({ dispatch, getState, client, sourceMaps }: ThunkArgs) {
|
||||
const generatedSource = getSource(
|
||||
|
|
|
@ -15,8 +15,8 @@ import { simpleMockThreadClient } from "./helpers/threadClient.js";
|
|||
import { asyncStore } from "../../utils/prefs";
|
||||
|
||||
function loadInitialState(opts = {}) {
|
||||
const mockedPendingBreakpoint = mockPendingBreakpoint({...opts, column: 2});
|
||||
const id = makePendingLocationId(mockedPendingBreakpoint.location)
|
||||
const mockedPendingBreakpoint = mockPendingBreakpoint({ ...opts, column: 2 });
|
||||
const id = makePendingLocationId(mockedPendingBreakpoint.location);
|
||||
asyncStore.pendingBreakpoints = { [id]: mockedPendingBreakpoint };
|
||||
|
||||
return { pendingBreakpoints: asyncStore.pendingBreakpoints };
|
||||
|
@ -61,7 +61,11 @@ function mockClient(bpPos = {}) {
|
|||
function mockSourceMaps() {
|
||||
return {
|
||||
...sourceMaps,
|
||||
getOriginalSourceText: async (source) => ({id: source.id, text: "", contentType: "text/javascript"}),
|
||||
getOriginalSourceText: async source => ({
|
||||
id: source.id,
|
||||
text: "",
|
||||
contentType: "text/javascript"
|
||||
}),
|
||||
getGeneratedRangesForOriginal: async () => [
|
||||
{ start: { line: 0, column: 0 }, end: { line: 10, column: 10 } }
|
||||
]
|
||||
|
@ -364,23 +368,19 @@ describe("adding sources", () => {
|
|||
|
||||
it("corresponding breakpoints are added to the original source", async () => {
|
||||
const source = makeOriginalSource("bar.js", { sourceMapURL: "foo" });
|
||||
const store = createStore(
|
||||
mockClient({ "5": [2] }),
|
||||
loadInitialState(),
|
||||
{
|
||||
getOriginalURLs: async () => [source.url],
|
||||
getOriginalSourceText: async () => ({ source: "" }),
|
||||
getGeneratedLocation: async (location, _source) => ({
|
||||
line: location.line,
|
||||
column: location.column,
|
||||
sourceId: _source.id
|
||||
}),
|
||||
getOriginalLocation: async location => location,
|
||||
getGeneratedRangesForOriginal: async () => [
|
||||
{ start: { line: 0, column: 0 }, end: { line: 10, column: 10 } }
|
||||
]
|
||||
}
|
||||
);
|
||||
const store = createStore(mockClient({ "5": [2] }), loadInitialState(), {
|
||||
getOriginalURLs: async () => [source.url],
|
||||
getOriginalSourceText: async () => ({ source: "" }),
|
||||
getGeneratedLocation: async (location, _source) => ({
|
||||
line: location.line,
|
||||
column: location.column,
|
||||
sourceId: _source.id
|
||||
}),
|
||||
getOriginalLocation: async location => location,
|
||||
getGeneratedRangesForOriginal: async () => [
|
||||
{ start: { line: 0, column: 0 }, end: { line: 10, column: 10 } }
|
||||
]
|
||||
});
|
||||
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
|
|
|
@ -130,4 +130,8 @@ export type PauseAction =
|
|||
+type: "TOGGLE_SKIP_PAUSING",
|
||||
+thread: string,
|
||||
skipPausing: boolean
|
||||
|}
|
||||
| {|
|
||||
+type: "TOGGLE_MAP_SCOPES",
|
||||
+mapScopes: boolean
|
||||
|};
|
||||
|
|
|
@ -2,6 +2,42 @@
|
|||
* 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/>. */
|
||||
|
||||
|
||||
|
||||
.scopes-content .toggle-map-scopes {
|
||||
border-bottom: 1px solid var(--theme-splitter-color);
|
||||
margin-bottom: 3px;
|
||||
margin-left: 10px;
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes input {
|
||||
padding-inline-start: 2px;
|
||||
margin-inline-start: 0;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes-label {
|
||||
padding-inline-start: 2px;
|
||||
padding-inline-end: 8px;
|
||||
cursor: default;
|
||||
flex-grow: 1;
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes a.mdn {
|
||||
padding-inline-end: 10px;
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes .img.shortcuts {
|
||||
background: var(--theme-comment);
|
||||
}
|
||||
|
||||
.scopes-content .toggle-map-scopes {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.object-node.default-property {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
// @flow
|
||||
import React, { PureComponent } from "react";
|
||||
import { isGeneratedId } from "devtools-source-map";
|
||||
import { connect } from "../../utils/connect";
|
||||
import { features } from "../../utils/prefs";
|
||||
import actions from "../../actions";
|
||||
import { createObjectClient } from "../../client/firefox";
|
||||
|
||||
|
@ -14,17 +16,21 @@ import {
|
|||
getGeneratedFrameScope,
|
||||
getOriginalFrameScope,
|
||||
isPaused as getIsPaused,
|
||||
getPauseReason
|
||||
getPauseReason,
|
||||
getMapScopes
|
||||
} from "../../selectors";
|
||||
import { getScopes } from "../../utils/pause/scopes";
|
||||
|
||||
import { objectInspector } from "devtools-reps";
|
||||
import AccessibleImage from "../shared/AccessibleImage";
|
||||
|
||||
import type { Why } from "../../types";
|
||||
import type { NamedValue } from "../../utils/pause/scopes/types";
|
||||
|
||||
import "./Scopes.css";
|
||||
|
||||
const mdnLink = "https://developer.mozilla.org/en-US/docs/Tools/Debugger";
|
||||
|
||||
const { ObjectInspector } = objectInspector;
|
||||
|
||||
type Props = {
|
||||
|
@ -34,8 +40,10 @@ type Props = {
|
|||
originalFrameScopes: Object | null,
|
||||
isLoading: boolean,
|
||||
why: Why,
|
||||
shouldMapScopes: boolean,
|
||||
openLink: typeof actions.openLink,
|
||||
openElementInInspector: typeof actions.openElementInInspectorCommand
|
||||
openElementInInspector: typeof actions.openElementInInspectorCommand,
|
||||
toggleMapScopes: typeof actions.toggleMapScopes
|
||||
};
|
||||
|
||||
type State = {
|
||||
|
@ -97,16 +105,46 @@ class Scopes extends PureComponent<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
onToggleMapScopes = () => {
|
||||
this.props.toggleMapScopes();
|
||||
};
|
||||
|
||||
renderMapScopes() {
|
||||
const { selectedFrame, shouldMapScopes } = this.props;
|
||||
|
||||
if (!features.mapScopes || isGeneratedId(selectedFrame.location.sourceId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="toggle-map-scopes" onClick={this.onToggleMapScopes}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={shouldMapScopes ? "checked" : ""}
|
||||
onChange={e => e.stopPropagation() && this.onToggleMapScopes()}
|
||||
/>
|
||||
<div className="toggle-map-scopes-label">
|
||||
<span>{L10N.getStr("scopes.mapScopes")}</span>
|
||||
</div>
|
||||
<a className="mdn" target="_blank" href={mdnLink}>
|
||||
<AccessibleImage className="shortcuts" />
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
renderScopesList() {
|
||||
const {
|
||||
isPaused,
|
||||
isLoading,
|
||||
openLink,
|
||||
openElementInInspector
|
||||
openElementInInspector,
|
||||
shouldMapScopes
|
||||
} = this.props;
|
||||
const { originalScopes, generatedScopes, showOriginal } = this.state;
|
||||
|
||||
const scopes = (showOriginal && originalScopes) || generatedScopes;
|
||||
const scopes =
|
||||
(showOriginal && shouldMapScopes && originalScopes) || generatedScopes;
|
||||
|
||||
if (scopes && !isLoading) {
|
||||
return (
|
||||
|
@ -122,7 +160,7 @@ class Scopes extends PureComponent<Props, State> {
|
|||
onDOMNodeClick={grip => openElementInInspector(grip)}
|
||||
onInspectIconClick={grip => openElementInInspector(grip)}
|
||||
/>
|
||||
{originalScopes ? (
|
||||
{originalScopes && shouldMapScopes ? (
|
||||
<div className="scope-type-toggle">
|
||||
<button
|
||||
onClick={e => {
|
||||
|
@ -155,6 +193,15 @@ class Scopes extends PureComponent<Props, State> {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="scopes-content">
|
||||
{this.renderMapScopes()}
|
||||
{this.renderScopesList()}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const mapStateToProps = state => {
|
||||
|
@ -180,6 +227,7 @@ const mapStateToProps = state => {
|
|||
|
||||
return {
|
||||
selectedFrame,
|
||||
shouldMapScopes: getMapScopes(state),
|
||||
isPaused: getIsPaused(state),
|
||||
isLoading: generatedPending || originalPending,
|
||||
why: getPauseReason(state),
|
||||
|
@ -192,6 +240,7 @@ export default connect(
|
|||
mapStateToProps,
|
||||
{
|
||||
openLink: actions.openLink,
|
||||
openElementInInspector: actions.openElementInInspectorCommand
|
||||
openElementInInspector: actions.openElementInInspectorCommand,
|
||||
toggleMapScopes: actions.toggleMapScopes
|
||||
}
|
||||
)(Scopes);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
import { createSelector } from "reselect";
|
||||
import { isGeneratedId } from "devtools-source-map";
|
||||
import { prefs } from "../utils/prefs";
|
||||
import { getSelectedSource } from "./sources";
|
||||
import { getSelectedSourceId } from "./sources";
|
||||
|
||||
import type { OriginalScope } from "../utils/pause/mapScopes";
|
||||
import type { Action } from "../actions/types";
|
||||
|
@ -78,14 +78,16 @@ export type PauseState = {
|
|||
currentThread: string,
|
||||
canRewind: boolean,
|
||||
threads: { [string]: ThreadPauseState },
|
||||
skipPausing: boolean
|
||||
skipPausing: boolean,
|
||||
mapScopes: boolean
|
||||
};
|
||||
|
||||
export const createPauseState = (): PauseState => ({
|
||||
currentThread: "UnknownThread",
|
||||
threads: {},
|
||||
canRewind: false,
|
||||
skipPausing: prefs.skipPausing
|
||||
skipPausing: prefs.skipPausing,
|
||||
mapScopes: prefs.mapScopes
|
||||
});
|
||||
|
||||
const resumedPauseState = {
|
||||
|
@ -306,6 +308,12 @@ function update(
|
|||
|
||||
return { ...state, skipPausing };
|
||||
}
|
||||
|
||||
case "TOGGLE_MAP_SCOPES": {
|
||||
const { mapScopes } = action;
|
||||
prefs.mapScopes = mapScopes;
|
||||
return { ...state, mapScopes };
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -503,14 +511,10 @@ export function getFrameScope(
|
|||
}
|
||||
|
||||
export function getSelectedScope(state: OuterState) {
|
||||
const source = getSelectedSource(state);
|
||||
const sourceId = getSelectedSourceId(state);
|
||||
const frameId = getSelectedFrameId(state);
|
||||
|
||||
if (!source) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const frameScope = getFrameScope(state, source.id, frameId);
|
||||
const frameScope = getFrameScope(state, sourceId, frameId);
|
||||
if (!frameScope) {
|
||||
return null;
|
||||
}
|
||||
|
@ -518,6 +522,17 @@ export function getSelectedScope(state: OuterState) {
|
|||
return frameScope.scope || null;
|
||||
}
|
||||
|
||||
export function getSelectedOriginalScope(state: OuterState) {
|
||||
const sourceId = getSelectedSourceId(state);
|
||||
const frameId = getSelectedFrameId(state);
|
||||
return getOriginalFrameScope(state, sourceId, frameId);
|
||||
}
|
||||
|
||||
export function getSelectedGeneratedScope(state: OuterState) {
|
||||
const frameId = getSelectedFrameId(state);
|
||||
return getGeneratedFrameScope(state, frameId);
|
||||
}
|
||||
|
||||
export function getSelectedScopeMappings(
|
||||
state: OuterState
|
||||
): {
|
||||
|
@ -556,6 +571,10 @@ export function getSkipPausing(state: OuterState) {
|
|||
return state.pause.skipPausing;
|
||||
}
|
||||
|
||||
export function getMapScopes(state: OuterState) {
|
||||
return state.pause.mapScopes;
|
||||
}
|
||||
|
||||
// NOTE: currently only used for chrome
|
||||
export function getChromeScopes(state: OuterState) {
|
||||
const frame: ?ChromeFrame = (getSelectedFrame(state): any);
|
||||
|
|
|
@ -539,6 +539,11 @@ export const getSelectedSource: Selector<?Source> = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export function getSelectedSourceId(state: OuterState) {
|
||||
const source = getSelectedSource((state: any));
|
||||
return source && source.id;
|
||||
}
|
||||
|
||||
export function getProjectDirectoryRoot(state: OuterState): string {
|
||||
return state.sources.projectDirectoryRoot;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ if (isDevelopment()) {
|
|||
pref("devtools.debugger.file-search-whole-word", false);
|
||||
pref("devtools.debugger.file-search-regex-match", false);
|
||||
pref("devtools.debugger.project-directory-root", "");
|
||||
pref("devtools.debugger.map-scopes-enabled", false);
|
||||
pref("devtools.debugger.prefs-schema-version", "1.0.1");
|
||||
pref("devtools.debugger.skip-pausing", false);
|
||||
pref("devtools.debugger.features.workers", true);
|
||||
|
@ -97,7 +98,8 @@ export const prefs = new PrefsHelper("devtools", {
|
|||
fileSearchRegexMatch: ["Bool", "debugger.file-search-regex-match"],
|
||||
debuggerPrefsSchemaVersion: ["Char", "debugger.prefs-schema-version"],
|
||||
projectDirectoryRoot: ["Char", "debugger.project-directory-root", ""],
|
||||
skipPausing: ["Bool", "debugger.skip-pausing"]
|
||||
skipPausing: ["Bool", "debugger.skip-pausing"],
|
||||
mapScopes: ["Bool", "debugger.map-scopes-enabled"]
|
||||
});
|
||||
|
||||
export const features = new PrefsHelper("devtools.debugger.features", {
|
||||
|
|
|
@ -515,6 +515,7 @@ function clearDebuggerPreferences() {
|
|||
Services.prefs.clearUserPref("devtools.debugger.call-stack-visible");
|
||||
Services.prefs.clearUserPref("devtools.debugger.scopes-visible");
|
||||
Services.prefs.clearUserPref("devtools.debugger.skip-pausing");
|
||||
pushPref("devtools.debugger.map-scopes-enabled", true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -713,6 +713,9 @@ sources.header=Sources
|
|||
# LOCALIZATION NOTE (outline.header): Outline left sidebar header
|
||||
outline.header=Outline
|
||||
|
||||
# LOCALIZATION NOTE (scopes.mapScopes): Label for toggling scope mappings
|
||||
scopes.mapScopes=Map Scopes
|
||||
|
||||
# LOCALIZATION NOTE (outline.placeholder): Placeholder text for the filter input
|
||||
# element
|
||||
outline.placeholder=Filter functions
|
||||
|
|
|
@ -52,6 +52,7 @@ pref("devtools.debugger.file-search-regex-match", false);
|
|||
pref("devtools.debugger.project-directory-root", "");
|
||||
pref("devtools.debugger.skip-pausing", false);
|
||||
pref("devtools.debugger.logging", false);
|
||||
pref("devtools.debugger.map-scopes-enabled", false);
|
||||
|
||||
pref("devtools.debugger.features.wasm", true);
|
||||
pref("devtools.debugger.features.shortcuts", true);
|
||||
|
|
Загрузка…
Ссылка в новой задаче