mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
fix(ui): selectstart blocker handles Text node event targets (#718)
* fix(ui): handle Text node targets in global selectstart blocker selectstart can target a Text node without closest(); resolve to the parent Element before checking inputs and data-selectable regions. * docs(changelog): note PR #718 selectstart Text node fix * fix(ui): narrow selectstart target to Node before parentNode Satisfies tsc: EventTarget has no parentElement/parentNode until narrowed with instanceof Node.
This commit is contained in:
@@ -1,5 +1,20 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
/** `Event.target` may be a Text node — only Elements expose `closest` / `tagName`. */
|
||||
function eventTargetElement(e: Event): Element | null {
|
||||
const t = e.target;
|
||||
if (!t) return null;
|
||||
if (t instanceof Element) return t;
|
||||
if (!(t instanceof Node)) return null;
|
||||
const parent = t.parentNode;
|
||||
return parent instanceof Element ? parent : null;
|
||||
}
|
||||
|
||||
function isTextInputElement(el: Element): boolean {
|
||||
const tag = el.tagName;
|
||||
return tag === 'INPUT' || tag === 'TEXTAREA' || (el as HTMLElement).isContentEditable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Globally tame Linux/WebKitGTK + Wayland behaviour that the page-level
|
||||
* CSS / Tauri config can't reach:
|
||||
@@ -29,16 +44,20 @@ export function useGlobalDndAndSelectionBlockers(): void {
|
||||
|
||||
const blockSelectAll = (e: KeyboardEvent) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'a') {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) return;
|
||||
const el = eventTargetElement(e);
|
||||
if (el && isTextInputElement(el)) return;
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
const blockSelectStart = (e: Event) => {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable) return;
|
||||
if ((target as HTMLElement).closest('[data-selectable]')) return;
|
||||
const el = eventTargetElement(e);
|
||||
if (!el) {
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
if (isTextInputElement(el)) return;
|
||||
if (el.closest('[data-selectable]')) return;
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user