tabs.js (2987B)
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 /** 6 * Redux actions for the editor tabs 7 */ 8 9 import { selectSource } from "./sources/index"; 10 11 import { getSelectedLocation, getOpenedSources } from "../selectors/index"; 12 13 export function addTab(source) { 14 return { 15 type: "ADD_TAB", 16 source, 17 }; 18 } 19 20 export function moveTab(url, tabIndex) { 21 return { 22 type: "MOVE_TAB", 23 url, 24 tabIndex, 25 }; 26 } 27 28 export function moveTabBySourceId(sourceId, tabIndex) { 29 return { 30 type: "MOVE_TAB_BY_SOURCE_ID", 31 sourceId, 32 tabIndex, 33 }; 34 } 35 36 export function closeTabForSource(source) { 37 return ({ dispatch }) => { 38 dispatch(closeTabsForSources([source])); 39 }; 40 } 41 42 export function closeTabsForSources(sources) { 43 return ({ dispatch, getState }) => { 44 if (!sources.length) { 45 return; 46 } 47 48 // If we are removing the tabs for the selected location, 49 // we need to select another source 50 const newSourceToSelect = getNewSourceToSelect(getState(), sources); 51 52 dispatch({ type: "CLOSE_TABS_FOR_SOURCES", sources }); 53 54 dispatch(selectSource(newSourceToSelect)); 55 }; 56 } 57 58 /** 59 * Compute the potential new source to select while closing tabs for a given set of sources. 60 * 61 * @param {object} state 62 * Redux state object. 63 * @param {Array<Source>} closedSources 64 * Ordered list of sources which should be closed. 65 * Should be a consecutive list of tabs matching the order of tabs reducer. 66 */ 67 function getNewSourceToSelect(state, closedSources) { 68 const selectedLocation = getSelectedLocation(state); 69 // Do not try to select any source if none was selected before 70 if (!selectedLocation) { 71 return null; 72 } 73 let selectedSource = selectedLocation.source; 74 75 // When a source is pretty printed, the tab always refer to its minimized/generated source 76 if (selectedSource.isPrettyPrinted) { 77 selectedSource = selectedSource.generatedSource; 78 } 79 80 // Keep selecting the same source if we aren't removing the currently selected source 81 if (!closedSources.includes(selectedSource)) { 82 return selectedSource; 83 } 84 const openedSources = getOpenedSources(state); 85 const selectedSourceIndex = openedSources.indexOf(selectedSource); 86 87 // Find the first source **after** the currently selected one, which will still be open and select it 88 for ( 89 let index = selectedSourceIndex + 1; 90 index < openedSources.length; 91 index++ 92 ) { 93 const source = openedSources[index]; 94 if (!closedSources.includes(source)) { 95 return source; 96 } 97 } 98 99 // Otherwise find the last source **before** the currently selected one. 100 for (let index = selectedSourceIndex - 1; index >= 0; index--) { 101 const source = openedSources[index]; 102 if (!closedSources.includes(source)) { 103 return source; 104 } 105 } 106 107 // It looks like we removed all the tabs 108 return null; 109 }