summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/selectors/sources-tree.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/debugger/src/selectors/sources-tree.js')
-rw-r--r--devtools/client/debugger/src/selectors/sources-tree.js151
1 files changed, 151 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/selectors/sources-tree.js b/devtools/client/debugger/src/selectors/sources-tree.js
new file mode 100644
index 0000000000..8ef67c93ba
--- /dev/null
+++ b/devtools/client/debugger/src/selectors/sources-tree.js
@@ -0,0 +1,151 @@
+/* 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 { createSelector } from "reselect";
+
+/**
+ * Main selector to build the SourceTree,
+ * but this is also the source of data for the QuickOpen dialog.
+ *
+ * If no project directory root is set, this will return the thread items.
+ * Otherwise this will return the items where we set the directory root.
+ */
+export const getSourcesTreeSources = createSelector(
+ getProjectDirectoryRoot,
+ state => state.sourcesTree.threadItems,
+ (projectDirectoryRoot, threadItems) => {
+ // Only accept thread which have their thread attribute set.
+ // This may come late, if we receive ADD_SOURCES before INSERT_THREAD.
+ // Also filter out threads which have no sources, in case we had
+ // INSERT_THREAD with no ADD_SOURCES.
+ threadItems = threadItems.filter(
+ item => !!item.thread && !!item.children.length
+ );
+
+ if (projectDirectoryRoot) {
+ const directory = getDirectoryForUniquePath(
+ projectDirectoryRoot,
+ threadItems
+ );
+ if (directory) {
+ return directory.children;
+ }
+ return [];
+ }
+
+ return threadItems;
+ }
+);
+
+// This is used by QuickOpen UI
+/**
+ * Main selector for the QuickOpen dialog.
+ *
+ * The returns the list of all the reducer's source objects
+ * that are possibly displayed in the Source Tree.
+ * This doesn't return Source Tree Items, but the source objects.
+ */
+export const getDisplayedSourcesList = createSelector(
+ getSourcesTreeSources,
+ roots => {
+ const sources = [];
+ function walk(item) {
+ if (item.type == "source") {
+ sources.push(item.source);
+ } else {
+ for (const child of item.children) {
+ walk(child);
+ }
+ }
+ }
+ for (const root of roots) {
+ walk(root);
+ }
+ return sources;
+ }
+);
+
+export function getExpandedState(state) {
+ return state.sourcesTree.expanded;
+}
+
+export function getFocusedSourceItem(state) {
+ return state.sourcesTree.focusedItem;
+}
+
+export function getProjectDirectoryRoot(state) {
+ return state.sourcesTree.projectDirectoryRoot;
+}
+
+export function getProjectDirectoryRootName(state) {
+ return state.sourcesTree.projectDirectoryRootName;
+}
+
+/**
+ * Lookup for project root item, matching the given "unique path".
+ */
+function getDirectoryForUniquePath(projectRoot, threadItems) {
+ const sections = projectRoot.split("|");
+ const thread = sections.shift();
+
+ const threadItem = threadItems.find(item => {
+ return (
+ item.uniquePath == thread ||
+ (thread == "top-level" && item.thread.isTopLevel)
+ );
+ });
+ if (!threadItem) {
+ dump(
+ `No thread item for: ${projectRoot} -- ${thread} -- ${Object.keys(
+ threadItems
+ )}\n`
+ );
+ return null;
+ }
+
+ // If we selected a thread, the project root is for a Thread Item
+ // and it only contains `${thread}`
+ if (!sections.length) {
+ return threadItem;
+ }
+
+ const group = sections.shift();
+ for (const child of threadItem.children) {
+ if (child.groupName != group) {
+ continue;
+ }
+ // In case we picked a group, return it...
+ // project root looked like this `${thread}|${group}`
+ if (!sections.length) {
+ return child;
+ }
+ // ..otherwise, we picked a directory, so look for it by traversing the tree
+ // project root looked like this `${thread}|${group}|${directoryPath}`
+ const path = sections.shift();
+ return findPathInDirectory(child, path);
+ }
+ dump(` Unable to find group: ${group}\n`);
+ return null;
+
+ function findPathInDirectory(directory, path) {
+ for (const child of directory.children) {
+ if (child.type == "directory") {
+ // `path` should be the absolute path from the group/domain
+ if (child.path == path) {
+ return child;
+ }
+ // Ignore folders which doesn't match the beginning of the lookup path
+ if (!path.startsWith(child.path)) {
+ continue;
+ }
+ const match = findPathInDirectory(child, path);
+ if (match) {
+ return match;
+ }
+ }
+ }
+ dump(`Unable to find directory: ${path}\n`);
+ return null;
+ }
+}