Better synchronize lines numbers and textarea

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2025-07-24 06:21:34 +02:00
committed by Adam Warner
parent c35022924c
commit c2ad23daf7
3 changed files with 63 additions and 11 deletions

View File

@@ -255,8 +255,8 @@ function parseStaticDHCPLine(line) {
// Split the line by commas and trim whitespace
const parts = line.split(",").map(s => s.trim());
// If there are more than 3 parts, it's considered advanced
if (parts.length > 3) return "advanced";
// If there are more than 3 parts or less than 2, it's considered advanced
if (parts.length > 3 || parts.length < 2) return "advanced";
// Check if first part is a valid MAC address
const haveMAC = parts.length > 0 && utils.validateMAC(parts[0]);
@@ -449,11 +449,31 @@ $(document).on("click", ".copy-to-static", function () {
document.addEventListener("DOMContentLoaded", function () {
const textarea = document.getElementById("dhcp-hosts");
const linesElem = document.getElementById("dhcp-hosts-lines");
function updateLineNumbers() {
let lastLineCount = 0;
function updateLineNumbers(force) {
if (!textarea || !linesElem) return;
const lines = textarea.value.split("\n").length || 1;
linesElem.innerHTML = Array.from({ length: lines }, function (_, i) {
return i + 1;
}).join("<br>");
if (!force && lines === lastLineCount) return;
lastLineCount = lines;
let html = "";
for (let i = 1; i <= lines; i++) html += i + "<br>";
linesElem.innerHTML = html;
// Apply the same styles to the lines element as the textarea
for (const property of [
"fontFamily",
"fontSize",
"fontWeight",
"letterSpacing",
"lineHeight",
"padding",
"height",
]) {
linesElem.style[property] = globalThis.getComputedStyle(textarea)[property];
}
// Match height and scroll
linesElem.style.height = textarea.offsetHeight > 0 ? textarea.offsetHeight + "px" : "auto";
}
function syncScroll() {
@@ -461,9 +481,15 @@ document.addEventListener("DOMContentLoaded", function () {
}
if (textarea && linesElem) {
textarea.addEventListener("input", updateLineNumbers);
textarea.addEventListener("input", function () {
updateLineNumbers(false);
});
textarea.addEventListener("scroll", syncScroll);
updateLineNumbers();
window.addEventListener("resize", function () {
updateLineNumbers(true);
});
updateLineNumbers(true);
syncScroll();
}
});

View File

@@ -193,9 +193,9 @@ mg.include('scripts/lua/settings_header.lp','r')
<div class="row">
<div class="col-xs-12 col-md-6">
<p>Specify per host parameters for the DHCP server. This allows a machine with a particular hardware address to be always allocated the same hostname, IP address and lease time. A hostname specified like this overrides any supplied by the DHCP client on the machine. It is also allowable to omit the hardware address and include the hostname, in which case the IP address and lease times will apply to any machine claiming that name.</p>
<div class="dhcp-hosts-wrapper mb-4" style="position:relative; display:flex;">
<div id="dhcp-hosts-lines" aria-hidden="true" style="user-select:none; text-align:right; color:#aaa; border-right:1px solid #ddd; padding:8px 4px 8px 0; font-family:monospace; font-size:13px; min-width:2em;"></div>
<textarea class="form-control field-sizing-content" id="dhcp-hosts" data-key="dhcp.hosts" style="resize: vertical; font-family:monospace; font-size:13px; width:100%;"></textarea>
<div class="dhcp-hosts-wrapper mb-4">
<div id="dhcp-hosts-lines" class="line-numbers" aria-hidden="true"></div>
<textarea class="form-control no-wrap" id="dhcp-hosts" data-key="dhcp.hosts" wrap="off"></textarea>
</div>
<p>Each entry should be on a separate line, and should be of the form:</p>
<pre>[&lt;hwaddr&gt;][,id:&lt;client_id&gt;|*][,set:&lt;tag&gt;][,tag:&lt;tag&gt;][,&lt;ipaddr&gt;][,&lt;hostname&gt;][,&lt;lease_time&gt;][,ignore]</pre>

View File

@@ -1583,6 +1583,32 @@ textarea.field-sizing-content {
field-sizing: content;
}
textarea.no-wrap {
white-space: pre;
overflow-x: auto;
overflow-y: auto;
resize: none;
}
div.line-numbers {
user-select: none;
text-align: right;
color: #aaa;
border-right: 1px solid #ddd;
padding: 8px 4px 8px 0;
font-family: monospace;
font-size: 13px;
min-width: 2em;
overflow-x: hidden;
overflow-y: hidden;
}
div.dhcp-hosts-wrapper {
position: relative;
display: flex;
gap: 0.5em;
}
/* Used in interfaces page */
.list-group-item {
background: transparent;