fix: prevent static settings text selection
Disable text selection across the active Settings view and every related dialog while explicitly preserving selection inside editable fields and text areas. Add regression coverage for the selection scope and input exceptions.
This commit is contained in:
@@ -10,6 +10,11 @@ Desktop downloader for Windows with package-based queue management, multi-provid
|
||||
|
||||
## Changelog
|
||||
|
||||
### 2.0.12
|
||||
|
||||
- Prevent static headings, labels, hints, and card text from being selected throughout Settings.
|
||||
- Keep editable fields and text areas selectable for normal copy and paste.
|
||||
|
||||
### 2.0.11
|
||||
|
||||
- Keep Account Overview and Usage Rules inside the same fixed layout frame.
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "real-debrid-downloader",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.12",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "real-debrid-downloader",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.12",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"adm-zip": "0.6.0",
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "real-debrid-downloader",
|
||||
"version": "2.0.11",
|
||||
"version": "2.0.12",
|
||||
"description": "Desktop downloader",
|
||||
"main": "build/main/main/main.js",
|
||||
"author": "Sucukdeluxe",
|
||||
|
||||
@@ -4796,7 +4796,7 @@ export function App(): ReactElement {
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`app-shell${dragOver ? " drag-over" : ""}`}
|
||||
className={`app-shell${dragOver ? " drag-over" : ""}${tab === "settings" ? " settings-active" : ""}`}
|
||||
onDragEnter={(event) => {
|
||||
event.preventDefault();
|
||||
if (draggedPackageIdRef.current) { return; }
|
||||
|
||||
+17
-7
@@ -1067,13 +1067,23 @@ body,
|
||||
margin-left: 26px;
|
||||
}
|
||||
|
||||
.settings-shell {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
gap: 8px;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
.settings-shell {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
gap: 8px;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.app-shell.settings-active {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.app-shell.settings-active input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
|
||||
.app-shell.settings-active textarea,
|
||||
.app-shell.settings-active [contenteditable]:not([contenteditable="false"]) {
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
.settings-toolbar {
|
||||
display: flex;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const styles = readFileSync(new URL("../src/renderer/styles.css", import.meta.url), "utf8");
|
||||
const appSource = readFileSync(new URL("../src/renderer/App.tsx", import.meta.url), "utf8");
|
||||
|
||||
describe("settings text selection", () => {
|
||||
it("blocks selection across the active settings view and its dialogs while preserving editable fields", () => {
|
||||
expect(appSource).toContain('${tab === "settings" ? " settings-active" : ""}');
|
||||
expect(styles).toMatch(/\.app-shell\.settings-active\s*{[^}]*user-select:\s*none;/s);
|
||||
expect(styles).toMatch(/\.app-shell\.settings-active input:not\(\[type="checkbox"\]\):not\(\[type="radio"\]\):not\(\[type="range"\]\),\s*\.app-shell\.settings-active textarea,\s*\.app-shell\.settings-active \[contenteditable\]:not\(\[contenteditable="false"\]\)\s*{[^}]*user-select:\s*text;/s);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user