@page "/source-viewer" @rendermode @(Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveServer) @using Microsoft.AspNetCore.Components @using Microsoft.AspNetCore.WebUtilities @inject IWebHostEnvironment Environment @inject NavigationManager Navigation @inject TrafagSalesExporter.Services.IUiTextService UiText @T("Source Viewer", "Source Viewer") @T("Source Viewer", "Source Viewer") @T("Zurueck zur Transformation", "Back to transformations") @if (!string.IsNullOrWhiteSpace(_requestedPath)) { @T("Datei:", "File:") @_requestedPath } @if (!string.IsNullOrWhiteSpace(_requestedType)) { @T("Klasse:", "Class:") @_requestedType @if (_highlightLineNumber is not null) { @T("bei Zeile", "at line") @_highlightLineNumber } } @if (!string.IsNullOrWhiteSpace(_error)) { @_error } else if (string.IsNullOrWhiteSpace(_content)) { } else {
@foreach (var line in _lines) {
@line.Number.ToString("0000") @line.Text
}
@if (_highlightLineNumber is not null) { } }
@code { private string? _requestedPath; private string? _requestedType; private string? _content; private string? _error; private List _lines = []; private int? _highlightLineNumber; protected override void OnInitialized() { var uri = Navigation.ToAbsoluteUri(Navigation.Uri); var query = QueryHelpers.ParseQuery(uri.Query); _requestedPath = query.TryGetValue("path", out var value) ? value.ToString() : null; _requestedType = query.TryGetValue("type", out var typeValue) ? typeValue.ToString() : null; if (string.IsNullOrWhiteSpace(_requestedPath)) { _error = T("Kein Dateipfad angegeben.", "No file path provided."); return; } if (_requestedPath.Contains("..", StringComparison.Ordinal) || Path.IsPathRooted(_requestedPath)) { _error = T("Ungueltiger Dateipfad.", "Invalid file path."); return; } var fullPath = Path.Combine(Environment.ContentRootPath, _requestedPath.Replace('/', Path.DirectorySeparatorChar)); if (!File.Exists(fullPath)) { _error = string.Format(T("Datei nicht gefunden: {0}", "File not found: {0}"), _requestedPath); return; } _content = File.ReadAllText(fullPath); _lines = _content .Replace("\r\n", "\n", StringComparison.Ordinal) .Split('\n') .Select((text, index) => new SourceLine(index + 1, text)) .ToList(); if (!string.IsNullOrWhiteSpace(_requestedType)) { _highlightLineNumber = _lines .FirstOrDefault(x => x.Text.Contains($"class {_requestedType}", StringComparison.Ordinal) || x.Text.Contains($"sealed class {_requestedType}", StringComparison.Ordinal) || x.Text.Contains($"public class {_requestedType}", StringComparison.Ordinal) || x.Text.Contains($"public sealed class {_requestedType}", StringComparison.Ordinal)) ?.Number; } } private static string GetLineAnchor(int lineNumber) => $"line-{lineNumber}"; private string GetLineStyle(int lineNumber) { var highlight = _highlightLineNumber == lineNumber; return highlight ? "background-color:#fff3cd; white-space:pre-wrap;" : "white-space:pre-wrap;"; } private sealed record SourceLine(int Number, string Text); private string T(string german, string english) => UiText.Text(german, english); }