@accelerated-agency/visual-editor 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/dist/vite.cjs +104 -22
  2. package/dist/vite.js +104 -22
  3. package/package.json +1 -1
package/dist/vite.cjs CHANGED
@@ -999,6 +999,7 @@ var selectedEl = null;
999
999
  var selectedElFingerprint = '';
1000
1000
  var selectedElRecoverMisses = 0;
1001
1001
  var MAX_SELECTED_RECOVER_MISSES = 12;
1002
+ var isDeselectingSelection = false;
1002
1003
  var suppressClickUntil = 0;
1003
1004
  var dragAttachDoc = null;
1004
1005
  var currentMainTab = 'design';
@@ -1027,6 +1028,8 @@ var iframeDocLoadingListeners = null;
1027
1028
  // Each entry: {selector, label, cssProp, value, targetEl}
1028
1029
  // cssProp is null for non-CSS attributes (href, alt, classes\u2026)
1029
1030
  var stateChanges = [];
1031
+ /** Per-variation unsaved Design-tab state changes (input edits not yet finalized). */
1032
+ var stateChangesByVarId = {};
1030
1033
  /** Pre-apply DOM snapshots for granular + body changesets (used when removing History rows) */
1031
1034
  var appliedChangesetSnapshots = {};
1032
1035
  /** Canonical JSON fingerprints of persisted changesets per variation (last load / finalize) */
@@ -1041,13 +1044,49 @@ function endSuppressIframeMutationDirty() {
1041
1044
  suppressIframeMutationDirty = Math.max(0, suppressIframeMutationDirty - 1);
1042
1045
  }
1043
1046
 
1047
+ function commitStateChangesForActiveVariation() {
1048
+ if (!activeVarId) return;
1049
+ stateChangesByVarId[activeVarId] = (stateChanges || []).slice();
1050
+ }
1051
+
1052
+ function loadStateChangesForActiveVariation() {
1053
+ if (!activeVarId) {
1054
+ stateChanges = [];
1055
+ return;
1056
+ }
1057
+ stateChanges = (stateChangesByVarId[activeVarId] || []).slice();
1058
+ }
1059
+
1044
1060
  function recoverSelectedElement(forceDeselectOnMiss) {
1045
1061
  if (selectedEl && selectedEl.ownerDocument && selectedEl.ownerDocument.contains(selectedEl)) {
1046
1062
  selectedElRecoverMisses = 0;
1047
1063
  return selectedEl;
1048
1064
  }
1049
1065
  if (!selectedElFingerprint) {
1050
- if (forceDeselectOnMiss) deselectElement();
1066
+ // Nothing to recover; clear stale reference without calling deselectElement
1067
+ // (which can recurse back through toolbar updates during rapid DOM churn).
1068
+ if (forceDeselectOnMiss && selectedEl) {
1069
+ beginSuppressIframeMutationDirty();
1070
+ try {
1071
+ try { selectedEl.classList.remove('vve-selected'); } catch(_) {}
1072
+ selectedEl = null;
1073
+ selectedElRecoverMisses = 0;
1074
+ } finally {
1075
+ endSuppressIframeMutationDirty();
1076
+ }
1077
+ var noSel = document.getElementById('no-sel');
1078
+ if (noSel) noSel.style.display = '';
1079
+ var elInfo = document.getElementById('el-info');
1080
+ if (elInfo) elInfo.style.display = 'none';
1081
+ var rp = document.getElementById('rp-accordion');
1082
+ if (rp) rp.style.display = 'none';
1083
+ var bc = document.getElementById('bc-path');
1084
+ if (bc) {
1085
+ bc.textContent = 'No element selected';
1086
+ bc.style.color = 'var(--text-3)';
1087
+ }
1088
+ syncDomTreeSelection();
1089
+ }
1051
1090
  return null;
1052
1091
  }
1053
1092
  var iframe = document.getElementById('iframeId');
@@ -1067,7 +1106,29 @@ function recoverSelectedElement(forceDeselectOnMiss) {
1067
1106
  }
1068
1107
  selectedElRecoverMisses += 1;
1069
1108
  if (forceDeselectOnMiss && selectedElRecoverMisses >= MAX_SELECTED_RECOVER_MISSES) {
1070
- deselectElement();
1109
+ beginSuppressIframeMutationDirty();
1110
+ try {
1111
+ if (selectedEl) {
1112
+ try { selectedEl.classList.remove('vve-selected'); } catch(_) {}
1113
+ }
1114
+ selectedEl = null;
1115
+ selectedElFingerprint = '';
1116
+ selectedElRecoverMisses = 0;
1117
+ } finally {
1118
+ endSuppressIframeMutationDirty();
1119
+ }
1120
+ var noSel2 = document.getElementById('no-sel');
1121
+ if (noSel2) noSel2.style.display = '';
1122
+ var elInfo2 = document.getElementById('el-info');
1123
+ if (elInfo2) elInfo2.style.display = 'none';
1124
+ var rp2 = document.getElementById('rp-accordion');
1125
+ if (rp2) rp2.style.display = 'none';
1126
+ var bc2 = document.getElementById('bc-path');
1127
+ if (bc2) {
1128
+ bc2.textContent = 'No element selected';
1129
+ bc2.style.color = 'var(--text-3)';
1130
+ }
1131
+ syncDomTreeSelection();
1071
1132
  }
1072
1133
  return null;
1073
1134
  }
