@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/index.cjs ADDED
@@ -0,0 +1,550 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ elementag: () => elementag,
34
+ version: () => version
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ var import_parser = require("@babel/parser");
38
+ var import_magic_string = __toESM(require("magic-string"), 1);
39
+ var import_node_path2 = __toESM(require("path"), 1);
40
+
41
+ // src/constants.ts
42
+ var DATA_ATTRIBUTES = {
43
+ METADATA: "data-elema-metadata",
44
+ COMPONENT_NAME: "data-elema-name"
45
+ };
46
+ var VALID_EXTENSIONS = /* @__PURE__ */ new Set([".jsx", ".tsx"]);
47
+ var R3F_IMPORT_SOURCES = /* @__PURE__ */ new Set([
48
+ "@react-three/fiber",
49
+ "@react-three/drei",
50
+ "react-three-fiber"
51
+ ]);
52
+ var R3F_BAILOUT_ELEMENTS = /* @__PURE__ */ new Set([
53
+ "Canvas",
54
+ "mesh",
55
+ "group",
56
+ "scene",
57
+ "primitive",
58
+ "points",
59
+ "instancedMesh",
60
+ "fog",
61
+ "fogExp2",
62
+ "object3D"
63
+ ]);
64
+ var R3F_BAILOUT_PATTERNS = [
65
+ /Geometry$/,
66
+ /Material$/,
67
+ /Light$/,
68
+ /Camera$/,
69
+ /Helper$/,
70
+ /Control$/
71
+ ];
72
+ var FRAGMENT_IMPORT_SOURCES = /* @__PURE__ */ new Set([
73
+ "react",
74
+ "react/jsx-runtime"
75
+ ]);
76
+ var TAILWIND_CONFIG_FILES = [
77
+ "tailwind.config.ts",
78
+ "tailwind.config.js",
79
+ "tailwind.config.mjs",
80
+ "tailwind.config.cjs"
81
+ ];
82
+ var TAILWIND_V4_CDN_URL = "https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.1.14";
83
+ var TAILWIND_V3_CDN_URL = "https://cdn.tailwindcss.com/3.4.17";
84
+
85
+ // src/ast-utils.ts
86
+ var t = __toESM(require("@babel/types"), 1);
87
+ function getElementName(jsxNode) {
88
+ const name = jsxNode.name;
89
+ if (name.type === "JSXIdentifier") {
90
+ return name.name;
91
+ }
92
+ if (name.type === "JSXMemberExpression") {
93
+ const object = name.object;
94
+ const property = name.property;
95
+ if (object.type === "JSXIdentifier" && property.type === "JSXIdentifier") {
96
+ return `${object.name}.${property.name}`;
97
+ }
98
+ }
99
+ return null;
100
+ }
101
+ function usesReactThreeFiber(ast) {
102
+ return ast.program.body.some(
103
+ (node) => t.isImportDeclaration(node) && typeof node.source.value === "string" && R3F_IMPORT_SOURCES.has(node.source.value)
104
+ );
105
+ }
106
+ function shouldBailout(name) {
107
+ if (R3F_BAILOUT_ELEMENTS.has(name)) return true;
108
+ return R3F_BAILOUT_PATTERNS.some((pattern) => pattern.test(name));
109
+ }
110
+ function collectFragmentAliases(ast) {
111
+ const namedAliases = /* @__PURE__ */ new Set();
112
+ const namespaceAliases = /* @__PURE__ */ new Set();
113
+ for (const node of ast.program.body) {
114
+ if (t.isImportDeclaration(node) && typeof node.source.value === "string" && FRAGMENT_IMPORT_SOURCES.has(node.source.value)) {
115
+ for (const specifier of node.specifiers) {
116
+ if (t.isImportSpecifier(specifier) && t.isIdentifier(specifier.imported) && specifier.imported.name === "Fragment") {
117
+ namedAliases.add(specifier.local.name);
118
+ } else if (t.isImportDefaultSpecifier(specifier) || t.isImportNamespaceSpecifier(specifier)) {
119
+ namespaceAliases.add(specifier.local.name);
120
+ }
121
+ }
122
+ }
123
+ }
124
+ return { namedAliases, namespaceAliases };
125
+ }
126
+ function isFragment(name, bindings) {
127
+ if (bindings.namedAliases.has(name)) return true;
128
+ const dotIndex = name.indexOf(".");
129
+ if (dotIndex !== -1) {
130
+ const ns = name.slice(0, dotIndex);
131
+ const prop = name.slice(dotIndex + 1);
132
+ if (prop === "Fragment" && bindings.namespaceAliases.has(ns)) return true;
133
+ }
134
+ return false;
135
+ }
136
+
137
+ // src/tailwind.ts
138
+ var import_promises = __toESM(require("fs/promises"), 1);
139
+ var import_node_path = __toESM(require("path"), 1);
140
+ async function findTailwindConfigPath(dir) {
141
+ for (const configFile of TAILWIND_CONFIG_FILES) {
142
+ const configPath = import_node_path.default.join(dir, configFile);
143
+ try {
144
+ await import_promises.default.access(configPath);
145
+ return configPath;
146
+ } catch {
147
+ }
148
+ }
149
+ return null;
150
+ }
151
+ async function detectTailwindMajorVersion(packageDir) {
152
+ try {
153
+ const packageJsonPath = import_node_path.default.join(packageDir, "package.json");
154
+ const content = await import_promises.default.readFile(packageJsonPath, "utf-8");
155
+ const pkg = JSON.parse(content);
156
+ const versionSpec = pkg.dependencies?.tailwindcss ?? pkg.devDependencies?.tailwindcss;
157
+ if (!versionSpec) return 4;
158
+ const match = String(versionSpec).match(/(\d+)/);
159
+ if (match) return parseInt(match[1], 10);
160
+ return 4;
161
+ } catch {
162
+ return 4;
163
+ }
164
+ }
165
+ function generateClientSideTailwindScript(majorVersion) {
166
+ const cdnUrl = majorVersion >= 4 ? JSON.stringify(TAILWIND_V4_CDN_URL) : JSON.stringify(TAILWIND_V3_CDN_URL);
167
+ const loadBody = majorVersion >= 4 ? `
168
+ var script = document.createElement('script');
169
+ script.src = ${cdnUrl};
170
+
171
+ if (window.REPLIT_APP_TAILWIND_CONFIG) {
172
+ script.setAttribute('data-config', JSON.stringify(window.REPLIT_APP_TAILWIND_CONFIG));
173
+ }
174
+
175
+ document.head.appendChild(script);` : `
176
+ var script = document.createElement('script');
177
+ script.src = ${cdnUrl};
178
+
179
+ script.onload = function() {
180
+ if (window.REPLIT_APP_TAILWIND_CONFIG) {
181
+ window.tailwind.config = window.REPLIT_APP_TAILWIND_CONFIG;
182
+ }
183
+ };
184
+
185
+ document.head.appendChild(script);`;
186
+ return `
187
+ (function() {
188
+ var initialized = false;
189
+
190
+ function loadTailwind() {
191
+ if (initialized) { return; }
192
+ initialized = true;
193
+ ${loadBody}
194
+ }
195
+
196
+ window.addEventListener('replit-init-tailwind', function() {
197
+ if (window.REPLIT_APP_TAILWIND_CONFIG) {
198
+ loadTailwind();
199
+ } else {
200
+ var configTimeout = setTimeout(function() { loadTailwind(); }, 1000);
201
+ window.addEventListener('replit-tailwind-config-ready', function() {
202
+ clearTimeout(configTimeout);
203
+ loadTailwind();
204
+ }, { once: true });
205
+ }
206
+ });
207
+ })();
208
+ `.trim();
209
+ }
210
+ function makeTailwindConfigBrowserSafe(code, traverse) {
211
+ const { parse: parse2 } = require("@babel/parser");
212
+ const ast = parse2(code, {
213
+ sourceType: "module",
214
+ plugins: ["typescript"]
215
+ });
216
+ const MagicString2 = require("magic-string");
217
+ const s = new MagicString2(code);
218
+ const importBindings = /* @__PURE__ */ new Map();
219
+ let bindingCounter = 0;
220
+ const requireSites = [];
221
+ traverse(ast, {
222
+ CallExpression(nodePath) {
223
+ const node = nodePath.node;
224
+ if (node.callee.type === "Identifier" && node.callee.name === "require" && node.arguments.length === 1 && node.arguments[0].type === "StringLiteral") {
225
+ if (node.start == null || node.end == null) return;
226
+ const moduleName = node.arguments[0].value;
227
+ let binding = importBindings.get(moduleName);
228
+ if (!binding) {
229
+ binding = `__req_${bindingCounter++}`;
230
+ importBindings.set(moduleName, binding);
231
+ }
232
+ requireSites.push({ start: node.start, end: node.end, binding });
233
+ }
234
+ }
235
+ });
236
+ if (requireSites.length === 0) return null;
237
+ const importLines = [];
238
+ for (const [moduleName, binding] of importBindings) {
239
+ importLines.push(`import ${binding} from ${JSON.stringify(moduleName)};`);
240
+ }
241
+ s.prepend(importLines.join("\n") + "\n");
242
+ for (const site of requireSites) {
243
+ s.overwrite(site.start, site.end, site.binding);
244
+ }
245
+ return { code: s.toString(), map: s.generateMap({ hires: true }) };
246
+ }
247
+
248
+ // src/beacon/index.ts
249
+ var BEACON_VERSION = "0.1.0";
250
+ var HIGHLIGHT_COLOR = "#0079F2";
251
+ var HIGHLIGHT_BG = "#0079F210";
252
+ var HIGHLIGHT_STYLES = `
253
+ [contenteditable] { outline: none !important; }
254
+ [contenteditable]:focus { outline: none !important; }
255
+ .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; }
256
+ .elema-highlighter-hover { position:fixed; z-index:2147483647; }
257
+ .elema-highlighter-selected { position:fixed; pointer-events:none; outline:2px solid ${HIGHLIGHT_COLOR}!important; outline-offset:3px!important; background:none!important; }
258
+ .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; }
259
+ .elema-label-hover { position:fixed; z-index:2147483647; }
260
+ .elema-label-selected { position:fixed; pointer-events:none; }
261
+ `;
262
+ function generateBeaconScript() {
263
+ return `
264
+ (function() {
265
+ "use strict";
266
+ var V = ${JSON.stringify(BEACON_VERSION)};
267
+ var sm = false, ee = false, sel = null, selMeta = null, he = null;
268
+ var hl = null, lb = null; // hover highlighter + label
269
+ var selHL = null, selLB = null; // selected highlighter + label
270
+ var rafId = null;
271
+
272
+ function isAllowedOrigin(o) {
273
+ if (o.startsWith("http://localhost:")) return true;
274
+ 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; }
275
+ }
276
+
277
+ // Inject styles
278
+ var st = document.createElement("style"); st.textContent = ${JSON.stringify(HIGHLIGHT_STYLES)}; document.head.appendChild(st);
279
+
280
+ // Create hover overlays
281
+ hl = document.createElement("div"); hl.className = "elema-highlighter elema-highlighter-hover"; document.body.appendChild(hl);
282
+ lb = document.createElement("div"); lb.className = "elema-label elema-label-hover"; document.body.appendChild(lb);
283
+
284
+ function getMetadata(el) {
285
+ var path = el.getAttribute("data-elema-metadata")||el.getAttribute("data-replit-metadata")||"";
286
+ var name = el.getAttribute("data-elema-name")||el.getAttribute("data-component-name")||el.tagName.toLowerCase();
287
+ var cs = window.getComputedStyle(el);
288
+ var styles = {};
289
+ 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"];
290
+ for (var i=0;i<props.length;i++) { try { styles[props[i]]=cs[props[i]]; } catch(e){} }
291
+ var pe = el.parentElement;
292
+ var parent = pe ? { tagName: pe.tagName.toLowerCase(), className: pe.getAttribute("class")||void 0, textContent: (pe.textContent||"").slice(0,100) } : null;
293
+ var children = [];
294
+ 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) }); }
295
+ return {
296
+ tagName: el.tagName.toLowerCase(), className: el.getAttribute("class")||void 0, textContent: (el.textContent||"").slice(0,100),
297
+ id: el.getAttribute("id")||void 0, elementPath: path, componentName: name,
298
+ computedStyles: styles, relatedElements: { parent:parent, children:children },
299
+ siblingCount: pe?pe.children.length-1:0, hasChildElements: el.children.length>0,
300
+ originalTextContent: el.textContent||void 0, srcAttribute: el.getAttribute("src")||void 0
301
+ };
302
+ }
303
+
304
+ function updateOverlay(el, h, l) {
305
+ if (!el||!h) return;
306
+ var r = el.getBoundingClientRect();
307
+ 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";
308
+ 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"; }
309
+ }
310
+
311
+ function clearHover() { if(hl) hl.style.opacity="0"; if(lb) lb.style.opacity="0"; }
312
+ function clearSelected() { if(selHL) { selHL.remove(); selHL=null; } if(selLB) { selLB.remove(); selLB=null; } }
313
+
314
+ // RAF-based position tracking for selected element
315
+ function startTracking() {
316
+ if (rafId) return;
317
+ function tick() {
318
+ if (sel) { updateOverlay(sel, selHL, selLB); }
319
+ rafId = requestAnimationFrame(tick);
320
+ }
321
+ rafId = requestAnimationFrame(tick);
322
+ }
323
+ function stopTracking() { if (rafId) { cancelAnimationFrame(rafId); rafId=null; } }
324
+
325
+ function showSelected(el) {
326
+ clearSelected();
327
+ if (!el) return;
328
+ selHL = document.createElement("div"); selHL.className="elema-highlighter elema-highlighter-selected"; document.body.appendChild(selHL);
329
+ selLB = document.createElement("div"); selLB.className="elema-label elema-label-selected"; document.body.appendChild(selLB);
330
+ updateOverlay(el, selHL, selLB);
331
+ startTracking();
332
+ }
333
+
334
+ // Hover handler
335
+ document.addEventListener("mouseover", function(e) {
336
+ if (!sm) return;
337
+ var t = e.target.closest("[data-elema-metadata],[data-replit-metadata],[data-component-id]");
338
+ if (t) {
339
+ if (t !== he) { he = t; updateOverlay(t, hl, lb); }
340
+ 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){}
341
+ } else { he=null; clearHover(); try { window.parent.postMessage({type:"ELEMENT_HOVERED",timestamp:Date.now(),elementBounds:null,elementName:""},"*"); } catch(e){} }
342
+ }, true);
343
+
344
+ // Click handler
345
+ document.addEventListener("click", function(e) {
346
+ if (!sm) return;
347
+ var t = e.target.closest("[data-elema-metadata],[data-replit-metadata],[data-component-id]");
348
+ if (!t) return; e.preventDefault(); e.stopPropagation();
349
+ sel = t; selMeta = getMetadata(t); showSelected(t); clearHover();
350
+ if (ee) { t.setAttribute("contentEditable","true"); t.focus(); }
351
+ try { window.parent.postMessage({type:"ELEMENT_SELECTED",payload:selMeta,timestamp:Date.now()},"*"); } catch(e){}
352
+ }, true);
353
+
354
+ // Real-time text sync via input event (for contentEditable)
355
+ document.addEventListener("input", function(e) {
356
+ if (!sm || !sel || e.target !== sel) return;
357
+ var updated = getMetadata(sel);
358
+ try { window.parent.postMessage({type:"ELEMENT_TEXT_CHANGED",payload:updated,timestamp:Date.now()},"*"); } catch(e2){}
359
+ }, true);
360
+
361
+ // Also sync on blur
362
+ document.addEventListener("blur", function(e) {
363
+ if (!sm || !sel || e.target !== sel) return;
364
+ var updated = getMetadata(sel);
365
+ try { window.parent.postMessage({type:"ELEMENT_TEXT_CHANGED",payload:updated,timestamp:Date.now()},"*"); } catch(e2){}
366
+ }, true);
367
+
368
+ // postMessage listener
369
+ window.addEventListener("message", function(event) {
370
+ var msg = event.data || {};
371
+ switch (msg.type) {
372
+ case "TOGGLE_ELEMENTAG":
373
+ case "TOGGLE_REPLIT_VISUAL_EDITOR":
374
+ sm = !!msg.enabled; ee = !!msg.enableEditing;
375
+ document.body.style.cursor = sm ? "crosshair" : "";
376
+ if (!sm) { sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); try { window.parent.postMessage({type:"ELEMENT_UNSELECTED",timestamp:Date.now()},"*"); } catch(e){} }
377
+ break;
378
+ case "UPDATE_SELECTED_ELEMENT":
379
+ if (!sel) break;
380
+ var a = msg.attributes||{};
381
+ if (a.className!==void 0) { sel.setAttribute("class",String(a.className)); sel.setAttribute("data-elema-dirty","true"); }
382
+ if (a.textContent!==void 0) { sel.textContent=String(a.textContent); sel.setAttribute("data-elema-dirty","true"); }
383
+ 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"); }
384
+ break;
385
+ case "CLEAR_SELECTION": sel=null; selMeta=null; clearHover(); clearSelected(); stopTracking(); break;
386
+ case "CLEAR_ELEMENT_DIRTY": if(sel) sel.removeAttribute("data-elema-dirty"); break;
387
+ }
388
+ });
389
+
390
+ try { window.parent.postMessage({type:"SELECTOR_SCRIPT_LOADED",timestamp:Date.now(),version:V},"*"); } catch(e){}
391
+ })();
392
+ `;
393
+ }
394
+
395
+ // src/index.ts
396
+ var version = BEACON_VERSION;
397
+ function elementag(options) {
398
+ let viteRoot = "";
399
+ let configuredRoot = "";
400
+ let configuredRootName = "";
401
+ let clientScript = null;
402
+ let tailwindConfigPath = null;
403
+ let tailwindMajorVersion = 4;
404
+ let tailwindInjectionTarget = null;
405
+ return {
406
+ name: "vite-plugin-elementag",
407
+ enforce: "pre",
408
+ async configResolved(config) {
409
+ viteRoot = normalizePath(config.root);
410
+ configuredRoot = options?.root ? normalizePath(
411
+ import_node_path2.default.isAbsolute(options.root) ? options.root : import_node_path2.default.resolve(config.root, options.root)
412
+ ) : viteRoot;
413
+ configuredRootName = import_node_path2.default.basename(configuredRoot);
414
+ clientScript = generateBeaconScript();
415
+ const packageDir = await findClosestPackageDir(configuredRoot);
416
+ const tailwindSearchRoot = packageDir ?? configuredRoot;
417
+ tailwindConfigPath = await findTailwindConfigPath(tailwindSearchRoot);
418
+ tailwindMajorVersion = await detectTailwindMajorVersion(tailwindSearchRoot);
419
+ },
420
+ async transform(code, id) {
421
+ const ext = import_node_path2.default.extname(id);
422
+ if (!VALID_EXTENSIONS.has(ext)) return null;
423
+ if (id.includes("node_modules")) return null;
424
+ const traverseModule = await import("@babel/traverse");
425
+ const traverse = traverseModule.default?.default ?? traverseModule.default ?? traverseModule;
426
+ if (typeof traverse !== "function") return null;
427
+ if (tailwindConfigPath && id === tailwindConfigPath) {
428
+ return makeTailwindConfigBrowserSafe(code, traverse);
429
+ }
430
+ let ast;
431
+ try {
432
+ ast = (0, import_parser.parse)(code, {
433
+ sourceType: "module",
434
+ plugins: ["jsx", "typescript"]
435
+ });
436
+ } catch {
437
+ return null;
438
+ }
439
+ if (usesReactThreeFiber(ast)) return null;
440
+ const magicString = new import_magic_string.default(code);
441
+ let didInjectTailwind = false;
442
+ if (tailwindConfigPath) {
443
+ const isInjectionCandidate = tailwindInjectionTarget === id || tailwindInjectionTarget === null && id.startsWith(viteRoot + "/");
444
+ if (isInjectionCandidate) {
445
+ const relativeConfigPath = normalizePath(
446
+ import_node_path2.default.relative(import_node_path2.default.dirname(id), tailwindConfigPath)
447
+ );
448
+ const importPath = relativeConfigPath.startsWith(".") ? relativeConfigPath : `./${relativeConfigPath}`;
449
+ magicString.prepend(
450
+ [
451
+ `(async () => {`,
452
+ ` try {`,
453
+ ` const __el_tag_tw_mod = await import(${JSON.stringify(importPath)});`,
454
+ ` const __el_tag_tw_raw = __el_tag_tw_mod.default ?? __el_tag_tw_mod;`,
455
+ ` if (typeof window !== 'undefined' && __el_tag_tw_raw && typeof __el_tag_tw_raw === 'object') {`,
456
+ ` window.REPLIT_APP_TAILWIND_CONFIG = __el_tag_tw_raw;`,
457
+ ` window.dispatchEvent(new CustomEvent('replit-tailwind-config-ready'));`,
458
+ ` }`,
459
+ ` } catch (e) {`,
460
+ ` console.warn('[elementag] Failed to load tailwind config:', e);`,
461
+ ` }`,
462
+ `})();`
463
+ ].join("\n") + "\n"
464
+ );
465
+ didInjectTailwind = true;
466
+ }
467
+ }
468
+ let currentElement = null;
469
+ const fragmentAliases = collectFragmentAliases(ast);
470
+ traverse(ast, {
471
+ JSXElement: {
472
+ enter(elementPath) {
473
+ currentElement = elementPath.node;
474
+ },
475
+ exit() {
476
+ currentElement = null;
477
+ }
478
+ },
479
+ JSXOpeningElement(elementPath) {
480
+ const jsxNode = elementPath.node;
481
+ const elementName = getElementName(jsxNode);
482
+ if (!elementName) return;
483
+ if (shouldBailout(elementName)) return;
484
+ if (elementName === "line") return;
485
+ if (isFragment(elementName, fragmentAliases)) return;
486
+ if (currentElement) {
487
+ const { line = 0, column: col = 0 } = jsxNode.loc?.start ?? {};
488
+ const relativeToConfigured = import_node_path2.default.relative(configuredRoot, id);
489
+ const componentPath = normalizePath(
490
+ import_node_path2.default.join(configuredRootName, relativeToConfigured)
491
+ );
492
+ const componentMetadata = col === 0 ? `${componentPath}:${line}` : `${componentPath}:${line}:${col}`;
493
+ const insertPos = jsxNode.name.end ?? 0;
494
+ magicString.appendLeft(
495
+ insertPos,
496
+ ` ${DATA_ATTRIBUTES.METADATA}="${componentMetadata}" ${DATA_ATTRIBUTES.COMPONENT_NAME}="${elementName}"`
497
+ );
498
+ }
499
+ }
500
+ });
501
+ if (didInjectTailwind) {
502
+ tailwindInjectionTarget = id;
503
+ }
504
+ return {
505
+ code: magicString.toString(),
506
+ map: magicString.generateMap({ hires: true })
507
+ };
508
+ },
509
+ transformIndexHtml() {
510
+ if (!clientScript) return [];
511
+ return [
512
+ {
513
+ tag: "script",
514
+ attrs: { type: "module" },
515
+ children: clientScript,
516
+ injectTo: "head"
517
+ },
518
+ {
519
+ tag: "script",
520
+ attrs: {},
521
+ children: generateClientSideTailwindScript(tailwindMajorVersion),
522
+ injectTo: "head"
523
+ }
524
+ ];
525
+ }
526
+ };
527
+ }
528
+ function normalizePath(p) {
529
+ return p.replace(/\\/g, "/");
530
+ }
531
+ async function findClosestPackageDir(startDir) {
532
+ let current = import_node_path2.default.resolve(startDir);
533
+ const { access } = await import("fs/promises");
534
+ while (true) {
535
+ try {
536
+ await access(import_node_path2.default.join(current, "package.json"));
537
+ return current;
538
+ } catch {
539
+ }
540
+ const parent = import_node_path2.default.dirname(current);
541
+ if (parent === current) return null;
542
+ current = parent;
543
+ }
544
+ }
545
+ // Annotate the CommonJS export names for ESM import in node:
546
+ 0 && (module.exports = {
547
+ elementag,
548
+ version
549
+ });
550
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/ast-utils.ts","../src/tailwind.ts","../src/beacon/index.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from \"vite\"\nimport type { SourceMapInput } from \"rollup\"\nimport { parse } from \"@babel/parser\"\nimport type { Visitor } from \"@babel/traverse\"\nimport * as t from \"@babel/types\"\nimport MagicString from \"magic-string\"\nimport path from \"node:path\"\nimport { DATA_ATTRIBUTES, VALID_EXTENSIONS } from \"./constants\"\nimport {\n getElementName,\n usesReactThreeFiber,\n shouldBailout,\n collectFragmentAliases,\n isFragment,\n} from \"./ast-utils\"\nimport {\n findTailwindConfigPath,\n detectTailwindMajorVersion,\n generateClientSideTailwindScript,\n makeTailwindConfigBrowserSafe,\n} from \"./tailwind\"\nimport { generateBeaconScript, BEACON_VERSION } from \"./beacon/index\"\n\nexport interface ElementagOptions {\n /** Override the root directory for metadata path resolution */\n root?: string\n}\n\nexport const version = BEACON_VERSION\n\nexport function elementag(options?: ElementagOptions): Plugin {\n let viteRoot = \"\"\n let configuredRoot = \"\"\n let configuredRootName = \"\"\n let clientScript: string | null = null\n let tailwindConfigPath: string | null = null\n let tailwindMajorVersion = 4\n let tailwindInjectionTarget: string | null = null\n\n return {\n name: \"vite-plugin-elementag\",\n enforce: \"pre\",\n\n async configResolved(config: ResolvedConfig) {\n viteRoot = normalizePath(config.root)\n configuredRoot = options?.root\n ? normalizePath(\n path.isAbsolute(options.root)\n ? options.root\n : path.resolve(config.root, options.root),\n )\n : viteRoot\n configuredRootName = path.basename(configuredRoot)\n\n clientScript = generateBeaconScript()\n\n const packageDir = await findClosestPackageDir(configuredRoot)\n const tailwindSearchRoot = packageDir ?? configuredRoot\n tailwindConfigPath = await findTailwindConfigPath(tailwindSearchRoot)\n tailwindMajorVersion = await detectTailwindMajorVersion(tailwindSearchRoot)\n },\n\n async transform(code: string, id: string) {\n const ext = path.extname(id)\n if (!VALID_EXTENSIONS.has(ext)) return null\n if (id.includes(\"node_modules\")) return null\n\n const traverseModule = await import(\"@babel/traverse\")\n const traverse =\n (traverseModule as any).default?.default ??\n (traverseModule as any).default ??\n traverseModule\n\n if (typeof traverse !== \"function\") return null\n\n if (tailwindConfigPath && id === tailwindConfigPath) {\n return makeTailwindConfigBrowserSafe(code, traverse) as any\n }\n\n let ast: t.File\n try {\n ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"],\n })\n } catch {\n return null\n }\n\n if (usesReactThreeFiber(ast)) return null\n\n const magicString = new MagicString(code)\n let didInjectTailwind = false\n\n if (tailwindConfigPath) {\n const isInjectionCandidate =\n tailwindInjectionTarget === id ||\n (tailwindInjectionTarget === null && id.startsWith(viteRoot + \"/\"))\n if (isInjectionCandidate) {\n const relativeConfigPath = normalizePath(\n path.relative(path.dirname(id), tailwindConfigPath),\n )\n const importPath = relativeConfigPath.startsWith(\".\")\n ? relativeConfigPath\n : `./${relativeConfigPath}`\n magicString.prepend(\n [\n `(async () => {`,\n ` try {`,\n ` const __el_tag_tw_mod = await import(${JSON.stringify(importPath)});`,\n ` const __el_tag_tw_raw = __el_tag_tw_mod.default ?? __el_tag_tw_mod;`,\n ` if (typeof window !== 'undefined' && __el_tag_tw_raw && typeof __el_tag_tw_raw === 'object') {`,\n ` window.REPLIT_APP_TAILWIND_CONFIG = __el_tag_tw_raw;`,\n ` window.dispatchEvent(new CustomEvent('replit-tailwind-config-ready'));`,\n ` }`,\n ` } catch (e) {`,\n ` console.warn('[elementag] Failed to load tailwind config:', e);`,\n ` }`,\n `})();`,\n ].join(\"\\n\") + \"\\n\",\n )\n didInjectTailwind = true\n }\n }\n\n let currentElement: t.JSXElement | null = null\n const fragmentAliases = collectFragmentAliases(ast)\n\n traverse(ast, {\n JSXElement: {\n enter(elementPath: any) {\n currentElement = elementPath.node\n },\n exit() {\n currentElement = null\n },\n },\n JSXOpeningElement(elementPath: any) {\n const jsxNode = elementPath.node as t.JSXOpeningElement\n const elementName = getElementName(jsxNode)\n if (!elementName) return\n if (shouldBailout(elementName)) return\n if (elementName === \"line\") return\n if (isFragment(elementName, fragmentAliases)) return\n\n if (currentElement) {\n const { line = 0, column: col = 0 } =\n jsxNode.loc?.start ?? {}\n const relativeToConfigured = path.relative(configuredRoot, id)\n const componentPath = normalizePath(\n path.join(configuredRootName, relativeToConfigured),\n )\n const componentMetadata =\n col === 0\n ? `${componentPath}:${line}`\n : `${componentPath}:${line}:${col}`\n\n const insertPos =\n (jsxNode.name as any).end ?? 0\n magicString.appendLeft(\n insertPos,\n ` ${DATA_ATTRIBUTES.METADATA}=\"${componentMetadata}\" ${DATA_ATTRIBUTES.COMPONENT_NAME}=\"${elementName}\"`,\n )\n }\n },\n } as Visitor)\n\n if (didInjectTailwind) {\n tailwindInjectionTarget = id\n }\n\n return {\n code: magicString.toString(),\n map: magicString.generateMap({ hires: true }) as SourceMapInput,\n }\n },\n\n transformIndexHtml() {\n if (!clientScript) return []\n return [\n {\n tag: \"script\",\n attrs: { type: \"module\" },\n children: clientScript,\n injectTo: \"head\" as const,\n },\n {\n tag: \"script\",\n attrs: {},\n children: generateClientSideTailwindScript(tailwindMajorVersion),\n injectTo: \"head\" as const,\n },\n ]\n },\n }\n}\n\nfunction normalizePath(p: string): string {\n return p.replace(/\\\\/g, \"/\")\n}\n\nasync function findClosestPackageDir(\n startDir: string,\n): Promise<string | null> {\n let current = path.resolve(startDir)\n const { access } = await import(\"node:fs/promises\")\n while (true) {\n try {\n await access(path.join(current, \"package.json\"))\n return current\n } catch {\n // continue\n }\n const parent = path.dirname(current)\n if (parent === current) return null\n current = parent\n }\n}\n","export const DATA_ATTRIBUTES = {\n METADATA: \"data-elema-metadata\",\n COMPONENT_NAME: \"data-elema-name\",\n} as const\n\n/** Only process these file extensions */\nexport const VALID_EXTENSIONS = new Set([\".jsx\", \".tsx\"])\n\n/** R3F (React Three Fiber) import sources — bail out of these files */\nexport const R3F_IMPORT_SOURCES = new Set([\n \"@react-three/fiber\",\n \"@react-three/drei\",\n \"react-three-fiber\",\n])\n\n/** R3F element names that should not be tagged */\nexport const R3F_BAILOUT_ELEMENTS = new Set([\n \"Canvas\",\n \"mesh\",\n \"group\",\n \"scene\",\n \"primitive\",\n \"points\",\n \"instancedMesh\",\n \"fog\",\n \"fogExp2\",\n \"object3D\",\n])\n\n/** R3F element name patterns that should not be tagged */\nexport const R3F_BAILOUT_PATTERNS = [\n /Geometry$/,\n /Material$/,\n /Light$/,\n /Camera$/,\n /Helper$/,\n /Control$/,\n]\n\n/** Fragment import sources */\nexport const FRAGMENT_IMPORT_SOURCES = new Set([\n \"react\",\n \"react/jsx-runtime\",\n])\n\n/** Tailwind config file names to search for */\nexport const TAILWIND_CONFIG_FILES = [\n \"tailwind.config.ts\",\n \"tailwind.config.js\",\n \"tailwind.config.mjs\",\n \"tailwind.config.cjs\",\n]\n\nexport const TAILWIND_V4_CDN_URL =\n \"https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4.1.14\"\nexport const TAILWIND_V3_CDN_URL = \"https://cdn.tailwindcss.com/3.4.17\"\n","import * as t from \"@babel/types\"\nimport type { Node } from \"@babel/types\"\nimport {\n R3F_IMPORT_SOURCES,\n R3F_BAILOUT_ELEMENTS,\n R3F_BAILOUT_PATTERNS,\n FRAGMENT_IMPORT_SOURCES,\n} from \"./constants\"\n\n/** Get the JSX element name from an opening element node */\nexport function getElementName(\n jsxNode: t.JSXOpeningElement,\n): string | null {\n const name = jsxNode.name\n if (name.type === \"JSXIdentifier\") {\n return name.name\n }\n if (name.type === \"JSXMemberExpression\") {\n const object = name.object\n const property = name.property\n if (object.type === \"JSXIdentifier\" && property.type === \"JSXIdentifier\") {\n return `${object.name}.${property.name}`\n }\n }\n return null\n}\n\n/** Check if a file imports from React Three Fiber (should bail out) */\nexport function usesReactThreeFiber(ast: t.File): boolean {\n return ast.program.body.some(\n (node) =>\n t.isImportDeclaration(node) &&\n typeof node.source.value === \"string\" &&\n R3F_IMPORT_SOURCES.has(node.source.value),\n )\n}\n\n/** Check if an element name should be bailed out (R3F elements/patterns) */\nexport function shouldBailout(name: string): boolean {\n if (R3F_BAILOUT_ELEMENTS.has(name)) return true\n return R3F_BAILOUT_PATTERNS.some((pattern) => pattern.test(name))\n}\n\ninterface FragmentAliases {\n namedAliases: Set<string>\n namespaceAliases: Set<string>\n}\n\n/** Collect Fragment import aliases from the AST */\nexport function collectFragmentAliases(ast: t.File): FragmentAliases {\n const namedAliases = new Set<string>()\n const namespaceAliases = new Set<string>()\n\n for (const node of ast.program.body) {\n if (\n t.isImportDeclaration(node) &&\n typeof node.source.value === \"string\" &&\n FRAGMENT_IMPORT_SOURCES.has(node.source.value)\n ) {\n for (const specifier of node.specifiers) {\n if (\n t.isImportSpecifier(specifier) &&\n t.isIdentifier(specifier.imported) &&\n specifier.imported.name === \"Fragment\"\n ) {\n namedAliases.add(specifier.local.name)\n } else if (\n t.isImportDefaultSpecifier(specifier) ||\n t.isImportNamespaceSpecifier(specifier)\n ) {\n namespaceAliases.add(specifier.local.name)\n }\n }\n }\n }\n\n return { namedAliases, namespaceAliases }\n}\n\n/** Check if an element name is a Fragment reference */\nexport function isFragment(\n name: string,\n bindings: FragmentAliases,\n): boolean {\n if (bindings.namedAliases.has(name)) return true\n\n const dotIndex = name.indexOf(\".\")\n if (dotIndex !== -1) {\n const ns = name.slice(0, dotIndex)\n const prop = name.slice(dotIndex + 1)\n if (prop === \"Fragment\" && bindings.namespaceAliases.has(ns)) return true\n }\n\n return false\n}\n","import fs from \"node:fs/promises\"\nimport path from \"node:path\"\nimport { TAILWIND_CONFIG_FILES, TAILWIND_V3_CDN_URL, TAILWIND_V4_CDN_URL } from \"./constants\"\n\n/** Find the tailwind config file path */\nexport async function findTailwindConfigPath(\n dir: string,\n): Promise<string | null> {\n for (const configFile of TAILWIND_CONFIG_FILES) {\n const configPath = path.join(dir, configFile)\n try {\n await fs.access(configPath)\n return configPath\n } catch {\n // file doesn't exist, try next\n }\n }\n return null\n}\n\n/** Detect Tailwind CSS major version from package.json */\nexport async function detectTailwindMajorVersion(\n packageDir: string,\n): Promise<number> {\n try {\n const packageJsonPath = path.join(packageDir, \"package.json\")\n const content = await fs.readFile(packageJsonPath, \"utf-8\")\n const pkg = JSON.parse(content)\n const versionSpec =\n pkg.dependencies?.tailwindcss ?? pkg.devDependencies?.tailwindcss\n if (!versionSpec) return 4\n const match = String(versionSpec).match(/(\\d+)/)\n if (match) return parseInt(match[1], 10)\n return 4\n } catch {\n return 4\n }\n}\n\n/**\n * Generate the client-side Tailwind CDN loader script.\n * Injects Tailwind CSS from CDN with project config.\n */\nexport function generateClientSideTailwindScript(\n majorVersion: number,\n): string {\n const cdnUrl =\n majorVersion >= 4\n ? JSON.stringify(TAILWIND_V4_CDN_URL)\n : JSON.stringify(TAILWIND_V3_CDN_URL)\n\n const loadBody =\n majorVersion >= 4\n ? `\n var script = document.createElement('script');\n script.src = ${cdnUrl};\n\n if (window.REPLIT_APP_TAILWIND_CONFIG) {\n script.setAttribute('data-config', JSON.stringify(window.REPLIT_APP_TAILWIND_CONFIG));\n }\n\n document.head.appendChild(script);`\n : `\n var script = document.createElement('script');\n script.src = ${cdnUrl};\n\n script.onload = function() {\n if (window.REPLIT_APP_TAILWIND_CONFIG) {\n window.tailwind.config = window.REPLIT_APP_TAILWIND_CONFIG;\n }\n };\n\n document.head.appendChild(script);`\n\n return `\n(function() {\n var initialized = false;\n\n function loadTailwind() {\n if (initialized) { return; }\n initialized = true;\n${loadBody}\n }\n\n window.addEventListener('replit-init-tailwind', function() {\n if (window.REPLIT_APP_TAILWIND_CONFIG) {\n loadTailwind();\n } else {\n var configTimeout = setTimeout(function() { loadTailwind(); }, 1000);\n window.addEventListener('replit-tailwind-config-ready', function() {\n clearTimeout(configTimeout);\n loadTailwind();\n }, { once: true });\n }\n });\n})();\n`.trim()\n}\n\n/**\n * Make a Tailwind config file browser-safe by converting require() calls\n * to import statements. Returns null if no conversion needed.\n */\nexport function makeTailwindConfigBrowserSafe(\n code: string,\n traverse: (ast: unknown, visitor: unknown) => void,\n): { code: string; map?: unknown } | null {\n // Parse the code\n const { parse } = require(\"@babel/parser\")\n const ast = parse(code, {\n sourceType: \"module\",\n plugins: [\"typescript\"],\n })\n\n const MagicString = require(\"magic-string\")\n const s = new MagicString(code)\n const importBindings = new Map<string, string>()\n let bindingCounter = 0\n const requireSites: Array<{\n start: number\n end: number\n binding: string\n }> = []\n\n traverse(ast, {\n CallExpression(nodePath: any) {\n const node = nodePath.node\n if (\n node.callee.type === \"Identifier\" &&\n node.callee.name === \"require\" &&\n node.arguments.length === 1 &&\n node.arguments[0].type === \"StringLiteral\"\n ) {\n if (node.start == null || node.end == null) return\n const moduleName = node.arguments[0].value\n let binding = importBindings.get(moduleName)\n if (!binding) {\n binding = `__req_${bindingCounter++}`\n importBindings.set(moduleName, binding)\n }\n requireSites.push({ start: node.start, end: node.end, binding })\n }\n },\n })\n\n if (requireSites.length === 0) return null\n\n const importLines: string[] = []\n for (const [moduleName, binding] of importBindings) {\n importLines.push(`import ${binding} from ${JSON.stringify(moduleName)};`)\n }\n s.prepend(importLines.join(\"\\n\") + \"\\n\")\n\n for (const site of requireSites) {\n s.overwrite(site.start, site.end, site.binding)\n }\n\n return { code: s.toString(), map: s.generateMap({ hires: true }) }\n}\n","/**\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":"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","names":["import_node_path","path","fs","parse","MagicString","path","MagicString"]}
@@ -0,0 +1,10 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ interface ElementagOptions {
4
+ /** Override the root directory for metadata path resolution */
5
+ root?: string;
6
+ }
7
+ declare const version = "0.1.0";
8
+ declare function elementag(options?: ElementagOptions): Plugin;
9
+
10
+ export { type ElementagOptions, elementag, version };
@@ -0,0 +1,10 @@
1
+ import { Plugin } from 'vite';
2
+
3
+ interface ElementagOptions {
4
+ /** Override the root directory for metadata path resolution */
5
+ root?: string;
6
+ }
7
+ declare const version = "0.1.0";
8
+ declare function elementag(options?: ElementagOptions): Plugin;
9
+
10
+ export { type ElementagOptions, elementag, version };