Bug 1811000 - [devtools] Move the project search to the side panel r=devtools-reviewers,nchevobbe,perftest-reviewers,sparky

Differential Revision: https://phabricator.services.mozilla.com/D172985
This commit is contained in:
Hubert Boma Manilla 2023-03-29 18:43:01 +00:00
Родитель b547ac4898
Коммит 048b95a8df
26 изменённых файлов: 201 добавлений и 232 удалений

Просмотреть файл

@ -11,7 +11,7 @@ import { isOriginalId } from "devtools/client/shared/source-map-loader/index";
import { setSymbols } from "./symbols"; import { setSymbols } from "./symbols";
import { setInScopeLines } from "../ast"; import { setInScopeLines } from "../ast";
import { closeActiveSearch, updateActiveFileSearch } from "../ui"; import { updateActiveFileSearch } from "../ui";
import { togglePrettyPrint } from "./prettyPrint"; import { togglePrettyPrint } from "./prettyPrint";
import { addTab, closeTab } from "../tabs"; import { addTab, closeTab } from "../tabs";
import { loadSourceText } from "./loadSourceText"; import { loadSourceText } from "./loadSourceText";
@ -28,7 +28,6 @@ import {
getFirstSourceActorForGeneratedSource, getFirstSourceActorForGeneratedSource,
getSourceByURL, getSourceByURL,
getPrettySource, getPrettySource,
getActiveSearch,
getSelectedLocation, getSelectedLocation,
getSelectedSource, getSelectedSource,
canPrettyPrintSource, canPrettyPrintSource,
@ -138,11 +137,6 @@ export function selectLocation(cx, location, { keepContext = true } = {}) {
return; return;
} }
const activeSearch = getActiveSearch(getState());
if (activeSearch && activeSearch !== "file") {
dispatch(closeActiveSearch());
}
// Preserve the current source map context (original / generated) // Preserve the current source map context (original / generated)
// when navigating to a new location. // when navigating to a new location.
// i.e. if keepContext isn't manually overriden to false, // i.e. if keepContext isn't manually overriden to false,

Просмотреть файл

@ -8,6 +8,7 @@ import classnames from "classnames";
import { connect } from "../utils/connect"; import { connect } from "../utils/connect";
import { prefs, features } from "../utils/prefs"; import { prefs, features } from "../utils/prefs";
import { primaryPaneTabs } from "../constants";
import actions from "../actions"; import actions from "../actions";
import A11yIntention from "./A11yIntention"; import A11yIntention from "./A11yIntention";
import { ShortcutsModal } from "./ShortcutsModal"; import { ShortcutsModal } from "./ShortcutsModal";
@ -40,7 +41,6 @@ import "./App.css";
import "./shared/menu.css"; import "./shared/menu.css";
import ProjectSearch from "./ProjectSearch";
import PrimaryPanes from "./PrimaryPanes"; import PrimaryPanes from "./PrimaryPanes";
import Editor from "./Editor"; import Editor from "./Editor";
import SecondaryPanes from "./SecondaryPanes"; import SecondaryPanes from "./SecondaryPanes";
@ -63,7 +63,6 @@ class App extends Component {
return { return {
activeSearch: PropTypes.oneOf(["file", "project"]), activeSearch: PropTypes.oneOf(["file", "project"]),
closeActiveSearch: PropTypes.func.isRequired, closeActiveSearch: PropTypes.func.isRequired,
closeProjectSearch: PropTypes.func.isRequired,
closeQuickOpen: PropTypes.func.isRequired, closeQuickOpen: PropTypes.func.isRequired,
endPanelCollapsed: PropTypes.bool.isRequired, endPanelCollapsed: PropTypes.bool.isRequired,
fluentBundles: PropTypes.array.isRequired, fluentBundles: PropTypes.array.isRequired,
@ -73,6 +72,7 @@ class App extends Component {
selectedSource: PropTypes.object, selectedSource: PropTypes.object,
setActiveSearch: PropTypes.func.isRequired, setActiveSearch: PropTypes.func.isRequired,
setOrientation: PropTypes.func.isRequired, setOrientation: PropTypes.func.isRequired,
setPrimaryPaneTab: PropTypes.func.isRequired,
startPanelCollapsed: PropTypes.bool.isRequired, startPanelCollapsed: PropTypes.bool.isRequired,
toolboxDoc: PropTypes.object.isRequired, toolboxDoc: PropTypes.object.isRequired,
}; };
@ -96,16 +96,20 @@ class App extends Component {
this.toggleQuickOpenModal(e, "@") this.toggleQuickOpenModal(e, "@")
); );
const searchKeys = [ [
L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.key2"),
L10N.getStr("sources.search.alt.key"), L10N.getStr("sources.search.alt.key"),
]; ].forEach(key => shortcuts.on(key, this.toggleQuickOpenModal));
searchKeys.forEach(key => shortcuts.on(key, this.toggleQuickOpenModal));
shortcuts.on(L10N.getStr("gotoLineModal.key3"), e => shortcuts.on(L10N.getStr("gotoLineModal.key3"), e =>
this.toggleQuickOpenModal(e, ":") this.toggleQuickOpenModal(e, ":")
); );
shortcuts.on(
L10N.getStr("projectTextSearch.key"),
this.jumpToProjectSearch
);
shortcuts.on("Escape", this.onEscape); shortcuts.on("Escape", this.onEscape);
shortcuts.on("CmdOrCtrl+/", this.onCommandSlash); shortcuts.on("CmdOrCtrl+/", this.onCommandSlash);
} }
@ -118,18 +122,28 @@ class App extends Component {
this.toggleQuickOpenModal this.toggleQuickOpenModal
); );
const searchKeys = [ [
L10N.getStr("sources.search.key2"), L10N.getStr("sources.search.key2"),
L10N.getStr("sources.search.alt.key"), L10N.getStr("sources.search.alt.key"),
]; ].forEach(key => shortcuts.off(key, this.toggleQuickOpenModal));
searchKeys.forEach(key => shortcuts.off(key, this.toggleQuickOpenModal));
shortcuts.off(L10N.getStr("gotoLineModal.key3"), this.toggleQuickOpenModal); shortcuts.off(L10N.getStr("gotoLineModal.key3"), this.toggleQuickOpenModal);
shortcuts.off(
L10N.getStr("projectTextSearch.key"),
this.jumpToProjectSearch
);
shortcuts.off("Escape", this.onEscape); shortcuts.off("Escape", this.onEscape);
shortcuts.off("CmdOrCtrl+/", this.onCommandSlash); shortcuts.off("CmdOrCtrl+/", this.onCommandSlash);
} }
jumpToProjectSearch = e => {
e.preventDefault();
this.props.setPrimaryPaneTab(primaryPaneTabs.PROJECT_SEARCH);
this.props.setActiveSearch(primaryPaneTabs.PROJECT_SEARCH);
};
onEscape = e => { onEscape = e => {
const { const {
activeSearch, activeSearch,
@ -217,7 +231,6 @@ class App extends Component {
/> />
) : null} ) : null}
<EditorFooter horizontal={horizontal} /> <EditorFooter horizontal={horizontal} />
<ProjectSearch />
</div> </div>
</div> </div>
); );
@ -335,8 +348,8 @@ const mapStateToProps = state => ({
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
setActiveSearch: actions.setActiveSearch, setActiveSearch: actions.setActiveSearch,
closeActiveSearch: actions.closeActiveSearch, closeActiveSearch: actions.closeActiveSearch,
closeProjectSearch: actions.closeProjectSearch,
openQuickOpen: actions.openQuickOpen, openQuickOpen: actions.openQuickOpen,
closeQuickOpen: actions.closeQuickOpen, closeQuickOpen: actions.closeQuickOpen,
setOrientation: actions.setOrientation, setOrientation: actions.setOrientation,
setPrimaryPaneTab: actions.setPrimaryPaneTab,
})(App); })(App);

