Last active
September 24, 2021 00:20
-
-
Save nathonius/d481232ce04b73099803562846f9792b to your computer and use it in GitHub Desktop.
collapse plugin with tag support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP | |
if you want to view the source visit the plugins github repository | |
*/ | |
'use strict'; | |
var obsidian = require('obsidian'); | |
/*! ***************************************************************************** | |
Copyright (c) Microsoft Corporation. | |
Permission to use, copy, modify, and/or distribute this software for any | |
purpose with or without fee is hereby granted. | |
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH | |
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, | |
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM | |
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR | |
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |
PERFORMANCE OF THIS SOFTWARE. | |
***************************************************************************** */ | |
function __awaiter(thisArg, _arguments, P, generator) { | |
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | |
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | |
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | |
step((generator = generator.apply(thisArg, _arguments || [])).next()); | |
}); | |
} | |
const COLLAPSE_ALL_ICON = '<svg viewBox="0 0 100 100" class="double-up-arrow-glyph" width="18" height="18"><path fill="currentColor" stroke="currentColor" d="M49.9,16.7c-0.9,0-1.7,0.4-2.3,1L14.3,51c-0.9,0.8-1.2,2.1-0.9,3.2c0.3,1.2,1.2,2.1,2.4,2.4s2.4,0,3.2-0.9l31-31l31,31 c0.8,0.9,2.1,1.2,3.2,0.9c1.2-0.3,2.1-1.2,2.4-2.4s0-2.4-0.9-3.2L52.4,17.6C51.7,17,50.8,16.7,49.9,16.7L49.9,16.7z M49.9,40 c-0.9,0-1.7,0.4-2.3,1L14.3,74.3c-0.9,0.8-1.2,2.1-0.9,3.2c0.3,1.2,1.2,2.1,2.4,2.4s2.4,0,3.2-0.9l31-31l31,31 c0.8,0.9,2.1,1.2,3.2,0.9c1.2-0.3,2.1-1.2,2.4-2.4c0.3-1.2,0-2.4-0.9-3.2L52.4,41C51.7,40.3,50.8,40,49.9,40L49.9,40z"></path></svg>'; | |
const EXPAND_ALL_ICON = '<svg viewBox="0 0 100 100" class="double-down-arrow-glyph" width="18" height="18"><path fill="currentColor" stroke="currentColor" d="M83.3,20c-0.9,0-1.7,0.4-2.3,1L50,52L19,21c-0.6-0.6-1.5-1-2.4-1c-1.4,0-2.6,0.8-3.1,2.1c-0.5,1.3-0.2,2.7,0.8,3.6 L47.6,59c1.3,1.3,3.4,1.3,4.7,0l33.3-33.3c1-1,1.3-2.4,0.8-3.7C85.9,20.7,84.7,19.9,83.3,20z M83.3,43.3c-0.9,0-1.7,0.4-2.3,1 l-31,31l-31-31c-0.6-0.6-1.5-1-2.4-1c-1.4,0-2.6,0.8-3.1,2.1s-0.2,2.7,0.8,3.6l33.3,33.3c1.3,1.3,3.4,1.3,4.7,0L85.7,49 c1-1,1.3-2.4,0.8-3.7C85.9,44.1,84.7,43.3,83.3,43.3L83.3,43.3z"></path></svg>'; | |
class ItemProviderBase { | |
constructor(plugin) { | |
this.plugin = plugin; | |
} | |
/** | |
* Collapse all open items in the given leaf or all leaves | |
*/ | |
collapseAll(leaf) { | |
const leaves = leaf ? [leaf] : this.leaves; | |
leaves.forEach((leaf) => { | |
this.collapseOrExpandAll(leaf, true); | |
this.updateButtonIcon(leaf, undefined, true); | |
}); | |
} | |
/** | |
* Expand all collapsed items in the given leaf or all leaves | |
*/ | |
expandAll(leaf) { | |
const leaves = leaf ? [leaf] : this.leaves; | |
leaves.forEach((leaf) => { | |
this.collapseOrExpandAll(leaf, false); | |
this.updateButtonIcon(leaf, undefined, false); | |
}); | |
} | |
/** | |
* Adds collapse buttons to all leaves. | |
*/ | |
addCollapseButtons() { | |
this.leaves.forEach((leaf) => { | |
const container = leaf.view.containerEl; | |
const navContainer = container.querySelector('div.nav-buttons-container'); | |
if (!navContainer) { | |
return null; | |
} | |
const existingButton = this.getCollapseButton(leaf); | |
if (existingButton) { | |
return; | |
} | |
const newIcon = document.createElement('div'); | |
this.updateButtonIcon(leaf, newIcon); | |
newIcon.className = `${this.collapseButtonClass} collapse-all-plugin-button`; | |
this.plugin.registerDomEvent(newIcon, 'click', () => { | |
this.onButtonClick(leaf); | |
}); | |
navContainer.appendChild(newIcon); | |
// Register click handler on leaf to toggle button icon | |
const handler = () => { | |
this.updateButtonIcon(leaf, newIcon); | |
}; | |
leaf.view.containerEl.on('click', this.collapseClickTarget, handler); | |
this.plugin.register(() => { | |
leaf.view.containerEl.off('click', this.collapseClickTarget, handler); | |
}); | |
}); | |
} | |
/** | |
* Refresh icons for all leaves to the correct state. | |
*/ | |
updateButtonIcons() { | |
this.leaves.forEach((leaf) => { | |
this.updateButtonIcon(leaf); | |
}); | |
} | |
/** | |
* Remove the collapse button from all leaves. | |
*/ | |
removeCollapseButtons() { | |
this.leaves.forEach((leaf) => { | |
const button = this.getCollapseButton(leaf); | |
if (button) { | |
button.remove(); | |
} | |
}); | |
} | |
/** | |
* Returns all loaded leaves of the class leafType | |
*/ | |
get leaves() { | |
return this.plugin.app.workspace.getLeavesOfType(this.leafType); | |
} | |
/** | |
* Get the collapse button for a given leaf, if it exists | |
*/ | |
getCollapseButton(leaf) { | |
return leaf.view.containerEl.querySelector('.collapse-all-plugin-button'); | |
} | |
/** | |
* Update icon for given leaf/button to collapse/expand all. | |
* Providing the forceAllCollapsed parameter will skip checking and assume that state | |
*/ | |
updateButtonIcon(leaf, button, forceAllCollapsed) { | |
if (!button) { | |
button = this.getCollapseButton(leaf); | |
} | |
if (button && forceAllCollapsed === undefined) { | |
const allCollapsed = this.allCollapsed(leaf); | |
button.innerHTML = allCollapsed ? EXPAND_ALL_ICON : COLLAPSE_ALL_ICON; | |
button.setAttribute('aria-label', allCollapsed ? 'Expand all' : 'Collapse all'); | |
} | |
else if (button) { | |
button.innerHTML = forceAllCollapsed | |
? EXPAND_ALL_ICON | |
: COLLAPSE_ALL_ICON; | |
button.setAttribute('aria-label', forceAllCollapsed ? 'Expand all' : 'Collapse all'); | |
} | |
} | |
/** | |
* Collapses or expands all items in the given leaf | |
*/ | |
onButtonClick(leaf) { | |
if (leaf) { | |
if (this.allCollapsed(leaf)) { | |
this.expandAll(leaf); | |
} | |
else { | |
this.collapseAll(leaf); | |
} | |
} | |
} | |
} | |
class FileExplorerProvider extends ItemProviderBase { | |
constructor(plugin) { | |
super(plugin); | |
this.collapseButtonClass = 'nav-action-button'; | |
this.collapseClickTarget = '.nav-folder-title'; | |
this.leafType = 'file-explorer'; | |
} | |
collapseOrExpandAll(leaf, collapsed) { | |
const items = this.getExplorerItems(leaf); | |
items.forEach((item) => { | |
if (this.explorerItemIsFolder(item) && item.collapsed !== collapsed) { | |
item.setCollapsed(collapsed); | |
} | |
}); | |
} | |
allCollapsed(leaf) { | |
return this.foldersAreCollapsed(this.getExplorerItems(leaf)); | |
} | |
/** | |
* Get all `fileItems` on explorer view. This property is not documented. | |
*/ | |
getExplorerItems(leaf) { | |
return Object.values(leaf.view.fileItems); | |
} | |
/** | |
* Ensures given explorer item is a folder and not the root or a note | |
*/ | |
explorerItemIsFolder(item) { | |
return (item.file instanceof obsidian.TFolder && | |
item.file.path !== '/' && | |
item.collapsed !== undefined); | |
} | |
/** | |
* Returns true if every folder in the given items (files and folders) is collapsed | |
*/ | |
foldersAreCollapsed(items) { | |
return items.every((i) => !this.explorerItemIsFolder(i) || i.collapsed === true); | |
} | |
} | |
class TagPaneProvider extends ItemProviderBase { | |
constructor(plugin) { | |
super(plugin); | |
this.collapseButtonClass = 'nav-action-button'; | |
this.collapseClickTarget = '.tag-container .tree-item'; | |
this.leafType = 'tag'; | |
} | |
collapseOrExpandAll(leaf, collapsed) { | |
const items = this.getTagItems(leaf); | |
this.collapseTags(items, collapsed); | |
} | |
allCollapsed(leaf) { | |
return this.tagsAreCollapsed(this.getTagItems(leaf)); | |
} | |
collapseTags(tagItems, collapsed) { | |
tagItems.forEach((i) => { | |
if (this.tagPaneItemHasChildren(i)) { | |
requestAnimationFrame(() => { | |
this.collapseTags(i.children, collapsed); | |
}); | |
} | |
i.setCollapsed(collapsed); | |
}); | |
} | |
/** | |
* Get the root tag pane items from the tag pane view. This property is not documented. | |
*/ | |
getTagItems(tagPane) { | |
return tagPane.view.root.children; | |
} | |
/** | |
* Returns true if this item has children | |
*/ | |
tagPaneItemHasChildren(item) { | |
return item.children && item.children.length > 0; | |
} | |
/** | |
* Given the root tags, checks all children to confirm they are closed. Note that this is recursive. | |
*/ | |
tagsAreCollapsed(items) { | |
return items.every((i) => !this.tagPaneItemHasChildren(i) || | |
(i.collapsed === true && this.tagsAreCollapsed(i.children))); | |
} | |
} | |
class CollapseAllPlugin extends obsidian.Plugin { | |
constructor() { | |
super(...arguments); | |
this.fileExplorerProvider = new FileExplorerProvider(this); | |
this.tagPaneProvider = new TagPaneProvider(this); | |
} | |
onload() { | |
return __awaiter(this, void 0, void 0, function* () { | |
// Initialize | |
this.app.workspace.onLayoutReady(() => { | |
this.fileExplorerProvider.addCollapseButtons(); | |
this.tagPaneProvider.addCollapseButtons(); | |
}); | |
// Leaves that get opened later on | |
this.registerEvent(this.app.workspace.on('layout-change', () => { | |
this.fileExplorerProvider.addCollapseButtons(); | |
this.tagPaneProvider.addCollapseButtons(); | |
})); | |
// Update icon when files are opened | |
this.registerEvent(this.app.workspace.on('file-open', () => { | |
this.fileExplorerProvider.updateButtonIcons(); | |
this.tagPaneProvider.updateButtonIcons(); | |
})); | |
// Add collapse command to palette | |
this.addCommand({ | |
id: 'collapse-all-collapse', | |
name: 'Collapse all open folders in all file explorers', | |
icon: 'double-up-arrow-glyph', | |
callback: () => { | |
this.fileExplorerProvider.collapseAll(); | |
} | |
}); | |
// Add expand command to palette | |
this.addCommand({ | |
id: 'collapse-all-expand', | |
name: 'Expand closed folders in all file explorers', | |
icon: 'double-down-arrow-glyph', | |
callback: () => { | |
this.fileExplorerProvider.expandAll(); | |
} | |
}); | |
}); | |
} | |
onunload() { | |
// Remove all collapse buttons | |
this.fileExplorerProvider.removeCollapseButtons(); | |
this.tagPaneProvider.removeCollapseButtons(); | |
} | |
} | |
module.exports = CollapseAllPlugin; | |
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9jb25zdGFudHMudHMiLCJzcmMvaXRlbS1wcm92aWRlci9iYXNlLnRzIiwic3JjL2l0ZW0tcHJvdmlkZXIvZmlsZS1leHBsb3Jlci50cyIsInNyYy9pdGVtLXByb3ZpZGVyL3RhZy1wYW5lLnRzIiwic3JjL3BsdWdpbi50cyJdLCJzb3VyY2VzQ29udGVudCI6bnVsbCwibmFtZXMiOlsiVEZvbGRlciIsIlBsdWdpbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQXVEQTtBQUNPLFNBQVMsU0FBUyxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRTtBQUM3RCxJQUFJLFNBQVMsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLE9BQU8sS0FBSyxZQUFZLENBQUMsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsVUFBVSxPQUFPLEVBQUUsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRTtBQUNoSCxJQUFJLE9BQU8sS0FBSyxDQUFDLEtBQUssQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLFVBQVUsT0FBTyxFQUFFLE1BQU0sRUFBRTtBQUMvRCxRQUFRLFNBQVMsU0FBUyxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7QUFDbkcsUUFBUSxTQUFTLFFBQVEsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMs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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment