/* 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 . */ import React, { Component } from "react"; import PropTypes from "prop-types"; import { connect } from "../utils/connect"; import { prefs } from "../utils/prefs"; import { primaryPaneTabs } from "../constants"; import actions from "../actions"; import A11yIntention from "./A11yIntention"; import { ShortcutsModal } from "./ShortcutsModal"; import { getSelectedSource, getPaneCollapse, getActiveSearch, getQuickOpenEnabled, getOrientation, } from "../selectors"; const KeyShortcuts = require("devtools/client/shared/key-shortcuts"); const SplitBox = require("devtools/client/shared/components/splitter/SplitBox"); const AppErrorBoundary = require("devtools/client/shared/components/AppErrorBoundary"); const shortcuts = new KeyShortcuts({ window }); const horizontalLayoutBreakpoint = window.matchMedia("(min-width: 800px)"); const verticalLayoutBreakpoint = window.matchMedia( "(min-width: 10px) and (max-width: 799px)" ); import "./variables.css"; import "./App.css"; import "./shared/menu.css"; import PrimaryPanes from "./PrimaryPanes"; import Editor from "./Editor"; import SecondaryPanes from "./SecondaryPanes"; import WelcomeBox from "./WelcomeBox"; import EditorTabs from "./Editor/Tabs"; import EditorFooter from "./Editor/Footer"; import QuickOpenModal from "./QuickOpenModal"; class App extends Component { constructor(props) { super(props); this.state = { shortcutsModalEnabled: false, startPanelSize: 0, endPanelSize: 0, }; } static get propTypes() { return { activeSearch: PropTypes.oneOf(["file", "project"]), closeActiveSearch: PropTypes.func.isRequired, closeQuickOpen: PropTypes.func.isRequired, endPanelCollapsed: PropTypes.bool.isRequired, fluentBundles: PropTypes.array.isRequired, openQuickOpen: PropTypes.func.isRequired, orientation: PropTypes.oneOf(["horizontal", "vertical"]).isRequired, quickOpenEnabled: PropTypes.bool.isRequired, selectedSource: PropTypes.object, setActiveSearch: PropTypes.func.isRequired, setOrientation: PropTypes.func.isRequired, setPrimaryPaneTab: PropTypes.func.isRequired, startPanelCollapsed: PropTypes.bool.isRequired, toolboxDoc: PropTypes.object.isRequired, }; } getChildContext() { return { fluentBundles: this.props.fluentBundles, toolboxDoc: this.props.toolboxDoc, shortcuts, l10n: L10N, }; } componentDidMount() { horizontalLayoutBreakpoint.addListener(this.onLayoutChange); verticalLayoutBreakpoint.addListener(this.onLayoutChange); this.setOrientation(); shortcuts.on(L10N.getStr("symbolSearch.search.key2"), e => this.toggleQuickOpenModal(e, "@") ); [ L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key"), ].forEach(key => shortcuts.on(key, this.toggleQuickOpenModal)); shortcuts.on(L10N.getStr("gotoLineModal.key3"), e => this.toggleQuickOpenModal(e, ":") ); shortcuts.on( L10N.getStr("projectTextSearch.key"), this.jumpToProjectSearch ); shortcuts.on("Escape", this.onEscape); shortcuts.on("CmdOrCtrl+/", this.onCommandSlash); } componentWillUnmount() { horizontalLayoutBreakpoint.removeListener(this.onLayoutChange); verticalLayoutBreakpoint.removeListener(this.onLayoutChange); shortcuts.off( L10N.getStr("symbolSearch.search.key2"), this.toggleQuickOpenModal ); [ L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.alt.key"), ].forEach(key => shortcuts.off(key, this.toggleQuickOpenModal)); shortcuts.off(L10N.getStr("gotoLineModal.key3"), this.toggleQuickOpenModal); shortcuts.off( L10N.getStr("projectTextSearch.key"), this.jumpToProjectSearch ); shortcuts.off("Escape", this.onEscape); shortcuts.off("CmdOrCtrl+/", this.onCommandSlash); } jumpToProjectSearch = e => { e.preventDefault(); this.props.setPrimaryPaneTab(primaryPaneTabs.PROJECT_SEARCH); this.props.setActiveSearch(primaryPaneTabs.PROJECT_SEARCH); }; onEscape = e => { const { activeSearch, closeActiveSearch, closeQuickOpen, quickOpenEnabled, } = this.props; const { shortcutsModalEnabled } = this.state; if (activeSearch) { e.preventDefault(); closeActiveSearch(); } if (quickOpenEnabled) { e.preventDefault(); closeQuickOpen(); } if (shortcutsModalEnabled) { e.preventDefault(); this.toggleShortcutsModal(); } }; onCommandSlash = () => { this.toggleShortcutsModal(); }; isHorizontal() { return this.props.orientation === "horizontal"; } 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(); }; onLayoutChange = () => { this.setOrientation(); }; 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"); } } renderEditorPane = () => { const { startPanelCollapsed, endPanelCollapsed } = this.props; const { endPanelSize, startPanelSize } = this.state; const horizontal = this.isHorizontal(); return (
{!this.props.selectedSource ? ( this.toggleShortcutsModal()} /> ) : null}
); }; toggleShortcutsModal() { this.setState(prevState => ({ shortcutsModalEnabled: !prevState.shortcutsModalEnabled, })); } // Important so that the tabs chevron updates appropriately when // the user resizes the left or right columns triggerEditorPaneResize() { const editorPane = window.document.querySelector(".editor-pane"); if (editorPane) { editorPane.dispatchEvent(new Event("resizeend")); } } renderLayout = () => { const { startPanelCollapsed, endPanelCollapsed } = this.props; const horizontal = this.isHorizontal(); return ( { prefs.endPanelSize = num; this.triggerEditorPaneResize(); }} startPanel={ { prefs.startPanelSize = num; }} startPanelCollapsed={startPanelCollapsed} startPanel={} endPanel={this.renderEditorPane()} /> } endPanelControl={true} endPanel={} endPanelCollapsed={endPanelCollapsed} /> ); }; render() { const { quickOpenEnabled } = this.props; return (
{this.renderLayout()} {quickOpenEnabled === true && ( this.toggleShortcutsModal()} /> )} this.toggleShortcutsModal()} />
); } } App.childContextTypes = { toolboxDoc: PropTypes.object, shortcuts: PropTypes.object, l10n: PropTypes.object, fluentBundles: PropTypes.array, }; const mapStateToProps = state => ({ selectedSource: getSelectedSource(state), startPanelCollapsed: getPaneCollapse(state, "start"), endPanelCollapsed: getPaneCollapse(state, "end"), activeSearch: getActiveSearch(state), quickOpenEnabled: getQuickOpenEnabled(state), orientation: getOrientation(state), }); export default connect(mapStateToProps, { setActiveSearch: actions.setActiveSearch, closeActiveSearch: actions.closeActiveSearch, openQuickOpen: actions.openQuickOpen, closeQuickOpen: actions.closeQuickOpen, setOrientation: actions.setOrientation, setPrimaryPaneTab: actions.setPrimaryPaneTab, })(App);