fix(ui): Make read-only content selectable with a Copy context menu (#48)

Root cause: body is user-select: none and each feature had to opt back in; the Markdown preview (and other read-only views) never did, and the app-wide contextmenu guard left no Copy item.
Fix: shared selectableText class (src/ui) for read-only content, and a fallback Copy context menu from browserGuards when right-clicking a selection or a selectable area (component menus still win).
Siblings covered: Quick Documentation / hover / completion docs, hover errors, Quick Definition, debugger value tooltip, inspection messages, message dialogs (no drag on body text), notification titles, About dialog; existing selectable consoles now get Copy too.
Verified in-app on macOS: select in Markdown preview, right-click Copy puts the text on the clipboard; tab context menu unchanged.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-10-27 08:56:13 +08:00
1 джерело 6dfd82de4c
коміт de84a643aa
17 files changed
+453 -55

No files matched your search

+3 -3
Переглянути файл
@@ -9,7 +9,7 @@ import { workflowSettings } from "@/platform/workflowSettings";
import { activeSession, evaluate } from "../state";
import { inlineValue } from "../values";
import { tx } from "@/platform/i18n";
import { iconMarkup } from "@/ui";
import { iconMarkup, selectableText } from "@/ui";
import { mountValueTree } from "../ui/ValueHintTree";
import styles from "./editor.module.css";
@@ -59,7 +59,7 @@ export function valueTooltip(): Extension {
above: true,
create: () => {
const dom = document.createElement("div");
dom.className = styles.valueTooltip!;
dom.className = `${styles.valueTooltip} ${selectableText}`;
let tree: { unmount(): void } | null = null;
if (value.variablesReference > 0) {
// IDEA's value hint: the "+" expands the object into a variables tree in place.
@@ -73,7 +73,7 @@ export function valueTooltip(): Extension {
expand.addEventListener("click", () => {
if (tree) return;
expand.remove();
dom.classList.add(styles.valueTooltipTree!);
dom.classList.replace(selectableText, styles.valueTooltipTree!);
dom.replaceChildren();
tree = mountValueTree(dom, expr.text, value, session.id);
});