Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
🔨: Cleaning up some quick open code and adding tests. (#5015)
Browse files Browse the repository at this point in the history
  • Loading branch information
wldcordeiro authored and jasonLaster committed Jan 9, 2018
1 parent 6770c9d commit 2c6bcec
Show file tree
Hide file tree
Showing 4 changed files with 482 additions and 400 deletions.
183 changes: 90 additions & 93 deletions src/components/QuickOpenModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from "redux";
import { filter } from "fuzzaldrin-plus";

import actions from "../actions";
Expand All @@ -33,6 +32,8 @@ import type {
FormattedSymbolDeclarations,
QuickOpenResult
} from "../utils/quick-open";

import type { Location } from "debugger-html";
import type { SourceRecord } from "../reducers/sources";
import type { QuickOpenType } from "../reducers/quick-open";

Expand All @@ -43,7 +44,7 @@ type Props = {
query: string,
searchType: QuickOpenType,
symbols: FormattedSymbolDeclarations,
selectLocation: Object => void,
selectLocation: Location => void,
setQuickOpenQuery: (query: string) => void,
highlightLineRange: ({ start: number, end: number }) => void,
closeQuickOpen: () => void
Expand All @@ -54,6 +55,12 @@ type State = {
selectedIndex: number
};

type GotoLocationType = {
sourceId?: string,
line: number,
column?: number
};

export class QuickOpenModal extends Component<Props, State> {
constructor(props: Props) {
super(props);
Expand Down Expand Up @@ -86,8 +93,7 @@ export class QuickOpenModal extends Component<Props, State> {
searchSources = (query: string) => {
if (query == "") {
const results = this.props.sources;
this.setState({ results });
return;
return this.setState({ results });
}

if (this.isGotoSourceQuery()) {
Expand All @@ -108,8 +114,7 @@ export class QuickOpenModal extends Component<Props, State> {
results = variables;
}
if (query === "@" || query === "#") {
this.setState({ results });
return;
return this.setState({ results });
}

results = filter(results, query.slice(1), {
Expand Down Expand Up @@ -146,27 +151,24 @@ export class QuickOpenModal extends Component<Props, State> {
if (item == null) {
return;
}
const { selectLocation, selectedSource, query } = this.props;

if (this.isShortcutQuery()) {
this.setModifier(item);
return;
} else if (this.isGotoSourceQuery()) {
const location = parseLineColumn(query);
if (location != null) {
selectLocation({ ...location, sourceId: item.id });
}
} else if (this.isSymbolSearch()) {
if (selectedSource == null) {
return;
}
const line =
item.location && item.location.start ? item.location.start.line : 0;
selectLocation({ sourceId: selectedSource.get("id"), line });
} else {
selectLocation({ sourceId: item.id, line: 0 });
return this.setModifier(item);
}

this.closeModal();
if (this.isGotoSourceQuery()) {
const location = parseLineColumn(this.props.query);
return this.gotoLocation({ ...location, sourceId: item.id });
}

if (this.isSymbolSearch()) {
return this.gotoLocation({
line:
item.location && item.location.start ? item.location.start.line : 0
});
}

this.gotoLocation({ sourceId: item.id, line: 0 });
};

onSelectResultItem = (item: QuickOpenResult) => {
Expand All @@ -178,11 +180,15 @@ export class QuickOpenModal extends Component<Props, State> {
if (this.isVariableQuery()) {
const line =
item.location && item.location.start ? item.location.start.line : 0;
selectLocation({ sourceId: selectedSource.get("id"), line });
return selectLocation({
sourceId: selectedSource.get("id"),
line,
column: null
});
}

if (this.isFunctionQuery()) {
highlightLineRange({
return highlightLineRange({
...(item.location != null
? { start: item.location.start.line, end: item.location.end.line }
: {}),
Expand All @@ -191,9 +197,10 @@ export class QuickOpenModal extends Component<Props, State> {
}
};

traverseResults = (direction: number) => {
traverseResults = (e: SyntheticKeyboardEvent<HTMLElement>) => {
const direction = e.key === "ArrowUp" ? -1 : 1;
const { selectedIndex, results } = this.state;
const resultCount = this.resultCount();
const resultCount = this.getResultCount();
const index = selectedIndex + direction;
const nextIndex = (index + resultCount) % resultCount;

Expand All @@ -204,6 +211,20 @@ export class QuickOpenModal extends Component<Props, State> {
}
};

gotoLocation = (location: ?GotoLocationType) => {
const { selectLocation, selectedSource } = this.props;
const selectedSourceId = selectedSource ? selectedSource.get("id") : "";
if (location != null) {
const sourceId = location.sourceId ? location.sourceId : selectedSourceId;
selectLocation({
sourceId,
line: location.line,
column: location.column || null
});
this.closeModal();
}
};

onChange = (e: SyntheticInputEvent<HTMLElement>) => {
const { selectedSource, setQuickOpenQuery } = this.props;
setQuickOpenQuery(e.target.value);
Expand All @@ -215,81 +236,59 @@ export class QuickOpenModal extends Component<Props, State> {
};

onKeyDown = (e: SyntheticKeyboardEvent<HTMLElement>) => {
const { selectLocation, selectedSource, enabled, query } = this.props;
const { enabled, query } = this.props;
const { results, selectedIndex } = this.state;

if (!enabled || !results) {
return;
}

const canTraverse = !this.isGotoQuery();
if (e.key === "ArrowUp" && canTraverse) {
return this.traverseResults(-1);
} else if (e.key === "ArrowDown" && canTraverse) {
return this.traverseResults(1);
} else if (e.key === "Enter") {
if (e.key === "Enter") {
if (this.isGotoQuery()) {
if (!selectedSource) {
return;
}
const location = parseLineColumn(query);
if (location != null) {
selectLocation({ ...location, sourceId: selectedSource.get("id") });
}
} else if (this.isShortcutQuery()) {
this.setModifier(results[selectedIndex]);
return;
} else {
this.selectResultItem(e, results[selectedIndex]);
return this.gotoLocation(location);
}
return this.closeModal();
} else if (e.key === "Tab") {

if (this.isShortcutQuery()) {
return this.setModifier(results[selectedIndex]);
}

return this.selectResultItem(e, results[selectedIndex]);
}

if (e.key === "Tab") {
return this.closeModal();
}

if (["ArrowUp", "ArrowDown"].includes(e.key)) {
return this.traverseResults(e);
}
};

resultCount = () => {
getResultCount = () => {
const results = this.state.results;

if (results && results.length) {
return results.length;
}
return 0;
return results && results.length ? results.length : 0;
};

// Query helpers
isFunctionQuery = () => this.props.searchType === "functions";
isVariableQuery = () => this.props.searchType === "variables";
isSymbolSearch = () => this.isFunctionQuery() || this.isVariableQuery();
isGotoQuery = () => this.props.searchType === "goto";
isGotoSourceQuery = () => this.props.searchType === "gotoSource";
isShortcutQuery = () => this.props.searchType === "shortcuts";

renderResults() {
const { enabled, searchType } = this.props;
render() {
const { enabled, query, searchType } = this.props;
const { selectedIndex, results } = this.state;
if (!enabled || !results) {

if (!enabled) {
return null;
}

return (
<ResultList
key="results"
items={results}
selected={selectedIndex}
selectItem={this.selectResultItem}
ref="resultList"
{...(searchType === "sources" || searchType === "gotoSource"
? { size: "big" }
: {})}
/>
);
}

renderInput() {
const { query, searchType } = this.props;
const summaryMsg = L10N.getFormatStr(
"sourceSearch.resultsSummary1",
this.resultCount()
this.getResultCount()
);

const showSummary =
Expand All @@ -299,35 +298,34 @@ export class QuickOpenModal extends Component<Props, State> {
searchType === "shortcuts";

return (
<div key="input" className="input-wrapper">
<Modal in={enabled} handleClose={this.closeModal}>
<SearchInput
query={query}
count={this.resultCount()}
count={this.getResultCount()}
placeholder={L10N.getStr("sourceSearch.search")}
{...(showSummary === true ? { summaryMsg } : {})}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
handleClose={this.closeModal}
/>
</div>
);
}
render() {
const { enabled } = this.props;

if (!enabled) {
return null;
}

return (
<Modal in={enabled} handleClose={this.closeModal}>
{this.renderInput()}
{this.renderResults()}
{results && (
<ResultList
key="results"
items={results}
selected={selectedIndex}
selectItem={this.selectResultItem}
ref="resultList"
{...(searchType === "sources" || searchType === "gotoSource"
? { size: "big" }
: {})}
/>
)}
</Modal>
);
}
}

/* istanbul ignore next: ignoring testing of redux connection stuff */
function mapStateToProps(state) {
const selectedSource = getSelectedSource(state);
let symbols = null;
Expand All @@ -344,6 +342,5 @@ function mapStateToProps(state) {
};
}

export default connect(mapStateToProps, dispatch =>
bindActionCreators(actions, dispatch)
)(QuickOpenModal);
/* istanbul ignore next: ignoring testing of redux connection stuff */
export default connect(mapStateToProps, actions)(QuickOpenModal);
Loading

0 comments on commit 2c6bcec

Please sign in to comment.