From 18e1f4dc45138802ae7fb3cb95b3a8b3f4a26b92 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Mon, 16 Jun 2025 15:03:31 +0200 Subject: [PATCH] Stop folder collapsing without touching css styles --- src/events/MutationObserver.ts | 8 +-- src/events/handleClick.ts | 54 ------------------- src/functions/folderNoteFunctions.ts | 2 +- src/main.ts | 81 +++++++++++++++++++++++----- styles.css | 34 ------------ 5 files changed, 71 insertions(+), 108 deletions(-) diff --git a/src/events/MutationObserver.ts b/src/events/MutationObserver.ts index ba749a0..c2c71a3 100644 --- a/src/events/MutationObserver.ts +++ b/src/events/MutationObserver.ts @@ -1,7 +1,7 @@ import { Keymap, Platform } from 'obsidian'; import FolderNotesPlugin from 'src/main'; import { getFolderNote } from 'src/functions/folderNoteFunctions'; -import { handleFolderClick, handleViewHeaderClick } from './handleClick'; +import { handleViewHeaderClick } from './handleClick'; import { getExcludedFolder } from 'src/ExcludeFolders/functions/folderFunctions'; import { applyCSSClassesToFolder } from 'src/functions/styleFunctions'; @@ -122,12 +122,6 @@ async function setupFolderTitle(folderTitle: HTMLElement, plugin: FolderNotesPlu if (Platform.isMobile && plugin.settings.disableOpenFolderNoteOnClick) return; - folderTitle.addEventListener('auxclick', (event: MouseEvent) => { - if (event.button === 1) handleFolderClick(event, plugin); - }, { capture: true }); - - folderTitle.onclick = (event: MouseEvent) => handleFolderClick(event, plugin); - plugin.registerDomEvent(folderTitle, 'pointerover', (event: MouseEvent) => { plugin.hoveredElement = folderTitle; plugin.mouseEvent = event; diff --git a/src/events/handleClick.ts b/src/events/handleClick.ts index 208cc44..91c6617 100644 --- a/src/events/handleClick.ts +++ b/src/events/handleClick.ts @@ -46,57 +46,3 @@ export async function handleViewHeaderClick(event: MouseEvent, plugin: FolderNot event.target.onclick = null; event.target.click(); } - -export async function handleFolderClick(event: MouseEvent, plugin: FolderNotesPlugin) { - if (!(event.target instanceof HTMLElement)) return; - event.target.setAttribute('data-initialized', 'false'); - if (!event || !event.target) return; - - if (!event.shiftKey) { - event.stopImmediatePropagation(); - } else { - return; - } - - const folderPath = event.target.parentElement?.getAttribute('data-path'); - if (!folderPath) { return; } - - const excludedFolder = getExcludedFolder(plugin, folderPath, true); - if (excludedFolder?.disableFolderNote) { - event.target.onclick = null; - event.target.click(); - return; - } else if (excludedFolder?.enableCollapsing || plugin.settings.enableCollapsing) { - event.target.onclick = null; - event.target.click(); - } - - const folderNote = getFolderNote(plugin, folderPath); - - if (folderNote) { - if (plugin.settings.openByClick) { - return openFolderNote(plugin, folderNote, event); - } else if (plugin.settings.openWithCtrl && Keymap.isModEvent(event) === 'tab') { - return openFolderNote(plugin, folderNote, event); - } else if (plugin.settings.openWithAlt && event.altKey) { - return openFolderNote(plugin, folderNote, event); - } else { - if (plugin.settings.enableCollapsing) return; - event.target.parentElement?.click(); - return; - } - } else if (event.altKey || Keymap.isModEvent(event) === 'tab') { - if ((plugin.settings.altKey && event.altKey) || (plugin.settings.ctrlKey && Keymap.isModEvent(event) === 'tab')) { - await createFolderNote(plugin, folderPath, true, undefined, true); - addCSSClassToTitleEL(folderPath, 'has-folder-note', plugin); - removeCSSClassFromEL(folderPath, 'has-not-folder-note', plugin); - return; - } - } else if (!folderNote) { - if (plugin.settings.enableCollapsing) return; - return event.target.parentElement?.click(); - } - - event.target.onclick = null; - event.target.click(); -} diff --git a/src/functions/folderNoteFunctions.ts b/src/functions/folderNoteFunctions.ts index 89f73fe..fe8eb9b 100644 --- a/src/functions/folderNoteFunctions.ts +++ b/src/functions/folderNoteFunctions.ts @@ -223,7 +223,7 @@ export async function tempDisableSync(plugin: FolderNotesPlugin, folder: TFolder export async function openFolderNote(plugin: FolderNotesPlugin, file: TAbstractFile, evt?: MouseEvent) { const path = file.path; - const focusExistingTab = plugin.settings.focusExistingTab; + const focusExistingTab = plugin.settings.focusExistingTab && plugin.settings.openInNewTab; const activeFilePath = plugin.app.workspace.getActiveFile()?.path; // If already active and not opening in new tab, do nothing diff --git a/src/main.ts b/src/main.ts index 0e0c851..990387a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,11 @@ -import { Plugin, TFile, TFolder, TAbstractFile, MarkdownPostProcessorContext, parseYaml, Notice, Keymap, WorkspaceLeaf, requireApiVersion } from 'obsidian'; +import { Plugin, TFile, TFolder, TAbstractFile, MarkdownPostProcessorContext, parseYaml, Notice, Keymap, WorkspaceLeaf, requireApiVersion, Platform } from 'obsidian'; import { DEFAULT_SETTINGS, FolderNotesSettings, SettingsTab } from './settings/SettingsTab'; import { Commands } from './Commands'; import { FileExplorerWorkspaceLeaf } from './globals'; -import { handleFolderClick } from './events/handleClick'; import { registerFileExplorerObserver, unregisterFileExplorerObserver } from './events/MutationObserver'; import { handleRename } from './events/handleRename'; -import { getFolderNote, getFolder, openFolderNote } from './functions/folderNoteFunctions'; +import { getFolderNote, getFolder, openFolderNote, createFolderNote } from './functions/folderNoteFunctions'; import { handleCreate } from './events/handleCreate'; import { FrontMatterTitlePluginHandler } from './events/FrontMatterTitle'; import { FolderOverviewSettings } from './obsidian-folder-overview/src/modals/Settings'; @@ -14,7 +13,7 @@ import { FolderOverview } from './obsidian-folder-overview/src/FolderOverview'; import { TabManager } from './events/TabManager'; import './functions/ListComponent'; import { handleDelete } from './events/handleDelete'; -import { addCSSClassToTitleEL, getEl, updateAllFileStyles } from './functions/styleFunctions'; +import { addCSSClassToTitleEL, getEl, removeCSSClassFromEL, updateAllFileStyles } from './functions/styleFunctions'; import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import { FileExplorerView, InternalPlugin } from 'obsidian-typings'; import { getFocusedItem } from './functions/utils'; @@ -139,6 +138,19 @@ export default class FolderNotesPlugin extends Plugin { this.registerMarkdownCodeBlockProcessor('folder-overview', (source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) => { this.handleOverviewBlock(source, el, ctx); }); + + this.registerEvent( + this.app.workspace.on('layout-change', () => { + const fileExplorerLeaf = this.app.workspace.getLeavesOfType('file-explorer')[0]; + if (!fileExplorerLeaf) return; + const container = fileExplorerLeaf.view.containerEl; + if (container) { + this.registerDomEvent(container, 'click', (evt: MouseEvent) => { + this.handleFileExplorerClick(evt); + }, true); + } + }) + ); } onLayoutReady() { @@ -152,6 +164,16 @@ export default class FolderNotesPlugin extends Plugin { this.tabManager = new TabManager(this); this.tabManager.updateTabs(); + const fileExplorerLeaf = this.app.workspace.getLeavesOfType('file-explorer')[0]; + if (fileExplorerLeaf) { + const container = fileExplorerLeaf.view.containerEl; + if (container) { + this.registerDomEvent(container, 'click', (evt: MouseEvent) => { + this.handleFileExplorerClick(evt); + }, true); + } + } + const fileExplorerPlugin = this.app.internalPlugins.getEnabledPluginById('file-explorer'); if (fileExplorerPlugin) { const originalRevealInFolder = fileExplorerPlugin.revealInFolder.bind(fileExplorerPlugin); @@ -219,6 +241,49 @@ export default class FolderNotesPlugin extends Plugin { }; } + handleFileExplorerClick(evt: MouseEvent) { + const target = evt.target as HTMLElement; + if (evt.shiftKey) return; + + if (Platform.isMobile && this.settings.disableOpenFolderNoteOnClick) return; + + // Check if the click is on a folder + const folderTitleEl = target.closest('.nav-folder-title') as HTMLElement; + if (!folderTitleEl) return; + + const onlyClickedOnFolderTitle = !!target.closest('.nav-folder-title-content'); + if (!this.settings.stopWhitespaceCollapsing && !onlyClickedOnFolderTitle) return; + + // Ignore clicks on the collapse icon + if (target.closest('.collapse-icon')) return; + + const folderPath = folderTitleEl.getAttribute('data-path'); + if (!folderPath) return; + + const excludedFolder = getExcludedFolder(this, folderPath, true); + if (excludedFolder?.disableFolderNote) return; + + const folderNote = getFolderNote(this, folderPath); + if (!folderNote && (evt.altKey || Keymap.isModEvent(evt) === 'tab')) { + if ((this.settings.altKey && evt.altKey) || (this.settings.ctrlKey && Keymap.isModEvent(evt) === 'tab')) { + createFolderNote(this, folderPath, true, undefined, true); + addCSSClassToTitleEL(folderPath, 'has-folder-note', this); + removeCSSClassFromEL(folderPath, 'has-not-folder-note', this); + return; + } + } + if (!(folderNote instanceof TFile)) return; + + if (this.settings.openWithCtrl && !evt.ctrlKey) return; + if (this.settings.openWithAlt && !evt.altKey) return; + + if (!this.settings.enableCollapsing) { + evt.preventDefault(); + evt.stopImmediatePropagation(); + } + + openFolderNote(this, folderNote, evt); + } handleOverviewBlock(source: string, el: HTMLElement, ctx: MarkdownPostProcessorContext) { const observer = new MutationObserver(() => { @@ -358,14 +423,6 @@ export default class FolderNotesPlugin extends Plugin { }); } - reloadHandlers() { - document.querySelectorAll('div.nav-folder-title-content') - .forEach((element: HTMLElement) => { - if (element.onclick) return; - element.onclick = (event: MouseEvent) => handleFolderClick(event, this); - }); - } - onunload() { unregisterFileExplorerObserver(); document.body.classList.remove('folder-notes-plugin'); diff --git a/styles.css b/styles.css index a7a0f85..ce65659 100644 --- a/styles.css +++ b/styles.css @@ -1,37 +1,3 @@ - - -.fn-whitespace-stop-collapsing .nav-folder-title-content { - flex-grow: 1 !important; - display: flex; - padding-bottom: 4px !important; - padding-top: 4px !important; -} - -.version-1-7-2.fn-whitespace-stop-collapsing .nav-files-container .collapse-icon { - padding-top: 4px !important; -} - -.mod-rtl .fn-whitespace-stop-collapsing .nav-folder-title-content { - padding-left: 8px !important; -} - -.fn-whitespace-stop-collapsing .nav-folder-title { - padding-bottom: 0 !important; - padding-top: 0 !important; -} - -body:not(.mod-rtl).fn-whitespace-stop-collapsing .nav-folder-title { - padding-right: 0 !important; -} - -.mod-rtl.fn-whitespace-stop-collapsing .nav-folder-title { - padding-left: 0 !important; -} - -.fn-whitespace-stop-collapsing .nav-folder-collapse-indicator { - margin-top: 4px !important; -} - body:not(.is-grabbing) .tree-item-self.fn-is-active:hover, body:not(.disable-folder-highlight) .tree-item-self.fn-is-active { color: var(--nav-item-color-active);