Bug 1460371 - Update Debugger Frontend v51 r=jdescottes

--HG--
rename : devtools/client/debugger/new/debugger.css => devtools/client/debugger/new/dist/debugger.css
rename : devtools/client/debugger/new/parser-worker.js => devtools/client/debugger/new/dist/parser-worker.js
rename : devtools/client/debugger/new/pretty-print-worker.js => devtools/client/debugger/new/dist/pretty-print-worker.js
rename : devtools/client/debugger/new/search-worker.js => devtools/client/debugger/new/dist/search-worker.js
This commit is contained in:
Jason Laster 2018-05-10 09:24:21 -04:00
Родитель f86cc21a3b
Коммит 40117fd237
298 изменённых файлов: 41364 добавлений и 39707 удалений

Просмотреть файл

@ -14,7 +14,7 @@ let whitelist = [
{sourceName: /codemirror\.css$/i,
isFromDevTools: true},
// The debugger uses cross-browser CSS.
{sourceName: /devtools\/client\/debugger\/new\/debugger.css/i,
{sourceName: /devtools\/client\/debugger\/new\/dist\/debugger.css/i,
isFromDevTools: true},
// Reps uses cross-browser CSS.
{sourceName: /devtools-client-shared\/components\/reps\/reps.css/i,

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

12
devtools/client/debugger/new/dist/moz.build поставляемый Normal file
Просмотреть файл

@ -0,0 +1,12 @@
# vim: set filetype=python:
# 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/.
DevToolsModules(
'debugger.css',
'parser-worker.js',
'pretty-print-worker.js',
'search-worker.js',
'vendors.js'
)

Просмотреть файл

Просмотреть файл

466
devtools/client/debugger/new/dist/vendors.css поставляемый Normal file
Просмотреть файл

@ -0,0 +1,466 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* 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/. */
.split-box {
display: flex;
flex: 1;
min-width: 0;
height: 100%;
width: 100%;
}
.split-box.vert {
flex-direction: row;
}
.split-box.horz {
flex-direction: column;
}
.split-box > .uncontrolled {
display: flex;
flex: 1;
min-width: 0;
overflow: auto;
}
.split-box > .controlled {
display: flex;
overflow: auto;
}
.split-box > .splitter {
background-image: none;
border: 0;
border-style: solid;
border-color: transparent;
background-color: var(--theme-splitter-color);
background-clip: content-box;
position: relative;
box-sizing: border-box;
/* Positive z-index positions the splitter on top of its siblings and makes
it clickable on both sides. */
z-index: 1;
}
.split-box.vert > .splitter {
min-width: calc(var(--devtools-splitter-inline-start-width) +
var(--devtools-splitter-inline-end-width) + 1px);
border-left-width: var(--devtools-splitter-inline-start-width);
border-right-width: var(--devtools-splitter-inline-end-width);
margin-left: calc(-1 * var(--devtools-splitter-inline-start-width) - 1px);
margin-right: calc(-1 * var(--devtools-splitter-inline-end-width));
cursor: ew-resize;
}
.split-box.horz > .splitter {
min-height: calc(var(--devtools-splitter-top-width) +
var(--devtools-splitter-bottom-width) + 1px);
border-top-width: var(--devtools-splitter-top-width);
border-bottom-width: var(--devtools-splitter-bottom-width);
margin-top: calc(-1 * var(--devtools-splitter-top-width) - 1px);
margin-bottom: calc(-1 * var(--devtools-splitter-bottom-width));
cursor: ns-resize;
}
.split-box.disabled {
pointer-events: none;
}
/**
* Make sure splitter panels are not processing any mouse
* events. This is good for performance during splitter
* bar dragging.
*/
.split-box.dragging > .controlled,
.split-box.dragging > .uncontrolled {
pointer-events: none;
}
/* 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/>. */
.arrow,
.worker,
.refresh,
.shortcut,
.add-button {
fill: var(--theme-splitter-color);
}
.folder,
.domain,
.source-icon,
.file,
.extension {
background-color: var(--theme-comment);
}
.worker,
.file,
.folder,
.source-icon,
.extension {
position: relative;
top: 2px;
}
.domain,
.worker,
.refresh,
.add-button {
position: relative;
top: 1px;
}
.worker svg,
.refresh svg,
.shortcut svg,
.add-button svg {
width: 15px;
}
img.domain,
img.folder,
img.source-icon {
width: 15px;
height: 15px;
}
img.extension {
width: 13px;
height: 13px;
margin-inline-start: 2px;
}
img.result-item-icon {
height: 18px;
width: 18px;
}
img.domain {
mask: url("chrome://devtools/skin/images/debugger/domain.svg") no-repeat;
}
img.folder {
mask: url("chrome://devtools/skin/images/debugger/folder.svg") no-repeat;
}
img.coffeescript {
mask: url("chrome://devtools/skin/images/debugger/coffeescript.svg") no-repeat;
}
img.javascript {
mask: url("chrome://devtools/skin/images/debugger/javascript.svg") no-repeat;
}
img.tab {
mask: url("chrome://devtools/skin/images/debugger/tab.svg") no-repeat;
}
img.react {
mask: url("chrome://devtools/skin/images/debugger/react.svg") no-repeat;
}
img.typescript {
mask: url("chrome://devtools/skin/images/debugger/typescript.svg") no-repeat;
}
img.extension {
mask: url("chrome://devtools/skin/images/debugger/extension.svg") no-repeat;
}
img.file {
mask: url("chrome://devtools/skin/images/debugger/file.svg") no-repeat;
width: 13px;
height: 13px;
}
img.domain,
img.folder,
img.file,
img.source-icon,
img.extension {
mask-size: 100%;
margin-inline-end: 5px;
display: inline-block;
}
img.result-item-icon {
mask-size: 100%;
margin-inline-end: 15px;
margin-inline-start: 5px;
display: inline-block;
}
.refresh svg,
.shortcut svg,
.worker svg {
margin-inline-end: 5px;
}
img.arrow {
mask: url("chrome://devtools/skin/images/debugger/arrow.svg");
margin-inline-end: 5px;
margin-top: 3px;
width: 9px;
height: 9px;
padding-top: 9px;
background: var(--disclosure-arrow);
mask-size: 100%;
display: inline-block;
margin-bottom: 1px;
transform: rotate(-90deg);
transition: transform 0.18s ease;
}
html[dir="ltr"] img.arrow {
transform: rotate(-90deg);
}
html[dir="rtl"] img.arrow {
transform: rotate(90deg);
}
.arrow svg {
transition: transform 0.125s ease;
width: 10px;
margin-inline-end: 5px;
transform: rotate(-90deg);
}
html[dir="rtl"] .arrow svg,
.arrow svg:dir(rtl),
.arrow svg:-moz-locale-dir(rtl) {
transform: rotate(90deg);
}
.arrow.expanded.expanded svg {
transform: rotate(0deg);
}
.arrow.hidden {
visibility: hidden;
}
.webpack svg {
width: 15px;
height: 15px;
margin-right: 5px;
vertical-align: sub;
}
.function svg {
height: 10px;
width: 15px;
}
.function path {
fill: var(--theme-body-color);
}
.angular svg,
.source-icon svg {
width: 15px;
height: 15px;
margin-right: 5px;
vertical-align: sub;
}
.angular,
.webpack {
opacity: 0.8;
}
.theme-dark .angular,
.theme-dark .webpack {
opacity: 0.5;
}
.source-icon svg {
fill: var(--theme-comment);
}
/* 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/. */
.tree {
overflow: auto;
}
.tree.inline {
display: inline-block;
}
.tree.nowrap {
white-space: nowrap;
}
.tree.noselect {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
.tree .tree-node {
display: flex;
}
.tree .tree-node:not(.focused):hover {
background-color: var(--theme-selection-background-hover);
}
.tree-indent {
display: inline-block;
width: 12px;
margin-inline-start: 5px;
border-inline-start: 1px solid #A2D1FF;
flex-shrink: 0;
}
/* Align with expandables siblings (where we have the arrow) */
.tree-node[data-expandable="false"] .tree-indent:last-of-type {
margin-inline-end: 15px;
}
/* For non expandable root nodes, we don't have .tree-indent elements, so we declare
the margin on the start of the node */
.tree-node[data-expandable="false"][aria-level="1"] {
padding-inline-start: 15px
}
.tree .tree-node[data-expandable="true"] {
cursor: default;
}
.tree-node img.arrow {
mask: url("chrome://devtools/skin/images/devtools-components/arrow.svg") no-repeat;
mask-size: 100%;
width: 9px;
height: 9px;
margin-inline-start: 1px;
margin-inline-end: 4px;
background-color: var(--theme-splitter-color, #9B9B9B);
transform: rotate(-90deg);
transition: transform 0.125s ease;
align-self: center;
}
html[dir="rtl"] .tree-node img.arrow {
transform: rotate(90deg);
}
.tree-node img.arrow.expanded.expanded {
transform: rotate(0deg);
}
.tree .tree-node.focused {
color: white;
background-color: var(--theme-selection-background, #0a84ff);
}
.tree-node.focused img.arrow {
background-color: currentColor;
}
/* 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/. */
menu {
display: inline;
padding: 0;
}
menu > menuitem::after {
content: "\25BA";
float: right;
padding-left: 5px;
}
menu > menupopup {
display: none;
}
menu > menuitem:hover + menupopup,
menu > menupopup:hover {
display: block;
}
menupopup {
position: fixed;
z-index: 10000;
background: white;
border: 1px solid #cccccc;
padding: 5px 0;
background: #f2f2f2;
border-radius: 5px;
color: #585858;
box-shadow: 0 0 4px 0 rgba(190, 190, 190, 0.8);
min-width: 130px;
}
menuitem {
display: block;
padding: 0 20px;
line-height: 20px;
font-weight: 500;
font-size: 13px;
-moz-user-select: none;
user-select: none;
}
menuitem:hover {
background: #3780fb;
color: white;
cursor: pointer;
}
menuitem[disabled=true] {
color: #cccccc;
}
menuitem[disabled=true]:hover {
background-color: transparent;
cursor: default;
}
menuitem[type=checkbox]::before {
content: "";
width: 10px;
display: inline-block;
}
menuitem[type=checkbox][checked=true]::before {
content: "\2713";
left: -8px;
position: relative;
}
menuseparator {
border-bottom: 1px solid #cacdd3;
width: 100%;
height: 5px;
display: block;
margin-bottom: 5px;
}
#contextmenu-mask.show {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
}

9634
devtools/client/debugger/new/dist/vendors.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -3,29 +3,25 @@
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html>
<html dir="">
<head>
<link rel="stylesheet"
type="text/css"
href="chrome://devtools/content/sourceeditor/codemirror/lib/codemirror.css" />
<link rel="stylesheet"
type="text/css"
href="chrome://devtools/content/sourceeditor/codemirror/addon/dialog/dialog.css" />
<link rel="stylesheet"
type="text/css"
href="chrome://devtools/content/sourceeditor/codemirror/mozilla.css" />
<link rel="stylesheet" type="text/css" href="resource://devtools/client/debugger/new/debugger.css" />
</head>
<body>
<div id="mount"></div>
<script type="application/javascript"
src="chrome://devtools/content/shared/theme-switching.js"></script>
<script type="text/javascript">
const { BrowserLoader } = ChromeUtils.import("resource://devtools/client/shared/browser-loader.js", {});
const { require } = BrowserLoader({
baseURI: "resource://devtools/client/debugger/new/",
window,
});
Debugger = require("devtools/client/debugger/new/debugger");
</script>
</body>
</html>
<head>
<link rel="stylesheet" type="text/css" href="chrome://devtools/content/sourceeditor/codemirror/lib/codemirror.css" />
<link rel="stylesheet" type="text/css" href="chrome://devtools/content/sourceeditor/codemirror/addon/dialog/dialog.css" />
<link rel="stylesheet" type="text/css" href="chrome://devtools/content/sourceeditor/codemirror/mozilla.css" />
<link rel="stylesheet" type="text/css" href="resource://devtools/client/debugger/new/dist/debugger.css" />
</head>
<body>
<div id="mount"></div>
<script type="application/javascript" src="chrome://devtools/content/shared/theme-switching.js"></script>
<script type="text/javascript">
const { BrowserLoader } = ChromeUtils.import("resource://devtools/client/shared/browser-loader.js", {});
const { require } = BrowserLoader({
baseURI: "resource://devtools/client/debugger/new",
window,
});
Debugger = require("devtools/client/debugger/new/src/main");
</script>
</body>
</html>

Просмотреть файл

@ -3,11 +3,11 @@
# 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/.
DIRS += [
'dist',
'src',
]
DevToolsModules(
'debugger.css',
'debugger.js',
'panel.js',
'parser-worker.js',
'pretty-print-worker.js',
'search-worker.js',
)

Просмотреть файл

@ -0,0 +1,127 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setSourceMetaData = setSourceMetaData;
exports.setSymbols = setSymbols;
exports.setOutOfScopeLocations = setOutOfScopeLocations;
exports.setPausePoints = setPausePoints;
var _selectors = require("../selectors/index");
var _pause = require("./pause/index");
var _setInScopeLines = require("./ast/setInScopeLines");
var _parser = require("../workers/parser/index");
var _promise = require("./utils/middleware/promise");
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _prefs = require("../utils/prefs");
/* 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/>. */
function setSourceMetaData(sourceId) {
return async ({
dispatch,
getState
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
if (!source || !source.text || source.isWasm) {
return;
}
const framework = await (0, _parser.getFramework)(source.id);
dispatch({
type: "SET_SOURCE_METADATA",
sourceId: source.id,
sourceMetaData: {
framework
}
});
};
}
function setSymbols(sourceId) {
return async ({
dispatch,
getState
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
if (!source || !source.text || source.isWasm || (0, _selectors.hasSymbols)(getState(), source)) {
return;
}
await dispatch({
type: "SET_SYMBOLS",
sourceId,
[_promise.PROMISE]: (0, _parser.getSymbols)(sourceId)
});
if ((0, _selectors.isPaused)(getState())) {
await dispatch((0, _pause.fetchExtra)());
await dispatch((0, _pause.mapFrames)());
}
await dispatch(setPausePoints(sourceId));
await dispatch(setSourceMetaData(sourceId));
};
}
function setOutOfScopeLocations() {
return async ({
dispatch,
getState
}) => {
const location = (0, _selectors.getSelectedLocation)(getState());
if (!location) {
return;
}
const source = (0, _selectors.getSource)(getState(), location.sourceId);
let locations = null;
if (location.line && source && (0, _selectors.isPaused)(getState())) {
locations = await (0, _parser.findOutOfScopeLocations)(source.get("id"), location);
}
dispatch({
type: "OUT_OF_SCOPE_LOCATIONS",
locations
});
dispatch((0, _setInScopeLines.setInScopeLines)());
};
}
function setPausePoints(sourceId) {
return async ({
dispatch,
getState,
client
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
if (!_prefs.features.pausePoints || !source || !source.text || source.isWasm) {
return;
}
const pausePoints = await (0, _parser.getPausePoints)(source.id);
if ((0, _devtoolsSourceMap.isGeneratedId)(source.id)) {
await client.setPausePoints(source.id, pausePoints);
}
dispatch({
type: "SET_PAUSE_POINTS",
source: source.toJS(),
pausePoints
});
};
}

Просмотреть файл

@ -0,0 +1,12 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'setInScopeLines.js',
)

Просмотреть файл

@ -0,0 +1,46 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setInScopeLines = setInScopeLines;
var _selectors = require("../../selectors/index");
var _source = require("../../utils/source");
var _lodash = require("devtools/client/shared/vendor/lodash");
/* 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/>. */
function getOutOfScopeLines(outOfScopeLocations) {
if (!outOfScopeLocations) {
return null;
}
return (0, _lodash.uniq)((0, _lodash.flatMap)(outOfScopeLocations, location => (0, _lodash.range)(location.start.line, location.end.line)));
}
function setInScopeLines() {
return ({
dispatch,
getState
}) => {
const sourceRecord = (0, _selectors.getSelectedSource)(getState());
const outOfScopeLocations = (0, _selectors.getOutOfScopeLocations)(getState());
if (!sourceRecord || !sourceRecord.text) {
return;
}
const linesOutOfScope = getOutOfScopeLines(outOfScopeLocations);
const sourceNumLines = (0, _source.getSourceLineCount)(sourceRecord);
const sourceLines = (0, _lodash.range)(1, sourceNumLines + 1);
const inScopeLines = !linesOutOfScope ? sourceLines : (0, _lodash.without)(sourceLines, ...linesOutOfScope);
dispatch({
type: "IN_SCOPE_LINES",
lines: inScopeLines
});
};
}

Просмотреть файл

@ -0,0 +1,497 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.syncBreakpoint = syncBreakpoint;
exports.addBreakpoint = addBreakpoint;
exports.addHiddenBreakpoint = addHiddenBreakpoint;
exports.removeBreakpoint = removeBreakpoint;
exports.enableBreakpoint = enableBreakpoint;
exports.disableBreakpoint = disableBreakpoint;
exports.toggleAllBreakpoints = toggleAllBreakpoints;
exports.toggleBreakpoints = toggleBreakpoints;
exports.removeAllBreakpoints = removeAllBreakpoints;
exports.removeBreakpoints = removeBreakpoints;
exports.remapBreakpoints = remapBreakpoints;
exports.setBreakpointCondition = setBreakpointCondition;
exports.toggleBreakpoint = toggleBreakpoint;
exports.addOrToggleDisabledBreakpoint = addOrToggleDisabledBreakpoint;
exports.toggleDisabledBreakpoint = toggleDisabledBreakpoint;
var _promise = require("./utils/middleware/promise");
var _selectors = require("../selectors/index");
var _breakpoint = require("../utils/breakpoint/index");
var _addBreakpoint = require("./breakpoints/addBreakpoint");
var _addBreakpoint2 = _interopRequireDefault(_addBreakpoint);
var _remapLocations = require("./breakpoints/remapLocations");
var _remapLocations2 = _interopRequireDefault(_remapLocations);
var _ast = require("../reducers/ast");
var _syncBreakpoint = require("./breakpoints/syncBreakpoint");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Syncing a breakpoint add breakpoint information that is stored, and
* contact the server for more data.
*
* @memberof actions/breakpoints
* @static
* @param {String} $1.sourceId String value
* @param {PendingBreakpoint} $1.location PendingBreakpoint value
*/
function syncBreakpoint(sourceId, pendingBreakpoint) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const {
breakpoint,
previousLocation
} = await (0, _syncBreakpoint.syncClientBreakpoint)(getState, client, sourceMaps, sourceId, pendingBreakpoint);
return dispatch({
type: "SYNC_BREAKPOINT",
breakpoint,
previousLocation
});
};
}
/**
* Add a new breakpoint
*
* @memberof actions/breakpoints
* @static
* @param {String} $1.condition Conditional breakpoint condition value
* @param {Boolean} $1.disabled Disable value for breakpoint value
*/
function addBreakpoint(location, {
condition,
hidden
} = {}) {
const breakpoint = (0, _breakpoint.createBreakpoint)(location, {
condition,
hidden
});
return ({
dispatch,
getState,
sourceMaps,
client
}) => {
return dispatch({
type: "ADD_BREAKPOINT",
breakpoint,
[_promise.PROMISE]: (0, _addBreakpoint2.default)(getState, client, sourceMaps, breakpoint)
});
};
}
/**
* Add a new hidden breakpoint
*
* @memberOf actions/breakpoints
* @param location
* @return {function(ThunkArgs)}
*/
function addHiddenBreakpoint(location) {
return ({
dispatch
}) => {
return dispatch(addBreakpoint(location, {
hidden: true
}));
};
}
/**
* Remove a single breakpoint
*
* @memberof actions/breakpoints
* @static
*/
function removeBreakpoint(location) {
return ({
dispatch,
getState,
client
}) => {
const bp = (0, _selectors.getBreakpoint)(getState(), location);
if (!bp || bp.loading) {
return;
} // If the breakpoint is already disabled, we don't need to communicate
// with the server. We just need to dispatch an action
// simulating a successful server request
if (bp.disabled) {
return dispatch({
type: "REMOVE_BREAKPOINT",
breakpoint: bp,
status: "done"
});
}
return dispatch({
type: "REMOVE_BREAKPOINT",
breakpoint: bp,
disabled: false,
[_promise.PROMISE]: client.removeBreakpoint(bp.generatedLocation)
});
};
}
/**
* Enabling a breakpoint
* will reuse the existing breakpoint information that is stored.
*
* @memberof actions/breakpoints
* @static
* @param {Location} $1.location Location value
*/
function enableBreakpoint(location) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const breakpoint = (0, _selectors.getBreakpoint)(getState(), location);
if (!breakpoint || breakpoint.loading) {
return;
}
return dispatch({
type: "ENABLE_BREAKPOINT",
breakpoint,
[_promise.PROMISE]: (0, _addBreakpoint2.default)(getState, client, sourceMaps, breakpoint)
});
};
}
/**
* Disable a single breakpoint
*
* @memberof actions/breakpoints
* @static
*/
function disableBreakpoint(location) {
return async ({
dispatch,
getState,
client
}) => {
const bp = (0, _selectors.getBreakpoint)(getState(), location);
if (!bp || bp.loading) {
return;
}
await client.removeBreakpoint(bp.generatedLocation);
const newBreakpoint = _objectSpread({}, bp, {
disabled: true
});
return dispatch({
type: "DISABLE_BREAKPOINT",
breakpoint: newBreakpoint
});
};
}
/**
* Toggle All Breakpoints
*
* @memberof actions/breakpoints
* @static
*/
function toggleAllBreakpoints(shouldDisableBreakpoints) {
return async ({
dispatch,
getState,
client
}) => {
const breakpoints = (0, _selectors.getBreakpoints)(getState());
const modifiedBreakpoints = [];
for (const [, breakpoint] of breakpoints) {
if (shouldDisableBreakpoints) {
await client.removeBreakpoint(breakpoint.generatedLocation);
const newBreakpoint = _objectSpread({}, breakpoint, {
disabled: true
});
modifiedBreakpoints.push(newBreakpoint);
} else {
const newBreakpoint = _objectSpread({}, breakpoint, {
disabled: false
});
modifiedBreakpoints.push(newBreakpoint);
}
}
if (shouldDisableBreakpoints) {
return dispatch({
type: "DISABLE_ALL_BREAKPOINTS",
breakpoints: modifiedBreakpoints
});
}
return dispatch({
type: "ENABLE_ALL_BREAKPOINTS",
breakpoints: modifiedBreakpoints
});
};
}
/**
* Toggle Breakpoints
*
* @memberof actions/breakpoints
* @static
*/
function toggleBreakpoints(shouldDisableBreakpoints, breakpoints) {
return async ({
dispatch
}) => {
for (const [, breakpoint] of breakpoints) {
if (shouldDisableBreakpoints) {
await dispatch(disableBreakpoint(breakpoint.location));
} else {
await dispatch(enableBreakpoint(breakpoint.location));
}
}
};
}
/**
* Removes all breakpoints
*
* @memberof actions/breakpoints
* @static
*/
function removeAllBreakpoints() {
return async ({
dispatch,
getState
}) => {
const breakpoints = (0, _selectors.getBreakpoints)(getState());
for (const [, breakpoint] of breakpoints) {
await dispatch(removeBreakpoint(breakpoint.location));
}
};
}
/**
* Removes breakpoints
*
* @memberof actions/breakpoints
* @static
*/
function removeBreakpoints(breakpoints) {
return async ({
dispatch
}) => {
for (const [, breakpoint] of breakpoints) {
await dispatch(removeBreakpoint(breakpoint.location));
}
};
}
function remapBreakpoints(sourceId) {
return async ({
dispatch,
getState,
sourceMaps
}) => {
const breakpoints = (0, _selectors.getBreakpoints)(getState());
const newBreakpoints = await (0, _remapLocations2.default)(breakpoints, sourceId, sourceMaps);
return dispatch({
type: "REMAP_BREAKPOINTS",
breakpoints: newBreakpoints
});
};
}
/**
* Update the condition of a breakpoint.
*
* @throws {Error} "not implemented"
* @memberof actions/breakpoints
* @static
* @param {Location} location
* @see DebuggerController.Breakpoints.addBreakpoint
* @param {string} condition
* The condition to set on the breakpoint
* @param {Boolean} $1.disabled Disable value for breakpoint value
*/
function setBreakpointCondition(location, {
condition
} = {}) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const bp = (0, _selectors.getBreakpoint)(getState(), location);
if (!bp) {
return dispatch(addBreakpoint(location, {
condition
}));
}
if (bp.loading) {
return;
}
if (bp.disabled) {
await dispatch(enableBreakpoint(location));
bp.disabled = !bp.disabled;
}
await client.setBreakpointCondition(bp.id, location, condition, sourceMaps.isOriginalId(bp.location.sourceId));
const newBreakpoint = _objectSpread({}, bp, {
condition
});
(0, _breakpoint.assertBreakpoint)(newBreakpoint);
return dispatch({
type: "SET_BREAKPOINT_CONDITION",
breakpoint: newBreakpoint
});
};
}
function toggleBreakpoint(line, column) {
return ({
dispatch,
getState,
client,
sourceMaps
}) => {
if (!line) {
return;
}
const state = getState();
const selectedSource = (0, _selectors.getSelectedSource)(state);
const bp = (0, _selectors.getBreakpointAtLocation)(state, {
line,
column
});
const isEmptyLine = (0, _ast.isEmptyLineInSource)(state, line, selectedSource);
if (!bp && isEmptyLine || bp && bp.loading) {
return;
}
if (bp) {
// NOTE: it's possible the breakpoint has slid to a column
return dispatch(removeBreakpoint({
sourceId: bp.location.sourceId,
sourceUrl: bp.location.sourceUrl,
line: bp.location.line,
column: column || bp.location.column
}));
}
return dispatch(addBreakpoint({
sourceId: selectedSource.get("id"),
sourceUrl: selectedSource.get("url"),
line: line,
column: column
}));
};
}
function addOrToggleDisabledBreakpoint(line, column) {
return ({
dispatch,
getState,
client,
sourceMaps
}) => {
if (!line) {
return;
}
const selectedSource = (0, _selectors.getSelectedSource)(getState());
const bp = (0, _selectors.getBreakpointAtLocation)(getState(), {
line,
column
});
if (bp && bp.loading) {
return;
}
if (bp) {
// NOTE: it's possible the breakpoint has slid to a column
return dispatch(toggleDisabledBreakpoint(line, column || bp.location.column));
}
return dispatch(addBreakpoint({
sourceId: selectedSource.get("id"),
sourceUrl: selectedSource.get("url"),
line: line,
column: column
}));
};
}
function toggleDisabledBreakpoint(line, column) {
return ({
dispatch,
getState,
client,
sourceMaps
}) => {
const bp = (0, _selectors.getBreakpointAtLocation)(getState(), {
line,
column
});
if (!bp || bp.loading) {
return;
}
if (!bp.disabled) {
return dispatch(disableBreakpoint(bp.location));
}
return dispatch(enableBreakpoint(bp.location));
};
}

Просмотреть файл

@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = addBreakpoint;
var _breakpoint = require("../../utils/breakpoint/index");
var _selectors = require("../../selectors/index");
var _sourceMaps = require("../../utils/source-maps");
var _source = require("../../utils/source");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
async function addBreakpoint(getState, client, sourceMaps, breakpoint) {
const state = getState();
const source = (0, _selectors.getSource)(state, breakpoint.location.sourceId);
const location = _objectSpread({}, breakpoint.location, {
sourceUrl: source.url
});
const generatedLocation = await (0, _sourceMaps.getGeneratedLocation)(state, source, location, sourceMaps);
const generatedSource = (0, _selectors.getSource)(state, generatedLocation.sourceId);
(0, _breakpoint.assertLocation)(location);
(0, _breakpoint.assertLocation)(generatedLocation);
if ((0, _breakpoint.breakpointExists)(state, location)) {
const newBreakpoint = _objectSpread({}, breakpoint, {
location,
generatedLocation
});
(0, _breakpoint.assertBreakpoint)(newBreakpoint);
return {
breakpoint: newBreakpoint
};
}
const {
id,
hitCount,
actualLocation
} = await client.setBreakpoint(generatedLocation, breakpoint.condition, sourceMaps.isOriginalId(location.sourceId));
const newGeneratedLocation = actualLocation || generatedLocation;
const newLocation = await sourceMaps.getOriginalLocation(newGeneratedLocation);
const symbols = (0, _selectors.getSymbols)(getState(), source);
const astLocation = await (0, _breakpoint.getASTLocation)(source, symbols, newLocation);
const originalText = (0, _source.getTextAtPosition)(source, location);
const text = (0, _source.getTextAtPosition)(generatedSource, actualLocation);
const newBreakpoint = {
id,
disabled: false,
hidden: breakpoint.hidden,
loading: false,
condition: breakpoint.condition,
location: newLocation,
astLocation,
hitCount,
generatedLocation: newGeneratedLocation,
text,
originalText
};
(0, _breakpoint.assertBreakpoint)(newBreakpoint);
const previousLocation = (0, _breakpoint.locationMoved)(location, newLocation) ? location : null;
return {
breakpoint: newBreakpoint,
previousLocation
};
}

Просмотреть файл

@ -0,0 +1,14 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'addBreakpoint.js',
'remapLocations.js',
'syncBreakpoint.js',
)

Просмотреть файл

@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = remapLocations;
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/* 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/>. */
function remapLocations(breakpoints, sourceId, sourceMaps) {
const sourceBreakpoints = breakpoints.map(async breakpoint => {
if (breakpoint.location.sourceId !== sourceId) {
return breakpoint;
}
const location = await sourceMaps.getOriginalLocation(breakpoint.location);
return _objectSpread({}, breakpoint, {
location
});
});
return Promise.all(sourceBreakpoints.valueSeq());
}

Просмотреть файл

