@treelocator/runtime 0.4.0 → 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.
- package/dist/_generated_styles.js +115 -15
- package/dist/adapters/getElementInfo.js +3 -17
- package/dist/adapters/getParentsPath.js +3 -33
- package/dist/adapters/getTree.js +3 -33
- package/dist/adapters/jsx/getJSXComponentBoundingBox.js +0 -1
- package/dist/adapters/jsx/jsxAdapter.js +0 -3
- package/dist/adapters/jsx/runtimeStore.js +0 -12
- package/dist/adapters/react/reactAdapter.js +0 -8
- package/dist/adapters/resolveAdapter.d.ts +8 -0
- package/dist/adapters/resolveAdapter.js +28 -0
- package/dist/adapters/vue/vueAdapter.js +0 -14
- package/dist/browserApi.d.ts +1 -1
- package/dist/browserApi.js +8 -10
- package/dist/components/MaybeOutline.d.ts +1 -0
- package/dist/components/MaybeOutline.js +38 -29
- package/dist/components/Outline.d.ts +1 -0
- package/dist/components/Outline.js +20 -16
- package/dist/components/Runtime.js +30 -18
- package/dist/dejitter/recorder.js +8 -13
- package/dist/functions/formatAncestryChain.d.ts +6 -0
- package/dist/functions/formatAncestryChain.js +11 -0
- package/dist/functions/formatAncestryChain.test.js +75 -1
- package/dist/functions/getUsableName.js +0 -21
- package/dist/output.css +10 -40
- package/dist/types/types.d.ts +1 -32
- package/package.json +1 -1
- package/src/_generated_styles.ts +115 -15
- package/src/adapters/getElementInfo.tsx +3 -23
- package/src/adapters/getParentsPath.tsx +3 -42
- package/src/adapters/getTree.tsx +3 -42
- package/src/adapters/jsx/getJSXComponentBoundingBox.ts +0 -1
- package/src/adapters/jsx/jsxAdapter.ts +0 -2
- package/src/adapters/jsx/runtimeStore.ts +0 -11
- package/src/adapters/react/reactAdapter.ts +0 -7
- package/src/adapters/resolveAdapter.ts +38 -0
- package/src/adapters/vue/vueAdapter.ts +0 -14
- package/src/browserApi.ts +9 -12
- package/src/components/MaybeOutline.tsx +4 -2
- package/src/components/Outline.tsx +2 -1
- package/src/components/Runtime.tsx +27 -18
- package/src/dejitter/recorder.ts +51 -56
- package/src/functions/formatAncestryChain.test.ts +47 -0
- package/src/functions/formatAncestryChain.ts +11 -0
- package/src/functions/getUsableName.ts +0 -21
- package/src/types/types.ts +1 -32
- package/src/adapters/react/fiberToSimple.tsx +0 -72
- package/src/adapters/react/gatherFiberRoots.tsx +0 -36
- package/src/adapters/react/makeFiberId.tsx +0 -19
- package/src/adapters/react/searchDevtoolsRenderersForClosestTarget.ts +0 -15
- package/src/components/Button.tsx +0 -14
- package/src/components/ComponentOutline.tsx +0 -98
- package/src/components/SimpleNodeOutline.tsx +0 -27
- package/src/components/Tooltip.tsx +0 -28
- package/src/functions/cropPath.test.ts +0 -18
- package/src/functions/cropPath.ts +0 -12
- package/src/functions/evalTemplate.test.ts +0 -12
- package/src/functions/evalTemplate.ts +0 -8
- package/src/functions/findNames.ts +0 -20
- package/src/functions/getBoundingRect.tsx +0 -11
- package/src/functions/getComposedBoundingBox.tsx +0 -25
- package/src/functions/getIdsOnPathToRoot.tsx +0 -21
- package/src/functions/getMultipleElementsBoundingBox.tsx +0 -25
- package/src/functions/getPathToParent.tsx +0 -17
- package/src/functions/getUsableFileName.test.tsx +0 -24
- package/src/functions/getUsableFileName.tsx +0 -19
- package/src/functions/transformPath.test.ts +0 -28
- package/src/functions/transformPath.ts +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treelocator/runtime",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "TreeLocatorJS runtime for component ancestry tracking. Alt+click any element to copy its component tree to clipboard. Exposes window.__treelocator__ API for browser automation (Playwright, Puppeteer, Selenium, Cypress).",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"locator",
|
package/src/_generated_styles.ts
CHANGED
|
@@ -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]:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
9
|
-
|
|
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
|
|
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
|
-
|
|
18
|
-
|
|
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
|
}
|
package/src/adapters/getTree.tsx
CHANGED
|
@@ -1,45 +1,6 @@
|
|
|
1
|
-
import
|
|
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
|
-
|
|
14
|
-
|
|
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
|
}
|
|
@@ -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.
|
|
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
|
-
|
|
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=
|
|
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=
|
|
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=
|
|
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",
|