vite-plugin-visual-selector 0.1.3 → 0.1.4

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/runtime.js CHANGED
@@ -141,169 +141,6 @@ function handleInlineEdit(state, data, updatePositions) {
141
141
  }
142
142
  }
143
143
 
144
- // src/runtime/layer-navigation.ts
145
- function buildLayerTree(element) {
146
- const tree = [];
147
- const ancestors = [];
148
- let parent = element.parentElement;
149
- while (parent && parent !== document.body) {
150
- if (hasSourceLocation(parent)) {
151
- ancestors.push(parent);
152
- }
153
- parent = parent.parentElement;
154
- }
155
- ancestors.reverse();
156
- ancestors.forEach((el) => {
157
- tree.push({ element: el, tagName: el.tagName.toLowerCase(), depth: 0 });
158
- });
159
- tree.push({ element, tagName: element.tagName.toLowerCase(), depth: 0 });
160
- for (let i = 0; i < element.children.length; i++) {
161
- const child = element.children[i];
162
- if (hasSourceLocation(child)) {
163
- tree.push({ element: child, tagName: child.tagName.toLowerCase(), depth: 0 });
164
- }
165
- }
166
- return tree;
167
- }
168
- function removeLayerDropdown(state) {
169
- if (state.layerDropdown) {
170
- const parentOverlay = state.layerDropdown.parentElement;
171
- if (parentOverlay) {
172
- const arrowEl = parentOverlay.querySelector("[data-tag-arrow]");
173
- if (arrowEl) arrowEl.textContent = "\u2304";
174
- }
175
- state.layerDropdown.remove();
176
- state.layerDropdown = null;
177
- document.removeEventListener("keydown", handleLayerKeyboard);
178
- }
179
- }
180
- function toggleLayerDropdown(state, element, anchor, onSelectElement) {
181
- if (state.layerDropdown) {
182
- removeLayerDropdown(state);
183
- return;
184
- }
185
- const layers = buildLayerTree(element);
186
- renderLayerDropdown(state, anchor, layers, element, onSelectElement);
187
- }
188
- function renderLayerDropdown(state, anchor, layers, currentElement, onSelectElement) {
189
- const dropdown = document.createElement("div");
190
- dropdown.setAttribute("data-layer-dropdown", "true");
191
- dropdown.setAttribute(AGENT_ATTR, "");
192
- Object.assign(dropdown.style, {
193
- position: "absolute",
194
- backgroundColor: "#ffffff",
195
- border: "1px solid #e2e8f0",
196
- borderRadius: "6px",
197
- boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
198
- fontSize: "12px",
199
- zIndex: "99999",
200
- pointerEvents: "auto",
201
- padding: "4px 0",
202
- minWidth: "120px",
203
- maxHeight: "320px",
204
- overflowY: "auto"
205
- });
206
- let focusedIndex = -1;
207
- const items = [];
208
- layers.forEach((layer, idx) => {
209
- const item = document.createElement("div");
210
- item.setAttribute(AGENT_ATTR, "");
211
- item.textContent = layer.tagName;
212
- item.style.padding = "6px 16px";
213
- item.style.cursor = "pointer";
214
- item.style.whiteSpace = "nowrap";
215
- if (layer.element === currentElement) {
216
- item.style.color = "#000000";
217
- item.style.backgroundColor = "rgba(255, 204, 0, 0.2)";
218
- item.style.fontWeight = "600";
219
- focusedIndex = idx;
220
- } else {
221
- item.style.color = "#64748b";
222
- }
223
- item.addEventListener("click", (e) => {
224
- e.stopPropagation();
225
- removeLayerDropdown(state);
226
- onSelectElement(layer.element);
227
- });
228
- item.addEventListener("mouseenter", () => {
229
- if (layer.element !== currentElement) {
230
- item.style.backgroundColor = "#f1f5f9";
231
- item.style.color = "#334155";
232
- }
233
- });
234
- item.addEventListener("mouseleave", () => {
235
- if (layer.element !== currentElement) {
236
- item.style.backgroundColor = "transparent";
237
- item.style.color = "#64748b";
238
- }
239
- });
240
- items.push(item);
241
- dropdown.appendChild(item);
242
- });
243
- document.body.appendChild(dropdown);
244
- const anchorRect = anchor.getBoundingClientRect();
245
- dropdown.style.top = `${anchorRect.bottom + window.scrollY + 2}px`;
246
- dropdown.style.left = `${anchorRect.left + window.scrollX}px`;
247
- requestAnimationFrame(() => {
248
- const ddRect = dropdown.getBoundingClientRect();
249
- if (ddRect.right > window.innerWidth - 4) {
250
- dropdown.style.left = `${window.innerWidth - ddRect.width - 4 + window.scrollX}px`;
251
- }
252
- if (ddRect.left < 4) {
253
- dropdown.style.left = `${4 + window.scrollX}px`;
254
- }
255
- if (ddRect.bottom > window.innerHeight) {
256
- dropdown.style.top = `${anchorRect.top + window.scrollY - ddRect.height - 2}px`;
257
- }
258
- });
259
- state.layerDropdown = dropdown;
260
- const handleKeydown = (e) => {
261
- if (!state.layerDropdown) return;
262
- switch (e.key) {
263
- case "ArrowDown":
264
- e.preventDefault();
265
- focusedIndex = Math.min(focusedIndex + 1, items.length - 1);
266
- highlightItem(items, focusedIndex, layers, currentElement);
267
- break;
268
- case "ArrowUp":
269
- e.preventDefault();
270
- focusedIndex = Math.max(focusedIndex - 1, 0);
271
- highlightItem(items, focusedIndex, layers, currentElement);
272
- break;
273
- case "Enter":
274
- e.preventDefault();
275
- if (focusedIndex >= 0 && focusedIndex < layers.length) {
276
- removeLayerDropdown(state);
277
- onSelectElement(layers[focusedIndex].element);
278
- }
279
- break;
280
- case "Escape":
281
- e.preventDefault();
282
- removeLayerDropdown(state);
283
- break;
284
- }
285
- };
286
- handleLayerKeyboard.current = handleKeydown;
287
- document.addEventListener("keydown", handleLayerKeyboard);
288
- }
289
- function handleLayerKeyboard(e) {
290
- const current = handleLayerKeyboard.current;
291
- if (current) current(e);
292
- }
293
- function highlightItem(items, index, layers, currentElement) {
294
- items.forEach((item, i) => {
295
- if (layers[i].element === currentElement) {
296
- item.style.color = "#000000";
297
- item.style.backgroundColor = i === index ? "rgba(255, 204, 0, 0.35)" : "rgba(255, 204, 0, 0.2)";
298
- item.style.fontWeight = "600";
299
- } else {
300
- item.style.backgroundColor = i === index ? "#f1f5f9" : "transparent";
301
- item.style.color = i === index ? "#334155" : "#64748b";
302
- item.style.fontWeight = "normal";
303
- }
304
- });
305
- }
306
-
307
144
  // src/runtime/messages.ts
