agentation-vue 0.2.3 → 0.2.4
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/AgentationVue.vue +2 -6
- package/dist/components/AnnotationInput.vue +2 -2
- package/dist/components/AnnotationMarker.vue +5 -5
- package/dist/components/ComponentChain.vue +4 -1
- package/dist/components/SettingsPanel.vue +2 -6
- package/package.json +4 -10
- package/dist/composables/useAnimationPause.js +0 -52
- package/dist/composables/useAnnotations.js +0 -106
- package/dist/composables/useAreaSelect.js +0 -62
- package/dist/composables/useElementDetection.js +0 -85
- package/dist/composables/useInteractionMode.js +0 -29
- package/dist/composables/useKeyboardShortcuts.js +0 -202
- package/dist/composables/useMarkerPositions.js +0 -45
- package/dist/composables/useMultiSelect.js +0 -108
- package/dist/composables/useOutputFormatter.js +0 -100
- package/dist/composables/useSettings.js +0 -48
- package/dist/composables/useTextSelection.js +0 -33
- package/dist/composables/useToolbarAutoHide.js +0 -270
- package/dist/composables/useToolbarDragSnap.js +0 -296
- package/dist/constants.js +0 -8
- package/dist/directives/vaTooltip.js +0 -241
- package/dist/icons.js +0 -21
- package/dist/index.js +0 -168
- package/dist/types.js +0 -1
- package/dist/utils/clipboard.js +0 -22
- package/dist/utils/dom-inspector.js +0 -168
- package/dist/utils/math.js +0 -9
- package/dist/utils/portal.js +0 -18
- package/dist/utils/selectors.js +0 -103
- package/dist/utils/style.js +0 -14
package/dist/AgentationVue.vue
CHANGED
|
@@ -618,12 +618,8 @@ onBeforeUnmount(() => {
|
|
|
618
618
|
v-if="mode !== 'idle'"
|
|
619
619
|
ref="overlayEl"
|
|
620
620
|
class="__va-intercept"
|
|
621
|
-
:class="{
|
|
622
|
-
|
|
623
|
-
}"
|
|
624
|
-
:style="mode === 'inspect' && !effectiveBlockPageInteractions ? {
|
|
625
|
-
pointerEvents: 'none'
|
|
626
|
-
} : void 0"
|
|
621
|
+
:class="{ '__va-intercept--input-open': mode === 'input-open' }"
|
|
622
|
+
:style="mode === 'inspect' && !effectiveBlockPageInteractions ? { pointerEvents: 'none' } : void 0"
|
|
627
623
|
@mousemove="onOverlayMouseMove"
|
|
628
624
|
@mousedown="onOverlayMouseDown"
|
|
629
625
|
@mouseup="onOverlayMouseUp"
|
|
@@ -50,7 +50,7 @@ onMounted(() => {
|
|
|
50
50
|
>
|
|
51
51
|
<summary class="__va-input-styles-summary">
|
|
52
52
|
<ComponentChain v-if="componentChain" :chain="componentChain" variant="light" truncate="leaf" />
|
|
53
|
-
<span v-else class="__va-input-styles-element">{{ elementName ||
|
|
53
|
+
<span v-else class="__va-input-styles-element">{{ elementName || "Annotation" }}</span>
|
|
54
54
|
</summary>
|
|
55
55
|
<div class="__va-input-styles-block">
|
|
56
56
|
<div
|
|
@@ -65,7 +65,7 @@ onMounted(() => {
|
|
|
65
65
|
<div v-else-if="componentChain" class="__va-input-chain">
|
|
66
66
|
<ComponentChain :chain="componentChain" variant="light" truncate="leaf" />
|
|
67
67
|
</div>
|
|
68
|
-
<span v-else class="__va-input-label">{{ elementName ||
|
|
68
|
+
<span v-else class="__va-input-label">{{ elementName || "Annotation" }}</span>
|
|
69
69
|
<input
|
|
70
70
|
ref="inputEl"
|
|
71
71
|
v-model="comment"
|
|
@@ -21,11 +21,11 @@ const markerStyle = computed(() => ({
|
|
|
21
21
|
<div
|
|
22
22
|
class="__va-marker"
|
|
23
23
|
:class="{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
24
|
+
'__va-marker--fixed': isFixed,
|
|
25
|
+
'__va-marker--stale': isStale,
|
|
26
|
+
'__va-marker--pending': isPending,
|
|
27
|
+
'__va-marker--selection': isSelection
|
|
28
|
+
}"
|
|
29
29
|
:style="markerStyle"
|
|
30
30
|
data-agentation-vue
|
|
31
31
|
@click.stop="$emit('click')"
|
|
@@ -45,7 +45,10 @@ const leafExpanded = ref(false);
|
|
|
45
45
|
<span
|
|
46
46
|
v-else-if="truncate === 'leaf'"
|
|
47
47
|
class="__va-comp-chain"
|
|
48
|
-
:class="[
|
|
48
|
+
:class="[
|
|
49
|
+
`__va-comp-chain--${variant}`,
|
|
50
|
+
shouldTruncate ? '__va-comp-chain--collapsible' : ''
|
|
51
|
+
]"
|
|
49
52
|
@click.stop="shouldTruncate ? leafExpanded = !leafExpanded : void 0"
|
|
50
53
|
>
|
|
51
54
|
<template v-if="!shouldTruncate || leafExpanded">
|
|
@@ -72,12 +72,8 @@ function toggleTheme() {
|
|
|
72
72
|
:key="color"
|
|
73
73
|
type="button"
|
|
74
74
|
class="__va-color-swatch"
|
|
75
|
-
:class="{
|
|
76
|
-
|
|
77
|
-
}"
|
|
78
|
-
:style="{
|
|
79
|
-
background: color
|
|
80
|
-
}"
|
|
75
|
+
:class="{ '__va-color-swatch--active': settings.markerColor === color }"
|
|
76
|
+
:style="{ background: color }"
|
|
81
77
|
@click="update('markerColor', color)"
|
|
82
78
|
/>
|
|
83
79
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentation-vue",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "Visual feedback tool for AI coding agents — Vue 2.7 & 3",
|
|
5
5
|
"author": "Dorian Becker",
|
|
6
6
|
"license": "PolyForm-Shield-1.0.0",
|
|
@@ -23,18 +23,12 @@
|
|
|
23
23
|
],
|
|
24
24
|
"exports": {
|
|
25
25
|
".": {
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
"default": "./dist/index.mjs"
|
|
29
|
-
},
|
|
30
|
-
"require": {
|
|
31
|
-
"types": "./dist/index.d.ts",
|
|
32
|
-
"default": "./dist/index.js"
|
|
33
|
-
}
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.mjs"
|
|
34
28
|
},
|
|
35
29
|
"./style.css": "./dist/styles/agentation.css"
|
|
36
30
|
},
|
|
37
|
-
"main": "./dist/index.
|
|
31
|
+
"main": "./dist/index.mjs",
|
|
38
32
|
"module": "./dist/index.mjs",
|
|
39
33
|
"types": "./dist/index.d.ts",
|
|
40
34
|
"files": [
|
|
@@ -1,52 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,62 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useElementDetection = useElementDetection;
|
|
7
|
-
var _vueDemi = require("vue-demi");
|
|
8
|
-
var _constants = require("../constants");
|
|
9
|
-
var _domInspector = require("../utils/dom-inspector");
|
|
10
|
-
var _selectors = require("../utils/selectors");
|
|
11
|
-
function useElementDetection(overlayRef, showComponentTree) {
|
|
12
|
-
const hoveredElement = (0, _vueDemi.ref)(null);
|
|
13
|
-
const hoveredRect = (0, _vueDemi.ref)(null);
|
|
14
|
-
const hoveredName = (0, _vueDemi.ref)("");
|
|
15
|
-
const hoveredComponentChain = (0, _vueDemi.ref)();
|
|
16
|
-
let lastElement = null;
|
|
17
|
-
let rafId = null;
|
|
18
|
-
function getElementUnderOverlay(e) {
|
|
19
|
-
const overlay = overlayRef.value;
|
|
20
|
-
if (!overlay) return document.elementFromPoint(e.clientX, e.clientY);
|
|
21
|
-
const previousPointerEvents = overlay.style.pointerEvents;
|
|
22
|
-
overlay.style.pointerEvents = "none";
|
|
23
|
-
const el = document.elementFromPoint(e.clientX, e.clientY);
|
|
24
|
-
overlay.style.pointerEvents = previousPointerEvents;
|
|
25
|
-
return el;
|
|
26
|
-
}
|
|
27
|
-
function clearHighlight() {
|
|
28
|
-
hoveredElement.value = null;
|
|
29
|
-
hoveredRect.value = null;
|
|
30
|
-
hoveredName.value = "";
|
|
31
|
-
hoveredComponentChain.value = void 0;
|
|
32
|
-
lastElement = null;
|
|
33
|
-
}
|
|
34
|
-
function updateHighlight(el) {
|
|
35
|
-
const rect = el.getBoundingClientRect();
|
|
36
|
-
hoveredElement.value = el;
|
|
37
|
-
hoveredRect.value = {
|
|
38
|
-
x: rect.left,
|
|
39
|
-
y: rect.top,
|
|
40
|
-
width: rect.width,
|
|
41
|
-
height: rect.height
|
|
42
|
-
};
|
|
43
|
-
hoveredName.value = (0, _selectors.getElementName)(el);
|
|
44
|
-
if (showComponentTree?.()) {
|
|
45
|
-
hoveredComponentChain.value = (0, _domInspector.detectVueComponents)(el);
|
|
46
|
-
} else {
|
|
47
|
-
hoveredComponentChain.value = void 0;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
function onMouseMove(e) {
|
|
51
|
-
if (rafId !== null) return;
|
|
52
|
-
rafId = requestAnimationFrame(() => {
|
|
53
|
-
rafId = null;
|
|
54
|
-
const el = getElementUnderOverlay(e);
|
|
55
|
-
if (el === lastElement) return;
|
|
56
|
-
if (el?.closest(_constants.VA_DATA_ATTR_SELECTOR)) {
|
|
57
|
-
clearHighlight();
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
lastElement = el;
|
|
61
|
-
if (el) {
|
|
62
|
-
updateHighlight(el);
|
|
63
|
-
} else {
|
|
64
|
-
clearHighlight();
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function cleanup() {
|
|
69
|
-
if (rafId !== null) {
|
|
70
|
-
cancelAnimationFrame(rafId);
|
|
71
|
-
rafId = null;
|
|
72
|
-
}
|
|
73
|
-
clearHighlight();
|
|
74
|
-
}
|
|
75
|
-
return {
|
|
76
|
-
hoveredElement,
|
|
77
|
-
hoveredRect,
|
|
78
|
-
hoveredName,
|
|
79
|
-
hoveredComponentChain,
|
|
80
|
-
onMouseMove,
|
|
81
|
-
clearHighlight,
|
|
82
|
-
getElementUnderOverlay,
|
|
83
|
-
cleanup
|
|
84
|
-
};
|
|
85
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useInteractionMode = useInteractionMode;
|
|
7
|
-
var _vueDemi = require("vue-demi");
|
|
8
|
-
function useInteractionMode() {
|
|
9
|
-
const mode = (0, _vueDemi.ref)("idle");
|
|
10
|
-
const allowedTransitions = {
|
|
11
|
-
"idle": ["inspect"],
|
|
12
|
-
"inspect": ["idle", "input-open", "multi-selecting", "area-selecting"],
|
|
13
|
-
"multi-selecting": ["input-open", "inspect"],
|
|
14
|
-
"area-selecting": ["input-open", "inspect"],
|
|
15
|
-
"input-open": ["inspect", "idle"]
|
|
16
|
-
};
|
|
17
|
-
function transition(to) {
|
|
18
|
-
if (allowedTransitions[mode.value]?.includes(to)) {
|
|
19
|
-
mode.value = to;
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
console.warn(`[agentation-vue] Invalid transition: ${mode.value} \u2192 ${to}`);
|
|
23
|
-
return false;
|
|
24
|
-
}
|
|
25
|
-
return {
|
|
26
|
-
mode,
|
|
27
|
-
transition
|
|
28
|
-
};
|
|
29
|
-
}
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.DEFAULT_SHORTCUT_CONFIG = void 0;
|
|
7
|
-
exports.useKeyboardShortcuts = useKeyboardShortcuts;
|
|
8
|
-
var _vueDemi = require("vue-demi");
|
|
9
|
-
var _constants = require("../constants");
|
|
10
|
-
const DEFAULT_KEYMAP = {
|
|
11
|
-
"activate": "",
|
|
12
|
-
"element-select": "v",
|
|
13
|
-
"area-select": "a",
|
|
14
|
-
"pause-animations": "p",
|
|
15
|
-
"copy": "c",
|
|
16
|
-
"clear": "Backspace",
|
|
17
|
-
"settings": "",
|
|
18
|
-
"minimize": "Escape"
|
|
19
|
-
};
|
|
20
|
-
const DEFAULT_SHORTCUT_CONFIG = exports.DEFAULT_SHORTCUT_CONFIG = {
|
|
21
|
-
enabledWhenClosed: true,
|
|
22
|
-
priorityWhenOpen: true,
|
|
23
|
-
doubleTap: {
|
|
24
|
-
enabled: true,
|
|
25
|
-
key: "Shift",
|
|
26
|
-
thresholdMs: 280
|
|
27
|
-
},
|
|
28
|
-
keymap: {},
|
|
29
|
-
conflictPolicy: "ignore-editables"
|
|
30
|
-
};
|
|
31
|
-
const BROWSER_BLACKLIST = /* @__PURE__ */new Set(["Meta+l", "Meta+t", "Meta+w", "Meta+r", "Meta+n", "Meta+q", "Meta+Shift+t", "Meta+Shift+n", "Control+l", "Control+t", "Control+w", "Control+r", "Control+n", "Control+q", "Control+Shift+t", "Control+Shift+n", "Meta+c", "Meta+v", "Meta+x", "Meta+a", "Meta+z", "Control+c", "Control+v", "Control+x", "Control+a", "Control+z"]);
|
|
32
|
-
function useKeyboardShortcuts(options) {
|
|
33
|
-
const {
|
|
34
|
-
mode,
|
|
35
|
-
settingsOpen,
|
|
36
|
-
toolbarRef,
|
|
37
|
-
isInteractionLocked,
|
|
38
|
-
actions
|
|
39
|
-
} = options;
|
|
40
|
-
let lastActivationKeyUpTime = 0;
|
|
41
|
-
let listenerAttached = false;
|
|
42
|
-
let mergedKeymap = {
|
|
43
|
-
...DEFAULT_KEYMAP,
|
|
44
|
-
...options.config.value.keymap
|
|
45
|
-
};
|
|
46
|
-
(0, _vueDemi.watch)(options.config, cfg2 => {
|
|
47
|
-
mergedKeymap = {
|
|
48
|
-
...DEFAULT_KEYMAP,
|
|
49
|
-
...cfg2.keymap
|
|
50
|
-
};
|
|
51
|
-
});
|
|
52
|
-
function cfg() {
|
|
53
|
-
return options.config.value;
|
|
54
|
-
}
|
|
55
|
-
function getCurrentScope() {
|
|
56
|
-
if (mode.value === "idle" && (!toolbarRef.value || !toolbarRef.value.expanded)) {
|
|
57
|
-
return "closed";
|
|
58
|
-
}
|
|
59
|
-
if (settingsOpen.value) {
|
|
60
|
-
return "settings";
|
|
61
|
-
}
|
|
62
|
-
if (mode.value === "input-open") {
|
|
63
|
-
return "input";
|
|
64
|
-
}
|
|
65
|
-
return "open";
|
|
66
|
-
}
|
|
67
|
-
function isForeignEditable() {
|
|
68
|
-
const active = document.activeElement;
|
|
69
|
-
if (!active) return false;
|
|
70
|
-
const tag = active.tagName.toLowerCase();
|
|
71
|
-
const isEditable = tag === "input" || tag === "textarea" || active.isContentEditable;
|
|
72
|
-
if (!isEditable) return false;
|
|
73
|
-
return !active.closest(_constants.VA_DATA_ATTR_SELECTOR);
|
|
74
|
-
}
|
|
75
|
-
function isBrowserCombo(e) {
|
|
76
|
-
if (!e.metaKey && !e.ctrlKey) return false;
|
|
77
|
-
const parts = [];
|
|
78
|
-
if (e.metaKey) parts.push("Meta");
|
|
79
|
-
if (e.ctrlKey) parts.push("Control");
|
|
80
|
-
if (e.shiftKey) parts.push("Shift");
|
|
81
|
-
parts.push(e.key);
|
|
82
|
-
return BROWSER_BLACKLIST.has(parts.join("+"));
|
|
83
|
-
}
|
|
84
|
-
function findActionForKey(key) {
|
|
85
|
-
const normalized = key.toLowerCase();
|
|
86
|
-
for (const [action, mappedKey] of Object.entries(mergedKeymap)) {
|
|
87
|
-
if (!mappedKey) continue;
|
|
88
|
-
if (mappedKey.toLowerCase() === normalized || mappedKey === key) {
|
|
89
|
-
return action;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
function executeAction(action) {
|
|
95
|
-
switch (action) {
|
|
96
|
-
case "element-select":
|
|
97
|
-
actions.elementSelect();
|
|
98
|
-
break;
|
|
99
|
-
case "area-select":
|
|
100
|
-
actions.areaSelect();
|
|
101
|
-
break;
|
|
102
|
-
case "pause-animations":
|
|
103
|
-
actions.pauseAnimations();
|
|
104
|
-
break;
|
|
105
|
-
case "copy":
|
|
106
|
-
actions.copy();
|
|
107
|
-
break;
|
|
108
|
-
case "clear":
|
|
109
|
-
actions.clear();
|
|
110
|
-
break;
|
|
111
|
-
case "settings":
|
|
112
|
-
actions.openSettings();
|
|
113
|
-
break;
|
|
114
|
-
case "minimize":
|
|
115
|
-
actions.deactivate();
|
|
116
|
-
if (toolbarRef.value) toolbarRef.value.expanded = false;
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function consume(e) {
|
|
121
|
-
e.preventDefault();
|
|
122
|
-
e.stopPropagation();
|
|
123
|
-
}
|
|
124
|
-
function onKeyDown(e) {
|
|
125
|
-
if (e.repeat) return;
|
|
126
|
-
if (isBrowserCombo(e)) return;
|
|
127
|
-
const hasModifier = e.metaKey || e.ctrlKey || e.altKey;
|
|
128
|
-
const scope = getCurrentScope();
|
|
129
|
-
if (scope === "closed") {
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
if (scope === "settings") {
|
|
133
|
-
if (e.key === "Escape") {
|
|
134
|
-
consume(e);
|
|
135
|
-
actions.closeSettings();
|
|
136
|
-
}
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (scope === "input") {
|
|
140
|
-
if (e.key === "Escape") {
|
|
141
|
-
consume(e);
|
|
142
|
-
actions.inputCancel();
|
|
143
|
-
}
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
if (cfg().conflictPolicy === "ignore-editables" && isForeignEditable()) return;
|
|
147
|
-
if (isInteractionLocked()) return;
|
|
148
|
-
if (hasModifier) return;
|
|
149
|
-
const action = findActionForKey(e.key);
|
|
150
|
-
if (!action) return;
|
|
151
|
-
if (cfg().priorityWhenOpen) {
|
|
152
|
-
consume(e);
|
|
153
|
-
}
|
|
154
|
-
executeAction(action);
|
|
155
|
-
}
|
|
156
|
-
function onKeyUp(e) {
|
|
157
|
-
const {
|
|
158
|
-
doubleTap
|
|
159
|
-
} = cfg();
|
|
160
|
-
if (!doubleTap.enabled) return;
|
|
161
|
-
if (e.key !== doubleTap.key) return;
|
|
162
|
-
if (e.repeat) return;
|
|
163
|
-
const now = Date.now();
|
|
164
|
-
const delta = now - lastActivationKeyUpTime;
|
|
165
|
-
lastActivationKeyUpTime = now;
|
|
166
|
-
if (delta < doubleTap.thresholdMs && delta > 50) {
|
|
167
|
-
lastActivationKeyUpTime = 0;
|
|
168
|
-
const scope = getCurrentScope();
|
|
169
|
-
if (scope === "closed") {
|
|
170
|
-
actions.activate();
|
|
171
|
-
if (toolbarRef.value) toolbarRef.value.expanded = true;
|
|
172
|
-
} else if (scope === "open") {
|
|
173
|
-
actions.deactivate();
|
|
174
|
-
if (toolbarRef.value) toolbarRef.value.expanded = false;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
function onBlurOrVisibility() {
|
|
179
|
-
lastActivationKeyUpTime = 0;
|
|
180
|
-
}
|
|
181
|
-
function attach() {
|
|
182
|
-
if (listenerAttached) return;
|
|
183
|
-
listenerAttached = true;
|
|
184
|
-
document.addEventListener("keydown", onKeyDown, true);
|
|
185
|
-
document.addEventListener("keyup", onKeyUp, true);
|
|
186
|
-
window.addEventListener("blur", onBlurOrVisibility);
|
|
187
|
-
document.addEventListener("visibilitychange", onBlurOrVisibility);
|
|
188
|
-
}
|
|
189
|
-
function detach() {
|
|
190
|
-
if (!listenerAttached) return;
|
|
191
|
-
listenerAttached = false;
|
|
192
|
-
document.removeEventListener("keydown", onKeyDown, true);
|
|
193
|
-
document.removeEventListener("keyup", onKeyUp, true);
|
|
194
|
-
window.removeEventListener("blur", onBlurOrVisibility);
|
|
195
|
-
document.removeEventListener("visibilitychange", onBlurOrVisibility);
|
|
196
|
-
}
|
|
197
|
-
(0, _vueDemi.onMounted)(attach);
|
|
198
|
-
(0, _vueDemi.onBeforeUnmount)(detach);
|
|
199
|
-
return {
|
|
200
|
-
cleanup: detach
|
|
201
|
-
};
|
|
202
|
-
}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.useMarkerPositions = useMarkerPositions;
|
|
7
|
-
var _vueDemi = require("vue-demi");
|
|
8
|
-
function useMarkerPositions(annotations) {
|
|
9
|
-
let resizeObserver = null;
|
|
10
|
-
let rafId = null;
|
|
11
|
-
function recalculatePositions() {
|
|
12
|
-
if (rafId !== null) return;
|
|
13
|
-
rafId = requestAnimationFrame(() => {
|
|
14
|
-
rafId = null;
|
|
15
|
-
for (const annotation of annotations.value) {
|
|
16
|
-
const el = annotation._targetRef?.deref();
|
|
17
|
-
if (!el) continue;
|
|
18
|
-
const rect = el.getBoundingClientRect();
|
|
19
|
-
const scrollTop = window.scrollY || document.documentElement.scrollTop;
|
|
20
|
-
annotation.x = (rect.left + rect.width / 2) / window.innerWidth * 100;
|
|
21
|
-
annotation.y = annotation.isFixed ? rect.top + rect.height / 2 : rect.top + rect.height / 2 + scrollTop;
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
(0, _vueDemi.onMounted)(() => {
|
|
26
|
-
window.addEventListener("resize", recalculatePositions, {
|
|
27
|
-
passive: true
|
|
28
|
-
});
|
|
29
|
-
window.addEventListener("scroll", recalculatePositions, {
|
|
30
|
-
passive: true
|
|
31
|
-
});
|
|
32
|
-
resizeObserver = new ResizeObserver(recalculatePositions);
|
|
33
|
-
const appRoot = document.querySelector("#app") || document.body;
|
|
34
|
-
resizeObserver.observe(appRoot);
|
|
35
|
-
});
|
|
36
|
-
(0, _vueDemi.onBeforeUnmount)(() => {
|
|
37
|
-
window.removeEventListener("resize", recalculatePositions);
|
|
38
|
-
window.removeEventListener("scroll", recalculatePositions);
|
|
39
|
-
resizeObserver?.disconnect();
|
|
40
|
-
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
41
|
-
});
|
|
42
|
-
return {
|
|
43
|
-
recalculatePositions
|
|
44
|
-
};
|
|
45
|
-
}
|