summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/file-search.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/actions/file-search.js')
-rw-r--r--devtools/client/debugger/src/actions/file-search.js181
1 files changed, 181 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/file-search.js b/devtools/client/debugger/src/actions/file-search.js
new file mode 100644
index 0000000000..ec88b62044
--- /dev/null
+++ b/devtools/client/debugger/src/actions/file-search.js
@@ -0,0 +1,181 @@
+/* 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/>. */
+
+import {
+ clearSearch,
+ find,
+ findNext,
+ findPrev,
+ removeOverlay,
+ searchSourceForHighlight,
+} from "../utils/editor";
+import { renderWasmText } from "../utils/wasm";
+
+import {
+ getSelectedSourceId,
+ getSelectedSourceTextContent,
+ getFileSearchModifiers,
+ getFileSearchQuery,
+ getFileSearchResults,
+} from "../selectors";
+
+import {
+ closeActiveSearch,
+ clearHighlightLineRange,
+ setActiveSearch,
+} from "./ui";
+import { isFulfilled } from "../utils/async-value";
+
+export function doSearch(cx, query, editor) {
+ return ({ getState, dispatch }) => {
+ const sourceTextContent = getSelectedSourceTextContent(getState());
+ if (!sourceTextContent) {
+ return;
+ }
+
+ dispatch(setFileSearchQuery(cx, query));
+ dispatch(searchContents(cx, query, editor));
+ };
+}
+
+export function doSearchForHighlight(query, editor, line, ch) {
+ return async ({ getState, dispatch }) => {
+ const sourceTextContent = getSelectedSourceTextContent(getState());
+ if (!sourceTextContent) {
+ return;
+ }
+
+ dispatch(searchContentsForHighlight(query, editor, line, ch));
+ };
+}
+
+export function setFileSearchQuery(cx, query) {
+ return {
+ type: "UPDATE_FILE_SEARCH_QUERY",
+ cx,
+ query,
+ };
+}
+
+export function toggleFileSearchModifier(cx, modifier) {
+ return { type: "TOGGLE_FILE_SEARCH_MODIFIER", cx, modifier };
+}
+
+export function updateSearchResults(cx, characterIndex, line, matches) {
+ const matchIndex = matches.findIndex(
+ elm => elm.line === line && elm.ch === characterIndex
+ );
+
+ return {
+ type: "UPDATE_SEARCH_RESULTS",
+ cx,
+ results: {
+ matches,
+ matchIndex,
+ count: matches.length,
+ index: characterIndex,
+ },
+ };
+}
+
+export function searchContents(cx, query, editor, focusFirstResult = true) {
+ return async ({ getState, dispatch, searchWorker }) => {
+ const modifiers = getFileSearchModifiers(getState());
+ const sourceTextContent = getSelectedSourceTextContent(getState());
+
+ if (
+ !editor ||
+ !sourceTextContent ||
+ !isFulfilled(sourceTextContent) ||
+ !modifiers
+ ) {
+ return;
+ }
+ const selectedContent = sourceTextContent.value;
+
+ const ctx = { ed: editor, cm: editor.codeMirror };
+
+ if (!query) {
+ clearSearch(ctx.cm, query);
+ return;
+ }
+
+ let text;
+ if (selectedContent.type === "wasm") {
+ const selectedSourceId = getSelectedSourceId(getState());
+ text = renderWasmText(selectedSourceId, selectedContent).join("\n");
+ } else {
+ text = selectedContent.value;
+ }
+
+ const matches = await searchWorker.getMatches(query, text, modifiers);
+
+ const res = find(ctx, query, true, modifiers, focusFirstResult);
+ if (!res) {
+ return;
+ }
+
+ const { ch, line } = res;
+
+ dispatch(updateSearchResults(cx, ch, line, matches));
+ };
+}
+
+export function searchContentsForHighlight(query, editor, line, ch) {
+ return async ({ getState, dispatch }) => {
+ const modifiers = getFileSearchModifiers(getState());
+ const sourceTextContent = getSelectedSourceTextContent(getState());
+
+ if (!query || !editor || !sourceTextContent || !modifiers) {
+ return;
+ }
+
+ const ctx = { ed: editor, cm: editor.codeMirror };
+ searchSourceForHighlight(ctx, false, query, true, modifiers, line, ch);
+ };
+}
+
+export function traverseResults(cx, rev, editor) {
+ return async ({ getState, dispatch }) => {
+ if (!editor) {
+ return;
+ }
+
+ const ctx = { ed: editor, cm: editor.codeMirror };
+
+ const query = getFileSearchQuery(getState());
+ const modifiers = getFileSearchModifiers(getState());
+ const { matches } = getFileSearchResults(getState());
+
+ if (query === "") {
+ dispatch(setActiveSearch("file"));
+ }
+
+ if (modifiers) {
+ const matchedLocations = matches || [];
+ const findArgs = [ctx, query, true, modifiers];
+ const results = rev ? findPrev(...findArgs) : findNext(...findArgs);
+
+ if (!results) {
+ return;
+ }
+ const { ch, line } = results;
+ dispatch(updateSearchResults(cx, ch, line, matchedLocations));
+ }
+ };
+}
+
+export function closeFileSearch(cx, editor) {
+ return ({ getState, dispatch }) => {
+ if (editor) {
+ const query = getFileSearchQuery(getState());
+ const ctx = { ed: editor, cm: editor.codeMirror };
+ removeOverlay(ctx, query);
+ }
+
+ dispatch(setFileSearchQuery(cx, ""));
+ dispatch(closeActiveSearch());
+ dispatch(clearHighlightLineRange());
+ };
+}