@ -0,0 +1,119 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.syncClientBreakpoint = syncClientBreakpoint;
var _breakpoint = require("../../utils/breakpoint/index");
var _sourceMaps = require("../../utils/source-maps");
var _source = require("../../utils/source");
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _selectors = require("../../selectors/index");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
async function makeScopedLocation({
name,
offset
}, location, source) {
const scope = await (0, _breakpoint.findScopeByName)(source, name); // fallback onto the location line, if the scope is not found
// note: we may at some point want to delete the breakpoint if the scope
// disappears
const line = scope ? scope.location.start.line + offset.line : location.line;
return {
line,
column: location.column,
sourceUrl: source.url,
sourceId: source.id
};
}
function createSyncData(id, pendingBreakpoint, location, generatedLocation, previousLocation, text, originalText) {
const overrides = _objectSpread({}, pendingBreakpoint, {
generatedLocation,
id,
text,
originalText
});
const breakpoint = (0, _breakpoint.createBreakpoint)(location, overrides);
(0, _breakpoint.assertBreakpoint)(breakpoint);
return {
breakpoint,
previousLocation
};
} // we have three forms of syncing: disabled syncing, existing server syncing
// and adding a new breakpoint
async function syncClientBreakpoint(getState, client, sourceMaps, sourceId, pendingBreakpoint) {
(0, _breakpoint.assertPendingBreakpoint)(pendingBreakpoint);
const source = (0, _selectors.getSource)(getState(), sourceId);
const generatedSourceId = sourceMaps.isOriginalId(sourceId) ? (0, _devtoolsSourceMap.originalToGeneratedId)(sourceId) : sourceId;
const generatedSource = (0, _selectors.getSource)(getState(), generatedSourceId);
const {
location,
astLocation
} = pendingBreakpoint;
const previousLocation = _objectSpread({}, location, {
sourceId
});
const scopedLocation = await makeScopedLocation(astLocation, previousLocation, source);
const scopedGeneratedLocation = await (0, _sourceMaps.getGeneratedLocation)(getState(), source, scopedLocation, sourceMaps); // this is the generatedLocation of the pending breakpoint, with
// the source id updated to reflect the new connection
const generatedLocation = _objectSpread({}, pendingBreakpoint.generatedLocation, {
sourceId: generatedSourceId
});
const isSameLocation = !(0, _breakpoint.locationMoved)(generatedLocation, scopedGeneratedLocation);
const existingClient = client.getBreakpointByLocation(generatedLocation);
/** ******* CASE 1: No server change ***********/
// early return if breakpoint is disabled or we are in the sameLocation
// send update only to redux
if (pendingBreakpoint.disabled || existingClient && isSameLocation) {
const id = pendingBreakpoint.disabled ? "" : existingClient.id;
const originalText = (0, _source.getTextAtPosition)(source, previousLocation);
const text = (0, _source.getTextAtPosition)(generatedSource, generatedLocation);
return createSyncData(id, pendingBreakpoint, scopedLocation, scopedGeneratedLocation, previousLocation, text, originalText);
} // clear server breakpoints if they exist and we have moved
if (existingClient) {
await client.removeBreakpoint(generatedLocation);
}
/** ******* Case 2: Add New Breakpoint ***********/
// If we are not disabled, set the breakpoint on the server and get
// that info so we can set it on our breakpoints.
if (!scopedGeneratedLocation.line) {
return {
previousLocation,
breakpoint: null
};
}
const {
id,
actualLocation
} = await client.setBreakpoint(scopedGeneratedLocation, pendingBreakpoint.condition, sourceMaps.isOriginalId(sourceId)); // the breakpoint might have slid server side, so we want to get the location
// based on the server's return value
const newGeneratedLocation = actualLocation;
const newLocation = await sourceMaps.getOriginalLocation(newGeneratedLocation);
const originalText = (0, _source.getTextAtPosition)(source, newLocation);
const text = (0, _source.getTextAtPosition)(generatedSource, newGeneratedLocation);
return createSyncData(id, pendingBreakpoint, newLocation, newGeneratedLocation, previousLocation, text, originalText);
}

Просмотреть файл

@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.recordCoverage = recordCoverage;
/* 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/>. */
function recordCoverage() {
return async function ({
dispatch,
getState,
client
}) {
const {
coverage
} = await client.recordCoverage();
return dispatch({
type: "RECORD_COVERAGE",
value: {
coverage
}
});
};
}

Просмотреть файл

@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.updateWorkers = updateWorkers;
/* 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/>. */
function updateWorkers() {
return async function ({
dispatch,
client
}) {
const {
workers
} = await client.fetchWorkers();
dispatch({
type: "SET_WORKERS",
workers
});
};
}

Просмотреть файл

@ -0,0 +1,180 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.fetchEventListeners = fetchEventListeners;
exports.updateEventBreakpoints = updateEventBreakpoints;
var _DevToolsUtils = require("../utils/DevToolsUtils");
var _selectors = require("../selectors/index");
var _waitService = require("./utils/middleware/wait-service");
/* 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/>. */
/* global window gThreadClient setNamedTimeout EVENTS */
/* eslint no-shadow: 0 */
/**
* Redux actions for the event listeners state
* @module actions/event-listeners
*/
// delay is in ms
const FETCH_EVENT_LISTENERS_DELAY = 200;
let fetchListenersTimerID;
/**
* @memberof utils/utils
* @static
*/
async function asPaused(state, client, func) {
if (!(0, _selectors.isPaused)(state)) {
await client.interrupt();
let result;
try {
result = await func(client);
} catch (e) {
// Try to put the debugger back in a working state by resuming
// it
await client.resume();
throw e;
}
await client.resume();
return result;
}
return func(client);
}
/**
* @memberof actions/event-listeners
* @static
*/
function fetchEventListeners() {
return ({
dispatch,
getState,
client
}) => {
// Make sure we"re not sending a batch of closely repeated requests.
// This can easily happen whenever new sources are fetched.
if (fetchListenersTimerID) {
clearTimeout(fetchListenersTimerID);
}
fetchListenersTimerID = setTimeout(() => {
// In case there is still a request of listeners going on (it
// takes several RDP round trips right now), make sure we wait
// on a currently running request
if (getState().eventListeners.fetchingListeners) {
dispatch({
type: _waitService.NAME,
predicate: action => action.type === "FETCH_EVENT_LISTENERS" && action.status === "done",
run: dispatch => dispatch(fetchEventListeners())
});
return;
}
dispatch({
type: "FETCH_EVENT_LISTENERS",
status: "begin"
});
asPaused(getState(), client, _getEventListeners).then(listeners => {
dispatch({
type: "FETCH_EVENT_LISTENERS",
status: "done",
listeners: formatListeners(getState(), listeners)
});
});
}, FETCH_EVENT_LISTENERS_DELAY);
};
}
function formatListeners(state, listeners) {
return listeners.map(l => {
return {
selector: l.node.selector,
type: l.type,
sourceId: (0, _selectors.getSourceByURL)(state, l.function.location.url).get("id"),
line: l.function.location.line
};
});
}
async function _getEventListeners(threadClient) {
const response = await threadClient.eventListeners(); // Make sure all the listeners are sorted by the event type, since
// they"re not guaranteed to be clustered together.
response.listeners.sort((a, b) => a.type > b.type ? 1 : -1); // Add all the listeners in the debugger view event linsteners container.
const fetchedDefinitions = new Map();
const listeners = [];
for (const listener of response.listeners) {
let definitionSite;
if (fetchedDefinitions.has(listener.function.actor)) {
definitionSite = fetchedDefinitions.get(listener.function.actor);
} else if (listener.function.class == "Function") {
definitionSite = await _getDefinitionSite(threadClient, listener.function);
if (!definitionSite) {
// We don"t know where this listener comes from so don"t show it in
// the UI as breaking on it doesn"t work (bug 942899).
continue;
}
fetchedDefinitions.set(listener.function.actor, definitionSite);
}
listener.function.url = definitionSite;
listeners.push(listener);
}
fetchedDefinitions.clear();
return listeners;
}
async function _getDefinitionSite(threadClient, func) {
const grip = threadClient.pauseGrip(func);
let response;
try {
response = await grip.getDefinitionSite();
} catch (e) {
// Don't make this error fatal, it would break the entire events pane.
(0, _DevToolsUtils.reportException)("_getDefinitionSite", e);
return null;
}
return response.source.url;
}
/**
* @memberof actions/event-listeners
* @static
* @param {string} eventNames
*/
function updateEventBreakpoints(eventNames) {
return dispatch => {
setNamedTimeout("event-breakpoints-update", 0, () => {
gThreadClient.pauseOnDOMEvents(eventNames, () => {
// Notify that event breakpoints were added/removed on the server.
window.emit(EVENTS.EVENT_BREAKPOINTS_UPDATED);
dispatch({
type: "UPDATE_EVENT_BREAKPOINTS",
eventNames: eventNames
});
});
});
};
}

Просмотреть файл

@ -0,0 +1,218 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addExpression = addExpression;
exports.autocomplete = autocomplete;
exports.clearExpressionError = clearExpressionError;
exports.updateExpression = updateExpression;
exports.deleteExpression = deleteExpression;
exports.evaluateExpressions = evaluateExpressions;
exports.getMappedExpression = getMappedExpression;
var _selectors = require("../selectors/index");
var _promise = require("./utils/middleware/promise");
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _expressions = require("../utils/expressions");
var _parser = require("../workers/parser/index");
var parser = _interopRequireWildcard(_parser);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
/* 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/>. */
/**
* Add expression for debugger to watch
*
* @param {object} expression
* @param {number} expression.id
* @memberof actions/pause
* @static
*/
function addExpression(input) {
return async ({
dispatch,
getState
}) => {
if (!input) {
return;
}
const expressionError = await parser.hasSyntaxError(input);
const expression = (0, _selectors.getExpression)(getState(), input);
if (expression) {
return dispatch(evaluateExpression(expression));
}
dispatch({
type: "ADD_EXPRESSION",
input,
expressionError
});
const newExpression = (0, _selectors.getExpression)(getState(), input);
if (newExpression) {
return dispatch(evaluateExpression(newExpression));
}
};
}
function autocomplete(input, cursor) {
return async ({
dispatch,
getState,
client
}) => {
if (!input) {
return;
}
const frameId = (0, _selectors.getSelectedFrameId)(getState());
const result = await client.autocomplete(input, cursor, frameId);
await dispatch({
type: "AUTOCOMPLETE",
input,
result
});
};
}
function clearExpressionError() {
return {
type: "CLEAR_EXPRESSION_ERROR"
};
}
function updateExpression(input, expression) {
return async ({
dispatch,
getState
}) => {
if (!input) {
return;
}
const expressionError = await parser.hasSyntaxError(input);
dispatch({
type: "UPDATE_EXPRESSION",
expression,
input: expressionError ? expression.input : input,
expressionError
});
dispatch(evaluateExpressions());
};
}
/**
*
* @param {object} expression
* @param {number} expression.id
* @memberof actions/pause
* @static
*/
function deleteExpression(expression) {
return ({
dispatch
}) => {
dispatch({
type: "DELETE_EXPRESSION",
input: expression.input
});
};
}
/**
*
* @memberof actions/pause
* @param {number} selectedFrameId
* @static
*/
function evaluateExpressions() {
return async function ({
dispatch,
getState,
client
}) {
const expressions = (0, _selectors.getExpressions)(getState()).toJS();
const inputs = expressions.map(({
input
}) => input);
const frameId = (0, _selectors.getSelectedFrameId)(getState());
const results = await client.evaluateExpressions(inputs, frameId);
dispatch({
type: "EVALUATE_EXPRESSIONS",
inputs,
results
});
};
}
function evaluateExpression(expression) {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
if (!expression.input) {
console.warn("Expressions should not be empty");
return;
}
let input = expression.input;
const frame = (0, _selectors.getSelectedFrame)(getState());
if (frame) {
const {
location
} = frame;
const source = (0, _selectors.getSource)(getState(), location.sourceId);
const sourceId = source.get("id");
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (selectedSource && !(0, _devtoolsSourceMap.isGeneratedId)(sourceId) && !(0, _devtoolsSourceMap.isGeneratedId)(selectedSource.get("id"))) {
input = await dispatch(getMappedExpression(input));
}
}
const frameId = (0, _selectors.getSelectedFrameId)(getState());
return dispatch({
type: "EVALUATE_EXPRESSION",
input: expression.input,
[_promise.PROMISE]: client.evaluateInFrame((0, _expressions.wrapExpression)(input), frameId)
});
};
}
/**
* Gets information about original variable names from the source map
* and replaces all posible generated names.
*/
function getMappedExpression(expression) {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
const mappings = (0, _selectors.getSelectedScopeMappings)(getState());
if (!mappings) {
return expression;
}
return parser.mapOriginalExpression(expression, mappings);
};
}

Просмотреть файл

@ -0,0 +1,201 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.doSearch = doSearch;
exports.doSearchForHighlight = doSearchForHighlight;
exports.setFileSearchQuery = setFileSearchQuery;
exports.toggleFileSearchModifier = toggleFileSearchModifier;
exports.updateSearchResults = updateSearchResults;
exports.searchContents = searchContents;
exports.searchContentsForHighlight = searchContentsForHighlight;
exports.traverseResults = traverseResults;
exports.closeFileSearch = closeFileSearch;
var _editor = require("../utils/editor/index");
var _search = require("../workers/search/index");
var _selectors = require("../selectors/index");
var _ui = require("./ui");
/* 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/>. */
function doSearch(query, editor) {
return ({
getState,
dispatch
}) => {
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!selectedSource || !selectedSource.text) {
return;
}
dispatch(setFileSearchQuery(query));
dispatch(searchContents(query, editor));
};
}
function doSearchForHighlight(query, editor, line, ch) {
return async ({
getState,
dispatch
}) => {
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!selectedSource || !selectedSource.text) {
return;
}
dispatch(searchContentsForHighlight(query, editor, line, ch));
};
}
function setFileSearchQuery(query) {
return {
type: "UPDATE_FILE_SEARCH_QUERY",
query
};
}
function toggleFileSearchModifier(modifier) {
return {
type: "TOGGLE_FILE_SEARCH_MODIFIER",
modifier
};
}
function updateSearchResults(characterIndex, line, matches) {
const matchIndex = matches.findIndex(elm => elm.line === line && elm.ch === characterIndex);
return {
type: "UPDATE_SEARCH_RESULTS",
results: {
matches,
matchIndex,
count: matches.length,
index: characterIndex
}
};
}
function searchContents(query, editor) {
return async ({
getState,
dispatch
}) => {
const modifiers = (0, _selectors.getFileSearchModifiers)(getState());
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!query || !editor || !selectedSource || !selectedSource.text || !modifiers) {
return;
}
const ctx = {
ed: editor,
cm: editor.codeMirror
};
const _modifiers = modifiers.toJS();
const matches = await (0, _search.getMatches)(query, selectedSource.text, _modifiers);
const res = (0, _editor.find)(ctx, query, true, _modifiers);
if (!res) {
return;
}
const {
ch,
line
} = res;
dispatch(updateSearchResults(ch, line, matches));
};
}
function searchContentsForHighlight(query, editor, line, ch) {
return async ({
getState,
dispatch
}) => {
const modifiers = (0, _selectors.getFileSearchModifiers)(getState());
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!query || !editor || !selectedSource || !selectedSource.text || !modifiers) {
return;
}
const ctx = {
ed: editor,
cm: editor.codeMirror
};
const _modifiers = modifiers.toJS();
(0, _editor.searchSourceForHighlight)(ctx, false, query, true, _modifiers, line, ch);
};
}
function traverseResults(rev, editor) {
return async ({
getState,
dispatch
}) => {
if (!editor) {
return;
}
const ctx = {
ed: editor,
cm: editor.codeMirror
};
const query = (0, _selectors.getFileSearchQuery)(getState());
const modifiers = (0, _selectors.getFileSearchModifiers)(getState());
const {
matches
} = (0, _selectors.getFileSearchResults)(getState());
if (query === "") {
dispatch((0, _ui.setActiveSearch)("file"));
}
if (modifiers) {
const matchedLocations = matches || [];
const results = rev ? (0, _editor.findPrev)(ctx, query, true, modifiers.toJS()) : (0, _editor.findNext)(ctx, query, true, modifiers.toJS());
if (!results) {
return;
}
const {
ch,
line
} = results;
dispatch(updateSearchResults(ch, line, matchedLocations));
}
};
}
function closeFileSearch(editor) {
return ({
getState,
dispatch
}) => {
const query = (0, _selectors.getFileSearchQuery)(getState());
if (editor) {
const ctx = {
ed: editor,
cm: editor.codeMirror
};
(0, _editor.removeOverlay)(ctx, query);
}
dispatch(setFileSearchQuery(""));
dispatch((0, _ui.closeActiveSearch)());
dispatch((0, _ui.clearHighlightLineRange)());
};
}

Просмотреть файл

@ -0,0 +1,81 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _breakpoints = require("./breakpoints");
var breakpoints = _interopRequireWildcard(_breakpoints);
var _expressions = require("./expressions");
var expressions = _interopRequireWildcard(_expressions);
var _eventListeners = require("./event-listeners");
var eventListeners = _interopRequireWildcard(_eventListeners);
var _pause = require("./pause/index");
var pause = _interopRequireWildcard(_pause);
var _navigation = require("./navigation");
var navigation = _interopRequireWildcard(_navigation);
var _ui = require("./ui");
var ui = _interopRequireWildcard(_ui);
var _fileSearch = require("./file-search");
var fileSearch = _interopRequireWildcard(_fileSearch);
var _ast = require("./ast");
var ast = _interopRequireWildcard(_ast);
var _coverage = require("./coverage");
var coverage = _interopRequireWildcard(_coverage);
var _projectTextSearch = require("./project-text-search");
var projectTextSearch = _interopRequireWildcard(_projectTextSearch);
var _replay = require("./replay");
var replay = _interopRequireWildcard(_replay);
var _quickOpen = require("./quick-open");
var quickOpen = _interopRequireWildcard(_quickOpen);
var _sourceTree = require("./source-tree");
var sourceTree = _interopRequireWildcard(_sourceTree);
var _sources = require("./sources/index");
var sources = _interopRequireWildcard(_sources);
var _debuggee = require("./debuggee");
var debuggee = _interopRequireWildcard(_debuggee);
var _toolbox = require("./toolbox");
var toolbox = _interopRequireWildcard(_toolbox);
var _preview = require("./preview");
var preview = _interopRequireWildcard(_preview);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
exports.default = _objectSpread({}, navigation, breakpoints, expressions, eventListeners, sources, pause, ui, fileSearch, ast, coverage, projectTextSearch, replay, quickOpen, sourceTree, debuggee, toolbox, preview);

Просмотреть файл

@ -0,0 +1,31 @@
# vim: set filetype=python:
# 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/.
DIRS += [
'ast',
'breakpoints',
'pause',
'sources',
'utils',
]
DevToolsModules(
'ast.js',
'breakpoints.js',
'coverage.js',
'debuggee.js',
'event-listeners.js',
'expressions.js',
'file-search.js',
'index.js',
'navigation.js',
'preview.js',
'project-text-search.js',
'quick-open.js',
'replay.js',
'source-tree.js',
'toolbox.js',
'ui.js',
)

Просмотреть файл

@ -0,0 +1,103 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.willNavigate = willNavigate;
exports.navigate = navigate;
exports.connect = connect;
exports.navigated = navigated;
var _editor = require("../utils/editor/index");
var _sourceQueue = require("../utils/source-queue");
var _sourceQueue2 = _interopRequireDefault(_sourceQueue);
var _sources = require("../reducers/sources");
var _utils = require("../utils/utils");
var _sources2 = require("./sources/index");
var _debuggee = require("./debuggee");
var _parser = require("../workers/parser/index");
var _wasm = require("../utils/wasm");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
/**
* Redux actions for the navigation state
* @module actions/navigation
*/
/**
* @memberof actions/navigation
* @static
*/
function willNavigate(event) {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
await sourceMaps.clearSourceMaps();
(0, _wasm.clearWasmStates)();
(0, _editor.clearDocuments)();
(0, _editor.removeEditor)();
(0, _parser.clearSymbols)();
(0, _parser.clearASTs)();
(0, _parser.clearScopes)();
(0, _parser.clearSources)();
dispatch(navigate(event.url));
};
}
function navigate(url) {
_sourceQueue2.default.clear();
return {
type: "NAVIGATE",
url
};
}
function connect(url, canRewind) {
return async function ({
dispatch
}) {
await dispatch((0, _debuggee.updateWorkers)());
dispatch({
type: "CONNECT",
url,
canRewind
});
};
}
/**
* @memberof actions/navigation
* @static
*/
function navigated() {
return async function ({
dispatch,
getState,
client
}) {
await (0, _utils.waitForMs)(100);
if ((0, _sources.getSources)(getState()).size == 0) {
const sources = await client.fetchSources();
dispatch((0, _sources2.newSources)(sources));
}
};
}

Просмотреть файл

@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.breakOnNext = breakOnNext;
/* 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/>. */
/**
* Debugger breakOnNext command.
* It's different from the comand action because we also want to
* highlight the pause icon.
*
* @memberof actions/pause
* @static
*/
function breakOnNext() {
return ({
dispatch,
client
}) => {
client.breakOnNext();
return dispatch({
type: "BREAK_ON_NEXT",
value: true
});
};
}

Просмотреть файл

@ -0,0 +1,257 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.command = command;
exports.stepIn = stepIn;
exports.stepOver = stepOver;
exports.stepOut = stepOut;
exports.resume = resume;
exports.rewind = rewind;
exports.reverseStepIn = reverseStepIn;
exports.reverseStepOver = reverseStepOver;
exports.reverseStepOut = reverseStepOut;
exports.astCommand = astCommand;
var _selectors = require("../../selectors/index");
var _promise = require("../utils/middleware/promise");
var _parser = require("../../workers/parser/index");
var _breakpoints = require("../breakpoints");
var _prefs = require("../../utils/prefs");
/* -*- indent-tabs-mode: nil; js-indent-level: 2; js-indent-level: 2 -*- */
/* 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/>. */
/**
* Debugger commands like stepOver, stepIn, stepUp
*
* @param string $0.type
* @memberof actions/pause
* @static
*/
function command(type) {
return async ({
dispatch,
client
}) => {
return dispatch({
type: "COMMAND",
command: type,
[_promise.PROMISE]: client[type]()
});
};
}
/**
* StepIn
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function stepIn() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(command("stepIn"));
}
};
}
/**
* stepOver
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function stepOver() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(astCommand("stepOver"));
}
};
}
/**
* stepOut
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function stepOut() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(command("stepOut"));
}
};
}
/**
* resume
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function resume() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(command("resume"));
}
};
}
/**
* rewind
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function rewind() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(command("rewind"));
}
};
}
/**
* reverseStepIn
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function reverseStepIn() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(command("reverseStepIn"));
}
};
}
/**
* reverseStepOver
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function reverseStepOver() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(astCommand("reverseStepOver"));
}
};
}
/**
* reverseStepOut
* @memberof actions/pause
* @static
* @returns {Function} {@link command}
*/
function reverseStepOut() {
return ({
dispatch,
getState
}) => {
if ((0, _selectors.isPaused)(getState())) {
return dispatch(command("reverseStepOut"));
}
};
}
/*
* Checks for await or yield calls on the paused line
* This avoids potentially expensive parser calls when we are likely
* not at an async expression.
*/
function hasAwait(source, pauseLocation) {
const {
line,
column
} = pauseLocation;
if (!source.text) {
return false;
}
const lineText = source.text.split("\n")[line - 1];
if (!lineText) {
return false;
}
const snippet = lineText.slice(column - 50, column + 50);
return !!snippet.match(/(yield|await)/);
}
/**
* @memberOf actions/pause
* @static
* @param stepType
* @returns {function(ThunkArgs)}
*/
function astCommand(stepType) {
return async ({
dispatch,
getState,
sourceMaps
}) => {
if (!_prefs.features.asyncStepping) {
return dispatch(command(stepType));
}
if (stepType == "stepOver") {
// This type definition is ambiguous:
const frame = (0, _selectors.getTopFrame)(getState());
const source = (0, _selectors.getSource)(getState(), frame.location.sourceId);
if (source && hasAwait(source, frame.location)) {
const nextLocation = await (0, _parser.getNextStep)(source.id, frame.location);
if (nextLocation) {
await dispatch((0, _breakpoints.addHiddenBreakpoint)(nextLocation));
return dispatch(command("resume"));
}
}
}
return dispatch(command(stepType));
};
}

Просмотреть файл

@ -0,0 +1,43 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.continueToHere = continueToHere;
var _selectors = require("../../selectors/index");
var _breakpoints = require("../breakpoints");
var _commands = require("./commands");
/* 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/>. */
function continueToHere(line) {
return async function ({
dispatch,
getState
}) {
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!(0, _selectors.isPaused)(getState()) || !selectedSource) {
return;
}
const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
const debugLine = selectedFrame.location.line;
if (debugLine == line) {
return;
}
const action = (0, _selectors.getCanRewind)(getState()) && line < debugLine ? _commands.rewind : _commands.resume;
await dispatch((0, _breakpoints.addHiddenBreakpoint)({
line,
column: undefined,
sourceId: selectedSource.id
}));
dispatch(action());
};
}

Просмотреть файл

@ -0,0 +1,111 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.fetchExtra = fetchExtra;
exports.getExtra = getExtra;
var _selectors = require("../../selectors/index");
var _preview = require("../../utils/preview");
var _ast = require("../../utils/ast");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
async function getReactProps(evaluate) {
const componentNames = await evaluate(`
if(this.hasOwnProperty('_reactInternalFiber')) {
let componentNames = [];
let componentNode = this._reactInternalFiber;
while(componentNode) {
componentNames.push(componentNode.type.name);
componentNode = componentNode._debugOwner
}
componentNames;
}
else {
[this._reactInternalInstance.getName()];
}
`);
const items = componentNames.result.preview && componentNames.result.preview.items;
if (items) {
return {
displayName: items[0],
componentStack: items
};
}
}
async function getImmutableProps(expression, evaluate) {
const immutableEntries = await evaluate((exp => `${exp}.toJS()`)(expression));
const immutableType = await evaluate((exp => `${exp}.constructor.name`)(expression));
return {
type: immutableType.result,
entries: immutableEntries.result
};
}
async function getExtraProps(getState, expression, result, evaluate) {
const props = {};
if ((0, _preview.isReactComponent)(result)) {
const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
const source = (0, _selectors.getSource)(getState(), selectedFrame.location.sourceId);
const symbols = (0, _selectors.getSymbols)(getState(), source);
if (symbols && symbols.classes) {
const originalClass = (0, _ast.findClosestClass)(symbols, selectedFrame.location);
if (originalClass) {
props.react = {
displayName: originalClass.name
};
}
}
props.react = _objectSpread({}, (await getReactProps(evaluate)), props.react);
}
if ((0, _preview.isImmutable)(result)) {
props.immutable = await getImmutableProps(expression, evaluate);
}
return props;
}
function fetchExtra() {
return async function ({
dispatch,
getState
}) {
const frame = (0, _selectors.getSelectedFrame)(getState());
const extra = await dispatch(getExtra("this;", frame.this));
dispatch({
type: "ADD_EXTRA",
extra: extra
});
};
}
function getExtra(expression, result) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
if (!selectedFrame) {
return;
}
const extra = await getExtraProps(getState, expression, result, expr => client.evaluateInFrame(expr, selectedFrame.id));
return extra;
};
}

Просмотреть файл

@ -0,0 +1,40 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.fetchScopes = fetchScopes;
var _selectors = require("../../selectors/index");
var _mapScopes = require("./mapScopes");
var _promise = require("../utils/middleware/promise");
var _extra = require("./extra");
/* 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/>. */
function fetchScopes() {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
const frame = (0, _selectors.getSelectedFrame)(getState());
if (!frame || (0, _selectors.getGeneratedFrameScope)(getState(), frame.id)) {
return;
}
const scopes = dispatch({
type: "ADD_SCOPES",
frame,
[_promise.PROMISE]: client.getFrameScopes(frame)
});
await dispatch((0, _extra.fetchExtra)());
await dispatch((0, _mapScopes.mapScopes)(scopes, frame));
};
}

Просмотреть файл

@ -0,0 +1,161 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _commands = require("./commands");
Object.defineProperty(exports, "stepIn", {
enumerable: true,
get: function () {
return _commands.stepIn;
}
});
Object.defineProperty(exports, "stepOver", {
enumerable: true,
get: function () {
return _commands.stepOver;
}
});
Object.defineProperty(exports, "stepOut", {
enumerable: true,
get: function () {
return _commands.stepOut;
}
});
Object.defineProperty(exports, "resume", {
enumerable: true,
get: function () {
return _commands.resume;
}
});
Object.defineProperty(exports, "rewind", {
enumerable: true,
get: function () {
return _commands.rewind;
}
});
Object.defineProperty(exports, "reverseStepIn", {
enumerable: true,
get: function () {
return _commands.reverseStepIn;
}
});
Object.defineProperty(exports, "reverseStepOver", {
enumerable: true,
get: function () {
return _commands.reverseStepOver;
}
});
Object.defineProperty(exports, "reverseStepOut", {
enumerable: true,
get: function () {
return _commands.reverseStepOut;
}
});
var _fetchScopes = require("./fetchScopes");
Object.defineProperty(exports, "fetchScopes", {
enumerable: true,
get: function () {
return _fetchScopes.fetchScopes;
}
});
var _paused = require("./paused");
Object.defineProperty(exports, "paused", {
enumerable: true,
get: function () {
return _paused.paused;
}
});
var _resumed = require("./resumed");
Object.defineProperty(exports, "resumed", {
enumerable: true,
get: function () {
return _resumed.resumed;
}
});
var _continueToHere = require("./continueToHere");
Object.defineProperty(exports, "continueToHere", {
enumerable: true,
get: function () {
return _continueToHere.continueToHere;
}
});
var _breakOnNext = require("./breakOnNext");
Object.defineProperty(exports, "breakOnNext", {
enumerable: true,
get: function () {
return _breakOnNext.breakOnNext;
}
});
var _mapFrames = require("./mapFrames");
Object.defineProperty(exports, "mapFrames", {
enumerable: true,
get: function () {
return _mapFrames.mapFrames;
}
});
var _extra = require("./extra");
Object.defineProperty(exports, "fetchExtra", {
enumerable: true,
get: function () {
return _extra.fetchExtra;
}
});
Object.defineProperty(exports, "getExtra", {
enumerable: true,
get: function () {
return _extra.getExtra;
}
});
var _setPopupObjectProperties = require("./setPopupObjectProperties");
Object.defineProperty(exports, "setPopupObjectProperties", {
enumerable: true,
get: function () {
return _setPopupObjectProperties.setPopupObjectProperties;
}
});
var _pauseOnExceptions = require("./pauseOnExceptions");
Object.defineProperty(exports, "pauseOnExceptions", {
enumerable: true,
get: function () {
return _pauseOnExceptions.pauseOnExceptions;
}
});
var _selectFrame = require("./selectFrame");
Object.defineProperty(exports, "selectFrame", {
enumerable: true,
get: function () {
return _selectFrame.selectFrame;
}
});
var _skipPausing = require("./skipPausing");
Object.defineProperty(exports, "toggleSkipPausing", {
enumerable: true,
get: function () {
return _skipPausing.toggleSkipPausing;
}
});

