get-span-indices / standalone_index.html
wadood's picture
updating index.html to reflect react code
4dd77e2
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Text Selection</title>
<style>
#settings {
margin-bottom: 15px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 6px;
background: #fafafa;
width: 90%;
}
#inputBox {
width: 90%;
min-height: 150px;
border: 1px solid #ccc;
padding: 10px;
white-space: pre-wrap;
overflow-wrap: break-word;
}
#results {
margin-top: 15px;
font-family: monospace;
background: #f4f4f4;
padding: 10px;
border-radius: 6px;
border: 1px solid #ddd;
white-space: pre-wrap;
user-select: text;
}
label {
margin-right: 10px;
}
</style>
</head>
<body>
<h3>Highlight text to get indices (accurate whitespace & line break)</h3>
<!-- Settings Panel -->
<div id="settings">
<strong>Settings (rename keys):</strong><br><br>
<label>Span Text Key: <input id="keySpan" type="text" value="span_text"></label>
<label>Start Key: <input id="keyStart" type="text" value="start"></label>
<label>End Key: <input id="keyEnd" type="text" value="end"></label>
</div>
<!-- Editable div -->
<div id="inputBox" contenteditable="true"></div>
<button onclick="getSelectionIndices()">Get Span JSON</button>
<pre id="results"></pre>
<script>
let spans = [];
let lastText = "";
// Convert HTML content to normalized text where line breaks are \n
function getNormalizedText(container) {
let html = container.innerHTML;
// Replace empty divs with \n
html = html.replace(/<div><br><\/div>/gi, '\n');
// Replace remaining divs with \n at start, remove closing divs
html = html.replace(/<div>/gi, '\n').replace(/<\/div>/gi, '');
// Replace <br> with \n
html = html.replace(/<br\s*\/?>/gi, '\n');
// Replace &nbsp; with space
html = html.replace(/&nbsp;/g, ' ');
// Strip other tags just in case
html = html.replace(/<[^>]+>/g, '');
return html;
}
function getSelectionIndices() {
const container = document.getElementById("inputBox");
const selection = window.getSelection();
if (!selection || !selection.rangeCount) return;
const range = selection.getRangeAt(0);
if (!container.contains(range.startContainer) || !container.contains(range.endContainer)) return;
const selectedText = selection.toString();
if (!selectedText) return;
// Normalize the container text
const normalizedText = getNormalizedText(container);
// Get text before selection
const preRange = range.cloneRange();
preRange.selectNodeContents(container);
preRange.setEnd(range.startContainer, range.startOffset);
const tempDiv = document.createElement("div");
tempDiv.appendChild(preRange.cloneContents());
let preText = getNormalizedText(tempDiv);
const start = preText.length;
const end = start + selectedText.length;
const spanInfo = { span_text: selectedText, start, end };
// Prepend and keep last 5 spans
spans.unshift(spanInfo);
spans = spans.slice(0, 5);
renderSpans();
}
function renderSpans() {
const keySpan = document.getElementById("keySpan").value || "span_text";
const keyStart = document.getElementById("keyStart").value || "start";
const keyEnd = document.getElementById("keyEnd").value || "end";
const renamedSpans = spans.map(s => ({
[keySpan]: s.span_text,
[keyStart]: s.start,
[keyEnd]: s.end
}));
document.getElementById("results").innerText = renamedSpans.length
? JSON.stringify(renamedSpans, null, 2)
: "";
}
// Reset spans if input text changes
document.getElementById("inputBox").addEventListener("input", function() {
const currentText = getNormalizedText(this);
if (currentText !== lastText) {
spans = [];
document.getElementById("results").innerText = "";
lastText = currentText;
}
});
// Re-render spans if key names change
document.getElementById("keySpan").addEventListener("input", renderSpans);
document.getElementById("keyStart").addEventListener("input", renderSpans);
document.getElementById("keyEnd").addEventListener("input", renderSpans);
</script>
</body>
</html>