Skip to content

Commit a8e5677

Browse files
authored
sketch project search (firefox-devtools#3177)
initial working version
1 parent 22627ea commit a8e5677

File tree

6 files changed

+90
-19
lines changed

6 files changed

+90
-19
lines changed

src/components/ProjectSearch/ProjectSearch.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function projectSearchResults(sources, query) {
6565

6666
class ProjectSearch extends Component {
6767
state: Object;
68-
toggle: Function;
68+
toggleProjectSearch: Function;
6969
onEscape: Function;
7070
close: Function;
7171

@@ -76,7 +76,7 @@ class ProjectSearch extends Component {
7676
inputValue: ""
7777
};
7878

79-
this.toggle = this.toggle.bind(this);
79+
this.toggleProjectSearch = this.toggleProjectSearch.bind(this);
8080
this.onEscape = this.onEscape.bind(this);
8181
this.close = this.close.bind(this);
8282
}
@@ -87,7 +87,7 @@ class ProjectSearch extends Component {
8787
L10N.getStr("sources.search.key2"),
8888
L10N.getStr("sources.search.key2")
8989
];
90-
searchKeys.forEach(key => shortcuts.off(key, this.toggle));
90+
searchKeys.forEach(key => shortcuts.off(key, this.toggleProjectSearch));
9191
shortcuts.off("Escape", this.onEscape);
9292
}
9393

@@ -97,11 +97,11 @@ class ProjectSearch extends Component {
9797
L10N.getStr("sources.search.key2"),
9898
L10N.getStr("sources.search.alt.key")
9999
];
100-
searchKeys.forEach(key => shortcuts.on(key, this.toggle));
100+
searchKeys.forEach(key => shortcuts.on(key, this.toggleProjectSearch));
101101
shortcuts.on("Escape", this.onEscape);
102102
}
103103

104-
toggle(key, e) {
104+
toggleProjectSearch(key, e) {
105105
e.preventDefault();
106106
this.props.toggleProjectSearch();
107107
}

src/components/ProjectSearch/TextSearch.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
.project-text-search {
2+
flex-grow: 1;
3+
}
4+
15
.project-text-search .result {
26
display: flex;
37
margin-left: 20px;
@@ -18,3 +22,9 @@
1822
.project-text-search .result .line-number {
1923
padding-right: 5px;
2024
}
25+
26+
.project-text-search .search-field {
27+
display: flex;
28+
align-self: stretch;
29+
flex-grow: 1;
30+
}

src/components/ProjectSearch/TextSearch.js

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,50 @@ import Svg from "../shared/Svg";
55
import _ManagedTree from "../shared/ManagedTree";
66
const ManagedTree = createFactory(_ManagedTree);
77

8+
import _SearchInput from "../shared/SearchInput";
9+
const SearchInput = createFactory(_SearchInput);
10+
11+
import { searchSource } from "../../utils/project-search";
12+
813
import "./TextSearch.css";
914

15+
function search(query, sources) {
16+
const validSources = sources.valueSeq().filter(s => s.has("text")).toJS();
17+
return validSources.map(source => ({
18+
source,
19+
filepath: source.url,
20+
matches: searchSource(source, query)
21+
}));
22+
}
23+
1024
export default class TextSearch extends Component {
1125
constructor(props: Props) {
1226
super(props);
27+
this.state = {
28+
results: [],
29+
inputValue: props.inputValue || "",
30+
selectedIndex: 0,
31+
focused: false
32+
};
33+
}
34+
35+
async inputOnChange(e) {
36+
const { sources } = this.props;
37+
const inputValue = e.target.value;
38+
const results = await search(inputValue, sources);
39+
40+
this.setState({
41+
results,
42+
inputValue,
43+
selectedIndex: 0
44+
});
1345
}
1446

1547
renderFile(file, expanded) {
1648
return dom.div(
1749
{
18-
className: "file-result"
50+
className: "file-result",
51+
key: file.filepath
1952
},
2053
Svg("arrow", {
2154
className: classnames({
@@ -26,9 +59,9 @@ export default class TextSearch extends Component {
2659
);
2760
}
2861

29-
renderLine(match) {
62+
renderMatch(match) {
3063
return dom.div(
31-
{ className: "result" },
64+
{ className: "result", key: `${match.line}/${match.column}` },
3265
dom.span(
3366
{
3467
className: "line-number"
@@ -40,7 +73,7 @@ export default class TextSearch extends Component {
4073
}
4174

4275
renderResults() {
43-
const { results } = this.props;
76+
const { results } = this.state;
4477
return ManagedTree({
4578
getRoots: () => results,
4679
getChildren: file => {
@@ -52,7 +85,36 @@ export default class TextSearch extends Component {
5285
getParent: item => null,
5386
getKey: item => item.filepath || `${item.value}/${item.line}`,
5487
renderItem: (item, depth, focused, _, expanded) =>
55-
item.filepath ? this.renderFile(item, expanded) : this.renderLine(item)
88+
item.filepath ? this.renderFile(item, expanded) : this.renderMatch(item)
89+
});
90+
}
91+
92+
resultCount() {
93+
const { results } = this.state;
94+
return results.reduce(
95+
(count, file) => count + (file.matches ? file.matches.length : 0),
96+
0
97+
);
98+
}
99+
100+
renderInput() {
101+
const resultCount = this.resultCount();
102+
const summaryMsg = L10N.getFormatStr(
103+
"sourceSearch.resultsSummary1",
104+
resultCount
105+
);
106+
107+
return SearchInput({
108+
query: this.state.inputValue,
109+
count: resultCount,
110+
placeholder: "Search Project",
111+
size: "big",
112+
summaryMsg,
113+
onChange: e => this.inputOnChange(e),
114+
onFocus: () => this.setState({ focused: true }),
115+
onBlur: () => this.setState({ focused: false }),
116+
onKeyDown: this.onKeyDown,
117+
handleClose: this.props.close
56118
});
57119
}
58120

@@ -61,6 +123,7 @@ export default class TextSearch extends Component {
61123
{
62124
className: "project-text-search"
63125
},
126+
this.renderInput(),
64127
this.renderResults()
65128
);
66129
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
var foo = 1;
22
let bar = 2;
33
const baz = 3;
4-
const a = 4, b = 5;
4+
const a = 4,
5+
b = 5;

src/utils/project-search.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export function searchSource(source, queryText) {
2-
const { text, id, url, loading } = source;
2+
const { text, loading } = source;
33
if (loading || !text || queryText == "") {
44
return [];
55
}
@@ -17,9 +17,8 @@ export function searchSource(source, queryText) {
1717
line: line + 1,
1818
column: result.index,
1919
match: result[0],
20-
text: result.input,
21-
id,
22-
url
20+
value: _text,
21+
text: result.input
2322
});
2423
}
2524
return indices;

src/utils/tests/__snapshots__/project-search.js.snap

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@ exports[`project search simple 1`] = `
44
Array [
55
Object {
66
"column": 11,
7-
"id": "bar.js",
87
"line": 2,
98
"match": "foo",
109
"text": " function foo() {",
11-
"url": "http://example.com/foo/bar.js",
10+
"value": " function foo() {",
1211
},
1312
Object {
1413
"column": 4,
15-
"id": "bar.js",
1614
"line": 3,
1715
"match": "foo",
1816
"text": " foo();",
19-
"url": "http://example.com/foo/bar.js",
17+
"value": " foo();",
2018
},
2119
]
2220
`;

0 commit comments

Comments
 (0)