@treelocator/runtime 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +3 -0
- package/.turbo/turbo-build.log +30 -0
- package/.turbo/turbo-test.log +18 -0
- package/.turbo/turbo-ts.log +4 -0
- package/LICENSE +22 -0
- package/babel.config.js +14 -0
- package/dist/_generated_styles.d.ts +2 -0
- package/dist/_generated_styles.js +1734 -0
- package/dist/_generated_tree_icon.d.ts +2 -0
- package/dist/_generated_tree_icon.js +2 -0
- package/dist/adapters/HtmlElementTreeNode.d.ts +16 -0
- package/dist/adapters/HtmlElementTreeNode.js +43 -0
- package/dist/adapters/adapterApi.d.ts +30 -0
- package/dist/adapters/adapterApi.js +1 -0
- package/dist/adapters/createTreeNode.d.ts +2 -0
- package/dist/adapters/createTreeNode.js +17 -0
- package/dist/adapters/getElementInfo.d.ts +2 -0
- package/dist/adapters/getElementInfo.js +19 -0
- package/dist/adapters/getParentsPath.d.ts +2 -0
- package/dist/adapters/getParentsPath.js +35 -0
- package/dist/adapters/getTree.d.ts +1 -0
- package/dist/adapters/getTree.js +35 -0
- package/dist/adapters/goUpByTheTree.d.ts +7 -0
- package/dist/adapters/goUpByTheTree.js +22 -0
- package/dist/adapters/jsx/getExpressionData.d.ts +2 -0
- package/dist/adapters/jsx/getExpressionData.js +44 -0
- package/dist/adapters/jsx/getJSXComponentBoundingBox.d.ts +5 -0
- package/dist/adapters/jsx/getJSXComponentBoundingBox.js +46 -0
- package/dist/adapters/jsx/jsxAdapter.d.ts +11 -0
- package/dist/adapters/jsx/jsxAdapter.js +208 -0
- package/dist/adapters/jsx/runtimeStore.d.ts +10 -0
- package/dist/adapters/jsx/runtimeStore.js +87 -0
- package/dist/adapters/react/fiberToSimple.d.ts +3 -0
- package/dist/adapters/react/fiberToSimple.js +55 -0
- package/dist/adapters/react/findDebugSource.d.ts +5 -0
- package/dist/adapters/react/findDebugSource.js +13 -0
- package/dist/adapters/react/findFiberByHtmlElement.d.ts +2 -0
- package/dist/adapters/react/findFiberByHtmlElement.js +22 -0
- package/dist/adapters/react/gatherFiberRoots.d.ts +2 -0
- package/dist/adapters/react/gatherFiberRoots.js +29 -0
- package/dist/adapters/react/getAllFiberChildren.d.ts +2 -0
- package/dist/adapters/react/getAllFiberChildren.js +9 -0
- package/dist/adapters/react/getAllParentsElementsAndRootComponent.d.ts +8 -0
- package/dist/adapters/react/getAllParentsElementsAndRootComponent.js +34 -0
- package/dist/adapters/react/getAllWrappingParents.d.ts +2 -0
- package/dist/adapters/react/getAllWrappingParents.js +19 -0
- package/dist/adapters/react/getFiberComponentBoundingBox.d.ts +3 -0
- package/dist/adapters/react/getFiberComponentBoundingBox.js +27 -0
- package/dist/adapters/react/getFiberLabel.d.ts +3 -0
- package/dist/adapters/react/getFiberLabel.js +14 -0
- package/dist/adapters/react/getFiberOwnBoundingBox.d.ts +3 -0
- package/dist/adapters/react/getFiberOwnBoundingBox.js +6 -0
- package/dist/adapters/react/isStyled.d.ts +2 -0
- package/dist/adapters/react/isStyled.js +3 -0
- package/dist/adapters/react/makeFiberId.d.ts +2 -0
- package/dist/adapters/react/makeFiberId.js +16 -0
- package/dist/adapters/react/reactAdapter.d.ts +11 -0
- package/dist/adapters/react/reactAdapter.js +114 -0
- package/dist/adapters/react/searchDevtoolsRenderersForClosestTarget.d.ts +1 -0
- package/dist/adapters/react/searchDevtoolsRenderersForClosestTarget.js +11 -0
- package/dist/adapters/svelte/svelteAdapter.d.ts +22 -0
- package/dist/adapters/svelte/svelteAdapter.js +88 -0
- package/dist/adapters/vue/getVNodeBoundingBox.d.ts +4 -0
- package/dist/adapters/vue/getVNodeBoundingBox.js +31 -0
- package/dist/adapters/vue/vueAdapter.d.ts +15 -0
- package/dist/adapters/vue/vueAdapter.js +113 -0
- package/dist/browserApi.d.ts +103 -0
- package/dist/browserApi.js +160 -0
- package/dist/components/Button.d.ts +4 -0
- package/dist/components/Button.js +17 -0
- package/dist/components/ComponentOutline.d.ts +7 -0
- package/dist/components/ComponentOutline.js +93 -0
- package/dist/components/MaybeOutline.d.ts +7 -0
- package/dist/components/MaybeOutline.js +43 -0
- package/dist/components/Outline.d.ts +25 -0
- package/dist/components/Outline.js +135 -0
- package/dist/components/RenderBoxes.d.ts +4 -0
- package/dist/components/RenderBoxes.js +73 -0
- package/dist/components/Runtime.d.ts +3 -0
- package/dist/components/Runtime.js +188 -0
- package/dist/components/SimpleNodeOutline.d.ts +4 -0
- package/dist/components/SimpleNodeOutline.js +47 -0
- package/dist/components/Toast.d.ts +4 -0
- package/dist/components/Toast.js +68 -0
- package/dist/components/Tooltip.d.ts +5 -0
- package/dist/components/Tooltip.js +21 -0
- package/dist/consts.d.ts +6 -0
- package/dist/consts.js +5 -0
- package/dist/functions/cropPath.d.ts +1 -0
- package/dist/functions/cropPath.js +9 -0
- package/dist/functions/cropPath.test.d.ts +1 -0
- package/dist/functions/cropPath.test.js +16 -0
- package/dist/functions/deduplicateLabels.d.ts +2 -0
- package/dist/functions/deduplicateLabels.js +12 -0
- package/dist/functions/evalTemplate.d.ts +3 -0
- package/dist/functions/evalTemplate.js +7 -0
- package/dist/functions/evalTemplate.test.d.ts +1 -0
- package/dist/functions/evalTemplate.test.js +11 -0
- package/dist/functions/findNames.d.ts +5 -0
- package/dist/functions/findNames.js +15 -0
- package/dist/functions/formatAncestryChain.d.ts +9 -0
- package/dist/functions/formatAncestryChain.js +56 -0
- package/dist/functions/getBoundingRect.d.ts +1 -0
- package/dist/functions/getBoundingRect.js +11 -0
- package/dist/functions/getComposedBoundingBox.d.ts +2 -0
- package/dist/functions/getComposedBoundingBox.js +20 -0
- package/dist/functions/getIdsOnPathToRoot.d.ts +3 -0
- package/dist/functions/getIdsOnPathToRoot.js +15 -0
- package/dist/functions/getMultipleElementsBoundingBox.d.ts +2 -0
- package/dist/functions/getMultipleElementsBoundingBox.js +20 -0
- package/dist/functions/getPathToParent.d.ts +1 -0
- package/dist/functions/getPathToParent.js +15 -0
- package/dist/functions/getReferenceId.d.ts +1 -0
- package/dist/functions/getReferenceId.js +9 -0
- package/dist/functions/getUsableFileName.d.ts +1 -0
- package/dist/functions/getUsableFileName.js +17 -0
- package/dist/functions/getUsableFileName.test.d.ts +1 -0
- package/dist/functions/getUsableFileName.test.js +16 -0
- package/dist/functions/getUsableName.d.ts +2 -0
- package/dist/functions/getUsableName.js +47 -0
- package/dist/functions/isCombinationModifiersPressed.d.ts +4 -0
- package/dist/functions/isCombinationModifiersPressed.js +16 -0
- package/dist/functions/isLocatorsOwnElement.d.ts +1 -0
- package/dist/functions/isLocatorsOwnElement.js +3 -0
- package/dist/functions/mergeRects.d.ts +2 -0
- package/dist/functions/mergeRects.js +10 -0
- package/dist/functions/mergeRects.test.d.ts +1 -0
- package/dist/functions/mergeRects.test.js +23 -0
- package/dist/functions/nonNullable.d.ts +1 -0
- package/dist/functions/nonNullable.js +3 -0
- package/dist/functions/parseDataId.d.ts +3 -0
- package/dist/functions/parseDataId.js +44 -0
- package/dist/functions/transformPath.d.ts +1 -0
- package/dist/functions/transformPath.js +7 -0
- package/dist/functions/transformPath.test.d.ts +1 -0
- package/dist/functions/transformPath.test.js +16 -0
- package/dist/global.d.js +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +13 -0
- package/dist/initRuntime.d.ts +8 -0
- package/dist/initRuntime.js +80 -0
- package/dist/output.css +1733 -0
- package/dist/types/LabelData.d.ts +5 -0
- package/dist/types/LabelData.js +1 -0
- package/dist/types/TreeNode.d.ts +19 -0
- package/dist/types/TreeNode.js +1 -0
- package/dist/types/types.d.ts +53 -0
- package/dist/types/types.js +1 -0
- package/jest.config.ts +195 -0
- package/package.json +75 -0
- package/scripts/wrapCSS.js +26 -0
- package/scripts/wrapImage.js +24 -0
- package/src/_generated_styles.ts +1734 -0
- package/src/_generated_tree_icon.ts +2 -0
- package/src/adapters/HtmlElementTreeNode.ts +51 -0
- package/src/adapters/adapterApi.ts +35 -0
- package/src/adapters/createTreeNode.ts +25 -0
- package/src/adapters/getElementInfo.tsx +27 -0
- package/src/adapters/getParentsPath.tsx +49 -0
- package/src/adapters/getTree.tsx +45 -0
- package/src/adapters/goUpByTheTree.ts +20 -0
- package/src/adapters/jsx/getExpressionData.ts +47 -0
- package/src/adapters/jsx/getJSXComponentBoundingBox.ts +63 -0
- package/src/adapters/jsx/jsxAdapter.ts +276 -0
- package/src/adapters/jsx/runtimeStore.ts +94 -0
- package/src/adapters/react/fiberToSimple.tsx +72 -0
- package/src/adapters/react/findDebugSource.ts +15 -0
- package/src/adapters/react/findFiberByHtmlElement.ts +27 -0
- package/src/adapters/react/gatherFiberRoots.tsx +36 -0
- package/src/adapters/react/getAllFiberChildren.tsx +11 -0
- package/src/adapters/react/getAllParentsElementsAndRootComponent.ts +52 -0
- package/src/adapters/react/getAllWrappingParents.ts +25 -0
- package/src/adapters/react/getFiberComponentBoundingBox.ts +30 -0
- package/src/adapters/react/getFiberLabel.ts +20 -0
- package/src/adapters/react/getFiberOwnBoundingBox.ts +9 -0
- package/src/adapters/react/isStyled.ts +5 -0
- package/src/adapters/react/makeFiberId.tsx +19 -0
- package/src/adapters/react/reactAdapter.ts +148 -0
- package/src/adapters/react/searchDevtoolsRenderersForClosestTarget.ts +15 -0
- package/src/adapters/svelte/svelteAdapter.ts +111 -0
- package/src/adapters/vue/getVNodeBoundingBox.tsx +42 -0
- package/src/adapters/vue/vueAdapter.ts +139 -0
- package/src/assets/tree-icon.png +0 -0
- package/src/browserApi.ts +288 -0
- package/src/components/Button.tsx +14 -0
- package/src/components/ComponentOutline.tsx +98 -0
- package/src/components/MaybeOutline.tsx +49 -0
- package/src/components/Outline.tsx +153 -0
- package/src/components/RenderBoxes.tsx +57 -0
- package/src/components/Runtime.tsx +246 -0
- package/src/components/SimpleNodeOutline.tsx +27 -0
- package/src/components/Toast.tsx +83 -0
- package/src/components/Tooltip.tsx +28 -0
- package/src/consts.ts +7 -0
- package/src/functions/cropPath.test.ts +18 -0
- package/src/functions/cropPath.ts +12 -0
- package/src/functions/deduplicateLabels.ts +16 -0
- package/src/functions/evalTemplate.test.ts +12 -0
- package/src/functions/evalTemplate.ts +8 -0
- package/src/functions/findNames.ts +20 -0
- package/src/functions/formatAncestryChain.ts +80 -0
- package/src/functions/getBoundingRect.tsx +11 -0
- package/src/functions/getComposedBoundingBox.tsx +25 -0
- package/src/functions/getIdsOnPathToRoot.tsx +21 -0
- package/src/functions/getMultipleElementsBoundingBox.tsx +25 -0
- package/src/functions/getPathToParent.tsx +17 -0
- package/src/functions/getReferenceId.tsx +10 -0
- package/src/functions/getUsableFileName.test.tsx +24 -0
- package/src/functions/getUsableFileName.tsx +19 -0
- package/src/functions/getUsableName.ts +52 -0
- package/src/functions/isCombinationModifiersPressed.ts +32 -0
- package/src/functions/isLocatorsOwnElement.tsx +9 -0
- package/src/functions/mergeRects.test.ts +15 -0
- package/src/functions/mergeRects.tsx +12 -0
- package/src/functions/nonNullable.ts +3 -0
- package/src/functions/parseDataId.ts +62 -0
- package/src/functions/transformPath.test.ts +28 -0
- package/src/functions/transformPath.ts +7 -0
- package/src/global.d.ts +31 -0
- package/src/index.ts +18 -0
- package/src/initRuntime.ts +83 -0
- package/src/main.css +3 -0
- package/src/types/LabelData.ts +6 -0
- package/src/types/TreeNode.ts +22 -0
- package/src/types/types.ts +55 -0
- package/tailwind.config.js +9 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { parseDataId, parseDataPath, splitFullPath } from "../../functions/parseDataId";
|
|
2
|
+
import { goUpByTheTree } from "../goUpByTheTree";
|
|
3
|
+
import { HtmlElementTreeNode } from "../HtmlElementTreeNode";
|
|
4
|
+
import { getExpressionData } from "./getExpressionData";
|
|
5
|
+
import { getJSXComponentBoundingBox } from "./getJSXComponentBoundingBox";
|
|
6
|
+
export function getElementInfo(target) {
|
|
7
|
+
const found = target.closest("[data-locatorjs-id], [data-locatorjs]");
|
|
8
|
+
if (found && found instanceof HTMLElement && found.dataset && (found.dataset.locatorjsId || found.dataset.locatorjs || found.dataset.locatorjsStyled)) {
|
|
9
|
+
const dataId = found.dataset.locatorjsId;
|
|
10
|
+
const dataPath = found.dataset.locatorjs;
|
|
11
|
+
const styledDataId = found.dataset.locatorjsStyled;
|
|
12
|
+
if (!dataId && !dataPath) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
let fileFullPath;
|
|
16
|
+
if (dataPath) {
|
|
17
|
+
const parsed = parseDataPath(dataPath);
|
|
18
|
+
if (!parsed) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
[fileFullPath] = parsed;
|
|
22
|
+
} else if (dataId) {
|
|
23
|
+
[fileFullPath] = parseDataId(dataId);
|
|
24
|
+
} else {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const locatorData = window.__LOCATOR_DATA__;
|
|
28
|
+
const fileData = locatorData?.[fileFullPath];
|
|
29
|
+
|
|
30
|
+
// Handle styled components (only when locatorData is available)
|
|
31
|
+
const [styledFileFullPath, styledId] = styledDataId ? parseDataId(styledDataId) : [null, null];
|
|
32
|
+
const styledFileData = styledFileFullPath && locatorData?.[styledFileFullPath];
|
|
33
|
+
const styledExpData = styledFileData && styledFileData.styledDefinitions[Number(styledId)];
|
|
34
|
+
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
36
|
+
const styledLink = styledExpData && {
|
|
37
|
+
filePath: styledFileData.filePath,
|
|
38
|
+
projectPath: styledFileData.projectPath,
|
|
39
|
+
column: (styledExpData.loc?.start.column || 0) + 1,
|
|
40
|
+
line: styledExpData.loc?.start.line || 0
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Get expression data (works with or without locatorData)
|
|
44
|
+
const expData = getExpressionData(found, fileData || null);
|
|
45
|
+
if (!expData) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Extract file path components
|
|
50
|
+
let filePath;
|
|
51
|
+
let projectPath;
|
|
52
|
+
if (fileData) {
|
|
53
|
+
filePath = fileData.filePath;
|
|
54
|
+
projectPath = fileData.projectPath;
|
|
55
|
+
} else {
|
|
56
|
+
// If no fileData, split the full path
|
|
57
|
+
[projectPath, filePath] = splitFullPath(fileFullPath);
|
|
58
|
+
}
|
|
59
|
+
const wrappingComponent = expData.wrappingComponentId !== null && fileData ? fileData.components[Number(expData.wrappingComponentId)] : null;
|
|
60
|
+
return {
|
|
61
|
+
thisElement: {
|
|
62
|
+
box: found.getBoundingClientRect(),
|
|
63
|
+
label: expData.name,
|
|
64
|
+
link: {
|
|
65
|
+
filePath,
|
|
66
|
+
projectPath,
|
|
67
|
+
column: (expData.loc.start.column || 0) + 1,
|
|
68
|
+
line: expData.loc.start.line || 0
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
htmlElement: found,
|
|
72
|
+
parentElements: [],
|
|
73
|
+
componentBox: getJSXComponentBoundingBox(found, locatorData || {}, fileFullPath, Number(expData.wrappingComponentId)),
|
|
74
|
+
componentsLabels: wrappingComponent ? [{
|
|
75
|
+
label: wrappingComponent.name || "component",
|
|
76
|
+
link: {
|
|
77
|
+
filePath,
|
|
78
|
+
projectPath,
|
|
79
|
+
column: (wrappingComponent.loc?.start.column || 0) + 1,
|
|
80
|
+
line: wrappingComponent.loc?.start.line || 0
|
|
81
|
+
}
|
|
82
|
+
}] : []
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// return deduplicateLabels(labels);
|
|
87
|
+
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
export class JSXTreeNodeElement extends HtmlElementTreeNode {
|
|
91
|
+
getSource() {
|
|
92
|
+
const dataId = this.element.dataset.locatorjsId;
|
|
93
|
+
const dataPath = this.element.dataset.locatorjs;
|
|
94
|
+
if (!dataId && !dataPath) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
let fileFullPath;
|
|
98
|
+
if (dataPath) {
|
|
99
|
+
const parsed = parseDataPath(dataPath);
|
|
100
|
+
if (!parsed) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
[fileFullPath] = parsed;
|
|
104
|
+
} else if (dataId) {
|
|
105
|
+
[fileFullPath] = parseDataId(dataId);
|
|
106
|
+
} else {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const locatorData = window.__LOCATOR_DATA__;
|
|
110
|
+
const fileData = locatorData?.[fileFullPath];
|
|
111
|
+
|
|
112
|
+
// Get expression data (works with or without locatorData)
|
|
113
|
+
const expData = getExpressionData(this.element, fileData || null);
|
|
114
|
+
if (expData) {
|
|
115
|
+
let fileName;
|
|
116
|
+
let projectPath;
|
|
117
|
+
if (fileData) {
|
|
118
|
+
fileName = fileData.filePath;
|
|
119
|
+
projectPath = fileData.projectPath;
|
|
120
|
+
} else {
|
|
121
|
+
// If no fileData, split the full path
|
|
122
|
+
[projectPath, fileName] = splitFullPath(fileFullPath);
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
fileName,
|
|
126
|
+
projectPath,
|
|
127
|
+
columnNumber: (expData.loc.start.column || 0) + 1,
|
|
128
|
+
lineNumber: expData.loc.start.line || 0
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
getComponent() {
|
|
134
|
+
const dataId = this.element.dataset.locatorjsId;
|
|
135
|
+
const dataPath = this.element.dataset.locatorjs;
|
|
136
|
+
if (!dataId && !dataPath) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
let fileFullPath;
|
|
140
|
+
if (dataPath) {
|
|
141
|
+
const parsed = parseDataPath(dataPath);
|
|
142
|
+
if (!parsed) {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
[fileFullPath] = parsed;
|
|
146
|
+
} else if (dataId) {
|
|
147
|
+
[fileFullPath] = parseDataId(dataId);
|
|
148
|
+
} else {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
const locatorData = window.__LOCATOR_DATA__;
|
|
152
|
+
const fileData = locatorData?.[fileFullPath];
|
|
153
|
+
|
|
154
|
+
// Component information is only available when we have fileData
|
|
155
|
+
if (fileData) {
|
|
156
|
+
const expData = getExpressionData(this.element, fileData);
|
|
157
|
+
if (expData && expData.wrappingComponentId !== null) {
|
|
158
|
+
const component = fileData.components[expData.wrappingComponentId];
|
|
159
|
+
if (component) {
|
|
160
|
+
return {
|
|
161
|
+
label: component.name || "component",
|
|
162
|
+
definitionLink: {
|
|
163
|
+
fileName: fileData.filePath,
|
|
164
|
+
projectPath: fileData.projectPath,
|
|
165
|
+
columnNumber: (component.loc?.start.column || 0) + 1,
|
|
166
|
+
lineNumber: component.loc?.start.line || 0
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function getTree(element) {
|
|
176
|
+
const originalRoot = new JSXTreeNodeElement(element);
|
|
177
|
+
return goUpByTheTree(originalRoot);
|
|
178
|
+
}
|
|
179
|
+
function getParentsPaths(element) {
|
|
180
|
+
const path = [];
|
|
181
|
+
let currentElement = element;
|
|
182
|
+
let previousComponentKey = null;
|
|
183
|
+
do {
|
|
184
|
+
if (currentElement) {
|
|
185
|
+
const info = getElementInfo(currentElement);
|
|
186
|
+
const currentComponentKey = JSON.stringify(info?.componentsLabels);
|
|
187
|
+
if (info && currentComponentKey !== previousComponentKey) {
|
|
188
|
+
previousComponentKey = currentComponentKey;
|
|
189
|
+
const link = info.thisElement.link;
|
|
190
|
+
const label = info.thisElement.label;
|
|
191
|
+
if (link) {
|
|
192
|
+
path.push({
|
|
193
|
+
title: label,
|
|
194
|
+
link: link
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
currentElement = currentElement.parentElement;
|
|
200
|
+
} while (currentElement);
|
|
201
|
+
return path;
|
|
202
|
+
}
|
|
203
|
+
const jsxAdapter = {
|
|
204
|
+
getElementInfo,
|
|
205
|
+
getTree,
|
|
206
|
+
getParentsPaths
|
|
207
|
+
};
|
|
208
|
+
export default jsxAdapter;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { parseDataId, parseDataPath, splitFullPath } from "../../functions/parseDataId";
|
|
2
|
+
export function getDataForDataId(dataId) {
|
|
3
|
+
let fileFullPath;
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
5
|
+
let expData;
|
|
6
|
+
let filePath = "";
|
|
7
|
+
let projectPath = "";
|
|
8
|
+
const data = window.__LOCATOR_DATA__;
|
|
9
|
+
|
|
10
|
+
// Try parsing as path format first (new format)
|
|
11
|
+
const pathParsed = parseDataPath(dataId);
|
|
12
|
+
if (pathParsed) {
|
|
13
|
+
const [fullPath, line, column] = pathParsed;
|
|
14
|
+
fileFullPath = fullPath;
|
|
15
|
+
if (data) {
|
|
16
|
+
const fileData = data[fileFullPath];
|
|
17
|
+
if (fileData) {
|
|
18
|
+
// Find expression by location
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
+
expData = fileData.expressions.find(exp => exp.loc.start.line === line && exp.loc.start.column === column);
|
|
21
|
+
if (expData) {
|
|
22
|
+
filePath = fileData.filePath;
|
|
23
|
+
projectPath = fileData.projectPath;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// If no data or not found, create minimal data from path
|
|
29
|
+
if (!expData) {
|
|
30
|
+
[projectPath, filePath] = splitFullPath(fullPath);
|
|
31
|
+
expData = {
|
|
32
|
+
name: "Component",
|
|
33
|
+
loc: {
|
|
34
|
+
start: {
|
|
35
|
+
line,
|
|
36
|
+
column
|
|
37
|
+
},
|
|
38
|
+
end: {
|
|
39
|
+
line,
|
|
40
|
+
column
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
wrappingComponentId: null
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
// Fall back to ID format (old format) - requires __LOCATOR_DATA__
|
|
48
|
+
if (!data) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const [fullPath, id] = parseDataId(dataId);
|
|
52
|
+
fileFullPath = fullPath;
|
|
53
|
+
const fileData = data[fileFullPath];
|
|
54
|
+
if (!fileData) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
expData = fileData.expressions[Number(id)];
|
|
58
|
+
filePath = fileData.filePath;
|
|
59
|
+
projectPath = fileData.projectPath;
|
|
60
|
+
}
|
|
61
|
+
if (!expData) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
const link = {
|
|
65
|
+
filePath,
|
|
66
|
+
projectPath,
|
|
67
|
+
column: expData.loc.start.column || 0,
|
|
68
|
+
line: expData.loc.start.line || 0
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// let label;
|
|
72
|
+
// if (expData.type === "jsx") {
|
|
73
|
+
// label =
|
|
74
|
+
// (expData.wrappingComponent ? `${expData.wrappingComponent}: ` : "") +
|
|
75
|
+
// expData.name;
|
|
76
|
+
// } else {
|
|
77
|
+
// label = `${expData.htmlTag ? `styled.${expData.htmlTag}` : "styled"}${
|
|
78
|
+
// expData.name ? `: ${expData.name}` : ""
|
|
79
|
+
// }`;
|
|
80
|
+
// }
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
link,
|
|
84
|
+
label: expData.name,
|
|
85
|
+
componentLabel: expData
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { getBoundingRect } from "../../functions/getBoundingRect";
|
|
2
|
+
import { getComposedBoundingBox } from "../../functions/getComposedBoundingBox";
|
|
3
|
+
import { getUsableName } from "../../functions/getUsableName";
|
|
4
|
+
import { getAllFiberChildren } from "./getAllFiberChildren";
|
|
5
|
+
import { makeFiberId } from "./makeFiberId";
|
|
6
|
+
export function fiberToSimple(fiber, manualChildren) {
|
|
7
|
+
let simpleChildren;
|
|
8
|
+
if (fiber.elementType?.styledComponentId) {
|
|
9
|
+
const children = getAllFiberChildren(fiber);
|
|
10
|
+
if (children.length === 1) {
|
|
11
|
+
const simple = fiberToSimple(children[0], manualChildren);
|
|
12
|
+
simple.name = `${simple.name} (styled)`;
|
|
13
|
+
return simple;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
if (manualChildren) {
|
|
17
|
+
simpleChildren = manualChildren;
|
|
18
|
+
} else {
|
|
19
|
+
const children = getAllFiberChildren(fiber);
|
|
20
|
+
simpleChildren = children.map(child => {
|
|
21
|
+
return fiberToSimple(child);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const element = fiber.stateNode instanceof Element || fiber.stateNode instanceof Text ? fiber.stateNode : fiber.stateNode?.containerInfo;
|
|
25
|
+
if (element) {
|
|
26
|
+
const box = getBoundingRect(element);
|
|
27
|
+
return {
|
|
28
|
+
type: "element",
|
|
29
|
+
element: element,
|
|
30
|
+
fiber: fiber,
|
|
31
|
+
uniqueId: makeFiberId(fiber),
|
|
32
|
+
name: getUsableName(fiber),
|
|
33
|
+
box: box || getComposedBoundingBox(simpleChildren),
|
|
34
|
+
children: simpleChildren,
|
|
35
|
+
source: fiber._debugSource || null
|
|
36
|
+
};
|
|
37
|
+
} else {
|
|
38
|
+
return {
|
|
39
|
+
type: "component",
|
|
40
|
+
fiber: fiber,
|
|
41
|
+
uniqueId: makeFiberId(fiber),
|
|
42
|
+
name: getUsableName(fiber),
|
|
43
|
+
box: getComposedBoundingBox(simpleChildren),
|
|
44
|
+
children: simpleChildren,
|
|
45
|
+
source: fiber._debugSource || null,
|
|
46
|
+
definitionSourceFile: simpleChildren.reduce((acc, curr) => {
|
|
47
|
+
if (curr.source?.fileName) {
|
|
48
|
+
return curr.source?.fileName;
|
|
49
|
+
} else {
|
|
50
|
+
return acc;
|
|
51
|
+
}
|
|
52
|
+
}, null)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { findDebugSource } from "./findDebugSource";
|
|
2
|
+
export function findFiberByHtmlElement(target, shouldHaveDebugSource) {
|
|
3
|
+
const renderers = window.__REACT_DEVTOOLS_GLOBAL_HOOK__?.renderers;
|
|
4
|
+
// console.log("RENDERERS: ", renderers);
|
|
5
|
+
const renderersValues = renderers?.values();
|
|
6
|
+
if (renderersValues) {
|
|
7
|
+
for (const renderer of Array.from(renderersValues)) {
|
|
8
|
+
if (renderer.findFiberByHostInstance) {
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
10
|
+
const found = renderer.findFiberByHostInstance(target);
|
|
11
|
+
if (found) {
|
|
12
|
+
if (shouldHaveDebugSource) {
|
|
13
|
+
return findDebugSource(found)?.fiber || null;
|
|
14
|
+
} else {
|
|
15
|
+
return found;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
|
|
3
|
+
import { findFiberByHtmlElement } from "./findFiberByHtmlElement";
|
|
4
|
+
export function gatherFiberRoots(parentNode, mutable_foundFibers) {
|
|
5
|
+
const nodes = parentNode.childNodes;
|
|
6
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
7
|
+
const node = nodes[i];
|
|
8
|
+
if (node instanceof HTMLElement) {
|
|
9
|
+
const fiber = node._reactRootContainer?._internalRoot?.current || node._reactRootContainer?.current;
|
|
10
|
+
if (fiber) {
|
|
11
|
+
mutable_foundFibers.push(getRoot(fiber));
|
|
12
|
+
} else {
|
|
13
|
+
const rootFiber = findFiberByHtmlElement(node, false);
|
|
14
|
+
if (rootFiber) {
|
|
15
|
+
mutable_foundFibers.push(getRoot(rootFiber));
|
|
16
|
+
} else {
|
|
17
|
+
gatherFiberRoots(node, mutable_foundFibers);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function getRoot(fiber) {
|
|
24
|
+
let thisFiber = fiber;
|
|
25
|
+
while (thisFiber.return) {
|
|
26
|
+
thisFiber = thisFiber.return;
|
|
27
|
+
}
|
|
28
|
+
return thisFiber;
|
|
29
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Fiber } from "@locator/shared";
|
|
2
|
+
import { SimpleDOMRect } from "../../types/types";
|
|
3
|
+
import { ElementInfo } from "../adapterApi";
|
|
4
|
+
export declare function getAllParentsElementsAndRootComponent(fiber: Fiber): {
|
|
5
|
+
component: Fiber;
|
|
6
|
+
componentBox: SimpleDOMRect;
|
|
7
|
+
parentElements: ElementInfo[];
|
|
8
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getUsableName } from "../../functions/getUsableName";
|
|
2
|
+
import { mergeRects } from "../../functions/mergeRects";
|
|
3
|
+
import { getFiberComponentBoundingBox } from "./getFiberComponentBoundingBox";
|
|
4
|
+
import { isStyledElement } from "./isStyled";
|
|
5
|
+
export function getAllParentsElementsAndRootComponent(fiber) {
|
|
6
|
+
const parentElements = [];
|
|
7
|
+
const deepestElement = fiber.stateNode;
|
|
8
|
+
if (!deepestElement || !(deepestElement instanceof HTMLElement)) {
|
|
9
|
+
throw new Error("This functions works only for Fibres with HTMLElement stateNode");
|
|
10
|
+
}
|
|
11
|
+
let componentBox = deepestElement.getBoundingClientRect();
|
|
12
|
+
|
|
13
|
+
// For styled-components we rather use parent element
|
|
14
|
+
let currentFiber = isStyledElement(fiber) && fiber._debugOwner ? fiber._debugOwner : fiber;
|
|
15
|
+
while (currentFiber._debugOwner || currentFiber.return) {
|
|
16
|
+
currentFiber = currentFiber._debugOwner || currentFiber.return;
|
|
17
|
+
const currentElement = currentFiber.stateNode;
|
|
18
|
+
if (!currentElement || !(currentElement instanceof HTMLElement)) {
|
|
19
|
+
return {
|
|
20
|
+
component: currentFiber,
|
|
21
|
+
parentElements,
|
|
22
|
+
componentBox: getFiberComponentBoundingBox(currentFiber) || componentBox
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const usableName = getUsableName(currentFiber);
|
|
26
|
+
componentBox = mergeRects(componentBox, currentElement.getBoundingClientRect());
|
|
27
|
+
parentElements.push({
|
|
28
|
+
box: currentElement.getBoundingClientRect(),
|
|
29
|
+
label: usableName,
|
|
30
|
+
link: null
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
throw new Error("Could not find root component");
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getAllFiberChildren } from "./getAllFiberChildren";
|
|
2
|
+
export function getAllWrappingParents(fiber) {
|
|
3
|
+
const parents = [fiber];
|
|
4
|
+
let currentFiber = fiber;
|
|
5
|
+
while (currentFiber.return) {
|
|
6
|
+
currentFiber = currentFiber.return;
|
|
7
|
+
if (currentFiber.stateNode && currentFiber.stateNode instanceof HTMLElement) {
|
|
8
|
+
return parents;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// if there is multiple children, it means the parent is not just wrapping this one
|
|
12
|
+
const children = getAllFiberChildren(currentFiber);
|
|
13
|
+
if (children.length > 1) {
|
|
14
|
+
return parents;
|
|
15
|
+
}
|
|
16
|
+
parents.push(currentFiber);
|
|
17
|
+
}
|
|
18
|
+
return parents;
|
|
19
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getFiberOwnBoundingBox } from "./getFiberOwnBoundingBox";
|
|
2
|
+
import { getAllFiberChildren } from "./getAllFiberChildren";
|
|
3
|
+
import { mergeRects } from "../../functions/mergeRects";
|
|
4
|
+
const MAX_LEVEL = 6;
|
|
5
|
+
export function getFiberComponentBoundingBox(fiber, level = 0) {
|
|
6
|
+
const children = getAllFiberChildren(fiber);
|
|
7
|
+
let composedRect;
|
|
8
|
+
children.forEach(child => {
|
|
9
|
+
let box = getFiberOwnBoundingBox(child);
|
|
10
|
+
if (!box && level < MAX_LEVEL) {
|
|
11
|
+
box = getFiberComponentBoundingBox(child, level + 1) || null;
|
|
12
|
+
}
|
|
13
|
+
if (!box) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (box.width <= 0 || box.height <= 0) {
|
|
17
|
+
// ignore zero-sized rects
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (composedRect) {
|
|
21
|
+
composedRect = mergeRects(composedRect, box);
|
|
22
|
+
} else {
|
|
23
|
+
composedRect = box;
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return composedRect;
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getUsableName } from "../../functions/getUsableName";
|
|
2
|
+
export function getFiberLabel(fiber, source) {
|
|
3
|
+
const name = getUsableName(fiber);
|
|
4
|
+
const label = {
|
|
5
|
+
label: name,
|
|
6
|
+
link: source ? {
|
|
7
|
+
filePath: source.fileName,
|
|
8
|
+
projectPath: "",
|
|
9
|
+
line: source.lineNumber,
|
|
10
|
+
column: source.columnNumber || 0
|
|
11
|
+
} : null
|
|
12
|
+
};
|
|
13
|
+
return label;
|
|
14
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
let globalIdCounter = 0;
|
|
2
|
+
const globalIdMap = new WeakMap();
|
|
3
|
+
export function makeFiberId(fiber) {
|
|
4
|
+
if (fiber._debugID) {
|
|
5
|
+
return fiber._debugID.toString();
|
|
6
|
+
}
|
|
7
|
+
const found = globalIdMap.get(fiber);
|
|
8
|
+
if (found) {
|
|
9
|
+
return found;
|
|
10
|
+
} else {
|
|
11
|
+
globalIdCounter++;
|
|
12
|
+
const id = `fiber:${globalIdCounter}`;
|
|
13
|
+
globalIdMap.set(fiber, id);
|
|
14
|
+
return id;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AdapterObject, FullElementInfo } from "../adapterApi";
|
|
2
|
+
import { Source } from "@locator/shared";
|
|
3
|
+
import { TreeNodeComponent } from "../../types/TreeNode";
|
|
4
|
+
import { HtmlElementTreeNode } from "../HtmlElementTreeNode";
|
|
5
|
+
export declare function getElementInfo(found: HTMLElement): FullElementInfo | null;
|
|
6
|
+
export declare class ReactTreeNodeElement extends HtmlElementTreeNode {
|
|
7
|
+
getSource(): Source | null;
|
|
8
|
+
getComponent(): TreeNodeComponent | null;
|
|
9
|
+
}
|
|
10
|
+
declare const reactAdapter: AdapterObject;
|
|
11
|
+
export default reactAdapter;
|