diff --git a/css/styles.css b/css/styles.css
index eaafb42..8adb14f 100644
--- a/css/styles.css
+++ b/css/styles.css
@@ -161,11 +161,56 @@
.xyz-content-edit {
display: none;
}
- textarea.xyz-editor {
+ /* XYZ edit textarea + highlight overlay. The backdrop sits behind a
+ transparent-background textarea and tints the lines of selected
+ atoms; both share identical metrics so the text lines up exactly. */
+ #xyz-edit-wrap {
+ position: relative;
+ margin: 10px 0;
+ }
+ #xyz-content-edit.xyz-editor,
+ #xyz-edit-backdrop {
width: 100%;
- min-height: 200px;
+ box-sizing: border-box;
+ margin: 0;
+ padding: 6px;
+ border: 1px solid #ccc;
font-family: monospace;
- margin: 10px 0;
+ font-size: 13px;
+ line-height: 1.4;
+ white-space: pre;
+ letter-spacing: normal;
+ tab-size: 4;
+ }
+ #xyz-content-edit.xyz-editor {
+ position: relative;
+ z-index: 1;
+ display: block;
+ min-height: 200px;
+ resize: vertical;
+ overflow: auto;
+ background: transparent;
+ color: #000;
+ }
+ #xyz-edit-backdrop {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 0;
+ overflow: hidden;
+ pointer-events: none;
+ border-color: transparent;
+ background: #fff;
+ color: transparent;
+ }
+ #xyz-edit-highlights {
+ min-height: 200px;
+ }
+ #xyz-edit-highlights .xyz-edit-hl {
+ background: #fff3a0;
+ border-radius: 2px;
}
.mode-buttons {
margin: 10px 0;
diff --git a/index.html b/index.html
index 0269834..98ca1b7 100644
--- a/index.html
+++ b/index.html
@@ -160,7 +160,10 @@
XYZ Editor
Click atoms in the 3D structure or the rows below to select them.
-
+
diff --git a/js/selection.js b/js/selection.js
index 7ae084a..f654210 100644
--- a/js/selection.js
+++ b/js/selection.js
@@ -10,6 +10,16 @@ function updateSelectionUI() {
const n = selectedAtoms.size;
countEl.textContent = n > 0 ? `${n} selected` : '';
}
+ refreshEditHighlightsIfVisible();
+}
+
+// When the XYZ editor's text edit mode is open, keep its highlight overlay in
+// sync with the current selection (e.g. atoms picked in the 3D structure).
+function refreshEditHighlightsIfVisible() {
+ const wrap = document.getElementById('xyz-edit-wrap');
+ if (wrap && wrap.style.display !== 'none' && typeof renderXYZEditHighlights === 'function') {
+ renderXYZEditHighlights();
+ }
}
// Turn the 3D halo on/off for a single atom (atomIndex is 0-based).
diff --git a/js/xyz-editor.js b/js/xyz-editor.js
index 1d1d1bf..f6f7dd4 100644
--- a/js/xyz-editor.js
+++ b/js/xyz-editor.js
@@ -106,7 +106,9 @@ function showXYZEditor() {
// Update textarea content
const editArea = document.getElementById('xyz-content-edit');
editArea.value = lastXYZData;
- editArea.style.display = 'none'; // Ensure we start in selection mode
+ initXYZEditHighlights();
+ renderXYZEditHighlights();
+ document.getElementById('xyz-edit-wrap').style.display = 'none'; // Ensure we start in selection mode
xyzContent.style.display = 'block';
document.getElementById('toggle-edit-mode').textContent = 'Switch to Edit Mode';
@@ -126,16 +128,16 @@ function showXYZEditor() {
function toggleEditMode() {
const selectionView = document.getElementById('xyz-content');
- const editView = document.getElementById('xyz-content-edit');
+ const editView = document.getElementById('xyz-edit-wrap');
const editButton = document.getElementById('toggle-edit-mode');
-
+
if (selectionView.style.display !== 'none') {
- // Switch to edit mode
+ // Switch to edit mode. Keep the current selection so the chosen atoms
+ // stay highlighted in the textarea, making them easy to edit.
selectionView.style.display = 'none';
editView.style.display = 'block';
editButton.textContent = 'Switch to Selection Mode';
- // Clear any existing selections (keeps state Set, rows and halos in sync)
- clearAtomSelection();
+ renderXYZEditHighlights();
} else {
// Switch to selection mode
selectionView.style.display = 'block';
@@ -146,6 +148,51 @@ function toggleEditMode() {
}
}
+// Escape text so user-entered atom names/coordinates can't inject markup into
+// the highlight overlay.
+function escapeHtmlForHighlight(s) {
+ return s.replace(/&/g, '&').replace(//g, '>');
+}
+
+// Re-draw the edit-mode highlight overlay: tint the textarea lines that belong
+// to currently selected atoms. Atom i (0-based) lives on text line i + 2
+// (line 0 = atom count, line 1 = comment).
+function renderXYZEditHighlights() {
+ const textarea = document.getElementById('xyz-content-edit');
+ const backdrop = document.getElementById('xyz-edit-backdrop');
+ const highlights = document.getElementById('xyz-edit-highlights');
+ if (!textarea || !backdrop || !highlights) return;
+
+ const selectedLines = new Set(Array.from(selectedAtoms).map(i => i + 2));
+ const lines = textarea.value.split('\n');
+ highlights.innerHTML = lines.map((line, idx) => {
+ const safe = escapeHtmlForHighlight(line);
+ return selectedLines.has(idx) ? `${safe}` : safe;
+ }).join('\n');
+
+ // Keep the overlay scroll-aligned with the textarea.
+ backdrop.scrollTop = textarea.scrollTop;
+ backdrop.scrollLeft = textarea.scrollLeft;
+}
+
+// Attach the textarea listeners that keep the highlight overlay in sync. Runs
+// once; guarded by a data flag so repeated showXYZEditor() calls don't stack
+// listeners.
+function initXYZEditHighlights() {
+ const textarea = document.getElementById('xyz-content-edit');
+ if (!textarea || textarea.dataset.hlInit) return;
+ textarea.dataset.hlInit = '1';
+
+ const backdrop = document.getElementById('xyz-edit-backdrop');
+ textarea.addEventListener('input', renderXYZEditHighlights);
+ textarea.addEventListener('scroll', function() {
+ if (backdrop) {
+ backdrop.scrollTop = textarea.scrollTop;
+ backdrop.scrollLeft = textarea.scrollLeft;
+ }
+ });
+}
+
function updateStructure() {
const editView = document.getElementById('xyz-content-edit');
try {