/* 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);