/* 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 . */
import { createSelector } from "reselect";
import {
getPrettySourceURL,
isGenerated,
isPretty,
isJavaScript,
} from "../utils/source";
import { findPosition } from "../utils/breakpoint/breakpointPositions";
import { isFulfilled } from "../utils/async-value";
import { originalToGeneratedId } from "devtools/client/shared/source-map-loader/index";
import { prefs } from "../utils/prefs";
import {
hasSourceActor,
getSourceActor,
getBreakableLinesForSourceActors,
isSourceActorWithSourceMap,
} from "./source-actors";
import { getSourceTextContent } from "./sources-content";
export function hasSource(state, id) {
return state.sources.mutableSources.has(id);
}
export function getSource(state, id) {
return state.sources.mutableSources.get(id);
}
export function getSourceFromId(state, id) {
const source = getSource(state, id);
if (!source) {
console.warn(`source ${id} does not exist`);
}
return source;
}
export function getSourceByActorId(state, actorId) {
if (!hasSourceActor(state, actorId)) {
return null;
}
return getSource(state, getSourceActor(state, actorId).source);
}
function getSourcesByURL(state, url) {
return state.sources.mutableSourcesPerUrl.get(url) || [];
}
export function getSourceByURL(state, url) {
const foundSources = getSourcesByURL(state, url);
return foundSources[0];
}
// This is used by tabs selectors
export function getSpecificSourceByURL(state, url, isOriginal) {
const foundSources = getSourcesByURL(state, url);
return foundSources.find(source => source.isOriginal == isOriginal);
}
function getOriginalSourceByURL(state, url) {
return getSpecificSourceByURL(state, url, true);
}
export function getGeneratedSourceByURL(state, url) {
return getSpecificSourceByURL(state, url, false);
}
export function getGeneratedSource(state, source) {
if (!source) {
return null;
}
if (isGenerated(source)) {
return source;
}
return getSourceFromId(state, originalToGeneratedId(source.id));
}
export function getPendingSelectedLocation(state) {
return state.sources.pendingSelectedLocation;
}
export function getPrettySource(state, id) {
if (!id) {
return null;
}
const source = getSource(state, id);
if (!source) {
return null;
}
return getOriginalSourceByURL(state, getPrettySourceURL(source.url));
}
// This is only used by Project Search and tests.
export function getSourceList(state) {
return [...state.sources.mutableSources.values()];
}
// This is only used by tests and create.js
export function getSourceCount(state) {
return state.sources.mutableSources.size;
}
export function getSelectedLocation(state) {
return state.sources.selectedLocation;
}
export const getSelectedSource = createSelector(
getSelectedLocation,
selectedLocation => {
if (!selectedLocation) {
return undefined;
}
return selectedLocation.source;
}
);
// This is used by tests and pause reducers
export function getSelectedSourceId(state) {
const source = getSelectedSource(state);
return source?.id;
}
export function getShouldSelectOriginalLocation(state) {
return state.sources.shouldSelectOriginalLocation;
}
/**
* Gets the first source actor for the source and/or thread
* provided.
*
* @param {Object} state
* @param {String} sourceId
* The source used
* @param {String} [threadId]
* The thread to check, this is optional.
* @param {Object} sourceActor
*
*/
export function getFirstSourceActorForGeneratedSource(
state,
sourceId,
threadId
) {
let source = getSource(state, sourceId);
// The source may have been removed if we are being called by async code
if (!source) {
return null;
}
if (source.isOriginal) {
source = getSource(state, originalToGeneratedId(source.id));
}
const actors = getSourceActorsForSource(state, source.id);
if (threadId) {
return actors.find(actorInfo => actorInfo.thread == threadId) || null;
}
return actors[0] || null;
}
/**
* Get the source actor of the source
*
* @param {Object} state
* @param {String} id
* The source id
* @return {Array