@replohq/sandbox-runtime 1.10.2 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/_vendor/replo-utils/lib/fonts.d.ts +12 -1
  2. package/_vendor/replo-utils/lib/fonts.mjs +41 -3
  3. package/_vendor/replo-utils/lib/miniappPreview.d.ts +13 -0
  4. package/_vendor/replo-utils/lib/miniappPreview.mjs +48 -0
  5. package/_vendor/replo-utils/lib/misc.d.ts +4 -0
  6. package/_vendor/replo-utils/lib/misc.mjs +1 -1
  7. package/_vendor/schemas/componentPreview.d.ts +0 -55
  8. package/_vendor/schemas/componentPreview.mjs +1 -45
  9. package/_vendor/schemas/designLibrary.d.ts +23 -0
  10. package/_vendor/schemas/designLibrary.mjs +8 -1
  11. package/_vendor/schemas/generated/componentPreview.d.ts +0 -34
  12. package/_vendor/schemas/generated/selectMode.d.ts +8 -0
  13. package/_vendor/schemas/iframeRpcChannel.mjs +1 -1
  14. package/_vendor/schemas/selectMode.d.ts +25 -1
  15. package/_vendor/schemas/selectMode.mjs +2 -2
  16. package/_vendor/schemas/selectModeIframeRpc.d.ts +45 -5
  17. package/_vendor/schemas/selectModeIframeRpc.mjs +2 -2
  18. package/annotations/bridgeGate.d.ts +0 -5
  19. package/annotations/bridgeGate.js +2 -1
  20. package/buildMetadata.js +3 -3
  21. package/capturePage.d.ts +6 -0
  22. package/capturePage.js +118 -6
  23. package/{chunk-NBVMONRN.mjs → chunk-KFJZ2OLV.mjs} +10 -2
  24. package/{chunk-JUKCUPQ6.mjs → chunk-PH3S6LJI.mjs} +21 -1
  25. package/package.json +4 -4
  26. package/select-mode/descriptor/elementDescriptor.js +10 -2
  27. package/select-mode/descriptor/styleExtraction.d.ts +4 -0
  28. package/select-mode/descriptor/styleExtraction.js +143 -19
  29. package/select-mode/hooks/useOptimisticOverrides.js +7 -0
  30. package/select-mode/hooks/useSelectionInteractions.js +7 -5
  31. package/select-mode/iframeRpcChannel.d.ts +16 -1
  32. package/select-mode/selectModeStore.js +5 -1
@@ -10,7 +10,24 @@ const CONTROL_STYLE_PROPERTIES = [
10
10
  "font-weight",
11
11
  "line-height",
12
12
  "letter-spacing",
13
- "text-align"
13
+ "text-align",
14
+ "padding-top",
15
+ "padding-right",
16
+ "padding-bottom",
17
+ "padding-left",
18
+ "margin-top",
19
+ "margin-right",
20
+ "margin-bottom",
21
+ "margin-left",
22
+ "border-top-left-radius",
23
+ "border-top-right-radius",
24
+ "border-bottom-right-radius",
25
+ "border-bottom-left-radius",
26
+ "opacity",
27
+ "border-width",
28
+ "border-style",
29
+ "border-color",
30
+ "box-shadow"
14
31
  ];
15
32
  const CONTROL_STYLE_PROPERTY_SET = new Set(CONTROL_STYLE_PROPERTIES);
