diff --git a/packages/app/src/context/command.tsx b/packages/app/src/context/command.tsx index 03bd6318da..00d0511a22 100644 --- a/packages/app/src/context/command.tsx +++ b/packages/app/src/context/command.tsx @@ -4,6 +4,7 @@ import { createSimpleContext } from "@opencode-ai/ui/context" import { useDialog } from "@opencode-ai/ui/context/dialog" import { useLanguage } from "@/context/language" import { useSettings } from "@/context/settings" +import { isEditableTarget } from "@/utils/dom" import { Persist, persisted } from "@/utils/persist" const IS_MAC = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform) @@ -177,14 +178,6 @@ export function formatKeybind(config: string): string { return IS_MAC ? parts.join("") : parts.join("+") } -function isEditableTarget(target: EventTarget | null) { - if (!(target instanceof HTMLElement)) return false - if (target.isContentEditable) return true - if (target.closest("[contenteditable='true']")) return true - if (target.closest("input, textarea, select")) return true - return false -} - export const { use: useCommand, provider: CommandProvider } = createSimpleContext({ name: "Command", init: () => { diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 1909901c8f..f482f011d1 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -33,6 +33,7 @@ import { usePrompt } from "@/context/prompt" import { useComments } from "@/context/comments" import { SessionHeader, NewSessionView } from "@/components/session" import { same } from "@opencode-ai/util/array" +import { isEditableTarget } from "@/utils/dom" import { createOpenReviewFile } from "@/pages/session/helpers" import { createScrollSpy } from "@/pages/session/scroll-spy" import { SessionReviewTab, type DiffStyle, type SessionReviewTabProps } from "@/pages/session/review-tab" @@ -614,11 +615,6 @@ export default function Page() { saveLabel: language.t("common.save"), })) - const isEditableTarget = (target: EventTarget | null | undefined) => { - if (!(target instanceof HTMLElement)) return false - return /^(INPUT|TEXTAREA|SELECT|BUTTON)$/.test(target.tagName) || target.isContentEditable - } - const deepActiveElement = () => { let current: Element | null = document.activeElement while (current instanceof HTMLElement && current.shadowRoot?.activeElement) { diff --git a/packages/app/src/utils/dom.ts b/packages/app/src/utils/dom.ts index 4f3724c7c9..4169eb7e5a 100644 --- a/packages/app/src/utils/dom.ts +++ b/packages/app/src/utils/dom.ts @@ -1,3 +1,12 @@ +export function isEditableTarget(target: EventTarget | null | undefined) { + if (!(target instanceof HTMLElement)) return false + if (/^(INPUT|TEXTAREA|SELECT|BUTTON)$/.test(target.tagName)) return true + if (target.isContentEditable) return true + if (target.closest("[contenteditable='true']")) return true + if (target.closest("input, textarea, select")) return true + return false +} + export function getCharacterOffsetInLine(lineElement: Element, targetNode: Node, offset: number): number { const r = document.createRange() r.selectNodeContents(lineElement)