@treelocator/runtime 0.4.1 → 0.4.5

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 (67) hide show
  1. package/dist/_generated_styles.js +115 -15
  2. package/dist/adapters/getElementInfo.js +3 -17
  3. package/dist/adapters/getParentsPath.js +3 -33
  4. package/dist/adapters/getTree.js +3 -33
  5. package/dist/adapters/jsx/getJSXComponentBoundingBox.js +0 -1
  6. package/dist/adapters/jsx/jsxAdapter.js +0 -3
  7. package/dist/adapters/jsx/runtimeStore.js +0 -12
  8. package/dist/adapters/react/reactAdapter.js +0 -8
  9. package/dist/adapters/resolveAdapter.d.ts +8 -0
  10. package/dist/adapters/resolveAdapter.js +28 -0
  11. package/dist/adapters/vue/vueAdapter.js +0 -14
  12. package/dist/browserApi.d.ts +1 -1
  13. package/dist/browserApi.js +8 -10
  14. package/dist/components/MaybeOutline.d.ts +1 -0
  15. package/dist/components/MaybeOutline.js +38 -29
  16. package/dist/components/Outline.d.ts +1 -0
  17. package/dist/components/Outline.js +20 -16
  18. package/dist/components/Runtime.js +30 -18
  19. package/dist/dejitter/recorder.js +0 -1
  20. package/dist/functions/formatAncestryChain.d.ts +6 -0
  21. package/dist/functions/formatAncestryChain.js +11 -0
  22. package/dist/functions/formatAncestryChain.test.js +75 -1
  23. package/dist/functions/getUsableName.js +0 -21
  24. package/dist/output.css +10 -40
  25. package/dist/types/types.d.ts +1 -32
  26. package/package.json +1 -1
  27. package/src/_generated_styles.ts +115 -15
  28. package/src/adapters/getElementInfo.tsx +3 -23
  29. package/src/adapters/getParentsPath.tsx +3 -42
  30. package/src/adapters/getTree.tsx +3 -42
  31. package/src/adapters/jsx/getJSXComponentBoundingBox.ts +0 -1
  32. package/src/adapters/jsx/jsxAdapter.ts +0 -2
  33. package/src/adapters/jsx/runtimeStore.ts +0 -11
  34. package/src/adapters/react/reactAdapter.ts +0 -7
  35. package/src/adapters/resolveAdapter.ts +38 -0
  36. package/src/adapters/vue/vueAdapter.ts +0 -14
  37. package/src/browserApi.ts +9 -12
  38. package/src/components/MaybeOutline.tsx +4 -2
  39. package/src/components/Outline.tsx +2 -1
  40. package/src/components/Runtime.tsx +27 -18
  41. package/src/dejitter/recorder.ts +43 -44
  42. package/src/functions/formatAncestryChain.test.ts +47 -0
  43. package/src/functions/formatAncestryChain.ts +11 -0
  44. package/src/functions/getUsableName.ts +0 -21
  45. package/src/types/types.ts +1 -32
  46. package/src/adapters/react/fiberToSimple.tsx +0 -72
  47. package/src/adapters/react/gatherFiberRoots.tsx +0 -36
  48. package/src/adapters/react/makeFiberId.tsx +0 -19
  49. package/src/adapters/react/searchDevtoolsRenderersForClosestTarget.ts +0 -15
  50. package/src/components/Button.tsx +0 -14
  51. package/src/components/ComponentOutline.tsx +0 -98
  52. package/src/components/SimpleNodeOutline.tsx +0 -27
  53. package/src/components/Tooltip.tsx +0 -28
  54. package/src/functions/cropPath.test.ts +0 -18
  55. package/src/functions/cropPath.ts +0 -12
  56. package/src/functions/evalTemplate.test.ts +0 -12
  57. package/src/functions/evalTemplate.ts +0 -8
  58. package/src/functions/findNames.ts +0 -20
  59. package/src/functions/getBoundingRect.tsx +0 -11
  60. package/src/functions/getComposedBoundingBox.tsx +0 -25
  61. package/src/functions/getIdsOnPathToRoot.tsx +0 -21
  62. package/src/functions/getMultipleElementsBoundingBox.tsx +0 -25
  63. package/src/functions/getPathToParent.tsx +0 -17
  64. package/src/functions/getUsableFileName.test.tsx +0 -24
  65. package/src/functions/getUsableFileName.tsx +0 -19
  66. package/src/functions/transformPath.test.ts +0 -28
  67. package/src/functions/transformPath.ts +0 -7
