@accelerated-agency/visual-editor 0.4.3 → 0.4.5
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/vite.cjs +667 -69
- package/dist/vite.js +667 -69
- package/package.json +1 -1
package/dist/vite.cjs
CHANGED
|
@@ -86,17 +86,26 @@ function hasTrackingMarker(input, markers) {
|
|
|
86
86
|
}
|
|
87
87
|
return false;
|
|
88
88
|
}
|
|
89
|
+
function patchKnownUnsafeEditorPatterns(scriptTag) {
|
|
90
|
+
let out = String(scriptTag || "");
|
|
91
|
+
out = out.replace(
|
|
92
|
+
/dragRegion\.addEventListener\((['"])pointerdown\1,\s*onPointerDown\);?/g,
|
|
93
|
+
"if (typeof dragRegion !== 'undefined' && dragRegion) dragRegion.addEventListener($1pointerdown$1, onPointerDown);"
|
|
94
|
+
);
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
89
97
|
function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
90
98
|
let removedCount = 0;
|
|
91
99
|
let out = html;
|
|
92
100
|
out = out.replace(/<script\b[\s\S]*?<\/script>/gi, (tag) => {
|
|
101
|
+
var patchedTag = patchKnownUnsafeEditorPatterns(tag);
|
|
93
102
|
const srcMatch = tag.match(/\bsrc\s*=\s*(["'])(.*?)\1/i);
|
|
94
103
|
const src = srcMatch?.[2] || "";
|
|
95
104
|
if (hasTrackingMarker(src, markers) || hasTrackingMarker(tag, markers)) {
|
|
96
105
|
removedCount += 1;
|
|
97
106
|
return "";
|
|
98
107
|
}
|
|
99
|
-
return
|
|
108
|
+
return patchedTag;
|
|
100
109
|
});
|
|
101
110
|
out = out.replace(/<noscript\b[\s\S]*?<\/noscript>/gi, (tag) => {
|
|
102
111
|
if (!hasTrackingMarker(tag, markers)) return tag;
|
|
@@ -271,8 +280,97 @@ html,body{height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFo
|
|
|
271
280
|
.tb-viewport #dev-label{font-size:14px;font-weight:500;color:##404040;min-width:auto;background:none;border:none;padding:0;overflow:visible;white-space:nowrap;text-overflow:clip;border-radius:0;max-width:none}
|
|
272
281
|
.tb-viewport i{font-size:9px;color:##404040}
|
|
273
282
|
/* Device toggle buttons */
|
|
283
|
+
.tb-dev-wrap{position:relative;display:flex;align-items:center}
|
|
274
284
|
.tb-dev-btns{display:flex;align-items:center;gap:1px;padding:8px 4px;background:#F0F0F0;border-radius:7px; height: 30px;width: 116px;}
|
|
275
285
|
.tb-dev-3btns{display:flex;align-items:center;gap:2px;padding:8px 4px;background:#F0F0F0;border-radius:7px; height: 30px;width: 100px;}
|
|
286
|
+
.tb-dev-menu{
|
|
287
|
+
position:absolute;top:calc(100% + 8px);right:0;z-index:12040;display:none;
|
|
288
|
+
width:264px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:4px 4px;
|
|
289
|
+
box-shadow:0 12px 28px rgba(2,6,23,.18);color:#27272a
|
|
290
|
+
}
|
|
291
|
+
.tb-dev-menu.open{display:block}
|
|
292
|
+
.tb-dev-menu .hd{font-size:12px;font-weight:600;color:#3f3f46;margin-bottom:10px}
|
|
293
|
+
.tb-dev-menu .row{display:flex;align-items:center;gap:8px;}
|
|
294
|
+
.tb-dev-menu .row.height-width-row .row{
|
|
295
|
+
flex-direction: column;
|
|
296
|
+
align-items: flex-start;
|
|
297
|
+
}
|
|
298
|
+
.tb-dev-menu .row.height-width-row label{
|
|
299
|
+
color: var(--content-subtle, #737373);
|
|
300
|
+
font-size: 12px;
|
|
301
|
+
font-style: normal;
|
|
302
|
+
font-weight: 500;
|
|
303
|
+
line-height: 14px; /* 116.667% */
|
|
304
|
+
}
|
|
305
|
+
.tb-dev-menu > .row{
|
|
306
|
+
padding: 4px 12px;
|
|
307
|
+
}
|
|
308
|
+
.tb-dev-menu label{ flex-shrink: 0;
|
|
309
|
+
overflow: hidden;
|
|
310
|
+
color: var(--base-surface, #646465);
|
|
311
|
+
font-size: var(--font-size-sm, 14px);
|
|
312
|
+
font-style: normal;
|
|
313
|
+
font-weight: 500;
|
|
314
|
+
line-height: var(--font-leading-4, 16px);
|
|
315
|
+
white-space: nowrap;
|
|
316
|
+
min-width: fit-content;}
|
|
317
|
+
.tb-dev-menu input{
|
|
318
|
+
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);
|
|
319
|
+
width:100%;height:30px;border-radius:6px;
|
|
320
|
+
padding:0 8px;
|
|
321
|
+
font-size:12px;
|
|
322
|
+
color:#18181b;
|
|
323
|
+
background:#fff;
|
|
324
|
+
outline:none;
|
|
325
|
+
color:#404040;
|
|
326
|
+
border-color:transparent;
|
|
327
|
+
}
|
|
328
|
+
.tb-dev-menu input#dev-zoom-level{
|
|
329
|
+
max-width: fit-content;
|
|
330
|
+
margin-left: auto;
|
|
331
|
+
}
|
|
332
|
+
.tb-dev-menu input:focus{
|
|
333
|
+
border-color:#1A1A1A;
|
|
334
|
+
box-shadow:0 0 0 2px rgba(99,102,241,.14)
|
|
335
|
+
}
|
|
336
|
+
.tb-dev-menu .row-split > *{flex:1}
|
|
337
|
+
.tb-dev-menu .panel-toggle label{width:100%}
|
|
338
|
+
.tb-dev-menu .panel-toggle-label{
|
|
339
|
+
overflow:hidden;
|
|
340
|
+
color:var(--content-subtle, #737373);
|
|
341
|
+
text-overflow:ellipsis;
|
|
342
|
+
font-size:var(--font-size-sm, 14px);
|
|
343
|
+
font-style:normal;
|
|
344
|
+
font-weight:500;
|
|
345
|
+
line-height:var(--font-leading-4, 16px);
|
|
346
|
+
white-space:nowrap;
|
|
347
|
+
cursor:pointer;
|
|
348
|
+
}
|
|
349
|
+
.tb-dev-menu .vp-presets{
|
|
350
|
+
margin-top:8px;padding-top:8px;border-top:1px dashed #ececf0;
|
|
351
|
+
display:flex;flex-direction:column;gap:2px
|
|
352
|
+
}
|
|
353
|
+
.tb-dev-menu .vp-preset-btn{
|
|
354
|
+
border:none;background:transparent;text-align:left;cursor:pointer;
|
|
355
|
+
border-radius:6px;
|
|
356
|
+
padding:8px 12px;
|
|
357
|
+
color: var(--content-subtle, #737373);
|
|
358
|
+
text-overflow: ellipsis;
|
|
359
|
+
font-size: var(--font-size-sm, 14px);
|
|
360
|
+
font-style: normal;
|
|
361
|
+
font-weight: 500;
|
|
362
|
+
line-height: var(--font-leading-4, 16px);
|
|
363
|
+
}
|
|
364
|
+
.tb-dev-menu .vp-preset-btn:hover,.tb-dev-menu .vp-preset-btn.active{background:#f4f4f5}
|
|
365
|
+
.tb-dev-menu .ft{
|
|
366
|
+
margin-top:10px;padding-top:8px;border-top:1px solid #ececf0;
|
|
367
|
+
display:flex;justify-content:flex-end
|
|
368
|
+
}
|
|
369
|
+
.tb-dev-menu .apply-btn{
|
|
370
|
+
border:1px solid #d4d4d8;background:#f8fafc;color:#111827;border-radius:6px;
|
|
371
|
+
height:30px;padding:0 10px;font-size:12px;font-weight:600;cursor:pointer
|
|
372
|
+
}
|
|
373
|
+
.tb-dev-menu .apply-btn:hover{background:#eef2ff;border-color:#a5b4fc}
|
|
276
374
|
/* Dark icon buttons */
|
|
277
375
|
.tb-dk-btn{width:28px;height:28px;background:transparent;border:none;border-radius:5px;cursor:pointer;color:#71717a;display:flex;align-items:center;justify-content:center;font-size:13px;transition:all .12s;flex-shrink:0}
|
|
278
376
|
.tb-dk-btn:hover{color:#e4e4e7;background:rgba(255,255,255,.07)}
|
|
@@ -431,7 +529,12 @@ html,body{height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFo
|
|
|
431
529
|
/* \u2500\u2500 Device frame \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
432
530
|
#device-frame{
|
|
433
531
|
width:100%;min-height:100%;display:flex;align-items:stretch;
|
|
434
|
-
justify-content:center;
|
|
532
|
+
justify-content:center;transform-origin:top center;
|
|
533
|
+
transition:max-width .3s ease,width .2s ease,height .2s ease
|
|
534
|
+
}
|
|
535
|
+
#device-frame.desktop{
|
|
536
|
+
max-width:1440px;
|
|
537
|
+
box-shadow:0 0 0 1px var(--border),0 4px 24px rgba(0,0,0,.08)
|
|
435
538
|
}
|
|
436
539
|
#device-frame.tablet{
|
|
437
540
|
max-width:768px;
|
|
@@ -832,10 +935,8 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
832
935
|
</head>
|
|
833
936
|
<body class="mode-editor">
|
|
834
937
|
<div id="app">
|
|
835
|
-
|
|
836
938
|
<!-- \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->
|
|
837
939
|
<div id="toolbar">
|
|
838
|
-
|
|
839
940
|
<!-- Left: Logo + Breadcrumb -->
|
|
840
941
|
<div class="tb-left">
|
|
841
942
|
<span class="tb-logo">\u2733</span>
|
|
@@ -853,14 +954,48 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
853
954
|
<span id="dev-label">1440px</span>
|
|
854
955
|
<i class="bi bi-chevron-down"></i>
|
|
855
956
|
</div>
|
|
856
|
-
<div class="tb-dev-
|
|
857
|
-
<
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
957
|
+
<div class="tb-dev-wrap">
|
|
958
|
+
<div class="tb-dev-btns">
|
|
959
|
+
<button class="tb-dk-btn active" id="dev-desktop" onclick="setDevice('desktop')" title="Desktop \u2014 1440x1024"><i class="bi bi-display"></i></button>
|
|
960
|
+
<button class="tb-dk-btn" id="dev-tablet" onclick="setDevice('tablet')" title="Tablet \u2014 768x1024"><i class="bi bi-tablet"></i></button>
|
|
961
|
+
<button class="tb-dk-btn" id="dev-mobile" onclick="setDevice('mobile')" title="Mobile \u2014 390x844"><i class="bi bi-phone"></i></button>
|
|
962
|
+
<button class="tb-dk-btn" id="dev-more-btn" title="More options"><i class="bi bi-three-dots"></i></button>
|
|
963
|
+
</div>
|
|
964
|
+
<div id="dev-more-menu" class="tb-dev-menu" aria-hidden="true">
|
|
965
|
+
<div class="row row-zoom">
|
|
966
|
+
<label for="dev-zoom-level">Zoom</label>
|
|
967
|
+
<input id="dev-zoom-level" type="number" min="25" max="200" step="5" value="100" />
|
|
968
|
+
</div>
|
|
969
|
+
<div class="row row-split row-width height-width-row">
|
|
970
|
+
<div class="row" style="margin:0">
|
|
971
|
+
<label for="dev-custom-width">Width</label>
|
|
972
|
+
<input id="dev-custom-width" type="number" min="240" max="3840" step="1" value="1440" />
|
|
973
|
+
</div>
|
|
974
|
+
<div class="row row-height" style="margin:0">
|
|
975
|
+
<label for="dev-custom-height">Height</label>
|
|
976
|
+
<input id="dev-custom-height" type="number" min="320" max="3840" step="1" value="1024" />
|
|
977
|
+
</div>
|
|
978
|
+
</div>
|
|
979
|
+
<div class="row panel-toggle">
|
|
980
|
+
<label id="left-panel-toggle-label" class="panel-toggle-label">Collapse left panel</label>
|
|
981
|
+
</div>
|
|
982
|
+
|
|
983
|
+
<div class="vp-presets" id="dev-preset-list" aria-label="Device presets">
|
|
984
|
+
<button type="button" class="vp-preset-btn" data-preset="desktop">Desktop</button>
|
|
985
|
+
<button type="button" class="vp-preset-btn" data-preset="mobile">iPhone 13</button>
|
|
986
|
+
<button type="button" class="vp-preset-btn" data-preset="galaxy-s22">Galaxy S22</button>
|
|
987
|
+
<button type="button" class="vp-preset-btn" data-preset="tablet">iPad</button>
|
|
988
|
+
<button type="button" class="vp-preset-btn" data-preset="galaxy-j1">Galaxy J1</button>
|
|
989
|
+
<button type="button" class="vp-preset-btn" data-preset="iphone-7">iPhone 7</button>
|
|
990
|
+
<button type="button" class="vp-preset-btn" data-preset="responsive">Responsive</button>
|
|
991
|
+
</div>
|
|
992
|
+
<div class="ft">
|
|
993
|
+
<button type="button" class="apply-btn" id="dev-apply-btn">Apply</button>
|
|
994
|
+
</div>
|
|
995
|
+
</div>
|
|
861
996
|
</div>
|
|
862
997
|
<button class="tb-dk-btn" id="btn-undo" title="Undo (\u2318Z)"><i class="bi bi-arrow-counterclockwise"></i></button>
|
|
863
|
-
<button class="tb-dk-btn" id="btn-redo" title="Redo (\u2318\u21E7Z)"><i class="bi bi-arrow-clockwise"></i></button>
|
|
998
|
+
<button class="tb-dk-btn" id="btn-redo" title="Redo (\u2318\u21E7Z)" style="display:none"><i class="bi bi-arrow-clockwise"></i></button>
|
|
864
999
|
</div>
|
|
865
1000
|
|
|
866
1001
|
<div id="iframe-loading-toolbar" class="tb-page-loading" aria-live="polite" aria-atomic="true">
|
|
@@ -931,8 +1066,8 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
931
1066
|
<!-- Elements -->
|
|
932
1067
|
<div class="lp-sec lp-sec-no-border">
|
|
933
1068
|
<div class="lp-sec-hd">
|
|
934
|
-
<span class="lp-sec-hd-left">Elements <i class="bi bi-info-circle lp-info-icon" title="Page elements"></i></span>
|
|
935
|
-
<button class="lp-add-btn" title="Add element">+ Add</button>
|
|
1069
|
+
<span class="lp-sec-hd-left">Elements <i style="display:none" class="bi bi-info-circle lp-info-icon" title="Page elements"></i></span>
|
|
1070
|
+
<button class="lp-add-btn" id="btn-add-element" title="Add element">+ Add</button>
|
|
936
1071
|
</div>
|
|
937
1072
|
|
|
938
1073
|
<!-- Search (hidden, kept for JS) -->
|
|
@@ -994,7 +1129,7 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
994
1129
|
</div>
|
|
995
1130
|
|
|
996
1131
|
<!-- Device frame containing the editing iframe -->
|
|
997
|
-
<div id="device-frame">
|
|
1132
|
+
<div id="device-frame" class="desktop">
|
|
998
1133
|
<iframe id="iframeId" name="iframeId" allowfullscreen></iframe>
|
|
999
1134
|
</div>
|
|
1000
1135
|
|
|
@@ -1002,14 +1137,16 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
1002
1137
|
|
|
1003
1138
|
<!-- Right panel -->
|
|
1004
1139
|
<div id="right-panel">
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
<div class="
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
<div
|
|
1012
|
-
|
|
1140
|
+
<div id="section-components-panel" style="display:none">
|
|
1141
|
+
<!-- Left-tab controls moved here -->
|
|
1142
|
+
<div class="section-components-tabs">
|
|
1143
|
+
<div class="lp-tab" onclick="switchSectionComponentsTab('components')">Components</div>
|
|
1144
|
+
<div class="lp-tab" onclick="switchSectionComponentsTab('sections')">Sections</div>
|
|
1145
|
+
</div>
|
|
1146
|
+
<div class="lp-body">
|
|
1147
|
+
<div id="tab-components" class="tab-pane"></div>
|
|
1148
|
+
<div id="tab-sections" class="tab-pane"></div>
|
|
1149
|
+
</div>
|
|
1013
1150
|
</div>
|
|
1014
1151
|
<!-- Element badge (hidden until selection) -->
|
|
1015
1152
|
<div id="el-info" style="display:none">
|
|
@@ -1362,6 +1499,11 @@ var isDirty = false;
|
|
|
1362
1499
|
var vvvebReady = false;
|
|
1363
1500
|
var currentMode = 'editor';
|
|
1364
1501
|
var currentDevice = 'desktop';
|
|
1502
|
+
var leftPanelCollapsed = false;
|
|
1503
|
+
var viewportPreset = 'desktop';
|
|
1504
|
+
var viewportWidth = 1440;
|
|
1505
|
+
var viewportHeight = 1024;
|
|
1506
|
+
var viewportZoom = 1;
|
|
1365
1507
|
var selectedEl = null;
|
|
1366
1508
|
/** Stable selector fingerprint for resilient selection recovery after DOM churn. */
|
|
1367
1509
|
var selectedElFingerprint = '';
|
|
@@ -1614,15 +1756,202 @@ function setMode(mode) {
|
|
|
1614
1756
|
}
|
|
1615
1757
|
|
|
1616
1758
|
// \u2500\u2500 Device toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1617
|
-
var
|
|
1759
|
+
var DEVICE_PRESETS = {
|
|
1760
|
+
desktop: { label: 'Desktop', width: 1440, height: 1024, device: 'desktop' },
|
|
1761
|
+
tablet: { label: 'iPad', width: 768, height: 1024, device: 'tablet' },
|
|
1762
|
+
mobile: { label: 'iPhone 13', width: 390, height: 844, device: 'mobile' },
|
|
1763
|
+
'galaxy-s22': { label: 'Galaxy S22', width: 360, height: 780, device: 'mobile' },
|
|
1764
|
+
'iphone-7': { label: 'iPhone 7', width: 375, height: 667, device: 'mobile' },
|
|
1765
|
+
'galaxy-j1': { label: 'Galaxy J1', width: 360, height: 640, device: 'mobile' },
|
|
1766
|
+
responsive: { label: 'Responsive', width: 1280, height: 800, device: 'desktop' },
|
|
1767
|
+
};
|
|
1768
|
+
|
|
1769
|
+
function clampViewportNumber(v, fallback, min, max) {
|
|
1770
|
+
var n = parseInt(v, 10);
|
|
1771
|
+
if (!Number.isFinite(n)) return fallback;
|
|
1772
|
+
return Math.max(min, Math.min(max, n));
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
function getViewportFitZoom() {
|
|
1776
|
+
var panel = document.getElementById('iframe-panel');
|
|
1777
|
+
var available = panel ? Math.max(260, panel.clientWidth - 24) : viewportWidth;
|
|
1778
|
+
if (!viewportWidth || viewportWidth <= 0) return 1;
|
|
1779
|
+
return Math.min(1, available / viewportWidth);
|
|
1780
|
+
}
|
|
1781
|
+
|
|
1782
|
+
function getAppliedViewportZoom() {
|
|
1783
|
+
var z = Number(viewportZoom);
|
|
1784
|
+
if (!Number.isFinite(z) || z <= 0) z = 1;
|
|
1785
|
+
z = Math.max(0.25, Math.min(2, z));
|
|
1786
|
+
return Math.min(z, getViewportFitZoom());
|
|
1787
|
+
}
|
|
1788
|
+
|
|
1789
|
+
function updateViewportLabel() {
|
|
1790
|
+
var lbl = document.getElementById('dev-label');
|
|
1791
|
+
if (!lbl) return;
|
|
1792
|
+
var zoomPct = Math.round(getAppliedViewportZoom() * 100);
|
|
1793
|
+
lbl.textContent = viewportWidth + 'x' + viewportHeight + ' \xB7 ' + zoomPct + '%';
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
function syncViewportMenuControls() {
|
|
1797
|
+
var presetButtons = document.querySelectorAll('#dev-preset-list .vp-preset-btn');
|
|
1798
|
+
var widthInp = document.getElementById('dev-custom-width');
|
|
1799
|
+
var heightInp = document.getElementById('dev-custom-height');
|
|
1800
|
+
var zoomInp = document.getElementById('dev-zoom-level');
|
|
1801
|
+
if (presetButtons && presetButtons.length) {
|
|
1802
|
+
for (var i = 0; i < presetButtons.length; i++) {
|
|
1803
|
+
var key = presetButtons[i].getAttribute('data-preset') || '';
|
|
1804
|
+
presetButtons[i].classList.toggle('active', key === viewportPreset);
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
if (widthInp) widthInp.value = String(viewportWidth);
|
|
1808
|
+
if (heightInp) heightInp.value = String(viewportHeight);
|
|
1809
|
+
if (zoomInp) zoomInp.value = String(Math.round(getAppliedViewportZoom() * 100));
|
|
1810
|
+
}
|
|
1811
|
+
|
|
1812
|
+
function applyViewportFrame() {
|
|
1813
|
+
var frame = document.getElementById('device-frame');
|
|
1814
|
+
var iframe = document.getElementById('iframeId');
|
|
1815
|
+
if (!frame) return;
|
|
1816
|
+
frame.className = currentDevice;
|
|
1817
|
+
frame.style.width = viewportWidth + 'px';
|
|
1818
|
+
frame.style.height = viewportHeight + 'px';
|
|
1819
|
+
frame.style.maxWidth = 'none';
|
|
1820
|
+
frame.style.zoom = String(getAppliedViewportZoom());
|
|
1821
|
+
if (iframe) {
|
|
1822
|
+
iframe.style.height = viewportHeight + 'px';
|
|
1823
|
+
iframe.style.minHeight = viewportHeight + 'px';
|
|
1824
|
+
}
|
|
1825
|
+
updateViewportLabel();
|
|
1826
|
+
syncViewportMenuControls();
|
|
1827
|
+
if (selectedEl && currentMode === 'editor') requestAnimationFrame(function() { positionSelectionToolbar(); });
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
function setViewportPreset(presetKey) {
|
|
1831
|
+
var preset = DEVICE_PRESETS[presetKey];
|
|
1832
|
+
if (!preset) return;
|
|
1833
|
+
viewportPreset = presetKey;
|
|
1834
|
+
viewportWidth = preset.width;
|
|
1835
|
+
viewportHeight = preset.height;
|
|
1836
|
+
currentDevice = preset.device || 'desktop';
|
|
1837
|
+
['desktop','tablet','mobile'].forEach(function(d) {
|
|
1838
|
+
document.getElementById('dev-' + d).classList.toggle('active', d === currentDevice);
|
|
1839
|
+
});
|
|
1840
|
+
applyViewportFrame();
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1618
1843
|
function setDevice(device) {
|
|
1844
|
+
viewportPreset = device;
|
|
1619
1845
|
currentDevice = device;
|
|
1620
|
-
var
|
|
1621
|
-
|
|
1846
|
+
var preset = DEVICE_PRESETS[device] || DEVICE_PRESETS.desktop;
|
|
1847
|
+
viewportWidth = preset.width;
|
|
1848
|
+
viewportHeight = preset.height;
|
|
1622
1849
|
['desktop','tablet','mobile'].forEach(function(d) {
|
|
1623
1850
|
document.getElementById('dev-' + d).classList.toggle('active', d === device);
|
|
1624
1851
|
});
|
|
1625
|
-
|
|
1852
|
+
applyViewportFrame();
|
|
1853
|
+
}
|
|
1854
|
+
|
|
1855
|
+
function setViewportCustomFromInputs() {
|
|
1856
|
+
var widthInp = document.getElementById('dev-custom-width');
|
|
1857
|
+
var heightInp = document.getElementById('dev-custom-height');
|
|
1858
|
+
var zoomInp = document.getElementById('dev-zoom-level');
|
|
1859
|
+
viewportWidth = clampViewportNumber(widthInp ? widthInp.value : '', viewportWidth, 240, 3840);
|
|
1860
|
+
viewportHeight = clampViewportNumber(heightInp ? heightInp.value : '', viewportHeight, 320, 3840);
|
|
1861
|
+
var z = clampViewportNumber(zoomInp ? zoomInp.value : '', Math.round(getAppliedViewportZoom() * 100), 25, 200);
|
|
1862
|
+
viewportZoom = z / 100;
|
|
1863
|
+
viewportPreset = 'custom';
|
|
1864
|
+
currentDevice = viewportWidth <= 480 ? 'mobile' : (viewportWidth <= 1024 ? 'tablet' : 'desktop');
|
|
1865
|
+
['desktop','tablet','mobile'].forEach(function(d) {
|
|
1866
|
+
document.getElementById('dev-' + d).classList.toggle('active', d === currentDevice);
|
|
1867
|
+
});
|
|
1868
|
+
applyViewportFrame();
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
function closeViewportMenu() {
|
|
1872
|
+
var menu = document.getElementById('dev-more-menu');
|
|
1873
|
+
if (!menu) return;
|
|
1874
|
+
menu.classList.remove('open');
|
|
1875
|
+
menu.setAttribute('aria-hidden', 'true');
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
function toggleViewportMenu() {
|
|
1879
|
+
var menu = document.getElementById('dev-more-menu');
|
|
1880
|
+
if (!menu) return;
|
|
1881
|
+
var shouldOpen = !menu.classList.contains('open');
|
|
1882
|
+
menu.classList.toggle('open', shouldOpen);
|
|
1883
|
+
menu.setAttribute('aria-hidden', shouldOpen ? 'false' : 'true');
|
|
1884
|
+
}
|
|
1885
|
+
|
|
1886
|
+
function bindViewportControls() {
|
|
1887
|
+
var btn = document.getElementById('dev-more-btn');
|
|
1888
|
+
var menu = document.getElementById('dev-more-menu');
|
|
1889
|
+
var leftPanelToggleLabel = document.getElementById('left-panel-toggle-label');
|
|
1890
|
+
var presetButtons = document.querySelectorAll('#dev-preset-list .vp-preset-btn');
|
|
1891
|
+
var applyBtn = document.getElementById('dev-apply-btn');
|
|
1892
|
+
var zoomInp = document.getElementById('dev-zoom-level');
|
|
1893
|
+
var viewportBtn = document.querySelector('.tb-viewport');
|
|
1894
|
+
function updateLeftPanelToggleLabel() {
|
|
1895
|
+
if (!leftPanelToggleLabel) return;
|
|
1896
|
+
leftPanelToggleLabel.textContent = leftPanelCollapsed ? 'Expand left panel' : 'Collapse left panel';
|
|
1897
|
+
}
|
|
1898
|
+
function setLeftPanelCollapsed(collapsed) {
|
|
1899
|
+
var panel = document.getElementById('left-panel');
|
|
1900
|
+
leftPanelCollapsed = !!collapsed;
|
|
1901
|
+
if (panel) panel.style.display = leftPanelCollapsed ? 'none' : '';
|
|
1902
|
+
updateLeftPanelToggleLabel();
|
|
1903
|
+
applyViewportFrame();
|
|
1904
|
+
}
|
|
1905
|
+
if (leftPanelToggleLabel) {
|
|
1906
|
+
leftPanelToggleLabel.addEventListener('click', function(e) {
|
|
1907
|
+
e.preventDefault();
|
|
1908
|
+
e.stopPropagation();
|
|
1909
|
+
setLeftPanelCollapsed(!leftPanelCollapsed);
|
|
1910
|
+
});
|
|
1911
|
+
}
|
|
1912
|
+
if (btn) btn.addEventListener('click', function(e) {
|
|
1913
|
+
e.preventDefault();
|
|
1914
|
+
e.stopPropagation();
|
|
1915
|
+
toggleViewportMenu();
|
|
1916
|
+
});
|
|
1917
|
+
if (viewportBtn) viewportBtn.addEventListener('click', function(e) {
|
|
1918
|
+
e.preventDefault();
|
|
1919
|
+
e.stopPropagation();
|
|
1920
|
+
toggleViewportMenu();
|
|
1921
|
+
});
|
|
1922
|
+
if (applyBtn) applyBtn.addEventListener('click', function(e) {
|
|
1923
|
+
e.preventDefault();
|
|
1924
|
+
setViewportCustomFromInputs();
|
|
1925
|
+
closeViewportMenu();
|
|
1926
|
+
});
|
|
1927
|
+
if (zoomInp) {
|
|
1928
|
+
zoomInp.addEventListener('change', function() {
|
|
1929
|
+
var z = clampViewportNumber(zoomInp.value, Math.round(getAppliedViewportZoom() * 100), 25, 200);
|
|
1930
|
+
viewportZoom = z / 100;
|
|
1931
|
+
applyViewportFrame();
|
|
1932
|
+
});
|
|
1933
|
+
}
|
|
1934
|
+
if (presetButtons && presetButtons.length) {
|
|
1935
|
+
for (var i = 0; i < presetButtons.length; i++) {
|
|
1936
|
+
presetButtons[i].addEventListener('click', function(e) {
|
|
1937
|
+
e.preventDefault();
|
|
1938
|
+
var key = this.getAttribute('data-preset');
|
|
1939
|
+
if (!key) return;
|
|
1940
|
+
setViewportPreset(key);
|
|
1941
|
+
});
|
|
1942
|
+
}
|
|
1943
|
+
}
|
|
1944
|
+
document.addEventListener('click', function(e) {
|
|
1945
|
+
if (!menu || !menu.classList.contains('open')) return;
|
|
1946
|
+
if (menu.contains(e.target) || (btn && btn.contains(e.target)) || (viewportBtn && viewportBtn.contains(e.target))) return;
|
|
1947
|
+
closeViewportMenu();
|
|
1948
|
+
});
|
|
1949
|
+
document.addEventListener('keydown', function(e) {
|
|
1950
|
+
if (e.key === 'Escape') closeViewportMenu();
|
|
1951
|
+
});
|
|
1952
|
+
window.addEventListener('resize', function() { applyViewportFrame(); });
|
|
1953
|
+
updateLeftPanelToggleLabel();
|
|
1954
|
+
applyViewportFrame();
|
|
1626
1955
|
}
|
|
1627
1956
|
|
|
1628
1957
|
// \u2500\u2500 Left panel tab switch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -1666,6 +1995,19 @@ function switchSectionComponentsTab(tab) {
|
|
|
1666
1995
|
renderSidebar(inp ? inp.value : '');
|
|
1667
1996
|
}
|
|
1668
1997
|
|
|
1998
|
+
function toggleSectionComponentsPanel(forceVisible) {
|
|
1999
|
+
var panel = document.getElementById('section-components-panel');
|
|
2000
|
+
if (!panel) return;
|
|
2001
|
+
var shouldShow =
|
|
2002
|
+
typeof forceVisible === 'boolean'
|
|
2003
|
+
? forceVisible
|
|
2004
|
+
: panel.style.display === 'none';
|
|
2005
|
+
panel.style.display = shouldShow ? '' : 'none';
|
|
2006
|
+
if (shouldShow) {
|
|
2007
|
+
switchSectionComponentsTab(currentSectionComponentsTab || 'components');
|
|
2008
|
+
}
|
|
2009
|
+
}
|
|
2010
|
+
|
|
1669
2011
|
// \u2500\u2500 Accordion toggle \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1670
2012
|
function toggleAcc(name) {
|
|
1671
2013
|
var sec = document.getElementById('acc-' + name);
|
|
@@ -1771,9 +2113,60 @@ function getOriginalValue(inputId, el) {
|
|
|
1771
2113
|
}
|
|
1772
2114
|
}
|
|
1773
2115
|
|
|
2116
|
+
var PX_DEFAULT_INPUT_IDS = {
|
|
2117
|
+
'pp-mt': true, 'pp-mr': true, 'pp-mb': true, 'pp-ml': true,
|
|
2118
|
+
'pp-pt': true, 'pp-pr': true, 'pp-pb': true, 'pp-pl': true,
|
|
2119
|
+
};
|
|
2120
|
+
|
|
2121
|
+
var PX_DEFAULT_CSS_PROPS = {
|
|
2122
|
+
'margin-top': true, 'margin-right': true, 'margin-bottom': true, 'margin-left': true,
|
|
2123
|
+
'padding-top': true, 'padding-right': true, 'padding-bottom': true, 'padding-left': true,
|
|
2124
|
+
};
|
|
2125
|
+
|
|
2126
|
+
function normalizeCssValueForProperty(prop, value) {
|
|
2127
|
+
var p = prop == null ? '' : String(prop).trim();
|
|
2128
|
+
var pKebab = p
|
|
2129
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
2130
|
+
.replace(/_/g, '-')
|
|
2131
|
+
.replace(/!important/gi, '')
|
|
2132
|
+
.replace(/[^a-zA-Z-]/g, '')
|
|
2133
|
+
.toLowerCase();
|
|
2134
|
+
var raw = value == null ? '' : String(value).trim();
|
|
2135
|
+
var rawClean = raw.replace(/[\u200B\u200C\u200D\uFEFF]/g, '').trim();
|
|
2136
|
+
var numericCandidate = rawClean.replace(/[, ]+/g, '');
|
|
2137
|
+
var isSpacingProp = /^(?:margin|padding)(?:-(?:top|right|bottom|left))?$/.test(pKebab);
|
|
2138
|
+
if (!pKebab || !rawClean) return rawClean;
|
|
2139
|
+
var numericValue = Number(numericCandidate);
|
|
2140
|
+
var shouldAddPx =
|
|
2141
|
+
isSpacingProp &&
|
|
2142
|
+
numericCandidate !== '' &&
|
|
2143
|
+
Number.isFinite(numericValue) &&
|
|
2144
|
+
/^[-+]?(?:[0-9]+(?:[.][0-9]+)?|[.][0-9]+)$/.test(numericCandidate);
|
|
2145
|
+
var out = shouldAddPx ? numericCandidate + 'px' : rawClean;
|
|
2146
|
+
return out;
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
function normalizeChainSetRowUnits(row) {
|
|
2150
|
+
if (!row) return row;
|
|
2151
|
+
if (normalizeChangesetType(row) === 'style') {
|
|
2152
|
+
row.value = normalizeCssValueForProperty(row.property || row.cssProp, row.value);
|
|
2153
|
+
}
|
|
2154
|
+
return row;
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
function normalizeLoggedValue(inputId, value) {
|
|
2158
|
+
var raw = value == null ? '' : String(value).trim();
|
|
2159
|
+
if (!raw) return raw;
|
|
2160
|
+
if (PX_DEFAULT_INPUT_IDS[inputId] && /^-?d+(?:.d+)?$/.test(raw)) {
|
|
2161
|
+
return raw + 'px';
|
|
2162
|
+
}
|
|
2163
|
+
return raw;
|
|
2164
|
+
}
|
|
2165
|
+
|
|
1774
2166
|
function logChange(selector, inputId, value, targetEl, originalValue) {
|
|
1775
2167
|
var meta = PROP_META[inputId];
|
|
1776
2168
|
if (!meta) return;
|
|
2169
|
+
value = normalizeLoggedValue(inputId, value);
|
|
1777
2170
|
var key = selector + '||' + inputId;
|
|
1778
2171
|
// Skip trivially empty / reset values \u2014 remove from log if present
|
|
1779
2172
|
if (value === '' || value === 'none' || value === 'auto' || value === 'normal') {
|
|
@@ -1875,6 +2268,24 @@ function syncDesignInput(change) {
|
|
|
1875
2268
|
function removeStateChange(idx) {
|
|
1876
2269
|
var change = stateChanges[idx];
|
|
1877
2270
|
if (!change) return;
|
|
2271
|
+
if (change.isStructuralLive) {
|
|
2272
|
+
removeSessionStructuralRowByTimestamp(
|
|
2273
|
+
change.structuralVarId || activeVarId,
|
|
2274
|
+
change.vveTs,
|
|
2275
|
+
);
|
|
2276
|
+
stateChanges.splice(idx, 1);
|
|
2277
|
+
commitStateChangesForActiveVariation();
|
|
2278
|
+
renderStatesTab();
|
|
2279
|
+
if (currentMainTab === 'history') renderHistoryTab();
|
|
2280
|
+
try {
|
|
2281
|
+
delete varHtmlCache[activeVarId];
|
|
2282
|
+
} catch(_) {}
|
|
2283
|
+
appliedStructuralChangesetKeys = {};
|
|
2284
|
+
recomputeEditorDirty();
|
|
2285
|
+
scheduleDomTreeRefresh();
|
|
2286
|
+
softReloadEditorIframe();
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
1878
2289
|
revertChangeOnDom(change);
|
|
1879
2290
|
syncDesignInput(change);
|
|
1880
2291
|
stateChanges.splice(idx, 1);
|
|
@@ -2231,6 +2642,14 @@ function getLatestHistoryUndoTarget() {
|
|
|
2231
2642
|
return list.length ? list[0] : null;
|
|
2232
2643
|
}
|
|
2233
2644
|
|
|
2645
|
+
function getLatestLiveUndoTarget() {
|
|
2646
|
+
var list = getUnifiedHistoryItems();
|
|
2647
|
+
for (var i = 0; i < list.length; i++) {
|
|
2648
|
+
if (list[i] && list[i].source === 'live') return list[i];
|
|
2649
|
+
}
|
|
2650
|
+
return null;
|
|
2651
|
+
}
|
|
2652
|
+
|
|
2234
2653
|
function changesetListHasStructural(arr) {
|
|
2235
2654
|
if (!arr || !arr.length) return false;
|
|
2236
2655
|
for (var i = 0; i < arr.length; i++) {
|
|
@@ -2329,8 +2748,15 @@ function removeHistoryChangeset(idx, evt) {
|
|
|
2329
2748
|
function clearAllHistoryChangesets() {
|
|
2330
2749
|
var v = getActiveVariationForHistory();
|
|
2331
2750
|
if (!v) return;
|
|
2332
|
-
|
|
2751
|
+
var hasSavedChangesets = parseVariationChangesets(v).length > 0;
|
|
2752
|
+
var hasSessionStructural =
|
|
2753
|
+
!!(activeVarId && sessionStructuralChainRowsByVarId[activeVarId] && sessionStructuralChainRowsByVarId[activeVarId].length);
|
|
2754
|
+
if (!hasSavedChangesets && !hasSessionStructural) return;
|
|
2755
|
+
|
|
2333
2756
|
persistActiveVariationChangesets([]);
|
|
2757
|
+
if (activeVarId) {
|
|
2758
|
+
sessionStructuralChainRowsByVarId[activeVarId] = [];
|
|
2759
|
+
}
|
|
2334
2760
|
appliedChangesetSnapshots = {};
|
|
2335
2761
|
appliedStructuralChangesetKeys = {};
|
|
2336
2762
|
try {
|
|
@@ -2343,6 +2769,10 @@ function clearAllHistoryChangesets() {
|
|
|
2343
2769
|
}
|
|
2344
2770
|
|
|
2345
2771
|
function clearAllUnifiedHistory() {
|
|
2772
|
+
if (activeVarId) {
|
|
2773
|
+
// Ensure structural unsaved rows are also removed by "Clear all changes".
|
|
2774
|
+
sessionStructuralChainRowsByVarId[activeVarId] = [];
|
|
2775
|
+
}
|
|
2346
2776
|
clearAllStates();
|
|
2347
2777
|
clearAllHistoryChangesets();
|
|
2348
2778
|
if (currentMainTab === 'history') renderHistoryTab();
|
|
@@ -2354,15 +2784,32 @@ var VVE_LOCAL_STORAGE_PREFIX = 'vve:';
|
|
|
2354
2784
|
|
|
2355
2785
|
function clearVisualEditorLocalStorage() {
|
|
2356
2786
|
try {
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2787
|
+
var stores = [];
|
|
2788
|
+
try { stores.push(localStorage); } catch(_) {}
|
|
2789
|
+
try { stores.push(sessionStorage); } catch(_) {}
|
|
2790
|
+
for (var si = 0; si < stores.length; si++) {
|
|
2791
|
+
var store = stores[si];
|
|
2792
|
+
if (!store) continue;
|
|
2793
|
+
for (var i = store.length - 1; i >= 0; i--) {
|
|
2794
|
+
var k = store.key(i);
|
|
2795
|
+
if (k && k.indexOf(VVE_LOCAL_STORAGE_PREFIX) === 0) {
|
|
2796
|
+
store.removeItem(k);
|
|
2797
|
+
}
|
|
2361
2798
|
}
|
|
2362
2799
|
}
|
|
2363
2800
|
} catch(_) {}
|
|
2364
2801
|
}
|
|
2365
2802
|
|
|
2803
|
+
function clearPersistedActiveVariationForData(data) {
|
|
2804
|
+
try {
|
|
2805
|
+
var sk = activeVariationStorageKeyFromPayload(data);
|
|
2806
|
+
if (sk && sk !== VVE_LOCAL_STORAGE_PREFIX + 'activeVar::') {
|
|
2807
|
+
try { localStorage.removeItem(sk); } catch(_) {}
|
|
2808
|
+
try { sessionStorage.removeItem(sk); } catch(_) {}
|
|
2809
|
+
}
|
|
2810
|
+
} catch(_) {}
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2366
2813
|
function activeVariationStorageKeyFromPayload(data) {
|
|
2367
2814
|
return (
|
|
2368
2815
|
VVE_LOCAL_STORAGE_PREFIX +
|
|
@@ -2401,22 +2848,41 @@ function writePersistedActiveVariationId(varId) {
|
|
|
2401
2848
|
* @param allowPrevMemory when true, keep in-session activeVarId if still valid (skip-reload path).
|
|
2402
2849
|
*/
|
|
2403
2850
|
function pickActiveVariationIdForLoad(data, variationsArr, prevMemoryId, allowPrevMemory) {
|
|
2404
|
-
var
|
|
2405
|
-
var fallback = (
|
|
2851
|
+
var firstNonBaseline = variationsArr.find(function(v) { return !v.baseline; });
|
|
2852
|
+
var fallback = (firstNonBaseline || variationsArr[0] || {})._id || null;
|
|
2406
2853
|
if (!variationsArr.length) return null;
|
|
2407
2854
|
if (allowPrevMemory && prevMemoryId && variationsArr.some(function(v) { return v._id === prevMemoryId; })) {
|
|
2408
2855
|
return prevMemoryId;
|
|
2409
2856
|
}
|
|
2410
2857
|
var stored = readPersistedActiveVariationId(data);
|
|
2411
2858
|
if (stored && variationsArr.some(function(v) { return v._id === stored; })) {
|
|
2859
|
+
var storedVar = variationsArr.find(function(v) { return v._id === stored; });
|
|
2860
|
+
if (storedVar && storedVar.baseline && firstNonBaseline && firstNonBaseline._id) {
|
|
2861
|
+
return firstNonBaseline._id;
|
|
2862
|
+
}
|
|
2412
2863
|
return stored;
|
|
2413
2864
|
}
|
|
2414
2865
|
return fallback;
|
|
2415
2866
|
}
|
|
2416
2867
|
|
|
2868
|
+
function updateExperimentNameLabel(data) {
|
|
2869
|
+
var el = document.getElementById('tb-exp-name');
|
|
2870
|
+
if (!el) return;
|
|
2871
|
+
var name = '';
|
|
2872
|
+
try {
|
|
2873
|
+
name = data && data.name != null ? String(data.name).trim() : '';
|
|
2874
|
+
} catch(_) {
|
|
2875
|
+
name = '';
|
|
2876
|
+
}
|
|
2877
|
+
if (!name) name = 'Visual Editor';
|
|
2878
|
+
el.textContent = name;
|
|
2879
|
+
el.title = name;
|
|
2880
|
+
}
|
|
2881
|
+
|
|
2417
2882
|
// \u2500\u2500 Experiment loading \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
2418
2883
|
function handleLoadExperiment(data) {
|
|
2419
2884
|
clearPendingGranularChangesets();
|
|
2885
|
+
updateExperimentNameLabel(data);
|
|
2420
2886
|
var prevKey = experimentData
|
|
2421
2887
|
? String(experimentData.experimentId || '') + '|' + String(experimentData.pageUrl || '')
|
|
2422
2888
|
: '';
|
|
@@ -2632,7 +3098,13 @@ function granularAnySelectorMatches(doc, cs) {
|
|
|
2632
3098
|
|
|
2633
3099
|
/** Bust bfcache / same-URL no-op reloads so the iframe actually re-parses (loading \u2192 interactive). */
|
|
2634
3100
|
function appendIframeReloadBust(url) {
|
|
2635
|
-
|
|
3101
|
+
try {
|
|
3102
|
+
var u = new URL(String(url || ''), window.location.href);
|
|
3103
|
+
u.searchParams.set('_vve_reload', String(Date.now()));
|
|
3104
|
+
return u.toString();
|
|
3105
|
+
} catch(_) {
|
|
3106
|
+
return url;
|
|
3107
|
+
}
|
|
2636
3108
|
}
|
|
2637
3109
|
|
|
2638
3110
|
// True when the iframe contentDocument belongs to the current iframe.src navigation.
|
|
@@ -3010,11 +3482,55 @@ function appendSessionStructuralChainRow(varId, row) {
|
|
|
3010
3482
|
sessionStructuralChainRowsByVarId[varId].push(row);
|
|
3011
3483
|
}
|
|
3012
3484
|
|
|
3485
|
+
function markStructuralRowApplied(row) {
|
|
3486
|
+
try {
|
|
3487
|
+
var k = structuralChangesetDedupKey(row);
|
|
3488
|
+
if (k) appliedStructuralChangesetKeys[k] = true;
|
|
3489
|
+
} catch(_) {}
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
function logStructuralStateChange(row, label, value, targetEl) {
|
|
3493
|
+
if (!row || !row.selector) return;
|
|
3494
|
+
stateChanges.push({
|
|
3495
|
+
selector: row.selector,
|
|
3496
|
+
inputId: 'vve-struct',
|
|
3497
|
+
label: label || 'Structure change',
|
|
3498
|
+
cssProp: null,
|
|
3499
|
+
value: value != null ? String(value) : String(row.type || ''),
|
|
3500
|
+
targetEl: targetEl || null,
|
|
3501
|
+
originalValue: '',
|
|
3502
|
+
vveTs: row.vveTs || nextHistoryTimestamp(),
|
|
3503
|
+
isStructuralLive: true,
|
|
3504
|
+
structuralVarId: activeVarId || null,
|
|
3505
|
+
structuralType: row.type || '',
|
|
3506
|
+
});
|
|
3507
|
+
if (currentMainTab === 'history') renderHistoryTab();
|
|
3508
|
+
commitStateChangesForActiveVariation();
|
|
3509
|
+
}
|
|
3510
|
+
|
|
3511
|
+
function removeSessionStructuralRowByTimestamp(varId, ts) {
|
|
3512
|
+
if (!varId || !ts) return;
|
|
3513
|
+
var arr = sessionStructuralChainRowsByVarId[varId];
|
|
3514
|
+
if (!arr || !arr.length) return;
|
|
3515
|
+
for (var i = arr.length - 1; i >= 0; i--) {
|
|
3516
|
+
if (arr[i] && arr[i].vveTs === ts) {
|
|
3517
|
+
arr.splice(i, 1);
|
|
3518
|
+
return;
|
|
3519
|
+
}
|
|
3520
|
+
}
|
|
3521
|
+
}
|
|
3522
|
+
|
|
3013
3523
|
/** One States-tab row -> Conversion.io chain-set shape (matches applyChangesetEntry). */
|
|
3014
3524
|
function stateChangeToChainSet(c) {
|
|
3015
3525
|
if (!c || !c.selector) return null;
|
|
3016
3526
|
if (c.cssProp) {
|
|
3017
|
-
return {
|
|
3527
|
+
return {
|
|
3528
|
+
selector: c.selector,
|
|
3529
|
+
type: 'style',
|
|
3530
|
+
property: c.cssProp,
|
|
3531
|
+
value: normalizeCssValueForProperty(c.cssProp, c.value),
|
|
3532
|
+
vveTs: c.vveTs || nextHistoryTimestamp()
|
|
3533
|
+
};
|
|
3018
3534
|
}
|
|
3019
3535
|
switch (c.inputId) {
|
|
3020
3536
|
case 'pp-text':
|
|
@@ -3186,7 +3702,7 @@ function buildPersistentStyleRulesForActiveVariation() {
|
|
|
3186
3702
|
if (value == null || value === '') return;
|
|
3187
3703
|
var sel = sanitizeSelectorForMatch(String(selector)) || String(selector);
|
|
3188
3704
|
var pr = String(prop).trim();
|
|
3189
|
-
var val =
|
|
3705
|
+
var val = normalizeCssValueForProperty(pr, value);
|
|
3190
3706
|
if (!sel || !pr || !val) return;
|
|
3191
3707
|
var k = sel + '__vve_sep__' + pr;
|
|
3192
3708
|
if (!map[k]) order.push(k);
|
|
@@ -3224,7 +3740,8 @@ function buildPersistentStyleRulesForActiveVariation() {
|
|
|
3224
3740
|
var lines = [];
|
|
3225
3741
|
for (var oi = 0; oi < order.length; oi++) {
|
|
3226
3742
|
var row = map[order[oi]];
|
|
3227
|
-
|
|
3743
|
+
var outVal = normalizeCssValueForProperty(row.property, row.value);
|
|
3744
|
+
lines.push(row.selector + ' { ' + row.property + ': ' + outVal + ' !important; }');
|
|
3228
3745
|
}
|
|
3229
3746
|
return lines.join('\\n');
|
|
3230
3747
|
}
|
|
@@ -3375,7 +3892,9 @@ function buildPersistedChainSetsForVariation(v) {
|
|
|
3375
3892
|
var row = stateChangeToChainSet(sourceStateChanges[si]);
|
|
3376
3893
|
if (row) overlay.push(row);
|
|
3377
3894
|
}
|
|
3378
|
-
|
|
3895
|
+
var merged = mergeGranularChainSets(mergeGranularChainSets(base, sessionExtra), overlay);
|
|
3896
|
+
for (var mi = 0; mi < merged.length; mi++) normalizeChainSetRowUnits(merged[mi]);
|
|
3897
|
+
return merged;
|
|
3379
3898
|
}
|
|
3380
3899
|
|
|
3381
3900
|
/**
|
|
@@ -3704,12 +4223,15 @@ function duplicateSelectedEl() {
|
|
|
3704
4223
|
clone.setAttribute('data-vve-instance', generateVveInstanceId());
|
|
3705
4224
|
} catch(_) {}
|
|
3706
4225
|
if (activeVarId) {
|
|
3707
|
-
|
|
4226
|
+
var dupRow = {
|
|
3708
4227
|
selector: anchorSel,
|
|
3709
4228
|
type: 'insert',
|
|
3710
4229
|
action: 'after',
|
|
3711
4230
|
html: clone.outerHTML,
|
|
3712
|
-
}
|
|
4231
|
+
};
|
|
4232
|
+
appendSessionStructuralChainRow(activeVarId, dupRow);
|
|
4233
|
+
markStructuralRowApplied(dupRow);
|
|
4234
|
+
logStructuralStateChange(dupRow, 'Duplicated via toolbar', 'Duplicate inserted', selectedEl);
|
|
3713
4235
|
}
|
|
3714
4236
|
selectedEl.parentNode.insertBefore(clone, selectedEl.nextSibling);
|
|
3715
4237
|
saveCurrentVariationHtml();
|
|
@@ -3725,23 +4247,27 @@ function toggleHideSelectedEl() {
|
|
|
3725
4247
|
selectedEl.style.visibility = '';
|
|
3726
4248
|
selectedEl.removeAttribute('data-vve-hidden');
|
|
3727
4249
|
if (activeVarId) {
|
|
3728
|
-
|
|
4250
|
+
var showRow = {
|
|
3729
4251
|
selector: hidSel,
|
|
3730
4252
|
type: 'style',
|
|
3731
4253
|
property: 'visibility',
|
|
3732
4254
|
value: '',
|
|
3733
|
-
}
|
|
4255
|
+
};
|
|
4256
|
+
appendSessionStructuralChainRow(activeVarId, showRow);
|
|
4257
|
+
logStructuralStateChange(showRow, 'Shown via toolbar', 'Visibility restored', selectedEl);
|
|
3734
4258
|
}
|
|
3735
4259
|
} else {
|
|
3736
4260
|
selectedEl.style.visibility = 'hidden';
|
|
3737
4261
|
selectedEl.setAttribute('data-vve-hidden', '1');
|
|
3738
4262
|
if (activeVarId) {
|
|
3739
|
-
|
|
4263
|
+
var hideRow = {
|
|
3740
4264
|
selector: hidSel,
|
|
3741
4265
|
type: 'style',
|
|
3742
4266
|
property: 'visibility',
|
|
3743
4267
|
value: 'hidden',
|
|
3744
|
-
}
|
|
4268
|
+
};
|
|
4269
|
+
appendSessionStructuralChainRow(activeVarId, hideRow);
|
|
4270
|
+
logStructuralStateChange(hideRow, 'Hidden via toolbar', 'Visibility set to hidden', selectedEl);
|
|
3745
4271
|
}
|
|
3746
4272
|
}
|
|
3747
4273
|
saveCurrentVariationHtml();
|
|
@@ -3752,7 +4278,11 @@ function deleteSelectedEl() {
|
|
|
3752
4278
|
if (!selectedEl || !selectedEl.parentNode) return;
|
|
3753
4279
|
var delSel = buildSelector(selectedEl);
|
|
3754
4280
|
selectedEl.remove();
|
|
3755
|
-
if (activeVarId)
|
|
4281
|
+
if (activeVarId) {
|
|
4282
|
+
var delRow = { selector: delSel, type: 'remove' };
|
|
4283
|
+
appendSessionStructuralChainRow(activeVarId, delRow);
|
|
4284
|
+
logStructuralStateChange(delRow, 'Deleted via toolbar', 'Element removed', null);
|
|
4285
|
+
}
|
|
3756
4286
|
saveCurrentVariationHtml();
|
|
3757
4287
|
recomputeEditorDirty();
|
|
3758
4288
|
deselectElement();
|
|
@@ -4653,19 +5183,25 @@ function recordReorderAfterDrag(movedEl) {
|
|
|
4653
5183
|
var prev = movedEl.previousElementSibling;
|
|
4654
5184
|
var next = movedEl.nextElementSibling;
|
|
4655
5185
|
if (prev) {
|
|
4656
|
-
|
|
5186
|
+
var reorderAfterRow = {
|
|
4657
5187
|
selector: buildSelector(movedEl),
|
|
4658
5188
|
type: 'reorder',
|
|
4659
5189
|
targetSelector: buildSelector(prev),
|
|
4660
5190
|
action: 'after',
|
|
4661
|
-
}
|
|
5191
|
+
};
|
|
5192
|
+
appendSessionStructuralChainRow(activeVarId, reorderAfterRow);
|
|
5193
|
+
markStructuralRowApplied(reorderAfterRow);
|
|
5194
|
+
logStructuralStateChange(reorderAfterRow, 'Reordered via drag', 'Moved after sibling', movedEl);
|
|
4662
5195
|
} else if (next) {
|
|
4663
|
-
|
|
5196
|
+
var reorderBeforeRow = {
|
|
4664
5197
|
selector: buildSelector(movedEl),
|
|
4665
5198
|
type: 'reorder',
|
|
4666
5199
|
targetSelector: buildSelector(next),
|
|
4667
5200
|
action: 'before',
|
|
4668
|
-
}
|
|
5201
|
+
};
|
|
5202
|
+
appendSessionStructuralChainRow(activeVarId, reorderBeforeRow);
|
|
5203
|
+
markStructuralRowApplied(reorderBeforeRow);
|
|
5204
|
+
logStructuralStateChange(reorderBeforeRow, 'Reordered via drag', 'Moved before sibling', movedEl);
|
|
4669
5205
|
}
|
|
4670
5206
|
}
|
|
4671
5207
|
|
|
@@ -4946,12 +5482,15 @@ function insertHtml(html) {
|
|
|
4946
5482
|
}
|
|
4947
5483
|
if (firstEl) selectElement(firstEl);
|
|
4948
5484
|
if (activeVarId) {
|
|
4949
|
-
|
|
5485
|
+
var insertRow = {
|
|
4950
5486
|
selector: anchorSel,
|
|
4951
5487
|
type: 'insert',
|
|
4952
5488
|
action: 'after',
|
|
4953
5489
|
html: htmlStr,
|
|
4954
|
-
}
|
|
5490
|
+
};
|
|
5491
|
+
appendSessionStructuralChainRow(activeVarId, insertRow);
|
|
5492
|
+
markStructuralRowApplied(insertRow);
|
|
5493
|
+
logStructuralStateChange(insertRow, 'Added component/section', 'Inserted new element', firstEl || selectedEl);
|
|
4955
5494
|
}
|
|
4956
5495
|
saveCurrentVariationHtml();
|
|
4957
5496
|
recomputeEditorDirty();
|
|
@@ -5041,6 +5580,14 @@ document.getElementById('comp-search').addEventListener('input', function() {
|
|
|
5041
5580
|
renderSidebar(this.value);
|
|
5042
5581
|
}
|
|
5043
5582
|
});
|
|
5583
|
+
var btnAddElement = document.getElementById('btn-add-element');
|
|
5584
|
+
if (btnAddElement) {
|
|
5585
|
+
btnAddElement.addEventListener('click', function(e) {
|
|
5586
|
+
e.preventDefault();
|
|
5587
|
+
e.stopPropagation();
|
|
5588
|
+
toggleSectionComponentsPanel();
|
|
5589
|
+
});
|
|
5590
|
+
}
|
|
5044
5591
|
|
|
5045
5592
|
// \u2500\u2500 Save / Close \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5046
5593
|
document.getElementById('btn-save').addEventListener('click', handleSave);
|
|
@@ -5081,11 +5628,21 @@ function handleSave() {
|
|
|
5081
5628
|
}
|
|
5082
5629
|
|
|
5083
5630
|
function handleClose() {
|
|
5631
|
+
clearPersistedActiveVariationForData(experimentData);
|
|
5084
5632
|
clearVisualEditorLocalStorage();
|
|
5085
5633
|
// Unsaved-changes UX lives in the parent (PlatformVisualEditorV2); avoid double confirm here.
|
|
5086
5634
|
send('close-editor', {});
|
|
5087
5635
|
}
|
|
5088
5636
|
|
|
5637
|
+
// Defensive cleanup: if parent closes/unmounts the editor shell without
|
|
5638
|
+
// invoking handleClose(), clear persisted VVE keys on unload as well.
|
|
5639
|
+
window.addEventListener('pagehide', function() {
|
|
5640
|
+
clearVisualEditorLocalStorage();
|
|
5641
|
+
});
|
|
5642
|
+
window.addEventListener('beforeunload', function() {
|
|
5643
|
+
clearVisualEditorLocalStorage();
|
|
5644
|
+
});
|
|
5645
|
+
|
|
5089
5646
|
// \u2500\u2500 Keyboard shortcuts \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
5090
5647
|
function isNativeEditableTarget(target) {
|
|
5091
5648
|
if (!target || target.nodeType !== 1) return false;
|
|
@@ -5107,10 +5664,7 @@ document.addEventListener('keydown', function(e) {
|
|
|
5107
5664
|
e.preventDefault();
|
|
5108
5665
|
runEditorUndo();
|
|
5109
5666
|
}
|
|
5110
|
-
|
|
5111
|
-
e.preventDefault();
|
|
5112
|
-
runEditorRedo();
|
|
5113
|
-
}
|
|
5667
|
+
// Redo is intentionally hidden/disabled in this editor flow.
|
|
5114
5668
|
if (meta && e.key === 's') { e.preventDefault(); handleSave(); }
|
|
5115
5669
|
if (e.key === 'Escape') {
|
|
5116
5670
|
var openTips = document.querySelectorAll('.ve-pl-tip.is-tip-open');
|
|
@@ -5130,11 +5684,17 @@ document.addEventListener('keydown', function(e) {
|
|
|
5130
5684
|
}
|
|
5131
5685
|
});
|
|
5132
5686
|
function runEditorUndo() {
|
|
5133
|
-
|
|
5134
|
-
if (
|
|
5135
|
-
|
|
5687
|
+
// Undo only unsaved in-session edits; do not remove persisted history rows.
|
|
5688
|
+
if (!isDirty) return;
|
|
5689
|
+
|
|
5690
|
+
// 1) Prefer live unsaved change stack (stateChanges shown in History tab).
|
|
5691
|
+
var liveTarget = getLatestLiveUndoTarget();
|
|
5692
|
+
if (liveTarget) {
|
|
5693
|
+
removeHistoryItem('live', liveTarget.idx);
|
|
5136
5694
|
return;
|
|
5137
5695
|
}
|
|
5696
|
+
|
|
5697
|
+
// 2) Fallback to Vvveb internal undo stack (e.g. structural drag/drop ops).
|
|
5138
5698
|
if (!(typeof Vvveb !== 'undefined' && Vvveb.Undo)) return;
|
|
5139
5699
|
Vvveb.Undo.undo();
|
|
5140
5700
|
saveCurrentVariationHtml();
|
|
@@ -5157,11 +5717,10 @@ document.getElementById('btn-undo').addEventListener('click', function(e) {
|
|
|
5157
5717
|
e.stopPropagation();
|
|
5158
5718
|
runEditorUndo();
|
|
5159
5719
|
});
|
|
5160
|
-
document.getElementById('btn-redo')
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
});
|
|
5720
|
+
var btnRedo = document.getElementById('btn-redo');
|
|
5721
|
+
if (btnRedo) {
|
|
5722
|
+
btnRedo.style.display = 'none';
|
|
5723
|
+
}
|
|
5165
5724
|
|
|
5166
5725
|
function layoutLoadingTooltip(host) {
|
|
5167
5726
|
var tip = host.querySelector('.ve-pl-tooltip');
|
|
@@ -5237,6 +5796,7 @@ function registerCROSections() {
|
|
|
5237
5796
|
|
|
5238
5797
|
window.addEventListener('load', function() {
|
|
5239
5798
|
registerCROSections();
|
|
5799
|
+
bindViewportControls();
|
|
5240
5800
|
switchSectionComponentsTab(currentSectionComponentsTab);
|
|
5241
5801
|
renderElementsTree(document.getElementById('comp-search').value);
|
|
5242
5802
|
vvvebReady = true;
|
|
@@ -5944,8 +6504,32 @@ ${runtimePreflightScript}
|
|
|
5944
6504
|
var TARGET_ORIGIN=${JSON.stringify(origin)};
|
|
5945
6505
|
var TARGET_PAGE_URL=${JSON.stringify(targetUrl)};
|
|
5946
6506
|
var EMPTY_JSON_DATA="data:application/json;charset=utf-8,%7B%7D";
|
|
5947
|
-
|
|
5948
|
-
|
|
6507
|
+
var _proxyCtx=(function(){try{return new URL(window.location.href);}catch(_){return null;}})();
|
|
6508
|
+
var PROXY_ROOT="/api/conversion-proxy";
|
|
6509
|
+
var PROXY_PASSWORD=_proxyCtx?_proxyCtx.searchParams.get("password")||"":"";
|
|
6510
|
+
var PROXY_BASE_URL=_proxyCtx?_proxyCtx.searchParams.get("conversionProxyBaseUrl")||"":"";
|
|
6511
|
+
var PROXY_TRACKING_MARKERS=_proxyCtx?_proxyCtx.searchParams.get("trackingMarkers")||"":"";
|
|
6512
|
+
var PROXY_STRICT_FREEZE=_proxyCtx?_proxyCtx.searchParams.get("strictObserverFreeze")||"":"";
|
|
6513
|
+
var PROXY_UPSTREAM_MODE=_proxyCtx?_proxyCtx.searchParams.get("proxy")||"":"";
|
|
6514
|
+
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
6515
|
+
function toProxyNetworkUrl(raw){
|
|
6516
|
+
if(isSkippable(raw))return raw;
|
|
6517
|
+
try{
|
|
6518
|
+
var base=raw.startsWith("/")?TARGET_ORIGIN:TARGET_PAGE_URL;
|
|
6519
|
+
var abs=new URL(raw,base);
|
|
6520
|
+
if(abs.origin!==TARGET_ORIGIN)return raw;
|
|
6521
|
+
var prox=new URL(PROXY_ROOT,window.location.origin);
|
|
6522
|
+
prox.searchParams.set("password",PROXY_PASSWORD||"");
|
|
6523
|
+
prox.searchParams.set("url",abs.toString());
|
|
6524
|
+
if(PROXY_BASE_URL)prox.searchParams.set("conversionProxyBaseUrl",PROXY_BASE_URL);
|
|
6525
|
+
if(PROXY_TRACKING_MARKERS)prox.searchParams.set("trackingMarkers",PROXY_TRACKING_MARKERS);
|
|
6526
|
+
if(PROXY_STRICT_FREEZE)prox.searchParams.set("strictObserverFreeze",PROXY_STRICT_FREEZE);
|
|
6527
|
+
if(PROXY_UPSTREAM_MODE)prox.searchParams.set("proxy",PROXY_UPSTREAM_MODE);
|
|
6528
|
+
return prox.toString();
|
|
6529
|
+
}catch(_){
|
|
6530
|
+
return raw;
|
|
6531
|
+
}
|
|
6532
|
+
}
|
|
5949
6533
|
function resolveUrl(s){try{return new URL(s,window.location.href);}catch(_){return null;}}
|
|
5950
6534
|
function isNestedMalformedProxy(u){if(!u)return false;var p=u.pathname||"";if(p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0)return false;return p.indexOf("api/conversion-proxy")!==-1;}
|
|
5951
6535
|
function skipNestedProxyNetwork(s){var u=typeof s==="string"?resolveUrl(s):null;return u&&isNestedMalformedProxy(u);}
|
|
@@ -5958,9 +6542,9 @@ if(window.fetch){
|
|
|
5958
6542
|
var rawUrl=typeof input==="string"?input:(input&&input.url?String(input.url):"");
|
|
5959
6543
|
if(rawUrl&&skipNestedProxyNetwork(rawUrl))return emptyJsonFetchResponse();
|
|
5960
6544
|
if(typeof input==="string"){
|
|
5961
|
-
input=
|
|
6545
|
+
input=toProxyNetworkUrl(input);
|
|
5962
6546
|
}else if(input&&input.url){
|
|
5963
|
-
var next=
|
|
6547
|
+
var next=toProxyNetworkUrl(input.url);
|
|
5964
6548
|
if(next!==input.url){input=new Request(next,input);}
|
|
5965
6549
|
}
|
|
5966
6550
|
afterUrl=typeof input==="string"?input:(input&&input.url?String(input.url):"");
|
|
@@ -5970,8 +6554,22 @@ if(window.fetch){
|
|
|
5970
6554
|
try{
|
|
5971
6555
|
var u=afterUrl?resolveUrl(afterUrl):null;
|
|
5972
6556
|
var sameOrigin=!!(u&&u.origin===TARGET_ORIGIN);
|
|
5973
|
-
var
|
|
5974
|
-
|
|
6557
|
+
var reqMethod=(init&&init.method?String(init.method):(input&&input.method?String(input.method):"GET")).toUpperCase();
|
|
6558
|
+
var isSafeMethod=reqMethod==="GET"||reqMethod==="HEAD";
|
|
6559
|
+
var path=(u&&u.pathname?u.pathname:"").toLowerCase();
|
|
6560
|
+
var qs=(u&&u.search?u.search:"").toLowerCase();
|
|
6561
|
+
var likelyBackgroundEndpoint=!!(u&&(
|
|
6562
|
+
/(^|\\/)apps?(\\/|$)|(^|\\/)a(\\/|$)/.test(path)||
|
|
6563
|
+
path==="/cart"||
|
|
6564
|
+
path==="/cart.js"||
|
|
6565
|
+
path.indexOf("/cart/")===0||
|
|
6566
|
+
path.indexOf("/recommendations/")===0||
|
|
6567
|
+
path.indexOf("/search/suggest")===0||
|
|
6568
|
+
qs.indexOf("sections=")!==-1||
|
|
6569
|
+
qs.indexOf("section_id=")!==-1
|
|
6570
|
+
));
|
|
6571
|
+
var likelyThirdPartyBg=!sameOrigin||likelyBackgroundEndpoint;
|
|
6572
|
+
if(window.__CONVERSION_EDITOR_ACTIVE__&&isSafeMethod&&likelyThirdPartyBg){
|
|
5975
6573
|
console.warn("[conversion-proxy] suppressed fetch failure",{url:afterUrl,error:err&&err.message?err.message:String(err)});
|
|
5976
6574
|
return new Response("{}",{status:200,headers:{"Content-Type":"application/json; charset=utf-8"}});
|
|
5977
6575
|
}
|
|
@@ -5980,7 +6578,7 @@ if(window.fetch){
|
|
|
5980
6578
|
});
|
|
5981
6579
|
};
|
|
5982
6580
|
}
|
|
5983
|
-
if(window.XMLHttpRequest&&window.XMLHttpRequest.prototype&&window.XMLHttpRequest.prototype.open){var _open=window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open=function(method,url){try{var u=resolveUrl(String(url));if(u&&isNestedMalformedProxy(u)){arguments[1]=EMPTY_JSON_DATA;}else{arguments[1]=
|
|
6581
|
+
if(window.XMLHttpRequest&&window.XMLHttpRequest.prototype&&window.XMLHttpRequest.prototype.open){var _open=window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open=function(method,url){try{var u=resolveUrl(String(url));if(u&&isNestedMalformedProxy(u)){arguments[1]=EMPTY_JSON_DATA;}else{arguments[1]=toProxyNetworkUrl(url);}}catch(_){}return _open.apply(this,arguments);};}
|
|
5984
6582
|
if(window.navigator&&typeof window.navigator.sendBeacon==="function"){var _beacon=window.navigator.sendBeacon.bind(window.navigator);window.navigator.sendBeacon=function(url,data){try{if(skipNestedProxyNetwork(String(url)))return true;}catch(_){}return _beacon(url,data);};}
|
|
5985
6583
|
function withReloadBust(urlRaw){try{var u=resolveUrl(String(urlRaw||""));if(!u)return null;var p=u.pathname||"";var isRootProxyPath=p==="/api/conversion-proxy"||p.indexOf("/api/conversion-proxy/")===0;if(!isRootProxyPath)return null;return u.toString();}catch(_){return null;}}
|
|
5986
6584
|
document.addEventListener("click",function(ev){try{var t=ev&&ev.target;if(!t||!t.closest)return;var a=t.closest("a[href]");if(a){var href=a.getAttribute("href")||a.href||"";var hasModifier=!!(ev.metaKey||ev.ctrlKey||ev.shiftKey||ev.altKey);var targetAttr=(a.getAttribute("target")||"").toLowerCase();var isNewTab=targetAttr==="_blank";var isDownload=!!a.getAttribute("download");if(hasModifier||isNewTab||isDownload)return;var prox=toProxy(href);if(!prox)return;a.setAttribute("href",prox);if(ev&&typeof ev.preventDefault==="function")ev.preventDefault();safeNavigate(href,"assign");return;}var summary=t.closest("summary[data-link]");if(summary&&summary.getAttribute){var raw=summary.getAttribute("data-link")||"";if(raw){var prox2=toProxy(raw);if(prox2){summary.setAttribute("data-link",prox2);if(ev&&typeof ev.preventDefault==="function")ev.preventDefault();safeNavigate(raw,"assign");}}}}catch(_){}},true);
|