@strapi/content-manager 5.23.1 → 5.23.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.
@@ -12,6 +12,7 @@
12
12
  * ---------------------------------------------------------------------------------------------*/ const HIGHLIGHT_PADDING = 2; // in pixels
13
13
  const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500
14
14
  const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600
15
+ const DISABLE_STEGA_DECODING = window.STRAPI_DISABLE_STEGA_DECODING ?? false;
15
16
  const SOURCE_ATTRIBUTE = 'data-strapi-source';
16
17
  const OVERLAY_ID = 'strapi-preview-overlay';
17
18
  const INTERNAL_EVENTS = {
@@ -39,7 +40,67 @@
39
40
  };
40
41
  /* -----------------------------------------------------------------------------------------------
41
42
  * Functionality pieces
42
- * ---------------------------------------------------------------------------------------------*/ const createOverlaySystem = ()=>{
43
+ * ---------------------------------------------------------------------------------------------*/ const setupStegaDOMObserver = async ()=>{
44
+ if (DISABLE_STEGA_DECODING) {
45
+ return;
46
+ }
47
+ const { vercelStegaDecode: stegaDecode, vercelStegaClean: stegaClean } = await import(// @ts-expect-error it's not a local dependency
48
+ // eslint-disable-next-line import/no-unresolved
49
+ 'https://cdn.jsdelivr.net/npm/@vercel/stega@0.1.2/+esm');
50
+ const applyStegaToElement = (element)=>{
51
+ const directTextNodes = Array.from(element.childNodes).filter((node)=>node.nodeType === Node.TEXT_NODE);
52
+ const directTextContent = directTextNodes.map((node)=>node.textContent || '').join('');
53
+ if (directTextContent) {
54
+ try {
55
+ const result = stegaDecode(directTextContent);
56
+ if (result) {
57
+ element.setAttribute(SOURCE_ATTRIBUTE, result.key);
58
+ // Remove encoded part from DOM text content (to avoid breaking links for example)
59
+ directTextNodes.forEach((node)=>{
60
+ if (node.textContent) {
61
+ const cleanedText = stegaClean(node.textContent);
62
+ if (cleanedText !== node.textContent) {
63
+ node.textContent = cleanedText;
64
+ }
65
+ }
66
+ });
67
+ }
68
+ } catch (error) {}
69
+ }
70
+ };
71
+ // Process all existing elements
72
+ const allElements = document.querySelectorAll('*');
73
+ Array.from(allElements).forEach(applyStegaToElement);
74
+ // Create observer for new elements and text changes
75
+ const observer = new MutationObserver((mutations)=>{
76
+ mutations.forEach((mutation)=>{
77
+ // Handle added nodes
78
+ if (mutation.type === 'childList') {
79
+ mutation.addedNodes.forEach((node)=>{
80
+ if (node.nodeType === Node.ELEMENT_NODE) {
81
+ const element = node;
82
+ // Process the added element
83
+ applyStegaToElement(element);
84
+ // Process all child elements
85
+ const childElements = element.querySelectorAll('*');
86
+ Array.from(childElements).forEach(applyStegaToElement);
87
+ }
88
+ });
89
+ }
90
+ // Handle text content changes
91
+ if (mutation.type === 'characterData' && mutation.target.parentElement) {
92
+ applyStegaToElement(mutation.target.parentElement);
93
+ }
94
+ });
95
+ });
96
+ observer.observe(document, {
97
+ childList: true,
98
+ subtree: true,
99
+ characterData: true
100
+ });
101
+ return observer;
102
+ };
103
+ const createOverlaySystem = ()=>{
43
104
  // Clean up before creating a new overlay so we can safely call previewScript multiple times
44
105
  window.__strapi_previewCleanup?.();
45
106
  document.getElementById(OVERLAY_ID)?.remove();
@@ -58,9 +119,8 @@
58
119
  return overlay;
59
120
  };
60
121
  const createHighlightManager = (overlay)=>{
61
- const elements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
122
+ const elementsToHighlight = new Map();
62
123
  const eventListeners = [];
63
- const highlights = [];
64
124
  const focusedHighlights = [];
65
125
  let focusedField = null;
66
126
  const drawHighlight = (target, highlight)=>{
@@ -71,112 +131,134 @@
71
131
  highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;
72
132
  };
73
133
  const updateAllHighlights = ()=>{
74
- highlights.forEach((highlight, index)=>{
75
- const element = elements[index];
76
- if (element && highlight) {
77
- drawHighlight(element, highlight);
134
+ elementsToHighlight.forEach((highlight, element)=>{
135
+ drawHighlight(element, highlight);
136
+ });
137
+ };
138
+ const createHighlightForElement = (element)=>{
139
+ if (elementsToHighlight.has(element)) {
140
+ // Already has a highlight
141
+ return;
142
+ }
143
+ const highlight = document.createElement('div');
144
+ highlight.style.cssText = `
145
+ position: absolute;
146
+ outline: 2px solid transparent;
147
+ pointer-events: none;
148
+ border-radius: 2px;
149
+ background-color: transparent;
150
+ will-change: transform;
151
+ transition: outline-color 0.1s ease-in-out;
152
+ `;
153
+ // Move hover detection to the underlying element
154
+ const mouseEnterHandler = ()=>{
155
+ if (!focusedHighlights.includes(highlight)) {
156
+ highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;
157
+ }
158
+ };
159
+ const mouseLeaveHandler = ()=>{
160
+ if (!focusedHighlights.includes(highlight)) {
161
+ highlight.style.outlineColor = 'transparent';
162
+ }
163
+ };
164
+ const doubleClickHandler = ()=>{
165
+ const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);
166
+ if (sourceAttribute) {
167
+ const rect = element.getBoundingClientRect();
168
+ sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {
169
+ path: sourceAttribute,
170
+ position: {
171
+ top: rect.top,
172
+ left: rect.left,
173
+ right: rect.right,
174
+ bottom: rect.bottom,
175
+ width: rect.width,
176
+ height: rect.height
177
+ }
178
+ });
179
+ }
180
+ };
181
+ const mouseDownHandler = (event)=>{
182
+ // Prevent default multi click to select behavior
183
+ if (event.detail >= 2) {
184
+ event.preventDefault();
78
185
  }
186
+ };
187
+ element.addEventListener('mouseenter', mouseEnterHandler);
188
+ element.addEventListener('mouseleave', mouseLeaveHandler);
189
+ element.addEventListener('dblclick', doubleClickHandler);
190
+ element.addEventListener('mousedown', mouseDownHandler);
191
+ // Store event listeners for cleanup
192
+ eventListeners.push({
193
+ element,
194
+ type: 'mouseenter',
195
+ handler: mouseEnterHandler
196
+ }, {
197
+ element,
198
+ type: 'mouseleave',
199
+ handler: mouseLeaveHandler
200
+ }, {
201
+ element,
202
+ type: 'dblclick',
203
+ handler: doubleClickHandler
204
+ }, {
205
+ element,
206
+ type: 'mousedown',
207
+ handler: mouseDownHandler
79
208
  });
209
+ elementsToHighlight.set(element, highlight);
210
+ overlay.appendChild(highlight);
211
+ drawHighlight(element, highlight);
80
212
  };
81
- elements.forEach((element)=>{
213
+ const removeHighlightForElement = (element)=>{
214
+ const highlight = elementsToHighlight.get(element);
215
+ if (!highlight) return;
216
+ highlight.remove();
217
+ elementsToHighlight.delete(element);
218
+ // Remove event listeners for this element
219
+ const listenersToRemove = eventListeners.filter((listener)=>listener.element === element);
220
+ listenersToRemove.forEach(({ element, type, handler })=>{
221
+ element.removeEventListener(type, handler);
222
+ });
223
+ // Mutate eventListeners to remove listeners for this element
224
+ eventListeners.splice(0, eventListeners.length, ...eventListeners.filter((listener)=>listener.element !== element));
225
+ };
226
+ // Process all existing elements with source attributes
227
+ const initialElements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
228
+ Array.from(initialElements).forEach((element)=>{
82
229
  if (element instanceof HTMLElement) {
83
- const highlight = document.createElement('div');
84
- highlight.style.cssText = `
85
- position: absolute;
86
- outline: 2px solid transparent;
87
- pointer-events: none;
88
- border-radius: 2px;
89
- background-color: transparent;
90
- will-change: transform;
91
- transition: outline-color 0.1s ease-in-out;
92
- `;
93
- // Move hover detection to the underlying element
94
- const mouseEnterHandler = ()=>{
95
- if (!highlightManager.focusedHighlights.includes(highlight)) {
96
- highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;
97
- }
98
- };
99
- const mouseLeaveHandler = ()=>{
100
- if (!highlightManager.focusedHighlights.includes(highlight)) {
101
- highlight.style.outlineColor = 'transparent';
102
- }
103
- };
104
- const doubleClickHandler = ()=>{
105
- const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);
106
- if (sourceAttribute) {
107
- const rect = element.getBoundingClientRect();
108
- sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {
109
- path: sourceAttribute,
110
- position: {
111
- top: rect.top,
112
- left: rect.left,
113
- right: rect.right,
114
- bottom: rect.bottom,
115
- width: rect.width,
116
- height: rect.height
117
- }
118
- });
119
- }
120
- };
121
- const mouseDownHandler = (event)=>{
122
- // Prevent default multi click to select behavior
123
- if (event.detail >= 2) {
124
- event.preventDefault();
125
- }
126
- };
127
- element.addEventListener('mouseenter', mouseEnterHandler);
128
- element.addEventListener('mouseleave', mouseLeaveHandler);
129
- element.addEventListener('dblclick', doubleClickHandler);
130
- element.addEventListener('mousedown', mouseDownHandler);
131
- // Store event listeners for cleanup
132
- eventListeners.push({
133
- element,
134
- type: 'mouseenter',
135
- handler: mouseEnterHandler
136
- }, {
137
- element,
138
- type: 'mouseleave',
139
- handler: mouseLeaveHandler
140
- }, {
141
- element,
142
- type: 'dblclick',
143
- handler: doubleClickHandler
144
- }, {
145
- element,
146
- type: 'mousedown',
147
- handler: mouseDownHandler
148
- });
149
- highlights.push(highlight);
150
- overlay.appendChild(highlight);
151
- drawHighlight(element, highlight);
230
+ createHighlightForElement(element);
152
231
  }
153
232
  });
154
233
  return {
155
- elements,
234
+ get elements () {
235
+ return Array.from(elementsToHighlight.keys());
236
+ },
237
+ get highlights () {
238
+ return Array.from(elementsToHighlight.values());
239
+ },
156
240
  updateAllHighlights,
157
241
  eventListeners,
158
- highlights,
159
242
  focusedHighlights,
243
+ createHighlightForElement,
244
+ removeHighlightForElement,
160
245
  setFocusedField: (field)=>{
161
246
  focusedField = field;
162
247
  },
163
248
  getFocusedField: ()=>focusedField
164
249
  };
165
250
  };
166
- const setupObservers = (highlightManager)=>{
167
- const resizeObserver = new ResizeObserver(()=>{
168
- highlightManager.updateAllHighlights();
169
- });
170
- highlightManager.elements.forEach((element)=>{
171
- resizeObserver.observe(element);
172
- });
173
- resizeObserver.observe(document.documentElement);
251
+ /**
252
+ * We need to track scroll in all the element parents in order to keep the highlight position
253
+ * in sync with the element position. Listening to window scroll is not enough because the
254
+ * element can be inside one or more scrollable containers.
255
+ */ const setupScrollManagement = (highlightManager)=>{
174
256
  const updateOnScroll = ()=>{
175
257
  highlightManager.updateAllHighlights();
176
258
  };
177
259
  const scrollableElements = new Set();
178
260
  scrollableElements.add(window);
179
- // Find all scrollable ancestors for all tracked elements
261
+ // Find all scrollable ancestors for all tracked elements and set up scroll listeners
180
262
  highlightManager.elements.forEach((element)=>{
181
263
  let parent = element.parentElement;
182
264
  while(parent){
@@ -197,10 +279,82 @@
197
279
  element.addEventListener('scroll', updateOnScroll);
198
280
  }
199
281
  });
282
+ const cleanup = ()=>{
283
+ scrollableElements.forEach((element)=>{
284
+ if (element === window) {
285
+ window.removeEventListener('scroll', updateOnScroll);
286
+ window.removeEventListener('resize', updateOnScroll);
287
+ } else {
288
+ element.removeEventListener('scroll', updateOnScroll);
289
+ }
290
+ });
291
+ };
292
+ return {
293
+ cleanup
294
+ };
295
+ };
296
+ const setupObservers = (highlightManager, stegaObserver)=>{
297
+ const resizeObserver = new ResizeObserver(()=>{
298
+ highlightManager.updateAllHighlights();
299
+ });
300
+ const observeElementForResize = (element)=>{
301
+ resizeObserver.observe(element);
302
+ };
303
+ // Observe existing elements
304
+ highlightManager.elements.forEach(observeElementForResize);
305
+ resizeObserver.observe(document.documentElement);
306
+ // Create highlight observer to watch for new elements with source attributes
307
+ const highlightObserver = new MutationObserver((mutations)=>{
308
+ mutations.forEach((mutation)=>{
309
+ if (mutation.type === 'attributes' && mutation.attributeName === SOURCE_ATTRIBUTE) {
310
+ const target = mutation.target;
311
+ if (target.hasAttribute(SOURCE_ATTRIBUTE)) {
312
+ highlightManager.createHighlightForElement(target);
313
+ observeElementForResize(target);
314
+ } else {
315
+ highlightManager.removeHighlightForElement(target);
316
+ }
317
+ }
318
+ if (mutation.type === 'childList') {
319
+ mutation.addedNodes.forEach((node)=>{
320
+ if (node.nodeType === Node.ELEMENT_NODE) {
321
+ const element = node;
322
+ // Check if the added element has source attribute
323
+ if (element.hasAttribute(SOURCE_ATTRIBUTE) && element instanceof HTMLElement) {
324
+ highlightManager.createHighlightForElement(element);
325
+ observeElementForResize(element);
326
+ }
327
+ // Check all child elements for source attributes
328
+ const elementsWithSource = element.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
329
+ Array.from(elementsWithSource).forEach((childElement)=>{
330
+ if (childElement instanceof HTMLElement) {
331
+ highlightManager.createHighlightForElement(childElement);
332
+ observeElementForResize(childElement);
333
+ }
334
+ });
335
+ }
336
+ });
337
+ mutation.removedNodes.forEach((node)=>{
338
+ if (node.nodeType === Node.ELEMENT_NODE) {
339
+ const element = node;
340
+ highlightManager.removeHighlightForElement(element);
341
+ }
342
+ });
343
+ }
344
+ });
345
+ });
346
+ highlightObserver.observe(document, {
347
+ childList: true,
348
+ subtree: true,
349
+ attributes: true,
350
+ attributeFilter: [
351
+ SOURCE_ATTRIBUTE
352
+ ]
353
+ });
200
354
  return {
201
355
  resizeObserver,
202
- updateOnScroll,
203
- scrollableElements
356
+ highlightObserver,
357
+ stegaObserver
204
358
  };
205
359
  };
206
360
  const setupEventHandlers = (highlightManager)=>{
@@ -216,6 +370,8 @@
216
370
  element.textContent = value || '';
217
371
  }
218
372
  });
373
+ // Update highlight dimensions since the new text content may affect them
374
+ highlightManager.updateAllHighlights();
219
375
  return;
220
376
  }