308
145
  function reportElementSelected(state, element) {
309
146
  const el = element;
@@ -362,6 +199,18 @@ function reportPositionUpdate(state) {
362
199
  } catch {
363
200
  }
364
201
  }
202
+ function reportDropdownState(state, isOpen) {
203
+ try {
204
+ window.parent.postMessage(
205
+ {
206
+ type: "dropdown-state",
207
+ data: { isOpen }
208
+ },
209
+ state.targetOrigin
210
+ );
211
+ } catch {
212
+ }
213
+ }
365
214
  function handleMessage(state, e, callbacks) {
366
215
  if (state.targetOrigin !== "*" && e.origin !== state.targetOrigin) return;
367
216
  const msg = e.data;
@@ -395,10 +244,7 @@ function handleMessage(state, e, callbacks) {
395
244
  break;
396
245
  case "unselect-element":
397
246
  if (state.editingElement) callbacks.stopInlineEditing();
398
- state.selectionOverlays.forEach((o) => o.remove());
399
- state.selectionOverlays = [];
400
- state.selectedId = null;
401
- state.selectedElement = null;
247
+ callbacks.clearSelectionState();
402
248
  break;
403
249
  case "update-theme-variables":
404
250
  if (msg.data?.variables) {
@@ -488,6 +334,27 @@ function createOverlay(opts) {
488
334
  }
489
335
  return overlay;
490
336
  }
337
+ function setTagArrowExpanded(arrow, expanded) {
338
+ arrow.style.transform = expanded ? "rotate(0deg)" : "rotate(180deg)";
339
+ }
340
+ function createTagArrowSvg() {
341
+ const svgNs = "http://www.w3.org/2000/svg";
342
+ const svg = document.createElementNS(svgNs, "svg");
343
+ svg.setAttribute("xmlns", svgNs);
344
+ svg.setAttribute("width", "12");
345
+ svg.setAttribute("height", "12");
346
+ svg.setAttribute("viewBox", "0 0 12 12");
347
+ svg.setAttribute("fill", "none");
348
+ svg.style.display = "block";
349
+ const path = document.createElementNS(svgNs, "path");
350
+ path.setAttribute("stroke", "rgba(51, 51, 51, 1)");
351
+ path.setAttribute("stroke-width", "0.8325");
352
+ path.setAttribute("stroke-linejoin", "round");
353
+ path.setAttribute("stroke-linecap", "round");
354
+ path.setAttribute("d", "M3.24994 7.5L6.24994 4.5L9.24994 7.5");
355
+ svg.appendChild(path);
356
+ return svg;
357
+ }
491
358
  function positionOverlay(overlay, target, tagMode = "none", callbacks) {
492
359
  const rect = target.getBoundingClientRect();
493
360
  overlay.style.top = `${rect.top + window.scrollY}px`;
@@ -510,8 +377,10 @@ function positionOverlay(overlay, target, tagMode = "none", callbacks) {
510
377
  textAlign: "center",
511
378
  display: "flex",
512
379
  alignItems: "center",
380
+ justifyContent: "center",
513
381
  gap: "3px",
514
- lineHeight: "1.4"
382
+ lineHeight: "1.4",
383
+ whiteSpace: "nowrap"
515
384
  });
516
385
  if (tagMode === "selected") {
517
386
  tag.style.backgroundColor = "#FC0";
@@ -520,12 +389,23 @@ function positionOverlay(overlay, target, tagMode = "none", callbacks) {
520
389
  tag.style.pointerEvents = "auto";
521
390
  const textSpan = document.createElement("span");
522
391
  textSpan.textContent = target.tagName.toLowerCase();
392
+ textSpan.style.display = "inline-flex";
393
+ textSpan.style.alignItems = "center";
394
+ textSpan.style.lineHeight = "1";
523
395
  tag.appendChild(textSpan);
524
396
  const arrow = document.createElement("span");
525
397
  arrow.setAttribute("data-tag-arrow", "");
526
- arrow.textContent = "\u2304";
527
- arrow.style.fontSize = "10px";
398
+ arrow.textContent = "";
399
+ arrow.style.display = "inline-flex";
400
+ arrow.style.alignItems = "center";
401
+ arrow.style.justifyContent = "center";
402
+ arrow.style.width = "12px";
403
+ arrow.style.height = "12px";
404
+ arrow.style.flex = "0 0 auto";
405
+ arrow.style.transformOrigin = "center";
528
406
  arrow.style.lineHeight = "1";
407
+ arrow.appendChild(createTagArrowSvg());
408
+ setTagArrowExpanded(arrow, false);
529
409
  tag.appendChild(arrow);
530
410
  if (callbacks?.onTagClick) {
531
411
  const onTagClick = callbacks.onTagClick;
@@ -648,6 +528,171 @@ function unfreezeAnimations() {
648
528
  if (overflowStyle) overflowStyle.remove();
649
529
  }
650
530
 
531
+ // src/runtime/layer-navigation.ts
532
+ function buildLayerTree(element) {
533
+ const tree = [];
534
+ const ancestors = [];
535
+ let parent = element.parentElement;
536
+ while (parent && parent !== document.body) {
537
+ if (hasSourceLocation(parent)) {
538
+ ancestors.push(parent);
539
+ }
540
+ parent = parent.parentElement;
541
+ }
542
+ ancestors.reverse();
543
+ ancestors.forEach((el) => {
544
+ tree.push({ element: el, tagName: el.tagName.toLowerCase(), depth: 0 });
545
+ });
546
+ tree.push({ element, tagName: element.tagName.toLowerCase(), depth: 0 });
547
+ for (let i = 0; i < element.children.length; i++) {
548
+ const child = element.children[i];
549
+ if (hasSourceLocation(child)) {
550
+ tree.push({ element: child, tagName: child.tagName.toLowerCase(), depth: 0 });
551
+ }
552
+ }
553
+ return tree;
554
+ }
555
+ function removeLayerDropdown(state) {
556
+ if (state.layerDropdown) {
557
+ const parentOverlay = state.layerDropdown.parentElement;
558
+ if (parentOverlay) {
559
+ const arrowEl = parentOverlay.querySelector("[data-tag-arrow]");
560
+ if (arrowEl) setTagArrowExpanded(arrowEl, false);
561
+ }
562
+ state.layerDropdown.remove();
563
+ state.layerDropdown = null;
564
+ reportDropdownState(state, false);
565
+ document.removeEventListener("keydown", handleLayerKeyboard);
566
+ }
567
+ }
568
+ function toggleLayerDropdown(state, element, anchor, onSelectElement) {
569
+ if (state.layerDropdown) {
570
+ removeLayerDropdown(state);
571
+ return;
572
+ }
573
+ const layers = buildLayerTree(element);
574
+ renderLayerDropdown(state, anchor, layers, element, onSelectElement);
575
+ }
576
+ function renderLayerDropdown(state, anchor, layers, currentElement, onSelectElement) {
577
+ const dropdown = document.createElement("div");
578
+ dropdown.setAttribute("data-layer-dropdown", "true");
579
+ dropdown.setAttribute(AGENT_ATTR, "");
580
+ Object.assign(dropdown.style, {
581
+ position: "absolute",
582
+ backgroundColor: "#ffffff",
583
+ border: "1px solid #e2e8f0",
584
+ borderRadius: "6px",
585
+ boxShadow: "0 4px 12px rgba(0,0,0,0.15)",
586
+ fontSize: "12px",
587
+ zIndex: "2147483647",
588
+ pointerEvents: "auto",
589
+ padding: "4px 0",
590
+ minWidth: "120px",
591
+ maxHeight: "320px",
592
+ overflowY: "auto"
593
+ });
594
+ let focusedIndex = -1;
595
+ const items = [];
596
+ layers.forEach((layer, idx) => {
597
+ const item = document.createElement("div");
598
+ item.setAttribute(AGENT_ATTR, "");
599
+ item.textContent = layer.tagName;
600
+ item.style.padding = "6px 16px";
601
+ item.style.cursor = "pointer";
602
+ item.style.whiteSpace = "nowrap";
603
+ if (layer.element === currentElement) {
604
+ item.style.color = "#000000";
605
+ item.style.backgroundColor = "rgba(255, 204, 0, 0.2)";
606
+ item.style.fontWeight = "600";
607
+ focusedIndex = idx;
608
+ } else {
609
+ item.style.color = "#64748b";
610
+ }
611
+ item.addEventListener("click", (e) => {
612
+ e.stopPropagation();
613
+ removeLayerDropdown(state);
614
+ onSelectElement(layer.element);
615
+ });
616
+ item.addEventListener("mouseenter", () => {
617
+ if (layer.element !== currentElement) {
618
+ item.style.backgroundColor = "#f1f5f9";
619
+ item.style.color = "#334155";
620
+ }
621
+ });
622
+ item.addEventListener("mouseleave", () => {
623
+ if (layer.element !== currentElement) {
624
+ item.style.backgroundColor = "transparent";
625
+ item.style.color = "#64748b";
626
+ }
627
+ });
628
+ items.push(item);
629
+ dropdown.appendChild(item);
630
+ });
631
+ document.body.appendChild(dropdown);
632
+ const anchorRect = anchor.getBoundingClientRect();
633
+ dropdown.style.top = `${anchorRect.bottom + window.scrollY + 2}px`;
634
+ dropdown.style.left = `${anchorRect.left + window.scrollX}px`;
635
+ requestAnimationFrame(() => {
636
+ const ddRect = dropdown.getBoundingClientRect();
637
+ if (ddRect.right > window.innerWidth - 4) {
638
+ dropdown.style.left = `${window.innerWidth - ddRect.width - 4 + window.scrollX}px`;
639
+ }
640
+ if (ddRect.left < 4) {
641
+ dropdown.style.left = `${4 + window.scrollX}px`;
642
+ }
643
+ if (ddRect.bottom > window.innerHeight) {
644
+ dropdown.style.top = `${anchorRect.top + window.scrollY - ddRect.height - 2}px`;
645
+ }
646
+ });
647
+ state.layerDropdown = dropdown;
648
+ reportDropdownState(state, true);
649
+ const handleKeydown = (e) => {
650
+ if (!state.layerDropdown) return;
651
+ switch (e.key) {
652
+ case "ArrowDown":
653
+ e.preventDefault();
654
+ focusedIndex = Math.min(focusedIndex + 1, items.length - 1);
655
+ highlightItem(items, focusedIndex, layers, currentElement);
656
+ break;
657
+ case "ArrowUp":
658
+ e.preventDefault();
659
+ focusedIndex = Math.max(focusedIndex - 1, 0);
660
+ highlightItem(items, focusedIndex, layers, currentElement);
661
+ break;
662
+ case "Enter":
663
+ e.preventDefault();
664
+ if (focusedIndex >= 0 && focusedIndex < layers.length) {
665
+ removeLayerDropdown(state);
666
+ onSelectElement(layers[focusedIndex].element);
667
+ }
668
+ break;
669
+ case "Escape":
670
+ e.preventDefault();
671
+ removeLayerDropdown(state);
672
+ break;
673
+ }
674
+ };
675
+ handleLayerKeyboard.current = handleKeydown;
676
+ document.addEventListener("keydown", handleLayerKeyboard);
677
+ }
678
+ function handleLayerKeyboard(e) {
679
+ const current = handleLayerKeyboard.current;
680
+ if (current) current(e);
681
+ }
682
+ function highlightItem(items, index, layers, currentElement) {
683
+ items.forEach((item, i) => {
684
+ if (layers[i].element === currentElement) {
685
+ item.style.color = "#000000";
686
+ item.style.backgroundColor = i === index ? "rgba(255, 204, 0, 0.35)" : "rgba(255, 204, 0, 0.2)";
687
+ item.style.fontWeight = "600";
688
+ } else {
689
+ item.style.backgroundColor = i === index ? "#f1f5f9" : "transparent";
690
+ item.style.color = i === index ? "#334155" : "#64748b";
691
+ item.style.fontWeight = "normal";
692
+ }
693
+ });
694
+ }
695
+
651
696
  // src/runtime/state.ts
652
697
  function createAgentState(options = {}) {
653
698
  return {
@@ -661,13 +706,36 @@ function createAgentState(options = {}) {
661
706
  layerDropdown: null,
662
707
  mutationObserver: null,
663
708
  attributeName: options.attributeName ?? DEFAULT_ATTRIBUTE_NAME,
664
- targetOrigin: options.targetOrigin ?? "*"
709
+ targetOrigin: options.targetOrigin ?? "*",
710
+ runtimeIdCounter: 0
665
711
  };
666
712
  }
667
713
 
668
714
  // src/runtime/index.ts
669
715
  function setupVisualEditAgent(options = {}) {
670
716
  const state = createAgentState(options);
717
+ const trackedSelector = `[${state.attributeName}], [data-visual-selector-id]`;
718
+ function shouldAssignRuntimeId(element) {
719
+ return !element.closest(`[${AGENT_ATTR}]`) && !element.hasAttribute(state.attributeName) && !element.hasAttribute("data-visual-selector-id");
720
+ }
721
+ function assignRuntimeId(element) {
722
+ if (!shouldAssignRuntimeId(element)) return;
723
+ state.runtimeIdCounter += 1;
724
+ element.setAttribute("data-visual-selector-id", `runtime:${state.runtimeIdCounter}`);
725
+ }
726
+ function trackElementSubtree(root) {
727
+ assignRuntimeId(root);
728
+ root.querySelectorAll("*").forEach((element) => assignRuntimeId(element));
729
+ }
730
+ function trackCurrentDom() {
731
+ if (!document.body) return;
732
+ trackElementSubtree(document.body);
733
+ }
734
+ function ensureElementTracked(element) {
735
+ if (!element.closest(`[${AGENT_ATTR}]`)) {
736
+ assignRuntimeId(element);
737
+ }
738
+ }
671
739
  function updateAllOverlayPositions() {
672
740
  if (state.selectedId && state.selectedElement?.isConnected) {
673
741
  const siblings = findAllElementsById(state.selectedId);
@@ -684,7 +752,7 @@ function setupVisualEditAgent(options = {}) {
684
752
  function onTagClick(target, tag) {
685
753
  const arrowEl = tag.querySelector("[data-tag-arrow]");
686
754
  if (arrowEl) {
687
- arrowEl.textContent = state.layerDropdown ? "\u2304" : "\u2303";
755
+ setTagArrowExpanded(arrowEl, !state.layerDropdown);
688
756
  }
689
757
  toggleLayerDropdown(state, target, tag, selectElement);
690
758
  }
@@ -695,7 +763,10 @@ function setupVisualEditAgent(options = {}) {
695
763
  if (freezeStyle) freezeStyle.disabled = false;
696
764
  if (!element) return null;
697
765
  if (element.closest(`[${AGENT_ATTR}]`)) return null;
698
- return element.closest(`[${state.attributeName}], [data-visual-selector-id]`) ?? null;
766
+ const trackedElement = element.closest(trackedSelector);
767
+ if (trackedElement) return trackedElement;
768
+ ensureElementTracked(element);
769
+ return element.hasAttribute("data-visual-selector-id") ? element : null;
699
770
  }
700
771
  function findHoverTarget(x, y, excludeId) {
701
772
  const element = findElementAtPoint(x, y);
@@ -743,6 +814,7 @@ function setupVisualEditAgent(options = {}) {
743
814
  selectElement(element);
744
815
  }
745
816
  function selectElement(element) {
817
+ ensureElementTracked(element);
746
818
  const id = getSourceId(element);
747
819
  if (!id) return;
748
820
  if (state.editingElement) {
@@ -778,6 +850,7 @@ function setupVisualEditAgent(options = {}) {
778
850
  if (enabled) {
779
851
  document.body.style.cursor = "crosshair";
780
852
  freezeAnimations();
853
+ trackCurrentDom();
781
854
  document.addEventListener("mousemove", onMouseMove);
782
855
  document.addEventListener("mouseleave", onMouseLeave);
783
856
  document.addEventListener("click", onClick, true);
@@ -804,6 +877,13 @@ function setupVisualEditAgent(options = {}) {
804
877
  function startMutationObserver() {
805
878
  if (state.mutationObserver) return;
806
879
  state.mutationObserver = new MutationObserver((mutations) => {
880
+ mutations.forEach((mutation) => {
881
+ mutation.addedNodes.forEach((node) => {
882
+ if (node instanceof Element) {
883
+ trackElementSubtree(node);
884
+ }
885
+ });
886
+ });
807
887
  const hasRelevantChange = mutations.some((m) => {
808
888
  if (m.type === "attributes" && ["style", "class", "width", "height"].includes(m.attributeName ?? "") && containsTrackedElement(m.target))
809
889
  return true;
@@ -829,8 +909,8 @@ function setupVisualEditAgent(options = {}) {
829
909
  }
830
910
  function containsTrackedElement(node) {
831
911
  if (!(node instanceof Element)) return false;
832
- if (node.hasAttribute(AGENT_ATTR)) return false;
833
- return hasSourceLocation(node) || !!node.querySelector(`[${state.attributeName}]`);
912
+ if (node.closest(`[${AGENT_ATTR}]`)) return false;
913
+ return node.hasAttribute(state.attributeName) || node.hasAttribute("data-visual-selector-id") || !!node.querySelector(trackedSelector);
834
914
  }
835
915
  function setupSandboxMountObserver() {
836
916
  if (window.self === window.top) return;
@@ -839,7 +919,9 @@ function setupVisualEditAgent(options = {}) {
839
919
  (m) => m.addedNodes.length > 0 || m.removedNodes.length > 0
840
920
  );
841
921
  if (!hasChanges) return;
842
- const hasTrackedElements = document.body.querySelectorAll("[data-source-location], [data-dynamic-content]").length > 0;
922
+ const hasTrackedElements = document.body.querySelectorAll(
923
+ `[${state.attributeName}], [data-dynamic-content], [data-visual-selector-id]`
924
+ ).length > 0;
843
925
  try {
844
926
  window.parent.postMessage(
845
927
  {
@@ -859,18 +941,24 @@ function setupVisualEditAgent(options = {}) {
859
941
  }
860
942
  }
861
943
  function selectElementById(id) {
862
- const element = document.querySelector(`[${state.attributeName}="${id}"]`);
944
+ const element = document.querySelector(
945
+ `[${state.attributeName}="${id}"], [data-visual-selector-id="${id}"]`
946
+ );
863
947
  if (element) {
864
948
  selectElement(element);
865
949
  }
866
950
  }
951
+ function clearSelectionState() {
952
+ clearAllOverlays(state, () => removeLayerDropdown(state));
953
+ }
867
954
  const onMessage = (e) => {
868
955
  handleMessage(state, e, {
869
956
  enableEditMode,
870
957
  updateAllOverlayPositions,
871
958
  stopInlineEditing: () => stopInlineEditing(state, updateAllOverlayPositions),
872
959
  handleInlineEdit: (data) => handleInlineEdit(state, data, updateAllOverlayPositions),
873
- selectElementById
960
+ selectElementById,
961
+ clearSelectionState
874
962
  });
875
963
  };
876
964
  window.addEventListener("message", onMessage);
@@ -889,7 +977,7 @@ function setupVisualEditAgent(options = {}) {
889
977
  enableEditMode,
890
978
  selectElement,
891
979
  clearSelection() {
892
- clearAllOverlays(state, () => removeLayerDropdown(state));
980
+ clearSelectionState();
893
981
  },
894
982
  getSelectedId() {
895
983
  return state.selectedId;