summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/actions/ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/actions/ui.js')
-rw-r--r--devtools/client/debugger/src/actions/ui.js290
1 files changed, 290 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/actions/ui.js b/devtools/client/debugger/src/actions/ui.js
new file mode 100644
index 0000000000..67b2629135
--- /dev/null
+++ b/devtools/client/debugger/src/actions/ui.js
@@ -0,0 +1,290 @@
+/* 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 {
+ getActiveSearch,
+ getPaneCollapse,
+ getQuickOpenEnabled,
+ getSource,
+ getSourceContent,
+ getMainThread,
+ getIgnoreListSourceUrls,
+ getSourceByURL,
+ getBreakpointsForSource,
+} from "../selectors";
+import { selectSource } from "../actions/sources/select";
+import {
+ getEditor,
+ getLocationsInViewport,
+ updateDocuments,
+} from "../utils/editor";
+import { blackboxSourceActorsForSource } from "./sources/blackbox";
+import { toggleBreakpoints } from "./breakpoints";
+import { copyToTheClipboard } from "../utils/clipboard";
+import { isFulfilled } from "../utils/async-value";
+import { primaryPaneTabs } from "../constants";
+
+export function setPrimaryPaneTab(tabName) {
+ return { type: "SET_PRIMARY_PANE_TAB", tabName };
+}
+
+export function closeActiveSearch() {
+ return {
+ type: "TOGGLE_ACTIVE_SEARCH",
+ value: null,
+ };
+}
+
+export function setActiveSearch(activeSearch) {
+ return ({ dispatch, getState }) => {
+ const activeSearchState = getActiveSearch(getState());
+ if (activeSearchState === activeSearch) {
+ return;
+ }
+
+ if (getQuickOpenEnabled(getState())) {
+ dispatch({ type: "CLOSE_QUICK_OPEN" });
+ }
+
+ // Open start panel if it was collapsed so the project search UI is visible
+ if (
+ activeSearch === primaryPaneTabs.PROJECT_SEARCH &&
+ getPaneCollapse(getState(), "start")
+ ) {
+ dispatch({
+ type: "TOGGLE_PANE",
+ position: "start",
+ paneCollapsed: false,
+ });
+ }
+
+ dispatch({
+ type: "TOGGLE_ACTIVE_SEARCH",
+ value: activeSearch,
+ });
+ };
+}
+
+export function toggleFrameworkGrouping(toggleValue) {
+ return ({ dispatch, getState }) => {
+ dispatch({
+ type: "TOGGLE_FRAMEWORK_GROUPING",
+ value: toggleValue,
+ });
+ };
+}
+
+export function toggleInlinePreview(toggleValue) {
+ return ({ dispatch, getState }) => {
+ dispatch({
+ type: "TOGGLE_INLINE_PREVIEW",
+ value: toggleValue,
+ });
+ };
+}
+
+export function toggleEditorWrapping(toggleValue) {
+ return ({ dispatch, getState }) => {
+ updateDocuments(doc => doc.cm.setOption("lineWrapping", toggleValue));
+
+ dispatch({
+ type: "TOGGLE_EDITOR_WRAPPING",
+ value: toggleValue,
+ });
+ };
+}
+
+export function toggleSourceMapsEnabled(toggleValue) {
+ return ({ dispatch, getState }) => {
+ dispatch({
+ type: "TOGGLE_SOURCE_MAPS_ENABLED",
+ value: toggleValue,
+ });
+ };
+}
+
+export function showSource(cx, sourceId) {
+ return ({ dispatch, getState }) => {
+ const source = getSource(getState(), sourceId);
+ if (!source) {
+ return;
+ }
+
+ if (getPaneCollapse(getState(), "start")) {
+ dispatch({
+ type: "TOGGLE_PANE",
+ position: "start",
+ paneCollapsed: false,
+ });
+ }
+
+ dispatch(setPrimaryPaneTab("sources"));
+
+ dispatch(selectSource(cx, source));
+ };
+}
+
+export function togglePaneCollapse(position, paneCollapsed) {
+ return ({ dispatch, getState }) => {
+ const prevPaneCollapse = getPaneCollapse(getState(), position);
+ if (prevPaneCollapse === paneCollapsed) {
+ return;
+ }
+
+ // Set active search to null when closing start panel if project search was active
+ if (
+ position === "start" &&
+ paneCollapsed &&
+ getActiveSearch(getState()) === primaryPaneTabs.PROJECT_SEARCH
+ ) {
+ dispatch(closeActiveSearch());
+ }
+
+ dispatch({
+ type: "TOGGLE_PANE",
+ position,
+ paneCollapsed,
+ });
+ };
+}
+
+/**
+ * Highlight one or many lines in CodeMirror for a given source.
+ *
+ * @param {Object} location
+ * @param {String} location.sourceId
+ * The precise source to highlight.
+ * @param {Number} location.start
+ * The 1-based index of first line to highlight.
+ * @param {Number} location.end
+ * The 1-based index of last line to highlight.
+ */
+export function highlightLineRange(location) {
+ return {
+ type: "HIGHLIGHT_LINES",
+ location,
+ };
+}
+
+export function flashLineRange(location) {
+ return ({ dispatch }) => {
+ dispatch(highlightLineRange(location));
+ setTimeout(() => dispatch(clearHighlightLineRange()), 200);
+ };
+}
+
+export function clearHighlightLineRange() {
+ return {
+ type: "CLEAR_HIGHLIGHT_LINES",
+ };
+}
+
+export function openConditionalPanel(location, log = false) {
+ if (!location) {
+ return null;
+ }
+
+ return {
+ type: "OPEN_CONDITIONAL_PANEL",
+ location,
+ log,
+ };
+}
+
+export function closeConditionalPanel() {
+ return {
+ type: "CLOSE_CONDITIONAL_PANEL",
+ };
+}
+
+export function clearProjectDirectoryRoot(cx) {
+ return {
+ type: "SET_PROJECT_DIRECTORY_ROOT",
+ cx,
+ url: "",
+ name: "",
+ };
+}
+
+export function setProjectDirectoryRoot(cx, newRoot, newName) {
+ return ({ dispatch, getState }) => {
+ // If the new project root is against the top level thread,
+ // replace its thread ID with "top-level", so that later,
+ // getDirectoryForUniquePath could match the project root,
+ // even after a page reload where the new top level thread actor ID
+ // will be different.
+ const mainThread = getMainThread(getState());
+ if (mainThread && newRoot.startsWith(mainThread.actor)) {
+ newRoot = newRoot.replace(mainThread.actor, "top-level");
+ }
+ dispatch({
+ type: "SET_PROJECT_DIRECTORY_ROOT",
+ cx,
+ url: newRoot,
+ name: newName,
+ });
+ };
+}
+
+export function updateViewport() {
+ return {
+ type: "SET_VIEWPORT",
+ viewport: getLocationsInViewport(getEditor()),
+ };
+}
+
+export function updateCursorPosition(cursorPosition) {
+ return { type: "SET_CURSOR_POSITION", cursorPosition };
+}
+
+export function setOrientation(orientation) {
+ return { type: "SET_ORIENTATION", orientation };
+}
+
+export function setSearchOptions(searchKey, searchOptions) {
+ return { type: "SET_SEARCH_OPTIONS", searchKey, searchOptions };
+}
+
+export function copyToClipboard(location) {
+ return ({ dispatch, getState }) => {
+ const content = getSourceContent(getState(), location);
+ if (content && isFulfilled(content) && content.value.type === "text") {
+ copyToTheClipboard(content.value.value);
+ }
+ };
+}
+
+export function setJavascriptTracingLogMethod(value) {
+ return ({ dispatch, getState }) => {
+ dispatch({
+ type: "SET_JAVASCRIPT_TRACING_LOG_METHOD",
+ value,
+ });
+ };
+}
+
+export function setHideOrShowIgnoredSources(shouldHide) {
+ return ({ dispatch, getState }) => {
+ dispatch({ type: "HIDE_IGNORED_SOURCES", shouldHide });
+ };
+}
+
+export function toggleSourceMapIgnoreList(cx, shouldEnable) {
+ return async thunkArgs => {
+ const { dispatch, getState } = thunkArgs;
+ const ignoreListSourceUrls = getIgnoreListSourceUrls(getState());
+ // Blackbox the source actors on the server
+ for (const url of ignoreListSourceUrls) {
+ const source = getSourceByURL(getState(), url);
+ await blackboxSourceActorsForSource(thunkArgs, source, shouldEnable);
+ // Disable breakpoints in sources on the ignore list
+ const breakpoints = getBreakpointsForSource(getState(), source.id);
+ await dispatch(toggleBreakpoints(cx, shouldEnable, breakpoints));
+ }
+ await dispatch({
+ type: "ENABLE_SOURCEMAP_IGNORELIST",
+ shouldEnable,
+ });
+ };
+}