diff --git a/devtools/client/locales/en-US/webconsole.properties b/devtools/client/locales/en-US/webconsole.properties
index 675ac57b29dc..8690706f7f30 100644
--- a/devtools/client/locales/en-US/webconsole.properties
+++ b/devtools/client/locales/en-US/webconsole.properties
@@ -285,3 +285,35 @@ webconsole.closeSplitConsoleButton.tooltip=Close Split Console (Esc)
# LOCALIZATION NOTE (webconsole.closeSidebarButton.tooltip): This is the tooltip for
# the close button of the sidebar.
webconsole.closeSidebarButton.tooltip=Close Sidebar
+
+# LOCALIZATION NOTE (webconsole.reverseSearch.input.placeHolder):
+# This string is displayed in the placeholder of the reverse search input in the console.
+webconsole.reverseSearch.input.placeHolder=Search history
+
+# LOCALIZATION NOTE (webconsole.reverseSearch.result.closeButton.tooltip):
+# This string is displayed in the tooltip of the close button in the reverse search toolbar.
+# A keyboard shortcut will be shown inside the latter pair of brackets.
+webconsole.reverseSearch.closeButton.tooltip=Close (%S)
+
+# LOCALIZATION NOTE (webconsole.reverseSearch.results):
+# This string is displayed in the reverse search UI when there are at least one result
+# to the search.
+# This is a semi-colon list of plural forms.
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# #1 index of current search result displayed.
+# #2 total number of search results.
+webconsole.reverseSearch.results=1 result;#1 of #2 results
+
+# LOCALIZATION NOTE (webconsole.reverseSearch.noResult):
+# This string is displayed in the reverse search UI when there is no results to the search.
+webconsole.reverseSearch.noResult=No results
+
+# LOCALIZATION NOTE (webconsole.reverseSearch.result.previousButton.tooltip):
+# This string is displayed in the tooltip of the "previous result" button in the reverse search toolbar.
+# A keyboard shortcut will be shown inside the latter pair of brackets.
+webconsole.reverseSearch.result.previousButton.tooltip=Previous result (%S)
+
+# LOCALIZATION NOTE (webconsole.reverseSearch.result.nextButton.tooltip):
+# This string is displayed in the tooltip of the "next result" button in the reverse search toolbar.
+# A keyboard shortcut will be shown inside the latter pair of brackets.
+webconsole.reverseSearch.result.nextButton.tooltip=Next result (%S)
diff --git a/devtools/client/themes/webconsole.css b/devtools/client/themes/webconsole.css
index 0362df45f1ce..f474aff3c6e6 100644
--- a/devtools/client/themes/webconsole.css
+++ b/devtools/client/themes/webconsole.css
@@ -882,6 +882,7 @@ body {
min-height: 28px;
overflow-y: auto;
overflow-x: hidden;
+ flex-grow: 1;
}
.jsterm-cm .jsterm-input-container {
@@ -892,11 +893,6 @@ body {
border-top: none;
}
-/* Last item in the flex wrapper should take the whole remaining height */
-.webconsole-flex-wrapper > :last-child {
- flex-grow: 1;
-}
-
/* Object Inspector */
.webconsole-output-wrapper .object-inspector.tree {
display: inline-block;
diff --git a/devtools/client/webconsole/actions/history.js b/devtools/client/webconsole/actions/history.js
index b89b760d19b2..7fa023e7a64a 100644
--- a/devtools/client/webconsole/actions/history.js
+++ b/devtools/client/webconsole/actions/history.js
@@ -11,6 +11,9 @@ const {
CLEAR_HISTORY,
HISTORY_LOADED,
UPDATE_HISTORY_POSITION,
+ REVERSE_SEARCH_INPUT_CHANGE,
+ REVERSE_SEARCH_BACK,
+ REVERSE_SEARCH_NEXT,
} = require("devtools/client/webconsole/constants");
/**
@@ -57,9 +60,31 @@ function updateHistoryPosition(direction, expression) {
};
}
+function reverseSearchInputChange(value) {
+ return {
+ type: REVERSE_SEARCH_INPUT_CHANGE,
+ value,
+ };
+}
+
+function showReverseSearchNext() {
+ return {
+ type: REVERSE_SEARCH_NEXT,
+ };
+}
+
+function showReverseSearchBack() {
+ return {
+ type: REVERSE_SEARCH_BACK
+ };
+}
+
module.exports = {
appendToHistory,
clearHistory,
historyLoaded,
updateHistoryPosition,
+ reverseSearchInputChange,
+ showReverseSearchNext,
+ showReverseSearchBack,
};
diff --git a/devtools/client/webconsole/actions/ui.js b/devtools/client/webconsole/actions/ui.js
index 18a38631e7af..0d0f6f8b743b 100644
--- a/devtools/client/webconsole/actions/ui.js
+++ b/devtools/client/webconsole/actions/ui.js
@@ -14,14 +14,15 @@ const {
INITIALIZE,
PERSIST_TOGGLE,
PREFS,
+ REVERSE_SEARCH_INPUT_TOGGLE,
SELECT_NETWORK_MESSAGE_TAB,
- SIDEBAR_CLOSE,
SHOW_OBJECT_IN_SIDEBAR,
- TIMESTAMPS_TOGGLE,
+ SIDEBAR_CLOSE,
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE,
+ TIMESTAMPS_TOGGLE,
} = require("devtools/client/webconsole/constants");
-function filterBarToggle(show) {
+function filterBarToggle() {
return (dispatch, getState, {prefsService}) => {
dispatch({
type: FILTER_BAR_TOGGLE,
@@ -31,7 +32,7 @@ function filterBarToggle(show) {
};
}
-function persistToggle(show) {
+function persistToggle() {
return (dispatch, getState, {prefsService}) => {
dispatch({
type: PERSIST_TOGGLE,
@@ -102,14 +103,21 @@ function showObjectInSidebar(grip) {
};
}
+function reverseSearchInputToggle() {
+ return {
+ type: REVERSE_SEARCH_INPUT_TOGGLE
+ };
+}
+
module.exports = {
filterBarToggle,
initialize,
persistToggle,
+ reverseSearchInputToggle,
selectNetworkMessageTab,
- sidebarClose,
showMessageObjectInSidebar,
showObjectInSidebar,
- timestampsToggle,
+ sidebarClose,
splitConsoleCloseButtonToggle,
+ timestampsToggle,
};
diff --git a/devtools/client/webconsole/components/App.js b/devtools/client/webconsole/components/App.js
index 04a27bba5562..989365523d1f 100644
--- a/devtools/client/webconsole/components/App.js
+++ b/devtools/client/webconsole/components/App.js
@@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
+const Services = require("Services");
const { Component, createFactory } = require("devtools/client/shared/vendor/react");
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
const dom = require("devtools/client/shared/vendor/react-dom-factories");
@@ -12,6 +13,7 @@ const actions = require("devtools/client/webconsole/actions/index");
const ConsoleOutput = createFactory(require("devtools/client/webconsole/components/ConsoleOutput"));
const FilterBar = createFactory(require("devtools/client/webconsole/components/FilterBar"));
const SideBar = createFactory(require("devtools/client/webconsole/components/SideBar"));
+const ReverseSearchInput = createFactory(require("devtools/client/webconsole/components/ReverseSearchInput"));
const JSTerm = createFactory(require("devtools/client/webconsole/components/JSTerm"));
const NotificationBox = createFactory(require("devtools/client/shared/components/NotificationBox").NotificationBox);
@@ -27,8 +29,8 @@ const {
} = require("devtools/client/shared/components/NotificationBox");
const { getAllNotifications } = require("devtools/client/webconsole/selectors/notifications");
-
const { div } = dom;
+const isMacOS = Services.appinfo.OS === "Darwin";
/**
* Console root Application component.
@@ -44,6 +46,9 @@ class App extends Component {
serviceContainer: PropTypes.object.isRequired,
closeSplitConsole: PropTypes.func.isRequired,
jstermCodeMirror: PropTypes.bool,
+ jstermReverseSearch: PropTypes.bool,
+ currentReverseSearchEntry: PropTypes.string,
+ reverseSearchInputVisible: PropTypes.bool,
};
}
@@ -52,14 +57,41 @@ class App extends Component {
this.onClick = this.onClick.bind(this);
this.onPaste = this.onPaste.bind(this);
+ this.onKeyDown = this.onKeyDown.bind(this);
+ }
+
+ onKeyDown(event) {
+ const {
+ dispatch,
+ jstermReverseSearch,
+ } = this.props;
+
+ if (
+ jstermReverseSearch && (
+ (!isMacOS && event.key === "F9") ||
+ (isMacOS && event.key === "r" && event.ctrlKey === true)
+ )
+ ) {
+ dispatch(actions.reverseSearchInputToggle());
+ event.stopPropagation();
+ }
}
onClick(event) {
const target = event.originalTarget || event.target;
const {
+ reverseSearchInputVisible,
+ dispatch,
hud,
} = this.props;
+ if (reverseSearchInputVisible === true && !target.closest(".reverse-search")) {
+ event.preventDefault();
+ event.stopPropagation();
+ dispatch(actions.reverseSearchInputToggle());
+ return;
+ }
+
// Do not focus on middle/right-click or 2+ clicks.
if (event.detail !== 1 || event.button !== 0) {
return;
@@ -74,6 +106,12 @@ class App extends Component {
if (target.closest("input")) {
return;
}
+
+ // Do not focus if the click happened in the reverse search toolbar.
+ if (target.closest(".reverse-search")) {
+ return;
+ }
+
// Do not focus if something other than the output region was clicked
// (including e.g. the clear messages button in toolbar)
if (!target.closest(".webconsole-output-wrapper")) {
@@ -161,6 +199,7 @@ class App extends Component {
serviceContainer,
closeSplitConsole,
jstermCodeMirror,
+ jstermReverseSearch,
} = this.props;
const classNames = ["webconsole-output-wrapper"];
@@ -172,12 +211,14 @@ class App extends Component {
// from the following parts:
// * FilterBar - Buttons & free text for content filtering
// * Content - List of logs & messages
- // * SideBar - Object inspector
// * NotificationBox - Notifications for JSTerm (self-xss warning at the moment)
// * JSTerm - Input command line.
+ // * ReverseSearchInput - Reverse search input.
+ // * SideBar - Object inspector
return (
div({
className: classNames.join(" "),
+ onKeyDown: this.onKeyDown,
onClick: this.onClick,
ref: node => {
this.node = node;
@@ -204,6 +245,11 @@ class App extends Component {
onPaste: this.onPaste,
codeMirrorEnabled: jstermCodeMirror,
}),
+ jstermReverseSearch
+ ? ReverseSearchInput({
+ hud,
+ })
+ : null
),
SideBar({
serviceContainer,
@@ -215,6 +261,7 @@ class App extends Component {
const mapStateToProps = state => ({
notifications: getAllNotifications(state),
+ reverseSearchInputVisible: state.ui.reverseSearchInputVisible,
});
const mapDispatchToProps = dispatch => ({
diff --git a/devtools/client/webconsole/components/JSTerm.js b/devtools/client/webconsole/components/JSTerm.js
index ef636523ea3d..357fd9a581f4 100644
--- a/devtools/client/webconsole/components/JSTerm.js
+++ b/devtools/client/webconsole/components/JSTerm.js
@@ -682,7 +682,10 @@ class JSTerm extends Component {
* The new value to set.
* @returns void
*/
- setInputValue(newValue = "") {
+ setInputValue(newValue) {
+ newValue = newValue || "";
+ this.lastInputValue = newValue;
+
if (this.props.codeMirrorEnabled) {
if (this.editor) {
// In order to get the autocomplete popup to work properly, we need to set the
@@ -710,9 +713,7 @@ class JSTerm extends Component {
this.completeNode.value = "";
}
- this.lastInputValue = newValue;
this.resizeInput();
-
this.emit("set-input-value");
}
diff --git a/devtools/client/webconsole/components/ReverseSearchInput.css b/devtools/client/webconsole/components/ReverseSearchInput.css
new file mode 100644
index 000000000000..630dfa84b135
--- /dev/null
+++ b/devtools/client/webconsole/components/ReverseSearchInput.css
@@ -0,0 +1,84 @@
+/* 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/. */
+
+.reverse-search {
+ display: flex;
+ font-size: inherit;
+ min-height: 26px;
+ color: var(--theme-body-color);
+ padding-block-start: 2px;
+ align-items: baseline;
+ border: 1px solid transparent;
+ transition: border-color 0.2s ease-in-out;
+}
+
+.reverse-search:focus-within {
+ border-color: var(--blue-50);
+}
+
+.reverse-search {
+ flex-shrink: 0;
+}
+
+.reverse-search input {
+ border: none;
+ flex-grow: 1;
+ padding-inline-start: var(--console-inline-start-gutter);
+ background: transparent;
+ color: currentColor;
+ background-image: var(--magnifying-glass-image);
+ background-repeat: no-repeat;
+ background-size: 12px 12px;
+ background-position: 10px 2px;
+ -moz-context-properties: fill;
+}
+
+.reverse-search input:focus {
+ border: none;
+ outline: none;
+}
+
+.reverse-search:not(.no-result) input:focus {
+ fill: var(--console-input-icon-focused);
+}
+
+.reverse-search-info {
+ flex-shrink: 0;
+ padding: 0 8px;
+ color: var(--comment-node-color);
+}
+
+.search-result-button-prev,
+.search-result-button-next,
+.reverse-search-close-button {
+ padding: 4px 0;
+ margin: 0;
+ border-radius: 0;
+}
+
+.search-result-button-prev::before {
+ background-image: url("chrome://devtools/skin/images/arrowhead-up.svg");
+ background-size: 16px;
+ fill: var(--comment-node-color);
+}
+
+.search-result-button-next::before {
+ background-image: url("chrome://devtools/skin/images/arrowhead-down.svg");
+ background-size: 16px;
+ fill: var(--comment-node-color);
+}
+
+.reverse-search-close-button::before {
+ fill: var(--comment-node-color);
+ background-image: var(--close-button-image);
+}
+
+.reverse-search.no-result input {
+ fill: var(--error-color);
+}
+
+.reverse-search.no-result,
+.reverse-search.no-result input {
+ color: var(--error-color);
+}
diff --git a/devtools/client/webconsole/components/ReverseSearchInput.js b/devtools/client/webconsole/components/ReverseSearchInput.js
new file mode 100644
index 000000000000..1d6c198868ed
--- /dev/null
+++ b/devtools/client/webconsole/components/ReverseSearchInput.js
@@ -0,0 +1,225 @@
+/* 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";
+
+// React & Redux
+const { Component } = require("devtools/client/shared/vendor/react");
+const dom = require("devtools/client/shared/vendor/react-dom-factories");
+const { connect } = require("devtools/client/shared/vendor/react-redux");
+const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
+
+const { l10n } = require("devtools/client/webconsole/utils/messages");
+const { PluralForm } = require("devtools/shared/plural-form");
+const { KeyCodes } = require("devtools/client/shared/keycodes");
+
+const actions = require("devtools/client/webconsole/actions/index");
+const {
+ getReverseSearchTotalResults,
+ getReverseSearchResultPosition,
+ getReverseSearchResult,
+} = require("devtools/client/webconsole/selectors/history");
+
+const Services = require("Services");
+const isMacOS = Services.appinfo.OS === "Darwin";
+
+class ReverseSearchInput extends Component {
+ static get propTypes() {
+ return {
+ dispatch: PropTypes.func.isRequired,
+ hud: PropTypes.object.isRequired,
+ reverseSearchResult: PropTypes.string,
+ reverseSearchTotalResults: PropTypes.Array,
+ reverseSearchResultPosition: PropTypes.int,
+ visible: PropTypes.bool,
+ };
+ }
+
+ constructor(props) {
+ super(props);
+
+ this.onInputKeyDown = this.onInputKeyDown.bind(this);
+ }
+
+ componentDidUpdate(prevProps) {
+ const {jsterm} = this.props.hud;
+ if (
+ prevProps.reverseSearchResult !== this.props.reverseSearchResult
+ && this.props.visible
+ && this.props.reverseSearchTotalResults > 0
+ ) {
+ jsterm.setInputValue(this.props.reverseSearchResult);
+ }
+
+ if (prevProps.visible === true && this.props.visible === false) {
+ jsterm.focus();
+ }
+ }
+
+ onInputKeyDown(event) {
+ const {
+ keyCode,
+ key,
+ ctrlKey,
+ shiftKey,
+ } = event;
+
+ const {
+ dispatch,
+ hud,
+ reverseSearchTotalResults,
+ } = this.props;
+
+ // On Enter, we trigger an execute.
+ if (keyCode === KeyCodes.DOM_VK_RETURN) {
+ event.stopPropagation();
+ dispatch(actions.reverseSearchInputToggle());
+ hud.jsterm.execute();
+ return;
+ }
+
+ // On Escape (and Ctrl + c on OSX), we close the reverse search input.
+ if (
+ keyCode === KeyCodes.DOM_VK_ESCAPE || (
+ isMacOS && ctrlKey === true && key.toLowerCase() === "c"
+ )
+ ) {
+ event.stopPropagation();
+ dispatch(actions.reverseSearchInputToggle());
+ return;
+ }
+
+ const canNavigate = Number.isInteger(reverseSearchTotalResults)
+ && reverseSearchTotalResults > 1;
+
+ if (
+ (!isMacOS && key === "F9" && shiftKey === false) ||
+ (isMacOS && ctrlKey === true && key.toLowerCase() === "r")
+ ) {
+ event.stopPropagation();
+ event.preventDefault();
+ if (canNavigate) {
+ dispatch(actions.showReverseSearchBack());
+ }
+ return;
+ }
+
+ if (
+ (!isMacOS && key === "F9" && shiftKey === true) ||
+ (isMacOS && ctrlKey === true && key.toLowerCase() === "s")
+ ) {
+ event.stopPropagation();
+ event.preventDefault();
+ if (canNavigate) {
+ dispatch(actions.showReverseSearchNext());
+ }
+ }
+ }
+
+ renderSearchInformation() {
+ const {
+ reverseSearchTotalResults,
+ reverseSearchResultPosition,
+ } = this.props;
+
+ if (!Number.isInteger(reverseSearchTotalResults)) {
+ return null;
+ }
+
+ let text;
+ if (reverseSearchTotalResults === 0) {
+ text = l10n.getStr("webconsole.reverseSearch.noResult");
+ } else {
+ const resultsString = l10n.getStr("webconsole.reverseSearch.results");
+ text = PluralForm.get(reverseSearchTotalResults, resultsString)
+ .replace("#1", reverseSearchResultPosition)
+ .replace("#2", reverseSearchTotalResults);
+ }
+
+ return dom.div({className: "reverse-search-info"}, text);
+ }
+
+ renderNavigationButtons() {
+ const {
+ dispatch,
+ reverseSearchTotalResults,
+ } = this.props;
+
+ if (!Number.isInteger(reverseSearchTotalResults) || reverseSearchTotalResults <= 1) {
+ return null;
+ }
+
+ return [
+ dom.button({
+ className: "devtools-button search-result-button-prev",
+ title: l10n.getFormatStr("webconsole.reverseSearch.result.previousButton.tooltip",
+ [isMacOS ? "Ctrl + R" : "F9"]),
+ onClick: () => {
+ dispatch(actions.showReverseSearchBack());
+ this.inputNode.focus();
+ }
+ }),
+ dom.button({
+ className: "devtools-button search-result-button-next",
+ title: l10n.getFormatStr("webconsole.reverseSearch.result.nextButton.tooltip",
+ [isMacOS ? "Ctrl + S" : "Shift + F9"]),
+ onClick: () => {
+ dispatch(actions.showReverseSearchNext());
+ this.inputNode.focus();
+ }
+ })
+ ];
+ }
+
+ render() {
+ const {
+ dispatch,
+ visible,
+ reverseSearchTotalResults,
+ } = this.props;
+
+ if (!visible) {
+ return null;
+ }
+
+ const classNames = ["reverse-search"];
+ if (reverseSearchTotalResults === 0) {
+ classNames.push("no-result");
+ }
+
+ return dom.div({className: classNames.join(" ")},
+ dom.input({
+ ref: node => {
+ this.inputNode = node;
+ },
+ autoFocus: true,
+ placeHolder: l10n.getStr("webconsole.reverseSearch.input.placeHolder"),
+ className: "reverse-search-input devtools-monospace",
+ onKeyDown: this.onInputKeyDown,
+ onInput: ({target}) => dispatch(actions.reverseSearchInputChange(target.value))
+ }),
+ this.renderSearchInformation(),
+ this.renderNavigationButtons(),
+ dom.button({
+ className: "devtools-button reverse-search-close-button",
+ title: l10n.getFormatStr("webconsole.reverseSearch.closeButton.tooltip",
+ ["Esc" + (isMacOS ? " | Ctrl + C" : "")]),
+ onClick: () => {
+ dispatch(actions.reverseSearchInputToggle());
+ }
+ })
+ );
+ }
+}
+
+const mapStateToProps = state => ({
+ visible: state.ui.reverseSearchInputVisible,
+ reverseSearchTotalResults: getReverseSearchTotalResults(state),
+ reverseSearchResultPosition: getReverseSearchResultPosition(state),
+ reverseSearchResult: getReverseSearchResult(state),
+});
+
+const mapDispatchToProps = dispatch => ({dispatch});
+
+module.exports = connect(mapStateToProps, mapDispatchToProps)(ReverseSearchInput);
diff --git a/devtools/client/webconsole/components/moz.build b/devtools/client/webconsole/components/moz.build
index 31b12c04c895..06794fe469e9 100644
--- a/devtools/client/webconsole/components/moz.build
+++ b/devtools/client/webconsole/components/moz.build
@@ -22,5 +22,7 @@ DevToolsModules(
'MessageIcon.js',
'MessageIndent.js',
'MessageRepeat.js',
+ 'ReverseSearchInput.css',
+ 'ReverseSearchInput.js',
'SideBar.js'
)
diff --git a/devtools/client/webconsole/constants.js b/devtools/client/webconsole/constants.js
index bbd678da661c..909fde07aa49 100644
--- a/devtools/client/webconsole/constants.js
+++ b/devtools/client/webconsole/constants.js
@@ -6,12 +6,16 @@
"use strict";
const actionTypes = {
+ APPEND_NOTIFICATION: "APPEND_NOTIFICATION",
+ APPEND_TO_HISTORY: "APPEND_TO_HISTORY",
BATCH_ACTIONS: "BATCH_ACTIONS",
+ CLEAR_HISTORY: "CLEAR_HISTORY",
DEFAULT_FILTERS_RESET: "DEFAULT_FILTERS_RESET",
FILTER_BAR_TOGGLE: "FILTER_BAR_TOGGLE",
FILTER_TEXT_SET: "FILTER_TEXT_SET",
FILTER_TOGGLE: "FILTER_TOGGLE",
FILTERS_CLEAR: "FILTERS_CLEAR",
+ HISTORY_LOADED: "HISTORY_LOADED",
INITIALIZE: "INITIALIZE",
MESSAGE_CLOSE: "MESSAGE_CLOSE",
MESSAGE_OPEN: "MESSAGE_OPEN",
@@ -22,18 +26,18 @@ const actionTypes = {
NETWORK_UPDATE_REQUEST: "NETWORK_UPDATE_REQUEST",
PERSIST_TOGGLE: "PERSIST_TOGGLE",
PRIVATE_MESSAGES_CLEAR: "PRIVATE_MESSAGES_CLEAR",
- REMOVED_ACTORS_CLEAR: "REMOVED_ACTORS_CLEAR",
- SELECT_NETWORK_MESSAGE_TAB: "SELECT_NETWORK_MESSAGE_TAB",
- SIDEBAR_CLOSE: "SIDEBAR_CLOSE",
- SHOW_OBJECT_IN_SIDEBAR: "SHOW_OBJECT_IN_SIDEBAR",
- TIMESTAMPS_TOGGLE: "TIMESTAMPS_TOGGLE",
- APPEND_NOTIFICATION: "APPEND_NOTIFICATION",
REMOVE_NOTIFICATION: "REMOVE_NOTIFICATION",
+ REMOVED_ACTORS_CLEAR: "REMOVED_ACTORS_CLEAR",
+ REVERSE_SEARCH_INPUT_TOGGLE: "REVERSE_SEARCH_INPUT_TOGGLE",
+ SELECT_NETWORK_MESSAGE_TAB: "SELECT_NETWORK_MESSAGE_TAB",
+ SHOW_OBJECT_IN_SIDEBAR: "SHOW_OBJECT_IN_SIDEBAR",
+ SIDEBAR_CLOSE: "SIDEBAR_CLOSE",
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE: "SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE",
- APPEND_TO_HISTORY: "APPEND_TO_HISTORY",
- CLEAR_HISTORY: "CLEAR_HISTORY",
- HISTORY_LOADED: "HISTORY_LOADED",
+ TIMESTAMPS_TOGGLE: "TIMESTAMPS_TOGGLE",
UPDATE_HISTORY_POSITION: "UPDATE_HISTORY_POSITION",
+ REVERSE_SEARCH_INPUT_CHANGE: "REVERSE_SEARCH_INPUT_CHANGE",
+ REVERSE_SEARCH_NEXT: "REVERSE_SEARCH_NEXT",
+ REVERSE_SEARCH_BACK: "REVERSE_SEARCH_BACK",
};
const prefs = {
@@ -63,6 +67,7 @@ const prefs = {
// 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",
+ JSTERM_REVERSE_SEARCH: "devtools.webconsole.jsterm.reverse-search",
}
}
};
diff --git a/devtools/client/webconsole/index.html b/devtools/client/webconsole/index.html
index dfa1af4bc246..ddc783d2aaea 100644
--- a/devtools/client/webconsole/index.html
+++ b/devtools/client/webconsole/index.html
@@ -19,6 +19,7 @@
+