@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.
Files changed (227) hide show
  1. package/.eslintrc +3 -0
  2. package/.turbo/turbo-build.log +30 -0
  3. package/.turbo/turbo-test.log +18 -0
  4. package/.turbo/turbo-ts.log +4 -0
  5. package/LICENSE +22 -0
  6. package/babel.config.js +14 -0
  7. package/dist/_generated_styles.d.ts +2 -0
  8. package/dist/_generated_styles.js +1734 -0
  9. package/dist/_generated_tree_icon.d.ts +2 -0
  10. package/dist/_generated_tree_icon.js +2 -0
  11. package/dist/adapters/HtmlElementTreeNode.d.ts +16 -0
  12. package/dist/adapters/HtmlElementTreeNode.js +43 -0
  13. package/dist/adapters/adapterApi.d.ts +30 -0
  14. package/dist/adapters/adapterApi.js +1 -0
  15. package/dist/adapters/createTreeNode.d.ts +2 -0
  16. package/dist/adapters/createTreeNode.js +17 -0
  17. package/dist/adapters/getElementInfo.d.ts +2 -0
  18. package/dist/adapters/getElementInfo.js +19 -0
  19. package/dist/adapters/getParentsPath.d.ts +2 -0
  20. package/dist/adapters/getParentsPath.js +35 -0
  21. package/dist/adapters/getTree.d.ts +1 -0
  22. package/dist/adapters/getTree.js +35 -0
  23. package/dist/adapters/goUpByTheTree.d.ts +7 -0
  24. package/dist/adapters/goUpByTheTree.js +22 -0
  25. package/dist/adapters/jsx/getExpressionData.d.ts +2 -0
  26. package/dist/adapters/jsx/getExpressionData.js +44 -0
  27. package/dist/adapters/jsx/getJSXComponentBoundingBox.d.ts +5 -0
  28. package/dist/adapters/jsx/getJSXComponentBoundingBox.js +46 -0
  29. package/dist/adapters/jsx/jsxAdapter.d.ts +11 -0
  30. package/dist/adapters/jsx/jsxAdapter.js +208 -0
  31. package/dist/adapters/jsx/runtimeStore.d.ts +10 -0
  32. package/dist/adapters/jsx/runtimeStore.js +87 -0
  33. package/dist/adapters/react/fiberToSimple.d.ts +3 -0
  34. package/dist/adapters/react/fiberToSimple.js +55 -0
  35. package/dist/adapters/react/findDebugSource.d.ts +5 -0
  36. package/dist/adapters/react/findDebugSource.js +13 -0
  37. package/dist/adapters/react/findFiberByHtmlElement.d.ts +2 -0
  38. package/dist/adapters/react/findFiberByHtmlElement.js +22 -0
  39. package/dist/adapters/react/gatherFiberRoots.d.ts +2 -0
  40. package/dist/adapters/react/gatherFiberRoots.js +29 -0
  41. package/dist/adapters/react/getAllFiberChildren.d.ts +2 -0
  42. package/dist/adapters/react/getAllFiberChildren.js +9 -0
  43. package/dist/adapters/react/getAllParentsElementsAndRootComponent.d.ts +8 -0
  44. package/dist/adapters/react/getAllParentsElementsAndRootComponent.js +34 -0
  45. package/dist/adapters/react/getAllWrappingParents.d.ts +2 -0
  46. package/dist/adapters/react/getAllWrappingParents.js +19 -0
  47. package/dist/adapters/react/getFiberComponentBoundingBox.d.ts +3 -0
  48. package/dist/adapters/react/getFiberComponentBoundingBox.js +27 -0
  49. package/dist/adapters/react/getFiberLabel.d.ts +3 -0
  50. package/dist/adapters/react/getFiberLabel.js +14 -0
  51. package/dist/adapters/react/getFiberOwnBoundingBox.d.ts +3 -0
  52. package/dist/adapters/react/getFiberOwnBoundingBox.js +6 -0
  53. package/dist/adapters/react/isStyled.d.ts +2 -0
  54. package/dist/adapters/react/isStyled.js +3 -0
  55. package/dist/adapters/react/makeFiberId.d.ts +2 -0
  56. package/dist/adapters/react/makeFiberId.js +16 -0
  57. package/dist/adapters/react/reactAdapter.d.ts +11 -0
  58. package/dist/adapters/react/reactAdapter.js +114 -0
  59. package/dist/adapters/react/searchDevtoolsRenderersForClosestTarget.d.ts +1 -0
  60. package/dist/adapters/react/searchDevtoolsRenderersForClosestTarget.js +11 -0
  61. package/dist/adapters/svelte/svelteAdapter.d.ts +22 -0
  62. package/dist/adapters/svelte/svelteAdapter.js +88 -0
  63. package/dist/adapters/vue/getVNodeBoundingBox.d.ts +4 -0
  64. package/dist/adapters/vue/getVNodeBoundingBox.js +31 -0
  65. package/dist/adapters/vue/vueAdapter.d.ts +15 -0
  66. package/dist/adapters/vue/vueAdapter.js +113 -0
  67. package/dist/browserApi.d.ts +103 -0
  68. package/dist/browserApi.js +160 -0
  69. package/dist/components/Button.d.ts +4 -0
  70. package/dist/components/Button.js +17 -0
  71. package/dist/components/ComponentOutline.d.ts +7 -0
  72. package/dist/components/ComponentOutline.js +93 -0
  73. package/dist/components/MaybeOutline.d.ts +7 -0
  74. package/dist/components/MaybeOutline.js +43 -0
  75. package/dist/components/Outline.d.ts +25 -0
  76. package/dist/components/Outline.js +135 -0
  77. package/dist/components/RenderBoxes.d.ts +4 -0
  78. package/dist/components/RenderBoxes.js +73 -0
  79. package/dist/components/Runtime.d.ts +3 -0
  80. package/dist/components/Runtime.js +188 -0
  81. package/dist/components/SimpleNodeOutline.d.ts +4 -0
  82. package/dist/components/SimpleNodeOutline.js +47 -0
  83. package/dist/components/Toast.d.ts +4 -0
  84. package/dist/components/Toast.js +68 -0
  85. package/dist/components/Tooltip.d.ts +5 -0
  86. package/dist/components/Tooltip.js +21 -0
  87. package/dist/consts.d.ts +6 -0
  88. package/dist/consts.js +5 -0
  89. package/dist/functions/cropPath.d.ts +1 -0
  90. package/dist/functions/cropPath.js +9 -0
  91. package/dist/functions/cropPath.test.d.ts +1 -0
  92. package/dist/functions/cropPath.test.js +16 -0
  93. package/dist/functions/deduplicateLabels.d.ts +2 -0
  94. package/dist/functions/deduplicateLabels.js +12 -0
  95. package/dist/functions/evalTemplate.d.ts +3 -0
  96. package/dist/functions/evalTemplate.js +7 -0
  97. package/dist/functions/evalTemplate.test.d.ts +1 -0
  98. package/dist/functions/evalTemplate.test.js +11 -0
  99. package/dist/functions/findNames.d.ts +5 -0
  100. package/dist/functions/findNames.js +15 -0
  101. package/dist/functions/formatAncestryChain.d.ts +9 -0
  102. package/dist/functions/formatAncestryChain.js +56 -0
  103. package/dist/functions/getBoundingRect.d.ts +1 -0
  104. package/dist/functions/getBoundingRect.js +11 -0
  105. package/dist/functions/getComposedBoundingBox.d.ts +2 -0
  106. package/dist/functions/getComposedBoundingBox.js +20 -0
  107. package/dist/functions/getIdsOnPathToRoot.d.ts +3 -0
  108. package/dist/functions/getIdsOnPathToRoot.js +15 -0
  109. package/dist/functions/getMultipleElementsBoundingBox.d.ts +2 -0
  110. package/dist/functions/getMultipleElementsBoundingBox.js +20 -0
  111. package/dist/functions/getPathToParent.d.ts +1 -0
  112. package/dist/functions/getPathToParent.js +15 -0
  113. package/dist/functions/getReferenceId.d.ts +1 -0
  114. package/dist/functions/getReferenceId.js +9 -0
  115. package/dist/functions/getUsableFileName.d.ts +1 -0
  116. package/dist/functions/getUsableFileName.js +17 -0
  117. package/dist/functions/getUsableFileName.test.d.ts +1 -0
  118. package/dist/functions/getUsableFileName.test.js +16 -0
  119. package/dist/functions/getUsableName.d.ts +2 -0
  120. package/dist/functions/getUsableName.js +47 -0
  121. package/dist/functions/isCombinationModifiersPressed.d.ts +4 -0
  122. package/dist/functions/isCombinationModifiersPressed.js +16 -0
  123. package/dist/functions/isLocatorsOwnElement.d.ts +1 -0
  124. package/dist/functions/isLocatorsOwnElement.js +3 -0
  125. package/dist/functions/mergeRects.d.ts +2 -0
  126. package/dist/functions/mergeRects.js +10 -0
  127. package/dist/functions/mergeRects.test.d.ts +1 -0
  128. package/dist/functions/mergeRects.test.js +23 -0
  129. package/dist/functions/nonNullable.d.ts +1 -0
  130. package/dist/functions/nonNullable.js +3 -0
  131. package/dist/functions/parseDataId.d.ts +3 -0
  132. package/dist/functions/parseDataId.js +44 -0
  133. package/dist/functions/transformPath.d.ts +1 -0
  134. package/dist/functions/transformPath.js +7 -0
  135. package/dist/functions/transformPath.test.d.ts +1 -0
  136. package/dist/functions/transformPath.test.js +16 -0
  137. package/dist/global.d.js +1 -0
  138. package/dist/index.d.ts +11 -0
  139. package/dist/index.js +13 -0
  140. package/dist/initRuntime.d.ts +8 -0
  141. package/dist/initRuntime.js +80 -0
  142. package/dist/output.css +1733 -0
  143. package/dist/types/LabelData.d.ts +5 -0
  144. package/dist/types/LabelData.js +1 -0
  145. package/dist/types/TreeNode.d.ts +19 -0
  146. package/dist/types/TreeNode.js +1 -0
  147. package/dist/types/types.d.ts +53 -0
  148. package/dist/types/types.js +1 -0
  149. package/jest.config.ts +195 -0
  150. package/package.json +75 -0
  151. package/scripts/wrapCSS.js +26 -0
  152. package/scripts/wrapImage.js +24 -0
  153. package/src/_generated_styles.ts +1734 -0
  154. package/src/_generated_tree_icon.ts +2 -0
  155. package/src/adapters/HtmlElementTreeNode.ts +51 -0
  156. package/src/adapters/adapterApi.ts +35 -0
  157. package/src/adapters/createTreeNode.ts +25 -0
  158. package/src/adapters/getElementInfo.tsx +27 -0
  159. package/src/adapters/getParentsPath.tsx +49 -0
  160. package/src/adapters/getTree.tsx +45 -0
  161. package/src/adapters/goUpByTheTree.ts +20 -0
  162. package/src/adapters/jsx/getExpressionData.ts +47 -0
  163. package/src/adapters/jsx/getJSXComponentBoundingBox.ts +63 -0
  164. package/src/adapters/jsx/jsxAdapter.ts +276 -0
  165. package/src/adapters/jsx/runtimeStore.ts +94 -0
  166. package/src/adapters/react/fiberToSimple.tsx +72 -0
  167. package/src/adapters/react/findDebugSource.ts +15 -0
  168. package/src/adapters/react/findFiberByHtmlElement.ts +27 -0
  169. package/src/adapters/react/gatherFiberRoots.tsx +36 -0
  170. package/src/adapters/react/getAllFiberChildren.tsx +11 -0
  171. package/src/adapters/react/getAllParentsElementsAndRootComponent.ts +52 -0
  172. package/src/adapters/react/getAllWrappingParents.ts +25 -0
  173. package/src/adapters/react/getFiberComponentBoundingBox.ts +30 -0
  174. package/src/adapters/react/getFiberLabel.ts +20 -0
  175. package/src/adapters/react/getFiberOwnBoundingBox.ts +9 -0
  176. package/src/adapters/react/isStyled.ts +5 -0
  177. package/src/adapters/react/makeFiberId.tsx +19 -0
  178. package/src/adapters/react/reactAdapter.ts +148 -0
  179. package/src/adapters/react/searchDevtoolsRenderersForClosestTarget.ts +15 -0
  180. package/src/adapters/svelte/svelteAdapter.ts +111 -0
  181. package/src/adapters/vue/getVNodeBoundingBox.tsx +42 -0
  182. package/src/adapters/vue/vueAdapter.ts +139 -0
  183. package/src/assets/tree-icon.png +0 -0
  184. package/src/browserApi.ts +288 -0
  185. package/src/components/Button.tsx +14 -0
  186. package/src/components/ComponentOutline.tsx +98 -0
  187. package/src/components/MaybeOutline.tsx +49 -0
  188. package/src/components/Outline.tsx +153 -0
  189. package/src/components/RenderBoxes.tsx +57 -0
  190. package/src/components/Runtime.tsx +246 -0
  191. package/src/components/SimpleNodeOutline.tsx +27 -0
  192. package/src/components/Toast.tsx +83 -0
  193. package/src/components/Tooltip.tsx +28 -0
  194. package/src/consts.ts +7 -0
  195. package/src/functions/cropPath.test.ts +18 -0
  196. package/src/functions/cropPath.ts +12 -0
  197. package/src/functions/deduplicateLabels.ts +16 -0
  198. package/src/functions/evalTemplate.test.ts +12 -0
  199. package/src/functions/evalTemplate.ts +8 -0
  200. package/src/functions/findNames.ts +20 -0
  201. package/src/functions/formatAncestryChain.ts +80 -0
  202. package/src/functions/getBoundingRect.tsx +11 -0
  203. package/src/functions/getComposedBoundingBox.tsx +25 -0
  204. package/src/functions/getIdsOnPathToRoot.tsx +21 -0
  205. package/src/functions/getMultipleElementsBoundingBox.tsx +25 -0
  206. package/src/functions/getPathToParent.tsx +17 -0
  207. package/src/functions/getReferenceId.tsx +10 -0
  208. package/src/functions/getUsableFileName.test.tsx +24 -0
  209. package/src/functions/getUsableFileName.tsx +19 -0
  210. package/src/functions/getUsableName.ts +52 -0
  211. package/src/functions/isCombinationModifiersPressed.ts +32 -0
  212. package/src/functions/isLocatorsOwnElement.tsx +9 -0
  213. package/src/functions/mergeRects.test.ts +15 -0
  214. package/src/functions/mergeRects.tsx +12 -0
  215. package/src/functions/nonNullable.ts +3 -0
  216. package/src/functions/parseDataId.ts +62 -0
  217. package/src/functions/transformPath.test.ts +28 -0
  218. package/src/functions/transformPath.ts +7 -0
  219. package/src/global.d.ts +31 -0
  220. package/src/index.ts +18 -0
  221. package/src/initRuntime.ts +83 -0
  222. package/src/main.css +3 -0
  223. package/src/types/LabelData.ts +6 -0
  224. package/src/types/TreeNode.ts +22 -0
  225. package/src/types/types.ts +55 -0
  226. package/tailwind.config.js +9 -0
  227. 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,10 @@
