Bug 1519313 - Do not clear the console input when evaluating and 'devtools.webconsole.input.editor' is true. r=nchevobbe
authorBisola Omisore <solaocodes@gmail.com>
Mon, 11 Mar 2019 08:57:27 +0000
changeset 524322 90de1c90ae69901ff38e5e1c95f9f09ac73313be
parent 524321 b1c9e8f9dab7d6e12b4867f7f7245b5e52b33abf
child 524323 6e04cf2319d2c6513fc0d4e5df6cfd42e087d1fe
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnchevobbe
bugs1519313
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1519313 - Do not clear the console input when evaluating and 'devtools.webconsole.input.editor' is true. r=nchevobbe Create an `editorMode` prop that is initialized with the preference value, and passed to the JSTerm component. The prop is then used to check if the input should be cleared when an evaluation is done. A test is added to ensure this works as expected. Differential Revision: https://phabricator.services.mozilla.com/D22171
devtools/client/webconsole/components/App.js
devtools/client/webconsole/components/JSTerm.js
devtools/client/webconsole/constants.js
devtools/client/webconsole/reducers/ui.js
devtools/client/webconsole/store.js
devtools/client/webconsole/test/mochitest/browser.ini
devtools/client/webconsole/test/mochitest/browser_jsterm_editor_execute.js
--- a/devtools/client/webconsole/components/App.js
+++ b/devtools/client/webconsole/components/App.js
@@ -45,16 +45,17 @@ class App extends Component {
       notifications: PropTypes.object,
       onFirstMeaningfulPaint: PropTypes.func.isRequired,
       serviceContainer: PropTypes.object.isRequired,
       closeSplitConsole: PropTypes.func.isRequired,
       jstermCodeMirror: PropTypes.bool,
       currentReverseSearchEntry: PropTypes.string,
       reverseSearchInputVisible: PropTypes.bool,
       reverseSearchInitialValue: PropTypes.string,
+      editorMode: PropTypes.bool,
     };
   }
 
   constructor(props) {
     super(props);
 
     this.onClick = this.onClick.bind(this);
     this.onPaste = this.onPaste.bind(this);
@@ -195,22 +196,26 @@ class App extends Component {
       attachRefToWebConsoleUI,
       webConsoleUI,
       notifications,
       onFirstMeaningfulPaint,
       serviceContainer,
       closeSplitConsole,
       jstermCodeMirror,
       reverseSearchInitialValue,
+      editorMode,
     } = this.props;
 
     const classNames = ["webconsole-app"];
     if (jstermCodeMirror) {
       classNames.push("jsterm-cm");
     }
+    if (editorMode) {
+      classNames.push("jsterm-editor");
+    }
 
     // Render the entire Console panel. The panel consists
     // from the following parts:
     // * FilterBar - Buttons & free text for content filtering
     // * Content - List of logs & messages
     // * NotificationBox - Notifications for JSTerm (self-xss warning at the moment)
     // * JSTerm - Input command line.
     // * ReverseSearchInput - Reverse search input.
@@ -237,16 +242,17 @@ class App extends Component {
             id: "webconsole-notificationbox",
             notifications,
           }),
           JSTerm({
             webConsoleUI,
             serviceContainer,
             onPaste: this.onPaste,
             codeMirrorEnabled: jstermCodeMirror,
+            editorMode,
           }),
           ReverseSearchInput({
             setInputValue: serviceContainer.setInputValue,
             focusInput: serviceContainer.focusInput,
             evaluateInput: serviceContainer.evaluateInput,
             initialValue: reverseSearchInitialValue,
           })
         ),
@@ -262,15 +268,16 @@ class App extends Component {
     );
   }
 }
 
 const mapStateToProps = state => ({
   notifications: getAllNotifications(state),
   reverseSearchInputVisible: state.ui.reverseSearchInputVisible,
   reverseSearchInitialValue: state.ui.reverseSearchInitialValue,
+  editorMode: state.ui.editor,
 });
 
 const mapDispatchToProps = dispatch => ({
   dispatch,
 });
 
 module.exports = connect(mapStateToProps, mapDispatchToProps)(App);
