vite-plugin-ai-annotator 1.1.26 → 1.1.28
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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Inspection Manager for mouse inspection mode handling
|
|
3
|
+
* Supports both single-click selection and drag-to-select multiple elements
|
|
3
4
|
*/
|
|
4
5
|
export interface InspectionManager {
|
|
5
6
|
enterInspectionMode(): void;
|
|
@@ -9,6 +10,7 @@ export interface InspectionManager {
|
|
|
9
10
|
}
|
|
10
11
|
export interface InspectionCallbacks {
|
|
11
12
|
onElementSelect?: (element: Element) => void;
|
|
13
|
+
onMultiSelect?: (elements: Element[]) => void;
|
|
12
14
|
shouldIgnoreElement?: (element: Element) => boolean;
|
|
13
15
|
isElementSelected?: (element: Element) => boolean;
|
|
14
16
|
onEscape?: () => void;
|
|
@@ -44,6 +44,7 @@ export declare class AnnotatorToolbar extends LitElement {
|
|
|
44
44
|
private injectJS;
|
|
45
45
|
private getConsoleLogs;
|
|
46
46
|
private handleElementSelected;
|
|
47
|
+
private handleMultiSelect;
|
|
47
48
|
private removeSelectedElement;
|
|
48
49
|
private showCommentPopoverForElement;
|
|
49
50
|
private handlePopoverKeydown;
|
|
@@ -6706,11 +6706,15 @@
|
|
|
6706
6706
|
}
|
|
6707
6707
|
|
|
6708
6708
|
// src/annotator/inspection.ts
|
|
6709
|
+
var DRAG_THRESHOLD = 5;
|
|
6709
6710
|
function createInspectionManager(callbacks = {}) {
|
|
6710
|
-
const { onElementSelect, shouldIgnoreElement, isElementSelected, onEscape, onCopy } = callbacks;
|
|
6711
|
+
const { onElementSelect, onMultiSelect, shouldIgnoreElement, isElementSelected, onEscape, onCopy } = callbacks;
|
|
6711
6712
|
let isInspecting = false;
|
|
6712
6713
|
let currentHoveredElement = null;
|
|
6713
6714
|
let inspectionStyleElement = null;
|
|
6715
|
+
let selectionOverlay = null;
|
|
6716
|
+
let dragState = { isDragging: false, startX: 0, startY: 0, currentX: 0, currentY: 0 };
|
|
6717
|
+
let mouseDownTime = 0;
|
|
6714
6718
|
function addInspectionStyles() {
|
|
6715
6719
|
inspectionStyleElement = document.createElement("style");
|
|
6716
6720
|
inspectionStyleElement.id = "annotator-toolbar-styles";
|
|
@@ -6718,6 +6722,8 @@
|
|
|
6718
6722
|
* {
|
|
6719
6723
|
pointer-events: none !important;
|
|
6720
6724
|
cursor: crosshair !important;
|
|
6725
|
+
user-select: none !important;
|
|
6726
|
+
-webkit-user-select: none !important;
|
|
6721
6727
|
}
|
|
6722
6728
|
annotator-toolbar, annotator-toolbar *,
|
|
6723
6729
|
.annotator-badge, .annotator-badge *,
|
|
@@ -6754,7 +6760,100 @@
|
|
|
6754
6760
|
}
|
|
6755
6761
|
return element;
|
|
6756
6762
|
}
|
|
6763
|
+
function createSelectionOverlay() {
|
|
6764
|
+
const overlay = document.createElement("div");
|
|
6765
|
+
overlay.className = "annotator-ignore";
|
|
6766
|
+
overlay.style.cssText = `
|
|
6767
|
+
position: fixed;
|
|
6768
|
+
border: 2px dashed #00FFFF;
|
|
6769
|
+
background: rgba(0, 255, 255, 0.1);
|
|
6770
|
+
pointer-events: none;
|
|
6771
|
+
z-index: 999999;
|
|
6772
|
+
box-shadow: 0 0 10px rgba(0, 255, 255, 0.3);
|
|
6773
|
+
`;
|
|
6774
|
+
document.body.appendChild(overlay);
|
|
6775
|
+
return overlay;
|
|
6776
|
+
}
|
|
6777
|
+
function updateSelectionOverlay() {
|
|
6778
|
+
if (!selectionOverlay) return;
|
|
6779
|
+
const left = Math.min(dragState.startX, dragState.currentX);
|
|
6780
|
+
const top = Math.min(dragState.startY, dragState.currentY);
|
|
6781
|
+
const width = Math.abs(dragState.currentX - dragState.startX);
|
|
6782
|
+
const height = Math.abs(dragState.currentY - dragState.startY);
|
|
6783
|
+
selectionOverlay.style.left = `${left}px`;
|
|
6784
|
+
selectionOverlay.style.top = `${top}px`;
|
|
6785
|
+
selectionOverlay.style.width = `${width}px`;
|
|
6786
|
+
selectionOverlay.style.height = `${height}px`;
|
|
6787
|
+
}
|
|
6788
|
+
function removeSelectionOverlay() {
|
|
6789
|
+
if (selectionOverlay) {
|
|
6790
|
+
selectionOverlay.remove();
|
|
6791
|
+
selectionOverlay = null;
|
|
6792
|
+
}
|
|
6793
|
+
}
|
|
6794
|
+
function getSelectionRect() {
|
|
6795
|
+
const left = Math.min(dragState.startX, dragState.currentX);
|
|
6796
|
+
const top = Math.min(dragState.startY, dragState.currentY);
|
|
6797
|
+
const width = Math.abs(dragState.currentX - dragState.startX);
|
|
6798
|
+
const height = Math.abs(dragState.currentY - dragState.startY);
|
|
6799
|
+
return new DOMRect(left, top, width, height);
|
|
6800
|
+
}
|
|
6801
|
+
function isFullyContained(inner, outer) {
|
|
6802
|
+
return inner.left >= outer.left && inner.right <= outer.right && inner.top >= outer.top && inner.bottom <= outer.bottom;
|
|
6803
|
+
}
|
|
6804
|
+
function findElementsFullyInRect(rect) {
|
|
6805
|
+
if (inspectionStyleElement) {
|
|
6806
|
+
inspectionStyleElement.disabled = true;
|
|
6807
|
+
}
|
|
6808
|
+
const elements = [];
|
|
6809
|
+
const allElements = document.body.querySelectorAll("*");
|
|
6810
|
+
for (const element of allElements) {
|
|
6811
|
+
if (shouldIgnoreElement?.(element)) continue;
|
|
6812
|
+
if (element.tagName === "SCRIPT" || element.tagName === "STYLE" || element.tagName === "NOSCRIPT") continue;
|
|
6813
|
+
const elementRect = element.getBoundingClientRect();
|
|
6814
|
+
if (elementRect.width === 0 || elementRect.height === 0) continue;
|
|
6815
|
+
if (isFullyContained(elementRect, rect)) {
|
|
6816
|
+
elements.push(element);
|
|
6817
|
+
}
|
|
6818
|
+
}
|
|
6819
|
+
if (inspectionStyleElement) {
|
|
6820
|
+
inspectionStyleElement.disabled = false;
|
|
6821
|
+
}
|
|
6822
|
+
return elements;
|
|
6823
|
+
}
|
|
6824
|
+
function filterLeafElements(elements) {
|
|
6825
|
+
return elements.filter((el) => {
|
|
6826
|
+
return !elements.some((other) => other !== el && el.contains(other));
|
|
6827
|
+
});
|
|
6828
|
+
}
|
|
6829
|
+
function handleMouseDown(e5) {
|
|
6830
|
+
const clickedElement = e5.target;
|
|
6831
|
+
if (shouldIgnoreElement?.(clickedElement)) return;
|
|
6832
|
+
mouseDownTime = Date.now();
|
|
6833
|
+
dragState = {
|
|
6834
|
+
isDragging: false,
|
|
6835
|
+
startX: e5.clientX,
|
|
6836
|
+
startY: e5.clientY,
|
|
6837
|
+
currentX: e5.clientX,
|
|
6838
|
+
currentY: e5.clientY
|
|
6839
|
+
};
|
|
6840
|
+
}
|
|
6757
6841
|
function handleMouseMove(e5) {
|
|
6842
|
+
if (mouseDownTime > 0) {
|
|
6843
|
+
const dx = Math.abs(e5.clientX - dragState.startX);
|
|
6844
|
+
const dy = Math.abs(e5.clientY - dragState.startY);
|
|
6845
|
+
if (!dragState.isDragging && (dx > DRAG_THRESHOLD || dy > DRAG_THRESHOLD)) {
|
|
6846
|
+
dragState.isDragging = true;
|
|
6847
|
+
removeHoverHighlight();
|
|
6848
|
+
selectionOverlay = createSelectionOverlay();
|
|
6849
|
+
}
|
|
6850
|
+
if (dragState.isDragging) {
|
|
6851
|
+
dragState.currentX = e5.clientX;
|
|
6852
|
+
dragState.currentY = e5.clientY;
|
|
6853
|
+
updateSelectionOverlay();
|
|
6854
|
+
return;
|
|
6855
|
+
}
|
|
6856
|
+
}
|
|
6758
6857
|
const target = getElementAtPoint(e5.clientX, e5.clientY);
|
|
6759
6858
|
if (!target || shouldIgnoreElement?.(target)) {
|
|
6760
6859
|
removeHoverHighlight();
|
|
@@ -6766,19 +6865,38 @@
|
|
|
6766
6865
|
target.style.outlineOffset = "2px";
|
|
6767
6866
|
currentHoveredElement = target;
|
|
6768
6867
|
}
|
|
6769
|
-
function
|
|
6770
|
-
const
|
|
6771
|
-
if (
|
|
6868
|
+
function handleMouseUp(e5) {
|
|
6869
|
+
const wasDragging = dragState.isDragging;
|
|
6870
|
+
if (wasDragging) {
|
|
6871
|
+
removeSelectionOverlay();
|
|
6872
|
+
const selectionRect = getSelectionRect();
|
|
6873
|
+
if (selectionRect.width > 10 && selectionRect.height > 10) {
|
|
6874
|
+
const elementsInRect = findElementsFullyInRect(selectionRect);
|
|
6875
|
+
const leafElements = filterLeafElements(elementsInRect);
|
|
6876
|
+
if (leafElements.length > 0) {
|
|
6877
|
+
onMultiSelect?.(leafElements);
|
|
6878
|
+
}
|
|
6879
|
+
}
|
|
6880
|
+
} else if (mouseDownTime > 0) {
|
|
6881
|
+
const target = getElementAtPoint(e5.clientX, e5.clientY);
|
|
6882
|
+
if (target && !shouldIgnoreElement?.(target)) {
|
|
6883
|
+
onElementSelect?.(target);
|
|
6884
|
+
}
|
|
6885
|
+
}
|
|
6886
|
+
mouseDownTime = 0;
|
|
6887
|
+
dragState = { isDragging: false, startX: 0, startY: 0, currentX: 0, currentY: 0 };
|
|
6888
|
+
}
|
|
6889
|
+
function preventClick(e5) {
|
|
6890
|
+
const target = e5.target;
|
|
6891
|
+
if (shouldIgnoreElement?.(target)) return;
|
|
6772
6892
|
e5.preventDefault();
|
|
6773
6893
|
e5.stopPropagation();
|
|
6774
6894
|
e5.stopImmediatePropagation();
|
|
6775
|
-
const target = getElementAtPoint(e5.clientX, e5.clientY);
|
|
6776
|
-
if (!target || shouldIgnoreElement?.(target)) return;
|
|
6777
|
-
onElementSelect?.(target);
|
|
6778
6895
|
}
|
|
6779
6896
|
function preventMouseEvents(e5) {
|
|
6780
6897
|
const target = e5.target;
|
|
6781
6898
|
if (shouldIgnoreElement?.(target)) return;
|
|
6899
|
+
if (dragState.isDragging) return;
|
|
6782
6900
|
e5.preventDefault();
|
|
6783
6901
|
e5.stopPropagation();
|
|
6784
6902
|
e5.stopImmediatePropagation();
|
|
@@ -6797,15 +6915,20 @@
|
|
|
6797
6915
|
}
|
|
6798
6916
|
}
|
|
6799
6917
|
}
|
|
6918
|
+
function resetDragState() {
|
|
6919
|
+
mouseDownTime = 0;
|
|
6920
|
+
dragState = { isDragging: false, startX: 0, startY: 0, currentX: 0, currentY: 0 };
|
|
6921
|
+
removeSelectionOverlay();
|
|
6922
|
+
}
|
|
6800
6923
|
return {
|
|
6801
6924
|
enterInspectionMode() {
|
|
6802
6925
|
if (isInspecting) return;
|
|
6803
6926
|
isInspecting = true;
|
|
6804
6927
|
addInspectionStyles();
|
|
6928
|
+
document.addEventListener("mousedown", handleMouseDown, true);
|
|
6805
6929
|
document.addEventListener("mousemove", handleMouseMove, true);
|
|
6806
|
-
document.addEventListener("
|
|
6807
|
-
document.addEventListener("
|
|
6808
|
-
document.addEventListener("mouseup", preventMouseEvents, true);
|
|
6930
|
+
document.addEventListener("mouseup", handleMouseUp, true);
|
|
6931
|
+
document.addEventListener("click", preventClick, true);
|
|
6809
6932
|
document.addEventListener("dblclick", preventMouseEvents, true);
|
|
6810
6933
|
document.addEventListener("contextmenu", preventMouseEvents, true);
|
|
6811
6934
|
document.addEventListener("keydown", handleKeyDown);
|
|
@@ -6814,14 +6937,15 @@
|
|
|
6814
6937
|
if (!isInspecting) return;
|
|
6815
6938
|
isInspecting = false;
|
|
6816
6939
|
removeInspectionStyles();
|
|
6940
|
+
document.removeEventListener("mousedown", handleMouseDown, true);
|
|
6817
6941
|
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
6818
|
-
document.removeEventListener("
|
|
6819
|
-
document.removeEventListener("
|
|
6820
|
-
document.removeEventListener("mouseup", preventMouseEvents, true);
|
|
6942
|
+
document.removeEventListener("mouseup", handleMouseUp, true);
|
|
6943
|
+
document.removeEventListener("click", preventClick, true);
|
|
6821
6944
|
document.removeEventListener("dblclick", preventMouseEvents, true);
|
|
6822
6945
|
document.removeEventListener("contextmenu", preventMouseEvents, true);
|
|
6823
6946
|
document.removeEventListener("keydown", handleKeyDown);
|
|
6824
6947
|
removeHoverHighlight();
|
|
6948
|
+
resetDragState();
|
|
6825
6949
|
},
|
|
6826
6950
|
isInInspectionMode() {
|
|
6827
6951
|
return isInspecting;
|
|
@@ -6830,14 +6954,15 @@
|
|
|
6830
6954
|
if (isInspecting) {
|
|
6831
6955
|
isInspecting = false;
|
|
6832
6956
|
removeInspectionStyles();
|
|
6957
|
+
document.removeEventListener("mousedown", handleMouseDown, true);
|
|
6833
6958
|
document.removeEventListener("mousemove", handleMouseMove, true);
|
|
6834
|
-
document.removeEventListener("
|
|
6835
|
-
document.removeEventListener("
|
|
6836
|
-
document.removeEventListener("mouseup", preventMouseEvents, true);
|
|
6959
|
+
document.removeEventListener("mouseup", handleMouseUp, true);
|
|
6960
|
+
document.removeEventListener("click", preventClick, true);
|
|
6837
6961
|
document.removeEventListener("dblclick", preventMouseEvents, true);
|
|
6838
6962
|
document.removeEventListener("contextmenu", preventMouseEvents, true);
|
|
6839
6963
|
document.removeEventListener("keydown", handleKeyDown);
|
|
6840
6964
|
removeHoverHighlight();
|
|
6965
|
+
resetDragState();
|
|
6841
6966
|
}
|
|
6842
6967
|
}
|
|
6843
6968
|
};
|
|
@@ -7395,6 +7520,7 @@
|
|
|
7395
7520
|
});
|
|
7396
7521
|
this.inspectionManager = createInspectionManager({
|
|
7397
7522
|
onElementSelect: (element) => this.handleElementSelected(element),
|
|
7523
|
+
onMultiSelect: (elements) => this.handleMultiSelect(elements),
|
|
7398
7524
|
shouldIgnoreElement: (element) => this.shouldIgnoreElement(element),
|
|
7399
7525
|
isElementSelected: (element) => this.selectionManager?.hasElement(element) || false,
|
|
7400
7526
|
onEscape: () => this.exitInspectingMode(),
|
|
@@ -7563,12 +7689,12 @@
|
|
|
7563
7689
|
if (type === "element" && selector) {
|
|
7564
7690
|
const element = document.querySelector(selector);
|
|
7565
7691
|
if (!element) {
|
|
7566
|
-
|
|
7692
|
+
this.log(`Element not found for selector: ${selector}`);
|
|
7567
7693
|
return { success: false, error: `Element not found: ${selector}` };
|
|
7568
7694
|
}
|
|
7569
7695
|
targetElement = element;
|
|
7570
7696
|
}
|
|
7571
|
-
|
|
7697
|
+
this.log(`Capturing screenshot of ${type === "element" ? selector : "viewport"}`);
|
|
7572
7698
|
const blob = await toBlob(targetElement, {
|
|
7573
7699
|
quality,
|
|
7574
7700
|
type: "image/webp",
|
|
@@ -7576,10 +7702,10 @@
|
|
|
7576
7702
|
skipFonts: true
|
|
7577
7703
|
});
|
|
7578
7704
|
if (!blob) {
|
|
7579
|
-
|
|
7705
|
+
this.log("toBlob returned null - screenshot capture failed");
|
|
7580
7706
|
return { success: false, error: "Failed to capture screenshot (toBlob returned null)" };
|
|
7581
7707
|
}
|
|
7582
|
-
|
|
7708
|
+
this.log(`Screenshot captured, blob size: ${blob.size} bytes`);
|
|
7583
7709
|
const reader = new FileReader();
|
|
7584
7710
|
const base64 = await new Promise((resolve, reject) => {
|
|
7585
7711
|
reader.onload = () => {
|
|
@@ -7593,7 +7719,7 @@
|
|
|
7593
7719
|
return { success: true, base64 };
|
|
7594
7720
|
} catch (error) {
|
|
7595
7721
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
7596
|
-
|
|
7722
|
+
this.log(`Screenshot error: ${errorMessage}`, error);
|
|
7597
7723
|
return {
|
|
7598
7724
|
success: false,
|
|
7599
7725
|
error: errorMessage
|
|
@@ -7658,6 +7784,26 @@
|
|
|
7658
7784
|
});
|
|
7659
7785
|
}
|
|
7660
7786
|
}
|
|
7787
|
+
handleMultiSelect(elements) {
|
|
7788
|
+
if (!this.selectionManager) return;
|
|
7789
|
+
let newSelectCount = 0;
|
|
7790
|
+
for (const element of elements) {
|
|
7791
|
+
if (!this.selectionManager.hasElement(element)) {
|
|
7792
|
+
this.selectionManager.selectElement(element, (el) => findNearestComponent(el, this.verbose));
|
|
7793
|
+
newSelectCount++;
|
|
7794
|
+
}
|
|
7795
|
+
}
|
|
7796
|
+
this.selectionCount = this.selectionManager.getSelectedCount();
|
|
7797
|
+
if (newSelectCount > 0) {
|
|
7798
|
+
this.showToast(`Selected ${newSelectCount} element(s)`);
|
|
7799
|
+
}
|
|
7800
|
+
if (this.socket?.connected) {
|
|
7801
|
+
this.socket.emit("selectionChanged", {
|
|
7802
|
+
count: this.selectionCount,
|
|
7803
|
+
elements: this.getSelectedElements()
|
|
7804
|
+
});
|
|
7805
|
+
}
|
|
7806
|
+
}
|
|
7661
7807
|
removeSelectedElement() {
|
|
7662
7808
|
if (!this.commentPopover.element || !this.selectionManager) return;
|
|
7663
7809
|
const element = this.commentPopover.element;
|
package/package.json
CHANGED