@funcatehq/vite-plugin-elementag 0.1.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/dist/beacon/index.cjs +181 -0
- package/dist/beacon/index.cjs.map +1 -0
- package/dist/beacon/index.d.cts +14 -0
- package/dist/beacon/index.d.ts +14 -0
- package/dist/beacon/index.js +153 -0
- package/dist/beacon/index.js.map +1 -0
- package/dist/index.cjs +550 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +521 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/beacon/index.ts
|
|
21
|
+
var beacon_exports = {};
|
|
22
|
+
__export(beacon_exports, {
|
|
23
|
+
BEACON_VERSION: () => BEACON_VERSION,
|
|
24
|
+
HIGHLIGHT_BG: () => HIGHLIGHT_BG,
|
|
25
|
+
HIGHLIGHT_COLOR: () => HIGHLIGHT_COLOR,
|
|
26
|
+
generateBeaconScript: () => generateBeaconScript
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(beacon_exports);
|
|
29
|
+
var BEACON_VERSION = "0.1.0";
|
|
30
|
+
var HIGHLIGHT_COLOR = "#0079F2";
|
|
31
|
+
var HIGHLIGHT_BG = "#0079F210";
|
|
32
|
+
var HIGHLIGHT_STYLES = `
|
|
33
|
+
[contenteditable] { outline: none !important; }
|
|
34
|
+
[contenteditable]:focus { outline: none !important; }
|
|
35
|
+
.elema-highlighter { position:absolute; z-index:2147483644; box-sizing:border-box; pointer-events:none; outline:2px dashed ${HIGHLIGHT_COLOR}!important; outline-offset:0!important; margin:0!important; padding:0!important; transform:none!important; background:${HIGHLIGHT_BG}!important; opacity:0; }
|
|
36
|
+
.elema-highlighter-hover { position:fixed; z-index:2147483647; }
|
|
37
|
+
.elema-highlighter-selected { position:fixed; pointer-events:none; outline:2px solid ${HIGHLIGHT_COLOR}!important; outline-offset:3px!important; background:none!important; }
|
|
38
|
+
.elema-label { position:absolute; background:${HIGHLIGHT_COLOR}; color:#FFF; padding:4px 8px; border-radius:4px; font-size:14px; font-family:monospace; line-height:1; white-space:nowrap; box-shadow:0 2px 4px rgba(0,0,0,.2); transform:translateY(-100%); margin-top:-4px; left:0; z-index:2147483645; pointer-events:none; opacity:0; }
|
|
39
|
+
.elema-label-hover { position:fixed; z-index:2147483647; }
|
|
40
|
+
.elema-label-selected { position:fixed; pointer-events:none; }
|
|
41
|
+
`;
|
|
42
|
+
function generateBeaconScript() {
|
|
43
|
+
return `
|
|
44
|
+
(function() {
|
|
45
|
+
"use strict";
|
|
46
|
+
var V = ${JSON.stringify(BEACON_VERSION)};
|
|
47
|
+
var sm = false, ee = false, sel = null, selMeta = null, he = null;
|
|
48
|
+
var hl = null, lb = null; // hover highlighter + label
|
|
49
|
+
var selHL = null, selLB = null; // selected highlighter + label
|
|
50
|
+
var rafId = null;
|
|
51
|
+
|
|
52
|
+
function isAllowedOrigin(o) {
|
|
53
|
+
if (o.startsWith("http://localhost:")) return true;
|
|
54
|
+
try { var u = new URL(o); return [".replit.dev",".replit.com",".replit-staging.com",".rp-humain.com",".repl.co"].some(function(d){ return u.hostname===d.slice(1)||u.hostname.endsWith(d); }); } catch(e){ return false; }
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Inject styles
|
|
58
|
+
var st = document.createElement("style"); st.textContent = ${JSON.stringify(HIGHLIGHT_STYLES)}; document.head.appendChild(st);
|
|
59
|
+
|
|
60
|
+
// Create hover overlays
|
|
61
|
+
hl = document.createElement("div"); hl.className = "elema-highlighter elema-highlighter-hover"; document.body.appendChild(hl);
|
|
62
|
+
lb = document.createElement("div"); lb.className = "elema-label elema-label-hover"; document.body.appendChild(lb);
|
|
63
|
+
|
|
64
|
+
function getMetadata(el) {
|
|
65
|
+
var path = el.getAttribute("data-elema-metadata")||el.getAttribute("data-replit-metadata")||"";
|
|
66
|
+
var name = el.getAttribute("data-elema-name")||el.getAttribute("data-component-name")||el.tagName.toLowerCase();
|
|
67
|
+
var cs = window.getComputedStyle(el);
|
|
68
|
+
var styles = {};
|
|
69
|
+
var props = ["backgroundColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","color","display","position","width","height","fontSize","fontFamily","fontWeight","margin","padding","opacity","textAlign"];
|
|
70
|
+
for (var i=0;i<props.length;i++) { try { styles[props[i]]=cs[props[i]]; } catch(e){} }
|
|
71
|
+
var pe = el.parentElement;
|
|
72
|
+
var parent = pe ? { tagName: pe.tagName.toLowerCase(), className: pe.getAttribute("class")||void 0, textContent: (pe.textContent||"").slice(0,100) } : null;
|
|
73
|
+
var children = [];
|
|
74
|
+
for (var c=0;c<el.children.length&&c<10;c++) { var ch=el.children[c]; children.push({ tagName:ch.tagName.toLowerCase(), className:ch.getAttribute("class")||void 0, textContent:(ch.textContent||"").slice(0,100) }); }
|
|
75
|
+
return {
|
|
76
|
+
tagName: el.tagName.toLowerCase(), className: el.getAttribute("class")||void 0, textContent: (el.textContent||"").slice(0,100),
|
|
77
|
+
id: el.getAttribute("id")||void 0, elementPath: path, componentName: name,
|
|
78
|
+
computedStyles: styles, relatedElements: { parent:parent, children:children },
|
|
79
|
+
siblingCount: pe?pe.children.length-1:0, hasChildElements: el.children.length>0,
|
|
80
|
+
originalTextContent: el.textContent||void 0, srcAttribute: el.getAttribute("src")||void 0
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function updateOverlay(el, h, l) {
|
|
85
|
+
if (!el||!h) return;
|
|
86
|
+
var r = el.getBoundingClientRect();
|
|
87
|
+
h.style.left=r.left+"px"; h.style.top=r.top+"px"; h.style.width=r.width+"px"; h.style.height=r.height+"px"; h.style.opacity="1";
|
|
88
|
+
if (l) { var n=el.getAttribute("data-elema-name")||el.getAttribute("data-component-name")||el.tagName.toLowerCase(); l.textContent=n; l.style.left=r.left+"px"; l.style.top=r.top+"px"; l.style.opacity="1"; }
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function clearHover() { if(hl) hl.style.opacity="0"; if(lb) lb.style.opacity="0"; }
|
|
92
|
+
function clearSelected() { if(selHL) { selHL.remove(); selHL=null; } if(selLB) { selLB.remove(); selLB=null; } }
|
|
93
|
+
|
|
94
|
+
// RAF-based position tracking for selected element
|
|
95
|
+
function startTracking() {
|
|
96
|
+
if (rafId) return;
|
|
97
|
+
function tick() {
|
|
98
|
+
if (sel) { updateOverlay(sel, selHL, selLB); }
|
|
99
|
+
rafId = requestAnimationFrame(tick);
|
|
100
|
+
}
|
|
101
|
+
rafId = requestAnimationFrame(tick);
|
|
102
|
+
}
|
|
103
|
+
function stopTracking() { if (rafId) { cancelAnimationFrame(rafId); rafId=null; } }
|
|
104
|
+
|
|
105
|
+
function showSelected(el) {
|
|
106
|
+
clearSelected();
|
|
107
|
+
if (!el) return;
|
|
108
|
+
selHL = document.createElement("div"); selHL.className="elema-highlighter elema-highlighter-selected"; document.body.appendChild(selHL);
|
|
109
|
+
selLB = document.createElement("div"); selLB.className="elema-label elema-label-selected"; document.body.appendChild(selLB);
|
|
110
|
+
updateOverlay(el, selHL, selLB);
|
|
111
|
+
startTracking();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Hover handler
|
|
115
|
+
document.addEventListener("mouseover", function(e) {
|
|
116
|
+
if (!sm) return;
|
|
117
|
+
var t = e.target.closest("[data-elema-metadata],[data-replit-metadata],[data-component-id]");
|
|
118
|
+
if (t) {
|
|
119
|
+
if (t !== he) { he = t; updateOverlay(t, hl, lb); }
|
|
120
|
+
try { var r=t.getBoundingClientRect(); window.parent.postMessage({type:"ELEMENT_HOVERED",timestamp:Date.now(),elementBounds:{x:r.left,y:r.top,width:r.width,height:r.height},elementName:t.getAttribute("data-elema-name")||t.getAttribute("data-component-name")||t.tagName.toLowerCase()},"*"); } catch(e){}
|
|
121
|
+
} else { he=null; clearHover(); try { window.parent.postMessage({type:"ELEMENT_HOVERED",timestamp:Date.now(),elementBounds:null,elementName:""},"*"); } catch(e){} }
|
|
122
|
+
}, true);
|
|
123
|
+
|
|
124
|
+
// Click handler
|
|
125
|
+
document.addEventListener("click", function(e) {
|
|
126
|
+
if (!sm) return;
|
|
127
|
+
var t = e.target.closest("[data-elema-metadata],[data-replit-metadata],[data-component-id]");
|
|
128
|
+
if (!t) return; e.preventDefault(); e.stopPropagation();
|
|
129
|
+
sel = t; selMeta = getMetadata(t); showSelected(t); clearHover();
|
|
130
|
+
if (ee) { t.setAttribute("contentEditable","true"); t.focus(); }
|
|
131
|
+
try { window.parent.postMessage({type:"ELEMENT_SELECTED",payload:selMeta,timestamp:Date.now()},"*"); } catch(e){}
|
|
132
|
+
}, true);
|
|
133
|
+
|
|
134
|
+
// Real-time text sync via input event (for contentEditable)
|
|
135
|
+
document.addEventListener("input", function(e) {
|
|
136
|
+
if (!sm || !sel || e.target !== sel) return;
|
|
137
|
+
var updated = getMetadata(sel);
|
|
138
|
+
try { window.parent.postMessage({type:"ELEMENT_TEXT_CHANGED",payload:updated,timestamp:Date.now()},"*"); } catch(e2){}
|
|
139
|
+
}, true);
|
|
140
|
+
|
|
141
|
+
// Also sync on blur
|
|
142
|
+
document.addEventListener("blur", function(e) {
|
|
143
|
+
if (!sm || !sel || e.target !== sel) return;
|
|
144
|
+
var updated = getMetadata(sel);
|
|
145
|
+
try { window.parent.postMessage({type:"ELEMENT_TEXT_CHANGED",payload:updated,timestamp:Date.now()},"*"); } catch(e2){}
|
|
146
|
+
}, true);
|
|
147
|
+
|
|
148
|
+
// postMessage listener
|
|
149
|
+
window.addEventListener("message", function(event) {
|
|
150
|
+
var msg = event.data || {};
|
|
151
|
+
switch (msg.type) {
|
|
152
|
+
case "TOGGLE_ELEMENTAG":
|
|
153
|
+
case "TOGGLE_REPLIT_VISUAL_EDITOR":
|
|
154
|
+
sm = !!msg.enabled; ee = !!msg.enableEditing;
|
|
155
|
+
document.body.style.cursor = sm ? "crosshair" : "";
|
|
156
|
+
if (!sm) { sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); try { window.parent.postMessage({type:"ELEMENT_UNSELECTED",timestamp:Date.now()},"*"); } catch(e){} }
|
|
157
|
+
break;
|
|
158
|
+
case "UPDATE_SELECTED_ELEMENT":
|
|
159
|
+
if (!sel) break;
|
|
160
|
+
var a = msg.attributes||{};
|
|
161
|
+
if (a.className!==void 0) { sel.setAttribute("class",String(a.className)); sel.setAttribute("data-elema-dirty","true"); }
|
|
162
|
+
if (a.textContent!==void 0) { sel.textContent=String(a.textContent); sel.setAttribute("data-elema-dirty","true"); }
|
|
163
|
+
if (a.style!==void 0) { var p=String(a.style).split(":"); if(p.length>=2) { sel.style[p[0].trim()]=p.slice(1).join(":").trim(); } sel.setAttribute("data-elema-dirty","true"); }
|
|
164
|
+
break;
|
|
165
|
+
case "CLEAR_SELECTION": sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); break;
|
|
166
|
+
case "CLEAR_ELEMENT_DIRTY": if(sel) sel.removeAttribute("data-elema-dirty"); break;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
try { window.parent.postMessage({type:"SELECTOR_SCRIPT_LOADED",timestamp:Date.now(),version:V},"*"); } catch(e){}
|
|
171
|
+
})();
|
|
172
|
+
`;
|
|
173
|
+
}
|
|
174
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
175
|
+
0 && (module.exports = {
|
|
176
|
+
BEACON_VERSION,
|
|
177
|
+
HIGHLIGHT_BG,
|
|
178
|
+
HIGHLIGHT_COLOR,
|
|
179
|
+
generateBeaconScript
|
|
180
|
+
});
|
|
181
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/beacon/index.ts"],"sourcesContent":["/**\n * Elementag Beacon — client-side script injected into the page.\n * Handles element selection, hover highlighting, and postMessage\n * communication with the parent Console frame.\n *\n * This is the equivalent of Cartographer's beacon/index.global.js.\n * It's compiled separately and loaded via transformIndexHtml.\n */\n\nexport const BEACON_VERSION = \"0.1.0\"\nexport const HIGHLIGHT_COLOR = \"#0079F2\"\nexport const HIGHLIGHT_BG = \"#0079F210\"\n\nconst HIGHLIGHT_STYLES = `\n [contenteditable] { outline: none !important; }\n [contenteditable]:focus { outline: none !important; }\n .elema-highlighter { position:absolute; z-index:2147483644; box-sizing:border-box; pointer-events:none; outline:2px dashed ${HIGHLIGHT_COLOR}!important; outline-offset:0!important; margin:0!important; padding:0!important; transform:none!important; background:${HIGHLIGHT_BG}!important; opacity:0; }\n .elema-highlighter-hover { position:fixed; z-index:2147483647; }\n .elema-highlighter-selected { position:fixed; pointer-events:none; outline:2px solid ${HIGHLIGHT_COLOR}!important; outline-offset:3px!important; background:none!important; }\n .elema-label { position:absolute; background:${HIGHLIGHT_COLOR}; color:#FFF; padding:4px 8px; border-radius:4px; font-size:14px; font-family:monospace; line-height:1; white-space:nowrap; box-shadow:0 2px 4px rgba(0,0,0,.2); transform:translateY(-100%); margin-top:-4px; left:0; z-index:2147483645; pointer-events:none; opacity:0; }\n .elema-label-hover { position:fixed; z-index:2147483647; }\n .elema-label-selected { position:fixed; pointer-events:none; }\n`\n\nexport function generateBeaconScript(): string {\n return `\n(function() {\n \"use strict\";\n var V = ${JSON.stringify(BEACON_VERSION)};\n var sm = false, ee = false, sel = null, selMeta = null, he = null;\n var hl = null, lb = null; // hover highlighter + label\n var selHL = null, selLB = null; // selected highlighter + label\n var rafId = null;\n\n function isAllowedOrigin(o) {\n if (o.startsWith(\"http://localhost:\")) return true;\n try { var u = new URL(o); return [\".replit.dev\",\".replit.com\",\".replit-staging.com\",\".rp-humain.com\",\".repl.co\"].some(function(d){ return u.hostname===d.slice(1)||u.hostname.endsWith(d); }); } catch(e){ return false; }\n }\n\n // Inject styles\n var st = document.createElement(\"style\"); st.textContent = ${JSON.stringify(HIGHLIGHT_STYLES)}; document.head.appendChild(st);\n\n // Create hover overlays\n hl = document.createElement(\"div\"); hl.className = \"elema-highlighter elema-highlighter-hover\"; document.body.appendChild(hl);\n lb = document.createElement(\"div\"); lb.className = \"elema-label elema-label-hover\"; document.body.appendChild(lb);\n\n function getMetadata(el) {\n var path = el.getAttribute(\"data-elema-metadata\")||el.getAttribute(\"data-replit-metadata\")||\"\";\n var name = el.getAttribute(\"data-elema-name\")||el.getAttribute(\"data-component-name\")||el.tagName.toLowerCase();\n var cs = window.getComputedStyle(el);\n var styles = {};\n var props = [\"backgroundColor\",\"borderTopColor\",\"borderRightColor\",\"borderBottomColor\",\"borderLeftColor\",\"borderTopLeftRadius\",\"borderTopRightRadius\",\"borderBottomRightRadius\",\"borderBottomLeftRadius\",\"borderTopWidth\",\"borderRightWidth\",\"borderBottomWidth\",\"borderLeftWidth\",\"color\",\"display\",\"position\",\"width\",\"height\",\"fontSize\",\"fontFamily\",\"fontWeight\",\"margin\",\"padding\",\"opacity\",\"textAlign\"];\n for (var i=0;i<props.length;i++) { try { styles[props[i]]=cs[props[i]]; } catch(e){} }\n var pe = el.parentElement;\n var parent = pe ? { tagName: pe.tagName.toLowerCase(), className: pe.getAttribute(\"class\")||void 0, textContent: (pe.textContent||\"\").slice(0,100) } : null;\n var children = [];\n for (var c=0;c<el.children.length&&c<10;c++) { var ch=el.children[c]; children.push({ tagName:ch.tagName.toLowerCase(), className:ch.getAttribute(\"class\")||void 0, textContent:(ch.textContent||\"\").slice(0,100) }); }\n return {\n tagName: el.tagName.toLowerCase(), className: el.getAttribute(\"class\")||void 0, textContent: (el.textContent||\"\").slice(0,100),\n id: el.getAttribute(\"id\")||void 0, elementPath: path, componentName: name,\n computedStyles: styles, relatedElements: { parent:parent, children:children },\n siblingCount: pe?pe.children.length-1:0, hasChildElements: el.children.length>0,\n originalTextContent: el.textContent||void 0, srcAttribute: el.getAttribute(\"src\")||void 0\n };\n }\n\n function updateOverlay(el, h, l) {\n if (!el||!h) return;\n var r = el.getBoundingClientRect();\n h.style.left=r.left+\"px\"; h.style.top=r.top+\"px\"; h.style.width=r.width+\"px\"; h.style.height=r.height+\"px\"; h.style.opacity=\"1\";\n if (l) { var n=el.getAttribute(\"data-elema-name\")||el.getAttribute(\"data-component-name\")||el.tagName.toLowerCase(); l.textContent=n; l.style.left=r.left+\"px\"; l.style.top=r.top+\"px\"; l.style.opacity=\"1\"; }\n }\n\n function clearHover() { if(hl) hl.style.opacity=\"0\"; if(lb) lb.style.opacity=\"0\"; }\n function clearSelected() { if(selHL) { selHL.remove(); selHL=null; } if(selLB) { selLB.remove(); selLB=null; } }\n\n // RAF-based position tracking for selected element\n function startTracking() {\n if (rafId) return;\n function tick() {\n if (sel) { updateOverlay(sel, selHL, selLB); }\n rafId = requestAnimationFrame(tick);\n }\n rafId = requestAnimationFrame(tick);\n }\n function stopTracking() { if (rafId) { cancelAnimationFrame(rafId); rafId=null; } }\n\n function showSelected(el) {\n clearSelected();\n if (!el) return;\n selHL = document.createElement(\"div\"); selHL.className=\"elema-highlighter elema-highlighter-selected\"; document.body.appendChild(selHL);\n selLB = document.createElement(\"div\"); selLB.className=\"elema-label elema-label-selected\"; document.body.appendChild(selLB);\n updateOverlay(el, selHL, selLB);\n startTracking();\n }\n\n // Hover handler\n document.addEventListener(\"mouseover\", function(e) {\n if (!sm) return;\n var t = e.target.closest(\"[data-elema-metadata],[data-replit-metadata],[data-component-id]\");\n if (t) {\n if (t !== he) { he = t; updateOverlay(t, hl, lb); }\n try { var r=t.getBoundingClientRect(); window.parent.postMessage({type:\"ELEMENT_HOVERED\",timestamp:Date.now(),elementBounds:{x:r.left,y:r.top,width:r.width,height:r.height},elementName:t.getAttribute(\"data-elema-name\")||t.getAttribute(\"data-component-name\")||t.tagName.toLowerCase()},\"*\"); } catch(e){}\n } else { he=null; clearHover(); try { window.parent.postMessage({type:\"ELEMENT_HOVERED\",timestamp:Date.now(),elementBounds:null,elementName:\"\"},\"*\"); } catch(e){} }\n }, true);\n\n // Click handler\n document.addEventListener(\"click\", function(e) {\n if (!sm) return;\n var t = e.target.closest(\"[data-elema-metadata],[data-replit-metadata],[data-component-id]\");\n if (!t) return; e.preventDefault(); e.stopPropagation();\n sel = t; selMeta = getMetadata(t); showSelected(t); clearHover();\n if (ee) { t.setAttribute(\"contentEditable\",\"true\"); t.focus(); }\n try { window.parent.postMessage({type:\"ELEMENT_SELECTED\",payload:selMeta,timestamp:Date.now()},\"*\"); } catch(e){}\n }, true);\n\n // Real-time text sync via input event (for contentEditable)\n document.addEventListener(\"input\", function(e) {\n if (!sm || !sel || e.target !== sel) return;\n var updated = getMetadata(sel);\n try { window.parent.postMessage({type:\"ELEMENT_TEXT_CHANGED\",payload:updated,timestamp:Date.now()},\"*\"); } catch(e2){}\n }, true);\n\n // Also sync on blur\n document.addEventListener(\"blur\", function(e) {\n if (!sm || !sel || e.target !== sel) return;\n var updated = getMetadata(sel);\n try { window.parent.postMessage({type:\"ELEMENT_TEXT_CHANGED\",payload:updated,timestamp:Date.now()},\"*\"); } catch(e2){}\n }, true);\n\n // postMessage listener\n window.addEventListener(\"message\", function(event) {\n var msg = event.data || {};\n switch (msg.type) {\n case \"TOGGLE_ELEMENTAG\":\n case \"TOGGLE_REPLIT_VISUAL_EDITOR\":\n sm = !!msg.enabled; ee = !!msg.enableEditing;\n document.body.style.cursor = sm ? \"crosshair\" : \"\";\n if (!sm) { sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); try { window.parent.postMessage({type:\"ELEMENT_UNSELECTED\",timestamp:Date.now()},\"*\"); } catch(e){} }\n break;\n case \"UPDATE_SELECTED_ELEMENT\":\n if (!sel) break;\n var a = msg.attributes||{};\n if (a.className!==void 0) { sel.setAttribute(\"class\",String(a.className)); sel.setAttribute(\"data-elema-dirty\",\"true\"); }\n if (a.textContent!==void 0) { sel.textContent=String(a.textContent); sel.setAttribute(\"data-elema-dirty\",\"true\"); }\n if (a.style!==void 0) { var p=String(a.style).split(\":\"); if(p.length>=2) { sel.style[p[0].trim()]=p.slice(1).join(\":\").trim(); } sel.setAttribute(\"data-elema-dirty\",\"true\"); }\n break;\n case \"CLEAR_SELECTION\": sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); break;\n case \"CLEAR_ELEMENT_DIRTY\": if(sel) sel.removeAttribute(\"data-elema-dirty\"); break;\n }\n });\n\n try { window.parent.postMessage({type:\"SELECTOR_SCRIPT_LOADED\",timestamp:Date.now(),version:V},\"*\"); } catch(e){}\n})();\n`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASO,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,eAAe;AAE5B,IAAM,mBAAmB;AAAA;AAAA;AAAA,+HAGsG,eAAe,yHAAyH,YAAY;AAAA;AAAA,yFAE1L,eAAe;AAAA,iDACvD,eAAe;AAAA;AAAA;AAAA;AAKzD,SAAS,uBAA+B;AAC7C,SAAO;AAAA;AAAA;AAAA,YAGG,KAAK,UAAU,cAAc,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+DAYqB,KAAK,UAAU,gBAAgB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmH/F;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elementag Beacon — client-side script injected into the page.
|
|
3
|
+
* Handles element selection, hover highlighting, and postMessage
|
|
4
|
+
* communication with the parent Console frame.
|
|
5
|
+
*
|
|
6
|
+
* This is the equivalent of Cartographer's beacon/index.global.js.
|
|
7
|
+
* It's compiled separately and loaded via transformIndexHtml.
|
|
8
|
+
*/
|
|
9
|
+
declare const BEACON_VERSION = "0.1.0";
|
|
10
|
+
declare const HIGHLIGHT_COLOR = "#0079F2";
|
|
11
|
+
declare const HIGHLIGHT_BG = "#0079F210";
|
|
12
|
+
declare function generateBeaconScript(): string;
|
|
13
|
+
|
|
14
|
+
export { BEACON_VERSION, HIGHLIGHT_BG, HIGHLIGHT_COLOR, generateBeaconScript };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Elementag Beacon — client-side script injected into the page.
|
|
3
|
+
* Handles element selection, hover highlighting, and postMessage
|
|
4
|
+
* communication with the parent Console frame.
|
|
5
|
+
*
|
|
6
|
+
* This is the equivalent of Cartographer's beacon/index.global.js.
|
|
7
|
+
* It's compiled separately and loaded via transformIndexHtml.
|
|
8
|
+
*/
|
|
9
|
+
declare const BEACON_VERSION = "0.1.0";
|
|
10
|
+
declare const HIGHLIGHT_COLOR = "#0079F2";
|
|
11
|
+
declare const HIGHLIGHT_BG = "#0079F210";
|
|
12
|
+
declare function generateBeaconScript(): string;
|
|
13
|
+
|
|
14
|
+
export { BEACON_VERSION, HIGHLIGHT_BG, HIGHLIGHT_COLOR, generateBeaconScript };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// src/beacon/index.ts
|
|
2
|
+
var BEACON_VERSION = "0.1.0";
|
|
3
|
+
var HIGHLIGHT_COLOR = "#0079F2";
|
|
4
|
+
var HIGHLIGHT_BG = "#0079F210";
|
|
5
|
+
var HIGHLIGHT_STYLES = `
|
|
6
|
+
[contenteditable] { outline: none !important; }
|
|
7
|
+
[contenteditable]:focus { outline: none !important; }
|
|
8
|
+
.elema-highlighter { position:absolute; z-index:2147483644; box-sizing:border-box; pointer-events:none; outline:2px dashed ${HIGHLIGHT_COLOR}!important; outline-offset:0!important; margin:0!important; padding:0!important; transform:none!important; background:${HIGHLIGHT_BG}!important; opacity:0; }
|
|
9
|
+
.elema-highlighter-hover { position:fixed; z-index:2147483647; }
|
|
10
|
+
.elema-highlighter-selected { position:fixed; pointer-events:none; outline:2px solid ${HIGHLIGHT_COLOR}!important; outline-offset:3px!important; background:none!important; }
|
|
11
|
+
.elema-label { position:absolute; background:${HIGHLIGHT_COLOR}; color:#FFF; padding:4px 8px; border-radius:4px; font-size:14px; font-family:monospace; line-height:1; white-space:nowrap; box-shadow:0 2px 4px rgba(0,0,0,.2); transform:translateY(-100%); margin-top:-4px; left:0; z-index:2147483645; pointer-events:none; opacity:0; }
|
|
12
|
+
.elema-label-hover { position:fixed; z-index:2147483647; }
|
|
13
|
+
.elema-label-selected { position:fixed; pointer-events:none; }
|
|
14
|
+
`;
|
|
15
|
+
function generateBeaconScript() {
|
|
16
|
+
return `
|
|
17
|
+
(function() {
|
|
18
|
+
"use strict";
|
|
19
|
+
var V = ${JSON.stringify(BEACON_VERSION)};
|
|
20
|
+
var sm = false, ee = false, sel = null, selMeta = null, he = null;
|
|
21
|
+
var hl = null, lb = null; // hover highlighter + label
|
|
22
|
+
var selHL = null, selLB = null; // selected highlighter + label
|
|
23
|
+
var rafId = null;
|
|
24
|
+
|
|
25
|
+
function isAllowedOrigin(o) {
|
|
26
|
+
if (o.startsWith("http://localhost:")) return true;
|
|
27
|
+
try { var u = new URL(o); return [".replit.dev",".replit.com",".replit-staging.com",".rp-humain.com",".repl.co"].some(function(d){ return u.hostname===d.slice(1)||u.hostname.endsWith(d); }); } catch(e){ return false; }
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Inject styles
|
|
31
|
+
var st = document.createElement("style"); st.textContent = ${JSON.stringify(HIGHLIGHT_STYLES)}; document.head.appendChild(st);
|
|
32
|
+
|
|
33
|
+
// Create hover overlays
|
|
34
|
+
hl = document.createElement("div"); hl.className = "elema-highlighter elema-highlighter-hover"; document.body.appendChild(hl);
|
|
35
|
+
lb = document.createElement("div"); lb.className = "elema-label elema-label-hover"; document.body.appendChild(lb);
|
|
36
|
+
|
|
37
|
+
function getMetadata(el) {
|
|
38
|
+
var path = el.getAttribute("data-elema-metadata")||el.getAttribute("data-replit-metadata")||"";
|
|
39
|
+
var name = el.getAttribute("data-elema-name")||el.getAttribute("data-component-name")||el.tagName.toLowerCase();
|
|
40
|
+
var cs = window.getComputedStyle(el);
|
|
41
|
+
var styles = {};
|
|
42
|
+
var props = ["backgroundColor","borderTopColor","borderRightColor","borderBottomColor","borderLeftColor","borderTopLeftRadius","borderTopRightRadius","borderBottomRightRadius","borderBottomLeftRadius","borderTopWidth","borderRightWidth","borderBottomWidth","borderLeftWidth","color","display","position","width","height","fontSize","fontFamily","fontWeight","margin","padding","opacity","textAlign"];
|
|
43
|
+
for (var i=0;i<props.length;i++) { try { styles[props[i]]=cs[props[i]]; } catch(e){} }
|
|
44
|
+
var pe = el.parentElement;
|
|
45
|
+
var parent = pe ? { tagName: pe.tagName.toLowerCase(), className: pe.getAttribute("class")||void 0, textContent: (pe.textContent||"").slice(0,100) } : null;
|
|
46
|
+
var children = [];
|
|
47
|
+
for (var c=0;c<el.children.length&&c<10;c++) { var ch=el.children[c]; children.push({ tagName:ch.tagName.toLowerCase(), className:ch.getAttribute("class")||void 0, textContent:(ch.textContent||"").slice(0,100) }); }
|
|
48
|
+
return {
|
|
49
|
+
tagName: el.tagName.toLowerCase(), className: el.getAttribute("class")||void 0, textContent: (el.textContent||"").slice(0,100),
|
|
50
|
+
id: el.getAttribute("id")||void 0, elementPath: path, componentName: name,
|
|
51
|
+
computedStyles: styles, relatedElements: { parent:parent, children:children },
|
|
52
|
+
siblingCount: pe?pe.children.length-1:0, hasChildElements: el.children.length>0,
|
|
53
|
+
originalTextContent: el.textContent||void 0, srcAttribute: el.getAttribute("src")||void 0
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function updateOverlay(el, h, l) {
|
|
58
|
+
if (!el||!h) return;
|
|
59
|
+
var r = el.getBoundingClientRect();
|
|
60
|
+
h.style.left=r.left+"px"; h.style.top=r.top+"px"; h.style.width=r.width+"px"; h.style.height=r.height+"px"; h.style.opacity="1";
|
|
61
|
+
if (l) { var n=el.getAttribute("data-elema-name")||el.getAttribute("data-component-name")||el.tagName.toLowerCase(); l.textContent=n; l.style.left=r.left+"px"; l.style.top=r.top+"px"; l.style.opacity="1"; }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function clearHover() { if(hl) hl.style.opacity="0"; if(lb) lb.style.opacity="0"; }
|
|
65
|
+
function clearSelected() { if(selHL) { selHL.remove(); selHL=null; } if(selLB) { selLB.remove(); selLB=null; } }
|
|
66
|
+
|
|
67
|
+
// RAF-based position tracking for selected element
|
|
68
|
+
function startTracking() {
|
|
69
|
+
if (rafId) return;
|
|
70
|
+
function tick() {
|
|
71
|
+
if (sel) { updateOverlay(sel, selHL, selLB); }
|
|
72
|
+
rafId = requestAnimationFrame(tick);
|
|
73
|
+
}
|
|
74
|
+
rafId = requestAnimationFrame(tick);
|
|
75
|
+
}
|
|
76
|
+
function stopTracking() { if (rafId) { cancelAnimationFrame(rafId); rafId=null; } }
|
|
77
|
+
|
|
78
|
+
function showSelected(el) {
|
|
79
|
+
clearSelected();
|
|
80
|
+
if (!el) return;
|
|
81
|
+
selHL = document.createElement("div"); selHL.className="elema-highlighter elema-highlighter-selected"; document.body.appendChild(selHL);
|
|
82
|
+
selLB = document.createElement("div"); selLB.className="elema-label elema-label-selected"; document.body.appendChild(selLB);
|
|
83
|
+
updateOverlay(el, selHL, selLB);
|
|
84
|
+
startTracking();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Hover handler
|
|
88
|
+
document.addEventListener("mouseover", function(e) {
|
|
89
|
+
if (!sm) return;
|
|
90
|
+
var t = e.target.closest("[data-elema-metadata],[data-replit-metadata],[data-component-id]");
|
|
91
|
+
if (t) {
|
|
92
|
+
if (t !== he) { he = t; updateOverlay(t, hl, lb); }
|
|
93
|
+
try { var r=t.getBoundingClientRect(); window.parent.postMessage({type:"ELEMENT_HOVERED",timestamp:Date.now(),elementBounds:{x:r.left,y:r.top,width:r.width,height:r.height},elementName:t.getAttribute("data-elema-name")||t.getAttribute("data-component-name")||t.tagName.toLowerCase()},"*"); } catch(e){}
|
|
94
|
+
} else { he=null; clearHover(); try { window.parent.postMessage({type:"ELEMENT_HOVERED",timestamp:Date.now(),elementBounds:null,elementName:""},"*"); } catch(e){} }
|
|
95
|
+
}, true);
|
|
96
|
+
|
|
97
|
+
// Click handler
|
|
98
|
+
document.addEventListener("click", function(e) {
|
|
99
|
+
if (!sm) return;
|
|
100
|
+
var t = e.target.closest("[data-elema-metadata],[data-replit-metadata],[data-component-id]");
|
|
101
|
+
if (!t) return; e.preventDefault(); e.stopPropagation();
|
|
102
|
+
sel = t; selMeta = getMetadata(t); showSelected(t); clearHover();
|
|
103
|
+
if (ee) { t.setAttribute("contentEditable","true"); t.focus(); }
|
|
104
|
+
try { window.parent.postMessage({type:"ELEMENT_SELECTED",payload:selMeta,timestamp:Date.now()},"*"); } catch(e){}
|
|
105
|
+
}, true);
|
|
106
|
+
|
|
107
|
+
// Real-time text sync via input event (for contentEditable)
|
|
108
|
+
document.addEventListener("input", function(e) {
|
|
109
|
+
if (!sm || !sel || e.target !== sel) return;
|
|
110
|
+
var updated = getMetadata(sel);
|
|
111
|
+
try { window.parent.postMessage({type:"ELEMENT_TEXT_CHANGED",payload:updated,timestamp:Date.now()},"*"); } catch(e2){}
|
|
112
|
+
}, true);
|
|
113
|
+
|
|
114
|
+
// Also sync on blur
|
|
115
|
+
document.addEventListener("blur", function(e) {
|
|
116
|
+
if (!sm || !sel || e.target !== sel) return;
|
|
117
|
+
var updated = getMetadata(sel);
|
|
118
|
+
try { window.parent.postMessage({type:"ELEMENT_TEXT_CHANGED",payload:updated,timestamp:Date.now()},"*"); } catch(e2){}
|
|
119
|
+
}, true);
|
|
120
|
+
|
|
121
|
+
// postMessage listener
|
|
122
|
+
window.addEventListener("message", function(event) {
|
|
123
|
+
var msg = event.data || {};
|
|
124
|
+
switch (msg.type) {
|
|
125
|
+
case "TOGGLE_ELEMENTAG":
|
|
126
|
+
case "TOGGLE_REPLIT_VISUAL_EDITOR":
|
|
127
|
+
sm = !!msg.enabled; ee = !!msg.enableEditing;
|
|
128
|
+
document.body.style.cursor = sm ? "crosshair" : "";
|
|
129
|
+
if (!sm) { sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); try { window.parent.postMessage({type:"ELEMENT_UNSELECTED",timestamp:Date.now()},"*"); } catch(e){} }
|
|
130
|
+
break;
|
|
131
|
+
case "UPDATE_SELECTED_ELEMENT":
|
|
132
|
+
if (!sel) break;
|
|
133
|
+
var a = msg.attributes||{};
|
|
134
|
+
if (a.className!==void 0) { sel.setAttribute("class",String(a.className)); sel.setAttribute("data-elema-dirty","true"); }
|
|
135
|
+
if (a.textContent!==void 0) { sel.textContent=String(a.textContent); sel.setAttribute("data-elema-dirty","true"); }
|
|
136
|
+
if (a.style!==void 0) { var p=String(a.style).split(":"); if(p.length>=2) { sel.style[p[0].trim()]=p.slice(1).join(":").trim(); } sel.setAttribute("data-elema-dirty","true"); }
|
|
137
|
+
break;
|
|
138
|
+
case "CLEAR_SELECTION": sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); break;
|
|
139
|
+
case "CLEAR_ELEMENT_DIRTY": if(sel) sel.removeAttribute("data-elema-dirty"); break;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
try { window.parent.postMessage({type:"SELECTOR_SCRIPT_LOADED",timestamp:Date.now(),version:V},"*"); } catch(e){}
|
|
144
|
+
})();
|
|
145
|
+
`;
|
|
146
|
+
}
|
|
147
|
+
export {
|
|
148
|
+
BEACON_VERSION,
|
|
149
|
+
HIGHLIGHT_BG,
|
|
150
|
+
HIGHLIGHT_COLOR,
|
|
151
|
+
generateBeaconScript
|
|
152
|
+
};
|
|
153
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/beacon/index.ts"],"sourcesContent":["/**\n * Elementag Beacon — client-side script injected into the page.\n * Handles element selection, hover highlighting, and postMessage\n * communication with the parent Console frame.\n *\n * This is the equivalent of Cartographer's beacon/index.global.js.\n * It's compiled separately and loaded via transformIndexHtml.\n */\n\nexport const BEACON_VERSION = \"0.1.0\"\nexport const HIGHLIGHT_COLOR = \"#0079F2\"\nexport const HIGHLIGHT_BG = \"#0079F210\"\n\nconst HIGHLIGHT_STYLES = `\n [contenteditable] { outline: none !important; }\n [contenteditable]:focus { outline: none !important; }\n .elema-highlighter { position:absolute; z-index:2147483644; box-sizing:border-box; pointer-events:none; outline:2px dashed ${HIGHLIGHT_COLOR}!important; outline-offset:0!important; margin:0!important; padding:0!important; transform:none!important; background:${HIGHLIGHT_BG}!important; opacity:0; }\n .elema-highlighter-hover { position:fixed; z-index:2147483647; }\n .elema-highlighter-selected { position:fixed; pointer-events:none; outline:2px solid ${HIGHLIGHT_COLOR}!important; outline-offset:3px!important; background:none!important; }\n .elema-label { position:absolute; background:${HIGHLIGHT_COLOR}; color:#FFF; padding:4px 8px; border-radius:4px; font-size:14px; font-family:monospace; line-height:1; white-space:nowrap; box-shadow:0 2px 4px rgba(0,0,0,.2); transform:translateY(-100%); margin-top:-4px; left:0; z-index:2147483645; pointer-events:none; opacity:0; }\n .elema-label-hover { position:fixed; z-index:2147483647; }\n .elema-label-selected { position:fixed; pointer-events:none; }\n`\n\nexport function generateBeaconScript(): string {\n return `\n(function() {\n \"use strict\";\n var V = ${JSON.stringify(BEACON_VERSION)};\n var sm = false, ee = false, sel = null, selMeta = null, he = null;\n var hl = null, lb = null; // hover highlighter + label\n var selHL = null, selLB = null; // selected highlighter + label\n var rafId = null;\n\n function isAllowedOrigin(o) {\n if (o.startsWith(\"http://localhost:\")) return true;\n try { var u = new URL(o); return [\".replit.dev\",\".replit.com\",\".replit-staging.com\",\".rp-humain.com\",\".repl.co\"].some(function(d){ return u.hostname===d.slice(1)||u.hostname.endsWith(d); }); } catch(e){ return false; }\n }\n\n // Inject styles\n var st = document.createElement(\"style\"); st.textContent = ${JSON.stringify(HIGHLIGHT_STYLES)}; document.head.appendChild(st);\n\n // Create hover overlays\n hl = document.createElement(\"div\"); hl.className = \"elema-highlighter elema-highlighter-hover\"; document.body.appendChild(hl);\n lb = document.createElement(\"div\"); lb.className = \"elema-label elema-label-hover\"; document.body.appendChild(lb);\n\n function getMetadata(el) {\n var path = el.getAttribute(\"data-elema-metadata\")||el.getAttribute(\"data-replit-metadata\")||\"\";\n var name = el.getAttribute(\"data-elema-name\")||el.getAttribute(\"data-component-name\")||el.tagName.toLowerCase();\n var cs = window.getComputedStyle(el);\n var styles = {};\n var props = [\"backgroundColor\",\"borderTopColor\",\"borderRightColor\",\"borderBottomColor\",\"borderLeftColor\",\"borderTopLeftRadius\",\"borderTopRightRadius\",\"borderBottomRightRadius\",\"borderBottomLeftRadius\",\"borderTopWidth\",\"borderRightWidth\",\"borderBottomWidth\",\"borderLeftWidth\",\"color\",\"display\",\"position\",\"width\",\"height\",\"fontSize\",\"fontFamily\",\"fontWeight\",\"margin\",\"padding\",\"opacity\",\"textAlign\"];\n for (var i=0;i<props.length;i++) { try { styles[props[i]]=cs[props[i]]; } catch(e){} }\n var pe = el.parentElement;\n var parent = pe ? { tagName: pe.tagName.toLowerCase(), className: pe.getAttribute(\"class\")||void 0, textContent: (pe.textContent||\"\").slice(0,100) } : null;\n var children = [];\n for (var c=0;c<el.children.length&&c<10;c++) { var ch=el.children[c]; children.push({ tagName:ch.tagName.toLowerCase(), className:ch.getAttribute(\"class\")||void 0, textContent:(ch.textContent||\"\").slice(0,100) }); }\n return {\n tagName: el.tagName.toLowerCase(), className: el.getAttribute(\"class\")||void 0, textContent: (el.textContent||\"\").slice(0,100),\n id: el.getAttribute(\"id\")||void 0, elementPath: path, componentName: name,\n computedStyles: styles, relatedElements: { parent:parent, children:children },\n siblingCount: pe?pe.children.length-1:0, hasChildElements: el.children.length>0,\n originalTextContent: el.textContent||void 0, srcAttribute: el.getAttribute(\"src\")||void 0\n };\n }\n\n function updateOverlay(el, h, l) {\n if (!el||!h) return;\n var r = el.getBoundingClientRect();\n h.style.left=r.left+\"px\"; h.style.top=r.top+\"px\"; h.style.width=r.width+\"px\"; h.style.height=r.height+\"px\"; h.style.opacity=\"1\";\n if (l) { var n=el.getAttribute(\"data-elema-name\")||el.getAttribute(\"data-component-name\")||el.tagName.toLowerCase(); l.textContent=n; l.style.left=r.left+\"px\"; l.style.top=r.top+\"px\"; l.style.opacity=\"1\"; }\n }\n\n function clearHover() { if(hl) hl.style.opacity=\"0\"; if(lb) lb.style.opacity=\"0\"; }\n function clearSelected() { if(selHL) { selHL.remove(); selHL=null; } if(selLB) { selLB.remove(); selLB=null; } }\n\n // RAF-based position tracking for selected element\n function startTracking() {\n if (rafId) return;\n function tick() {\n if (sel) { updateOverlay(sel, selHL, selLB); }\n rafId = requestAnimationFrame(tick);\n }\n rafId = requestAnimationFrame(tick);\n }\n function stopTracking() { if (rafId) { cancelAnimationFrame(rafId); rafId=null; } }\n\n function showSelected(el) {\n clearSelected();\n if (!el) return;\n selHL = document.createElement(\"div\"); selHL.className=\"elema-highlighter elema-highlighter-selected\"; document.body.appendChild(selHL);\n selLB = document.createElement(\"div\"); selLB.className=\"elema-label elema-label-selected\"; document.body.appendChild(selLB);\n updateOverlay(el, selHL, selLB);\n startTracking();\n }\n\n // Hover handler\n document.addEventListener(\"mouseover\", function(e) {\n if (!sm) return;\n var t = e.target.closest(\"[data-elema-metadata],[data-replit-metadata],[data-component-id]\");\n if (t) {\n if (t !== he) { he = t; updateOverlay(t, hl, lb); }\n try { var r=t.getBoundingClientRect(); window.parent.postMessage({type:\"ELEMENT_HOVERED\",timestamp:Date.now(),elementBounds:{x:r.left,y:r.top,width:r.width,height:r.height},elementName:t.getAttribute(\"data-elema-name\")||t.getAttribute(\"data-component-name\")||t.tagName.toLowerCase()},\"*\"); } catch(e){}\n } else { he=null; clearHover(); try { window.parent.postMessage({type:\"ELEMENT_HOVERED\",timestamp:Date.now(),elementBounds:null,elementName:\"\"},\"*\"); } catch(e){} }\n }, true);\n\n // Click handler\n document.addEventListener(\"click\", function(e) {\n if (!sm) return;\n var t = e.target.closest(\"[data-elema-metadata],[data-replit-metadata],[data-component-id]\");\n if (!t) return; e.preventDefault(); e.stopPropagation();\n sel = t; selMeta = getMetadata(t); showSelected(t); clearHover();\n if (ee) { t.setAttribute(\"contentEditable\",\"true\"); t.focus(); }\n try { window.parent.postMessage({type:\"ELEMENT_SELECTED\",payload:selMeta,timestamp:Date.now()},\"*\"); } catch(e){}\n }, true);\n\n // Real-time text sync via input event (for contentEditable)\n document.addEventListener(\"input\", function(e) {\n if (!sm || !sel || e.target !== sel) return;\n var updated = getMetadata(sel);\n try { window.parent.postMessage({type:\"ELEMENT_TEXT_CHANGED\",payload:updated,timestamp:Date.now()},\"*\"); } catch(e2){}\n }, true);\n\n // Also sync on blur\n document.addEventListener(\"blur\", function(e) {\n if (!sm || !sel || e.target !== sel) return;\n var updated = getMetadata(sel);\n try { window.parent.postMessage({type:\"ELEMENT_TEXT_CHANGED\",payload:updated,timestamp:Date.now()},\"*\"); } catch(e2){}\n }, true);\n\n // postMessage listener\n window.addEventListener(\"message\", function(event) {\n var msg = event.data || {};\n switch (msg.type) {\n case \"TOGGLE_ELEMENTAG\":\n case \"TOGGLE_REPLIT_VISUAL_EDITOR\":\n sm = !!msg.enabled; ee = !!msg.enableEditing;\n document.body.style.cursor = sm ? \"crosshair\" : \"\";\n if (!sm) { sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); try { window.parent.postMessage({type:\"ELEMENT_UNSELECTED\",timestamp:Date.now()},\"*\"); } catch(e){} }\n break;\n case \"UPDATE_SELECTED_ELEMENT\":\n if (!sel) break;\n var a = msg.attributes||{};\n if (a.className!==void 0) { sel.setAttribute(\"class\",String(a.className)); sel.setAttribute(\"data-elema-dirty\",\"true\"); }\n if (a.textContent!==void 0) { sel.textContent=String(a.textContent); sel.setAttribute(\"data-elema-dirty\",\"true\"); }\n if (a.style!==void 0) { var p=String(a.style).split(\":\"); if(p.length>=2) { sel.style[p[0].trim()]=p.slice(1).join(\":\").trim(); } sel.setAttribute(\"data-elema-dirty\",\"true\"); }\n break;\n case \"CLEAR_SELECTION\": sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); break;\n case \"CLEAR_ELEMENT_DIRTY\": if(sel) sel.removeAttribute(\"data-elema-dirty\"); break;\n }\n });\n\n try { window.parent.postMessage({type:\"SELECTOR_SCRIPT_LOADED\",timestamp:Date.now(),version:V},\"*\"); } catch(e){}\n})();\n`\n}\n"],"mappings":";AASO,IAAM,iBAAiB;AACvB,IAAM,kBAAkB;AACxB,IAAM,eAAe;AAE5B,IAAM,mBAAmB;AAAA;AAAA;AAAA,+HAGsG,eAAe,yHAAyH,YAAY;AAAA;AAAA,yFAE1L,eAAe;AAAA,iDACvD,eAAe;AAAA;AAAA;AAAA;AAKzD,SAAS,uBAA+B;AAC7C,SAAO;AAAA;AAAA;AAAA,YAGG,KAAK,UAAU,cAAc,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+DAYqB,KAAK,UAAU,gBAAgB,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmH/F;","names":[]}
|