@salesforce/ui-bundle 1.117.2

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.
Files changed (68) hide show
  1. package/LICENSE.txt +82 -0
  2. package/README.md +3 -0
  3. package/dist/api/clients.d.ts +22 -0
  4. package/dist/api/clients.d.ts.map +1 -0
  5. package/dist/api/clients.js +84 -0
  6. package/dist/api/graphql-operations-types.d.ts +225 -0
  7. package/dist/api/graphql-operations-types.d.ts.map +1 -0
  8. package/dist/api/index.d.ts +10 -0
  9. package/dist/api/index.d.ts.map +1 -0
  10. package/dist/api/index.js +13 -0
  11. package/dist/api/utils/accounts.d.ts +33 -0
  12. package/dist/api/utils/accounts.d.ts.map +1 -0
  13. package/dist/api/utils/accounts.js +47 -0
  14. package/dist/api/utils/records.d.ts +16 -0
  15. package/dist/api/utils/records.d.ts.map +1 -0
  16. package/dist/api/utils/records.js +26 -0
  17. package/dist/api/utils/user.d.ts +17 -0
  18. package/dist/api/utils/user.d.ts.map +1 -0
  19. package/dist/api/utils/user.js +25 -0
  20. package/dist/app/index.d.ts +10 -0
  21. package/dist/app/index.d.ts.map +1 -0
  22. package/dist/app/index.js +7 -0
  23. package/dist/app/manifest.d.ts +34 -0
  24. package/dist/app/manifest.d.ts.map +1 -0
  25. package/dist/app/manifest.js +28 -0
  26. package/dist/app/org.d.ts +28 -0
  27. package/dist/app/org.d.ts.map +1 -0
  28. package/dist/app/org.js +67 -0
  29. package/dist/design/design-mode-interactions.js +761 -0
  30. package/dist/design/index.d.ts +12 -0
  31. package/dist/design/index.d.ts.map +1 -0
  32. package/dist/design/index.js +14 -0
  33. package/dist/design/interactions/communicationManager.d.ts +25 -0
  34. package/dist/design/interactions/communicationManager.d.ts.map +1 -0
  35. package/dist/design/interactions/componentMatcher.d.ts +43 -0
  36. package/dist/design/interactions/componentMatcher.d.ts.map +1 -0
  37. package/dist/design/interactions/editableManager.d.ts +25 -0
  38. package/dist/design/interactions/editableManager.d.ts.map +1 -0
  39. package/dist/design/interactions/eventHandlers.d.ts +40 -0
  40. package/dist/design/interactions/eventHandlers.d.ts.map +1 -0
  41. package/dist/design/interactions/index.d.ts +7 -0
  42. package/dist/design/interactions/index.d.ts.map +1 -0
  43. package/dist/design/interactions/interactionsController.d.ts +36 -0
  44. package/dist/design/interactions/interactionsController.d.ts.map +1 -0
  45. package/dist/design/interactions/styleManager.d.ts +49 -0
  46. package/dist/design/interactions/styleManager.d.ts.map +1 -0
  47. package/dist/design/interactions/utils/cssUtils.d.ts +54 -0
  48. package/dist/design/interactions/utils/cssUtils.d.ts.map +1 -0
  49. package/dist/design/interactions/utils/sourceUtils.d.ts +36 -0
  50. package/dist/design/interactions/utils/sourceUtils.d.ts.map +1 -0
  51. package/dist/index.d.ts +10 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +25 -0
  54. package/dist/package.json.js +4 -0
  55. package/dist/proxy/handler.d.ts +38 -0
  56. package/dist/proxy/handler.d.ts.map +1 -0
  57. package/dist/proxy/handler.js +530 -0
  58. package/dist/proxy/index.d.ts +8 -0
  59. package/dist/proxy/index.d.ts.map +1 -0
  60. package/dist/proxy/index.js +7 -0
  61. package/dist/proxy/livePreviewScript.d.ts +21 -0
  62. package/dist/proxy/livePreviewScript.d.ts.map +1 -0
  63. package/dist/proxy/livePreviewScript.js +16 -0
  64. package/dist/proxy/routing.d.ts +35 -0
  65. package/dist/proxy/routing.d.ts.map +1 -0
  66. package/dist/proxy/routing.js +83 -0
  67. package/dist/proxy/templates/livePreviewScript.js +553 -0
  68. package/package.json +65 -0
