From eb779a806e5866efab71481fa2462c58e165b057 Mon Sep 17 00:00:00 2001 From: Benedikt Seeger <benedikt.seeger@ptb.de> Date: Wed, 26 Feb 2025 12:53:21 +0100 Subject: [PATCH] fixed input sugestion state maschine --- dsiUnits-js/src/dsiUnitInput.js | 36 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/dsiUnits-js/src/dsiUnitInput.js b/dsiUnits-js/src/dsiUnitInput.js index 2e6a116..540daf9 100644 --- a/dsiUnits-js/src/dsiUnitInput.js +++ b/dsiUnits-js/src/dsiUnitInput.js @@ -19,7 +19,7 @@ export class DSIUnitInput extends HTMLElement { this.liveUpdate = true; this.allowedTokens = defaultAllowedTokens; this.selectedSuggestionIndex = -1; - this.lastAcceptedToken = ""; // NEW: track last accepted token + this.lastAcceptedToken = ""; // Tracks the last accepted token // Create elements. this.input = document.createElement("input"); @@ -32,16 +32,16 @@ export class DSIUnitInput extends HTMLElement { this.display = document.createElement("div"); // Rendered output on blur. this.display.id = "dsiDisplay"; - this.display.style.cursor = "text"; + this.display.style.cursor = "text"; // Clickable for editing. - // Container. + // Container for input and suggestions. const container = document.createElement("div"); container.style.position = "relative"; container.appendChild(this.input); container.appendChild(this.suggestions); container.appendChild(this.display); - // Styles. + // Append styles. const style = document.createElement("style"); style.textContent = ` #dsiInput { @@ -77,7 +77,7 @@ export class DSIUnitInput extends HTMLElement { `; this.shadowRoot.append(style, container); - // Bind handlers. + // Bind event handlers. this.onInput = this.onInput.bind(this); this.onKeyDown = this.onKeyDown.bind(this); this.onBlur = this.onBlur.bind(this); @@ -121,16 +121,18 @@ export class DSIUnitInput extends HTMLElement { // Determines contextual suggestions. getContextualSuggestions() { const value = this.input.value; - const tokens = value.split("\\").filter(Boolean); - // If there are no complete tokens, allow all suggestions. - if (tokens.length <= 1) { + // Trim the value to remove extra whitespace. + const tokens = value.trim().split("\\").filter(t => t !== ""); + // If no complete tokens, return all. + if (tokens.length === 0) { return this.allowedTokens; } - // Use last accepted token if available. + // If a last accepted token exists and is a prefix, use that. if (this.lastAcceptedToken && (this.lastAcceptedToken in dsiPrefixesHTML)) { return Object.keys(dsiUnitsHTML); } - const prevToken = tokens[tokens.length - 2]; + // Otherwise, use the previous token from the current input. + const prevToken = tokens.length >= 2 ? tokens[tokens.length - 2] : "<empty>"; if (prevToken in dsiPrefixesHTML) { return Object.keys(dsiUnitsHTML); } else if (prevToken in dsiUnitsHTML) { @@ -147,7 +149,7 @@ export class DSIUnitInput extends HTMLElement { onInput(e) { this._rawValue = this.input.value; - // Auto-insert a backslash after a token if a space is typed. + // Auto-insert a backslash after a complete token if space is typed. if (this.input.value.endsWith(" ")) { const trimmed = this.input.value.trimEnd(); if (!trimmed.endsWith("\\")) { @@ -165,7 +167,7 @@ export class DSIUnitInput extends HTMLElement { updateSuggestions() { const cursorPos = this.input.selectionStart; const value = this.input.value; - // Suppress suggestions if caret is inside tothe braces. + // Do not show suggestions if caret is inside tothe braces. const regexTothe = /\\tothe\{([^}]*)$/; const substring = value.substring(0, cursorPos); const matchTothe = substring.match(regexTothe); @@ -181,20 +183,19 @@ export class DSIUnitInput extends HTMLElement { if (match) { currentToken = match[1]; } - // If current token exactly matches a known prefix, treat it as complete. + // If current token exactly matches a known prefix, auto-complete it. if (currentToken && (currentToken in dsiPrefixesHTML)) { console.log("Token complete: using accepted prefix", currentToken); - // Update lastAcceptedToken. this.lastAcceptedToken = currentToken; - // Auto-complete by appending a trailing backslash if not already present. + // Auto-append trailing backslash if not present. if (!value.endsWith("\\")) { this.input.value = value + "\\"; this._rawValue = this.input.value; } currentToken = ""; } - const tokens = value.split("\\").filter(Boolean); - let prevToken = tokens.length >= 2 ? tokens[tokens.length - 2] : "<empty>"; + const tokens = value.trim().split("\\").filter(t => t !== ""); + let prevToken = tokens.length >= 2 ? tokens[tokens.length - 2] : (this.lastAcceptedToken || "<empty>"); const contextSuggestions = this.getContextualSuggestions(); let filtered = currentToken === "" ? contextSuggestions @@ -291,7 +292,6 @@ export class DSIUnitInput extends HTMLElement { renderOutput() { try { const unit = new DSIUnit(this.input.value); - // Call DSIUnit.toHTML with oneLine option. this.display.innerHTML = unit.toHTML({ oneLine: true }); if (unit.warnings && unit.warnings.length > 0) { this.display.title = unit.warnings.join("; "); -- GitLab