Просмотреть файл

@ -0,0 +1,84 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.updateFrameLocation = updateFrameLocation;
exports.mapDisplayNames = mapDisplayNames;
exports.mapFrames = mapFrames;
var _selectors = require("../../selectors/index");
var _ast = require("../../utils/ast");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function updateFrameLocation(frame, sourceMaps) {
return sourceMaps.getOriginalLocation(frame.location).then(loc => _objectSpread({}, frame, {
location: loc,
generatedLocation: frame.generatedLocation || frame.location
}));
}
function updateFrameLocations(frames, sourceMaps) {
if (!frames || frames.length == 0) {
return Promise.resolve(frames);
}
return Promise.all(frames.map(frame => updateFrameLocation(frame, sourceMaps)));
}
function mapDisplayNames(frames, getState) {
return frames.map(frame => {
const source = (0, _selectors.getSource)(getState(), frame.location.sourceId);
const symbols = (0, _selectors.getSymbols)(getState(), source);
if (!symbols || !symbols.functions) {
return frame;
}
const originalFunction = (0, _ast.findClosestFunction)(symbols, frame.location);
if (!originalFunction) {
return frame;
}
const originalDisplayName = originalFunction.name;
return _objectSpread({}, frame, {
originalDisplayName
});
});
}
/**
* Map call stack frame locations and display names to originals.
* e.g.
* 1. When the debuggee pauses
* 2. When a source is pretty printed
* 3. When symbols are loaded
* @memberof actions/pause
* @static
*/
function mapFrames() {
return async function ({
dispatch,
getState,
sourceMaps
}) {
const frames = (0, _selectors.getFrames)(getState());
if (!frames) {
return;
}
let mappedFrames = await updateFrameLocations(frames, sourceMaps);
mappedFrames = mapDisplayNames(mappedFrames, getState);
dispatch({
type: "MAP_FRAMES",
frames: mappedFrames
});
};
}

Просмотреть файл

@ -0,0 +1,54 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mapScopes = mapScopes;
var _selectors = require("../../selectors/index");
var _loadSourceText = require("../sources/loadSourceText");
var _promise = require("../utils/middleware/promise");
var _prefs = require("../../utils/prefs");
var _log = require("../../utils/log");
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _mapScopes = require("../../utils/pause/mapScopes/index");
/* 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/>. */
function mapScopes(scopes, frame) {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
const generatedSourceRecord = (0, _selectors.getSource)(getState(), frame.generatedLocation.sourceId);
const sourceRecord = (0, _selectors.getSource)(getState(), frame.location.sourceId);
const shouldMapScopes = _prefs.features.mapScopes && !generatedSourceRecord.isWasm && !sourceRecord.isPrettyPrinted && !(0, _devtoolsSourceMap.isGeneratedId)(frame.location.sourceId);
await dispatch({
type: "MAP_SCOPES",
frame,
[_promise.PROMISE]: async function () {
if (!shouldMapScopes) {
return null;
}
await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
try {
return await (0, _mapScopes.buildMappedScopes)(sourceRecord.toJS(), frame, (await scopes), sourceMaps, client);
} catch (e) {
(0, _log.log)(e);
return null;
}
}()
});
};
}

Просмотреть файл

@ -0,0 +1,25 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'breakOnNext.js',
'commands.js',
'continueToHere.js',
'extra.js',
'fetchScopes.js',
'index.js',
'mapFrames.js',
'mapScopes.js',
'paused.js',
'pauseOnExceptions.js',
'resumed.js',
'selectFrame.js',
'setPopupObjectProperties.js',
'skipPausing.js',
)

Просмотреть файл

@ -0,0 +1,31 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.pauseOnExceptions = pauseOnExceptions;
var _promise = require("../utils/middleware/promise");
/* 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/>. */
/**
*
* @memberof actions/pause
* @static
*/
function pauseOnExceptions(shouldPauseOnExceptions, shouldPauseOnCaughtExceptions) {
return ({
dispatch,
client
}) => {
return dispatch({
type: "PAUSE_ON_EXCEPTIONS",
shouldPauseOnExceptions,
shouldPauseOnCaughtExceptions,
[_promise.PROMISE]: client.pauseOnExceptions(shouldPauseOnExceptions, shouldPauseOnCaughtExceptions)
});
};
}

Просмотреть файл

@ -0,0 +1,105 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.paused = paused;
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _selectors = require("../../selectors/index");
var _ = require("./index");
var _breakpoints = require("../breakpoints");
var _expressions = require("../expressions");
var _sources = require("../sources/index");
var _loadSourceText = require("../sources/loadSourceText");
var _ui = require("../ui");
var _commands = require("./commands");
var _pause = require("../../utils/pause/index");
var _mapFrames = require("./mapFrames");
var _fetchScopes = require("./fetchScopes");
/* 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/>. */
async function getOriginalSourceForFrame(state, frame) {
return (0, _selectors.getSources)(state).get(frame.location.sourceId);
}
/**
* Debugger has just paused
*
* @param {object} pauseInfo
* @memberof actions/pause
* @static
*/
function paused(pauseInfo) {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
const {
frames,
why,
loadedObjects
} = pauseInfo;
const rootFrame = frames.length > 0 ? frames[0] : null;
if (rootFrame) {
const mappedFrame = await (0, _mapFrames.updateFrameLocation)(rootFrame, sourceMaps);
const source = await getOriginalSourceForFrame(getState(), mappedFrame); // Ensure that the original file has loaded if there is one.
await dispatch((0, _loadSourceText.loadSourceText)(source));
if ((0, _pause.shouldStep)(mappedFrame, getState(), sourceMaps)) {
dispatch((0, _commands.command)("stepOver"));
return;
}
}
dispatch({
type: "PAUSED",
why,
frames,
selectedFrameId: rootFrame ? rootFrame.id : undefined,
loadedObjects: loadedObjects || []
});
const hiddenBreakpointLocation = (0, _selectors.getHiddenBreakpointLocation)(getState());
if (hiddenBreakpointLocation) {
dispatch((0, _breakpoints.removeBreakpoint)(hiddenBreakpointLocation));
}
await dispatch((0, _.mapFrames)());
const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
if (selectedFrame) {
const visibleFrame = (0, _selectors.getVisibleSelectedFrame)(getState());
const location = (0, _devtoolsSourceMap.isGeneratedId)(visibleFrame.location.sourceId) ? selectedFrame.generatedLocation : selectedFrame.location;
await dispatch((0, _sources.selectLocation)(location));
}
dispatch((0, _ui.togglePaneCollapse)("end", false));
await dispatch((0, _fetchScopes.fetchScopes)()); // 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 || !(0, _selectors.isEvaluatingExpression)(getState())) {
await dispatch((0, _expressions.evaluateExpressions)());
}
};
}

Просмотреть файл

@ -0,0 +1,41 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.resumed = resumed;
var _selectors = require("../../selectors/index");
var _expressions = require("../expressions");
var _pause = require("../../utils/pause/index");
/* 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/>. */
/**
* Debugger has just resumed
*
* @memberof actions/pause
* @static
*/
function resumed() {
return async ({
dispatch,
client,
getState
}) => {
const why = (0, _selectors.getPauseReason)(getState());
const wasPausedInEval = (0, _pause.inDebuggerEval)(why);
const wasStepping = (0, _selectors.isStepping)(getState());
dispatch({
type: "RESUME"
});
if (!wasStepping && !wasPausedInEval) {
await dispatch((0, _expressions.evaluateExpressions)());
}
};
}

Просмотреть файл

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.selectFrame = selectFrame;
var _sources = require("../sources/index");
var _expressions = require("../expressions");
var _fetchScopes = require("./fetchScopes");
/* 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/>. */
/**
* @memberof actions/pause
* @static
*/
function selectFrame(frame) {
return async ({
dispatch,
client,
getState,
sourceMaps
}) => {
dispatch({
type: "SELECT_FRAME",
frame
});
dispatch((0, _sources.selectLocation)(frame.location));
dispatch((0, _expressions.evaluateExpressions)());
dispatch((0, _fetchScopes.fetchScopes)());
};
}

Просмотреть файл

@ -0,0 +1,36 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setPopupObjectProperties = setPopupObjectProperties;
var _selectors = require("../../selectors/index");
/* 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/>. */
/**
* @memberof actions/pause
* @static
*/
function setPopupObjectProperties(object, properties) {
return ({
dispatch,
client,
getState
}) => {
const objectId = object.actor || object.objectId;
if ((0, _selectors.getPopupObjectProperties)(getState(), object.actor)) {
return;
}
dispatch({
type: "SET_POPUP_OBJECT_PROPERTIES",
objectId,
properties
});
};
}

Просмотреть файл

@ -0,0 +1,33 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toggleSkipPausing = toggleSkipPausing;
var _selectors = require("../../selectors/index");
/* 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/>. */
/**
* @memberof actions/pause
* @static
*/
function toggleSkipPausing() {
return async ({
dispatch,
client,
getState,
sourceMaps
}) => {
const skipPausing = !(0, _selectors.getSkipPausing)(getState()); // NOTE: enable this when we land the endpoint in m-c
// await client.setSkipPausing(skipPausing);
dispatch({
type: "TOGGLE_SKIP_PAUSING",
skipPausing
});
};
}

Просмотреть файл

@ -0,0 +1,174 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.updatePreview = updatePreview;
exports.setPreview = setPreview;
exports.clearPreview = clearPreview;
var _preview = require("../utils/preview");
var _ast = require("../utils/ast");
var _editor = require("../utils/editor/index");
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _promise = require("./utils/middleware/promise");
var _getExpression = require("../utils/editor/get-expression");
var _selectors = require("../selectors/index");
var _expressions = require("./expressions");
var _pause = require("./pause/index");
var _lodash = require("devtools/client/shared/vendor/lodash");
/* 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/>. */
function isInvalidTarget(target) {
if (!target || !target.innerText) {
return true;
}
const tokenText = target.innerText.trim();
const cursorPos = target.getBoundingClientRect(); // exclude literal tokens where it does not make sense to show a preview
const invalidType = ["cm-atom", ""].includes(target.className); // exclude syntax where the expression would be a syntax error
const invalidToken = tokenText === "" || tokenText.match(/^[(){}\|&%,.;=<>\+-/\*\s](?=)/);
const isPresentation = target.attributes.role && target.attributes.getNamedItem("role").value == "presentation"; // exclude codemirror elements that are not tokens
const invalidTarget = target.parentElement && !target.parentElement.closest(".CodeMirror-line") || cursorPos.top == 0;
return invalidTarget || invalidToken || invalidType || isPresentation;
}
function updatePreview(target, editor) {
return ({
dispatch,
getState,
client,
sourceMaps
}) => {
const tokenPos = (0, _editor.getTokenLocation)(editor.codeMirror, target);
const cursorPos = target.getBoundingClientRect();
const preview = (0, _selectors.getPreview)(getState());
if ((0, _selectors.getCanRewind)(getState())) {
return;
}
if (preview) {
// Return early if we are currently showing another preview or
// if we are mousing over the same token as before
if (preview.updating || (0, _lodash.isEqual)(preview.tokenPos, tokenPos)) {
return;
} // We are mousing over a new token that is not in the preview
if (!target.classList.contains("debug-expression")) {
dispatch(clearPreview());
}
}
if (isInvalidTarget(target)) {
dispatch(clearPreview());
return;
}
if (!(0, _selectors.isSelectedFrameVisible)(getState()) || !(0, _selectors.isLineInScope)(getState(), tokenPos.line)) {
return;
}
const source = (0, _selectors.getSelectedSource)(getState());
const symbols = (0, _selectors.getSymbols)(getState(), source);
let match;
if (!symbols || symbols.loading) {
match = (0, _getExpression.getExpressionFromCoords)(editor.codeMirror, tokenPos);
} else {
match = (0, _ast.findBestMatchExpression)(symbols, tokenPos);
}
if (!match || !match.expression) {
return;
}
const {
expression,
location
} = match;
if ((0, _preview.isConsole)(expression)) {
return;
}
dispatch(setPreview(expression, location, tokenPos, cursorPos));
};
}
function setPreview(expression, location, tokenPos, cursorPos) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
await dispatch({
type: "SET_PREVIEW",
[_promise.PROMISE]: async function () {
const source = (0, _selectors.getSelectedSource)(getState());
const sourceId = source.id;
const selectedFrame = (0, _selectors.getSelectedFrame)(getState());
if (location && !(0, _devtoolsSourceMap.isGeneratedId)(sourceId)) {
expression = await dispatch((0, _expressions.getMappedExpression)(expression));
}
if (!selectedFrame) {
return;
}
const {
result
} = await client.evaluateInFrame(expression, selectedFrame.id);
if (result === undefined) {
return;
}
const extra = await dispatch((0, _pause.getExtra)(expression, result));
return {
expression,
result,
location,
tokenPos,
cursorPos,
extra
};
}()
});
};
}
function clearPreview() {
return ({
dispatch,
getState,
client
}) => {
const currentSelection = (0, _selectors.getPreview)(getState());
if (!currentSelection) {
return;
}
return dispatch({
type: "CLEAR_SELECTION"
});
};
}

Просмотреть файл

@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addSearchQuery = addSearchQuery;
exports.clearSearchQuery = clearSearchQuery;
exports.clearSearchResults = clearSearchResults;
exports.clearSearch = clearSearch;
exports.updateSearchStatus = updateSearchStatus;
exports.closeProjectSearch = closeProjectSearch;
exports.searchSources = searchSources;
exports.searchSource = searchSource;
var _search = require("../workers/search/index");
var _selectors = require("../selectors/index");
var _source = require("../utils/source");
var _loadSourceText = require("./sources/loadSourceText");
var _projectTextSearch = require("../reducers/project-text-search");
/* 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/>. */
/**
* Redux actions for the search state
* @module actions/search
*/
function addSearchQuery(query) {
return {
type: "ADD_QUERY",
query
};
}
function clearSearchQuery() {
return {
type: "CLEAR_QUERY"
};
}
function clearSearchResults() {
return {
type: "CLEAR_SEARCH_RESULTS"
};
}
function clearSearch() {
return {
type: "CLEAR_SEARCH"
};
}
function updateSearchStatus(status) {
return {
type: "UPDATE_STATUS",
status
};
}
function closeProjectSearch() {
return {
type: "CLOSE_PROJECT_SEARCH"
};
}
function searchSources(query) {
return async ({
dispatch,
getState
}) => {
await dispatch(clearSearchResults());
await dispatch(addSearchQuery(query));
dispatch(updateSearchStatus(_projectTextSearch.statusType.fetching));
const sources = (0, _selectors.getSources)(getState());
const validSources = sources.valueSeq().filter(source => !(0, _selectors.hasPrettySource)(getState(), source.id) && !(0, _source.isThirdParty)(source));
for (const source of validSources) {
await dispatch((0, _loadSourceText.loadSourceText)(source));
await dispatch(searchSource(source.id, query));
}
dispatch(updateSearchStatus(_projectTextSearch.statusType.done));
};
}
function searchSource(sourceId, query) {
return async ({
dispatch,
getState
}) => {
const sourceRecord = (0, _selectors.getSource)(getState(), sourceId);
if (!sourceRecord) {
return;
}
const matches = await (0, _search.findSourceMatches)(sourceRecord.toJS(), query);
if (!matches.length) {
return;
}
dispatch({
type: "ADD_SEARCH_RESULT",
result: {
sourceId: sourceRecord.id,
filepath: sourceRecord.url,
matches
}
});
};
}

Просмотреть файл

@ -0,0 +1,37 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setQuickOpenQuery = setQuickOpenQuery;
exports.openQuickOpen = openQuickOpen;
exports.closeQuickOpen = closeQuickOpen;
/* 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/>. */
function setQuickOpenQuery(query) {
return {
type: "SET_QUICK_OPEN_QUERY",
query
};
}
function openQuickOpen(query) {
if (query != null) {
return {
type: "OPEN_QUICK_OPEN",
query
};
}
return {
type: "OPEN_QUICK_OPEN"
};
}
function closeQuickOpen() {
return {
type: "CLOSE_QUICK_OPEN"
};
}

Просмотреть файл

@ -0,0 +1,45 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.timeTravelTo = timeTravelTo;
exports.clearHistory = clearHistory;
var _selectors = require("../selectors/index");
var _sources = require("./sources/index");
/* 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/>. */
/**
* Redux actions for replay
* @module actions/replay
*/
function timeTravelTo(position) {
return ({
dispatch,
getState
}) => {
const data = (0, _selectors.getHistoryFrame)(getState(), position);
dispatch({
type: "TRAVEL_TO",
data,
position
});
dispatch((0, _sources.selectLocation)(data.paused.frames[0].location));
};
}
function clearHistory() {
return ({
dispatch,
getState
}) => {
dispatch({
type: "CLEAR_HISTORY"
});
};
}

Просмотреть файл

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setExpandedState = setExpandedState;
/* 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/>. */
function setExpandedState(expanded) {
return ({
dispatch,
getState
}) => {
dispatch({
type: "SET_EXPANDED_STATE",
expanded
});
};
}

Просмотреть файл

@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.toggleBlackBox = toggleBlackBox;
var _promise = require("../utils/middleware/promise");
/* 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/>. */
/**
* Redux actions for the sources state
* @module actions/sources
*/
function toggleBlackBox(source) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const {
isBlackBoxed,
id
} = source;
return dispatch({
type: "BLACKBOX",
source,
[_promise.PROMISE]: client.blackBox(id, isBlackBoxed)
});
};
}

Просмотреть файл

@ -0,0 +1,77 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _loadSourceText = require("./loadSourceText");
Object.keys(_loadSourceText).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _loadSourceText[key];
}
});
});
var _prettyPrint = require("./prettyPrint");
Object.keys(_prettyPrint).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _prettyPrint[key];
}
});
});
var _newSources = require("./newSources");
Object.keys(_newSources).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _newSources[key];
}
});
});
var _blackbox = require("./blackbox");
Object.keys(_blackbox).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _blackbox[key];
}
});
});
var _select = require("./select");
Object.keys(_select).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _select[key];
}
});
});
var _tabs = require("./tabs");
Object.keys(_tabs).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
Object.defineProperty(exports, key, {
enumerable: true,
get: function () {
return _tabs[key];
}
});
});

Просмотреть файл

@ -0,0 +1,114 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.loadSourceText = loadSourceText;
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _promise = require("../utils/middleware/promise");
var _selectors = require("../../selectors/index");
var _parser = require("../../workers/parser/index");
var parser = _interopRequireWildcard(_parser);
var _source = require("../../utils/source");
var _defer = require("../../utils/defer");
var _defer2 = _interopRequireDefault(_defer);
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
/* 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/>. */
const requests = new Map();
const loadSourceHistogram = _devtoolsModules.Services.telemetry.getHistogramById("DEVTOOLS_DEBUGGER_LOAD_SOURCE_MS");
async function loadSource(source, {
sourceMaps,
client
}) {
const id = source.get("id");
if ((0, _devtoolsSourceMap.isOriginalId)(id)) {
return await sourceMaps.getOriginalSourceText(source.toJS());
}
const response = await client.sourceContents(id);
return {
id,
text: response.source,
contentType: response.contentType || "text/javascript"
};
}
/**
* @memberof actions/sources
* @static
*/
function loadSourceText(source) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const id = source.get("id"); // Fetch the source text only once.
if (requests.has(id)) {
return requests.get(id);
}
if ((0, _source.isLoaded)(source)) {
return Promise.resolve();
}
const telemetryStart = performance.now();
const deferred = (0, _defer2.default)();
requests.set(id, deferred.promise);
try {
await dispatch({
type: "LOAD_SOURCE_TEXT",
sourceId: id,
[_promise.PROMISE]: loadSource(source, {
sourceMaps,
client
})
});
} catch (e) {
deferred.resolve();
requests.delete(id);
return;
}
const newSource = (0, _selectors.getSource)(getState(), source.get("id")).toJS();
if ((0, _devtoolsSourceMap.isOriginalId)(newSource.id) && !newSource.isWasm) {
const generatedSource = (0, _selectors.getGeneratedSource)(getState(), source.toJS());
await dispatch(loadSourceText(generatedSource));
}
if (!newSource.isWasm) {
await parser.setSource(newSource);
} // signal that the action is finished
deferred.resolve();
requests.delete(id);
const telemetryEnd = performance.now();
const duration = telemetryEnd - telemetryStart;
loadSourceHistogram.add(duration);
};
}

Просмотреть файл

@ -0,0 +1,18 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'blackbox.js',
'index.js',
'loadSourceText.js',
'newSources.js',
'prettyPrint.js',
'select.js',
'tabs.js',
)

Просмотреть файл

