diff options
Diffstat (limited to 'devtools/client/webconsole/components/Input/ConfirmDialog.js')
-rw-r--r-- | devtools/client/webconsole/components/Input/ConfirmDialog.js | 197 |
1 files changed, 197 insertions, 0 deletions
diff --git a/devtools/client/webconsole/components/Input/ConfirmDialog.js b/devtools/client/webconsole/components/Input/ConfirmDialog.js new file mode 100644 index 0000000000..799d8d76b1 --- /dev/null +++ b/devtools/client/webconsole/components/Input/ConfirmDialog.js @@ -0,0 +1,197 @@ +/* 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/. */ + +"use strict"; + +loader.lazyRequireGetter( + this, + "PropTypes", + "resource://devtools/client/shared/vendor/react-prop-types.js" +); +loader.lazyRequireGetter( + this, + "HTMLTooltip", + "resource://devtools/client/shared/widgets/tooltip/HTMLTooltip.js", + true +); +loader.lazyRequireGetter( + this, + "createPortal", + "resource://devtools/client/shared/vendor/react-dom.js", + true +); + +// React & Redux +const { + Component, +} = require("resource://devtools/client/shared/vendor/react.js"); +const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js"); +const { + connect, +} = require("resource://devtools/client/shared/vendor/react-redux.js"); + +const { + getAutocompleteState, +} = require("resource://devtools/client/webconsole/selectors/autocomplete.js"); +const autocompleteActions = require("resource://devtools/client/webconsole/actions/autocomplete.js"); +const { + l10n, +} = require("resource://devtools/client/webconsole/utils/messages.js"); + +const LEARN_MORE_URL = `https://firefox-source-docs.mozilla.org/devtools-user/web_console/invoke_getters_from_autocomplete/`; + +class ConfirmDialog extends Component { + static get propTypes() { + return { + // Console object. + webConsoleUI: PropTypes.object.isRequired, + // Update autocomplete popup state. + autocompleteUpdate: PropTypes.func.isRequired, + autocompleteClear: PropTypes.func.isRequired, + // Data to be displayed in the confirm dialog. + getterPath: PropTypes.array, + serviceContainer: PropTypes.object.isRequired, + }; + } + + constructor(props) { + super(props); + + const { webConsoleUI } = props; + webConsoleUI.confirmDialog = this; + + this.cancel = this.cancel.bind(this); + this.confirm = this.confirm.bind(this); + this.onLearnMoreClick = this.onLearnMoreClick.bind(this); + } + + componentDidMount() { + const doc = this.props.webConsoleUI.document; + const { toolbox } = this.props.webConsoleUI.wrapper; + const tooltipDoc = toolbox ? toolbox.doc : doc; + // The popup will be attached to the toolbox document or HUD document in the case + // such as the browser console which doesn't have a toolbox. + this.tooltip = new HTMLTooltip(tooltipDoc, { + className: "invoke-confirm", + }); + } + + componentDidUpdate() { + const { getterPath, serviceContainer } = this.props; + + if (getterPath) { + this.tooltip.show(serviceContainer.getJsTermTooltipAnchor(), { y: 5 }); + } else { + this.tooltip.hide(); + this.props.webConsoleUI.jsterm.focus(); + } + } + + componentDidThrow(e) { + console.error("Error in ConfirmDialog", e); + this.setState(state => ({ ...state, hasError: true })); + } + + onLearnMoreClick(e) { + this.props.serviceContainer.openLink(LEARN_MORE_URL, e); + } + + cancel() { + this.tooltip.hide(); + this.props.autocompleteClear(); + } + + confirm() { + this.tooltip.hide(); + this.props.autocompleteUpdate(this.props.getterPath); + } + + render() { + if ( + (this.state && this.state.hasError) || + !this.props || + !this.props.getterPath + ) { + return null; + } + + const { getterPath } = this.props; + const getterName = getterPath.join("."); + + // We deliberately use getStr, and not getFormatStr, because we want getterName to + // be wrapped in its own span. + const description = l10n.getStr("webconsole.confirmDialog.getter.label"); + const [descriptionPrefix, descriptionSuffix] = description.split("%S"); + + const closeButtonTooltip = l10n.getFormatStr( + "webconsole.confirmDialog.getter.closeButton.tooltip", + ["Esc"] + ); + const invokeButtonLabel = l10n.getFormatStr( + "webconsole.confirmDialog.getter.invokeButtonLabelWithShortcut", + ["Tab"] + ); + + const learnMoreElement = dom.a( + { + className: "learn-more-link", + key: "learn-more-link", + title: LEARN_MORE_URL.split("?")[0], + onClick: this.onLearnMoreClick, + }, + l10n.getStr("webConsoleMoreInfoLabel") + ); + + return createPortal( + [ + dom.div( + { + className: "confirm-label", + key: "confirm-label", + }, + dom.p( + {}, + dom.span({}, descriptionPrefix), + dom.span({ className: "emphasized" }, getterName), + dom.span({}, descriptionSuffix) + ), + dom.button({ + className: "devtools-button close-confirm-dialog-button", + key: "close-button", + title: closeButtonTooltip, + onClick: this.cancel, + }) + ), + dom.button( + { + className: "confirm-button", + key: "confirm-button", + onClick: this.confirm, + }, + invokeButtonLabel + ), + learnMoreElement, + ], + this.tooltip.panel + ); + } +} + +// Redux connect +function mapStateToProps(state) { + const autocompleteData = getAutocompleteState(state); + return { + getterPath: autocompleteData.getterPath, + }; +} + +function mapDispatchToProps(dispatch) { + return { + autocompleteUpdate: getterPath => + dispatch(autocompleteActions.autocompleteUpdate(true, getterPath)), + autocompleteClear: () => dispatch(autocompleteActions.autocompleteClear()), + }; +} + +module.exports = connect(mapStateToProps, mapDispatchToProps)(ConfirmDialog); |