summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/context-menus/tab.js
blob: 193396a746e3f719f92ba824817185fe1a529c08 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* 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, buildMenu } from "../../context-menu/menu";
import { getTabMenuItems } from "../../utils/tabs";

import {
  getSelectedLocation,
  getSourcesForTabs,
  isSourceBlackBoxed,
  isSourceMapIgnoreListEnabled,
  isSourceOnSourceMapIgnoreList,
} from "../../selectors/index";

import { toggleBlackBox } from "../sources/blackbox";
import { prettyPrintAndSelectSource } from "../sources/prettyPrint";
import { copyToClipboard, showSource } from "../ui";
import { closeTab, closeTabs } from "../tabs";

import { getRawSourceURL, isPretty, shouldBlackbox } from "../../utils/source";
import { copyToTheClipboard } from "../../utils/clipboard";

/**
 * Show the context menu of Tab.
 *
 * @param {object} event
 *        The context-menu DOM event.
 * @param {object} source
 *        Source object of the related Tab.
 */
export function showTabContextMenu(event, source) {
  return async ({ dispatch, getState }) => {
    const state = getState();
    const selectedLocation = getSelectedLocation(state);

    const isBlackBoxed = isSourceBlackBoxed(state, source);
    const isSourceOnIgnoreList =
      isSourceMapIgnoreListEnabled(state) &&
      isSourceOnSourceMapIgnoreList(state, source);
    const tabsSources = getSourcesForTabs(state);

    const otherTabsSources = tabsSources.filter(s => s !== source);
    const tabIndex = tabsSources.findIndex(s => s === source);
    const followingTabsSources = tabsSources.slice(tabIndex + 1);

    const tabMenuItems = getTabMenuItems();
    const items = [
      {
        item: {
          ...tabMenuItems.closeTab,
          click: () => dispatch(closeTab(source)),
        },
      },
      {
        item: {
          ...tabMenuItems.closeOtherTabs,
          disabled: otherTabsSources.length === 0,
          click: () => dispatch(closeTabs(otherTabsSources)),
        },
      },
      {
        item: {
          ...tabMenuItems.closeTabsToEnd,
          disabled: followingTabsSources.length === 0,
          click: () => {
            dispatch(closeTabs(followingTabsSources));
          },
        },
      },
      {
        item: {
          ...tabMenuItems.closeAllTabs,
          click: () => dispatch(closeTabs(tabsSources)),
        },
      },
      { item: { type: "separator" } },
      {
        item: {
          ...tabMenuItems.copySource,
          // Only enable when this is the selected source as this requires the source to be loaded,
          // which may not be the case if the tab wasn't ever selected.
          //
          // Note that when opening the debugger, you may have tabs opened from a previous session,
          // but no selected location.
          disabled: selectedLocation?.source.id !== source.id,
          click: () => {
            dispatch(copyToClipboard(selectedLocation));
          },
        },
      },
      {
        item: {
          ...tabMenuItems.copySourceUri2,
          disabled: !source.url,
          click: () => copyToTheClipboard(getRawSourceURL(source.url)),
        },
      },
      {
        item: {
          ...tabMenuItems.showSource,
          // Source Tree only shows sources with URL
          disabled: !source.url,
          click: () => dispatch(showSource(source.id)),
        },
      },
      {
        item: {
          ...tabMenuItems.toggleBlackBox,
          label: isBlackBoxed
            ? L10N.getStr("ignoreContextItem.unignore")
            : L10N.getStr("ignoreContextItem.ignore"),
          disabled: isSourceOnIgnoreList || !shouldBlackbox(source),
          click: () => dispatch(toggleBlackBox(source)),
        },
      },
      {
        item: {
          ...tabMenuItems.prettyPrint,
          disabled: isPretty(source),
          click: () => dispatch(prettyPrintAndSelectSource(source)),
        },
      },
    ];

    showMenu(event, buildMenu(items));
  };
}