221
377
  // The user focused a new input, update the highlights in the preview
@@ -264,18 +420,13 @@
264
420
  messageEventListener
265
421
  ];
266
422
  };
267
- const createCleanupSystem = (overlay, observers, eventHandlers)=>{
423
+ const createCleanupSystem = (overlay, observers, scrollManager, eventHandlers)=>{
268
424
  window.__strapi_previewCleanup = ()=>{
269
425
  observers.resizeObserver.disconnect();
270
- // Remove all scroll listeners
271
- observers.scrollableElements.forEach((element)=>{
272
- if (element === window) {
273
- window.removeEventListener('scroll', observers.updateOnScroll);
274
- window.removeEventListener('resize', observers.updateOnScroll);
275
- } else {
276
- element.removeEventListener('scroll', observers.updateOnScroll);
277
- }
278
- });
426
+ observers.highlightObserver.disconnect();
427
+ observers.stegaObserver?.disconnect();
428
+ // Clean up scroll listeners
429
+ scrollManager.cleanup();
279
430
  // Remove highlight event listeners
280
431
  eventHandlers.forEach(({ element, type, handler })=>{
281
432
  element.removeEventListener(type, handler);
@@ -285,11 +436,14 @@
285
436
  };
286
437
  /* -----------------------------------------------------------------------------------------------
287
438
  * Orchestration
288
- * ---------------------------------------------------------------------------------------------*/ const overlay = createOverlaySystem();
289
- const highlightManager = createHighlightManager(overlay);
290
- const observers = setupObservers(highlightManager);
291
- const eventHandlers = setupEventHandlers(highlightManager);
292
- createCleanupSystem(overlay, observers, eventHandlers);
439
+ * ---------------------------------------------------------------------------------------------*/ setupStegaDOMObserver().then((stegaObserver)=>{
440
+ const overlay = createOverlaySystem();
441
+ const highlightManager = createHighlightManager(overlay);
442
+ const observers = setupObservers(highlightManager, stegaObserver);
443
+ const scrollManager = setupScrollManagement(highlightManager);
444
+ const eventHandlers = setupEventHandlers(highlightManager);
445
+ createCleanupSystem(overlay, observers, scrollManager, eventHandlers);
446
+ });
293
447
  };
294
448
 
295
449
  exports.previewScript = previewScript;
@@ -1 +1 @@
1
- {"version":3,"file":"previewScript.js","sources":["../../../../admin/src/preview/utils/previewScript.ts"],"sourcesContent":["// NOTE: This override is for the properties on _user's site_, it's not about Strapi Admin.\ndeclare global {\n interface Window {\n __strapi_previewCleanup?: () => void;\n STRAPI_HIGHLIGHT_HOVER_COLOR?: string;\n STRAPI_HIGHLIGHT_ACTIVE_COLOR?: string;\n }\n}\n\n/**\n * previewScript will be injected into the preview iframe after being stringified.\n * Therefore it CANNOT use any imports, or refer to any variables outside of its own scope.\n * It's why many functions are defined within previewScript, it's the only way to avoid going full spaghetti.\n * To get a better overview of everything previewScript does, go to the orchestration part at its end.\n */\nconst previewScript = (shouldRun = true) => {\n /* -----------------------------------------------------------------------------------------------\n * Params\n * ---------------------------------------------------------------------------------------------*/\n const HIGHLIGHT_PADDING = 2; // in pixels\n const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500\n const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600\n\n const SOURCE_ATTRIBUTE = 'data-strapi-source';\n const OVERLAY_ID = 'strapi-preview-overlay';\n const INTERNAL_EVENTS = {\n STRAPI_FIELD_FOCUS: 'strapiFieldFocus',\n STRAPI_FIELD_BLUR: 'strapiFieldBlur',\n STRAPI_FIELD_CHANGE: 'strapiFieldChange',\n STRAPI_FIELD_FOCUS_INTENT: 'strapiFieldFocusIntent',\n } as const;\n\n /**\n * Calling the function in no-run mode lets us retrieve the constants from other files and keep\n * a single source of truth for them. It's the only way to do this because this script can't\n * refer to any variables outside of its own scope, because it's stringified before it's run.\n */\n if (!shouldRun) {\n return { INTERNAL_EVENTS };\n }\n\n /* -----------------------------------------------------------------------------------------------\n * Utils\n * ---------------------------------------------------------------------------------------------*/\n\n const sendMessage = (\n type: (typeof INTERNAL_EVENTS)[keyof typeof INTERNAL_EVENTS],\n payload: unknown\n ) => {\n window.parent.postMessage({ type, payload }, '*');\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Functionality pieces\n * ---------------------------------------------------------------------------------------------*/\n\n const createOverlaySystem = () => {\n // Clean up before creating a new overlay so we can safely call previewScript multiple times\n window.__strapi_previewCleanup?.();\n document.getElementById(OVERLAY_ID)?.remove();\n\n const overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 9999;\n `;\n\n window.document.body.appendChild(overlay);\n return overlay;\n };\n\n type EventListenersList = Array<{\n element: HTMLElement | Window;\n type: keyof HTMLElementEventMap | 'message';\n handler: EventListener;\n }>;\n\n const createHighlightManager = (overlay: HTMLElement) => {\n const elements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);\n const eventListeners: EventListenersList = [];\n const highlights: HTMLElement[] = [];\n const focusedHighlights: HTMLElement[] = [];\n let focusedField: string | null = null;\n\n const drawHighlight = (target: Element, highlight: HTMLElement) => {\n if (!highlight) return;\n\n const rect = target.getBoundingClientRect();\n highlight.style.width = `${rect.width + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.height = `${rect.height + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;\n };\n\n const updateAllHighlights = () => {\n highlights.forEach((highlight, index) => {\n const element = elements[index];\n if (element && highlight) {\n drawHighlight(element, highlight);\n }\n });\n };\n\n elements.forEach((element) => {\n if (element instanceof HTMLElement) {\n const highlight = document.createElement('div');\n highlight.style.cssText = `\n position: absolute;\n outline: 2px solid transparent;\n pointer-events: none;\n border-radius: 2px;\n background-color: transparent;\n will-change: transform;\n transition: outline-color 0.1s ease-in-out;\n `;\n\n // Move hover detection to the underlying element\n const mouseEnterHandler = () => {\n if (!highlightManager.focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;\n }\n };\n const mouseLeaveHandler = () => {\n if (!highlightManager.focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = 'transparent';\n }\n };\n const doubleClickHandler = () => {\n const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);\n if (sourceAttribute) {\n const rect = element.getBoundingClientRect();\n sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {\n path: sourceAttribute,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n },\n });\n }\n };\n const mouseDownHandler = (event: MouseEvent) => {\n // Prevent default multi click to select behavior\n if (event.detail >= 2) {\n event.preventDefault();\n }\n };\n\n element.addEventListener('mouseenter', mouseEnterHandler);\n element.addEventListener('mouseleave', mouseLeaveHandler);\n element.addEventListener('dblclick', doubleClickHandler);\n element.addEventListener('mousedown', mouseDownHandler);\n\n // Store event listeners for cleanup\n eventListeners.push(\n { element, type: 'mouseenter', handler: mouseEnterHandler },\n { element, type: 'mouseleave', handler: mouseLeaveHandler },\n { element, type: 'dblclick', handler: doubleClickHandler },\n { element, type: 'mousedown', handler: mouseDownHandler as EventListener }\n );\n\n highlights.push(highlight);\n overlay.appendChild(highlight);\n\n drawHighlight(element, highlight);\n }\n });\n\n return {\n elements,\n updateAllHighlights,\n eventListeners,\n highlights,\n focusedHighlights,\n setFocusedField: (field: string | null) => {\n focusedField = field;\n },\n getFocusedField: () => focusedField,\n };\n };\n\n type HighlightManager = ReturnType<typeof createHighlightManager>;\n\n const setupObservers = (highlightManager: HighlightManager) => {\n const resizeObserver = new ResizeObserver(() => {\n highlightManager.updateAllHighlights();\n });\n\n highlightManager.elements.forEach((element: Element) => {\n resizeObserver.observe(element);\n });\n\n resizeObserver.observe(document.documentElement);\n\n const updateOnScroll = () => {\n highlightManager.updateAllHighlights();\n };\n\n const scrollableElements = new Set<Element | Window>();\n scrollableElements.add(window);\n\n // Find all scrollable ancestors for all tracked elements\n highlightManager.elements.forEach((element) => {\n let parent = element.parentElement;\n while (parent) {\n const computedStyle = window.getComputedStyle(parent);\n const overflow = computedStyle.overflow + computedStyle.overflowX + computedStyle.overflowY;\n\n if (overflow.includes('scroll') || overflow.includes('auto')) {\n scrollableElements.add(parent);\n }\n\n parent = parent.parentElement;\n }\n });\n\n // Add scroll listeners to all scrollable elements\n scrollableElements.forEach((element) => {\n if (element === window) {\n window.addEventListener('scroll', updateOnScroll);\n window.addEventListener('resize', updateOnScroll);\n } else {\n element.addEventListener('scroll', updateOnScroll);\n }\n });\n\n return {\n resizeObserver,\n updateOnScroll,\n scrollableElements,\n };\n };\n\n const setupEventHandlers = (highlightManager: HighlightManager) => {\n const handleMessage = (event: MessageEvent) => {\n if (!event.data?.type) return;\n\n // The user typed in an input, reflect the change in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_CHANGE) {\n const { field, value } = event.data.payload;\n if (!field) return;\n\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n if (element instanceof HTMLElement) {\n element.textContent = value || '';\n }\n });\n return;\n }\n\n // The user focused a new input, update the highlights in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_FOCUS) {\n const { field } = event.data.payload;\n if (!field) return;\n\n // Clear existing focused highlights\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n });\n highlightManager.focusedHighlights.length = 0;\n\n // Set new focused field and highlight matching elements\n highlightManager.setFocusedField(field);\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n const highlight =\n highlightManager.highlights[Array.from(highlightManager.elements).indexOf(element)];\n if (highlight) {\n highlight.style.outlineColor = HIGHLIGHT_ACTIVE_COLOR;\n highlight.style.outlineWidth = '3px';\n highlightManager.focusedHighlights.push(highlight);\n }\n });\n return;\n }\n\n // The user is no longer focusing an input, remove the highlights\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_BLUR) {\n const { field } = event.data.payload;\n if (field !== highlightManager.getFocusedField()) return;\n\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n highlight.style.outlineWidth = '2px';\n });\n highlightManager.focusedHighlights.length = 0;\n highlightManager.setFocusedField(null);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Add the message handler to the cleanup list\n const messageEventListener = {\n element: window,\n type: 'message' as keyof HTMLElementEventMap,\n handler: handleMessage as EventListener,\n };\n\n return [...highlightManager.eventListeners, messageEventListener];\n };\n\n const createCleanupSystem = (\n overlay: HTMLElement,\n observers: ReturnType<typeof setupObservers>,\n eventHandlers: EventListenersList\n ) => {\n window.__strapi_previewCleanup = () => {\n observers.resizeObserver.disconnect();\n\n // Remove all scroll listeners\n observers.scrollableElements.forEach((element) => {\n if (element === window) {\n window.removeEventListener('scroll', observers.updateOnScroll);\n window.removeEventListener('resize', observers.updateOnScroll);\n } else {\n (element as Element).removeEventListener('scroll', observers.updateOnScroll);\n }\n });\n\n // Remove highlight event listeners\n eventHandlers.forEach(({ element, type, handler }) => {\n element.removeEventListener(type, handler);\n });\n\n overlay.remove();\n };\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Orchestration\n * ---------------------------------------------------------------------------------------------*/\n\n const overlay = createOverlaySystem();\n const highlightManager = createHighlightManager(overlay);\n const observers = setupObservers(highlightManager);\n const eventHandlers = setupEventHandlers(highlightManager);\n createCleanupSystem(overlay, observers, eventHandlers);\n};\n\nexport { previewScript };\n"],"names":["previewScript","shouldRun","HIGHLIGHT_PADDING","HIGHLIGHT_HOVER_COLOR","window","STRAPI_HIGHLIGHT_HOVER_COLOR","HIGHLIGHT_ACTIVE_COLOR","STRAPI_HIGHLIGHT_ACTIVE_COLOR","SOURCE_ATTRIBUTE","OVERLAY_ID","INTERNAL_EVENTS","STRAPI_FIELD_FOCUS","STRAPI_FIELD_BLUR","STRAPI_FIELD_CHANGE","STRAPI_FIELD_FOCUS_INTENT","sendMessage","type","payload","parent","postMessage","createOverlaySystem","__strapi_previewCleanup","document","getElementById","remove","overlay","createElement","id","style","cssText","body","appendChild","createHighlightManager","elements","querySelectorAll","eventListeners","highlights","focusedHighlights","focusedField","drawHighlight","target","highlight","rect","getBoundingClientRect","width","height","transform","left","top","updateAllHighlights","forEach","index","element","HTMLElement","mouseEnterHandler","highlightManager","includes","outlineColor","mouseLeaveHandler","doubleClickHandler","sourceAttribute","getAttribute","path","position","right","bottom","mouseDownHandler","event","detail","preventDefault","addEventListener","push","handler","setFocusedField","field","getFocusedField","setupObservers","resizeObserver","ResizeObserver","observe","documentElement","updateOnScroll","scrollableElements","Set","add","parentElement","computedStyle","getComputedStyle","overflow","overflowX","overflowY","setupEventHandlers","handleMessage","data","value","matchingElements","textContent","length","Array","from","indexOf","outlineWidth","messageEventListener","createCleanupSystem","observers","eventHandlers","disconnect","removeEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"previewScript.js","sources":["../../../../admin/src/preview/utils/previewScript.ts"],"sourcesContent":["// NOTE: This override is for the properties on _user's site_, it's not about Strapi Admin.\ndeclare global {\n interface Window {\n __strapi_previewCleanup?: () => void;\n STRAPI_HIGHLIGHT_HOVER_COLOR?: string;\n STRAPI_HIGHLIGHT_ACTIVE_COLOR?: string;\n STRAPI_DISABLE_STEGA_DECODING?: boolean;\n }\n}\n\n/**\n * previewScript will be injected into the preview iframe after being stringified.\n * Therefore it CANNOT use any imports, or refer to any variables outside of its own scope.\n * It's why many functions are defined within previewScript, it's the only way to avoid going full spaghetti.\n * To get a better overview of everything previewScript does, go to the orchestration part at its end.\n */\nconst previewScript = (shouldRun = true) => {\n /* -----------------------------------------------------------------------------------------------\n * Params\n * ---------------------------------------------------------------------------------------------*/\n const HIGHLIGHT_PADDING = 2; // in pixels\n const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500\n const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600\n\n const DISABLE_STEGA_DECODING = window.STRAPI_DISABLE_STEGA_DECODING ?? false;\n const SOURCE_ATTRIBUTE = 'data-strapi-source';\n const OVERLAY_ID = 'strapi-preview-overlay';\n const INTERNAL_EVENTS = {\n STRAPI_FIELD_FOCUS: 'strapiFieldFocus',\n STRAPI_FIELD_BLUR: 'strapiFieldBlur',\n STRAPI_FIELD_CHANGE: 'strapiFieldChange',\n STRAPI_FIELD_FOCUS_INTENT: 'strapiFieldFocusIntent',\n } as const;\n\n /**\n * Calling the function in no-run mode lets us retrieve the constants from other files and keep\n * a single source of truth for them. It's the only way to do this because this script can't\n * refer to any variables outside of its own scope, because it's stringified before it's run.\n */\n if (!shouldRun) {\n return { INTERNAL_EVENTS };\n }\n\n /* -----------------------------------------------------------------------------------------------\n * Utils\n * ---------------------------------------------------------------------------------------------*/\n\n const sendMessage = (\n type: (typeof INTERNAL_EVENTS)[keyof typeof INTERNAL_EVENTS],\n payload: unknown\n ) => {\n window.parent.postMessage({ type, payload }, '*');\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Functionality pieces\n * ---------------------------------------------------------------------------------------------*/\n\n const setupStegaDOMObserver = async () => {\n if (DISABLE_STEGA_DECODING) {\n return;\n }\n\n const { vercelStegaDecode: stegaDecode, vercelStegaClean: stegaClean } = await import(\n // @ts-expect-error it's not a local dependency\n // eslint-disable-next-line import/no-unresolved\n 'https://cdn.jsdelivr.net/npm/@vercel/stega@0.1.2/+esm'\n );\n\n const applyStegaToElement = (element: Element) => {\n const directTextNodes = Array.from(element.childNodes).filter(\n (node) => node.nodeType === Node.TEXT_NODE\n );\n\n const directTextContent = directTextNodes.map((node) => node.textContent || '').join('');\n\n if (directTextContent) {\n try {\n const result = stegaDecode(directTextContent);\n if (result) {\n element.setAttribute(SOURCE_ATTRIBUTE, result.key);\n\n // Remove encoded part from DOM text content (to avoid breaking links for example)\n directTextNodes.forEach((node) => {\n if (node.textContent) {\n const cleanedText = stegaClean(node.textContent);\n if (cleanedText !== node.textContent) {\n node.textContent = cleanedText;\n }\n }\n });\n }\n } catch (error) {}\n }\n };\n\n // Process all existing elements\n const allElements = document.querySelectorAll('*');\n Array.from(allElements).forEach(applyStegaToElement);\n\n // Create observer for new elements and text changes\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n // Handle added nodes\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n // Process the added element\n applyStegaToElement(element);\n // Process all child elements\n const childElements = element.querySelectorAll('*');\n Array.from(childElements).forEach(applyStegaToElement);\n }\n });\n }\n\n // Handle text content changes\n if (mutation.type === 'characterData' && mutation.target.parentElement) {\n applyStegaToElement(mutation.target.parentElement);\n }\n });\n });\n\n observer.observe(document, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n return observer;\n };\n\n const createOverlaySystem = () => {\n // Clean up before creating a new overlay so we can safely call previewScript multiple times\n window.__strapi_previewCleanup?.();\n document.getElementById(OVERLAY_ID)?.remove();\n\n const overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 9999;\n `;\n\n window.document.body.appendChild(overlay);\n return overlay;\n };\n\n type EventListenersList = Array<{\n element: HTMLElement | Window;\n type: keyof HTMLElementEventMap | 'message';\n handler: EventListener;\n }>;\n\n const createHighlightManager = (overlay: HTMLElement) => {\n const elementsToHighlight = new Map<Element, HTMLElement>();\n const eventListeners: EventListenersList = [];\n const focusedHighlights: HTMLElement[] = [];\n let focusedField: string | null = null;\n\n const drawHighlight = (target: Element, highlight: HTMLElement) => {\n if (!highlight) return;\n\n const rect = target.getBoundingClientRect();\n highlight.style.width = `${rect.width + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.height = `${rect.height + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;\n };\n\n const updateAllHighlights = () => {\n elementsToHighlight.forEach((highlight, element) => {\n drawHighlight(element, highlight);\n });\n };\n\n const createHighlightForElement = (element: HTMLElement) => {\n if (elementsToHighlight.has(element)) {\n // Already has a highlight\n return;\n }\n\n const highlight = document.createElement('div');\n highlight.style.cssText = `\n position: absolute;\n outline: 2px solid transparent;\n pointer-events: none;\n border-radius: 2px;\n background-color: transparent;\n will-change: transform;\n transition: outline-color 0.1s ease-in-out;\n `;\n\n // Move hover detection to the underlying element\n const mouseEnterHandler = () => {\n if (!focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;\n }\n };\n const mouseLeaveHandler = () => {\n if (!focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = 'transparent';\n }\n };\n const doubleClickHandler = () => {\n const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);\n if (sourceAttribute) {\n const rect = element.getBoundingClientRect();\n sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {\n path: sourceAttribute,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n },\n });\n }\n };\n const mouseDownHandler = (event: MouseEvent) => {\n // Prevent default multi click to select behavior\n if (event.detail >= 2) {\n event.preventDefault();\n }\n };\n\n element.addEventListener('mouseenter', mouseEnterHandler);\n element.addEventListener('mouseleave', mouseLeaveHandler);\n element.addEventListener('dblclick', doubleClickHandler);\n element.addEventListener('mousedown', mouseDownHandler);\n\n // Store event listeners for cleanup\n eventListeners.push(\n { element, type: 'mouseenter', handler: mouseEnterHandler },\n { element, type: 'mouseleave', handler: mouseLeaveHandler },\n { element, type: 'dblclick', handler: doubleClickHandler },\n { element, type: 'mousedown', handler: mouseDownHandler as EventListener }\n );\n\n elementsToHighlight.set(element, highlight);\n overlay.appendChild(highlight);\n drawHighlight(element, highlight);\n };\n\n const removeHighlightForElement = (element: Element) => {\n const highlight = elementsToHighlight.get(element);\n\n if (!highlight) return;\n\n highlight.remove();\n elementsToHighlight.delete(element);\n\n // Remove event listeners for this element\n const listenersToRemove = eventListeners.filter((listener) => listener.element === element);\n listenersToRemove.forEach(({ element, type, handler }) => {\n element.removeEventListener(type, handler);\n });\n\n // Mutate eventListeners to remove listeners for this element\n eventListeners.splice(\n 0,\n eventListeners.length,\n ...eventListeners.filter((listener) => listener.element !== element)\n );\n };\n\n // Process all existing elements with source attributes\n const initialElements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);\n Array.from(initialElements).forEach((element) => {\n if (element instanceof HTMLElement) {\n createHighlightForElement(element);\n }\n });\n\n return {\n get elements() {\n return Array.from(elementsToHighlight.keys());\n },\n get highlights() {\n return Array.from(elementsToHighlight.values());\n },\n updateAllHighlights,\n eventListeners,\n focusedHighlights,\n createHighlightForElement,\n removeHighlightForElement,\n setFocusedField: (field: string | null) => {\n focusedField = field;\n },\n getFocusedField: () => focusedField,\n };\n };\n\n type HighlightManager = ReturnType<typeof createHighlightManager>;\n\n /**\n * We need to track scroll in all the element parents in order to keep the highlight position\n * in sync with the element position. Listening to window scroll is not enough because the\n * element can be inside one or more scrollable containers.\n */\n const setupScrollManagement = (highlightManager: HighlightManager) => {\n const updateOnScroll = () => {\n highlightManager.updateAllHighlights();\n };\n\n const scrollableElements = new Set<Element | Window>();\n scrollableElements.add(window);\n\n // Find all scrollable ancestors for all tracked elements and set up scroll listeners\n highlightManager.elements.forEach((element) => {\n let parent = element.parentElement;\n while (parent) {\n const computedStyle = window.getComputedStyle(parent);\n const overflow = computedStyle.overflow + computedStyle.overflowX + computedStyle.overflowY;\n\n if (overflow.includes('scroll') || overflow.includes('auto')) {\n scrollableElements.add(parent);\n }\n\n parent = parent.parentElement;\n }\n });\n\n // Add scroll listeners to all scrollable elements\n scrollableElements.forEach((element) => {\n if (element === window) {\n window.addEventListener('scroll', updateOnScroll);\n window.addEventListener('resize', updateOnScroll);\n } else {\n element.addEventListener('scroll', updateOnScroll);\n }\n });\n\n const cleanup = () => {\n scrollableElements.forEach((element) => {\n if (element === window) {\n window.removeEventListener('scroll', updateOnScroll);\n window.removeEventListener('resize', updateOnScroll);\n } else {\n (element as Element).removeEventListener('scroll', updateOnScroll);\n }\n });\n };\n\n return { cleanup };\n };\n\n const setupObservers = (\n highlightManager: HighlightManager,\n stegaObserver: MutationObserver | undefined\n ) => {\n const resizeObserver = new ResizeObserver(() => {\n highlightManager.updateAllHighlights();\n });\n\n const observeElementForResize = (element: Element) => {\n resizeObserver.observe(element);\n };\n\n // Observe existing elements\n highlightManager.elements.forEach(observeElementForResize);\n resizeObserver.observe(document.documentElement);\n\n // Create highlight observer to watch for new elements with source attributes\n const highlightObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.type === 'attributes' && mutation.attributeName === SOURCE_ATTRIBUTE) {\n const target = mutation.target as HTMLElement;\n if (target.hasAttribute(SOURCE_ATTRIBUTE)) {\n highlightManager.createHighlightForElement(target);\n observeElementForResize(target);\n } else {\n highlightManager.removeHighlightForElement(target);\n }\n }\n\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n // Check if the added element has source attribute\n if (element.hasAttribute(SOURCE_ATTRIBUTE) && element instanceof HTMLElement) {\n highlightManager.createHighlightForElement(element);\n observeElementForResize(element);\n }\n // Check all child elements for source attributes\n const elementsWithSource = element.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);\n Array.from(elementsWithSource).forEach((childElement) => {\n if (childElement instanceof HTMLElement) {\n highlightManager.createHighlightForElement(childElement);\n observeElementForResize(childElement);\n }\n });\n }\n });\n\n mutation.removedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n highlightManager.removeHighlightForElement(element);\n }\n });\n }\n });\n });\n\n highlightObserver.observe(document, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [SOURCE_ATTRIBUTE],\n });\n\n return {\n resizeObserver,\n highlightObserver,\n stegaObserver,\n };\n };\n\n const setupEventHandlers = (highlightManager: HighlightManager) => {\n const handleMessage = (event: MessageEvent) => {\n if (!event.data?.type) return;\n\n // The user typed in an input, reflect the change in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_CHANGE) {\n const { field, value } = event.data.payload;\n if (!field) return;\n\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n if (element instanceof HTMLElement) {\n element.textContent = value || '';\n }\n });\n\n // Update highlight dimensions since the new text content may affect them\n highlightManager.updateAllHighlights();\n return;\n }\n\n // The user focused a new input, update the highlights in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_FOCUS) {\n const { field } = event.data.payload;\n if (!field) return;\n\n // Clear existing focused highlights\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n });\n highlightManager.focusedHighlights.length = 0;\n\n // Set new focused field and highlight matching elements\n highlightManager.setFocusedField(field);\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n const highlight =\n highlightManager.highlights[Array.from(highlightManager.elements).indexOf(element)];\n if (highlight) {\n highlight.style.outlineColor = HIGHLIGHT_ACTIVE_COLOR;\n highlight.style.outlineWidth = '3px';\n highlightManager.focusedHighlights.push(highlight);\n }\n });\n return;\n }\n\n // The user is no longer focusing an input, remove the highlights\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_BLUR) {\n const { field } = event.data.payload;\n if (field !== highlightManager.getFocusedField()) return;\n\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n highlight.style.outlineWidth = '2px';\n });\n highlightManager.focusedHighlights.length = 0;\n highlightManager.setFocusedField(null);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Add the message handler to the cleanup list\n const messageEventListener = {\n element: window,\n type: 'message' as keyof HTMLElementEventMap,\n handler: handleMessage as EventListener,\n };\n\n return [...highlightManager.eventListeners, messageEventListener];\n };\n\n const createCleanupSystem = (\n overlay: HTMLElement,\n observers: ReturnType<typeof setupObservers>,\n scrollManager: ReturnType<typeof setupScrollManagement>,\n eventHandlers: EventListenersList\n ) => {\n window.__strapi_previewCleanup = () => {\n observers.resizeObserver.disconnect();\n observers.highlightObserver.disconnect();\n observers.stegaObserver?.disconnect();\n\n // Clean up scroll listeners\n scrollManager.cleanup();\n\n // Remove highlight event listeners\n eventHandlers.forEach(({ element, type, handler }) => {\n element.removeEventListener(type, handler);\n });\n\n overlay.remove();\n };\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Orchestration\n * ---------------------------------------------------------------------------------------------*/\n\n setupStegaDOMObserver().then((stegaObserver) => {\n const overlay = createOverlaySystem();\n const highlightManager = createHighlightManager(overlay);\n const observers = setupObservers(highlightManager, stegaObserver);\n const scrollManager = setupScrollManagement(highlightManager);\n const eventHandlers = setupEventHandlers(highlightManager);\n createCleanupSystem(overlay, observers, scrollManager, eventHandlers);\n });\n};\n\nexport { previewScript };\n"],"names":["previewScript","shouldRun","HIGHLIGHT_PADDING","HIGHLIGHT_HOVER_COLOR","window","STRAPI_HIGHLIGHT_HOVER_COLOR","HIGHLIGHT_ACTIVE_COLOR","STRAPI_HIGHLIGHT_ACTIVE_COLOR","DISABLE_STEGA_DECODING","STRAPI_DISABLE_STEGA_DECODING","SOURCE_ATTRIBUTE","OVERLAY_ID","INTERNAL_EVENTS","STRAPI_FIELD_FOCUS","STRAPI_FIELD_BLUR","STRAPI_FIELD_CHANGE","STRAPI_FIELD_FOCUS_INTENT","sendMessage","type","payload","parent","postMessage","setupStegaDOMObserver","vercelStegaDecode","stegaDecode","vercelStegaClean","stegaClean","applyStegaToElement","element","directTextNodes","Array","from","childNodes","filter","node","nodeType","Node","TEXT_NODE","directTextContent","map","textContent","join","result","setAttribute","key","forEach","cleanedText","error","allElements","document","querySelectorAll","observer","MutationObserver","mutations","mutation","addedNodes","ELEMENT_NODE","childElements","target","parentElement","observe","childList","subtree","characterData","createOverlaySystem","__strapi_previewCleanup","getElementById","remove","overlay","createElement","id","style","cssText","body","appendChild","createHighlightManager","elementsToHighlight","Map","eventListeners","focusedHighlights","focusedField","drawHighlight","highlight","rect","getBoundingClientRect","width","height","transform","left","top","updateAllHighlights","createHighlightForElement","has","mouseEnterHandler","includes","outlineColor","mouseLeaveHandler","doubleClickHandler","sourceAttribute","getAttribute","path","position","right","bottom","mouseDownHandler","event","detail","preventDefault","addEventListener","push","handler","set","removeHighlightForElement","get","delete","listenersToRemove","listener","removeEventListener","splice","length","initialElements","HTMLElement","elements","keys","highlights","values","setFocusedField","field","getFocusedField","setupScrollManagement","highlightManager","updateOnScroll","scrollableElements","Set","add","computedStyle","getComputedStyle","overflow","overflowX","overflowY","cleanup","setupObservers","stegaObserver","resizeObserver","ResizeObserver","observeElementForResize","documentElement","highlightObserver","attributeName","hasAttribute","elementsWithSource","childElement","removedNodes","attributes","attributeFilter","setupEventHandlers","handleMessage","data","value","matchingElements","indexOf","outlineWidth","messageEventListener","createCleanupSystem","observers","scrollManager","eventHandlers","disconnect","then"],"mappings":"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"}
@@ -10,6 +10,7 @@
10
10
  * ---------------------------------------------------------------------------------------------*/ const HIGHLIGHT_PADDING = 2; // in pixels
11
11
  const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500
12
12
  const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600
13
+ const DISABLE_STEGA_DECODING = window.STRAPI_DISABLE_STEGA_DECODING ?? false;
13
14
  const SOURCE_ATTRIBUTE = 'data-strapi-source';
14
15
  const OVERLAY_ID = 'strapi-preview-overlay';
15
16
  const INTERNAL_EVENTS = {
@@ -37,7 +38,67 @@
37
38
  };
38
39
  /* -----------------------------------------------------------------------------------------------
39
40
  * Functionality pieces
40
- * ---------------------------------------------------------------------------------------------*/ const createOverlaySystem = ()=>{
41
+ * ---------------------------------------------------------------------------------------------*/ const setupStegaDOMObserver = async ()=>{
42
+ if (DISABLE_STEGA_DECODING) {
43
+ return;
44
+ }
45
+ const { vercelStegaDecode: stegaDecode, vercelStegaClean: stegaClean } = await import(// @ts-expect-error it's not a local dependency
46
+ // eslint-disable-next-line import/no-unresolved
47
+ 'https://cdn.jsdelivr.net/npm/@vercel/stega@0.1.2/+esm');
48
+ const applyStegaToElement = (element)=>{
49
+ const directTextNodes = Array.from(element.childNodes).filter((node)=>node.nodeType === Node.TEXT_NODE);
50
+ const directTextContent = directTextNodes.map((node)=>node.textContent || '').join('');
51
+ if (directTextContent) {
52
+ try {
53
+ const result = stegaDecode(directTextContent);
54
+ if (result) {
55
+ element.setAttribute(SOURCE_ATTRIBUTE, result.key);
56
+ // Remove encoded part from DOM text content (to avoid breaking links for example)
57
+ directTextNodes.forEach((node)=>{
58
+ if (node.textContent) {
59
+ const cleanedText = stegaClean(node.textContent);
60
+ if (cleanedText !== node.textContent) {
61
+ node.textContent = cleanedText;
62
+ }
63
+ }
64
+ });
65
+ }
66
+ } catch (error) {}
67
+ }
68
+ };
69
+ // Process all existing elements
70
+ const allElements = document.querySelectorAll('*');
71
+ Array.from(allElements).forEach(applyStegaToElement);
72
+ // Create observer for new elements and text changes
73
+ const observer = new MutationObserver((mutations)=>{
74
+ mutations.forEach((mutation)=>{
75
+ // Handle added nodes
76
+ if (mutation.type === 'childList') {
77
+ mutation.addedNodes.forEach((node)=>{
78
+ if (node.nodeType === Node.ELEMENT_NODE) {
79
+ const element = node;
80
+ // Process the added element
81
+ applyStegaToElement(element);
82
+ // Process all child elements
83
+ const childElements = element.querySelectorAll('*');
84
+ Array.from(childElements).forEach(applyStegaToElement);
85
+ }
86
+ });
87
+ }
88
+ // Handle text content changes
89
+ if (mutation.type === 'characterData' && mutation.target.parentElement) {
90
+ applyStegaToElement(mutation.target.parentElement);
91
+ }
92
+ });
93
+ });
94
+ observer.observe(document, {
95
+ childList: true,
96
+ subtree: true,
97
+ characterData: true
98
+ });
99
+ return observer;
100
+ };
101
+ const createOverlaySystem = ()=>{
41
102
  // Clean up before creating a new overlay so we can safely call previewScript multiple times
42
103
  window.__strapi_previewCleanup?.();
43
104
  document.getElementById(OVERLAY_ID)?.remove();
@@ -56,9 +117,8 @@
56
117
  return overlay;
57
118
  };
58
119
  const createHighlightManager = (overlay)=>{
59
- const elements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
120
+ const elementsToHighlight = new Map();
60
121
  const eventListeners = [];
61
- const highlights = [];
62
122
  const focusedHighlights = [];
63
123
  let focusedField = null;
64
124
  const drawHighlight = (target, highlight)=>{
@@ -69,112 +129,134 @@
69
129
  highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;
70
130
  };
71
131
  const updateAllHighlights = ()=>{
72
- highlights.forEach((highlight, index)=>{
73
- const element = elements[index];
74
- if (element && highlight) {
75
- drawHighlight(element, highlight);
132
+ elementsToHighlight.forEach((highlight, element)=>{
133
+ drawHighlight(element, highlight);
134
+ });
135
+ };
136
+ const createHighlightForElement = (element)=>{
137
+ if (elementsToHighlight.has(element)) {
138
+ // Already has a highlight
139
+ return;
140
+ }
141
+ const highlight = document.createElement('div');
142
+ highlight.style.cssText = `
143
+ position: absolute;
144
+ outline: 2px solid transparent;
145
+ pointer-events: none;
146
+ border-radius: 2px;
147
+ background-color: transparent;
148
+ will-change: transform;
149
+ transition: outline-color 0.1s ease-in-out;
150
+ `;
151
+ // Move hover detection to the underlying element
152
+ const mouseEnterHandler = ()=>{
153
+ if (!focusedHighlights.includes(highlight)) {
154
+ highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;
155
+ }
156
+ };
157
+ const mouseLeaveHandler = ()=>{
158
+ if (!focusedHighlights.includes(highlight)) {
159
+ highlight.style.outlineColor = 'transparent';
160
+ }
161
+ };
162
+ const doubleClickHandler = ()=>{
163
+ const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);
164
+ if (sourceAttribute) {
165
+ const rect = element.getBoundingClientRect();
166
+ sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {
167
+ path: sourceAttribute,
168
+ position: {
169
+ top: rect.top,
170
+ left: rect.left,
171
+ right: rect.right,
172
+ bottom: rect.bottom,
173
+ width: rect.width,
174
+ height: rect.height
175
+ }
176
+ });
177
+ }
178
+ };
179
+ const mouseDownHandler = (event)=>{
180
+ // Prevent default multi click to select behavior
181
+ if (event.detail >= 2) {
182
+ event.preventDefault();
76
183
  }
184
+ };
185
+ element.addEventListener('mouseenter', mouseEnterHandler);
186
+ element.addEventListener('mouseleave', mouseLeaveHandler);
187
+ element.addEventListener('dblclick', doubleClickHandler);
188
+ element.addEventListener('mousedown', mouseDownHandler);
189
+ // Store event listeners for cleanup
190
+ eventListeners.push({
191
+ element,
192
+ type: 'mouseenter',
193
+ handler: mouseEnterHandler
194
+ }, {
195
+ element,
196
+ type: 'mouseleave',
197
+ handler: mouseLeaveHandler
198
+ }, {
199
+ element,
200
+ type: 'dblclick',
201
+ handler: doubleClickHandler
202
+ }, {
203
+ element,
204
+ type: 'mousedown',
205
+ handler: mouseDownHandler
77
206
  });
207
+ elementsToHighlight.set(element, highlight);
208
+ overlay.appendChild(highlight);
209
+ drawHighlight(element, highlight);
78
210
  };
79
- elements.forEach((element)=>{
211
+ const removeHighlightForElement = (element)=>{
212
+ const highlight = elementsToHighlight.get(element);
213
+ if (!highlight) return;
214
+ highlight.remove();
215
+ elementsToHighlight.delete(element);
216
+ // Remove event listeners for this element
217
+ const listenersToRemove = eventListeners.filter((listener)=>listener.element === element);
218
+ listenersToRemove.forEach(({ element, type, handler })=>{
219
+ element.removeEventListener(type, handler);
220
+ });
221
+ // Mutate eventListeners to remove listeners for this element
222
+ eventListeners.splice(0, eventListeners.length, ...eventListeners.filter((listener)=>listener.element !== element));
223
+ };
224
+ // Process all existing elements with source attributes
225
+ const initialElements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
226
+ Array.from(initialElements).forEach((element)=>{
80
227
  if (element instanceof HTMLElement) {
81
- const highlight = document.createElement('div');
82
- highlight.style.cssText = `
83
- position: absolute;
84
- outline: 2px solid transparent;
85
- pointer-events: none;
86
- border-radius: 2px;
87
- background-color: transparent;
88
- will-change: transform;
89
- transition: outline-color 0.1s ease-in-out;
90
- `;
91
- // Move hover detection to the underlying element
92
- const mouseEnterHandler = ()=>{
93
- if (!highlightManager.focusedHighlights.includes(highlight)) {
94
- highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;
95
- }
96
- };
97
- const mouseLeaveHandler = ()=>{
98
- if (!highlightManager.focusedHighlights.includes(highlight)) {
99
- highlight.style.outlineColor = 'transparent';
100
- }
101
- };
102
- const doubleClickHandler = ()=>{
103
- const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);
104
- if (sourceAttribute) {
105
- const rect = element.getBoundingClientRect();
106
- sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {
107
- path: sourceAttribute,
108
- position: {
109
- top: rect.top,
110
- left: rect.left,
111
- right: rect.right,
112
- bottom: rect.bottom,
113
- width: rect.width,
114
- height: rect.height
115
- }
116
- });
117
- }
118
- };
119
- const mouseDownHandler = (event)=>{
120
- // Prevent default multi click to select behavior
121
- if (event.detail >= 2) {
122
- event.preventDefault();
123
- }
124
- };
125
- element.addEventListener('mouseenter', mouseEnterHandler);
126
- element.addEventListener('mouseleave', mouseLeaveHandler);
127
- element.addEventListener('dblclick', doubleClickHandler);
128
- element.addEventListener('mousedown', mouseDownHandler);
129
- // Store event listeners for cleanup
130
- eventListeners.push({
131
- element,
132
- type: 'mouseenter',
133
- handler: mouseEnterHandler
134
- }, {
135
- element,
136
- type: 'mouseleave',
137
- handler: mouseLeaveHandler
138
- }, {
139
- element,
140
- type: 'dblclick',
141
- handler: doubleClickHandler
142
- }, {
143
- element,
144
- type: 'mousedown',
145
- handler: mouseDownHandler
146
- });
147
- highlights.push(highlight);
148
- overlay.appendChild(highlight);
149
- drawHighlight(element, highlight);
228
+ createHighlightForElement(element);
150
229
  }
151
230
  });
152
231
  return {
153
- elements,
232
+ get elements () {
233
+ return Array.from(elementsToHighlight.keys());
234
+ },
235
+ get highlights () {
236
+ return Array.from(elementsToHighlight.values());
237
+ },
154
238
  updateAllHighlights,
155
239
  eventListeners,
156
- highlights,
157
240
  focusedHighlights,
241
+ createHighlightForElement,
242
+ removeHighlightForElement,
158
243
  setFocusedField: (field)=>{
159
244
  focusedField = field;
160
245
  },
161
246
  getFocusedField: ()=>focusedField
162
247
  };
163
248
  };
164
- const setupObservers = (highlightManager)=>{
165
- const resizeObserver = new ResizeObserver(()=>{
166
- highlightManager.updateAllHighlights();
167
- });
168
- highlightManager.elements.forEach((element)=>{
169
- resizeObserver.observe(element);
170
- });
171
- resizeObserver.observe(document.documentElement);
249
+ /**
250
+ * We need to track scroll in all the element parents in order to keep the highlight position
251
+ * in sync with the element position. Listening to window scroll is not enough because the
252
+ * element can be inside one or more scrollable containers.
253
+ */ const setupScrollManagement = (highlightManager)=>{
172
254
  const updateOnScroll = ()=>{
173
255
  highlightManager.updateAllHighlights();
174
256
  };
175
257
  const scrollableElements = new Set();
176
258
  scrollableElements.add(window);
177
- // Find all scrollable ancestors for all tracked elements
259
+ // Find all scrollable ancestors for all tracked elements and set up scroll listeners
178
260
  highlightManager.elements.forEach((element)=>{
179
261
  let parent = element.parentElement;
180
262
  while(parent){
@@ -195,10 +277,82 @@
195
277
  element.addEventListener('scroll', updateOnScroll);
196
278
  }
197
279
  });
280
+ const cleanup = ()=>{
281
+ scrollableElements.forEach((element)=>{
282
+ if (element === window) {
283
+ window.removeEventListener('scroll', updateOnScroll);
284
+ window.removeEventListener('resize', updateOnScroll);
285
+ } else {
286
+ element.removeEventListener('scroll', updateOnScroll);
287
+ }
288
+ });
289
+ };
290
+ return {
291
+ cleanup
292
+ };
293
+ };
294
+ const setupObservers = (highlightManager, stegaObserver)=>{
295
+ const resizeObserver = new ResizeObserver(()=>{
296
+ highlightManager.updateAllHighlights();
297
+ });
298
+ const observeElementForResize = (element)=>{
299
+ resizeObserver.observe(element);
300
+ };
301
+ // Observe existing elements
302
+ highlightManager.elements.forEach(observeElementForResize);
303
+ resizeObserver.observe(document.documentElement);
304
+ // Create highlight observer to watch for new elements with source attributes
305
+ const highlightObserver = new MutationObserver((mutations)=>{
306
+ mutations.forEach((mutation)=>{
307
+ if (mutation.type === 'attributes' && mutation.attributeName === SOURCE_ATTRIBUTE) {
308
+ const target = mutation.target;
309
+ if (target.hasAttribute(SOURCE_ATTRIBUTE)) {
310
+ highlightManager.createHighlightForElement(target);
311
+ observeElementForResize(target);
312
+ } else {
313
+ highlightManager.removeHighlightForElement(target);
314
+ }
315
+ }
316
+ if (mutation.type === 'childList') {
317
+ mutation.addedNodes.forEach((node)=>{
318
+ if (node.nodeType === Node.ELEMENT_NODE) {
319
+ const element = node;
320
+ // Check if the added element has source attribute
321
+ if (element.hasAttribute(SOURCE_ATTRIBUTE) && element instanceof HTMLElement) {
322
+ highlightManager.createHighlightForElement(element);
323
+ observeElementForResize(element);
324
+ }
325
+ // Check all child elements for source attributes
326
+ const elementsWithSource = element.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);
327
+ Array.from(elementsWithSource).forEach((childElement)=>{
328
+ if (childElement instanceof HTMLElement) {
329
+ highlightManager.createHighlightForElement(childElement);
330
+ observeElementForResize(childElement);
331
+ }
332
+ });
333
+ }
334
+ });
335
+ mutation.removedNodes.forEach((node)=>{
336
+ if (node.nodeType === Node.ELEMENT_NODE) {
337
+ const element = node;
338
+ highlightManager.removeHighlightForElement(element);
339
+ }
340
+ });
341
+ }
342
+ });
343
+ });
344
+ highlightObserver.observe(document, {
345
+ childList: true,
346
+ subtree: true,
347
+ attributes: true,
348
+ attributeFilter: [
349
+ SOURCE_ATTRIBUTE
350
+ ]
351
+ });
198
352
  return {
199
353
  resizeObserver,
200
- updateOnScroll,
201
- scrollableElements
354
+ highlightObserver,
355
+ stegaObserver
202
356
  };
203
357
  };
204
358
  const setupEventHandlers = (highlightManager)=>{
@@ -214,6 +368,8 @@
214
368
  element.textContent = value || '';
215
369
  }
216
370
  });
371
+ // Update highlight dimensions since the new text content may affect them
372
+ highlightManager.updateAllHighlights();
217
373
  return;
218
374
  }
219
375
  // The user focused a new input, update the highlights in the preview
@@ -262,18 +418,13 @@
262
418
  messageEventListener
263
419
  ];
264
420
  };
265
- const createCleanupSystem = (overlay, observers, eventHandlers)=>{
421
+ const createCleanupSystem = (overlay, observers, scrollManager, eventHandlers)=>{
266
422
  window.__strapi_previewCleanup = ()=>{
267
423
  observers.resizeObserver.disconnect();
268
- // Remove all scroll listeners
269
- observers.scrollableElements.forEach((element)=>{
270
- if (element === window) {
271
- window.removeEventListener('scroll', observers.updateOnScroll);
272
- window.removeEventListener('resize', observers.updateOnScroll);
273
- } else {
274
- element.removeEventListener('scroll', observers.updateOnScroll);
275
- }
276
- });
424
+ observers.highlightObserver.disconnect();
425
+ observers.stegaObserver?.disconnect();
426
+ // Clean up scroll listeners
427
+ scrollManager.cleanup();
277
428
  // Remove highlight event listeners
278
429
  eventHandlers.forEach(({ element, type, handler })=>{
279
430
  element.removeEventListener(type, handler);
@@ -283,11 +434,14 @@
283
434
  };
284
435
  /* -----------------------------------------------------------------------------------------------
285
436
  * Orchestration
286
- * ---------------------------------------------------------------------------------------------*/ const overlay = createOverlaySystem();
287
- const highlightManager = createHighlightManager(overlay);
288
- const observers = setupObservers(highlightManager);
289
- const eventHandlers = setupEventHandlers(highlightManager);
290
- createCleanupSystem(overlay, observers, eventHandlers);
437
+ * ---------------------------------------------------------------------------------------------*/ setupStegaDOMObserver().then((stegaObserver)=>{
438
+ const overlay = createOverlaySystem();
439
+ const highlightManager = createHighlightManager(overlay);
440
+ const observers = setupObservers(highlightManager, stegaObserver);
441
+ const scrollManager = setupScrollManagement(highlightManager);
442
+ const eventHandlers = setupEventHandlers(highlightManager);
443
+ createCleanupSystem(overlay, observers, scrollManager, eventHandlers);
444
+ });
291
445
  };
292
446
 
293
447
  export { previewScript };
@@ -1 +1 @@
1
- {"version":3,"file":"previewScript.mjs","sources":["../../../../admin/src/preview/utils/previewScript.ts"],"sourcesContent":["// NOTE: This override is for the properties on _user's site_, it's not about Strapi Admin.\ndeclare global {\n interface Window {\n __strapi_previewCleanup?: () => void;\n STRAPI_HIGHLIGHT_HOVER_COLOR?: string;\n STRAPI_HIGHLIGHT_ACTIVE_COLOR?: string;\n }\n}\n\n/**\n * previewScript will be injected into the preview iframe after being stringified.\n * Therefore it CANNOT use any imports, or refer to any variables outside of its own scope.\n * It's why many functions are defined within previewScript, it's the only way to avoid going full spaghetti.\n * To get a better overview of everything previewScript does, go to the orchestration part at its end.\n */\nconst previewScript = (shouldRun = true) => {\n /* -----------------------------------------------------------------------------------------------\n * Params\n * ---------------------------------------------------------------------------------------------*/\n const HIGHLIGHT_PADDING = 2; // in pixels\n const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500\n const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600\n\n const SOURCE_ATTRIBUTE = 'data-strapi-source';\n const OVERLAY_ID = 'strapi-preview-overlay';\n const INTERNAL_EVENTS = {\n STRAPI_FIELD_FOCUS: 'strapiFieldFocus',\n STRAPI_FIELD_BLUR: 'strapiFieldBlur',\n STRAPI_FIELD_CHANGE: 'strapiFieldChange',\n STRAPI_FIELD_FOCUS_INTENT: 'strapiFieldFocusIntent',\n } as const;\n\n /**\n * Calling the function in no-run mode lets us retrieve the constants from other files and keep\n * a single source of truth for them. It's the only way to do this because this script can't\n * refer to any variables outside of its own scope, because it's stringified before it's run.\n */\n if (!shouldRun) {\n return { INTERNAL_EVENTS };\n }\n\n /* -----------------------------------------------------------------------------------------------\n * Utils\n * ---------------------------------------------------------------------------------------------*/\n\n const sendMessage = (\n type: (typeof INTERNAL_EVENTS)[keyof typeof INTERNAL_EVENTS],\n payload: unknown\n ) => {\n window.parent.postMessage({ type, payload }, '*');\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Functionality pieces\n * ---------------------------------------------------------------------------------------------*/\n\n const createOverlaySystem = () => {\n // Clean up before creating a new overlay so we can safely call previewScript multiple times\n window.__strapi_previewCleanup?.();\n document.getElementById(OVERLAY_ID)?.remove();\n\n const overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 9999;\n `;\n\n window.document.body.appendChild(overlay);\n return overlay;\n };\n\n type EventListenersList = Array<{\n element: HTMLElement | Window;\n type: keyof HTMLElementEventMap | 'message';\n handler: EventListener;\n }>;\n\n const createHighlightManager = (overlay: HTMLElement) => {\n const elements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);\n const eventListeners: EventListenersList = [];\n const highlights: HTMLElement[] = [];\n const focusedHighlights: HTMLElement[] = [];\n let focusedField: string | null = null;\n\n const drawHighlight = (target: Element, highlight: HTMLElement) => {\n if (!highlight) return;\n\n const rect = target.getBoundingClientRect();\n highlight.style.width = `${rect.width + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.height = `${rect.height + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;\n };\n\n const updateAllHighlights = () => {\n highlights.forEach((highlight, index) => {\n const element = elements[index];\n if (element && highlight) {\n drawHighlight(element, highlight);\n }\n });\n };\n\n elements.forEach((element) => {\n if (element instanceof HTMLElement) {\n const highlight = document.createElement('div');\n highlight.style.cssText = `\n position: absolute;\n outline: 2px solid transparent;\n pointer-events: none;\n border-radius: 2px;\n background-color: transparent;\n will-change: transform;\n transition: outline-color 0.1s ease-in-out;\n `;\n\n // Move hover detection to the underlying element\n const mouseEnterHandler = () => {\n if (!highlightManager.focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;\n }\n };\n const mouseLeaveHandler = () => {\n if (!highlightManager.focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = 'transparent';\n }\n };\n const doubleClickHandler = () => {\n const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);\n if (sourceAttribute) {\n const rect = element.getBoundingClientRect();\n sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {\n path: sourceAttribute,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n },\n });\n }\n };\n const mouseDownHandler = (event: MouseEvent) => {\n // Prevent default multi click to select behavior\n if (event.detail >= 2) {\n event.preventDefault();\n }\n };\n\n element.addEventListener('mouseenter', mouseEnterHandler);\n element.addEventListener('mouseleave', mouseLeaveHandler);\n element.addEventListener('dblclick', doubleClickHandler);\n element.addEventListener('mousedown', mouseDownHandler);\n\n // Store event listeners for cleanup\n eventListeners.push(\n { element, type: 'mouseenter', handler: mouseEnterHandler },\n { element, type: 'mouseleave', handler: mouseLeaveHandler },\n { element, type: 'dblclick', handler: doubleClickHandler },\n { element, type: 'mousedown', handler: mouseDownHandler as EventListener }\n );\n\n highlights.push(highlight);\n overlay.appendChild(highlight);\n\n drawHighlight(element, highlight);\n }\n });\n\n return {\n elements,\n updateAllHighlights,\n eventListeners,\n highlights,\n focusedHighlights,\n setFocusedField: (field: string | null) => {\n focusedField = field;\n },\n getFocusedField: () => focusedField,\n };\n };\n\n type HighlightManager = ReturnType<typeof createHighlightManager>;\n\n const setupObservers = (highlightManager: HighlightManager) => {\n const resizeObserver = new ResizeObserver(() => {\n highlightManager.updateAllHighlights();\n });\n\n highlightManager.elements.forEach((element: Element) => {\n resizeObserver.observe(element);\n });\n\n resizeObserver.observe(document.documentElement);\n\n const updateOnScroll = () => {\n highlightManager.updateAllHighlights();\n };\n\n const scrollableElements = new Set<Element | Window>();\n scrollableElements.add(window);\n\n // Find all scrollable ancestors for all tracked elements\n highlightManager.elements.forEach((element) => {\n let parent = element.parentElement;\n while (parent) {\n const computedStyle = window.getComputedStyle(parent);\n const overflow = computedStyle.overflow + computedStyle.overflowX + computedStyle.overflowY;\n\n if (overflow.includes('scroll') || overflow.includes('auto')) {\n scrollableElements.add(parent);\n }\n\n parent = parent.parentElement;\n }\n });\n\n // Add scroll listeners to all scrollable elements\n scrollableElements.forEach((element) => {\n if (element === window) {\n window.addEventListener('scroll', updateOnScroll);\n window.addEventListener('resize', updateOnScroll);\n } else {\n element.addEventListener('scroll', updateOnScroll);\n }\n });\n\n return {\n resizeObserver,\n updateOnScroll,\n scrollableElements,\n };\n };\n\n const setupEventHandlers = (highlightManager: HighlightManager) => {\n const handleMessage = (event: MessageEvent) => {\n if (!event.data?.type) return;\n\n // The user typed in an input, reflect the change in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_CHANGE) {\n const { field, value } = event.data.payload;\n if (!field) return;\n\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n if (element instanceof HTMLElement) {\n element.textContent = value || '';\n }\n });\n return;\n }\n\n // The user focused a new input, update the highlights in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_FOCUS) {\n const { field } = event.data.payload;\n if (!field) return;\n\n // Clear existing focused highlights\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n });\n highlightManager.focusedHighlights.length = 0;\n\n // Set new focused field and highlight matching elements\n highlightManager.setFocusedField(field);\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n const highlight =\n highlightManager.highlights[Array.from(highlightManager.elements).indexOf(element)];\n if (highlight) {\n highlight.style.outlineColor = HIGHLIGHT_ACTIVE_COLOR;\n highlight.style.outlineWidth = '3px';\n highlightManager.focusedHighlights.push(highlight);\n }\n });\n return;\n }\n\n // The user is no longer focusing an input, remove the highlights\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_BLUR) {\n const { field } = event.data.payload;\n if (field !== highlightManager.getFocusedField()) return;\n\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n highlight.style.outlineWidth = '2px';\n });\n highlightManager.focusedHighlights.length = 0;\n highlightManager.setFocusedField(null);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Add the message handler to the cleanup list\n const messageEventListener = {\n element: window,\n type: 'message' as keyof HTMLElementEventMap,\n handler: handleMessage as EventListener,\n };\n\n return [...highlightManager.eventListeners, messageEventListener];\n };\n\n const createCleanupSystem = (\n overlay: HTMLElement,\n observers: ReturnType<typeof setupObservers>,\n eventHandlers: EventListenersList\n ) => {\n window.__strapi_previewCleanup = () => {\n observers.resizeObserver.disconnect();\n\n // Remove all scroll listeners\n observers.scrollableElements.forEach((element) => {\n if (element === window) {\n window.removeEventListener('scroll', observers.updateOnScroll);\n window.removeEventListener('resize', observers.updateOnScroll);\n } else {\n (element as Element).removeEventListener('scroll', observers.updateOnScroll);\n }\n });\n\n // Remove highlight event listeners\n eventHandlers.forEach(({ element, type, handler }) => {\n element.removeEventListener(type, handler);\n });\n\n overlay.remove();\n };\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Orchestration\n * ---------------------------------------------------------------------------------------------*/\n\n const overlay = createOverlaySystem();\n const highlightManager = createHighlightManager(overlay);\n const observers = setupObservers(highlightManager);\n const eventHandlers = setupEventHandlers(highlightManager);\n createCleanupSystem(overlay, observers, eventHandlers);\n};\n\nexport { previewScript };\n"],"names":["previewScript","shouldRun","HIGHLIGHT_PADDING","HIGHLIGHT_HOVER_COLOR","window","STRAPI_HIGHLIGHT_HOVER_COLOR","HIGHLIGHT_ACTIVE_COLOR","STRAPI_HIGHLIGHT_ACTIVE_COLOR","SOURCE_ATTRIBUTE","OVERLAY_ID","INTERNAL_EVENTS","STRAPI_FIELD_FOCUS","STRAPI_FIELD_BLUR","STRAPI_FIELD_CHANGE","STRAPI_FIELD_FOCUS_INTENT","sendMessage","type","payload","parent","postMessage","createOverlaySystem","__strapi_previewCleanup","document","getElementById","remove","overlay","createElement","id","style","cssText","body","appendChild","createHighlightManager","elements","querySelectorAll","eventListeners","highlights","focusedHighlights","focusedField","drawHighlight","target","highlight","rect","getBoundingClientRect","width","height","transform","left","top","updateAllHighlights","forEach","index","element","HTMLElement","mouseEnterHandler","highlightManager","includes","outlineColor","mouseLeaveHandler","doubleClickHandler","sourceAttribute","getAttribute","path","position","right","bottom","mouseDownHandler","event","detail","preventDefault","addEventListener","push","handler","setFocusedField","field","getFocusedField","setupObservers","resizeObserver","ResizeObserver","observe","documentElement","updateOnScroll","scrollableElements","Set","add","parentElement","computedStyle","getComputedStyle","overflow","overflowX","overflowY","setupEventHandlers","handleMessage","data","value","matchingElements","textContent","length","Array","from","indexOf","outlineWidth","messageEventListener","createCleanupSystem","observers","eventHandlers","disconnect","removeEventListener"],"mappings":"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"}
1
+ {"version":3,"file":"previewScript.mjs","sources":["../../../../admin/src/preview/utils/previewScript.ts"],"sourcesContent":["// NOTE: This override is for the properties on _user's site_, it's not about Strapi Admin.\ndeclare global {\n interface Window {\n __strapi_previewCleanup?: () => void;\n STRAPI_HIGHLIGHT_HOVER_COLOR?: string;\n STRAPI_HIGHLIGHT_ACTIVE_COLOR?: string;\n STRAPI_DISABLE_STEGA_DECODING?: boolean;\n }\n}\n\n/**\n * previewScript will be injected into the preview iframe after being stringified.\n * Therefore it CANNOT use any imports, or refer to any variables outside of its own scope.\n * It's why many functions are defined within previewScript, it's the only way to avoid going full spaghetti.\n * To get a better overview of everything previewScript does, go to the orchestration part at its end.\n */\nconst previewScript = (shouldRun = true) => {\n /* -----------------------------------------------------------------------------------------------\n * Params\n * ---------------------------------------------------------------------------------------------*/\n const HIGHLIGHT_PADDING = 2; // in pixels\n const HIGHLIGHT_HOVER_COLOR = window.STRAPI_HIGHLIGHT_HOVER_COLOR ?? '#4945ff'; // dark primary500\n const HIGHLIGHT_ACTIVE_COLOR = window.STRAPI_HIGHLIGHT_ACTIVE_COLOR ?? '#7b79ff'; // dark primary600\n\n const DISABLE_STEGA_DECODING = window.STRAPI_DISABLE_STEGA_DECODING ?? false;\n const SOURCE_ATTRIBUTE = 'data-strapi-source';\n const OVERLAY_ID = 'strapi-preview-overlay';\n const INTERNAL_EVENTS = {\n STRAPI_FIELD_FOCUS: 'strapiFieldFocus',\n STRAPI_FIELD_BLUR: 'strapiFieldBlur',\n STRAPI_FIELD_CHANGE: 'strapiFieldChange',\n STRAPI_FIELD_FOCUS_INTENT: 'strapiFieldFocusIntent',\n } as const;\n\n /**\n * Calling the function in no-run mode lets us retrieve the constants from other files and keep\n * a single source of truth for them. It's the only way to do this because this script can't\n * refer to any variables outside of its own scope, because it's stringified before it's run.\n */\n if (!shouldRun) {\n return { INTERNAL_EVENTS };\n }\n\n /* -----------------------------------------------------------------------------------------------\n * Utils\n * ---------------------------------------------------------------------------------------------*/\n\n const sendMessage = (\n type: (typeof INTERNAL_EVENTS)[keyof typeof INTERNAL_EVENTS],\n payload: unknown\n ) => {\n window.parent.postMessage({ type, payload }, '*');\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Functionality pieces\n * ---------------------------------------------------------------------------------------------*/\n\n const setupStegaDOMObserver = async () => {\n if (DISABLE_STEGA_DECODING) {\n return;\n }\n\n const { vercelStegaDecode: stegaDecode, vercelStegaClean: stegaClean } = await import(\n // @ts-expect-error it's not a local dependency\n // eslint-disable-next-line import/no-unresolved\n 'https://cdn.jsdelivr.net/npm/@vercel/stega@0.1.2/+esm'\n );\n\n const applyStegaToElement = (element: Element) => {\n const directTextNodes = Array.from(element.childNodes).filter(\n (node) => node.nodeType === Node.TEXT_NODE\n );\n\n const directTextContent = directTextNodes.map((node) => node.textContent || '').join('');\n\n if (directTextContent) {\n try {\n const result = stegaDecode(directTextContent);\n if (result) {\n element.setAttribute(SOURCE_ATTRIBUTE, result.key);\n\n // Remove encoded part from DOM text content (to avoid breaking links for example)\n directTextNodes.forEach((node) => {\n if (node.textContent) {\n const cleanedText = stegaClean(node.textContent);\n if (cleanedText !== node.textContent) {\n node.textContent = cleanedText;\n }\n }\n });\n }\n } catch (error) {}\n }\n };\n\n // Process all existing elements\n const allElements = document.querySelectorAll('*');\n Array.from(allElements).forEach(applyStegaToElement);\n\n // Create observer for new elements and text changes\n const observer = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n // Handle added nodes\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n // Process the added element\n applyStegaToElement(element);\n // Process all child elements\n const childElements = element.querySelectorAll('*');\n Array.from(childElements).forEach(applyStegaToElement);\n }\n });\n }\n\n // Handle text content changes\n if (mutation.type === 'characterData' && mutation.target.parentElement) {\n applyStegaToElement(mutation.target.parentElement);\n }\n });\n });\n\n observer.observe(document, {\n childList: true,\n subtree: true,\n characterData: true,\n });\n\n return observer;\n };\n\n const createOverlaySystem = () => {\n // Clean up before creating a new overlay so we can safely call previewScript multiple times\n window.__strapi_previewCleanup?.();\n document.getElementById(OVERLAY_ID)?.remove();\n\n const overlay = document.createElement('div');\n overlay.id = OVERLAY_ID;\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 9999;\n `;\n\n window.document.body.appendChild(overlay);\n return overlay;\n };\n\n type EventListenersList = Array<{\n element: HTMLElement | Window;\n type: keyof HTMLElementEventMap | 'message';\n handler: EventListener;\n }>;\n\n const createHighlightManager = (overlay: HTMLElement) => {\n const elementsToHighlight = new Map<Element, HTMLElement>();\n const eventListeners: EventListenersList = [];\n const focusedHighlights: HTMLElement[] = [];\n let focusedField: string | null = null;\n\n const drawHighlight = (target: Element, highlight: HTMLElement) => {\n if (!highlight) return;\n\n const rect = target.getBoundingClientRect();\n highlight.style.width = `${rect.width + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.height = `${rect.height + HIGHLIGHT_PADDING * 2}px`;\n highlight.style.transform = `translate(${rect.left - HIGHLIGHT_PADDING}px, ${rect.top - HIGHLIGHT_PADDING}px)`;\n };\n\n const updateAllHighlights = () => {\n elementsToHighlight.forEach((highlight, element) => {\n drawHighlight(element, highlight);\n });\n };\n\n const createHighlightForElement = (element: HTMLElement) => {\n if (elementsToHighlight.has(element)) {\n // Already has a highlight\n return;\n }\n\n const highlight = document.createElement('div');\n highlight.style.cssText = `\n position: absolute;\n outline: 2px solid transparent;\n pointer-events: none;\n border-radius: 2px;\n background-color: transparent;\n will-change: transform;\n transition: outline-color 0.1s ease-in-out;\n `;\n\n // Move hover detection to the underlying element\n const mouseEnterHandler = () => {\n if (!focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = HIGHLIGHT_HOVER_COLOR;\n }\n };\n const mouseLeaveHandler = () => {\n if (!focusedHighlights.includes(highlight)) {\n highlight.style.outlineColor = 'transparent';\n }\n };\n const doubleClickHandler = () => {\n const sourceAttribute = element.getAttribute(SOURCE_ATTRIBUTE);\n if (sourceAttribute) {\n const rect = element.getBoundingClientRect();\n sendMessage(INTERNAL_EVENTS.STRAPI_FIELD_FOCUS_INTENT, {\n path: sourceAttribute,\n position: {\n top: rect.top,\n left: rect.left,\n right: rect.right,\n bottom: rect.bottom,\n width: rect.width,\n height: rect.height,\n },\n });\n }\n };\n const mouseDownHandler = (event: MouseEvent) => {\n // Prevent default multi click to select behavior\n if (event.detail >= 2) {\n event.preventDefault();\n }\n };\n\n element.addEventListener('mouseenter', mouseEnterHandler);\n element.addEventListener('mouseleave', mouseLeaveHandler);\n element.addEventListener('dblclick', doubleClickHandler);\n element.addEventListener('mousedown', mouseDownHandler);\n\n // Store event listeners for cleanup\n eventListeners.push(\n { element, type: 'mouseenter', handler: mouseEnterHandler },\n { element, type: 'mouseleave', handler: mouseLeaveHandler },\n { element, type: 'dblclick', handler: doubleClickHandler },\n { element, type: 'mousedown', handler: mouseDownHandler as EventListener }\n );\n\n elementsToHighlight.set(element, highlight);\n overlay.appendChild(highlight);\n drawHighlight(element, highlight);\n };\n\n const removeHighlightForElement = (element: Element) => {\n const highlight = elementsToHighlight.get(element);\n\n if (!highlight) return;\n\n highlight.remove();\n elementsToHighlight.delete(element);\n\n // Remove event listeners for this element\n const listenersToRemove = eventListeners.filter((listener) => listener.element === element);\n listenersToRemove.forEach(({ element, type, handler }) => {\n element.removeEventListener(type, handler);\n });\n\n // Mutate eventListeners to remove listeners for this element\n eventListeners.splice(\n 0,\n eventListeners.length,\n ...eventListeners.filter((listener) => listener.element !== element)\n );\n };\n\n // Process all existing elements with source attributes\n const initialElements = window.document.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);\n Array.from(initialElements).forEach((element) => {\n if (element instanceof HTMLElement) {\n createHighlightForElement(element);\n }\n });\n\n return {\n get elements() {\n return Array.from(elementsToHighlight.keys());\n },\n get highlights() {\n return Array.from(elementsToHighlight.values());\n },\n updateAllHighlights,\n eventListeners,\n focusedHighlights,\n createHighlightForElement,\n removeHighlightForElement,\n setFocusedField: (field: string | null) => {\n focusedField = field;\n },\n getFocusedField: () => focusedField,\n };\n };\n\n type HighlightManager = ReturnType<typeof createHighlightManager>;\n\n /**\n * We need to track scroll in all the element parents in order to keep the highlight position\n * in sync with the element position. Listening to window scroll is not enough because the\n * element can be inside one or more scrollable containers.\n */\n const setupScrollManagement = (highlightManager: HighlightManager) => {\n const updateOnScroll = () => {\n highlightManager.updateAllHighlights();\n };\n\n const scrollableElements = new Set<Element | Window>();\n scrollableElements.add(window);\n\n // Find all scrollable ancestors for all tracked elements and set up scroll listeners\n highlightManager.elements.forEach((element) => {\n let parent = element.parentElement;\n while (parent) {\n const computedStyle = window.getComputedStyle(parent);\n const overflow = computedStyle.overflow + computedStyle.overflowX + computedStyle.overflowY;\n\n if (overflow.includes('scroll') || overflow.includes('auto')) {\n scrollableElements.add(parent);\n }\n\n parent = parent.parentElement;\n }\n });\n\n // Add scroll listeners to all scrollable elements\n scrollableElements.forEach((element) => {\n if (element === window) {\n window.addEventListener('scroll', updateOnScroll);\n window.addEventListener('resize', updateOnScroll);\n } else {\n element.addEventListener('scroll', updateOnScroll);\n }\n });\n\n const cleanup = () => {\n scrollableElements.forEach((element) => {\n if (element === window) {\n window.removeEventListener('scroll', updateOnScroll);\n window.removeEventListener('resize', updateOnScroll);\n } else {\n (element as Element).removeEventListener('scroll', updateOnScroll);\n }\n });\n };\n\n return { cleanup };\n };\n\n const setupObservers = (\n highlightManager: HighlightManager,\n stegaObserver: MutationObserver | undefined\n ) => {\n const resizeObserver = new ResizeObserver(() => {\n highlightManager.updateAllHighlights();\n });\n\n const observeElementForResize = (element: Element) => {\n resizeObserver.observe(element);\n };\n\n // Observe existing elements\n highlightManager.elements.forEach(observeElementForResize);\n resizeObserver.observe(document.documentElement);\n\n // Create highlight observer to watch for new elements with source attributes\n const highlightObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.type === 'attributes' && mutation.attributeName === SOURCE_ATTRIBUTE) {\n const target = mutation.target as HTMLElement;\n if (target.hasAttribute(SOURCE_ATTRIBUTE)) {\n highlightManager.createHighlightForElement(target);\n observeElementForResize(target);\n } else {\n highlightManager.removeHighlightForElement(target);\n }\n }\n\n if (mutation.type === 'childList') {\n mutation.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n // Check if the added element has source attribute\n if (element.hasAttribute(SOURCE_ATTRIBUTE) && element instanceof HTMLElement) {\n highlightManager.createHighlightForElement(element);\n observeElementForResize(element);\n }\n // Check all child elements for source attributes\n const elementsWithSource = element.querySelectorAll(`[${SOURCE_ATTRIBUTE}]`);\n Array.from(elementsWithSource).forEach((childElement) => {\n if (childElement instanceof HTMLElement) {\n highlightManager.createHighlightForElement(childElement);\n observeElementForResize(childElement);\n }\n });\n }\n });\n\n mutation.removedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n const element = node as Element;\n highlightManager.removeHighlightForElement(element);\n }\n });\n }\n });\n });\n\n highlightObserver.observe(document, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [SOURCE_ATTRIBUTE],\n });\n\n return {\n resizeObserver,\n highlightObserver,\n stegaObserver,\n };\n };\n\n const setupEventHandlers = (highlightManager: HighlightManager) => {\n const handleMessage = (event: MessageEvent) => {\n if (!event.data?.type) return;\n\n // The user typed in an input, reflect the change in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_CHANGE) {\n const { field, value } = event.data.payload;\n if (!field) return;\n\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n if (element instanceof HTMLElement) {\n element.textContent = value || '';\n }\n });\n\n // Update highlight dimensions since the new text content may affect them\n highlightManager.updateAllHighlights();\n return;\n }\n\n // The user focused a new input, update the highlights in the preview\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_FOCUS) {\n const { field } = event.data.payload;\n if (!field) return;\n\n // Clear existing focused highlights\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n });\n highlightManager.focusedHighlights.length = 0;\n\n // Set new focused field and highlight matching elements\n highlightManager.setFocusedField(field);\n const matchingElements = document.querySelectorAll(`[${SOURCE_ATTRIBUTE}=\"${field}\"]`);\n matchingElements.forEach((element) => {\n const highlight =\n highlightManager.highlights[Array.from(highlightManager.elements).indexOf(element)];\n if (highlight) {\n highlight.style.outlineColor = HIGHLIGHT_ACTIVE_COLOR;\n highlight.style.outlineWidth = '3px';\n highlightManager.focusedHighlights.push(highlight);\n }\n });\n return;\n }\n\n // The user is no longer focusing an input, remove the highlights\n if (event.data.type === INTERNAL_EVENTS.STRAPI_FIELD_BLUR) {\n const { field } = event.data.payload;\n if (field !== highlightManager.getFocusedField()) return;\n\n highlightManager.focusedHighlights.forEach((highlight: HTMLElement) => {\n highlight.style.outlineColor = 'transparent';\n highlight.style.outlineWidth = '2px';\n });\n highlightManager.focusedHighlights.length = 0;\n highlightManager.setFocusedField(null);\n }\n };\n\n window.addEventListener('message', handleMessage);\n\n // Add the message handler to the cleanup list\n const messageEventListener = {\n element: window,\n type: 'message' as keyof HTMLElementEventMap,\n handler: handleMessage as EventListener,\n };\n\n return [...highlightManager.eventListeners, messageEventListener];\n };\n\n const createCleanupSystem = (\n overlay: HTMLElement,\n observers: ReturnType<typeof setupObservers>,\n scrollManager: ReturnType<typeof setupScrollManagement>,\n eventHandlers: EventListenersList\n ) => {\n window.__strapi_previewCleanup = () => {\n observers.resizeObserver.disconnect();\n observers.highlightObserver.disconnect();\n observers.stegaObserver?.disconnect();\n\n // Clean up scroll listeners\n scrollManager.cleanup();\n\n // Remove highlight event listeners\n eventHandlers.forEach(({ element, type, handler }) => {\n element.removeEventListener(type, handler);\n });\n\n overlay.remove();\n };\n };\n\n /* -----------------------------------------------------------------------------------------------\n * Orchestration\n * ---------------------------------------------------------------------------------------------*/\n\n setupStegaDOMObserver().then((stegaObserver) => {\n const overlay = createOverlaySystem();\n const highlightManager = createHighlightManager(overlay);\n const observers = setupObservers(highlightManager, stegaObserver);\n const scrollManager = setupScrollManagement(highlightManager);\n const eventHandlers = setupEventHandlers(highlightManager);\n createCleanupSystem(overlay, observers, scrollManager, eventHandlers);\n });\n};\n\nexport { previewScript };\n"],"names":["previewScript","shouldRun","HIGHLIGHT_PADDING","HIGHLIGHT_HOVER_COLOR","window","STRAPI_HIGHLIGHT_HOVER_COLOR","HIGHLIGHT_ACTIVE_COLOR","STRAPI_HIGHLIGHT_ACTIVE_COLOR","DISABLE_STEGA_DECODING","STRAPI_DISABLE_STEGA_DECODING","SOURCE_ATTRIBUTE","OVERLAY_ID","INTERNAL_EVENTS","STRAPI_FIELD_FOCUS","STRAPI_FIELD_BLUR","STRAPI_FIELD_CHANGE","STRAPI_FIELD_FOCUS_INTENT","sendMessage","type","payload","parent","postMessage","setupStegaDOMObserver","vercelStegaDecode","stegaDecode","vercelStegaClean","stegaClean","applyStegaToElement","element","directTextNodes","Array","from","childNodes","filter","node","nodeType","Node","TEXT_NODE","directTextContent","map","textContent","join","result","setAttribute","key","forEach","cleanedText","error","allElements","document","querySelectorAll","observer","MutationObserver","mutations","mutation","addedNodes","ELEMENT_NODE","childElements","target","parentElement","observe","childList","subtree","characterData","createOverlaySystem","__strapi_previewCleanup","getElementById","remove","overlay","createElement","id","style","cssText","body","appendChild","createHighlightManager","elementsToHighlight","Map","eventListeners","focusedHighlights","focusedField","drawHighlight","highlight","rect","getBoundingClientRect","width","height","transform","left","top","updateAllHighlights","createHighlightForElement","has","mouseEnterHandler","includes","outlineColor","mouseLeaveHandler","doubleClickHandler","sourceAttribute","getAttribute","path","position","right","bottom","mouseDownHandler","event","detail","preventDefault","addEventListener","push","handler","set","removeHighlightForElement","get","delete","listenersToRemove","listener","removeEventListener","splice","length","initialElements","HTMLElement","elements","keys","highlights","values","setFocusedField","field","getFocusedField","setupScrollManagement","highlightManager","updateOnScroll","scrollableElements","Set","add","computedStyle","getComputedStyle","overflow","overflowX","overflowY","cleanup","setupObservers","stegaObserver","resizeObserver","ResizeObserver","observeElementForResize","documentElement","highlightObserver","attributeName","hasAttribute","elementsWithSource","childElement","removedNodes","attributes","attributeFilter","setupEventHandlers","handleMessage","data","value","matchingElements","indexOf","outlineWidth","messageEventListener","createCleanupSystem","observers","scrollManager","eventHandlers","disconnect","then"],"mappings":"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"}
@@ -3,6 +3,7 @@ declare global {
3
3
  __strapi_previewCleanup?: () => void;
4
4
  STRAPI_HIGHLIGHT_HOVER_COLOR?: string;
5
5
  STRAPI_HIGHLIGHT_ACTIVE_COLOR?: string;
6
+ STRAPI_DISABLE_STEGA_DECODING?: boolean;
6
7
  }
7
8
  }
8
9
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/content-manager",
3
- "version": "5.23.1",
3
+ "version": "5.23.2",
4
4
  "description": "A powerful UI to easily manage your data.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -69,8 +69,8 @@
69
69
  "@sindresorhus/slugify": "1.1.0",
70
70
  "@strapi/design-system": "2.0.0-rc.29",
71
71
  "@strapi/icons": "2.0.0-rc.29",
72
- "@strapi/types": "5.23.1",
73
- "@strapi/utils": "5.23.1",
72
+ "@strapi/types": "5.23.2",
73
+ "@strapi/utils": "5.23.2",
74
74
  "codemirror5": "npm:codemirror@^5.65.11",
75
75
  "date-fns": "2.30.0",
76
76
  "fractional-indexing": "3.2.0",
@@ -104,8 +104,8 @@
104
104
  "yup": "0.32.9"
105
105
  },
106
106
  "devDependencies": {
107
- "@strapi/admin": "5.23.1",
108
- "@strapi/database": "5.23.1",
107
+ "@strapi/admin": "5.23.2",
108
+ "@strapi/database": "5.23.2",
109
109
  "@testing-library/react": "15.0.7",
110
110
  "@types/jest": "29.5.2",
111
111
  "@types/lodash": "^4.14.191",