Stop folder collapsing without touching css styles

This commit is contained in:
Lost Paul 2025-06-16 15:03:31 +02:00
parent 1d55c4117c
commit 18e1f4dc45
5 changed files with 71 additions and 108 deletions

View file

@ -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;

View file

@ -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();
}

View file

@ -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

View file

@ -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');

View file

@ -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);