@accelerated-agency/visual-editor 0.5.0 → 0.5.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.
- package/dist/index.js +583 -115
- package/dist/vite.cjs +161 -11
- package/dist/vite.js +161 -11
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5012,15 +5012,15 @@ function PlatformVisualEditorV2({
|
|
|
5012
5012
|
) }) });
|
|
5013
5013
|
}
|
|
5014
5014
|
var AI_EDITOR_CHANNEL = "ve-ai-editor";
|
|
5015
|
-
var
|
|
5016
|
-
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
}
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5015
|
+
var AI_LOCAL_STORAGE_PREFIX = "conversion-vvveb-v2::";
|
|
5016
|
+
var DEVICE_PRESETS = {
|
|
5017
|
+
desktop: { label: "Desktop", width: 1440, height: 1024, device: "desktop" },
|
|
5018
|
+
tablet: { label: "iPad", width: 768, height: 1024, device: "tablet" },
|
|
5019
|
+
mobile: { label: "iPhone 13", width: 390, height: 844, device: "mobile" },
|
|
5020
|
+
"galaxy-s22": { label: "Galaxy S22", width: 360, height: 780, device: "mobile" },
|
|
5021
|
+
"iphone-7": { label: "iPhone 7", width: 375, height: 667, device: "mobile" },
|
|
5022
|
+
"galaxy-j1": { label: "Galaxy J1", width: 360, height: 640, device: "mobile" },
|
|
5023
|
+
responsive: { label: "Responsive", width: 1280, height: 800, device: "desktop" }
|
|
5024
5024
|
};
|
|
5025
5025
|
function fingerprint(value) {
|
|
5026
5026
|
let hash = 5381;
|
|
@@ -5029,9 +5029,17 @@ function fingerprint(value) {
|
|
|
5029
5029
|
}
|
|
5030
5030
|
return (hash >>> 0).toString(36);
|
|
5031
5031
|
}
|
|
5032
|
+
function activeVariationStorageKeyFromExperiment(experiment) {
|
|
5033
|
+
const experimentId = String(experiment?.experimentId || "");
|
|
5034
|
+
const pageUrl = String(experiment?.pageUrl || "");
|
|
5035
|
+
const key = `${AI_LOCAL_STORAGE_PREFIX}activeVar:${experimentId}:${pageUrl}`;
|
|
5036
|
+
if (key === `${AI_LOCAL_STORAGE_PREFIX}activeVar::`) return null;
|
|
5037
|
+
return key;
|
|
5038
|
+
}
|
|
5032
5039
|
function PlatformAiEditor({
|
|
5033
5040
|
embeddedGlobalKey = "__CONVERSION_EMBEDDED__",
|
|
5034
5041
|
proxyBaseUrl = "",
|
|
5042
|
+
trackingMarkers = [],
|
|
5035
5043
|
chatComponent,
|
|
5036
5044
|
className = "fixed inset-0 z-[9999] flex flex-col bg-white",
|
|
5037
5045
|
editorClassName = "flex-1 min-h-0",
|
|
@@ -5061,7 +5069,20 @@ function PlatformAiEditor({
|
|
|
5061
5069
|
const [localActiveVariationId, setLocalActiveVariationId] = useState(null);
|
|
5062
5070
|
const [isSaving, setIsSaving] = useState(false);
|
|
5063
5071
|
const [isIframeLoading, setIsIframeLoading] = useState(false);
|
|
5064
|
-
const [
|
|
5072
|
+
const [currentDevice, setCurrentDevice] = useState("desktop");
|
|
5073
|
+
const [viewportWidth, setViewportWidth] = useState(1440);
|
|
5074
|
+
const [viewportHeight, setViewportHeight] = useState(1024);
|
|
5075
|
+
const [viewportZoom, setViewportZoom] = useState(1);
|
|
5076
|
+
const [viewportPreset, setViewportPreset] = useState("desktop");
|
|
5077
|
+
const [isViewportMenuOpen, setIsViewportMenuOpen] = useState(false);
|
|
5078
|
+
const [menuWidth, setMenuWidth] = useState("1440");
|
|
5079
|
+
const [menuHeight, setMenuHeight] = useState("1024");
|
|
5080
|
+
const [menuZoom, setMenuZoom] = useState("100");
|
|
5081
|
+
const [iframePanelWidth, setIframePanelWidth] = useState(null);
|
|
5082
|
+
const iframePanelRef = useRef(null);
|
|
5083
|
+
const viewportMenuRef = useRef(null);
|
|
5084
|
+
const viewportMenuButtonRef = useRef(null);
|
|
5085
|
+
const viewportLabelRef = useRef(null);
|
|
5065
5086
|
useEffect(() => {
|
|
5066
5087
|
window[embeddedGlobalKey] = true;
|
|
5067
5088
|
return () => {
|
|
@@ -5074,6 +5095,32 @@ function PlatformAiEditor({
|
|
|
5074
5095
|
const variations = experiment?.variations ?? [];
|
|
5075
5096
|
const activeVariationId = controlledActiveVariationId ?? localActiveVariationId;
|
|
5076
5097
|
const setActiveVariationId = controlledSetActiveVariationId ?? setLocalActiveVariationId;
|
|
5098
|
+
const persistedVariationStorageKey = useMemo(
|
|
5099
|
+
() => activeVariationStorageKeyFromExperiment(experiment),
|
|
5100
|
+
[experiment?.experimentId, experiment?.pageUrl]
|
|
5101
|
+
);
|
|
5102
|
+
const readPersistedVariationId = useCallback(() => {
|
|
5103
|
+
if (!persistedVariationStorageKey) return null;
|
|
5104
|
+
try {
|
|
5105
|
+
return sessionStorage.getItem(persistedVariationStorageKey);
|
|
5106
|
+
} catch {
|
|
5107
|
+
return null;
|
|
5108
|
+
}
|
|
5109
|
+
}, [persistedVariationStorageKey]);
|
|
5110
|
+
const persistVariationId = useCallback(
|
|
5111
|
+
(variationId) => {
|
|
5112
|
+
if (!persistedVariationStorageKey) return;
|
|
5113
|
+
try {
|
|
5114
|
+
if (variationId) {
|
|
5115
|
+
sessionStorage.setItem(persistedVariationStorageKey, variationId);
|
|
5116
|
+
} else {
|
|
5117
|
+
sessionStorage.removeItem(persistedVariationStorageKey);
|
|
5118
|
+
}
|
|
5119
|
+
} catch {
|
|
5120
|
+
}
|
|
5121
|
+
},
|
|
5122
|
+
[persistedVariationStorageKey]
|
|
5123
|
+
);
|
|
5077
5124
|
useEffect(() => {
|
|
5078
5125
|
if (!variations.length) {
|
|
5079
5126
|
setActiveVariationId(null);
|
|
@@ -5081,10 +5128,12 @@ function PlatformAiEditor({
|
|
|
5081
5128
|
}
|
|
5082
5129
|
setActiveVariationId((current) => {
|
|
5083
5130
|
if (current && variations.some((variation) => variation._id === current)) return current;
|
|
5084
|
-
const
|
|
5085
|
-
|
|
5131
|
+
const stored = readPersistedVariationId();
|
|
5132
|
+
if (stored && variations.some((variation) => variation._id === stored)) return stored;
|
|
5133
|
+
const firstNonBaseline = variations.find((variation) => !variation.baseline);
|
|
5134
|
+
return firstNonBaseline?._id ?? variations[0]._id;
|
|
5086
5135
|
});
|
|
5087
|
-
}, [variations]);
|
|
5136
|
+
}, [variations, readPersistedVariationId]);
|
|
5088
5137
|
const activeVariation = useMemo(
|
|
5089
5138
|
() => variations.find((variation) => variation._id === activeVariationId) ?? null,
|
|
5090
5139
|
[variations, activeVariationId]
|
|
@@ -5105,18 +5154,52 @@ function PlatformAiEditor({
|
|
|
5105
5154
|
() => `ai-iframe-${activeVariationId ?? "default"}-${cssFingerprint}-${jsFingerprint}`,
|
|
5106
5155
|
[activeVariationId, cssFingerprint, jsFingerprint]
|
|
5107
5156
|
);
|
|
5108
|
-
|
|
5157
|
+
useEffect(() => {
|
|
5158
|
+
const panel = iframePanelRef.current;
|
|
5159
|
+
if (!panel) return;
|
|
5160
|
+
const updateWidth = () => {
|
|
5161
|
+
setIframePanelWidth(panel.clientWidth);
|
|
5162
|
+
};
|
|
5163
|
+
updateWidth();
|
|
5164
|
+
const observer = new ResizeObserver(() => {
|
|
5165
|
+
updateWidth();
|
|
5166
|
+
});
|
|
5167
|
+
observer.observe(panel);
|
|
5168
|
+
return () => {
|
|
5169
|
+
observer.disconnect();
|
|
5170
|
+
};
|
|
5171
|
+
}, []);
|
|
5172
|
+
const viewportFitZoom = useMemo(() => {
|
|
5173
|
+
const available = iframePanelWidth ? Math.max(260, iframePanelWidth - 24) : viewportWidth;
|
|
5174
|
+
if (!viewportWidth || viewportWidth <= 0) return 1;
|
|
5175
|
+
return Math.min(1, available / viewportWidth);
|
|
5176
|
+
}, [viewportWidth, iframePanelWidth]);
|
|
5177
|
+
const appliedViewportZoom = useMemo(() => {
|
|
5178
|
+
let z = Number(viewportZoom);
|
|
5179
|
+
if (!Number.isFinite(z) || z <= 0) z = 1;
|
|
5180
|
+
z = Math.max(0.25, Math.min(2, z));
|
|
5181
|
+
return Math.min(z, viewportFitZoom);
|
|
5182
|
+
}, [viewportZoom, viewportFitZoom]);
|
|
5183
|
+
const viewportLabel = useMemo(
|
|
5184
|
+
() => `${viewportWidth}x${viewportHeight} \xB7 ${Math.round(appliedViewportZoom * 100)}%`,
|
|
5185
|
+
[viewportWidth, viewportHeight, appliedViewportZoom]
|
|
5186
|
+
);
|
|
5109
5187
|
const editorSrc = useMemo(() => {
|
|
5110
5188
|
const pageUrl = experiment?.pageUrl;
|
|
5111
5189
|
if (!pageUrl) return "about:blank";
|
|
5112
5190
|
const safeBaseUrl = normalizeProxyBaseUrl(proxyBaseUrl);
|
|
5113
|
-
const
|
|
5191
|
+
const safeTrackingMarkers = Array.isArray(trackingMarkers) ? trackingMarkers.filter((marker) => typeof marker === "string" && marker.trim().length > 0) : [];
|
|
5192
|
+
const queryParams = new URLSearchParams({
|
|
5114
5193
|
password: experiment?.editorPassword ?? "",
|
|
5115
5194
|
url: pageUrl
|
|
5116
|
-
})
|
|
5195
|
+
});
|
|
5196
|
+
if (safeTrackingMarkers.length) {
|
|
5197
|
+
queryParams.set("trackingMarkers", JSON.stringify(safeTrackingMarkers));
|
|
5198
|
+
}
|
|
5199
|
+
const query = queryParams.toString();
|
|
5117
5200
|
const previewPath = `/api/conversion-proxy?${query}`;
|
|
5118
5201
|
return safeBaseUrl ? `${safeBaseUrl}${previewPath}` : previewPath;
|
|
5119
|
-
}, [proxyBaseUrl, experiment?.pageUrl, experiment?.editorPassword]);
|
|
5202
|
+
}, [proxyBaseUrl, experiment?.pageUrl, experiment?.editorPassword, trackingMarkers]);
|
|
5120
5203
|
const postAiCodeToIframe = useCallback(() => {
|
|
5121
5204
|
const targetWindow = iframeRef.current?.contentWindow;
|
|
5122
5205
|
if (!targetWindow) return;
|
|
@@ -5233,6 +5316,90 @@ function PlatformAiEditor({
|
|
|
5233
5316
|
onSaveSuccess,
|
|
5234
5317
|
onSaveError
|
|
5235
5318
|
]);
|
|
5319
|
+
const clampViewportNumber = useCallback(
|
|
5320
|
+
(value, fallback, min, max) => {
|
|
5321
|
+
const parsed = Number.parseInt(value, 10);
|
|
5322
|
+
if (!Number.isFinite(parsed)) return fallback;
|
|
5323
|
+
return Math.max(min, Math.min(max, parsed));
|
|
5324
|
+
},
|
|
5325
|
+
[]
|
|
5326
|
+
);
|
|
5327
|
+
const setDevicePreset = useCallback((device) => {
|
|
5328
|
+
const preset = DEVICE_PRESETS[device];
|
|
5329
|
+
setViewportPreset(device);
|
|
5330
|
+
setCurrentDevice(device);
|
|
5331
|
+
setViewportWidth(preset.width);
|
|
5332
|
+
setViewportHeight(preset.height);
|
|
5333
|
+
setMenuWidth(String(preset.width));
|
|
5334
|
+
setMenuHeight(String(preset.height));
|
|
5335
|
+
}, []);
|
|
5336
|
+
const setViewportFromPreset = useCallback((presetKey) => {
|
|
5337
|
+
const preset = DEVICE_PRESETS[presetKey];
|
|
5338
|
+
setViewportPreset(presetKey);
|
|
5339
|
+
setViewportWidth(preset.width);
|
|
5340
|
+
setViewportHeight(preset.height);
|
|
5341
|
+
setCurrentDevice(preset.device);
|
|
5342
|
+
setMenuWidth(String(preset.width));
|
|
5343
|
+
setMenuHeight(String(preset.height));
|
|
5344
|
+
}, []);
|
|
5345
|
+
const applyCustomViewport = useCallback(() => {
|
|
5346
|
+
const nextWidth = clampViewportNumber(menuWidth, viewportWidth, 240, 3840);
|
|
5347
|
+
const nextHeight = clampViewportNumber(menuHeight, viewportHeight, 320, 3840);
|
|
5348
|
+
const nextZoomPct = clampViewportNumber(
|
|
5349
|
+
menuZoom,
|
|
5350
|
+
Math.round(appliedViewportZoom * 100),
|
|
5351
|
+
25,
|
|
5352
|
+
200
|
|
5353
|
+
);
|
|
5354
|
+
setViewportWidth(nextWidth);
|
|
5355
|
+
setViewportHeight(nextHeight);
|
|
5356
|
+
setViewportZoom(nextZoomPct / 100);
|
|
5357
|
+
setViewportPreset("custom");
|
|
5358
|
+
setCurrentDevice(nextWidth <= 480 ? "mobile" : nextWidth <= 1024 ? "tablet" : "desktop");
|
|
5359
|
+
setMenuWidth(String(nextWidth));
|
|
5360
|
+
setMenuHeight(String(nextHeight));
|
|
5361
|
+
setMenuZoom(String(nextZoomPct));
|
|
5362
|
+
setIsViewportMenuOpen(false);
|
|
5363
|
+
}, [
|
|
5364
|
+
clampViewportNumber,
|
|
5365
|
+
menuWidth,
|
|
5366
|
+
menuHeight,
|
|
5367
|
+
menuZoom,
|
|
5368
|
+
viewportWidth,
|
|
5369
|
+
viewportHeight,
|
|
5370
|
+
appliedViewportZoom
|
|
5371
|
+
]);
|
|
5372
|
+
useEffect(() => {
|
|
5373
|
+
setMenuWidth(String(viewportWidth));
|
|
5374
|
+
setMenuHeight(String(viewportHeight));
|
|
5375
|
+
setMenuZoom(String(Math.round(appliedViewportZoom * 100)));
|
|
5376
|
+
}, [viewportWidth, viewportHeight, appliedViewportZoom]);
|
|
5377
|
+
useEffect(() => {
|
|
5378
|
+
const onWindowResize = () => {
|
|
5379
|
+
setMenuZoom(String(Math.round(Math.min(viewportZoom, viewportFitZoom) * 100)));
|
|
5380
|
+
};
|
|
5381
|
+
window.addEventListener("resize", onWindowResize);
|
|
5382
|
+
return () => window.removeEventListener("resize", onWindowResize);
|
|
5383
|
+
}, [viewportZoom, viewportFitZoom]);
|
|
5384
|
+
useEffect(() => {
|
|
5385
|
+
if (!isViewportMenuOpen) return;
|
|
5386
|
+
const onDocClick = (event) => {
|
|
5387
|
+
const target = event.target;
|
|
5388
|
+
if (viewportMenuRef.current?.contains(target)) return;
|
|
5389
|
+
if (viewportMenuButtonRef.current?.contains(target)) return;
|
|
5390
|
+
if (viewportLabelRef.current?.contains(target)) return;
|
|
5391
|
+
setIsViewportMenuOpen(false);
|
|
5392
|
+
};
|
|
5393
|
+
const onDocKeyDown = (event) => {
|
|
5394
|
+
if (event.key === "Escape") setIsViewportMenuOpen(false);
|
|
5395
|
+
};
|
|
5396
|
+
document.addEventListener("click", onDocClick);
|
|
5397
|
+
document.addEventListener("keydown", onDocKeyDown);
|
|
5398
|
+
return () => {
|
|
5399
|
+
document.removeEventListener("click", onDocClick);
|
|
5400
|
+
document.removeEventListener("keydown", onDocKeyDown);
|
|
5401
|
+
};
|
|
5402
|
+
}, [isViewportMenuOpen]);
|
|
5236
5403
|
if (error) {
|
|
5237
5404
|
if (renderError) return renderError(error);
|
|
5238
5405
|
return /* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-[9999] flex items-center justify-center bg-slate-50", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-center px-8", children: [
|
|
@@ -5241,112 +5408,413 @@ function PlatformAiEditor({
|
|
|
5241
5408
|
/* @__PURE__ */ jsx("p", { className: "text-xs text-red-400", children: error })
|
|
5242
5409
|
] }) });
|
|
5243
5410
|
}
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5251
|
-
|
|
5252
|
-
|
|
5253
|
-
|
|
5254
|
-
|
|
5255
|
-
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
|
|
5260
|
-
|
|
5261
|
-
|
|
5262
|
-
|
|
5263
|
-
|
|
5264
|
-
|
|
5265
|
-
|
|
5266
|
-
|
|
5267
|
-
|
|
5268
|
-
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5411
|
+
const handleVariationSelectChange = useCallback(
|
|
5412
|
+
(nextVariationId) => {
|
|
5413
|
+
persistVariationId(nextVariationId);
|
|
5414
|
+
setActiveVariationId(nextVariationId);
|
|
5415
|
+
},
|
|
5416
|
+
[persistVariationId, setActiveVariationId]
|
|
5417
|
+
);
|
|
5418
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5419
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
5420
|
+
.ai-dev-toolbar {
|
|
5421
|
+
display: flex;
|
|
5422
|
+
align-items: center;
|
|
5423
|
+
gap: 8px;
|
|
5424
|
+
}
|
|
5425
|
+
.ai-tb-viewport {
|
|
5426
|
+
display: flex;
|
|
5427
|
+
align-items: center;
|
|
5428
|
+
gap: 4px;
|
|
5429
|
+
padding: 6px 10px;
|
|
5430
|
+
border-radius: 6px;
|
|
5431
|
+
border: 1px solid #e5e7eb;
|
|
5432
|
+
background: #fff;
|
|
5433
|
+
height: 30px;
|
|
5434
|
+
flex-shrink: 0;
|
|
5435
|
+
cursor: pointer;
|
|
5436
|
+
color: #404040;
|
|
5437
|
+
font-size: 14px;
|
|
5438
|
+
font-weight: 500;
|
|
5439
|
+
line-height: 1;
|
|
5440
|
+
}
|
|
5441
|
+
.ai-tb-viewport > i {
|
|
5442
|
+
font-size: 9px;
|
|
5443
|
+
}
|
|
5444
|
+
.ai-tb-dev-wrap {
|
|
5445
|
+
position: relative;
|
|
5446
|
+
}
|
|
5447
|
+
.ai-tb-dev-btns {
|
|
5448
|
+
display: flex;
|
|
5449
|
+
align-items: center;
|
|
5450
|
+
gap: 1px;
|
|
5451
|
+
padding: 8px 4px;
|
|
5452
|
+
background: #f0f0f0;
|
|
5453
|
+
border-radius: 7px;
|
|
5454
|
+
height: 30px;
|
|
5455
|
+
width: auto;
|
|
5456
|
+
}
|
|
5457
|
+
.ai-tb-dk-btn {
|
|
5458
|
+
width: 28px;
|
|
5459
|
+
height: 28px;
|
|
5460
|
+
background: transparent;
|
|
5461
|
+
border: none;
|
|
5462
|
+
border-radius: 5px;
|
|
5463
|
+
cursor: pointer;
|
|
5464
|
+
color: #71717a;
|
|
5465
|
+
display: flex;
|
|
5466
|
+
align-items: center;
|
|
5467
|
+
justify-content: center;
|
|
5468
|
+
font-size: 13px;
|
|
5469
|
+
transition: all 0.12s;
|
|
5470
|
+
flex-shrink: 0;
|
|
5471
|
+
}
|
|
5472
|
+
.ai-tb-dk-btn.active {
|
|
5473
|
+
background: #fff;
|
|
5474
|
+
color: #27272a;
|
|
5475
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
|
|
5476
|
+
}
|
|
5477
|
+
.ai-tb-dev-menu {
|
|
5478
|
+
position: absolute;
|
|
5479
|
+
top: calc(100% + 8px);
|
|
5480
|
+
right: 0;
|
|
5481
|
+
z-index: 12040;
|
|
5482
|
+
width: 264px;
|
|
5483
|
+
background: #fff;
|
|
5484
|
+
border: 1px solid #e5e7eb;
|
|
5485
|
+
border-radius: 8px;
|
|
5486
|
+
padding: 4px 4px;
|
|
5487
|
+
box-shadow: 0 12px 28px rgba(2, 6, 23, 0.18);
|
|
5488
|
+
color: #27272a;
|
|
5489
|
+
}
|
|
5490
|
+
.ai-tb-dev-menu > .row {
|
|
5491
|
+
display: flex;
|
|
5492
|
+
align-items: center;
|
|
5493
|
+
gap: 8px;
|
|
5494
|
+
margin: 0 0 8px;
|
|
5495
|
+
justify-content: space-between;
|
|
5496
|
+
padding: 4px 12px;
|
|
5497
|
+
}
|
|
5498
|
+
.ai-tb-dev-menu .row-split {
|
|
5499
|
+
display: flex;
|
|
5500
|
+
gap: 8px;
|
|
5501
|
+
}
|
|
5502
|
+
.ai-tb-dev-menu .row-split > .row{
|
|
5503
|
+
flex-direction: column;
|
|
5504
|
+
align-items: flex-start;
|
|
5505
|
+
}
|
|
5506
|
+
.ai-tb-dev-menu .row-split > * {
|
|
5507
|
+
flex: 1;
|
|
5508
|
+
}
|
|
5509
|
+
.ai-tb-dev-menu .row-split > row {
|
|
5510
|
+
display: flex;
|
|
5511
|
+
flex-direction: column;
|
|
5512
|
+
align-items: flex-start;
|
|
5513
|
+
}
|
|
5514
|
+
.ai-tb-dev-menu label {
|
|
5515
|
+
min-width: fit-content;
|
|
5516
|
+
color: var(--content-subtle, #737373);
|
|
5517
|
+
font-size: 12px;
|
|
5518
|
+
font-style: normal;
|
|
5519
|
+
font-weight: 500;
|
|
5520
|
+
line-height: 14px;
|
|
5521
|
+
}
|
|
5522
|
+
.ai-tb-dev-menu input {
|
|
5523
|
+
box-shadow: 0 0 1px 0 rgba(0, 0, 0, 0.20), 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 1px 1px 0 rgba(0, 0, 0, 0.01);
|
|
5524
|
+
width: 100%;
|
|
5525
|
+
height: 30px;
|
|
5526
|
+
border-radius: 6px;
|
|
5527
|
+
padding: 0 8px;
|
|
5528
|
+
font-size: 12px;
|
|
5529
|
+
color: #18181b;
|
|
5530
|
+
background: #fff;
|
|
5531
|
+
outline: none;
|
|
5532
|
+
color: #404040;
|
|
5533
|
+
border-color: transparent;
|
|
5534
|
+
}
|
|
5535
|
+
.ai-tb-dev-menu input#ai-dev-zoom-level {
|
|
5536
|
+
max-width: fit-content;
|
|
5537
|
+
width: 72px;
|
|
5538
|
+
}
|
|
5539
|
+
.ai-tb-dev-menu input:focus {
|
|
5540
|
+
border-color: #818cf8;
|
|
5541
|
+
box-shadow: 0 0 0 3px rgba(129, 140, 248, 0.15);
|
|
5542
|
+
}
|
|
5543
|
+
.ai-vp-presets {
|
|
5544
|
+
display: flex;
|
|
5545
|
+
flex-wrap: wrap;
|
|
5546
|
+
gap: 6px;
|
|
5547
|
+
padding: 4px 12px;
|
|
5548
|
+
}
|
|
5549
|
+
.ai-vp-preset-btn {
|
|
5550
|
+
border: 1px solid #e4e4e7;
|
|
5551
|
+
background: #fff;
|
|
5552
|
+
color: #3f3f46;
|
|
5553
|
+
border-radius: 6px;
|
|
5554
|
+
font-size: 11px;
|
|
5555
|
+
line-height: 1;
|
|
5556
|
+
padding: 7px 8px;
|
|
5557
|
+
cursor: pointer;
|
|
5558
|
+
}
|
|
5559
|
+
.ai-vp-preset-btn:hover,
|
|
5560
|
+
.ai-vp-preset-btn.active {
|
|
5561
|
+
background: #f4f4f5;
|
|
5562
|
+
}
|
|
5563
|
+
.ai-dev-ft {
|
|
5564
|
+
display: flex;
|
|
5565
|
+
justify-content: flex-end;
|
|
5566
|
+
padding: 4px 12px;
|
|
5567
|
+
}
|
|
5568
|
+
.ai-apply-btn {
|
|
5569
|
+
border: 1px solid #c7d2fe;
|
|
5570
|
+
background: #eef2ff;
|
|
5571
|
+
color: #3730a3;
|
|
5572
|
+
border-radius: 6px;
|
|
5573
|
+
height: 30px;
|
|
5574
|
+
padding: 0 10px;
|
|
5575
|
+
font-size: 12px;
|
|
5576
|
+
font-weight: 600;
|
|
5577
|
+
cursor: pointer;
|
|
5578
|
+
}
|
|
5579
|
+
.ai-apply-btn:hover {
|
|
5580
|
+
background: #e0e7ff;
|
|
5581
|
+
border-color: #a5b4fc;
|
|
5582
|
+
}
|
|
5583
|
+
|
|
5584
|
+
` }),
|
|
5585
|
+
/* @__PURE__ */ jsxs("div", { className, children: [
|
|
5586
|
+
showHeader ? renderHeader?.({
|
|
5587
|
+
title: title ?? experiment?.name,
|
|
5588
|
+
status: status ?? experiment?.status,
|
|
5589
|
+
tabs,
|
|
5590
|
+
activeTab,
|
|
5591
|
+
onTabClick,
|
|
5592
|
+
onClose
|
|
5593
|
+
}) ?? /* @__PURE__ */ jsxs("div", { className: "h-12 border-b border-slate-200 bg-white flex items-center justify-between px-4 shadow-[0_1px_3px_rgba(0,0,0,0.04)] shrink-0", children: [
|
|
5594
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5 min-w-0", children: [
|
|
5595
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold tracking-wide px-1.5 py-0.5 rounded bg-indigo-50 text-indigo-600 border border-indigo-100 shrink-0", children: "AI" }),
|
|
5596
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold text-sm text-slate-800 truncate", children: title ?? experiment?.name ?? "AI Editor" }),
|
|
5597
|
+
status ? /* @__PURE__ */ jsx("span", { className: "hidden sm:inline-flex text-[10px] px-2 py-0.5 rounded-full border border-slate-200 text-slate-500 font-medium bg-slate-50 capitalize", children: status }) : null
|
|
5272
5598
|
] }),
|
|
5273
|
-
/* @__PURE__ */ jsx("div", { className: "
|
|
5274
|
-
{ key: "desktop", icon: "bi-display", title: "Desktop \u2014 full width" },
|
|
5275
|
-
{ key: "tablet", icon: "bi-tablet", title: "Tablet \u2014 768px" },
|
|
5276
|
-
{ key: "mobile", icon: "bi-phone", title: "Mobile \u2014 390px" }
|
|
5277
|
-
].map((vp) => /* @__PURE__ */ jsx(
|
|
5599
|
+
tabs.length > 0 ? /* @__PURE__ */ jsx("div", { className: "hidden md:flex items-center gap-1 absolute left-1/2 -translate-x-1/2", children: tabs.map((tab) => /* @__PURE__ */ jsx(
|
|
5278
5600
|
"button",
|
|
5279
5601
|
{
|
|
5280
5602
|
type: "button",
|
|
5281
|
-
onClick: () =>
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
children: /* @__PURE__ */ jsx("i", { className: `bi ${vp.icon} text-[12px]` })
|
|
5603
|
+
onClick: () => onTabClick(tab),
|
|
5604
|
+
className: `text-[11px] font-semibold px-3 py-1 rounded-full border transition-all ${tab.label === activeTab ? "bg-indigo-600 text-white border-indigo-600 shadow-sm" : "bg-white text-slate-500 border-slate-200 hover:border-slate-300 hover:text-slate-700"}`,
|
|
5605
|
+
children: tab.label
|
|
5285
5606
|
},
|
|
5286
|
-
|
|
5287
|
-
)) })
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5302
|
-
|
|
5303
|
-
|
|
5304
|
-
|
|
5305
|
-
|
|
5306
|
-
|
|
5307
|
-
|
|
5308
|
-
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5607
|
+
tab.hash
|
|
5608
|
+
)) }) : null,
|
|
5609
|
+
/* @__PURE__ */ jsxs("div", { className: "ai-dev-toolbar", children: [
|
|
5610
|
+
/* @__PURE__ */ jsxs(
|
|
5611
|
+
"div",
|
|
5612
|
+
{
|
|
5613
|
+
ref: viewportLabelRef,
|
|
5614
|
+
role: "button",
|
|
5615
|
+
tabIndex: 0,
|
|
5616
|
+
className: "ai-tb-viewport",
|
|
5617
|
+
onClick: () => setIsViewportMenuOpen((prev) => !prev),
|
|
5618
|
+
onKeyDown: (event) => {
|
|
5619
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
5620
|
+
event.preventDefault();
|
|
5621
|
+
setIsViewportMenuOpen((prev) => !prev);
|
|
5622
|
+
}
|
|
5623
|
+
},
|
|
5624
|
+
children: [
|
|
5625
|
+
/* @__PURE__ */ jsx("span", { children: viewportLabel }),
|
|
5626
|
+
/* @__PURE__ */ jsx("i", { className: "bi bi-chevron-down" })
|
|
5627
|
+
]
|
|
5628
|
+
}
|
|
5629
|
+
),
|
|
5630
|
+
/* @__PURE__ */ jsxs("div", { className: "ai-tb-dev-wrap", children: [
|
|
5631
|
+
/* @__PURE__ */ jsxs("div", { className: "ai-tb-dev-btns", children: [
|
|
5632
|
+
[
|
|
5633
|
+
{ key: "desktop", icon: "bi-display", title: "Desktop \u2014 full width" },
|
|
5634
|
+
{ key: "tablet", icon: "bi-tablet", title: "Tablet \u2014 768px" },
|
|
5635
|
+
{ key: "mobile", icon: "bi-phone", title: "Mobile \u2014 390px" }
|
|
5636
|
+
].map((vp) => /* @__PURE__ */ jsx(
|
|
5637
|
+
"button",
|
|
5638
|
+
{
|
|
5639
|
+
type: "button",
|
|
5640
|
+
onClick: () => setDevicePreset(vp.key),
|
|
5641
|
+
title: vp.title,
|
|
5642
|
+
className: `ai-tb-dk-btn ${currentDevice === vp.key ? "active" : ""}`,
|
|
5643
|
+
children: /* @__PURE__ */ jsx("i", { className: `bi ${vp.icon}` })
|
|
5644
|
+
},
|
|
5645
|
+
vp.key
|
|
5646
|
+
)),
|
|
5647
|
+
/* @__PURE__ */ jsx(
|
|
5648
|
+
"button",
|
|
5649
|
+
{
|
|
5650
|
+
ref: viewportMenuButtonRef,
|
|
5651
|
+
type: "button",
|
|
5652
|
+
onClick: () => setIsViewportMenuOpen((prev) => !prev),
|
|
5653
|
+
title: "More options",
|
|
5654
|
+
className: `ai-tb-dk-btn ${isViewportMenuOpen ? "active" : ""}`,
|
|
5655
|
+
children: /* @__PURE__ */ jsx("i", { className: "bi bi-three-dots" })
|
|
5656
|
+
}
|
|
5657
|
+
)
|
|
5658
|
+
] }),
|
|
5659
|
+
isViewportMenuOpen ? /* @__PURE__ */ jsxs(
|
|
5660
|
+
"div",
|
|
5661
|
+
{
|
|
5662
|
+
ref: viewportMenuRef,
|
|
5663
|
+
className: "ai-tb-dev-menu",
|
|
5664
|
+
children: [
|
|
5665
|
+
/* @__PURE__ */ jsxs("div", { className: "row row-zoom", children: [
|
|
5666
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "ai-dev-zoom-level", children: "Zoom" }),
|
|
5667
|
+
/* @__PURE__ */ jsx(
|
|
5668
|
+
"input",
|
|
5669
|
+
{
|
|
5670
|
+
id: "ai-dev-zoom-level",
|
|
5671
|
+
type: "number",
|
|
5672
|
+
min: 25,
|
|
5673
|
+
max: 200,
|
|
5674
|
+
step: 5,
|
|
5675
|
+
value: menuZoom,
|
|
5676
|
+
onChange: (event) => setMenuZoom(event.target.value),
|
|
5677
|
+
onBlur: (event) => {
|
|
5678
|
+
const nextZoomPct = clampViewportNumber(
|
|
5679
|
+
event.target.value,
|
|
5680
|
+
Math.round(appliedViewportZoom * 100),
|
|
5681
|
+
25,
|
|
5682
|
+
200
|
|
5683
|
+
);
|
|
5684
|
+
setViewportZoom(nextZoomPct / 100);
|
|
5685
|
+
setMenuZoom(String(nextZoomPct));
|
|
5686
|
+
}
|
|
5687
|
+
}
|
|
5688
|
+
)
|
|
5689
|
+
] }),
|
|
5690
|
+
/* @__PURE__ */ jsxs("div", { className: "row row-split row-width height-width-row", children: [
|
|
5691
|
+
/* @__PURE__ */ jsxs("div", { className: "row", style: { margin: 0 }, children: [
|
|
5692
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "ai-dev-custom-width", children: "Width" }),
|
|
5693
|
+
/* @__PURE__ */ jsx(
|
|
5694
|
+
"input",
|
|
5695
|
+
{
|
|
5696
|
+
id: "ai-dev-custom-width",
|
|
5697
|
+
type: "number",
|
|
5698
|
+
min: 240,
|
|
5699
|
+
max: 3840,
|
|
5700
|
+
step: 1,
|
|
5701
|
+
value: menuWidth,
|
|
5702
|
+
onChange: (event) => setMenuWidth(event.target.value)
|
|
5703
|
+
}
|
|
5704
|
+
)
|
|
5705
|
+
] }),
|
|
5706
|
+
/* @__PURE__ */ jsxs("div", { className: "row", style: { margin: 0 }, children: [
|
|
5707
|
+
/* @__PURE__ */ jsx("label", { htmlFor: "ai-dev-custom-height", children: "Height" }),
|
|
5708
|
+
/* @__PURE__ */ jsx(
|
|
5709
|
+
"input",
|
|
5710
|
+
{
|
|
5711
|
+
id: "ai-dev-custom-height",
|
|
5712
|
+
type: "number",
|
|
5713
|
+
min: 320,
|
|
5714
|
+
max: 3840,
|
|
5715
|
+
step: 1,
|
|
5716
|
+
value: menuHeight,
|
|
5717
|
+
onChange: (event) => setMenuHeight(event.target.value)
|
|
5718
|
+
}
|
|
5719
|
+
)
|
|
5720
|
+
] })
|
|
5721
|
+
] }),
|
|
5722
|
+
/* @__PURE__ */ jsx("div", { className: "ai-vp-presets vp-presets", id: "dev-preset-list", children: [
|
|
5723
|
+
{ key: "desktop", label: "Desktop" },
|
|
5724
|
+
{ key: "mobile", label: "iPhone 13" },
|
|
5725
|
+
{ key: "galaxy-s22", label: "Galaxy S22" },
|
|
5726
|
+
{ key: "tablet", label: "iPad" },
|
|
5727
|
+
{ key: "galaxy-j1", label: "Galaxy J1" },
|
|
5728
|
+
{ key: "iphone-7", label: "iPhone 7" },
|
|
5729
|
+
{ key: "responsive", label: "Responsive" }
|
|
5730
|
+
].map((preset) => /* @__PURE__ */ jsx(
|
|
5731
|
+
"button",
|
|
5732
|
+
{
|
|
5733
|
+
type: "button",
|
|
5734
|
+
onClick: () => setViewportFromPreset(preset.key),
|
|
5735
|
+
className: `ai-vp-preset-btn ${viewportPreset === preset.key ? "active" : ""}`,
|
|
5736
|
+
children: preset.label
|
|
5737
|
+
},
|
|
5738
|
+
preset.key
|
|
5739
|
+
)) }),
|
|
5740
|
+
/* @__PURE__ */ jsx("div", { className: "ai-dev-ft", children: /* @__PURE__ */ jsx(
|
|
5741
|
+
"button",
|
|
5742
|
+
{
|
|
5743
|
+
type: "button",
|
|
5744
|
+
onClick: applyCustomViewport,
|
|
5745
|
+
className: "ai-apply-btn",
|
|
5746
|
+
children: "Apply"
|
|
5747
|
+
}
|
|
5748
|
+
) })
|
|
5749
|
+
]
|
|
5750
|
+
}
|
|
5751
|
+
) : null
|
|
5752
|
+
] })
|
|
5753
|
+
] }),
|
|
5754
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
5755
|
+
variations.length > 0 ? /* @__PURE__ */ jsx(
|
|
5756
|
+
"select",
|
|
5757
|
+
{
|
|
5758
|
+
className: "h-8 max-w-[220px] rounded-md border border-slate-200 bg-white px-2 text-xs text-slate-700",
|
|
5759
|
+
value: activeVariationId ?? "",
|
|
5760
|
+
onChange: (event) => handleVariationSelectChange(event.target.value || null),
|
|
5761
|
+
"aria-label": "Select variation",
|
|
5762
|
+
children: variations.map((variation) => /* @__PURE__ */ jsx("option", { value: variation._id, children: variation.name }, variation._id))
|
|
5763
|
+
}
|
|
5764
|
+
) : null,
|
|
5765
|
+
onRequestSave ? /* @__PURE__ */ jsx(
|
|
5766
|
+
"button",
|
|
5767
|
+
{
|
|
5768
|
+
type: "button",
|
|
5769
|
+
className: "text-[11px] font-medium px-3 py-1.5 rounded-md border border-indigo-200 text-indigo-700 bg-indigo-50 hover:bg-indigo-100 hover:border-indigo-300 transition-all disabled:opacity-60 disabled:cursor-not-allowed",
|
|
5770
|
+
onClick: () => void handleSave(),
|
|
5771
|
+
disabled: isSaving,
|
|
5772
|
+
children: isSaving ? "Saving..." : "Save"
|
|
5773
|
+
}
|
|
5774
|
+
) : null,
|
|
5775
|
+
showCloseButton ? /* @__PURE__ */ jsx(
|
|
5776
|
+
"button",
|
|
5777
|
+
{
|
|
5778
|
+
type: "button",
|
|
5779
|
+
className: "text-[11px] font-medium px-3 py-1.5 rounded-md border border-slate-200 text-slate-600 hover:bg-slate-50 hover:border-slate-300 transition-all",
|
|
5780
|
+
onClick: () => onClose?.(),
|
|
5781
|
+
children: closeLabel
|
|
5782
|
+
}
|
|
5783
|
+
) : null
|
|
5784
|
+
] })
|
|
5785
|
+
] }) : null,
|
|
5786
|
+
/* @__PURE__ */ jsxs("div", { className: `${editorClassName} relative`, children: [
|
|
5787
|
+
/* @__PURE__ */ jsx("div", { ref: iframePanelRef, className: "w-full h-full bg-slate-100 overflow-auto flex justify-center items-start p-3", children: /* @__PURE__ */ jsx(
|
|
5788
|
+
"div",
|
|
5312
5789
|
{
|
|
5313
|
-
|
|
5314
|
-
|
|
5315
|
-
|
|
5316
|
-
|
|
5790
|
+
className: "h-full bg-white border border-slate-200 shadow-sm overflow-hidden",
|
|
5791
|
+
style: {
|
|
5792
|
+
width: `${viewportWidth}px`,
|
|
5793
|
+
minWidth: `${viewportWidth}px`,
|
|
5794
|
+
height: `${viewportHeight}px`,
|
|
5795
|
+
maxWidth: "none",
|
|
5796
|
+
zoom: String(appliedViewportZoom)
|
|
5797
|
+
},
|
|
5798
|
+
children: /* @__PURE__ */ jsx(
|
|
5799
|
+
"iframe",
|
|
5800
|
+
{
|
|
5801
|
+
ref: iframeRef,
|
|
5802
|
+
src: editorSrc,
|
|
5803
|
+
onLoad: handleIframeLoad,
|
|
5804
|
+
className: "w-full h-full border-0",
|
|
5805
|
+
title: "AI Editor Preview",
|
|
5806
|
+
allow: "same-origin"
|
|
5807
|
+
},
|
|
5808
|
+
iframeKey
|
|
5809
|
+
)
|
|
5317
5810
|
}
|
|
5318
|
-
)
|
|
5811
|
+
) }),
|
|
5812
|
+
isIframeLoading ? /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-slate-100/95 backdrop-blur-[1px]", children: /* @__PURE__ */ jsxs("div", { className: "w-[560px] max-w-[88vw]", children: [
|
|
5813
|
+
/* @__PURE__ */ jsx("p", { className: "mb-3 text-center text-base font-semibold text-slate-700", children: "Loading changes..." }),
|
|
5814
|
+
/* @__PURE__ */ jsx("div", { className: "h-4 w-full rounded-full border border-slate-300 bg-white/90 p-1 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full overflow-hidden rounded-full bg-slate-200", children: /* @__PURE__ */ jsx("div", { className: "h-full w-1/3 rounded-full bg-gradient-to-r from-emerald-300 via-sky-500 to-indigo-600 animate-pulse" }) }) })
|
|
5815
|
+
] }) }) : null,
|
|
5816
|
+
chatComponent ?? null
|
|
5319
5817
|
] })
|
|
5320
|
-
] }) : null,
|
|
5321
|
-
/* @__PURE__ */ jsxs("div", { className: `${editorClassName} relative`, children: [
|
|
5322
|
-
/* @__PURE__ */ jsx("div", { className: "w-full h-full bg-slate-100 overflow-auto flex justify-center items-start p-3", children: /* @__PURE__ */ jsx(
|
|
5323
|
-
"div",
|
|
5324
|
-
{
|
|
5325
|
-
className: "h-full bg-white border border-slate-200 shadow-sm overflow-hidden",
|
|
5326
|
-
style: {
|
|
5327
|
-
width: iframeWidth,
|
|
5328
|
-
minWidth: iframeWidth,
|
|
5329
|
-
maxWidth: "100%"
|
|
5330
|
-
},
|
|
5331
|
-
children: /* @__PURE__ */ jsx(
|
|
5332
|
-
"iframe",
|
|
5333
|
-
{
|
|
5334
|
-
ref: iframeRef,
|
|
5335
|
-
src: editorSrc,
|
|
5336
|
-
onLoad: handleIframeLoad,
|
|
5337
|
-
className: "w-full h-full border-0",
|
|
5338
|
-
title: "AI Editor Preview",
|
|
5339
|
-
allow: "same-origin"
|
|
5340
|
-
},
|
|
5341
|
-
iframeKey
|
|
5342
|
-
)
|
|
5343
|
-
}
|
|
5344
|
-
) }),
|
|
5345
|
-
isIframeLoading ? /* @__PURE__ */ jsx("div", { className: "absolute inset-0 z-30 flex items-center justify-center bg-slate-100/95 backdrop-blur-[1px]", children: /* @__PURE__ */ jsxs("div", { className: "w-[560px] max-w-[88vw]", children: [
|
|
5346
|
-
/* @__PURE__ */ jsx("p", { className: "mb-3 text-center text-base font-semibold text-slate-700", children: "Loading changes..." }),
|
|
5347
|
-
/* @__PURE__ */ jsx("div", { className: "h-4 w-full rounded-full border border-slate-300 bg-white/90 p-1 shadow-sm", children: /* @__PURE__ */ jsx("div", { className: "h-full w-full overflow-hidden rounded-full bg-slate-200", children: /* @__PURE__ */ jsx("div", { className: "h-full w-1/3 rounded-full bg-gradient-to-r from-emerald-300 via-sky-500 to-indigo-600 animate-pulse" }) }) })
|
|
5348
|
-
] }) }) : null,
|
|
5349
|
-
chatComponent ?? null
|
|
5350
5818
|
] })
|
|
5351
5819
|
] });
|
|
5352
5820
|
}
|
package/dist/vite.cjs
CHANGED
|
@@ -17,22 +17,116 @@ var DEFAULT_TRACKING_MARKERS = [
|
|
|
17
17
|
"googletagmanager",
|
|
18
18
|
"google-analytics",
|
|
19
19
|
"googleads",
|
|
20
|
+
"googleadservices",
|
|
21
|
+
"googlesyndication",
|
|
20
22
|
"doubleclick",
|
|
21
23
|
"gtag(",
|
|
22
24
|
"ga(",
|
|
23
25
|
"fbq(",
|
|
24
|
-
"
|
|
26
|
+
"connect.facebook.net",
|
|
27
|
+
"clarity.ms",
|
|
25
28
|
"hotjar",
|
|
26
29
|
"segment.com",
|
|
30
|
+
"segment.io",
|
|
31
|
+
"segmentapis",
|
|
27
32
|
"mixpanel",
|
|
28
|
-
"amplitude",
|
|
33
|
+
"amplitude.com",
|
|
34
|
+
"api.amplitude",
|
|
29
35
|
"fullstory",
|
|
30
36
|
"northbeam",
|
|
31
37
|
"nb-collector",
|
|
38
|
+
"j.northbeam.io",
|
|
32
39
|
"/api/collect",
|
|
33
40
|
"/nb-collector",
|
|
34
41
|
'"r":"periodic"',
|
|
35
|
-
'"r": "periodic"'
|
|
42
|
+
'"r": "periodic"',
|
|
43
|
+
"shopify-pixel",
|
|
44
|
+
"config-security.com",
|
|
45
|
+
"heap.io",
|
|
46
|
+
"heapanalytics",
|
|
47
|
+
"posthog",
|
|
48
|
+
"matomo",
|
|
49
|
+
"piwik",
|
|
50
|
+
"plausible.io",
|
|
51
|
+
"umami",
|
|
52
|
+
"statcounter",
|
|
53
|
+
"kissmetrics",
|
|
54
|
+
"pendo.io",
|
|
55
|
+
"mouseflow",
|
|
56
|
+
"quantserve",
|
|
57
|
+
"quantcast",
|
|
58
|
+
"chartbeat",
|
|
59
|
+
"parse.ly",
|
|
60
|
+
"parsely",
|
|
61
|
+
"optimizely",
|
|
62
|
+
"logrocket",
|
|
63
|
+
"smartlook",
|
|
64
|
+
"inspectlet",
|
|
65
|
+
"crazyegg",
|
|
66
|
+
"lucky-orange",
|
|
67
|
+
"luckyorange",
|
|
68
|
+
"vwo.com",
|
|
69
|
+
"contentsquare",
|
|
70
|
+
"decibel",
|
|
71
|
+
"medallia",
|
|
72
|
+
"bat.bing.com",
|
|
73
|
+
"bing.com/action",
|
|
74
|
+
"analytics.tiktok.com",
|
|
75
|
+
"tiktok-pixel",
|
|
76
|
+
"snap.licdn.com",
|
|
77
|
+
"/li/track",
|
|
78
|
+
"ads-twitter.com",
|
|
79
|
+
"static.ads-twitter",
|
|
80
|
+
"pinimg.com",
|
|
81
|
+
"pinterest-tag",
|
|
82
|
+
"reddit.com/api/v2/conversions",
|
|
83
|
+
"redditstatic",
|
|
84
|
+
"criteo",
|
|
85
|
+
"adroll",
|
|
86
|
+
"outbrain",
|
|
87
|
+
"amazon-adsystem",
|
|
88
|
+
"adsystem.amazon",
|
|
89
|
+
"q.quora.com",
|
|
90
|
+
"quora-pixel",
|
|
91
|
+
"tealium",
|
|
92
|
+
"rudderstack",
|
|
93
|
+
"mparticle",
|
|
94
|
+
"freshpaint",
|
|
95
|
+
"jitsu",
|
|
96
|
+
"customer.io",
|
|
97
|
+
"hs-analytics",
|
|
98
|
+
"hsforms",
|
|
99
|
+
"hubspot",
|
|
100
|
+
"marketo",
|
|
101
|
+
"munchkin",
|
|
102
|
+
"pardot",
|
|
103
|
+
"intercom",
|
|
104
|
+
"drift",
|
|
105
|
+
"klaviyo",
|
|
106
|
+
"omnisend",
|
|
107
|
+
"attentive",
|
|
108
|
+
"sentry",
|
|
109
|
+
"bugsnag",
|
|
110
|
+
"datadog",
|
|
111
|
+
"dd-rum",
|
|
112
|
+
"browser-intake-datadoghq",
|
|
113
|
+
"newrelic",
|
|
114
|
+
"nr-data",
|
|
115
|
+
"rollbar",
|
|
116
|
+
"cloudflareinsights",
|
|
117
|
+
"vercel-insights",
|
|
118
|
+
"_vercel/insights",
|
|
119
|
+
"vercel-speed-insights",
|
|
120
|
+
"plausible",
|
|
121
|
+
"usermaven",
|
|
122
|
+
"freshmarketer",
|
|
123
|
+
"mc.yandex",
|
|
124
|
+
"yandex.ru/metrika",
|
|
125
|
+
"hm.baidu.com",
|
|
126
|
+
"getclicky",
|
|
127
|
+
"clicky.com",
|
|
128
|
+
"backend.shrinetheme.com",
|
|
129
|
+
"backend.shrinetheme.com/api/analytics"
|
|
36
130
|
];
|
|
37
131
|
function normalizeTrackingMarkers(input) {
|
|
38
132
|
if (!Array.isArray(input)) return [];
|
|
@@ -67,8 +161,17 @@ function parseTrackingMarkersParam(raw) {
|
|
|
67
161
|
}
|
|
68
162
|
function hasTrackingMarker(input, markers) {
|
|
69
163
|
const text = String(input || "").toLowerCase();
|
|
164
|
+
const compactText = text.replace(/[^a-z0-9]/g, "");
|
|
70
165
|
for (let i = 0; i < markers.length; i += 1) {
|
|
71
|
-
|
|
166
|
+
const marker = String(markers[i] || "").toLowerCase().trim();
|
|
167
|
+
if (!marker) continue;
|
|
168
|
+
if (text.includes(marker)) return true;
|
|
169
|
+
const markerNoProto = marker.replace(/^https?:\/\//, "");
|
|
170
|
+
const markerNoWww = markerNoProto.replace(/^www\./, "");
|
|
171
|
+
const compactMarker = markerNoWww.replace(/[^a-z0-9]/g, "");
|
|
172
|
+
if (markerNoProto && text.includes(markerNoProto)) return true;
|
|
173
|
+
if (markerNoWww && text.includes(markerNoWww)) return true;
|
|
174
|
+
if (compactMarker && compactText.includes(compactMarker)) return true;
|
|
72
175
|
}
|
|
73
176
|
return false;
|
|
74
177
|
}
|
|
@@ -80,8 +183,30 @@ function patchKnownUnsafeEditorPatterns(scriptTag) {
|
|
|
80
183
|
);
|
|
81
184
|
return out;
|
|
82
185
|
}
|
|
186
|
+
function escapeHtmlAttribute(value) {
|
|
187
|
+
return String(value || "").replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
188
|
+
}
|
|
189
|
+
function getFirstMatchedTrackingMarker(input, markers) {
|
|
190
|
+
const text = String(input || "").toLowerCase();
|
|
191
|
+
for (let i = 0; i < markers.length; i += 1) {
|
|
192
|
+
if (text.includes(markers[i])) return markers[i];
|
|
193
|
+
}
|
|
194
|
+
return "";
|
|
195
|
+
}
|
|
196
|
+
function describeRemovedTrackingTag(tag, markers) {
|
|
197
|
+
const srcMatch = String(tag || "").match(/\bsrc\s*=\s*(["'])(.*?)\1/i);
|
|
198
|
+
const src = srcMatch?.[2]?.trim();
|
|
199
|
+
if (src) return `script:${src}`;
|
|
200
|
+
const idMatch = String(tag || "").match(/\bid\s*=\s*(["'])(.*?)\1/i);
|
|
201
|
+
const id = idMatch?.[2]?.trim();
|
|
202
|
+
if (id) return `tag#${id}`;
|
|
203
|
+
const marker = getFirstMatchedTrackingMarker(tag, markers);
|
|
204
|
+
if (marker) return `marker:${marker}`;
|
|
205
|
+
return "inline-script";
|
|
206
|
+
}
|
|
83
207
|
function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
84
208
|
let removedCount = 0;
|
|
209
|
+
const removedScripts = [];
|
|
85
210
|
let out = html;
|
|
86
211
|
out = out.replace(/<script\b[\s\S]*?<\/script>/gi, (tag) => {
|
|
87
212
|
var patchedTag = patchKnownUnsafeEditorPatterns(tag);
|
|
@@ -89,6 +214,9 @@ function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
|
89
214
|
const src = srcMatch?.[2] || "";
|
|
90
215
|
if (hasTrackingMarker(src, markers) || hasTrackingMarker(tag, markers)) {
|
|
91
216
|
removedCount += 1;
|
|
217
|
+
if (removedScripts.length < 25) {
|
|
218
|
+
removedScripts.push(describeRemovedTrackingTag(tag, markers).slice(0, 240));
|
|
219
|
+
}
|
|
92
220
|
return "";
|
|
93
221
|
}
|
|
94
222
|
return patchedTag;
|
|
@@ -96,13 +224,18 @@ function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
|
96
224
|
out = out.replace(/<noscript\b[\s\S]*?<\/noscript>/gi, (tag) => {
|
|
97
225
|
if (!hasTrackingMarker(tag, markers)) return tag;
|
|
98
226
|
removedCount += 1;
|
|
227
|
+
if (removedScripts.length < 25) {
|
|
228
|
+
const marker = getFirstMatchedTrackingMarker(tag, markers);
|
|
229
|
+
removedScripts.push(`noscript:${(marker || "tracking").slice(0, 240)}`);
|
|
230
|
+
}
|
|
99
231
|
return "";
|
|
100
232
|
});
|
|
101
233
|
if (removedCount > 0) {
|
|
234
|
+
const dataScriptsValue = removedScripts.length ? ` data-scripts="${escapeHtmlAttribute(removedScripts.join(" | "))}"` : "";
|
|
102
235
|
out = out.replace(
|
|
103
236
|
/<head([^>]*)>/i,
|
|
104
237
|
`<head$1>
|
|
105
|
-
<meta name="conversion-editor-tracking-scripts-stripped" content="${removedCount}">
|
|
238
|
+
<meta name="conversion-editor-tracking-scripts-stripped" content="${removedCount}"${dataScriptsValue}>
|
|
106
239
|
`
|
|
107
240
|
);
|
|
108
241
|
}
|
|
@@ -1377,15 +1510,29 @@ function showEditorNotification(message, kind, durationMs) {
|
|
|
1377
1510
|
}, Math.max(1200, durationMs || 2600));
|
|
1378
1511
|
}
|
|
1379
1512
|
|
|
1513
|
+
function resolveSimulationId(source, keys) {
|
|
1514
|
+
var obj = source || {};
|
|
1515
|
+
var arr = Array.isArray(keys) ? keys : [];
|
|
1516
|
+
for (var i = 0; i < arr.length; i++) {
|
|
1517
|
+
var key = arr[i];
|
|
1518
|
+
var value = obj[key];
|
|
1519
|
+
if (value === undefined || value === null) continue;
|
|
1520
|
+
// Preserve numeric ids (including 0), but reject empty-string ids.
|
|
1521
|
+
if (typeof value === 'string' && value.trim() === '') continue;
|
|
1522
|
+
return value;
|
|
1523
|
+
}
|
|
1524
|
+
return null;
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1380
1527
|
function generatePreviewUrlString(args) {
|
|
1381
1528
|
var baseUrl = (args && args.url) || '';
|
|
1382
1529
|
var test = (args && args.test) || {};
|
|
1383
1530
|
var variation = (args && args.variation) || {};
|
|
1384
1531
|
if (!baseUrl) return '';
|
|
1385
|
-
var testId = test
|
|
1386
|
-
var variationId = variation
|
|
1387
|
-
if (
|
|
1388
|
-
var cId = String(testId
|
|
1532
|
+
var testId = resolveSimulationId(test, ['iid', 'experimentIid', 'experimentId', '_id', 'id']);
|
|
1533
|
+
var variationId = resolveSimulationId(variation, ['iid', 'platformIid', 'variationIid', '_id', 'id']);
|
|
1534
|
+
if (testId === null || variationId === null) return '';
|
|
1535
|
+
var cId = String(testId) + '_' + String(variationId);
|
|
1389
1536
|
var hasQueryParams = String(baseUrl).indexOf('?') >= 0;
|
|
1390
1537
|
return (
|
|
1391
1538
|
baseUrl +
|
|
@@ -1408,8 +1555,10 @@ function simulateExperiment() {
|
|
|
1408
1555
|
test.pageUrl ||
|
|
1409
1556
|
(test.metadata_1 && test.metadata_1.editor_url) ||
|
|
1410
1557
|
'';
|
|
1411
|
-
|
|
1412
|
-
|
|
1558
|
+
var testId = resolveSimulationId(test, ['iid', 'experimentIid', 'experimentId', '_id', 'id']);
|
|
1559
|
+
var variationId = resolveSimulationId(activeVariation, ['iid', 'platformIid', 'variationIid', '_id', 'id']);
|
|
1560
|
+
if (testId === null || !activeVariation || variationId === null) {
|
|
1561
|
+
showEditorNotification('Cannot simulate: missing test/variation id.', 'error', 3200);
|
|
1413
1562
|
return;
|
|
1414
1563
|
}
|
|
1415
1564
|
var url = generatePreviewUrlString({
|
|
@@ -6243,6 +6392,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
6243
6392
|
const trackingMarkersForRequest = mergeTrackingMarkers(
|
|
6244
6393
|
extraTrackingMarkersForRequest
|
|
6245
6394
|
);
|
|
6395
|
+
console.log("trackingMarkersForRequest", trackingMarkersForRequest);
|
|
6246
6396
|
const strictFreezeParam = (url.searchParams.get("strictObserverFreeze") || "").toLowerCase();
|
|
6247
6397
|
const strictObserverFreezeForRequest = strictFreezeParam === "1" || strictFreezeParam === "true" || strictFreezeParam === "yes" ? true : strictFreezeParam === "0" || strictFreezeParam === "false" || strictFreezeParam === "no" ? false : strictObserverFreeze;
|
|
6248
6398
|
if (!targetUrl) {
|
package/dist/vite.js
CHANGED
|
@@ -9,22 +9,116 @@ var DEFAULT_TRACKING_MARKERS = [
|
|
|
9
9
|
"googletagmanager",
|
|
10
10
|
"google-analytics",
|
|
11
11
|
"googleads",
|
|
12
|
+
"googleadservices",
|
|
13
|
+
"googlesyndication",
|
|
12
14
|
"doubleclick",
|
|
13
15
|
"gtag(",
|
|
14
16
|
"ga(",
|
|
15
17
|
"fbq(",
|
|
16
|
-
"
|
|
18
|
+
"connect.facebook.net",
|
|
19
|
+
"clarity.ms",
|
|
17
20
|
"hotjar",
|
|
18
21
|
"segment.com",
|
|
22
|
+
"segment.io",
|
|
23
|
+
"segmentapis",
|
|
19
24
|
"mixpanel",
|
|
20
|
-
"amplitude",
|
|
25
|
+
"amplitude.com",
|
|
26
|
+
"api.amplitude",
|
|
21
27
|
"fullstory",
|
|
22
28
|
"northbeam",
|
|
23
29
|
"nb-collector",
|
|
30
|
+
"j.northbeam.io",
|
|
24
31
|
"/api/collect",
|
|
25
32
|
"/nb-collector",
|
|
26
33
|
'"r":"periodic"',
|
|
27
|
-
'"r": "periodic"'
|
|
34
|
+
'"r": "periodic"',
|
|
35
|
+
"shopify-pixel",
|
|
36
|
+
"config-security.com",
|
|
37
|
+
"heap.io",
|
|
38
|
+
"heapanalytics",
|
|
39
|
+
"posthog",
|
|
40
|
+
"matomo",
|
|
41
|
+
"piwik",
|
|
42
|
+
"plausible.io",
|
|
43
|
+
"umami",
|
|
44
|
+
"statcounter",
|
|
45
|
+
"kissmetrics",
|
|
46
|
+
"pendo.io",
|
|
47
|
+
"mouseflow",
|
|
48
|
+
"quantserve",
|
|
49
|
+
"quantcast",
|
|
50
|
+
"chartbeat",
|
|
51
|
+
"parse.ly",
|
|
52
|
+
"parsely",
|
|
53
|
+
"optimizely",
|
|
54
|
+
"logrocket",
|
|
55
|
+
"smartlook",
|
|
56
|
+
"inspectlet",
|
|
57
|
+
"crazyegg",
|
|
58
|
+
"lucky-orange",
|
|
59
|
+
"luckyorange",
|
|
60
|
+
"vwo.com",
|
|
61
|
+
"contentsquare",
|
|
62
|
+
"decibel",
|
|
63
|
+
"medallia",
|
|
64
|
+
"bat.bing.com",
|
|
65
|
+
"bing.com/action",
|
|
66
|
+
"analytics.tiktok.com",
|
|
67
|
+
"tiktok-pixel",
|
|
68
|
+
"snap.licdn.com",
|
|
69
|
+
"/li/track",
|
|
70
|
+
"ads-twitter.com",
|
|
71
|
+
"static.ads-twitter",
|
|
72
|
+
"pinimg.com",
|
|
73
|
+
"pinterest-tag",
|
|
74
|
+
"reddit.com/api/v2/conversions",
|
|
75
|
+
"redditstatic",
|
|
76
|
+
"criteo",
|
|
77
|
+
"adroll",
|
|
78
|
+
"outbrain",
|
|
79
|
+
"amazon-adsystem",
|
|
80
|
+
"adsystem.amazon",
|
|
81
|
+
"q.quora.com",
|
|
82
|
+
"quora-pixel",
|
|
83
|
+
"tealium",
|
|
84
|
+
"rudderstack",
|
|
85
|
+
"mparticle",
|
|
86
|
+
"freshpaint",
|
|
87
|
+
"jitsu",
|
|
88
|
+
"customer.io",
|
|
89
|
+
"hs-analytics",
|
|
90
|
+
"hsforms",
|
|
91
|
+
"hubspot",
|
|
92
|
+
"marketo",
|
|
93
|
+
"munchkin",
|
|
94
|
+
"pardot",
|
|
95
|
+
"intercom",
|
|
96
|
+
"drift",
|
|
97
|
+
"klaviyo",
|
|
98
|
+
"omnisend",
|
|
99
|
+
"attentive",
|
|
100
|
+
"sentry",
|
|
101
|
+
"bugsnag",
|
|
102
|
+
"datadog",
|
|
103
|
+
"dd-rum",
|
|
104
|
+
"browser-intake-datadoghq",
|
|
105
|
+
"newrelic",
|
|
106
|
+
"nr-data",
|
|
107
|
+
"rollbar",
|
|
108
|
+
"cloudflareinsights",
|
|
109
|
+
"vercel-insights",
|
|
110
|
+
"_vercel/insights",
|
|
111
|
+
"vercel-speed-insights",
|
|
112
|
+
"plausible",
|
|
113
|
+
"usermaven",
|
|
114
|
+
"freshmarketer",
|
|
115
|
+
"mc.yandex",
|
|
116
|
+
"yandex.ru/metrika",
|
|
117
|
+
"hm.baidu.com",
|
|
118
|
+
"getclicky",
|
|
119
|
+
"clicky.com",
|
|
120
|
+
"backend.shrinetheme.com",
|
|
121
|
+
"backend.shrinetheme.com/api/analytics"
|
|
28
122
|
];
|
|
29
123
|
function normalizeTrackingMarkers(input) {
|
|
30
124
|
if (!Array.isArray(input)) return [];
|
|
@@ -59,8 +153,17 @@ function parseTrackingMarkersParam(raw) {
|
|
|
59
153
|
}
|
|
60
154
|
function hasTrackingMarker(input, markers) {
|
|
61
155
|
const text = String(input || "").toLowerCase();
|
|
156
|
+
const compactText = text.replace(/[^a-z0-9]/g, "");
|
|
62
157
|
for (let i = 0; i < markers.length; i += 1) {
|
|
63
|
-
|
|
158
|
+
const marker = String(markers[i] || "").toLowerCase().trim();
|
|
159
|
+
if (!marker) continue;
|
|
160
|
+
if (text.includes(marker)) return true;
|
|
161
|
+
const markerNoProto = marker.replace(/^https?:\/\//, "");
|
|
162
|
+
const markerNoWww = markerNoProto.replace(/^www\./, "");
|
|
163
|
+
const compactMarker = markerNoWww.replace(/[^a-z0-9]/g, "");
|
|
164
|
+
if (markerNoProto && text.includes(markerNoProto)) return true;
|
|
165
|
+
if (markerNoWww && text.includes(markerNoWww)) return true;
|
|
166
|
+
if (compactMarker && compactText.includes(compactMarker)) return true;
|
|
64
167
|
}
|
|
65
168
|
return false;
|
|
66
169
|
}
|
|
@@ -72,8 +175,30 @@ function patchKnownUnsafeEditorPatterns(scriptTag) {
|
|
|
72
175
|
);
|
|
73
176
|
return out;
|
|
74
177
|
}
|
|
178
|
+
function escapeHtmlAttribute(value) {
|
|
179
|
+
return String(value || "").replace(/&/g, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
180
|
+
}
|
|
181
|
+
function getFirstMatchedTrackingMarker(input, markers) {
|
|
182
|
+
const text = String(input || "").toLowerCase();
|
|
183
|
+
for (let i = 0; i < markers.length; i += 1) {
|
|
184
|
+
if (text.includes(markers[i])) return markers[i];
|
|
185
|
+
}
|
|
186
|
+
return "";
|
|
187
|
+
}
|
|
188
|
+
function describeRemovedTrackingTag(tag, markers) {
|
|
189
|
+
const srcMatch = String(tag || "").match(/\bsrc\s*=\s*(["'])(.*?)\1/i);
|
|
190
|
+
const src = srcMatch?.[2]?.trim();
|
|
191
|
+
if (src) return `script:${src}`;
|
|
192
|
+
const idMatch = String(tag || "").match(/\bid\s*=\s*(["'])(.*?)\1/i);
|
|
193
|
+
const id = idMatch?.[2]?.trim();
|
|
194
|
+
if (id) return `tag#${id}`;
|
|
195
|
+
const marker = getFirstMatchedTrackingMarker(tag, markers);
|
|
196
|
+
if (marker) return `marker:${marker}`;
|
|
197
|
+
return "inline-script";
|
|
198
|
+
}
|
|
75
199
|
function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
76
200
|
let removedCount = 0;
|
|
201
|
+
const removedScripts = [];
|
|
77
202
|
let out = html;
|
|
78
203
|
out = out.replace(/<script\b[\s\S]*?<\/script>/gi, (tag) => {
|
|
79
204
|
var patchedTag = patchKnownUnsafeEditorPatterns(tag);
|
|
@@ -81,6 +206,9 @@ function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
|
81
206
|
const src = srcMatch?.[2] || "";
|
|
82
207
|
if (hasTrackingMarker(src, markers) || hasTrackingMarker(tag, markers)) {
|
|
83
208
|
removedCount += 1;
|
|
209
|
+
if (removedScripts.length < 25) {
|
|
210
|
+
removedScripts.push(describeRemovedTrackingTag(tag, markers).slice(0, 240));
|
|
211
|
+
}
|
|
84
212
|
return "";
|
|
85
213
|
}
|
|
86
214
|
return patchedTag;
|
|
@@ -88,13 +216,18 @@ function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
|
88
216
|
out = out.replace(/<noscript\b[\s\S]*?<\/noscript>/gi, (tag) => {
|
|
89
217
|
if (!hasTrackingMarker(tag, markers)) return tag;
|
|
90
218
|
removedCount += 1;
|
|
219
|
+
if (removedScripts.length < 25) {
|
|
220
|
+
const marker = getFirstMatchedTrackingMarker(tag, markers);
|
|
221
|
+
removedScripts.push(`noscript:${(marker || "tracking").slice(0, 240)}`);
|
|
222
|
+
}
|
|
91
223
|
return "";
|
|
92
224
|
});
|
|
93
225
|
if (removedCount > 0) {
|
|
226
|
+
const dataScriptsValue = removedScripts.length ? ` data-scripts="${escapeHtmlAttribute(removedScripts.join(" | "))}"` : "";
|
|
94
227
|
out = out.replace(
|
|
95
228
|
/<head([^>]*)>/i,
|
|
96
229
|
`<head$1>
|
|
97
|
-
<meta name="conversion-editor-tracking-scripts-stripped" content="${removedCount}">
|
|
230
|
+
<meta name="conversion-editor-tracking-scripts-stripped" content="${removedCount}"${dataScriptsValue}>
|
|
98
231
|
`
|
|
99
232
|
);
|
|
100
233
|
}
|
|
@@ -1369,15 +1502,29 @@ function showEditorNotification(message, kind, durationMs) {
|
|
|
1369
1502
|
}, Math.max(1200, durationMs || 2600));
|
|
1370
1503
|
}
|
|
1371
1504
|
|
|
1505
|
+
function resolveSimulationId(source, keys) {
|
|
1506
|
+
var obj = source || {};
|
|
1507
|
+
var arr = Array.isArray(keys) ? keys : [];
|
|
1508
|
+
for (var i = 0; i < arr.length; i++) {
|
|
1509
|
+
var key = arr[i];
|
|
1510
|
+
var value = obj[key];
|
|
1511
|
+
if (value === undefined || value === null) continue;
|
|
1512
|
+
// Preserve numeric ids (including 0), but reject empty-string ids.
|
|
1513
|
+
if (typeof value === 'string' && value.trim() === '') continue;
|
|
1514
|
+
return value;
|
|
1515
|
+
}
|
|
1516
|
+
return null;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1372
1519
|
function generatePreviewUrlString(args) {
|
|
1373
1520
|
var baseUrl = (args && args.url) || '';
|
|
1374
1521
|
var test = (args && args.test) || {};
|
|
1375
1522
|
var variation = (args && args.variation) || {};
|
|
1376
1523
|
if (!baseUrl) return '';
|
|
1377
|
-
var testId = test
|
|
1378
|
-
var variationId = variation
|
|
1379
|
-
if (
|
|
1380
|
-
var cId = String(testId
|
|
1524
|
+
var testId = resolveSimulationId(test, ['iid', 'experimentIid', 'experimentId', '_id', 'id']);
|
|
1525
|
+
var variationId = resolveSimulationId(variation, ['iid', 'platformIid', 'variationIid', '_id', 'id']);
|
|
1526
|
+
if (testId === null || variationId === null) return '';
|
|
1527
|
+
var cId = String(testId) + '_' + String(variationId);
|
|
1381
1528
|
var hasQueryParams = String(baseUrl).indexOf('?') >= 0;
|
|
1382
1529
|
return (
|
|
1383
1530
|
baseUrl +
|
|
@@ -1400,8 +1547,10 @@ function simulateExperiment() {
|
|
|
1400
1547
|
test.pageUrl ||
|
|
1401
1548
|
(test.metadata_1 && test.metadata_1.editor_url) ||
|
|
1402
1549
|
'';
|
|
1403
|
-
|
|
1404
|
-
|
|
1550
|
+
var testId = resolveSimulationId(test, ['iid', 'experimentIid', 'experimentId', '_id', 'id']);
|
|
1551
|
+
var variationId = resolveSimulationId(activeVariation, ['iid', 'platformIid', 'variationIid', '_id', 'id']);
|
|
1552
|
+
if (testId === null || !activeVariation || variationId === null) {
|
|
1553
|
+
showEditorNotification('Cannot simulate: missing test/variation id.', 'error', 3200);
|
|
1405
1554
|
return;
|
|
1406
1555
|
}
|
|
1407
1556
|
var url = generatePreviewUrlString({
|
|
@@ -6235,6 +6384,7 @@ function createVisualEditorMiddleware(options) {
|
|
|
6235
6384
|
const trackingMarkersForRequest = mergeTrackingMarkers(
|
|
6236
6385
|
extraTrackingMarkersForRequest
|
|
6237
6386
|
);
|
|
6387
|
+
console.log("trackingMarkersForRequest", trackingMarkersForRequest);
|
|
6238
6388
|
const strictFreezeParam = (url.searchParams.get("strictObserverFreeze") || "").toLowerCase();
|
|
6239
6389
|
const strictObserverFreezeForRequest = strictFreezeParam === "1" || strictFreezeParam === "true" || strictFreezeParam === "yes" ? true : strictFreezeParam === "0" || strictFreezeParam === "false" || strictFreezeParam === "no" ? false : strictObserverFreeze;
|
|
6240
6390
|
if (!targetUrl) {
|