1
+ export declare function getDataForDataId(dataId: string): {
2
+ link: {
3
+ filePath: string;
4
+ projectPath: string;
5
+ column: any;
6
+ line: any;
7
+ };
8
+ label: any;
9
+ componentLabel: any;
10
+ } | null;
@@ -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,3 @@
1
+ import { Fiber } from "@locator/shared";
2
+ import { SimpleNode } from "../../types/types";
3
+ export declare function fiberToSimple(fiber: Fiber, manualChildren?: SimpleNode[]): SimpleNode;
@@ -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,5 @@
1
+ import { Fiber, Source } from "@locator/shared";
2
+ export declare function findDebugSource(fiber: Fiber): {
3
+ fiber: Fiber;
4
+ source: Source;
5
+ } | null;
@@ -0,0 +1,13 @@
1
+ export function findDebugSource(fiber) {
2
+ let current = fiber;
3
+ while (current) {
4
+ if (current._debugSource) {
5
+ return {
6
+ fiber: current,
7
+ source: current._debugSource
8
+ };
9
+ }
10
+ current = current._debugOwner || null;
11
+ }
12
+ return null;
13
+ }
@@ -0,0 +1,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function findFiberByHtmlElement(target: HTMLElement, shouldHaveDebugSource: boolean): Fiber | null;
@@ -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,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function gatherFiberRoots(parentNode: HTMLElement, mutable_foundFibers: Fiber[]): void;
@@ -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,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function getAllFiberChildren(fiber: Fiber): Fiber[];
@@ -0,0 +1,9 @@
1
+ export function getAllFiberChildren(fiber) {
2
+ const allChildren = [];
3
+ let child = fiber.child;
4
+ while (child) {
5
+ allChildren.push(child);
6
+ child = child.sibling;
7
+ }
8
+ return allChildren;
9
+ }
@@ -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,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function getAllWrappingParents(fiber: Fiber): Fiber[];
@@ -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,3 @@
1
+ import { Fiber } from "@locator/shared";
2
+ import { SimpleDOMRect } from "../../types/types";
3
+ export declare function getFiberComponentBoundingBox(fiber: Fiber, level?: number): SimpleDOMRect | undefined;
@@ -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,3 @@
1
+ import { Fiber, Source } from "@locator/shared";
2
+ import { LabelData } from "../../types/LabelData";
3
+ export declare function getFiberLabel(fiber: Fiber, source?: Source): LabelData;
@@ -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,3 @@
1
+ import { Fiber } from "@locator/shared";
2
+ import { SimpleDOMRect } from "../../types/types";
3
+ export declare function getFiberOwnBoundingBox(fiber: Fiber): SimpleDOMRect | null;
@@ -0,0 +1,6 @@
1
+ export function getFiberOwnBoundingBox(fiber) {
2
+ if (fiber.stateNode && fiber.stateNode.getBoundingClientRect) {
3
+ return fiber.stateNode.getBoundingClientRect();
4
+ }
5
+ return null;
6
+ }
@@ -0,0 +1,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function isStyledElement(fiber: Fiber): boolean;
@@ -0,0 +1,3 @@
1
+ export function isStyledElement(fiber) {
2
+ return !!fiber._debugOwner?.elementType?.styledComponentId;
3
+ }
@@ -0,0 +1,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function makeFiberId(fiber: Fiber): string;
@@ -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;