diff --git a/samples/language-service-sample/app.js b/samples/language-service-sample/app.js index b8579d8..64b8698 100644 --- a/samples/language-service-sample/app.js +++ b/samples/language-service-sample/app.js @@ -161,12 +161,12 @@ function loadExampleFromUrl() { return false; } -// Split pane resizing +// Vertical resizing for bottom split (context/results) (function() { - const resizer = document.getElementById('resizer'); - const leftPane = document.getElementById('leftPane'); - const rightPane = document.getElementById('rightPane'); - const mainContent = document.getElementById('mainContent'); + const resizer = document.getElementById('verticalResizer'); + const contextPane = document.getElementById('contextPane'); + const resultsPane = document.getElementById('resultsPane'); + const bottomArea = document.getElementById('bottomArea'); let isResizing = false; resizer.addEventListener('mousedown', (e) => { @@ -180,15 +180,15 @@ function loadExampleFromUrl() { if (!isResizing) return; e.preventDefault(); - const containerRect = mainContent.getBoundingClientRect(); + const containerRect = bottomArea.getBoundingClientRect(); const containerWidth = containerRect.width; const resizerWidth = 6; let newLeftWidth = e.clientX - containerRect.left; - newLeftWidth = Math.max(containerWidth * 0.15, Math.min(containerWidth * 0.85, newLeftWidth)); + newLeftWidth = Math.max(containerWidth * 0.2, Math.min(containerWidth * 0.8, newLeftWidth)); - leftPane.style.width = newLeftWidth + 'px'; - rightPane.style.width = (containerWidth - newLeftWidth - resizerWidth) + 'px'; + const percentage = (newLeftWidth / containerWidth) * 100; + contextPane.style.width = percentage + '%'; }); document.addEventListener('mouseup', () => { @@ -417,6 +417,24 @@ require(['vs/editor/editor.main'], function () { highlightDecorations = expressionEditor.deltaDecorations(highlightDecorations, decorations); } + // Syntax highlight JSON + function syntaxHighlightJson(json) { + if (typeof json !== 'string') { + json = JSON.stringify(json, null, 2); + } + json = json.replace(/&/g, '&').replace(//g, '>'); + return json.replace(/("+[^"]*"+)(:)?/g, function(match, p1, p2) { + let cls = 'json-key'; + if (!p2) { + cls = 'json-string'; + } + return '' + p1 + '' + (p2 || ''); + }) + .replace(/: (true|false)/g, ': $1') + .replace(/: (null)/g, ': $1') + .replace(/: (-?\d+\.?\d*)/g, ': $1'); + } + // Result display functions function showResult(result) { const resultSuccess = document.getElementById('resultSuccess'); @@ -432,21 +450,42 @@ require(['vs/editor/editor.main'], function () { // Format the result let displayValue; let typeInfo; + let isJson = false; + if (result === null) { - displayValue = 'null'; + displayValue = 'null'; typeInfo = 'Type: null'; + isJson = true; } else if (result === undefined) { - displayValue = 'undefined'; + displayValue = 'undefined'; typeInfo = 'Type: undefined'; + isJson = true; } else if (typeof result === 'object') { - displayValue = JSON.stringify(result, null, 2); + displayValue = syntaxHighlightJson(result); typeInfo = Array.isArray(result) ? `Type: array (${result.length} items)` : 'Type: object'; + isJson = true; + } else if (typeof result === 'boolean') { + displayValue = `${result}`; + typeInfo = 'Type: boolean'; + isJson = true; + } else if (typeof result === 'number') { + displayValue = `${result}`; + typeInfo = 'Type: number'; + isJson = true; + } else if (typeof result === 'string') { + displayValue = `"${result}"`; + typeInfo = 'Type: string'; + isJson = true; } else { displayValue = String(result); typeInfo = `Type: ${typeof result}`; } - resultValue.textContent = displayValue; + if (isJson) { + resultValue.innerHTML = displayValue; + } else { + resultValue.textContent = displayValue; + } resultType.textContent = typeInfo; } @@ -456,15 +495,17 @@ require(['vs/editor/editor.main'], function () { const resultEmpty = document.getElementById('resultEmpty'); const errorMessage = document.getElementById('errorMessage'); const errorDetails = document.getElementById('errorDetails'); - const footer = document.getElementById('footer'); + const resultsPane = document.getElementById('resultsPane'); resultSuccess.classList.add('hidden'); resultError.classList.remove('hidden'); resultEmpty.classList.add('hidden'); // Shake animation - footer.classList.add('error-shake'); - setTimeout(() => footer.classList.remove('error-shake'), 300); + if (resultsPane) { + resultsPane.classList.add('error-shake'); + setTimeout(() => resultsPane.classList.remove('error-shake'), 300); + } errorMessage.textContent = error.message; diff --git a/samples/language-service-sample/index.html b/samples/language-service-sample/index.html index eda05c1..00cc0e0 100644 --- a/samples/language-service-sample/index.html +++ b/samples/language-service-sample/index.html @@ -66,73 +66,77 @@

-
- Expression - Enter your expr-eval expression -
-
-
+ +
+ +
+
+ Expression + Enter your expr-eval expression +
+
+
+
-
- -
+ +
+ +
+
+ Context (JSON) + Variables available in expressions +
+
+
+
+
- -
-
- Context (JSON) - Variables available in expressions -
-
-
-
-
- + +
- -
-
-
- Result -
-
-
+
diff --git a/samples/language-service-sample/styles.css b/samples/language-service-sample/styles.css index ff35d92..8c819b9 100644 --- a/samples/language-service-sample/styles.css +++ b/samples/language-service-sample/styles.css @@ -22,6 +22,35 @@ html, body { display: flex; } +/* Work area layout */ +#workArea { + flex: 1; + display: flex; + flex-direction: column; + min-width: 0; +} + +#expressionPane { + height: 300px; + flex-shrink: 0; +} + +#bottomArea { + flex: 1; + min-height: 0; + display: flex; +} + +#contextPane { + width: 50%; + flex-shrink: 0; +} + +#resultsPane { + flex: 1; + min-width: 0; +} + /* Split pane styles */ .pane { display: flex; @@ -47,18 +76,19 @@ html, body { bottom: 0; } -#resizer { +/* Vertical resizer */ +#verticalResizer { width: 6px; cursor: col-resize; flex-shrink: 0; position: relative; } -#resizer:hover { +#verticalResizer:hover { background-color: #6366f1 !important; } -#resizer::after { +#verticalResizer::after { content: ''; position: absolute; top: 50%; @@ -70,9 +100,58 @@ html, body { border-radius: 2px; } -#footer { - flex-shrink: 0; - height: 300px; +#resultContainer { + flex: 1; + overflow-y: auto; +} + +/* JSON syntax highlighting */ +#resultValue { + white-space: pre-wrap; + word-break: break-word; +} + +.json-key { + color: #0451a5; + font-weight: 500; +} + +.json-string { + color: #a31515; +} + +.json-number { + color: #098658; +} + +.json-boolean { + color: #0000ff; + font-weight: 600; +} + +.json-null { + color: #0000ff; + font-weight: 600; +} + +.dark .json-key { + color: #9cdcfe; +} + +.dark .json-string { + color: #ce9178; +} + +.dark .json-number { + color: #b5cea8; +} + +.dark .json-boolean { + color: #569cd6; +} + +.dark .json-null { + color: #569cd6; } /* Light theme token colors */