@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,19 @@
|
|
|
1
|
+
import { Fiber } from "@locator/shared";
|
|
2
|
+
|
|
3
|
+
let globalIdCounter = 0;
|
|
4
|
+
const globalIdMap = new WeakMap<Fiber, string>();
|
|
5
|
+
|
|
6
|
+
export function makeFiberId(fiber: Fiber) {
|
|
7
|
+
if (fiber._debugID) {
|
|
8
|
+
return fiber._debugID.toString();
|
|
9
|
+
}
|
|
10
|
+
const found = globalIdMap.get(fiber);
|
|
11
|
+
if (found) {
|
|
12
|
+
return found;
|
|
13
|
+
} else {
|
|
14
|
+
globalIdCounter++;
|
|
15
|
+
const id = `fiber:${globalIdCounter}`;
|
|
16
|
+
globalIdMap.set(fiber, id);
|
|
17
|
+
return id;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { findDebugSource } from "./findDebugSource";
|
|
2
|
+
import { findFiberByHtmlElement } from "./findFiberByHtmlElement";
|
|
3
|
+
import { getFiberLabel } from "./getFiberLabel";
|
|
4
|
+
import { getAllWrappingParents } from "./getAllWrappingParents";
|
|
5
|
+
import { deduplicateLabels } from "../../functions/deduplicateLabels";
|
|
6
|
+
import { LabelData } from "../../types/LabelData";
|
|
7
|
+
import { getFiberOwnBoundingBox } from "./getFiberOwnBoundingBox";
|
|
8
|
+
import { getAllParentsElementsAndRootComponent } from "./getAllParentsElementsAndRootComponent";
|
|
9
|
+
import { isStyledElement } from "./isStyled";
|
|
10
|
+
import {
|
|
11
|
+
AdapterObject,
|
|
12
|
+
FullElementInfo,
|
|
13
|
+
ParentPathItem,
|
|
14
|
+
TreeState,
|
|
15
|
+
} from "../adapterApi";
|
|
16
|
+
import { Fiber, Source } from "@locator/shared";
|
|
17
|
+
import { TreeNode, TreeNodeComponent } from "../../types/TreeNode";
|
|
18
|
+
import { goUpByTheTree } from "../goUpByTheTree";
|
|
19
|
+
import { HtmlElementTreeNode } from "../HtmlElementTreeNode";
|
|
20
|
+
|
|
21
|
+
export function getElementInfo(found: HTMLElement): FullElementInfo | null {
|
|
22
|
+
// Instead of labels, return this element, parent elements leading to closest component, its component labels, all wrapping components labels.
|
|
23
|
+
const labels: LabelData[] = [];
|
|
24
|
+
|
|
25
|
+
const fiber = findFiberByHtmlElement(found, false);
|
|
26
|
+
if (fiber) {
|
|
27
|
+
const { component, componentBox, parentElements } =
|
|
28
|
+
getAllParentsElementsAndRootComponent(fiber);
|
|
29
|
+
|
|
30
|
+
const allPotentialComponentFibers = getAllWrappingParents(component);
|
|
31
|
+
|
|
32
|
+
// This handles a common case when the component root is basically the comopnent itself, so I want to go to usage of the component
|
|
33
|
+
// TODO: whaat? why? currently I see that it adds the original styled components which is not necessary.
|
|
34
|
+
|
|
35
|
+
// if (fiber.return && fiber.return === fiber._debugOwner) {
|
|
36
|
+
// allPotentialComponentFibers.unshift(fiber.return);
|
|
37
|
+
// }
|
|
38
|
+
|
|
39
|
+
allPotentialComponentFibers.forEach((fiber) => {
|
|
40
|
+
const fiberWithSource = findDebugSource(fiber);
|
|
41
|
+
if (fiberWithSource) {
|
|
42
|
+
const label = getFiberLabel(
|
|
43
|
+
fiberWithSource.fiber,
|
|
44
|
+
fiberWithSource.source
|
|
45
|
+
);
|
|
46
|
+
labels.push(label);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const thisLabel = getFiberLabel(fiber, findDebugSource(fiber)?.source);
|
|
51
|
+
|
|
52
|
+
if (isStyledElement(fiber)) {
|
|
53
|
+
thisLabel.label = `${thisLabel.label} (styled)`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
thisElement: {
|
|
58
|
+
box: getFiberOwnBoundingBox(fiber) || found.getBoundingClientRect(),
|
|
59
|
+
...thisLabel,
|
|
60
|
+
},
|
|
61
|
+
htmlElement: found,
|
|
62
|
+
parentElements: parentElements,
|
|
63
|
+
componentBox,
|
|
64
|
+
componentsLabels: deduplicateLabels(labels),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export class ReactTreeNodeElement extends HtmlElementTreeNode {
|
|
72
|
+
getSource(): Source | null {
|
|
73
|
+
const fiber = findFiberByHtmlElement(this.element, false);
|
|
74
|
+
|
|
75
|
+
if (fiber && fiber._debugSource) {
|
|
76
|
+
return {
|
|
77
|
+
fileName: fiber._debugSource.fileName,
|
|
78
|
+
lineNumber: fiber._debugSource.lineNumber,
|
|
79
|
+
columnNumber: fiber._debugSource.columnNumber,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
getComponent(): TreeNodeComponent | null {
|
|
85
|
+
const fiber = findFiberByHtmlElement(this.element, false);
|
|
86
|
+
const componentFiber = fiber?._debugOwner;
|
|
87
|
+
|
|
88
|
+
if (componentFiber) {
|
|
89
|
+
const fiberLabel = getFiberLabel(
|
|
90
|
+
componentFiber,
|
|
91
|
+
findDebugSource(componentFiber)?.source
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
label: fiberLabel.label,
|
|
96
|
+
callLink:
|
|
97
|
+
(fiberLabel.link && {
|
|
98
|
+
fileName: fiberLabel.link.filePath,
|
|
99
|
+
lineNumber: fiberLabel.link.line,
|
|
100
|
+
columnNumber: fiberLabel.link.column,
|
|
101
|
+
projectPath: fiberLabel.link.projectPath,
|
|
102
|
+
}) ||
|
|
103
|
+
undefined,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getTree(element: HTMLElement): TreeState | null {
|
|
111
|
+
const originalRoot: TreeNode = new ReactTreeNodeElement(element);
|
|
112
|
+
|
|
113
|
+
return goUpByTheTree(originalRoot);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function fiberToPathItem(fiber: Fiber): ParentPathItem {
|
|
117
|
+
const label = getFiberLabel(fiber, findDebugSource(fiber)?.source);
|
|
118
|
+
|
|
119
|
+
return {
|
|
120
|
+
title: label.label,
|
|
121
|
+
link: label.link,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function getParentsPaths(element: HTMLElement) {
|
|
126
|
+
const fiber = findFiberByHtmlElement(element, false);
|
|
127
|
+
if (fiber) {
|
|
128
|
+
const pathItems: ParentPathItem[] = [];
|
|
129
|
+
let currentFiber = fiber;
|
|
130
|
+
pathItems.push(fiberToPathItem(currentFiber));
|
|
131
|
+
|
|
132
|
+
while (currentFiber._debugOwner) {
|
|
133
|
+
currentFiber = currentFiber._debugOwner;
|
|
134
|
+
pathItems.push(fiberToPathItem(currentFiber));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return pathItems;
|
|
138
|
+
}
|
|
139
|
+
return [];
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const reactAdapter: AdapterObject = {
|
|
143
|
+
getElementInfo,
|
|
144
|
+
getTree,
|
|
145
|
+
getParentsPaths,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export default reactAdapter;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { findFiberByHtmlElement } from "./findFiberByHtmlElement";
|
|
2
|
+
|
|
3
|
+
export function searchDevtoolsRenderersForClosestTarget(
|
|
4
|
+
target: HTMLElement
|
|
5
|
+
): HTMLElement | null {
|
|
6
|
+
let closest: HTMLElement | null = target;
|
|
7
|
+
while (closest) {
|
|
8
|
+
if (findFiberByHtmlElement(closest, false)) {
|
|
9
|
+
return closest;
|
|
10
|
+
}
|
|
11
|
+
closest = closest.parentElement;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { Source } from "@locator/shared";
|
|
2
|
+
import { TreeNode, TreeNodeComponent } from "../../types/TreeNode";
|
|
3
|
+
import {
|
|
4
|
+
AdapterObject,
|
|
5
|
+
FullElementInfo,
|
|
6
|
+
ParentPathItem,
|
|
7
|
+
TreeState,
|
|
8
|
+
} from "../adapterApi";
|
|
9
|
+
import { goUpByTheTree } from "../goUpByTheTree";
|
|
10
|
+
import { HtmlElementTreeNode } from "../HtmlElementTreeNode";
|
|
11
|
+
|
|
12
|
+
type SvelteLoc = {
|
|
13
|
+
char: number;
|
|
14
|
+
column: number;
|
|
15
|
+
file: string;
|
|
16
|
+
line: number;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
type SvelteElement = HTMLElement & { __svelte_meta?: { loc: SvelteLoc } };
|
|
20
|
+
|
|
21
|
+
export function getElementInfo(found: SvelteElement): FullElementInfo | null {
|
|
22
|
+
if (found.__svelte_meta) {
|
|
23
|
+
const { loc } = found.__svelte_meta;
|
|
24
|
+
return {
|
|
25
|
+
thisElement: {
|
|
26
|
+
box: found.getBoundingClientRect(),
|
|
27
|
+
label: found.nodeName.toLowerCase(),
|
|
28
|
+
link: {
|
|
29
|
+
column: loc.column + 1,
|
|
30
|
+
line: loc.line + 1,
|
|
31
|
+
filePath: loc.file,
|
|
32
|
+
projectPath: "",
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
htmlElement: found,
|
|
36
|
+
parentElements: [],
|
|
37
|
+
componentBox: found.getBoundingClientRect(),
|
|
38
|
+
componentsLabels: [],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export class SvelteTreeNodeElement extends HtmlElementTreeNode {
|
|
45
|
+
getSource(): Source | null {
|
|
46
|
+
const element = this.element as SvelteElement;
|
|
47
|
+
if (element.__svelte_meta) {
|
|
48
|
+
const { loc } = element.__svelte_meta;
|
|
49
|
+
return {
|
|
50
|
+
fileName: loc.file,
|
|
51
|
+
lineNumber: loc.line + 1,
|
|
52
|
+
columnNumber: loc.column + 1,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
getComponent(): TreeNodeComponent | null {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function getTree(element: HTMLElement): TreeState | null {
|
|
63
|
+
const originalRoot: TreeNode = new SvelteTreeNodeElement(element);
|
|
64
|
+
|
|
65
|
+
return goUpByTheTree(originalRoot);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function getParentsPaths(element: HTMLElement): ParentPathItem[] {
|
|
69
|
+
const path: ParentPathItem[] = [];
|
|
70
|
+
let currentElement: SvelteElement | null = element;
|
|
71
|
+
|
|
72
|
+
let maxDepth = 10000; // just in case, it should not be needed
|
|
73
|
+
|
|
74
|
+
do {
|
|
75
|
+
if (currentElement?.__svelte_meta) {
|
|
76
|
+
const { loc } = currentElement.__svelte_meta;
|
|
77
|
+
|
|
78
|
+
// we assume that there is one component per file
|
|
79
|
+
const isSameFileAsTheLastOne =
|
|
80
|
+
loc.file === path[path.length - 1]?.link?.filePath;
|
|
81
|
+
|
|
82
|
+
if (!isSameFileAsTheLastOne) {
|
|
83
|
+
path.push({
|
|
84
|
+
title: currentElement!.nodeName.toLowerCase(),
|
|
85
|
+
link: {
|
|
86
|
+
column: loc.column + 1,
|
|
87
|
+
line: loc.line + 1,
|
|
88
|
+
filePath: loc.file,
|
|
89
|
+
projectPath: "",
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
currentElement = currentElement.parentElement;
|
|
96
|
+
maxDepth--;
|
|
97
|
+
if (maxDepth < 0) {
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
} while (currentElement);
|
|
101
|
+
|
|
102
|
+
return path;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const svelteAdapter: AdapterObject = {
|
|
106
|
+
getElementInfo,
|
|
107
|
+
getTree,
|
|
108
|
+
getParentsPaths,
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export default svelteAdapter;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { mergeRects } from "../../functions/mergeRects";
|
|
2
|
+
import { SimpleDOMRect } from "../../types/types";
|
|
3
|
+
import type { ComponentInternalInstance, VNode } from "vue";
|
|
4
|
+
|
|
5
|
+
export function getVueComponentBoundingBox(
|
|
6
|
+
vcomponent: ComponentInternalInstance
|
|
7
|
+
) {
|
|
8
|
+
let composedRect: SimpleDOMRect | null = null;
|
|
9
|
+
if (
|
|
10
|
+
vcomponent?.subTree?.children &&
|
|
11
|
+
vcomponent?.subTree?.children instanceof Array
|
|
12
|
+
) {
|
|
13
|
+
vcomponent?.subTree?.children.forEach((child: any) => {
|
|
14
|
+
const box = getVNodeBoundingBox(child);
|
|
15
|
+
if (!box) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (box.width <= 0 || box.height <= 0) {
|
|
19
|
+
// ignore zero-sized rects
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (composedRect) {
|
|
23
|
+
composedRect = mergeRects(composedRect, box);
|
|
24
|
+
} else {
|
|
25
|
+
composedRect = box;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return composedRect;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getVNodeBoundingBox(vnode: VNode): SimpleDOMRect | null {
|
|
33
|
+
if (vnode.el instanceof HTMLElement) {
|
|
34
|
+
return vnode.el.getBoundingClientRect();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (vnode.component) {
|
|
38
|
+
return getVueComponentBoundingBox(vnode.component);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { Source } from "@locator/shared";
|
|
2
|
+
import type { ComponentInternalInstance } from "vue";
|
|
3
|
+
import { TreeNode, TreeNodeComponent } from "../../types/TreeNode";
|
|
4
|
+
import {
|
|
5
|
+
AdapterObject,
|
|
6
|
+
FullElementInfo,
|
|
7
|
+
ParentPathItem,
|
|
8
|
+
TreeState,
|
|
9
|
+
} from "../adapterApi";
|
|
10
|
+
import { goUpByTheTree } from "../goUpByTheTree";
|
|
11
|
+
import { HtmlElementTreeNode } from "../HtmlElementTreeNode";
|
|
12
|
+
import { getVueComponentBoundingBox } from "./getVNodeBoundingBox";
|
|
13
|
+
|
|
14
|
+
type VueElement = HTMLElement & {
|
|
15
|
+
__vueParentComponent?: ComponentInternalInstance;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function getElementInfo(found: VueElement): FullElementInfo | null {
|
|
19
|
+
const parentComponent = found.__vueParentComponent;
|
|
20
|
+
if (parentComponent) {
|
|
21
|
+
if (!parentComponent.type) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const componentBBox = getVueComponentBoundingBox(parentComponent);
|
|
26
|
+
|
|
27
|
+
const { __file, __name } = parentComponent.type;
|
|
28
|
+
if (__file && __name) {
|
|
29
|
+
return {
|
|
30
|
+
thisElement: {
|
|
31
|
+
box: found.getBoundingClientRect(),
|
|
32
|
+
label: found.nodeName.toLowerCase(),
|
|
33
|
+
link: {
|
|
34
|
+
column: 1,
|
|
35
|
+
line: 1,
|
|
36
|
+
filePath: __file,
|
|
37
|
+
projectPath: "",
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
htmlElement: found,
|
|
41
|
+
parentElements: [],
|
|
42
|
+
componentBox: componentBBox || found.getBoundingClientRect(),
|
|
43
|
+
componentsLabels: [
|
|
44
|
+
{
|
|
45
|
+
label: __name,
|
|
46
|
+
link: {
|
|
47
|
+
column: 1,
|
|
48
|
+
line: 1,
|
|
49
|
+
filePath: __file,
|
|
50
|
+
projectPath: "",
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class VueTreeNodeElement extends HtmlElementTreeNode {
|
|
61
|
+
getSource(): Source | null {
|
|
62
|
+
const element = this.element as VueElement;
|
|
63
|
+
const parentComponent = element.__vueParentComponent;
|
|
64
|
+
if (parentComponent && parentComponent.type) {
|
|
65
|
+
const { __file } = parentComponent.type;
|
|
66
|
+
if (__file) {
|
|
67
|
+
return {
|
|
68
|
+
fileName: __file,
|
|
69
|
+
lineNumber: 1,
|
|
70
|
+
columnNumber: 1,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
getComponent(): TreeNodeComponent | null {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// getComponent(): TreeNodeComponent | null {
|
|
80
|
+
// const element = this.element as VueElement;
|
|
81
|
+
// const parentComponent = element.__vueParentComponent;
|
|
82
|
+
// if (parentComponent && parentComponent.type) {
|
|
83
|
+
// const { __name } = parentComponent.type;
|
|
84
|
+
// if (__name) {
|
|
85
|
+
// return {
|
|
86
|
+
// label: __name,
|
|
87
|
+
// definitionLink: this.getSource() || undefined,
|
|
88
|
+
// };
|
|
89
|
+
// }
|
|
90
|
+
// }
|
|
91
|
+
// return null;
|
|
92
|
+
// }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function getTree(element: HTMLElement): TreeState | null {
|
|
96
|
+
const originalRoot: TreeNode = new VueTreeNodeElement(element);
|
|
97
|
+
|
|
98
|
+
return goUpByTheTree(originalRoot);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function getParentsPaths(element: HTMLElement): ParentPathItem[] {
|
|
102
|
+
const path: ParentPathItem[] = [];
|
|
103
|
+
let currentElement: HTMLElement | null = element;
|
|
104
|
+
let previousComponentKey: string | null = null;
|
|
105
|
+
|
|
106
|
+
do {
|
|
107
|
+
if (currentElement) {
|
|
108
|
+
const info = getElementInfo(currentElement);
|
|
109
|
+
|
|
110
|
+
const currentComponentKey = JSON.stringify(info?.componentsLabels);
|
|
111
|
+
|
|
112
|
+
if (info && currentComponentKey !== previousComponentKey) {
|
|
113
|
+
previousComponentKey = currentComponentKey;
|
|
114
|
+
|
|
115
|
+
const link = info.thisElement.link;
|
|
116
|
+
const label = info.thisElement.label;
|
|
117
|
+
|
|
118
|
+
if (link) {
|
|
119
|
+
path.push({
|
|
120
|
+
title: label,
|
|
121
|
+
link: link,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
currentElement = currentElement.parentElement;
|
|
128
|
+
} while (currentElement);
|
|
129
|
+
|
|
130
|
+
return path;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const vueAdapter: AdapterObject = {
|
|
134
|
+
getElementInfo,
|
|
135
|
+
getTree,
|
|
136
|
+
getParentsPaths,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export default vueAdapter;
|
|
Binary file
|