fix(editor): prevent F7 from triggering browser caret browsing

This commit is contained in:
lxk955
2026-10-13 08:59:21 +08:00
committed by GitHub
parent 2c6e0c8145
commit 26a61b8d69
24 changed files with 185 additions and 0 deletions
+17
View File
@@ -117,6 +117,8 @@ import { restoreGlobalNavigationEntry } from "@/lib/navigation/globalNavigationE
import {
isBrowserReloadShortcut,
isBrowserTaskManagerShortcut,
isCaretBrowsingShortcut,
shouldBlockCaretBrowsing,
isCloseAllTabsShortcut,
isCloseOtherTabsShortcut,
isCloseTabShortcut,
@@ -4149,6 +4151,16 @@ function handleNativeSelectAll(e: KeyboardEvent) {
e.stopPropagation();
return;
}
if (
shouldBlockCaretBrowsing(e, {
caretBrowsingEnabled: settingsStore.editorSettings.caretBrowsingEnabled,
shortcuts: settingsStore.editorSettings.shortcuts,
})
) {
e.preventDefault();
e.stopPropagation();
return;
}
if (shouldBlockAppNativeSelectAll(e)) e.preventDefault();
}
@@ -4496,6 +4508,11 @@ async function handleKeydown(e: KeyboardEvent) {
e.stopPropagation();
return;
}
if (!settingsStore.editorSettings.caretBrowsingEnabled && isCaretBrowsingShortcut(e)) {
e.preventDefault();
e.stopPropagation();
return;
}
if (isDesktop && isBrowserReloadShortcut(e)) {
e.preventDefault();
e.stopPropagation();
@@ -738,6 +738,7 @@ const editWordWrap = ref(settingsStore.editorSettings.wordWrap);
const editShowWhitespace = ref(settingsStore.editorSettings.showWhitespace);
const editDdlOpenMode = ref<EditorSettings["ddlOpenMode"]>(settingsStore.editorSettings.ddlOpenMode);
const editVimModeEnabled = ref(settingsStore.editorSettings.vimModeEnabled);
const editCaretBrowsingEnabled = ref(settingsStore.editorSettings.caretBrowsingEnabled);
const editDoubleClickStringSelectionMode = ref<EditorSettings["doubleClickStringSelectionMode"]>(settingsStore.editorSettings.doubleClickStringSelectionMode);
const editAutoCloseBrackets = ref(settingsStore.editorSettings.autoCloseBrackets);
const editRestoreSqlFromSourcePasteEnabled = ref(settingsStore.editorSettings.restoreSqlFromSourcePasteEnabled);
@@ -1129,6 +1130,7 @@ function currentEditorSettingsDraft(): EditorSettingsDraft {
showWhitespace: editShowWhitespace.value,
ddlOpenMode: editDdlOpenMode.value,
vimModeEnabled: editVimModeEnabled.value,
caretBrowsingEnabled: editCaretBrowsingEnabled.value,
doubleClickStringSelectionMode: editDoubleClickStringSelectionMode.value,
autoCloseBrackets: editAutoCloseBrackets.value,
restoreSqlFromSourcePasteEnabled: editRestoreSqlFromSourcePasteEnabled.value,
@@ -1817,6 +1819,7 @@ function syncEditorSettingsDraftFromStore() {
editShowWhitespace.value = settingsStore.editorSettings.showWhitespace;
editDdlOpenMode.value = settingsStore.editorSettings.ddlOpenMode;
editVimModeEnabled.value = settingsStore.editorSettings.vimModeEnabled;
editCaretBrowsingEnabled.value = settingsStore.editorSettings.caretBrowsingEnabled;
editDoubleClickStringSelectionMode.value = settingsStore.editorSettings.doubleClickStringSelectionMode;
editAutoCloseBrackets.value = settingsStore.editorSettings.autoCloseBrackets;
editRestoreSqlFromSourcePasteEnabled.value = settingsStore.editorSettings.restoreSqlFromSourcePasteEnabled;
@@ -1982,6 +1985,7 @@ const editorSettingsDraftRefs: EditorSettingsDraftRefMap = {
showWhitespace: editShowWhitespace,
ddlOpenMode: editDdlOpenMode,
vimModeEnabled: editVimModeEnabled,
caretBrowsingEnabled: editCaretBrowsingEnabled,
doubleClickStringSelectionMode: editDoubleClickStringSelectionMode,
autoCloseBrackets: editAutoCloseBrackets,
restoreSqlFromSourcePasteEnabled: editRestoreSqlFromSourcePasteEnabled,
@@ -2550,6 +2554,7 @@ function resetDefaultsForTab(tab: SettingsCategory) {
editShowWhitespace.value = DEFAULT_EDITOR_SETTINGS.showWhitespace;
editDdlOpenMode.value = DEFAULT_EDITOR_SETTINGS.ddlOpenMode;
editVimModeEnabled.value = DEFAULT_EDITOR_SETTINGS.vimModeEnabled;
editCaretBrowsingEnabled.value = DEFAULT_EDITOR_SETTINGS.caretBrowsingEnabled;
editDoubleClickStringSelectionMode.value = DEFAULT_EDITOR_SETTINGS.doubleClickStringSelectionMode;
editAutoCloseBrackets.value = DEFAULT_EDITOR_SETTINGS.autoCloseBrackets;
editRestoreSqlFromSourcePasteEnabled.value = DEFAULT_EDITOR_SETTINGS.restoreSqlFromSourcePasteEnabled;
@@ -2735,6 +2740,7 @@ function resetAllDefaults() {
editShowWhitespace.value = DEFAULT_EDITOR_SETTINGS.showWhitespace;
editDdlOpenMode.value = DEFAULT_EDITOR_SETTINGS.ddlOpenMode;
editVimModeEnabled.value = DEFAULT_EDITOR_SETTINGS.vimModeEnabled;
editCaretBrowsingEnabled.value = DEFAULT_EDITOR_SETTINGS.caretBrowsingEnabled;
editDoubleClickStringSelectionMode.value = DEFAULT_EDITOR_SETTINGS.doubleClickStringSelectionMode;
editAutoCloseBrackets.value = DEFAULT_EDITOR_SETTINGS.autoCloseBrackets;
editRestoreSqlFromSourcePasteEnabled.value = DEFAULT_EDITOR_SETTINGS.restoreSqlFromSourcePasteEnabled;
@@ -7191,6 +7197,16 @@ onUnmounted(() => {
<Switch id="editor-vim-mode" v-model="editVimModeEnabled" class="mt-0.5" />
</div>
<div class="settings-item flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="space-y-1">
<Label for="editor-caret-browsing">{{ t("settings.caretBrowsing") }}</Label>
<p class="text-xs text-muted-foreground">
{{ t("settings.caretBrowsingDescription") }}
</p>
</div>
<Switch id="editor-caret-browsing" v-model="editCaretBrowsingEnabled" class="mt-0.5" />
</div>
<div class="settings-item flex items-center justify-between gap-4 rounded-md border bg-muted/20 px-3 py-2">
<div class="space-y-1">
<Label for="regex-max-match-count">{{ t("settings.regexMaxMatchCount") }}</Label>
+2
View File
@@ -7870,6 +7870,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "Yalnız sözü seç",
vimMode: "Vim rejimi",
vimModeDescription: "SQL redaktorunda Vim üslublu modal redaktədən istifadə et",
caretBrowsing: "Kursorla naviqasiya (F7)",
caretBrowsingDescription: "Brauzerin kursorla naviqasiya rejimini dəyişmək üçün F7 düyməsinə basmağa icazə verin. Deaktiv edildikdə təsadüfi dialoqların qarşısını almaq üçün F7 qarşılanır.",
autoCloseBrackets: "Mötərizələri avtomatik bağla",
restoreSqlFromSourcePaste: "Mənbə koddan yapışdırılan SQL-i bərpa et",
restoreSqlFromSourcePasteDescription: "Java, JavaScript, Python və bənzər mənbələrdən kopyalanan sətir birləşdirməli SQL (dırnaqlar, plus işarələri və escape sətir keçidləri) yapışdırılarkən adi SQL-ə bərpa olunur. Yalnız aydın birləşdirmələr çevrilir, digər məzmun olduğu kimi yapışdırılır.",
+2
View File
@@ -8995,6 +8995,8 @@ export default {
doubleClickStringSelectionModeWord: "Select single word",
vimMode: "Vim mode",
vimModeDescription: "Use Vim-style modal editing in the SQL editor",
caretBrowsing: "Caret browsing (F7)",
caretBrowsingDescription: "Allow pressing F7 to toggle browser caret browsing. When disabled, the F7 key is intercepted to prevent accidental prompts.",
autoCloseBrackets: "Auto-close brackets",
restoreSqlFromSourcePaste: "Restore SQL pasted from source code",
restoreSqlFromSourcePasteDescription: "When pasting SQL assembled from string literals in Java, JavaScript, Python or similar source files (quotes, plus signs, escaped newlines), restore it to plain SQL. Only clear concatenations are rewritten; anything else is pasted as-is.",
+2
View File
@@ -8225,6 +8225,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "Seleccionar una sola palabra",
vimMode: "Modo Vim",
vimModeDescription: "Usar edición modal estilo Vim en el editor SQL",
caretBrowsing: "Navegación por cursor (F7)",
caretBrowsingDescription: "Permite presionar F7 para alternar el modo de navegación por cursor del navegador. Al desactivarlo, se intercepta la tecla F7 para evitar avisos accidentales.",
autoCloseBrackets: "Cerrar paréntesis automáticamente",
restoreSqlFromSourcePaste: "Restaurar SQL pegado desde código fuente",
restoreSqlFromSourcePasteDescription: "Al pegar SQL construido con literales de cadena en Java, JavaScript, Python y similares (comillas, signos más y saltos de línea escapados), se restaura como SQL normal. Solo se reescriben las concatenaciones claras; el resto se pega tal cual.",
+2
View File
@@ -8678,6 +8678,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "Pilih satu kata",
vimMode: "Mode Vim",
vimModeDescription: "Gunakan pengeditan modal bergaya Vim di editor SQL",
caretBrowsing: "Penjelajahan kursor (F7)",
caretBrowsingDescription: "Izinkan menekan F7 untuk beralih mode penjelajahan kursor peramban. Saat dinonaktifkan, tombol F7 dicegat untuk mencegah dialog tidak disengaja.",
autoCloseBrackets: "Tutup kurung otomatis",
restoreSqlFromSourcePaste: "Pulihkan SQL yang ditempel dari kode sumber",
restoreSqlFromSourcePasteDescription:
+2
View File
@@ -7991,6 +7991,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "Seleziona solo la parola",
vimMode: "Modalita Vim",
vimModeDescription: "Usa la modifica modale in stile Vim nell'editor SQL",
caretBrowsing: "Navigazione con cursore (F7)",
caretBrowsingDescription: "Consenti la pressione di F7 per attivare la navigazione con cursore del browser. Se disattivata, il tasto F7 viene intercettato per evitare richieste accidentali.",
autoCloseBrackets: "Chiusura automatica parentesi",
restoreSqlFromSourcePaste: "Ripristina l'SQL incollato dal codice sorgente",
restoreSqlFromSourcePasteDescription:
+2
View File
@@ -8003,6 +8003,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "単語だけを選択",
vimMode: "Vimモード",
vimModeDescription: "SQLエディターでVim形式のモーダル編集を使用します",
caretBrowsing: "キャレットブラウズ (F7)",
caretBrowsingDescription: "F7 キーによるブラウザーのキャレットブラウズ切り替えを許可します。無効時は F7 キーをインターセプトし誤操作のプロンプトを防ぎます。",
autoCloseBrackets: "自動括弧補完",
restoreSqlFromSourcePaste: "貼り付け時にソースコードの SQL を復元",
restoreSqlFromSourcePasteDescription: "Java、JavaScript、Python などのソースからコピーした文字列連結の SQL(引用符・プラス記号・エスケープ改行を含む)を、貼り付け時に通常の SQL へ復元します。明確な連結のみを対象とし、それ以外はそのまま貼り付けます。",
+2
View File
@@ -7872,6 +7872,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "단어만 선택",
vimMode: "Vim 모드",
vimModeDescription: "SQL 편집기에서 Vim 스타일의 모달 편집을 사용합니다",
caretBrowsing: "캐럿 브라우징 (F7)",
caretBrowsingDescription: "F7 키를 눌러 브라우저의 캐럿 브라우징 모드를 전환할 수 있도록 허용합니다. 비활성화 시 F7 키를 가로채어 실수로 인한 대화상자 표시를 방지합니다.",
autoCloseBrackets: "괄호 자동 닫기",
restoreSqlFromSourcePaste: "붙여넣기 시 소스 코드 SQL 복원",
restoreSqlFromSourcePasteDescription: "Java, JavaScript, Python 등 소스에서 복사한 문자열 연결 SQL(따옴표, 더하기 기호, 이스케이프 줄바꿈 포함)을 붙여넣을 때 일반 SQL로 복원합니다. 명확한 연결만 변환하며 그 외에는 원문 그대로 붙여넣습니다.",
+2
View File
@@ -7990,6 +7990,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "Selecionar apenas a palavra",
vimMode: "Modo Vim",
vimModeDescription: "Usar edição modal no estilo Vim no editor SQL",
caretBrowsing: "Navegação por cursor (F7)",
caretBrowsingDescription: "Permite pressionar F7 para alternar o modo de navegação por cursor do navegador. Quando desativado, a tecla F7 é interceptada para evitar diálogos acidentais.",
autoCloseBrackets: "Fechar parênteses automaticamente",
restoreSqlFromSourcePaste: "Restaurar SQL colado do código-fonte",
restoreSqlFromSourcePasteDescription: "Ao colar SQL montado com literais de string em Java, JavaScript, Python e afins (aspas, sinais de mais e quebras de linha escapadas), ele é restaurado como SQL normal. Apenas concatenações claras são reescritas; o restante é colado como está.",
+2
View File
@@ -9327,6 +9327,8 @@ export default withEnglishFallback({
showWhitespaceDescription: "Показывать пробелы как ·, а табуляции как → в SQL-редакторе. Меняется только отображение, а не текст SQL.",
vimMode: "Режим Vim",
vimModeDescription: "Использовать модальное редактирование в стиле Vim в SQL-редакторе",
caretBrowsing: "Просмотр курсором (F7)",
caretBrowsingDescription: "Разрешить нажатие F7 для переключения режима просмотра с помощью курсора. При отключении клавиша F7 перехватывается для предотвращения случайных окон.",
autoCloseBrackets: "Автозакрытие скобок",
restoreSqlFromSourcePaste: "Восстанавливать SQL, вставленный из кода",
restoreSqlFromSourcePasteDescription:
+2
View File
@@ -7768,6 +7768,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "Yalnızca sözcüğü seç",
vimMode: "Vim modu",
vimModeDescription: "SQL düzenleyicisinde Vim biçemli kipli düzenleme kullan",
caretBrowsing: "Gezinme imleci (F7)",
caretBrowsingDescription: "Tarayıcının metin imleciyle gezinme modunu değiştirmek için F7 tuşuna basılmasına izin verin. Devre dışı bırakıldığında yanlışlıkla iletişim kutusu açılmasını önlemek için F7 engellenir.",
autoCloseBrackets: "Parantezleri otomatik kapat",
restoreSqlFromSourcePaste: "Kaynak koddan yapıştırılan SQL'i geri yükle",
restoreSqlFromSourcePasteDescription:
+2
View File
@@ -8975,6 +8975,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "只选中单词",
vimMode: "Vim 模式",
vimModeDescription: "在 SQL 编辑器中使用 Vim 风格的模态编辑",
caretBrowsing: "光标浏览 (F7)",
caretBrowsingDescription: "允许按 F7 切换浏览器的插入光标浏览模式。关闭时拦截 F7 键,避免误触弹出提示。",
autoCloseBrackets: "自动成对补全",
restoreSqlFromSourcePaste: "粘贴时自动还原源码 SQL",
restoreSqlFromSourcePasteDescription: "粘贴从 Java、JavaScript、Python 等源码复制的字符串拼接 SQL(含引号、加号与转义换行)时,自动还原为普通 SQL;只识别明确的拼接写法,其余内容原样粘贴。",
+2
View File
@@ -7333,6 +7333,8 @@ export default withEnglishFallback({
doubleClickStringSelectionModeWord: "只選取單詞",
vimMode: "Vim 模式",
vimModeDescription: "在 SQL 編輯器中使用 Vim 風格的模態編輯",
caretBrowsing: "游標瀏覽 (F7)",
caretBrowsingDescription: "允許按 F7 切換瀏覽器的游標瀏覽模式。關閉時攔截 F7 鍵,避免誤觸彈出提示。",
autoCloseBrackets: "自動成對補全",
restoreSqlFromSourcePaste: "貼上時自動還原來源 SQL",
restoreSqlFromSourcePasteDescription: "貼上從 Java、JavaScript、Python 等原始碼複製的字串拼接 SQL(含引號、加號與轉義換行)時,自動還原為一般 SQL;只辨識明確的拼接寫法,其餘內容原樣貼上。",
@@ -3,6 +3,8 @@ import {
eventToModifierOnlyShortcut,
eventToShortcut,
isBrowserTaskManagerShortcut,
isCaretBrowsingShortcut,
shouldBlockCaretBrowsing,
isConvertNamingStyleShortcut,
isEditCellShortcut,
isEditTableStructureShortcut,
@@ -298,3 +300,40 @@ describe("isBrowserTaskManagerShortcut", () => {
expect(isBrowserTaskManagerShortcut({ key: "x", shiftKey: true })).toBe(false);
});
});
describe("isCaretBrowsingShortcut", () => {
it("matches F7 key and code without modifiers", () => {
expect(isCaretBrowsingShortcut({ key: "F7" })).toBe(true);
expect(isCaretBrowsingShortcut({ code: "F7", key: "Unidentified" })).toBe(true);
expect(isCaretBrowsingShortcut({ key: "F7", code: "F7" })).toBe(true);
expect(isCaretBrowsingShortcut({ key: "F7", ctrlKey: true })).toBe(false);
expect(isCaretBrowsingShortcut({ key: "F7", metaKey: true })).toBe(false);
expect(isCaretBrowsingShortcut({ key: "F7", altKey: true })).toBe(false);
expect(isCaretBrowsingShortcut({ key: "F7", shiftKey: true })).toBe(false);
expect(isCaretBrowsingShortcut({ key: "F7", isComposing: true })).toBe(false);
expect(isCaretBrowsingShortcut({ key: "F8" })).toBe(false);
});
});
describe("shouldBlockCaretBrowsing", () => {
it("blocks F7 when caretBrowsingEnabled is false or unset", () => {
expect(shouldBlockCaretBrowsing({ key: "F7" })).toBe(true);
expect(shouldBlockCaretBrowsing({ key: "F7" }, { caretBrowsingEnabled: false })).toBe(true);
});
it("does not block when caretBrowsingEnabled is true", () => {
expect(shouldBlockCaretBrowsing({ key: "F7" }, { caretBrowsingEnabled: true })).toBe(false);
});
it("does not block non-F7 keys or modified keys", () => {
expect(shouldBlockCaretBrowsing({ key: "F5" })).toBe(false);
expect(shouldBlockCaretBrowsing({ key: "F7", ctrlKey: true })).toBe(false);
expect(shouldBlockCaretBrowsing({ key: "F7", shiftKey: true })).toBe(false);
});
it("does not block when F7 is bound to a custom shortcut action", () => {
expect(shouldBlockCaretBrowsing({ key: "F7" }, { caretBrowsingEnabled: false, shortcuts: { executeSql: "F7" } })).toBe(false);
expect(shouldBlockCaretBrowsing({ key: "F7" }, { caretBrowsingEnabled: false, shortcuts: { executeSql: "Ctrl+Enter" } })).toBe(true);
});
});
@@ -409,3 +409,26 @@ export function isBrowserTaskManagerShortcut(event: ShortcutLikeEvent): boolean
if (!event.shiftKey) return false;
return event.key === "Escape" || event.key === "Esc" || event.code === "Escape";
}
export function isCaretBrowsingShortcut(event: ShortcutLikeEvent): boolean {
if (event.isComposing || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return false;
return event.key === "F7" || event.code === "F7";
}
export function isConfiguredShortcut(event: ShortcutLikeEvent, shortcuts?: Partial<ShortcutSettings>, platform = globalThis.navigator?.platform || ""): boolean {
if (!shortcuts) return false;
const normalized = normalizeShortcutSettings(shortcuts, platform);
return Object.values(normalized).some((shortcut) => matchesShortcut(event, shortcut, platform));
}
export interface CaretBrowsingBlockOptions {
caretBrowsingEnabled?: boolean;
shortcuts?: Partial<ShortcutSettings>;
}
export function shouldBlockCaretBrowsing(event: ShortcutLikeEvent, options?: CaretBrowsingBlockOptions, platform = globalThis.navigator?.platform || ""): boolean {
if (options?.caretBrowsingEnabled) return false;
if (!isCaretBrowsingShortcut(event)) return false;
if (options?.shortcuts && isConfiguredShortcut(event, options.shortcuts, platform)) return false;
return true;
}
@@ -56,6 +56,12 @@ describe("EDITOR_SETTINGS_DRAFT_KEYS", () => {
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("ddlOpenMode");
});
it("includes caretBrowsingEnabled (#11827)", () => {
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("caretBrowsingEnabled");
const draft = editorSettingsDraftFromSettings(makeSettings({ caretBrowsingEnabled: true } as Partial<EditorSettings>));
expect(draft.caretBrowsingEnabled).toBe(true);
});
it("includes continueOnErrorOnBatch", () => {
expect(EDITOR_SETTINGS_DRAFT_KEYS).toContain("continueOnErrorOnBatch");
});
@@ -75,6 +75,42 @@ describe("settings search", () => {
expect(searchSettings(entries, "line number", "en").map((entry) => entry.id)).toEqual(["editor-line-numbers"]);
});
it("indexes the query editor caret-browsing preference (#11827)", () => {
const definition = SETTINGS_SEARCH_DEFINITIONS.find((entry) => entry.id === "editor-caret-browsing");
expect(definition).toEqual({
id: "editor-caret-browsing",
category: "editor",
titleKey: "settings.caretBrowsing",
descriptionKey: "settings.caretBrowsingDescription",
targetId: "editor",
});
const entries = resolveSettingsSearchEntries(
[definition!],
{ isWeb: false, visibleCategories: new Set<SettingsCategory>(["editor"]) },
(key) =>
({
"settings.caretBrowsing": "光标浏览 (F7)",
"settings.caretBrowsingDescription": "允许按 F7 切换浏览器的插入光标浏览模式",
})[key] ?? key,
categoryLabels,
);
expect(searchSettings(entries, "光标", "zh-CN")).toEqual([
expect.objectContaining({
id: "editor-caret-browsing",
category: "editor",
targetId: "editor",
}),
]);
expect(searchSettings(entries, "F7", "zh-CN")).toEqual([
expect.objectContaining({
id: "editor-caret-browsing",
category: "editor",
targetId: "editor",
}),
]);
});
it("indexes SQL Server space confirmation when SQL Server exists or an exported setting is enabled", () => {
const definition = SETTINGS_SEARCH_DEFINITIONS.find((entry) => entry.id === "editor-sqlserver-space-completion");
expect(definition).toEqual(
@@ -593,4 +593,12 @@ describe("settingsTransfer", () => {
expect(result.value.editorSettings.dataGridCrosshairRowBg).toBe("#232323");
expect(result.value.editorSettings.dataGridCrosshairColBg).toBe("#343434");
});
it("round-trips caretBrowsingEnabled in editor category (#11827)", () => {
expect(transferCategoryForKey("caretBrowsingEnabled")).toBe("editor");
const text = serializeSettingsTransfer({ ...DEFAULT_EDITOR_SETTINGS, caretBrowsingEnabled: true });
const result = parseSettingsTransferFile(text);
expect(result.ok).toBe(true);
if (result.ok) expect(result.value.editorSettings.caretBrowsingEnabled).toBe(true);
});
});
@@ -40,6 +40,7 @@ export const EDITOR_SETTINGS_DRAFT_KEYS = [
"showWhitespace",
"ddlOpenMode",
"vimModeEnabled",
"caretBrowsingEnabled",
"doubleClickStringSelectionMode",
"autoCloseBrackets",
"restoreSqlFromSourcePasteEnabled",
@@ -143,6 +143,7 @@ export const SETTINGS_SEARCH_DEFINITIONS: readonly SettingsSearchDefinition[] =
{ id: "editor-show-whitespace", category: "editor", titleKey: "settings.showWhitespace", descriptionKey: "settings.showWhitespaceDescription", targetId: "editor" },
{ id: "editor-word-wrap", category: "editor", titleKey: "settings.wordWrap", descriptionKey: "settings.wordWrapDescription", targetId: "editor" },
{ id: "editor-vim", category: "editor", titleKey: "settings.vimMode", descriptionKey: "settings.vimModeDescription", targetId: "editor" },
{ id: "editor-caret-browsing", category: "editor", titleKey: "settings.caretBrowsing", descriptionKey: "settings.caretBrowsingDescription", targetId: "editor" },
{ id: "editor-brackets", category: "editor", titleKey: "settings.autoCloseBrackets", descriptionKey: "settings.autoCloseBracketsDescription", targetId: "editor" },
{ id: "editor-source-paste-restore", category: "editor", titleKey: "settings.restoreSqlFromSourcePaste", descriptionKey: "settings.restoreSqlFromSourcePasteDescription", targetId: "editor" },
{ id: "editor-double-click-string", category: "editor", titleKey: "settings.doubleClickStringSelectionMode", descriptionKey: "settings.doubleClickStringSelectionModeDescription", targetId: "editor" },
@@ -95,6 +95,7 @@ const SETTINGS_TRANSFER_CATEGORY_KEYS: Record<SettingsTransferCategoryId, readon
"wordWrap",
"showWhitespace",
"vimModeEnabled",
"caretBrowsingEnabled",
"doubleClickStringSelectionMode",
"autoCloseBrackets",
"restoreSqlFromSourcePasteEnabled",
@@ -50,6 +50,14 @@ describe("normalizeEditorSettings", () => {
expect(normalizeEditorSettings({ webLogoPosition: undefined }).webLogoPosition).toBe("left");
});
it("defaults caretBrowsingEnabled to false and normalizes boolean values (#11827)", () => {
expect(DEFAULT_EDITOR_SETTINGS.caretBrowsingEnabled).toBe(false);
expect(normalizeEditorSettings({}).caretBrowsingEnabled).toBe(false);
expect(normalizeEditorSettings({ caretBrowsingEnabled: true }).caretBrowsingEnabled).toBe(true);
expect(normalizeEditorSettings({ caretBrowsingEnabled: false }).caretBrowsingEnabled).toBe(false);
expect(normalizeEditorSettings({ caretBrowsingEnabled: "true" as any }).caretBrowsingEnabled).toBe(false);
});
it("defaults the welcome page to the workspace overview and honors an explicitly saved intro mode", () => {
expect(DEFAULT_EDITOR_SETTINGS.welcomePageMode).toBe("workspace");
expect(normalizeEditorSettings({}).welcomePageMode).toBe("workspace");
+5
View File
@@ -967,6 +967,8 @@ export interface EditorSettings {
refreshDdlOnOpen: boolean;
excludeDdlStorage: boolean;
vimModeEnabled: boolean;
/** 是否允许按 F7 切换浏览器的插入光标浏览模式(关闭时拦截 F7 避免误触)。 */
caretBrowsingEnabled: boolean;
/** Double click inside a string literal selects the whole value ("content") or a single word ("word"). */
doubleClickStringSelectionMode: DoubleClickStringSelectionMode;
autoCloseBrackets: boolean;
@@ -1328,6 +1330,7 @@ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = {
refreshDdlOnOpen: false,
excludeDdlStorage: true,
vimModeEnabled: false,
caretBrowsingEnabled: false,
doubleClickStringSelectionMode: "content",
autoCloseBrackets: true,
restoreSqlFromSourcePasteEnabled: true,
@@ -1976,6 +1979,7 @@ export function normalizeEditorSettings(settings: Partial<EditorSettings>, exist
ddlOpenMode: settings.ddlOpenMode === "tab" ? "tab" : DEFAULT_EDITOR_SETTINGS.ddlOpenMode,
refreshDdlOnOpen: typeof settings.refreshDdlOnOpen === "boolean" ? settings.refreshDdlOnOpen : DEFAULT_EDITOR_SETTINGS.refreshDdlOnOpen,
vimModeEnabled: typeof settings.vimModeEnabled === "boolean" ? settings.vimModeEnabled : DEFAULT_EDITOR_SETTINGS.vimModeEnabled,
caretBrowsingEnabled: typeof settings.caretBrowsingEnabled === "boolean" ? settings.caretBrowsingEnabled : DEFAULT_EDITOR_SETTINGS.caretBrowsingEnabled,
doubleClickStringSelectionMode: normalizeDoubleClickStringSelectionMode(settings.doubleClickStringSelectionMode),
autoCloseBrackets: typeof settings.autoCloseBrackets === "boolean" ? settings.autoCloseBrackets : DEFAULT_EDITOR_SETTINGS.autoCloseBrackets,
restoreSqlFromSourcePasteEnabled: typeof settings.restoreSqlFromSourcePasteEnabled === "boolean" ? settings.restoreSqlFromSourcePasteEnabled : DEFAULT_EDITOR_SETTINGS.restoreSqlFromSourcePasteEnabled,
@@ -2855,6 +2859,7 @@ export const useSettingsStore = defineStore("settings", () => {
if (partial.ddlOpenMode !== undefined) editorSettings.value.ddlOpenMode = partial.ddlOpenMode === "tab" ? "tab" : "dialog";
if (partial.refreshDdlOnOpen !== undefined) editorSettings.value.refreshDdlOnOpen = partial.refreshDdlOnOpen === true;
if (partial.vimModeEnabled !== undefined) editorSettings.value.vimModeEnabled = partial.vimModeEnabled === true;
if (partial.caretBrowsingEnabled !== undefined) editorSettings.value.caretBrowsingEnabled = partial.caretBrowsingEnabled === true;
if (partial.doubleClickStringSelectionMode !== undefined) editorSettings.value.doubleClickStringSelectionMode = normalizeDoubleClickStringSelectionMode(partial.doubleClickStringSelectionMode);
if (partial.autoCloseBrackets !== undefined) editorSettings.value.autoCloseBrackets = partial.autoCloseBrackets === true;
if (partial.restoreSqlFromSourcePasteEnabled !== undefined) editorSettings.value.restoreSqlFromSourcePasteEnabled = partial.restoreSqlFromSourcePasteEnabled === true;