@accelerated-agency/visual-editor 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +346 -1
- package/dist/vite.cjs +454 -60
- package/dist/vite.js +454 -60
- package/package.json +2 -1
package/dist/vite.js
CHANGED
|
@@ -140,6 +140,17 @@ html,body{height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFo
|
|
|
140
140
|
.tb-save-txt{font-size:14px;color:#00C951;white-space:nowrap}
|
|
141
141
|
.tb-save-txt::before{content:'Saved'}
|
|
142
142
|
#dirty-dot.on~.tb-save-txt::before{content:'Unsaved'}
|
|
143
|
+
|
|
144
|
+
/* \u2500\u2500 In-editor toast notification \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
145
|
+
#ve-notification{
|
|
146
|
+
position:fixed;right:16px;top:64px;z-index:13000;max-width:360px;
|
|
147
|
+
padding:10px 12px;border-radius:8px;font-size:12px;line-height:1.35;
|
|
148
|
+
border:1px solid var(--border);background:#fff;color:var(--text);
|
|
149
|
+
box-shadow:0 10px 24px rgba(2,6,23,.18);display:none
|
|
150
|
+
}
|
|
151
|
+
#ve-notification.show{display:block}
|
|
152
|
+
#ve-notification.error{border-color:#fecaca;background:#fef2f2;color:#991b1b}
|
|
153
|
+
#ve-notification.success{border-color:#bbf7d0;background:#f0fdf4;color:#166534}
|
|
143
154
|
.tb-save-time{font-size:12px;color:#52525b;white-space:nowrap}
|
|
144
155
|
#dirty-dot.on~.tb-save-time{display:none}
|
|
145
156
|
/* Simulate + Finalize buttons */
|
|
@@ -447,6 +458,49 @@ html,body{height:100%;overflow:hidden;font-family:-apple-system,BlinkMacSystemFo
|
|
|
447
458
|
/* \u2500\u2500 Subgroup label \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
448
459
|
.sub-lbl{font-size:10px;text-transform:uppercase;color:var(--text-3);font-weight:700;letter-spacing:.05em;margin:8px 0 5px}
|
|
449
460
|
.sub-lbl:first-child{margin-top:0}
|
|
461
|
+
.sub-lbl-row{display:flex;align-items:center;justify-content:space-between;gap:8px;margin:8px 0 5px}
|
|
462
|
+
.sub-lbl-row .sub-lbl{margin:0}
|
|
463
|
+
.css-expand-btn{
|
|
464
|
+
width:22px;height:22px;border:1px solid var(--border);border-radius:5px;background:#fff;
|
|
465
|
+
display:inline-flex;align-items:center;justify-content:center;cursor:pointer;color:var(--text-3);
|
|
466
|
+
transition:all .15s
|
|
467
|
+
}
|
|
468
|
+
.css-expand-btn:hover{border-color:var(--accent);color:var(--accent-txt);background:var(--accent-bg)}
|
|
469
|
+
|
|
470
|
+
/* \u2500\u2500 Custom CSS modal \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
471
|
+
#custom-css-modal{
|
|
472
|
+
position:fixed;inset:0;z-index:12000;background:rgba(15,23,42,.5);
|
|
473
|
+
display:none;align-items:center;justify-content:center;padding:20px
|
|
474
|
+
}
|
|
475
|
+
#custom-css-modal.open{display:flex}
|
|
476
|
+
.custom-css-dialog{
|
|
477
|
+
width:min(860px,96vw);max-height:86vh;background:#fff;border:1px solid var(--border);
|
|
478
|
+
border-radius:10px;box-shadow:0 20px 40px rgba(2,6,23,.35);display:flex;flex-direction:column;overflow:hidden
|
|
479
|
+
}
|
|
480
|
+
.custom-css-head{
|
|
481
|
+
display:flex;align-items:center;justify-content:space-between;gap:10px;
|
|
482
|
+
padding:10px 12px;border-bottom:1px solid var(--border);background:#fff
|
|
483
|
+
}
|
|
484
|
+
.custom-css-title{font-size:12px;font-weight:700;color:var(--text)}
|
|
485
|
+
.custom-css-close{
|
|
486
|
+
border:none;background:transparent;color:var(--text-3);cursor:pointer;width:24px;height:24px;border-radius:5px
|
|
487
|
+
}
|
|
488
|
+
.custom-css-close:hover{background:var(--bg-hover);color:var(--text)}
|
|
489
|
+
#custom-css-modal-textarea{
|
|
490
|
+
width:100%;min-height:360px;max-height:58vh;resize:vertical;border:none;outline:none;
|
|
491
|
+
font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;
|
|
492
|
+
font-size:12px;line-height:1.5;padding:12px;background:#0b1220;color:#e2e8f0
|
|
493
|
+
}
|
|
494
|
+
.custom-css-actions{
|
|
495
|
+
display:flex;justify-content:flex-end;gap:8px;padding:10px 12px;border-top:1px solid var(--border);background:#fff
|
|
496
|
+
}
|
|
497
|
+
.custom-css-btn{
|
|
498
|
+
border:1px solid var(--border);background:#fff;color:var(--text-2);border-radius:6px;padding:6px 10px;cursor:pointer;
|
|
499
|
+
font-size:12px;font-weight:600;font-family:inherit
|
|
500
|
+
}
|
|
501
|
+
.custom-css-btn:hover{background:var(--bg-hover)}
|
|
502
|
+
.custom-css-btn.primary{background:var(--accent);border-color:var(--accent);color:#fff}
|
|
503
|
+
.custom-css-btn.primary:hover{filter:brightness(.97)}
|
|
450
504
|
|
|
451
505
|
/* \u2500\u2500 Shadow presets \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
|
|
452
506
|
.shadow-presets{display:flex;gap:4px;flex-wrap:wrap;margin-top:6px}
|
|
@@ -836,6 +890,23 @@ select.pr-inp{cursor:pointer;background:#fff}
|
|
|
836
890
|
|
|
837
891
|
</div><!-- #app -->
|
|
838
892
|
|
|
893
|
+
<!-- Custom CSS full-screen modal -->
|
|
894
|
+
<div id="custom-css-modal" aria-hidden="true">
|
|
895
|
+
<div class="custom-css-dialog" role="dialog" aria-modal="true" aria-labelledby="custom-css-modal-title">
|
|
896
|
+
<div class="custom-css-head">
|
|
897
|
+
<div class="custom-css-title" id="custom-css-modal-title"><i class="bi bi-code-slash"></i> Custom CSS</div>
|
|
898
|
+
<button type="button" class="custom-css-close" onclick="closeCustomCssModal()" title="Close">
|
|
899
|
+
<i class="bi bi-x-lg"></i>
|
|
900
|
+
</button>
|
|
901
|
+
</div>
|
|
902
|
+
<textarea id="custom-css-modal-textarea" spellcheck="false" placeholder="Type your css here"></textarea>
|
|
903
|
+
<div class="custom-css-actions">
|
|
904
|
+
<button type="button" class="custom-css-btn" onclick="closeCustomCssModal()">Cancel</button>
|
|
905
|
+
<button type="button" class="custom-css-btn primary" onclick="applyCustomCssModal()">Add</button>
|
|
906
|
+
</div>
|
|
907
|
+
</div>
|
|
908
|
+
</div>
|
|
909
|
+
|
|
839
910
|
<!-- CDN scripts -->
|
|
840
911
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
|
841
912
|
<script src="https://cdn.jsdelivr.net/gh/givanz/VvvebJs@master/libs/builder/builder.js"></script>
|
|
@@ -907,13 +978,37 @@ function send(type, payload) {
|
|
|
907
978
|
window.parent.postMessage({ channel: CHANNEL, type: type, payload: payload || {} }, '*');
|
|
908
979
|
}
|
|
909
980
|
|
|
981
|
+
var notificationTimer = null;
|
|
982
|
+
function showEditorNotification(message, kind, durationMs) {
|
|
983
|
+
var id = 've-notification';
|
|
984
|
+
var el = document.getElementById(id);
|
|
985
|
+
if (!el) {
|
|
986
|
+
el = document.createElement('div');
|
|
987
|
+
el.id = id;
|
|
988
|
+
el.setAttribute('role', 'status');
|
|
989
|
+
el.setAttribute('aria-live', 'polite');
|
|
990
|
+
document.body.appendChild(el);
|
|
991
|
+
}
|
|
992
|
+
el.className = '';
|
|
993
|
+
el.classList.add(kind === 'success' ? 'success' : 'error');
|
|
994
|
+
el.classList.add('show');
|
|
995
|
+
el.textContent = String(message || 'Something went wrong');
|
|
996
|
+
if (notificationTimer) clearTimeout(notificationTimer);
|
|
997
|
+
notificationTimer = setTimeout(function() {
|
|
998
|
+
var cur = document.getElementById(id);
|
|
999
|
+
if (!cur) return;
|
|
1000
|
+
cur.classList.remove('show');
|
|
1001
|
+
}, Math.max(1200, durationMs || 2600));
|
|
1002
|
+
}
|
|
1003
|
+
|
|
910
1004
|
function generatePreviewUrlString(args) {
|
|
911
1005
|
var baseUrl = (args && args.url) || '';
|
|
912
1006
|
var test = (args && args.test) || {};
|
|
913
1007
|
var variation = (args && args.variation) || {};
|
|
914
1008
|
if (!baseUrl) return '';
|
|
915
|
-
var testId = test.iid ||
|
|
916
|
-
var variationId = variation.iid ||
|
|
1009
|
+
var testId = test.iid || '';
|
|
1010
|
+
var variationId = variation.iid || '';
|
|
1011
|
+
if (!testId || !variationId) return '';
|
|
917
1012
|
var cId = String(testId || '') + '_' + String(variationId || '');
|
|
918
1013
|
var hasQueryParams = String(baseUrl).indexOf('?') >= 0;
|
|
919
1014
|
return (
|
|
@@ -937,6 +1032,10 @@ function simulateExperiment() {
|
|
|
937
1032
|
test.pageUrl ||
|
|
938
1033
|
(test.metadata_1 && test.metadata_1.editor_url) ||
|
|
939
1034
|
'';
|
|
1035
|
+
if (!test.iid || !activeVariation || !activeVariation.iid) {
|
|
1036
|
+
showEditorNotification('Cannot simulate: missing test.iid or variation.iid.', 'error', 3200);
|
|
1037
|
+
return;
|
|
1038
|
+
}
|
|
940
1039
|
var url = generatePreviewUrlString({
|
|
941
1040
|
url: targetUrl,
|
|
942
1041
|
test: test,
|
|
@@ -944,6 +1043,7 @@ function simulateExperiment() {
|
|
|
944
1043
|
});
|
|
945
1044
|
if (!url) {
|
|
946
1045
|
console.warn('[V2] simulateExperiment: missing target URL');
|
|
1046
|
+
showEditorNotification('Cannot simulate: missing target URL.', 'error', 3200);
|
|
947
1047
|
return;
|
|
948
1048
|
}
|
|
949
1049
|
try {
|
|
@@ -961,6 +1061,19 @@ window.addEventListener('message', function(e) {
|
|
|
961
1061
|
}
|
|
962
1062
|
});
|
|
963
1063
|
|
|
1064
|
+
document.addEventListener('keydown', function(e) {
|
|
1065
|
+
if (e.key !== 'Escape') return;
|
|
1066
|
+
var modal = document.getElementById('custom-css-modal');
|
|
1067
|
+
if (!modal || !modal.classList.contains('open')) return;
|
|
1068
|
+
closeCustomCssModal();
|
|
1069
|
+
});
|
|
1070
|
+
|
|
1071
|
+
document.addEventListener('click', function(e) {
|
|
1072
|
+
var modal = document.getElementById('custom-css-modal');
|
|
1073
|
+
if (!modal || !modal.classList.contains('open')) return;
|
|
1074
|
+
if (e.target === modal) closeCustomCssModal();
|
|
1075
|
+
});
|
|
1076
|
+
|
|
964
1077
|
// \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
965
1078
|
var experimentData = null;
|
|
966
1079
|
var variations = [];
|
|
@@ -1040,14 +1153,17 @@ function endSuppressIframeMutationDirty() {
|
|
|
1040
1153
|
function commitStateChangesForActiveVariation() {
|
|
1041
1154
|
if (!activeVarId) return;
|
|
1042
1155
|
stateChangesByVarId[activeVarId] = (stateChanges || []).slice();
|
|
1156
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1043
1157
|
}
|
|
1044
1158
|
|
|
1045
1159
|
function loadStateChangesForActiveVariation() {
|
|
1046
1160
|
if (!activeVarId) {
|
|
1047
1161
|
stateChanges = [];
|
|
1162
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1048
1163
|
return;
|
|
1049
1164
|
}
|
|
1050
1165
|
stateChanges = (stateChangesByVarId[activeVarId] || []).slice();
|
|
1166
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1051
1167
|
}
|
|
1052
1168
|
|
|
1053
1169
|
function recoverSelectedElement(forceDeselectOnMiss) {
|
|
@@ -1527,24 +1643,26 @@ function persistActiveVariationChangesets(arr) {
|
|
|
1527
1643
|
}
|
|
1528
1644
|
}
|
|
1529
1645
|
}
|
|
1646
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1530
1647
|
}
|
|
1531
1648
|
|
|
1532
1649
|
function entrySnapshotKey(entry) {
|
|
1533
1650
|
if (!entry || !entry.selector) return '';
|
|
1651
|
+
var SEP = '__vve_sep__';
|
|
1534
1652
|
var selKey = sanitizeSelectorForMatch(entry.selector) || entry.selector;
|
|
1535
1653
|
return (
|
|
1536
1654
|
selKey +
|
|
1537
|
-
|
|
1655
|
+
SEP +
|
|
1538
1656
|
normalizeChangesetType(entry) +
|
|
1539
|
-
|
|
1657
|
+
SEP +
|
|
1540
1658
|
String(entry.property || '') +
|
|
1541
|
-
|
|
1659
|
+
SEP +
|
|
1542
1660
|
String(entry.attribute || '') +
|
|
1543
|
-
|
|
1661
|
+
SEP +
|
|
1544
1662
|
String(entry.action || '') +
|
|
1545
|
-
|
|
1663
|
+
SEP +
|
|
1546
1664
|
String(entry.html != null ? 'h' + String(entry.html).length : '') +
|
|
1547
|
-
|
|
1665
|
+
SEP +
|
|
1548
1666
|
String(entry.value != null ? 'v:' + entry.value : '')
|
|
1549
1667
|
);
|
|
1550
1668
|
}
|
|
@@ -1594,7 +1712,6 @@ function softReloadEditorIframe() {
|
|
|
1594
1712
|
var navGen = nextIframeContentNavGen();
|
|
1595
1713
|
resetIframeBindings();
|
|
1596
1714
|
setIframePageLoadingUi(true);
|
|
1597
|
-
iframe.src = '';
|
|
1598
1715
|
iframe.src = appendIframeReloadBust(src);
|
|
1599
1716
|
startIframeContentApplyWatcher(navGen);
|
|
1600
1717
|
scheduleDomTreeRefresh();
|
|
@@ -1603,6 +1720,7 @@ function softReloadEditorIframe() {
|
|
|
1603
1720
|
/** @returns {boolean} true if a full iframe reload was started */
|
|
1604
1721
|
function revertChangesetEntryOnDom(entry) {
|
|
1605
1722
|
if (!entry) return false;
|
|
1723
|
+
var styleOnly = isStyleOnlyChangesetEntry(entry);
|
|
1606
1724
|
if (entry.selector === '__vvveb_body__') {
|
|
1607
1725
|
var iframeDoc0 = document.getElementById('iframeId').contentDocument;
|
|
1608
1726
|
if (!iframeDoc0 || !iframeDoc0.body) return false;
|
|
@@ -1623,6 +1741,11 @@ function revertChangesetEntryOnDom(entry) {
|
|
|
1623
1741
|
var snap = appliedChangesetSnapshots[k];
|
|
1624
1742
|
var el = querySelectorResolved(iframeDoc, entry.selector);
|
|
1625
1743
|
if (!snap || !el) {
|
|
1744
|
+
if (styleOnly) {
|
|
1745
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1746
|
+
delete appliedChangesetSnapshots[k];
|
|
1747
|
+
return false;
|
|
1748
|
+
}
|
|
1626
1749
|
softReloadEditorIframe();
|
|
1627
1750
|
delete appliedChangesetSnapshots[k];
|
|
1628
1751
|
return true;
|
|
@@ -1637,6 +1760,11 @@ function revertChangesetEntryOnDom(entry) {
|
|
|
1637
1760
|
else el.setAttribute(snap.name, snap.v);
|
|
1638
1761
|
} else if (snap.kind === 'display') el.style.display = snap.v;
|
|
1639
1762
|
else {
|
|
1763
|
+
if (styleOnly) {
|
|
1764
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1765
|
+
delete appliedChangesetSnapshots[k];
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1640
1768
|
softReloadEditorIframe();
|
|
1641
1769
|
delete appliedChangesetSnapshots[k];
|
|
1642
1770
|
return true;
|
|
@@ -1696,7 +1824,9 @@ function renderHistoryTab() {
|
|
|
1696
1824
|
var lab = historyEntryTypeLabel(item.entry);
|
|
1697
1825
|
var val = historyEntryValuePreview(item.entry);
|
|
1698
1826
|
html +=
|
|
1699
|
-
'<div class="state-item"
|
|
1827
|
+
'<div class="state-item" role="button" tabindex="0" title="Jump to element in iframe" onclick="focusHistoryChangeset(' +
|
|
1828
|
+
item.idx +
|
|
1829
|
+
')">' +
|
|
1700
1830
|
'<span class="state-item-idx" style="opacity:0.55;font-size:10px;min-width:2.2em;display:inline-block" title="Order in saved changesets">#' +
|
|
1701
1831
|
item.idx +
|
|
1702
1832
|
'</span>' +
|
|
@@ -1712,7 +1842,7 @@ function renderHistoryTab() {
|
|
|
1712
1842
|
item.idx +
|
|
1713
1843
|
')" onclick="removeHistoryChangeset(' +
|
|
1714
1844
|
item.idx +
|
|
1715
|
-
')">✕</button>' +
|
|
1845
|
+
', event)">✕</button>' +
|
|
1716
1846
|
'</div>';
|
|
1717
1847
|
});
|
|
1718
1848
|
html += '</div>';
|
|
@@ -1730,7 +1860,38 @@ function changesetListHasStructural(arr) {
|
|
|
1730
1860
|
return false;
|
|
1731
1861
|
}
|
|
1732
1862
|
|
|
1733
|
-
function
|
|
1863
|
+
function isStyleOnlyChangesetEntry(entry) {
|
|
1864
|
+
if (!entry) return false;
|
|
1865
|
+
var t = normalizeChangesetType(entry);
|
|
1866
|
+
if (t === 'style') return true;
|
|
1867
|
+
if (t === 'attribute' && String(entry.attribute || '').toLowerCase() === 'style') return true;
|
|
1868
|
+
return false;
|
|
1869
|
+
}
|
|
1870
|
+
|
|
1871
|
+
function focusHistoryChangeset(idx) {
|
|
1872
|
+
var v = getActiveVariationForHistory();
|
|
1873
|
+
if (!v) return;
|
|
1874
|
+
var arr = parseVariationChangesets(v);
|
|
1875
|
+
if (idx < 0 || idx >= arr.length) return;
|
|
1876
|
+
var entry = arr[idx];
|
|
1877
|
+
if (!entry || !entry.selector || entry.selector === '__vvveb_body__') return;
|
|
1878
|
+
try {
|
|
1879
|
+
var iframe = document.getElementById('iframeId');
|
|
1880
|
+
var iframeDoc = iframe && iframe.contentDocument;
|
|
1881
|
+
if (!iframeDoc) return;
|
|
1882
|
+
var el = querySelectorResolved(iframeDoc, entry.selector);
|
|
1883
|
+
if (!el) return;
|
|
1884
|
+
selectElement(el);
|
|
1885
|
+
try {
|
|
1886
|
+
el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
|
|
1887
|
+
} catch(_) {
|
|
1888
|
+
el.scrollIntoView();
|
|
1889
|
+
}
|
|
1890
|
+
} catch(_) {}
|
|
1891
|
+
}
|
|
1892
|
+
|
|
1893
|
+
function removeHistoryChangeset(idx, evt) {
|
|
1894
|
+
if (evt && evt.stopPropagation) evt.stopPropagation();
|
|
1734
1895
|
var v = getActiveVariationForHistory();
|
|
1735
1896
|
if (!v) return;
|
|
1736
1897
|
var arr = parseVariationChangesets(v);
|
|
@@ -1738,6 +1899,16 @@ function removeHistoryChangeset(idx) {
|
|
|
1738
1899
|
var removed = arr[idx];
|
|
1739
1900
|
arr.splice(idx, 1);
|
|
1740
1901
|
persistActiveVariationChangesets(arr);
|
|
1902
|
+
if (isStyleOnlyChangesetEntry(removed)) {
|
|
1903
|
+
try {
|
|
1904
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1905
|
+
saveCurrentVariationHtml();
|
|
1906
|
+
} catch(_) {}
|
|
1907
|
+
if (currentMainTab === 'history') renderHistoryTab();
|
|
1908
|
+
recomputeEditorDirty();
|
|
1909
|
+
scheduleDomTreeRefresh();
|
|
1910
|
+
return;
|
|
1911
|
+
}
|
|
1741
1912
|
var didReload = revertChangesetEntryOnDom(removed);
|
|
1742
1913
|
try {
|
|
1743
1914
|
delete varHtmlCache[activeVarId];
|
|
@@ -1745,15 +1916,19 @@ function removeHistoryChangeset(idx) {
|
|
|
1745
1916
|
// Re-applying remaining rows on top of current DOM duplicates insert/reorder nodes; reload when any
|
|
1746
1917
|
// structural row remains or was removed (revert may already have started a reload for insert/body).
|
|
1747
1918
|
var removedType = normalizeChangesetType(removed);
|
|
1748
|
-
var
|
|
1749
|
-
|
|
1750
|
-
(removedType === 'insert' ||
|
|
1751
|
-
removedType === 'reorder' ||
|
|
1752
|
-
changesetListHasStructural(arr));
|
|
1919
|
+
var hasStructuralRemaining = changesetListHasStructural(arr);
|
|
1920
|
+
var removedIsStructural = removedType === 'insert' || removedType === 'reorder';
|
|
1753
1921
|
if (didReload) {
|
|
1754
1922
|
/* revertChangesetEntryOnDom already kicked off iframe reload */
|
|
1755
|
-
} else if (
|
|
1923
|
+
} else if (removedIsStructural) {
|
|
1756
1924
|
softReloadEditorIframe();
|
|
1925
|
+
} else if (hasStructuralRemaining) {
|
|
1926
|
+
// Keep current DOM state (already reverted for removed row) and only refresh style layer.
|
|
1927
|
+
// Avoid full reload and avoid re-applying all rows, which can duplicate structural insert/reorder entries.
|
|
1928
|
+
try {
|
|
1929
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
1930
|
+
saveCurrentVariationHtml();
|
|
1931
|
+
} catch(_) {}
|
|
1757
1932
|
} else {
|
|
1758
1933
|
try {
|
|
1759
1934
|
appliedStructuralChangesetKeys = {};
|
|
@@ -2121,7 +2296,7 @@ function runConsistencyReconcile() {
|
|
|
2121
2296
|
if (!cs.length || changesetsHaveBodySnapshot(cs)) return;
|
|
2122
2297
|
var granular = filterGranularChangesetEntries(cs);
|
|
2123
2298
|
var unresolved = countUnresolvedGranularSelectors(doc, granular);
|
|
2124
|
-
if (unresolved > 0 ||
|
|
2299
|
+
if (unresolved > 0 || hasUnappliedStructuralChangesets(cs)) {
|
|
2125
2300
|
reapplyActiveVariationGranular(doc);
|
|
2126
2301
|
registerPendingGranularChangesets(cs, doc);
|
|
2127
2302
|
}
|
|
@@ -2491,24 +2666,136 @@ function flushPendingGranularChangesets() {
|
|
|
2491
2666
|
function structuralChangesetDedupKey(entry) {
|
|
2492
2667
|
var nt = normalizeChangesetType(entry);
|
|
2493
2668
|
if (!entry || (nt !== 'insert' && nt !== 'reorder')) return '';
|
|
2669
|
+
var SEP = '__vve_sep__';
|
|
2494
2670
|
var vid = activeVarId || '';
|
|
2495
2671
|
try {
|
|
2496
2672
|
return (
|
|
2497
2673
|
vid +
|
|
2498
|
-
|
|
2674
|
+
SEP +
|
|
2499
2675
|
nt +
|
|
2500
|
-
|
|
2676
|
+
SEP +
|
|
2501
2677
|
entry.selector +
|
|
2502
|
-
|
|
2678
|
+
SEP +
|
|
2503
2679
|
String(entry.action || '') +
|
|
2504
|
-
|
|
2680
|
+
SEP +
|
|
2505
2681
|
String(entry.html != null ? entry.html : '').slice(0, 240) +
|
|
2506
|
-
|
|
2682
|
+
SEP +
|
|
2507
2683
|
String(entry.targetSelector || '')
|
|
2508
2684
|
);
|
|
2509
2685
|
} catch(_) {
|
|
2510
|
-
return vid +
|
|
2686
|
+
return vid + SEP + nt + SEP + entry.selector;
|
|
2687
|
+
}
|
|
2688
|
+
}
|
|
2689
|
+
|
|
2690
|
+
function hasUnappliedStructuralChangesets(cs) {
|
|
2691
|
+
if (!cs || !cs.length) return false;
|
|
2692
|
+
for (var i = 0; i < cs.length; i++) {
|
|
2693
|
+
var e = cs[i];
|
|
2694
|
+
var t = normalizeChangesetType(e);
|
|
2695
|
+
if (t !== 'insert' && t !== 'reorder') continue;
|
|
2696
|
+
var k = structuralChangesetDedupKey(e);
|
|
2697
|
+
if (!k) return true;
|
|
2698
|
+
if (!appliedStructuralChangesetKeys[k]) return true;
|
|
2511
2699
|
}
|
|
2700
|
+
return false;
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
function parseInlineStyleDeclarations(styleText) {
|
|
2704
|
+
var out = [];
|
|
2705
|
+
if (styleText == null) return out;
|
|
2706
|
+
var s = String(styleText);
|
|
2707
|
+
if (!s.trim()) return out;
|
|
2708
|
+
var parts = s.split(';');
|
|
2709
|
+
for (var i = 0; i < parts.length; i++) {
|
|
2710
|
+
var seg = parts[i];
|
|
2711
|
+
if (!seg) continue;
|
|
2712
|
+
var idx = seg.indexOf(':');
|
|
2713
|
+
if (idx <= 0) continue;
|
|
2714
|
+
var prop = seg.slice(0, idx).trim();
|
|
2715
|
+
var value = seg.slice(idx + 1).trim();
|
|
2716
|
+
if (!prop || !value) continue;
|
|
2717
|
+
out.push({ prop: prop, value: value });
|
|
2718
|
+
}
|
|
2719
|
+
return out;
|
|
2720
|
+
}
|
|
2721
|
+
|
|
2722
|
+
function buildPersistentStyleRulesForActiveVariation() {
|
|
2723
|
+
if (!activeVarId) return '';
|
|
2724
|
+
var v = variations.find(function(x) { return x && x._id === activeVarId; });
|
|
2725
|
+
var parsed = parseVariationChangesets(v);
|
|
2726
|
+
var map = {};
|
|
2727
|
+
var order = [];
|
|
2728
|
+
function put(selector, prop, value) {
|
|
2729
|
+
if (!selector || !prop) return;
|
|
2730
|
+
if (value == null || value === '') return;
|
|
2731
|
+
var sel = sanitizeSelectorForMatch(String(selector)) || String(selector);
|
|
2732
|
+
var pr = String(prop).trim();
|
|
2733
|
+
var val = String(value).trim();
|
|
2734
|
+
if (!sel || !pr || !val) return;
|
|
2735
|
+
var k = sel + '__vve_sep__' + pr;
|
|
2736
|
+
if (!map[k]) order.push(k);
|
|
2737
|
+
map[k] = { selector: sel, property: pr, value: val };
|
|
2738
|
+
}
|
|
2739
|
+
for (var i = 0; i < parsed.length; i++) {
|
|
2740
|
+
var e = parsed[i];
|
|
2741
|
+
if (!e) continue;
|
|
2742
|
+
var t = normalizeChangesetType(e);
|
|
2743
|
+
if (t === 'style') {
|
|
2744
|
+
put(e.selector, e.property || e.cssProp, e.value);
|
|
2745
|
+
continue;
|
|
2746
|
+
}
|
|
2747
|
+
if (t === 'attribute' && String(e.attribute || '').toLowerCase() === 'style') {
|
|
2748
|
+
var decls = parseInlineStyleDeclarations(e.value);
|
|
2749
|
+
for (var di = 0; di < decls.length; di++) {
|
|
2750
|
+
put(e.selector, decls[di].prop, decls[di].value);
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
for (var j = 0; j < stateChanges.length; j++) {
|
|
2755
|
+
var c = stateChanges[j];
|
|
2756
|
+
if (!c) continue;
|
|
2757
|
+
if (c.cssProp) {
|
|
2758
|
+
put(c.selector, c.cssProp, c.value);
|
|
2759
|
+
continue;
|
|
2760
|
+
}
|
|
2761
|
+
if (c.inputId === 'pp-css') {
|
|
2762
|
+
var liveDecls = parseInlineStyleDeclarations(c.value);
|
|
2763
|
+
for (var ldi = 0; ldi < liveDecls.length; ldi++) {
|
|
2764
|
+
put(c.selector, liveDecls[ldi].prop, liveDecls[ldi].value);
|
|
2765
|
+
}
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
var lines = [];
|
|
2769
|
+
for (var oi = 0; oi < order.length; oi++) {
|
|
2770
|
+
var row = map[order[oi]];
|
|
2771
|
+
lines.push(row.selector + ' { ' + row.property + ': ' + row.value + ' !important; }');
|
|
2772
|
+
}
|
|
2773
|
+
return lines.join('\\n');
|
|
2774
|
+
}
|
|
2775
|
+
|
|
2776
|
+
function upsertPersistentChangesetStyleTag(iframeDoc, rulesText) {
|
|
2777
|
+
if (!iframeDoc) return;
|
|
2778
|
+
var STYLE_ID = '__vve_persist_changesets_style__';
|
|
2779
|
+
var prev = iframeDoc.getElementById(STYLE_ID);
|
|
2780
|
+
if (!rulesText) {
|
|
2781
|
+
if (prev && prev.parentNode) prev.parentNode.removeChild(prev);
|
|
2782
|
+
return;
|
|
2783
|
+
}
|
|
2784
|
+
var head = iframeDoc.head || iframeDoc.getElementsByTagName('head')[0];
|
|
2785
|
+
if (!head) return;
|
|
2786
|
+
var styleEl = prev || iframeDoc.createElement('style');
|
|
2787
|
+
styleEl.id = STYLE_ID;
|
|
2788
|
+
if (styleEl.textContent !== rulesText) styleEl.textContent = rulesText;
|
|
2789
|
+
if (!styleEl.parentNode) head.appendChild(styleEl);
|
|
2790
|
+
}
|
|
2791
|
+
|
|
2792
|
+
function refreshPersistentChangesetStyleTagForActiveVariation() {
|
|
2793
|
+
try {
|
|
2794
|
+
var iframe = document.getElementById('iframeId');
|
|
2795
|
+
var iframeDoc = iframe && iframe.contentDocument;
|
|
2796
|
+
if (!iframeDoc) return;
|
|
2797
|
+
upsertPersistentChangesetStyleTag(iframeDoc, buildPersistentStyleRulesForActiveVariation());
|
|
2798
|
+
} catch(_) {}
|
|
2512
2799
|
}
|
|
2513
2800
|
|
|
2514
2801
|
/**
|
|
@@ -2545,23 +2832,11 @@ function applyChangesetEntry(entry, iframeDoc) {
|
|
|
2545
2832
|
else if (entry.value != null) el.textContent = entry.value;
|
|
2546
2833
|
break;
|
|
2547
2834
|
case 'style':
|
|
2548
|
-
|
|
2549
|
-
var propKebab = entry.property;
|
|
2550
|
-
var cam = camelize(propKebab);
|
|
2551
|
-
if (entry.value == null || entry.value === '') {
|
|
2552
|
-
try { el.style.removeProperty(propKebab); } catch(_) {}
|
|
2553
|
-
try { if (cam in el.style) el.style[cam] = ''; } catch(__) {}
|
|
2554
|
-
} else {
|
|
2555
|
-
try {
|
|
2556
|
-
el.style.setProperty(propKebab, entry.value, 'important');
|
|
2557
|
-
} catch(_) {
|
|
2558
|
-
el.style[cam] = entry.value;
|
|
2559
|
-
}
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2835
|
+
// Style changes are applied via persistent stylesheet injection.
|
|
2562
2836
|
break;
|
|
2563
2837
|
case 'attribute':
|
|
2564
2838
|
if (entry.attribute && entry.value != null) {
|
|
2839
|
+
if (String(entry.attribute).toLowerCase() === 'style') break;
|
|
2565
2840
|
el.setAttribute(entry.attribute, entry.value);
|
|
2566
2841
|
}
|
|
2567
2842
|
break;
|
|
@@ -2598,6 +2873,7 @@ function applyActiveVariationHtml() {
|
|
|
2598
2873
|
|
|
2599
2874
|
var variation = variations.find(function(v) { return v._id === activeVarId; });
|
|
2600
2875
|
var cs = parseVariationChangesets(variation);
|
|
2876
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
2601
2877
|
|
|
2602
2878
|
beginSuppressIframeMutationDirty();
|
|
2603
2879
|
try {
|
|
@@ -2612,6 +2888,7 @@ function applyActiveVariationHtml() {
|
|
|
2612
2888
|
for (var i = 0; i < cs.length; i++) {
|
|
2613
2889
|
applyChangesetEntry(cs[i], iframeDoc);
|
|
2614
2890
|
}
|
|
2891
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
2615
2892
|
// Selectors often miss on first paint (client-rendered sections). Retry via timer + mutations.
|
|
2616
2893
|
registerPendingGranularChangesets(cs, iframeDoc);
|
|
2617
2894
|
} finally {
|
|
@@ -2660,6 +2937,7 @@ function applyVariationGranularOnly(iframeDoc) {
|
|
|
2660
2937
|
for (var i = 0; i < cs.length; i++) {
|
|
2661
2938
|
applyChangesetEntry(cs[i], iframeDoc);
|
|
2662
2939
|
}
|
|
2940
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
2663
2941
|
registerPendingGranularChangesets(cs, iframeDoc);
|
|
2664
2942
|
} finally {
|
|
2665
2943
|
endSuppressIframeMutationDirty();
|
|
@@ -2678,6 +2956,7 @@ function reapplyActiveVariationGranular(iframeDoc) {
|
|
|
2678
2956
|
for (var i = 0; i < cs.length; i++) {
|
|
2679
2957
|
applyChangesetEntry(cs[i], iframeDoc);
|
|
2680
2958
|
}
|
|
2959
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
2681
2960
|
} finally {
|
|
2682
2961
|
endSuppressIframeMutationDirty();
|
|
2683
2962
|
}
|
|
@@ -3166,6 +3445,40 @@ function pr2(l1, i1, l2, i2) {
|
|
|
3166
3445
|
'<div class="pr2-item"><div class="pr2-lbl">'+l2+'</div>'+i2+'</div></div>';
|
|
3167
3446
|
}
|
|
3168
3447
|
function subLbl(text) { return '<div class="sub-lbl">'+text+'</div>'; }
|
|
3448
|
+
function openCustomCssModal() {
|
|
3449
|
+
var modal = document.getElementById('custom-css-modal');
|
|
3450
|
+
var ta = document.getElementById('custom-css-modal-textarea');
|
|
3451
|
+
if (!modal || !ta) return;
|
|
3452
|
+
var inp = document.getElementById('pp-css');
|
|
3453
|
+
var v = inp ? inp.value : (selectedEl && selectedEl.getAttribute ? (selectedEl.getAttribute('style') || '') : '');
|
|
3454
|
+
ta.value = v || '';
|
|
3455
|
+
modal.classList.add('open');
|
|
3456
|
+
modal.setAttribute('aria-hidden', 'false');
|
|
3457
|
+
setTimeout(function() {
|
|
3458
|
+
try { ta.focus(); ta.setSelectionRange(ta.value.length, ta.value.length); } catch(_) {}
|
|
3459
|
+
}, 0);
|
|
3460
|
+
}
|
|
3461
|
+
function closeCustomCssModal() {
|
|
3462
|
+
var modal = document.getElementById('custom-css-modal');
|
|
3463
|
+
if (!modal) return;
|
|
3464
|
+
modal.classList.remove('open');
|
|
3465
|
+
modal.setAttribute('aria-hidden', 'true');
|
|
3466
|
+
}
|
|
3467
|
+
function applyCustomCssModal() {
|
|
3468
|
+
var ta = document.getElementById('custom-css-modal-textarea');
|
|
3469
|
+
var inp = document.getElementById('pp-css');
|
|
3470
|
+
if (!ta || !inp) {
|
|
3471
|
+
closeCustomCssModal();
|
|
3472
|
+
return;
|
|
3473
|
+
}
|
|
3474
|
+
inp.value = ta.value || '';
|
|
3475
|
+
try {
|
|
3476
|
+
inp.dispatchEvent(new Event('input', { bubbles: true }));
|
|
3477
|
+
} catch(_) {
|
|
3478
|
+
if (typeof inp.oninput === 'function') inp.oninput();
|
|
3479
|
+
}
|
|
3480
|
+
closeCustomCssModal();
|
|
3481
|
+
}
|
|
3169
3482
|
function weightOpts(cur) {
|
|
3170
3483
|
return [['100','Thin'],['200','Extra Light'],['300','Light'],['400','Normal'],['500','Medium'],
|
|
3171
3484
|
['600','Semi Bold'],['700','Bold'],['800','Extra Bold'],['900','Black']]
|
|
@@ -3446,7 +3759,12 @@ function renderRightPanel(el) {
|
|
|
3446
3759
|
// \u2500\u2500 CSS and Classes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
3447
3760
|
document.getElementById('acc-body-css').innerHTML =
|
|
3448
3761
|
pr('Classes', '<input class="pr-inp" id="pp-cls" type="text" value="'+esc(el.className||'')+'" placeholder="class1 class2">') +
|
|
3449
|
-
|
|
3762
|
+
'<div class="sub-lbl-row">' +
|
|
3763
|
+
'<div class="sub-lbl">Custom CSS</div>' +
|
|
3764
|
+
'<button type="button" class="css-expand-btn" title="Open full-screen editor" onclick="openCustomCssModal()">' +
|
|
3765
|
+
'<i class="bi bi-fullscreen"></i>' +
|
|
3766
|
+
'</button>' +
|
|
3767
|
+
'</div>' +
|
|
3450
3768
|
'<textarea class="pr-inp" id="pp-css" style="width:100%;min-height:80px;font-family:monospace;font-size:11px" placeholder="color: red; font-size: 16px;">'+esc(el.getAttribute('style')||'')+'</textarea>';
|
|
3451
3769
|
|
|
3452
3770
|
// \u2500\u2500 Attributes \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
@@ -3810,26 +4128,6 @@ function attachChangeObserver() {
|
|
|
3810
4128
|
}
|
|
3811
4129
|
changeObserver = new MutationObserver(function(mutations) {
|
|
3812
4130
|
// Dirty state is derived from changesets baseline + stateChanges (not raw DOM mutations).
|
|
3813
|
-
var bodyReplaced = false;
|
|
3814
|
-
for (var mi = 0; mi < mutations.length; mi++) {
|
|
3815
|
-
var m = mutations[mi];
|
|
3816
|
-
if (
|
|
3817
|
-
m &&
|
|
3818
|
-
m.type === 'childList' &&
|
|
3819
|
-
m.target === doc.body &&
|
|
3820
|
-
m.addedNodes &&
|
|
3821
|
-
m.removedNodes &&
|
|
3822
|
-
m.addedNodes.length > 0 &&
|
|
3823
|
-
m.removedNodes.length > 0
|
|
3824
|
-
) {
|
|
3825
|
-
bodyReplaced = true;
|
|
3826
|
-
break;
|
|
3827
|
-
}
|
|
3828
|
-
}
|
|
3829
|
-
if (bodyReplaced) {
|
|
3830
|
-
// Page JS replaced body children; allow structural rows (insert/reorder) to apply again.
|
|
3831
|
-
appliedStructuralChangesetKeys = {};
|
|
3832
|
-
}
|
|
3833
4131
|
// Host scripts can replace selected nodes every few frames (e.g. A/B tool observers).
|
|
3834
4132
|
// Keep selection sticky by re-resolving from fingerprint.
|
|
3835
4133
|
recoverSelectedElement(false);
|
|
@@ -3863,6 +4161,7 @@ function syncIframeInteractions(reason) {
|
|
|
3863
4161
|
}
|
|
3864
4162
|
showNoUrl(false);
|
|
3865
4163
|
injectIframeSelectionStyles(doc);
|
|
4164
|
+
refreshPersistentChangesetStyleTagForActiveVariation();
|
|
3866
4165
|
attachClickHandler();
|
|
3867
4166
|
attachDragReposition();
|
|
3868
4167
|
attachChangeObserver();
|
|
@@ -4686,6 +4985,101 @@ if(window.navigator&&window.navigator.serviceWorker&&typeof window.navigator.ser
|
|
|
4686
4985
|
} else {
|
|
4687
4986
|
html = runtimeProxyScript + html;
|
|
4688
4987
|
}
|
|
4988
|
+
const aiBridgeRuntimeScript = `<script>(function(){try{
|
|
4989
|
+
var AI_CHANNEL="ve-ai-editor";
|
|
4990
|
+
var lastJs="";
|
|
4991
|
+
var aiSheet=null;
|
|
4992
|
+
var lastAiContainerIds=[];
|
|
4993
|
+
function extractAiContainerIds(source){
|
|
4994
|
+
try{
|
|
4995
|
+
var re=/ai-generated-container-[a-zA-Z0-9_-]+/g;
|
|
4996
|
+
var found=String(source||"").match(re)||[];
|
|
4997
|
+
var uniq=[];
|
|
4998
|
+
for(var i=0;i<found.length;i++){
|
|
4999
|
+
if(uniq.indexOf(found[i])===-1) uniq.push(found[i]);
|
|
5000
|
+
}
|
|
5001
|
+
return uniq;
|
|
5002
|
+
}catch(_){
|
|
5003
|
+
return [];
|
|
5004
|
+
}
|
|
5005
|
+
}
|
|
5006
|
+
function cleanupRemovedAiContainers(nextIds){
|
|
5007
|
+
try{
|
|
5008
|
+
for(var i=0;i<lastAiContainerIds.length;i++){
|
|
5009
|
+
var prevId=lastAiContainerIds[i];
|
|
5010
|
+
if(nextIds.indexOf(prevId)!==-1) continue;
|
|
5011
|
+
var el=document.getElementById(prevId);
|
|
5012
|
+
if(!el) continue;
|
|
5013
|
+
var marker=(el.getAttribute("data-ai-generated")||"").toLowerCase();
|
|
5014
|
+
if(marker==="true"||prevId.indexOf("ai-generated-container-")===0){
|
|
5015
|
+
if(el.parentNode) el.parentNode.removeChild(el);
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
}catch(_){}
|
|
5019
|
+
}
|
|
5020
|
+
function getProxyPayload(){
|
|
5021
|
+
try{
|
|
5022
|
+
var u=new URL(window.location.href);
|
|
5023
|
+
return {
|
|
5024
|
+
url:u.searchParams.get("url")||undefined,
|
|
5025
|
+
password:u.searchParams.get("password")||undefined
|
|
5026
|
+
};
|
|
5027
|
+
}catch(_){
|
|
5028
|
+
return {};
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
function applyAiCode(payload){
|
|
5032
|
+
try{
|
|
5033
|
+
var p=payload||{};
|
|
5034
|
+
var css=typeof p.cssCode==="string"?p.cssCode:"";
|
|
5035
|
+
var js=typeof p.jsCode==="string"?p.jsCode:"";
|
|
5036
|
+
var doc=document;
|
|
5037
|
+
if(typeof CSSStyleSheet!=="undefined"&&"adoptedStyleSheets" in doc){
|
|
5038
|
+
var sheets=doc.adoptedStyleSheets||[];
|
|
5039
|
+
if(css){
|
|
5040
|
+
if(!aiSheet) aiSheet=new CSSStyleSheet();
|
|
5041
|
+
aiSheet.replaceSync(css);
|
|
5042
|
+
if(sheets.indexOf(aiSheet)===-1){
|
|
5043
|
+
doc.adoptedStyleSheets=sheets.concat(aiSheet);
|
|
5044
|
+
}
|
|
5045
|
+
}else if(aiSheet&&sheets.indexOf(aiSheet)!==-1){
|
|
5046
|
+
doc.adoptedStyleSheets=sheets.filter(function(s){return s!==aiSheet;});
|
|
5047
|
+
}
|
|
5048
|
+
}
|
|
5049
|
+
if(js!==lastJs){
|
|
5050
|
+
var nextIds=extractAiContainerIds(js);
|
|
5051
|
+
cleanupRemovedAiContainers(nextIds);
|
|
5052
|
+
if(js) (new Function(js)).call(window);
|
|
5053
|
+
lastJs=js;
|
|
5054
|
+
lastAiContainerIds=nextIds;
|
|
5055
|
+
}
|
|
5056
|
+
try{
|
|
5057
|
+
doc.documentElement.setAttribute("data-ve-ai-applied","1");
|
|
5058
|
+
window.parent&&window.parent.postMessage({
|
|
5059
|
+
channel:AI_CHANNEL,
|
|
5060
|
+
type:"ai-code-applied",
|
|
5061
|
+
payload:{cssLen:css.length,jsLen:js.length}
|
|
5062
|
+
},"*");
|
|
5063
|
+
}catch(_){}
|
|
5064
|
+
}catch(_){}
|
|
5065
|
+
}
|
|
5066
|
+
window.addEventListener("message",function(ev){
|
|
5067
|
+
try{
|
|
5068
|
+
var d=ev&&ev.data;
|
|
5069
|
+
if(!d||d.channel!==AI_CHANNEL||d.type!=="apply-ai-code") return;
|
|
5070
|
+
applyAiCode(d.payload||{});
|
|
5071
|
+
}catch(_){}
|
|
5072
|
+
});
|
|
5073
|
+
try{
|
|
5074
|
+
if(window.parent){
|
|
5075
|
+
window.parent.postMessage({channel:AI_CHANNEL,type:"ai-code-ready"},"*");
|
|
5076
|
+
window.parent.postMessage({channel:AI_CHANNEL,type:"ai-url-changed",payload:getProxyPayload()},"*");
|
|
5077
|
+
}
|
|
5078
|
+
}catch(_){}
|
|
5079
|
+
}catch(_){}})();</script>`;
|
|
5080
|
+
html = html.includes("</head>") ? html.replace("</head>", `${aiBridgeRuntimeScript}
|
|
5081
|
+
</head>`) : `${aiBridgeRuntimeScript}
|
|
5082
|
+
${html}`;
|
|
4689
5083
|
const bridgeScript = `<script src="/bridge.js"></script>`;
|
|
4690
5084
|
html = html.includes("</body>") ? html.replace("</body>", `${bridgeScript}
|
|
4691
5085
|
</body>`) : html + bridgeScript;
|