@ -0,0 +1,206 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.newSource = newSource;
exports.newSources = newSources;
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _lodash = require("devtools/client/shared/vendor/lodash");
var _blackbox = require("./blackbox");
var _breakpoints = require("../breakpoints");
var _loadSourceText = require("./loadSourceText");
var _prettyPrint = require("./prettyPrint");
var _sources = require("../sources/index");
var _source = require("../../utils/source");
var _selectors = require("../../selectors/index");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function createOriginalSource(originalUrl, generatedSource, sourceMaps) {
return {
url: originalUrl,
id: sourceMaps.generatedToOriginalId(generatedSource.id, originalUrl),
isPrettyPrinted: false,
isWasm: false,
isBlackBoxed: false,
loadedState: "unloaded"
};
}
function loadSourceMaps(sources) {
return async function ({
dispatch,
sourceMaps
}) {
if (!sourceMaps) {
return;
}
const originalSources = await Promise.all(sources.map(source => dispatch(loadSourceMap(source.id))));
await dispatch(newSources((0, _lodash.flatten)(originalSources)));
};
}
/**
* @memberof actions/sources
* @static
*/
function loadSourceMap(sourceId) {
return async function ({
dispatch,
getState,
sourceMaps
}) {
const source = (0, _selectors.getSource)(getState(), sourceId).toJS();
if (!sourceMaps || !(0, _devtoolsSourceMap.isGeneratedId)(sourceId) || !source.sourceMapURL) {
return;
}
let urls = null;
try {
urls = await sourceMaps.getOriginalURLs(source);
} catch (e) {
console.error(e);
}
if (!urls) {
// If this source doesn't have a sourcemap, enable it for pretty printing
dispatch({
type: "UPDATE_SOURCE",
source: _objectSpread({}, source, {
sourceMapURL: ""
})
});
return;
}
return urls.map(url => createOriginalSource(url, source, sourceMaps));
};
} // If a request has been made to show this source, go ahead and
// select it.
function checkSelectedSource(sourceId) {
return async ({
dispatch,
getState
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
const pendingLocation = (0, _selectors.getPendingSelectedLocation)(getState());
if (!pendingLocation || !pendingLocation.url || !source.url) {
return;
}
const pendingUrl = pendingLocation.url;
const rawPendingUrl = (0, _source.getRawSourceURL)(pendingUrl);
if (rawPendingUrl === source.url) {
if ((0, _source.isPrettyURL)(pendingUrl)) {
return await dispatch((0, _prettyPrint.togglePrettyPrint)(source.id));
}
await dispatch((0, _sources.selectLocation)(_objectSpread({}, pendingLocation, {
sourceId: source.id
})));
}
};
}
function checkPendingBreakpoints(sourceId) {
return async ({
dispatch,
getState
}) => {
// source may have been modified by selectLocation
const source = (0, _selectors.getSource)(getState(), sourceId);
const pendingBreakpoints = (0, _selectors.getPendingBreakpointsForSource)(getState(), source.get("url"));
if (!pendingBreakpoints.size) {
return;
} // load the source text if there is a pending breakpoint for it
await dispatch((0, _loadSourceText.loadSourceText)(source));
const pendingBreakpointsArray = pendingBreakpoints.valueSeq().toJS();
for (const pendingBreakpoint of pendingBreakpointsArray) {
await dispatch((0, _breakpoints.syncBreakpoint)(sourceId, pendingBreakpoint));
}
};
}
function restoreBlackBoxedSources(sources) {
return async ({
dispatch
}) => {
const tabs = (0, _selectors.getBlackBoxList)();
if (tabs.length == 0) {
return;
}
for (const source of sources) {
if (tabs.includes(source.url) && !source.isBlackBoxed) {
dispatch((0, _blackbox.toggleBlackBox)(source));
}
}
};
}
/**
* Handler for the debugger client's unsolicited newSource notification.
* @memberof actions/sources
* @static
*/
function newSource(source) {
return async ({
dispatch
}) => {
await dispatch(newSources([source]));
};
}
function newSources(sources) {
return async ({
dispatch,
getState
}) => {
const filteredSources = sources.filter(source => source && !(0, _selectors.getSource)(getState(), source.id));
if (filteredSources.length == 0) {
return;
}
dispatch({
type: "ADD_SOURCES",
sources: filteredSources
});
for (const source of filteredSources) {
dispatch(checkSelectedSource(source.id));
dispatch(checkPendingBreakpoints(source.id));
}
await dispatch(loadSourceMaps(filteredSources)); // We would like to restore the blackboxed state
// after loading all states to make sure the correctness.
await dispatch(restoreBlackBoxedSources(filteredSources));
};
}

Просмотреть файл

@ -0,0 +1,139 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createPrettySource = createPrettySource;
exports.togglePrettyPrint = togglePrettyPrint;
var _assert = require("../../utils/assert");
var _assert2 = _interopRequireDefault(_assert);
var _breakpoints = require("../breakpoints");
var _ast = require("../ast");
var _prettyPrint = require("../../workers/pretty-print/index");
var _parser = require("../../workers/parser/index");
var _source = require("../../utils/source");
var _loadSourceText = require("./loadSourceText");
var _sources = require("../sources/index");
var _pause = require("../pause/index");
var _selectors = require("../../selectors/index");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function createPrettySource(sourceId) {
return async ({
dispatch,
getState,
sourceMaps
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
const url = (0, _source.getPrettySourceURL)(source.url);
const id = await sourceMaps.generatedToOriginalId(sourceId, url);
const prettySource = {
url,
id,
isBlackBoxed: false,
isPrettyPrinted: true,
isWasm: false,
contentType: "text/javascript",
loadedState: "loading"
};
dispatch({
type: "ADD_SOURCE",
source: prettySource
});
const {
code,
mappings
} = await (0, _prettyPrint.prettyPrint)({
source,
url
});
await sourceMaps.applySourceMap(source.id, url, code, mappings);
const loadedPrettySource = _objectSpread({}, prettySource, {
text: code,
loadedState: "loaded"
});
(0, _parser.setSource)(loadedPrettySource);
dispatch({
type: "UPDATE_SOURCE",
source: loadedPrettySource
});
return prettySource;
};
}
/**
* Toggle the pretty printing of a source's text. All subsequent calls to
* |getText| will return the pretty-toggled text. Nothing will happen for
* non-javascript files.
*
* @memberof actions/sources
* @static
* @param string id The source form from the RDP.
* @returns Promise
* A promise that resolves to [aSource, prettyText] or rejects to
* [aSource, error].
*/
function togglePrettyPrint(sourceId) {
return async ({
dispatch,
getState,
client,
sourceMaps
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
if (!source) {
return {};
}
if (!(0, _source.isLoaded)(source)) {
await dispatch((0, _loadSourceText.loadSourceText)(source));
}
(0, _assert2.default)(sourceMaps.isGeneratedId(sourceId), "Pretty-printing only allowed on generated sources");
const selectedLocation = (0, _selectors.getSelectedLocation)(getState());
const url = (0, _source.getPrettySourceURL)(source.url);
const prettySource = (0, _selectors.getSourceByURL)(getState(), url);
const options = {};
if (selectedLocation) {
options.location = await sourceMaps.getOriginalLocation(selectedLocation);
}
if (prettySource) {
const _sourceId = prettySource.get("id");
return dispatch((0, _sources.selectLocation)(_objectSpread({}, options.location, {
sourceId: _sourceId
})));
}
const newPrettySource = await dispatch(createPrettySource(sourceId));
await dispatch((0, _breakpoints.remapBreakpoints)(sourceId));
await dispatch((0, _pause.mapFrames)());
await dispatch((0, _ast.setPausePoints)(newPrettySource.id));
await dispatch((0, _ast.setSymbols)(newPrettySource.id));
return dispatch((0, _sources.selectLocation)(_objectSpread({}, options.location, {
sourceId: newPrettySource.id
})));
};
}

Просмотреть файл

@ -0,0 +1,251 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.selectSourceURL = selectSourceURL;
exports.selectSource = selectSource;
exports.selectLocation = selectLocation;
exports.selectSpecificLocation = selectSpecificLocation;
exports.selectSpecificSource = selectSpecificSource;
exports.jumpToMappedLocation = jumpToMappedLocation;
exports.jumpToMappedSelectedLocation = jumpToMappedSelectedLocation;
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _ast = require("../ast");
var _ui = require("../ui");
var _prettyPrint = require("./prettyPrint");
var _tabs = require("./tabs");
var _loadSourceText = require("./loadSourceText");
var _prefs = require("../../utils/prefs");
var _source = require("../../utils/source");
var _location = require("../../utils/location");
var _sourceMaps = require("../../utils/source-maps");
var _selectors = require("../../selectors/index");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Deterministically select a source that has a given URL. This will
* work regardless of the connection status or if the source exists
* yet. This exists mostly for external things to interact with the
* debugger.
*
* @memberof actions/sources
* @static
*/
function selectSourceURL(url, options = {}) {
return async ({
dispatch,
getState
}) => {
const source = (0, _selectors.getSourceByURL)(getState(), url);
if (source) {
const sourceId = source.id;
const location = (0, _location.createLocation)(_objectSpread({}, options.location, {
sourceId
}));
await dispatch(selectLocation(location));
} else {
dispatch({
type: "SELECT_SOURCE_URL",
url: url,
line: options.location ? options.location.line : null
});
}
};
}
/**
* @memberof actions/sources
* @static
*/
function selectSource(sourceId) {
return async ({
dispatch
}) => {
const location = (0, _location.createLocation)({
sourceId
});
return await dispatch(selectLocation(location));
};
}
/**
* @memberof actions/sources
* @static
*/
function selectLocation(location) {
return async ({
dispatch,
getState,
client
}) => {
if (!client) {
// No connection, do nothing. This happens when the debugger is
// shut down too fast and it tries to display a default source.
return;
}
const sourceRecord = (0, _selectors.getSource)(getState(), location.sourceId);
if (!sourceRecord) {
// If there is no source we deselect the current selected source
return dispatch({
type: "CLEAR_SELECTED_SOURCE"
});
}
const activeSearch = (0, _selectors.getActiveSearch)(getState());
if (activeSearch !== "file") {
dispatch((0, _ui.closeActiveSearch)());
}
const source = sourceRecord.toJS();
dispatch((0, _tabs.addTab)(source, 0));
dispatch({
type: "SELECT_SOURCE",
source,
location
});
await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!selectedSource) {
return;
}
const sourceId = selectedSource.id;
if (_prefs.prefs.autoPrettyPrint && !(0, _selectors.getPrettySource)(getState(), sourceId) && (0, _source.shouldPrettyPrint)(selectedSource) && (0, _source.isMinified)(selectedSource)) {
await dispatch((0, _prettyPrint.togglePrettyPrint)(sourceId));
dispatch((0, _tabs.closeTab)(source.url));
}
dispatch((0, _ast.setSymbols)(sourceId));
dispatch((0, _ast.setOutOfScopeLocations)());
};
}
/**
* @memberof actions/sources
* @static
*/
function selectSpecificLocation(location) {
return async ({
dispatch,
getState,
client
}) => {
if (!client) {
// No connection, do nothing. This happens when the debugger is
// shut down too fast and it tries to display a default source.
return;
}
const sourceRecord = (0, _selectors.getSource)(getState(), location.sourceId);
if (!sourceRecord) {
// If there is no source we deselect the current selected source
return dispatch({
type: "CLEAR_SELECTED_SOURCE"
});
}
const activeSearch = (0, _selectors.getActiveSearch)(getState());
if (activeSearch !== "file") {
dispatch((0, _ui.closeActiveSearch)());
}
const source = sourceRecord.toJS();
dispatch((0, _tabs.addTab)(source, 0));
dispatch({
type: "SELECT_SOURCE",
source,
location
});
await dispatch((0, _loadSourceText.loadSourceText)(sourceRecord));
const selectedSource = (0, _selectors.getSelectedSource)(getState());
if (!selectedSource) {
return;
}
const sourceId = selectedSource.id;
dispatch((0, _ast.setSymbols)(sourceId));
dispatch((0, _ast.setOutOfScopeLocations)());
};
}
/**
* @memberof actions/sources
* @static
*/
function selectSpecificSource(sourceId) {
return async ({
dispatch
}) => {
const location = (0, _location.createLocation)({
sourceId
});
return await dispatch(selectSpecificLocation(location));
};
}
/**
* @memberof actions/sources
* @static
*/
function jumpToMappedLocation(location) {
return async function ({
dispatch,
getState,
client,
sourceMaps
}) {
if (!client) {
return;
}
const source = (0, _selectors.getSource)(getState(), location.sourceId);
let pairedLocation;
if ((0, _devtoolsSourceMap.isOriginalId)(location.sourceId)) {
pairedLocation = await (0, _sourceMaps.getGeneratedLocation)(getState(), source, location, sourceMaps);
} else {
pairedLocation = await sourceMaps.getOriginalLocation(location, source.toJS());
}
return dispatch(selectLocation(_objectSpread({}, pairedLocation)));
};
}
function jumpToMappedSelectedLocation() {
return async function ({
dispatch,
getState
}) {
const location = (0, _selectors.getSelectedLocation)(getState());
await dispatch(jumpToMappedLocation(location));
};
}

Просмотреть файл

@ -0,0 +1,91 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addTab = addTab;
exports.moveTab = moveTab;
exports.closeTab = closeTab;
exports.closeTabs = closeTabs;
var _editor = require("../../utils/editor/index");
var _sources = require("../sources/index");
var _selectors = require("../../selectors/index");
/* 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/>. */
/**
* Redux actions for the sources state
* @module actions/sources
*/
function addTab(source, tabIndex) {
return {
type: "ADD_TAB",
source,
tabIndex
};
}
function moveTab(url, tabIndex) {
return {
type: "MOVE_TAB",
url,
tabIndex
};
}
/**
* @memberof actions/sources
* @static
*/
function closeTab(url) {
return ({
dispatch,
getState,
client
}) => {
(0, _editor.removeDocument)(url);
const tabs = (0, _selectors.removeSourceFromTabList)((0, _selectors.getSourceTabs)(getState()), url);
const sourceId = (0, _selectors.getNewSelectedSourceId)(getState(), tabs);
dispatch({
type: "CLOSE_TAB",
url,
tabs
});
dispatch((0, _sources.selectSource)(sourceId));
};
}
/**
* @memberof actions/sources
* @static
*/
function closeTabs(urls) {
return ({
dispatch,
getState,
client
}) => {
urls.forEach(url => {
const source = (0, _selectors.getSourceByURL)(getState(), url);
if (source) {
(0, _editor.removeDocument)(source.get("id"));
}
});
const tabs = (0, _selectors.removeSourcesFromTabList)((0, _selectors.getSourceTabs)(getState()), urls);
dispatch({
type: "CLOSE_TABS",
urls,
tabs
});
const sourceId = (0, _selectors.getNewSelectedSourceId)(getState(), tabs);
dispatch((0, _sources.selectSource)(sourceId));
};
}

Просмотреть файл

@ -0,0 +1,61 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.openLink = openLink;
exports.openWorkerToolbox = openWorkerToolbox;
exports.evaluateInConsole = evaluateInConsole;
/* 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/>. */
const {
isDevelopment
} = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-environment"];
const {
getSelectedFrameId
} = require("../selectors/index");
/**
* @memberof actions/toolbox
* @static
*/
function openLink(url) {
return async function ({
openLink: openLinkCommand
}) {
if (isDevelopment()) {
const win = window.open(url, "_blank");
win.focus();
} else {
openLinkCommand(url);
}
};
}
function openWorkerToolbox(worker) {
return async function ({
getState,
openWorkerToolbox: openWorkerToolboxCommand
}) {
if (isDevelopment()) {
alert(worker.url);
} else {
openWorkerToolboxCommand(worker);
}
};
}
function evaluateInConsole(inputString) {
return async ({
client,
getState
}) => {
const frameId = getSelectedFrameId(getState());
client.evaluate(`console.log("${inputString}"); console.log(${inputString})`, {
frameId
});
};
}

Просмотреть файл

@ -0,0 +1,226 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.setContextMenu = setContextMenu;
exports.setPrimaryPaneTab = setPrimaryPaneTab;
exports.closeActiveSearch = closeActiveSearch;
exports.setActiveSearch = setActiveSearch;
exports.toggleFrameworkGrouping = toggleFrameworkGrouping;
exports.showSource = showSource;
exports.togglePaneCollapse = togglePaneCollapse;
exports.highlightLineRange = highlightLineRange;
exports.flashLineRange = flashLineRange;
exports.clearHighlightLineRange = clearHighlightLineRange;
exports.openConditionalPanel = openConditionalPanel;
exports.closeConditionalPanel = closeConditionalPanel;
exports.clearProjectDirectoryRoot = clearProjectDirectoryRoot;
exports.setProjectDirectoryRoot = setProjectDirectoryRoot;
exports.setOrientation = setOrientation;
var _selectors = require("../selectors/index");
var _ui = require("../reducers/ui");
var _source = require("../utils/source");
/* 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/>. */
function setContextMenu(type, event) {
return ({
dispatch
}) => {
dispatch({
type: "SET_CONTEXT_MENU",
contextMenu: {
type,
event
}
});
};
}
function setPrimaryPaneTab(tabName) {
return {
type: "SET_PRIMARY_PANE_TAB",
tabName
};
}
function closeActiveSearch() {
return {
type: "TOGGLE_ACTIVE_SEARCH",
value: null
};
}
function setActiveSearch(activeSearch) {
return ({
dispatch,
getState
}) => {
const activeSearchState = (0, _selectors.getActiveSearch)(getState());
if (activeSearchState === activeSearch) {
return;
}
if ((0, _selectors.getQuickOpenEnabled)(getState())) {
dispatch({
type: "CLOSE_QUICK_OPEN"
});
}
dispatch({
type: "TOGGLE_ACTIVE_SEARCH",
value: activeSearch
});
};
}
function toggleFrameworkGrouping(toggleValue) {
return ({
dispatch,
getState
}) => {
dispatch({
type: "TOGGLE_FRAMEWORK_GROUPING",
value: toggleValue
});
};
}
function showSource(sourceId) {
return ({
dispatch,
getState
}) => {
const source = (0, _selectors.getSource)(getState(), sourceId);
if ((0, _selectors.getPaneCollapse)(getState(), "start")) {
dispatch({
type: "TOGGLE_PANE",
position: "start",
paneCollapsed: false
});
}
dispatch(setPrimaryPaneTab("sources"));
dispatch({
type: "SHOW_SOURCE",
sourceUrl: ""
});
dispatch({
type: "SHOW_SOURCE",
sourceUrl: (0, _source.getRawSourceURL)(source.get("url"))
});
};
}
function togglePaneCollapse(position, paneCollapsed) {
return ({
dispatch,
getState
}) => {
const prevPaneCollapse = (0, _selectors.getPaneCollapse)(getState(), position);
if (prevPaneCollapse === paneCollapsed) {
return;
}
dispatch({
type: "TOGGLE_PANE",
position,
paneCollapsed
});
};
}
/**
* @memberof actions/sources
* @static
*/
function highlightLineRange(location) {
return {
type: "HIGHLIGHT_LINES",
location
};
}
function flashLineRange(location) {
return ({
dispatch
}) => {
dispatch(highlightLineRange(location));
setTimeout(() => dispatch(clearHighlightLineRange()), 200);
};
}
/**
* @memberof actions/sources
* @static
*/
function clearHighlightLineRange() {
return {
type: "CLEAR_HIGHLIGHT_LINES"
};
}
function openConditionalPanel(line) {
if (!line) {
return;
}
return {
type: "OPEN_CONDITIONAL_PANEL",
line
};
}
function closeConditionalPanel() {
return {
type: "CLOSE_CONDITIONAL_PANEL"
};
}
function clearProjectDirectoryRoot() {
return {
type: "SET_PROJECT_DIRECTORY_ROOT",
url: ""
};
}
function setProjectDirectoryRoot(newRoot) {
return ({
dispatch,
getState
}) => {
const curRoot = (0, _ui.getProjectDirectoryRoot)(getState());
if (newRoot && curRoot) {
const newRootArr = newRoot.replace(/\/+/g, "/").split("/");
const curRootArr = curRoot.replace(/^\//, "").replace(/\/+/g, "/").split("/");
if (newRootArr[0] !== curRootArr[0]) {
newRootArr.splice(0, 2);
newRoot = `${curRoot}/${newRootArr.join("/")}`;
}
}
dispatch({
type: "SET_PROJECT_DIRECTORY_ROOT",
url: newRoot
});
};
}
function setOrientation(orientation) {
return {
type: "SET_ORIENTATION",
orientation
};
}

Просмотреть файл

@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _redux = require("devtools/client/shared/vendor/redux");
var _waitService = require("./middleware/wait-service");
var _log = require("./middleware/log");
var _history = require("./middleware/history");
var _promise = require("./middleware/promise");
var _thunk = require("./middleware/thunk");
var _timing = require("./middleware/timing");
/* 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/>. */
/* global window */
/**
* Redux store utils
* @module utils/create-store
*/
/**
* This creates a dispatcher with all the standard middleware in place
* that all code requires. It can also be optionally configured in
* various ways, such as logging and recording.
*
* @param {object} opts:
* - log: log all dispatched actions to console
* - history: an array to store every action in. Should only be
* used in tests.
* - middleware: array of middleware to be included in the redux store
* @memberof utils/create-store
* @static
*/
const configureStore = (opts = {}) => {
const middleware = [(0, _thunk.thunk)(opts.makeThunkArgs), _promise.promise, // Order is important: services must go last as they always
// operate on "already transformed" actions. Actions going through
// them shouldn't have any special fields like promises, they
// should just be normal JSON objects.
_waitService.waitUntilService];
if (opts.history) {
middleware.push((0, _history.history)(opts.history));
}
if (opts.middleware) {
opts.middleware.forEach(fn => middleware.push(fn));
}
if (opts.log) {
middleware.push(_log.log);
}
if (opts.timing) {
middleware.push(_timing.timing);
} // Hook in the redux devtools browser extension if it exists
const devtoolsExt = typeof window === "object" && window.devToolsExtension ? window.devToolsExtension() : f => f;
return (0, _redux.applyMiddleware)(...middleware)(devtoolsExt(_redux.createStore));
};
exports.default = configureStore;

Просмотреть файл

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.history = undefined;
var _devtoolsEnvironment = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-environment"];
/* 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/>. */
/* global window */
/**
* A middleware that stores every action coming through the store in the passed
* in logging object. Should only be used for tests, as it collects all
* action information, which will cause memory bloat.
*/
const history = exports.history = (log = []) => ({
dispatch,
getState
}) => {
return next => action => {
if ((0, _devtoolsEnvironment.isDevelopment)()) {
log.push(action);
}
return next(action);
};
};

Просмотреть файл

@ -0,0 +1,117 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.log = log;
var _devtoolsEnvironment = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-environment"];
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
const blacklist = ["SET_POPUP_OBJECT_PROPERTIES", "SET_PAUSE_POINTS", "SET_SYMBOLS", "OUT_OF_SCOPE_LOCATIONS", "MAP_SCOPES", "MAP_FRAMES", "ADD_SCOPES", "IN_SCOPE_LINES", "REMOVE_BREAKPOINT", "ADD_BREAKPOINT"];
function cloneAction(action) {
action = action || {};
action = _objectSpread({}, action); // ADD_TAB, ...
if (action.source && action.source.text) {
const source = _objectSpread({}, action.source, {
text: ""
});
action.source = source;
}
if (action.sources) {
const sources = action.sources.slice(0, 20).map(source => {
const url = !source.url || source.url.includes("data:") ? "" : source.url;
return _objectSpread({}, source, {
url
});
});
action.sources = sources;
} // LOAD_SOURCE_TEXT
if (action.text) {
action.text = "";
}
if (action.value && action.value.text) {
const value = _objectSpread({}, action.value, {
text: ""
});
action.value = value;
}
return action;
}
function formatFrame(frame) {
const {
id,
location,
displayName
} = frame;
return {
id,
location,
displayName
};
}
function formatPause(pause) {
return _objectSpread({}, pause, {
pauseInfo: {
why: pause.why
},
scopes: [],
frames: pause.frames.map(formatFrame),
loadedObjects: []
});
}
function serializeAction(action) {
try {
action = cloneAction(action);
if (blacklist.includes(action.type)) {
action = {};
}
if (action.type === "PAUSED") {
action = formatPause(action);
} // dump(`> ${action.type}...\n ${JSON.stringify(action)}\n`);
return JSON.stringify(action);
} catch (e) {
console.error(e);
}
}
/**
* A middleware that logs all actions coming through the system
* to the console.
*/
function log({
dispatch,
getState
}) {
return next => action => {
const asyncMsg = !action.status ? "" : `[${action.status}]`;
if ((0, _devtoolsEnvironment.isTesting)()) {
dump(`[ACTION] ${action.type} ${asyncMsg} - ${serializeAction(action)}\n`);
} else {
console.log(action, asyncMsg);
}
next(action);
};
}

Просмотреть файл

@ -0,0 +1,17 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'history.js',
'log.js',
'promise.js',
'thunk.js',
'timing.js',
'wait-service.js',
)

Просмотреть файл

@ -0,0 +1,70 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.promise = exports.PROMISE = undefined;
var _lodash = require("devtools/client/shared/vendor/lodash");
var _DevToolsUtils = require("../../../utils/DevToolsUtils");
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
let seqIdVal = 1;
function seqIdGen() {
return seqIdVal++;
}
function filterAction(action) {
return (0, _lodash.fromPairs)((0, _lodash.toPairs)(action).filter(pair => pair[0] !== PROMISE));
}
function promiseMiddleware({
dispatch,
getState
}) {
return next => action => {
if (!(PROMISE in action)) {
return next(action);
}
const promiseInst = action[PROMISE];
const seqId = seqIdGen().toString(); // Create a new action that doesn't have the promise field and has
// the `seqId` field that represents the sequence id
action = _objectSpread({}, filterAction(action), {
seqId
});
dispatch(_objectSpread({}, action, {
status: "start"
})); // Return the promise so action creators can still compose if they
// want to.
return new Promise((resolve, reject) => {
promiseInst.then(value => {
(0, _DevToolsUtils.executeSoon)(() => {
dispatch(_objectSpread({}, action, {
status: "done",
value: value
}));
resolve(value);
});
}, error => {
(0, _DevToolsUtils.executeSoon)(() => {
dispatch(_objectSpread({}, action, {
status: "error",
error: error.message || error
}));
reject(error);
});
});
});
};
}
const PROMISE = exports.PROMISE = "@@dispatch/promise";
exports.promise = promiseMiddleware;

Просмотреть файл

@ -0,0 +1,34 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.thunk = thunk;
/* 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/>. */
/* global window */
/**
* A middleware that allows thunks (functions) to be dispatched. If
* it's a thunk, it is called with an argument that contains
* `dispatch`, `getState`, and any additional args passed in via the
* middleware constructure. This allows the action to create multiple
* actions (most likely asynchronously).
*/
function thunk(makeArgs) {
return ({
dispatch,
getState
}) => {
const args = {
dispatch,
getState
};
return next => action => {
return typeof action === "function" ? action(makeArgs ? makeArgs(args, getState()) : args) : next(action);
};
};
}

Просмотреть файл

@ -0,0 +1,29 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.timing = timing;
/* 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/>. */
/* global window */
/**
* Redux middleware that sets performance markers for all actions such that they
* will appear in performance tooling under the User Timing API
*/
const mark = window.performance && window.performance.mark ? window.performance.mark.bind(window.performance) : () => {};
const measure = window.performance && window.performance.measure ? window.performance.measure.bind(window.performance) : () => {};
function timing(store) {
return next => action => {
mark(`${action.type}_start`);
const result = next(action);
mark(`${action.type}_end`);
measure(`${action.type}`, `${action.type}_start`, `${action.type}_end`);
return result;
};
}

Просмотреть файл

@ -0,0 +1,75 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.waitUntilService = waitUntilService;
/* 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/>. */
/* global window */
/**
* A middleware which acts like a service, because it is stateful
* and "long-running" in the background. It provides the ability
* for actions to install a function to be run once when a specific
* condition is met by an action coming through the system. Think of
* it as a thunk that blocks until the condition is met. Example:
*
* ```js
* const services = { WAIT_UNTIL: require('wait-service').NAME };
*
* { type: services.WAIT_UNTIL,
* predicate: action => action.type === "ADD_ITEM",
* run: (dispatch, getState, action) => {
* // Do anything here. You only need to accept the arguments
* // if you need them. `action` is the action that satisfied
* // the predicate.
* }
* }
* ```
*/
const NAME = exports.NAME = "@@service/waitUntil";
function waitUntilService({
dispatch,
getState
}) {
let pending = [];
function checkPending(action) {
const readyRequests = [];
const stillPending = []; // Find the pending requests whose predicates are satisfied with
// this action. Wait to run the requests until after we update the
// pending queue because the request handler may synchronously
// dispatch again and run this service (that use case is
// completely valid).
for (const request of pending) {
if (request.predicate(action)) {
readyRequests.push(request);
} else {
stillPending.push(request);
}
}
pending = stillPending;
for (const request of readyRequests) {
request.run(dispatch, getState, action);
}
}
return next => action => {
if (action.type === NAME) {
pending.push(action);
return null;
}
const result = next(action);
checkPending(action);
return result;
};
}

Просмотреть файл

@ -0,0 +1,12 @@
# vim: set filetype=python:
# 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/.
DIRS += [
'middleware',
]
DevToolsModules(
'create-store.js',
)

Просмотреть файл

@ -0,0 +1,89 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clientEvents = exports.clientCommands = exports.createObjectClient = undefined;
exports.onConnect = onConnect;
var _commands = require("./firefox/commands");
var _events = require("./firefox/events");
var _prefs = require("../utils/prefs");
/* 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/>. */
let DebuggerClient;
function createObjectClient(grip) {
return DebuggerClient.createObjectClient(grip);
}
async function onConnect(connection, actions) {
const {
tabConnection: {
tabTarget,
threadClient,
debuggerClient
}
} = connection;
DebuggerClient = debuggerClient;
if (!tabTarget || !threadClient || !debuggerClient) {
return {
bpClients: {}
};
}
const supportsWasm = _prefs.features.wasm && !!debuggerClient.mainRoot.traits.wasmBinarySource;
const {
bpClients
} = (0, _commands.setupCommands)({
threadClient,
tabTarget,
debuggerClient,
supportsWasm
});
if (actions) {
(0, _events.setupEvents)({
threadClient,
actions,
supportsWasm
});
}
tabTarget.on("will-navigate", actions.willNavigate);
tabTarget.on("navigate", actions.navigated);
await threadClient.reconfigure({
observeAsmJS: true,
wasmBinarySource: supportsWasm
}); // In Firefox, we need to initially request all of the sources. This
// usually fires off individual `newSource` notifications as the
// debugger finds them, but there may be existing sources already in
// the debugger (if it's paused already, or if loading the page from
// bfcache) so explicity fire `newSource` events for all returned
// sources.
const sources = await _commands.clientCommands.fetchSources();
const traits = tabTarget.activeTab ? tabTarget.activeTab.traits : null;
await actions.connect(tabTarget.url, traits && traits.canRewind);
await actions.newSources(sources); // If the threadClient is already paused, make sure to show a
// paused state.
const pausedPacket = threadClient.getLastPausePacket();
if (pausedPacket) {
_events.clientEvents.paused("paused", pausedPacket);
}
return {
bpClients
};
}
exports.createObjectClient = createObjectClient;
exports.clientCommands = _commands.clientCommands;
exports.clientEvents = _events.clientEvents;

Просмотреть файл

@ -0,0 +1,437 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clientCommands = exports.setupCommands = undefined;
var _breakpoint = require("../../utils/breakpoint/index");
var _create = require("./create");
var _frontsDevice = require("devtools/shared/fronts/device");
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
/* 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/>. */
let bpClients;
let threadClient;
let tabTarget;
let debuggerClient;
let supportsWasm;
function setupCommands(dependencies) {
threadClient = dependencies.threadClient;
tabTarget = dependencies.tabTarget;
debuggerClient = dependencies.debuggerClient;
supportsWasm = dependencies.supportsWasm;
bpClients = {};
return {
bpClients
};
}
function sendPacket(packet, callback = r => r) {
return debuggerClient.request(packet).then(callback);
}
function resume() {
return new Promise(resolve => {
threadClient.resume(resolve);
});
}
function stepIn() {
return new Promise(resolve => {
threadClient.stepIn(resolve);
});
}
function stepOver() {
return new Promise(resolve => {
threadClient.stepOver(resolve);
});
}
function stepOut() {
return new Promise(resolve => {
threadClient.stepOut(resolve);
});
}
function rewind() {
return new Promise(resolve => {
threadClient.rewind(resolve);
});
}
function reverseStepIn() {
return new Promise(resolve => {
threadClient.reverseStepIn(resolve);
});
}
function reverseStepOver() {
return new Promise(resolve => {
threadClient.reverseStepOver(resolve);
});
}
function reverseStepOut() {
return new Promise(resolve => {
threadClient.reverseStepOut(resolve);
});
}
function breakOnNext() {
return threadClient.breakOnNext();
}
function sourceContents(sourceId) {
const sourceClient = threadClient.source({
actor: sourceId
});
return sourceClient.source();
}
function getBreakpointByLocation(location) {
const id = (0, _breakpoint.makePendingLocationId)(location);
const bpClient = bpClients[id];
if (bpClient) {
const {
actor,
url,
line,
column,
condition
} = bpClient.location;
return {
id: bpClient.actor,
condition,
actualLocation: {
line,
column,
sourceId: actor,
sourceUrl: url
}
};
}
return null;
}
function setBreakpoint(location, condition, noSliding) {
const sourceClient = threadClient.source({
actor: location.sourceId
});
return sourceClient.setBreakpoint({
line: location.line,
column: location.column,
condition,
noSliding
}).then(([{
actualLocation
}, bpClient]) => {
actualLocation = (0, _create.createBreakpointLocation)(location, actualLocation);
const id = (0, _breakpoint.makePendingLocationId)(actualLocation);
bpClients[id] = bpClient;
bpClient.location.line = actualLocation.line;
bpClient.location.column = actualLocation.column;
bpClient.location.url = actualLocation.sourceUrl || "";
return {
id,
actualLocation
};
});
}
function removeBreakpoint(generatedLocation) {
try {
const id = (0, _breakpoint.makePendingLocationId)(generatedLocation);
const bpClient = bpClients[id];
if (!bpClient) {
console.warn("No breakpoint to delete on server");
return Promise.resolve();
}
delete bpClients[id];
return bpClient.remove();
} catch (_error) {
console.warn("No breakpoint to delete on server");
}
}
function setBreakpointCondition(breakpointId, location, condition, noSliding) {
const bpClient = bpClients[breakpointId];
delete bpClients[breakpointId];
return bpClient.setCondition(threadClient, condition, noSliding).then(_bpClient => {
bpClients[breakpointId] = _bpClient;
return {
id: breakpointId
};
});
}
async function evaluateInFrame(script, frameId) {
return evaluate(script, {
frameId
});
}
async function evaluateExpressions(scripts, frameId) {
return Promise.all(scripts.map(script => evaluate(script, {
frameId
})));
}
function evaluate(script, {
frameId
} = {}) {
const params = frameId ? {
frameActor: frameId
} : {};
if (!tabTarget || !tabTarget.activeConsole || !script) {
return Promise.resolve({});
}
return new Promise(resolve => {
tabTarget.activeConsole.evaluateJSAsync(script, result => resolve(result), params);
});
}
function autocomplete(input, cursor, frameId) {
if (!tabTarget || !tabTarget.activeConsole || !input) {
return Promise.resolve({});
}
return new Promise(resolve => {
tabTarget.activeConsole.autocomplete(input, cursor, result => resolve(result), frameId);
});
}
function debuggeeCommand(script) {
tabTarget.activeConsole.evaluateJS(script, () => {}, {});
if (!debuggerClient) {
return;
}
const consoleActor = tabTarget.form.consoleActor;
const request = debuggerClient._activeRequests.get(consoleActor);
request.emit("json-reply", {});
debuggerClient._activeRequests.delete(consoleActor);
return Promise.resolve();
}
function navigate(url) {
return tabTarget.activeTab.navigateTo(url);
}
function reload() {
return tabTarget.activeTab.reload();
}
function getProperties(grip) {
const objClient = threadClient.pauseGrip(grip);
return objClient.getPrototypeAndProperties().then(resp => {
const {
ownProperties,
safeGetterValues
} = resp;
for (const name in safeGetterValues) {
const {
enumerable,
writable,
getterValue
} = safeGetterValues[name];
ownProperties[name] = {
enumerable,
writable,
value: getterValue
};
}
return resp;
});
}
async function getFrameScopes(frame) {
if (frame.scope) {
return frame.scope;
}
return threadClient.getEnvironment(frame.id);
}
function pauseOnExceptions(shouldPauseOnExceptions, shouldPauseOnCaughtExceptions) {
return threadClient.pauseOnExceptions(shouldPauseOnExceptions, // Providing opposite value because server
// uses "shouldIgnoreCaughtExceptions"
!shouldPauseOnCaughtExceptions);
}
function prettyPrint(sourceId, indentSize) {
const sourceClient = threadClient.source({
actor: sourceId
});
return sourceClient.prettyPrint(indentSize);
}
async function blackBox(sourceId, isBlackBoxed) {
const sourceClient = threadClient.source({
actor: sourceId
});
if (isBlackBoxed) {
await sourceClient.unblackBox();
} else {
await sourceClient.blackBox();
}
return {
isBlackBoxed: !isBlackBoxed
};
}
function disablePrettyPrint(sourceId) {
const sourceClient = threadClient.source({
actor: sourceId
});
return sourceClient.disablePrettyPrint();
}
async function setPausePoints(sourceId, pausePoints) {
return sendPacket({
to: sourceId,
type: "setPausePoints",
pausePoints
});
}
async function setSkipPausing(shouldSkip) {
return threadClient.request({
skip: shouldSkip,
to: threadClient.actor,
type: "skipPausing"
});
}
function interrupt() {
return threadClient.interrupt();
}
function eventListeners() {
return threadClient.eventListeners();
}
function pauseGrip(func) {
return threadClient.pauseGrip(func);
}
async function fetchSources() {
const {
sources
} = await threadClient.getSources();
return sources.map(source => (0, _create.createSource)(source, {
supportsWasm
}));
}
/**
* Temporary helper to check if the current server will support a call to
* listWorkers. On Fennec 60 or older, the call will silently crash and prevent
* the client from resuming.
* XXX: Remove when FF60 for Android is no longer used or available.
*
* See https://bugzilla.mozilla.org/show_bug.cgi?id=1443550 for more details.
*/
async function checkServerSupportsListWorkers() {
const root = await tabTarget.root; // root is not available on all debug targets.
if (!root) {
return false;
}
const deviceFront = await (0, _frontsDevice.getDeviceFront)(debuggerClient, root);
const description = await deviceFront.getDescription();
const isFennec = description.apptype === "mobile/android";
if (!isFennec) {
// Explicitly return true early to avoid calling Services.vs.compare.
// This would force us to extent the Services shim provided by
// devtools-modules, used when this code runs in a tab.
return true;
} // We are only interested in Fennec release versions here.
// We assume that the server fix for Bug 1443550 will land in FF61.
const version = description.platformversion;
return _devtoolsModules.Services.vc.compare(version, "61.0") >= 0;
}
async function fetchWorkers() {
// Temporary workaround for Bug 1443550
// XXX: Remove when FF60 for Android is no longer used or available.
const supportsListWorkers = await checkServerSupportsListWorkers(); // NOTE: The Worker and Browser Content toolboxes do not have a parent
// with a listWorkers function
// TODO: there is a listWorkers property, but it is not a function on the
// parent. Investigate what it is
if (!threadClient._parent || typeof threadClient._parent.listWorkers != "function" || !supportsListWorkers) {
return Promise.resolve({
workers: []
});
}
return threadClient._parent.listWorkers();
}
const clientCommands = {
autocomplete,
blackBox,
interrupt,
eventListeners,
pauseGrip,
resume,
stepIn,
stepOut,
stepOver,
rewind,
reverseStepIn,
reverseStepOut,
reverseStepOver,
breakOnNext,
sourceContents,
getBreakpointByLocation,
setBreakpoint,
removeBreakpoint,
setBreakpointCondition,
evaluate,
evaluateInFrame,
evaluateExpressions,
debuggeeCommand,
navigate,
reload,
getProperties,
getFrameScopes,
pauseOnExceptions,
prettyPrint,
disablePrettyPrint,
fetchSources,
fetchWorkers,
sendPacket,
setPausePoints,
setSkipPausing
};
exports.setupCommands = setupCommands;
exports.clientCommands = clientCommands;

Просмотреть файл

@ -0,0 +1,85 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.createFrame = createFrame;
exports.createSource = createSource;
exports.createPause = createPause;
exports.createBreakpointLocation = createBreakpointLocation;
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/* 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/>. */
// This module converts Firefox specific types to the generic types
function createFrame(frame) {
if (!frame) {
return null;
}
let title;
if (frame.type == "call") {
const c = frame.callee;
title = c.name || c.userDisplayName || c.displayName || L10N.getStr("anonymous");
} else {
title = `(${frame.type})`;
}
const location = {
sourceId: frame.where.source.actor,
line: frame.where.line,
column: frame.where.column
};
return {
id: frame.actor,
displayName: title,
location,
generatedLocation: location,
this: frame.this,
scope: frame.environment
};
}
function createSource(source, {
supportsWasm
}) {
return {
id: source.actor,
url: source.url,
isPrettyPrinted: false,
isWasm: supportsWasm && source.introductionType === "wasm",
sourceMapURL: source.sourceMapURL,
isBlackBoxed: false,
loadedState: "unloaded"
};
}
function createPause(packet, response) {
// NOTE: useful when the debugger is already paused
const frame = packet.frame || response.frames[0];
return _objectSpread({}, packet, {
frame: createFrame(frame),
frames: response.frames.map(createFrame)
});
} // Firefox only returns `actualLocation` if it actually changed,
// but we want it always to exist. Format `actualLocation` if it
// exists, otherwise use `location`.
function createBreakpointLocation(location, actualLocation) {
if (!actualLocation) {
return location;
}
return {
sourceId: actualLocation.source.actor,
sourceUrl: actualLocation.source.url,
line: actualLocation.line,
column: actualLocation.column
};
}

Просмотреть файл

@ -0,0 +1,104 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.clientEvents = exports.setupEvents = undefined;
var _create = require("./create");
var _sourceQueue = require("../../utils/source-queue");
var _sourceQueue2 = _interopRequireDefault(_sourceQueue);
var _prefs = require("../../utils/prefs");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
const CALL_STACK_PAGE_SIZE = 1000;
let threadClient;
let actions;
let supportsWasm;
let isInterrupted;
function setupEvents(dependencies) {
threadClient = dependencies.threadClient;
actions = dependencies.actions;
supportsWasm = dependencies.supportsWasm;
_sourceQueue2.default.initialize({
actions,
supportsWasm,
createSource: _create.createSource
});
if (threadClient) {
Object.keys(clientEvents).forEach(eventName => {
threadClient.addListener(eventName, clientEvents[eventName]);
});
if (threadClient._parent) {
threadClient._parent.addListener("workerListChanged", workerListChanged);
}
}
}
async function paused(_, packet) {
// If paused by an explicit interrupt, which are generated by the
// slow script dialog and internal events such as setting
// breakpoints, ignore the event.
const {
why
} = packet;
if (why.type === "interrupted" && !packet.why.onNext) {
isInterrupted = true;
return;
} // Eagerly fetch the frames
const response = await threadClient.getFrames(0, CALL_STACK_PAGE_SIZE);
if (why.type != "alreadyPaused") {
const pause = (0, _create.createPause)(packet, response);
await _sourceQueue2.default.flush();
actions.paused(pause);
}
}
function resumed(_, packet) {
// NOTE: the client suppresses resumed events while interrupted
// to prevent unintentional behavior.
// see [client docs](../README.md#interrupted) for more information.
if (isInterrupted) {
isInterrupted = false;
return;
}
actions.resumed(packet);
}
function newSource(_, {
source
}) {
_sourceQueue2.default.queue(source);
if (_prefs.features.eventListeners) {
actions.fetchEventListeners();
}
}
function workerListChanged() {
actions.updateWorkers();
}
const clientEvents = {
paused,
resumed,
newSource
};
exports.setupEvents = setupEvents;
exports.clientEvents = clientEvents;

Просмотреть файл

@ -0,0 +1,21 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getDeviceFront = getDeviceFront;
/* 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/>. */
function getDeviceFront() {
return {
getDescription: function () {
return {
// Return anything that will not match Fennec v60
apptype: "apptype",
version: "version"
};
}
};
}

Просмотреть файл

@ -0,0 +1,15 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'commands.js',
'create.js',
'events.js',
'fronts-device.js',
)

Просмотреть файл

@ -0,0 +1,73 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.onConnect = undefined;
var _firefox = require("./firefox");
var firefox = _interopRequireWildcard(_firefox);
var _prefs = require("../utils/prefs");
var _dbg = require("../utils/dbg");
var _bootstrap = require("../utils/bootstrap");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function loadFromPrefs(actions) {
const {
pauseOnExceptions,
pauseOnCaughtExceptions
} = _prefs.prefs;
if (pauseOnExceptions || pauseOnCaughtExceptions) {
return actions.pauseOnExceptions(pauseOnExceptions, pauseOnCaughtExceptions);
}
}
async function onConnect(connection, {
services,
toolboxActions
}) {
// NOTE: the landing page does not connect to a JS process
if (!connection) {
return;
}
const commands = firefox.clientCommands;
const {
store,
actions,
selectors
} = (0, _bootstrap.bootstrapStore)(commands, {
services,
toolboxActions
});
const workers = (0, _bootstrap.bootstrapWorkers)();
await firefox.onConnect(connection, actions);
await loadFromPrefs(actions);
(0, _dbg.setupHelper)({
store,
actions,
selectors,
workers: _objectSpread({}, workers, services),
connection,
client: firefox.clientCommands
});
(0, _bootstrap.bootstrapApp)(store);
return {
store,
actions,
selectors,
client: commands
};
}
exports.onConnect = onConnect;

Просмотреть файл

@ -0,0 +1,13 @@
# vim: set filetype=python:
# 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/.
DIRS += [
'firefox',
]
DevToolsModules(
'firefox.js',
'index.js',
)

Просмотреть файл

@ -0,0 +1,297 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _propTypes = require("devtools/client/shared/vendor/react-prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _prefs = require("../utils/prefs");
var _actions = require("../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _ShortcutsModal = require("./ShortcutsModal");
var _selectors = require("../selectors/index");
var _devtoolsModules = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-modules"];
var _devtoolsSplitter = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-splitter"];
var _devtoolsSplitter2 = _interopRequireDefault(_devtoolsSplitter);
var _ProjectSearch = require("./ProjectSearch");
var _ProjectSearch2 = _interopRequireDefault(_ProjectSearch);
var _PrimaryPanes = require("./PrimaryPanes/index");
var _PrimaryPanes2 = _interopRequireDefault(_PrimaryPanes);
var _Editor = require("./Editor/index");
var _Editor2 = _interopRequireDefault(_Editor);
var _SecondaryPanes = require("./SecondaryPanes/index");
var _SecondaryPanes2 = _interopRequireDefault(_SecondaryPanes);
var _WelcomeBox = require("./WelcomeBox");
var _WelcomeBox2 = _interopRequireDefault(_WelcomeBox);
var _Tabs = require("./Editor/Tabs");
var _Tabs2 = _interopRequireDefault(_Tabs);
var _QuickOpenModal = require("./QuickOpenModal");
var _QuickOpenModal2 = _interopRequireDefault(_QuickOpenModal);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
const shortcuts = new _devtoolsModules.KeyShortcuts({
window
});
const {
appinfo
} = _devtoolsModules.Services;
const isMacOS = appinfo.OS === "Darwin";
const horizontalLayoutBreakpoint = window.matchMedia("(min-width: 800px)");
const verticalLayoutBreakpoint = window.matchMedia("(min-width: 10px) and (max-width: 800px)");
class App extends _react.Component {
constructor(props) {
super(props);
this.getChildContext = () => {
return {
shortcuts
};
};
this.onEscape = (_, e) => {
const {
activeSearch,
closeActiveSearch,
closeQuickOpen,
quickOpenEnabled
} = this.props;
if (activeSearch) {
e.preventDefault();
closeActiveSearch();
}
if (quickOpenEnabled) {
e.preventDefault();
closeQuickOpen();
}
};
this.onCommandSlash = () => {
this.toggleShortcutsModal();
};
this.toggleQuickOpenModal = (_, e, query) => {
const {
quickOpenEnabled,
openQuickOpen,
closeQuickOpen
} = this.props;
e.preventDefault();
e.stopPropagation();
if (quickOpenEnabled === true) {
closeQuickOpen();
return;
}
if (query != null) {
openQuickOpen(query);
return;
}
openQuickOpen();
return;
};
this.onLayoutChange = () => {
this.setOrientation();
};
this.renderEditorPane = () => {
const {
startPanelCollapsed,
endPanelCollapsed
} = this.props;
const {
endPanelSize,
startPanelSize
} = this.state;
const horizontal = this.isHorizontal();
return _react2.default.createElement("div", {
className: "editor-pane"
}, _react2.default.createElement("div", {
className: "editor-container"
}, _react2.default.createElement(_Tabs2.default, {
startPanelCollapsed: startPanelCollapsed,
endPanelCollapsed: endPanelCollapsed,
horizontal: horizontal,
startPanelSize: startPanelSize,
endPanelSize: endPanelSize
}), _react2.default.createElement(_Editor2.default, {
horizontal: horizontal,
startPanelSize: startPanelSize,
endPanelSize: endPanelSize
}), !this.props.selectedSource ? _react2.default.createElement(_WelcomeBox2.default, {
horizontal: horizontal
}) : null, _react2.default.createElement(_ProjectSearch2.default, null)));
};
this.renderLayout = () => {
const {
startPanelCollapsed,
endPanelCollapsed
} = this.props;
const horizontal = this.isHorizontal();
const maxSize = horizontal ? "70%" : "95%";
const primaryInitialSize = horizontal ? "250px" : "150px";
return _react2.default.createElement(_devtoolsSplitter2.default, {
style: {
width: "100vw"
},
initialHeight: 400,
initialWidth: 300,
minSize: 30,
maxSize: maxSize,
splitterSize: 1,
vert: horizontal,
startPanel: _react2.default.createElement(_devtoolsSplitter2.default, {
style: {
width: "100vw"
},
initialSize: primaryInitialSize,
minSize: 30,
maxSize: "85%",
splitterSize: 1,
startPanelCollapsed: startPanelCollapsed,
startPanel: _react2.default.createElement(_PrimaryPanes2.default, {
horizontal: horizontal
}),
endPanel: this.renderEditorPane()
}),
endPanelControl: true,
endPanel: _react2.default.createElement(_SecondaryPanes2.default, {
horizontal: horizontal,
toggleShortcutsModal: () => this.toggleShortcutsModal()
}),
endPanelCollapsed: endPanelCollapsed
});
};
this.state = {
shortcutsModalEnabled: false,
startPanelSize: 0,
endPanelSize: 0
};
}
componentDidMount() {
horizontalLayoutBreakpoint.addListener(this.onLayoutChange);
verticalLayoutBreakpoint.addListener(this.onLayoutChange);
this.setOrientation();
shortcuts.on(L10N.getStr("symbolSearch.search.key2"), (_, e) => this.toggleQuickOpenModal(_, e, "@"));
const searchKeys = [L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key")];
searchKeys.forEach(key => shortcuts.on(key, this.toggleQuickOpenModal));
shortcuts.on(L10N.getStr("gotoLineModal.key2"), (_, e) => this.toggleQuickOpenModal(_, e, ":"));
shortcuts.on("Escape", this.onEscape);
shortcuts.on("Cmd+/", this.onCommandSlash);
}
componentWillUnmount() {
horizontalLayoutBreakpoint.removeListener(this.onLayoutChange);
verticalLayoutBreakpoint.removeListener(this.onLayoutChange);
shortcuts.off(L10N.getStr("symbolSearch.search.key2"), this.toggleQuickOpenModal);
const searchKeys = [L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key")];
searchKeys.forEach(key => shortcuts.off(key, this.toggleQuickOpenModal));
shortcuts.off(L10N.getStr("gotoLineModal.key2"), this.toggleQuickOpenModal);
shortcuts.off("Escape", this.onEscape);
}
isHorizontal() {
return this.props.orientation === "horizontal";
}
setOrientation() {
// If the orientation does not match (if it is not visible) it will
// not setOrientation, or if it is the same as before, calling
// setOrientation will not cause a rerender.
if (horizontalLayoutBreakpoint.matches) {
this.props.setOrientation("horizontal");
} else if (verticalLayoutBreakpoint.matches) {
this.props.setOrientation("vertical");
}
}
toggleShortcutsModal() {
this.setState(prevState => ({
shortcutsModalEnabled: !prevState.shortcutsModalEnabled
}));
}
renderShortcutsModal() {
const additionalClass = isMacOS ? "mac" : "";
if (!_prefs.features.shortcuts) {
return;
}
return _react2.default.createElement(_ShortcutsModal.ShortcutsModal, {
additionalClass: additionalClass,
enabled: this.state.shortcutsModalEnabled,
handleClose: () => this.toggleShortcutsModal()
});
}
render() {
const {
quickOpenEnabled
} = this.props;
return _react2.default.createElement("div", {
className: "debugger"
}, this.renderLayout(), quickOpenEnabled === true && _react2.default.createElement(_QuickOpenModal2.default, {
shortcutsModalEnabled: this.state.shortcutsModalEnabled,
toggleShortcutsModal: () => this.toggleShortcutsModal()
}), this.renderShortcutsModal());
}
}
App.childContextTypes = {
shortcuts: _propTypes2.default.object
};
const mapStateToProps = state => ({
selectedSource: (0, _selectors.getSelectedSource)(state),
startPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "start"),
endPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "end"),
activeSearch: (0, _selectors.getActiveSearch)(state),
quickOpenEnabled: (0, _selectors.getQuickOpenEnabled)(state),
orientation: (0, _selectors.getOrientation)(state)
});
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(App);

Просмотреть файл

@ -0,0 +1,138 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactDom = require("devtools/client/shared/vendor/react-dom");
var _reactDom2 = _interopRequireDefault(_reactDom);
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
var _Svg = require("devtools/client/debugger/new/dist/vendors").vendored["Svg"];
var _Svg2 = _interopRequireDefault(_Svg);
var _editor = require("../../utils/editor/index");
var _prefs = require("../../utils/prefs");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
const breakpointSvg = document.createElement("div");
_reactDom2.default.render(_react2.default.createElement(_Svg2.default, {
name: "breakpoint"
}), breakpointSvg);
function makeMarker(isDisabled) {
const bp = breakpointSvg.cloneNode(true);
bp.className = (0, _classnames2.default)("editor new-breakpoint", {
"breakpoint-disabled": isDisabled,
"folding-enabled": _prefs.features.codeFolding
});
return bp;
}
class Breakpoint extends _react.Component {
constructor() {
super();
this.addBreakpoint = () => {
const {
breakpoint,
editor,
selectedSource
} = this.props; // Hidden Breakpoints are never rendered on the client
if (breakpoint.hidden) {
return;
} // NOTE: we need to wait for the breakpoint to be loaded
// to get the generated location
if (!selectedSource || breakpoint.loading) {
return;
}
const sourceId = selectedSource.id;
const line = (0, _editor.toEditorLine)(sourceId, breakpoint.location.line);
editor.codeMirror.setGutterMarker(line, "breakpoints", makeMarker(breakpoint.disabled));
editor.codeMirror.addLineClass(line, "line", "new-breakpoint");
if (breakpoint.condition) {
editor.codeMirror.addLineClass(line, "line", "has-condition");
} else {
editor.codeMirror.removeLineClass(line, "line", "has-condition");
}
};
}
shouldComponentUpdate(nextProps) {
const {
editor,
breakpoint,
selectedSource
} = this.props;
return editor !== nextProps.editor || breakpoint.disabled !== nextProps.breakpoint.disabled || breakpoint.hidden !== nextProps.breakpoint.hidden || breakpoint.condition !== nextProps.breakpoint.condition || breakpoint.loading !== nextProps.breakpoint.loading || selectedSource !== nextProps.selectedSource;
}
componentDidMount() {
this.addBreakpoint();
}
componentDidUpdate() {
this.addBreakpoint();
}
componentWillUnmount() {
const {
editor,
breakpoint,
selectedSource
} = this.props;
if (!selectedSource) {
return;
}
if (breakpoint.loading) {
return;
}
const sourceId = selectedSource.id;
const doc = (0, _editor.getDocument)(sourceId);
if (!doc) {
return;
}
const line = (0, _editor.toEditorLine)(sourceId, breakpoint.location.line); // NOTE: when we upgrade codemirror we can use `doc.setGutterMarker`
if (doc.setGutterMarker) {
doc.setGutterMarker(line, "breakpoints", null);
} else {
editor.codeMirror.setGutterMarker(line, "breakpoints", null);
}
doc.removeLineClass(line, "line", "new-breakpoint");
doc.removeLineClass(line, "line", "has-condition");
}
render() {
return null;
}
}
exports.default = Breakpoint;

Просмотреть файл

@ -0,0 +1,63 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _Breakpoint = require("./Breakpoint");
var _Breakpoint2 = _interopRequireDefault(_Breakpoint);
var _selectors = require("../../selectors/index");
var _breakpoint = require("../../utils/breakpoint/index");
var _source = require("../../utils/source");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class Breakpoints extends _react.Component {
shouldComponentUpdate(nextProps) {
if (nextProps.selectedSource && !(0, _source.isLoaded)(nextProps.selectedSource)) {
return false;
}
return true;
}
render() {
const {
breakpoints,
selectedSource,
editor
} = this.props;
if (!selectedSource || !breakpoints || selectedSource.get("isBlackBoxed")) {
return null;
}
return _react2.default.createElement("div", null, breakpoints.valueSeq().map(bp => {
return _react2.default.createElement(_Breakpoint2.default, {
key: (0, _breakpoint.makeLocationId)(bp.location),
breakpoint: bp,
selectedSource: selectedSource,
editor: editor
});
}));
}
}
exports.default = (0, _reactRedux.connect)(state => ({
breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
selectedSource: (0, _selectors.getSelectedSource)(state)
}))(Breakpoints);

Просмотреть файл

@ -0,0 +1,99 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _editor = require("../../utils/editor/index");
/* 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/>. */
class CallSite extends _react.Component {
constructor() {
super();
this.addCallSite = nextProps => {
const {
editor,
callSite,
breakpoint,
source
} = nextProps || this.props;
const className = !breakpoint ? "call-site" : "call-site-bp";
const sourceId = source.get("id");
const editorRange = (0, _editor.toEditorRange)(sourceId, callSite.location);
this.marker = (0, _editor.markText)(editor, className, editorRange);
};
this.clearCallSite = () => {
if (this.marker) {
this.marker.clear();
this.marker = null;
}
};
this.marker = undefined;
}
shouldComponentUpdate(nextProps) {
return this.props.editor !== nextProps.editor;
}
componentDidMount() {
const {
breakpoint,
showCallSite
} = this.props;
if (!breakpoint && !showCallSite) {
return;
}
this.addCallSite();
}
componentWillReceiveProps(nextProps) {
const {
breakpoint,
showCallSite
} = this.props;
if (nextProps.breakpoint !== breakpoint) {
if (this.marker) {
this.clearCallSite();
}
if (nextProps.showCallSite) {
this.addCallSite(nextProps);
}
}
if (nextProps.showCallSite !== showCallSite) {
if (nextProps.showCallSite) {
if (!this.marker) {
this.addCallSite();
}
} else if (!nextProps.breakpoint) {
this.clearCallSite();
}
}
}
componentWillUnmount() {
if (!this.marker) {
return;
}
this.marker.clear();
}
render() {
return null;
}
}
exports.default = CallSite;

Просмотреть файл

@ -0,0 +1,257 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _lodash = require("devtools/client/shared/vendor/lodash");
var _CallSite = require("./CallSite");
var _CallSite2 = _interopRequireDefault(_CallSite);
var _selectors = require("../../selectors/index");
var _editor = require("../../utils/editor/index");
var _wasm = require("../../utils/wasm");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function getCallSiteAtLocation(callSites, location) {
return callSites.find(callSite => (0, _lodash.isEqualWith)(callSite.location, location, (cloc, loc) => {
return loc.line === cloc.start.line && loc.column >= cloc.start.column && loc.column <= cloc.end.column;
}));
}
class CallSites extends _react.Component {
constructor(props) {
super(props);
this.onKeyUp = e => {
if (e.key === "Alt") {
e.preventDefault();
this.setState({
showCallSites: false
});
}
};
this.onKeyDown = e => {
if (e.key === "Alt") {
e.preventDefault();
this.setState({
showCallSites: true
});
}
};
this.state = {
showCallSites: false
};
}
componentDidMount() {
const {
editor
} = this.props;
const codeMirrorWrapper = editor.codeMirror.getWrapperElement();
codeMirrorWrapper.addEventListener("click", e => this.onTokenClick(e));
document.body.addEventListener("keydown", this.onKeyDown);
document.body.addEventListener("keyup", this.onKeyUp);
}
componentWillUnmount() {
const {
editor
} = this.props;
const codeMirrorWrapper = editor.codeMirror.getWrapperElement();
codeMirrorWrapper.removeEventListener("click", e => this.onTokenClick(e));
document.body.removeEventListener("keydown", this.onKeyDown);
document.body.removeEventListener("keyup", this.onKeyUp);
}
onTokenClick(e) {
const {
target
} = e;
const {
editor,
selectedLocation
} = this.props;
if (!e.altKey && !target.classList.contains("call-site-bp") || !target.classList.contains("call-site") && !target.classList.contains("call-site-bp")) {
return;
}
const {
sourceId
} = selectedLocation;
const {
line,
column
} = (0, _editor.getTokenLocation)(editor.codeMirror, target);
this.toggleBreakpoint(line, (0, _wasm.isWasm)(sourceId) ? undefined : column);
}
toggleBreakpoint(line, column = undefined) {
const {
selectedSource,
selectedLocation,
addBreakpoint,
removeBreakpoint,
callSites
} = this.props;
const callSite = getCallSiteAtLocation(callSites, {
line,
column
});
if (!callSite) {
return;
}
const bp = callSite.breakpoint;
if (bp && bp.loading || !selectedLocation || !selectedSource) {
return;
}
const {
sourceId
} = selectedLocation;
if (bp) {
// NOTE: it's possible the breakpoint has slid to a column
column = column || bp.location.column;
removeBreakpoint({
sourceId: sourceId,
line: line,
column
});
} else {
addBreakpoint({
sourceId: sourceId,
sourceUrl: selectedSource.get("url"),
line: line,
column: column
});
}
}
render() {
const {
editor,
callSites,
selectedSource
} = this.props;
const {
showCallSites
} = this.state;
let sites;
if (!callSites) {
return null;
}
editor.codeMirror.operation(() => {
const childCallSites = callSites.map((callSite, index) => {
const props = {
key: index,
callSite,
editor,
source: selectedSource,
breakpoint: callSite.breakpoint,
showCallSite: showCallSites
};
return _react2.default.createElement(_CallSite2.default, props);
});
sites = _react2.default.createElement("div", null, childCallSites);
});
return sites;
}
}
function getCallSites(symbols, breakpoints) {
if (!symbols || !symbols.callExpressions) {
return;
}
const callSites = symbols.callExpressions; // NOTE: we create a breakpoint map keyed on location
// to speed up the lookups. Hopefully we'll fix the
// inconsistency with column offsets so that we can expect
// a breakpoint to be added at the beginning of a call expression.
const bpLocationMap = (0, _lodash.keyBy)(breakpoints.valueSeq().toJS(), ({
location
}) => locationKey(location));
function locationKey({
line,
column
}) {
return `${line}/${column}`;
}
function findBreakpoint(callSite) {
const {
location: {
start,
end
}
} = callSite;
const breakpointId = (0, _lodash.range)(start.column - 1, end.column).map(column => locationKey({
line: start.line,
column
})).find(key => bpLocationMap[key]);
if (breakpointId) {
return bpLocationMap[breakpointId];
}
}
return callSites.filter(({
location
}) => location.start.line === location.end.line).map(callSite => _objectSpread({}, callSite, {
breakpoint: findBreakpoint(callSite)
}));
}
const mapStateToProps = state => {
const selectedLocation = (0, _selectors.getSelectedLocation)(state);
const selectedSource = (0, _selectors.getSelectedSource)(state);
const sourceId = selectedLocation && selectedLocation.sourceId;
const symbols = (0, _selectors.getSymbols)(state, selectedSource);
const breakpoints = (0, _selectors.getBreakpointsForSource)(state, sourceId);
return {
selectedLocation,
selectedSource,
callSites: getCallSites(symbols, breakpoints),
breakpoints: breakpoints
};
};
const {
addBreakpoint,
removeBreakpoint
} = _actions2.default;
const mapDispatchToProps = {
addBreakpoint,
removeBreakpoint
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(CallSites);

Просмотреть файл

@ -0,0 +1,213 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ConditionalPanel = undefined;
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactDom = require("devtools/client/shared/vendor/react-dom");
var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _editor = require("../../utils/editor/index");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../selectors/index");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class ConditionalPanel extends _react.PureComponent {
constructor() {
super();
this.saveAndClose = () => {
if (this.input) {
this.setBreakpoint(this.input.value);
}
this.props.closeConditionalPanel();
};
this.onKey = e => {
if (e.key === "Enter") {
this.saveAndClose();
} else if (e.key === "Escape") {
this.props.closeConditionalPanel();
}
};
this.repositionOnScroll = () => {
if (this.panelNode && this.scrollParent) {
const {
scrollLeft
} = this.scrollParent;
this.panelNode.style.transform = `translateX(${scrollLeft}px)`;
}
};
this.cbPanel = null;
}
keepFocusOnInput() {
if (this.input) {
this.input.focus();
}
}
setBreakpoint(condition) {
const {
selectedLocation,
line
} = this.props;
const sourceId = selectedLocation ? selectedLocation.sourceId : "";
const location = {
sourceId,
line
};
return this.props.setBreakpointCondition(location, {
condition
});
}
clearConditionalPanel() {
if (this.cbPanel) {
this.cbPanel.clear();
this.cbPanel = null;
}
if (this.scrollParent) {
this.scrollParent.removeEventListener("scroll", this.repositionOnScroll);
}
}
componentWillMount() {
if (this.props.line) {
return this.renderToWidget(this.props);
}
}
componentWillUpdate(nextProps) {
if (nextProps.line) {
return this.renderToWidget(nextProps);
}
return this.clearConditionalPanel();
}
componentWillUnmount() {
// This is called if CodeMirror is re-initializing itself before the
// user closes the conditional panel. Clear the widget, and re-render it
// as soon as this component gets remounted
return this.clearConditionalPanel();
}
renderToWidget(props) {
if (this.cbPanel) {
if (this.props.line && this.props.line == props.line) {
return props.closeConditionalPanel();
}
this.clearConditionalPanel();
}
const {
selectedLocation,
line,
editor
} = props;
const sourceId = selectedLocation ? selectedLocation.sourceId : "";
const editorLine = (0, _editor.toEditorLine)(sourceId, line);
this.cbPanel = editor.codeMirror.addLineWidget(editorLine, this.renderConditionalPanel(props), {
coverGutter: true,
noHScroll: false
});
if (this.input) {
let parent = this.input.parentNode;
while (parent) {
if (parent instanceof HTMLElement && parent.classList.contains("CodeMirror-scroll")) {
this.scrollParent = parent;
break;
}
parent = parent.parentNode;
}
if (this.scrollParent) {
this.scrollParent.addEventListener("scroll", this.repositionOnScroll);
this.repositionOnScroll();
}
this.input.focus();
}
}
renderConditionalPanel(props) {
const {
breakpoint
} = props;
const condition = breakpoint ? breakpoint.condition : "";
const panel = document.createElement("div");
_reactDom2.default.render(_react2.default.createElement("div", {
className: "conditional-breakpoint-panel",
onClick: () => this.keepFocusOnInput(),
onBlur: this.props.closeConditionalPanel,
ref: node => this.panelNode = node
}, _react2.default.createElement("div", {
className: "prompt"
}, "\xBB"), _react2.default.createElement("input", {
defaultValue: condition,
placeholder: L10N.getStr("editor.conditionalPanel.placeholder"),
onKeyDown: this.onKey,
ref: input => {
this.input = input;
this.keepFocusOnInput();
}
})), panel);
return panel;
}
render() {
return null;
}
}
exports.ConditionalPanel = ConditionalPanel;
const mapStateToProps = state => {
const line = (0, _selectors.getConditionalPanelLine)(state);
const selectedLocation = (0, _selectors.getSelectedLocation)(state);
return {
selectedLocation,
breakpoint: (0, _selectors.getBreakpointForLine)(state, selectedLocation.sourceId, line),
line
};
};
const {
setBreakpointCondition,
openConditionalPanel,
closeConditionalPanel
} = _actions2.default;
const mapDispatchToProps = {
setBreakpointCondition,
openConditionalPanel,
closeConditionalPanel
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(ConditionalPanel);

Просмотреть файл

@ -0,0 +1,134 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.DebugLine = undefined;
var _react = require("devtools/client/shared/vendor/react");
var _editor = require("../../utils/editor/index");
var _source = require("../../utils/source");
var _pause = require("../../utils/pause/index");
var _indentation = require("../../utils/indentation");
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _selectors = require("../../selectors/index");
/* 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/>. */
function isDocumentReady(selectedSource, selectedFrame) {
return selectedFrame && (0, _source.isLoaded)(selectedSource) && (0, _editor.hasDocument)(selectedFrame.location.sourceId);
}
class DebugLine extends _react.Component {
componentDidUpdate(prevProps) {
const {
why,
selectedFrame,
selectedSource
} = this.props;
this.setDebugLine(why, selectedFrame, selectedSource);
}
componentWillUpdate() {
const {
why,
selectedFrame,
selectedSource
} = this.props;
this.clearDebugLine(selectedFrame, selectedSource, why);
}
componentDidMount() {
const {
why,
selectedFrame,
selectedSource
} = this.props;
this.setDebugLine(why, selectedFrame, selectedSource);
}
setDebugLine(why, selectedFrame, selectedSource) {
if (!isDocumentReady(selectedSource, selectedFrame)) {
return;
}
const sourceId = selectedFrame.location.sourceId;
const doc = (0, _editor.getDocument)(sourceId);
let {
line,
column
} = (0, _editor.toEditorPosition)(selectedFrame.location);
const {
markTextClass,
lineClass
} = this.getTextClasses(why);
doc.addLineClass(line, "line", lineClass);
const lineText = doc.getLine(line);
column = Math.max(column, (0, _indentation.getIndentation)(lineText));
this.debugExpression = doc.markText({
ch: column,
line
}, {
ch: null,
line
}, {
className: markTextClass
});
}
clearDebugLine(selectedFrame, selectedSource, why) {
if (!isDocumentReady(selectedSource, selectedFrame)) {
return;
}
if (this.debugExpression) {
this.debugExpression.clear();
}
const sourceId = selectedFrame.location.sourceId;
const {
line
} = (0, _editor.toEditorPosition)(selectedFrame.location);
const doc = (0, _editor.getDocument)(sourceId);
const {
lineClass
} = this.getTextClasses(why);
doc.removeLineClass(line, "line", lineClass);
}
getTextClasses(why) {
if ((0, _pause.isException)(why)) {
return {
markTextClass: "debug-expression-error",
lineClass: "new-debug-line-error"
};
}
return {
markTextClass: "debug-expression",
lineClass: "new-debug-line"
};
}
render() {
return null;
}
}
exports.DebugLine = DebugLine;
const mapStateToProps = state => ({
selectedFrame: (0, _selectors.getVisibleSelectedFrame)(state),
selectedSource: (0, _selectors.getSelectedSource)(state),
why: (0, _selectors.getPauseReason)(state)
});
exports.default = (0, _reactRedux.connect)(mapStateToProps)(DebugLine);

Просмотреть файл

@ -0,0 +1,242 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _devtoolsContextmenu = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-contextmenu"];
var _devtoolsSourceMap = require("devtools/client/shared/source-map/index.js");
var _clipboard = require("../../utils/clipboard");
var _function = require("../../utils/function");
var _ast = require("../../utils/ast");
var _editor = require("../../utils/editor/index");
var _source = require("../../utils/source");
var _selectors = require("../../selectors/index");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function getMenuItems(event, {
addExpression,
editor,
evaluateInConsole,
flashLineRange,
getFunctionLocation,
getFunctionText,
hasPrettyPrint,
jumpToMappedLocation,
onGutterContextMenu,
selectedLocation,
selectedSource,
showSource,
toggleBlackBox
}) {
// variables
const hasSourceMap = !!selectedSource.get("sourceMapURL");
const isOriginal = (0, _devtoolsSourceMap.isOriginalId)(selectedLocation.sourceId);
const isPrettyPrinted = (0, _source.isPretty)(selectedSource);
const isPrettified = isPrettyPrinted || hasPrettyPrint;
const isMapped = isOriginal || hasSourceMap;
const {
line
} = editor.codeMirror.coordsChar({
left: event.clientX,
top: event.clientY
});
const selectionText = editor.codeMirror.getSelection().trim();
const sourceLocation = (0, _editor.getSourceLocationFromMouseEvent)(editor, selectedLocation, event);
const isTextSelected = editor.codeMirror.somethingSelected(); // localizations
const blackboxKey = L10N.getStr("sourceFooter.blackbox.accesskey");
const blackboxLabel = L10N.getStr("sourceFooter.blackbox");
const unblackboxLabel = L10N.getStr("sourceFooter.unblackbox");
const toggleBlackBoxLabel = selectedSource.isBlackBoxed ? unblackboxLabel : blackboxLabel;
const copyFunctionKey = L10N.getStr("copyFunction.accesskey");
const copyFunctionLabel = L10N.getStr("copyFunction.label");
const copySourceKey = L10N.getStr("copySource.accesskey");
const copySourceLabel = L10N.getStr("copySource");
const copyToClipboardKey = L10N.getStr("copyToClipboard.accesskey");
const copyToClipboardLabel = L10N.getStr("copyToClipboard.label");
const copySourceUri2Key = L10N.getStr("copySourceUri2.accesskey");
const copySourceUri2Label = L10N.getStr("copySourceUri2");
const evaluateInConsoleLabel = L10N.getStr("evaluateInConsole.label");
const jumpToMappedLocKey = L10N.getStr("editor.jumpToMappedLocation1.accesskey");
const jumpToMappedLocLabel = L10N.getFormatStr("editor.jumpToMappedLocation1", isOriginal ? L10N.getStr("generated") : L10N.getStr("original"));
const revealInTreeKey = L10N.getStr("sourceTabs.revealInTree.accesskey");
const revealInTreeLabel = L10N.getStr("sourceTabs.revealInTree");
const watchExpressionKey = L10N.getStr("expressions.accesskey");
const watchExpressionLabel = L10N.getStr("expressions.label"); // menu items
const copyToClipboardItem = {
id: "node-menu-copy-to-clipboard",
label: copyToClipboardLabel,
accesskey: copyToClipboardKey,
disabled: false,
click: () => (0, _clipboard.copyToTheClipboard)(selectedSource.text)
};
const copySourceItem = {
id: "node-menu-copy-source",
label: copySourceLabel,
accesskey: copySourceKey,
disabled: selectionText.length === 0,
click: () => (0, _clipboard.copyToTheClipboard)(selectionText)
};
const copySourceUri2Item = {
id: "node-menu-copy-source-url",
label: copySourceUri2Label,
accesskey: copySourceUri2Key,
disabled: false,
click: () => (0, _clipboard.copyToTheClipboard)((0, _source.getRawSourceURL)(selectedSource.url))
};
const sourceId = selectedSource.get("id");
const sourceLine = (0, _editor.toSourceLine)(sourceId, line);
const functionText = getFunctionText(sourceLine);
const copyFunctionItem = {
id: "node-menu-copy-function",
label: copyFunctionLabel,
accesskey: copyFunctionKey,
disabled: !functionText,
click: () => {
const {
location: {
start,
end
}
} = getFunctionLocation(sourceLine);
flashLineRange({
start: start.line,
end: end.line,
sourceId: selectedLocation.sourceId
});
return (0, _clipboard.copyToTheClipboard)(functionText);
}
};
const jumpToMappedLocationItem = {
id: "node-menu-jump",
label: jumpToMappedLocLabel,
accesskey: jumpToMappedLocKey,
disabled: !isMapped && !isPrettified,
click: () => jumpToMappedLocation(sourceLocation)
};
const showSourceMenuItem = {
id: "node-menu-show-source",
label: revealInTreeLabel,
accesskey: revealInTreeKey,
disabled: false,
click: () => showSource(sourceId)
};
const blackBoxMenuItem = {
id: "node-menu-blackbox",
label: toggleBlackBoxLabel,
accesskey: blackboxKey,
disabled: isOriginal || isPrettyPrinted || hasSourceMap,
click: () => toggleBlackBox(selectedSource.toJS())
};
const watchExpressionItem = {
id: "node-menu-add-watch-expression",
label: watchExpressionLabel,
accesskey: watchExpressionKey,
click: () => addExpression(editor.codeMirror.getSelection())
};
const evaluateInConsoleItem = {
id: "node-menu-evaluate-in-console",
label: evaluateInConsoleLabel,
click: () => evaluateInConsole(selectionText)
}; // construct menu
const menuItems = [copyToClipboardItem, copySourceItem, copySourceUri2Item, copyFunctionItem, {
type: "separator"
}, jumpToMappedLocationItem, showSourceMenuItem, blackBoxMenuItem]; // conditionally added items
// TODO: Find a new way to only add this for mapped sources?
if (isTextSelected) {
menuItems.push(watchExpressionItem, evaluateInConsoleItem);
}
return menuItems;
}
class EditorMenu extends _react.Component {
constructor() {
super();
}
shouldComponentUpdate(nextProps) {
return nextProps.contextMenu.type === "Editor";
}
componentWillUpdate(nextProps) {
// clear the context menu since it is open
this.props.setContextMenu("", null);
return this.showMenu(nextProps);
}
showMenu(nextProps) {
const {
contextMenu
} = nextProps,
options = _objectWithoutProperties(nextProps, ["contextMenu"]);
const {
event
} = contextMenu;
(0, _devtoolsContextmenu.showMenu)(event, getMenuItems(event, options));
}
render() {
return null;
}
}
const mapStateToProps = state => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
const symbols = (0, _selectors.getSymbols)(state, selectedSource);
return {
selectedLocation: (0, _selectors.getSelectedLocation)(state),
selectedSource,
hasPrettyPrint: !!(0, _selectors.getPrettySource)(state, selectedSource.get("id")),
contextMenu: (0, _selectors.getContextMenu)(state),
getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource.toJS(), symbols),
getFunctionLocation: line => (0, _ast.findClosestFunction)(symbols, {
line,
column: Infinity
})
};
};
const {
addExpression,
evaluateInConsole,
flashLineRange,
jumpToMappedLocation,
setContextMenu,
showSource,
toggleBlackBox
} = _actions2.default;
const mapDispatchToProps = {
addExpression,
evaluateInConsole,
flashLineRange,
jumpToMappedLocation,
setContextMenu,
showSource,
toggleBlackBox
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(EditorMenu);

Просмотреть файл

@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _react = require("devtools/client/shared/vendor/react");
var _selectors = require("../../selectors/index");
var _editor = require("../../utils/editor/index");
/* 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/>. */
class EmptyLines extends _react.Component {
componentDidMount() {
this.disableEmptyLines();
}
componentDidUpdate() {
this.disableEmptyLines();
}
componentWillUnmount() {
const {
emptyLines,
selectedSource,
editor
} = this.props;
if (!emptyLines) {
return;
}
editor.codeMirror.operation(() => {
emptyLines.forEach(emptyLine => {
const line = (0, _editor.toEditorLine)(selectedSource.get("id"), emptyLine);
editor.codeMirror.removeLineClass(line, "line", "empty-line");
});
});
}
disableEmptyLines() {
const {
emptyLines,
selectedSource,
editor
} = this.props;
if (!emptyLines) {
return;
}
editor.codeMirror.operation(() => {
emptyLines.forEach(emptyLine => {
const line = (0, _editor.toEditorLine)(selectedSource.get("id"), emptyLine);
editor.codeMirror.addLineClass(line, "line", "empty-line");
});
});
}
render() {
return null;
}
}
const mapStateToProps = state => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
const foundEmptyLines = (0, _selectors.getEmptyLines)(state, selectedSource.toJS());
return {
selectedSource,
emptyLines: selectedSource ? foundEmptyLines : []
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps)(EmptyLines);

Просмотреть файл

@ -0,0 +1,202 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../selectors/index");
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
var _prefs = require("../../utils/prefs");
var _source = require("../../utils/source");
var _sources = require("../../reducers/sources");
var _editor = require("../../utils/editor/index");
var _PaneToggle = require("../shared/Button/PaneToggle");
var _PaneToggle2 = _interopRequireDefault(_PaneToggle);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class SourceFooter extends _react.PureComponent {
prettyPrintButton() {
const {
selectedSource,
togglePrettyPrint
} = this.props;
const sourceLoaded = selectedSource && (0, _source.isLoaded)(selectedSource);
if (!(0, _editor.shouldShowPrettyPrint)(selectedSource)) {
return;
}
const tooltip = L10N.getStr("sourceTabs.prettyPrint");
const type = "prettyPrint";
return _react2.default.createElement("button", {
onClick: () => togglePrettyPrint(selectedSource.get("id")),
className: (0, _classnames2.default)("action", type, {
active: sourceLoaded,
pretty: (0, _source.isPretty)(selectedSource)
}),
key: type,
title: tooltip,
"aria-label": tooltip
}, _react2.default.createElement("img", {
className: type
}));
}
blackBoxButton() {
const {
selectedSource,
toggleBlackBox
} = this.props;
const sourceLoaded = selectedSource && (0, _source.isLoaded)(selectedSource);
if (!sourceLoaded) {
return;
}
const blackboxed = selectedSource.isBlackBoxed;
const tooltip = L10N.getStr("sourceFooter.blackbox");
const type = "black-box";
return _react2.default.createElement("button", {
onClick: () => toggleBlackBox(selectedSource.toJS()),
className: (0, _classnames2.default)("action", type, {
active: sourceLoaded,
blackboxed: blackboxed
}),
key: type,
title: tooltip,
"aria-label": tooltip
}, _react2.default.createElement("img", {
className: "blackBox"
}));
}
blackBoxSummary() {
const {
selectedSource
} = this.props;
if (!selectedSource || !selectedSource.isBlackBoxed) {
return;
}
return _react2.default.createElement("span", {
className: "blackbox-summary"
}, L10N.getStr("sourceFooter.blackboxed"));
}
coverageButton() {
const {
recordCoverage
} = this.props;
if (!_prefs.features.codeCoverage) {
return;
}
return _react2.default.createElement("button", {
className: "coverage action",
title: L10N.getStr("sourceFooter.codeCoverage"),
onClick: () => recordCoverage(),
"aria-label": L10N.getStr("sourceFooter.codeCoverage")
}, "C");
}
renderToggleButton() {
if (this.props.horizontal) {
return;
}
return _react2.default.createElement(_PaneToggle2.default, {
position: "end",
collapsed: !this.props.endPanelCollapsed,
horizontal: this.props.horizontal,
handleClick: this.props.togglePaneCollapse
});
}
renderCommands() {
return _react2.default.createElement("div", {
className: "commands"
}, this.prettyPrintButton(), this.blackBoxButton(), this.blackBoxSummary(), this.coverageButton());
}
renderSourceSummary() {
const {
mappedSource,
jumpToMappedLocation,
selectedSource
} = this.props;
if (mappedSource) {
const bundleSource = mappedSource.toJS();
const filename = (0, _source.getFilename)(bundleSource);
const tooltip = L10N.getFormatStr("sourceFooter.mappedSourceTooltip", filename);
const title = L10N.getFormatStr("sourceFooter.mappedSource", filename);
const mappedSourceLocation = {
sourceId: selectedSource.get("id"),
line: 1,
column: 1
};
return _react2.default.createElement("button", {
className: "mapped-source",
onClick: () => jumpToMappedLocation(mappedSourceLocation),
title: tooltip
}, _react2.default.createElement("span", null, title));
}
return null;
}
render() {
const {
selectedSource,
horizontal
} = this.props;
if (!(0, _editor.shouldShowFooter)(selectedSource, horizontal)) {
return null;
}
return _react2.default.createElement("div", {
className: "source-footer"
}, this.renderCommands(), this.renderSourceSummary(), this.renderToggleButton());
}
}
const mapStateToProps = state => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
const selectedId = selectedSource.get("id");
const source = selectedSource.toJS();
return {
selectedSource,
mappedSource: (0, _sources.getGeneratedSource)(state, source),
prettySource: (0, _selectors.getPrettySource)(state, selectedId),
endPanelCollapsed: (0, _selectors.getPaneCollapse)(state, "end")
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(SourceFooter);

Просмотреть файл

@ -0,0 +1,176 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.gutterMenu = gutterMenu;
var _react = require("devtools/client/shared/vendor/react");
var _devtoolsContextmenu = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-contextmenu"];
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _editor = require("../../utils/editor/index");
var _selectors = require("../../selectors/index");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function gutterMenu({
breakpoint,
line,
event,
isPaused,
toggleBreakpoint,
openConditionalPanel,
toggleDisabledBreakpoint,
isCbPanelOpen,
closeConditionalPanel,
continueToHere
}) {
event.stopPropagation();
event.preventDefault();
const gutterItems = {
addBreakpoint: {
id: "node-menu-add-breakpoint",
label: L10N.getStr("editor.addBreakpoint")
},
addConditional: {
id: "node-menu-add-conditional-breakpoint",
label: L10N.getStr("editor.addConditionalBreakpoint")
},
removeBreakpoint: {
id: "node-menu-remove-breakpoint",
label: L10N.getStr("editor.removeBreakpoint")
},
editConditional: {
id: "node-menu-edit-conditional-breakpoint",
label: L10N.getStr("editor.editBreakpoint")
},
enableBreakpoint: {
id: "node-menu-enable-breakpoint",
label: L10N.getStr("editor.enableBreakpoint")
},
disableBreakpoint: {
id: "node-menu-disable-breakpoint",
label: L10N.getStr("editor.disableBreakpoint")
},
continueToHere: {
id: "node-menu-continue-to-here",
label: L10N.getStr("editor.continueToHere.label")
}
};
const toggleBreakpointItem = _objectSpread({
accesskey: L10N.getStr("shortcuts.toggleBreakpoint.accesskey"),
disabled: false,
click: () => {
toggleBreakpoint(line);
if (isCbPanelOpen) {
closeConditionalPanel();
}
}
}, breakpoint ? gutterItems.removeBreakpoint : gutterItems.addBreakpoint);
const conditionalBreakpoint = _objectSpread({
accesskey: L10N.getStr("editor.addConditionalBreakpoint.accesskey"),
disabled: false,
click: () => openConditionalPanel(line)
}, breakpoint && breakpoint.condition ? gutterItems.editConditional : gutterItems.addConditional);
const items = [toggleBreakpointItem, conditionalBreakpoint];
if (isPaused) {
const continueToHereItem = _objectSpread({
accesskey: L10N.getStr("editor.continueToHere.accesskey"),
disabled: false,
click: () => continueToHere(line)
}, gutterItems.continueToHere);
items.push(continueToHereItem);
}
if (breakpoint) {
const disableBreakpoint = _objectSpread({
accesskey: L10N.getStr("editor.disableBreakpoint.accesskey"),
disabled: false,
click: () => toggleDisabledBreakpoint(line)
}, breakpoint.disabled ? gutterItems.enableBreakpoint : gutterItems.disableBreakpoint);
items.push(disableBreakpoint);
}
(0, _devtoolsContextmenu.showMenu)(event, items);
}
class GutterContextMenuComponent extends _react.Component {
constructor() {
super();
}
shouldComponentUpdate(nextProps) {
return nextProps.contextMenu.type === "Gutter";
}
componentWillUpdate(nextProps) {
// clear the context menu since it is open
this.props.setContextMenu("", null);
return this.showMenu(nextProps);
}
showMenu(nextProps) {
const {
contextMenu
} = nextProps,
props = _objectWithoutProperties(nextProps, ["contextMenu"]);
const {
event
} = contextMenu;
const sourceId = props.selectedSource ? props.selectedSource.get("id") : "";
const line = (0, _editor.lineAtHeight)(props.editor, sourceId, event);
const breakpoint = nextProps.breakpoints.find(bp => bp.location.line === line);
if (props.emptyLines && props.emptyLines.includes(line)) {
return;
}
gutterMenu(_objectSpread({
event,
sourceId,
line,
breakpoint
}, props));
}
render() {
return null;
}
}
const mapStateToProps = state => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
return {
selectedLocation: (0, _selectors.getSelectedLocation)(state),
selectedSource: selectedSource,
breakpoints: (0, _selectors.getVisibleBreakpoints)(state),
isPaused: (0, _selectors.isPaused)(state),
contextMenu: (0, _selectors.getContextMenu)(state),
emptyLines: (0, _selectors.getEmptyLines)(state, selectedSource.toJS())
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(GutterContextMenuComponent);

Просмотреть файл

@ -0,0 +1,132 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.HighlightLine = undefined;
var _react = require("devtools/client/shared/vendor/react");
var _editor = require("../../utils/editor/index");
var _sourceDocuments = require("../../utils/editor/source-documents");
var _source = require("../../utils/source");
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _selectors = require("../../selectors/index");
/* 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/>. */
function isDebugLine(selectedFrame, selectedLocation) {
if (!selectedFrame) {
return;
}
return selectedFrame.location.sourceId == selectedLocation.sourceId && selectedFrame.location.line == selectedLocation.line;
}
function isDocumentReady(selectedSource, selectedLocation) {
return selectedLocation && (0, _source.isLoaded)(selectedSource) && (0, _sourceDocuments.hasDocument)(selectedLocation.sourceId);
}
class HighlightLine extends _react.Component {
constructor(...args) {
var _temp;
return _temp = super(...args), this.isStepping = false, this.previousEditorLine = null, _temp;
}
shouldComponentUpdate(nextProps) {
const {
selectedLocation,
selectedSource
} = nextProps;
return this.shouldSetHighlightLine(selectedLocation, selectedSource);
}
shouldSetHighlightLine(selectedLocation, selectedSource) {
const {
sourceId,
line
} = selectedLocation;
const editorLine = (0, _editor.toEditorLine)(sourceId, line);
if (!isDocumentReady(selectedSource, selectedLocation)) {
return false;
}
if (this.isStepping && editorLine === this.previousEditorLine) {
return false;
}
return true;
}
componentDidUpdate(prevProps) {
const {
pauseCommand,
selectedLocation,
selectedFrame,
selectedSource
} = this.props;
if (pauseCommand) {
this.isStepping = true;
}
this.clearHighlightLine(prevProps.selectedLocation, prevProps.selectedSource);
this.setHighlightLine(selectedLocation, selectedFrame, selectedSource);
}
setHighlightLine(selectedLocation, selectedFrame, selectedSource) {
const {
sourceId,
line
} = selectedLocation;
if (!this.shouldSetHighlightLine(selectedLocation, selectedSource)) {
return;
}
this.isStepping = false;
const editorLine = (0, _editor.toEditorLine)(sourceId, line);
this.previousEditorLine = editorLine;
if (!line || isDebugLine(selectedFrame, selectedLocation)) {
return;
}
const doc = (0, _sourceDocuments.getDocument)(sourceId);
doc.addLineClass(editorLine, "line", "highlight-line");
}
clearHighlightLine(selectedLocation, selectedSource) {
if (!isDocumentReady(selectedSource, selectedLocation)) {
return;
}
const {
line,
sourceId
} = selectedLocation;
const editorLine = (0, _editor.toEditorLine)(sourceId, line);
const doc = (0, _sourceDocuments.getDocument)(sourceId);
doc.removeLineClass(editorLine, "line", "highlight-line");
}
render() {
return null;
}
}
exports.HighlightLine = HighlightLine;
exports.default = (0, _reactRedux.connect)(state => ({
pauseCommand: (0, _selectors.getPauseCommand)(state),
selectedFrame: (0, _selectors.getVisibleSelectedFrame)(state),
selectedLocation: (0, _selectors.getSelectedLocation)(state),
selectedSource: (0, _selectors.getSelectedSource)(state)
}))(HighlightLine);

Просмотреть файл

@ -0,0 +1,96 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _lodash = require("devtools/client/shared/vendor/lodash");
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _selectors = require("../../selectors/index");
/* 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/>. */
class HighlightLines extends _react.Component {
constructor() {
super();
this.highlightLineRange = () => {
const {
highlightedLineRange,
editor
} = this.props;
const {
codeMirror
} = editor;
if ((0, _lodash.isEmpty)(highlightedLineRange) || !codeMirror) {
return;
}
const {
start,
end
} = highlightedLineRange;
codeMirror.operation(() => {
editor.alignLine(start);
(0, _lodash.range)(start - 1, end).forEach(line => {
codeMirror.addLineClass(line, "line", "highlight-lines");
});
});
};
}
componentDidMount() {
this.highlightLineRange();
}
componentWillUpdate() {
this.clearHighlightRange();
}
componentDidUpdate() {
this.highlightLineRange();
}
componentWillUnmount() {
this.clearHighlightRange();
}
clearHighlightRange() {
const {
highlightedLineRange,
editor
} = this.props;
const {
codeMirror
} = editor;
if ((0, _lodash.isEmpty)(highlightedLineRange) || !codeMirror) {
return;
}
const {
start,
end
} = highlightedLineRange;
codeMirror.operation(() => {
(0, _lodash.range)(start - 1, end).forEach(line => {
codeMirror.removeLineClass(line, "line", "highlight-lines");
});
});
}
render() {
return null;
}
}
exports.default = (0, _reactRedux.connect)(state => ({
highlightedLineRange: (0, _selectors.getHighlightedLineRange)(state)
}))(HighlightLines);

Просмотреть файл

@ -0,0 +1,53 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
/* 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/>. */
const markerEl = document.createElement("div");
function makeMarker() {
const marker = markerEl.cloneNode(true);
marker.className = "editor hit-marker";
return marker;
}
class HitMarker extends _react.Component {
addMarker() {
const hitData = this.props.hitData;
const line = hitData.line - 1;
this.props.editor.setGutterMarker(line, "hit-markers", makeMarker());
this.props.editor.addLineClass(line, "line", "hit-marker");
}
shouldComponentUpdate(nextProps) {
return this.props.editor !== nextProps.editor || this.props.hitData !== nextProps.hitData;
}
componentDidMount() {
this.addMarker();
}
componentDidUpdate() {
this.addMarker();
}
componentWillUnmount() {
const hitData = this.props.hitData;
const line = hitData.line - 1;
this.props.editor.setGutterMarker(line, "hit-markers", null);
this.props.editor.removeLineClass(line, "line", "hit-marker");
}
render() {
return null;
}
}
exports.default = HitMarker;

Просмотреть файл

@ -0,0 +1,336 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Popup = undefined;
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _devtoolsReps = require("devtools/client/shared/components/reps/reps.js");
var _devtoolsReps2 = _interopRequireDefault(_devtoolsReps);
var _actions = require("../../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../../selectors/index");
var _Popover = require("../../shared/Popover");
var _Popover2 = _interopRequireDefault(_Popover);
var _PreviewFunction = require("../../shared/PreviewFunction");
var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
var _editor = require("../../../utils/editor/index");
var _Svg = require("devtools/client/debugger/new/dist/vendors").vendored["Svg"];
var _Svg2 = _interopRequireDefault(_Svg);
var _firefox = require("../../../client/firefox");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
const {
REPS: {
Rep
},
MODE,
ObjectInspector,
ObjectInspectorUtils
} = _devtoolsReps2.default;
const {
createNode,
getChildren,
getValue,
nodeIsPrimitive,
NODE_TYPES
} = ObjectInspectorUtils.node;
const {
loadItemProperties
} = ObjectInspectorUtils.loadProperties;
class Popup extends _react.Component {
constructor(...args) {
var _temp;
return _temp = super(...args), this.onMouseLeave = e => {
const relatedTarget = e.relatedTarget;
if (relatedTarget && (relatedTarget.classList.contains("popover") || relatedTarget.classList.contains("debug-expression") || relatedTarget.classList.contains("editor-mount"))) {
return;
}
this.props.onClose();
}, _temp;
}
async componentWillMount() {
const {
value,
setPopupObjectProperties,
popupObjectProperties
} = this.props;
const root = this.getRoot();
if (!nodeIsPrimitive(root) && value && value.actor && !popupObjectProperties[value.actor]) {
const onLoadItemProperties = loadItemProperties(root, _firefox.createObjectClient);
if (onLoadItemProperties !== null) {
const properties = await onLoadItemProperties;
setPopupObjectProperties(root.contents.value, properties);
}
}
}
componentDidMount() {
const {
value,
editor,
range
} = this.props;
if (!value || !value.type == "object") {
return;
}
this.marker = (0, _editor.markText)(editor, "preview-selection", range);
}
componentWillUnmount() {
if (this.marker) {
this.marker.clear();
}
}
getRoot() {
const {
expression,
value,
extra
} = this.props;
let rootValue = value;
if (extra.immutable) {
rootValue = extra.immutable.entries;
}
return createNode({
name: expression,
path: expression,
contents: {
value: rootValue
}
});
}
getChildren() {
const {
popupObjectProperties
} = this.props;
const root = this.getRoot();
const value = getValue(root);
const actor = value ? value.actor : null;
const loadedRootProperties = popupObjectProperties[actor];
if (!loadedRootProperties) {
return null;
}
const children = getChildren({
item: root,
loadedProperties: new Map([[root.path, loadedRootProperties]])
});
if (children.length > 0) {
return children;
}
return null;
}
renderFunctionPreview() {
const {
selectSourceURL,
value
} = this.props;
if (!value) {
return null;
}
const {
location
} = value;
return _react2.default.createElement("div", {
className: "preview-popup",
onClick: () => selectSourceURL(location.url, {
line: location.line
})
}, _react2.default.createElement(_PreviewFunction2.default, {
func: value
}));
}
renderReact(react, roots) {
const reactHeader = react.displayName || "React Component";
return _react2.default.createElement("div", {
className: "header-container"
}, _react2.default.createElement(_Svg2.default, {
name: "react",
className: "logo"
}), _react2.default.createElement("h3", null, reactHeader));
}
renderImmutable(immutable) {
const immutableHeader = immutable.type || "Immutable";
return _react2.default.createElement("div", {
className: "header-container"
}, _react2.default.createElement(_Svg2.default, {
name: "immutable",
className: "logo"
}), _react2.default.createElement("h3", null, immutableHeader));
}
renderObjectPreview() {
const {
extra
} = this.props;
const root = this.getRoot();
if (nodeIsPrimitive(root)) {
return null;
}
let roots = this.getChildren();
if (!Array.isArray(roots) || roots.length === 0) {
return null;
}
let header = null;
if (extra.immutable) {
header = this.renderImmutable(extra.immutable);
roots = roots.filter(r => r.type != NODE_TYPES.PROTOTYPE);
}
if (extra.react) {
header = this.renderReact(extra.react);
roots = roots.filter(r => ["state", "props"].includes(r.name));
}
return _react2.default.createElement("div", {
className: "preview-popup"
}, header, this.renderObjectInspector(roots));
}
renderSimplePreview(value) {
const {
openLink
} = this.props;
return _react2.default.createElement("div", {
className: "preview-popup"
}, Rep({
object: value,
mode: MODE.LONG,
openLink
}));
}
renderObjectInspector(roots) {
const {
openLink
} = this.props;
return _react2.default.createElement(ObjectInspector, {
roots: roots,
autoExpandDepth: 0,
disableWrap: true,
focusable: false,
openLink: openLink,
createObjectClient: grip => (0, _firefox.createObjectClient)(grip)
});
}
renderPreview() {
const {
value
} = this.props;
if (!value) {
return null;
}
if (value.class === "Function") {
return this.renderFunctionPreview();
}
if (value.type === "object") {
return _react2.default.createElement("div", null, this.renderObjectPreview());
}
return this.renderSimplePreview(value);
}
getPreviewType(value) {
if (typeof value == "number" || typeof value == "boolean" || typeof value == "string" && value.length < 10 || typeof value == "number" && value.toString().length < 10 || value.type == "null" || value.type == "undefined" || value.class === "Function") {
return "tooltip";
}
return "popover";
}
render() {
const {
popoverPos,
value,
editorRef
} = this.props;
const type = this.getPreviewType(value);
if (value && value.type === "object" && !this.getChildren()) {
return null;
}
return _react2.default.createElement(_Popover2.default, {
targetPosition: popoverPos,
onMouseLeave: this.onMouseLeave,
type: type,
editorRef: editorRef
}, this.renderPreview());
}
}
exports.Popup = Popup;
const mapStateToProps = state => ({
popupObjectProperties: (0, _selectors.getAllPopupObjectProperties)(state)
});
const {
addExpression,
selectSourceURL,
selectLocation,
setPopupObjectProperties,
openLink
} = _actions2.default;
const mapDispatchToProps = {
addExpression,
selectSourceURL,
selectLocation,
setPopupObjectProperties,
openLink
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(Popup);

Просмотреть файл

@ -0,0 +1,161 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _Popup = require("./Popup");
var _Popup2 = _interopRequireDefault(_Popup);
var _selectors = require("../../../selectors/index");
var _actions = require("../../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _editor = require("../../../utils/editor/index");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class Preview extends _react.PureComponent {
constructor(props) {
super(props);
this.onMouseOver = e => {
const {
target
} = e;
this.props.updatePreview(target, this.props.editor);
};
this.onMouseUp = () => {
this.setState({
selecting: false
});
return true;
};
this.onMouseDown = () => {
this.setState({
selecting: true
});
return true;
};
this.onMouseLeave = e => {
const target = e.target;
if (target.classList.contains("CodeMirror")) {
return;
}
this.props.clearPreview();
};
this.onClose = () => {
this.props.clearPreview();
};
this.state = {
selecting: false
};
}
componentDidMount() {
const {
codeMirror
} = this.props.editor;
const codeMirrorWrapper = codeMirror.getWrapperElement();
codeMirrorWrapper.addEventListener("mouseover", this.onMouseOver);
codeMirrorWrapper.addEventListener("mouseup", this.onMouseUp);
codeMirrorWrapper.addEventListener("mousedown", this.onMouseDown);
codeMirrorWrapper.addEventListener("mouseleave", this.onMouseLeave);
if (document.body) {
document.body.addEventListener("mouseleave", this.onMouseLeave);
}
}
componentWillUnmount() {
const codeMirror = this.props.editor.codeMirror;
const codeMirrorWrapper = codeMirror.getWrapperElement();
codeMirrorWrapper.removeEventListener("mouseover", this.onMouseOver);
codeMirrorWrapper.removeEventListener("mouseup", this.onMouseUp);
codeMirrorWrapper.removeEventListener("mousedown", this.onMouseDown);
codeMirrorWrapper.removeEventListener("mouseleave", this.onMouseLeave);
if (document.body) {
document.body.removeEventListener("mouseleave", this.onMouseLeave);
}
}
render() {
const {
selectedSource,
preview
} = this.props;
if (!this.props.editor || !selectedSource || this.state.selecting) {
return null;
}
if (!preview || preview.updating) {
return null;
}
const {
result,
expression,
location,
cursorPos,
extra
} = preview;
const value = result;
if (typeof value == "undefined" || value.optimizedOut) {
return null;
}
const editorRange = (0, _editor.toEditorRange)(selectedSource.get("id"), location);
return _react2.default.createElement(_Popup2.default, {
value: value,
editor: this.props.editor,
editorRef: this.props.editorRef,
range: editorRange,
expression: expression,
popoverPos: cursorPos,
extra: extra,
onClose: this.onClose
});
}
}
const mapStateToProps = state => ({
preview: (0, _selectors.getPreview)(state),
selectedSource: (0, _selectors.getSelectedSource)(state)
});
const {
addExpression,
setPopupObjectProperties,
updatePreview,
clearPreview
} = _actions2.default;
const mapDispatchToProps = {
addExpression,
setPopupObjectProperties,
updatePreview,
clearPreview
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, mapDispatchToProps)(Preview);

Просмотреть файл

@ -0,0 +1,13 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'index.js',
'Popup.js',
)

Просмотреть файл

@ -0,0 +1,368 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _propTypes = require("devtools/client/shared/vendor/react-prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _Svg = require("devtools/client/debugger/new/dist/vendors").vendored["Svg"];
var _Svg2 = _interopRequireDefault(_Svg);
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../selectors/index");
var _editor = require("../../utils/editor/index");
var _resultList = require("../../utils/result-list");
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
var _SearchInput = require("../shared/SearchInput");
var _SearchInput2 = _interopRequireDefault(_SearchInput);
var _lodash = require("devtools/client/shared/vendor/lodash");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
function getShortcuts() {
const searchAgainKey = L10N.getStr("sourceSearch.search.again.key2");
const searchAgainPrevKey = L10N.getStr("sourceSearch.search.againPrev.key2");
const searchKey = L10N.getStr("sourceSearch.search.key2");
return {
shiftSearchAgainShortcut: searchAgainPrevKey,
searchAgainShortcut: searchAgainKey,
searchShortcut: searchKey
};
}
class SearchBar extends _react.Component {
constructor(props) {
super(props);
this.onEscape = e => {
this.closeSearch(e);
};
this.clearSearch = () => {
const {
editor: ed,
query
} = this.props;
if (ed) {
const ctx = {
ed,
cm: ed.codeMirror
};
(0, _editor.removeOverlay)(ctx, query);
}
};
this.closeSearch = e => {
const {
closeFileSearch,
editor,
searchOn
} = this.props;
if (editor && searchOn) {
this.clearSearch();
closeFileSearch(editor);
e.stopPropagation();
e.preventDefault();
}
this.setState({
query: "",
inputFocused: false
});
};
this.toggleSearch = e => {
e.stopPropagation();
e.preventDefault();
const {
editor,
searchOn,
setActiveSearch
} = this.props;
if (!searchOn) {
setActiveSearch("file");
}
if (searchOn && editor) {
const query = editor.codeMirror.getSelection() || this.state.query;
if (query !== "") {
this.setState({
query,
inputFocused: true
});
this.doSearch(query);
} else {
this.setState({
query: "",
inputFocused: true
});
}
}
};
this.doSearch = query => {
const {
selectedSource
} = this.props;
if (!selectedSource || !selectedSource.get("text")) {
return;
}
this.props.doSearch(query, this.props.editor);
};
this.updateSearchResults = (characterIndex, line, matches) => {
const matchIndex = matches.findIndex(elm => elm.line === line && elm.ch === characterIndex);
this.props.updateSearchResults({
matches,
matchIndex,
count: matches.length,
index: characterIndex
});
};
this.traverseResults = (e, rev) => {
e.stopPropagation();
e.preventDefault();
const editor = this.props.editor;
if (!editor) {
return;
}
this.props.traverseResults(rev, editor);
};
this.onChange = e => {
this.setState({
query: e.target.value
});
return this.doSearch(e.target.value);
};
this.onBlur = e => {
this.setState({
inputFocused: false
});
};
this.onKeyDown = e => {
if (e.key !== "Enter" && e.key !== "F3") {
return;
}
this.traverseResults(e, e.shiftKey);
e.preventDefault();
};
this.renderSearchModifiers = () => {
const {
modifiers,
toggleFileSearchModifier,
query
} = this.props;
const {
doSearch
} = this;
function SearchModBtn({
modVal,
className,
svgName,
tooltip
}) {
const preppedClass = (0, _classnames2.default)(className, {
active: modifiers && modifiers.get(modVal)
});
return _react2.default.createElement("button", {
className: preppedClass,
onClick: () => {
toggleFileSearchModifier(modVal);
doSearch(query);
},
title: tooltip
}, _react2.default.createElement(_Svg2.default, {
name: svgName
}));
}
return _react2.default.createElement("div", {
className: "search-modifiers"
}, _react2.default.createElement("span", {
className: "search-type-name"
}, L10N.getStr("symbolSearch.searchModifier.modifiersLabel")), _react2.default.createElement(SearchModBtn, {
modVal: "regexMatch",
className: "regex-match-btn",
svgName: "regex-match",
tooltip: L10N.getStr("symbolSearch.searchModifier.regex")
}), _react2.default.createElement(SearchModBtn, {
modVal: "caseSensitive",
className: "case-sensitive-btn",
svgName: "case-match",
tooltip: L10N.getStr("symbolSearch.searchModifier.caseSensitive")
}), _react2.default.createElement(SearchModBtn, {
modVal: "wholeWord",
className: "whole-word-btn",
svgName: "whole-word-match",
tooltip: L10N.getStr("symbolSearch.searchModifier.wholeWord")
}));
};
this.state = {
query: props.query,
selectedResultIndex: 0,
count: 0,
index: -1,
inputFocused: false
};
}
componentWillUnmount() {
const shortcuts = this.context.shortcuts;
const {
searchShortcut,
searchAgainShortcut,
shiftSearchAgainShortcut
} = getShortcuts();
shortcuts.off(searchShortcut);
shortcuts.off("Escape");
shortcuts.off(searchAgainShortcut);
shortcuts.off(shiftSearchAgainShortcut);
}
componentDidMount() {
// overwrite this.doSearch with debounced version to
// reduce frequency of queries
this.doSearch = (0, _lodash.debounce)(this.doSearch, 100);
const shortcuts = this.context.shortcuts;
const {
searchShortcut,
searchAgainShortcut,
shiftSearchAgainShortcut
} = getShortcuts();
shortcuts.on(searchShortcut, (_, e) => this.toggleSearch(e));
shortcuts.on("Escape", (_, e) => this.onEscape(e));
shortcuts.on(shiftSearchAgainShortcut, (_, e) => this.traverseResults(e, true));
shortcuts.on(searchAgainShortcut, (_, e) => this.traverseResults(e, false));
}
componentDidUpdate(prevProps, prevState) {
if (this.refs.resultList && this.refs.resultList.refs) {
(0, _resultList.scrollList)(this.refs.resultList.refs, this.state.selectedResultIndex);
}
}
// Renderers
buildSummaryMsg() {
const {
searchResults: {
matchIndex,
count,
index
},
query
} = this.props;
if (query.trim() == "") {
return "";
}
if (count == 0) {
return L10N.getStr("editor.noResults");
}
if (index == -1) {
return L10N.getFormatStr("sourceSearch.resultsSummary1", count);
}
return L10N.getFormatStr("editor.searchResults", matchIndex + 1, count);
}
shouldShowErrorEmoji() {
const {
query,
searchResults: {
count
}
} = this.props;
return !!query && !count;
}
render() {
const {
searchResults: {
count
},
searchOn
} = this.props;
if (!searchOn) {
return _react2.default.createElement("div", null);
}
return _react2.default.createElement("div", {
className: "search-bar"
}, _react2.default.createElement(_SearchInput2.default, {
query: this.state.query,
count: count,
placeholder: L10N.getStr("sourceSearch.search.placeholder"),
summaryMsg: this.buildSummaryMsg(),
onChange: this.onChange,
onBlur: this.onBlur,
showErrorEmoji: this.shouldShowErrorEmoji(),
onKeyDown: this.onKeyDown,
handleNext: e => this.traverseResults(e, false),
handlePrev: e => this.traverseResults(e, true),
handleClose: this.closeSearch,
shouldFocus: this.state.inputFocused
}), _react2.default.createElement("div", {
className: "search-bottom-bar"
}, this.renderSearchModifiers()));
}
}
SearchBar.contextTypes = {
shortcuts: _propTypes2.default.object
};
const mapStateToProps = state => ({
searchOn: (0, _selectors.getActiveSearch)(state) === "file",
selectedSource: (0, _selectors.getSelectedSource)(state),
selectedLocation: (0, _selectors.getSelectedLocation)(state),
query: (0, _selectors.getFileSearchQuery)(state),
modifiers: (0, _selectors.getFileSearchModifiers)(state),
highlightedLineRange: (0, _selectors.getHighlightedLineRange)(state),
searchResults: (0, _selectors.getFileSearchResults)(state)
});
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(SearchBar);

Просмотреть файл

@ -0,0 +1,194 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _devtoolsContextmenu = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-contextmenu"];
var _Close = require("../shared/Button/Close");
var _Close2 = _interopRequireDefault(_Close);
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _source = require("../../utils/source");
var _clipboard = require("../../utils/clipboard");
var _tabs = require("../../utils/tabs");
var _selectors = require("../../selectors/index");
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
class Tab extends _react.PureComponent {
constructor(...args) {
var _temp;
return _temp = super(...args), this.onTabContextMenu = (event, tab) => {
event.preventDefault();
this.showContextMenu(event, tab);
}, _temp;
}
showContextMenu(e, tab) {
const {
closeTab,
closeTabs,
tabSources,
showSource,
togglePrettyPrint,
selectedSource
} = this.props;
const otherTabs = tabSources.filter(t => t.get("id") !== tab);
const sourceTab = tabSources.find(t => t.get("id") == tab);
const tabURLs = tabSources.map(t => t.get("url"));
const otherTabURLs = otherTabs.map(t => t.get("url"));
if (!sourceTab) {
return;
}
const isPrettySource = (0, _source.isPretty)(sourceTab);
const tabMenuItems = (0, _tabs.getTabMenuItems)();
const items = [{
item: _objectSpread({}, tabMenuItems.closeTab, {
click: () => closeTab(sourceTab.get("url"))
})
}, {
item: _objectSpread({}, tabMenuItems.closeOtherTabs, {
click: () => closeTabs(otherTabURLs)
}),
hidden: () => tabSources.size === 1
}, {
item: _objectSpread({}, tabMenuItems.closeTabsToEnd, {
click: () => {
const tabIndex = tabSources.findIndex(t => t.get("id") == tab);
closeTabs(tabURLs.filter((t, i) => i > tabIndex));
}
}),
hidden: () => tabSources.size === 1 || tabSources.some((t, i) => t === tab && tabSources.size - 1 === i)
}, {
item: _objectSpread({}, tabMenuItems.closeAllTabs, {
click: () => closeTabs(tabURLs)
})
}, {
item: {
type: "separator"
}
}, {
item: _objectSpread({}, tabMenuItems.copyToClipboard, {
disabled: selectedSource.get("id") !== tab,
click: () => (0, _clipboard.copyToTheClipboard)(sourceTab.text)
})
}, {
item: _objectSpread({}, tabMenuItems.copySourceUri2, {
click: () => (0, _clipboard.copyToTheClipboard)((0, _source.getRawSourceURL)(sourceTab.get("url")))
})
}];
items.push({
item: _objectSpread({}, tabMenuItems.showSource, {
click: () => showSource(tab)
})
});
if (!isPrettySource) {
items.push({
item: _objectSpread({}, tabMenuItems.prettyPrint, {
click: () => togglePrettyPrint(tab)
})
});
}
(0, _devtoolsContextmenu.showMenu)(e, (0, _devtoolsContextmenu.buildMenu)(items));
}
isProjectSearchEnabled() {
return this.props.activeSearch === "project";
}
isSourceSearchEnabled() {
return this.props.activeSearch === "source";
}
render() {
const {
selectedSource,
selectSpecificSource,
closeTab,
source,
sourceMetaData
} = this.props;
const src = source.toJS();
const filename = (0, _source.getFilename)(src);
const sourceId = source.id;
const active = selectedSource && sourceId == selectedSource.get("id") && !this.isProjectSearchEnabled() && !this.isSourceSearchEnabled();
const isPrettyCode = (0, _source.isPretty)(source);
const sourceAnnotation = (0, _tabs.getSourceAnnotation)(source, sourceMetaData);
function onClickClose(e) {
e.stopPropagation();
closeTab(source.url);
}
function handleTabClick(e) {
e.preventDefault();
e.stopPropagation(); // Accommodate middle click to close tab
if (e.button === 1) {
return closeTab(source.url);
}
return selectSpecificSource(sourceId);
}
const className = (0, _classnames2.default)("source-tab", {
active,
pretty: isPrettyCode
});
return _react2.default.createElement("div", {
className: className,
key: sourceId,
onMouseUp: handleTabClick,
onContextMenu: e => this.onTabContextMenu(e, sourceId),
title: (0, _source.getFileURL)(src)
}, sourceAnnotation, _react2.default.createElement("div", {
className: "filename"
}, filename), _react2.default.createElement(_Close2.default, {
handleClick: onClickClose,
tooltip: L10N.getStr("sourceTabs.closeTabButtonTooltip")
}));
}
}
const mapStateToProps = (state, {
source
}) => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
return {
tabSources: (0, _selectors.getSourcesForTabs)(state),
selectedSource: selectedSource,
sourceMetaData: (0, _selectors.getSourceMetaData)(state, source.id),
activeSearch: (0, _selectors.getActiveSearch)(state)
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Tab);

Просмотреть файл

@ -0,0 +1,216 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _immutable = require("devtools/client/shared/vendor/immutable");
var I = _interopRequireWildcard(_immutable);
var _selectors = require("../../selectors/index");
var _ui = require("../../utils/ui");
var _tabs = require("../../utils/tabs");
var _source = require("../../utils/source");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _lodash = require("devtools/client/shared/vendor/lodash");
var _Tab = require("./Tab");
var _Tab2 = _interopRequireDefault(_Tab);
var _PaneToggle = require("../shared/Button/PaneToggle");
var _PaneToggle2 = _interopRequireDefault(_PaneToggle);
var _Dropdown = require("../shared/Dropdown");
var _Dropdown2 = _interopRequireDefault(_Dropdown);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class Tabs extends _react.PureComponent {
constructor(props) {
super(props);
this.updateHiddenTabs = () => {
if (!this.refs.sourceTabs) {
return;
}
const {
selectedSource,
tabSources,
moveTab
} = this.props;
const sourceTabEls = this.refs.sourceTabs.children;
const hiddenTabs = (0, _tabs.getHiddenTabs)(tabSources, sourceTabEls);
if ((0, _ui.isVisible)() && hiddenTabs.indexOf(selectedSource) !== -1) {
return moveTab(selectedSource.url, 0);
}
this.setState({
hiddenTabs
});
};
this.renderDropdownSource = source => {
const {
selectSpecificSource
} = this.props;
const filename = (0, _source.getFilename)(source.toJS());
const onClick = () => selectSpecificSource(source.id);
return _react2.default.createElement("li", {
key: source.id,
onClick: onClick
}, _react2.default.createElement("img", {
className: `dropdown-icon ${this.getIconClass(source)}`
}), filename);
};
this.state = {
dropdownShown: false,
hiddenTabs: I.List()
};
this.onResize = (0, _lodash.debounce)(() => {
this.updateHiddenTabs();
});
}
componentDidUpdate(prevProps) {
if (!(prevProps === this.props)) {
this.updateHiddenTabs();
}
}
componentDidMount() {
window.requestIdleCallback(this.updateHiddenTabs);
window.addEventListener("resize", this.onResize);
}
componentWillUnmount() {
window.removeEventListener("resize", this.onResize);
}
/*
* Updates the hiddenSourceTabs state, by
* finding the source tabs which are wrapped and are not on the top row.
*/
toggleSourcesDropdown(e) {
this.setState(prevState => ({
dropdownShown: !prevState.dropdownShown
}));
}
getIconClass(source) {
if ((0, _source.isPretty)(source)) {
return "prettyPrint";
}
if (source.isBlackBoxed) {
return "blackBox";
}
return "file";
}
renderTabs() {
const {
tabSources
} = this.props;
if (!tabSources) {
return;
}
return _react2.default.createElement("div", {
className: "source-tabs",
ref: "sourceTabs"
}, tabSources.map((source, index) => _react2.default.createElement(_Tab2.default, {
key: index,
source: source
})));
}
renderDropdown() {
const hiddenTabs = this.state.hiddenTabs;
if (!hiddenTabs || hiddenTabs.size == 0) {
return null;
}
const Panel = _react2.default.createElement("ul", null, hiddenTabs.map(this.renderDropdownSource));
const icon = _react2.default.createElement("img", {
className: "moreTabs"
});
return _react2.default.createElement(_Dropdown2.default, {
panel: Panel,
icon: icon
});
}
renderStartPanelToggleButton() {
return _react2.default.createElement(_PaneToggle2.default, {
position: "start",
collapsed: !this.props.startPanelCollapsed,
handleClick: this.props.togglePaneCollapse
});
}
renderEndPanelToggleButton() {
const {
horizontal,
endPanelCollapsed,
togglePaneCollapse
} = this.props;
if (!horizontal) {
return;
}
return _react2.default.createElement(_PaneToggle2.default, {
position: "end",
collapsed: !endPanelCollapsed,
handleClick: togglePaneCollapse,
horizontal: horizontal
});
}
render() {
return _react2.default.createElement("div", {
className: "source-header"
}, this.renderStartPanelToggleButton(), this.renderTabs(), this.renderDropdown(), this.renderEndPanelToggleButton());
}
}
const mapStateToProps = state => ({
selectedSource: (0, _selectors.getSelectedSource)(state),
tabSources: (0, _selectors.getSourcesForTabs)(state)
});
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Tabs);

Просмотреть файл

@ -0,0 +1,638 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _propTypes = require("devtools/client/shared/vendor/react-prop-types");
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactDom = require("devtools/client/shared/vendor/react-dom");
var _reactDom2 = _interopRequireDefault(_reactDom);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
var _source = require("../../utils/source");
var _devtoolsEnvironment = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-environment"];
var _prefs = require("../../utils/prefs");
var _indentation = require("../../utils/indentation");
var _selectors = require("../../selectors/index");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _Footer = require("./Footer");
var _Footer2 = _interopRequireDefault(_Footer);
var _SearchBar = require("./SearchBar");
var _SearchBar2 = _interopRequireDefault(_SearchBar);
var _HighlightLines = require("./HighlightLines");
var _HighlightLines2 = _interopRequireDefault(_HighlightLines);
var _Preview = require("./Preview/index");
var _Preview2 = _interopRequireDefault(_Preview);
var _Breakpoints = require("./Breakpoints");
var _Breakpoints2 = _interopRequireDefault(_Breakpoints);
var _HitMarker = require("./HitMarker");
var _HitMarker2 = _interopRequireDefault(_HitMarker);
var _CallSites = require("./CallSites");
var _CallSites2 = _interopRequireDefault(_CallSites);
var _DebugLine = require("./DebugLine");
var _DebugLine2 = _interopRequireDefault(_DebugLine);
var _HighlightLine = require("./HighlightLine");
var _HighlightLine2 = _interopRequireDefault(_HighlightLine);
var _EmptyLines = require("./EmptyLines");
var _EmptyLines2 = _interopRequireDefault(_EmptyLines);
var _GutterMenu = require("./GutterMenu");
var _GutterMenu2 = _interopRequireDefault(_GutterMenu);
var _EditorMenu = require("./EditorMenu");
var _EditorMenu2 = _interopRequireDefault(_EditorMenu);
var _ConditionalPanel = require("./ConditionalPanel");
var _ConditionalPanel2 = _interopRequireDefault(_ConditionalPanel);
var _editor = require("../../utils/editor/index");
var _ui = require("../../utils/ui");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
// Redux actions
const cssVars = {
searchbarHeight: "var(--editor-searchbar-height)",
secondSearchbarHeight: "var(--editor-second-searchbar-height)",
footerHeight: "var(--editor-footer-height)"
};
class Editor extends _react.PureComponent {
constructor(props) {
super(props);
this.onToggleBreakpoint = (key, e) => {
e.preventDefault();
e.stopPropagation();
const {
selectedSource,
conditionalPanelLine
} = this.props;
if (!selectedSource) {
return;
}
const line = this.getCurrentLine();
if (e.shiftKey) {
this.toggleConditionalPanel(line);
} else if (!conditionalPanelLine) {
this.props.toggleBreakpoint(line);
} else {
this.toggleConditionalPanel(line);
this.props.toggleBreakpoint(line);
}
};
this.onToggleConditionalPanel = (key, e) => {
e.stopPropagation();
e.preventDefault();
const line = this.getCurrentLine();
this.toggleConditionalPanel(line);
};
this.onEscape = (key, e) => {
if (!this.state.editor) {
return;
}
const {
codeMirror
} = this.state.editor;
if (codeMirror.listSelections().length > 1) {
codeMirror.execCommand("singleSelection");
e.preventDefault();
}
};
this.onSearchAgain = (_, e) => {
this.props.traverseResults(e.shiftKey, this.state.editor);
};
this.onGutterClick = (cm, line, gutter, ev) => {
const {
selectedSource,
conditionalPanelLine,
closeConditionalPanel,
addOrToggleDisabledBreakpoint,
toggleBreakpoint,
continueToHere
} = this.props; // ignore right clicks in the gutter
if (ev.ctrlKey && ev.button === 0 || ev.which === 3 || selectedSource && selectedSource.isBlackBoxed || !selectedSource) {
return;
}
if (conditionalPanelLine) {
return closeConditionalPanel();
}
if (gutter === "CodeMirror-foldgutter") {
return;
}
const sourceLine = (0, _editor.toSourceLine)(selectedSource.get("id"), line);
if (ev.altKey) {
return continueToHere(sourceLine);
}
if (ev.shiftKey) {
return addOrToggleDisabledBreakpoint(sourceLine);
}
return toggleBreakpoint(sourceLine);
};
this.onGutterContextMenu = event => {
event.stopPropagation();
event.preventDefault();
return this.props.setContextMenu("Gutter", event);
};
this.toggleConditionalPanel = line => {
const {
conditionalPanelLine,
closeConditionalPanel,
openConditionalPanel
} = this.props;
if (conditionalPanelLine) {
return closeConditionalPanel();
}
return openConditionalPanel(line);
};
this.closeConditionalPanel = () => {
return this.props.closeConditionalPanel();
};
this.state = {
highlightedLineRange: null,
editor: null
};
}
componentWillReceiveProps(nextProps) {
if (!this.state.editor) {
return;
}
(0, _ui.resizeBreakpointGutter)(this.state.editor.codeMirror);
(0, _ui.resizeToggleButton)(this.state.editor.codeMirror);
}
componentWillUpdate(nextProps) {
this.setText(nextProps);
this.setSize(nextProps);
this.scrollToLocation(nextProps);
}
setupEditor() {
const editor = (0, _editor.createEditor)(); // disables the default search shortcuts
// $FlowIgnore
editor._initShortcuts = () => {};
const node = _reactDom2.default.findDOMNode(this);
if (node instanceof HTMLElement) {
editor.appendToLocalElement(node.querySelector(".editor-mount"));
}
const {
codeMirror
} = editor;
const codeMirrorWrapper = codeMirror.getWrapperElement();
(0, _ui.resizeBreakpointGutter)(codeMirror);
(0, _ui.resizeToggleButton)(codeMirror);
codeMirror.on("gutterClick", this.onGutterClick); // Set code editor wrapper to be focusable
codeMirrorWrapper.tabIndex = 0;
codeMirrorWrapper.addEventListener("keydown", e => this.onKeyDown(e));
codeMirrorWrapper.addEventListener("click", e => this.onClick(e));
const toggleFoldMarkerVisibility = e => {
if (node instanceof HTMLElement) {
node.querySelectorAll(".CodeMirror-guttermarker-subtle").forEach(elem => {
elem.classList.toggle("visible");
});
}
};
const codeMirrorGutter = codeMirror.getGutterElement();
codeMirrorGutter.addEventListener("mouseleave", toggleFoldMarkerVisibility);
codeMirrorGutter.addEventListener("mouseenter", toggleFoldMarkerVisibility);
if (!(0, _devtoolsEnvironment.isFirefox)()) {
codeMirror.on("gutterContextMenu", (cm, line, eventName, event) => this.onGutterContextMenu(event));
codeMirror.on("contextmenu", (cm, event) => this.openMenu(event));
} else {
codeMirrorWrapper.addEventListener("contextmenu", event => this.openMenu(event));
}
this.setState({
editor
});
(0, _editor.setEditor)(editor);
return editor;
}
componentDidMount() {
const {
shortcuts
} = this.context;
const searchAgainKey = L10N.getStr("sourceSearch.search.again.key2");
const searchAgainPrevKey = L10N.getStr("sourceSearch.search.againPrev.key2");
shortcuts.on(L10N.getStr("toggleBreakpoint.key"), this.onToggleBreakpoint);
shortcuts.on(L10N.getStr("toggleCondPanel.key"), this.onToggleConditionalPanel);
shortcuts.on("Esc", this.onEscape);
shortcuts.on(searchAgainPrevKey, this.onSearchAgain);
shortcuts.on(searchAgainKey, this.onSearchAgain);
}
componentWillUnmount() {
if (this.state.editor) {
this.state.editor.destroy();
this.setState({
editor: null
});
}
const searchAgainKey = L10N.getStr("sourceSearch.search.again.key2");
const searchAgainPrevKey = L10N.getStr("sourceSearch.search.againPrev.key2");
const shortcuts = this.context.shortcuts;
shortcuts.off(L10N.getStr("toggleBreakpoint.key"));
shortcuts.off(L10N.getStr("toggleCondPanel.key"));
shortcuts.off(searchAgainPrevKey);
shortcuts.off(searchAgainKey);
}
componentDidUpdate(prevProps, prevState) {
const {
selectedSource
} = this.props; // NOTE: when devtools are opened, the editor is not set when
// the source loads so we need to wait until the editor is
// set to update the text and size.
if (!prevState.editor && selectedSource) {
if (!this.state.editor) {
const editor = this.setupEditor();
(0, _editor.updateDocument)(editor, selectedSource);
} else {
this.setText(this.props);
this.setSize(this.props);
}
}
}
getCurrentLine() {
const {
codeMirror
} = this.state.editor;
const {
selectedSource
} = this.props;
const line = (0, _editor.getCursorLine)(codeMirror);
return (0, _editor.toSourceLine)(selectedSource.get("id"), line);
}
onKeyDown(e) {
const {
codeMirror
} = this.state.editor;
const {
key,
target
} = e;
const codeWrapper = codeMirror.getWrapperElement();
const textArea = codeWrapper.querySelector("textArea");
if (key === "Escape" && target == textArea) {
e.stopPropagation();
e.preventDefault();
codeWrapper.focus();
} else if (key === "Enter" && target == codeWrapper) {
e.preventDefault(); // Focus into editor's text area
textArea.focus();
}
}
/*
* The default Esc command is overridden in the CodeMirror keymap to allow
* the Esc keypress event to be catched by the toolbox and trigger the
* split console. Restore it here, but preventDefault if and only if there
* is a multiselection.
*/
openMenu(event) {
event.stopPropagation();
event.preventDefault();
const {
setContextMenu
} = this.props;
if (event.target.classList.contains("CodeMirror-linenumber")) {
return setContextMenu("Gutter", event);
}
return setContextMenu("Editor", event);
}
onClick(e) {
const {
selectedLocation,
jumpToMappedLocation
} = this.props;
if (e.metaKey && e.altKey) {
const sourceLocation = (0, _editor.getSourceLocationFromMouseEvent)(this.state.editor, selectedLocation, e);
jumpToMappedLocation(sourceLocation);
}
}
shouldScrollToLocation(nextProps) {
const {
selectedLocation,
selectedSource
} = this.props;
const {
editor
} = this.state;
if (!nextProps.selectedSource || !editor || !nextProps.selectedLocation) {
return false;
}
if (!(0, _source.isLoaded)(nextProps.selectedSource)) {
return false;
}
if (!nextProps.selectedLocation.line) {
return false;
}
const isFirstLoad = (!selectedSource || !(0, _source.isLoaded)(selectedSource)) && (0, _source.isLoaded)(nextProps.selectedSource);
const locationChanged = selectedLocation !== nextProps.selectedLocation;
return isFirstLoad || locationChanged;
}
scrollToLocation(nextProps) {
const {
editor
} = this.state;
if (this.shouldScrollToLocation(nextProps)) {
let {
line,
column
} = (0, _editor.toEditorPosition)(nextProps.selectedLocation);
if ((0, _editor.hasDocument)(nextProps.selectedSource.get("id"))) {
const doc = (0, _editor.getDocument)(nextProps.selectedSource.get("id"));
const lineText = doc.getLine(line);
column = Math.max(column, (0, _indentation.getIndentation)(lineText));
}
(0, _editor.scrollToColumn)(editor.codeMirror, line, column);
}
}
setSize(nextProps) {
if (!this.state.editor) {
return;
}
if (nextProps.startPanelSize !== this.props.startPanelSize || nextProps.endPanelSize !== this.props.endPanelSize) {
this.state.editor.codeMirror.setSize();
}
}
setText(props) {
const {
selectedSource,
symbols
} = props;
if (!this.state.editor) {
return;
} // check if we previously had a selected source
if (!selectedSource) {
return this.clearEditor();
}
if (!(0, _source.isLoaded)(selectedSource)) {
return (0, _editor.showLoading)(this.state.editor);
}
if (selectedSource.get("error")) {
return this.showErrorMessage(selectedSource.get("error"));
}
if (selectedSource) {
return (0, _editor.showSourceText)(this.state.editor, selectedSource.toJS(), symbols);
}
}
clearEditor() {
const {
editor
} = this.state;
if (!editor) {
return;
}
(0, _editor.clearEditor)(editor);
}
showErrorMessage(msg) {
const {
editor
} = this.state;
if (!editor) {
return;
}
(0, _editor.showErrorMessage)(editor, msg);
}
getInlineEditorStyles() {
const {
selectedSource,
horizontal,
searchOn
} = this.props;
const subtractions = [];
if ((0, _editor.shouldShowFooter)(selectedSource, horizontal)) {
subtractions.push(cssVars.footerHeight);
}
if (searchOn) {
subtractions.push(cssVars.searchbarHeight);
subtractions.push(cssVars.secondSearchbarHeight);
}
return {
height: subtractions.length === 0 ? "100%" : `calc(100% - ${subtractions.join(" - ")})`
};
}
renderHitCounts() {
const {
hitCount,
selectedSource
} = this.props;
if (!selectedSource || !(0, _source.isLoaded)(selectedSource) || !hitCount || !this.state.editor) {
return;
}
return hitCount.filter(marker => marker.get("count") > 0).map(marker => _react2.default.createElement(_HitMarker2.default, {
key: marker.get("line"),
hitData: marker.toJS(),
editor: this.state.editor.codeMirror
}));
}
renderItems() {
const {
horizontal,
selectedSource
} = this.props;
const {
editor
} = this.state;
if (!editor || !selectedSource) {
return null;
}
return _react2.default.createElement("div", null, _react2.default.createElement(_DebugLine2.default, null), _react2.default.createElement(_HighlightLine2.default, null), _react2.default.createElement(_EmptyLines2.default, {
editor: editor
}), _react2.default.createElement(_Breakpoints2.default, {
editor: editor
}), _react2.default.createElement(_Preview2.default, {
editor: editor,
editorRef: this.$editorWrapper
}), ";", _react2.default.createElement(_Footer2.default, {
editor: editor,
horizontal: horizontal
}), _react2.default.createElement(_HighlightLines2.default, {
editor: editor
}), _react2.default.createElement(_EditorMenu2.default, {
editor: editor
}), _react2.default.createElement(_GutterMenu2.default, {
editor: editor
}), _react2.default.createElement(_ConditionalPanel2.default, {
editor: editor
}), _prefs.features.columnBreakpoints ? _react2.default.createElement(_CallSites2.default, {
editor: editor
}) : null, this.renderHitCounts());
}
renderSearchBar() {
const {
editor
} = this.state;
if (!editor) {
return null;
}
return _react2.default.createElement(_SearchBar2.default, {
editor: editor
});
}
render() {
const {
coverageOn
} = this.props;
return _react2.default.createElement("div", {
className: (0, _classnames2.default)("editor-wrapper", {
"coverage-on": coverageOn
}),
ref: c => this.$editorWrapper = c
}, this.renderSearchBar(), _react2.default.createElement("div", {
className: "editor-mount devtools-monospace",
style: this.getInlineEditorStyles()
}), this.renderItems());
}
}
Editor.contextTypes = {
shortcuts: _propTypes2.default.object
};
const mapStateToProps = state => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
const sourceId = selectedSource ? selectedSource.get("id") : "";
return {
selectedLocation: (0, _selectors.getSelectedLocation)(state),
selectedSource,
searchOn: (0, _selectors.getActiveSearch)(state) === "file",
hitCount: (0, _selectors.getHitCountForSource)(state, sourceId),
coverageOn: (0, _selectors.getCoverageEnabled)(state),
conditionalPanelLine: (0, _selectors.getConditionalPanelLine)(state),
symbols: (0, _selectors.getSymbols)(state, selectedSource && selectedSource.toJS())
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Editor);

Просмотреть файл

@ -0,0 +1,28 @@
# vim: set filetype=python:
# 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/.
DIRS += [
'Preview',
]
DevToolsModules(
'Breakpoint.js',
'Breakpoints.js',
'CallSite.js',
'CallSites.js',
'ConditionalPanel.js',
'DebugLine.js',
'EditorMenu.js',
'EmptyLines.js',
'Footer.js',
'GutterMenu.js',
'HighlightLine.js',
'HighlightLines.js',
'HitMarker.js',
'index.js',
'SearchBar.js',
'Tab.js',
'Tabs.js',
)

Просмотреть файл

@ -0,0 +1,205 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.Outline = undefined;
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _devtoolsContextmenu = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-contextmenu"];
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _clipboard = require("../../utils/clipboard");
var _function = require("../../utils/function");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../selectors/index");
var _PreviewFunction = require("../shared/PreviewFunction");
var _PreviewFunction2 = _interopRequireDefault(_PreviewFunction);
var _lodash = require("devtools/client/shared/vendor/lodash");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class Outline extends _react.Component {
selectItem(location) {
const {
selectedSource,
selectLocation
} = this.props;
if (!selectedSource) {
return;
}
const selectedSourceId = selectedSource.get("id");
const startLine = location.start.line;
selectLocation({
sourceId: selectedSourceId,
line: startLine
});
}
onContextMenu(event, func) {
event.stopPropagation();
event.preventDefault();
const {
selectedSource,
getFunctionText,
flashLineRange,
selectedLocation
} = this.props;
const copyFunctionKey = L10N.getStr("copyFunction.accesskey");
const copyFunctionLabel = L10N.getStr("copyFunction.label");
if (!selectedSource) {
return;
}
const sourceLine = func.location.start.line;
const functionText = getFunctionText(sourceLine);
const copyFunctionItem = {
id: "node-menu-copy-function",
label: copyFunctionLabel,
accesskey: copyFunctionKey,
disabled: !functionText,
click: () => {
flashLineRange({
start: func.location.start.line,
end: func.location.end.line,
sourceId: selectedLocation.sourceId
});
return (0, _clipboard.copyToTheClipboard)(functionText);
}
};
const menuOptions = [copyFunctionItem];
(0, _devtoolsContextmenu.showMenu)(event, menuOptions);
}
renderPlaceholder() {
const placeholderMessage = this.props.selectedSource ? L10N.getStr("outline.noFunctions") : L10N.getStr("outline.noFileSelected");
return _react2.default.createElement("div", {
className: "outline-pane-info"
}, placeholderMessage);
}
renderLoading() {
return _react2.default.createElement("div", {
className: "outline-pane-info"
}, L10N.getStr("loadingText"));
}
renderFunction(func) {
const {
name,
location,
parameterNames
} = func;
return _react2.default.createElement("li", {
key: `${name}:${location.start.line}:${location.start.column}`,
className: "outline-list__element",
onClick: () => this.selectItem(location),
onContextMenu: e => this.onContextMenu(e, func)
}, _react2.default.createElement("span", {
className: "outline-list__element-icon"
}, "\u03BB"), _react2.default.createElement(_PreviewFunction2.default, {
func: {
name,
parameterNames
}
}));
}
renderClassFunctions(klass, functions) {
if (klass == null || functions.length == 0) {
return null;
}
const classFunc = functions.find(func => func.name === klass);
const classFunctions = functions.filter(func => func.klass === klass);
const classInfo = this.props.symbols.classes.find(c => c.name === klass);
const heading = classFunc ? _react2.default.createElement("h2", null, this.renderFunction(classFunc)) : _react2.default.createElement("h2", {
onClick: classInfo ? () => this.selectItem(classInfo.location) : null
}, _react2.default.createElement("span", {
className: "keyword"
}, "class"), " ", klass);
return _react2.default.createElement("div", {
className: "outline-list__class",
key: klass
}, heading, _react2.default.createElement("ul", {
className: "outline-list__class-list"
}, classFunctions.map(func => this.renderFunction(func))));
}
renderFunctions(functions) {
let classes = (0, _lodash.uniq)(functions.map(func => func.klass));
let namedFunctions = functions.filter(func => func.name != "anonymous" && !func.klass && !classes.includes(func.name));
let classFunctions = functions.filter(func => func.name != "anonymous" && !!func.klass);
if (this.props.alphabetizeOutline) {
namedFunctions = (0, _lodash.sortBy)(namedFunctions, "name");
classes = (0, _lodash.sortBy)(classes, "klass");
classFunctions = (0, _lodash.sortBy)(classFunctions, "name");
}
return _react2.default.createElement("div", null, _react2.default.createElement("ul", {
className: "outline-list"
}, namedFunctions.map(func => this.renderFunction(func)), classes.map(klass => this.renderClassFunctions(klass, classFunctions))), _react2.default.createElement("div", {
className: "outline-footer bottom"
}, _react2.default.createElement("button", {
onClick: () => {
this.props.onAlphabetizeClick();
},
className: this.props.alphabetizeOutline ? "active" : ""
}, L10N.getStr("outline.sortLabel"))));
}
render() {
const {
symbols,
selectedSource
} = this.props;
if (!selectedSource) {
return this.renderPlaceholder();
}
if (!symbols || symbols.loading) {
return this.renderLoading();
}
const symbolsToDisplay = symbols.functions.filter(func => func.name != "anonymous");
return _react2.default.createElement("div", {
className: "outline"
}, symbolsToDisplay.length > 0 ? this.renderFunctions(symbols.functions) : this.renderPlaceholder());
}
}
exports.Outline = Outline;
const mapStateToProps = state => {
const selectedSource = (0, _selectors.getSelectedSource)(state);
const symbols = (0, _selectors.getSymbols)(state, selectedSource);
return {
symbols,
selectedSource,
selectedLocation: (0, _selectors.getSelectedLocation)(state),
getFunctionText: line => (0, _function.findFunctionText)(line, selectedSource, symbols)
};
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(Outline);

Просмотреть файл

@ -0,0 +1,415 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
var _devtoolsContextmenu = require("devtools/client/debugger/new/dist/vendors").vendored["devtools-contextmenu"];
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _selectors = require("../../selectors/index");
var _sourceTree = require("../../actions/source-tree");
var _sources = require("../../actions/sources/index");
var _ui = require("../../actions/ui");
var _ManagedTree = require("../shared/ManagedTree");
var _ManagedTree2 = _interopRequireDefault(_ManagedTree);
var _Svg = require("devtools/client/debugger/new/dist/vendors").vendored["Svg"];
var _Svg2 = _interopRequireDefault(_Svg);
var _sourcesTree = require("../../utils/sources-tree/index");
var _source = require("../../utils/source");
var _clipboard = require("../../utils/clipboard");
var _prefs = require("../../utils/prefs");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
// Dependencies
// Selectors
// Actions
// Components
// Utils
class SourcesTree extends _react.Component {
constructor(props) {
super(props);
_initialiseProps.call(this);
const {
debuggeeUrl,
sources,
projectRoot
} = this.props;
this.state = (0, _sourcesTree.createTree)({
projectRoot,
debuggeeUrl,
sources
});
}
componentWillReceiveProps(nextProps) {
const {
projectRoot,
debuggeeUrl,
sources,
shownSource,
selectedSource
} = this.props;
const {
uncollapsedTree,
sourceTree
} = this.state;
if (projectRoot != nextProps.projectRoot || debuggeeUrl != nextProps.debuggeeUrl || nextProps.sources.size === 0) {
// early recreate tree because of changes
// to project root, debugee url or lack of sources
return this.setState((0, _sourcesTree.createTree)({
sources: nextProps.sources,
debuggeeUrl: nextProps.debuggeeUrl,
projectRoot: nextProps.projectRoot
}));
}
if (nextProps.shownSource && nextProps.shownSource != shownSource) {
const listItems = (0, _sourcesTree.getDirectories)(nextProps.shownSource, sourceTree);
if (listItems && listItems[0]) {
this.selectItem(listItems[0]);
}
return this.setState({
listItems
});
}
if (nextProps.selectedSource && nextProps.selectedSource != selectedSource) {
const highlightItems = (0, _sourcesTree.getDirectories)((0, _source.getRawSourceURL)(nextProps.selectedSource.get("url")), sourceTree);
return this.setState({
highlightItems
});
} // NOTE: do not run this every time a source is clicked,
// only when a new source is added
if (nextProps.sources != this.props.sources) {
this.setState((0, _sourcesTree.updateTree)({
newSources: nextProps.sources,
prevSources: sources,
debuggeeUrl,
projectRoot,
uncollapsedTree,
sourceTree
}));
}
}
renderItemName(name) {
const hosts = {
"ng://": "Angular",
"webpack://": "Webpack",
"moz-extension://": L10N.getStr("extensionsText")
};
return hosts[name] || name;
}
renderEmptyElement(message) {
return _react2.default.createElement("div", {
className: "no-sources-message"
}, message);
}
render() {
const {
expanded,
projectRoot
} = this.props;
const {
focusedItem,
highlightItems,
listItems,
parentMap,
sourceTree
} = this.state;
const onExpand = (item, expandedState) => {
this.props.setExpandedState(expandedState);
};
const onCollapse = (item, expandedState) => {
this.props.setExpandedState(expandedState);
};
const isEmpty = sourceTree.contents.length === 0;
const isCustomRoot = projectRoot !== "";
let roots = () => sourceTree.contents;
let clearProjectRootButton = null; // The "sourceTree.contents[0]" check ensures that there are contents
// A custom root with no existing sources will be ignored
if (isCustomRoot) {
const sourceContents = sourceTree.contents[0];
let rootLabel = projectRoot.split("/").pop();
roots = () => sourceContents.contents;
if (sourceContents && sourceContents.name !== rootLabel) {
rootLabel = sourceContents.contents[0].name;
roots = () => sourceContents.contents[0].contents;
}
clearProjectRootButton = _react2.default.createElement("button", {
className: "sources-clear-root",
onClick: () => this.props.clearProjectDirectoryRoot(),
title: L10N.getStr("removeDirectoryRoot.label")
}, _react2.default.createElement(_Svg2.default, {
name: "home"
}), _react2.default.createElement(_Svg2.default, {
name: "breadcrumb",
"class": true
}), _react2.default.createElement("span", {
className: "sources-clear-root-label"
}, rootLabel));
}
if (isEmpty && !isCustomRoot) {
return this.renderEmptyElement(L10N.getStr("sources.noSourcesAvailable"));
}
const treeProps = {
autoExpandAll: false,
autoExpandDepth: expanded ? 0 : 1,
expanded,
getChildren: item => (0, _sourcesTree.nodeHasChildren)(item) ? item.contents : [],
getParent: item => parentMap.get(item),
getPath: this.getPath,
getRoots: roots,
highlightItems,
itemHeight: 21,
key: isEmpty ? "empty" : "full",
listItems,
onCollapse,
onExpand,
onFocus: this.focusItem,
renderItem: this.renderItem
};
const tree = _react2.default.createElement(_ManagedTree2.default, treeProps);
const onKeyDown = e => {
if (e.keyCode === 13 && focusedItem) {
this.selectItem(focusedItem);
}
};
return _react2.default.createElement("div", {
className: (0, _classnames2.default)("sources-pane", {
"sources-list-custom-root": isCustomRoot
})
}, isCustomRoot ? _react2.default.createElement("div", {
className: "sources-clear-root-container"
}, clearProjectRootButton) : null, isEmpty ? this.renderEmptyElement(L10N.getStr("sources.noSourcesAvailableRoot")) : _react2.default.createElement("div", {
className: "sources-list",
onKeyDown: onKeyDown
}, tree));
}
}
var _initialiseProps = function () {
this.focusItem = item => {
this.setState({
focusedItem: item
});
};
this.selectItem = item => {
if (!(0, _sourcesTree.nodeHasChildren)(item)) {
this.props.selectLocation({
sourceId: item.contents.get("id")
});
}
};
this.getPath = item => {
const {
sources
} = this.props;
const obj = item.contents.get && item.contents.get("id");
let blackBoxedPart = "";
if (typeof obj !== "undefined" && sources.has(obj) && sources.get(obj).get("isBlackBoxed")) {
blackBoxedPart = "update";
}
return `${item.path}/${item.name}/${blackBoxedPart}`;
};
this.getIcon = (sources, item, depth) => {
const {
debuggeeUrl,
projectRoot
} = this.props;
if (item.path === "webpack://") {
return _react2.default.createElement(_Svg2.default, {
name: "webpack"
});
} else if (item.path === "ng://") {
return _react2.default.createElement(_Svg2.default, {
name: "angular"
});
} else if (item.path === "moz-extension://") {
return _react2.default.createElement("img", {
className: "extension"
});
}
if (depth === 0 && projectRoot === "") {
return _react2.default.createElement("img", {
className: (0, _classnames2.default)("domain", {
debuggee: debuggeeUrl && debuggeeUrl.includes(item.name)
})
});
}
if (!(0, _sourcesTree.nodeHasChildren)(item)) {
const obj = item.contents.get("id");
const source = sources.get(obj);
const className = (0, _classnames2.default)((0, _source.getSourceClassnames)(source), "source-icon");
return _react2.default.createElement("img", {
className: className
});
}
return _react2.default.createElement("img", {
className: "folder"
});
};
this.onContextMenu = (event, item) => {
const copySourceUri2Label = L10N.getStr("copySourceUri2");
const copySourceUri2Key = L10N.getStr("copySourceUri2.accesskey");
const setDirectoryRootLabel = L10N.getStr("setDirectoryRoot.label");
const setDirectoryRootKey = L10N.getStr("setDirectoryRoot.accesskey");
const removeDirectoryRootLabel = L10N.getStr("removeDirectoryRoot.label");
event.stopPropagation();
event.preventDefault();
const menuOptions = [];
if (!(0, _sourcesTree.isDirectory)(item)) {
const source = item.contents.get("url");
const copySourceUri2 = {
id: "node-menu-copy-source",
label: copySourceUri2Label,
accesskey: copySourceUri2Key,
disabled: false,
click: () => (0, _clipboard.copyToTheClipboard)(source)
};
menuOptions.push(copySourceUri2);
}
if ((0, _sourcesTree.isDirectory)(item) && _prefs.features.root) {
const {
path
} = item;
const {
projectRoot
} = this.props;
if (projectRoot.endsWith(path)) {
menuOptions.push({
id: "node-remove-directory-root",
label: removeDirectoryRootLabel,
disabled: false,
click: () => this.props.clearProjectDirectoryRoot()
});
} else {
menuOptions.push({
id: "node-set-directory-root",
label: setDirectoryRootLabel,
accesskey: setDirectoryRootKey,
disabled: false,
click: () => this.props.setProjectDirectoryRoot(path)
});
}
}
(0, _devtoolsContextmenu.showMenu)(event, menuOptions);
};
this.renderItem = (item, depth, focused, _, expanded, {
setExpanded
}) => {
const arrow = (0, _sourcesTree.nodeHasChildren)(item) ? _react2.default.createElement("img", {
className: (0, _classnames2.default)("arrow", {
expanded: expanded
})
}) : _react2.default.createElement("i", {
className: "no-arrow"
});
const {
sources
} = this.props;
const icon = this.getIcon(sources, item, depth);
return _react2.default.createElement("div", {
className: (0, _classnames2.default)("node", {
focused
}),
key: item.path,
onClick: e => {
this.focusItem(item);
if ((0, _sourcesTree.isDirectory)(item)) {
setExpanded(item, !!expanded, e.altKey);
} else {
this.selectItem(item);
}
},
onContextMenu: e => this.onContextMenu(e, item)
}, arrow, icon, _react2.default.createElement("span", {
className: "label"
}, " ", this.renderItemName(item.name), " "));
};
};
const mapStateToProps = state => {
return {
shownSource: (0, _selectors.getShownSource)(state),
selectedSource: (0, _selectors.getSelectedSource)(state),
debuggeeUrl: (0, _selectors.getDebuggeeUrl)(state),
expanded: (0, _selectors.getExpandedState)(state),
projectRoot: (0, _selectors.getProjectDirectoryRoot)(state),
sources: (0, _selectors.getSources)(state)
};
};
const actionCreators = {
setExpandedState: _sourceTree.setExpandedState,
selectLocation: _sources.selectLocation,
setProjectDirectoryRoot: _ui.setProjectDirectoryRoot,
clearProjectDirectoryRoot: _ui.clearProjectDirectoryRoot
};
exports.default = (0, _reactRedux.connect)(mapStateToProps, actionCreators)(SourcesTree);

Просмотреть файл

@ -0,0 +1,127 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require("devtools/client/shared/vendor/react");
var _react2 = _interopRequireDefault(_react);
var _reactRedux = require("devtools/client/shared/vendor/react-redux");
var _text = require("../../utils/text");
var _actions = require("../../actions/index");
var _actions2 = _interopRequireDefault(_actions);
var _selectors = require("../../selectors/index");
var _prefs = require("../../utils/prefs");
var _classnames = require("devtools/client/debugger/new/dist/vendors").vendored["classnames"];
var _classnames2 = _interopRequireDefault(_classnames);
var _Outline = require("./Outline");
var _Outline2 = _interopRequireDefault(_Outline);
var _SourcesTree = require("./SourcesTree");
var _SourcesTree2 = _interopRequireDefault(_SourcesTree);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/* 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/>. */
class PrimaryPanes extends _react.Component {
constructor(props) {
super(props);
this.showPane = selectedPane => {
this.props.setPrimaryPaneTab(selectedPane);
};
this.onAlphabetizeClick = () => {
const alphabetizeOutline = !_prefs.prefs.alphabetizeOutline;
_prefs.prefs.alphabetizeOutline = alphabetizeOutline;
this.setState({
alphabetizeOutline
});
};
this.renderTabs = () => {
return _react2.default.createElement("div", {
className: "source-outline-tabs"
}, this.renderOutlineTabs());
};
this.renderShortcut = () => {
if (this.props.horizontal) {
const onClick = () => {
if (this.props.sourceSearchOn) {
return this.props.closeActiveSearch();
}
this.props.setActiveSearch("source");
};
return _react2.default.createElement("span", {
className: "sources-header-info",
dir: "ltr",
onClick: onClick
}, L10N.getFormatStr("sources.search", (0, _text.formatKeyShortcut)(L10N.getStr("sources.search.key2"))));
}
};
this.state = {
alphabetizeOutline: _prefs.prefs.alphabetizeOutline
};
}
renderOutlineTabs() {
if (!_prefs.features.outline) {
return;
}
const sources = (0, _text.formatKeyShortcut)(L10N.getStr("sources.header"));
const outline = (0, _text.formatKeyShortcut)(L10N.getStr("outline.header"));
return [_react2.default.createElement("div", {
className: (0, _classnames2.default)("tab sources-tab", {
active: this.props.selectedTab === "sources"
}),
onClick: () => this.showPane("sources"),
key: "sources-tab"
}, sources), _react2.default.createElement("div", {
className: (0, _classnames2.default)("tab outline-tab", {
active: this.props.selectedTab === "outline"
}),
onClick: () => this.showPane("outline"),
key: "outline-tab"
}, outline)];
}
render() {
const {
selectedTab
} = this.props;
return _react2.default.createElement("div", {
className: "sources-panel"
}, this.renderTabs(), selectedTab === "sources" ? _react2.default.createElement(_SourcesTree2.default, null) : _react2.default.createElement(_Outline2.default, {
alphabetizeOutline: this.state.alphabetizeOutline,
onAlphabetizeClick: this.onAlphabetizeClick
}));
}
}
const mapStateToProps = state => ({
selectedTab: (0, _selectors.getSelectedPrimaryPaneTab)(state),
sources: (0, _selectors.getSources)(state),
sourceSearchOn: (0, _selectors.getActiveSearch)(state) === "source"
});
exports.default = (0, _reactRedux.connect)(mapStateToProps, _actions2.default)(PrimaryPanes);

Просмотреть файл

@ -0,0 +1,14 @@
# vim: set filetype=python:
# 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/.
DIRS += [
]
DevToolsModules(
'index.js',
'Outline.js',
'SourcesTree.js',
)

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше