@base44-preview/vite-plugin 0.2.22-pr.37.eb62313 → 0.2.22-pr.38.2655a87
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/injections/visual-edit-agent.d.ts +1 -1
- package/dist/injections/visual-edit-agent.d.ts.map +1 -1
- package/dist/injections/visual-edit-agent.js +466 -1
- package/dist/injections/visual-edit-agent.js.map +1 -1
- package/dist/statics/index.mjs +1 -5
- package/dist/statics/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/injections/visual-edit-agent.ts +570 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.d.ts +0 -25
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.js +0 -95
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/core.js.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.d.ts +0 -4
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.js +0 -4
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/index.js.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.d.ts +0 -9
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.js +0 -26
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/styles.js.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.d.ts +0 -10
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.js +0 -60
- package/dist/injections/visual-edit-agent/capabilities/inline-editing/validation.js.map +0 -1
- package/dist/injections/visual-edit-agent/constants.d.ts +0 -10
- package/dist/injections/visual-edit-agent/constants.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/constants.js +0 -10
- package/dist/injections/visual-edit-agent/constants.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/click-handlers.d.ts +0 -10
- package/dist/injections/visual-edit-agent/handlers/click-handlers.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/click-handlers.js +0 -108
- package/dist/injections/visual-edit-agent/handlers/click-handlers.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.d.ts +0 -14
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.js +0 -64
- package/dist/injections/visual-edit-agent/handlers/hover-handlers.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.d.ts +0 -14
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.js +0 -109
- package/dist/injections/visual-edit-agent/handlers/inline-edit-handlers.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/message-handlers.d.ts +0 -26
- package/dist/injections/visual-edit-agent/handlers/message-handlers.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/message-handlers.js +0 -145
- package/dist/injections/visual-edit-agent/handlers/message-handlers.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.d.ts +0 -7
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.js +0 -58
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.d.ts +0 -11
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.js +0 -32
- package/dist/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.js.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/messages/types.d.ts +0 -86
- package/dist/injections/visual-edit-agent/handlers/messages/types.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/handlers/messages/types.js +0 -28
- package/dist/injections/visual-edit-agent/handlers/messages/types.js.map +0 -1
- package/dist/injections/visual-edit-agent/index.d.ts +0 -5
- package/dist/injections/visual-edit-agent/index.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/index.js +0 -95
- package/dist/injections/visual-edit-agent/index.js.map +0 -1
- package/dist/injections/visual-edit-agent/state/agent-state.d.ts +0 -17
- package/dist/injections/visual-edit-agent/state/agent-state.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/state/agent-state.js +0 -18
- package/dist/injections/visual-edit-agent/state/agent-state.js.map +0 -1
- package/dist/injections/visual-edit-agent/ui/overlay.d.ts +0 -26
- package/dist/injections/visual-edit-agent/ui/overlay.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/ui/overlay.js +0 -104
- package/dist/injections/visual-edit-agent/ui/overlay.js.map +0 -1
- package/dist/injections/visual-edit-agent/utils/dom-utils.d.ts +0 -14
- package/dist/injections/visual-edit-agent/utils/dom-utils.d.ts.map +0 -1
- package/dist/injections/visual-edit-agent/utils/dom-utils.js +0 -34
- package/dist/injections/visual-edit-agent/utils/dom-utils.js.map +0 -1
- package/src/injections/visual-edit-agent/README.md +0 -222
- package/src/injections/visual-edit-agent/capabilities/inline-editing/core.ts +0 -120
- package/src/injections/visual-edit-agent/capabilities/inline-editing/index.ts +0 -10
- package/src/injections/visual-edit-agent/capabilities/inline-editing/styles.ts +0 -26
- package/src/injections/visual-edit-agent/capabilities/inline-editing/validation.ts +0 -67
- package/src/injections/visual-edit-agent/constants.ts +0 -9
- package/src/injections/visual-edit-agent/handlers/click-handlers.ts +0 -135
- package/src/injections/visual-edit-agent/handlers/hover-handlers.ts +0 -78
- package/src/injections/visual-edit-agent/handlers/inline-edit-handlers.ts +0 -141
- package/src/injections/visual-edit-agent/handlers/message-handlers.ts +0 -191
- package/src/injections/visual-edit-agent/handlers/messages/toggle-inline-edit-mode.ts +0 -70
- package/src/injections/visual-edit-agent/handlers/messages/toggle-visual-edit-mode.ts +0 -40
- package/src/injections/visual-edit-agent/handlers/messages/types.ts +0 -112
- package/src/injections/visual-edit-agent/index.ts +0 -108
- package/src/injections/visual-edit-agent/state/agent-state.ts +0 -31
- package/src/injections/visual-edit-agent/ui/overlay.ts +0 -126
- package/src/injections/visual-edit-agent/utils/dom-utils.ts +0 -39
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { OVERLAY_TRANSITION, OVERLAY_Z_INDEX, SELECTED_BORDER_COLOR, HOVER_BORDER_COLOR, HOVER_BACKGROUND_COLOR, LABEL_TOP_OFFSET, LABEL_LEFT_OFFSET, } from "../constants.js";
|
|
2
|
-
import { findElementsById } from "../../utils.js";
|
|
3
|
-
/**
|
|
4
|
-
* Create an overlay element for highlighting
|
|
5
|
-
*/
|
|
6
|
-
export function createOverlay(isSelected = false) {
|
|
7
|
-
const overlay = document.createElement("div");
|
|
8
|
-
overlay.style.position = "absolute";
|
|
9
|
-
overlay.style.pointerEvents = "none";
|
|
10
|
-
overlay.style.transition = OVERLAY_TRANSITION;
|
|
11
|
-
overlay.style.zIndex = OVERLAY_Z_INDEX;
|
|
12
|
-
if (isSelected) {
|
|
13
|
-
overlay.style.border = `2px solid ${SELECTED_BORDER_COLOR}`;
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
overlay.style.border = `2px solid ${HOVER_BORDER_COLOR}`;
|
|
17
|
-
overlay.style.backgroundColor = HOVER_BACKGROUND_COLOR;
|
|
18
|
-
}
|
|
19
|
-
return overlay;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Position overlay relative to element
|
|
23
|
-
*/
|
|
24
|
-
export function positionOverlay(overlay, element, isSelected = false, isVisualEditMode = true) {
|
|
25
|
-
if (!element || !isVisualEditMode)
|
|
26
|
-
return;
|
|
27
|
-
// Force layout recalculation before reading bounding rect
|
|
28
|
-
void element.offsetWidth;
|
|
29
|
-
const rect = element.getBoundingClientRect();
|
|
30
|
-
overlay.style.top = `${rect.top + window.scrollY}px`;
|
|
31
|
-
overlay.style.left = `${rect.left + window.scrollX}px`;
|
|
32
|
-
overlay.style.width = `${rect.width}px`;
|
|
33
|
-
overlay.style.height = `${rect.height}px`;
|
|
34
|
-
// Check if label already exists in overlay
|
|
35
|
-
let label = overlay.querySelector("div");
|
|
36
|
-
if (!label) {
|
|
37
|
-
label = document.createElement("div");
|
|
38
|
-
label.textContent = element.tagName.toLowerCase();
|
|
39
|
-
label.style.position = "absolute";
|
|
40
|
-
label.style.top = LABEL_TOP_OFFSET;
|
|
41
|
-
label.style.left = LABEL_LEFT_OFFSET;
|
|
42
|
-
label.style.padding = "2px 8px";
|
|
43
|
-
label.style.fontSize = "11px";
|
|
44
|
-
label.style.fontWeight = isSelected ? "500" : "400";
|
|
45
|
-
label.style.color = isSelected ? "#ffffff" : "#526cff";
|
|
46
|
-
label.style.backgroundColor = isSelected ? "#526cff" : "#DBEAFE";
|
|
47
|
-
label.style.borderRadius = "3px";
|
|
48
|
-
label.style.minWidth = "24px";
|
|
49
|
-
label.style.textAlign = "center";
|
|
50
|
-
overlay.appendChild(label);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Clear all overlays from DOM
|
|
55
|
-
*/
|
|
56
|
-
export function clearOverlays(overlays) {
|
|
57
|
-
overlays.forEach((overlay) => {
|
|
58
|
-
if (overlay && overlay.parentNode) {
|
|
59
|
-
overlay.remove();
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Remove data-selected attribute, clear selected overlays, and reset selection state
|
|
65
|
-
*/
|
|
66
|
-
export function clearSelection(state) {
|
|
67
|
-
if (state.isInlineEditExperimentEnabled && state.selectedElementId) {
|
|
68
|
-
const elements = findElementsById(state.selectedElementId);
|
|
69
|
-
elements.forEach((el) => {
|
|
70
|
-
if (el instanceof HTMLElement) {
|
|
71
|
-
delete el.dataset.selected;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
clearOverlays(state.selectedOverlays);
|
|
76
|
-
state.selectedOverlays = [];
|
|
77
|
-
state.selectedElementId = null;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Reposition selected overlays to match current element bounds
|
|
81
|
-
*/
|
|
82
|
-
export function repositionSelectedOverlays(state) {
|
|
83
|
-
if (!state.selectedElementId)
|
|
84
|
-
return;
|
|
85
|
-
const elements = findElementsById(state.selectedElementId);
|
|
86
|
-
state.selectedOverlays.forEach((overlay, index) => {
|
|
87
|
-
const element = elements[index];
|
|
88
|
-
if (element) {
|
|
89
|
-
positionOverlay(overlay, element, true, state.isVisualEditMode);
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Reposition hover overlays to match current element bounds
|
|
95
|
-
*/
|
|
96
|
-
export function repositionHoverOverlays(state) {
|
|
97
|
-
state.hoverOverlays.forEach((overlay, index) => {
|
|
98
|
-
const element = state.currentHighlightedElements[index];
|
|
99
|
-
if (element) {
|
|
100
|
-
positionOverlay(overlay, element, false, state.isVisualEditMode);
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
//# sourceMappingURL=overlay.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.js","sourceRoot":"","sources":["../../../../src/injections/visual-edit-agent/ui/overlay.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { ElementPosition } from "../handlers/messages/types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Calculate element position from bounding rect
|
|
4
|
-
*/
|
|
5
|
-
export declare function getElementPosition(rect: DOMRect): ElementPosition;
|
|
6
|
-
/**
|
|
7
|
-
* Check if element rect is in viewport
|
|
8
|
-
*/
|
|
9
|
-
export declare function isElementInViewport(rect: DOMRect): boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Get element classes (handles both HTML and SVG)
|
|
12
|
-
*/
|
|
13
|
-
export declare function getElementClasses(element: Element): string;
|
|
14
|
-
//# sourceMappingURL=dom-utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dom-utils.d.ts","sourceRoot":"","sources":["../../../../src/injections/visual-edit-agent/utils/dom-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAErE;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,eAAe,CAWjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAO1D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAK1D"}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Calculate element position from bounding rect
|
|
3
|
-
*/
|
|
4
|
-
export function getElementPosition(rect) {
|
|
5
|
-
return {
|
|
6
|
-
top: rect.top,
|
|
7
|
-
left: rect.left,
|
|
8
|
-
right: rect.right,
|
|
9
|
-
bottom: rect.bottom,
|
|
10
|
-
width: rect.width,
|
|
11
|
-
height: rect.height,
|
|
12
|
-
centerX: rect.left + rect.width / 2,
|
|
13
|
-
centerY: rect.top + rect.height / 2,
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Check if element rect is in viewport
|
|
18
|
-
*/
|
|
19
|
-
export function isElementInViewport(rect) {
|
|
20
|
-
return (rect.top < window.innerHeight &&
|
|
21
|
-
rect.bottom > 0 &&
|
|
22
|
-
rect.left < window.innerWidth &&
|
|
23
|
-
rect.right > 0);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Get element classes (handles both HTML and SVG)
|
|
27
|
-
*/
|
|
28
|
-
export function getElementClasses(element) {
|
|
29
|
-
if (element instanceof SVGElement) {
|
|
30
|
-
return element.className?.baseVal || "";
|
|
31
|
-
}
|
|
32
|
-
return element.className || "";
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=dom-utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dom-utils.js","sourceRoot":"","sources":["../../../../src/injections/visual-edit-agent/utils/dom-utils.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAa;IAC9C,OAAO;QACL,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO,EAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;QACnC,OAAO,EAAE,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;KACpC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAa;IAC/C,OAAO,CACL,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,WAAW;QAC7B,IAAI,CAAC,MAAM,GAAG,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,UAAU;QAC7B,IAAI,CAAC,KAAK,GAAG,CAAC,CACf,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAgB;IAChD,IAAI,OAAO,YAAY,UAAU,EAAE,CAAC;QAClC,OAAQ,OAAO,CAAC,SAA0C,EAAE,OAAO,IAAI,EAAE,CAAC;IAC5E,CAAC;IACD,OAAO,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;AACjC,CAAC"}
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
# Visual Edit Agent - Modular Architecture
|
|
2
|
-
|
|
3
|
-
The visual edit agent has been refactored into a clean, modular structure with proper separation of concerns.
|
|
4
|
-
|
|
5
|
-
## Directory Structure
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
src/injections/visual-edit-agent/
|
|
9
|
-
├── index.ts # Main entry point & setup orchestration
|
|
10
|
-
├── constants.ts # Shared constants
|
|
11
|
-
├── state/
|
|
12
|
-
│ └── agent-state.ts # Centralized state management
|
|
13
|
-
├── ui/
|
|
14
|
-
│ └── overlay.ts # Overlay creation, positioning & selection helpers
|
|
15
|
-
├── utils/
|
|
16
|
-
│ └── dom-utils.ts # DOM helpers (position, viewport, classes)
|
|
17
|
-
├── handlers/
|
|
18
|
-
│ ├── hover-handlers.ts # Mouse hover interactions
|
|
19
|
-
│ ├── click-handlers.ts # Element selection & click handling
|
|
20
|
-
│ ├── inline-edit-handlers.ts # Bridges to inline editing capability
|
|
21
|
-
│ ├── message-handlers.ts # Parent window message handling
|
|
22
|
-
│ └── messages/
|
|
23
|
-
│ ├── types.ts # Message type enums & interfaces
|
|
24
|
-
│ ├── toggle-visual-edit-mode.ts # Handles toggle-visual-edit-mode
|
|
25
|
-
│ └── toggle-inline-edit-mode.ts # Handles toggle-inline-edit-mode
|
|
26
|
-
└── capabilities/
|
|
27
|
-
└── inline-editing/ # Inline text editing capability
|
|
28
|
-
├── index.ts # Public API
|
|
29
|
-
├── core.ts # ContentEditable logic
|
|
30
|
-
├── validation.ts # Element eligibility checks
|
|
31
|
-
├── styles.ts # CSS injection / removal
|
|
32
|
-
└── README.md # Documentation
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Module Responsibilities
|
|
36
|
-
|
|
37
|
-
### `index.ts` - Setup & Orchestration
|
|
38
|
-
- Initializes the visual edit agent
|
|
39
|
-
- Sets up all event listeners
|
|
40
|
-
- Creates mutation observers
|
|
41
|
-
- Coordinates between different modules
|
|
42
|
-
|
|
43
|
-
### `constants.ts` - Configuration
|
|
44
|
-
- Defines all magic numbers and styling constants
|
|
45
|
-
- Single source of truth for configuration values
|
|
46
|
-
- Easy to modify behavior without touching logic
|
|
47
|
-
|
|
48
|
-
### `state/agent-state.ts` - State Management
|
|
49
|
-
- **`AgentState` interface**: TypeScript interface defining all state
|
|
50
|
-
- **`createAgentState()`**: Factory function to create initial state
|
|
51
|
-
- Centralizes all state in one place for easier debugging
|
|
52
|
-
|
|
53
|
-
### `ui/overlay.ts` - UI Components & Overlay State Helpers
|
|
54
|
-
- **`createOverlay()`**: Creates hover/selection overlay elements
|
|
55
|
-
- **`positionOverlay()`**: Positions a single overlay relative to an element
|
|
56
|
-
- **`clearOverlays()`**: Removes overlay elements from the DOM
|
|
57
|
-
- **`clearSelection(state)`**: Removes `data-selected`, clears selected overlays, and nulls `selectedElementId` — single source of truth for deselection used by `unselectElement`, `handleElementSelection`, and `toggleVisualEditMode`
|
|
58
|
-
- **`repositionSelectedOverlays(state)`**: Re-positions all selected overlays after layout changes
|
|
59
|
-
- **`repositionHoverOverlays(state)`**: Re-positions all hover overlays after layout changes
|
|
60
|
-
|
|
61
|
-
### `handlers/hover-handlers.ts` - Hover Interactions
|
|
62
|
-
- **`handleMouseOver()`**: Shows hover overlays on element hover
|
|
63
|
-
- **`handleMouseOut()`**: Clears hover overlays
|
|
64
|
-
- **`clearHoverOverlays()`**: Cleanup utility
|
|
65
|
-
- Manages the hover state and visual feedback
|
|
66
|
-
|
|
67
|
-
### `handlers/click-handlers.ts` - Selection Logic
|
|
68
|
-
- **`handleElementClick()`**: Main click event handler
|
|
69
|
-
- **`handleElementSelection()`**: Handles first click (selection)
|
|
70
|
-
- Manages the selection flow and second-click inline editing trigger
|
|
71
|
-
- Sends `element-selected` messages to parent
|
|
72
|
-
|
|
73
|
-
### `handlers/inline-edit-handlers.ts` - Inline Editing
|
|
74
|
-
- **`handleEnterInlineEditingMode()`**: Enables contentEditable
|
|
75
|
-
- **`handleClearInlineEditingMode()`**: Disables contentEditable
|
|
76
|
-
- **`setupInlineEditCallback()`**: Wires up text input handler
|
|
77
|
-
- **Debounced reporting**: 500ms debounce for `inline-edit` messages
|
|
78
|
-
- Bridges between visual edit agent and the inline-editing capability
|
|
79
|
-
|
|
80
|
-
### `capabilities/inline-editing/` - Inline Editing Capability
|
|
81
|
-
Reusable inline text editing using contentEditable.
|
|
82
|
-
- **`core.ts`**: Main contentEditable logic — `enterInlineEditingMode` injects the focus-suppression CSS; `clearInlineEditingMode` removes it automatically
|
|
83
|
-
- **`validation.ts`**: Element eligibility checks
|
|
84
|
-
- **`styles.ts`**: CSS injection (`injectFocusOutlineCSS`) and removal (`removeFocusOutlineCSS`)
|
|
85
|
-
- **`README.md`**: Complete documentation
|
|
86
|
-
- See [capabilities/inline-editing/README.md](./capabilities/inline-editing/README.md) for details
|
|
87
|
-
|
|
88
|
-
### `handlers/messages/` - Per-Message Handlers
|
|
89
|
-
Split out of `message-handlers.ts` to keep each handler focused:
|
|
90
|
-
- **`types.ts`**: `IncomingMessageType` / `OutgoingMessageType` enums and all message interfaces
|
|
91
|
-
- **`toggle-visual-edit-mode.ts`**: Enables/disables visual edit mode, clears all overlays & selection via `clearSelection`, updates the inline-edit experiment flag
|
|
92
|
-
- **`toggle-inline-edit-mode.ts`**: Programmatically enters/exits inline editing for a given element
|
|
93
|
-
|
|
94
|
-
### `handlers/message-handlers.ts` - Parent Communication
|
|
95
|
-
- **`handleMessage()`**: Switch-board for all incoming messages — delegates to per-message handlers above
|
|
96
|
-
- **`handleScroll()`**: Sends `element-position-update` to parent on scroll
|
|
97
|
-
- **`handleResize()`**: Calls `repositionSelectedOverlays` + `repositionHoverOverlays` on resize
|
|
98
|
-
- **`updateElementClassesAndReposition()`**: Updates classes & repositions overlays after CSS reflow
|
|
99
|
-
- **`updateElementContent()`**: Updates element `innerText` & repositions overlays
|
|
100
|
-
- **`unselectElement()`**: Exits inline editing if active, then delegates to `clearSelection`
|
|
101
|
-
- Central hub for all parent-iframe communication
|
|
102
|
-
|
|
103
|
-
## State Flow
|
|
104
|
-
|
|
105
|
-
```
|
|
106
|
-
User Action
|
|
107
|
-
↓
|
|
108
|
-
Handler (e.g., handleElementClick)
|
|
109
|
-
↓
|
|
110
|
-
Modifies State (AgentState)
|
|
111
|
-
↓
|
|
112
|
-
Updates UI (overlay.ts)
|
|
113
|
-
↓
|
|
114
|
-
Sends Message to Parent (window.parent.postMessage)
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## Position Update Strategy
|
|
118
|
-
|
|
119
|
-
Following Framewire's reactive pattern, we **update positions at the source** instead of using a broad MutationObserver. This is more performant and predictable.
|
|
120
|
-
|
|
121
|
-
### Position Updates Happen:
|
|
122
|
-
1. **Element Selection** - When user clicks an element
|
|
123
|
-
2. **Inline Editing** - During text input (debounced)
|
|
124
|
-
3. **Scroll Events** - Via scroll listener
|
|
125
|
-
4. **Window Resize** - Via resize listener
|
|
126
|
-
5. **Parent Updates** - When parent sends class/content changes (with 50ms delay for CSS reflow)
|
|
127
|
-
6. **Hover Events** - When user hovers over elements
|
|
128
|
-
|
|
129
|
-
See [POSITION_UPDATES.md](./POSITION_UPDATES.md) for detailed analysis.
|
|
130
|
-
|
|
131
|
-
## Key Features
|
|
132
|
-
|
|
133
|
-
### 1. **Separation of Concerns**
|
|
134
|
-
Each module has a single, well-defined responsibility
|
|
135
|
-
|
|
136
|
-
### 2. **Shared Helpers Over Repeated Logic**
|
|
137
|
-
Overlay repositioning and selection clearing live in `overlay.ts` as named helpers (`repositionSelectedOverlays`, `repositionHoverOverlays`, `clearSelection`) rather than being duplicated across handler files
|
|
138
|
-
|
|
139
|
-
### 3. **Centralized State**
|
|
140
|
-
All state is in `AgentState`, passed to handlers explicitly
|
|
141
|
-
|
|
142
|
-
### 4. **Type Safety**
|
|
143
|
-
TypeScript interfaces define clear contracts between modules
|
|
144
|
-
|
|
145
|
-
### 5. **Easy to Extend**
|
|
146
|
-
Adding new handlers or message types is straightforward
|
|
147
|
-
|
|
148
|
-
### 6. **Better Debugging**
|
|
149
|
-
Smaller files and clear responsibilities make debugging easier
|
|
150
|
-
|
|
151
|
-
## Message Types
|
|
152
|
-
|
|
153
|
-
### Incoming (from Parent)
|
|
154
|
-
- `toggle-visual-edit-mode` - Enable/disable visual edit mode + experiment flags
|
|
155
|
-
- `update-classes` - Update element classes
|
|
156
|
-
- `update-content` - Update element text content
|
|
157
|
-
- `unselect-element` - Clear current selection
|
|
158
|
-
- `refresh-page` - Reload the page
|
|
159
|
-
- `toggle-inline-edit-mode` - Programmatically enable/disable inline editing
|
|
160
|
-
- `request-element-position` - Request position of selected element
|
|
161
|
-
- `popover-drag-state` - Notify about popover drag state
|
|
162
|
-
- `dropdown-state` - Notify about dropdown open state
|
|
163
|
-
|
|
164
|
-
### Outgoing (to Parent)
|
|
165
|
-
- `visual-edit-agent-ready` - Agent initialized and ready
|
|
166
|
-
- `element-selected` - Element was selected
|
|
167
|
-
- `element-position-update` - Selected element position changed
|
|
168
|
-
- `content-editing-started` - Inline editing began
|
|
169
|
-
- `inline-edit` - Debounced content change during editing
|
|
170
|
-
- `content-editing-ended` - Inline editing finished
|
|
171
|
-
- `close-dropdowns` - Request to close dropdowns
|
|
172
|
-
|
|
173
|
-
## Inline Editing Experiment
|
|
174
|
-
|
|
175
|
-
Inline editing is gated behind an experiment flag: `specs.newInlineEditEnabled`
|
|
176
|
-
|
|
177
|
-
**Enable via:**
|
|
178
|
-
```typescript
|
|
179
|
-
{
|
|
180
|
-
type: "toggle-visual-edit-mode",
|
|
181
|
-
data: {
|
|
182
|
-
enabled: true,
|
|
183
|
-
specs: {
|
|
184
|
-
newInlineEditEnabled: true
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
**When enabled:**
|
|
191
|
-
- Second click on selected text element enters inline edit mode
|
|
192
|
-
- `toggle-inline-edit-mode` messages work
|
|
193
|
-
- 500ms debounced `inline-edit` messages sent during typing
|
|
194
|
-
|
|
195
|
-
**When disabled:**
|
|
196
|
-
- Second click does nothing
|
|
197
|
-
- `toggle-inline-edit-mode` messages ignored
|
|
198
|
-
|
|
199
|
-
## Constants
|
|
200
|
-
|
|
201
|
-
All configurable values are in `constants.ts`:
|
|
202
|
-
|
|
203
|
-
```typescript
|
|
204
|
-
INLINE_EDIT_DEBOUNCE_MS = 500 // Debounce time for inline edits
|
|
205
|
-
OVERLAY_Z_INDEX = "9999" // Z-index for overlays
|
|
206
|
-
SELECTED_BORDER_COLOR = "#2563EB" // Selected element border color
|
|
207
|
-
HOVER_BORDER_COLOR = "#95a5fc" // Hover element border color
|
|
208
|
-
REPOSITION_DELAY_MS = 50 // Delay before repositioning overlays
|
|
209
|
-
// ... and more
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
## Usage
|
|
213
|
-
|
|
214
|
-
Import and call the setup function:
|
|
215
|
-
|
|
216
|
-
```typescript
|
|
217
|
-
import { setupVisualEditAgent } from './visual-edit-agent.js';
|
|
218
|
-
|
|
219
|
-
setupVisualEditAgent();
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
That's it! The agent will initialize, set up all listeners, and start responding to messages.
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import { injectFocusOutlineCSS, removeFocusOutlineCSS } from "./styles.js";
|
|
2
|
-
import { selectText, isEditableTextElement } from "./validation.js";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Callback function type for handling text input changes
|
|
6
|
-
*/
|
|
7
|
-
type OnTextInputChange = (element: HTMLElement) => void;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Global callback that gets triggered on every input event
|
|
11
|
-
* This is set by the visual-edit-agent and includes both updatePosition and reportInlineEdit
|
|
12
|
-
*/
|
|
13
|
-
let onTextInputChangeCallback: OnTextInputChange | null = null;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Set the callback function that will be called on text input changes
|
|
17
|
-
*/
|
|
18
|
-
export function setInlineEditCallback(callback: OnTextInputChange | null): void {
|
|
19
|
-
onTextInputChangeCallback = callback;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* WeakMap to track AbortControllers for each element's input listener.
|
|
24
|
-
* Using WeakMap ensures no memory leaks — when an element is garbage collected,
|
|
25
|
-
* its entry is automatically removed.
|
|
26
|
-
*/
|
|
27
|
-
const listenerAbortControllers = new WeakMap<HTMLElement, AbortController>();
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Internal handler for the native input event
|
|
31
|
-
*/
|
|
32
|
-
function handleInputEvent(this: HTMLElement, e: Event): void {
|
|
33
|
-
if (onTextInputChangeCallback) {
|
|
34
|
-
onTextInputChangeCallback(this);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Check if an element should enter inline editing mode
|
|
40
|
-
* Called when user clicks on an already-selected element
|
|
41
|
-
*/
|
|
42
|
-
export function shouldEnterInlineEditingMode(element: Element): boolean {
|
|
43
|
-
// Must have data-selected="true"
|
|
44
|
-
if (!(element instanceof HTMLElement) || element.dataset.selected !== "true") {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Must pass all editability checks
|
|
49
|
-
if (!isEditableTextElement(element)) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Enable contentEditable mode on an element
|
|
58
|
-
* Follows the exact flow from inlineEdit.md
|
|
59
|
-
*/
|
|
60
|
-
export function enterInlineEditingMode(element: HTMLElement): void {
|
|
61
|
-
// Inject CSS to suppress focus outline
|
|
62
|
-
injectFocusOutlineCSS();
|
|
63
|
-
|
|
64
|
-
// Store original state
|
|
65
|
-
element.dataset.originalTextContent = element.textContent || "";
|
|
66
|
-
element.dataset.originalCursor = element.style.cursor;
|
|
67
|
-
|
|
68
|
-
// Enable contentEditable
|
|
69
|
-
element.contentEditable = "true";
|
|
70
|
-
|
|
71
|
-
// Create an AbortController to manage the input listener lifecycle
|
|
72
|
-
const abortController = new AbortController();
|
|
73
|
-
listenerAbortControllers.set(element, abortController);
|
|
74
|
-
|
|
75
|
-
// Add input event listener with AbortSignal for automatic cleanup
|
|
76
|
-
element.addEventListener("input", handleInputEvent, { signal: abortController.signal });
|
|
77
|
-
|
|
78
|
-
// Set cursor to text
|
|
79
|
-
element.style.cursor = "text";
|
|
80
|
-
|
|
81
|
-
// Select all text
|
|
82
|
-
selectText(element);
|
|
83
|
-
|
|
84
|
-
// Focus after render
|
|
85
|
-
setTimeout(() => {
|
|
86
|
-
element.focus();
|
|
87
|
-
}, 0);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Disable contentEditable mode on an element
|
|
92
|
-
* Reverses everything done by enterInlineEditingMode
|
|
93
|
-
*/
|
|
94
|
-
export function clearInlineEditingMode(element: HTMLElement): void {
|
|
95
|
-
// Abort the input event listener using the stored AbortController
|
|
96
|
-
const abortController = listenerAbortControllers.get(element);
|
|
97
|
-
if (abortController) {
|
|
98
|
-
abortController.abort();
|
|
99
|
-
listenerAbortControllers.delete(element);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// If element was removed from DOM before cleanup, skip DOM operations
|
|
103
|
-
if (!element.isConnected) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
removeFocusOutlineCSS();
|
|
108
|
-
|
|
109
|
-
// Disable contentEditable
|
|
110
|
-
element.contentEditable = "false";
|
|
111
|
-
|
|
112
|
-
// Remove stored original text content
|
|
113
|
-
delete element.dataset.originalTextContent;
|
|
114
|
-
|
|
115
|
-
// Restore original cursor
|
|
116
|
-
if (element.dataset.originalCursor !== undefined) {
|
|
117
|
-
element.style.cursor = element.dataset.originalCursor;
|
|
118
|
-
delete element.dataset.originalCursor;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export {
|
|
2
|
-
enterInlineEditingMode,
|
|
3
|
-
clearInlineEditingMode,
|
|
4
|
-
shouldEnterInlineEditingMode,
|
|
5
|
-
setInlineEditCallback,
|
|
6
|
-
} from "./core.js";
|
|
7
|
-
|
|
8
|
-
export { injectFocusOutlineCSS, removeFocusOutlineCSS } from "./styles.js";
|
|
9
|
-
|
|
10
|
-
export { isEditableTextElement, selectText } from "./validation.js";
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Inject CSS to suppress the browser's default focus outline on contentEditable elements
|
|
3
|
-
*/
|
|
4
|
-
export function injectFocusOutlineCSS(): void {
|
|
5
|
-
const existingStyle = document.getElementById("visual-edit-focus-styles");
|
|
6
|
-
if (existingStyle) return;
|
|
7
|
-
|
|
8
|
-
const style = document.createElement("style");
|
|
9
|
-
style.id = "visual-edit-focus-styles";
|
|
10
|
-
style.textContent = `
|
|
11
|
-
[data-selected="true"][contenteditable="true"]:focus {
|
|
12
|
-
outline: none !important;
|
|
13
|
-
}
|
|
14
|
-
`;
|
|
15
|
-
document.head.appendChild(style);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Remove the injected focus outline CSS
|
|
20
|
-
*/
|
|
21
|
-
export function removeFocusOutlineCSS(): void {
|
|
22
|
-
const style = document.getElementById("visual-edit-focus-styles");
|
|
23
|
-
if (style) {
|
|
24
|
-
style.remove();
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Select all text content in an element using the Selection API
|
|
3
|
-
*/
|
|
4
|
-
export function selectText(element: HTMLElement): void {
|
|
5
|
-
const range = document.createRange();
|
|
6
|
-
range.selectNodeContents(element);
|
|
7
|
-
const selection = window.getSelection();
|
|
8
|
-
selection?.removeAllRanges();
|
|
9
|
-
selection?.addRange(range);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Check if an element is an editable text element
|
|
14
|
-
* Based on the eligibility rules from inlineEdit.md (non-dynamic only)
|
|
15
|
-
*/
|
|
16
|
-
export function isEditableTextElement(element: Element): boolean {
|
|
17
|
-
// Must be an HTMLElement
|
|
18
|
-
if (!(element instanceof HTMLElement)) {
|
|
19
|
-
return false;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Must be an allowed tag
|
|
23
|
-
const allowedTags = [
|
|
24
|
-
"div",
|
|
25
|
-
"p",
|
|
26
|
-
"h1",
|
|
27
|
-
"h2",
|
|
28
|
-
"h3",
|
|
29
|
-
"h4",
|
|
30
|
-
"h5",
|
|
31
|
-
"h6",
|
|
32
|
-
"span",
|
|
33
|
-
"li",
|
|
34
|
-
"td",
|
|
35
|
-
"a",
|
|
36
|
-
"button",
|
|
37
|
-
"label",
|
|
38
|
-
];
|
|
39
|
-
if (!allowedTags.includes(element.tagName.toLowerCase())) {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Must have text content
|
|
44
|
-
const textContent = element.textContent?.trim() || "";
|
|
45
|
-
if (textContent.length === 0) {
|
|
46
|
-
return false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Must NOT contain img, video, canvas, or svg
|
|
50
|
-
const hasMediaElements =
|
|
51
|
-
element.querySelector("img, video, canvas, svg") !== null;
|
|
52
|
-
if (hasMediaElements) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Must NOT have complex children (must be a leaf text node or simple container)
|
|
57
|
-
if (element.children.length > 0) {
|
|
58
|
-
return false;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Must NOT be dynamic content
|
|
62
|
-
if (element.dataset.dynamicContent === "true") {
|
|
63
|
-
return false;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export const INLINE_EDIT_DEBOUNCE_MS = 500;
|
|
2
|
-
export const OVERLAY_TRANSITION = "all 0.1s ease-in-out";
|
|
3
|
-
export const OVERLAY_Z_INDEX = "9999";
|
|
4
|
-
export const SELECTED_BORDER_COLOR = "#2563EB";
|
|
5
|
-
export const HOVER_BORDER_COLOR = "#95a5fc";
|
|
6
|
-
export const HOVER_BACKGROUND_COLOR = "rgba(99, 102, 241, 0.05)";
|
|
7
|
-
export const LABEL_TOP_OFFSET = "-27px";
|
|
8
|
-
export const LABEL_LEFT_OFFSET = "-2px";
|
|
9
|
-
export const REPOSITION_DELAY_MS = 50;
|