summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/context-menus/frame.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/actions/context-menus/frame.js')
-rw-r--r--devtools/client/debugger/src/actions/context-menus/frame.js97
1 files changed, 97 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/context-menus/frame.js b/devtools/client/debugger/src/actions/context-menus/frame.js
new file mode 100644
index 0000000000..1d287b1028
--- /dev/null
+++ b/devtools/client/debugger/src/actions/context-menus/frame.js
@@ -0,0 +1,97 @@
+/* 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/>. */
+
+import { showMenu } from "../../context-menu/menu";
+import { copyToTheClipboard } from "../../utils/clipboard";
+import {
+ getShouldSelectOriginalLocation,
+ getCurrentThreadFrames,
+ getFrameworkGroupingState,
+} from "../../selectors/index";
+import { toggleFrameworkGrouping } from "../../actions/ui";
+import { restart, toggleBlackBox } from "../../actions/pause/index";
+import { formatCopyName } from "../../utils/pause/frames/index";
+
+function formatMenuElement(labelString, click, disabled = false) {
+ const label = L10N.getStr(labelString);
+ const accesskey = L10N.getStr(`${labelString}.accesskey`);
+ const id = `node-menu-${labelString}`;
+ return {
+ id,
+ label,
+ accesskey,
+ disabled,
+ click,
+ };
+}
+
+function isValidRestartFrame(frame, callbacks) {
+ // Any frame state than 'on-stack' is either dismissed by the server
+ // or can potentially cause unexpected errors.
+ // Global frame has frame.callee equal to null and can't be restarted.
+ return frame.type === "call" && frame.state === "on-stack";
+}
+
+function copyStackTrace() {
+ return async ({ dispatch, getState }) => {
+ const frames = getCurrentThreadFrames(getState());
+ const shouldDisplayOriginalLocation = getShouldSelectOriginalLocation(
+ getState()
+ );
+
+ const framesToCopy = frames
+ .map(frame => formatCopyName(frame, L10N, shouldDisplayOriginalLocation))
+ .join("\n");
+ copyToTheClipboard(framesToCopy);
+ };
+}
+
+export function showFrameContextMenu(event, frame, hideRestart = false) {
+ return async ({ dispatch, getState }) => {
+ const items = [];
+
+ // Hides 'Restart Frame' item for call stack groups context menu,
+ // otherwise can be misleading for the user which frame gets restarted.
+ if (!hideRestart && isValidRestartFrame(frame)) {
+ items.push(
+ formatMenuElement("restartFrame", () => dispatch(restart(frame)))
+ );
+ }
+
+ const toggleFrameWorkL10nLabel = getFrameworkGroupingState(getState())
+ ? "framework.disableGrouping"
+ : "framework.enableGrouping";
+ items.push(
+ formatMenuElement(toggleFrameWorkL10nLabel, () =>
+ dispatch(
+ toggleFrameworkGrouping(!getFrameworkGroupingState(getState()))
+ )
+ )
+ );
+
+ const { source } = frame;
+ if (frame.source) {
+ items.push(
+ formatMenuElement("copySourceUri2", () =>
+ copyToTheClipboard(source.url)
+ )
+ );
+
+ const toggleBlackBoxL10nLabel = source.isBlackBoxed
+ ? "ignoreContextItem.unignore"
+ : "ignoreContextItem.ignore";
+ items.push(
+ formatMenuElement(toggleBlackBoxL10nLabel, () =>
+ dispatch(toggleBlackBox(source))
+ )
+ );
+ }
+
+ items.push(
+ formatMenuElement("copyStackTrace", () => dispatch(copyStackTrace()))
+ );
+
+ showMenu(event, items);
+ };
+}