--- a/devtools/client/webconsole/components/JSTerm.js
+++ b/devtools/client/webconsole/components/JSTerm.js
@@ -74,16 +74,18 @@ class JSTerm extends Component {
       onPaste: PropTypes.func,
       codeMirrorEnabled: PropTypes.bool,
       // Update position in the history after executing an expression (action).
       updateHistoryPosition: PropTypes.func.isRequired,
       // Update autocomplete popup state.
       autocompleteUpdate: PropTypes.func.isRequired,
       // Data to be displayed in the autocomplete popup.
       autocompleteData: PropTypes.object.isRequired,
+      // Is the input in editor mode.
+      editorMode: PropTypes.bool,
     };
   }
 
   constructor(props) {
     super(props);
 
     const {
       webConsoleUI,
@@ -587,17 +589,21 @@ class JSTerm extends Component {
     if (!executeString) {
       return null;
     }
 
     // Append executed expression into the history list.
     this.props.appendToHistory(executeString);
 
     WebConsoleUtils.usageCount++;
-    this._setValue("");
+
+    if (!this.props.editorMode) {
+      this._setValue("");
+    }
+
     this.clearCompletion();
 
     let selectedNodeActor = null;
     const inspectorSelection = this.webConsoleUI.hud.getInspectorSelection();
     if (inspectorSelection && inspectorSelection.nodeFront) {
       selectedNodeActor = inspectorSelection.nodeFront.actorID;
     }
 
--- a/devtools/client/webconsole/constants.js
+++ b/devtools/client/webconsole/constants.js
@@ -60,16 +60,18 @@ const prefs = {
       NET: "filter.net",
       NETXHR: "filter.netxhr",
     },
     UI: {
       // Persist is only used by the webconsole.
       PERSIST: "devtools.webconsole.persistlog",
       // Max number of entries in history list.
       INPUT_HISTORY_COUNT: "devtools.webconsole.inputHistoryCount",
+      // Is editor mode enabled.
+      EDITOR: "devtools.webconsole.input.editor",
     },
     FEATURES: {
       // We use the same pref to enable the sidebar on webconsole and browser console.
       SIDEBAR_TOGGLE: "devtools.webconsole.sidebarToggle",
       JSTERM_CODE_MIRROR: "devtools.webconsole.jsterm.codeMirror",
     },
   },
 };
--- a/devtools/client/webconsole/reducers/ui.js
+++ b/devtools/client/webconsole/reducers/ui.js
@@ -26,16 +26,17 @@ const UiState = (overrides) => Object.fr
   networkMessageActiveTabId: PANELS.HEADERS,
   persistLogs: false,
   sidebarVisible: false,
   timestampsVisible: true,
   gripInSidebar: null,
   closeButtonVisible: false,
   reverseSearchInputVisible: false,
   reverseSearchInitialValue: "",
+  editor: false,
 }, overrides));
 
 function ui(state = UiState(), action) {
   switch (action.type) {
     case PERSIST_TOGGLE:
       return Object.assign({}, state, {persistLogs: !state.persistLogs});
     case TIMESTAMPS_TOGGLE:
       return Object.assign({}, state, {timestampsVisible: action.visible});
--- a/devtools/client/webconsole/store.js
+++ b/devtools/client/webconsole/store.js
@@ -66,16 +66,17 @@ function configureStore(webConsoleUI, op
       log: getBoolPref(PREFS.FILTER.LOG),
       css: getBoolPref(PREFS.FILTER.CSS),
       net: getBoolPref(PREFS.FILTER.NET),
       netxhr: getBoolPref(PREFS.FILTER.NETXHR),
     }),
     ui: UiState({
       networkMessageActiveTabId: "headers",
       persistLogs: getBoolPref(PREFS.UI.PERSIST),
+      editor: getBoolPref(PREFS.UI.EDITOR),
     }),
   };
 
   // Prepare middleware.
   const services = (options.services || {});
 
   const middleware = applyMiddleware(
     thunk.bind(null, {
--- a/devtools/client/webconsole/test/mochitest/browser.ini
+++ b/devtools/client/webconsole/test/mochitest/browser.ini
@@ -192,16 +192,17 @@ skip-if = verify
 [browser_jsterm_completion.js]
 [browser_jsterm_content_defined_helpers.js]
 [browser_jsterm_context_menu_labels.js]
 [browser_jsterm_copy_command.js]
 [browser_jsterm_ctrl_a_select_all.js]
 [browser_jsterm_ctrl_key_nav.js]
 skip-if = os != 'mac' # The tested ctrl+key shortcuts are OSX only
 [browser_jsterm_document_no_xray.js]
+[browser_jsterm_editor_execute.js]
 [browser_jsterm_error_docs.js]
 [browser_jsterm_error_outside_valid_range.js]
 [browser_jsterm_focus_reload.js]
 [browser_jsterm_helper_clear.js]
 [browser_jsterm_helper_dollar_dollar.js]
 [browser_jsterm_helper_dollar_x.js]
 [browser_jsterm_helper_dollar.js]
 [browser_jsterm_helper_help.js]
new file mode 100644
--- /dev/null
+++ b/devtools/client/webconsole/test/mochitest/browser_jsterm_editor_execute.js
@@ -0,0 +1,30 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+// Test that user input is not cleared when 'devtools.webconsole.input.editor'
+// is set to true.
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=1519313
+
+"use strict";
+
+const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 1519313";
+
+add_task(async function() {
+  await pushPref("devtools.webconsole.input.editor", true);
+  // Run test with legacy JsTerm
+  await pushPref("devtools.webconsole.jsterm.codeMirror", false);
+  await performTests();
+  // And then run it with the CodeMirror-powered one.
+  await pushPref("devtools.webconsole.jsterm.codeMirror", true);
+  await performTests();
+});
+
+async function performTests() {
+  const hud = await openNewTabAndConsole(TEST_URI);
+  const {jsterm} = hud;
+
+  const expression = `x = 10`;
+  setInputValue(hud, expression);
+  await jsterm.execute();
+  is(getInputValue(hud), expression, "input line is not cleared after submit");
+}