agentation-vue 0.2.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/LICENSE +27 -0
- package/dist/AgentationVue.d.vue.ts +27 -0
- package/dist/AgentationVue.vue +839 -0
- package/dist/AgentationVue.vue.d.ts +27 -0
- package/dist/components/AgentationToolbar.d.vue.ts +36 -0
- package/dist/components/AgentationToolbar.vue +233 -0
- package/dist/components/AgentationToolbar.vue.d.ts +36 -0
- package/dist/components/AnnotationInput.d.vue.ts +21 -0
- package/dist/components/AnnotationInput.vue +105 -0
- package/dist/components/AnnotationInput.vue.d.ts +21 -0
- package/dist/components/AnnotationMarker.d.vue.ts +15 -0
- package/dist/components/AnnotationMarker.vue +46 -0
- package/dist/components/AnnotationMarker.vue.d.ts +15 -0
- package/dist/components/ComponentChain.d.vue.ts +10 -0
- package/dist/components/ComponentChain.vue +91 -0
- package/dist/components/ComponentChain.vue.d.ts +10 -0
- package/dist/components/ElementHighlight.d.vue.ts +9 -0
- package/dist/components/ElementHighlight.vue +33 -0
- package/dist/components/ElementHighlight.vue.d.ts +9 -0
- package/dist/components/SettingsPanel.d.vue.ts +10 -0
- package/dist/components/SettingsPanel.vue +143 -0
- package/dist/components/SettingsPanel.vue.d.ts +10 -0
- package/dist/components/SettingsPopover.d.vue.ts +14 -0
- package/dist/components/SettingsPopover.vue +235 -0
- package/dist/components/SettingsPopover.vue.d.ts +14 -0
- package/dist/components/VaButton.d.vue.ts +23 -0
- package/dist/components/VaButton.vue +19 -0
- package/dist/components/VaButton.vue.d.ts +23 -0
- package/dist/components/VaIcon.d.vue.ts +6 -0
- package/dist/components/VaIcon.vue +18 -0
- package/dist/components/VaIcon.vue.d.ts +6 -0
- package/dist/components/VaIconButton.d.vue.ts +25 -0
- package/dist/components/VaIconButton.vue +43 -0
- package/dist/components/VaIconButton.vue.d.ts +25 -0
- package/dist/components/VaToggle.d.vue.ts +10 -0
- package/dist/components/VaToggle.vue +23 -0
- package/dist/components/VaToggle.vue.d.ts +10 -0
- package/dist/composables/useAnimationPause.d.ts +7 -0
- package/dist/composables/useAnimationPause.js +52 -0
- package/dist/composables/useAnimationPause.mjs +43 -0
- package/dist/composables/useAnnotations.d.ts +105 -0
- package/dist/composables/useAnnotations.js +106 -0
- package/dist/composables/useAnnotations.mjs +108 -0
- package/dist/composables/useAreaSelect.d.ts +21 -0
- package/dist/composables/useAreaSelect.js +62 -0
- package/dist/composables/useAreaSelect.mjs +41 -0
- package/dist/composables/useElementDetection.d.ts +22 -0
- package/dist/composables/useElementDetection.js +85 -0
- package/dist/composables/useElementDetection.mjs +82 -0
- package/dist/composables/useInteractionMode.d.ts +5 -0
- package/dist/composables/useInteractionMode.js +29 -0
- package/dist/composables/useInteractionMode.mjs +20 -0
- package/dist/composables/useKeyboardShortcuts.d.ts +43 -0
- package/dist/composables/useKeyboardShortcuts.js +202 -0
- package/dist/composables/useKeyboardShortcuts.mjs +223 -0
- package/dist/composables/useMarkerPositions.d.ts +5 -0
- package/dist/composables/useMarkerPositions.js +45 -0
- package/dist/composables/useMarkerPositions.mjs +36 -0
- package/dist/composables/useMultiSelect.d.ts +20 -0
- package/dist/composables/useMultiSelect.js +108 -0
- package/dist/composables/useMultiSelect.mjs +85 -0
- package/dist/composables/useOutputFormatter.d.ts +5 -0
- package/dist/composables/useOutputFormatter.js +100 -0
- package/dist/composables/useOutputFormatter.mjs +91 -0
- package/dist/composables/useSettings.d.ts +14 -0
- package/dist/composables/useSettings.js +48 -0
- package/dist/composables/useSettings.mjs +38 -0
- package/dist/composables/useTextSelection.d.ts +11 -0
- package/dist/composables/useTextSelection.js +33 -0
- package/dist/composables/useTextSelection.mjs +22 -0
- package/dist/composables/useToolbarAutoHide.d.ts +19 -0
- package/dist/composables/useToolbarAutoHide.js +270 -0
- package/dist/composables/useToolbarAutoHide.mjs +208 -0
- package/dist/composables/useToolbarDragSnap.d.ts +30 -0
- package/dist/composables/useToolbarDragSnap.js +296 -0
- package/dist/composables/useToolbarDragSnap.mjs +245 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +8 -0
- package/dist/constants.mjs +2 -0
- package/dist/directives/vaTooltip.d.ts +22 -0
- package/dist/directives/vaTooltip.js +241 -0
- package/dist/directives/vaTooltip.mjs +257 -0
- package/dist/icons.d.ts +16 -0
- package/dist/icons.js +21 -0
- package/dist/icons.mjs +15 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +168 -0
- package/dist/index.mjs +30 -0
- package/dist/styles/agentation.css +1 -0
- package/dist/types.d.ts +70 -0
- package/dist/types.js +1 -0
- package/dist/types.mjs +0 -0
- package/dist/utils/clipboard.d.ts +1 -0
- package/dist/utils/clipboard.js +22 -0
- package/dist/utils/clipboard.mjs +16 -0
- package/dist/utils/dom-inspector.d.ts +7 -0
- package/dist/utils/dom-inspector.js +168 -0
- package/dist/utils/dom-inspector.mjs +242 -0
- package/dist/utils/math.d.ts +1 -0
- package/dist/utils/math.js +9 -0
- package/dist/utils/math.mjs +3 -0
- package/dist/utils/portal.d.ts +2 -0
- package/dist/utils/portal.js +18 -0
- package/dist/utils/portal.mjs +11 -0
- package/dist/utils/selectors.d.ts +3 -0
- package/dist/utils/selectors.js +103 -0
- package/dist/utils/selectors.mjs +105 -0
- package/dist/utils/style.d.ts +2 -0
- package/dist/utils/style.js +14 -0
- package/dist/utils/style.mjs +8 -0
- package/package.json +49 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
active?: boolean;
|
|
3
|
+
disabled?: boolean;
|
|
4
|
+
title?: string;
|
|
5
|
+
shortcut?: string;
|
|
6
|
+
};
|
|
7
|
+
declare var __VLS_1: {};
|
|
8
|
+
type __VLS_Slots = {} & {
|
|
9
|
+
default?: (props: typeof __VLS_1) => any;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_component: import("vue-demi").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue-demi").ComponentOptionsMixin, import("vue-demi").ComponentOptionsMixin, {
|
|
12
|
+
click: (event: MouseEvent) => any;
|
|
13
|
+
}, string, import("vue-demi").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
14
|
+
onClick?: ((event: MouseEvent) => any) | undefined;
|
|
15
|
+
}>, {
|
|
16
|
+
disabled: boolean;
|
|
17
|
+
active: boolean;
|
|
18
|
+
}, {}, {}, {}, string, import("vue-demi").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
declare const _default: __VLS_WithSlots<typeof __VLS_component, __VLS_Slots>;
|
|
20
|
+
export default _default;
|
|
21
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
22
|
+
new (): {
|
|
23
|
+
$slots: S;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
modelValue: boolean;
|
|
3
|
+
ariaLabel?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:model-value": (value: boolean) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
"onUpdate:model-value"?: ((value: boolean) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
const props = defineProps<{
|
|
3
|
+
modelValue: boolean
|
|
4
|
+
ariaLabel?: string
|
|
5
|
+
}>()
|
|
6
|
+
const emit = defineEmits<{ 'update:model-value': [value: boolean] }>()
|
|
7
|
+
|
|
8
|
+
function toggle() {
|
|
9
|
+
emit('update:model-value', !props.modelValue)
|
|
10
|
+
}
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<template>
|
|
14
|
+
<button
|
|
15
|
+
type="button"
|
|
16
|
+
class="__va-toggle"
|
|
17
|
+
:class="{ '__va-toggle--active': modelValue }"
|
|
18
|
+
role="switch"
|
|
19
|
+
:aria-checked="modelValue"
|
|
20
|
+
:aria-label="ariaLabel"
|
|
21
|
+
@click="toggle"
|
|
22
|
+
/>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
modelValue: boolean;
|
|
3
|
+
ariaLabel?: string;
|
|
4
|
+
};
|
|
5
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:model-value": (value: boolean) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
"onUpdate:model-value"?: ((value: boolean) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useAnimationPause = useAnimationPause;
|
|
7
|
+
var _vueDemi = require("vue-demi");
|
|
8
|
+
function useAnimationPause() {
|
|
9
|
+
const isPaused = (0, _vueDemi.ref)(false);
|
|
10
|
+
let styleEl = null;
|
|
11
|
+
function pause() {
|
|
12
|
+
if (styleEl) return;
|
|
13
|
+
styleEl = document.createElement("style");
|
|
14
|
+
styleEl.setAttribute("data-agentation-pause", "");
|
|
15
|
+
styleEl.textContent = `
|
|
16
|
+
*, *::before, *::after {
|
|
17
|
+
animation-play-state: paused !important;
|
|
18
|
+
transition: none !important;
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
document.head.appendChild(styleEl);
|
|
22
|
+
document.querySelectorAll("video").forEach(v => v.pause());
|
|
23
|
+
isPaused.value = true;
|
|
24
|
+
}
|
|
25
|
+
function resume() {
|
|
26
|
+
if (styleEl) {
|
|
27
|
+
styleEl.remove();
|
|
28
|
+
styleEl = null;
|
|
29
|
+
}
|
|
30
|
+
document.querySelectorAll("video").forEach(v => {
|
|
31
|
+
v.play().catch(() => {});
|
|
32
|
+
});
|
|
33
|
+
isPaused.value = false;
|
|
34
|
+
}
|
|
35
|
+
function toggle() {
|
|
36
|
+
if (isPaused.value) {
|
|
37
|
+
resume();
|
|
38
|
+
} else {
|
|
39
|
+
pause();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function cleanup() {
|
|
43
|
+
if (isPaused.value) resume();
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
isPaused,
|
|
47
|
+
toggle,
|
|
48
|
+
pause,
|
|
49
|
+
resume,
|
|
50
|
+
cleanup
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ref } from "vue-demi";
|
|
2
|
+
export function useAnimationPause() {
|
|
3
|
+
const isPaused = ref(false);
|
|
4
|
+
let styleEl = null;
|
|
5
|
+
function pause() {
|
|
6
|
+
if (styleEl)
|
|
7
|
+
return;
|
|
8
|
+
styleEl = document.createElement("style");
|
|
9
|
+
styleEl.setAttribute("data-agentation-pause", "");
|
|
10
|
+
styleEl.textContent = `
|
|
11
|
+
*, *::before, *::after {
|
|
12
|
+
animation-play-state: paused !important;
|
|
13
|
+
transition: none !important;
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
document.head.appendChild(styleEl);
|
|
17
|
+
document.querySelectorAll("video").forEach((v) => v.pause());
|
|
18
|
+
isPaused.value = true;
|
|
19
|
+
}
|
|
20
|
+
function resume() {
|
|
21
|
+
if (styleEl) {
|
|
22
|
+
styleEl.remove();
|
|
23
|
+
styleEl = null;
|
|
24
|
+
}
|
|
25
|
+
document.querySelectorAll("video").forEach((v) => {
|
|
26
|
+
v.play().catch(() => {
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
isPaused.value = false;
|
|
30
|
+
}
|
|
31
|
+
function toggle() {
|
|
32
|
+
if (isPaused.value) {
|
|
33
|
+
resume();
|
|
34
|
+
} else {
|
|
35
|
+
pause();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function cleanup() {
|
|
39
|
+
if (isPaused.value)
|
|
40
|
+
resume();
|
|
41
|
+
}
|
|
42
|
+
return { isPaused, toggle, pause, resume, cleanup };
|
|
43
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { Annotation } from '../types';
|
|
2
|
+
declare function setScopeUrl(url: string): void;
|
|
3
|
+
declare function addAnnotation(annotation: Omit<Annotation, 'id' | 'timestamp'>): Annotation;
|
|
4
|
+
declare function removeAnnotation(id: string): Annotation | undefined;
|
|
5
|
+
declare function updateAnnotation(id: string, updates: Partial<Annotation>): Annotation | undefined;
|
|
6
|
+
declare function clearAnnotations(): Annotation[];
|
|
7
|
+
export declare function useAnnotations(initialUrl?: string): {
|
|
8
|
+
annotations: import("vue-demi").Ref<{
|
|
9
|
+
id: string;
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
comment: string;
|
|
13
|
+
element: string;
|
|
14
|
+
elementPath: string;
|
|
15
|
+
timestamp: number;
|
|
16
|
+
_targetRef?: WeakRef<Element>;
|
|
17
|
+
url?: string | undefined;
|
|
18
|
+
selectedText?: string | undefined;
|
|
19
|
+
boundingBox?: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
width: number;
|
|
23
|
+
height: number;
|
|
24
|
+
} | undefined;
|
|
25
|
+
nearbyText?: string | undefined;
|
|
26
|
+
cssClasses?: string | undefined;
|
|
27
|
+
nearbyElements?: string | undefined;
|
|
28
|
+
computedStyles?: string | undefined;
|
|
29
|
+
fullPath?: string | undefined;
|
|
30
|
+
accessibility?: string | undefined;
|
|
31
|
+
isFixed?: boolean | undefined;
|
|
32
|
+
vueComponents?: string | undefined;
|
|
33
|
+
isMultiSelect?: boolean | undefined;
|
|
34
|
+
elements?: {
|
|
35
|
+
element: string;
|
|
36
|
+
elementPath: string;
|
|
37
|
+
cssClasses?: string | undefined;
|
|
38
|
+
boundingBox?: {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
width: number;
|
|
42
|
+
height: number;
|
|
43
|
+
} | undefined;
|
|
44
|
+
vueComponents?: string | undefined;
|
|
45
|
+
}[] | undefined;
|
|
46
|
+
isAreaSelect?: boolean | undefined;
|
|
47
|
+
area?: {
|
|
48
|
+
x: number;
|
|
49
|
+
y: number;
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
} | undefined;
|
|
53
|
+
}[], Annotation[] | {
|
|
54
|
+
id: string;
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
comment: string;
|
|
58
|
+
element: string;
|
|
59
|
+
elementPath: string;
|
|
60
|
+
timestamp: number;
|
|
61
|
+
_targetRef?: WeakRef<Element>;
|
|
62
|
+
url?: string | undefined;
|
|
63
|
+
selectedText?: string | undefined;
|
|
64
|
+
boundingBox?: {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
width: number;
|
|
68
|
+
height: number;
|
|
69
|
+
} | undefined;
|
|
70
|
+
nearbyText?: string | undefined;
|
|
71
|
+
cssClasses?: string | undefined;
|
|
72
|
+
nearbyElements?: string | undefined;
|
|
73
|
+
computedStyles?: string | undefined;
|
|
74
|
+
fullPath?: string | undefined;
|
|
75
|
+
accessibility?: string | undefined;
|
|
76
|
+
isFixed?: boolean | undefined;
|
|
77
|
+
vueComponents?: string | undefined;
|
|
78
|
+
isMultiSelect?: boolean | undefined;
|
|
79
|
+
elements?: {
|
|
80
|
+
element: string;
|
|
81
|
+
elementPath: string;
|
|
82
|
+
cssClasses?: string | undefined;
|
|
83
|
+
boundingBox?: {
|
|
84
|
+
x: number;
|
|
85
|
+
y: number;
|
|
86
|
+
width: number;
|
|
87
|
+
height: number;
|
|
88
|
+
} | undefined;
|
|
89
|
+
vueComponents?: string | undefined;
|
|
90
|
+
}[] | undefined;
|
|
91
|
+
isAreaSelect?: boolean | undefined;
|
|
92
|
+
area?: {
|
|
93
|
+
x: number;
|
|
94
|
+
y: number;
|
|
95
|
+
width: number;
|
|
96
|
+
height: number;
|
|
97
|
+
} | undefined;
|
|
98
|
+
}[]>;
|
|
99
|
+
addAnnotation: typeof addAnnotation;
|
|
100
|
+
removeAnnotation: typeof removeAnnotation;
|
|
101
|
+
updateAnnotation: typeof updateAnnotation;
|
|
102
|
+
clearAnnotations: typeof clearAnnotations;
|
|
103
|
+
setScopeUrl: typeof setScopeUrl;
|
|
104
|
+
};
|
|
105
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useAnnotations = useAnnotations;
|
|
7
|
+
var _vueDemi = require("vue-demi");
|
|
8
|
+
const STORAGE_KEY = "agentation-vue-annotations";
|
|
9
|
+
function serializeAnnotations(annotations2) {
|
|
10
|
+
return JSON.stringify(annotations2.map(({
|
|
11
|
+
_targetRef,
|
|
12
|
+
...rest
|
|
13
|
+
}) => rest));
|
|
14
|
+
}
|
|
15
|
+
function getCurrentUrl() {
|
|
16
|
+
return typeof window !== "undefined" ? window.location.href : "";
|
|
17
|
+
}
|
|
18
|
+
function parseStore(raw, currentUrl) {
|
|
19
|
+
if (!raw) return {};
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(raw);
|
|
22
|
+
if (Array.isArray(parsed)) return {
|
|
23
|
+
[currentUrl]: parsed
|
|
24
|
+
};
|
|
25
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
26
|
+
return Object.fromEntries(Object.entries(parsed).filter(([, value]) => Array.isArray(value)));
|
|
27
|
+
} catch {}
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
function loadAnnotations(url) {
|
|
31
|
+
try {
|
|
32
|
+
const stored = sessionStorage.getItem(STORAGE_KEY);
|
|
33
|
+
const store = parseStore(stored, url);
|
|
34
|
+
const annotations2 = store[url];
|
|
35
|
+
return Array.isArray(annotations2) ? annotations2 : [];
|
|
36
|
+
} catch {}
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
function getCounterSeed(annotations2) {
|
|
40
|
+
return annotations2.reduce((max, annotation) => {
|
|
41
|
+
const parsed = Number.parseInt(annotation.id, 10);
|
|
42
|
+
return Number.isFinite(parsed) ? Math.max(max, parsed) : max;
|
|
43
|
+
}, 0);
|
|
44
|
+
}
|
|
45
|
+
const annotations = (0, _vueDemi.ref)([]);
|
|
46
|
+
let scopedUrl = getCurrentUrl();
|
|
47
|
+
let counter = 0;
|
|
48
|
+
function setScopeUrl(url) {
|
|
49
|
+
scopedUrl = url || getCurrentUrl();
|
|
50
|
+
annotations.value = loadAnnotations(scopedUrl);
|
|
51
|
+
counter = getCounterSeed(annotations.value);
|
|
52
|
+
}
|
|
53
|
+
function save() {
|
|
54
|
+
try {
|
|
55
|
+
const stored = sessionStorage.getItem(STORAGE_KEY);
|
|
56
|
+
const store = parseStore(stored, scopedUrl);
|
|
57
|
+
if (annotations.value.length > 0) store[scopedUrl] = annotations.value;else delete store[scopedUrl];
|
|
58
|
+
const serialized = JSON.stringify(Object.fromEntries(Object.entries(store).map(([url, scopedAnnotations]) => [url, JSON.parse(serializeAnnotations(scopedAnnotations))])));
|
|
59
|
+
sessionStorage.setItem(STORAGE_KEY, serialized);
|
|
60
|
+
} catch {}
|
|
61
|
+
}
|
|
62
|
+
function addAnnotation(annotation) {
|
|
63
|
+
counter++;
|
|
64
|
+
const full = {
|
|
65
|
+
...annotation,
|
|
66
|
+
url: annotation.url || scopedUrl,
|
|
67
|
+
id: String(counter),
|
|
68
|
+
timestamp: Date.now()
|
|
69
|
+
};
|
|
70
|
+
annotations.value.push(full);
|
|
71
|
+
save();
|
|
72
|
+
return full;
|
|
73
|
+
}
|
|
74
|
+
function removeAnnotation(id) {
|
|
75
|
+
const index = annotations.value.findIndex(a => a.id === id);
|
|
76
|
+
if (index === -1) return void 0;
|
|
77
|
+
const [removed] = annotations.value.splice(index, 1);
|
|
78
|
+
save();
|
|
79
|
+
return removed;
|
|
80
|
+
}
|
|
81
|
+
function updateAnnotation(id, updates) {
|
|
82
|
+
const ann = annotations.value.find(a => a.id === id);
|
|
83
|
+
if (!ann) return void 0;
|
|
84
|
+
Object.assign(ann, updates);
|
|
85
|
+
save();
|
|
86
|
+
return ann;
|
|
87
|
+
}
|
|
88
|
+
function clearAnnotations() {
|
|
89
|
+
const cleared = [...annotations.value];
|
|
90
|
+
annotations.value.splice(0);
|
|
91
|
+
counter = 0;
|
|
92
|
+
save();
|
|
93
|
+
return cleared;
|
|
94
|
+
}
|
|
95
|
+
setScopeUrl(scopedUrl);
|
|
96
|
+
function useAnnotations(initialUrl = getCurrentUrl()) {
|
|
97
|
+
setScopeUrl(initialUrl);
|
|
98
|
+
return {
|
|
99
|
+
annotations,
|
|
100
|
+
addAnnotation,
|
|
101
|
+
removeAnnotation,
|
|
102
|
+
updateAnnotation,
|
|
103
|
+
clearAnnotations,
|
|
104
|
+
setScopeUrl
|
|
105
|
+
};
|
|
106
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { ref } from "vue-demi";
|
|
2
|
+
const STORAGE_KEY = "agentation-vue-annotations";
|
|
3
|
+
function serializeAnnotations(annotations2) {
|
|
4
|
+
return JSON.stringify(annotations2.map(({ _targetRef, ...rest }) => rest));
|
|
5
|
+
}
|
|
6
|
+
function getCurrentUrl() {
|
|
7
|
+
return typeof window !== "undefined" ? window.location.href : "";
|
|
8
|
+
}
|
|
9
|
+
function parseStore(raw, currentUrl) {
|
|
10
|
+
if (!raw)
|
|
11
|
+
return {};
|
|
12
|
+
try {
|
|
13
|
+
const parsed = JSON.parse(raw);
|
|
14
|
+
if (Array.isArray(parsed))
|
|
15
|
+
return { [currentUrl]: parsed };
|
|
16
|
+
if (!parsed || typeof parsed !== "object")
|
|
17
|
+
return {};
|
|
18
|
+
return Object.fromEntries(
|
|
19
|
+
Object.entries(parsed).filter(([, value]) => Array.isArray(value))
|
|
20
|
+
);
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
function loadAnnotations(url) {
|
|
26
|
+
try {
|
|
27
|
+
const stored = sessionStorage.getItem(STORAGE_KEY);
|
|
28
|
+
const store = parseStore(stored, url);
|
|
29
|
+
const annotations2 = store[url];
|
|
30
|
+
return Array.isArray(annotations2) ? annotations2 : [];
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
function getCounterSeed(annotations2) {
|
|
36
|
+
return annotations2.reduce((max, annotation) => {
|
|
37
|
+
const parsed = Number.parseInt(annotation.id, 10);
|
|
38
|
+
return Number.isFinite(parsed) ? Math.max(max, parsed) : max;
|
|
39
|
+
}, 0);
|
|
40
|
+
}
|
|
41
|
+
const annotations = ref([]);
|
|
42
|
+
let scopedUrl = getCurrentUrl();
|
|
43
|
+
let counter = 0;
|
|
44
|
+
function setScopeUrl(url) {
|
|
45
|
+
scopedUrl = url || getCurrentUrl();
|
|
46
|
+
annotations.value = loadAnnotations(scopedUrl);
|
|
47
|
+
counter = getCounterSeed(annotations.value);
|
|
48
|
+
}
|
|
49
|
+
function save() {
|
|
50
|
+
try {
|
|
51
|
+
const stored = sessionStorage.getItem(STORAGE_KEY);
|
|
52
|
+
const store = parseStore(stored, scopedUrl);
|
|
53
|
+
if (annotations.value.length > 0)
|
|
54
|
+
store[scopedUrl] = annotations.value;
|
|
55
|
+
else
|
|
56
|
+
delete store[scopedUrl];
|
|
57
|
+
const serialized = JSON.stringify(
|
|
58
|
+
Object.fromEntries(
|
|
59
|
+
Object.entries(store).map(([url, scopedAnnotations]) => [
|
|
60
|
+
url,
|
|
61
|
+
JSON.parse(serializeAnnotations(scopedAnnotations))
|
|
62
|
+
])
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
sessionStorage.setItem(STORAGE_KEY, serialized);
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function addAnnotation(annotation) {
|
|
70
|
+
counter++;
|
|
71
|
+
const full = {
|
|
72
|
+
...annotation,
|
|
73
|
+
url: annotation.url || scopedUrl,
|
|
74
|
+
id: String(counter),
|
|
75
|
+
timestamp: Date.now()
|
|
76
|
+
};
|
|
77
|
+
annotations.value.push(full);
|
|
78
|
+
save();
|
|
79
|
+
return full;
|
|
80
|
+
}
|
|
81
|
+
function removeAnnotation(id) {
|
|
82
|
+
const index = annotations.value.findIndex((a) => a.id === id);
|
|
83
|
+
if (index === -1)
|
|
84
|
+
return void 0;
|
|
85
|
+
const [removed] = annotations.value.splice(index, 1);
|
|
86
|
+
save();
|
|
87
|
+
return removed;
|
|
88
|
+
}
|
|
89
|
+
function updateAnnotation(id, updates) {
|
|
90
|
+
const ann = annotations.value.find((a) => a.id === id);
|
|
91
|
+
if (!ann)
|
|
92
|
+
return void 0;
|
|
93
|
+
Object.assign(ann, updates);
|
|
94
|
+
save();
|
|
95
|
+
return ann;
|
|
96
|
+
}
|
|
97
|
+
function clearAnnotations() {
|
|
98
|
+
const cleared = [...annotations.value];
|
|
99
|
+
annotations.value.splice(0);
|
|
100
|
+
counter = 0;
|
|
101
|
+
save();
|
|
102
|
+
return cleared;
|
|
103
|
+
}
|
|
104
|
+
setScopeUrl(scopedUrl);
|
|
105
|
+
export function useAnnotations(initialUrl = getCurrentUrl()) {
|
|
106
|
+
setScopeUrl(initialUrl);
|
|
107
|
+
return { annotations, addAnnotation, removeAnnotation, updateAnnotation, clearAnnotations, setScopeUrl };
|
|
108
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Ref } from 'vue-demi';
|
|
2
|
+
import type { BoundingBox, InteractionMode } from '../types';
|
|
3
|
+
export declare function useAreaSelect(mode: Ref<InteractionMode>, transitionFn: (to: InteractionMode) => boolean): {
|
|
4
|
+
areaRect: Ref<{
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
} | null, BoundingBox | {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
} | null>;
|
|
15
|
+
isAreaMode: Ref<boolean, boolean>;
|
|
16
|
+
toggleAreaMode: () => void;
|
|
17
|
+
onMouseDown: (e: MouseEvent) => boolean;
|
|
18
|
+
onMouseMove: (e: MouseEvent) => void;
|
|
19
|
+
onMouseUp: () => void;
|
|
20
|
+
reset: () => void;
|
|
21
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useAreaSelect = useAreaSelect;
|
|
7
|
+
var _vueDemi = require("vue-demi");
|
|
8
|
+
function useAreaSelect(mode, transitionFn) {
|
|
9
|
+
const areaRect = (0, _vueDemi.ref)(null);
|
|
10
|
+
const isAreaMode = (0, _vueDemi.ref)(false);
|
|
11
|
+
let startX = 0;
|
|
12
|
+
let startY = 0;
|
|
13
|
+
function toggleAreaMode() {
|
|
14
|
+
isAreaMode.value = !isAreaMode.value;
|
|
15
|
+
}
|
|
16
|
+
function onMouseDown(e) {
|
|
17
|
+
const shouldActivate = mode.value === "inspect" && e.altKey || mode.value === "inspect" && isAreaMode.value;
|
|
18
|
+
if (!shouldActivate) return false;
|
|
19
|
+
e.preventDefault();
|
|
20
|
+
document.documentElement.style.userSelect = "none";
|
|
21
|
+
startX = e.clientX;
|
|
22
|
+
startY = e.clientY;
|
|
23
|
+
areaRect.value = {
|
|
24
|
+
x: startX,
|
|
25
|
+
y: startY,
|
|
26
|
+
width: 0,
|
|
27
|
+
height: 0
|
|
28
|
+
};
|
|
29
|
+
transitionFn("area-selecting");
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
function onMouseMove(e) {
|
|
33
|
+
if (mode.value !== "area-selecting") return;
|
|
34
|
+
const x = Math.min(startX, e.clientX);
|
|
35
|
+
const y = Math.min(startY, e.clientY);
|
|
36
|
+
const width = Math.abs(e.clientX - startX);
|
|
37
|
+
const height = Math.abs(e.clientY - startY);
|
|
38
|
+
areaRect.value = {
|
|
39
|
+
x,
|
|
40
|
+
y,
|
|
41
|
+
width,
|
|
42
|
+
height
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function onMouseUp() {
|
|
46
|
+
if (mode.value !== "area-selecting") return;
|
|
47
|
+
document.documentElement.style.userSelect = "";
|
|
48
|
+
}
|
|
49
|
+
function reset() {
|
|
50
|
+
areaRect.value = null;
|
|
51
|
+
document.documentElement.style.userSelect = "";
|
|
52
|
+
}
|
|
53
|
+
return {
|
|
54
|
+
areaRect,
|
|
55
|
+
isAreaMode,
|
|
56
|
+
toggleAreaMode,
|
|
57
|
+
onMouseDown,
|
|
58
|
+
onMouseMove,
|
|
59
|
+
onMouseUp,
|
|
60
|
+
reset
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ref } from "vue-demi";
|
|
2
|
+
export function useAreaSelect(mode, transitionFn) {
|
|
3
|
+
const areaRect = ref(null);
|
|
4
|
+
const isAreaMode = ref(false);
|
|
5
|
+
let startX = 0;
|
|
6
|
+
let startY = 0;
|
|
7
|
+
function toggleAreaMode() {
|
|
8
|
+
isAreaMode.value = !isAreaMode.value;
|
|
9
|
+
}
|
|
10
|
+
function onMouseDown(e) {
|
|
11
|
+
const shouldActivate = mode.value === "inspect" && e.altKey || mode.value === "inspect" && isAreaMode.value;
|
|
12
|
+
if (!shouldActivate)
|
|
13
|
+
return false;
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
document.documentElement.style.userSelect = "none";
|
|
16
|
+
startX = e.clientX;
|
|
17
|
+
startY = e.clientY;
|
|
18
|
+
areaRect.value = { x: startX, y: startY, width: 0, height: 0 };
|
|
19
|
+
transitionFn("area-selecting");
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
function onMouseMove(e) {
|
|
23
|
+
if (mode.value !== "area-selecting")
|
|
24
|
+
return;
|
|
25
|
+
const x = Math.min(startX, e.clientX);
|
|
26
|
+
const y = Math.min(startY, e.clientY);
|
|
27
|
+
const width = Math.abs(e.clientX - startX);
|
|
28
|
+
const height = Math.abs(e.clientY - startY);
|
|
29
|
+
areaRect.value = { x, y, width, height };
|
|
30
|
+
}
|
|
31
|
+
function onMouseUp() {
|
|
32
|
+
if (mode.value !== "area-selecting")
|
|
33
|
+
return;
|
|
34
|
+
document.documentElement.style.userSelect = "";
|
|
35
|
+
}
|
|
36
|
+
function reset() {
|
|
37
|
+
areaRect.value = null;
|
|
38
|
+
document.documentElement.style.userSelect = "";
|
|
39
|
+
}
|
|
40
|
+
return { areaRect, isAreaMode, toggleAreaMode, onMouseDown, onMouseMove, onMouseUp, reset };
|
|
41
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Ref } from 'vue-demi';
|
|
2
|
+
import type { BoundingBox } from '../types';
|
|
3
|
+
export declare function useElementDetection(overlayRef: Ref<HTMLElement | null>, showComponentTree?: () => boolean): {
|
|
4
|
+
hoveredElement: Ref<Element | null, Element | null>;
|
|
5
|
+
hoveredRect: Ref<{
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
} | null, BoundingBox | {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
} | null>;
|
|
16
|
+
hoveredName: Ref<string, string>;
|
|
17
|
+
hoveredComponentChain: Ref<string | undefined, string | undefined>;
|
|
18
|
+
onMouseMove: (e: MouseEvent) => void;
|
|
19
|
+
clearHighlight: () => void;
|
|
20
|
+
getElementUnderOverlay: (e: MouseEvent) => Element | null;
|
|
21
|
+
cleanup: () => void;
|
|
22
|
+
};
|