mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Backed out 5 changesets (bug 1024913) for causing perma damp failures. CLOSED TREE
Backed out changeset 1c18e0422ffa (bug 1024913) Backed out changeset c4e5a7ff8e53 (bug 1024913) Backed out changeset 7f269add6e54 (bug 1024913) Backed out changeset ccd6afc2a739 (bug 1024913) Backed out changeset 1613377c1b43 (bug 1024913)
This commit is contained in:
parent
1a38ec4710
commit
4133050728
@ -109,8 +109,6 @@ devtools.jar:
|
||||
skin/tooltips.css (themes/tooltips.css)
|
||||
skin/images/accessibility.svg (themes/images/accessibility.svg)
|
||||
skin/images/add.svg (themes/images/add.svg)
|
||||
skin/images/arrowhead-down.svg (themes/images/arrowhead-down.svg)
|
||||
skin/images/arrowhead-up.svg (themes/images/arrowhead-up.svg)
|
||||
skin/images/breadcrumbs-divider.svg (themes/images/breadcrumbs-divider.svg)
|
||||
skin/images/filters.svg (themes/images/filters.svg)
|
||||
skin/images/filter-swatch.svg (themes/images/filter-swatch.svg)
|
||||
|
@ -285,35 +285,3 @@ 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)
|
||||
|
@ -290,13 +290,6 @@ pref("devtools.webconsole.jsterm.codeMirror", true);
|
||||
pref("devtools.webconsole.jsterm.codeMirror", false);
|
||||
#endif
|
||||
|
||||
// Enable console input reverse-search in Nightly builds
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("devtools.webconsole.jsterm.reverse-search", true);
|
||||
#else
|
||||
pref("devtools.webconsole.jsterm.reverse-search", false);
|
||||
#endif
|
||||
|
||||
// Disable the new performance recording panel by default
|
||||
pref("devtools.performance.new-panel-enabled", false);
|
||||
|
||||
|
@ -1,6 +0,0 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="context-fill #0C0C0D" fill-rule="evenodd" clip-rule="evenodd" d="M4.293 8.293a1 1 0 0 1 1.414 0L12 14.586l6.293-6.293a1 1 0 1 1 1.414 1.414l-7 7a1 1 0 0 1-1.414 0l-7-7a1 1 0 0 1 0-1.414z"></path>
|
||||
</svg>
|
Before Width: | Height: | Size: 525 B |
@ -1,6 +0,0 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill="context-fill #0C0C0D" fill-rule="evenodd" clip-rule="evenodd" d="M12.707 7.293a1 1 0 0 0-1.414 0l-7 7a1 1 0 0 0 1.414 1.414L12 9.414l6.293 6.293a1 1 0 0 0 1.414-1.414l-7-7z"></path>
|
||||
</svg>
|
Before Width: | Height: | Size: 511 B |
@ -1,6 +1,6 @@
|
||||
<!-- 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/. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="context-fill #aaa">
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" fill="#aaa">
|
||||
<path d="M10.716 10.032C11.516 9.077 12 7.845 12 6.5 12 3.462 9.538 1 6.5 1S1 3.462 1 6.5 3.462 12 6.5 12c1.345 0 2.577-.483 3.532-1.284l4.143 4.142c.19.19.495.19.683 0 .19-.188.19-.494 0-.683l-4.142-4.143zM6.5 11C8.985 11 11 8.985 11 6.5S8.985 2 6.5 2 2 4.015 2 6.5 4.015 11 6.5 11z" fill-rule="evenodd"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 637 B After Width: | Height: | Size: 624 B |
@ -882,7 +882,6 @@ body {
|
||||
min-height: 28px;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.jsterm-cm .jsterm-input-container {
|
||||
@ -893,6 +892,11 @@ 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;
|
||||
|
@ -11,9 +11,6 @@ const {
|
||||
CLEAR_HISTORY,
|
||||
HISTORY_LOADED,
|
||||
UPDATE_HISTORY_POSITION,
|
||||
REVERSE_SEARCH_INPUT_CHANGE,
|
||||
REVERSE_SEARCH_BACK,
|
||||
REVERSE_SEARCH_NEXT,
|
||||
} = require("devtools/client/webconsole/constants");
|
||||
|
||||
/**
|
||||
@ -60,31 +57,9 @@ 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,
|
||||
};
|
||||
|
@ -14,15 +14,14 @@ const {
|
||||
INITIALIZE,
|
||||
PERSIST_TOGGLE,
|
||||
PREFS,
|
||||
REVERSE_SEARCH_INPUT_TOGGLE,
|
||||
SELECT_NETWORK_MESSAGE_TAB,
|
||||
SHOW_OBJECT_IN_SIDEBAR,
|
||||
SIDEBAR_CLOSE,
|
||||
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE,
|
||||
SHOW_OBJECT_IN_SIDEBAR,
|
||||
TIMESTAMPS_TOGGLE,
|
||||
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE,
|
||||
} = require("devtools/client/webconsole/constants");
|
||||
|
||||
function filterBarToggle() {
|
||||
function filterBarToggle(show) {
|
||||
return (dispatch, getState, {prefsService}) => {
|
||||
dispatch({
|
||||
type: FILTER_BAR_TOGGLE,
|
||||
@ -32,7 +31,7 @@ function filterBarToggle() {
|
||||
};
|
||||
}
|
||||
|
||||
function persistToggle() {
|
||||
function persistToggle(show) {
|
||||
return (dispatch, getState, {prefsService}) => {
|
||||
dispatch({
|
||||
type: PERSIST_TOGGLE,
|
||||
@ -103,21 +102,14 @@ function showObjectInSidebar(grip) {
|
||||
};
|
||||
}
|
||||
|
||||
function reverseSearchInputToggle() {
|
||||
return {
|
||||
type: REVERSE_SEARCH_INPUT_TOGGLE
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
filterBarToggle,
|
||||
initialize,
|
||||
persistToggle,
|
||||
reverseSearchInputToggle,
|
||||
selectNetworkMessageTab,
|
||||
sidebarClose,
|
||||
showMessageObjectInSidebar,
|
||||
showObjectInSidebar,
|
||||
sidebarClose,
|
||||
splitConsoleCloseButtonToggle,
|
||||
timestampsToggle,
|
||||
splitConsoleCloseButtonToggle,
|
||||
};
|
||||
|
@ -3,7 +3,6 @@
|
||||
* 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");
|
||||
@ -13,7 +12,6 @@ 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);
|
||||
|
||||
@ -29,8 +27,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.
|
||||
@ -46,87 +44,13 @@ class App extends Component {
|
||||
serviceContainer: PropTypes.object.isRequired,
|
||||
closeSplitConsole: PropTypes.func.isRequired,
|
||||
jstermCodeMirror: PropTypes.bool,
|
||||
jstermReverseSearch: PropTypes.bool,
|
||||
currentReverseSearchEntry: PropTypes.string,
|
||||
reverseSearchInputVisible: PropTypes.bool,
|
||||
};
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
// Do not focus if a link was clicked
|
||||
if (target.closest("a")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not focus if an input field was clicked
|
||||
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")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not focus if something is selected
|
||||
const selection = hud.document.defaultView.getSelection();
|
||||
if (selection && !selection.isCollapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (hud && hud.jsterm) {
|
||||
hud.jsterm.focus();
|
||||
}
|
||||
}
|
||||
|
||||
onPaste(event) {
|
||||
@ -199,7 +123,6 @@ class App extends Component {
|
||||
serviceContainer,
|
||||
closeSplitConsole,
|
||||
jstermCodeMirror,
|
||||
jstermReverseSearch,
|
||||
} = this.props;
|
||||
|
||||
const classNames = ["webconsole-output-wrapper"];
|
||||
@ -211,15 +134,12 @@ 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;
|
||||
}},
|
||||
@ -245,11 +165,6 @@ class App extends Component {
|
||||
onPaste: this.onPaste,
|
||||
codeMirrorEnabled: jstermCodeMirror,
|
||||
}),
|
||||
jstermReverseSearch
|
||||
? ReverseSearchInput({
|
||||
hud,
|
||||
})
|
||||
: null
|
||||
),
|
||||
SideBar({
|
||||
serviceContainer,
|
||||
@ -261,7 +176,6 @@ class App extends Component {
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
notifications: getAllNotifications(state),
|
||||
reverseSearchInputVisible: state.ui.reverseSearchInputVisible,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
|
@ -682,10 +682,7 @@ class JSTerm extends Component {
|
||||
* The new value to set.
|
||||
* @returns void
|
||||
*/
|
||||
setInputValue(newValue) {
|
||||
newValue = newValue || "";
|
||||
this.lastInputValue = newValue;
|
||||
|
||||
setInputValue(newValue = "") {
|
||||
if (this.props.codeMirrorEnabled) {
|
||||
if (this.editor) {
|
||||
// In order to get the autocomplete popup to work properly, we need to set the
|
||||
@ -713,7 +710,9 @@ class JSTerm extends Component {
|
||||
this.completeNode.value = "";
|
||||
}
|
||||
|
||||
this.lastInputValue = newValue;
|
||||
this.resizeInput();
|
||||
|
||||
this.emit("set-input-value");
|
||||
}
|
||||
|
||||
|
@ -1,84 +0,0 @@
|
||||
/* 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);
|
||||
}
|
@ -1,225 +0,0 @@
|
||||
/* 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);
|
@ -22,7 +22,5 @@ DevToolsModules(
|
||||
'MessageIcon.js',
|
||||
'MessageIndent.js',
|
||||
'MessageRepeat.js',
|
||||
'ReverseSearchInput.css',
|
||||
'ReverseSearchInput.js',
|
||||
'SideBar.js'
|
||||
)
|
||||
|
@ -6,16 +6,12 @@
|
||||
"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",
|
||||
@ -26,18 +22,18 @@ const actionTypes = {
|
||||
NETWORK_UPDATE_REQUEST: "NETWORK_UPDATE_REQUEST",
|
||||
PERSIST_TOGGLE: "PERSIST_TOGGLE",
|
||||
PRIVATE_MESSAGES_CLEAR: "PRIVATE_MESSAGES_CLEAR",
|
||||
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",
|
||||
SHOW_OBJECT_IN_SIDEBAR: "SHOW_OBJECT_IN_SIDEBAR",
|
||||
TIMESTAMPS_TOGGLE: "TIMESTAMPS_TOGGLE",
|
||||
APPEND_NOTIFICATION: "APPEND_NOTIFICATION",
|
||||
REMOVE_NOTIFICATION: "REMOVE_NOTIFICATION",
|
||||
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE: "SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE",
|
||||
APPEND_TO_HISTORY: "APPEND_TO_HISTORY",
|
||||
CLEAR_HISTORY: "CLEAR_HISTORY",
|
||||
HISTORY_LOADED: "HISTORY_LOADED",
|
||||
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 = {
|
||||
@ -67,7 +63,6 @@ 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",
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,6 @@
|
||||
<link rel="stylesheet" href="resource://devtools/client/shared/components/tabs/TabBar.css"/>
|
||||
<link rel="stylesheet" href="resource://devtools/client/shared/components/NotificationBox.css"/>
|
||||
<link rel="stylesheet" href="chrome://devtools/content/netmonitor/src/assets/styles/httpi.css"/>
|
||||
<link rel="stylesheet" href="resource://devtools/client/webconsole/components/ReverseSearchInput.css"/>
|
||||
|
||||
<script src="chrome://devtools/content/shared/theme-switching.js"></script>
|
||||
<script type="application/javascript"
|
||||
|
@ -12,10 +12,6 @@ const {
|
||||
UPDATE_HISTORY_POSITION,
|
||||
HISTORY_BACK,
|
||||
HISTORY_FORWARD,
|
||||
REVERSE_SEARCH_INPUT_TOGGLE,
|
||||
REVERSE_SEARCH_INPUT_CHANGE,
|
||||
REVERSE_SEARCH_BACK,
|
||||
REVERSE_SEARCH_NEXT,
|
||||
} = require("devtools/client/webconsole/constants");
|
||||
|
||||
/**
|
||||
@ -36,10 +32,6 @@ function getInitialState() {
|
||||
// pick up anything from the history and wants to return all
|
||||
// the way back to see the original input text.
|
||||
originalUserValue: null,
|
||||
|
||||
reverseSearchEnabled: false,
|
||||
currentReverseSearchResults: null,
|
||||
currentReverseSearchResultsPosition: null,
|
||||
};
|
||||
}
|
||||
|
||||
@ -53,14 +45,6 @@ function history(state = getInitialState(), action, prefsState) {
|
||||
return historyLoaded(state, action.entries);
|
||||
case UPDATE_HISTORY_POSITION:
|
||||
return updateHistoryPosition(state, action.direction, action.expression);
|
||||
case REVERSE_SEARCH_INPUT_TOGGLE:
|
||||
return reverseSearchInputToggle(state);
|
||||
case REVERSE_SEARCH_INPUT_CHANGE:
|
||||
return reverseSearchInputChange(state, action.value);
|
||||
case REVERSE_SEARCH_BACK:
|
||||
return reverseSearchBack(state);
|
||||
case REVERSE_SEARCH_NEXT:
|
||||
return reverseSearchNext(state);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
@ -143,66 +127,4 @@ function updateHistoryPosition(state, direction, expression) {
|
||||
return state;
|
||||
}
|
||||
|
||||
function reverseSearchInputToggle(state) {
|
||||
return {
|
||||
...state,
|
||||
reverseSearchEnabled: !state.reverseSearchEnabled,
|
||||
position: state.reverseSearchEnabled === true ? state.entries.length : undefined,
|
||||
currentReverseSearchResults: null,
|
||||
currentReverseSearchResultsPosition: null,
|
||||
};
|
||||
}
|
||||
|
||||
function reverseSearchInputChange(state, searchString) {
|
||||
if (searchString === "") {
|
||||
return {
|
||||
...state,
|
||||
position: undefined,
|
||||
currentReverseSearchResults: null,
|
||||
currentReverseSearchResultsPosition: null,
|
||||
};
|
||||
}
|
||||
|
||||
searchString = searchString.toLocaleLowerCase();
|
||||
const matchingEntries = state.entries.filter(entry =>
|
||||
entry.toLocaleLowerCase().includes(searchString));
|
||||
// We only return unique entries, but we want to keep the latest entry in the array if
|
||||
// it's duplicated (e.g. if we have [1,2,1], we want to get [2,1], not [1,2]).
|
||||
// To do that, we need to reverse the matching entries array, provide it to a Set,
|
||||
// transform it back to an array and reverse it again.
|
||||
const uniqueEntries = new Set(matchingEntries.reverse());
|
||||
const currentReverseSearchResults = Array.from(new Set(uniqueEntries)).reverse();
|
||||
|
||||
return {
|
||||
...state,
|
||||
position: undefined,
|
||||
currentReverseSearchResults,
|
||||
currentReverseSearchResultsPosition: currentReverseSearchResults.length - 1,
|
||||
};
|
||||
}
|
||||
|
||||
function reverseSearchBack(state) {
|
||||
let nextPosition = state.currentReverseSearchResultsPosition - 1;
|
||||
if (nextPosition < 0) {
|
||||
nextPosition = state.currentReverseSearchResults.length - 1;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
currentReverseSearchResultsPosition: nextPosition
|
||||
};
|
||||
}
|
||||
|
||||
function reverseSearchNext(state) {
|
||||
let previousPosition = state.currentReverseSearchResultsPosition + 1;
|
||||
if (previousPosition >= state.currentReverseSearchResults.length) {
|
||||
previousPosition = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
...state,
|
||||
currentReverseSearchResultsPosition: previousPosition
|
||||
};
|
||||
}
|
||||
|
||||
exports.history = history;
|
||||
|
@ -8,14 +8,13 @@
|
||||
const {
|
||||
FILTER_BAR_TOGGLE,
|
||||
INITIALIZE,
|
||||
MESSAGES_CLEAR,
|
||||
PERSIST_TOGGLE,
|
||||
REVERSE_SEARCH_INPUT_TOGGLE,
|
||||
SELECT_NETWORK_MESSAGE_TAB,
|
||||
SHOW_OBJECT_IN_SIDEBAR,
|
||||
SIDEBAR_CLOSE,
|
||||
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE,
|
||||
SHOW_OBJECT_IN_SIDEBAR,
|
||||
TIMESTAMPS_TOGGLE,
|
||||
MESSAGES_CLEAR,
|
||||
SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE,
|
||||
} = require("devtools/client/webconsole/constants");
|
||||
|
||||
const {
|
||||
@ -31,7 +30,6 @@ const UiState = (overrides) => Object.freeze(Object.assign({
|
||||
timestampsVisible: true,
|
||||
gripInSidebar: null,
|
||||
closeButtonVisible: false,
|
||||
reverseSearchInputVisible: false,
|
||||
}, overrides));
|
||||
|
||||
function ui(state = UiState(), action) {
|
||||
@ -60,8 +58,6 @@ function ui(state = UiState(), action) {
|
||||
return Object.assign({}, state, {sidebarVisible: true, gripInSidebar: action.grip});
|
||||
case SPLIT_CONSOLE_CLOSE_BUTTON_TOGGLE:
|
||||
return Object.assign({}, state, {closeButtonVisible: action.shouldDisplayButton});
|
||||
case REVERSE_SEARCH_INPUT_TOGGLE:
|
||||
return {...state, reverseSearchInputVisible: !state.reverseSearchInputVisible};
|
||||
}
|
||||
|
||||
return state;
|
||||
|
@ -46,44 +46,8 @@ function getPreviousHistoryValue(state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function getReverseSearchResult(state) {
|
||||
const { history } = state;
|
||||
const { currentReverseSearchResults, currentReverseSearchResultsPosition } = history;
|
||||
|
||||
if (!Array.isArray(currentReverseSearchResults)
|
||||
|| currentReverseSearchResults.length === 0
|
||||
|| !Number.isInteger(currentReverseSearchResultsPosition)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
return currentReverseSearchResults[currentReverseSearchResultsPosition];
|
||||
}
|
||||
|
||||
function getReverseSearchResultPosition(state) {
|
||||
const { history } = state;
|
||||
const { currentReverseSearchResultsPosition } = history;
|
||||
if (!Number.isInteger(currentReverseSearchResultsPosition)) {
|
||||
return currentReverseSearchResultsPosition;
|
||||
}
|
||||
|
||||
return currentReverseSearchResultsPosition + 1;
|
||||
}
|
||||
|
||||
function getReverseSearchTotalResults(state) {
|
||||
const { history } = state;
|
||||
const { currentReverseSearchResults } = history;
|
||||
if (!currentReverseSearchResults) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return currentReverseSearchResults.length;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getHistory,
|
||||
getHistoryEntries,
|
||||
getHistoryValue,
|
||||
getReverseSearchResult,
|
||||
getReverseSearchResultPosition,
|
||||
getReverseSearchTotalResults,
|
||||
};
|
||||
|
@ -49,7 +49,6 @@ function configureStore(hud, options = {}) {
|
||||
|| Math.max(getIntPref("devtools.hud.loglimit"), 1);
|
||||
const sidebarToggle = getBoolPref(PREFS.FEATURES.SIDEBAR_TOGGLE);
|
||||
const jstermCodeMirror = getBoolPref(PREFS.FEATURES.JSTERM_CODE_MIRROR);
|
||||
const jstermReverseSearch = getBoolPref(PREFS.FEATURES.JSTERM_REVERSE_SEARCH);
|
||||
const historyCount = getIntPref(PREFS.UI.INPUT_HISTORY_COUNT);
|
||||
|
||||
const initialState = {
|
||||
@ -57,7 +56,6 @@ function configureStore(hud, options = {}) {
|
||||
logLimit,
|
||||
sidebarToggle,
|
||||
jstermCodeMirror,
|
||||
jstermReverseSearch,
|
||||
historyCount,
|
||||
}),
|
||||
filters: FilterState({
|
||||
|
@ -343,10 +343,6 @@ subsuite = clipboard
|
||||
[browser_webconsole_persist.js]
|
||||
[browser_webconsole_reopen_closed_tab.js]
|
||||
[browser_webconsole_repeat_different_objects.js]
|
||||
[browser_webconsole_reverse_search.js]
|
||||
[browser_webconsole_reverse_search_keyboard_navigation.js]
|
||||
[browser_webconsole_reverse_search_mouse_navigation.js]
|
||||
[browser_webconsole_reverse_search_toggle.js]
|
||||
[browser_webconsole_sandbox_update_after_navigation.js]
|
||||
[browser_webconsole_script_errordoc_urls.js]
|
||||
[browser_webconsole_scroll.js]
|
||||
|
@ -1,117 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
// Tests reverse search features.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = `data:text/html,<meta charset=utf8>Test reverse search`;
|
||||
const isMacOS = AppConstants.platform === "macosx";
|
||||
|
||||
add_task(async function() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
const jstermHistory = [
|
||||
`document`,
|
||||
`Dog = "Snoopy"`,
|
||||
`document
|
||||
.querySelectorAll("*")
|
||||
.forEach(console.log)`,
|
||||
`document`,
|
||||
`"😎"`
|
||||
];
|
||||
|
||||
const onLastMessage = waitForMessage(hud, `"😎"`);
|
||||
for (const input of jstermHistory) {
|
||||
await hud.jsterm.execute(input);
|
||||
}
|
||||
await onLastMessage;
|
||||
|
||||
const jstermInitialValue = "initialValue";
|
||||
hud.jsterm.setInputValue(jstermInitialValue);
|
||||
|
||||
info("Check that the reverse search toolbar as the expected initial state");
|
||||
let reverseSearchElement = await openReverseSearch(hud);
|
||||
ok(reverseSearchElement, "Reverse search is displayed with a keyboard shortcut");
|
||||
ok(!getReverseSearchInfoElement(hud),
|
||||
"The result info element is not displayed by default");
|
||||
ok(
|
||||
!reverseSearchElement.querySelector(".search-result-button-prev") &&
|
||||
!reverseSearchElement.querySelector(".search-result-button-next"),
|
||||
"The results navigation buttons are not displayed by default"
|
||||
);
|
||||
is(hud.jsterm.getInputValue(), jstermInitialValue,
|
||||
"The jsterm value is not changed when opening reverse search");
|
||||
is(isReverseSearchInputFocused(hud), true, "reverse search input is focused");
|
||||
|
||||
EventUtils.sendString("d");
|
||||
let infoElement = await waitFor(() => getReverseSearchInfoElement(hud));
|
||||
is(infoElement.textContent, "3 of 3 results", "The reverse info has the expected text "
|
||||
+ "— duplicated results (`document`) are coalesced");
|
||||
|
||||
const previousButton = reverseSearchElement.querySelector(".search-result-button-prev");
|
||||
const nextButton = reverseSearchElement.querySelector(".search-result-button-next");
|
||||
ok(previousButton, "Previous navigation button is now displayed");
|
||||
is(previousButton.title, `Previous result (${isMacOS ? "Ctrl + R" : "F9"})`,
|
||||
"Previous navigation button has expected title");
|
||||
|
||||
ok(nextButton, "Next navigation button is now displayed");
|
||||
is(nextButton.title, `Next result (${isMacOS ? "Ctrl + S" : "Shift + F9"})`,
|
||||
"Next navigation button has expected title");
|
||||
is(hud.jsterm.getInputValue(), "document", "JsTerm has the expected input");
|
||||
is(hud.jsterm.autocompletePopup.isOpen, false,
|
||||
"Setting the input value did not trigger the autocompletion");
|
||||
is(isReverseSearchInputFocused(hud), true, "reverse search input is focused");
|
||||
|
||||
let onJsTermValueChanged = hud.jsterm.once("set-input-value");
|
||||
EventUtils.sendString("og");
|
||||
await onJsTermValueChanged;
|
||||
is(hud.jsterm.getInputValue(), `Dog = "Snoopy"`, "JsTerm input was updated");
|
||||
is(infoElement.textContent, "1 result", "The reverse info has the expected text");
|
||||
ok(
|
||||
!reverseSearchElement.querySelector(".search-result-button-prev") &&
|
||||
!reverseSearchElement.querySelector(".search-result-button-next"),
|
||||
"The results navigation buttons are not displayed when there's only one result"
|
||||
);
|
||||
|
||||
info("Check that the UI and results are updated when typing in the input");
|
||||
onJsTermValueChanged = hud.jsterm.once("set-input-value");
|
||||
EventUtils.sendString("g");
|
||||
await waitFor(() => reverseSearchElement.classList.contains("no-result"));
|
||||
is(hud.jsterm.getInputValue(), `Dog = "Snoopy"`,
|
||||
"JsTerm input was not updated since there's no results");
|
||||
is(infoElement.textContent, "No results", "The reverse info has the expected text");
|
||||
ok(
|
||||
!reverseSearchElement.querySelector(".search-result-button-prev") &&
|
||||
!reverseSearchElement.querySelector(".search-result-button-next"),
|
||||
"The results navigation buttons are not displayed when there's no result"
|
||||
);
|
||||
|
||||
info("Check that Backspace updates the UI");
|
||||
EventUtils.synthesizeKey("KEY_Backspace");
|
||||
await waitFor(() => !reverseSearchElement.classList.contains("no-result"));
|
||||
is(infoElement.textContent, "1 result", "The reverse info has the expected text");
|
||||
is(hud.jsterm.getInputValue(), `Dog = "Snoopy"`, "JsTerm kept its value");
|
||||
|
||||
info("Check that Escape does not affect the jsterm value");
|
||||
EventUtils.synthesizeKey("KEY_Escape");
|
||||
await waitFor(() => !getReverseSearchElement(hud));
|
||||
is(hud.jsterm.getInputValue(), `Dog = "Snoopy"`,
|
||||
"Closing the input did not changed the JsTerm value");
|
||||
is(isJstermFocused(hud.jsterm), true, "JsTerm is focused");
|
||||
|
||||
info("Check that the search works with emojis");
|
||||
reverseSearchElement = await openReverseSearch(hud);
|
||||
onJsTermValueChanged = hud.jsterm.once("set-input-value");
|
||||
EventUtils.sendString("😎");
|
||||
infoElement = await waitFor(() => getReverseSearchInfoElement(hud));
|
||||
is(infoElement.textContent, "1 result", "The reverse info has the expected text");
|
||||
|
||||
info("Check that Enter evaluates the JsTerm and closes the UI");
|
||||
const onMessage = waitForMessage(hud, `"😎"`);
|
||||
const onReverseSearchClose = waitFor(() => !getReverseSearchElement(hud));
|
||||
EventUtils.synthesizeKey("KEY_Enter");
|
||||
await Promise.all([onMessage, onReverseSearchClose]);
|
||||
ok(true, "Enter evaluates what's in the JsTerm and closes the reverse search UI");
|
||||
});
|
@ -1,122 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
// Tests reverse search results keyboard navigation.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = `data:text/html,<meta charset=utf8>Test reverse search`;
|
||||
const isMacOS = AppConstants.platform === "macosx";
|
||||
|
||||
add_task(async function() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
const jstermHistory = [
|
||||
`document`,
|
||||
`document
|
||||
.querySelectorAll("*")
|
||||
.forEach(console.log)`,
|
||||
`Dog = "Snoopy"`,
|
||||
];
|
||||
|
||||
const onLastMessage = waitForMessage(hud, `"Snoopy"`);
|
||||
for (const input of jstermHistory) {
|
||||
await hud.jsterm.execute(input);
|
||||
}
|
||||
await onLastMessage;
|
||||
|
||||
await openReverseSearch(hud);
|
||||
EventUtils.sendString("d");
|
||||
const infoElement = await waitFor(() => getReverseSearchInfoElement(hud));
|
||||
is(infoElement.textContent, "3 of 3 results", "The reverse info has the expected text");
|
||||
|
||||
is(hud.jsterm.getInputValue(), jstermHistory[2], "JsTerm has the expected input");
|
||||
is(hud.jsterm.autocompletePopup.isOpen, false,
|
||||
"Setting the input value did not trigger the autocompletion");
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "previous",
|
||||
expectedInfoText: "2 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[1]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "previous",
|
||||
expectedInfoText: "1 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[0]
|
||||
});
|
||||
|
||||
info("Check that we go back to the last matching item if we were at the first");
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "previous",
|
||||
expectedInfoText: "3 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[2]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "next",
|
||||
expectedInfoText: "1 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[0]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "next",
|
||||
expectedInfoText: "2 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[1]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "next",
|
||||
expectedInfoText: "3 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[2]
|
||||
});
|
||||
|
||||
info("Check that trying to navigate when there's only 1 result does not throw");
|
||||
EventUtils.sendString("og");
|
||||
await waitFor(() => getReverseSearchInfoElement(hud).textContent === "1 result");
|
||||
triggerPreviousResultShortcut();
|
||||
triggerNextResultShortcut();
|
||||
|
||||
info("Check that trying to navigate when there's no result does not throw");
|
||||
EventUtils.sendString("g");
|
||||
await waitFor(() => getReverseSearchInfoElement(hud).textContent === "No results");
|
||||
triggerPreviousResultShortcut();
|
||||
triggerNextResultShortcut();
|
||||
});
|
||||
|
||||
async function navigateResultsAndCheckState(hud, {
|
||||
direction,
|
||||
expectedInfoText,
|
||||
expectedJsTermInputValue,
|
||||
}) {
|
||||
const onJsTermValueChanged = hud.jsterm.once("set-input-value");
|
||||
if (direction === "previous") {
|
||||
triggerPreviousResultShortcut();
|
||||
} else {
|
||||
triggerNextResultShortcut();
|
||||
}
|
||||
await onJsTermValueChanged;
|
||||
|
||||
is(hud.jsterm.getInputValue(), expectedJsTermInputValue, "JsTerm has expected value");
|
||||
|
||||
const infoElement = getReverseSearchInfoElement(hud);
|
||||
is(infoElement.textContent, expectedInfoText, "The reverse info has the expected text");
|
||||
is(isReverseSearchInputFocused(hud), true, "reverse search input is still focused");
|
||||
}
|
||||
|
||||
function triggerPreviousResultShortcut() {
|
||||
if (isMacOS) {
|
||||
EventUtils.synthesizeKey("r", {ctrlKey: true});
|
||||
} else {
|
||||
EventUtils.synthesizeKey("VK_F9");
|
||||
}
|
||||
}
|
||||
|
||||
function triggerNextResultShortcut() {
|
||||
if (isMacOS) {
|
||||
EventUtils.synthesizeKey("s", {ctrlKey: true});
|
||||
} else {
|
||||
EventUtils.synthesizeKey("VK_F9", {shiftKey: true});
|
||||
}
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
// Tests reverse search results mouse navigation.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = `data:text/html,<meta charset=utf8>Test reverse search`;
|
||||
|
||||
add_task(async function() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
const jstermHistory = [
|
||||
`document`,
|
||||
`document
|
||||
.querySelectorAll("*")
|
||||
.forEach(console.log)`,
|
||||
`Dog = "Snoopy"`,
|
||||
];
|
||||
|
||||
const onLastMessage = waitForMessage(hud, `"Snoopy"`);
|
||||
for (const input of jstermHistory) {
|
||||
await hud.jsterm.execute(input);
|
||||
}
|
||||
await onLastMessage;
|
||||
|
||||
await openReverseSearch(hud);
|
||||
EventUtils.sendString("d");
|
||||
const infoElement = await waitFor(() => getReverseSearchInfoElement(hud));
|
||||
is(infoElement.textContent, "3 of 3 results", "The reverse info has the expected text");
|
||||
|
||||
is(hud.jsterm.getInputValue(), jstermHistory[2], "JsTerm has the expected input");
|
||||
is(hud.jsterm.autocompletePopup.isOpen, false,
|
||||
"Setting the input value did not trigger the autocompletion");
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "previous",
|
||||
expectedInfoText: "2 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[1]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "previous",
|
||||
expectedInfoText: "1 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[0]
|
||||
});
|
||||
|
||||
info("Check that we go back to the last matching item if we were at the first");
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "previous",
|
||||
expectedInfoText: "3 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[2]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "next",
|
||||
expectedInfoText: "1 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[0]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "next",
|
||||
expectedInfoText: "2 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[1]
|
||||
});
|
||||
|
||||
await navigateResultsAndCheckState(hud, {
|
||||
direction: "next",
|
||||
expectedInfoText: "3 of 3 results",
|
||||
expectedJsTermInputValue: jstermHistory[2]
|
||||
});
|
||||
});
|
||||
|
||||
async function navigateResultsAndCheckState(hud, {
|
||||
direction,
|
||||
expectedInfoText,
|
||||
expectedJsTermInputValue,
|
||||
}) {
|
||||
const onJsTermValueChanged = hud.jsterm.once("set-input-value");
|
||||
if (direction === "previous") {
|
||||
clickPreviousButton(hud);
|
||||
} else {
|
||||
clickNextButton(hud);
|
||||
}
|
||||
await onJsTermValueChanged;
|
||||
|
||||
is(hud.jsterm.getInputValue(), expectedJsTermInputValue, "JsTerm has expected value");
|
||||
|
||||
const infoElement = getReverseSearchInfoElement(hud);
|
||||
is(infoElement.textContent, expectedInfoText, "The reverse info has the expected text");
|
||||
is(isReverseSearchInputFocused(hud), true, "reverse search input is still focused");
|
||||
}
|
||||
|
||||
function clickPreviousButton(hud) {
|
||||
const reverseSearchElement = getReverseSearchElement(hud);
|
||||
if (!reverseSearchElement) {
|
||||
return;
|
||||
}
|
||||
const button = reverseSearchElement.querySelector(".search-result-button-prev");
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.click();
|
||||
}
|
||||
|
||||
function clickNextButton(hud) {
|
||||
const reverseSearchElement = getReverseSearchElement(hud);
|
||||
if (!reverseSearchElement) {
|
||||
return;
|
||||
}
|
||||
const button = reverseSearchElement.querySelector(".search-result-button-next");
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
|
||||
button.click();
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/* 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/. */
|
||||
|
||||
// Tests showing and hiding the reverse search UI.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = `data:text/html,<meta charset=utf8>Test reverse search toggle`;
|
||||
const isMacOS = AppConstants.platform === "macosx";
|
||||
|
||||
add_task(async function() {
|
||||
const hud = await openNewTabAndConsole(TEST_URI);
|
||||
|
||||
info("Close the reverse search UI with ESC");
|
||||
await openReverseSearch(hud);
|
||||
let onReverseSearchUiClose = waitFor(() => getReverseSearchElement(hud) === null);
|
||||
EventUtils.sendKey("ESCAPE");
|
||||
await onReverseSearchUiClose;
|
||||
ok(true, "Reverse search was closed with the Esc keyboard shortcut");
|
||||
|
||||
if (isMacOS) {
|
||||
info("Close the reverse search UI with Ctrl + C on OSX");
|
||||
await openReverseSearch(hud);
|
||||
onReverseSearchUiClose = waitFor(() => getReverseSearchElement(hud) === null);
|
||||
EventUtils.synthesizeKey("c", {ctrlKey: true});
|
||||
await onReverseSearchUiClose;
|
||||
ok(true, "Reverse search was closed with the Ctrl + C keyboard shortcut");
|
||||
}
|
||||
|
||||
info("Close the reverse search UI with the close button");
|
||||
const reverseSearchElement = await openReverseSearch(hud);
|
||||
const closeButton = reverseSearchElement.querySelector(".reverse-search-close-button");
|
||||
ok(closeButton, "The close button is displayed");
|
||||
is(closeButton.title, `Close (Esc${isMacOS ? " | Ctrl + C" : ""})`,
|
||||
"The close button has the expected tooltip");
|
||||
onReverseSearchUiClose = waitFor(() => getReverseSearchElement(hud) === null);
|
||||
closeButton.click();
|
||||
await onReverseSearchUiClose;
|
||||
ok(true, "Reverse search was closed by clicking on the close button");
|
||||
|
||||
info("Close the reverse search UI by clicking on the output");
|
||||
await openReverseSearch(hud);
|
||||
hud.ui.outputNode.querySelector(".jsterm-input-container").click();
|
||||
ok(true, "Reverse search was closed by clicking in the output");
|
||||
});
|
@ -66,6 +66,7 @@ registerCleanupFunction(async function() {
|
||||
async function openNewTabAndConsole(url, clearJstermHistory = true) {
|
||||
const toolbox = await openNewTabAndToolbox(url, "webconsole");
|
||||
const hud = toolbox.getCurrentPanel().hud;
|
||||
hud.jsterm._lazyVariablesView = false;
|
||||
|
||||
if (clearJstermHistory) {
|
||||
// Clearing history that might have been set in previous tests.
|
||||
@ -862,52 +863,3 @@ async function resetFilters(hud) {
|
||||
const store = hud.ui.consoleOutput.getStore();
|
||||
store.dispatch(wcActions.filtersClear());
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the reverse search input by simulating the appropriate keyboard shortcut.
|
||||
*
|
||||
* @param {Object} hud
|
||||
* @returns {DOMNode} The reverse search dom node.
|
||||
*/
|
||||
async function openReverseSearch(hud) {
|
||||
info("Open the reverse search UI with a keyboard shortcut");
|
||||
const onReverseSearchUiOpen = waitFor(() => getReverseSearchElement(hud));
|
||||
const isMacOS = AppConstants.platform === "macosx";
|
||||
if (isMacOS) {
|
||||
EventUtils.synthesizeKey("r", {ctrlKey: true});
|
||||
} else {
|
||||
EventUtils.synthesizeKey("VK_F9");
|
||||
}
|
||||
|
||||
const element = await onReverseSearchUiOpen;
|
||||
return element;
|
||||
}
|
||||
|
||||
function getReverseSearchElement(hud) {
|
||||
const {outputNode} = hud.ui;
|
||||
return outputNode.querySelector(".reverse-search");
|
||||
}
|
||||
|
||||
function getReverseSearchInfoElement(hud) {
|
||||
const reverseSearchElement = getReverseSearchElement(hud);
|
||||
if (!reverseSearchElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return reverseSearchElement.querySelector(".reverse-search-info");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating if the reverse search input is focused.
|
||||
*
|
||||
* @param {JsTerm} jsterm
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isReverseSearchInputFocused(hud) {
|
||||
const {outputNode} = hud.ui;
|
||||
const document = outputNode.ownerDocument;
|
||||
const documentIsFocused = document.hasFocus();
|
||||
const reverseSearchInput = outputNode.querySelector(".reverse-search-input");
|
||||
|
||||
return document.activeElement == reverseSearchInput && documentIsFocused;
|
||||
}
|
||||
|
@ -52,7 +52,43 @@ WebConsoleOutputWrapper.prototype = {
|
||||
const attachRefToHud = (id, node) => {
|
||||
this.hud[id] = node;
|
||||
};
|
||||
// Focus the input line whenever the output area is clicked.
|
||||
this.parentNode.addEventListener("click", (event) => {
|
||||
// Do not focus on middle/right-click or 2+ clicks.
|
||||
if (event.detail !== 1 || event.button !== 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not focus if a link was clicked
|
||||
const target = event.originalTarget || event.target;
|
||||
if (target.closest("a")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not focus if an input field was clicked
|
||||
if (target.closest("input")) {
|
||||
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")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not focus if something is selected
|
||||
const selection = this.document.defaultView.getSelection();
|
||||
if (selection && !selection.isCollapsed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.hud && this.hud.jsterm) {
|
||||
this.hud.jsterm.focus();
|
||||
}
|
||||
});
|
||||
|
||||
const { hud } = this;
|
||||
|
||||
const serviceContainer = {
|
||||
attachRefToHud,
|
||||
emitNewMessage: (node, messageId, timeStamp) => {
|
||||
@ -210,16 +246,14 @@ WebConsoleOutputWrapper.prototype = {
|
||||
});
|
||||
}
|
||||
|
||||
const {prefs} = store.getState();
|
||||
const app = App({
|
||||
attachRefToHud,
|
||||
serviceContainer,
|
||||
hud,
|
||||
onFirstMeaningfulPaint: resolve,
|
||||
closeSplitConsole: this.closeSplitConsole.bind(this),
|
||||
jstermCodeMirror: prefs.jstermCodeMirror
|
||||
jstermCodeMirror: store.getState().prefs.jstermCodeMirror
|
||||
&& !Services.appinfo.accessibilityEnabled,
|
||||
jstermReverseSearch: prefs.jstermReverseSearch,
|
||||
});
|
||||
|
||||
// Render the root Application component.
|
||||
|
Loading…
Reference in New Issue
Block a user