tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TabboxPanel.js (8422B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  Component,
      9  createFactory,
     10 } = require("resource://devtools/client/shared/vendor/react.mjs");
     11 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     12 const {
     13  connect,
     14 } = require("resource://devtools/client/shared/vendor/react-redux.js");
     15 const {
     16  L10N,
     17 } = require("resource://devtools/client/netmonitor/src/utils/l10n.js");
     18 const {
     19  PANELS,
     20 } = require("resource://devtools/client/netmonitor/src/constants.js");
     21 const {
     22  getOverriddenUrl,
     23 } = require("resource://devtools/client/netmonitor/src/selectors/index.js");
     24 
     25 // Components
     26 const Tabbar = createFactory(
     27  require("resource://devtools/client/shared/components/tabs/TabBar.js")
     28 );
     29 const TabPanel = createFactory(
     30  ChromeUtils.importESModule(
     31    "resource://devtools/client/shared/components/tabs/Tabs.mjs"
     32  ).TabPanel
     33 );
     34 const CookiesPanel = createFactory(
     35  require("resource://devtools/client/netmonitor/src/components/request-details/CookiesPanel.js")
     36 );
     37 const HeadersPanel = createFactory(
     38  require("resource://devtools/client/netmonitor/src/components/request-details/HeadersPanel.js")
     39 );
     40 const RequestPanel = createFactory(
     41  require("resource://devtools/client/netmonitor/src/components/request-details/RequestPanel.js")
     42 );
     43 const CachePanel = createFactory(
     44  require("resource://devtools/client/netmonitor/src/components/request-details/CachePanel.js")
     45 );
     46 const ResponsePanel = createFactory(
     47  require("resource://devtools/client/netmonitor/src/components/request-details/ResponsePanel.js")
     48 );
     49 const SecurityPanel = createFactory(
     50  require("resource://devtools/client/netmonitor/src/components/request-details/SecurityPanel.js")
     51 );
     52 const StackTracePanel = createFactory(
     53  require("resource://devtools/client/netmonitor/src/components/request-details/StackTracePanel.js")
     54 );
     55 const TimingsPanel = createFactory(
     56  require("resource://devtools/client/netmonitor/src/components/request-details/TimingsPanel.js")
     57 );
     58 
     59 const COLLAPSE_DETAILS_PANE = L10N.getStr("collapseDetailsPane");
     60 const ALL_TABS_MENU_BUTTON_TOOLTIP = L10N.getStr("allTabsMenuButton.tooltip");
     61 const CACHE_TITLE = L10N.getStr("netmonitor.tab.cache");
     62 const COOKIES_TITLE = L10N.getStr("netmonitor.tab.cookies");
     63 const HEADERS_TITLE = L10N.getStr("netmonitor.tab.headers");
     64 const REQUEST_TITLE = L10N.getStr("netmonitor.tab.request");
     65 const RESPONSE_TITLE = L10N.getStr("netmonitor.tab.response");
     66 const SECURITY_TITLE = L10N.getStr("netmonitor.tab.security");
     67 const STACK_TRACE_TITLE = L10N.getStr("netmonitor.tab.stackTrace");
     68 const TIMINGS_TITLE = L10N.getStr("netmonitor.tab.timings");
     69 
     70 /**
     71 * Tabbox panel component
     72 * Display the network request details
     73 */
     74 class TabboxPanel extends Component {
     75  static get propTypes() {
     76    return {
     77      activeTabId: PropTypes.string,
     78      cloneSelectedRequest: PropTypes.func,
     79      connector: PropTypes.object.isRequired,
     80      openLink: PropTypes.func,
     81      request: PropTypes.object,
     82      selectTab: PropTypes.func.isRequired,
     83      sourceMapURLService: PropTypes.object,
     84      hideToggleButton: PropTypes.bool,
     85      toggleNetworkDetails: PropTypes.func,
     86      openNetworkDetails: PropTypes.func.isRequired,
     87      showMessagesView: PropTypes.bool,
     88      targetSearchResult: PropTypes.object,
     89      defaultRawResponse: PropTypes.bool,
     90      setDefaultRawResponse: PropTypes.func,
     91      isOverridden: PropTypes.bool,
     92      overriddenUrl: PropTypes.string,
     93    };
     94  }
     95  static get defaultProps() {
     96    return {
     97      showMessagesView: true,
     98    };
     99  }
    100  componentDidMount() {
    101    this.closeOnEscRef = this.closeOnEsc.bind(this);
    102    window.addEventListener("keydown", this.closeOnEscRef);
    103  }
    104 
    105  componentWillUnmount() {
    106    window.removeEventListener("keydown", this.closeOnEscRef);
    107  }
    108 
    109  closeOnEsc(event) {
    110    if (event.key == "Escape") {
    111      event.preventDefault();
    112      // Don't take focus when the keyboard shortcut is triggered in a CodeMirror instance,
    113      // so the CodeMirror search UI is closed.
    114      if (event.target.closest(".cm-search")) {
    115        return;
    116      }
    117      this.props.openNetworkDetails(false);
    118    }
    119  }
    120 
    121  render() {
    122    const {
    123      activeTabId,
    124      cloneSelectedRequest = () => {},
    125      connector,
    126      hideToggleButton,
    127      openLink,
    128      defaultRawResponse,
    129      isOverridden,
    130      overriddenUrl,
    131      request,
    132      selectTab,
    133      setDefaultRawResponse,
    134      sourceMapURLService,
    135      toggleNetworkDetails,
    136      targetSearchResult,
    137    } = this.props;
    138 
    139    if (!request) {
    140      return null;
    141    }
    142 
    143    const isWs = request.cause.type === "websocket";
    144    const isSse = request.isEventStream;
    145 
    146    const showMessagesView = (isWs || isSse) && this.props.showMessagesView;
    147    return Tabbar(
    148      {
    149        activeTabId,
    150        menuDocument: window.parent.document,
    151        onSelect: selectTab,
    152        renderOnlySelected: true,
    153        showAllTabsMenu: true,
    154        allTabsMenuButtonTooltip: ALL_TABS_MENU_BUTTON_TOOLTIP,
    155        sidebarToggleButton: hideToggleButton
    156          ? null
    157          : {
    158              collapsed: false,
    159              collapsePaneTitle: COLLAPSE_DETAILS_PANE,
    160              expandPaneTitle: "",
    161              onClick: toggleNetworkDetails,
    162            },
    163      },
    164      TabPanel(
    165        {
    166          id: PANELS.HEADERS,
    167          title: HEADERS_TITLE,
    168          className: "panel-with-code",
    169        },
    170        HeadersPanel({
    171          cloneSelectedRequest,
    172          connector,
    173          openLink,
    174          request,
    175          targetSearchResult,
    176        })
    177      ),
    178      TabPanel(
    179        {
    180          id: PANELS.COOKIES,
    181          title: COOKIES_TITLE,
    182          className: "panel-with-code",
    183        },
    184        CookiesPanel({
    185          connector,
    186          openLink,
    187          request,
    188          targetSearchResult,
    189        })
    190      ),
    191      TabPanel(
    192        {
    193          id: PANELS.REQUEST,
    194          title: REQUEST_TITLE,
    195          className: "panel-with-code",
    196        },
    197        RequestPanel({
    198          connector,
    199          openLink,
    200          request,
    201          targetSearchResult,
    202        })
    203      ),
    204      TabPanel(
    205        {
    206          id: PANELS.RESPONSE,
    207          title: RESPONSE_TITLE,
    208          className:
    209            "panel-with-code" +
    210            (isOverridden ? " tab-response-overridden" : ""),
    211          tooltip: isOverridden
    212            ? L10N.getFormatStr(
    213                "netmonitor.tab.response-overridden.tooltip",
    214                overriddenUrl
    215              )
    216            : RESPONSE_TITLE,
    217        },
    218        ResponsePanel({
    219          request,
    220          openLink,
    221          connector,
    222          showMessagesView,
    223          targetSearchResult,
    224          defaultRawResponse,
    225          setDefaultRawResponse,
    226        })
    227      ),
    228      (request.fromCache || request.status == "304") &&
    229        TabPanel(
    230          {
    231            id: PANELS.CACHE,
    232            title: CACHE_TITLE,
    233          },
    234          CachePanel({ request, openLink, connector })
    235        ),
    236      TabPanel(
    237        {
    238          id: PANELS.TIMINGS,
    239          title: TIMINGS_TITLE,
    240        },
    241        TimingsPanel({
    242          connector,
    243          request,
    244        })
    245      ),
    246      request.cause?.stacktraceAvailable &&
    247        TabPanel(
    248          {
    249            id: PANELS.STACK_TRACE,
    250            title: STACK_TRACE_TITLE,
    251            className: "panel-with-code",
    252          },
    253          StackTracePanel({ connector, openLink, request, sourceMapURLService })
    254        ),
    255      request.securityState &&
    256        request.securityState !== "insecure" &&
    257        TabPanel(
    258          {
    259            id: PANELS.SECURITY,
    260            title: SECURITY_TITLE,
    261          },
    262          SecurityPanel({
    263            connector,
    264            openLink,
    265            request,
    266          })
    267        )
    268    );
    269  }
    270 }
    271 
    272 module.exports = {
    273  ConnectedTabboxPanel: connect(
    274    (state, props) => {
    275      const overriddenUrl = getOverriddenUrl(
    276        state,
    277        props.request.urlDetails?.url
    278      );
    279      return {
    280        isOverridden: !!overriddenUrl,
    281        overriddenUrl,
    282      };
    283    },
    284    {},
    285    undefined,
    286    { storeKey: "toolbox-store" }
    287  )(TabboxPanel),
    288  // Export the non-connected variant of the component for the browser console
    289  // which might not have toolbox store available.
    290  TabboxPanel,
    291 };