(props: TextFileProps<T>)
| 702 | // --------------------------------------------------------------------------- |
| 703 | |
| 704 | function TextViewer<T>(props: TextFileProps<T>) { |
| 705 | let instance: PierreFile<T> | VirtualizedFile<T> | undefined |
| 706 | let viewer!: Viewer |
| 707 | |
| 708 | const [local, others] = splitProps(props, textKeys) |
| 709 | |
| 710 | const text = () => { |
| 711 | const value = local.file.contents as unknown |
| 712 | if (typeof value === "string") return value |
| 713 | if (Array.isArray(value)) return value.join("\n") |
| 714 | if (value == null) return "" |
| 715 | // oxlint-disable-next-line no-base-to-string -- file contents cast to unknown, coercion is intentional |
| 716 | return String(value) |
| 717 | } |
| 718 | |
| 719 | const lineCount = () => { |
| 720 | const value = text() |
| 721 | const total = value.split("\n").length - (value.endsWith("\n") ? 1 : 0) |
| 722 | return Math.max(1, total) |
| 723 | } |
| 724 | |
| 725 | const bytes = createMemo(() => { |
| 726 | const value = local.file.contents as unknown |
| 727 | if (typeof value === "string") return value.length |
| 728 | if (Array.isArray(value)) { |
| 729 | return value.reduce( |
| 730 | // oxlint-disable-next-line no-base-to-string -- array parts coerced intentionally |
| 731 | (sum, part) => sum + (typeof part === "string" ? part.length + 1 : String(part).length + 1), |
| 732 | 0, |
| 733 | ) |
| 734 | } |
| 735 | if (value == null) return 0 |
| 736 | // oxlint-disable-next-line no-base-to-string -- file contents cast to unknown, coercion is intentional |
| 737 | return String(value).length |
| 738 | }) |
| 739 | |
| 740 | const virtual = createMemo(() => bytes() > VIRTUALIZE_BYTES) |
| 741 | |
| 742 | const virtuals = createLocalVirtualStrategy(() => viewer.wrapper, virtual) |
| 743 | |
| 744 | const lineFromMouseEvent = (event: MouseEvent): MouseHit => mouseHit(event, parseLine) |
| 745 | |
| 746 | const applySelection = (range: SelectedLineRange | null) => { |
| 747 | const current = instance |
| 748 | if (!current) return false |
| 749 | |
| 750 | if (virtual()) { |
| 751 | current.setSelectedLines(range) |
| 752 | return true |
| 753 | } |
| 754 | |
| 755 | const root = viewer.getRoot() |
| 756 | if (!root) return false |
| 757 | |
| 758 | const total = lineCount() |
| 759 | if (root.querySelectorAll("[data-line]").length < total) return false |
| 760 | |
| 761 | if (!range) { |
no test coverage detected