16
33
  function isControlStyleProperty(propertyName) {
@@ -88,6 +105,57 @@ function getDefinedStyleKey({
88
105
  }) {
89
106
  return `${property}:${getStyleVariantKey(variant)}`;
90
107
  }
108
+ function getVariantApplicability(variant) {
109
+ if (!variant) {
110
+ return "applies";
111
+ }
112
+ if (variant.pseudo) {
113
+ return "skipped";
114
+ }
115
+ let applicability = "applies";
116
+ for (const atRule of variant.atRules) {
117
+ if (atRule.type === "@media") {
118
+ if (!window.matchMedia(atRule.text).matches) {
119
+ return "skipped";
120
+ }
121
+ } else if (atRule.type === "@supports") {
122
+ if (!CSS.supports(atRule.text)) {
123
+ return "skipped";
124
+ }
125
+ } else {
126
+ applicability = "unknown";
127
+ }
128
+ }
129
+ return applicability;
130
+ }
131
+ function setAuthoredDeclaration({
132
+ collector,
133
+ property,
134
+ declaration
135
+ }) {
136
+ const current = collector.authoredByProperty.get(property);
137
+ if (current?.isImportant && !declaration.isImportant) {
138
+ return;
139
+ }
140
+ collector.authoredByProperty.set(property, declaration);
141
+ }
142
+ const CUSTOM_PROPERTY_PATTERN = /^var\(\s*(--[\w-]+)\s*(?:,\s*(.+))?\)$/u;
143
+ const MAX_CUSTOM_PROPERTY_DEPTH = 5;
144
+ function expandCustomProperties({
145
+ element,
146
+ value
147
+ }) {
148
+ const computedStyle = window.getComputedStyle(element);
149
+ let expanded = value;
150
+ for (let depth = 0; depth < MAX_CUSTOM_PROPERTY_DEPTH; depth += 1) {
151
+ const match = expanded.match(CUSTOM_PROPERTY_PATTERN);
152
+ if (!match?.[1]) {
153
+ return expanded;
154
+ }
155
+ expanded = computedStyle.getPropertyValue(match[1]).trim() || match[2]?.trim() || "";
156
+ }
157
+ return expanded;
158
+ }
91
159
  function getResolvedClassStyleValue({
92
160
  className,
93
161
  property,
@@ -105,7 +173,7 @@ function getResolvedClassStyleValue({
105
173
  return resolved.trim() || raw;
106
174
  }
107
175
  function setDefinedStyle({
108
- definedStylesByKey,
176
+ collector: { definedStylesByKey },
109
177
  property,
110
178
  variant,
111
179
  className,
@@ -124,7 +192,7 @@ function addRuleDefinedStyles({
124
192
  rule,
125
193
  activeAtRules,
126
194
  classNames,
127
- definedStylesByKey
195
+ collector
128
196
  }) {
129
197
  const selectorMatches = getClassSelectorMatches({
130
198
  selectorText: rule.selectorText ?? "",
@@ -138,6 +206,7 @@ function addRuleDefinedStyles({
138
206
  atRules: activeAtRules,
139
207
  pseudo: selectorMatch.pseudo
140
208
  });
209
+ const applicability = getVariantApplicability(variant);
141
210
  for (let styleIndex = 0; styleIndex < rule.style.length; styleIndex += 1) {
142
211
  const property = rule.style.item(styleIndex);
143
212
  if (!property || !isControlStyleProperty(property)) {
@@ -148,7 +217,7 @@ function addRuleDefinedStyles({
148
217
  continue;
149
218
  }
150
219
  setDefinedStyle({
151
- definedStylesByKey,
220
+ collector,
152
221
  property,
153
222
  variant,
154
223
  className: selectorMatch.className,
@@ -160,6 +229,16 @@ function addRuleDefinedStyles({
160
229
  variant
161
230
  })
162
231
  });
232
+ if (applicability !== "skipped") {
233
+ setAuthoredDeclaration({
234
+ collector,
235
+ property,
236
+ declaration: {
237
+ value: applicability === "applies" ? raw : null,
238
+ isImportant: rule.style.getPropertyPriority(property) === "important"
239
+ }
240
+ });
241
+ }
163
242
  }
164
243
  }
165
244
  }
@@ -167,7 +246,7 @@ function addStyleRulesRecursively({
167
246
  ruleList,
168
247
  activeAtRules,
169
248
  classNames,
170
- definedStylesByKey
249
+ collector
171
250
  }) {
172
251
  for (const rule of Array.from(ruleList)) {
173
252
  const nestedRuleList = getNestedRuleList(rule);
@@ -176,7 +255,7 @@ function addStyleRulesRecursively({
176
255
  ruleList: nestedRuleList,
177
256
  activeAtRules: getNestedAtRules({ rule, activeAtRules }),
178
257
  classNames,
179
- definedStylesByKey
258
+ collector
180
259
  });
181
260
  }
182
261
  if (rule instanceof CSSStyleRule) {
@@ -184,14 +263,14 @@ function addStyleRulesRecursively({
184
263
  rule,
185
264
  activeAtRules,
186
265
  classNames,
187
- definedStylesByKey
266
+ collector
188
267
  });
189
268
  }
190
269
  }
191
270
  }
192
271
  function addClassDefinedStyles({
193
272
  element,
194
- definedStylesByKey
273
+ collector
195
274
  }) {
196
275
  const classNames = Array.from(
197
276
  new Set([...element.classList].filter(Boolean))
@@ -218,7 +297,7 @@ function addClassDefinedStyles({
218
297
  ruleList: sheet.cssRules,
219
298
  activeAtRules: [],
220
299
  classNames,
221
- definedStylesByKey
300
+ collector
222
301
  });
223
302
  } catch (error) {
224
303
  if (error instanceof DOMException && error.name === "SecurityError") {
@@ -230,7 +309,7 @@ function addClassDefinedStyles({
230
309
  }
231
310
  function addInlineDefinedStyles({
232
311
  element,
233
- definedStylesByKey
312
+ collector
234
313
  }) {
235
314
  if (!(element instanceof HTMLElement)) {
236
315
  return;
@@ -245,13 +324,21 @@ function addInlineDefinedStyles({
245
324
  continue;
246
325
  }
247
326
  setDefinedStyle({
248
- definedStylesByKey,
327
+ collector,
249
328
  property,
250
329
  variant: null,
251
330
  className: null,
252
331
  raw,
253
332
  resolved: raw
254
333
  });
334
+ setAuthoredDeclaration({
335
+ collector,
336
+ property,
337
+ declaration: {
338
+ value: raw,
339
+ isImportant: element.style.getPropertyPriority(property) === "important"
340
+ }
341
+ });
255
342
  }
256
343
  }
257
344
  function getOverrideStyleDeclarations(styleElement) {
@@ -279,7 +366,7 @@ function getOverrideStyleDeclarations(styleElement) {
279
366
  }
280
367
  function addOptimisticDefinedStyles({
281
368
  element,
282
- definedStylesByKey
369
+ collector
283
370
  }) {
284
371
  const tokens = (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? "").split(/\s+/).filter(Boolean);
285
372
  if (tokens.length === 0) {
@@ -300,13 +387,23 @@ function addOptimisticDefinedStyles({
300
387
  continue;
301
388
  }
302
389
  if (raw.toLowerCase() === "revert") {
303
- definedStylesByKey.delete(
390
+ collector.definedStylesByKey.delete(
304
391
  getDefinedStyleKey({ property, variant: null })
305
392
  );
393
+ setAuthoredDeclaration({
394
+ collector,
395
+ property,
396
+ declaration: { value: null, isImportant: true }
397
+ });
306
398
  continue;
307
399
  }
400
+ setAuthoredDeclaration({
401
+ collector,
402
+ property,
403
+ declaration: { value: raw, isImportant: true }
404
+ });
308
405
  setDefinedStyle({
309
- definedStylesByKey,
406
+ collector,
310
407
  property,
311
408
  variant: null,
312
409
  className: null,
@@ -316,12 +413,38 @@ function addOptimisticDefinedStyles({
316
413
  }
317
414
  }
318
415
  }
416
+ function collectStyles(element) {
417
+ const collector = {
418
+ definedStylesByKey: /* @__PURE__ */ new Map(),
419
+ authoredByProperty: /* @__PURE__ */ new Map()
420
+ };
421
+ addClassDefinedStyles({ element, collector });
422
+ addInlineDefinedStyles({ element, collector });
423
+ addOptimisticDefinedStyles({ element, collector });
424
+ return collector;
425
+ }
426
+ function getAuthoredStyles({
427
+ element,
428
+ collector
429
+ }) {
430
+ const authoredStyles = {};
431
+ for (const [property, declaration] of collector.authoredByProperty) {
432
+ const value = declaration.value && expandCustomProperties({ element, value: declaration.value });
433
+ if (value) {
434
+ authoredStyles[property] = value;
435
+ }
436
+ }
437
+ return authoredStyles;
438
+ }
439
+ function getElementStyles(element) {
440
+ const collector = collectStyles(element);
441
+ return {
442
+ definedStyles: Array.from(collector.definedStylesByKey.values()),
443
+ authoredStyles: getAuthoredStyles({ element, collector })
444
+ };
445
+ }
319
446
  function getDefinedStyles(element) {
320
- const definedStylesByKey = /* @__PURE__ */ new Map();
321
- addClassDefinedStyles({ element, definedStylesByKey });
322
- addInlineDefinedStyles({ element, definedStylesByKey });
323
- addOptimisticDefinedStyles({ element, definedStylesByKey });
324
- return Array.from(definedStylesByKey.values());
447
+ return getElementStyles(element).definedStyles;
325
448
  }
326
449
  function getInheritedStyles(element) {
327
450
  const computedStyle = window.getComputedStyle(element);
@@ -333,5 +456,6 @@ function getInheritedStyles(element) {
333
456
  }
334
457
  export {
335
458
  getDefinedStyles,
459
+ getElementStyles,
336
460
  getInheritedStyles
337
461
  };
@@ -1,5 +1,6 @@
1
1
  import { useCallback } from "react";
2
2
  import { buildGoogleFontsCssUrl, quoteFontFamily } from "../../_vendor/replo-utils/lib/fonts.mjs";
3
+ import { z } from "zod";
3
4
  import { buildSelector } from "../descriptor/elementDescriptor";
4
5
  import { createImagePreview } from "../imageOverridePreview";
5
6
  import {
@@ -115,6 +116,12 @@ function restoreOriginalState({
115
116
  } else {
116
117
  element.setAttribute(name, value);
117
118
  }
119
+ if (name === "src" && value === null) {
120
+ const video = z.instanceof(HTMLVideoElement).safeParse(element);
121
+ if (video.success) {
122
+ video.data.load();
123
+ }
124
+ }
118
125
  }
119
126
  return;
120
127
  }
@@ -88,16 +88,14 @@ function useSelectionInteractions() {
88
88
  cancelAnimationFrame(dragAnimationFrameId);
89
89
  actions().setDragAnimationFrameId(null);
90
90
  };
91
- const resetDragState = ({
92
- notifyParentDragCleared = true
93
- } = {}) => {
91
+ const resetDragState = () => {
94
92
  const currentSession = interactionSessionRef.current;
95
93
  stopDragAnimation();
96
94
  if (currentSession.type !== "drag") {
97
95
  actions().setDragCandidates([]);
98
96
  return;
99
97
  }
100
- if (notifyParentDragCleared && currentSession.hasExceededThreshold) {
98
+ if (currentSession.hasExceededThreshold) {
101
99
  getWebsiteBuilderRpc()?.dragRectUpdated({
102
100
  dragRect: null,
103
101
  selectionRects: []
@@ -214,6 +212,10 @@ function useSelectionInteractions() {
214
212
  if (session.type !== "drag") {
215
213
  return;
216
214
  }
215
+ if ((event.buttons & 1) === 0) {
216
+ resetDragState();
217
+ return;
218
+ }
217
219
  interactionSessionRef.current = {
218
220
  ...session,
219
221
  dragCurrent: getDragPositionFromClient({
@@ -375,7 +377,7 @@ function useSelectionInteractions() {
375
377
  const dragCurrent = snapshot.type === "drag" ? snapshot.dragCurrent : null;
376
378
  const scrollOffset = snapshot.type === "drag" ? snapshot.scrollOffset : getDocumentScrollOffset();
377
379
  const candidates = store().dragCandidates;
378
- resetDragState({ notifyParentDragCleared: false });
380
+ resetDragState();
379
381
  if (snapshot.type !== "drag" || !dragStart) {
380
382
  return;
381
383
  }
@@ -50,6 +50,10 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
50
50
  previewUrl: import("zod").ZodNullable<import("zod").ZodString>;
51
51
  }, import("zod/v4/core").$strip>>;
52
52
  }, import("zod/v4/core").$strip>>;
53
+ video: import("zod").ZodOptional<import("zod").ZodObject<{
54
+ src: import("zod").ZodString;
55
+ currentSrc: import("zod").ZodString;
56
+ }, import("zod/v4/core").$strip>>;
53
57
  definedStyles: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
54
58
  property: import("zod").ZodString;
55
59
  variant: import("zod").ZodNullable<import("zod").ZodObject<{
@@ -63,6 +67,7 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
63
67
  raw: import("zod").ZodString;
64
68
  resolved: import("zod").ZodString;
65
69
  }, import("zod/v4/core").$strip>>>;
70
+ authoredStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
66
71
  inheritedStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
67
72
  clickPosition: import("zod").ZodObject<{
68
73
  x: import("zod").ZodNumber;
@@ -145,6 +150,10 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
145
150
  previewUrl: import("zod").ZodNullable<import("zod").ZodString>;
146
151
  }, import("zod/v4/core").$strip>>;
147
152
  }, import("zod/v4/core").$strip>>;
153
+ video: import("zod").ZodOptional<import("zod").ZodObject<{
154
+ src: import("zod").ZodString;
155
+ currentSrc: import("zod").ZodString;
156
+ }, import("zod/v4/core").$strip>>;
148
157
  definedStyles: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
149
158
  property: import("zod").ZodString;
150
159
  variant: import("zod").ZodNullable<import("zod").ZodObject<{
@@ -158,6 +167,7 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
158
167
  raw: import("zod").ZodString;
159
168
  resolved: import("zod").ZodString;
160
169
  }, import("zod/v4/core").$strip>>>;
170
+ authoredStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
161
171
  inheritedStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
162
172
  clickPosition: import("zod").ZodObject<{
163
173
  x: import("zod").ZodNumber;
@@ -329,6 +339,10 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
329
339
  previewUrl: import("zod").ZodNullable<import("zod").ZodString>;
330
340
  }, import("zod/v4/core").$strip>>;
331
341
  }, import("zod/v4/core").$strip>>;
342
+ video: import("zod").ZodOptional<import("zod").ZodObject<{
343
+ src: import("zod").ZodString;
344
+ currentSrc: import("zod").ZodString;
345
+ }, import("zod/v4/core").$strip>>;
332
346
  definedStyles: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
333
347
  property: import("zod").ZodString;
334
348
  variant: import("zod").ZodNullable<import("zod").ZodObject<{
@@ -342,6 +356,7 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
342
356
  raw: import("zod").ZodString;
343
357
  resolved: import("zod").ZodString;
344
358
  }, import("zod/v4/core").$strip>>>;
359
+ authoredStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
345
360
  inheritedStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
346
361
  clickPosition: import("zod").ZodObject<{
347
362
  x: import("zod").ZodNumber;
@@ -396,8 +411,8 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
396
411
  inputSchema: import("zod").ZodObject<{
397
412
  feedback: import("zod").ZodNullable<import("zod").ZodObject<{
398
413
  status: import("zod").ZodEnum<{
399
- unavailable: "unavailable";
400
414
  pending: "pending";
415
+ unavailable: "unavailable";
401
416
  failed: "failed";
402
417
  }>;
403
418
  rect: import("zod").ZodObject<{
@@ -630,7 +630,11 @@ const selectModeStore = createShallowStore(
630
630
  element: symbolicated
631
631
  });
632
632
  resolveEditRequest({ editId, allowed });
633
- }).catch(() => {
633
+ }).catch((error) => {
634
+ console.error(
635
+ "[selectMode] inline text edit prepare failed",
636
+ error
637
+ );
634
638
  if (get().editId === editId) {
635
639
  revertInlineEdit();
636
640
  } else {