@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,68 @@
1
+ import { template as _$template } from "solid-js/web";
2
+ import { createComponent as _$createComponent } from "solid-js/web";
3
+ import { insert as _$insert } from "solid-js/web";
4
+ import { setAttribute as _$setAttribute } from "solid-js/web";
5
+ import { effect as _$effect } from "solid-js/web";
6
+ import { setStyleProperty as _$setStyleProperty } from "solid-js/web";
7
+ var _tmpl$ = /*#__PURE__*/_$template(`<div style="z-index:99999;background-color:rgba(56, 189, 248, 0.5);pointer-events:none">`),
8
+ _tmpl$2 = /*#__PURE__*/_$template(`<div style=z-index:100000;pointer-events:none><img alt=Tree>`),
9
+ _tmpl$3 = /*#__PURE__*/_$template(`<div style="background-color:#111827;border-radius:8px;box-shadow:0 10px 15px -3px rgba(0, 0, 0, 0.1);font-size:14px;z-index:100000;pointer-events:auto">`);
10
+ import { createSignal, onCleanup, onMount } from "solid-js";
11
+ import { Portal } from "solid-js/web";
12
+ import TREE_ICON from "../_generated_tree_icon";
13
+ export function Toast(props) {
14
+ let timeoutId;
15
+ const [flashOpacity, setFlashOpacity] = createSignal(1);
16
+ onMount(() => {
17
+ // Start flash fade after a brief moment so it's visible
18
+ setTimeout(() => {
19
+ setFlashOpacity(0);
20
+ }, 100);
21
+ timeoutId = setTimeout(() => {
22
+ props.onClose();
23
+ }, 1500);
24
+ });
25
+ onCleanup(() => {
26
+ clearTimeout(timeoutId);
27
+ });
28
+ return _$createComponent(Portal, {
29
+ get mount() {
30
+ return document.body;
31
+ },
32
+ get children() {
33
+ return [(() => {
34
+ var _el$ = _tmpl$();
35
+ _$setStyleProperty(_el$, "position", "fixed");
36
+ _$setStyleProperty(_el$, "top", "0");
37
+ _$setStyleProperty(_el$, "left", "0");
38
+ _$setStyleProperty(_el$, "right", "0");
39
+ _$setStyleProperty(_el$, "bottom", "0");
40
+ _$setStyleProperty(_el$, "width", "100vw");
41
+ _$setStyleProperty(_el$, "height", "100vh");
42
+ _$setStyleProperty(_el$, "transition", "opacity 0.3s ease-out");
43
+ _$effect(_$p => _$setStyleProperty(_el$, "opacity", flashOpacity()));
44
+ return _el$;
45
+ })(), (() => {
46
+ var _el$2 = _tmpl$2(),
47
+ _el$3 = _el$2.firstChild;
48
+ _$setStyleProperty(_el$2, "position", "fixed");
49
+ _$setStyleProperty(_el$2, "bottom", "16px");
50
+ _$setStyleProperty(_el$2, "left", "16px");
51
+ _$setAttribute(_el$3, "src", TREE_ICON);
52
+ _$setStyleProperty(_el$3, "width", "32px");
53
+ _$setStyleProperty(_el$3, "height", "32px");
54
+ return _el$2;
55
+ })(), (() => {
56
+ var _el$4 = _tmpl$3();
57
+ _$setStyleProperty(_el$4, "position", "fixed");
58
+ _$setStyleProperty(_el$4, "bottom", "16px");
59
+ _$setStyleProperty(_el$4, "left", "50%");
60
+ _$setStyleProperty(_el$4, "transform", "translateX(-50%)");
61
+ _$setStyleProperty(_el$4, "color", "white");
62
+ _$setStyleProperty(_el$4, "padding", "8px 16px");
63
+ _$insert(_el$4, () => props.message);
64
+ return _el$4;
65
+ })()];
66
+ }
67
+ });
68
+ }
@@ -0,0 +1,5 @@
1
+ export default function Tooltip(props: {
2
+ tooltipText?: string;
3
+ position?: "bottom" | "left" | "right" | "top";
4
+ children: any;
5
+ }): import("solid-js").JSX.Element;
@@ -0,0 +1,21 @@
1
+ import { template as _$template } from "solid-js/web";
2
+ import { className as _$className } from "solid-js/web";
3
+ import { effect as _$effect } from "solid-js/web";
4
+ import { insert as _$insert } from "solid-js/web";
5
+ var _tmpl$ = /*#__PURE__*/_$template(`<div class="group/tooltip relative block"><div role=tooltip>`);
6
+ export default function Tooltip(props) {
7
+ const positionMap = {
8
+ bottom: "-bottom-7 left-1/2 -translate-x-1/2 transform",
9
+ left: "-left-2 top-1/2 -translate-y-1/2 -translate-x-full transform",
10
+ right: "-right-2 top-1/2 -translate-y-1/2 translate-x-full transform",
11
+ top: "-top-7 left-1/2 -translate-x-1/2 transform"
12
+ };
13
+ return (() => {
14
+ var _el$ = _tmpl$(),
15
+ _el$2 = _el$.firstChild;
16
+ _$insert(_el$, () => props.children, _el$2);
17
+ _$insert(_el$2, () => props.tooltipText);
18
+ _$effect(() => _$className(_el$2, "pointer-events-none invisible absolute z-10 whitespace-nowrap rounded bg-gray-700 px-2 py-1 text-center text-xs text-white opacity-0 transition-opacity duration-300 group-hover/tooltip:visible group-hover/tooltip:opacity-100" + " " + positionMap[props.position || "top"]));
19
+ return _el$;
20
+ })();
21
+ }
@@ -0,0 +1,6 @@
1
+ export declare const HREF_TARGET = "_self";
2
+ export declare const PADDING = 6;
3
+ export declare const baseColor = "#e90139";
4
+ export declare const hoverColor = "#C70139";
5
+ export declare const fontFamily = "Helvetica, sans-serif, Arial";
6
+ export type AdapterId = "react" | "jsx" | "svelte" | "vue";
package/dist/consts.js ADDED
@@ -0,0 +1,5 @@
1
+ export const HREF_TARGET = "_self";
2
+ export const PADDING = 6;
3
+ export const baseColor = "#e90139";
4
+ export const hoverColor = "#C70139";
5
+ export const fontFamily = "Helvetica, sans-serif, Arial";
@@ -0,0 +1 @@
1
+ export default function cropPath(fullPath: string): string;
@@ -0,0 +1,9 @@
1
+ export default function cropPath(fullPath) {
2
+ const array = fullPath.split("/");
3
+ const newPath = array.slice(Math.max(array.length - 3, 0), array.length).join("/");
4
+ if (newPath !== fullPath) {
5
+ return `.../${newPath}`;
6
+ } else {
7
+ return newPath;
8
+ }
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import cropPath from "./cropPath";
2
+ import { describe, expect, test } from "vitest";
3
+ describe("cropPath", () => {
4
+ test("crop", () => {
5
+ expect(cropPath("aaa/bbb/ccc/ddd.tsx")).toBe(".../bbb/ccc/ddd.tsx");
6
+ expect(cropPath("/aaa/bbb/ccc/ddd.tsx")).toBe(".../bbb/ccc/ddd.tsx");
7
+ });
8
+ test("no crop", () => {
9
+ // expect(cropPath("/bbb/ccc/ddd.tsx")).toBe("/bbb/ccc/ddd.tsx");
10
+ expect(cropPath("bbb/ccc/ddd.tsx")).toBe("bbb/ccc/ddd.tsx");
11
+ expect(cropPath("/ccc/ddd.tsx")).toBe("/ccc/ddd.tsx");
12
+ expect(cropPath("ccc/ddd.tsx")).toBe("ccc/ddd.tsx");
13
+ expect(cropPath("")).toBe("");
14
+ expect(cropPath("xxx")).toBe("xxx");
15
+ });
16
+ });
@@ -0,0 +1,2 @@
1
+ import { LabelData } from "../types/LabelData";
2
+ export declare function deduplicateLabels(labels: LabelData[]): LabelData[];
@@ -0,0 +1,12 @@
1
+ import nonNullable from "./nonNullable";
2
+ export function deduplicateLabels(labels) {
3
+ const labelsIds = {};
4
+ return labels.map(label => {
5
+ const id = JSON.stringify(label);
6
+ if (labelsIds[id]) {
7
+ return null;
8
+ }
9
+ labelsIds[id] = true;
10
+ return label;
11
+ }).filter(nonNullable);
12
+ }
@@ -0,0 +1,3 @@
1
+ export declare function evalTemplate(str: string, params: {
2
+ [key: string]: string;
3
+ }): string;
@@ -0,0 +1,7 @@
1
+ export function evalTemplate(str, params) {
2
+ let newStr = str;
3
+ Object.entries(params).forEach(([key, value]) => {
4
+ newStr = newStr.replace("${" + key + "}", value);
5
+ });
6
+ return newStr;
7
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,11 @@
1
+ import { evalTemplate } from "./evalTemplate";
2
+ import { describe, expect, test } from "vitest";
3
+ describe("evalTemplate", () => {
4
+ test("basic", () => {
5
+ const res = evalTemplate("https://example.com/${filePath}${ext}", {
6
+ filePath: "test",
7
+ ext: ".js"
8
+ });
9
+ expect(res).toBe("https://example.com/test.js");
10
+ });
11
+ });
@@ -0,0 +1,5 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function findNames(fiber: Fiber): {
3
+ name: string;
4
+ wrappingComponent: string;
5
+ };
@@ -0,0 +1,15 @@
1
+ import { getUsableName } from "./getUsableName";
2
+ export function findNames(fiber) {
3
+ // if (fiber._debugOwner?.elementType?.styledComponentId) {
4
+ // // This is special case for styled-components, we need to show one level up
5
+ // return {
6
+ // name: getUsableName(fiber._debugOwner),
7
+ // wrappingComponent: getUsableName(fiber._debugOwner?._debugOwner),
8
+ // };
9
+ // } else {
10
+ return {
11
+ name: getUsableName(fiber),
12
+ wrappingComponent: getUsableName(fiber._debugOwner)
13
+ };
14
+ // }
15
+ }
@@ -0,0 +1,9 @@
1
+ import { TreeNode } from "../types/TreeNode";
2
+ export interface AncestryItem {
3
+ elementName: string;
4
+ componentName?: string;
5
+ filePath?: string;
6
+ line?: number;
7
+ }
8
+ export declare function collectAncestry(node: TreeNode): AncestryItem[];
9
+ export declare function formatAncestryChain(items: AncestryItem[]): string;
@@ -0,0 +1,56 @@
1
+ // Elements to exclude from ancestry (not useful for debugging)
2
+ const EXCLUDED_ELEMENTS = new Set(["html", "body", "head"]);
3
+ export function collectAncestry(node) {
4
+ const items = [];
5
+ let current = node;
6
+ while (current) {
7
+ // Skip html, body, head elements
8
+ if (EXCLUDED_ELEMENTS.has(current.name)) {
9
+ current = current.getParent();
10
+ continue;
11
+ }
12
+ const component = current.getComponent();
13
+ const source = current.getSource();
14
+ const item = {
15
+ elementName: current.name
16
+ };
17
+ if (component) {
18
+ item.componentName = component.label;
19
+ if (component.callLink) {
20
+ item.filePath = component.callLink.fileName;
21
+ item.line = component.callLink.lineNumber;
22
+ }
23
+ }
24
+ if (!item.filePath && source) {
25
+ item.filePath = source.fileName;
26
+ item.line = source.lineNumber;
27
+ }
28
+
29
+ // Only include items that have useful info (component name or file path)
30
+ if (item.componentName || item.filePath) {
31
+ items.push(item);
32
+ }
33
+ current = current.getParent();
34
+ }
35
+ return items;
36
+ }
37
+ export function formatAncestryChain(items) {
38
+ if (items.length === 0) {
39
+ return "";
40
+ }
41
+
42
+ // Reverse so root is at top, clicked element at bottom
43
+ const reversed = [...items].reverse();
44
+ const lines = [];
45
+ reversed.forEach((item, index) => {
46
+ const indent = " ".repeat(index);
47
+ const prefix = index === 0 ? "" : "└─ ";
48
+ let description = item.elementName;
49
+ if (item.componentName) {
50
+ description = `${item.elementName} in ${item.componentName}`;
51
+ }
52
+ const location = item.filePath ? ` at ${item.filePath}:${item.line}` : "";
53
+ lines.push(`${indent}${prefix}${description}${location}`);
54
+ });
55
+ return lines.join("\n");
56
+ }
@@ -0,0 +1 @@
1
+ export declare function getBoundingRect(node: Element | Text): DOMRect | null;
@@ -0,0 +1,11 @@
1
+ export function getBoundingRect(node) {
2
+ if (node instanceof Element) {
3
+ return node.getBoundingClientRect();
4
+ } else if (node instanceof Text) {
5
+ const range = document.createRange();
6
+ range.selectNodeContents(node);
7
+ return range.getBoundingClientRect();
8
+ } else {
9
+ return null;
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ import { SimpleDOMRect, SimpleNode } from "./../types/types";
2
+ export declare function getComposedBoundingBox(children: SimpleNode[]): SimpleDOMRect | null;
@@ -0,0 +1,20 @@
1
+ import { mergeRects } from "./mergeRects";
2
+ export function getComposedBoundingBox(children) {
3
+ let composedRect = null;
4
+ children.forEach(child => {
5
+ const box = child.box;
6
+ if (!box) {
7
+ return;
8
+ }
9
+ if (box.width <= 0 || box.height <= 0) {
10
+ // ignore zero-sized rects
11
+ return;
12
+ }
13
+ if (composedRect) {
14
+ composedRect = mergeRects(composedRect, box);
15
+ } else {
16
+ composedRect = box;
17
+ }
18
+ });
19
+ return composedRect;
20
+ }
@@ -0,0 +1,3 @@
1
+ export declare function getIdsOnPathToRoot(element: HTMLElement): {
2
+ [id: string]: true;
3
+ };
@@ -0,0 +1,15 @@
1
+ import { findFiberByHtmlElement } from "./../adapters/react/findFiberByHtmlElement";
2
+ import { makeFiberId } from "./../adapters/react/makeFiberId";
3
+ export function getIdsOnPathToRoot(element) {
4
+ const fiber = findFiberByHtmlElement(element, false);
5
+ if (!fiber) {
6
+ return {};
7
+ }
8
+ const res = {};
9
+ let parent = fiber?._debugOwner;
10
+ while (parent) {
11
+ res[makeFiberId(parent)] = true;
12
+ parent = parent?._debugOwner;
13
+ }
14
+ return res;
15
+ }
@@ -0,0 +1,2 @@
1
+ import { SimpleDOMRect } from "../types/types";
2
+ export declare function getMultipleElementsBoundingBox(children: HTMLElement[]): SimpleDOMRect | null;
@@ -0,0 +1,20 @@
1
+ import { mergeRects } from "./mergeRects";
2
+ export function getMultipleElementsBoundingBox(children) {
3
+ let composedRect = null;
4
+ children.forEach(child => {
5
+ const box = child.getBoundingClientRect();
6
+ if (!box) {
7
+ return;
8
+ }
9
+ if (box.width <= 0 || box.height <= 0) {
10
+ // ignore zero-sized rects
11
+ return;
12
+ }
13
+ if (composedRect) {
14
+ composedRect = mergeRects(composedRect, box);
15
+ } else {
16
+ composedRect = box;
17
+ }
18
+ });
19
+ return composedRect;
20
+ }
@@ -0,0 +1 @@
1
+ export declare function getPathToParent(element: HTMLElement): import("../types/types").SimpleNode | undefined;
@@ -0,0 +1,15 @@
1
+ import { findFiberByHtmlElement } from "../adapters/react/findFiberByHtmlElement";
2
+ import { fiberToSimple } from "../adapters/react/fiberToSimple";
3
+ export function getPathToParent(element) {
4
+ const fiber = findFiberByHtmlElement(element, false);
5
+ if (!fiber) {
6
+ return;
7
+ }
8
+ let res = fiberToSimple(fiber);
9
+ let parent = fiber?._debugOwner;
10
+ while (parent) {
11
+ res = fiberToSimple(parent, [res]);
12
+ parent = parent?._debugOwner;
13
+ }
14
+ return res;
15
+ }
@@ -0,0 +1 @@
1
+ export declare function getReferenceId(ref: object): number;
@@ -0,0 +1,9 @@
1
+ const map = new WeakMap();
2
+ let lastId = 0;
3
+ export function getReferenceId(ref) {
4
+ if (!map.has(ref)) {
5
+ lastId++;
6
+ map.set(ref, lastId);
7
+ }
8
+ return map.get(ref);
9
+ }
@@ -0,0 +1 @@
1
+ export default function getUsableFileName(path: string): string;
@@ -0,0 +1,17 @@
1
+ export default function getUsableFileName(path) {
2
+ const pathSegments = path.split("/");
3
+
4
+ // If the path has only one segment, return it directly.
5
+ if (pathSegments.length === 1) {
6
+ return pathSegments[0] || "unnamed";
7
+ }
8
+ const fileName = pathSegments[pathSegments.length - 1] || "unnamed";
9
+ if (fileName.startsWith("index.")) {
10
+ // If the file name is index.<extension>, return the parent folder's name
11
+ // along with the filename.
12
+ return `${pathSegments[pathSegments.length - 2]}/${fileName}`;
13
+ } else {
14
+ // Otherwise, just return the filename.
15
+ return fileName;
16
+ }
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import getUsableFileName from "./getUsableFileName"; // assuming the function is in filenameUtils.ts
2
+ import { describe, expect, it } from "vitest";
3
+ describe("getUsableFileName", () => {
4
+ it("should return filename if it is not index.<extension>", () => {
5
+ expect(getUsableFileName("myProject/utils/getSomething.js")).toBe("getSomething.js");
6
+ });
7
+ it("should return parent folder and filename if the filename is index.<extension>", () => {
8
+ expect(getUsableFileName("myProject/Button/index.tsx")).toBe("Button/index.tsx");
9
+ });
10
+ it("should handle paths with only one segment", () => {
11
+ expect(getUsableFileName("file.ts")).toBe("file.ts");
12
+ });
13
+ it("should handle paths with index.<extension> without parent folder", () => {
14
+ expect(getUsableFileName("index.ts")).toBe("index.ts");
15
+ });
16
+ });
@@ -0,0 +1,2 @@
1
+ import { Fiber } from "@locator/shared";
2
+ export declare function getUsableName(fiber: Fiber | null | undefined): string;
@@ -0,0 +1,47 @@
1
+ // function printDebugOwnerTree(fiber: Fiber): string | null {
2
+ // let current: Fiber | null = fiber || null;
3
+ // let results = [];
4
+ // while (current) {
5
+ // results.push(getUsableName(current));
6
+ // current = current._debugOwner || null;
7
+ // }
8
+ // console.log('DEBUG OWNER: ', results);
9
+ // return null;
10
+ // }
11
+ // function printReturnTree(fiber: Fiber): string | null {
12
+ // let current: Fiber | null = fiber || null;
13
+ // let results = [];
14
+ // while (current) {
15
+ // results.push(getUsableName(current));
16
+ // current = current.return || null;
17
+ // }
18
+ // console.log('RETURN: ', results);
19
+ // return null;
20
+ // }
21
+
22
+ export function getUsableName(fiber) {
23
+ if (!fiber) {
24
+ return "Not found";
25
+ }
26
+ if (typeof fiber.elementType === "string") {
27
+ return fiber.elementType;
28
+ }
29
+ if (!fiber.elementType) {
30
+ return "Anonymous";
31
+ }
32
+ if (fiber.elementType.name) {
33
+ return fiber.elementType.name;
34
+ }
35
+ // Not sure about this
36
+ if (fiber.elementType.displayName) {
37
+ return fiber.elementType.displayName;
38
+ }
39
+ // Used in rect.memo
40
+ if (fiber.elementType.type?.name) {
41
+ return fiber.elementType.type.name;
42
+ }
43
+ if (fiber.elementType._payload?._result?.name) {
44
+ return fiber.elementType._payload._result.name;
45
+ }
46
+ return "Anonymous";
47
+ }
@@ -0,0 +1,4 @@
1
+ export declare function getMouseModifiers(): {
2
+ [key: string]: true;
3
+ };
4
+ export declare function isCombinationModifiersPressed(e: MouseEvent | KeyboardEvent, rightClick?: boolean): boolean;
@@ -0,0 +1,16 @@
1
+ export function getMouseModifiers() {
2
+ const mouseModifiers = document.documentElement.dataset.locatorMouseModifiers || "alt";
3
+ const mouseModifiersArray = mouseModifiers.split("+");
4
+ const modifiers = {};
5
+ mouseModifiersArray.forEach(modifier => {
6
+ modifiers[modifier] = true;
7
+ }, {});
8
+ return modifiers;
9
+ }
10
+ export function isCombinationModifiersPressed(e, rightClick = false) {
11
+ const modifiers = getMouseModifiers();
12
+ if (rightClick) {
13
+ return e.altKey == !!modifiers.alt && e.metaKey == !!modifiers.meta && e.shiftKey == !!modifiers.shift;
14
+ }
15
+ return e.altKey == !!modifiers.alt && e.ctrlKey == !!modifiers.ctrl && e.metaKey == !!modifiers.meta && e.shiftKey == !!modifiers.shift;
16
+ }
@@ -0,0 +1 @@
1
+ export declare function isLocatorsOwnElement(element: HTMLElement): boolean;
@@ -0,0 +1,3 @@
1
+ export function isLocatorsOwnElement(element) {
2
+ return element.className == "locatorjs-label" || element.id == "locatorjs-labels-section" || element.id == "locatorjs-layer" || element.id == "locatorjs-wrapper" || element.matches("#locatorjs-wrapper *");
3
+ }
@@ -0,0 +1,2 @@
1
+ import { SimpleDOMRect } from "../types/types";
2
+ export declare function mergeRects(a: SimpleDOMRect, b: SimpleDOMRect): SimpleDOMRect;
@@ -0,0 +1,10 @@
1
+ export function mergeRects(a, b) {
2
+ const x = Math.min(a.x, b.x);
3
+ const y = Math.min(a.y, b.y);
4
+ return {
5
+ x,
6
+ y,
7
+ width: Math.max(a.x + a.width, b.x + b.width) - x,
8
+ height: Math.max(a.y + a.height, b.y + b.height) - y
9
+ };
10
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,23 @@
1
+ import { mergeRects } from "./mergeRects";
2
+ import { describe, expect, test } from "vitest";
3
+ describe("mergeRects", () => {
4
+ test("basic", () => {
5
+ const a = {
6
+ x: 0,
7
+ y: 0,
8
+ width: 10,
9
+ height: 10
10
+ };
11
+ const b = {
12
+ x: 5,
13
+ y: 5,
14
+ width: 10,
15
+ height: 10
16
+ };
17
+ const res = mergeRects(a, b);
18
+ expect(res.x).toEqual(0);
19
+ expect(res.y).toEqual(0);
20
+ expect(res.width).toEqual(15);
21
+ expect(res.height).toEqual(15);
22
+ });
23
+ });
@@ -0,0 +1 @@
1
+ export default function nonNullable<T>(value: T): value is NonNullable<T>;
@@ -0,0 +1,3 @@
1
+ export default function nonNullable(value) {
2
+ return value !== null && value !== undefined;
3
+ }
@@ -0,0 +1,3 @@
1
+ export declare function parseDataId(dataId: string): [fileFullPath: string, id: string];
2
+ export declare function parseDataPath(dataPath: string): [fileFullPath: string, line: number, column: number] | null;
3
+ export declare function splitFullPath(fullPath: string): [projectPath: string, filePath: string];
@@ -0,0 +1,44 @@
1
+ export function parseDataId(dataId) {
2
+ const [fileFullPath, id] = dataId.split("::");
3
+ if (!fileFullPath || !id) {
4
+ throw new Error("locatorjsId is malformed");
5
+ }
6
+ return [fileFullPath, id];
7
+ }
8
+ export function parseDataPath(dataPath) {
9
+ // Format: /path/to/file.tsx:line:column
10
+ // Need to handle Windows paths like C:\path\to\file.tsx:line:column
11
+
12
+ // Find the last two colons (for line and column)
13
+ const lastColonIndex = dataPath.lastIndexOf(":");
14
+ if (lastColonIndex === -1) return null;
15
+ const secondLastColonIndex = dataPath.lastIndexOf(":", lastColonIndex - 1);
16
+ if (secondLastColonIndex === -1) return null;
17
+ const fileFullPath = dataPath.substring(0, secondLastColonIndex);
18
+ const lineStr = dataPath.substring(secondLastColonIndex + 1, lastColonIndex);
19
+ const columnStr = dataPath.substring(lastColonIndex + 1);
20
+ const line = parseInt(lineStr, 10);
21
+ const column = parseInt(columnStr, 10);
22
+ if (Number.isNaN(line) || Number.isNaN(column)) {
23
+ return null;
24
+ }
25
+ return [fileFullPath, line, column];
26
+ }
27
+ export function splitFullPath(fullPath) {
28
+ // Try to find a common project root indicator
29
+ const indicators = ["/src/", "/app/", "/pages/", "/components/"];
30
+ for (const indicator of indicators) {
31
+ const index = fullPath.indexOf(indicator);
32
+ if (index !== -1) {
33
+ return [fullPath.substring(0, index), fullPath.substring(index)];
34
+ }
35
+ }
36
+
37
+ // Fallback: treat the whole path as project path with empty file path
38
+ // or try to split at the last reasonable directory
39
+ const lastSlash = fullPath.lastIndexOf("/");
40
+ if (lastSlash !== -1) {
41
+ return [fullPath.substring(0, lastSlash + 1), fullPath.substring(lastSlash + 1)];
42
+ }
43
+ return [fullPath, ""];
44
+ }
@@ -0,0 +1 @@
1
+ export declare function transformPath(path: string, from: string, to: string): string;