Assessor_2.0/src/components/PathText/PathText.tsx

42 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Fragment } from 'react';
import { highlightText } from '../HighlightText/highlight-text';
import { annotateWindowsCodes } from '../../shared/windows-codes';
const pathLabel = /^(?:(?:source|registry|file|folder|directory|binary)\s+)?path$/i;
const placeholder = /^(?:–|—|-|not configured|not available|none)$/i;
export function isPathField(label = ''): boolean {
return pathLabel.test(label.trim());
}
/** Conservative presentation hint; never resolves, opens or changes a path. */
export function isWholePath(value: string): boolean {
const text = value.trim();
if (!text || /[\r\n]/.test(text) || /^\w+:\/\//.test(text)) return false;
return /^(?:[a-z]:[\\/]|\\\\|\/(?!\/)|\.{1,2}[\\/]|%[\w()]+%[\\/]|(?:HKEY_[A-Z_]+|HKLM|HKCU|HKCR|HKU|HKCC|SOFTWARE|SYSTEM)[\\/])/i.test(text)
|| /^[^\s<>:\\/]+[\\/][^<>\r\n]+\.[a-z0-9]{1,12}(?:#.*)?$/i.test(text);
}
/** Plain text with the documented meaning after each standard Windows code (SID, user right, registry type). */
function annotated(text: string, search: string) {
return annotateWindowsCodes(text).map((segment, index) => <Fragment key={index}>{highlightText(segment.text, search)}
{segment.meaning && <span className="windows-code-meaning"> ({segment.meaning})</span>}</Fragment>);
}
/** Inert text, including imported markup. Path labels stay in the UI typeface. */
export function PathText({ value, search = '', label = '' }: { value: string; search?: string; label?: string }) {
const renderPath = (path: string) => <code className="technical-path">{highlightText(path, search)}</code>;
if (isPathField(label) && value.trim() && !placeholder.test(value.trim())) return renderPath(value);
const titledRegistryPath = /^(registry(?:\s+values)?\s*\u00b7\s*)(.+)$/i.exec(value.trim());
if (titledRegistryPath && (isWholePath(titledRegistryPath[2]) || /^(?:MACHINE|USER)[\\/]/i.test(titledRegistryPath[2]))) {
return <>{highlightText(titledRegistryPath[1], search)}{renderPath(titledRegistryPath[2])}</>;
}
return <>{value.split(/(\r?\n)/).map((line, index) => {
const labeled = /^((?:(?:(?:source|registry|file|folder|directory|binary)\s+)?path|key|computer policy|user policy):\s*)(.+)$/i.exec(line);
if (labeled && !placeholder.test(labeled[2].trim()) && (isPathField(labeled[1].split(':')[0]) || isWholePath(labeled[2]))) {
return <Fragment key={index}>{highlightText(labeled[1], search)}{renderPath(labeled[2])}</Fragment>;
}
return <Fragment key={index}>{isWholePath(line) ? renderPath(line) : annotated(line, search)}</Fragment>;
})}</>;
}