ui.js (6527B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 import { 6 getActiveSearch, 7 getPaneCollapse, 8 getQuickOpenEnabled, 9 getSource, 10 getSourceTextContentForLocation, 11 getIgnoreListSourceUrls, 12 getSourceByURL, 13 getBreakpointsForSource, 14 } from "../selectors/index"; 15 import { selectSource } from "../actions/sources/select"; 16 import { getEditor, updateEditorLineWrapping } from "../utils/editor/index"; 17 import { blackboxSourceActorsForSource } from "./sources/blackbox"; 18 import { toggleBreakpoints } from "./breakpoints/index"; 19 import { copyToTheClipboard } from "../utils/clipboard"; 20 import { isFulfilled } from "../utils/async-value"; 21 import { primaryPaneTabs } from "../constants"; 22 23 export function setPrimaryPaneTab(tabName) { 24 return { type: "SET_PRIMARY_PANE_TAB", tabName }; 25 } 26 27 export function closeActiveSearch() { 28 return { 29 type: "TOGGLE_ACTIVE_SEARCH", 30 value: null, 31 }; 32 } 33 34 export function setActiveSearch(activeSearch) { 35 return ({ dispatch, getState }) => { 36 const activeSearchState = getActiveSearch(getState()); 37 if (activeSearchState === activeSearch) { 38 return; 39 } 40 41 if (getQuickOpenEnabled(getState())) { 42 dispatch({ type: "CLOSE_QUICK_OPEN" }); 43 } 44 45 // Open start panel if it was collapsed so the project search UI is visible 46 if ( 47 activeSearch === primaryPaneTabs.PROJECT_SEARCH && 48 getPaneCollapse(getState(), "start") 49 ) { 50 dispatch({ 51 type: "TOGGLE_PANE", 52 position: "start", 53 paneCollapsed: false, 54 }); 55 } 56 57 dispatch({ 58 type: "TOGGLE_ACTIVE_SEARCH", 59 value: activeSearch, 60 }); 61 }; 62 } 63 64 export function toggleFrameworkGrouping(toggleValue) { 65 return ({ dispatch }) => { 66 dispatch({ 67 type: "TOGGLE_FRAMEWORK_GROUPING", 68 value: toggleValue, 69 }); 70 }; 71 } 72 73 export function toggleInlinePreview(toggleValue) { 74 return ({ dispatch }) => { 75 dispatch({ 76 type: "TOGGLE_INLINE_PREVIEW", 77 value: toggleValue, 78 }); 79 }; 80 } 81 82 export function toggleEditorWrapping(toggleValue) { 83 return ({ dispatch }) => { 84 updateEditorLineWrapping(toggleValue); 85 86 dispatch({ 87 type: "TOGGLE_EDITOR_WRAPPING", 88 value: toggleValue, 89 }); 90 }; 91 } 92 93 export function toggleSourceMapsEnabled(toggleValue) { 94 return ({ dispatch }) => { 95 dispatch({ 96 type: "TOGGLE_SOURCE_MAPS_ENABLED", 97 value: toggleValue, 98 }); 99 }; 100 } 101 102 export function showSource(sourceId) { 103 return ({ dispatch, getState }) => { 104 const source = getSource(getState(), sourceId); 105 if (!source) { 106 return; 107 } 108 109 if (getPaneCollapse(getState(), "start")) { 110 dispatch({ 111 type: "TOGGLE_PANE", 112 position: "start", 113 paneCollapsed: false, 114 }); 115 } 116 117 dispatch(setPrimaryPaneTab("sources")); 118 119 dispatch(selectSource(source)); 120 }; 121 } 122 123 export function togglePaneCollapse(position, paneCollapsed) { 124 return ({ dispatch, getState }) => { 125 const prevPaneCollapse = getPaneCollapse(getState(), position); 126 if (prevPaneCollapse === paneCollapsed) { 127 return; 128 } 129 130 // Set active search to null when closing start panel if project search was active 131 if ( 132 position === "start" && 133 paneCollapsed && 134 getActiveSearch(getState()) === primaryPaneTabs.PROJECT_SEARCH 135 ) { 136 dispatch(closeActiveSearch()); 137 } 138 139 dispatch({ 140 type: "TOGGLE_PANE", 141 position, 142 paneCollapsed, 143 }); 144 }; 145 } 146 147 /** 148 * Highlight one or many lines in CodeMirror for a given source. 149 * 150 * @param {object} location 151 * @param {string} location.sourceId 152 * The precise source to highlight. 153 * @param {number} location.start 154 * The 1-based index of first line to highlight. 155 * @param {number} location.end 156 * The 1-based index of last line to highlight. 157 */ 158 export function highlightLineRange(location) { 159 return { 160 type: "HIGHLIGHT_LINES", 161 location, 162 }; 163 } 164 165 export function flashLineRange(location) { 166 return ({ dispatch }) => { 167 dispatch(highlightLineRange(location)); 168 setTimeout(() => dispatch(clearHighlightLineRange()), 200); 169 }; 170 } 171 172 export function clearHighlightLineRange() { 173 return { 174 type: "CLEAR_HIGHLIGHT_LINES", 175 }; 176 } 177 178 export function openConditionalPanel(location, log = false) { 179 if (!location) { 180 return null; 181 } 182 183 return { 184 type: "OPEN_CONDITIONAL_PANEL", 185 location, 186 log, 187 }; 188 } 189 190 export function closeConditionalPanel() { 191 return { 192 type: "CLOSE_CONDITIONAL_PANEL", 193 }; 194 } 195 196 export function updateViewport() { 197 const editor = getEditor(); 198 return { 199 type: "SET_VIEWPORT", 200 // The viewport locations are set and used for rendering column breakpoints 201 // markers correctly within the viewport. 202 // The offsets value represents an allowance of characters or lines offscreen to improve 203 // perceived performance of column breakpoint rendering. 204 viewport: editor.getLocationsInViewport(100, 20), 205 }; 206 } 207 208 export function setOrientation(orientation) { 209 return { type: "SET_ORIENTATION", orientation }; 210 } 211 212 export function setSearchOptions(searchKey, searchOptions) { 213 return { type: "SET_SEARCH_OPTIONS", searchKey, searchOptions }; 214 } 215 216 export function copyToClipboard(location) { 217 return ({ getState }) => { 218 const content = getSourceTextContentForLocation(getState(), location); 219 if (content && isFulfilled(content) && content.value.type === "text") { 220 copyToTheClipboard(content.value.value); 221 } 222 }; 223 } 224 225 export function setHideOrShowIgnoredSources(shouldHide) { 226 return { type: "HIDE_IGNORED_SOURCES", shouldHide }; 227 } 228 229 export function toggleSourceMapIgnoreList(shouldEnable) { 230 return async thunkArgs => { 231 const { dispatch, getState } = thunkArgs; 232 const ignoreListSourceUrls = getIgnoreListSourceUrls(getState()); 233 // Blackbox the source actors on the server 234 for (const url of ignoreListSourceUrls) { 235 const source = getSourceByURL(getState(), url); 236 await blackboxSourceActorsForSource(thunkArgs, source, shouldEnable); 237 // Disable breakpoints in sources on the ignore list 238 const breakpoints = getBreakpointsForSource(getState(), source); 239 await dispatch(toggleBreakpoints(shouldEnable, breakpoints)); 240 } 241 await dispatch({ 242 type: "ENABLE_SOURCEMAP_IGNORELIST", 243 shouldEnable, 244 }); 245 }; 246 } 247 248 export function togglePausedOverlay(shouldEnable) { 249 return { 250 type: "ENABLE_PAUSED_OVERLAY", 251 shouldEnable, 252 }; 253 }