@@ -1328,6 +1389,7 @@ function logChange(selector, inputId, value, targetEl, originalValue) {
1328
1389
  if (idx >= 0) { stateChanges[idx] = entry; } else { stateChanges.push(entry); }
1329
1390
  }
1330
1391
  if (currentMainTab === 'states') renderStatesTab();
1392
+ commitStateChangesForActiveVariation();
1331
1393
  recomputeEditorDirty();
1332
1394
  }
1333
1395
 
@@ -1434,6 +1496,7 @@ function removeStateChange(idx) {
1434
1496
  revertChangeOnDom(change);
1435
1497
  syncDesignInput(change);
1436
1498
  stateChanges.splice(idx, 1);
1499
+ commitStateChangesForActiveVariation();
1437
1500
  renderStatesTab();
1438
1501
  recomputeEditorDirty();
1439
1502
  }
@@ -1444,6 +1507,7 @@ function clearAllStates() {
1444
1507
  syncDesignInput(c);
1445
1508
  });
1446
1509
  stateChanges = [];
1510
+ commitStateChangesForActiveVariation();
1447
1511
  renderStatesTab();
1448
1512
  recomputeEditorDirty();
1449
1513
  }
@@ -1818,7 +1882,9 @@ function handleLoadExperiment(data) {
1818
1882
  experimentData = data;
1819
1883
  variations = Array.isArray(data.variations) ? data.variations : [];
1820
1884
  var prevActive = activeVarId;
1885
+ commitStateChangesForActiveVariation();
1821
1886
  activeVarId = pickActiveVariationIdForLoad(data, variations, prevActive, true);
1887
+ loadStateChangesForActiveVariation();
1822
1888
  writePersistedActiveVariationId(activeVarId);
1823
1889
  renderVariationTabs();
1824
1890
  var urlBarSkip = document.getElementById('url-bar');
@@ -1841,6 +1907,8 @@ function handleLoadExperiment(data) {
1841
1907
  if (!experimentData || prevKey !== nextKey) {
1842
1908
  varHtmlCache = {};
1843
1909
  sessionStructuralChainRowsByVarId = {};
1910
+ stateChangesByVarId = {};
1911
+ stateChanges = [];
1844
1912
  appliedChangesetSnapshots = {};
1845
1913
  appliedStructuralChangesetKeys = {};
1846
1914
  }
@@ -1848,6 +1916,7 @@ function handleLoadExperiment(data) {
1848
1916
  variations = Array.isArray(data.variations) ? data.variations : [];
1849
1917
  var sameExpPage = prevKey === nextKey;
1850
1918
  activeVarId = pickActiveVariationIdForLoad(data, variations, activeVarId, sameExpPage);
1919
+ loadStateChangesForActiveVariation();
1851
1920
  writePersistedActiveVariationId(activeVarId);
1852
1921
  renderVariationTabs();
1853
1922
 
@@ -2171,8 +2240,10 @@ function renderVariationTabs() {
2171
2240
  function switchVariation(varId) {
2172
2241
  if (varId === activeVarId) return;
2173
2242
  saveCurrentVariationHtml();
2243
+ commitStateChangesForActiveVariation();
2174
2244
  clearPendingGranularChangesets();
2175
2245
  activeVarId = varId;
2246
+ loadStateChangesForActiveVariation();
2176
2247
  writePersistedActiveVariationId(varId);
2177
2248
  renderVariationTabs();
2178
2249
  deselectElement();
@@ -2208,6 +2279,7 @@ function switchVariation(varId) {
2208
2279
  }
2209
2280
  } catch(_) {}
2210
2281
  if (currentMainTab === 'history') renderHistoryTab();
2282
+ if (currentMainTab === 'states') renderStatesTab();
2211
2283
  recomputeEditorDirty();
2212
2284
  }
2213
2285
 
@@ -2564,12 +2636,13 @@ function buildPersistedChainSetsForVariation(v) {
2564
2636
  var parsed = parseVariationChangesets(v);
2565
2637
  var base = filterGranularChangesetEntries(parsed);
2566
2638
  var sessionExtra = sessionStructuralChainRowsByVarId[v._id] || [];
2567
- if (v._id !== activeVarId) {
2568
- return mergeGranularChainSets(base, sessionExtra);
2569
- }
2639
+ var sourceStateChanges =
2640
+ v._id === activeVarId
2641
+ ? stateChanges
2642
+ : (stateChangesByVarId[v._id] || []);
2570
2643
  var overlay = [];
2571
- for (var si = 0; si < stateChanges.length; si++) {
2572
- var row = stateChangeToChainSet(stateChanges[si]);
2644
+ for (var si = 0; si < sourceStateChanges.length; si++) {
2645
+ var row = stateChangeToChainSet(sourceStateChanges[si]);
2573
2646
  if (row) overlay.push(row);
2574
2647
  }
2575
2648
  return mergeGranularChainSets(mergeGranularChainSets(base, sessionExtra), overlay);
@@ -2693,24 +2766,31 @@ function selectElement(el) {
2693
2766
  }
2694
2767
  }
2695
2768
 
2696
- function deselectElement() {
2697
- setDragHandleActive(false);
2698
- beginSuppressIframeMutationDirty();
2769
+ function deselectElement(options) {
2770
+ if (isDeselectingSelection) return;
2771
+ isDeselectingSelection = true;
2772
+ var skipToolbarUpdate = !!(options && options.skipToolbarUpdate);
2699
2773
  try {
2700
- if (selectedEl) { try { selectedEl.classList.remove('vve-selected'); } catch(_) {} selectedEl = null; }
2701
- selectedElFingerprint = '';
2702
- selectedElRecoverMisses = 0;
2774
+ setDragHandleActive(false);
2775
+ beginSuppressIframeMutationDirty();
2776
+ try {
2777
+ if (selectedEl) { try { selectedEl.classList.remove('vve-selected'); } catch(_) {} selectedEl = null; }
2778
+ selectedElFingerprint = '';
2779
+ selectedElRecoverMisses = 0;
2780
+ } finally {
2781
+ endSuppressIframeMutationDirty();
2782
+ }
2783
+ document.getElementById('no-sel').style.display = '';
2784
+ document.getElementById('el-info').style.display = 'none';
2785
+ document.getElementById('rp-accordion').style.display = 'none';
2786
+ document.getElementById('bc-path').textContent = 'No element selected';
2787
+ document.getElementById('bc-path').style.color = 'var(--text-3)';
2788
+ switchMainTab('design');
2789
+ if (!skipToolbarUpdate) updateSelectionToolbar();
2790
+ syncDomTreeSelection();
2703
2791
  } finally {
2704
- endSuppressIframeMutationDirty();
2792
+ isDeselectingSelection = false;
2705
2793
  }
2706
- document.getElementById('no-sel').style.display = '';
2707
- document.getElementById('el-info').style.display = 'none';
2708
- document.getElementById('rp-accordion').style.display = 'none';
2709
- document.getElementById('bc-path').textContent = 'No element selected';
2710
- document.getElementById('bc-path').style.color = 'var(--text-3)';
2711
- switchMainTab('design');
2712
- updateSelectionToolbar();
2713
- syncDomTreeSelection();
2714
2794
  }
2715
2795
 
2716
2796
  // \u2500\u2500 Iframe selection chrome, floater toolbar, DOM tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
@@ -3967,6 +4047,7 @@ document.getElementById('btn-close').addEventListener('click', handleClose);
3967
4047
 
3968
4048
  function handleSave() {
3969
4049
  saveCurrentVariationHtml();
4050
+ commitStateChangesForActiveVariation();
3970
4051
  var updatedVariations = variations.map(function(v) {
3971
4052
  var prevParsed = parseVariationChangesets(v);
3972
4053
  var granularPrev = filterGranularChangesetEntries(prevParsed);
@@ -3987,6 +4068,7 @@ function handleSave() {
3987
4068
  variations = updatedVariations;
3988
4069
  varHtmlCache = {};
3989
4070
  sessionStructuralChainRowsByVarId = {};
4071
+ stateChangesByVarId = {};
3990
4072
  stateChanges = [];
3991
4073
  if (currentMainTab === 'states') renderStatesTab();
3992
4074
  captureBaselineFromVariations(variations);
package/dist/vite.js CHANGED
@@ -991,6 +991,7 @@ var selectedEl = null;
991
991
  var selectedElFingerprint = '';
992
992
  var selectedElRecoverMisses = 0;
993
993
  var MAX_SELECTED_RECOVER_MISSES = 12;
994
+ var isDeselectingSelection = false;
994
995
  var suppressClickUntil = 0;
995
996
  var dragAttachDoc = null;
996
997
  var currentMainTab = 'design';
@@ -1019,6 +1020,8 @@ var iframeDocLoadingListeners = null;
1019
1020
  // Each entry: {selector, label, cssProp, value, targetEl}
1020
1021
  // cssProp is null for non-CSS attributes (href, alt, classes\u2026)
1021
1022
  var stateChanges = [];
1023
+ /** Per-variation unsaved Design-tab state changes (input edits not yet finalized). */
1024
+ var stateChangesByVarId = {};
1022
1025
  /** Pre-apply DOM snapshots for granular + body changesets (used when removing History rows) */
1023
1026
  var appliedChangesetSnapshots = {};
1024
1027
  /** Canonical JSON fingerprints of persisted changesets per variation (last load / finalize) */
@@ -1033,13 +1036,49 @@ function endSuppressIframeMutationDirty() {
1033
1036
  suppressIframeMutationDirty = Math.max(0, suppressIframeMutationDirty - 1);
1034
1037
  }
1035
1038
 
1039
+ function commitStateChangesForActiveVariation() {
1040
+ if (!activeVarId) return;
1041
+ stateChangesByVarId[activeVarId] = (stateChanges || []).slice();
1042
+ }
1043
+
1044
+ function loadStateChangesForActiveVariation() {
1045
+ if (!activeVarId) {
1046
+ stateChanges = [];
1047
+ return;
1048
+ }
1049
+ stateChanges = (stateChangesByVarId[activeVarId] || []).slice();
1050
+ }
1051
+
1036
1052
  function recoverSelectedElement(forceDeselectOnMiss) {
1037
1053
  if (selectedEl && selectedEl.ownerDocument && selectedEl.ownerDocument.contains(selectedEl)) {
1038
1054
  selectedElRecoverMisses = 0;
1039
1055
  return selectedEl;
1040
1056
  }
1041
1057
  if (!selectedElFingerprint) {
1042
- if (forceDeselectOnMiss) deselectElement();
1058
+ // Nothing to recover; clear stale reference without calling deselectElement
1059
+ // (which can recurse back through toolbar updates during rapid DOM churn).
1060
+ if (forceDeselectOnMiss && selectedEl) {
1061
+ beginSuppressIframeMutationDirty();
1062
+ try {
1063
+ try { selectedEl.classList.remove('vve-selected'); } catch(_) {}
1064
+ selectedEl = null;
1065
+ selectedElRecoverMisses = 0;
1066
+ } finally {
1067
+ endSuppressIframeMutationDirty();
1068
+ }
1069
+ var noSel = document.getElementById('no-sel');
1070
+ if (noSel) noSel.style.display = '';
1071
+ var elInfo = document.getElementById('el-info');
1072
+ if (elInfo) elInfo.style.display = 'none';
1073
+ var rp = document.getElementById('rp-accordion');
1074
+ if (rp) rp.style.display = 'none';
1075
+ var bc = document.getElementById('bc-path');
1076
+ if (bc) {
1077
+ bc.textContent = 'No element selected';
1078
+ bc.style.color = 'var(--text-3)';
1079
+ }
1080
+ syncDomTreeSelection();
1081
+ }
1043
1082
  return null;
1044
1083
  }
1045
1084
  var iframe = document.getElementById('iframeId');
@@ -1059,7 +1098,29 @@ function recoverSelectedElement(forceDeselectOnMiss) {
1059
1098
  }
1060
1099
  selectedElRecoverMisses += 1;
1061
1100
  if (forceDeselectOnMiss && selectedElRecoverMisses >= MAX_SELECTED_RECOVER_MISSES) {
1062
- deselectElement();
1101
+ beginSuppressIframeMutationDirty();
1102
+ try {
1103
+ if (selectedEl) {
1104
+ try { selectedEl.classList.remove('vve-selected'); } catch(_) {}
1105
+ }
1106
+ selectedEl = null;
1107
+ selectedElFingerprint = '';
1108
+ selectedElRecoverMisses = 0;
1109
+ } finally {
1110
+ endSuppressIframeMutationDirty();
1111
+ }
1112
+ var noSel2 = document.getElementById('no-sel');
1113
+ if (noSel2) noSel2.style.display = '';
1114
+ var elInfo2 = document.getElementById('el-info');
1115
+ if (elInfo2) elInfo2.style.display = 'none';
1116
+ var rp2 = document.getElementById('rp-accordion');
1117
+ if (rp2) rp2.style.display = 'none';
1118
+ var bc2 = document.getElementById('bc-path');
1119
+ if (bc2) {
1120
+ bc2.textContent = 'No element selected';
1121
+ bc2.style.color = 'var(--text-3)';
1122
+ }
1123
+ syncDomTreeSelection();
1063
1124
  }
1064
1125
  return null;
1065
1126
  }
@@ -1320,6 +1381,7 @@ function logChange(selector, inputId, value, targetEl, originalValue) {
1320
1381
  if (idx >= 0) { stateChanges[idx] = entry; } else { stateChanges.push(entry); }
1321
1382
  }
1322
1383
  if (currentMainTab === 'states') renderStatesTab();
1384
+ commitStateChangesForActiveVariation();
1323
1385
  recomputeEditorDirty();
1324
1386
  }
1325
1387
 
@@ -1426,6 +1488,7 @@ function removeStateChange(idx) {
1426
1488
  revertChangeOnDom(change);
1427
1489
  syncDesignInput(change);
1428
1490
  stateChanges.splice(idx, 1);
1491
+ commitStateChangesForActiveVariation();
1429
1492
  renderStatesTab();
1430
1493
  recomputeEditorDirty();
1431
1494
  }
@@ -1436,6 +1499,7 @@ function clearAllStates() {
1436
1499
  syncDesignInput(c);
1437
1500
  });
1438
1501
  stateChanges = [];
1502
+ commitStateChangesForActiveVariation();
1439
1503
  renderStatesTab();
1440
1504
  recomputeEditorDirty();
1441
1505
  }
@@ -1810,7 +1874,9 @@ function handleLoadExperiment(data) {
1810
1874
  experimentData = data;
1811
1875
  variations = Array.isArray(data.variations) ? data.variations : [];
1812
1876
  var prevActive = activeVarId;
1877
+ commitStateChangesForActiveVariation();
1813
1878
  activeVarId = pickActiveVariationIdForLoad(data, variations, prevActive, true);
1879
+ loadStateChangesForActiveVariation();
1814
1880
  writePersistedActiveVariationId(activeVarId);
1815
1881
  renderVariationTabs();
1816
1882
  var urlBarSkip = document.getElementById('url-bar');
@@ -1833,6 +1899,8 @@ function handleLoadExperiment(data) {
1833
1899
  if (!experimentData || prevKey !== nextKey) {
1834
1900
  varHtmlCache = {};
1835
1901
  sessionStructuralChainRowsByVarId = {};
1902
+ stateChangesByVarId = {};
1903
+ stateChanges = [];
1836
1904
  appliedChangesetSnapshots = {};
1837
1905
  appliedStructuralChangesetKeys = {};
1838
1906
  }
@@ -1840,6 +1908,7 @@ function handleLoadExperiment(data) {
1840
1908
  variations = Array.isArray(data.variations) ? data.variations : [];
1841
1909
  var sameExpPage = prevKey === nextKey;
1842
1910
  activeVarId = pickActiveVariationIdForLoad(data, variations, activeVarId, sameExpPage);
1911
+ loadStateChangesForActiveVariation();
1843
1912
  writePersistedActiveVariationId(activeVarId);
1844
1913
  renderVariationTabs();
1845
1914
 
@@ -2163,8 +2232,10 @@ function renderVariationTabs() {
2163
2232
  function switchVariation(varId) {
2164
2233
  if (varId === activeVarId) return;
2165
2234
  saveCurrentVariationHtml();
2235
+ commitStateChangesForActiveVariation();
2166
2236
  clearPendingGranularChangesets();
2167
2237
  activeVarId = varId;
2238
+ loadStateChangesForActiveVariation();
2168
2239
  writePersistedActiveVariationId(varId);
2169
2240
  renderVariationTabs();
2170
2241
  deselectElement();
@@ -2200,6 +2271,7 @@ function switchVariation(varId) {
2200
2271
  }
2201
2272
  } catch(_) {}
2202
2273
  if (currentMainTab === 'history') renderHistoryTab();
2274
+ if (currentMainTab === 'states') renderStatesTab();
2203
2275
  recomputeEditorDirty();
2204
2276
  }
2205
2277
 
@@ -2556,12 +2628,13 @@ function buildPersistedChainSetsForVariation(v) {
2556
2628
  var parsed = parseVariationChangesets(v);
2557
2629
  var base = filterGranularChangesetEntries(parsed);
2558
2630
  var sessionExtra = sessionStructuralChainRowsByVarId[v._id] || [];
2559
- if (v._id !== activeVarId) {
2560
- return mergeGranularChainSets(base, sessionExtra);
2561
- }
2631
+ var sourceStateChanges =
2632
+ v._id === activeVarId
2633
+ ? stateChanges
2634
+ : (stateChangesByVarId[v._id] || []);
2562
2635
  var overlay = [];
2563
- for (var si = 0; si < stateChanges.length; si++) {
2564
- var row = stateChangeToChainSet(stateChanges[si]);
2636
+ for (var si = 0; si < sourceStateChanges.length; si++) {
2637
+ var row = stateChangeToChainSet(sourceStateChanges[si]);
2565
2638
  if (row) overlay.push(row);
2566
2639
  }
2567
2640
  return mergeGranularChainSets(mergeGranularChainSets(base, sessionExtra), overlay);
@@ -2685,24 +2758,31 @@ function selectElement(el) {
2685
2758
  }
2686
2759
  }
2687
2760
 
2688
- function deselectElement() {
2689
- setDragHandleActive(false);
2690
- beginSuppressIframeMutationDirty();
2761
+ function deselectElement(options) {
2762
+ if (isDeselectingSelection) return;
2763
+ isDeselectingSelection = true;
2764
+ var skipToolbarUpdate = !!(options && options.skipToolbarUpdate);
2691
2765
  try {
2692
- if (selectedEl) { try { selectedEl.classList.remove('vve-selected'); } catch(_) {} selectedEl = null; }
2693
- selectedElFingerprint = '';
2694
- selectedElRecoverMisses = 0;
2766
+ setDragHandleActive(false);
2767
+ beginSuppressIframeMutationDirty();
2768
+ try {
2769
+ if (selectedEl) { try { selectedEl.classList.remove('vve-selected'); } catch(_) {} selectedEl = null; }
2770
+ selectedElFingerprint = '';
2771
+ selectedElRecoverMisses = 0;
2772
+ } finally {
2773
+ endSuppressIframeMutationDirty();
2774
+ }
2775
+ document.getElementById('no-sel').style.display = '';
2776
+ document.getElementById('el-info').style.display = 'none';
2777
+ document.getElementById('rp-accordion').style.display = 'none';
2778
+ document.getElementById('bc-path').textContent = 'No element selected';
2779
+ document.getElementById('bc-path').style.color = 'var(--text-3)';
2780
+ switchMainTab('design');
2781
+ if (!skipToolbarUpdate) updateSelectionToolbar();
2782
+ syncDomTreeSelection();
2695
2783
  } finally {
2696
- endSuppressIframeMutationDirty();
2784
+ isDeselectingSelection = false;
2697
2785
  }
2698
- document.getElementById('no-sel').style.display = '';
2699
- document.getElementById('el-info').style.display = 'none';
2700
- document.getElementById('rp-accordion').style.display = 'none';
2701
- document.getElementById('bc-path').textContent = 'No element selected';
2702
- document.getElementById('bc-path').style.color = 'var(--text-3)';
2703
- switchMainTab('design');
2704
- updateSelectionToolbar();
2705
- syncDomTreeSelection();
2706
2786
  }
2707
2787
 
2708
2788
  // \u2500\u2500 Iframe selection chrome, floater toolbar, DOM tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
@@ -3959,6 +4039,7 @@ document.getElementById('btn-close').addEventListener('click', handleClose);
3959
4039
 
3960
4040
  function handleSave() {
3961
4041
  saveCurrentVariationHtml();
4042
+ commitStateChangesForActiveVariation();
3962
4043
  var updatedVariations = variations.map(function(v) {
3963
4044
  var prevParsed = parseVariationChangesets(v);
3964
4045
  var granularPrev = filterGranularChangesetEntries(prevParsed);
@@ -3979,6 +4060,7 @@ function handleSave() {
3979
4060
  variations = updatedVariations;
3980
4061
  varHtmlCache = {};
3981
4062
  sessionStructuralChainRowsByVarId = {};
4063
+ stateChangesByVarId = {};
3982
4064
  stateChanges = [];
3983
4065
  if (currentMainTab === 'states') renderStatesTab();
3984
4066
  captureBaselineFromVariations(variations);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@accelerated-agency/visual-editor",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "private": false,
5
5
  "description": "Conversion visual editor as a reusable React package",
6
6
  "type": "module",