@@ -0,0 +1,761 @@
1
+ /**
2
+ * Design Mode Interactions (Bundled)
3
+ *
4
+ * This file is auto-generated by esbuild from the modular design mode interactions files.
5
+ * Do not edit this file directly - edit the modules in src/design/interactions/
6
+ */
7
+ (function () {
8
+
9
+ "use strict";
10
+ (() => {
11
+ var __defProp = Object.defineProperty;
12
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
14
+
15
+ // src/design/interactions/utils/sourceUtils.ts
16
+ function parseOptionalInt(value) {
17
+ if (value === null || value === void 0 || value === "") {
18
+ return null;
19
+ }
20
+ const parsed = Number.parseInt(String(value), 10);
21
+ return Number.isFinite(parsed) ? parsed : null;
22
+ }
23
+ function parseSourceFileAttribute(value) {
24
+ const match = /^(.*):(\d+):(\d+)$/.exec(value);
25
+ if (!match) {
26
+ return { fileName: value, lineNumber: null, columnNumber: null };
27
+ }
28
+ return {
29
+ fileName: match[1] ?? value,
30
+ lineNumber: parseOptionalInt(match[2]),
31
+ columnNumber: parseOptionalInt(match[3])
32
+ };
33
+ }
34
+ function getSourceFromDataAttributes(element) {
35
+ if (!element) {
36
+ return null;
37
+ }
38
+ const source = element.getAttribute("data-source-file") || null;
39
+ if (!source) {
40
+ return null;
41
+ }
42
+ return parseSourceFileAttribute(source);
43
+ }
44
+ function findElementsBySourceLocation(location) {
45
+ const results = [];
46
+ const elements = document.querySelectorAll("[data-source-file]");
47
+ for (const el of elements) {
48
+ const elSource = getSourceFromDataAttributes(el);
49
+ if (elSource && elSource.fileName === location.fileName && elSource.lineNumber === location.lineNumber && elSource.columnNumber === location.columnNumber) {
50
+ results.push(el);
51
+ }
52
+ }
53
+ return results;
54
+ }
55
+ function parseSourceLocation(sl) {
56
+ if (!sl || typeof sl !== "object") return void 0;
57
+ const obj = sl;
58
+ return {
59
+ fileName: String(obj.sourceFile ?? ""),
60
+ lineNumber: typeof obj.lineNumber === "number" ? obj.lineNumber : null,
61
+ columnNumber: typeof obj.columnNumber === "number" ? obj.columnNumber : null
62
+ };
63
+ }
64
+ function getLabelFromSource(element) {
65
+ if (!element) {
66
+ return "";
67
+ }
68
+ const source = element.getAttribute("data-source-file");
69
+ if (!source) {
70
+ return element.tagName ? element.tagName.toLowerCase() : "";
71
+ }
72
+ const { fileName } = parseSourceFileAttribute(source);
73
+ const parts = fileName.split(/[/\\]/);
74
+ const baseName = parts[parts.length - 1] || fileName;
75
+ console.log("baseName", baseName);
76
+ return baseName;
77
+ }
78
+
79
+ // src/design/interactions/editableManager.ts
80
+ var TEXT_TAGS = ["H1", "H2", "H3", "H4", "H5", "H6", "P", "SPAN", "A", "BUTTON", "LABEL"];
81
+ var EditableManager = class {
82
+ constructor(communicationManager) {
83
+ __publicField(this, "communicationManager");
84
+ __publicField(this, "boundHandleBlur");
85
+ __publicField(this, "boundHandleKeydown");
86
+ __publicField(this, "boundHandleInput");
87
+ __publicField(this, "editableGroup");
88
+ this.communicationManager = communicationManager;
89
+ this.boundHandleBlur = this._handleBlur.bind(this);
90
+ this.boundHandleKeydown = this._handleKeydown.bind(this);
91
+ this.boundHandleInput = this._handleInput.bind(this);
92
+ this.editableGroup = [];
93
+ }
94
+ makeEditableIfText(element) {
95
+ if (!this._isTextElement(element)) {
96
+ return;
97
+ }
98
+ const source = getSourceFromDataAttributes(element);
99
+ const siblings = source ? findElementsBySourceLocation(source) : [];
100
+ const others = siblings.filter((el) => el !== element);
101
+ this.editableGroup = [element, ...others];
102
+ for (const el of this.editableGroup) {
103
+ el.dataset.originalText = el.textContent ?? "";
104
+ }
105
+ element.contentEditable = "true";
106
+ element.addEventListener("blur", this.boundHandleBlur);
107
+ element.addEventListener("keydown", this.boundHandleKeydown);
108
+ element.addEventListener("input", this.boundHandleInput);
109
+ }
110
+ removeEditable(element) {
111
+ if (element.contentEditable === "true") {
112
+ element.contentEditable = "false";
113
+ }
114
+ element.removeEventListener("blur", this.boundHandleBlur);
115
+ element.removeEventListener("keydown", this.boundHandleKeydown);
116
+ element.removeEventListener("input", this.boundHandleInput);
117
+ for (const el of this.editableGroup) {
118
+ delete el.dataset.originalText;
119
+ }
120
+ this.editableGroup = [];
121
+ }
122
+ _isTextElement(element) {
123
+ return TEXT_TAGS.includes(element.tagName) && (element.textContent ?? "").trim().length > 0 && element.dataset.textType === "static";
124
+ }
125
+ _handleInput(e) {
126
+ const primary = e.target;
127
+ const text = primary.textContent ?? "";
128
+ for (let i = 1; i < this.editableGroup.length; i++) {
129
+ this.editableGroup[i].textContent = text;
130
+ }
131
+ }
132
+ _handleBlur(e) {
133
+ const element = e.target;
134
+ const newText = element.textContent ?? "";
135
+ const originalText = element.dataset.originalText ?? "";
136
+ if (newText !== originalText) {
137
+ for (const el of this.editableGroup) {
138
+ el.dataset.originalText = newText;
139
+ }
140
+ if (this.communicationManager) {
141
+ this.communicationManager.notifyTextChange(element, originalText, newText);
142
+ }
143
+ }
144
+ this.removeEditable(element);
145
+ }
146
+ _handleKeydown(e) {
147
+ const element = e.target;
148
+ if (e.key === "Enter" && !e.shiftKey) {
149
+ e.preventDefault();
150
+ element.blur();
151
+ }
152
+ if (e.key === "Escape") {
153
+ for (const el of this.editableGroup) {
154
+ if (el.dataset.originalText) {
155
+ el.textContent = el.dataset.originalText;
156
+ }
157
+ }
158
+ element.blur();
159
+ }
160
+ }
161
+ };
162
+
163
+ // src/design/interactions/utils/cssUtils.ts
164
+ function getElementStyles(element) {
165
+ if (!element) return {};
166
+ const computed = window.getComputedStyle(element);
167
+ const inlineStyle = element.style;
168
+ const prop = (name, fallback) => ({
169
+ inline: inlineStyle[name] || (fallback ? inlineStyle[fallback] : "") || "",
170
+ computed: (fallback ? computed[fallback] : computed[name]) || ""
171
+ });
172
+ const box = (shorthand, top, right, bottom, left) => {
173
+ let inlineValue = inlineStyle[shorthand] || "";
174
+ if (!inlineValue) {
175
+ const iT = inlineStyle[top] || "", iR = inlineStyle[right] || "", iB = inlineStyle[bottom] || "", iL = inlineStyle[left] || "";
176
+ if (iT || iR || iB || iL) {
177
+ inlineValue = `${iT || "0px"} ${iR || "0px"} ${iB || "0px"} ${iL || "0px"}`;
178
+ }
179
+ }
180
+ return {
181
+ inline: inlineValue,
182
+ computed: `${computed[top] || ""} ${computed[right] || ""} ${computed[bottom] || ""} ${computed[left] || ""}`
183
+ };
184
+ };
185
+ return {
186
+ width: prop("width"),
187
+ minWidth: prop("minWidth"),
188
+ maxWidth: prop("maxWidth"),
189
+ height: prop("height"),
190
+ minHeight: prop("minHeight"),
191
+ maxHeight: prop("maxHeight"),
192
+ overflow: prop("overflow"),
193
+ padding: box("padding", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft"),
194
+ margin: box("margin", "marginTop", "marginRight", "marginBottom", "marginLeft"),
195
+ backgroundColor: prop("backgroundColor"),
196
+ borderWidth: box(
197
+ "borderWidth",
198
+ "borderTopWidth",
199
+ "borderRightWidth",
200
+ "borderBottomWidth",
201
+ "borderLeftWidth"
202
+ ),
203
+ borderStyle: prop("borderStyle", "borderTopStyle"),
204
+ borderColor: prop("borderColor", "borderTopColor"),
205
+ borderRadius: box(
206
+ "borderRadius",
207
+ "borderTopLeftRadius",
208
+ "borderTopRightRadius",
209
+ "borderBottomRightRadius",
210
+ "borderBottomLeftRadius"
211
+ ),
212
+ color: prop("color"),
213
+ fontFamily: prop("fontFamily"),
214
+ fontSize: prop("fontSize"),
215
+ fontWeight: prop("fontWeight"),
216
+ fontStyle: prop("fontStyle"),
217
+ lineHeight: prop("lineHeight"),
218
+ letterSpacing: prop("letterSpacing"),
219
+ textAlign: prop("textAlign"),
220
+ textDecoration: prop("textDecoration", "textDecorationLine"),
221
+ textTransform: prop("textTransform")
222
+ };
223
+ }
224
+
225
+ // src/design/interactions/communicationManager.ts
226
+ var CommunicationManager = class {
227
+ constructor() {
228
+ }
229
+ /**
230
+ * Notify the extension about a selected component
231
+ * @param element - The selected element
232
+ */
233
+ notifyComponentSelected(element) {
234
+ const label = getLabelFromSource(element);
235
+ const wasSelected = element.classList.contains("design-mode-selected");
236
+ if (wasSelected) {
237
+ element.classList.remove("design-mode-selected");
238
+ }
239
+ const styles = getElementStyles(element);
240
+ if (wasSelected) {
241
+ element.classList.add("design-mode-selected");
242
+ }
243
+ const debugSource = getSourceFromDataAttributes(element);
244
+ const textType = element.dataset?.textType ?? "none";
245
+ const hasNonEditableText = TEXT_TAGS.includes(element.tagName) && (textType === "dynamic" || textType === "mixed");
246
+ try {
247
+ if (window.parent !== window) {
248
+ window.parent.postMessage(
249
+ {
250
+ type: "component-selected",
251
+ component: {
252
+ name: label,
253
+ tagName: element.tagName,
254
+ styles: {
255
+ ...styles
256
+ },
257
+ debugSource,
258
+ hasNonEditableText
259
+ }
260
+ },
261
+ "*"
262
+ );
263
+ }
264
+ } catch (error) {
265
+ console.log("Could not notify extension:", error);
266
+ }
267
+ window.selectedComponentInfo = {
268
+ name: label,
269
+ element,
270
+ tagName: element.tagName
271
+ };
272
+ }
273
+ /**
274
+ * Notify the extension about a text change
275
+ * @param element - The element that changed
276
+ * @param originalText - The original text
277
+ * @param newText - The new text
278
+ */
279
+ notifyTextChange(element, originalText, newText) {
280
+ const label = getLabelFromSource(element);
281
+ const debugSource = getSourceFromDataAttributes(element);
282
+ try {
283
+ if (window.parent !== window) {
284
+ window.parent.postMessage(
285
+ {
286
+ type: "text-changed",
287
+ change: {
288
+ componentName: label,
289
+ tagName: element.tagName,
290
+ originalText,
291
+ newText,
292
+ debugSource
293
+ }
294
+ },
295
+ "*"
296
+ );
297
+ }
298
+ } catch (error) {
299
+ console.log("Could not notify extension about text change:", error);
300
+ }
301
+ }
302
+ /**
303
+ * Notify the parent window that interactions initialization is complete
304
+ */
305
+ notifyInitializationComplete() {
306
+ try {
307
+ if (typeof window !== "undefined" && window.parent && window.parent !== window) {
308
+ window.parent.postMessage(
309
+ {
310
+ type: "interactions-initialized"
311
+ },
312
+ "*"
313
+ );
314
+ }
315
+ } catch (error) {
316
+ const err = error;
317
+ console.warn("Could not send initialization message to parent:", err.message);
318
+ }
319
+ }
320
+ };
321
+
322
+ // src/design/interactions/componentMatcher.ts
323
+ var ComponentMatcher = class {
324
+ constructor(options = {}) {
325
+ __publicField(this, "allowlist");
326
+ this.allowlist = options.allowlist ?? [];
327
+ }
328
+ /**
329
+ * Check whether an element contains compile-time source metadata attributes.
330
+ * @param element - The element to check
331
+ * @returns True if the data-source-file attribute is present
332
+ */
333
+ hasSourceMetadata(element) {
334
+ if (!element) {
335
+ return false;
336
+ }
337
+ return element.hasAttribute("data-source-file");
338
+ }
339
+ matchesList(element, selectors) {
340
+ return selectors.some((selector) => element.matches(selector));
341
+ }
342
+ /**
343
+ * Checks if a label represents a component name (not a fallback like tag name, ID, or text content)
344
+ * @param label - The label to check
345
+ * @param tagName - The element's tag name (lowercase)
346
+ * @returns True if the label is a component name
347
+ */
348
+ isComponentNameLabel(label, tagName) {
349
+ return label !== tagName && !label.includes("#") && !label.includes("(") && !label.includes('"');
350
+ }
351
+ /**
352
+ * Check if an element is highlightable.
353
+ * @param element - The element to check
354
+ * @returns True if the element should be highlighted
355
+ */
356
+ isHighlightableElement(element) {
357
+ if (!element || element === document.body || element === document.documentElement) {
358
+ return false;
359
+ }
360
+ if (!this.hasSourceMetadata(element)) {
361
+ return false;
362
+ }
363
+ if (this.allowlist.length > 0) {
364
+ return this.matchesList(element, this.allowlist);
365
+ }
366
+ return true;
367
+ }
368
+ /**
369
+ * Find the nearest highlightable element by walking up the DOM tree
370
+ * @param target - The target element
371
+ * @returns The highlightable element or null
372
+ */
373
+ findHighlightableElement(target) {
374
+ if (!target || target === document.body || target === document.documentElement) {
375
+ return null;
376
+ }
377
+ const closest = typeof target.closest === "function" ? target.closest("[data-source-file]") : null;
378
+ if (closest && closest !== document.body && closest !== document.documentElement && this.isHighlightableElement(closest)) {
379
+ return closest;
380
+ }
381
+ let current = target;
382
+ while (current && current !== document.body && current !== document.documentElement) {
383
+ if (this.isHighlightableElement(current)) {
384
+ return current;
385
+ }
386
+ current = current.parentElement;
387
+ }
388
+ return null;
389
+ }
390
+ };
391
+
392
+ // src/design/interactions/eventHandlers.ts
393
+ var EventHandlers = class {
394
+ constructor(isInteractionsActive, componentMatcher, styleManager, editableManager, communicationManager) {
395
+ __publicField(this, "isInteractionsActive");
396
+ __publicField(this, "componentMatcher");
397
+ __publicField(this, "styleManager");
398
+ __publicField(this, "editableManager");
399
+ __publicField(this, "communicationManager");
400
+ __publicField(this, "currentHighlightedElements");
401
+ __publicField(this, "selectedElement");
402
+ __publicField(this, "selectedElements");
403
+ this.isInteractionsActive = isInteractionsActive;
404
+ this.componentMatcher = componentMatcher;
405
+ this.styleManager = styleManager;
406
+ this.editableManager = editableManager;
407
+ this.communicationManager = communicationManager;
408
+ this.currentHighlightedElements = [];
409
+ this.selectedElement = null;
410
+ this.selectedElements = [];
411
+ this.handleMouseOver = this.handleMouseOver.bind(this);
412
+ this.handleMouseLeave = this.handleMouseLeave.bind(this);
413
+ this.handleClick = this.handleClick.bind(this);
414
+ }
415
+ _findHighlightableElement(target) {
416
+ return this.componentMatcher.findHighlightableElement(target);
417
+ }
418
+ handleMouseOver(e) {
419
+ if (!this.isInteractionsActive()) {
420
+ return;
421
+ }
422
+ e.stopPropagation();
423
+ const target = e.target;
424
+ if (target.nodeType !== 1 || target.tagName === "HTML" || target.tagName === "BODY") {
425
+ return;
426
+ }
427
+ const element = this._findHighlightableElement(target);
428
+ if (!element) {
429
+ return;
430
+ }
431
+ if (this.currentHighlightedElements.includes(element) || this.selectedElement && this.selectedElement === element) {
432
+ return;
433
+ }
434
+ if (this.currentHighlightedElements.length > 0 && !this.currentHighlightedElements[0].classList.contains("design-mode-selected")) {
435
+ this.styleManager.unhighlightElements(this.currentHighlightedElements);
436
+ this.currentHighlightedElements = [];
437
+ }
438
+ const allElements = findElementsBySourceLocation(getSourceFromDataAttributes(element));
439
+ this.styleManager.highlightElements(allElements);
440
+ this.currentHighlightedElements = allElements;
441
+ }
442
+ handleMouseLeave() {
443
+ if (!this.isInteractionsActive()) {
444
+ return;
445
+ }
446
+ if (this.currentHighlightedElements.length > 0 && !this.currentHighlightedElements[0].classList.contains("design-mode-selected")) {
447
+ this.styleManager.unhighlightElements(this.currentHighlightedElements);
448
+ this.currentHighlightedElements = [];
449
+ }
450
+ }
451
+ handleClick(e) {
452
+ if (!this.isInteractionsActive()) {
453
+ return;
454
+ }
455
+ e.preventDefault();
456
+ e.stopPropagation();
457
+ const target = e.target;
458
+ if (target.nodeType !== 1 || target.tagName === "HTML" || target.tagName === "BODY") {
459
+ return;
460
+ }
461
+ const element = this._findHighlightableElement(target);
462
+ if (!element) {
463
+ return;
464
+ }
465
+ if (this.selectedElement && this.selectedElement === element) {
466
+ return;
467
+ }
468
+ if (this.selectedElement) {
469
+ this.styleManager.deselectElements(this.selectedElements);
470
+ this.editableManager.removeEditable(this.selectedElement);
471
+ }
472
+ if (this.currentHighlightedElements.length > 0) {
473
+ this.styleManager.unhighlightElements(this.currentHighlightedElements);
474
+ this.currentHighlightedElements = [];
475
+ }
476
+ this.selectedElement = element;
477
+ const allElements = findElementsBySourceLocation(getSourceFromDataAttributes(element));
478
+ this.selectedElements = allElements;
479
+ this.styleManager.selectElements(allElements);
480
+ this.editableManager.makeEditableIfText(element);
481
+ this.communicationManager.notifyComponentSelected(element);
482
+ }
483
+ clearAll() {
484
+ if (this.currentHighlightedElements.length > 0) {
485
+ this.styleManager.unhighlightElements(this.currentHighlightedElements);
486
+ this.currentHighlightedElements = [];
487
+ }
488
+ if (this.selectedElement) {
489
+ this.styleManager.deselectElements(this.selectedElements);
490
+ this.editableManager.removeEditable(this.selectedElement);
491
+ this.selectedElement = null;
492
+ this.selectedElements = [];
493
+ }
494
+ }
495
+ getSelectedElement() {
496
+ return this.selectedElement;
497
+ }
498
+ };
499
+
500
+ // src/design/interactions/styleManager.ts
501
+ var StyleManager = class {
502
+ constructor() {
503
+ __publicField(this, "styleId");
504
+ __publicField(this, "stylesAdded");
505
+ this.styleId = "design-mode-styles";
506
+ this.stylesAdded = false;
507
+ }
508
+ /**
509
+ * Add CSS styles for highlighting to the document
510
+ */
511
+ addHighlightStyles() {
512
+ if (this.stylesAdded) {
513
+ return;
514
+ }
515
+ const style = document.createElement("style");
516
+ style.id = this.styleId;
517
+ style.textContent = this._getStyles();
518
+ document.head.appendChild(style);
519
+ this.stylesAdded = true;
520
+ }
521
+ /**
522
+ * Remove highlight styles from the document
523
+ */
524
+ removeHighlightStyles() {
525
+ const style = document.getElementById(this.styleId);
526
+ if (style) {
527
+ style.remove();
528
+ this.stylesAdded = false;
529
+ }
530
+ }
531
+ /**
532
+ * Get the CSS styles for highlighting
533
+ * @private
534
+ * @returns CSS styles
535
+ */
536
+ _getStyles() {
537
+ return `
538
+ .design-mode-highlight {
539
+ outline: 4px dashed #007acc !important;
540
+ outline-offset: -4px !important;
541
+ transition: all 0.2s ease !important;
542
+ position: relative !important;
543
+ cursor: pointer !important;
544
+ }
545
+ .design-mode-selected {
546
+ outline: 5px dashed #ff6b35 !important;
547
+ outline-offset: -5px !important;
548
+ position: relative !important;
549
+ }
550
+ `;
551
+ }
552
+ /**
553
+ * Apply highlight class to one or more elements
554
+ * @param elements - The elements to highlight
555
+ */
556
+ highlightElements(elements) {
557
+ for (const el of elements) {
558
+ el.classList.add("design-mode-highlight");
559
+ }
560
+ }
561
+ /**
562
+ * Remove highlight class from one or more elements
563
+ * @param elements - The elements to unhighlight
564
+ */
565
+ unhighlightElements(elements) {
566
+ for (const el of elements) {
567
+ el.classList.remove("design-mode-highlight");
568
+ }
569
+ }
570
+ /**
571
+ * Apply selected class to one or more elements
572
+ * @param elements - The elements to select
573
+ */
574
+ selectElements(elements) {
575
+ for (const el of elements) {
576
+ el.classList.add("design-mode-selected");
577
+ }
578
+ }
579
+ /**
580
+ * Remove selected class from one or more elements
581
+ * @param elements - The elements to deselect
582
+ */
583
+ deselectElements(elements) {
584
+ for (const el of elements) {
585
+ el.classList.remove("design-mode-selected");
586
+ }
587
+ }
588
+ };
589
+
590
+ // src/design/interactions/interactionsController.ts
591
+ var InteractionsController = class {
592
+ constructor(enabled = true) {
593
+ __publicField(this, "enabled");
594
+ __publicField(this, "isActive");
595
+ __publicField(this, "componentMatcher");
596
+ __publicField(this, "styleManager");
597
+ __publicField(this, "communicationManager");
598
+ __publicField(this, "editableManager");
599
+ __publicField(this, "eventHandlers");
600
+ this.enabled = enabled;
601
+ this.isActive = false;
602
+ this.componentMatcher = new ComponentMatcher({
603
+ allowlist: [
604
+ "div",
605
+ "p",
606
+ "span",
607
+ "h1",
608
+ "h2",
609
+ "h3",
610
+ "h4",
611
+ "h5",
612
+ "h6",
613
+ "a",
614
+ "button",
615
+ "input",
616
+ "select",
617
+ "textarea",
618
+ "label",
619
+ "section",
620
+ "article",
621
+ "main",
622
+ "aside",
623
+ "header",
624
+ "footer",
625
+ "nav",
626
+ "figure",
627
+ "figcaption",
628
+ "ul",
629
+ "ol",
630
+ "li",
631
+ "table",
632
+ "tr",
633
+ "td",
634
+ "th",
635
+ "blockquote",
636
+ "img"
637
+ ]
638
+ });
639
+ this.styleManager = new StyleManager();
640
+ this.communicationManager = new CommunicationManager();
641
+ this.editableManager = new EditableManager(this.communicationManager);
642
+ this.eventHandlers = new EventHandlers(
643
+ () => this.isActive,
644
+ this.componentMatcher,
645
+ this.styleManager,
646
+ this.editableManager,
647
+ this.communicationManager
648
+ );
649
+ }
650
+ /**
651
+ * Initialize the design mode interactions
652
+ */
653
+ initialize() {
654
+ if (!this.enabled) {
655
+ console.log("Design Mode Interactions disabled");
656
+ return;
657
+ }
658
+ console.log("Initializing Design Mode Interactions...");
659
+ this.styleManager.addHighlightStyles();
660
+ document.addEventListener("mouseover", this.eventHandlers.handleMouseOver);
661
+ document.addEventListener("mouseleave", this.eventHandlers.handleMouseLeave);
662
+ document.addEventListener("click", this.eventHandlers.handleClick, true);
663
+ console.log("Design Mode Interactions initialized!");
664
+ this.communicationManager.notifyInitializationComplete();
665
+ }
666
+ /**
667
+ * Enable the design mode interactions
668
+ */
669
+ enable() {
670
+ this.isActive = true;
671
+ console.log("Design Mode Interactions enabled");
672
+ }
673
+ /**
674
+ * Disable the design mode interactions
675
+ */
676
+ disable() {
677
+ this.isActive = false;
678
+ this.eventHandlers.clearAll();
679
+ console.log("Design Mode Interactions disabled");
680
+ }
681
+ resolveTargets(sourceLocation) {
682
+ let location = sourceLocation ?? null;
683
+ if (!location?.fileName) {
684
+ const selectedElement = this.eventHandlers.getSelectedElement();
685
+ location = getSourceFromDataAttributes(selectedElement);
686
+ }
687
+ return location ? findElementsBySourceLocation(location) : [];
688
+ }
689
+ /**
690
+ * Apply a style change to all elements at the given source location.
691
+ * When sourceLocation is provided (undo/redo), it is used directly.
692
+ * Otherwise the source location is read from the currently selected element.
693
+ */
694
+ applyStyleChange(property, value, sourceLocation) {
695
+ for (const el of this.resolveTargets(sourceLocation)) {
696
+ el.style[property] = value;
697
+ }
698
+ }
699
+ applyTextChange(text, sourceLocation) {
700
+ for (const el of this.resolveTargets(sourceLocation)) {
701
+ el.textContent = text;
702
+ }
703
+ }
704
+ /**
705
+ * Cleanup and remove event listeners
706
+ */
707
+ destroy() {
708
+ document.removeEventListener("mouseover", this.eventHandlers.handleMouseOver);
709
+ document.removeEventListener("mouseleave", this.eventHandlers.handleMouseLeave);
710
+ document.removeEventListener("click", this.eventHandlers.handleClick, true);
711
+ this.styleManager.removeHighlightStyles();
712
+ this.eventHandlers.clearAll();
713
+ }
714
+ };
715
+
716
+ // src/design/interactions/index.ts
717
+ var interactions = new InteractionsController(true);
718
+ if (typeof document !== "undefined") {
719
+ if (document.readyState === "loading") {
720
+ document.addEventListener("DOMContentLoaded", () => {
721
+ interactions.initialize();
722
+ });
723
+ } else {
724
+ interactions.initialize();
725
+ }
726
+ }
727
+ if (typeof window !== "undefined") {
728
+ window.enableInteractions = function() {
729
+ interactions.enable();
730
+ };
731
+ window.disableInteractions = function() {
732
+ interactions.disable();
733
+ };
734
+ window.addEventListener("message", function(event) {
735
+ const data = event.data;
736
+ const typed = data && typeof data === "object" ? data : null;
737
+ if (typed && typed.type === "style-change") {
738
+ interactions.applyStyleChange(
739
+ String(typed.property ?? ""),
740
+ String(typed.value ?? ""),
741
+ parseSourceLocation(typed.sourceLocation)
742
+ );
743
+ }
744
+ if (typed && typed.type === "text-change") {
745
+ interactions.applyTextChange(
746
+ String(typed.text ?? ""),
747
+ parseSourceLocation(typed.sourceLocation)
748
+ );
749
+ }
750
+ if (typed && typed.type === "enable-interactions") {
751
+ window.enableInteractions?.();
752
+ }
753
+ if (typed && typed.type === "disable-interactions") {
754
+ window.disableInteractions?.();
755
+ }
756
+ });
757
+ }
758
+ })();
759
+
760
+ })();
761
+