@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.js
CHANGED
|
@@ -78,17 +78,26 @@ function hasTrackingMarker(input, markers) {
|
|
|
78
78
|
}
|
|
79
79
|
return false;
|
|
80
80
|
}
|
|
81
|
+
function patchKnownUnsafeEditorPatterns(scriptTag) {
|
|
82
|
+
let out = String(scriptTag || "");
|
|
83
|
+
out = out.replace(
|
|
84
|
+
/dragRegion\.addEventListener\((['"])pointerdown\1,\s*onPointerDown\);?/g,
|
|
85
|
+
"if (typeof dragRegion !== 'undefined' && dragRegion) dragRegion.addEventListener($1pointerdown$1, onPointerDown);"
|
|
86
|
+
);
|
|
87
|
+
return out;
|
|
88
|
+
}
|
|
81
89
|
function stripTrackingScriptsFromScrapedHtml(html, markers) {
|
|
82
90
|
let removedCount = 0;
|
|
83
91
|
let out = html;
|
|
84
92
|
out = out.replace(/<script\b[\s\S]*?<\/script>/gi, (tag) => {
|
|
93
|
+
var patchedTag = patchKnownUnsafeEditorPatterns(tag);
|
|
85
94
|
const srcMatch = tag.match(/\bsrc\s*=\s*(["'])(.*?)\1/i);
|
|
86
95
|
const src = srcMatch?.[2] || "";
|
|
87
96
|
if (hasTrackingMarker(src, markers) || hasTrackingMarker(tag, markers)) {
|
|
88
97
|
removedCount += 1;
|
|
89
98
|
return "";
|
|
90
99
|
}
|
|
91
|
-
return
|
|
100
|
+
return patchedTag;
|
|
92
101
|
});
|
|
93
102
|
out = out.replace(/<noscript\b[\s\S]*?<\/noscript>/gi, (tag) => {
|
|
94
103
|
if (!hasTrackingMarker(tag, markers)) return tag;
|
|
@@ -263,8 +272,97 @@ html,body{height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFo
|
|
|
263
272
|
.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}
|
|
264
273
|
.tb-viewport i{font-size:9px;color:##404040}
|
|
265
274
|
/* Device toggle buttons */
|
|
275
|
+
.tb-dev-wrap{position:relative;display:flex;align-items:center}
|
|
266
276
|
.tb-dev-btns{display:flex;align-items:center;gap:1px;padding:8px 4px;background:#F0F0F0;border-radius:7px; height: 30px;width: 116px;}
|
|
267
277
|
.tb-dev-3btns{display:flex;align-items:center;gap:2px;padding:8px 4px;background:#F0F0F0;border-radius:7px; height: 30px;width: 100px;}
|
|
278
|
+
.tb-dev-menu{
|
|
279
|
+
position:absolute;top:calc(100% + 8px);right:0;z-index:12040;display:none;
|
|
280
|
+
width:264px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:4px 4px;
|
|
281
|
+
box-shadow:0 12px 28px rgba(2,6,23,.18);color:#27272a
|
|
282
|
+
}
|
|
283
|
+
.tb-dev-menu.open{display:block}
|
|
284
|
+
.tb-dev-menu .hd{font-size:12px;font-weight:600;color:#3f3f46;margin-bottom:10px}
|
|
285
|
+
.tb-dev-menu .row{display:flex;align-items:center;gap:8px;}
|
|
286
|
+
.tb-dev-menu .row.height-width-row .row{
|
|
287
|
+
flex-direction: column;
|
|
288
|
+
align-items: flex-start;
|
|
289
|
+
}
|
|
290
|
+
.tb-dev-menu .row.height-width-row label{
|
|
291
|
+
color: var(--content-subtle, #737373);
|
|
292
|
+
font-size: 12px;
|
|
293
|
+
font-style: normal;
|
|
294
|
+
font-weight: 500;
|
|
295
|
+
line-height: 14px; /* 116.667% */
|
|
296
|
+
}
|
|
297
|
+
.tb-dev-menu > .row{
|
|
298
|
+
padding: 4px 12px;
|
|
299
|
+
}
|
|
300
|
+
.tb-dev-menu label{ flex-shrink: 0;
|
|
301
|
+
overflow: hidden;
|
|
302
|
+
color: var(--base-surface, #646465);
|
|
303
|
+
font-size: var(--font-size-sm, 14px);
|
|
304
|
+
font-style: normal;
|
|
305
|
+
font-weight: 500;
|
|
306
|
+
line-height: var(--font-leading-4, 16px);
|
|
307
|
+
white-space: nowrap;
|
|
308
|
+
min-width: fit-content;}
|
|
309
|
+
.tb-dev-menu input{
|
|
310
|
+
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);
|
|
311
|
+
width:100%;height:30px;border-radius:6px;
|
|
312
|
+
padding:0 8px;
|
|
313
|
+
font-size:12px;
|
|
314
|
+
color:#18181b;
|
|
315
|
+
background:#fff;
|
|
316
|
+
outline:none;
|
|
317
|
+
color:#404040;
|
|
318
|
+
border-color:transparent;
|
|
319
|
+
}
|
|
320
|
+
.tb-dev-menu input#dev-zoom-level{
|
|
321
|
+
max-width: fit-content;
|
|
322
|
+
margin-left: auto;
|
|
323
|
+
}
|
|
324
|
+
.tb-dev-menu input:focus{
|
|
325
|
+
border-color:#1A1A1A;
|
|
326
|
+
box-shadow:0 0 0 2px rgba(99,102,241,.14)
|
|
327
|
+
}
|
|
328
|
+
.tb-dev-menu .row-split > *{flex:1}
|
|
329
|
+
.tb-dev-menu .panel-toggle label{width:100%}
|
|
330
|
+
.tb-dev-menu .panel-toggle-label{
|
|
331
|
+
overflow:hidden;
|
|
332
|
+
color:var(--content-subtle, #737373);
|
|
333
|
+
text-overflow:ellipsis;
|
|
334
|
+
font-size:var(--font-size-sm, 14px);
|
|
335
|
+
font-style:normal;
|
|
336
|
+
font-weight:500;
|
|
337
|
+
line-height:var(--font-leading-4, 16px);
|
|
338
|
+
white-space:nowrap;
|
|
339
|
+
cursor:pointer;
|
|
340
|
+
}
|
|
341
|
+
.tb-dev-menu .vp-presets{
|
|
342
|
+
margin-top:8px;padding-top:8px;border-top:1px dashed #ececf0;
|
|
343
|
+
display:flex;flex-direction:column;gap:2px
|
|
344
|
+
}
|
|
345
|
+
.tb-dev-menu .vp-preset-btn{
|
|
346
|
+
border:none;background:transparent;text-align:left;cursor:pointer;
|
|
347
|
+
border-radius:6px;
|
|
348
|
+
padding:8px 12px;
|
|
349
|
+
color: var(--content-subtle, #737373);
|
|
350
|
+
text-overflow: ellipsis;
|
|
351
|
+
font-size: var(--font-size-sm, 14px);
|
|
352
|
+
font-style: normal;
|
|
353
|
+
font-weight: 500;
|
|
354
|
+
line-height: var(--font-leading-4, 16px);
|
|
355
|
+
}
|
|
356
|
+
.tb-dev-menu .vp-preset-btn:hover,.tb-dev-menu .vp-preset-btn.active{background:#f4f4f5}
|
|
357
|
+
.tb-dev-menu .ft{
|
|
358
|
+
margin-top:10px;padding-top:8px;border-top:1px solid #ececf0;
|
|
359
|
+
display:flex;justify-content:flex-end
|
|
360
|
+
}
|
|
361
|
+
.tb-dev-menu .apply-btn{
|
|
362
|
+
border:1px solid #d4d4d8;background:#f8fafc;color:#111827;border-radius:6px;
|
|
363
|
+
height:30px;padding:0 10px;font-size:12px;font-weight:600;cursor:pointer
|
|
364
|
+
}
|
|
365
|
+
.tb-dev-menu .apply-btn:hover{background:#eef2ff;border-color:#a5b4fc}
|
|
268
366
|
/* Dark icon buttons */
|
|
269
367
|
.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}
|
|
270
368
|
.tb-dk-btn:hover{color:#e4e4e7;background:rgba(255,255,255,.07)}
|
|
@@ -423,7 +521,12 @@ html,body{height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFo
|
|
|
423
521
|
/* \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 */
|
|
424
522
|
#device-frame{
|
|
425
523
|
width:100%;min-height:100%;display:flex;align-items:stretch;
|
|
426
|
-
justify-content:center;
|
|
524
|
+
justify-content:center;transform-origin:top center;
|
|
525
|
+
transition:max-width .3s ease,width .2s ease,height .2s ease
|
|
526
|
+
}
|
|
527
|
+
#device-frame.desktop{
|
|
528
|
+
max-width:1440px;
|
|
529
|
+
box-shadow:0 0 0 1px var(--border),0 4px 24px rgba(0,0,0,.08)
|
|
427
530
|
}
|
|
428
531
|
#device-frame.tablet{
|
|
429
532
|
max-width:768px;
|
|
@@ -824,10 +927,8 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
824
927
|
</head>
|
|
825
928
|
<body class="mode-editor">
|
|
826
929
|
<div id="app">
|
|
827
|
-
|
|
828
930
|
<!-- \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 -->
|
|
829
931
|
<div id="toolbar">
|
|
830
|
-
|
|
831
932
|
<!-- Left: Logo + Breadcrumb -->
|
|
832
933
|
<div class="tb-left">
|
|
833
934
|
<span class="tb-logo">\u2733</span>
|
|
@@ -845,14 +946,48 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
845
946
|
<span id="dev-label">1440px</span>
|
|
846
947
|
<i class="bi bi-chevron-down"></i>
|
|
847
948
|
</div>
|
|
848
|
-
<div class="tb-dev-
|
|
849
|
-
<
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
949
|
+
<div class="tb-dev-wrap">
|
|
950
|
+
<div class="tb-dev-btns">
|
|
951
|
+
<button class="tb-dk-btn active" id="dev-desktop" onclick="setDevice('desktop')" title="Desktop \u2014 1440x1024"><i class="bi bi-display"></i></button>
|
|
952
|
+
<button class="tb-dk-btn" id="dev-tablet" onclick="setDevice('tablet')" title="Tablet \u2014 768x1024"><i class="bi bi-tablet"></i></button>
|
|
953
|
+
<button class="tb-dk-btn" id="dev-mobile" onclick="setDevice('mobile')" title="Mobile \u2014 390x844"><i class="bi bi-phone"></i></button>
|
|
954
|
+
<button class="tb-dk-btn" id="dev-more-btn" title="More options"><i class="bi bi-three-dots"></i></button>
|
|
955
|
+
</div>
|
|
956
|
+
<div id="dev-more-menu" class="tb-dev-menu" aria-hidden="true">
|
|
957
|
+
<div class="row row-zoom">
|
|
958
|
+
<label for="dev-zoom-level">Zoom</label>
|
|
959
|
+
<input id="dev-zoom-level" type="number" min="25" max="200" step="5" value="100" />
|
|
960
|
+
</div>
|
|
961
|
+
<div class="row row-split row-width height-width-row">
|
|
962
|
+
<div class="row" style="margin:0">
|
|
963
|
+
<label for="dev-custom-width">Width</label>
|
|
964
|
+
<input id="dev-custom-width" type="number" min="240" max="3840" step="1" value="1440" />
|
|
965
|
+
</div>
|
|
966
|
+
<div class="row row-height" style="margin:0">
|
|
967
|
+
<label for="dev-custom-height">Height</label>
|
|
968
|
+
<input id="dev-custom-height" type="number" min="320" max="3840" step="1" value="1024" />
|
|
969
|
+
</div>
|
|
970
|
+
</div>
|
|
971
|
+
<div class="row panel-toggle">
|
|
972
|
+
<label id="left-panel-toggle-label" class="panel-toggle-label">Collapse left panel</label>
|
|
973
|
+
</div>
|
|
974
|
+
|
|
975
|
+
<div class="vp-presets" id="dev-preset-list" aria-label="Device presets">
|
|
976
|
+
<button type="button" class="vp-preset-btn" data-preset="desktop">Desktop</button>
|
|
977
|
+
<button type="button" class="vp-preset-btn" data-preset="mobile">iPhone 13</button>
|
|
978
|
+
<button type="button" class="vp-preset-btn" data-preset="galaxy-s22">Galaxy S22</button>
|
|
979
|
+
<button type="button" class="vp-preset-btn" data-preset="tablet">iPad</button>
|
|
980
|
+
<button type="button" class="vp-preset-btn" data-preset="galaxy-j1">Galaxy J1</button>
|
|
981
|
+
<button type="button" class="vp-preset-btn" data-preset="iphone-7">iPhone 7</button>
|
|
982
|
+
<button type="button" class="vp-preset-btn" data-preset="responsive">Responsive</button>
|
|
983
|
+
</div>
|
|
984
|
+
<div class="ft">
|
|
985
|
+
<button type="button" class="apply-btn" id="dev-apply-btn">Apply</button>
|
|
986
|
+
</div>
|
|
987
|
+
</div>
|
|
853
988
|
</div>
|
|
854
989
|
<button class="tb-dk-btn" id="btn-undo" title="Undo (\u2318Z)"><i class="bi bi-arrow-counterclockwise"></i></button>
|
|
855
|
-
<button class="tb-dk-btn" id="btn-redo" title="Redo (\u2318\u21E7Z)"><i class="bi bi-arrow-clockwise"></i></button>
|
|
990
|
+
<button class="tb-dk-btn" id="btn-redo" title="Redo (\u2318\u21E7Z)" style="display:none"><i class="bi bi-arrow-clockwise"></i></button>
|
|
856
991
|
</div>
|
|
857
992
|
|
|
858
993
|
<div id="iframe-loading-toolbar" class="tb-page-loading" aria-live="polite" aria-atomic="true">
|
|
@@ -923,8 +1058,8 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
923
1058
|
<!-- Elements -->
|
|
924
1059
|
<div class="lp-sec lp-sec-no-border">
|
|
925
1060
|
<div class="lp-sec-hd">
|
|
926
|
-
<span class="lp-sec-hd-left">Elements <i class="bi bi-info-circle lp-info-icon" title="Page elements"></i></span>
|
|
927
|
-
<button class="lp-add-btn" title="Add element">+ Add</button>
|
|
1061
|
+
<span class="lp-sec-hd-left">Elements <i style="display:none" class="bi bi-info-circle lp-info-icon" title="Page elements"></i></span>
|
|
1062
|
+
<button class="lp-add-btn" id="btn-add-element" title="Add element">+ Add</button>
|
|
928
1063
|
</div>
|
|
929
1064
|
|
|
930
1065
|
<!-- Search (hidden, kept for JS) -->
|
|
@@ -986,7 +1121,7 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
986
1121
|
</div>
|
|
987
1122
|
|
|
988
1123
|
<!-- Device frame containing the editing iframe -->
|
|
989
|
-
<div id="device-frame">
|
|
1124
|
+
<div id="device-frame" class="desktop">
|
|
990
1125
|
<iframe id="iframeId" name="iframeId" allowfullscreen></iframe>
|
|
991
1126
|
</div>
|
|
992
1127
|
|
|
@@ -994,14 +1129,16 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
994
1129
|
|
|
995
1130
|
<!-- Right panel -->
|
|
996
1131
|
<div id="right-panel">
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
<div class="
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
<div
|
|
1004
|
-
|
|
1132
|
+
<div id="section-components-panel" style="display:none">
|
|
1133
|
+
<!-- Left-tab controls moved here -->
|
|
1134
|
+
<div class="section-components-tabs">
|
|
1135
|
+
<div class="lp-tab" onclick="switchSectionComponentsTab('components')">Components</div>
|
|
1136
|
+
<div class="lp-tab" onclick="switchSectionComponentsTab('sections')">Sections</div>
|
|
1137
|
+
</div>
|
|
1138
|
+
<div class="lp-body">
|
|
1139
|
+
<div id="tab-components" class="tab-pane"></div>
|
|
1140
|
+
<div id="tab-sections" class="tab-pane"></div>
|
|
1141
|
+
</div>
|
|
1005
1142
|
</div>
|
|
1006
1143
|
<!-- Element badge (hidden until selection) -->
|
|
1007
1144
|
<div id="el-info" style="display:none">
|
|
@@ -1354,6 +1491,11 @@ var isDirty = false;
|
|
|
1354
1491
|
var vvvebReady = false;
|
|
1355
1492
|
var currentMode = 'editor';
|
|
1356
1493
|
var currentDevice = 'desktop';
|
|
1494
|
+
var leftPanelCollapsed = false;
|
|
1495
|
+
var viewportPreset = 'desktop';
|
|
1496
|
+
var viewportWidth = 1440;
|
|
1497
|
+
var viewportHeight = 1024;
|
|
1498
|
+
var viewportZoom = 1;
|
|
1357
1499
|
var selectedEl = null;
|
|
1358
1500
|
/** Stable selector fingerprint for resilient selection recovery after DOM churn. */
|
|
1359
1501
|
var selectedElFingerprint = '';
|
|
@@ -1606,15 +1748,202 @@ function setMode(mode) {
|
|
|
1606
1748
|
}
|
|
1607
1749
|
|
|
1608
1750
|
// \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
|
|
1609
|
-
var
|
|
1751
|
+
var DEVICE_PRESETS = {
|
|
1752
|
+
desktop: { label: 'Desktop', width: 1440, height: 1024, device: 'desktop' },
|
|
1753
|
+
tablet: { label: 'iPad', width: 768, height: 1024, device: 'tablet' },
|
|
1754
|
+
mobile: { label: 'iPhone 13', width: 390, height: 844, device: 'mobile' },
|
|
1755
|
+
'galaxy-s22': { label: 'Galaxy S22', width: 360, height: 780, device: 'mobile' },
|
|
1756
|
+
'iphone-7': { label: 'iPhone 7', width: 375, height: 667, device: 'mobile' },
|
|
1757
|
+
'galaxy-j1': { label: 'Galaxy J1', width: 360, height: 640, device: 'mobile' },
|
|
1758
|
+
responsive: { label: 'Responsive', width: 1280, height: 800, device: 'desktop' },
|
|
1759
|
+
};
|
|
1760
|
+
|
|
1761
|
+
function clampViewportNumber(v, fallback, min, max) {
|
|
1762
|
+
var n = parseInt(v, 10);
|
|
1763
|
+
if (!Number.isFinite(n)) return fallback;
|
|
1764
|
+
return Math.max(min, Math.min(max, n));
|
|
1765
|
+
}
|
|
1766
|
+
|
|
1767
|
+
function getViewportFitZoom() {
|
|
1768
|
+
var panel = document.getElementById('iframe-panel');
|
|
1769
|
+
var available = panel ? Math.max(260, panel.clientWidth - 24) : viewportWidth;
|
|
1770
|
+
if (!viewportWidth || viewportWidth <= 0) return 1;
|
|
1771
|
+
return Math.min(1, available / viewportWidth);
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
function getAppliedViewportZoom() {
|
|
1775
|
+
var z = Number(viewportZoom);
|
|
1776
|
+
if (!Number.isFinite(z) || z <= 0) z = 1;
|
|
1777
|
+
z = Math.max(0.25, Math.min(2, z));
|
|
1778
|
+
return Math.min(z, getViewportFitZoom());
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
function updateViewportLabel() {
|
|
1782
|
+
var lbl = document.getElementById('dev-label');
|
|
1783
|
+
if (!lbl) return;
|
|
1784
|
+
var zoomPct = Math.round(getAppliedViewportZoom() * 100);
|
|
1785
|
+
lbl.textContent = viewportWidth + 'x' + viewportHeight + ' \xB7 ' + zoomPct + '%';
|
|
1786
|
+
}
|
|
1787
|
+
|
|
1788
|
+
function syncViewportMenuControls() {
|
|
1789
|
+
var presetButtons = document.querySelectorAll('#dev-preset-list .vp-preset-btn');
|
|
1790
|
+
var widthInp = document.getElementById('dev-custom-width');
|
|
1791
|
+
var heightInp = document.getElementById('dev-custom-height');
|
|
1792
|
+
var zoomInp = document.getElementById('dev-zoom-level');
|
|
1793
|
+
if (presetButtons && presetButtons.length) {
|
|
1794
|
+
for (var i = 0; i < presetButtons.length; i++) {
|
|
1795
|
+
var key = presetButtons[i].getAttribute('data-preset') || '';
|
|
1796
|
+
presetButtons[i].classList.toggle('active', key === viewportPreset);
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
if (widthInp) widthInp.value = String(viewportWidth);
|
|
1800
|
+
if (heightInp) heightInp.value = String(viewportHeight);
|
|
1801
|
+
if (zoomInp) zoomInp.value = String(Math.round(getAppliedViewportZoom() * 100));
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
function applyViewportFrame() {
|
|
1805
|
+
var frame = document.getElementById('device-frame');
|
|
1806
|
+
var iframe = document.getElementById('iframeId');
|
|
1807
|
+
if (!frame) return;
|
|
1808
|
+
frame.className = currentDevice;
|
|
1809
|
+
frame.style.width = viewportWidth + 'px';
|
|
1810
|
+
frame.style.height = viewportHeight + 'px';
|
|
1811
|
+
frame.style.maxWidth = 'none';
|
|
1812
|
+
frame.style.zoom = String(getAppliedViewportZoom());
|
|
1813
|
+
if (iframe) {
|
|
1814
|
+
iframe.style.height = viewportHeight + 'px';
|
|
1815
|
+
iframe.style.minHeight = viewportHeight + 'px';
|
|
1816
|
+
}
|
|
1817
|
+
updateViewportLabel();
|
|
1818
|
+
syncViewportMenuControls();
|
|
1819
|
+
if (selectedEl && currentMode === 'editor') requestAnimationFrame(function() { positionSelectionToolbar(); });
|
|
1820
|
+
}
|
|
1821
|
+
|
|
1822
|
+
function setViewportPreset(presetKey) {
|
|
1823
|
+
var preset = DEVICE_PRESETS[presetKey];
|
|
1824
|
+
if (!preset) return;
|
|
1825
|
+
viewportPreset = presetKey;
|
|
1826
|
+
viewportWidth = preset.width;
|
|
1827
|
+
viewportHeight = preset.height;
|
|
1828
|
+
currentDevice = preset.device || 'desktop';
|
|
1829
|
+
['desktop','tablet','mobile'].forEach(function(d) {
|
|
1830
|
+
document.getElementById('dev-' + d).classList.toggle('active', d === currentDevice);
|
|
1831
|
+
});
|
|
1832
|
+
applyViewportFrame();
|
|
1833
|
+
}
|
|
1834
|
+
|
|
1610
1835
|
function setDevice(device) {
|
|
1836
|
+
viewportPreset = device;
|
|
1611
1837
|
currentDevice = device;
|
|
1612
|
-
var
|
|
1613
|
-
|
|
1838
|
+
var preset = DEVICE_PRESETS[device] || DEVICE_PRESETS.desktop;
|
|
1839
|
+
viewportWidth = preset.width;
|
|
1840
|
+
viewportHeight = preset.height;
|
|
1614
1841
|
['desktop','tablet','mobile'].forEach(function(d) {
|
|
1615
1842
|
document.getElementById('dev-' + d).classList.toggle('active', d === device);
|
|
1616
1843
|
});
|
|
1617
|
-
|
|
1844
|
+
applyViewportFrame();
|
|
1845
|
+
}
|
|
1846
|
+
|
|
1847
|
+
function setViewportCustomFromInputs() {
|
|
1848
|
+
var widthInp = document.getElementById('dev-custom-width');
|
|
1849
|
+
var heightInp = document.getElementById('dev-custom-height');
|
|
1850
|
+
var zoomInp = document.getElementById('dev-zoom-level');
|
|
1851
|
+
viewportWidth = clampViewportNumber(widthInp ? widthInp.value : '', viewportWidth, 240, 3840);
|
|
1852
|
+
viewportHeight = clampViewportNumber(heightInp ? heightInp.value : '', viewportHeight, 320, 3840);
|
|
1853
|
+
var z = clampViewportNumber(zoomInp ? zoomInp.value : '', Math.round(getAppliedViewportZoom() * 100), 25, 200);
|
|
1854
|
+
viewportZoom = z / 100;
|
|
1855
|
+
viewportPreset = 'custom';
|
|
1856
|
+
currentDevice = viewportWidth <= 480 ? 'mobile' : (viewportWidth <= 1024 ? 'tablet' : 'desktop');
|
|
1857
|
+
['desktop','tablet','mobile'].forEach(function(d) {
|
|
1858
|
+
document.getElementById('dev-' + d).classList.toggle('active', d === currentDevice);
|
|
1859
|
+
});
|
|
1860
|
+
applyViewportFrame();
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
function closeViewportMenu() {
|
|
1864
|
+
var menu = document.getElementById('dev-more-menu');
|
|
1865
|
+
if (!menu) return;
|
|
1866
|
+
menu.classList.remove('open');
|
|
1867
|
+
menu.setAttribute('aria-hidden', 'true');
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
function toggleViewportMenu() {
|
|
1871
|
+
var menu = document.getElementById('dev-more-menu');
|
|
1872
|
+
if (!menu) return;
|
|
1873
|
+
var shouldOpen = !menu.classList.contains('open');
|
|
1874
|
+
menu.classList.toggle('open', shouldOpen);
|
|
1875
|
+
menu.setAttribute('aria-hidden', shouldOpen ? 'false' : 'true');
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
function bindViewportControls() {
|
|
1879
|
+
var btn = document.getElementById('dev-more-btn');
|
|
1880
|
+
var menu = document.getElementById('dev-more-menu');
|
|
1881
|
+
var leftPanelToggleLabel = document.getElementById('left-panel-toggle-label');
|
|
1882
|
+
var presetButtons = document.querySelectorAll('#dev-preset-list .vp-preset-btn');
|
|
1883
|
+
var applyBtn = document.getElementById('dev-apply-btn');
|
|
1884
|
+
var zoomInp = document.getElementById('dev-zoom-level');
|
|
1885
|
+
var viewportBtn = document.querySelector('.tb-viewport');
|
|
1886
|
+
function updateLeftPanelToggleLabel() {
|
|
1887
|
+
if (!leftPanelToggleLabel) return;
|
|
1888
|
+
leftPanelToggleLabel.textContent = leftPanelCollapsed ? 'Expand left panel' : 'Collapse left panel';
|
|
1889
|
+
}
|
|
1890
|
+
function setLeftPanelCollapsed(collapsed) {
|
|
1891
|
+
var panel = document.getElementById('left-panel');
|
|
1892
|
+
leftPanelCollapsed = !!collapsed;
|
|
1893
|
+
if (panel) panel.style.display = leftPanelCollapsed ? 'none' : '';
|
|
1894
|
+
updateLeftPanelToggleLabel();
|
|
1895
|
+
applyViewportFrame();
|
|
1896
|
+
}
|
|
1897
|
+
if (leftPanelToggleLabel) {
|
|
1898
|
+
leftPanelToggleLabel.addEventListener('click', function(e) {
|
|
1899
|
+
e.preventDefault();
|
|
1900
|
+
e.stopPropagation();
|
|
1901
|
+
setLeftPanelCollapsed(!leftPanelCollapsed);
|
|
1902
|
+
});
|
|
1903
|
+
}
|
|
1904
|
+
if (btn) btn.addEventListener('click', function(e) {
|
|
1905
|
+
e.preventDefault();
|
|
1906
|
+
e.stopPropagation();
|
|
1907
|
+
toggleViewportMenu();
|
|
1908
|
+
});
|
|
1909
|
+
if (viewportBtn) viewportBtn.addEventListener('click', function(e) {
|
|
1910
|
+
e.preventDefault();
|
|
1911
|
+
e.stopPropagation();
|
|
1912
|
+
toggleViewportMenu();
|
|
1913
|
+
});
|
|
1914
|
+
if (applyBtn) applyBtn.addEventListener('click', function(e) {
|
|
1915
|
+
e.preventDefault();
|
|
1916
|
+
setViewportCustomFromInputs();
|
|
1917
|
+
closeViewportMenu();
|
|
1918
|
+
});
|
|
1919
|
+
if (zoomInp) {
|
|
1920
|
+
zoomInp.addEventListener('change', function() {
|
|
1921
|
+
var z = clampViewportNumber(zoomInp.value, Math.round(getAppliedViewportZoom() * 100), 25, 200);
|
|
1922
|
+
viewportZoom = z / 100;
|
|
1923
|
+
applyViewportFrame();
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
if (presetButtons && presetButtons.length) {
|
|
1927
|
+
for (var i = 0; i < presetButtons.length; i++) {
|
|
1928
|
+
presetButtons[i].addEventListener('click', function(e) {
|
|
1929
|
+
e.preventDefault();
|
|
1930
|
+
var key = this.getAttribute('data-preset');
|
|
1931
|
+
if (!key) return;
|
|
1932
|
+
setViewportPreset(key);
|
|
1933
|
+
});
|
|
1934
|
+
}
|
|
1935
|
+
}
|
|
1936
|
+
document.addEventListener('click', function(e) {
|
|
1937
|
+
if (!menu || !menu.classList.contains('open')) return;
|
|
1938
|
+
if (menu.contains(e.target) || (btn && btn.contains(e.target)) || (viewportBtn && viewportBtn.contains(e.target))) return;
|
|
1939
|
+
closeViewportMenu();
|
|
1940
|
+
});
|
|
1941
|
+
document.addEventListener('keydown', function(e) {
|
|
1942
|
+
if (e.key === 'Escape') closeViewportMenu();
|
|
1943
|
+
});
|
|
1944
|
+
window.addEventListener('resize', function() { applyViewportFrame(); });
|
|
1945
|
+
updateLeftPanelToggleLabel();
|
|
1946
|
+
applyViewportFrame();
|
|
1618
1947
|
}
|
|
1619
1948
|
|
|
1620
1949
|
// \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
|
|
@@ -1658,6 +1987,19 @@ function switchSectionComponentsTab(tab) {
|
|
|
1658
1987
|
renderSidebar(inp ? inp.value : '');
|
|
1659
1988
|
}
|
|
1660
1989
|
|
|
1990
|
+
function toggleSectionComponentsPanel(forceVisible) {
|
|
1991
|
+
var panel = document.getElementById('section-components-panel');
|
|
1992
|
+
if (!panel) return;
|
|
1993
|
+
var shouldShow =
|
|
1994
|
+
typeof forceVisible === 'boolean'
|
|
1995
|
+
? forceVisible
|
|
1996
|
+
: panel.style.display === 'none';
|
|
1997
|
+
panel.style.display = shouldShow ? '' : 'none';
|
|
1998
|
+
if (shouldShow) {
|
|
1999
|
+
switchSectionComponentsTab(currentSectionComponentsTab || 'components');
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
|
|
1661
2003
|
// \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
|
|
1662
2004
|
function toggleAcc(name) {
|
|
1663
2005
|
var sec = document.getElementById('acc-' + name);
|
|
@@ -1763,9 +2105,60 @@ function getOriginalValue(inputId, el) {
|
|
|
1763
2105
|
}
|
|
1764
2106
|
}
|
|
1765
2107
|
|
|
2108
|
+
var PX_DEFAULT_INPUT_IDS = {
|
|
2109
|
+
'pp-mt': true, 'pp-mr': true, 'pp-mb': true, 'pp-ml': true,
|
|
2110
|
+
'pp-pt': true, 'pp-pr': true, 'pp-pb': true, 'pp-pl': true,
|
|
2111
|
+
};
|
|
2112
|
+
|
|
2113
|
+
var PX_DEFAULT_CSS_PROPS = {
|
|
2114
|
+
'margin-top': true, 'margin-right': true, 'margin-bottom': true, 'margin-left': true,
|
|
2115
|
+
'padding-top': true, 'padding-right': true, 'padding-bottom': true, 'padding-left': true,
|
|
2116
|
+
};
|
|
2117
|
+
|
|
2118
|
+
function normalizeCssValueForProperty(prop, value) {
|
|
2119
|
+
var p = prop == null ? '' : String(prop).trim();
|
|
2120
|
+
var pKebab = p
|
|
2121
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
2122
|
+
.replace(/_/g, '-')
|
|
2123
|
+
.replace(/!important/gi, '')
|
|
2124
|
+
.replace(/[^a-zA-Z-]/g, '')
|
|
2125
|
+
.toLowerCase();
|
|
2126
|
+
var raw = value == null ? '' : String(value).trim();
|
|
2127
|
+
var rawClean = raw.replace(/[\u200B\u200C\u200D\uFEFF]/g, '').trim();
|
|
2128
|
+
var numericCandidate = rawClean.replace(/[, ]+/g, '');
|
|
2129
|
+
var isSpacingProp = /^(?:margin|padding)(?:-(?:top|right|bottom|left))?$/.test(pKebab);
|
|
2130
|
+
if (!pKebab || !rawClean) return rawClean;
|
|
2131
|
+
var numericValue = Number(numericCandidate);
|
|
2132
|
+
var shouldAddPx =
|
|
2133
|
+
isSpacingProp &&
|
|
2134
|
+
numericCandidate !== '' &&
|
|
2135
|
+
Number.isFinite(numericValue) &&
|
|
2136
|
+
/^[-+]?(?:[0-9]+(?:[.][0-9]+)?|[.][0-9]+)$/.test(numericCandidate);
|
|
2137
|
+
var out = shouldAddPx ? numericCandidate + 'px' : rawClean;
|
|
2138
|
+
return out;
|
|
2139
|
+
}
|
|
2140
|
+
|
|
2141
|
+
function normalizeChainSetRowUnits(row) {
|
|
2142
|
+
if (!row) return row;
|
|
2143
|
+
if (normalizeChangesetType(row) === 'style') {
|
|
2144
|
+
row.value = normalizeCssValueForProperty(row.property || row.cssProp, row.value);
|
|
2145
|
+
}
|
|
2146
|
+
return row;
|
|
2147
|
+
}
|
|
2148
|
+
|
|
2149
|
+
function normalizeLoggedValue(inputId, value) {
|
|
2150
|
+
var raw = value == null ? '' : String(value).trim();
|
|
2151
|
+
if (!raw) return raw;
|
|
2152
|
+
if (PX_DEFAULT_INPUT_IDS[inputId] && /^-?d+(?:.d+)?$/.test(raw)) {
|
|
2153
|
+
return raw + 'px';
|
|
2154
|
+
}
|
|
2155
|
+
return raw;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
1766
2158
|
function logChange(selector, inputId, value, targetEl, originalValue) {
|
|
1767
2159
|
var meta = PROP_META[inputId];
|
|
1768
2160
|
if (!meta) return;
|
|
2161
|
+
value = normalizeLoggedValue(inputId, value);
|
|
1769
2162
|
var key = selector + '||' + inputId;
|
|
1770
2163
|
// Skip trivially empty / reset values \u2014 remove from log if present
|
|
1771
2164
|
if (value === '' || value === 'none' || value === 'auto' || value === 'normal') {
|
|
@@ -1867,6 +2260,24 @@ function syncDesignInput(change) {
|
|
|
1867
2260
|
function removeStateChange(idx) {
|
|
1868
2261
|
var change = stateChanges[idx];
|
|
1869
2262
|
if (!change) return;
|
|
2263
|
+
if (change.isStructuralLive) {
|
|
2264
|
+
removeSessionStructuralRowByTimestamp(
|
|
2265
|
+
change.structuralVarId || activeVarId,
|
|
2266
|
+
change.vveTs,
|
|
2267
|
+
);
|
|
2268
|
+
stateChanges.splice(idx, 1);
|
|
2269
|
+
commitStateChangesForActiveVariation();
|
|
2270
|
+
renderStatesTab();
|
|
2271
|
+
if (currentMainTab === 'history') renderHistoryTab();
|
|
2272
|
+
try {
|
|
2273
|
+
delete varHtmlCache[activeVarId];
|
|
2274
|
+
} catch(_) {}
|
|
2275
|
+
appliedStructuralChangesetKeys = {};
|
|
2276
|
+
recomputeEditorDirty();
|
|
2277
|
+
scheduleDomTreeRefresh();
|
|
2278
|
+
softReloadEditorIframe();
|
|
2279
|
+
return;
|
|
2280
|
+
}
|
|
1870
2281
|
revertChangeOnDom(change);
|
|
1871
2282
|
syncDesignInput(change);
|
|
1872
2283
|
stateChanges.splice(idx, 1);
|
|
@@ -2223,6 +2634,14 @@ function getLatestHistoryUndoTarget() {
|
|
|
2223
2634
|
return list.length ? list[0] : null;
|
|
2224
2635
|
}
|
|
2225
2636
|
|
|
2637
|
+
function getLatestLiveUndoTarget() {
|
|
2638
|
+
var list = getUnifiedHistoryItems();
|
|
2639
|
+
for (var i = 0; i < list.length; i++) {
|
|
2640
|
+
if (list[i] && list[i].source === 'live') return list[i];
|
|
2641
|
+
}
|
|
2642
|
+
return null;
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2226
2645
|
function changesetListHasStructural(arr) {
|
|
2227
2646
|
if (!arr || !arr.length) return false;
|
|
2228
2647
|
for (var i = 0; i < arr.length; i++) {
|
|
@@ -2321,8 +2740,15 @@ function removeHistoryChangeset(idx, evt) {
|
|
|
2321
2740
|
function clearAllHistoryChangesets() {
|
|
2322
2741
|
var v = getActiveVariationForHistory();
|
|
2323
2742
|
if (!v) return;
|
|
2324
|
-
|
|
2743
|
+
var hasSavedChangesets = parseVariationChangesets(v).length > 0;
|
|
2744
|
+
var hasSessionStructural =
|
|
2745
|
+
!!(activeVarId && sessionStructuralChainRowsByVarId[activeVarId] && sessionStructuralChainRowsByVarId[activeVarId].length);
|
|
2746
|
+
if (!hasSavedChangesets && !hasSessionStructural) return;
|
|
2747
|
+
|
|
2325
2748
|
persistActiveVariationChangesets([]);
|
|
2749
|
+
if (activeVarId) {
|
|
2750
|
+
sessionStructuralChainRowsByVarId[activeVarId] = [];
|
|
2751
|
+
}
|
|
2326
2752
|
appliedChangesetSnapshots = {};
|
|
2327
2753
|
appliedStructuralChangesetKeys = {};
|
|
2328
2754
|
try {
|
|
@@ -2335,6 +2761,10 @@ function clearAllHistoryChangesets() {
|
|
|
2335
2761
|
}
|
|
2336
2762
|
|
|
2337
2763
|
function clearAllUnifiedHistory() {
|
|
2764
|
+
if (activeVarId) {
|
|
2765
|
+
// Ensure structural unsaved rows are also removed by "Clear all changes".
|
|
2766
|
+
sessionStructuralChainRowsByVarId[activeVarId] = [];
|
|
2767
|
+
}
|
|
2338
2768
|
clearAllStates();
|
|
2339
2769
|
clearAllHistoryChangesets();
|
|
2340
2770
|
if (currentMainTab === 'history') renderHistoryTab();
|
|
@@ -2346,15 +2776,32 @@ var VVE_LOCAL_STORAGE_PREFIX = 'vve:';
|
|
|
2346
2776
|
|
|
2347
2777
|
function clearVisualEditorLocalStorage() {
|
|
2348
2778
|
try {
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2779
|
+
var stores = [];
|
|
2780
|
+
try { stores.push(localStorage); } catch(_) {}
|
|
2781
|
+
try { stores.push(sessionStorage); } catch(_) {}
|
|
2782
|
+
for (var si = 0; si < stores.length; si++) {
|
|
2783
|
+
var store = stores[si];
|
|
2784
|
+
if (!store) continue;
|
|
2785
|
+
for (var i = store.length - 1; i >= 0; i--) {
|
|
2786
|
+
var k = store.key(i);
|
|
2787
|
+
if (k && k.indexOf(VVE_LOCAL_STORAGE_PREFIX) === 0) {
|
|
2788
|
+
store.removeItem(k);
|
|
2789
|
+
}
|
|
2353
2790
|
}
|
|
2354
2791
|
}
|
|
2355
2792
|
} catch(_) {}
|
|
2356
2793
|
}
|
|
2357
2794
|
|
|
2795
|
+
function clearPersistedActiveVariationForData(data) {
|
|
2796
|
+
try {
|
|
2797
|
+
var sk = activeVariationStorageKeyFromPayload(data);
|
|
2798
|
+
if (sk && sk !== VVE_LOCAL_STORAGE_PREFIX + 'activeVar::') {
|
|
2799
|
+
try { localStorage.removeItem(sk); } catch(_) {}
|
|
2800
|
+
try { sessionStorage.removeItem(sk); } catch(_) {}
|
|
2801
|
+
}
|
|
2802
|
+
} catch(_) {}
|
|
2803
|
+
}
|
|
2804
|
+
|
|
2358
2805
|
function activeVariationStorageKeyFromPayload(data) {
|
|
2359
2806
|
return (
|
|
2360
2807
|
VVE_LOCAL_STORAGE_PREFIX +
|
|
@@ -2393,22 +2840,41 @@ function writePersistedActiveVariationId(varId) {
|
|
|
2393
2840
|
* @param allowPrevMemory when true, keep in-session activeVarId if still valid (skip-reload path).
|
|
2394
2841
|
*/
|
|
2395
2842
|
function pickActiveVariationIdForLoad(data, variationsArr, prevMemoryId, allowPrevMemory) {
|
|
2396
|
-
var
|
|
2397
|
-
var fallback = (
|
|
2843
|
+
var firstNonBaseline = variationsArr.find(function(v) { return !v.baseline; });
|
|
2844
|
+
var fallback = (firstNonBaseline || variationsArr[0] || {})._id || null;
|
|
2398
2845
|
if (!variationsArr.length) return null;
|
|
2399
2846
|
if (allowPrevMemory && prevMemoryId && variationsArr.some(function(v) { return v._id === prevMemoryId; })) {
|
|
2400
2847
|
return prevMemoryId;
|
|
2401
2848
|
}
|
|
2402
2849
|
var stored = readPersistedActiveVariationId(data);
|
|
2403
2850
|
if (stored && variationsArr.some(function(v) { return v._id === stored; })) {
|
|
2851
|
+
var storedVar = variationsArr.find(function(v) { return v._id === stored; });
|
|
2852
|
+
if (storedVar && storedVar.baseline && firstNonBaseline && firstNonBaseline._id) {
|
|
2853
|
+
return firstNonBaseline._id;
|
|
2854
|
+
}
|
|
2404
2855
|
return stored;
|
|
2405
2856
|
}
|
|
2406
2857
|
return fallback;
|
|
2407
2858
|
}
|
|
2408
2859
|
|
|
2860
|
+
function updateExperimentNameLabel(data) {
|
|
2861
|
+
var el = document.getElementById('tb-exp-name');
|
|
2862
|
+
if (!el) return;
|
|
2863
|
+
var name = '';
|
|
2864
|
+
try {
|
|
2865
|
+
name = data && data.name != null ? String(data.name).trim() : '';
|
|
2866
|
+
} catch(_) {
|
|
2867
|
+
name = '';
|
|
2868
|
+
}
|
|
2869
|
+
if (!name) name = 'Visual Editor';
|
|
2870
|
+
el.textContent = name;
|
|
2871
|
+
el.title = name;
|
|
2872
|
+
}
|
|
2873
|
+
|
|
2409
2874
|
// \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
|
|
2410
2875
|
function handleLoadExperiment(data) {
|
|
2411
2876
|
clearPendingGranularChangesets();
|
|
2877
|
+
updateExperimentNameLabel(data);
|
|
2412
2878
|
var prevKey = experimentData
|
|
2413
2879
|
? String(experimentData.experimentId || '') + '|' + String(experimentData.pageUrl || '')
|
|
2414
2880
|
: '';
|
|
@@ -2624,7 +3090,13 @@ function granularAnySelectorMatches(doc, cs) {
|
|
|
2624
3090
|
|
|
2625
3091
|
/** Bust bfcache / same-URL no-op reloads so the iframe actually re-parses (loading \u2192 interactive). */
|
|
2626
3092
|
function appendIframeReloadBust(url) {
|
|
2627
|
-
|
|
3093
|
+
try {
|
|
3094
|
+
var u = new URL(String(url || ''), window.location.href);
|
|
3095
|
+
u.searchParams.set('_vve_reload', String(Date.now()));
|
|
3096
|
+
return u.toString();
|
|
3097
|
+
} catch(_) {
|
|
3098
|
+
return url;
|
|
3099
|
+
}
|
|
2628
3100
|
}
|
|
2629
3101
|
|
|
2630
3102
|
// True when the iframe contentDocument belongs to the current iframe.src navigation.
|
|
@@ -3002,11 +3474,55 @@ function appendSessionStructuralChainRow(varId, row) {
|
|
|
3002
3474
|
sessionStructuralChainRowsByVarId[varId].push(row);
|
|
3003
3475
|
}
|
|
3004
3476
|
|
|
3477
|
+
function markStructuralRowApplied(row) {
|
|
3478
|
+
try {
|
|
3479
|
+
var k = structuralChangesetDedupKey(row);
|
|
3480
|
+
if (k) appliedStructuralChangesetKeys[k] = true;
|
|
3481
|
+
} catch(_) {}
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3484
|
+
function logStructuralStateChange(row, label, value, targetEl) {
|
|
3485
|
+
if (!row || !row.selector) return;
|
|
3486
|
+
stateChanges.push({
|
|
3487
|
+
selector: row.selector,
|
|
3488
|
+
inputId: 'vve-struct',
|
|
3489
|
+
label: label || 'Structure change',
|
|
3490
|
+
cssProp: null,
|
|
3491
|
+
value: value != null ? String(value) : String(row.type || ''),
|
|
3492
|
+
targetEl: targetEl || null,
|
|
3493
|
+
originalValue: '',
|
|
3494
|
+
vveTs: row.vveTs || nextHistoryTimestamp(),
|
|
3495
|
+
isStructuralLive: true,
|
|
3496
|
+
structuralVarId: activeVarId || null,
|
|
3497
|
+
structuralType: row.type || '',
|
|
3498
|
+
});
|
|
3499
|
+
if (currentMainTab === 'history') renderHistoryTab();
|
|
3500
|
+
commitStateChangesForActiveVariation();
|
|
3501
|
+
}
|
|
3502
|
+
|
|
3503
|
+
function removeSessionStructuralRowByTimestamp(varId, ts) {
|
|
3504
|
+
if (!varId || !ts) return;
|
|
3505
|
+
var arr = sessionStructuralChainRowsByVarId[varId];
|
|
3506
|
+
if (!arr || !arr.length) return;
|
|
3507
|
+
for (var i = arr.length - 1; i >= 0; i--) {
|
|
3508
|
+
if (arr[i] && arr[i].vveTs === ts) {
|
|
3509
|
+
arr.splice(i, 1);
|
|
3510
|
+
return;
|
|
3511
|
+
}
|
|
3512
|
+
}
|
|
3513
|
+
}
|
|
3514
|
+
|
|
3005
3515
|
/** One States-tab row -> Conversion.io chain-set shape (matches applyChangesetEntry). */
|
|
3006
3516
|
function stateChangeToChainSet(c) {
|
|
3007
3517
|
if (!c || !c.selector) return null;
|
|
3008
3518
|
if (c.cssProp) {
|
|
3009
|
-
return {
|
|
3519
|
+
return {
|
|
3520
|
+
selector: c.selector,
|
|
3521
|
+
type: 'style',
|
|
3522
|
+
property: c.cssProp,
|
|
3523
|
+
value: normalizeCssValueForProperty(c.cssProp, c.value),
|
|
3524
|
+
vveTs: c.vveTs || nextHistoryTimestamp()
|
|
3525
|
+
};
|
|
3010
3526
|
}
|
|
3011
3527
|
switch (c.inputId) {
|
|
3012
3528
|
case 'pp-text':
|
|
@@ -3178,7 +3694,7 @@ function buildPersistentStyleRulesForActiveVariation() {
|
|
|
3178
3694
|
if (value == null || value === '') return;
|
|
3179
3695
|
var sel = sanitizeSelectorForMatch(String(selector)) || String(selector);
|
|
3180
3696
|
var pr = String(prop).trim();
|
|
3181
|
-
var val =
|
|
3697
|
+
var val = normalizeCssValueForProperty(pr, value);
|
|
3182
3698
|
if (!sel || !pr || !val) return;
|
|
3183
3699
|
var k = sel + '__vve_sep__' + pr;
|
|
3184
3700
|
if (!map[k]) order.push(k);
|
|
@@ -3216,7 +3732,8 @@ function buildPersistentStyleRulesForActiveVariation() {
|
|
|
3216
3732
|
var lines = [];
|
|
3217
3733
|
for (var oi = 0; oi < order.length; oi++) {
|
|
3218
3734
|
var row = map[order[oi]];
|
|
3219
|
-
|
|
3735
|
+
var outVal = normalizeCssValueForProperty(row.property, row.value);
|
|
3736
|
+
lines.push(row.selector + ' { ' + row.property + ': ' + outVal + ' !important; }');
|
|
3220
3737
|
}
|
|
3221
3738
|
return lines.join('\\n');
|
|
3222
3739
|
}
|
|
@@ -3367,7 +3884,9 @@ function buildPersistedChainSetsForVariation(v) {
|
|
|
3367
3884
|
var row = stateChangeToChainSet(sourceStateChanges[si]);
|
|
3368
3885
|
if (row) overlay.push(row);
|
|
3369
3886
|
}
|
|
3370
|
-
|
|
3887
|
+
var merged = mergeGranularChainSets(mergeGranularChainSets(base, sessionExtra), overlay);
|
|
3888
|
+
for (var mi = 0; mi < merged.length; mi++) normalizeChainSetRowUnits(merged[mi]);
|
|
3889
|
+
return merged;
|
|
3371
3890
|
}
|
|
3372
3891
|
|
|
3373
3892
|
/**
|
|
@@ -3696,12 +4215,15 @@ function duplicateSelectedEl() {
|
|
|
3696
4215
|
clone.setAttribute('data-vve-instance', generateVveInstanceId());
|
|
3697
4216
|
} catch(_) {}
|
|
3698
4217
|
if (activeVarId) {
|
|
3699
|
-
|
|
4218
|
+
var dupRow = {
|
|
3700
4219
|
selector: anchorSel,
|
|
3701
4220
|
type: 'insert',
|
|
3702
4221
|
action: 'after',
|
|
3703
4222
|
html: clone.outerHTML,
|
|
3704
|
-
}
|
|
4223
|
+
};
|
|
4224
|
+
appendSessionStructuralChainRow(activeVarId, dupRow);
|
|
4225
|
+
markStructuralRowApplied(dupRow);
|
|
4226
|
+
logStructuralStateChange(dupRow, 'Duplicated via toolbar', 'Duplicate inserted', selectedEl);
|
|
3705
4227
|
}
|
|
3706
4228
|
selectedEl.parentNode.insertBefore(clone, selectedEl.nextSibling);
|
|
3707
4229
|
saveCurrentVariationHtml();
|
|
@@ -3717,23 +4239,27 @@ function toggleHideSelectedEl() {
|
|
|
3717
4239
|
selectedEl.style.visibility = '';
|
|
3718
4240
|
selectedEl.removeAttribute('data-vve-hidden');
|
|
3719
4241
|
if (activeVarId) {
|
|
3720
|
-
|
|
4242
|
+
var showRow = {
|
|
3721
4243
|
selector: hidSel,
|
|
3722
4244
|
type: 'style',
|
|
3723
4245
|
property: 'visibility',
|
|
3724
4246
|
value: '',
|
|
3725
|
-
}
|
|
4247
|
+
};
|
|
4248
|
+
appendSessionStructuralChainRow(activeVarId, showRow);
|
|
4249
|
+
logStructuralStateChange(showRow, 'Shown via toolbar', 'Visibility restored', selectedEl);
|
|
3726
4250
|
}
|
|
3727
4251
|
} else {
|
|
3728
4252
|
selectedEl.style.visibility = 'hidden';
|
|
3729
4253
|
selectedEl.setAttribute('data-vve-hidden', '1');
|
|
3730
4254
|
if (activeVarId) {
|
|
3731
|
-
|
|
4255
|
+
var hideRow = {
|
|
3732
4256
|
selector: hidSel,
|
|
3733
4257
|
type: 'style',
|
|
3734
4258
|
property: 'visibility',
|
|
3735
4259
|
value: 'hidden',
|
|
3736
|
-
}
|
|
4260
|
+
};
|
|
4261
|
+
appendSessionStructuralChainRow(activeVarId, hideRow);
|
|
4262
|
+
logStructuralStateChange(hideRow, 'Hidden via toolbar', 'Visibility set to hidden', selectedEl);
|
|
3737
4263
|
}
|
|
3738
4264
|
}
|
|
3739
4265
|
saveCurrentVariationHtml();
|
|
@@ -3744,7 +4270,11 @@ function deleteSelectedEl() {
|
|
|
3744
4270
|
if (!selectedEl || !selectedEl.parentNode) return;
|
|
3745
4271
|
var delSel = buildSelector(selectedEl);
|
|
3746
4272
|
selectedEl.remove();
|
|
3747
|
-
if (activeVarId)
|
|
4273
|
+
if (activeVarId) {
|
|
4274
|
+
var delRow = { selector: delSel, type: 'remove' };
|
|
4275
|
+
appendSessionStructuralChainRow(activeVarId, delRow);
|
|
4276
|
+
logStructuralStateChange(delRow, 'Deleted via toolbar', 'Element removed', null);
|
|
4277
|
+
}
|
|
3748
4278
|
saveCurrentVariationHtml();
|
|
3749
4279
|
recomputeEditorDirty();
|
|
3750
4280
|
deselectElement();
|
|
@@ -4645,19 +5175,25 @@ function recordReorderAfterDrag(movedEl) {
|
|
|
4645
5175
|
var prev = movedEl.previousElementSibling;
|
|
4646
5176
|
var next = movedEl.nextElementSibling;
|
|
4647
5177
|
if (prev) {
|
|
4648
|
-
|
|
5178
|
+
var reorderAfterRow = {
|
|
4649
5179
|
selector: buildSelector(movedEl),
|
|
4650
5180
|
type: 'reorder',
|
|
4651
5181
|
targetSelector: buildSelector(prev),
|
|
4652
5182
|
action: 'after',
|
|
4653
|
-
}
|
|
5183
|
+
};
|
|
5184
|
+
appendSessionStructuralChainRow(activeVarId, reorderAfterRow);
|
|
5185
|
+
markStructuralRowApplied(reorderAfterRow);
|
|
5186
|
+
logStructuralStateChange(reorderAfterRow, 'Reordered via drag', 'Moved after sibling', movedEl);
|
|
4654
5187
|
} else if (next) {
|
|
4655
|
-
|
|
5188
|
+
var reorderBeforeRow = {
|
|
4656
5189
|
selector: buildSelector(movedEl),
|
|
4657
5190
|
type: 'reorder',
|
|
4658
5191
|
targetSelector: buildSelector(next),
|
|
4659
5192
|
action: 'before',
|
|
4660
|
-
}
|
|
5193
|
+
};
|
|
5194
|
+
appendSessionStructuralChainRow(activeVarId, reorderBeforeRow);
|
|
5195
|
+
markStructuralRowApplied(reorderBeforeRow);
|
|
5196
|
+
logStructuralStateChange(reorderBeforeRow, 'Reordered via drag', 'Moved before sibling', movedEl);
|
|
4661
5197
|
}
|
|
4662
5198
|
}
|
|
4663
5199
|
|
|
@@ -4938,12 +5474,15 @@ function insertHtml(html) {
|
|
|
4938
5474
|
}
|
|
4939
5475
|
if (firstEl) selectElement(firstEl);
|
|
4940
5476
|
if (activeVarId) {
|
|
4941
|
-
|
|
5477
|
+
var insertRow = {
|
|
4942
5478
|
selector: anchorSel,
|
|
4943
5479
|
type: 'insert',
|
|
4944
5480
|
action: 'after',
|
|
4945
5481
|
html: htmlStr,
|
|
4946
|
-
}
|
|
5482
|
+
};
|
|
5483
|
+
appendSessionStructuralChainRow(activeVarId, insertRow);
|
|
5484
|
+
markStructuralRowApplied(insertRow);
|
|
5485
|
+
logStructuralStateChange(insertRow, 'Added component/section', 'Inserted new element', firstEl || selectedEl);
|
|
4947
5486
|
}
|
|
4948
5487
|
saveCurrentVariationHtml();
|
|
4949
5488
|
recomputeEditorDirty();
|
|
@@ -5033,6 +5572,14 @@ document.getElementById('comp-search').addEventListener('input', function() {
|
|
|
5033
5572
|
renderSidebar(this.value);
|
|
5034
5573
|
}
|
|
5035
5574
|
});
|
|
5575
|
+
var btnAddElement = document.getElementById('btn-add-element');
|
|
5576
|
+
if (btnAddElement) {
|
|
5577
|
+
btnAddElement.addEventListener('click', function(e) {
|
|
5578
|
+
e.preventDefault();
|
|
5579
|
+
e.stopPropagation();
|
|
5580
|
+
toggleSectionComponentsPanel();
|
|
5581
|
+
});
|
|
5582
|
+
}
|
|
5036
5583
|
|
|
5037
5584
|
// \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
|
|
5038
5585
|
document.getElementById('btn-save').addEventListener('click', handleSave);
|
|
@@ -5073,11 +5620,21 @@ function handleSave() {
|
|
|
5073
5620
|
}
|
|
5074
5621
|
|
|
5075
5622
|
function handleClose() {
|
|
5623
|
+
clearPersistedActiveVariationForData(experimentData);
|
|
5076
5624
|
clearVisualEditorLocalStorage();
|
|
5077
5625
|
// Unsaved-changes UX lives in the parent (PlatformVisualEditorV2); avoid double confirm here.
|
|
5078
5626
|
send('close-editor', {});
|
|
5079
5627
|
}
|
|
5080
5628
|
|
|
5629
|
+
// Defensive cleanup: if parent closes/unmounts the editor shell without
|
|
5630
|
+
// invoking handleClose(), clear persisted VVE keys on unload as well.
|
|
5631
|
+
window.addEventListener('pagehide', function() {
|
|
5632
|
+
clearVisualEditorLocalStorage();
|
|
5633
|
+
});
|
|
5634
|
+
window.addEventListener('beforeunload', function() {
|
|
5635
|
+
clearVisualEditorLocalStorage();
|
|
5636
|
+
});
|
|
5637
|
+
|
|
5081
5638
|
// \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
|
|
5082
5639
|
function isNativeEditableTarget(target) {
|
|
5083
5640
|
if (!target || target.nodeType !== 1) return false;
|
|
@@ -5099,10 +5656,7 @@ document.addEventListener('keydown', function(e) {
|
|
|
5099
5656
|
e.preventDefault();
|
|
5100
5657
|
runEditorUndo();
|
|
5101
5658
|
}
|
|
5102
|
-
|
|
5103
|
-
e.preventDefault();
|
|
5104
|
-
runEditorRedo();
|
|
5105
|
-
}
|
|
5659
|
+
// Redo is intentionally hidden/disabled in this editor flow.
|
|
5106
5660
|
if (meta && e.key === 's') { e.preventDefault(); handleSave(); }
|
|
5107
5661
|
if (e.key === 'Escape') {
|
|
5108
5662
|
var openTips = document.querySelectorAll('.ve-pl-tip.is-tip-open');
|
|
@@ -5122,11 +5676,17 @@ document.addEventListener('keydown', function(e) {
|
|
|
5122
5676
|
}
|
|
5123
5677
|
});
|
|
5124
5678
|
function runEditorUndo() {
|
|
5125
|
-
|
|
5126
|
-
if (
|
|
5127
|
-
|
|
5679
|
+
// Undo only unsaved in-session edits; do not remove persisted history rows.
|
|
5680
|
+
if (!isDirty) return;
|
|
5681
|
+
|
|
5682
|
+
// 1) Prefer live unsaved change stack (stateChanges shown in History tab).
|
|
5683
|
+
var liveTarget = getLatestLiveUndoTarget();
|
|
5684
|
+
if (liveTarget) {
|
|
5685
|
+
removeHistoryItem('live', liveTarget.idx);
|
|
5128
5686
|
return;
|
|
5129
5687
|
}
|
|
5688
|
+
|
|
5689
|
+
// 2) Fallback to Vvveb internal undo stack (e.g. structural drag/drop ops).
|
|
5130
5690
|
if (!(typeof Vvveb !== 'undefined' && Vvveb.Undo)) return;
|
|
5131
5691
|
Vvveb.Undo.undo();
|
|
5132
5692
|
saveCurrentVariationHtml();
|
|
@@ -5149,11 +5709,10 @@ document.getElementById('btn-undo').addEventListener('click', function(e) {
|
|
|
5149
5709
|
e.stopPropagation();
|
|
5150
5710
|
runEditorUndo();
|
|
5151
5711
|
});
|
|
5152
|
-
document.getElementById('btn-redo')
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
});
|
|
5712
|
+
var btnRedo = document.getElementById('btn-redo');
|
|
5713
|
+
if (btnRedo) {
|
|
5714
|
+
btnRedo.style.display = 'none';
|
|
5715
|
+
}
|
|
5157
5716
|
|
|
5158
5717
|
function layoutLoadingTooltip(host) {
|
|
5159
5718
|
var tip = host.querySelector('.ve-pl-tooltip');
|
|
@@ -5229,6 +5788,7 @@ function registerCROSections() {
|
|
|
5229
5788
|
|
|
5230
5789
|
window.addEventListener('load', function() {
|
|
5231
5790
|
registerCROSections();
|
|
5791
|
+
bindViewportControls();
|
|
5232
5792
|
switchSectionComponentsTab(currentSectionComponentsTab);
|
|
5233
5793
|
renderElementsTree(document.getElementById('comp-search').value);
|
|
5234
5794
|
vvvebReady = true;
|
|
@@ -5936,8 +6496,32 @@ ${runtimePreflightScript}
|
|
|
5936
6496
|
var TARGET_ORIGIN=${JSON.stringify(origin)};
|
|
5937
6497
|
var TARGET_PAGE_URL=${JSON.stringify(targetUrl)};
|
|
5938
6498
|
var EMPTY_JSON_DATA="data:application/json;charset=utf-8,%7B%7D";
|
|
5939
|
-
|
|
5940
|
-
|
|
6499
|
+
var _proxyCtx=(function(){try{return new URL(window.location.href);}catch(_){return null;}})();
|
|
6500
|
+
var PROXY_ROOT="/api/conversion-proxy";
|
|
6501
|
+
var PROXY_PASSWORD=_proxyCtx?_proxyCtx.searchParams.get("password")||"":"";
|
|
6502
|
+
var PROXY_BASE_URL=_proxyCtx?_proxyCtx.searchParams.get("conversionProxyBaseUrl")||"":"";
|
|
6503
|
+
var PROXY_TRACKING_MARKERS=_proxyCtx?_proxyCtx.searchParams.get("trackingMarkers")||"":"";
|
|
6504
|
+
var PROXY_STRICT_FREEZE=_proxyCtx?_proxyCtx.searchParams.get("strictObserverFreeze")||"":"";
|
|
6505
|
+
var PROXY_UPSTREAM_MODE=_proxyCtx?_proxyCtx.searchParams.get("proxy")||"":"";
|
|
6506
|
+
function isSkippable(raw){if(!raw||typeof raw!=="string")return true;return raw.startsWith("data:")||raw.startsWith("blob:")||raw.startsWith("javascript:")||raw.startsWith("#");}
|
|
6507
|
+
function toProxyNetworkUrl(raw){
|
|
6508
|
+
if(isSkippable(raw))return raw;
|
|
6509
|
+
try{
|
|
6510
|
+
var base=raw.startsWith("/")?TARGET_ORIGIN:TARGET_PAGE_URL;
|
|
6511
|
+
var abs=new URL(raw,base);
|
|
6512
|
+
if(abs.origin!==TARGET_ORIGIN)return raw;
|
|
6513
|
+
var prox=new URL(PROXY_ROOT,window.location.origin);
|
|
6514
|
+
prox.searchParams.set("password",PROXY_PASSWORD||"");
|
|
6515
|
+
prox.searchParams.set("url",abs.toString());
|
|
6516
|
+
if(PROXY_BASE_URL)prox.searchParams.set("conversionProxyBaseUrl",PROXY_BASE_URL);
|
|
6517
|
+
if(PROXY_TRACKING_MARKERS)prox.searchParams.set("trackingMarkers",PROXY_TRACKING_MARKERS);
|
|
6518
|
+
if(PROXY_STRICT_FREEZE)prox.searchParams.set("strictObserverFreeze",PROXY_STRICT_FREEZE);
|
|
6519
|
+
if(PROXY_UPSTREAM_MODE)prox.searchParams.set("proxy",PROXY_UPSTREAM_MODE);
|
|
6520
|
+
return prox.toString();
|
|
6521
|
+
}catch(_){
|
|
6522
|
+
return raw;
|
|
6523
|
+
}
|
|
6524
|
+
}
|
|
5941
6525
|
function resolveUrl(s){try{return new URL(s,window.location.href);}catch(_){return null;}}
|
|
5942
6526
|
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;}
|
|
5943
6527
|
function skipNestedProxyNetwork(s){var u=typeof s==="string"?resolveUrl(s):null;return u&&isNestedMalformedProxy(u);}
|
|
@@ -5950,9 +6534,9 @@ if(window.fetch){
|
|
|
5950
6534
|
var rawUrl=typeof input==="string"?input:(input&&input.url?String(input.url):"");
|
|
5951
6535
|
if(rawUrl&&skipNestedProxyNetwork(rawUrl))return emptyJsonFetchResponse();
|
|
5952
6536
|
if(typeof input==="string"){
|
|
5953
|
-
input=
|
|
6537
|
+
input=toProxyNetworkUrl(input);
|
|
5954
6538
|
}else if(input&&input.url){
|
|
5955
|
-
var next=
|
|
6539
|
+
var next=toProxyNetworkUrl(input.url);
|
|
5956
6540
|
if(next!==input.url){input=new Request(next,input);}
|
|
5957
6541
|
}
|
|
5958
6542
|
afterUrl=typeof input==="string"?input:(input&&input.url?String(input.url):"");
|
|
@@ -5962,8 +6546,22 @@ if(window.fetch){
|
|
|
5962
6546
|
try{
|
|
5963
6547
|
var u=afterUrl?resolveUrl(afterUrl):null;
|
|
5964
6548
|
var sameOrigin=!!(u&&u.origin===TARGET_ORIGIN);
|
|
5965
|
-
var
|
|
5966
|
-
|
|
6549
|
+
var reqMethod=(init&&init.method?String(init.method):(input&&input.method?String(input.method):"GET")).toUpperCase();
|
|
6550
|
+
var isSafeMethod=reqMethod==="GET"||reqMethod==="HEAD";
|
|
6551
|
+
var path=(u&&u.pathname?u.pathname:"").toLowerCase();
|
|
6552
|
+
var qs=(u&&u.search?u.search:"").toLowerCase();
|
|
6553
|
+
var likelyBackgroundEndpoint=!!(u&&(
|
|
6554
|
+
/(^|\\/)apps?(\\/|$)|(^|\\/)a(\\/|$)/.test(path)||
|
|
6555
|
+
path==="/cart"||
|
|
6556
|
+
path==="/cart.js"||
|
|
6557
|
+
path.indexOf("/cart/")===0||
|
|
6558
|
+
path.indexOf("/recommendations/")===0||
|
|
6559
|
+
path.indexOf("/search/suggest")===0||
|
|
6560
|
+
qs.indexOf("sections=")!==-1||
|
|
6561
|
+
qs.indexOf("section_id=")!==-1
|
|
6562
|
+
));
|
|
6563
|
+
var likelyThirdPartyBg=!sameOrigin||likelyBackgroundEndpoint;
|
|
6564
|
+
if(window.__CONVERSION_EDITOR_ACTIVE__&&isSafeMethod&&likelyThirdPartyBg){
|
|
5967
6565
|
console.warn("[conversion-proxy] suppressed fetch failure",{url:afterUrl,error:err&&err.message?err.message:String(err)});
|
|
5968
6566
|
return new Response("{}",{status:200,headers:{"Content-Type":"application/json; charset=utf-8"}});
|
|
5969
6567
|
}
|
|
@@ -5972,7 +6570,7 @@ if(window.fetch){
|
|
|
5972
6570
|
});
|
|
5973
6571
|
};
|
|
5974
6572
|
}
|
|
5975
|
-
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]=
|
|
6573
|
+
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);};}
|
|
5976
6574
|
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);};}
|
|
5977
6575
|
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;}}
|
|
5978
6576
|
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);
|