@@ -554,7 +554,7 @@ video {
554
554
  display: none;
555
555
  }
556
556
 
557
- [type='text'],input:where(:not([type])),[type='email'],[type='url'],[type='password'],[type='number'],[type='date'],[type='datetime-local'],[type='month'],[type='search'],[type='tel'],[type='time'],[type='week'],[multiple],textarea,select {
557
+ input:where([type='text']),input:where(:not([type])),input:where([type='email']),input:where([type='url']),input:where([type='password']),input:where([type='number']),input:where([type='date']),input:where([type='datetime-local']),input:where([type='month']),input:where([type='search']),input:where([type='tel']),input:where([type='time']),input:where([type='week']),select:where([multiple]),textarea,select {
558
558
  -webkit-appearance: none;
559
559
  -moz-appearance: none;
560
560
  appearance: none;
@@ -571,7 +571,7 @@ video {
571
571
  --tw-shadow: 0 0 #0000;
572
572
  }
573
573
 
574
- [type='text']:focus, input:where(:not([type])):focus, [type='email']:focus, [type='url']:focus, [type='password']:focus, [type='number']:focus, [type='date']:focus, [type='datetime-local']:focus, [type='month']:focus, [type='search']:focus, [type='tel']:focus, [type='time']:focus, [type='week']:focus, [multiple]:focus, textarea:focus, select:focus {
574
+ input:where([type='text']):focus, input:where(:not([type])):focus, input:where([type='email']):focus, input:where([type='url']):focus, input:where([type='password']):focus, input:where([type='number']):focus, input:where([type='date']):focus, input:where([type='datetime-local']):focus, input:where([type='month']):focus, input:where([type='search']):focus, input:where([type='tel']):focus, input:where([type='time']):focus, input:where([type='week']):focus, select:where([multiple]):focus, textarea:focus, select:focus {
575
575
  outline: 2px solid transparent;
576
576
  outline-offset: 2px;
577
577
  --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
@@ -600,6 +600,11 @@ input::placeholder,textarea::placeholder {
600
600
 
601
601
  ::-webkit-date-and-time-value {
602
602
  min-height: 1.5em;
603
+ text-align: inherit;
604
+ }
605
+
606
+ ::-webkit-datetime-edit {
607
+ display: inline-flex;
603
608
  }
604
609
 
605
610
  ::-webkit-datetime-edit,::-webkit-datetime-edit-year-field,::-webkit-datetime-edit-month-field,::-webkit-datetime-edit-day-field,::-webkit-datetime-edit-hour-field,::-webkit-datetime-edit-minute-field,::-webkit-datetime-edit-second-field,::-webkit-datetime-edit-millisecond-field,::-webkit-datetime-edit-meridiem-field {
@@ -617,7 +622,7 @@ select {
617
622
  print-color-adjust: exact;
618
623
  }
619
624
 
620
- [multiple],[size]:where(select:not([size="1"])) {
625
+ select:where([multiple]),select:where([size]:not([size="1"])) {
621
626
  background-image: initial;
622
627
  background-position: initial;
623
628
  background-repeat: unset;
@@ -627,7 +632,7 @@ select {
627
632
  print-color-adjust: unset;
628
633
  }
629
634
 
630
- [type='checkbox'],[type='radio'] {
635
+ input:where([type='checkbox']),input:where([type='radio']) {
631
636
  -webkit-appearance: none;
632
637
  -moz-appearance: none;
633
638
  appearance: none;
@@ -650,15 +655,15 @@ select {
650
655
  --tw-shadow: 0 0 #0000;
651
656
  }
652
657
 
653
- [type='checkbox'] {
658
+ input:where([type='checkbox']) {
654
659
  border-radius: 0px;
655
660
  }
656
661
 
657
- [type='radio'] {
662
+ input:where([type='radio']) {
658
663
  border-radius: 100%;
659
664
  }
660
665
 
661
- [type='checkbox']:focus,[type='radio']:focus {
666
+ input:where([type='checkbox']):focus,input:where([type='radio']):focus {
662
667
  outline: 2px solid transparent;
663
668
  outline-offset: 2px;
664
669
  --tw-ring-inset: var(--tw-empty,/*!*/ /*!*/);
@@ -670,7 +675,7 @@ select {
670
675
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
671
676
  }
672
677
 
673
- [type='checkbox']:checked,[type='radio']:checked {
678
+ input:where([type='checkbox']):checked,input:where([type='radio']):checked {
674
679
  border-color: transparent;
675
680
  background-color: currentColor;
676
681
  background-size: 100% 100%;
@@ -678,20 +683,36 @@ select {
678
683
  background-repeat: no-repeat;
679
684
  }
680
685
 
681
- [type='checkbox']:checked {
686
+ input:where([type='checkbox']):checked {
682
687
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
683
688
  }
684
689
 
685
- [type='radio']:checked {
690
+ @media (forced-colors: active) {
691
+ input:where([type='checkbox']):checked {
692
+ -webkit-appearance: auto;
693
+ -moz-appearance: auto;
694
+ appearance: auto;
695
+ }
696
+ }
697
+
698
+ input:where([type='radio']):checked {
686
699
  background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
687
700
  }
688
701
 
689
- [type='checkbox']:checked:hover,[type='checkbox']:checked:focus,[type='radio']:checked:hover,[type='radio']:checked:focus {
702
+ @media (forced-colors: active) {
703
+ input:where([type='radio']):checked {
704
+ -webkit-appearance: auto;
705
+ -moz-appearance: auto;
706
+ appearance: auto;
707
+ }
708
+ }
709
+
710
+ input:where([type='checkbox']):checked:hover,input:where([type='checkbox']):checked:focus,input:where([type='radio']):checked:hover,input:where([type='radio']):checked:focus {
690
711
  border-color: transparent;
691
712
  background-color: currentColor;
692
713
  }
693
714
 
694
- [type='checkbox']:indeterminate {
715
+ input:where([type='checkbox']):indeterminate {
695
716
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 16 16'%3e%3cpath stroke='white' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M4 8h8'/%3e%3c/svg%3e");
696
717
  border-color: transparent;
697
718
  background-color: currentColor;
@@ -700,12 +721,20 @@ select {
700
721
  background-repeat: no-repeat;
701
722
  }
702
723
 
703
- [type='checkbox']:indeterminate:hover,[type='checkbox']:indeterminate:focus {
724
+ @media (forced-colors: active) {
725
+ input:where([type='checkbox']):indeterminate {
726
+ -webkit-appearance: auto;
727
+ -moz-appearance: auto;
728
+ appearance: auto;
729
+ }
730
+ }
731
+
732
+ input:where([type='checkbox']):indeterminate:hover,input:where([type='checkbox']):indeterminate:focus {
704
733
  border-color: transparent;
705
734
  background-color: currentColor;
706
735
  }
707
736
 
708
- [type='file'] {
737
+ input:where([type='file']) {
709
738
  background: unset;
710
739
  border-color: inherit;
711
740
  border-width: 0;
@@ -715,11 +744,45 @@ select {
715
744
  line-height: inherit;
716
745
  }
717
746
 
718
- [type='file']:focus {
747
+ input:where([type='file']):focus {
719
748
  outline: 1px solid ButtonText;
720
749
  outline: 1px auto -webkit-focus-ring-color;
721
750
  }
722
751
 
752
+ .container {
753
+ width: 100%;
754
+ }
755
+
756
+ @media (min-width: 640px) {
757
+ .container {
758
+ max-width: 640px;
759
+ }
760
+ }
761
+
762
+ @media (min-width: 768px) {
763
+ .container {
764
+ max-width: 768px;
765
+ }
766
+ }
767
+
768
+ @media (min-width: 1024px) {
769
+ .container {
770
+ max-width: 1024px;
771
+ }
772
+ }
773
+
774
+ @media (min-width: 1280px) {
775
+ .container {
776
+ max-width: 1280px;
777
+ }
778
+ }
779
+
780
+ @media (min-width: 1536px) {
781
+ .container {
782
+ max-width: 1536px;
783
+ }
784
+ }
785
+
723
786
  .sr-only {
724
787
  position: absolute;
725
788
  width: 1px;
@@ -764,6 +827,10 @@ select {
764
827
  position: relative;
765
828
  }
766
829
 
830
+ .sticky {
831
+ position: sticky;
832
+ }
833
+
767
834
  .-bottom-7 {
768
835
  bottom: -1.75rem;
769
836
  }
@@ -1108,6 +1175,12 @@ select {
1108
1175
  overflow: scroll;
1109
1176
  }
1110
1177
 
1178
+ .truncate {
1179
+ overflow: hidden;
1180
+ text-overflow: ellipsis;
1181
+ white-space: nowrap;
1182
+ }
1183
+
1111
1184
  .text-ellipsis {
1112
1185
  text-overflow: ellipsis;
1113
1186
  }
@@ -1164,6 +1237,15 @@ select {
1164
1237
  border-style: solid;
1165
1238
  }
1166
1239
 
1240
+ .border-dashed {
1241
+ border-style: dashed;
1242
+ }
1243
+
1244
+ .border-amber-500 {
1245
+ --tw-border-opacity: 1;
1246
+ border-color: rgb(245 158 11 / var(--tw-border-opacity, 1));
1247
+ }
1248
+
1167
1249
  .border-blue-500 {
1168
1250
  --tw-border-opacity: 1;
1169
1251
  border-color: rgb(59 130 246 / var(--tw-border-opacity, 1));
@@ -1179,6 +1261,11 @@ select {
1179
1261
  border-color: rgb(209 213 219 / var(--tw-border-opacity, 1));
1180
1262
  }
1181
1263
 
1264
+ .border-gray-500 {
1265
+ --tw-border-opacity: 1;
1266
+ border-color: rgb(107 114 128 / var(--tw-border-opacity, 1));
1267
+ }
1268
+
1182
1269
  .border-gray-600 {
1183
1270
  --tw-border-opacity: 1;
1184
1271
  border-color: rgb(75 85 99 / var(--tw-border-opacity, 1));
@@ -1346,6 +1433,10 @@ select {
1346
1433
  padding: 1rem;
1347
1434
  }
1348
1435
 
1436
+ .p-5 {
1437
+ padding: 1.25rem;
1438
+ }
1439
+
1349
1440
  .p-6 {
1350
1441
  padding: 1.5rem;
1351
1442
  }
@@ -1681,10 +1772,19 @@ select {
1681
1772
  --tw-ring-color: rgb(30 64 175 / var(--tw-ring-opacity, 1));
1682
1773
  }
1683
1774
 
1775
+ .blur {
1776
+ --tw-blur: blur(8px);
1777
+ filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
1778
+ }
1779
+
1684
1780
  .filter {
1685
1781
  filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow);
1686
1782
  }
1687
1783
 
1784
+ .backdrop-filter {
1785
+ backdrop-filter: var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);
1786
+ }
1787
+
1688
1788
  .transition {
1689
1789
  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1690
1790
  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
@@ -1,27 +1,7 @@
1
- import reactAdapter from "./react/reactAdapter";
2
- import jsxAdapter from "./jsx/jsxAdapter";
3
- import svelteAdapter from "./svelte/svelteAdapter";
4
- import vueAdapter from "./vue/vueAdapter";
5
1
  import { AdapterId } from "../consts";
2
+ import { resolveAdapter } from "./resolveAdapter";
6
3
 
7
4
  export function getElementInfo(target: HTMLElement, adapterId?: AdapterId) {
8
- if (adapterId === "react") {
9
- return reactAdapter.getElementInfo(target);
10
- }
11
- if (adapterId === "svelte") {
12
- return svelteAdapter.getElementInfo(target);
13
- }
14
- if (adapterId === "jsx") {
15
- return jsxAdapter.getElementInfo(target);
16
- }
17
- if (adapterId === "vue") {
18
- return vueAdapter.getElementInfo(target);
19
- }
20
-
21
- return (
22
- jsxAdapter.getElementInfo(target) ||
23
- reactAdapter.getElementInfo(target) ||
24
- svelteAdapter.getElementInfo(target) ||
25
- vueAdapter.getElementInfo(target)
26
- );
5
+ const adapter = resolveAdapter(adapterId);
6
+ return adapter?.getElementInfo(target) ?? null;
27
7
  }
@@ -1,49 +1,10 @@
1
- import reactAdapter from "./react/reactAdapter";
2
- import {
3
- detectJSX,
4
- detectReact,
5
- detectSvelte,
6
- detectVue,
7
- } from "@locator/shared";
8
1
  import { ParentPathItem } from "./adapterApi";
9
- import svelteAdapter from "./svelte/svelteAdapter";
10
- import jsxAdapter from "./jsx/jsxAdapter";
11
- import vueAdapter from "./vue/vueAdapter";
2
+ import { resolveAdapter } from "./resolveAdapter";
12
3
 
13
4
  export function getParentsPaths(
14
5
  target: HTMLElement,
15
6
  adapterId?: string
16
7
  ): ParentPathItem[] {
17
- if (adapterId === "react" && reactAdapter.getParentsPaths) {
18
- return reactAdapter.getParentsPaths(target);
19
- }
20
- if (adapterId === "svelte" && svelteAdapter.getParentsPaths) {
21
- return svelteAdapter.getParentsPaths(target);
22
- }
23
- if (adapterId === "vue" && vueAdapter.getParentsPaths) {
24
- return vueAdapter.getParentsPaths(target);
25
- }
26
- if (adapterId === "jsx" && jsxAdapter.getParentsPaths) {
27
- return jsxAdapter.getParentsPaths(target);
28
- }
29
-
30
- if (detectSvelte() && svelteAdapter.getParentsPaths) {
31
- return svelteAdapter.getParentsPaths(target);
32
- }
33
-
34
- if (detectVue() && vueAdapter.getParentsPaths) {
35
- return vueAdapter.getParentsPaths(target);
36
- }
37
-
38
- if (detectReact() && reactAdapter.getParentsPaths) {
39
- return reactAdapter.getParentsPaths(target);
40
- }
41
-
42
- // // Must be last, because its global data leaks from Locator extension.
43
- // // Because the extension is in SolidJS and it uses JSX plugin in dev mode.
44
- if (detectJSX() && jsxAdapter.getParentsPaths) {
45
- return jsxAdapter.getParentsPaths(target);
46
- }
47
-
48
- return [];
8
+ const adapter = resolveAdapter(adapterId as any);
9
+ return adapter?.getParentsPaths(target) ?? [];
49
10
  }
@@ -1,45 +1,6 @@
1
- import reactAdapter from "./react/reactAdapter";
2
- import jsxAdapter from "./jsx/jsxAdapter";
3
- import svelteAdapter from "./svelte/svelteAdapter";
4
- import {
5
- detectJSX,
6
- detectReact,
7
- detectSvelte,
8
- detectVue,
9
- } from "@locator/shared";
10
- import vueAdapter from "./vue/vueAdapter";
1
+ import { resolveAdapter } from "./resolveAdapter";
11
2
 
12
3
  export function getTree(target: HTMLElement, adapterId?: string) {
13
- if (adapterId === "react" && reactAdapter.getTree) {
14
- return reactAdapter.getTree(target);
15
- }
16
- if (adapterId === "svelte" && svelteAdapter.getTree) {
17
- return svelteAdapter.getTree(target);
18
- }
19
- if (adapterId === "vue" && vueAdapter.getTree) {
20
- return vueAdapter.getTree(target);
21
- }
22
- if (adapterId === "jsx" && jsxAdapter.getTree) {
23
- return jsxAdapter.getTree(target);
24
- }
25
-
26
- if (detectSvelte() && svelteAdapter.getTree) {
27
- return svelteAdapter.getTree(target);
28
- }
29
-
30
- if (detectVue() && vueAdapter.getTree) {
31
- return vueAdapter.getTree(target);
32
- }
33
-
34
- if (detectReact() && reactAdapter.getTree) {
35
- return reactAdapter.getTree(target);
36
- }
37
-
38
- // Must be last, because its global data leaks from Locator extension.
39
- // Because the extension is in SolidJS and it uses JSX plugin in dev mode.
40
- if (detectJSX() && jsxAdapter.getTree) {
41
- return jsxAdapter.getTree(target);
42
- }
43
-
44
- return null;
4
+ const adapter = resolveAdapter(adapterId as any);
5
+ return adapter?.getTree?.(target) ?? null;
45
6
  }
@@ -54,7 +54,6 @@ export function getJSXComponentBoundingBox(
54
54
  );
55
55
  goParent(parent);
56
56
  }
57
- expData.wrappingComponentId;
58
57
  }
59
58
  } else {
60
59
  // If there is no locatorjs-id or locatorjs, we should go to the parent, because it can be some library element
@@ -128,8 +128,6 @@ export function getElementInfo(target: HTMLElement): FullElementInfo | null {
128
128
  };
129
129
  }
130
130
 
131
- // return deduplicateLabels(labels);
132
-
133
131
  return null;
134
132
  }
135
133
 
@@ -75,17 +75,6 @@ export function getDataForDataId(dataId: string) {
75
75
  line: expData.loc.start.line || 0,
76
76
  };
77
77
 
78
- // let label;
79
- // if (expData.type === "jsx") {
80
- // label =
81
- // (expData.wrappingComponent ? `${expData.wrappingComponent}: ` : "") +
82
- // expData.name;
83
- // } else {
84
- // label = `${expData.htmlTag ? `styled.${expData.htmlTag}` : "styled"}${
85
- // expData.name ? `: ${expData.name}` : ""
86
- // }`;
87
- // }
88
-
89
78
  return {
90
79
  link,
91
80
  label: expData.name,
@@ -33,13 +33,6 @@ export function getElementInfo(found: HTMLElement): FullElementInfo | null {
33
33
 
34
34
  const allPotentialComponentFibers = getAllWrappingParents(component);
35
35
 
36
- // This handles a common case when the component root is basically the comopnent itself, so I want to go to usage of the component
37
- // TODO: whaat? why? currently I see that it adds the original styled components which is not necessary.
38
-
39
- // if (fiber.return && fiber.return === fiber._debugOwner) {
40
- // allPotentialComponentFibers.unshift(fiber.return);
41
- // }
42
-
43
36
  allPotentialComponentFibers.forEach((fiber) => {
44
37
  const fiberWithSource = findDebugSource(fiber);
45
38
  if (fiberWithSource) {
@@ -0,0 +1,38 @@
1
+ import reactAdapter from "./react/reactAdapter";
2
+ import jsxAdapter from "./jsx/jsxAdapter";
3
+ import svelteAdapter from "./svelte/svelteAdapter";
4
+ import vueAdapter from "./vue/vueAdapter";
5
+ import {
6
+ detectJSX,
7
+ detectReact,
8
+ detectSvelte,
9
+ detectVue,
10
+ } from "@locator/shared";
11
+ import type { AdapterObject } from "./adapterApi";
12
+ import type { AdapterId } from "../consts";
13
+
14
+ const adapterMap: Record<AdapterId, AdapterObject> = {
15
+ react: reactAdapter,
16
+ svelte: svelteAdapter,
17
+ vue: vueAdapter,
18
+ jsx: jsxAdapter,
19
+ };
20
+
21
+ /**
22
+ * Resolve the framework adapter to use.
23
+ * If an explicit adapterId is given, return that adapter.
24
+ * Otherwise, auto-detect the framework in priority order.
25
+ */
26
+ export function resolveAdapter(adapterId?: AdapterId): AdapterObject | null {
27
+ if (adapterId) {
28
+ return adapterMap[adapterId] ?? null;
29
+ }
30
+
31
+ if (detectSvelte()) return svelteAdapter;
32
+ if (detectVue()) return vueAdapter;
33
+ if (detectReact()) return reactAdapter;
34
+ // Must be last: global data leaks from the LocatorJS extension (SolidJS + JSX plugin in dev)
35
+ if (detectJSX()) return jsxAdapter;
36
+
37
+ return null;
38
+ }
@@ -76,20 +76,6 @@ export class VueTreeNodeElement extends HtmlElementTreeNode {
76
76
  getComponent(): TreeNodeComponent | null {
77
77
  return null;
78
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
79
  }
94
80
 
95
81
  function getTree(element: HTMLElement): TreeState | null {
package/src/browserApi.ts CHANGED
@@ -158,8 +158,6 @@ export interface LocatorJSAPI {
158
158
  } | null>;
159
159
  }
160
160
 
161
- let adapterId: AdapterId | undefined;
162
-
163
161
  function resolveElement(
164
162
  elementOrSelector: HTMLElement | string
165
163
  ): HTMLElement | null {
@@ -170,7 +168,7 @@ function resolveElement(
170
168
  return elementOrSelector;
171
169
  }
172
170
 
173
- function getAncestryForElement(element: HTMLElement): AncestryItem[] | null {
171
+ function getAncestryForElement(element: HTMLElement, adapterId?: AdapterId): AncestryItem[] | null {
174
172
  const treeNode = createTreeNode(element, adapterId);
175
173
  if (!treeNode) {
176
174
  return null;
@@ -179,9 +177,10 @@ function getAncestryForElement(element: HTMLElement): AncestryItem[] | null {
179
177
  }
180
178
 
181
179
  async function getEnrichedAncestryForElement(
182
- element: HTMLElement
180
+ element: HTMLElement,
181
+ adapterId?: AdapterId
183
182
  ): Promise<AncestryItem[] | null> {
184
- const ancestry = getAncestryForElement(element);
183
+ const ancestry = getAncestryForElement(element, adapterId);
185
184
  if (!ancestry) return null;
186
185
  return enrichAncestryWithSourceMaps(ancestry, element);
187
186
  }
@@ -286,7 +285,7 @@ CYPRESS EXAMPLES:
286
285
  ----------------
287
286
 
288
287
  cy.window().then((win) => {
289
- const path = win.__locatorjs__.getPath('button.submit');
288
+ const path = win.__treelocator__.getPath('button.submit');
290
289
  cy.log(path);
291
290
  });
292
291
 
@@ -301,10 +300,8 @@ Documentation: https://github.com/wende/treelocatorjs
301
300
  `;
302
301
 
303
302
  export function createBrowserAPI(
304
- adapterIdParam?: AdapterId
303
+ adapterId?: AdapterId
305
304
  ): LocatorJSAPI {
306
- adapterId = adapterIdParam;
307
-
308
305
  return {
309
306
  getPath(elementOrSelector: HTMLElement | string): Promise<string | null> {
310
307
  const element = resolveElement(elementOrSelector);
@@ -312,7 +309,7 @@ export function createBrowserAPI(
312
309
  return Promise.resolve(null);
313
310
  }
314
311
 
315
- return getEnrichedAncestryForElement(element).then((ancestry) =>
312
+ return getEnrichedAncestryForElement(element, adapterId).then((ancestry) =>
316
313
  ancestry ? formatAncestryChain(ancestry) : null
317
314
  );
318
315
  },
@@ -325,7 +322,7 @@ export function createBrowserAPI(
325
322
  return Promise.resolve(null);
326
323
  }
327
324
 
328
- return getEnrichedAncestryForElement(element);
325
+ return getEnrichedAncestryForElement(element, adapterId);
329
326
  },
330
327
 
331
328
  getPathData(
@@ -336,7 +333,7 @@ export function createBrowserAPI(
336
333
  return Promise.resolve(null);
337
334
  }
338
335
 
339
- return getEnrichedAncestryForElement(element).then((ancestry) =>
336
+ return getEnrichedAncestryForElement(element, adapterId).then((ancestry) =>
340
337
  ancestry ? { path: formatAncestryChain(ancestry), ancestry } : null
341
338
  );
342
339
  },
@@ -9,6 +9,7 @@ export function MaybeOutline(props: {
9
9
  currentElement: HTMLElement;
10
10
  adapterId?: AdapterId;
11
11
  targets: Targets;
12
+ dashed?: boolean;
12
13
  }) {
13
14
  const elInfo = createMemo(() =>
14
15
  getElementInfo(props.currentElement, props.adapterId)
@@ -41,12 +42,13 @@ export function MaybeOutline(props: {
41
42
  <Outline
42
43
  element={elInfo()!}
43
44
  targets={props.targets}
45
+ dashed={props.dashed}
44
46
  />
45
47
  ) : phoenixInfo() ? (
46
48
  <div>
47
49
  {/* Element outline box */}
48
50
  <div
49
- class="fixed rounded border border-solid border-amber-500"
51
+ class={`fixed rounded border ${props.dashed ? "border-dashed" : "border-solid"} border-amber-500`}
50
52
  style={{
51
53
  "z-index": 2,
52
54
  left: box().x + "px",
@@ -81,7 +83,7 @@ export function MaybeOutline(props: {
81
83
  <div>
82
84
  {/* Element outline box */}
83
85
  <div
84
- class="fixed rounded border border-solid border-gray-500"
86
+ class={`fixed rounded border ${props.dashed ? "border-dashed" : "border-solid"} border-gray-500`}
85
87
  style={{
86
88
  "z-index": 2,
87
89
  left: box().x + "px",
@@ -25,6 +25,7 @@ export type AllBoxes = {
25
25
  export function Outline(props: {
26
26
  element: FullElementInfo;
27
27
  targets: Targets;
28
+ dashed?: boolean;
28
29
  }) {
29
30
  const box = () => props.element.thisElement.box;
30
31
 
@@ -130,7 +131,7 @@ export function Outline(props: {
130
131
  {domElementInfo() && <RenderBoxes allBoxes={domElementInfo()!} />}
131
132
  {/* Element outline box */}
132
133
  <div
133
- class="fixed rounded border border-solid border-sky-500"
134
+ class={`fixed rounded border ${props.dashed ? "border-dashed" : "border-solid"} border-sky-500`}
134
135
  style={{
135
136
  "z-index": 2,
136
137
  left: box().x + "px",