Просмотреть файл

@ -54,6 +54,7 @@ class Tab extends PureComponent {
tabSources: PropTypes.array.isRequired, tabSources: PropTypes.array.isRequired,
toggleBlackBox: PropTypes.func.isRequired, toggleBlackBox: PropTypes.func.isRequired,
togglePrettyPrint: PropTypes.func.isRequired, togglePrettyPrint: PropTypes.func.isRequired,
isBlackBoxed: PropTypes.bool.isRequired,
}; };
} }
@ -167,10 +168,6 @@ class Tab extends PureComponent {
showMenu(e, buildMenu(items)); showMenu(e, buildMenu(items));
} }
isProjectSearchEnabled() {
return this.props.activeSearch === "project";
}
isSourceSearchEnabled() { isSourceSearchEnabled() {
return this.props.activeSearch === "source"; return this.props.activeSearch === "source";
} }
@ -192,7 +189,6 @@ class Tab extends PureComponent {
const active = const active =
selectedLocation && selectedLocation &&
sourceId == selectedLocation.sourceId && sourceId == selectedLocation.sourceId &&
!this.isProjectSearchEnabled() &&
!this.isSourceSearchEnabled(); !this.isSourceSearchEnabled();
const isPrettyCode = isPretty(source); const isPrettyCode = isPretty(source);

Просмотреть файл

@ -11,7 +11,6 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
z-index: 20; z-index: 20;
background-color: var(--theme-body-background);
overflow-y: hidden; overflow-y: hidden;
/* Using the same colors as the Netmonitor's --table-selection-background-hover */ /* Using the same colors as the Netmonitor's --table-selection-background-hover */

Просмотреть файл

@ -4,27 +4,26 @@
import React, { Component } from "react"; import React, { Component } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { connect } from "../utils/connect"; import { connect } from "../../utils/connect";
import classnames from "classnames"; import classnames from "classnames";
import actions from "../actions"; import actions from "../../actions";
import { getEditor } from "../utils/editor"; import { getEditor } from "../../utils/editor";
import { searchKeys } from "../constants"; import { searchKeys } from "../../constants";
import { statusType } from "../reducers/project-text-search"; import { statusType } from "../../reducers/project-text-search";
import { getRelativePath } from "../utils/sources-tree/utils"; import { getRelativePath } from "../../utils/sources-tree/utils";
import { getFormattedSourceId } from "../utils/source"; import { getFormattedSourceId } from "../../utils/source";
import { import {
getActiveSearch,
getProjectSearchResults, getProjectSearchResults,
getProjectSearchStatus, getProjectSearchStatus,
getProjectSearchQuery, getProjectSearchQuery,
getContext, getContext,
} from "../selectors"; } from "../../selectors";
import ManagedTree from "./shared/ManagedTree"; import ManagedTree from "../shared/ManagedTree";
import SearchInput from "./shared/SearchInput"; import SearchInput from "../shared/SearchInput";
import AccessibleImage from "./shared/AccessibleImage"; import AccessibleImage from "../shared/AccessibleImage";
const { PluralForm } = require("devtools/shared/plural-form"); const { PluralForm } = require("devtools/shared/plural-form");
@ -50,9 +49,7 @@ export class ProjectSearch extends Component {
static get propTypes() { static get propTypes() {
return { return {
activeSearch: PropTypes.string,
clearSearch: PropTypes.func.isRequired, clearSearch: PropTypes.func.isRequired,
closeProjectSearch: PropTypes.func.isRequired,
cx: PropTypes.object.isRequired, cx: PropTypes.object.isRequired,
doSearchForHighlight: PropTypes.func.isRequired, doSearchForHighlight: PropTypes.func.isRequired,
query: PropTypes.string.isRequired, query: PropTypes.string.isRequired,
@ -74,20 +71,11 @@ export class ProjectSearch extends Component {
componentDidMount() { componentDidMount() {
const { shortcuts } = this.context; const { shortcuts } = this.context;
shortcuts.on(
L10N.getStr("projectTextSearch.key"),
this.toggleProjectTextSearch
);
shortcuts.on("Enter", this.onEnterPress); shortcuts.on("Enter", this.onEnterPress);
} }
componentWillUnmount() { componentWillUnmount() {
const { shortcuts } = this.context; const { shortcuts } = this.context;
shortcuts.off(
L10N.getStr("projectTextSearch.key"),
this.toggleProjectTextSearch
);
shortcuts.off("Enter", this.onEnterPress); shortcuts.off("Enter", this.onEnterPress);
} }
@ -104,21 +92,6 @@ export class ProjectSearch extends Component {
} }
} }
toggleProjectTextSearch = e => {
const { cx, closeProjectSearch, setActiveSearch } = this.props;
if (e) {
e.preventDefault();
}
if (this.isProjectSearchEnabled()) {
return closeProjectSearch(cx);
}
return setActiveSearch("project");
};
isProjectSearchEnabled = () => this.props.activeSearch === "project";
selectMatchItem = matchItem => { selectMatchItem = matchItem => {
this.props.selectSpecificLocation(this.props.cx, matchItem.location); this.props.selectSpecificLocation(this.props.cx, matchItem.location);
this.props.doSearchForHighlight( this.props.doSearchForHighlight(
@ -167,11 +140,8 @@ export class ProjectSearch extends Component {
}; };
onEnterPress = () => { onEnterPress = () => {
if ( // This is to select a match from the search result.
!this.isProjectSearchEnabled() || if (!this.state.focusedItem || this.state.inputFocused) {
!this.state.focusedItem ||
this.state.inputFocused
) {
return; return;
} }
if (this.state.focusedItem.type === "MATCH") { if (this.state.focusedItem.type === "MATCH") {
@ -278,7 +248,7 @@ export class ProjectSearch extends Component {
} }
renderInput() { renderInput() {
const { closeProjectSearch, status } = this.props; const { status } = this.props;
return ( return (
<SearchInput <SearchInput
@ -294,7 +264,7 @@ export class ProjectSearch extends Component {
onBlur={() => this.setState({ inputFocused: false })} onBlur={() => this.setState({ inputFocused: false })}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
onHistoryScroll={this.onHistoryScroll} onHistoryScroll={this.onHistoryScroll}
showClose={true} showClose={false}
showExcludePatterns={true} showExcludePatterns={true}
excludePatternsLabel={L10N.getStr( excludePatternsLabel={L10N.getStr(
"projectTextSearch.excludePatterns.label" "projectTextSearch.excludePatterns.label"
@ -302,7 +272,6 @@ export class ProjectSearch extends Component {
excludePatternsPlaceholder={L10N.getStr( excludePatternsPlaceholder={L10N.getStr(
"projectTextSearch.excludePatterns.placeholder" "projectTextSearch.excludePatterns.placeholder"
)} )}
handleClose={closeProjectSearch}
ref="searchInput" ref="searchInput"
showSearchModifiers={true} showSearchModifiers={true}
searchKey={searchKeys.PROJECT_SEARCH} searchKey={searchKeys.PROJECT_SEARCH}
@ -312,10 +281,6 @@ export class ProjectSearch extends Component {
} }
render() { render() {
if (!this.isProjectSearchEnabled()) {
return null;
}
return ( return (
<div className="search-container"> <div className="search-container">
<div className="project-text-search"> <div className="project-text-search">
@ -333,14 +298,12 @@ ProjectSearch.contextTypes = {
const mapStateToProps = state => ({ const mapStateToProps = state => ({
cx: getContext(state), cx: getContext(state),
activeSearch: getActiveSearch(state),
results: getProjectSearchResults(state), results: getProjectSearchResults(state),
query: getProjectSearchQuery(state), query: getProjectSearchQuery(state),
status: getProjectSearchStatus(state), status: getProjectSearchStatus(state),
}); });
export default connect(mapStateToProps, { export default connect(mapStateToProps, {
closeProjectSearch: actions.closeProjectSearch,
searchSources: actions.searchSources, searchSources: actions.searchSources,
clearSearch: actions.clearSearch, clearSearch: actions.clearSearch,
selectSpecificLocation: actions.selectSpecificLocation, selectSpecificLocation: actions.selectSpecificLocation,

Просмотреть файл

@ -15,14 +15,22 @@ import {
} from "../../selectors"; } from "../../selectors";
import { prefs } from "../../utils/prefs"; import { prefs } from "../../utils/prefs";
import { connect } from "../../utils/connect"; import { connect } from "../../utils/connect";
import { primaryPaneTabs } from "../../constants";
import { formatKeyShortcut } from "../../utils/text"; import { formatKeyShortcut } from "../../utils/text";
import Outline from "./Outline"; import Outline from "./Outline";
import SourcesTree from "./SourcesTree"; import SourcesTree from "./SourcesTree";
import ProjectSearch from "./ProjectSearch";
import AccessibleImage from "../shared/AccessibleImage"; import AccessibleImage from "../shared/AccessibleImage";
import "./Sources.css"; import "./Sources.css";
const tabs = [
primaryPaneTabs.SOURCES,
primaryPaneTabs.OUTLINE,
primaryPaneTabs.PROJECT_SEARCH,
];
class PrimaryPanes extends Component { class PrimaryPanes extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
@ -37,15 +45,13 @@ class PrimaryPanes extends Component {
clearProjectDirectoryRoot: PropTypes.func.isRequired, clearProjectDirectoryRoot: PropTypes.func.isRequired,
cx: PropTypes.object.isRequired, cx: PropTypes.object.isRequired,
projectRootName: PropTypes.string.isRequired, projectRootName: PropTypes.string.isRequired,
selectedTab: PropTypes.oneOf(["sources", "outline"]).isRequired, selectedTab: PropTypes.oneOf(tabs).isRequired,
setPrimaryPaneTab: PropTypes.func.isRequired, setPrimaryPaneTab: PropTypes.func.isRequired,
setActiveSearch: PropTypes.func.isRequired,
closeActiveSearch: PropTypes.func.isRequired,
}; };
} }
showPane = selectedPane => {
this.props.setPrimaryPaneTab(selectedPane);
};
onAlphabetizeClick = () => { onAlphabetizeClick = () => {
const alphabetizeOutline = !prefs.alphabetizeOutline; const alphabetizeOutline = !prefs.alphabetizeOutline;
prefs.alphabetizeOutline = alphabetizeOutline; prefs.alphabetizeOutline = alphabetizeOutline;
@ -53,31 +59,40 @@ class PrimaryPanes extends Component {
}; };
onActivateTab = index => { onActivateTab = index => {
if (index === 0) { const tab = tabs.at(index);
this.showPane("sources"); this.props.setPrimaryPaneTab(tab);
if (tab == primaryPaneTabs.PROJECT_SEARCH) {
this.props.setActiveSearch(tab);
} else { } else {
this.showPane("outline"); this.props.closeActiveSearch();
} }
}; };
renderOutlineTabs() { renderTabList() {
const sources = formatKeyShortcut(L10N.getStr("sources.header"));
const outline = formatKeyShortcut(L10N.getStr("outline.header"));
const isSources = this.props.selectedTab === "sources";
const isOutline = this.props.selectedTab === "outline";
return [ return [
<Tab <Tab
className={classnames("tab sources-tab", { active: isSources })} className={classnames("tab sources-tab", {
active: this.props.selectedTab === primaryPaneTabs.SOURCES,
})}
key="sources-tab" key="sources-tab"
> >
{sources} {formatKeyShortcut(L10N.getStr("sources.header"))}
</Tab>, </Tab>,
<Tab <Tab
className={classnames("tab outline-tab", { active: isOutline })} className={classnames("tab outline-tab", {
active: this.props.selectedTab === primaryPaneTabs.OUTLINE,
})}
key="outline-tab" key="outline-tab"
> >
{outline} {formatKeyShortcut(L10N.getStr("outline.header"))}
</Tab>,
<Tab
className={classnames("tab search-tab", {
active: this.props.selectedTab === primaryPaneTabs.PROJECT_SEARCH,
})}
key="search-tab"
>
{formatKeyShortcut(L10N.getStr("search.header"))}
</Tab>, </Tab>,
]; ];
} }
@ -104,22 +119,16 @@ class PrimaryPanes extends Component {
); );
} }
renderThreadSources() {
return <SourcesTree />;
}
render() { render() {
const { selectedTab, projectRootName } = this.props; const { selectedTab, projectRootName } = this.props;
const activeIndex = selectedTab === "sources" ? 0 : 1;
return ( return (
<Tabs <Tabs
activeIndex={activeIndex} activeIndex={tabs.indexOf(selectedTab)}
className="sources-panel" className="sources-panel"
onActivateTab={this.onActivateTab} onActivateTab={this.onActivateTab}
> >
<TabList className="source-outline-tabs"> <TabList className="source-outline-tabs">
{this.renderOutlineTabs()} {this.renderTabList()}
</TabList> </TabList>
<TabPanels <TabPanels
className={classnames("source-outline-panel", { className={classnames("source-outline-panel", {
@ -129,12 +138,13 @@ class PrimaryPanes extends Component {
> >
<div className="threads-list"> <div className="threads-list">
{this.renderProjectRootHeader()} {this.renderProjectRootHeader()}
{this.renderThreadSources()} <SourcesTree />
</div> </div>
<Outline <Outline
alphabetizeOutline={this.state.alphabetizeOutline} alphabetizeOutline={this.state.alphabetizeOutline}
onAlphabetizeClick={this.onAlphabetizeClick} onAlphabetizeClick={this.onAlphabetizeClick}
/> />
<ProjectSearch />
</TabPanels> </TabPanels>
</Tabs> </Tabs>
); );

Просмотреть файл

@ -9,6 +9,7 @@ CompiledModules(
"index.js", "index.js",
"Outline.js", "Outline.js",
"OutlineFilter.js", "OutlineFilter.js",
"ProjectSearch.js",
"SourcesTree.js", "SourcesTree.js",
"SourcesTreeItem.js", "SourcesTreeItem.js",
) )

Просмотреть файл

@ -38,6 +38,8 @@ function generateDefaults(overrides) {
setActiveSearch: jest.fn(), setActiveSearch: jest.fn(),
closeActiveSearch: jest.fn(), closeActiveSearch: jest.fn(),
clearProjectDirectoryRoot: jest.fn(), clearProjectDirectoryRoot: jest.fn(),
selectedTab: "sources",
cx: {},
threads: [], threads: [],
...overrides, ...overrides,
}; };

Просмотреть файл

@ -9,9 +9,9 @@ import PropTypes from "prop-types";
import { mount, shallow } from "enzyme"; import { mount, shallow } from "enzyme";
import { ProjectSearch } from "../ProjectSearch"; import { ProjectSearch } from "../ProjectSearch";
import { statusType } from "../../reducers/project-text-search"; import { statusType } from "../../../reducers/project-text-search";
import { mockcx } from "../../utils/test-mockup"; import { mockcx } from "../../../utils/test-mockup";
import { searchKeys } from "../../constants"; import { searchKeys } from "../../../constants";
const hooks = { on: [], off: [] }; const hooks = { on: [], off: [] };
const shortcuts = { const shortcuts = {

Просмотреть файл

@ -2,7 +2,7 @@
exports[`PrimaryPanes should not render the directory root header if the directory root has not been set. 1`] = ` exports[`PrimaryPanes should not render the directory root header if the directory root has not been set. 1`] = `
<Tabs <Tabs
activeIndex={1} activeIndex={0}
className="sources-panel" className="sources-panel"
onActivateTab={[Function]} onActivateTab={[Function]}
> >
@ -14,7 +14,7 @@ exports[`PrimaryPanes should not render the directory root header if the directo
> >
<Tab <Tab
active={false} active={false}
className="tab sources-tab" className="tab sources-tab active"
key="sources-tab" key="sources-tab"
> >
Sources Sources
@ -26,6 +26,13 @@ exports[`PrimaryPanes should not render the directory root header if the directo
> >
Outline Outline
</Tab> </Tab>
<Tab
active={false}
className="tab search-tab"
key="search-tab"
>
Search
</Tab>
</TabList> </TabList>
<TabPanels <TabPanels
activeIndex={0} activeIndex={0}
@ -41,13 +48,14 @@ exports[`PrimaryPanes should not render the directory root header if the directo
alphabetizeOutline={false} alphabetizeOutline={false}
onAlphabetizeClick={[Function]} onAlphabetizeClick={[Function]}
/> />
<Connect(ProjectSearch) />
</TabPanels> </TabPanels>
</Tabs> </Tabs>
`; `;
exports[`PrimaryPanes should render the directory root header if the directory root has been set. 1`] = ` exports[`PrimaryPanes should render the directory root header if the directory root has been set. 1`] = `
<Tabs <Tabs
activeIndex={1} activeIndex={0}
className="sources-panel" className="sources-panel"
onActivateTab={[Function]} onActivateTab={[Function]}
> >
@ -59,7 +67,7 @@ exports[`PrimaryPanes should render the directory root header if the directory r
> >
<Tab <Tab
active={false} active={false}
className="tab sources-tab" className="tab sources-tab active"
key="sources-tab" key="sources-tab"
> >
Sources Sources
@ -71,6 +79,13 @@ exports[`PrimaryPanes should render the directory root header if the directory r
> >
Outline Outline
</Tab> </Tab>
<Tab
active={false}
className="tab search-tab"
key="search-tab"
>
Search
</Tab>
</TabList> </TabList>
<TabPanels <TabPanels
activeIndex={0} activeIndex={0}
@ -108,6 +123,7 @@ exports[`PrimaryPanes should render the directory root header if the directory r
alphabetizeOutline={false} alphabetizeOutline={false}
onAlphabetizeClick={[Function]} onAlphabetizeClick={[Function]}
/> />
<Connect(ProjectSearch) />
</TabPanels> </TabPanels>
</Tabs> </Tabs>
`; `;

Просмотреть файл

@ -14,7 +14,6 @@ exports[`ProjectSearch found no search results 1`] = `
count={0} count={0}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={false} isLoading={false}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -25,7 +24,7 @@ exports[`ProjectSearch found no search results 1`] = `
placeholder="Find in files…" placeholder="Find in files…"
query="foo" query="foo"
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={true} showErrorEmoji={true}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -143,7 +142,6 @@ exports[`ProjectSearch found search results 1`] = `
count={5} count={5}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={false} isLoading={false}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -154,7 +152,7 @@ exports[`ProjectSearch found search results 1`] = `
placeholder="Find in files…" placeholder="Find in files…"
query="match" query="match"
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={false} showErrorEmoji={false}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -166,7 +164,6 @@ exports[`ProjectSearch found search results 1`] = `
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
expanded={false} expanded={false}
handleClose={[MockFunction]}
hasPrefix={false} hasPrefix={false}
isLoading={false} isLoading={false}
onBlur={[Function]} onBlur={[Function]}
@ -188,7 +185,7 @@ exports[`ProjectSearch found search results 1`] = `
} }
selectedItemId="" selectedItemId=""
setSearchOptions={[Function]} setSearchOptions={[Function]}
showClose={true} showClose={false}
showErrorEmoji={false} showErrorEmoji={false}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -250,16 +247,11 @@ exports[`ProjectSearch found search results 1`] = `
<span <span
className="pipe-divider" className="pipe-divider"
/> />
<span
className="search-type-name"
>
Modifiers:
</span>
<button <button
className="regex-match-btn " className="regex-match-btn "
onKeyDown={[Function]} onKeyDown={[Function]}
onMouseDown={[Function]} onMouseDown={[Function]}
title="Regex" title="Use Regular Expression"
> >
<span <span
className="regex-match" className="regex-match"
@ -269,7 +261,7 @@ exports[`ProjectSearch found search results 1`] = `
className="case-sensitive-btn " className="case-sensitive-btn "
onKeyDown={[Function]} onKeyDown={[Function]}
onMouseDown={[Function]} onMouseDown={[Function]}
title="Case sensitive" title="Match Case"
> >
<span <span
className="case-match" className="case-match"
@ -279,7 +271,7 @@ exports[`ProjectSearch found search results 1`] = `
className="whole-word-btn " className="whole-word-btn "
onKeyDown={[Function]} onKeyDown={[Function]}
onMouseDown={[Function]} onMouseDown={[Function]}
title="Whole word" title="Match Whole Word"
> >
<span <span
className="whole-word-match" className="whole-word-match"
@ -287,26 +279,6 @@ exports[`ProjectSearch found search results 1`] = `
</button> </button>
</div> </div>
</SearchModifiers> </SearchModifiers>
<span
className="pipe-divider"
/>
<CloseButton
buttonClass="small"
handleClick={[MockFunction]}
>
<button
className="close-btn small"
onClick={[MockFunction]}
>
<AccessibleImage
className="close"
>
<span
className="img close"
/>
</AccessibleImage>
</button>
</CloseButton>
</div> </div>
</div> </div>
<div <div
@ -908,7 +880,46 @@ exports[`ProjectSearch found search results 1`] = `
</ProjectSearch> </ProjectSearch>
`; `;
exports[`ProjectSearch renders nothing when disabled 1`] = `""`; exports[`ProjectSearch renders nothing when disabled 1`] = `
<div
className="search-container"
>
<div
className="project-text-search"
>
<div
className="header"
>
<Connect(SearchInput)
count={0}
excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
isLoading={false}
onBlur={[Function]}
onChange={[Function]}
onFocus={[Function]}
onHistoryScroll={[Function]}
onKeyDown={[Function]}
onToggleSearchModifier={[Function]}
placeholder="Find in files…"
query="foo"
searchKey="project-search"
showClose={false}
showErrorEmoji={true}
showExcludePatterns={true}
showSearchModifiers={true}
size="small"
summaryMsg="0 results"
/>
</div>
<div
className="no-result-msg absolute-center"
>
No results found
</div>
</div>
</div>
`;
exports[`ProjectSearch should display loading message while search is in progress 1`] = ` exports[`ProjectSearch should display loading message while search is in progress 1`] = `
<div <div
@ -924,7 +935,6 @@ exports[`ProjectSearch should display loading message while search is in progres
count={0} count={0}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={true} isLoading={true}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -935,7 +945,7 @@ exports[`ProjectSearch should display loading message while search is in progres
placeholder="Find in files…" placeholder="Find in files…"
query="match" query="match"
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={false} showErrorEmoji={false}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -966,7 +976,6 @@ exports[`ProjectSearch showErrorEmoji false if not done & no results 1`] = `
count={0} count={0}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={true} isLoading={true}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -977,7 +986,7 @@ exports[`ProjectSearch showErrorEmoji false if not done & no results 1`] = `
placeholder="Find in files…" placeholder="Find in files…"
query="foo" query="foo"
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={false} showErrorEmoji={false}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -1008,7 +1017,6 @@ exports[`ProjectSearch showErrorEmoji false if not done & results 1`] = `
count={5} count={5}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={true} isLoading={true}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -1019,7 +1027,7 @@ exports[`ProjectSearch showErrorEmoji false if not done & results 1`] = `
placeholder="Find in files…" placeholder="Find in files…"
query="foo" query="foo"
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={false} showErrorEmoji={false}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -1058,7 +1066,6 @@ exports[`ProjectSearch turns off shortcuts on unmount 1`] = `
count={0} count={0}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={false} isLoading={false}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -1069,7 +1076,7 @@ exports[`ProjectSearch turns off shortcuts on unmount 1`] = `
placeholder="Find in files…" placeholder="Find in files…"
query="" query=""
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={true} showErrorEmoji={true}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}
@ -1095,7 +1102,6 @@ exports[`ProjectSearch where <Enter> has not been pressed 1`] = `
count={0} count={0}
excludePatternsLabel="files to exclude" excludePatternsLabel="files to exclude"
excludePatternsPlaceholder="e.g. **/node_modules/**,app.js" excludePatternsPlaceholder="e.g. **/node_modules/**,app.js"
handleClose={[MockFunction]}
isLoading={false} isLoading={false}
onBlur={[Function]} onBlur={[Function]}
onChange={[Function]} onChange={[Function]}
@ -1106,7 +1112,7 @@ exports[`ProjectSearch where <Enter> has not been pressed 1`] = `
placeholder="Find in files…" placeholder="Find in files…"
query="" query=""
searchKey="project-search" searchKey="project-search"
showClose={true} showClose={false}
showErrorEmoji={true} showErrorEmoji={true}
showExcludePatterns={true} showExcludePatterns={true}
showSearchModifiers={true} showSearchModifiers={true}

Просмотреть файл

@ -6,6 +6,7 @@ import React, { Component } from "react";
import PropTypes from "prop-types"; import PropTypes from "prop-types";
import { connect } from "../utils/connect"; import { connect } from "../utils/connect";
import { primaryPaneTabs } from "../constants";
import actions from "../actions"; import actions from "../actions";
import { getPaneCollapse } from "../selectors"; import { getPaneCollapse } from "../selectors";
@ -19,6 +20,7 @@ export class WelcomeBox extends Component {
openQuickOpen: PropTypes.func.isRequired, openQuickOpen: PropTypes.func.isRequired,
setActiveSearch: PropTypes.func.isRequired, setActiveSearch: PropTypes.func.isRequired,
toggleShortcutsModal: PropTypes.func.isRequired, toggleShortcutsModal: PropTypes.func.isRequired,
setPrimaryPaneTab: PropTypes.func.isRequired,
}; };
} }
@ -38,7 +40,6 @@ export class WelcomeBox extends Component {
const allShortcutsLabel = L10N.getStr("welcome.allShortcuts"); const allShortcutsLabel = L10N.getStr("welcome.allShortcuts");
const searchSourcesLabel = L10N.getStr("welcome.search2").substring(2); const searchSourcesLabel = L10N.getStr("welcome.search2").substring(2);
const searchProjectLabel = L10N.getStr("welcome.findInFiles2").substring(2); const searchProjectLabel = L10N.getStr("welcome.findInFiles2").substring(2);
const { setActiveSearch, openQuickOpen, toggleShortcutsModal } = this.props;
return ( return (
<div className="welcomebox"> <div className="welcomebox">
@ -48,7 +49,7 @@ export class WelcomeBox extends Component {
className="welcomebox__searchSources" className="welcomebox__searchSources"
role="button" role="button"
tabIndex="0" tabIndex="0"
onClick={() => openQuickOpen()} onClick={() => this.props.openQuickOpen()}
> >
<span className="shortcutKey">{searchSourcesShortcut}</span> <span className="shortcutKey">{searchSourcesShortcut}</span>
<span className="shortcutLabel">{searchSourcesLabel}</span> <span className="shortcutLabel">{searchSourcesLabel}</span>
@ -57,7 +58,10 @@ export class WelcomeBox extends Component {
className="welcomebox__searchProject" className="welcomebox__searchProject"
role="button" role="button"
tabIndex="0" tabIndex="0"
onClick={setActiveSearch.bind(null, "project")} onClick={() => {
this.props.setActiveSearch(primaryPaneTabs.PROJECT_SEARCH);
this.props.setPrimaryPaneTab(primaryPaneTabs.PROJECT_SEARCH);
}}
> >
<span className="shortcutKey">{searchProjectShortcut}</span> <span className="shortcutKey">{searchProjectShortcut}</span>
<span className="shortcutLabel">{searchProjectLabel}</span> <span className="shortcutLabel">{searchProjectLabel}</span>
@ -66,7 +70,7 @@ export class WelcomeBox extends Component {
className="welcomebox__allShortcuts" className="welcomebox__allShortcuts"
role="button" role="button"
tabIndex="0" tabIndex="0"
onClick={() => toggleShortcutsModal()} onClick={() => this.props.toggleShortcutsModal()}
> >
<span className="shortcutKey">{allShortcutsShortcut}</span> <span className="shortcutKey">{allShortcutsShortcut}</span>
<span className="shortcutLabel">{allShortcutsLabel}</span> <span className="shortcutLabel">{allShortcutsLabel}</span>
@ -86,4 +90,5 @@ export default connect(mapStateToProps, {
togglePaneCollapse: actions.togglePaneCollapse, togglePaneCollapse: actions.togglePaneCollapse,
setActiveSearch: actions.setActiveSearch, setActiveSearch: actions.setActiveSearch,
openQuickOpen: actions.openQuickOpen, openQuickOpen: actions.openQuickOpen,
setPrimaryPaneTab: actions.setPrimaryPaneTab,
})(WelcomeBox); })(WelcomeBox);

Просмотреть файл

@ -13,7 +13,6 @@ DIRS += [
CompiledModules( CompiledModules(
"A11yIntention.js", "A11yIntention.js",
"App.js", "App.js",
"ProjectSearch.js",
"QuickOpenModal.js", "QuickOpenModal.js",
"ShortcutsModal.js", "ShortcutsModal.js",
"WelcomeBox.js", "WelcomeBox.js",

Просмотреть файл

@ -42,7 +42,6 @@ export class SearchInput extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
history: [], history: [],
excludePatterns: props.searchOptions.excludePatterns, excludePatterns: props.searchOptions.excludePatterns,

Просмотреть файл

@ -15,6 +15,7 @@ function render(overrides = {}) {
setActiveSearch: jest.fn(), setActiveSearch: jest.fn(),
openQuickOpen: jest.fn(), openQuickOpen: jest.fn(),
toggleShortcutsModal: jest.fn(), toggleShortcutsModal: jest.fn(),
setPrimaryPaneTab: jest.fn(),
...overrides, ...overrides,
}; };
const component = shallow(<WelcomeBox {...props} />); const component = shallow(<WelcomeBox {...props} />);

Просмотреть файл

@ -7,3 +7,9 @@ export const searchKeys = {
FILE_SEARCH: "file-search", FILE_SEARCH: "file-search",
QUICKOPEN_SEARCH: "quickopen-search", QUICKOPEN_SEARCH: "quickopen-search",
}; };
export const primaryPaneTabs = {
SOURCES: "sources",
OUTLINE: "outline",
PROJECT_SEARCH: "project",
};

Просмотреть файл

@ -38,8 +38,8 @@
@import url("chrome://devtools/content/debugger/src/components/Editor/Tabs.css"); @import url("chrome://devtools/content/debugger/src/components/Editor/Tabs.css");
@import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/Outline.css"); @import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/Outline.css");
@import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/OutlineFilter.css"); @import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/OutlineFilter.css");
@import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/ProjectSearch.css");
@import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/Sources.css"); @import url("chrome://devtools/content/debugger/src/components/PrimaryPanes/Sources.css");
@import url("chrome://devtools/content/debugger/src/components/ProjectSearch.css");
@import url("chrome://devtools/content/debugger/src/components/QuickOpenModal.css"); @import url("chrome://devtools/content/debugger/src/components/QuickOpenModal.css");
@import url("chrome://devtools/content/debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css"); @import url("chrome://devtools/content/debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css");
@import url("chrome://devtools/content/debugger/src/components/SecondaryPanes/CommandBar.css"); @import url("chrome://devtools/content/debugger/src/components/SecondaryPanes/CommandBar.css");

Просмотреть файл

@ -19,9 +19,9 @@ export const statusType = {
error: "ERROR", error: "ERROR",
}; };
export function initialProjectTextSearchState() { export function initialProjectTextSearchState(state) {
return { return {
query: "", query: state?.query || "",
results: [], results: [],
ongoingSearch: null, ongoingSearch: null,
status: statusType.initial, status: statusType.initial,
@ -72,8 +72,9 @@ function update(state = initialProjectTextSearchState(), action) {
case "CLEAR_SEARCH": case "CLEAR_SEARCH":
case "CLOSE_PROJECT_SEARCH": case "CLOSE_PROJECT_SEARCH":
case "NAVIGATE":
return initialProjectTextSearchState(); return initialProjectTextSearchState();
case "NAVIGATE":
return initialProjectTextSearchState(state);
} }
return state; return state;
} }

Просмотреть файл

@ -8,15 +8,6 @@
requestLongerTimeout(3); requestLongerTimeout(3);
add_task(async function testOpeningAndClosingEmptyProjectSearch() {
const dbg = await initDebugger(
"doc-script-switching.html",
"script-switching-01.js"
);
await openProjectSearch(dbg);
await closeProjectSearch(dbg);
});
add_task(async function testProjectSearchCloseOnNavigation() { add_task(async function testProjectSearchCloseOnNavigation() {
const dbg = await initDebugger( const dbg = await initDebugger(
"doc-script-switching.html", "doc-script-switching.html",
@ -42,8 +33,6 @@ add_task(async function testSimpleProjectSearch() {
"script-switching-01.js" "script-switching-01.js"
); );
await selectSource(dbg, "script-switching-01.js");
await openProjectSearch(dbg); await openProjectSearch(dbg);
const searchTerm = "first"; const searchTerm = "first";
await doProjectSearch(dbg, searchTerm); await doProjectSearch(dbg, searchTerm);
@ -58,15 +47,8 @@ add_task(async function testSimpleProjectSearch() {
); );
info("Select a result match to open the location in the source"); info("Select a result match to open the location in the source");
await selectResultMatch(dbg); await clickElement(dbg, "fileMatch");
await waitForLoadedSource(dbg, "script-switching-01.js"); await waitForSelectedSource(dbg, "script-switching-01.js");
is(dbg.selectors.getActiveSearch(), null);
ok(
dbg.selectors.getSelectedSource().url.includes("script-switching-01.js"),
"The correct source (script-switching-01.js) is selected"
);
}); });
add_task(async function testMatchesForRegexSearches() { add_task(async function testMatchesForRegexSearches() {
@ -90,7 +72,6 @@ add_task(async function testMatchesForRegexSearches() {
// Turn off the regex modifier so does not break tests below // Turn off the regex modifier so does not break tests below
await clickElement(dbg, "projectSearchModifiersRegexMatch"); await clickElement(dbg, "projectSearchModifiersRegexMatch");
await closeProjectSearch(dbg);
}); });
// Test expanding search results to reveal the search matches. // Test expanding search results to reveal the search matches.
@ -113,6 +94,8 @@ add_task(async function testExpandSearchResultsToShowMatches() {
add_task(async function testSearchModifiers() { add_task(async function testSearchModifiers() {
const dbg = await initDebugger("doc-react.html", "App.js"); const dbg = await initDebugger("doc-react.html", "App.js");
await openProjectSearch(dbg);
await assertProjectSearchModifier( await assertProjectSearchModifier(
dbg, dbg,
"projectSearchModifiersCaseSensitive", "projectSearchModifiersCaseSensitive",
@ -212,7 +195,8 @@ add_task(async function testSearchExcludePatterns() {
"The exclude pattern for node modules is persisted accross reloads" "The exclude pattern for node modules is persisted accross reloads"
); );
// Clear the exclude patterns field so that it does not impact on the subsequent tests // Clear the fields so that it does not impact on the subsequent tests
await clearElement(dbg, "projectSearchSearchInput");
await clearElement(dbg, "excludePatternsInput"); await clearElement(dbg, "excludePatternsInput");
pressKey(dbg, "Enter"); pressKey(dbg, "Enter");
}); });
@ -225,11 +209,10 @@ async function assertProjectSearchModifier(
expected expected
) { ) {
info(`Assert ${title} search modifier`); info(`Assert ${title} search modifier`);
await openProjectSearch(dbg);
type(dbg, searchTerm); type(dbg, searchTerm);
info(`Turn on the ${title} search modifier option`); info(`Turn on the ${title} search modifier option`);
await clickElement(dbg, searchModifierBtn); await clickElement(dbg, searchModifierBtn);
let results = await waitForSearchResults(dbg, expected.resultWithModifierOn); let results = await waitForSearchResults(dbg, expected.resultWithModifierOn);
is( is(
results.length, results.length,
@ -246,12 +229,5 @@ async function assertProjectSearchModifier(
expected.resultWithModifierOff, expected.resultWithModifierOff,
`${results.length} results where found` `${results.length} results where found`
); );
await clearElement(dbg, "projectSearchSearchInput");
await closeProjectSearch(dbg);
}
async function selectResultMatch(dbg) {
const select = waitForState(dbg, () => !dbg.selectors.getActiveSearch());
await clickElement(dbg, "fileMatch");
return select;
} }

Просмотреть файл

@ -6,6 +6,8 @@
"use strict"; "use strict";
requestLongerTimeout(3);
// Tests for searching in dynamic (without urls) sources // Tests for searching in dynamic (without urls) sources
add_task(async function testSearchDynamicScripts() { add_task(async function testSearchDynamicScripts() {
const dbg = await initDebugger("doc-minified.html"); const dbg = await initDebugger("doc-minified.html");
@ -22,7 +24,6 @@ add_task(async function testSearchDynamicScripts() {
"The search result was found in the eval script." "The search result was found in the eval script."
); );
await closeProjectSearch(dbg);
await resume(dbg); await resume(dbg);
await executeComplete; await executeComplete;
}); });
@ -41,15 +42,12 @@ add_task(async function testIgnoreMinifiedSourceForPrettySource() {
"The search result was found in the minified (pretty.js) source" "The search result was found in the minified (pretty.js) source"
); );
await closeProjectSearch(dbg);
await selectSource(dbg, "pretty.js"); await selectSource(dbg, "pretty.js");
await waitForSelectedSource(dbg, "pretty.js"); await waitForSelectedSource(dbg, "pretty.js");
info("Pretty print the source"); info("Pretty print the source");
await prettyPrint(dbg); await prettyPrint(dbg);
await openProjectSearch(dbg);
fileResults = await doProjectSearch(dbg, "stuff"); fileResults = await doProjectSearch(dbg, "stuff");
is( is(
@ -114,8 +112,6 @@ add_task(async function testBlackBoxedSources() {
is(fileResults.length, 0, "No results were found as pretty.js is blackboxed"); is(fileResults.length, 0, "No results were found as pretty.js is blackboxed");
await closeProjectSearch(dbg);
info("Unblackbox pretty.js"); info("Unblackbox pretty.js");
await toggleBlackbox(dbg); await toggleBlackbox(dbg);

Просмотреть файл

@ -1667,6 +1667,7 @@ const selectors = {
logPointInSecPane: ".breakpoint.is-log", logPointInSecPane: ".breakpoint.is-log",
searchField: ".search-field", searchField: ".search-field",
blackbox: ".action.black-box", blackbox: ".action.black-box",
projectSearchSearchInput: ".project-text-search .search-field input",
projectSearchCollapsed: ".project-text-search .arrow:not(.expanded)", projectSearchCollapsed: ".project-text-search .arrow:not(.expanded)",
projectSearchExpandedResults: ".project-text-search .result", projectSearchExpandedResults: ".project-text-search .result",
projectSearchFileResults: ".project-text-search .file-result", projectSearchFileResults: ".project-text-search .file-result",
@ -2486,6 +2487,7 @@ function openProjectSearch(dbg) {
* @return {Array} List of search results element nodes * @return {Array} List of search results element nodes
*/ */
async function doProjectSearch(dbg, searchTerm) { async function doProjectSearch(dbg, searchTerm) {
await clearElement(dbg, "projectSearchSearchInput");
type(dbg, searchTerm); type(dbg, searchTerm);
pressKey(dbg, "Enter"); pressKey(dbg, "Enter");
return waitForSearchResults(dbg); return waitForSearchResults(dbg);
@ -2510,18 +2512,6 @@ async function waitForSearchResults(dbg, expectedResults) {
return findAllElements(dbg, "projectSearchFileResults"); return findAllElements(dbg, "projectSearchFileResults");
} }
/**
* Closes the project search panel
*
* @param {Object} dbg
* @return {Boolean} When the panel closes
*/
function closeProjectSearch(dbg) {
info("Closing the project search panel");
synthesizeKeyShortcut("CmdOrCtrl+Shift+F");
return waitForState(dbg, state => !dbg.selectors.getActiveSearch());
}
/** /**
* Get the no of expanded search results * Get the no of expanded search results
* *

Просмотреть файл

@ -287,7 +287,6 @@ devtools.jar:
content/debugger/src/components/variables.css (debugger/src/components/variables.css) content/debugger/src/components/variables.css (debugger/src/components/variables.css)
content/debugger/src/components/A11yIntention.css (debugger/src/components/A11yIntention.css) content/debugger/src/components/A11yIntention.css (debugger/src/components/A11yIntention.css)
content/debugger/src/components/App.css (debugger/src/components/App.css) content/debugger/src/components/App.css (debugger/src/components/App.css)
content/debugger/src/components/ProjectSearch.css (debugger/src/components/ProjectSearch.css)
content/debugger/src/components/QuickOpenModal.css (debugger/src/components/QuickOpenModal.css) content/debugger/src/components/QuickOpenModal.css (debugger/src/components/QuickOpenModal.css)
content/debugger/src/components/ShortcutsModal.css (debugger/src/components/ShortcutsModal.css) content/debugger/src/components/ShortcutsModal.css (debugger/src/components/ShortcutsModal.css)
content/debugger/src/components/WelcomeBox.css (debugger/src/components/WelcomeBox.css) content/debugger/src/components/WelcomeBox.css (debugger/src/components/WelcomeBox.css)
@ -319,6 +318,7 @@ devtools.jar:
content/debugger/src/components/Editor/Tabs.css (debugger/src/components/Editor/Tabs.css) content/debugger/src/components/Editor/Tabs.css (debugger/src/components/Editor/Tabs.css)
content/debugger/src/components/PrimaryPanes/Outline.css (debugger/src/components/PrimaryPanes/Outline.css) content/debugger/src/components/PrimaryPanes/Outline.css (debugger/src/components/PrimaryPanes/Outline.css)
content/debugger/src/components/PrimaryPanes/OutlineFilter.css (debugger/src/components/PrimaryPanes/OutlineFilter.css) content/debugger/src/components/PrimaryPanes/OutlineFilter.css (debugger/src/components/PrimaryPanes/OutlineFilter.css)
content/debugger/src/components/PrimaryPanes/ProjectSearch.css (debugger/src/components/PrimaryPanes/ProjectSearch.css)
content/debugger/src/components/PrimaryPanes/Sources.css (debugger/src/components/PrimaryPanes/Sources.css) content/debugger/src/components/PrimaryPanes/Sources.css (debugger/src/components/PrimaryPanes/Sources.css)
content/debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css (debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css) content/debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css (debugger/src/components/SecondaryPanes/Breakpoints/Breakpoints.css)
content/debugger/src/components/SecondaryPanes/CommandBar.css (debugger/src/components/SecondaryPanes/CommandBar.css) content/debugger/src/components/SecondaryPanes/CommandBar.css (debugger/src/components/SecondaryPanes/CommandBar.css)

Просмотреть файл

@ -36,18 +36,14 @@ appErrorBoundary.fileBugButton=File Bug Report
# after the panel errors to instruct the user to reload the panel. # after the panel errors to instruct the user to reload the panel.
appErrorBoundary.reloadPanelInfo=Close and reopen the toolbox to clear this error. appErrorBoundary.reloadPanelInfo=Close and reopen the toolbox to clear this error.
# LOCALIZATION NOTE(searchModifier.modifiersLabel): A label # LOCALIZATION NOTE(searchModifier.regExpModifier): A search option
# preceding the group of modifiers
searchModifier.modifiersLabel=Modifiers:
# LOCALIZATION NOTE(searchModifier.regex): A search option
# when searching text in a file # when searching text in a file
searchModifier.regex=Regex searchModifier.regExpModifier=Use Regular Expression
# LOCALIZATION NOTE(searchModifier.caseSensitive): A search option # LOCALIZATION NOTE(searchModifier.caseSensitiveModifier): A search option
# when searching text in a file # when searching text in a file
searchModifier.caseSensitive=Case sensitive searchModifier.caseSensitiveModifier=Match Case
# LOCALIZATION NOTE(searchModifier.wholeWord): A search option # LOCALIZATION NOTE(searchModifier.wholeWordModifier): A search option
# when searching text in a file # when searching text in a file
searchModifier.wholeWord=Whole word searchModifier.wholeWordModifier=Match Whole Word

Просмотреть файл

@ -766,6 +766,9 @@ sources.header=Sources
# LOCALIZATION NOTE (outline.header): Outline left sidebar header # LOCALIZATION NOTE (outline.header): Outline left sidebar header
outline.header=Outline outline.header=Outline
# LOCALIZATION NOTE (search.header): Search left sidebar header
search.header=Search
# LOCALIZATION NOTE (outline.placeholder): Placeholder text for the filter input # LOCALIZATION NOTE (outline.placeholder): Placeholder text for the filter input
# element # element
outline.placeholder=Filter functions outline.placeholder=Filter functions

Просмотреть файл

@ -26,19 +26,19 @@ const modifierOptions = [
value: "regexMatch", value: "regexMatch",
className: "regex-match-btn", className: "regex-match-btn",
svgName: "regex-match", svgName: "regex-match",
tooltip: l10n.getStr("searchModifier.regex"), tooltip: l10n.getStr("searchModifier.regExpModifier"),
}, },
{ {
value: "caseSensitive", value: "caseSensitive",
className: "case-sensitive-btn", className: "case-sensitive-btn",
svgName: "case-match", svgName: "case-match",
tooltip: l10n.getStr("searchModifier.caseSensitive"), tooltip: l10n.getStr("searchModifier.caseSensitiveModifier"),
}, },
{ {
value: "wholeWord", value: "wholeWord",
className: "whole-word-btn", className: "whole-word-btn",
svgName: "whole-word-match", svgName: "whole-word-match",
tooltip: l10n.getStr("searchModifier.wholeWord"), tooltip: l10n.getStr("searchModifier.wholeWordModifier"),
}, },
]; ];
@ -76,10 +76,6 @@ class SearchModifiers extends Component {
return div( return div(
{ className: "search-modifiers" }, { className: "search-modifiers" },
span({ className: "pipe-divider" }), span({ className: "pipe-divider" }),
span(
{ className: "search-type-name" },
l10n.getStr("searchModifier.modifiersLabel")
),
modifierOptions.map(options => this.#renderSearchModifier(options)) modifierOptions.map(options => this.#renderSearchModifier(options))
); );
} }

Просмотреть файл

@ -133,6 +133,7 @@ async function testProjectSearch(tab, toolbox) {
const firstSearchResultTest = runTest( const firstSearchResultTest = runTest(
`custom.jsdebugger.project-search.first-search-result.DAMP` `custom.jsdebugger.project-search.first-search-result.DAMP`
); );
await dbg.actions.setPrimaryPaneTab("project");
await dbg.actions.setActiveSearch("project"); await dbg.actions.setActiveSearch("project");
const complete = dbg.actions.searchSources(cx, "return"); const complete = dbg.actions.searchSources(cx, "return");
// Wait till the first search result match is rendered // Wait till the first search result match is rendered