template-obsidian-vault/.obsidian/plugins/folder-notes/main.js

5907 lines
236 KiB
JavaScript

/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js
var require_Api = __commonJS({
"node_modules/front-matter-plugin-api-provider/lib/contracts/Api.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
}
});
// node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js
var require_EventDispatcher = __commonJS({
"node_modules/front-matter-plugin-api-provider/lib/contracts/EventDispatcher.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
}
});
// node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js
var require_Resolver = __commonJS({
"node_modules/front-matter-plugin-api-provider/lib/contracts/Resolver.js"(exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
}
});
// node_modules/front-matter-plugin-api-provider/lib/index.js
var require_lib = __commonJS({
"node_modules/front-matter-plugin-api-provider/lib/index.js"(exports) {
"use strict";
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === void 0)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getApiSafe = exports.getDefer = exports.isPluginEnabled = exports.PluginNotEnabledError = exports.pluginId = void 0;
__exportStar(require_Api(), exports);
__exportStar(require_EventDispatcher(), exports);
__exportStar(require_Resolver(), exports);
exports.pluginId = "obsidian-front-matter-title-plugin";
var PluginNotEnabledError = class extends Error {
};
exports.PluginNotEnabledError = PluginNotEnabledError;
function isPluginEnabled(app2) {
var _a, _b, _c;
return (_c = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.enabledPlugins) === null || _b === void 0 ? void 0 : _b.has(exports.pluginId)) !== null && _c !== void 0 ? _c : false;
}
exports.isPluginEnabled = isPluginEnabled;
function getDefer2(app2) {
var _a, _b, _c, _d;
const plugin = (_b = (_a = app2 === null || app2 === void 0 ? void 0 : app2.plugins) === null || _a === void 0 ? void 0 : _a.getPlugin(exports.pluginId)) !== null && _b !== void 0 ? _b : null;
const defer = (_d = (_c = plugin === null || plugin === void 0 ? void 0 : plugin.getDefer) === null || _c === void 0 ? void 0 : _c.call(plugin)) !== null && _d !== void 0 ? _d : null;
if (defer === null) {
throw new PluginNotEnabledError(`Plugin ${exports.pluginId} is not enabled or old version`);
}
return defer;
}
exports.getDefer = getDefer2;
function getApiSafe(app2) {
return new ApiWrapper(null, app2);
}
exports.getApiSafe = getApiSafe;
var ApiWrapper = class {
constructor(api, app2) {
this.api = api;
this.app = app2;
}
before() {
if (this.api !== null) {
return;
}
const defer = this.getDeffer();
if (defer === null) {
return;
}
const api = defer.getApi();
if (api === null) {
return defer.awaitPlugin().then(() => {
this.api = defer.getApi();
});
} else {
this.api = api;
}
}
getDeffer() {
try {
return getDefer2(this.app);
} catch (e) {
if (e instanceof PluginNotEnabledError) {
return null;
}
throw e;
}
}
getResolverFactory() {
var _a, _b;
this.before();
return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getResolverFactory()) !== null && _b !== void 0 ? _b : null;
}
getEventDispatcher() {
var _a, _b;
this.before();
return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEventDispatcher()) !== null && _b !== void 0 ? _b : null;
}
getEnabledFeatures() {
var _a, _b;
this.before();
return (_b = (_a = this.api) === null || _a === void 0 ? void 0 : _a.getEnabledFeatures()) !== null && _b !== void 0 ? _b : [];
}
};
}
});
// src/main.ts
var main_exports = {};
__export(main_exports, {
default: () => FolderNotesPlugin
});
module.exports = __toCommonJS(main_exports);
var import_obsidian33 = require("obsidian");
// src/settings/SettingsTab.ts
var import_obsidian24 = require("obsidian");
// src/modals/ExistingNote.ts
var import_obsidian = require("obsidian");
var ExistingFolderNoteModal = class extends import_obsidian.Modal {
constructor(app2, plugin, file, folder, folderNote) {
super(app2);
this.plugin = plugin;
this.app = app2;
this.file = file;
this.folder = folder;
this.folderNote = folderNote;
}
onOpen() {
var _a;
const { contentEl } = this;
contentEl.createEl("h2", { text: "A folder note for this folder already exists" });
const setting = new import_obsidian.Setting(contentEl);
setting.infoEl.createEl("p", { text: "Are you sure you want to turn the note into a folder note and rename the existing folder note?" });
(_a = setting.infoEl.parentElement) == null ? void 0 : _a.classList.add("fn-delete-confirmation-modal");
const buttonContainer = setting.infoEl.createEl("div", { cls: "fn-delete-confirmation-modal-buttons" });
if (import_obsidian.Platform.isMobileApp) {
const confirmButton = buttonContainer.createEl("button", { text: "Rename and don't ask again" });
confirmButton.classList.add("mod-warning", "fn-confirmation-modal-button");
confirmButton.addEventListener("click", async () => {
this.plugin.settings.showRenameConfirmation = false;
this.plugin.saveSettings();
this.close();
turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true);
});
} else {
const checkbox = buttonContainer.createEl("input", { type: "checkbox" });
checkbox.addEventListener("change", (e) => {
const target = e.target;
if (target.checked) {
this.plugin.settings.showRenameConfirmation = false;
} else {
this.plugin.settings.showRenameConfirmation = true;
}
});
const checkBoxText = buttonContainer.createEl("span", { text: "Don't ask again" });
checkBoxText.addEventListener("click", () => {
checkbox.click();
});
}
const button = buttonContainer.createEl("button", { text: "Rename" });
button.classList.add("mod-warning", "fn-confirmation-modal-button");
button.addEventListener("click", async () => {
this.plugin.saveSettings();
this.close();
turnIntoFolderNote(this.plugin, this.file, this.folder, this.folderNote, true);
});
button.focus();
const cancelButton = buttonContainer.createEl("button", { text: "Cancel" });
cancelButton.addEventListener("click", async () => {
this.close();
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/template.ts
var import_obsidian2 = require("obsidian");
async function applyTemplate(plugin, file, leaf, templatePath) {
const templateFile = templatePath ? plugin.app.vault.getAbstractFileByPath(templatePath) : null;
if (templateFile && templateFile instanceof import_obsidian2.TFile) {
try {
const {
templatesEnabled,
templaterEnabled,
templatesPlugin,
templaterPlugin
} = getTemplatePlugins(plugin.app);
const templateContent = await plugin.app.vault.read(templateFile);
if (templateContent.includes("==\u26A0 Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. \u26A0==")) {
return;
}
if (templatesEnabled && templaterEnabled) {
if (/<%/.test(templateContent)) {
return await templaterPlugin.write_template_to_file(templateFile, file);
} else {
if (leaf instanceof import_obsidian2.WorkspaceLeaf) {
leaf.openFile(file).then(async () => {
return await templatesPlugin.instance.insertTemplate(templateFile, file);
});
}
}
}
if (templatesEnabled) {
if (leaf instanceof import_obsidian2.WorkspaceLeaf) {
leaf.openFile(file);
}
return await templatesPlugin.instance.insertTemplate(templateFile);
}
if (templaterEnabled) {
return await templaterPlugin.write_template_to_file(templateFile, file);
}
} catch (e) {
console.error(e);
}
}
}
function getTemplatePlugins(app2) {
var _a;
const templatesPlugin = app2.internalPlugins.plugins.templates;
const templatesEnabled = templatesPlugin.enabled;
const templaterPlugin = app2.plugins.plugins["templater-obsidian"];
const templaterEnabled = app2.plugins.enabledPlugins.has("templater-obsidian");
const templaterEmptyFileTemplate = templaterPlugin && ((_a = this.app.plugins.plugins["templater-obsidian"].settings) == null ? void 0 : _a.empty_file_template);
const templateFolder = templatesEnabled ? templatesPlugin.instance.options.folder : templaterPlugin ? templaterPlugin.settings.template_folder : void 0;
return {
templatesPlugin,
templatesEnabled,
templaterPlugin: templaterPlugin == null ? void 0 : templaterPlugin.templater,
templaterEnabled,
templaterEmptyFileTemplate,
templateFolder
};
}
// src/functions/folderNoteFunctions.ts
var import_obsidian12 = require("obsidian");
// src/modals/DeleteConfirmation.ts
var import_obsidian3 = require("obsidian");
var DeleteConfirmationModal = class extends import_obsidian3.Modal {
constructor(app2, plugin, file) {
super(app2);
this.plugin = plugin;
this.app = app2;
this.file = file;
}
onOpen() {
const { contentEl, plugin } = this;
const modalTitle = contentEl.createDiv({ cls: "fn-modal-title" });
const modalContent = contentEl.createDiv({ cls: "fn-modal-content" });
modalTitle.createEl("h2", { text: "Delete folder note" });
modalContent.createEl("p", { text: `Are you sure you want to delete the folder note "${this.file.name}" ?` });
switch (plugin.settings.deleteFilesAction) {
case "trash":
modalContent.createEl("p", { text: "It will be moved to your system trash." });
break;
case "obsidianTrash":
modalContent.createEl("p", { text: 'It will be moved to your Obsidian trash, which is located in the ".trash" hidden folder in your vault.' });
break;
case "delete":
modalContent.createEl("p", { text: "It will be permanently deleted." }).setCssStyles({ color: "red" });
break;
}
const buttonContainer = contentEl.createEl("div", { cls: "modal-button-container" });
if (!import_obsidian3.Platform.isMobile) {
const checkbox = buttonContainer.createEl("label", { cls: "mod-checkbox" });
checkbox.tabIndex = -1;
const input = checkbox.createEl("input", { type: "checkbox" });
checkbox.appendText("Don't ask again");
input.addEventListener("change", (e) => {
const target = e.target;
if (target.checked) {
plugin.settings.showDeleteConfirmation = false;
} else {
plugin.settings.showDeleteConfirmation = true;
}
plugin.saveSettings();
});
} else {
const confirmButton = buttonContainer.createEl("button", { text: "Delete and don't ask again", cls: "mod-destructive" });
confirmButton.addEventListener("click", async () => {
plugin.settings.showDeleteConfirmation = false;
plugin.saveSettings();
this.close();
deleteFolderNote(plugin, this.file, false);
});
}
const deleteButton = buttonContainer.createEl("button", { text: "Delete", cls: "mod-warning" });
deleteButton.addEventListener("click", async () => {
this.close();
deleteFolderNote(plugin, this.file, false);
});
deleteButton.focus();
const cancelButton = buttonContainer.createEl("button", { text: "Cancel", cls: "mod-cancel" });
cancelButton.addEventListener("click", async () => {
this.close();
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/functions/utils.ts
function getFileNameFromPathString(path) {
return path.substring(path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") + 1 : 0);
}
function getFolderNameFromPathString(path) {
if (path.endsWith(".md") || path.endsWith(".canvas")) {
return path.split("/").slice(-2)[0];
} else {
return path.split("/").slice(-1)[0];
}
}
function removeExtension(name) {
return name.replace(/\.[^/.]+$/, "");
}
function getFolderPathFromString(path) {
const subString = path.lastIndexOf("/") >= 0 ? path.lastIndexOf("/") : 0;
return path.substring(0, subString);
}
function getFileExplorer() {
return this.app.workspace.getLeavesOfType("file-explorer")[0];
}
// src/ExcludeFolders/ExcludePattern.ts
var ExcludePattern = class {
constructor(pattern, position, plugin) {
this.type = "pattern";
this.string = pattern;
this.position = position;
this.subFolders = plugin.settings.excludePatternDefaultSettings.subFolders;
this.disableSync = plugin.settings.excludePatternDefaultSettings.disableSync;
this.disableAutoCreate = plugin.settings.excludePatternDefaultSettings.disableAutoCreate;
this.disableFolderNote = plugin.settings.excludePatternDefaultSettings.disableFolderNote;
this.enableCollapsing = plugin.settings.excludePatternDefaultSettings.enableCollapsing;
this.excludeFromFolderOverview = plugin.settings.excludePatternDefaultSettings.excludeFromFolderOverview;
this.path = "";
this.hideInSettings = false;
}
};
// src/ExcludeFolders/functions/folderFunctions.ts
var import_obsidian9 = require("obsidian");
// src/suggesters/FolderSuggester.ts
var import_obsidian5 = require("obsidian");
// src/suggesters/Suggest.ts
var import_obsidian4 = require("obsidian");
// node_modules/@popperjs/core/lib/enums.js
var top = "top";
var bottom = "bottom";
var right = "right";
var left = "left";
var auto = "auto";
var basePlacements = [top, bottom, right, left];
var start = "start";
var end = "end";
var clippingParents = "clippingParents";
var viewport = "viewport";
var popper = "popper";
var reference = "reference";
var variationPlacements = /* @__PURE__ */ basePlacements.reduce(function(acc, placement) {
return acc.concat([placement + "-" + start, placement + "-" + end]);
}, []);
var placements = /* @__PURE__ */ [].concat(basePlacements, [auto]).reduce(function(acc, placement) {
return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
}, []);
var beforeRead = "beforeRead";
var read = "read";
var afterRead = "afterRead";
var beforeMain = "beforeMain";
var main = "main";
var afterMain = "afterMain";
var beforeWrite = "beforeWrite";
var write = "write";
var afterWrite = "afterWrite";
var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];
// node_modules/@popperjs/core/lib/dom-utils/getNodeName.js
function getNodeName(element) {
return element ? (element.nodeName || "").toLowerCase() : null;
}
// node_modules/@popperjs/core/lib/dom-utils/getWindow.js
function getWindow(node) {
if (node == null) {
return window;
}
if (node.toString() !== "[object Window]") {
var ownerDocument = node.ownerDocument;
return ownerDocument ? ownerDocument.defaultView || window : window;
}
return node;
}
// node_modules/@popperjs/core/lib/dom-utils/instanceOf.js
function isElement(node) {
var OwnElement = getWindow(node).Element;
return node instanceof OwnElement || node instanceof Element;
}
function isHTMLElement(node) {
var OwnElement = getWindow(node).HTMLElement;
return node instanceof OwnElement || node instanceof HTMLElement;
}
function isShadowRoot(node) {
if (typeof ShadowRoot === "undefined") {
return false;
}
var OwnElement = getWindow(node).ShadowRoot;
return node instanceof OwnElement || node instanceof ShadowRoot;
}
// node_modules/@popperjs/core/lib/modifiers/applyStyles.js
function applyStyles(_ref) {
var state = _ref.state;
Object.keys(state.elements).forEach(function(name) {
var style = state.styles[name] || {};
var attributes = state.attributes[name] || {};
var element = state.elements[name];
if (!isHTMLElement(element) || !getNodeName(element)) {
return;
}
Object.assign(element.style, style);
Object.keys(attributes).forEach(function(name2) {
var value = attributes[name2];
if (value === false) {
element.removeAttribute(name2);
} else {
element.setAttribute(name2, value === true ? "" : value);
}
});
});
}
function effect(_ref2) {
var state = _ref2.state;
var initialStyles = {
popper: {
position: state.options.strategy,
left: "0",
top: "0",
margin: "0"
},
arrow: {
position: "absolute"
},
reference: {}
};
Object.assign(state.elements.popper.style, initialStyles.popper);
state.styles = initialStyles;
if (state.elements.arrow) {
Object.assign(state.elements.arrow.style, initialStyles.arrow);
}
return function() {
Object.keys(state.elements).forEach(function(name) {
var element = state.elements[name];
var attributes = state.attributes[name] || {};
var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]);
var style = styleProperties.reduce(function(style2, property) {
style2[property] = "";
return style2;
}, {});
if (!isHTMLElement(element) || !getNodeName(element)) {
return;
}
Object.assign(element.style, style);
Object.keys(attributes).forEach(function(attribute) {
element.removeAttribute(attribute);
});
});
};
}
var applyStyles_default = {
name: "applyStyles",
enabled: true,
phase: "write",
fn: applyStyles,
effect,
requires: ["computeStyles"]
};
// node_modules/@popperjs/core/lib/utils/getBasePlacement.js
function getBasePlacement(placement) {
return placement.split("-")[0];
}
// node_modules/@popperjs/core/lib/utils/math.js
var max = Math.max;
var min = Math.min;
var round = Math.round;
// node_modules/@popperjs/core/lib/utils/userAgent.js
function getUAString() {
var uaData = navigator.userAgentData;
if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
return uaData.brands.map(function(item) {
return item.brand + "/" + item.version;
}).join(" ");
}
return navigator.userAgent;
}
// node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js
function isLayoutViewport() {
return !/^((?!chrome|android).)*safari/i.test(getUAString());
}
// node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js
function getBoundingClientRect(element, includeScale, isFixedStrategy) {
if (includeScale === void 0) {
includeScale = false;
}
if (isFixedStrategy === void 0) {
isFixedStrategy = false;
}
var clientRect = element.getBoundingClientRect();
var scaleX = 1;
var scaleY = 1;
if (includeScale && isHTMLElement(element)) {
scaleX = element.offsetWidth > 0 ? round(clientRect.width) / element.offsetWidth || 1 : 1;
scaleY = element.offsetHeight > 0 ? round(clientRect.height) / element.offsetHeight || 1 : 1;
}
var _ref = isElement(element) ? getWindow(element) : window, visualViewport = _ref.visualViewport;
var addVisualOffsets = !isLayoutViewport() && isFixedStrategy;
var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
var width = clientRect.width / scaleX;
var height = clientRect.height / scaleY;
return {
width,
height,
top: y,
right: x + width,
bottom: y + height,
left: x,
x,
y
};
}
// node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js
function getLayoutRect(element) {
var clientRect = getBoundingClientRect(element);
var width = element.offsetWidth;
var height = element.offsetHeight;
if (Math.abs(clientRect.width - width) <= 1) {
width = clientRect.width;
}
if (Math.abs(clientRect.height - height) <= 1) {
height = clientRect.height;
}
return {
x: element.offsetLeft,
y: element.offsetTop,
width,
height
};
}
// node_modules/@popperjs/core/lib/dom-utils/contains.js
function contains(parent, child) {
var rootNode = child.getRootNode && child.getRootNode();
if (parent.contains(child)) {
return true;
} else if (rootNode && isShadowRoot(rootNode)) {
var next = child;
do {
if (next && parent.isSameNode(next)) {
return true;
}
next = next.parentNode || next.host;
} while (next);
}
return false;
}
// node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js
function getComputedStyle(element) {
return getWindow(element).getComputedStyle(element);
}
// node_modules/@popperjs/core/lib/dom-utils/isTableElement.js
function isTableElement(element) {
return ["table", "td", "th"].indexOf(getNodeName(element)) >= 0;
}
// node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js
function getDocumentElement(element) {
return ((isElement(element) ? element.ownerDocument : element.document) || window.document).documentElement;
}
// node_modules/@popperjs/core/lib/dom-utils/getParentNode.js
function getParentNode(element) {
if (getNodeName(element) === "html") {
return element;
}
return element.assignedSlot || element.parentNode || (isShadowRoot(element) ? element.host : null) || getDocumentElement(element);
}
// node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js
function getTrueOffsetParent(element) {
if (!isHTMLElement(element) || getComputedStyle(element).position === "fixed") {
return null;
}
return element.offsetParent;
}
function getContainingBlock(element) {
var isFirefox = /firefox/i.test(getUAString());
var isIE = /Trident/i.test(getUAString());
if (isIE && isHTMLElement(element)) {
var elementCss = getComputedStyle(element);
if (elementCss.position === "fixed") {
return null;
}
}
var currentNode = getParentNode(element);
if (isShadowRoot(currentNode)) {
currentNode = currentNode.host;
}
while (isHTMLElement(currentNode) && ["html", "body"].indexOf(getNodeName(currentNode)) < 0) {
var css = getComputedStyle(currentNode);
if (css.transform !== "none" || css.perspective !== "none" || css.contain === "paint" || ["transform", "perspective"].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === "filter" || isFirefox && css.filter && css.filter !== "none") {
return currentNode;
} else {
currentNode = currentNode.parentNode;
}
}
return null;
}
function getOffsetParent(element) {
var window2 = getWindow(element);
var offsetParent = getTrueOffsetParent(element);
while (offsetParent && isTableElement(offsetParent) && getComputedStyle(offsetParent).position === "static") {
offsetParent = getTrueOffsetParent(offsetParent);
}
if (offsetParent && (getNodeName(offsetParent) === "html" || getNodeName(offsetParent) === "body" && getComputedStyle(offsetParent).position === "static")) {
return window2;
}
return offsetParent || getContainingBlock(element) || window2;
}
// node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js
function getMainAxisFromPlacement(placement) {
return ["top", "bottom"].indexOf(placement) >= 0 ? "x" : "y";
}
// node_modules/@popperjs/core/lib/utils/within.js
function within(min2, value, max2) {
return max(min2, min(value, max2));
}
function withinMaxClamp(min2, value, max2) {
var v = within(min2, value, max2);
return v > max2 ? max2 : v;
}
// node_modules/@popperjs/core/lib/utils/getFreshSideObject.js
function getFreshSideObject() {
return {
top: 0,
right: 0,
bottom: 0,
left: 0
};
}
// node_modules/@popperjs/core/lib/utils/mergePaddingObject.js
function mergePaddingObject(paddingObject) {
return Object.assign({}, getFreshSideObject(), paddingObject);
}
// node_modules/@popperjs/core/lib/utils/expandToHashMap.js
function expandToHashMap(value, keys) {
return keys.reduce(function(hashMap, key) {
hashMap[key] = value;
return hashMap;
}, {});
}
// node_modules/@popperjs/core/lib/modifiers/arrow.js
var toPaddingObject = function toPaddingObject2(padding, state) {
padding = typeof padding === "function" ? padding(Object.assign({}, state.rects, {
placement: state.placement
})) : padding;
return mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
};
function arrow(_ref) {
var _state$modifiersData$;
var state = _ref.state, name = _ref.name, options = _ref.options;
var arrowElement = state.elements.arrow;
var popperOffsets2 = state.modifiersData.popperOffsets;
var basePlacement = getBasePlacement(state.placement);
var axis = getMainAxisFromPlacement(basePlacement);
var isVertical = [left, right].indexOf(basePlacement) >= 0;
var len = isVertical ? "height" : "width";
if (!arrowElement || !popperOffsets2) {
return;
}
var paddingObject = toPaddingObject(options.padding, state);
var arrowRect = getLayoutRect(arrowElement);
var minProp = axis === "y" ? top : left;
var maxProp = axis === "y" ? bottom : right;
var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets2[axis] - state.rects.popper[len];
var startDiff = popperOffsets2[axis] - state.rects.reference[axis];
var arrowOffsetParent = getOffsetParent(arrowElement);
var clientSize = arrowOffsetParent ? axis === "y" ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
var centerToReference = endDiff / 2 - startDiff / 2;
var min2 = paddingObject[minProp];
var max2 = clientSize - arrowRect[len] - paddingObject[maxProp];
var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
var offset2 = within(min2, center, max2);
var axisProp = axis;
state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset2, _state$modifiersData$.centerOffset = offset2 - center, _state$modifiersData$);
}
function effect2(_ref2) {
var state = _ref2.state, options = _ref2.options;
var _options$element = options.element, arrowElement = _options$element === void 0 ? "[data-popper-arrow]" : _options$element;
if (arrowElement == null) {
return;
}
if (typeof arrowElement === "string") {
arrowElement = state.elements.popper.querySelector(arrowElement);
if (!arrowElement) {
return;
}
}
if (!contains(state.elements.popper, arrowElement)) {
return;
}
state.elements.arrow = arrowElement;
}
var arrow_default = {
name: "arrow",
enabled: true,
phase: "main",
fn: arrow,
effect: effect2,
requires: ["popperOffsets"],
requiresIfExists: ["preventOverflow"]
};
// node_modules/@popperjs/core/lib/utils/getVariation.js
function getVariation(placement) {
return placement.split("-")[1];
}
// node_modules/@popperjs/core/lib/modifiers/computeStyles.js
var unsetSides = {
top: "auto",
right: "auto",
bottom: "auto",
left: "auto"
};
function roundOffsetsByDPR(_ref, win) {
var x = _ref.x, y = _ref.y;
var dpr = win.devicePixelRatio || 1;
return {
x: round(x * dpr) / dpr || 0,
y: round(y * dpr) / dpr || 0
};
}
function mapToStyles(_ref2) {
var _Object$assign2;
var popper2 = _ref2.popper, popperRect = _ref2.popperRect, placement = _ref2.placement, variation = _ref2.variation, offsets = _ref2.offsets, position = _ref2.position, gpuAcceleration = _ref2.gpuAcceleration, adaptive = _ref2.adaptive, roundOffsets = _ref2.roundOffsets, isFixed = _ref2.isFixed;
var _offsets$x = offsets.x, x = _offsets$x === void 0 ? 0 : _offsets$x, _offsets$y = offsets.y, y = _offsets$y === void 0 ? 0 : _offsets$y;
var _ref3 = typeof roundOffsets === "function" ? roundOffsets({
x,
y
}) : {
x,
y
};
x = _ref3.x;
y = _ref3.y;
var hasX = offsets.hasOwnProperty("x");
var hasY = offsets.hasOwnProperty("y");
var sideX = left;
var sideY = top;
var win = window;
if (adaptive) {
var offsetParent = getOffsetParent(popper2);
var heightProp = "clientHeight";
var widthProp = "clientWidth";
if (offsetParent === getWindow(popper2)) {
offsetParent = getDocumentElement(popper2);
if (getComputedStyle(offsetParent).position !== "static" && position === "absolute") {
heightProp = "scrollHeight";
widthProp = "scrollWidth";
}
}
offsetParent = offsetParent;
if (placement === top || (placement === left || placement === right) && variation === end) {
sideY = bottom;
var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height : offsetParent[heightProp];
y -= offsetY - popperRect.height;
y *= gpuAcceleration ? 1 : -1;
}
if (placement === left || (placement === top || placement === bottom) && variation === end) {
sideX = right;
var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width : offsetParent[widthProp];
x -= offsetX - popperRect.width;
x *= gpuAcceleration ? 1 : -1;
}
}
var commonStyles = Object.assign({
position
}, adaptive && unsetSides);
var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
x,
y
}, getWindow(popper2)) : {
x,
y
};
x = _ref4.x;
y = _ref4.y;
if (gpuAcceleration) {
var _Object$assign;
return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? "0" : "", _Object$assign[sideX] = hasX ? "0" : "", _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
}
return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : "", _Object$assign2[sideX] = hasX ? x + "px" : "", _Object$assign2.transform = "", _Object$assign2));
}
function computeStyles(_ref5) {
var state = _ref5.state, options = _ref5.options;
var _options$gpuAccelerat = options.gpuAcceleration, gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat, _options$adaptive = options.adaptive, adaptive = _options$adaptive === void 0 ? true : _options$adaptive, _options$roundOffsets = options.roundOffsets, roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
var commonStyles = {
placement: getBasePlacement(state.placement),
variation: getVariation(state.placement),
popper: state.elements.popper,
popperRect: state.rects.popper,
gpuAcceleration,
isFixed: state.options.strategy === "fixed"
};
if (state.modifiersData.popperOffsets != null) {
state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
offsets: state.modifiersData.popperOffsets,
position: state.options.strategy,
adaptive,
roundOffsets
})));
}
if (state.modifiersData.arrow != null) {
state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
offsets: state.modifiersData.arrow,
position: "absolute",
adaptive: false,
roundOffsets
})));
}
state.attributes.popper = Object.assign({}, state.attributes.popper, {
"data-popper-placement": state.placement
});
}
var computeStyles_default = {
name: "computeStyles",
enabled: true,
phase: "beforeWrite",
fn: computeStyles,
data: {}
};
// node_modules/@popperjs/core/lib/modifiers/eventListeners.js
var passive = {
passive: true
};
function effect3(_ref) {
var state = _ref.state, instance = _ref.instance, options = _ref.options;
var _options$scroll = options.scroll, scroll = _options$scroll === void 0 ? true : _options$scroll, _options$resize = options.resize, resize = _options$resize === void 0 ? true : _options$resize;
var window2 = getWindow(state.elements.popper);
var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
if (scroll) {
scrollParents.forEach(function(scrollParent) {
scrollParent.addEventListener("scroll", instance.update, passive);
});
}
if (resize) {
window2.addEventListener("resize", instance.update, passive);
}
return function() {
if (scroll) {
scrollParents.forEach(function(scrollParent) {
scrollParent.removeEventListener("scroll", instance.update, passive);
});
}
if (resize) {
window2.removeEventListener("resize", instance.update, passive);
}
};
}
var eventListeners_default = {
name: "eventListeners",
enabled: true,
phase: "write",
fn: function fn() {
},
effect: effect3,
data: {}
};
// node_modules/@popperjs/core/lib/utils/getOppositePlacement.js
var hash = {
left: "right",
right: "left",
bottom: "top",
top: "bottom"
};
function getOppositePlacement(placement) {
return placement.replace(/left|right|bottom|top/g, function(matched) {
return hash[matched];
});
}
// node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js
var hash2 = {
start: "end",
end: "start"
};
function getOppositeVariationPlacement(placement) {
return placement.replace(/start|end/g, function(matched) {
return hash2[matched];
});
}
// node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js
function getWindowScroll(node) {
var win = getWindow(node);
var scrollLeft = win.pageXOffset;
var scrollTop = win.pageYOffset;
return {
scrollLeft,
scrollTop
};
}
// node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js
function getWindowScrollBarX(element) {
return getBoundingClientRect(getDocumentElement(element)).left + getWindowScroll(element).scrollLeft;
}
// node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js
function getViewportRect(element, strategy) {
var win = getWindow(element);
var html = getDocumentElement(element);
var visualViewport = win.visualViewport;
var width = html.clientWidth;
var height = html.clientHeight;
var x = 0;
var y = 0;
if (visualViewport) {
width = visualViewport.width;
height = visualViewport.height;
var layoutViewport = isLayoutViewport();
if (layoutViewport || !layoutViewport && strategy === "fixed") {
x = visualViewport.offsetLeft;
y = visualViewport.offsetTop;
}
}
return {
width,
height,
x: x + getWindowScrollBarX(element),
y
};
}
// node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js
function getDocumentRect(element) {
var _element$ownerDocumen;
var html = getDocumentElement(element);
var winScroll = getWindowScroll(element);
var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
var width = max(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
var height = max(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
var x = -winScroll.scrollLeft + getWindowScrollBarX(element);
var y = -winScroll.scrollTop;
if (getComputedStyle(body || html).direction === "rtl") {
x += max(html.clientWidth, body ? body.clientWidth : 0) - width;
}
return {
width,
height,
x,
y
};
}
// node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js
function isScrollParent(element) {
var _getComputedStyle = getComputedStyle(element), overflow = _getComputedStyle.overflow, overflowX = _getComputedStyle.overflowX, overflowY = _getComputedStyle.overflowY;
return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
}
// node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js
function getScrollParent(node) {
if (["html", "body", "#document"].indexOf(getNodeName(node)) >= 0) {
return node.ownerDocument.body;
}
if (isHTMLElement(node) && isScrollParent(node)) {
return node;
}
return getScrollParent(getParentNode(node));
}
// node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js
function listScrollParents(element, list) {
var _element$ownerDocumen;
if (list === void 0) {
list = [];
}
var scrollParent = getScrollParent(element);
var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
var win = getWindow(scrollParent);
var target = isBody ? [win].concat(win.visualViewport || [], isScrollParent(scrollParent) ? scrollParent : []) : scrollParent;
var updatedList = list.concat(target);
return isBody ? updatedList : updatedList.concat(listScrollParents(getParentNode(target)));
}
// node_modules/@popperjs/core/lib/utils/rectToClientRect.js
function rectToClientRect(rect) {
return Object.assign({}, rect, {
left: rect.x,
top: rect.y,
right: rect.x + rect.width,
bottom: rect.y + rect.height
});
}
// node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js
function getInnerBoundingClientRect(element, strategy) {
var rect = getBoundingClientRect(element, false, strategy === "fixed");
rect.top = rect.top + element.clientTop;
rect.left = rect.left + element.clientLeft;
rect.bottom = rect.top + element.clientHeight;
rect.right = rect.left + element.clientWidth;
rect.width = element.clientWidth;
rect.height = element.clientHeight;
rect.x = rect.left;
rect.y = rect.top;
return rect;
}
function getClientRectFromMixedType(element, clippingParent, strategy) {
return clippingParent === viewport ? rectToClientRect(getViewportRect(element, strategy)) : isElement(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : rectToClientRect(getDocumentRect(getDocumentElement(element)));
}
function getClippingParents(element) {
var clippingParents2 = listScrollParents(getParentNode(element));
var canEscapeClipping = ["absolute", "fixed"].indexOf(getComputedStyle(element).position) >= 0;
var clipperElement = canEscapeClipping && isHTMLElement(element) ? getOffsetParent(element) : element;
if (!isElement(clipperElement)) {
return [];
}
return clippingParents2.filter(function(clippingParent) {
return isElement(clippingParent) && contains(clippingParent, clipperElement) && getNodeName(clippingParent) !== "body";
});
}
function getClippingRect(element, boundary, rootBoundary, strategy) {
var mainClippingParents = boundary === "clippingParents" ? getClippingParents(element) : [].concat(boundary);
var clippingParents2 = [].concat(mainClippingParents, [rootBoundary]);
var firstClippingParent = clippingParents2[0];
var clippingRect = clippingParents2.reduce(function(accRect, clippingParent) {
var rect = getClientRectFromMixedType(element, clippingParent, strategy);
accRect.top = max(rect.top, accRect.top);
accRect.right = min(rect.right, accRect.right);
accRect.bottom = min(rect.bottom, accRect.bottom);
accRect.left = max(rect.left, accRect.left);
return accRect;
}, getClientRectFromMixedType(element, firstClippingParent, strategy));
clippingRect.width = clippingRect.right - clippingRect.left;
clippingRect.height = clippingRect.bottom - clippingRect.top;
clippingRect.x = clippingRect.left;
clippingRect.y = clippingRect.top;
return clippingRect;
}
// node_modules/@popperjs/core/lib/utils/computeOffsets.js
function computeOffsets(_ref) {
var reference2 = _ref.reference, element = _ref.element, placement = _ref.placement;
var basePlacement = placement ? getBasePlacement(placement) : null;
var variation = placement ? getVariation(placement) : null;
var commonX = reference2.x + reference2.width / 2 - element.width / 2;
var commonY = reference2.y + reference2.height / 2 - element.height / 2;
var offsets;
switch (basePlacement) {
case top:
offsets = {
x: commonX,
y: reference2.y - element.height
};
break;
case bottom:
offsets = {
x: commonX,
y: reference2.y + reference2.height
};
break;
case right:
offsets = {
x: reference2.x + reference2.width,
y: commonY
};
break;
case left:
offsets = {
x: reference2.x - element.width,
y: commonY
};
break;
default:
offsets = {
x: reference2.x,
y: reference2.y
};
}
var mainAxis = basePlacement ? getMainAxisFromPlacement(basePlacement) : null;
if (mainAxis != null) {
var len = mainAxis === "y" ? "height" : "width";
switch (variation) {
case start:
offsets[mainAxis] = offsets[mainAxis] - (reference2[len] / 2 - element[len] / 2);
break;
case end:
offsets[mainAxis] = offsets[mainAxis] + (reference2[len] / 2 - element[len] / 2);
break;
default:
}
}
return offsets;
}
// node_modules/@popperjs/core/lib/utils/detectOverflow.js
function detectOverflow(state, options) {
if (options === void 0) {
options = {};
}
var _options = options, _options$placement = _options.placement, placement = _options$placement === void 0 ? state.placement : _options$placement, _options$strategy = _options.strategy, strategy = _options$strategy === void 0 ? state.strategy : _options$strategy, _options$boundary = _options.boundary, boundary = _options$boundary === void 0 ? clippingParents : _options$boundary, _options$rootBoundary = _options.rootBoundary, rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary, _options$elementConte = _options.elementContext, elementContext = _options$elementConte === void 0 ? popper : _options$elementConte, _options$altBoundary = _options.altBoundary, altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary, _options$padding = _options.padding, padding = _options$padding === void 0 ? 0 : _options$padding;
var paddingObject = mergePaddingObject(typeof padding !== "number" ? padding : expandToHashMap(padding, basePlacements));
var altContext = elementContext === popper ? reference : popper;
var popperRect = state.rects.popper;
var element = state.elements[altBoundary ? altContext : elementContext];
var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);
var referenceClientRect = getBoundingClientRect(state.elements.reference);
var popperOffsets2 = computeOffsets({
reference: referenceClientRect,
element: popperRect,
strategy: "absolute",
placement
});
var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets2));
var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect;
var overflowOffsets = {
top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
right: elementClientRect.right - clippingClientRect.right + paddingObject.right
};
var offsetData = state.modifiersData.offset;
if (elementContext === popper && offsetData) {
var offset2 = offsetData[placement];
Object.keys(overflowOffsets).forEach(function(key) {
var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
var axis = [top, bottom].indexOf(key) >= 0 ? "y" : "x";
overflowOffsets[key] += offset2[axis] * multiply;
});
}
return overflowOffsets;
}
// node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js
function computeAutoPlacement(state, options) {
if (options === void 0) {
options = {};
}
var _options = options, placement = _options.placement, boundary = _options.boundary, rootBoundary = _options.rootBoundary, padding = _options.padding, flipVariations = _options.flipVariations, _options$allowedAutoP = _options.allowedAutoPlacements, allowedAutoPlacements = _options$allowedAutoP === void 0 ? placements : _options$allowedAutoP;
var variation = getVariation(placement);
var placements2 = variation ? flipVariations ? variationPlacements : variationPlacements.filter(function(placement2) {
return getVariation(placement2) === variation;
}) : basePlacements;
var allowedPlacements = placements2.filter(function(placement2) {
return allowedAutoPlacements.indexOf(placement2) >= 0;
});
if (allowedPlacements.length === 0) {
allowedPlacements = placements2;
}
var overflows = allowedPlacements.reduce(function(acc, placement2) {
acc[placement2] = detectOverflow(state, {
placement: placement2,
boundary,
rootBoundary,
padding
})[getBasePlacement(placement2)];
return acc;
}, {});
return Object.keys(overflows).sort(function(a, b) {
return overflows[a] - overflows[b];
});
}
// node_modules/@popperjs/core/lib/modifiers/flip.js
function getExpandedFallbackPlacements(placement) {
if (getBasePlacement(placement) === auto) {
return [];
}
var oppositePlacement = getOppositePlacement(placement);
return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
}
function flip(_ref) {
var state = _ref.state, options = _ref.options, name = _ref.name;
if (state.modifiersData[name]._skip) {
return;
}
var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis, specifiedFallbackPlacements = options.fallbackPlacements, padding = options.padding, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, _options$flipVariatio = options.flipVariations, flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio, allowedAutoPlacements = options.allowedAutoPlacements;
var preferredPlacement = state.options.placement;
var basePlacement = getBasePlacement(preferredPlacement);
var isBasePlacement = basePlacement === preferredPlacement;
var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
var placements2 = [preferredPlacement].concat(fallbackPlacements).reduce(function(acc, placement2) {
return acc.concat(getBasePlacement(placement2) === auto ? computeAutoPlacement(state, {
placement: placement2,
boundary,
rootBoundary,
padding,
flipVariations,
allowedAutoPlacements
}) : placement2);
}, []);
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var checksMap = /* @__PURE__ */ new Map();
var makeFallbackChecks = true;
var firstFittingPlacement = placements2[0];
for (var i = 0; i < placements2.length; i++) {
var placement = placements2[i];
var _basePlacement = getBasePlacement(placement);
var isStartVariation = getVariation(placement) === start;
var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
var len = isVertical ? "width" : "height";
var overflow = detectOverflow(state, {
placement,
boundary,
rootBoundary,
altBoundary,
padding
});
var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
if (referenceRect[len] > popperRect[len]) {
mainVariationSide = getOppositePlacement(mainVariationSide);
}
var altVariationSide = getOppositePlacement(mainVariationSide);
var checks = [];
if (checkMainAxis) {
checks.push(overflow[_basePlacement] <= 0);
}
if (checkAltAxis) {
checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
}
if (checks.every(function(check) {
return check;
})) {
firstFittingPlacement = placement;
makeFallbackChecks = false;
break;
}
checksMap.set(placement, checks);
}
if (makeFallbackChecks) {
var numberOfChecks = flipVariations ? 3 : 1;
var _loop = function _loop2(_i2) {
var fittingPlacement = placements2.find(function(placement2) {
var checks2 = checksMap.get(placement2);
if (checks2) {
return checks2.slice(0, _i2).every(function(check) {
return check;
});
}
});
if (fittingPlacement) {
firstFittingPlacement = fittingPlacement;
return "break";
}
};
for (var _i = numberOfChecks; _i > 0; _i--) {
var _ret = _loop(_i);
if (_ret === "break")
break;
}
}
if (state.placement !== firstFittingPlacement) {
state.modifiersData[name]._skip = true;
state.placement = firstFittingPlacement;
state.reset = true;
}
}
var flip_default = {
name: "flip",
enabled: true,
phase: "main",
fn: flip,
requiresIfExists: ["offset"],
data: {
_skip: false
}
};
// node_modules/@popperjs/core/lib/modifiers/hide.js
function getSideOffsets(overflow, rect, preventedOffsets) {
if (preventedOffsets === void 0) {
preventedOffsets = {
x: 0,
y: 0
};
}
return {
top: overflow.top - rect.height - preventedOffsets.y,
right: overflow.right - rect.width + preventedOffsets.x,
bottom: overflow.bottom - rect.height + preventedOffsets.y,
left: overflow.left - rect.width - preventedOffsets.x
};
}
function isAnySideFullyClipped(overflow) {
return [top, right, bottom, left].some(function(side) {
return overflow[side] >= 0;
});
}
function hide(_ref) {
var state = _ref.state, name = _ref.name;
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var preventedOffsets = state.modifiersData.preventOverflow;
var referenceOverflow = detectOverflow(state, {
elementContext: "reference"
});
var popperAltOverflow = detectOverflow(state, {
altBoundary: true
});
var referenceClippingOffsets = getSideOffsets(referenceOverflow, referenceRect);
var popperEscapeOffsets = getSideOffsets(popperAltOverflow, popperRect, preventedOffsets);
var isReferenceHidden = isAnySideFullyClipped(referenceClippingOffsets);
var hasPopperEscaped = isAnySideFullyClipped(popperEscapeOffsets);
state.modifiersData[name] = {
referenceClippingOffsets,
popperEscapeOffsets,
isReferenceHidden,
hasPopperEscaped
};
state.attributes.popper = Object.assign({}, state.attributes.popper, {
"data-popper-reference-hidden": isReferenceHidden,
"data-popper-escaped": hasPopperEscaped
});
}
var hide_default = {
name: "hide",
enabled: true,
phase: "main",
requiresIfExists: ["preventOverflow"],
fn: hide
};
// node_modules/@popperjs/core/lib/modifiers/offset.js
function distanceAndSkiddingToXY(placement, rects, offset2) {
var basePlacement = getBasePlacement(placement);
var invertDistance = [left, top].indexOf(basePlacement) >= 0 ? -1 : 1;
var _ref = typeof offset2 === "function" ? offset2(Object.assign({}, rects, {
placement
})) : offset2, skidding = _ref[0], distance = _ref[1];
skidding = skidding || 0;
distance = (distance || 0) * invertDistance;
return [left, right].indexOf(basePlacement) >= 0 ? {
x: distance,
y: skidding
} : {
x: skidding,
y: distance
};
}
function offset(_ref2) {
var state = _ref2.state, options = _ref2.options, name = _ref2.name;
var _options$offset = options.offset, offset2 = _options$offset === void 0 ? [0, 0] : _options$offset;
var data = placements.reduce(function(acc, placement) {
acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset2);
return acc;
}, {});
var _data$state$placement = data[state.placement], x = _data$state$placement.x, y = _data$state$placement.y;
if (state.modifiersData.popperOffsets != null) {
state.modifiersData.popperOffsets.x += x;
state.modifiersData.popperOffsets.y += y;
}
state.modifiersData[name] = data;
}
var offset_default = {
name: "offset",
enabled: true,
phase: "main",
requires: ["popperOffsets"],
fn: offset
};
// node_modules/@popperjs/core/lib/modifiers/popperOffsets.js
function popperOffsets(_ref) {
var state = _ref.state, name = _ref.name;
state.modifiersData[name] = computeOffsets({
reference: state.rects.reference,
element: state.rects.popper,
strategy: "absolute",
placement: state.placement
});
}
var popperOffsets_default = {
name: "popperOffsets",
enabled: true,
phase: "read",
fn: popperOffsets,
data: {}
};
// node_modules/@popperjs/core/lib/utils/getAltAxis.js
function getAltAxis(axis) {
return axis === "x" ? "y" : "x";
}
// node_modules/@popperjs/core/lib/modifiers/preventOverflow.js
function preventOverflow(_ref) {
var state = _ref.state, options = _ref.options, name = _ref.name;
var _options$mainAxis = options.mainAxis, checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis, _options$altAxis = options.altAxis, checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis, boundary = options.boundary, rootBoundary = options.rootBoundary, altBoundary = options.altBoundary, padding = options.padding, _options$tether = options.tether, tether = _options$tether === void 0 ? true : _options$tether, _options$tetherOffset = options.tetherOffset, tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
var overflow = detectOverflow(state, {
boundary,
rootBoundary,
padding,
altBoundary
});
var basePlacement = getBasePlacement(state.placement);
var variation = getVariation(state.placement);
var isBasePlacement = !variation;
var mainAxis = getMainAxisFromPlacement(basePlacement);
var altAxis = getAltAxis(mainAxis);
var popperOffsets2 = state.modifiersData.popperOffsets;
var referenceRect = state.rects.reference;
var popperRect = state.rects.popper;
var tetherOffsetValue = typeof tetherOffset === "function" ? tetherOffset(Object.assign({}, state.rects, {
placement: state.placement
})) : tetherOffset;
var normalizedTetherOffsetValue = typeof tetherOffsetValue === "number" ? {
mainAxis: tetherOffsetValue,
altAxis: tetherOffsetValue
} : Object.assign({
mainAxis: 0,
altAxis: 0
}, tetherOffsetValue);
var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
var data = {
x: 0,
y: 0
};
if (!popperOffsets2) {
return;
}
if (checkMainAxis) {
var _offsetModifierState$;
var mainSide = mainAxis === "y" ? top : left;
var altSide = mainAxis === "y" ? bottom : right;
var len = mainAxis === "y" ? "height" : "width";
var offset2 = popperOffsets2[mainAxis];
var min2 = offset2 + overflow[mainSide];
var max2 = offset2 - overflow[altSide];
var additive = tether ? -popperRect[len] / 2 : 0;
var minLen = variation === start ? referenceRect[len] : popperRect[len];
var maxLen = variation === start ? -popperRect[len] : -referenceRect[len];
var arrowElement = state.elements.arrow;
var arrowRect = tether && arrowElement ? getLayoutRect(arrowElement) : {
width: 0,
height: 0
};
var arrowPaddingObject = state.modifiersData["arrow#persistent"] ? state.modifiersData["arrow#persistent"].padding : getFreshSideObject();
var arrowPaddingMin = arrowPaddingObject[mainSide];
var arrowPaddingMax = arrowPaddingObject[altSide];
var arrowLen = within(0, referenceRect[len], arrowRect[len]);
var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
var arrowOffsetParent = state.elements.arrow && getOffsetParent(state.elements.arrow);
var clientOffset = arrowOffsetParent ? mainAxis === "y" ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
var tetherMin = offset2 + minOffset - offsetModifierValue - clientOffset;
var tetherMax = offset2 + maxOffset - offsetModifierValue;
var preventedOffset = within(tether ? min(min2, tetherMin) : min2, offset2, tether ? max(max2, tetherMax) : max2);
popperOffsets2[mainAxis] = preventedOffset;
data[mainAxis] = preventedOffset - offset2;
}
if (checkAltAxis) {
var _offsetModifierState$2;
var _mainSide = mainAxis === "x" ? top : left;
var _altSide = mainAxis === "x" ? bottom : right;
var _offset = popperOffsets2[altAxis];
var _len = altAxis === "y" ? "height" : "width";
var _min = _offset + overflow[_mainSide];
var _max = _offset - overflow[_altSide];
var isOriginSide = [top, left].indexOf(basePlacement) !== -1;
var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
var _preventedOffset = tether && isOriginSide ? withinMaxClamp(_tetherMin, _offset, _tetherMax) : within(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
popperOffsets2[altAxis] = _preventedOffset;
data[altAxis] = _preventedOffset - _offset;
}
state.modifiersData[name] = data;
}
var preventOverflow_default = {
name: "preventOverflow",
enabled: true,
phase: "main",
fn: preventOverflow,
requiresIfExists: ["offset"]
};
// node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js
function getHTMLElementScroll(element) {
return {
scrollLeft: element.scrollLeft,
scrollTop: element.scrollTop
};
}
// node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js
function getNodeScroll(node) {
if (node === getWindow(node) || !isHTMLElement(node)) {
return getWindowScroll(node);
} else {
return getHTMLElementScroll(node);
}
}
// node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js
function isElementScaled(element) {
var rect = element.getBoundingClientRect();
var scaleX = round(rect.width) / element.offsetWidth || 1;
var scaleY = round(rect.height) / element.offsetHeight || 1;
return scaleX !== 1 || scaleY !== 1;
}
function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
if (isFixed === void 0) {
isFixed = false;
}
var isOffsetParentAnElement = isHTMLElement(offsetParent);
var offsetParentIsScaled = isHTMLElement(offsetParent) && isElementScaled(offsetParent);
var documentElement = getDocumentElement(offsetParent);
var rect = getBoundingClientRect(elementOrVirtualElement, offsetParentIsScaled, isFixed);
var scroll = {
scrollLeft: 0,
scrollTop: 0
};
var offsets = {
x: 0,
y: 0
};
if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
if (getNodeName(offsetParent) !== "body" || isScrollParent(documentElement)) {
scroll = getNodeScroll(offsetParent);
}
if (isHTMLElement(offsetParent)) {
offsets = getBoundingClientRect(offsetParent, true);
offsets.x += offsetParent.clientLeft;
offsets.y += offsetParent.clientTop;
} else if (documentElement) {
offsets.x = getWindowScrollBarX(documentElement);
}
}
return {
x: rect.left + scroll.scrollLeft - offsets.x,
y: rect.top + scroll.scrollTop - offsets.y,
width: rect.width,
height: rect.height
};
}
// node_modules/@popperjs/core/lib/utils/orderModifiers.js
function order(modifiers) {
var map = /* @__PURE__ */ new Map();
var visited = /* @__PURE__ */ new Set();
var result = [];
modifiers.forEach(function(modifier) {
map.set(modifier.name, modifier);
});
function sort(modifier) {
visited.add(modifier.name);
var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
requires.forEach(function(dep) {
if (!visited.has(dep)) {
var depModifier = map.get(dep);
if (depModifier) {
sort(depModifier);
}
}
});
result.push(modifier);
}
modifiers.forEach(function(modifier) {
if (!visited.has(modifier.name)) {
sort(modifier);
}
});
return result;
}
function orderModifiers(modifiers) {
var orderedModifiers = order(modifiers);
return modifierPhases.reduce(function(acc, phase) {
return acc.concat(orderedModifiers.filter(function(modifier) {
return modifier.phase === phase;
}));
}, []);
}
// node_modules/@popperjs/core/lib/utils/debounce.js
function debounce(fn2) {
var pending;
return function() {
if (!pending) {
pending = new Promise(function(resolve) {
Promise.resolve().then(function() {
pending = void 0;
resolve(fn2());
});
});
}
return pending;
};
}
// node_modules/@popperjs/core/lib/utils/mergeByName.js
function mergeByName(modifiers) {
var merged = modifiers.reduce(function(merged2, current) {
var existing = merged2[current.name];
merged2[current.name] = existing ? Object.assign({}, existing, current, {
options: Object.assign({}, existing.options, current.options),
data: Object.assign({}, existing.data, current.data)
}) : current;
return merged2;
}, {});
return Object.keys(merged).map(function(key) {
return merged[key];
});
}
// node_modules/@popperjs/core/lib/createPopper.js
var DEFAULT_OPTIONS = {
placement: "bottom",
modifiers: [],
strategy: "absolute"
};
function areValidElements() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return !args.some(function(element) {
return !(element && typeof element.getBoundingClientRect === "function");
});
}
function popperGenerator(generatorOptions) {
if (generatorOptions === void 0) {
generatorOptions = {};
}
var _generatorOptions = generatorOptions, _generatorOptions$def = _generatorOptions.defaultModifiers, defaultModifiers2 = _generatorOptions$def === void 0 ? [] : _generatorOptions$def, _generatorOptions$def2 = _generatorOptions.defaultOptions, defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
return function createPopper2(reference2, popper2, options) {
if (options === void 0) {
options = defaultOptions;
}
var state = {
placement: "bottom",
orderedModifiers: [],
options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
modifiersData: {},
elements: {
reference: reference2,
popper: popper2
},
attributes: {},
styles: {}
};
var effectCleanupFns = [];
var isDestroyed = false;
var instance = {
state,
setOptions: function setOptions(setOptionsAction) {
var options2 = typeof setOptionsAction === "function" ? setOptionsAction(state.options) : setOptionsAction;
cleanupModifierEffects();
state.options = Object.assign({}, defaultOptions, state.options, options2);
state.scrollParents = {
reference: isElement(reference2) ? listScrollParents(reference2) : reference2.contextElement ? listScrollParents(reference2.contextElement) : [],
popper: listScrollParents(popper2)
};
var orderedModifiers = orderModifiers(mergeByName([].concat(defaultModifiers2, state.options.modifiers)));
state.orderedModifiers = orderedModifiers.filter(function(m) {
return m.enabled;
});
runModifierEffects();
return instance.update();
},
forceUpdate: function forceUpdate() {
if (isDestroyed) {
return;
}
var _state$elements = state.elements, reference3 = _state$elements.reference, popper3 = _state$elements.popper;
if (!areValidElements(reference3, popper3)) {
return;
}
state.rects = {
reference: getCompositeRect(reference3, getOffsetParent(popper3), state.options.strategy === "fixed"),
popper: getLayoutRect(popper3)
};
state.reset = false;
state.placement = state.options.placement;
state.orderedModifiers.forEach(function(modifier) {
return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
});
for (var index = 0; index < state.orderedModifiers.length; index++) {
if (state.reset === true) {
state.reset = false;
index = -1;
continue;
}
var _state$orderedModifie = state.orderedModifiers[index], fn2 = _state$orderedModifie.fn, _state$orderedModifie2 = _state$orderedModifie.options, _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2, name = _state$orderedModifie.name;
if (typeof fn2 === "function") {
state = fn2({
state,
options: _options,
name,
instance
}) || state;
}
}
},
update: debounce(function() {
return new Promise(function(resolve) {
instance.forceUpdate();
resolve(state);
});
}),
destroy: function destroy() {
cleanupModifierEffects();
isDestroyed = true;
}
};
if (!areValidElements(reference2, popper2)) {
return instance;
}
instance.setOptions(options).then(function(state2) {
if (!isDestroyed && options.onFirstUpdate) {
options.onFirstUpdate(state2);
}
});
function runModifierEffects() {
state.orderedModifiers.forEach(function(_ref) {
var name = _ref.name, _ref$options = _ref.options, options2 = _ref$options === void 0 ? {} : _ref$options, effect4 = _ref.effect;
if (typeof effect4 === "function") {
var cleanupFn = effect4({
state,
name,
instance,
options: options2
});
var noopFn = function noopFn2() {
};
effectCleanupFns.push(cleanupFn || noopFn);
}
});
}
function cleanupModifierEffects() {
effectCleanupFns.forEach(function(fn2) {
return fn2();
});
effectCleanupFns = [];
}
return instance;
};
}
// node_modules/@popperjs/core/lib/popper.js
var defaultModifiers = [eventListeners_default, popperOffsets_default, computeStyles_default, applyStyles_default, offset_default, flip_default, preventOverflow_default, arrow_default, hide_default];
var createPopper = /* @__PURE__ */ popperGenerator({
defaultModifiers
});
// src/suggesters/Suggest.ts
var wrapAround = (value, size) => {
return (value % size + size) % size;
};
var Suggest = class {
constructor(owner, containerEl, scope) {
this.owner = owner;
this.containerEl = containerEl;
containerEl.on("click", ".suggestion-item", this.onSuggestionClick.bind(this));
containerEl.on("mousemove", ".suggestion-item", this.onSuggestionMouseover.bind(this));
scope.register([], "ArrowUp", (event) => {
if (!event.isComposing) {
this.setSelectedItem(this.selectedItem - 1, true);
return false;
}
});
scope.register([], "ArrowDown", (event) => {
if (!event.isComposing) {
this.setSelectedItem(this.selectedItem + 1, true);
return false;
}
});
scope.register([], "Enter", (event) => {
if (!event.isComposing) {
this.useSelectedItem(event);
return false;
}
});
}
onSuggestionClick(event, el) {
event.preventDefault();
const item = this.suggestions.indexOf(el);
this.setSelectedItem(item, false);
this.useSelectedItem(event);
}
onSuggestionMouseover(_event, el) {
const item = this.suggestions.indexOf(el);
this.setSelectedItem(item, false);
}
setSuggestions(values) {
this.containerEl.empty();
const suggestionEls = [];
values.forEach((value) => {
const suggestionEl = this.containerEl.createDiv("suggestion-item");
this.owner.renderSuggestion(value, suggestionEl);
suggestionEls.push(suggestionEl);
});
this.values = values;
this.suggestions = suggestionEls;
this.setSelectedItem(0, false);
}
useSelectedItem(event) {
const currentValue = this.values[this.selectedItem];
if (currentValue) {
this.owner.selectSuggestion(currentValue, event);
}
}
setSelectedItem(selectedIndex, scrollIntoView) {
const normalizedIndex = wrapAround(selectedIndex, this.suggestions.length);
const prevSelectedSuggestion = this.suggestions[this.selectedItem];
const selectedSuggestion = this.suggestions[normalizedIndex];
prevSelectedSuggestion == null ? void 0 : prevSelectedSuggestion.removeClass("is-selected");
selectedSuggestion == null ? void 0 : selectedSuggestion.addClass("is-selected");
this.selectedItem = normalizedIndex;
if (scrollIntoView) {
selectedSuggestion.scrollIntoView(false);
}
}
};
var TextInputSuggest = class {
constructor(inputEl, plugin) {
this.inputEl = inputEl;
this.plugin = plugin;
this.scope = new import_obsidian4.Scope();
this.suggestEl = createDiv("suggestion-container");
const suggestion = this.suggestEl.createDiv("suggestion");
this.suggest = new Suggest(this, suggestion, this.scope);
this.scope.register([], "Escape", this.close.bind(this));
this.inputEl.addEventListener("input", this.onInputChanged.bind(this));
this.inputEl.addEventListener("focus", this.onInputChanged.bind(this));
this.inputEl.addEventListener("blur", this.close.bind(this));
this.suggestEl.on("mousedown", ".suggestion-container", (event) => {
event.preventDefault();
});
}
onInputChanged() {
const inputStr = this.inputEl.value;
const suggestions = this.getSuggestions(inputStr);
if (!suggestions) {
this.close();
return;
}
if (suggestions.length > 0) {
this.suggest.setSuggestions(suggestions);
this.open(app.dom.appContainerEl, this.inputEl);
} else {
this.close();
}
}
open(container, inputEl) {
this.plugin.app.keymap.pushScope(this.scope);
container.appendChild(this.suggestEl);
this.popper = createPopper(inputEl, this.suggestEl, {
placement: "bottom-start",
modifiers: [
{
name: "sameWidth",
enabled: true,
fn: ({ state, instance }) => {
const targetWidth = `${state.rects.reference.width}px`;
if (state.styles.popper.width === targetWidth) {
return;
}
state.styles.popper.width = targetWidth;
instance.update();
},
phase: "beforeWrite",
requires: ["computeStyles"]
}
]
});
}
close() {
this.plugin.app.keymap.popScope(this.scope);
this.suggest.setSuggestions([]);
if (this.popper)
this.popper.destroy();
this.suggestEl.detach();
}
};
// src/suggesters/FolderSuggester.ts
var FolderSuggest = class extends TextInputSuggest {
constructor(inputEl, plugin, folder) {
super(inputEl, plugin);
this.inputEl = inputEl;
this.folder = folder;
}
get_error_msg(mode) {
switch (mode) {
case 0 /* TemplateFiles */:
return "Templates folder doesn't exist";
case 1 /* ScriptFiles */:
return "User Scripts folder doesn't exist";
}
}
getSuggestions(input_str) {
const folders = [];
const lower_input_str = input_str.toLowerCase();
let files = [];
if (this.folder) {
files = this.folder.children;
} else {
files = this.plugin.app.vault.getAllLoadedFiles();
}
files.forEach((folder) => {
if (folder instanceof import_obsidian5.TFolder && folder.path.toLowerCase().contains(lower_input_str) && !this.plugin.settings.excludeFolders.find((f) => f.path === folder.path)) {
folders.push(folder);
}
});
return folders;
}
renderSuggestion(folder, el) {
el.setText(folder.path);
}
selectSuggestion(folder) {
this.inputEl.value = folder.path;
this.inputEl.trigger("input");
this.close();
}
};
// src/ExcludeFolders/modals/ExcludeFolderSettings.ts
var import_obsidian6 = require("obsidian");
var ExcludedFolderSettings = class extends import_obsidian6.Modal {
constructor(app2, plugin, excludedFolder) {
super(app2);
this.plugin = plugin;
this.app = app2;
this.excludedFolder = excludedFolder;
}
onOpen() {
this.display();
}
display() {
const { contentEl } = this;
contentEl.empty();
contentEl.createEl("h2", { text: "Excluded folder settings" });
new import_obsidian6.Setting(contentEl).setName("Include subfolders").setDesc("Choose if the subfolders of the folder should also be excluded").addToggle((toggle) => toggle.setValue(this.excludedFolder.subFolders).onChange(async (value) => {
this.excludedFolder.subFolders = value;
await this.plugin.saveSettings(true);
}));
new import_obsidian6.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder note should be renamed when the folder name is changed").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableSync).onChange(async (value) => {
this.excludedFolder.disableSync = value;
await this.plugin.saveSettings();
}));
new import_obsidian6.Setting(contentEl).setName("Don't show folder in folder overview").setDesc("Choose if the folder should be shown in the folder overview").addToggle((toggle) => toggle.setValue(this.excludedFolder.excludeFromFolderOverview).onChange(async (value) => {
this.excludedFolder.excludeFromFolderOverview = value;
await this.plugin.saveSettings();
}));
new import_obsidian6.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableAutoCreate).onChange(async (value) => {
this.excludedFolder.disableAutoCreate = value;
await this.plugin.saveSettings();
}));
new import_obsidian6.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.disableFolderNote).onChange(async (value) => {
this.excludedFolder.disableFolderNote = value;
await this.plugin.saveSettings(true);
this.display();
}));
if (!this.excludedFolder.disableFolderNote) {
new import_obsidian6.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.excludedFolder.enableCollapsing).onChange(async (value) => {
this.excludedFolder.enableCollapsing = value;
await this.plugin.saveSettings();
}));
}
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/ExcludeFolders/functions/patternFunctions.ts
var import_obsidian8 = require("obsidian");
// src/ExcludeFolders/modals/PatternSettings.ts
var import_obsidian7 = require("obsidian");
var PatternSettings = class extends import_obsidian7.Modal {
constructor(app2, plugin, pattern) {
super(app2);
this.plugin = plugin;
this.app = app2;
this.pattern = pattern;
}
onOpen() {
this.display();
}
display() {
const { contentEl } = this;
contentEl.empty();
contentEl.createEl("h2", { text: "Pattern settings" });
new import_obsidian7.Setting(contentEl).setName("Disable folder name sync").setDesc("Choose if the folder name should be renamed when the file name has been changed").addToggle((toggle) => toggle.setValue(this.pattern.disableSync).onChange(async (value) => {
this.pattern.disableSync = value;
await this.plugin.saveSettings();
}));
new import_obsidian7.Setting(contentEl).setName("Disable auto creation of folder notes in this folder").setDesc("Choose if a folder note should be created when a new folder is created that matches this pattern").addToggle((toggle) => toggle.setValue(this.pattern.disableAutoCreate).onChange(async (value) => {
this.pattern.disableAutoCreate = value;
await this.plugin.saveSettings();
}));
new import_obsidian7.Setting(contentEl).setName("Don't show folder in folder overview").setDesc("Choose if the folder should be shown in the folder overview").addToggle((toggle) => toggle.setValue(this.pattern.excludeFromFolderOverview).onChange(async (value) => {
this.pattern.excludeFromFolderOverview = value;
await this.plugin.saveSettings();
}));
new import_obsidian7.Setting(contentEl).setName("Disable open folder note").setDesc("Choose if the folder note should be opened when the folder is opened").addToggle((toggle) => toggle.setValue(this.pattern.disableFolderNote).onChange(async (value) => {
this.pattern.disableFolderNote = value;
await this.plugin.saveSettings();
this.display();
}));
if (!this.pattern.disableFolderNote) {
new import_obsidian7.Setting(contentEl).setName("Collapse folder when opening folder note").setDesc("Choose if the folder should be collapsed when the folder note is opened").addToggle((toggle) => toggle.setValue(this.pattern.enableCollapsing).onChange(async (value) => {
this.pattern.enableCollapsing = value;
await this.plugin.saveSettings();
}));
}
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/ExcludeFolders/functions/patternFunctions.ts
function updatePattern(plugin, pattern, newPattern) {
plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string);
addExcludedFolder(plugin, newPattern);
}
function deletePattern(plugin, pattern) {
plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.string !== pattern.string || folder.type === "folder");
plugin.saveSettings();
resyncArray(plugin);
}
function getExcludedFolderByPattern(plugin, folderName) {
return plugin.settings.excludeFolders.filter((s) => s.type == "pattern").find((pattern) => {
if (!pattern.string) {
return false;
}
const string = pattern.string.trim();
if (!string.startsWith("{regex}") && !(string.startsWith("*") || string.endsWith("*"))) {
return false;
}
const regex = string.replace("{regex}", "").trim();
if (string.startsWith("{regex}") && regex === "") {
return false;
}
if (regex !== void 0 && string.startsWith("{regex}")) {
const match = new RegExp(regex).exec(folderName);
if (match) {
return true;
}
} else if (string.startsWith("*") && string.endsWith("*")) {
if (folderName.includes(string.slice(1, -1))) {
return true;
}
} else if (string.startsWith("*")) {
if (folderName.endsWith(string.slice(1))) {
return true;
}
} else if (string.endsWith("*")) {
if (folderName.startsWith(string.slice(0, -1))) {
return true;
}
}
});
}
function addExcludePatternListItem(settings, containerEl, pattern) {
const plugin = settings.plugin;
const setting = new import_obsidian8.Setting(containerEl);
setting.setClass("fn-exclude-folder-list");
setting.addSearch((cb) => {
cb.containerEl.addClass("fn-exclude-folder-path");
cb.setPlaceholder("Pattern");
cb.setValue(pattern.string);
cb.onChange((value) => {
if (plugin.settings.excludeFolders.find((folder) => folder.string === value)) {
return;
}
pattern.string = value;
updatePattern(plugin, pattern, pattern);
});
});
setting.addButton((cb) => {
cb.setIcon("edit");
cb.setTooltip("Edit pattern");
cb.onClick(() => {
new PatternSettings(plugin.app, plugin, pattern).open();
});
});
setting.addButton((cb) => {
cb.setIcon("up-chevron-glyph");
cb.setTooltip("Move up");
cb.onClick(() => {
if (pattern.position === 0) {
return;
}
pattern.position -= 1;
updatePattern(plugin, pattern, pattern);
const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position);
if (oldPattern) {
oldPattern.position += 1;
if (oldPattern.type === "pattern") {
updatePattern(plugin, oldPattern, oldPattern);
} else {
updateExcludedFolder(plugin, oldPattern, oldPattern);
}
}
settings.display();
});
});
setting.addButton((cb) => {
cb.setIcon("down-chevron-glyph");
cb.setTooltip("Move down");
cb.onClick(() => {
if (pattern.position === plugin.settings.excludeFolders.length - 1) {
return;
}
pattern.position += 1;
updatePattern(plugin, pattern, pattern);
const oldPattern = plugin.settings.excludeFolders.find((folder) => folder.position === pattern.position);
if (oldPattern) {
oldPattern.position -= 1;
if (oldPattern.type === "pattern") {
updatePattern(plugin, oldPattern, oldPattern);
} else {
updateExcludedFolder(plugin, oldPattern, oldPattern);
}
}
settings.display();
});
});
setting.addButton((cb) => {
cb.setIcon("trash-2");
cb.setTooltip("Delete pattern");
cb.onClick(() => {
deletePattern(plugin, pattern);
setting.clear();
setting.settingEl.remove();
});
});
}
// src/ExcludeFolders/functions/folderFunctions.ts
function getExcludedFolder(plugin, path) {
const folderName = getFolderNameFromPathString(path);
const matchedPattern = getExcludedFolderByPattern(plugin, folderName);
if (matchedPattern) {
return matchedPattern;
}
const excludedFolder = getExcludedFolderByPath(plugin, path);
if ((excludedFolder == null ? void 0 : excludedFolder.path) === "") {
return;
}
return excludedFolder;
}
function getExcludedFolderByPath(plugin, path) {
return plugin.settings.excludeFolders.find((excludedFolder) => {
if (excludedFolder.path === path) {
return true;
}
if (!excludedFolder.subFolders) {
return false;
}
const excludedFolderPath = excludedFolder.path.includes("/") ? excludedFolder.path : excludedFolder.path + "/";
let folderPath = getFolderPathFromString(path);
folderPath = folderPath.includes("/") ? folderPath : folderPath + "/";
if (folderPath.includes("/") || folderPath.includes("\\")) {
return folderPath.startsWith(excludedFolderPath) || folderPath === excludedFolderPath;
} else {
return folderPath === excludedFolderPath;
}
});
}
function addExcludedFolder(plugin, excludedFolder) {
plugin.settings.excludeFolders.push(excludedFolder);
plugin.saveSettings(true);
}
function deleteExcludedFolder(plugin, excludedFolder) {
plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path || folder.type === "pattern");
plugin.saveSettings(true);
resyncArray(plugin);
}
function updateExcludedFolder(plugin, excludedFolder, newExcludeFolder) {
plugin.settings.excludeFolders = plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path);
addExcludedFolder(plugin, newExcludeFolder);
}
function resyncArray(plugin) {
plugin.settings.excludeFolders = plugin.settings.excludeFolders.sort((a, b) => a.position - b.position);
plugin.settings.excludeFolders.forEach((folder, index) => {
folder.position = index;
});
plugin.saveSettings();
}
function addExcludeFolderListItem(settings, containerEl, excludedFolder) {
const plugin = settings.plugin;
const setting = new import_obsidian9.Setting(containerEl);
setting.setClass("fn-exclude-folder-list");
setting.addSearch((cb) => {
new FolderSuggest(cb.inputEl, plugin);
cb.containerEl.addClass("fn-exclude-folder-path");
cb.setPlaceholder("Folder path");
cb.setValue(excludedFolder.path);
cb.onChange((value) => {
if (value.startsWith("{regex}") || value.includes("*")) {
deleteExcludedFolder(plugin, excludedFolder);
const pattern = new ExcludePattern(value, plugin.settings.excludeFolders.length, plugin);
addExcludedFolder(plugin, pattern);
addExcludePatternListItem(settings, containerEl, pattern);
setting.clear();
setting.settingEl.remove();
}
if (!plugin.app.vault.getAbstractFileByPath(value))
return;
excludedFolder.path = value;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
});
});
setting.addButton((cb) => {
cb.setIcon("edit");
cb.setTooltip("Edit folder note");
cb.onClick(() => {
new ExcludedFolderSettings(plugin.app, plugin, excludedFolder).open();
});
});
setting.addButton((cb) => {
cb.setIcon("up-chevron-glyph");
cb.setTooltip("Move up");
cb.onClick(() => {
if (excludedFolder.position === 0) {
return;
}
excludedFolder.position -= 1;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position);
if (oldExcludedFolder) {
oldExcludedFolder.position += 1;
if (oldExcludedFolder.type === "pattern") {
updatePattern(plugin, oldExcludedFolder, oldExcludedFolder);
} else {
updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder);
}
}
settings.display();
});
});
setting.addButton((cb) => {
cb.setIcon("down-chevron-glyph");
cb.setTooltip("Move down");
cb.onClick(() => {
if (excludedFolder.position === plugin.settings.excludeFolders.length - 1) {
return;
}
excludedFolder.position += 1;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
const oldExcludedFolder = plugin.settings.excludeFolders.find((folder) => folder.position === excludedFolder.position);
if (oldExcludedFolder) {
oldExcludedFolder.position -= 1;
if (oldExcludedFolder.type === "pattern") {
updatePattern(plugin, oldExcludedFolder, oldExcludedFolder);
} else {
updateExcludedFolder(plugin, oldExcludedFolder, oldExcludedFolder);
}
}
settings.display();
});
});
setting.addButton((cb) => {
cb.setIcon("trash-2");
cb.setTooltip("Delete excluded folder");
cb.onClick(() => {
deleteExcludedFolder(plugin, excludedFolder);
setting.clear();
setting.settingEl.remove();
});
});
}
// src/ExcludeFolders/ExcludeFolder.ts
var ExcludedFolder = class {
constructor(path, position, plugin) {
this.type = "folder";
this.path = path;
this.subFolders = plugin.settings.excludeFolderDefaultSettings.subFolders;
this.disableSync = plugin.settings.excludeFolderDefaultSettings.disableSync;
this.disableAutoCreate = plugin.settings.excludeFolderDefaultSettings.disableAutoCreate;
this.disableFolderNote = plugin.settings.excludeFolderDefaultSettings.disableFolderNote;
this.enableCollapsing = plugin.settings.excludeFolderDefaultSettings.enableCollapsing;
this.position = position;
this.excludeFromFolderOverview = plugin.settings.excludeFolderDefaultSettings.excludeFromFolderOverview;
this.string = "";
this.hideInSettings = false;
}
};
// src/functions/excalidraw.ts
async function openExcalidrawView(leaf) {
const { excalidraw, excalidrawEnabled } = await getExcalidrawPlugin(this.app);
if (excalidrawEnabled) {
excalidraw.setExcalidrawView(leaf);
}
}
async function getExcalidrawPlugin(app2) {
const excalidraw = app2.plugins.plugins["obsidian-excalidraw-plugin"];
const excalidrawEnabled = app2.plugins.enabledPlugins.has("obsidian-excalidraw-plugin");
return {
excalidraw,
excalidrawEnabled
};
}
// src/modals/AskForExtension.ts
var import_obsidian10 = require("obsidian");
var AskForExtensionModal = class extends import_obsidian10.FuzzySuggestModal {
constructor(plugin, folderPath, openFile, extension, useModal, existingNote) {
super(plugin.app);
this.plugin = plugin;
this.folderPath = folderPath;
this.extension = extension;
this.openFile = openFile;
this.useModal = useModal;
this.existingNote = existingNote;
}
getItems() {
return this.plugin.settings.supportedFileTypes.filter((item) => item.toLowerCase() !== ".ask");
}
getItemText(item) {
return item;
}
onChooseItem(item, evt) {
this.extension = "." + item;
createFolderNote(this.plugin, this.folderPath, this.openFile, this.extension, this.useModal, this.existingNote);
this.close();
}
};
// src/functions/styleFunctions.ts
var import_obsidian11 = require("obsidian");
function loadFileClasses(forceReload = false, plugin) {
if (plugin.activeFileExplorer === getFileExplorer() && !forceReload) {
return;
}
plugin.activeFileExplorer = getFileExplorer();
plugin.app.vault.getAllLoadedFiles().forEach((file) => {
if (!(file instanceof import_obsidian11.TFolder)) {
return;
}
const folderNote = getFolderNote(plugin, file.path);
if (!folderNote) {
removeCSSClassFromEL(file == null ? void 0 : file.path, "has-folder-note");
removeCSSClassFromEL(file == null ? void 0 : file.path, "only-has-folder-note");
return;
}
const excludedFolder = getExcludedFolder(plugin, file.path);
if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
removeCSSClassFromEL(folderNote.path, "is-folder-note");
removeCSSClassFromEL(file.path, "has-folder-note");
removeCSSClassFromEL(file == null ? void 0 : file.path, "only-has-folder-note");
} else {
addCSSClassToTitleEL(folderNote.path, "is-folder-note");
addCSSClassToTitleEL(file.path, "has-folder-note");
if (plugin.isEmptyFolderNoteFolder(file)) {
addCSSClassToTitleEL(file.path, "only-has-folder-note");
} else {
removeCSSClassFromEL(file.path, "only-has-folder-note");
}
}
});
}
function applyCSSClassesToFolder(folderPath, plugin) {
const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
if (!folder || !(folder instanceof import_obsidian11.TFolder)) {
return;
}
const excludedFolder = getExcludedFolder(plugin, folder.path);
if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
return;
}
const folderNote = getFolderNote(plugin, folder.path);
if (!folderNote) {
return;
}
addCSSClassesToBothFolderAndNote(folderNote, folder, plugin);
}
function addCSSClassesToBothFolderAndNote(file, folder, plugin) {
addCSSClassToFolderNote(file);
addCSSClassesToFolder(folder, plugin);
}
function addCSSClassesToFolder(folder, plugin) {
addCSSClassToTitleEL(folder.path, "has-folder-note");
if (plugin.isEmptyFolderNoteFolder(folder)) {
addCSSClassToTitleEL(folder.path, "only-has-folder-note");
} else {
removeCSSClassFromEL(folder.path, "only-has-folder-note");
}
}
function addCSSClassToFolderNote(file) {
addCSSClassToTitleEL(file.path, "is-folder-note");
}
async function addCSSClassToTitleEL(path, cssClass, waitForCreate = false, count = 0) {
const fileExplorerItem = getEl(path);
if (!fileExplorerItem) {
if (waitForCreate && count < 5) {
await new Promise((r) => setTimeout(r, 500));
addCSSClassToTitleEL(path, cssClass, waitForCreate, count + 1);
return;
}
return;
}
fileExplorerItem.addClass(cssClass);
const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
viewHeaderItems.forEach((item) => {
item.addClass(cssClass);
});
}
function removeCSSClassFromEL(path, cssClass) {
if (!path)
return;
const fileExplorerItem = getEl(path);
const viewHeaderItems = document.querySelectorAll(`[data-path="${path}"]`);
viewHeaderItems.forEach((item) => {
item.removeClass(cssClass);
});
if (!fileExplorerItem) {
return;
}
fileExplorerItem.removeClass(cssClass);
}
function getEl(path) {
const fileExplorer = getFileExplorer();
if (!fileExplorer) {
return null;
}
const fileExplorerItem = fileExplorer.view.fileItems[path];
if (!fileExplorerItem) {
return null;
}
if (fileExplorerItem.selfEl)
return fileExplorerItem.selfEl;
return fileExplorerItem.titleEl;
}
// src/functions/folderNoteFunctions.ts
var defaultExcalidrawTemplate = `---
excalidraw-plugin: parsed
tags: [excalidraw]
---
==\u26A0 Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. \u26A0==
%%
# Drawing
\`\`\`json
{"type":"excalidraw","version":2,"source":"https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/1.9.20","elements":[],"appState":{"gridSize":null,"viewBackgroundColor":"#ffffff"}}
\`\`\`
%%`;
async function createFolderNote(plugin, folderPath, openFile, extension, useModal, existingNote) {
var _a;
const leaf = plugin.app.workspace.getLeaf(false);
const folderName = getFolderNameFromPathString(folderPath);
const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName);
let folderNoteType = extension != null ? extension : plugin.settings.folderNoteType;
if (folderNoteType === ".excalidraw") {
folderNoteType = ".md";
extension = ".excalidraw";
} else if (folderNoteType === ".ask") {
return new AskForExtensionModal(plugin, folderPath, openFile, folderNoteType, useModal, existingNote).open();
}
let path = "";
if (plugin.settings.storageLocation === "parentFolder") {
const parentFolderPath = getFolderPathFromString(folderPath);
if (parentFolderPath.trim() === "") {
path = `${fileName}${folderNoteType}`;
} else {
path = `${parentFolderPath}/${fileName}${folderNoteType}`;
}
} else if (plugin.settings.storageLocation === "vaultFolder") {
path = `${fileName}${folderNoteType}`;
} else {
path = `${folderPath}/${fileName}${folderNoteType}`;
}
let file;
if (!existingNote) {
let content = "";
if (extension !== ".md") {
if (plugin.settings.templatePath && folderNoteType.split(".").pop() == plugin.settings.templatePath.split(".").pop()) {
const templateFile = plugin.app.vault.getAbstractFileByPath(plugin.settings.templatePath);
if (templateFile instanceof import_obsidian12.TFile) {
if (["md", "canvas", "txt"].includes(templateFile.extension)) {
content = await plugin.app.vault.read(templateFile);
if (extension === ".excalidraw" && !content.includes("==\u26A0 Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. \u26A0==")) {
content = defaultExcalidrawTemplate;
}
} else {
return plugin.app.vault.readBinary(templateFile).then(async (data) => {
file = await plugin.app.vault.createBinary(path, data);
if (openFile) {
await leaf.openFile(file);
}
});
}
}
} else if (plugin.settings.folderNoteType === ".excalidraw" || extension === ".excalidraw") {
content = defaultExcalidrawTemplate;
} else if (plugin.settings.folderNoteType === ".canvas") {
content = "{}";
}
}
file = await plugin.app.vault.create(path, content);
} else {
file = existingNote;
await plugin.app.fileManager.renameFile(existingNote, path).then(() => {
file = existingNote;
});
}
if (openFile) {
if (((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path) === path) {
if (plugin.activeFolderDom) {
plugin.activeFolderDom.removeClass("fn-is-active");
plugin.activeFolderDom = null;
}
const folder2 = getFolder2(plugin, file);
if (!folder2) {
return;
}
plugin.activeFolderDom = getEl(folder2.path);
if (plugin.activeFolderDom)
plugin.activeFolderDom.addClass("fn-is-active");
}
await leaf.openFile(file);
if (plugin.settings.folderNoteType === ".excalidraw" || extension === ".excalidraw") {
openExcalidrawView(leaf);
}
}
const matchingExtension = (extension == null ? void 0 : extension.split(".").pop()) == plugin.settings.templatePath.split(".").pop();
if (file && !existingNote && matchingExtension && plugin.settings.folderNoteType !== ".excalidraw") {
applyTemplate(plugin, file, leaf, plugin.settings.templatePath);
}
const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
if (!(folder instanceof import_obsidian12.TFolder))
return;
addCSSClassToTitleEL(path, "is-folder-note", true);
addCSSClassToTitleEL(folder.path, "has-folder-note");
}
async function turnIntoFolderNote(plugin, file, folder, folderNote, skipConfirmation) {
var _a;
const extension = file.extension;
if (folderNote) {
if (plugin.settings.showRenameConfirmation && !skipConfirmation) {
return new ExistingFolderNoteModal(plugin.app, plugin, file, folder, folderNote).open();
}
removeCSSClassFromEL(folderNote.path, "is-folder-note");
let excludedFolder = getExcludedFolder(plugin, folder.path);
let excludedFolderExisted = true;
let disabledSync = false;
if (!excludedFolder) {
excludedFolderExisted = false;
excludedFolder = new ExcludedFolder(folder.path, plugin.settings.excludeFolders.length, plugin);
addExcludedFolder(plugin, excludedFolder);
} else if (!excludedFolder.disableSync) {
disabledSync = false;
excludedFolder.disableSync = true;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
}
const newPath = `${folder.path}/${folder.name} (${file.stat.ctime.toString().slice(10) + Math.floor(Math.random() * 1e3)}).${extension}`;
plugin.app.fileManager.renameFile(folderNote, newPath).then(() => {
if (!excludedFolder) {
return;
}
if (!excludedFolderExisted) {
deleteExcludedFolder(plugin, excludedFolder);
} else if (!disabledSync) {
excludedFolder.disableSync = false;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
}
});
}
const folderName = folder.name;
const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folderName);
let path = `${folder.path}/${fileName}.${extension}`;
if (plugin.settings.storageLocation === "parentFolder") {
const parentFolderPath = (_a = folder.parent) == null ? void 0 : _a.path;
if (!parentFolderPath)
return;
if (parentFolderPath.trim() === "") {
path = `${fileName}.${extension}`;
} else {
path = `${parentFolderPath}/${fileName}.${extension}`;
}
}
await plugin.app.fileManager.renameFile(file, path);
addCSSClassToTitleEL(path, "is-folder-note", true);
addCSSClassToTitleEL(folder.path, "has-folder-note");
}
async function openFolderNote(plugin, file, evt) {
var _a;
const path = file.path;
if (((_a = plugin.app.workspace.getActiveFile()) == null ? void 0 : _a.path) === path && !(import_obsidian12.Keymap.isModEvent(evt) == "tab")) {
return;
}
const leaf = plugin.app.workspace.getLeaf(import_obsidian12.Keymap.isModEvent(evt) || plugin.settings.openInNewTab);
if (file instanceof import_obsidian12.TFile) {
await leaf.openFile(file);
}
}
async function deleteFolderNote(plugin, file, displayModal) {
if (plugin.settings.showDeleteConfirmation && displayModal) {
return new DeleteConfirmationModal(plugin.app, plugin, file).open();
}
const folder = getFolder2(plugin, file);
if (!folder)
return;
removeCSSClassFromEL(folder.path, "has-folder-note");
switch (plugin.settings.deleteFilesAction) {
case "trash":
await plugin.app.vault.trash(file, true);
break;
case "obsidianTrash":
await plugin.app.vault.trash(file, false);
break;
case "delete":
await plugin.app.vault.delete(file);
break;
}
}
function extractFolderName(template, changedFileName) {
const [prefix, suffix] = template.split("{{folder_name}}");
if (prefix.trim() === "" && suffix.trim() === "") {
return changedFileName;
}
if (!changedFileName.startsWith(prefix) || !changedFileName.endsWith(suffix)) {
return null;
}
if (changedFileName.startsWith(prefix) && prefix.trim() !== "") {
return changedFileName.slice(prefix.length).replace(suffix, "");
} else if (changedFileName.endsWith(suffix) && suffix.trim() !== "") {
return changedFileName.slice(0, -suffix.length);
}
return null;
}
function getFolderNote(plugin, folderPath, storageLocation, file) {
if (!folderPath)
return null;
const folder = {
path: folderPath,
name: getFolderNameFromPathString(folderPath)
};
let fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", folder.name);
if (file) {
fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.basename);
}
if (!fileName)
return null;
if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") {
folder.path = getFolderPathFromString(folderPath);
}
let path = `${folder.path}/${fileName}`;
if (folder.path.trim() === "") {
folder.path = fileName;
path = `${fileName}`;
}
let folderNoteType = plugin.settings.folderNoteType;
if (folderNoteType === ".excalidraw") {
folderNoteType = ".md";
}
let folderNote = plugin.app.vault.getAbstractFileByPath(path + folderNoteType);
if (folderNote instanceof import_obsidian12.TFile) {
return folderNote;
} else {
const supportedFileTypes = plugin.settings.supportedFileTypes.filter((type) => type !== plugin.settings.folderNoteType.replace(".", ""));
for (let type of supportedFileTypes) {
if (type === "excalidraw" || type === ".excalidraw") {
type = ".md";
}
if (!type.startsWith(".")) {
type = "." + type;
}
folderNote = plugin.app.vault.getAbstractFileByPath(path + type);
if (folderNote instanceof import_obsidian12.TFile) {
return folderNote;
}
}
}
}
function getFolder2(plugin, file, storageLocation) {
var _a, _b;
if (!file)
return null;
let folderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
if (plugin.settings.folderNoteName === file.basename && plugin.settings.storageLocation === "insideFolder") {
folderName = (_b = (_a = file.parent) == null ? void 0 : _a.name) != null ? _b : "";
}
if (!folderName)
return null;
let folderPath = getFolderPathFromString(file.path);
let folder = null;
if ((plugin.settings.storageLocation === "parentFolder" || storageLocation === "parentFolder") && storageLocation !== "insideFolder") {
if (folderPath.trim() === "") {
folderPath = folderName;
} else {
folderPath = `${folderPath}/${folderName}`;
}
folder = plugin.app.vault.getAbstractFileByPath(folderPath);
} else {
folder = plugin.app.vault.getAbstractFileByPath(folderPath);
}
if (!folder) {
return null;
}
return folder;
}
function getFolderNoteFolder(plugin, folderNote, fileName) {
if (!folderNote)
return null;
let filePath = "";
if (typeof folderNote === "string") {
filePath = folderNote;
} else {
fileName = folderNote.basename;
filePath = folderNote.path;
}
const folderName = extractFolderName(plugin.settings.folderNoteName, fileName);
if (!folderName)
return null;
let folderPath = getFolderPathFromString(filePath);
if (plugin.settings.storageLocation === "parentFolder") {
if (folderPath.trim() === "") {
folderPath = folderName;
} else {
folderPath = `${folderPath}/${folderName}`;
}
} else {
folderPath = getFolderPathFromString(filePath);
}
const folder = plugin.app.vault.getAbstractFileByPath(folderPath);
if (!folder) {
return null;
}
return folder;
}
// src/settings/GeneralSettings.ts
var import_obsidian17 = require("obsidian");
// src/modals/AddSupportedFileType.ts
var import_obsidian13 = require("obsidian");
var AddSupportedFileModal = class extends import_obsidian13.Modal {
constructor(app2, plugin, settingsTab, list) {
super(app2);
this.plugin = plugin;
this.app = app2;
this.name = "";
this.list = list;
this.settingsTab = settingsTab;
}
onOpen() {
const { contentEl } = this;
contentEl.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
this.close();
}
});
contentEl.createEl("h2", { text: "Extension name" });
new import_obsidian13.Setting(contentEl).setName('Enter the name of the extension (only the short form, e.g. "md")').addText((text) => text.setValue("").onChange(async (value) => {
if (value.trim() !== "") {
this.name = value.trim();
}
}));
}
async onClose() {
if (this.name.toLocaleLowerCase() === "markdown") {
this.name = "md";
}
const { contentEl } = this;
if (this.name === "") {
contentEl.empty();
this.settingsTab.display();
} else if (this.plugin.settings.supportedFileTypes.includes(this.name.toLowerCase())) {
return new import_obsidian13.Notice("This extension is already supported");
} else {
await this.list.addValue(this.name.toLowerCase());
this.settingsTab.display();
this.plugin.saveSettings();
contentEl.empty();
}
}
};
// src/events/FrontMatterTitle.ts
var import_front_matter_plugin_api_provider = __toESM(require_lib());
var import_obsidian14 = require("obsidian");
var FrontMatterTitlePluginHandler = class {
constructor(plugin) {
this.api = null;
this.deffer = null;
this.modifiedFolders = /* @__PURE__ */ new Map();
this.plugin = plugin;
this.app = plugin.app;
(async () => {
var _a;
this.deffer = (0, import_front_matter_plugin_api_provider.getDefer)(this.app);
if (this.deffer.isPluginReady()) {
this.api = this.deffer.getApi();
} else {
await this.deffer.awaitPlugin();
this.api = this.deffer.getApi();
if (!this.deffer.isFeaturesReady()) {
await this.deffer.awaitFeatures();
}
}
const dispatcher = (_a = this.api) == null ? void 0 : _a.getEventDispatcher();
if (dispatcher) {
this.dispatcher = dispatcher;
}
const event = {
name: "manager:update",
cb: (data) => {
this.handleRename(data, true);
}
};
const ref = dispatcher == null ? void 0 : dispatcher.addListener(event);
if (ref) {
this.eventRef = ref;
}
this.plugin.app.vault.getFiles().forEach((file) => {
this.handleRename({ id: "", result: false, path: file.path }, false);
});
this.plugin.updateBreadcrumbs();
})();
}
deleteEvent() {
if (this.eventRef) {
this.dispatcher.removeListener(this.eventRef);
}
}
async handleRename(data, isEvent) {
var _a, _b, _c;
if (data.data)
data = data.data;
const file = this.app.vault.getAbstractFileByPath(data.path);
if (!(file instanceof import_obsidian14.TFile)) {
return;
}
const resolver = (_b = (_a = this.api) == null ? void 0 : _a.getResolverFactory()) == null ? void 0 : _b.createResolver("#feature-id#");
const newName = resolver == null ? void 0 : resolver.resolve((_c = file == null ? void 0 : file.path) != null ? _c : "");
const folder = getFolder2(this.plugin, file);
if (!(folder instanceof import_obsidian14.TFolder)) {
return;
}
const folderNote = getFolderNote(this.plugin, folder.path);
if (!folderNote) {
return;
}
if (folderNote !== file) {
return;
}
if (isEvent) {
this.plugin.changeName(folder, newName, true);
} else {
this.plugin.changeName(folder, newName, false);
}
if (newName) {
folder.newName = newName;
this.modifiedFolders.set(folder.path, folder);
} else {
folder.newName = null;
this.modifiedFolders.delete(folder.path);
}
}
};
// src/modals/ConfirmCreation.ts
var import_obsidian15 = require("obsidian");
var ConfirmationModal = class extends import_obsidian15.Modal {
constructor(app2, plugin) {
super(app2);
this.plugin = plugin;
this.app = app2;
this.extension = plugin.settings.folderNoteType;
}
onOpen() {
var _a, _b, _c;
this.modalEl.addClass("fn-confirmation-modal");
let templateFolderPath;
const { templateFolder, templaterPlugin } = getTemplatePlugins(this.plugin.app);
if ((!templateFolder || (templateFolder == null ? void 0 : templateFolder.trim()) === "") && !templaterPlugin) {
templateFolderPath = "";
}
if (templaterPlugin) {
templateFolderPath = (_b = (_a = templaterPlugin.plugin) == null ? void 0 : _a.settings) == null ? void 0 : _b.templates_folder;
} else {
templateFolderPath = templateFolder;
}
const { contentEl } = this;
contentEl.createEl("h2", { text: "Create folder note for every folder" });
const setting = new import_obsidian15.Setting(contentEl);
setting.infoEl.createEl("p", { text: "Make sure to backup your vault before using this feature." }).style.color = "#fb464c";
setting.infoEl.createEl("p", { text: "This feature will create a folder note for every folder in your vault." });
setting.infoEl.createEl("p", { text: "Every folder that already has a folder note will be ignored." });
setting.infoEl.createEl("p", { text: "Every excluded folder will be ignored." });
if (!this.plugin.settings.templatePath || ((_c = this.plugin.settings.templatePath) == null ? void 0 : _c.trim()) === "") {
new import_obsidian15.Setting(contentEl).setName("Folder note file extension").setDesc("Choose the file extension for the folder notes.").addDropdown((cb) => {
this.plugin.settings.supportedFileTypes.forEach((extension) => {
cb.addOption("." + extension, extension);
});
cb.setValue(this.extension);
cb.onChange(async (value) => {
this.extension = value;
});
});
}
new import_obsidian15.Setting(contentEl).addButton((cb) => {
cb.setButtonText("Create");
cb.setCta();
cb.buttonEl.focus();
cb.onClick(async () => {
if (this.plugin.settings.templatePath && this.plugin.settings.templatePath.trim() !== "") {
this.extension = "." + this.plugin.settings.templatePath.split(".").pop();
}
if (this.extension === ".ask") {
return new import_obsidian15.Notice("Please choose a file extension");
}
this.close();
const folders = this.app.vault.getAllLoadedFiles().filter((file) => file.parent instanceof import_obsidian15.TFolder);
for (const folder of folders) {
if (folder instanceof import_obsidian15.TFolder) {
const excludedFolder = getExcludedFolder(this.plugin, folder.path);
if (excludedFolder)
continue;
if (folder.path === templateFolderPath)
continue;
const folderNote = getFolderNote(this.plugin, folder.path);
if (folderNote)
continue;
await createFolderNote(this.plugin, folder.path, false, this.extension);
}
}
});
}).addButton((cb) => {
cb.setButtonText("Cancel");
cb.onClick(async () => {
this.close();
});
});
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/suggesters/TemplateSuggester.ts
var import_obsidian16 = require("obsidian");
var TemplateSuggest = class extends TextInputSuggest {
constructor(inputEl, plugin) {
super(inputEl, plugin);
this.inputEl = inputEl;
}
get_error_msg(mode) {
switch (mode) {
case 0 /* TemplateFiles */:
return "Templates folder doesn't exist";
case 1 /* ScriptFiles */:
return "User Scripts folder doesn't exist";
}
}
getSuggestions(input_str) {
var _a, _b;
const { templateFolder, templaterPlugin } = getTemplatePlugins(this.plugin.app);
if ((!templateFolder || (templateFolder == null ? void 0 : templateFolder.trim()) === "") && !templaterPlugin) {
this.plugin.settings.templatePath = "";
this.plugin.saveSettings();
return [];
}
let folder;
if (templaterPlugin) {
folder = this.plugin.app.vault.getAbstractFileByPath((_b = (_a = templaterPlugin.plugin) == null ? void 0 : _a.settings) == null ? void 0 : _b.templates_folder);
} else {
folder = this.plugin.app.vault.getAbstractFileByPath(templateFolder);
}
const files = [];
const lower_input_str = input_str.toLowerCase();
import_obsidian16.Vault.recurseChildren(folder, (file) => {
if (file instanceof import_obsidian16.TFile && file.path.toLowerCase().contains(lower_input_str)) {
files.push(file);
}
});
return files;
}
renderSuggestion(file, el) {
el.setText(file.name.replace(".md", ""));
}
selectSuggestion(file) {
this.inputEl.value = file.name.replace(".md", "");
this.inputEl.trigger("input");
this.plugin.settings.templatePath = file.path;
this.plugin.saveSettings();
this.close();
}
};
// src/settings/GeneralSettings.ts
async function renderGeneral(settingsTab) {
const containerEl = settingsTab.settingsPage;
const nameSetting = new import_obsidian17.Setting(containerEl).setName("Folder note name").setDesc("{{folder_name}} will be replaced with the name of the folder").addText((text) => text.setValue(settingsTab.plugin.settings.newFolderNoteName).onChange(async (value) => {
if (value.trim() === "") {
return;
}
settingsTab.plugin.settings.newFolderNoteName = value;
await settingsTab.plugin.saveSettings();
})).addButton((button) => button.setButtonText("Rename existing folder notes").setCta().onClick(async () => {
settingsTab.updateFolderNotes(settingsTab.plugin.settings.newFolderNoteName);
settingsTab.display();
}));
nameSetting.infoEl.appendText("Requires a restart to take effect");
nameSetting.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
if (settingsTab.plugin.settings.newFolderNoteName !== "{{folder_name}}") {
new import_obsidian17.Setting(containerEl).setName("Use folder name instead of folder note name in the tab title").setDesc(`When you're using a folder note name like "folder note" and have multiple folder notes open you can't separate them anymore by their name. This setting uses the folder name instead and allows you to indentify the different files.`).addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.tabManagerEnabled).onChange(async (value) => {
if (!value) {
settingsTab.plugin.tabManager.resetTabs();
} else {
settingsTab.plugin.settings.tabManagerEnabled = value;
settingsTab.plugin.tabManager.updateTabs();
}
settingsTab.plugin.settings.tabManagerEnabled = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
}
new import_obsidian17.Setting(containerEl).setName("Default folder note type for new folder notes").setDesc("Choose the default file type for new folder notes. (canvas, markdown, ...)").addDropdown((dropdown) => {
dropdown.addOption(".ask", "ask for file type");
settingsTab.plugin.settings.supportedFileTypes.forEach((type) => {
if (type === ".md" || type === "md") {
dropdown.addOption(".md", "markdown");
} else {
dropdown.addOption("." + type, type);
}
});
if (!settingsTab.plugin.settings.supportedFileTypes.includes(settingsTab.plugin.settings.folderNoteType.replace(".", "")) && settingsTab.plugin.settings.folderNoteType !== ".ask") {
settingsTab.plugin.settings.folderNoteType = ".md";
settingsTab.plugin.saveSettings();
}
const defaultType = settingsTab.plugin.settings.folderNoteType.startsWith(".") ? settingsTab.plugin.settings.folderNoteType : "." + settingsTab.plugin.settings.folderNoteType;
dropdown.setValue(defaultType).onChange(async (value) => {
settingsTab.plugin.settings.folderNoteType = value;
settingsTab.plugin.saveSettings();
settingsTab.display();
});
});
const setting0 = new import_obsidian17.Setting(containerEl);
setting0.setName("Supported file types for folder notes");
const desc0 = document.createDocumentFragment();
desc0.append("Choose the file types that should be supported for folder notes. (e.g. if you click on a folder name it searches for all file extensions that are supported)", desc0.createEl("br"), "Adding more file types may cause performance issues becareful when adding more file types and don't add too many.");
setting0.setDesc(desc0);
const list = setting0.createList((list2) => {
list2.addSettings(settingsTab);
list2.setValues(settingsTab.plugin.settings.supportedFileTypes || ["md", "canvas"]);
list2.addResetButton();
});
if (!settingsTab.plugin.settings.supportedFileTypes.includes("md") || !settingsTab.plugin.settings.supportedFileTypes.includes("canvas") || !settingsTab.plugin.settings.supportedFileTypes.includes("excalidraw")) {
setting0.addDropdown((dropdown) => {
const options = [
{ value: "md", label: "Markdown" },
{ value: "canvas", label: "Canvas" },
{ value: "excalidraw", label: "excalidraw" },
{ value: "custom", label: "Custom extension" }
];
options.forEach((option) => {
var _a;
if (!((_a = settingsTab.plugin.settings.supportedFileTypes) == null ? void 0 : _a.includes(option.value))) {
dropdown.addOption(option.value, option.label);
}
});
dropdown.addOption("+", "+");
dropdown.setValue("+");
dropdown.onChange(async (value) => {
if (value === "custom") {
return new AddSupportedFileModal(settingsTab.app, settingsTab.plugin, settingsTab, list).open();
}
await list.addValue(value.toLowerCase());
settingsTab.display();
settingsTab.plugin.saveSettings();
});
});
} else {
setting0.addButton((button) => button.setButtonText("Add custom file type").setCta().onClick(async () => {
new AddSupportedFileModal(settingsTab.app, settingsTab.plugin, settingsTab, list).open();
}));
}
const setting = new import_obsidian17.Setting(containerEl);
const desc = document.createDocumentFragment();
desc.append("Restart after changing the template path");
setting.setName("Template path");
setting.setDesc(desc).descEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
setting.addSearch((cb) => {
var _a;
new TemplateSuggest(cb.inputEl, settingsTab.plugin);
cb.setPlaceholder("Template path");
cb.setValue(((_a = settingsTab.plugin.app.vault.getAbstractFileByPath(settingsTab.plugin.settings.templatePath)) == null ? void 0 : _a.name.replace(".md", "")) || "");
cb.onChange(async (value) => {
if (value.trim() === "") {
settingsTab.plugin.settings.templatePath = "";
await settingsTab.plugin.saveSettings();
settingsTab.display();
return;
}
});
});
const storageLocation = new import_obsidian17.Setting(containerEl).setName("Storage location").setDesc("Choose where to store the folder notes").addDropdown((dropdown) => dropdown.addOption("insideFolder", "Inside the folder").addOption("parentFolder", "In the parent folder").setValue(settingsTab.plugin.settings.storageLocation).onChange(async (value) => {
settingsTab.plugin.settings.storageLocation = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
loadFileClasses(void 0, settingsTab.plugin);
}));
storageLocation.infoEl.appendText("Requires a restart to take effect");
storageLocation.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
const switchLocation = new import_obsidian17.Setting(containerEl).setName("Switch to new storage location").setDesc("Move all folder notes to the new storage location").addButton((button) => button.setButtonText("Switch").setCta().onClick(async () => {
let oldStorageLocation = settingsTab.plugin.settings.storageLocation;
if (settingsTab.plugin.settings.storageLocation === "parentFolder") {
oldStorageLocation = "insideFolder";
} else if (settingsTab.plugin.settings.storageLocation === "insideFolder") {
oldStorageLocation = "parentFolder";
}
settingsTab.switchStorageLocation(oldStorageLocation);
}));
switchLocation.infoEl.appendText("Requires a restart to take effect");
switchLocation.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
if (settingsTab.plugin.settings.storageLocation === "parentFolder") {
new import_obsidian17.Setting(containerEl).setName("Delete folder notes when deleting the folder").setDesc("Delete the folder note when deleting the folder").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.syncDelete).onChange(async (value) => {
settingsTab.plugin.settings.syncDelete = value;
await settingsTab.plugin.saveSettings();
}));
new import_obsidian17.Setting(containerEl).setName("Move folder notes when moving the folder").setDesc("Move the folder note when moving the folder").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.syncMove).onChange(async (value) => {
settingsTab.plugin.settings.syncMove = value;
await settingsTab.plugin.saveSettings();
}));
}
if (import_obsidian17.Platform.isDesktopApp) {
new import_obsidian17.Setting(containerEl).setName("Key for creating folder note").setDesc("The key combination to create a folder note").addDropdown((dropdown) => {
if (!import_obsidian17.Platform.isMacOS) {
dropdown.addOption("ctrl", "Ctrl + Click");
} else {
dropdown.addOption("ctrl", "Cmd + Click");
}
dropdown.addOption("alt", "Alt + Click");
dropdown.setValue(settingsTab.plugin.settings.ctrlKey ? "ctrl" : "alt");
dropdown.onChange(async (value) => {
settingsTab.plugin.settings.ctrlKey = value === "ctrl";
settingsTab.plugin.settings.altKey = value === "alt";
await settingsTab.plugin.saveSettings();
settingsTab.display();
});
});
new import_obsidian17.Setting(containerEl).setName("Key for opening folder note").setDesc("Select the combination to open a folder note").addDropdown((dropdown) => {
dropdown.addOption("click", "Mouse Click");
if (!import_obsidian17.Platform.isMacOS) {
dropdown.addOption("ctrl", "Ctrl + Click");
} else {
dropdown.addOption("ctrl", "Cmd + Click");
}
dropdown.addOption("alt", "Alt + Click");
if (settingsTab.plugin.settings.openByClick) {
dropdown.setValue("click");
} else if (settingsTab.plugin.settings.openWithCtrl) {
dropdown.setValue("ctrl");
} else {
dropdown.setValue("alt");
}
dropdown.onChange(async (value) => {
settingsTab.plugin.settings.openByClick = value === "click";
settingsTab.plugin.settings.openWithCtrl = value === "ctrl";
settingsTab.plugin.settings.openWithAlt = value === "alt";
await settingsTab.plugin.saveSettings();
settingsTab.display();
});
});
}
new import_obsidian17.Setting(containerEl).setName("Sync folder name").setDesc("Automatically rename the folder note when the folder name is changed").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.syncFolderName).onChange(async (value) => {
settingsTab.plugin.settings.syncFolderName = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
new import_obsidian17.Setting(containerEl).setName("Confirm folder note deletion").setDesc("Ask for confirmation before deleting a folder note").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.showDeleteConfirmation).onChange(async (value) => {
settingsTab.plugin.settings.showDeleteConfirmation = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
new import_obsidian17.Setting(containerEl).setName("Deleted folder notes").setDesc("What happens to the folder note after you delete it").addDropdown((dropdown) => {
dropdown.addOption("trash", "Move to system trash");
dropdown.addOption("obsidianTrash", "Move to Obsidian trash (.trash folder)");
dropdown.addOption("delete", "Delete permanently");
dropdown.setValue(settingsTab.plugin.settings.deleteFilesAction);
dropdown.onChange(async (value) => {
settingsTab.plugin.settings.deleteFilesAction = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
});
});
if (import_obsidian17.Platform.isDesktop) {
const setting3 = new import_obsidian17.Setting(containerEl);
setting3.setName("Open folder note in a new tab by default");
setting3.setDesc("Always open folder notes in a new tab (except when you try to open the same note) instead of having to use ctrl/cmd + click to open in a new tab");
setting3.addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.openInNewTab).onChange(async (value) => {
settingsTab.plugin.settings.openInNewTab = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
setting3.infoEl.appendText("Requires a restart to take effect");
setting3.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
}
new import_obsidian17.Setting(containerEl).setName("Automatically create folder notes").setDesc("Automatically create a folder note when a new folder is created").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.autoCreate).onChange(async (value) => {
settingsTab.plugin.settings.autoCreate = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
new import_obsidian17.Setting(containerEl).setName("Enable front matter title plugin integration").setDesc("Automatically rename a folder name when the folder note is renamed").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.frontMatterTitle.enabled).onChange(async (value) => {
var _a;
settingsTab.plugin.settings.frontMatterTitle.enabled = value;
await settingsTab.plugin.saveSettings();
if (value) {
settingsTab.plugin.fmtpHandler = new FrontMatterTitlePluginHandler(settingsTab.plugin);
} else {
if (settingsTab.plugin.fmtpHandler) {
settingsTab.plugin.updateBreadcrumbs(true);
}
settingsTab.plugin.app.vault.getFiles().forEach((file) => {
var _a2;
(_a2 = settingsTab.plugin.fmtpHandler) == null ? void 0 : _a2.handleRename({ id: "", result: false, path: file.path }, false);
});
(_a = settingsTab.plugin.fmtpHandler) == null ? void 0 : _a.deleteEvent();
settingsTab.plugin.fmtpHandler = null;
}
settingsTab.display();
}));
new import_obsidian17.Setting(containerEl).setName("Create folder note for every folder").setDesc("Create a folder note for every folder in the vault").addButton((cb) => {
cb.setIcon("plus");
cb.setTooltip("Create folder notes");
cb.onClick(async () => {
new ConfirmationModal(settingsTab.app, settingsTab.plugin).open();
});
});
}
// src/settings/FileExplorerSettings.ts
var import_obsidian18 = require("obsidian");
async function renderFileExplorer(settingsTab) {
const containerEl = settingsTab.settingsPage;
new import_obsidian18.Setting(containerEl).setName("Hide folder note").setDesc("Hide the folder note in the file explorer").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.hideFolderNote).onChange(async (value) => {
settingsTab.plugin.settings.hideFolderNote = value;
await settingsTab.plugin.saveSettings();
if (value) {
document.body.classList.add("hide-folder-note");
} else {
document.body.classList.remove("hide-folder-note");
}
settingsTab.display();
}));
const setting2 = new import_obsidian18.Setting(containerEl).setName("Don't open folder notes by clicking on the name (on mobile)").setDesc("Folder notes don't open when clicking on the name of the folder (on mobile)").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.disableOpenFolderNoteOnClick).onChange(async (value) => {
settingsTab.plugin.settings.disableOpenFolderNoteOnClick = value;
await settingsTab.plugin.saveSettings();
}));
setting2.infoEl.appendText("Requires a restart to take effect");
setting2.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
new import_obsidian18.Setting(containerEl).setName("Only open folder notes through the name").setDesc("Only open folder notes in the file explorer by clicking on the folder name").addToggle((toggle) => toggle.setValue(!settingsTab.plugin.settings.stopWhitespaceCollapsing).onChange(async (value) => {
if (!value) {
document.body.classList.add("fn-whitespace-stop-collapsing");
} else {
document.body.classList.remove("fn-whitespace-stop-collapsing");
}
settingsTab.plugin.settings.stopWhitespaceCollapsing = !value;
await settingsTab.plugin.saveSettings();
}));
const disableSetting = new import_obsidian18.Setting(containerEl);
disableSetting.setName("Disable folder collapsing");
disableSetting.setDesc("Disable the ability to collapse folders by clicking exactly on the folder name");
disableSetting.addToggle((toggle) => toggle.setValue(!settingsTab.plugin.settings.enableCollapsing).onChange(async (value) => {
settingsTab.plugin.settings.enableCollapsing = !value;
await settingsTab.plugin.saveSettings();
}));
disableSetting.infoEl.appendText("Requires a restart to take effect");
disableSetting.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
new import_obsidian18.Setting(containerEl).setName("Use submenus").setDesc("Use submenus for file/folder commands").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.useSubmenus).onChange(async (value) => {
settingsTab.plugin.settings.useSubmenus = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
if (settingsTab.plugin.settings.frontMatterTitle.enabled) {
new import_obsidian18.Setting(containerEl).setName("Change folder name in the file explorer").setDesc("Automatically rename a folder name in the file explorer when the folder note is renamed").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.frontMatterTitle.explorer).onChange(async (value) => {
settingsTab.plugin.settings.frontMatterTitle.explorer = value;
await settingsTab.plugin.saveSettings();
settingsTab.plugin.app.vault.getFiles().forEach((file) => {
var _a;
(_a = settingsTab.plugin.fmtpHandler) == null ? void 0 : _a.handleRename({ id: "", result: false, path: file.path }, false);
});
}));
}
settingsTab.settingsPage.createEl("h3", { text: "Style settings" });
new import_obsidian18.Setting(containerEl).setName("Hide collapse icon").setDesc("Hide the collapse icon in the file explorer next to the name of a folder when a folder only contains a folder note").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.hideCollapsingIcon).onChange(async (value) => {
settingsTab.plugin.settings.hideCollapsingIcon = value;
await settingsTab.plugin.saveSettings();
if (value) {
document.body.classList.add("fn-hide-collapse-icon");
} else {
document.body.classList.remove("fn-hide-collapse-icon");
}
settingsTab.display();
}));
if (settingsTab.plugin.settings.hideCollapsingIcon) {
new import_obsidian18.Setting(containerEl).setName("Hide collapse icon also when the attachment folder is in the same folder").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.ignoreAttachmentFolder).onChange(async (value) => {
settingsTab.plugin.settings.ignoreAttachmentFolder = value;
await settingsTab.plugin.saveSettings();
}));
}
new import_obsidian18.Setting(containerEl).setName("Underline the name of folder notes").setDesc("Add an underline to folders that have a folder note in the file explorer").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.underlineFolder).onChange(async (value) => {
settingsTab.plugin.settings.underlineFolder = value;
if (value) {
document.body.classList.add("folder-note-underline");
} else {
document.body.classList.remove("folder-note-underline");
}
await settingsTab.plugin.saveSettings();
}));
new import_obsidian18.Setting(containerEl).setName("Bold the name of folder notes").setDesc("Make the folder name bold in the file explorer").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.boldName).onChange(async (value) => {
settingsTab.plugin.settings.boldName = value;
if (value) {
document.body.classList.add("folder-note-bold");
} else {
document.body.classList.remove("folder-note-bold");
}
await settingsTab.plugin.saveSettings();
}));
new import_obsidian18.Setting(containerEl).setName("Cursive the name of folder notes").setDesc("Make the folder name cursive in the file explorer").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.cursiveName).onChange(async (value) => {
settingsTab.plugin.settings.cursiveName = value;
if (value) {
document.body.classList.add("folder-note-cursive");
} else {
document.body.classList.remove("folder-note-cursive");
}
await settingsTab.plugin.saveSettings();
}));
}
// src/settings/PathSettings.ts
var import_obsidian19 = require("obsidian");
async function renderPath(settingsTab) {
const containerEl = settingsTab.settingsPage;
new import_obsidian19.Setting(containerEl).setName("Open folder note through path").setDesc("Open a folder note when clicking on a folder name in the path if it is a folder note").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.openFolderNoteOnClickInPath).onChange(async (value) => {
settingsTab.plugin.settings.openFolderNoteOnClickInPath = value;
await settingsTab.plugin.saveSettings();
settingsTab.display();
}));
new import_obsidian19.Setting(containerEl).setName("Change folder name in the path").setDesc("Automatically rename a folder name in the path above a note when the folder note is renamed").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.frontMatterTitle.path).onChange(async (value) => {
settingsTab.plugin.settings.frontMatterTitle.path = value;
await settingsTab.plugin.saveSettings();
if (value) {
settingsTab.plugin.updateBreadcrumbs();
} else {
settingsTab.plugin.updateBreadcrumbs(true);
}
}));
settingsTab.settingsPage.createEl("h3", { text: "Style settings" });
new import_obsidian19.Setting(containerEl).setName("Underline folders in the path").setDesc("Add an underline to folders that have a folder note in the path above a note").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.underlineFolderInPath).onChange(async (value) => {
settingsTab.plugin.settings.underlineFolderInPath = value;
if (value) {
document.body.classList.add("folder-note-underline-path");
} else {
document.body.classList.remove("folder-note-underline-path");
}
await settingsTab.plugin.saveSettings();
}));
new import_obsidian19.Setting(containerEl).setName("Bold folders in the path").setDesc("Make the folder name bold in the path above a note").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.boldNameInPath).onChange(async (value) => {
settingsTab.plugin.settings.boldNameInPath = value;
if (value) {
document.body.classList.add("folder-note-bold-path");
} else {
document.body.classList.remove("folder-note-bold-path");
}
await settingsTab.plugin.saveSettings();
}));
new import_obsidian19.Setting(containerEl).setName("Cursive the name of folder notes in the path").setDesc("Make the folder name cursive in the path above a note").addToggle((toggle) => toggle.setValue(settingsTab.plugin.settings.cursiveNameInPath).onChange(async (value) => {
settingsTab.plugin.settings.cursiveNameInPath = value;
if (value) {
document.body.classList.add("folder-note-cursive-path");
} else {
document.body.classList.remove("folder-note-cursive-path");
}
await settingsTab.plugin.saveSettings();
}));
}
// src/settings/FolderOverviewSettings.ts
var import_obsidian22 = require("obsidian");
// src/folderOverview/ModalSettings.ts
var import_obsidian21 = require("obsidian");
// src/folderOverview/FolderOverview.ts
var import_obsidian20 = require("obsidian");
var FolderOverview = class {
constructor(plugin, ctx, source, el) {
this.pathBlacklist = [];
this.folders = [];
let yaml = (0, import_obsidian20.parseYaml)(source);
if (!yaml) {
yaml = {};
}
const includeTypes = (yaml == null ? void 0 : yaml.includeTypes) || plugin.settings.defaultOverview.includeTypes || ["folder", "markdown"];
this.plugin = plugin;
this.ctx = ctx;
this.source = source;
this.el = el;
this.sourceFilePath = this.ctx.sourcePath;
this.yaml = {
id: (yaml == null ? void 0 : yaml.id) || crypto.randomUUID(),
folderPath: (yaml == null ? void 0 : yaml.folderPath) === void 0 || (yaml == null ? void 0 : yaml.folderPath) === null ? getFolderPathFromString(ctx.sourcePath) : yaml == null ? void 0 : yaml.folderPath,
title: (yaml == null ? void 0 : yaml.title) || plugin.settings.defaultOverview.title,
showTitle: (yaml == null ? void 0 : yaml.showTitle) === void 0 || (yaml == null ? void 0 : yaml.showTitle) === null ? plugin.settings.defaultOverview.showTitle : yaml == null ? void 0 : yaml.showTitle,
depth: (yaml == null ? void 0 : yaml.depth) || plugin.settings.defaultOverview.depth,
style: (yaml == null ? void 0 : yaml.style) || "list",
includeTypes: includeTypes.map((type) => type.toLowerCase()),
disableFileTag: (yaml == null ? void 0 : yaml.disableFileTag) === void 0 || (yaml == null ? void 0 : yaml.disableFileTag) === null ? plugin.settings.defaultOverview.disableFileTag : yaml == null ? void 0 : yaml.disableFileTag,
sortBy: (yaml == null ? void 0 : yaml.sortBy) || plugin.settings.defaultOverview.sortBy,
sortByAsc: (yaml == null ? void 0 : yaml.sortByAsc) === void 0 || (yaml == null ? void 0 : yaml.sortByAsc) === null ? plugin.settings.defaultOverview.sortByAsc : yaml == null ? void 0 : yaml.sortByAsc,
showEmptyFolders: (yaml == null ? void 0 : yaml.showEmptyFolders) === void 0 || (yaml == null ? void 0 : yaml.showEmptyFolders) === null ? plugin.settings.defaultOverview.showEmptyFolders : yaml == null ? void 0 : yaml.showEmptyFolders,
onlyIncludeSubfolders: (yaml == null ? void 0 : yaml.onlyIncludeSubfolders) === void 0 || (yaml == null ? void 0 : yaml.onlyIncludeSubfolders) === null ? plugin.settings.defaultOverview.onlyIncludeSubfolders : yaml == null ? void 0 : yaml.onlyIncludeSubfolders,
storeFolderCondition: (yaml == null ? void 0 : yaml.storeFolderCondition) === void 0 || (yaml == null ? void 0 : yaml.storeFolderCondition) === null ? plugin.settings.defaultOverview.storeFolderCondition : yaml == null ? void 0 : yaml.storeFolderCondition,
showFolderNotes: (yaml == null ? void 0 : yaml.showFolderNotes) === void 0 || (yaml == null ? void 0 : yaml.showFolderNotes) === null ? plugin.settings.defaultOverview.showFolderNotes : yaml == null ? void 0 : yaml.showFolderNotes,
disableCollapseIcon: (yaml == null ? void 0 : yaml.disableCollapseIcon) === void 0 || (yaml == null ? void 0 : yaml.disableCollapseIcon) === null ? plugin.settings.defaultOverview.disableCollapseIcon : yaml == null ? void 0 : yaml.disableCollapseIcon
};
}
create(plugin, source, el, ctx) {
var _a;
el.empty();
(_a = el.parentElement) == null ? void 0 : _a.classList.add("folder-overview-container");
const root = el.createEl("div", { cls: "folder-overview" });
const titleEl = root.createEl("h1", { cls: "folder-overview-title" });
const ul = root.createEl("ul", { cls: "folder-overview-list" });
if (this.yaml.includeTypes.length === 0) {
return this.addEditButton(root);
}
let files = [];
const sourceFile = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath);
if (!sourceFile)
return;
let sourceFolderPath = this.yaml.folderPath || getFolderPathFromString(ctx.sourcePath);
let sourceFolder;
if (sourceFolderPath !== "/") {
if (this.yaml.folderPath === "") {
sourceFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(ctx.sourcePath));
} else {
sourceFolder = plugin.app.vault.getAbstractFileByPath(this.yaml.folderPath);
}
}
if (this.yaml.showTitle) {
if (sourceFolder && sourceFolderPath !== "/") {
titleEl.innerText = this.yaml.title.replace("{{folderName}}", sourceFolder.name);
} else if (sourceFolderPath == "/") {
titleEl.innerText = this.yaml.title.replace("{{folderName}}", "Vault");
} else {
titleEl.innerText = this.yaml.title.replace("{{folderName}}", "");
}
}
if (!sourceFolder && (sourceFolderPath !== "/" && sourceFolderPath !== "")) {
return new import_obsidian20.Notice("Folder overview: Couldn't find the folder");
}
if (!sourceFolder && sourceFolderPath == "") {
sourceFolderPath = "/";
}
if (sourceFolderPath == "/") {
const rootFiles = [];
plugin.app.vault.getAllLoadedFiles().filter((f) => {
var _a2;
return ((_a2 = f.parent) == null ? void 0 : _a2.path) === "/";
}).forEach((file) => {
if (!file.path.includes("/")) {
rootFiles.push(file);
}
});
files = rootFiles;
} else if (sourceFolder) {
files = sourceFolder.children;
}
files = this.filterFiles(files, plugin, sourceFolderPath, this.yaml.depth, this.pathBlacklist);
if (!this.yaml.includeTypes.includes("folder")) {
files = this.getAllFiles(files, sourceFolderPath, this.yaml.depth);
}
if (files.length === 0) {
return this.addEditButton(root);
}
files = this.sortFiles(files);
if (this.yaml.style === "grid") {
const grid = root.createEl("div", { cls: "folder-overview-grid" });
files.forEach(async (file) => {
const gridItem = grid.createEl("div", { cls: "folder-overview-grid-item" });
const gridArticle = gridItem.createEl("article", { cls: "folder-overview-grid-item-article" });
if (file instanceof import_obsidian20.TFile) {
const fileContent = await plugin.app.vault.read(file);
const descriptionEl = gridArticle.createEl("p", { cls: "folder-overview-grid-item-description" });
let description = fileContent.split("\n")[0];
if (description.length > 64) {
description = description.slice(0, 64) + "...";
}
descriptionEl.innerText = description;
const link = gridArticle.createEl("a", { cls: "folder-overview-grid-item-link internal-link" });
const title = link.createEl("h1", { cls: "folder-overview-grid-item-link-title" });
title.innerText = file.name.replace(".md", "").replace(".canvas", "");
link.href = file.path;
} else if (file instanceof import_obsidian20.TFolder) {
const folderItem = gridArticle.createEl("div", { cls: "folder-overview-grid-item-folder" });
const folderName = folderItem.createEl("h1", { cls: "folder-overview-grid-item-folder-name" });
folderName.innerText = file.name;
}
});
} else if (this.yaml.style === "list") {
const folders = this.sortFiles(files.filter((f) => f instanceof import_obsidian20.TFolder));
files = this.sortFiles(files.filter((f) => f instanceof import_obsidian20.TFile));
folders.forEach((file) => {
if (file instanceof import_obsidian20.TFolder) {
const folderItem = this.addFolderList(plugin, ul, this.pathBlacklist, file);
if (!folderItem) {
return;
}
this.goThroughFolders(plugin, folderItem, file, this.yaml.depth, sourceFolderPath, ctx, this.yaml, this.pathBlacklist, this.yaml.includeTypes, this.yaml.disableFileTag);
}
});
files.forEach((file) => {
if (file instanceof import_obsidian20.TFile) {
this.addFileList(plugin, ul, this.pathBlacklist, file, this.yaml.includeTypes, this.yaml.disableFileTag);
}
});
} else if (this.yaml.style === "explorer") {
if (this.plugin.app.workspace.layoutReady) {
this.cloneFileExplorerView(plugin, ctx, root, this.yaml, this.pathBlacklist);
} else {
this.plugin.app.workspace.onLayoutReady(() => {
this.cloneFileExplorerView(plugin, ctx, root, this.yaml, this.pathBlacklist);
});
}
}
const overviewListEl = el.childNodes[0].childNodes[1];
if (overviewListEl && overviewListEl.childNodes.length === 0) {
if (this.yaml.style === "explorer") {
const overview = el.childNodes[0];
if (!overview.childNodes[2]) {
if (this.plugin.app.workspace.layoutReady) {
return this.addEditButton(root);
}
}
} else {
if (this.plugin.app.workspace.layoutReady) {
return this.addEditButton(root);
}
}
}
if (this.yaml.includeTypes.length > 1 && (!this.yaml.showEmptyFolders || this.yaml.onlyIncludeSubfolders) && this.yaml.style === "list") {
this.removeEmptyFolders(ul, 1, this.yaml);
}
}
addEditButton(root) {
const editButton = root.createEl("button", { cls: "folder-overview-edit-button" });
editButton.innerText = "Edit overview";
editButton.addEventListener("click", (e) => {
e.stopImmediatePropagation();
e.preventDefault();
e.stopPropagation();
new FolderOverviewSettings(this.plugin.app, this.plugin, this.yaml, this.ctx, this.el).open();
}, { capture: true });
}
cloneFileExplorerView(plugin, ctx, root, yaml, pathBlacklist) {
const folder = getEl(this.yaml.folderPath);
let folderElement = folder == null ? void 0 : folder.parentElement;
let tFolder = plugin.app.vault.getAbstractFileByPath(this.yaml.folderPath);
if (!tFolder && yaml.folderPath.trim() == "") {
tFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(ctx.sourcePath));
}
if (!folderElement && yaml.folderPath.trim() !== "")
return;
folderElement = document.querySelector("div.nav-files-container");
if (!folderElement)
return;
const newFolderElement = folderElement.cloneNode(true);
newFolderElement.querySelectorAll("div.nav-folder-title ").forEach((el) => {
var _a;
const folder2 = plugin.app.vault.getAbstractFileByPath(el.getAttribute("data-path") || "");
if (!(folder2 instanceof import_obsidian20.TFolder))
return;
if (this.yaml.storeFolderCondition) {
if (folder2.collapsed) {
el.classList.add("is-collapsed");
} else {
el.classList.remove("is-collapsed");
}
} else {
if ((_a = el.parentElement) == null ? void 0 : _a.classList.contains("is-collapsed")) {
folder2.collapsed = true;
} else {
folder2.collapsed = false;
}
}
if (el.classList.contains("has-folder-note")) {
const folderNote = getFolderNote(plugin, folder2.path);
if (folderNote) {
this.pathBlacklist.push(folderNote.path);
}
}
});
if (tFolder instanceof import_obsidian20.TFolder) {
this.addFiles(tFolder.children, root);
} else if (yaml.folderPath.trim() === "/") {
const rootFiles = [];
plugin.app.vault.getAllLoadedFiles().filter((f) => f instanceof import_obsidian20.TFolder).forEach((file) => {
if (!file.path.includes("/")) {
rootFiles.push(file);
}
});
this.addFiles(rootFiles, root);
}
newFolderElement.querySelectorAll("div.tree-item-icon").forEach((el) => {
if (el instanceof HTMLElement) {
el.onclick = () => {
var _a;
const path = (_a = el.parentElement) == null ? void 0 : _a.getAttribute("data-path");
if (!path)
return;
const folder2 = plugin.app.vault.getAbstractFileByPath(path);
this.handleCollapseClick(el, plugin, yaml, pathBlacklist, this.source, folder2);
};
}
});
}
async addFiles(files, childrenElement) {
const folders = this.sortFiles(files.filter((file) => file instanceof import_obsidian20.TFolder));
const filesWithoutFolders = this.sortFiles(files.filter((file) => !(file instanceof import_obsidian20.TFolder)));
for (const child of folders) {
if (child instanceof import_obsidian20.TFolder) {
const folderNote = getFolderNote(this.plugin, child.path);
if (folderNote) {
this.pathBlacklist.push(folderNote.path);
}
const excludedFolder = getExcludedFolder(this.plugin, child.path);
if (excludedFolder == null ? void 0 : excludedFolder.excludeFromFolderOverview) {
continue;
}
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon right-triangle"><path d="M3 8L12 17L21 8"></path></svg>';
const folderElement = childrenElement.createDiv({
cls: "tree-item nav-folder"
});
const folderTitle = folderElement.createDiv({
cls: "tree-item-self is-clickable nav-folder-title",
attr: {
"data-path": child.path,
"draggable": "true"
}
});
if (!child.collapsed) {
folderTitle.classList.remove("is-collapsed");
const childrenElement2 = folderElement == null ? void 0 : folderElement.createDiv({ cls: "tree-item-children nav-folder-children" });
this.addFiles(child.children, childrenElement2);
} else {
folderTitle.classList.add("is-collapsed");
}
if (folderNote) {
folderTitle.classList.add("has-folder-note");
}
if (folderNote && child.children.length === 1 && this.yaml.disableCollapseIcon) {
folderTitle.classList.add("fn-has-no-files");
}
const collapseIcon = folderTitle.createDiv({
cls: "tree-item-icon collapse-icon nav-folder-collapse-indicator fn-folder-overview-collapse-icon"
});
if (child.collapsed) {
collapseIcon.classList.add("is-collapsed");
}
collapseIcon.innerHTML = svg;
collapseIcon.onclick = () => {
this.handleCollapseClick(collapseIcon, this.plugin, this.yaml, this.pathBlacklist, this.source, child);
};
folderTitle.createDiv({
cls: "tree-item-inner nav-folder-title-content",
text: child.name
});
}
}
for (const child of filesWithoutFolders) {
if (child instanceof import_obsidian20.TFile) {
if (this.pathBlacklist.includes(child.path) && !this.yaml.showFolderNotes) {
continue;
}
const extension = child.extension.toLowerCase() == "md" ? "markdown" : child.extension.toLowerCase();
const includeTypes = this.yaml.includeTypes;
if (includeTypes.length > 0 && !includeTypes.includes("all")) {
if ((extension === "md" || extension === "markdown") && !includeTypes.includes("markdown"))
continue;
if (extension === "canvas" && !includeTypes.includes("canvas"))
continue;
if (extension === "pdf" && !includeTypes.includes("pdf"))
continue;
const imageTypes = ["jpg", "jpeg", "png", "gif", "svg", "webp"];
if (imageTypes.includes(extension) && !includeTypes.includes("image"))
continue;
const videoTypes = ["mp4", "webm", "ogv", "mov", "mkv"];
if (videoTypes.includes(extension) && !includeTypes.includes("video"))
continue;
const audioTypes = ["mp3", "wav", "m4a", "3gp", "flac", "ogg", "oga", "opus"];
if (audioTypes.includes(extension) && includeTypes.includes("audio"))
continue;
const allTypes = ["markdown", "md", "canvas", "pdf", ...imageTypes, ...videoTypes, ...audioTypes];
if (!allTypes.includes(extension) && !includeTypes.includes("other"))
continue;
}
const fileElement = childrenElement.createDiv({
cls: "tree-item nav-file"
});
const fileTitle = fileElement.createDiv({
cls: "tree-item-self is-clickable nav-file-title pointer-cursor",
attr: {
"data-path": child.path,
"draggable": "true"
}
});
fileTitle.onclick = () => {
this.plugin.app.workspace.openLinkText(child.path, child.path, true);
};
fileTitle.createDiv({
cls: "tree-item-inner nav-file-title-content",
text: child.basename
});
if (child.extension !== "md") {
fileTitle.createDiv({
cls: "nav-file-tag",
text: child.extension
});
}
}
}
}
handleCollapseClick(el, plugin, yaml, pathBlacklist, sourcePath, folder) {
var _a, _b, _c, _d;
el.classList.toggle("is-collapsed");
if (el.classList.contains("is-collapsed")) {
if (!(folder instanceof import_obsidian20.TFolder))
return;
folder.collapsed = true;
(_c = (_b = (_a = el.parentElement) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.childNodes[1]) == null ? void 0 : _c.remove();
} else {
if (!(folder instanceof import_obsidian20.TFolder))
return;
folder.collapsed = false;
const folderElement = (_d = el.parentElement) == null ? void 0 : _d.parentElement;
if (!folderElement)
return;
const childrenElement = folderElement.createDiv({ cls: "tree-item-children nav-folder-children" });
let files = this.sortFiles(folder.children);
files = this.filterFiles(files, plugin, folder.path, this.yaml.depth || 1, pathBlacklist);
this.addFiles(files, childrenElement);
}
}
goThroughFolders(plugin, list, folder, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag) {
if (sourceFolderPath === "") {
depth--;
}
let files = this.filterFiles(folder.children, plugin, sourceFolderPath, depth, pathBlacklist);
files = this.sortFiles(files.filter((file) => !(file instanceof import_obsidian20.TFolder)));
if (this.yaml.sortByAsc) {
files = files.reverse();
}
const folders = this.sortFiles(files.filter((file) => file instanceof import_obsidian20.TFolder));
const ul = list.createEl("ul", { cls: "folder-overview-list" });
folders.forEach((file) => {
if (file instanceof import_obsidian20.TFolder) {
const folderItem = this.addFolderList(plugin, ul, pathBlacklist, file);
if (!folderItem)
return;
this.goThroughFolders(plugin, folderItem, file, depth, sourceFolderPath, ctx, yaml, pathBlacklist, includeTypes, disableFileTag);
}
});
files.forEach((file) => {
if (file instanceof import_obsidian20.TFile) {
this.addFileList(plugin, ul, pathBlacklist, file, includeTypes, disableFileTag);
}
});
}
filterFiles(files, plugin, sourceFolderPath, depth, pathBlacklist) {
return files.filter((file) => {
if (pathBlacklist.includes(file.path) && !this.yaml.showFolderNotes) {
return false;
}
const folderPath = getFolderPathFromString(file.path);
if (!folderPath.startsWith(sourceFolderPath) && sourceFolderPath !== "/") {
return false;
}
if (file.path === this.sourceFilePath) {
return false;
}
const excludedFolder = getExcludedFolder(plugin, file.path);
if (excludedFolder == null ? void 0 : excludedFolder.excludeFromFolderOverview) {
return false;
}
if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth) {
return true;
}
});
}
sortFiles(files) {
const yaml = this.yaml;
if (!(yaml == null ? void 0 : yaml.sortBy)) {
yaml.sortBy = this.plugin.settings.defaultOverview.sortBy || "name";
yaml.sortByAsc = this.plugin.settings.defaultOverview.sortByAsc || false;
}
files.sort((a, b) => {
if (a instanceof import_obsidian20.TFolder && !(b instanceof import_obsidian20.TFolder)) {
return -1;
}
if (!(a instanceof import_obsidian20.TFolder) && b instanceof import_obsidian20.TFolder) {
return 1;
}
if (a instanceof import_obsidian20.TFolder && b instanceof import_obsidian20.TFolder) {
if (a.name.localeCompare(b.name) < 0) {
return -1;
} else if (a.name.localeCompare(b.name) > 0) {
return 1;
}
}
if (!(a instanceof import_obsidian20.TFile) || !(b instanceof import_obsidian20.TFile)) {
return -1;
}
if (yaml.sortBy === "created") {
if (a.stat.ctime > b.stat.ctime) {
return -1;
} else if (a.stat.ctime < b.stat.ctime) {
return 1;
}
} else if (yaml.sortBy === "modified") {
if (a.stat.mtime > b.stat.mtime) {
return -1;
} else if (a.stat.mtime < b.stat.mtime) {
return 1;
}
} else if (yaml.sortBy === "name") {
if (a.basename.localeCompare(b.basename) < 0) {
return -1;
} else if (a.basename.localeCompare(b.basename) > 0) {
return 1;
}
}
return 0;
});
if (!(yaml == null ? void 0 : yaml.sortByAsc)) {
files = files.reverse();
}
return files;
}
removeEmptyFolders(ul, depth, yaml) {
const childrensToRemove = [];
ul.childNodes.forEach((el) => {
var _a, _b;
if (((_a = el.childNodes[0]) == null ? void 0 : _a.classList) && ((_b = el.childNodes[0]) == null ? void 0 : _b.classList.contains("internal-link"))) {
return;
}
const childrens = el.querySelector("ul");
if (!childrens || childrens === null) {
return;
}
if (childrens && !(childrens == null ? void 0 : childrens.hasChildNodes()) && !(el instanceof HTMLUListElement)) {
childrensToRemove.push(el);
} else if (el instanceof HTMLUListElement || el instanceof HTMLLIElement) {
this.removeEmptyFolders(el, depth + 1, yaml);
}
});
childrensToRemove.forEach((el) => {
if (yaml.onlyIncludeSubfolders && depth === 1) {
return;
}
el.remove();
});
}
addFolderList(plugin, list, pathBlacklist, folder) {
const folderItem = list.createEl("li", { cls: "folder-overview-list folder-list" });
const folderNote = getFolderNote(plugin, folder.path);
if (folderNote instanceof import_obsidian20.TFile) {
const folderNoteLink = folderItem.createEl("a", { cls: "folder-overview-list-item folder-name-item internal-link", href: folderNote.path });
folderNoteLink.innerText = folder.name;
pathBlacklist.push(folderNote.path);
} else {
const folderName = folderItem.createEl("span", { cls: "folder-overview-list-item folder-name-item" });
folderName.innerText = folder.name;
}
return folderItem;
}
addFileList(plugin, list, pathBlacklist, file, includeTypes, disableFileTag) {
if (includeTypes.length > 0 && !includeTypes.includes("all")) {
if (file.extension === "md" && !includeTypes.includes("markdown"))
return;
if (file.extension === "canvas" && !includeTypes.includes("canvas"))
return;
if (file.extension === "pdf" && !includeTypes.includes("pdf"))
return;
const imageTypes = ["jpg", "jpeg", "png", "gif", "svg", "webp"];
if (imageTypes.includes(file.extension) && !includeTypes.includes("image"))
return;
const videoTypes = ["mp4", "webm", "ogv", "mov", "mkv"];
if (videoTypes.includes(file.extension) && !includeTypes.includes("video"))
return;
const audioTypes = ["mp3", "wav", "m4a", "3gp", "flac", "ogg", "oga", "opus"];
if (audioTypes.includes(file.extension) && includeTypes.includes("audio"))
return;
const allTypes = ["md", "canvas", "pdf", ...imageTypes, ...videoTypes, ...audioTypes];
if (!allTypes.includes(file.extension) && !includeTypes.includes("other"))
return;
}
if (!this.yaml.showFolderNotes) {
if (pathBlacklist.includes(file.path))
return;
}
const listItem = list.createEl("li", { cls: "folder-overview-list file-link" });
const nameItem = listItem.createEl("div", { cls: "folder-overview-list-item" });
const link = nameItem.createEl("a", { cls: "internal-link", href: file.path });
link.innerText = file.basename;
if (file.extension !== "md" && !disableFileTag) {
nameItem.createDiv({ cls: "nav-file-tag" }).innerText = file.extension;
}
}
getAllFiles(files, sourceFolderPath, depth) {
const allFiles = [];
files.forEach((file) => {
if (file instanceof import_obsidian20.TFolder) {
if (file.path.split("/").length - sourceFolderPath.split("/").length - 1 < depth - 1) {
allFiles.push(...this.getAllFiles(file.children, sourceFolderPath, depth));
}
} else {
allFiles.push(file);
}
});
return allFiles;
}
};
async function updateYaml(plugin, ctx, el, yaml) {
const file = plugin.app.vault.getAbstractFileByPath(ctx.sourcePath);
if (!(file instanceof import_obsidian20.TFile))
return;
let stringYaml = (0, import_obsidian20.stringifyYaml)(yaml);
await plugin.app.vault.process(file, (text) => {
const info = ctx.getSectionInfo(el);
if (stringYaml[stringYaml.length - 1] !== "\n") {
stringYaml += "\n";
}
if (info) {
const { lineStart } = info;
const lineEnd = getCodeBlockEndLine(text, lineStart);
if (lineEnd === -1 || !lineEnd)
return text;
const lineLength = lineEnd - lineStart;
const lines = text.split("\n");
lines.splice(lineStart, lineLength + 1, `\`\`\`folder-overview
${stringYaml}\`\`\``);
return lines.join("\n");
}
return `\`\`\`folder-overview
${stringYaml}\`\`\``;
});
}
function getCodeBlockEndLine(text, startLine, count = 1) {
let line = startLine + 1;
const lines = text.split("\n");
while (line < lines.length) {
if (count > 50) {
return -1;
}
if (lines[line].startsWith("```")) {
return line;
}
line++;
count++;
}
return line;
}
// src/folderOverview/ModalSettings.ts
var FolderOverviewSettings = class extends import_obsidian21.Modal {
constructor(app2, plugin, yaml, ctx, el, defaultSettings) {
super(app2);
this.plugin = plugin;
this.app = app2;
if (!yaml) {
this.yaml = this.plugin.settings.defaultOverview;
} else if (ctx) {
const includeTypes = (yaml == null ? void 0 : yaml.includeTypes) || plugin.settings.defaultOverview.includeTypes || ["folder", "markdown"];
this.yaml = {
id: (yaml == null ? void 0 : yaml.id) || crypto.randomUUID(),
folderPath: (yaml == null ? void 0 : yaml.folderPath) === void 0 || (yaml == null ? void 0 : yaml.folderPath) === null ? getFolderPathFromString(ctx.sourcePath) : yaml == null ? void 0 : yaml.folderPath,
title: (yaml == null ? void 0 : yaml.title) || plugin.settings.defaultOverview.title,
showTitle: (yaml == null ? void 0 : yaml.showTitle) === void 0 || (yaml == null ? void 0 : yaml.showTitle) === null ? plugin.settings.defaultOverview.showTitle : yaml == null ? void 0 : yaml.showTitle,
depth: (yaml == null ? void 0 : yaml.depth) || plugin.settings.defaultOverview.depth,
style: (yaml == null ? void 0 : yaml.style) || "list",
includeTypes: includeTypes.map((type) => type.toLowerCase()),
disableFileTag: (yaml == null ? void 0 : yaml.disableFileTag) === void 0 || (yaml == null ? void 0 : yaml.disableFileTag) === null ? plugin.settings.defaultOverview.disableFileTag : yaml == null ? void 0 : yaml.disableFileTag,
sortBy: (yaml == null ? void 0 : yaml.sortBy) || plugin.settings.defaultOverview.sortBy,
sortByAsc: (yaml == null ? void 0 : yaml.sortByAsc) === void 0 || (yaml == null ? void 0 : yaml.sortByAsc) === null ? plugin.settings.defaultOverview.sortByAsc : yaml == null ? void 0 : yaml.sortByAsc,
showEmptyFolders: (yaml == null ? void 0 : yaml.showEmptyFolders) === void 0 || (yaml == null ? void 0 : yaml.showEmptyFolders) === null ? plugin.settings.defaultOverview.showEmptyFolders : yaml == null ? void 0 : yaml.showEmptyFolders,
onlyIncludeSubfolders: (yaml == null ? void 0 : yaml.onlyIncludeSubfolders) === void 0 || (yaml == null ? void 0 : yaml.onlyIncludeSubfolders) === null ? plugin.settings.defaultOverview.onlyIncludeSubfolders : yaml == null ? void 0 : yaml.onlyIncludeSubfolders,
storeFolderCondition: (yaml == null ? void 0 : yaml.storeFolderCondition) === void 0 || (yaml == null ? void 0 : yaml.storeFolderCondition) === null ? plugin.settings.defaultOverview.storeFolderCondition : yaml == null ? void 0 : yaml.storeFolderCondition,
showFolderNotes: (yaml == null ? void 0 : yaml.showFolderNotes) === void 0 || (yaml == null ? void 0 : yaml.showFolderNotes) === null ? plugin.settings.defaultOverview.showFolderNotes : yaml == null ? void 0 : yaml.showFolderNotes,
disableCollapseIcon: (yaml == null ? void 0 : yaml.disableCollapseIcon) === void 0 || (yaml == null ? void 0 : yaml.disableCollapseIcon) === null ? plugin.settings.defaultOverview.disableCollapseIcon : yaml == null ? void 0 : yaml.disableCollapseIcon
};
}
if (ctx) {
this.ctx = ctx;
}
if (el) {
this.el = el;
}
if (defaultSettings) {
this.yaml = this.plugin.settings.defaultOverview;
this.defaultSettings = true;
return;
}
updateYaml(this.plugin, this.ctx, this.el, this.yaml);
}
onOpen() {
this.display();
}
display() {
var _a, _b, _c, _d;
const { contentEl } = this;
contentEl.empty();
contentEl.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
this.close();
}
});
if (!this.defaultSettings) {
contentEl.createEl("h2", { text: "Folder overview settings" });
} else {
contentEl.createEl("h2", { text: "Default folder overview settings" });
}
new import_obsidian21.Setting(contentEl).setName("Show the title").setDesc("Choose if the title should be shown").addToggle((toggle) => toggle.setValue(this.yaml.showTitle).onChange(async (value) => {
this.yaml.showTitle = value;
this.display();
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
;
}));
if (this.yaml.showTitle) {
new import_obsidian21.Setting(contentEl).setName("Title").setDesc("Choose the title of the folder overview").addText((text) => {
var _a2;
return text.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.title) || "{{folderName}} overview").onChange(async (value) => {
this.yaml.title = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
;
});
});
}
new import_obsidian21.Setting(contentEl).setName("Folder path for the overview").setDesc("Choose the folder path for the overview").addSearch((search) => {
var _a2;
new FolderSuggest(search.inputEl, this.plugin);
search.setPlaceholder("Folder path").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.folderPath) || "").onChange(async (value) => {
if (!(this.app.vault.getAbstractFileByPath(value) instanceof import_obsidian21.TFolder) && value !== "")
return;
this.yaml.folderPath = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
;
});
});
new import_obsidian21.Setting(contentEl).setName("Overview style").setDesc("Choose the style of the overview (grid style soon)").addDropdown((dropdown) => {
var _a2;
return dropdown.addOption("list", "List").addOption("explorer", "Explorer").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.style) || "list").onChange(async (value) => {
this.yaml.style = value;
this.display();
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
if (this.yaml.style === "explorer") {
new import_obsidian21.Setting(contentEl).setName("Store collapsed condition").setDesc("Choose if the collapsed condition should be stored stored until you restart Obsidian").addToggle((toggle) => toggle.setValue(this.yaml.storeFolderCondition).onChange(async (value) => {
this.yaml.storeFolderCondition = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
;
}));
}
const setting = new import_obsidian21.Setting(contentEl);
setting.setName("Include types");
const list = setting.createList((list2) => {
var _a2;
return list2.addModal(this).setValues(((_a2 = this.yaml) == null ? void 0 : _a2.includeTypes) || this.plugin.settings.defaultOverview.includeTypes || []).addResetButton();
});
if ((((_b = (_a = this.yaml) == null ? void 0 : _a.includeTypes) == null ? void 0 : _b.length) || 0) < 8 && !((_c = this.yaml.includeTypes) == null ? void 0 : _c.includes("all"))) {
setting.addDropdown((dropdown) => {
if (!this.yaml.includeTypes)
this.yaml.includeTypes = this.plugin.settings.defaultOverview.includeTypes || [];
this.yaml.includeTypes = this.yaml.includeTypes.map((type) => type.toLowerCase());
const options = [
{ value: "markdown", label: "Markdown" },
{ value: "folder", label: "Folder" },
{ value: "canvas", label: "Canvas" },
{ value: "pdf", label: "PDF" },
{ value: "image", label: "Image" },
{ value: "audio", label: "Audio" },
{ value: "video", label: "Video" },
{ value: "other", label: "All other file types" },
{ value: "all", label: "All file types" }
];
options.forEach((option) => {
var _a2;
if (!((_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.includes(option.value))) {
dropdown.addOption(option.value, option.label);
}
});
dropdown.addOption("+", "+");
dropdown.setValue("+");
dropdown.onChange(async (value) => {
var _a2;
if (value === "all") {
this.yaml.includeTypes = (_a2 = this.yaml.includeTypes) == null ? void 0 : _a2.filter((type) => type === "folder");
list.setValues(this.yaml.includeTypes);
}
await list.addValue(value.toLowerCase());
this.display();
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
}
let disableFileTag;
(_d = this.yaml.includeTypes) == null ? void 0 : _d.forEach((type) => {
type === "folder" || type === "markdown" ? disableFileTag = true : null;
});
if (disableFileTag) {
new import_obsidian21.Setting(contentEl).setName("Disable file tag").setDesc("Choose if the file tag should be shown after the file name").addToggle((toggle) => {
toggle.setValue(this.yaml.disableFileTag).onChange(async (value) => {
this.yaml.disableFileTag = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
}
new import_obsidian21.Setting(contentEl).setName("Show folder notes").setDesc("Choose if folder notes (the note itself and not the folder name) should be shown in the overview").addToggle((toggle) => toggle.setValue(this.yaml.showFolderNotes).onChange(async (value) => {
this.yaml.showFolderNotes = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
}));
if (this.yaml.style !== "explorer") {
new import_obsidian21.Setting(contentEl).setName("File depth").setDesc("File & folder = +1 depth").addSlider((slider) => {
var _a2;
return slider.setValue(((_a2 = this.yaml) == null ? void 0 : _a2.depth) || 2).setLimits(1, 10, 1).onChange(async (value) => {
this.yaml.depth = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
}
new import_obsidian21.Setting(contentEl).setName("Sort files by").setDesc("Choose how the files should be sorted").addDropdown((dropdown) => {
var _a2;
return dropdown.addOption("name", "Name").addOption("created", "Created").addOption("modified", "Modified").setValue(((_a2 = this.yaml) == null ? void 0 : _a2.sortBy) || "name").onChange(async (value) => {
this.yaml.sortBy = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
}).addDropdown((dropdown) => {
dropdown.addOption("desc", "Descending").addOption("asc", "Ascending");
if (this.yaml.sortByAsc) {
dropdown.setValue("asc");
} else {
dropdown.setValue("desc");
}
dropdown.onChange(async (value) => {
if (value === "desc") {
this.yaml.sortByAsc = false;
} else {
this.yaml.sortByAsc = true;
}
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
if (this.yaml.style === "list") {
new import_obsidian21.Setting(contentEl).setName("Show folder names of folders that appear empty in the folder overview").setDesc("Show the names of folders that appear to have no files/folders in the folder overview. That's mostly the case when you set the file depth to 1.").addToggle((toggle) => {
toggle.setValue(this.yaml.showEmptyFolders).onChange(async (value) => {
this.yaml.showEmptyFolders = value;
this.yaml.onlyIncludeSubfolders = false;
this.display();
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
if (this.yaml.showEmptyFolders) {
new import_obsidian21.Setting(contentEl).setName("Only show first empty subfolders of current folder").addToggle((toggle) => {
toggle.setValue(this.yaml.onlyIncludeSubfolders).onChange(async (value) => {
this.yaml.onlyIncludeSubfolders = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
}
}
if (this.yaml.style === "explorer") {
new import_obsidian21.Setting(contentEl).setName("Disable collapse icon for folder notes").setDesc("Remove the collapse icon next to the folder name for folder notes when they only contain the folder note itself").addToggle((toggle) => {
toggle.setValue(this.yaml.disableCollapseIcon).onChange(async (value) => {
this.yaml.disableCollapseIcon = value;
if (this.defaultSettings) {
return this.plugin.saveSettings();
}
await updateYaml(this.plugin, this.ctx, this.el, this.yaml);
});
});
}
}
onClose() {
const { contentEl } = this;
contentEl.empty();
}
};
// src/settings/FolderOverviewSettings.ts
async function renderFolderOverview(settingsTab) {
const containerEl = settingsTab.settingsPage;
new import_obsidian22.Setting(containerEl).setName("Manage folder overview defaults").setDesc("Manage the default settings for the folder overview plugin").addButton((button) => button.setButtonText("Manage").setCta().onClick(async () => {
new FolderOverviewSettings(settingsTab.plugin.app, settingsTab.plugin, settingsTab.plugin.settings.defaultOverview, null, null, true).open();
}));
}
// src/settings/ExcludedFoldersSettings.ts
var import_obsidian23 = require("obsidian");
async function renderExcludeFolders(settingsTab) {
const containerEl = settingsTab.settingsPage;
const manageExcluded = new import_obsidian23.Setting(containerEl).setHeading().setClass("fn-excluded-folder-heading").setName("Manage excluded folders");
const desc3 = document.createDocumentFragment();
desc3.append("Add {regex} at the beginning of the folder name to use a regex pattern.", desc3.createEl("br"), "Use * before and after to exclude folders that include the name between the *s.", desc3.createEl("br"), "Use * before the folder name to exclude folders that end with the folder name.", desc3.createEl("br"), "Use * after the folder name to exclude folders that start with the folder name.");
manageExcluded.setDesc(desc3);
manageExcluded.infoEl.appendText("The regexes and wildcards are only for the folder name, not the path.");
manageExcluded.infoEl.createEl("br");
manageExcluded.infoEl.appendText("If you want to switch to a folder path delete the pattern first.");
manageExcluded.infoEl.style.color = settingsTab.app.vault.getConfig("accentColor") || "#7d5bed";
new import_obsidian23.Setting(containerEl).setName("Exclude folder default settings").addButton((cb) => {
cb.setButtonText("Manage");
cb.setCta();
cb.onClick(async () => {
new ExcludedFolderSettings(settingsTab.app, settingsTab.plugin, settingsTab.plugin.settings.excludeFolderDefaultSettings).open();
});
});
new import_obsidian23.Setting(containerEl).setName("Exclude pattern default settings").addButton((cb) => {
cb.setButtonText("Manage");
cb.setCta();
cb.onClick(async () => {
new PatternSettings(settingsTab.app, settingsTab.plugin, settingsTab.plugin.settings.excludePatternDefaultSettings).open();
});
});
new import_obsidian23.Setting(containerEl).setName("Add excluded folder").setClass("add-exclude-folder-item").addButton((cb) => {
cb.setIcon("plus");
cb.setClass("add-exclude-folder");
cb.setTooltip("Add excluded folder");
cb.onClick(() => {
const excludedFolder = new ExcludedFolder("", settingsTab.plugin.settings.excludeFolders.length, settingsTab.plugin);
addExcludeFolderListItem(settingsTab, containerEl, excludedFolder);
addExcludedFolder(settingsTab.plugin, excludedFolder);
settingsTab.display();
});
});
settingsTab.plugin.settings.excludeFolders.sort((a, b) => a.position - b.position).forEach((excludedFolder) => {
var _a, _b;
if (((_a = excludedFolder.string) == null ? void 0 : _a.trim()) !== "" && ((_b = excludedFolder.path) == null ? void 0 : _b.trim()) === "") {
addExcludePatternListItem(settingsTab, containerEl, excludedFolder);
} else {
addExcludeFolderListItem(settingsTab, containerEl, excludedFolder);
}
});
}
// src/settings/SettingsTab.ts
var DEFAULT_SETTINGS = {
syncFolderName: true,
ctrlKey: true,
altKey: false,
hideFolderNote: true,
templatePath: "",
autoCreate: false,
enableCollapsing: false,
excludeFolders: [],
whitelistFolders: [],
showDeleteConfirmation: true,
underlineFolder: true,
stopWhitespaceCollapsing: true,
underlineFolderInPath: true,
openFolderNoteOnClickInPath: true,
openInNewTab: false,
folderNoteName: "{{folder_name}}",
folderNoteType: ".md",
disableFolderHighlighting: false,
newFolderNoteName: "{{folder_name}}",
storageLocation: "insideFolder",
syncDelete: false,
showRenameConfirmation: true,
defaultOverview: {
id: "",
folderPath: "",
title: "{{folderName}} overview",
showTitle: false,
depth: 3,
includeTypes: ["folder", "markdown"],
style: "list",
disableFileTag: false,
sortBy: "name",
sortByAsc: true,
showEmptyFolders: false,
onlyIncludeSubfolders: false,
storeFolderCondition: true,
showFolderNotes: false,
disableCollapseIcon: true
},
useSubmenus: true,
syncMove: true,
frontMatterTitle: {
enabled: false,
explorer: true,
path: true
},
settingsTab: "general",
supportedFileTypes: ["md", "canvas"],
boldName: false,
boldNameInPath: false,
cursiveName: false,
cursiveNameInPath: false,
disableOpenFolderNoteOnClick: false,
openByClick: true,
openWithCtrl: false,
openWithAlt: false,
excludeFolderDefaultSettings: {
type: "folder",
path: "",
subFolders: true,
disableSync: true,
disableAutoCreate: true,
disableFolderNote: false,
enableCollapsing: false,
position: 0,
excludeFromFolderOverview: false,
string: "",
hideInSettings: false
},
excludePatternDefaultSettings: {
type: "pattern",
path: "",
subFolders: true,
disableSync: true,
disableAutoCreate: true,
disableFolderNote: false,
enableCollapsing: false,
position: 0,
excludeFromFolderOverview: false,
string: "",
hideInSettings: false
},
hideCollapsingIcon: false,
tabManagerEnabled: true,
ignoreAttachmentFolder: true,
deleteFilesAction: "trash"
};
var SettingsTab = class extends import_obsidian24.PluginSettingTab {
constructor(app2, plugin) {
super(app2, plugin);
this.TABS = {
GENERAL: {
name: "General",
id: "general"
},
FOLDER_OVERVIEW: {
name: "Folder overview",
id: "folder_overview"
},
EXCLUDE_FOLDERS: {
name: "Exclude folders",
id: "exclude_folders"
},
FILE_EXPLORER: {
name: "File explorer",
id: "file_explorer"
},
PATH: {
name: "Path",
id: "path"
}
};
}
renderSettingsPage(tabId) {
this.settingsPage.empty();
switch (tabId.toLocaleLowerCase()) {
case this.TABS.GENERAL.id:
renderGeneral(this);
break;
case this.TABS.FOLDER_OVERVIEW.id:
renderFolderOverview(this);
break;
case this.TABS.EXCLUDE_FOLDERS.id:
renderExcludeFolders(this);
break;
case this.TABS.FILE_EXPLORER.id:
renderFileExplorer(this);
break;
case this.TABS.PATH.id:
renderPath(this);
break;
}
}
display() {
this.plugin.settingsOpened = true;
const { containerEl } = this;
containerEl.empty();
const tabBar = containerEl.createEl("nav", { cls: "fn-settings-tab-bar" });
for (const [tabId, tabInfo] of Object.entries(this.TABS)) {
const tabEl = tabBar.createEl("div", { cls: "fn-settings-tab" });
const tabName = tabEl.createEl("div", { cls: "fn-settings-tab-name", text: tabInfo.name });
if (this.plugin.settings.settingsTab.toLocaleLowerCase() === tabId.toLocaleLowerCase()) {
tabEl.addClass("fn-settings-tab-active");
}
tabEl.addEventListener("click", () => {
for (const tabEl2 of tabBar.children) {
tabEl2.removeClass("fn-settings-tab-active");
this.plugin.settings.settingsTab = tabId.toLocaleLowerCase();
this.plugin.saveSettings();
}
tabEl.addClass("fn-settings-tab-active");
this.renderSettingsPage(tabId);
});
}
this.settingsPage = containerEl.createDiv({ cls: "fn-settings-page" });
this.renderSettingsPage(this.plugin.settings.settingsTab);
}
updateFolderNotes(newTemplate) {
new import_obsidian24.Notice("Starting to update folder notes...");
for (const folder of this.app.vault.getAllLoadedFiles()) {
if (folder instanceof import_obsidian24.TFolder) {
const folderNote = getFolderNote(this.plugin, folder.path);
if (!(folderNote instanceof import_obsidian24.TFile)) {
continue;
}
const folderNoteName = newTemplate.replace("{{folder_name}}", folder.name);
const newPath = `${folder.path}/${folderNoteName}.${folderNote.extension}`;
if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
continue;
}
this.plugin.app.fileManager.renameFile(folderNote, newPath);
}
}
this.plugin.settings.folderNoteName = newTemplate;
this.plugin.saveSettings();
new import_obsidian24.Notice("Finished updating folder notes");
}
switchStorageLocation(oldMethod) {
new import_obsidian24.Notice("Starting to switch storage location...");
this.app.vault.getAllLoadedFiles().forEach((file) => {
if (file instanceof import_obsidian24.TFolder) {
const folderNote = getFolderNote(this.plugin, file.path, oldMethod);
if (folderNote instanceof import_obsidian24.TFile) {
if (this.plugin.settings.storageLocation === "parentFolder") {
let newPath = "";
if (getFolderPathFromString(file.path).trim() === "") {
newPath = `${folderNote.name}`;
} else {
newPath = `${getFolderPathFromString(file.path)}/${folderNote.name}`;
}
this.plugin.app.fileManager.renameFile(folderNote, newPath);
} else if (this.plugin.settings.storageLocation === "insideFolder") {
if (getFolderPathFromString(folderNote.path) === file.path) {
return;
} else {
const newPath = `${file.path}/${folderNote.name}`;
this.plugin.app.fileManager.renameFile(folderNote, newPath);
}
}
}
}
});
new import_obsidian24.Notice("Finished switching storage location");
}
onClose() {
this.plugin.settingsOpened = false;
}
};
// src/Commands.ts
var import_obsidian25 = require("obsidian");
var Commands = class {
constructor(app2, plugin) {
this.plugin = plugin;
this.app = app2;
}
registerCommands() {
this.editorCommands();
this.fileCommands();
this.regularCommands();
}
regularCommands() {
this.plugin.addCommand({
id: "turn-into-folder-note",
name: "Make current active note a folder note for the folder of the active note",
callback: () => {
const file = this.app.workspace.getActiveFile();
if (!(file instanceof import_obsidian25.TFile))
return;
const folder = file.parent;
if (!(folder instanceof import_obsidian25.TFolder))
return;
const folderNote = getFolderNote(this.plugin, folder.path);
turnIntoFolderNote(this.plugin, file, folder, folderNote);
}
});
this.plugin.addCommand({
id: "create-folder-note",
name: "Create folder note with a new folder for the active note in the current folder",
callback: async () => {
var _a, _b, _c;
const file = this.app.workspace.getActiveFile();
if (!(file instanceof import_obsidian25.TFile))
return;
let newPath = ((_a = file.parent) == null ? void 0 : _a.path) + "/" + file.basename;
if (((_b = file.parent) == null ? void 0 : _b.path) === "" || ((_c = file.parent) == null ? void 0 : _c.path) === "/") {
newPath = file.basename;
}
if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
return new import_obsidian25.Notice("Folder already exists");
}
const automaticallyCreateFolderNote = this.plugin.settings.autoCreate;
this.plugin.settings.autoCreate = false;
this.plugin.saveSettings();
await this.plugin.app.vault.createFolder(newPath);
const folder = this.plugin.app.vault.getAbstractFileByPath(newPath);
if (!(folder instanceof import_obsidian25.TFolder))
return;
createFolderNote(this.plugin, folder.path, true, "." + file.extension, false, file);
this.plugin.settings.autoCreate = automaticallyCreateFolderNote;
this.plugin.saveSettings();
}
});
this.plugin.addCommand({
id: "create-folder-note-for-current-folder",
name: "Create markdown folder note for current folder of active note",
callback: () => {
const file = this.app.workspace.getActiveFile();
if (!(file instanceof import_obsidian25.TFile))
return;
const folder = file.parent;
if (!(folder instanceof import_obsidian25.TFolder))
return;
createFolderNote(this.plugin, folder.path, true, ".md", false);
}
});
this.plugin.settings.supportedFileTypes.forEach((fileType) => {
if (fileType === "md")
return;
this.plugin.addCommand({
id: `create-${fileType}-folder-note-for-current-folder`,
name: `Create ${fileType} folder note for current folder of active note`,
callback: () => {
const file = this.app.workspace.getActiveFile();
if (!(file instanceof import_obsidian25.TFile))
return;
const folder = file.parent;
if (!(folder instanceof import_obsidian25.TFolder))
return;
createFolderNote(this.plugin, folder.path, true, "." + fileType, false);
}
});
});
this.plugin.addCommand({
id: "delete-folder-note-for-current-folder",
name: "Delete folder note of current folder of active note",
callback: () => {
const file = this.app.workspace.getActiveFile();
if (!(file instanceof import_obsidian25.TFile))
return;
const folder = file.parent;
if (!(folder instanceof import_obsidian25.TFolder))
return;
const folderNote = getFolderNote(this.plugin, folder.path);
if (!(folderNote instanceof import_obsidian25.TFile))
return;
deleteFolderNote(this.plugin, folderNote, true);
}
});
this.plugin.addCommand({
id: "open-folder-note-for-current-folder",
name: "Open folder note of current folder of active note",
callback: () => {
const file = this.app.workspace.getActiveFile();
if (!(file instanceof import_obsidian25.TFile))
return;
const folder = file.parent;
if (!(folder instanceof import_obsidian25.TFolder))
return;
const folderNote = getFolderNote(this.plugin, folder.path);
if (!(folderNote instanceof import_obsidian25.TFile))
return;
openFolderNote(this.plugin, folderNote);
}
});
this.plugin.addCommand({
id: "insert-folder-overview-fn",
name: "Insert folder overview",
editorCheckCallback: (checking, editor) => {
const line = editor.getCursor().line;
const lineText = editor.getLine(line);
if (lineText.trim() === "" || lineText.trim() === ">") {
if (!checking) {
let json = Object.assign({}, this.plugin.settings.defaultOverview);
json.id = crypto.randomUUID();
const yaml = (0, import_obsidian25.stringifyYaml)(json);
if (lineText.trim() === "") {
editor.replaceSelection(`\`\`\`folder-overview
${yaml}\`\`\`
`);
} else if (lineText.trim() === ">") {
const lines = yaml.split("\n");
const newLines = lines.map((line2) => {
return `> ${line2}`;
});
editor.replaceSelection(`\`\`\`folder-overview
${newLines.join("\n")}\`\`\`
`);
}
}
return true;
}
return false;
}
});
this.plugin.addCommand({
id: "create-folder-note-from-selected-text",
name: "Create folder note from selected text",
editorCheckCallback: (checking, editor, view) => {
const text = editor.getSelection().trim();
const line = editor.getCursor().line;
const file = view.file;
if (!(file instanceof import_obsidian25.TFile))
return false;
if (text && text.trim() !== "") {
if (checking) {
return true;
}
const blacklist = ["*", "\\", '"', "/", "<", ">", "?", "|", ":"];
for (const char of blacklist) {
if (text.includes(char)) {
new import_obsidian25.Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?');
return false;
}
}
if (text.endsWith(".")) {
new import_obsidian25.Notice("File name cannot end with a dot");
return;
}
let folder;
const folderPath = getFolderPathFromString(file.path);
if (folderPath === "") {
folder = this.plugin.app.vault.getAbstractFileByPath(text);
if (folder instanceof import_obsidian25.TFolder) {
new import_obsidian25.Notice("Folder note already exists");
return false;
} else {
this.plugin.app.vault.createFolder(text);
createFolderNote(this.plugin, text, false);
}
} else {
folder = this.plugin.app.vault.getAbstractFileByPath(folderPath + "/" + text);
if (folder instanceof import_obsidian25.TFolder) {
new import_obsidian25.Notice("Folder note already exists");
return false;
}
if (this.plugin.settings.storageLocation === "parentFolder") {
if (this.app.vault.getAbstractFileByPath(folderPath + "/" + text + this.plugin.settings.folderNoteType)) {
new import_obsidian25.Notice("File already exists");
return false;
}
}
this.plugin.app.vault.createFolder(folderPath + "/" + text);
createFolderNote(this.plugin, folderPath + "/" + text, false);
}
const fileName = this.plugin.settings.folderNoteName.replace("{{folder_name}}", text);
if (fileName !== text) {
editor.replaceSelection(`[[${fileName}]]`);
} else {
editor.replaceSelection(`[[${fileName}|${text}]]`);
}
return true;
}
return false;
}
});
}
fileCommands() {
this.plugin.registerEvent(this.app.workspace.on("file-menu", (menu, file) => {
var _a, _b, _c;
let folder = file.parent;
if (file instanceof import_obsidian25.TFile) {
if (this.plugin.settings.storageLocation === "insideFolder") {
folder = file.parent;
} else {
const fileName = extractFolderName(this.plugin.settings.folderNoteName, file.basename);
if (fileName) {
if (((_a = file.parent) == null ? void 0 : _a.path) === "" || ((_b = file.parent) == null ? void 0 : _b.path) === "/") {
folder = this.plugin.app.vault.getAbstractFileByPath(fileName);
} else {
folder = this.plugin.app.vault.getAbstractFileByPath(((_c = file.parent) == null ? void 0 : _c.path) + "/" + fileName);
}
}
}
if (folder instanceof import_obsidian25.TFolder) {
const folderNote = getFolderNote(this.plugin, folder.path);
if ((folderNote == null ? void 0 : folderNote.path) === file.path) {
return;
}
} else if (file.parent instanceof import_obsidian25.TFolder) {
folder = file.parent;
}
}
menu.addItem((item) => {
if (import_obsidian25.Platform.isDesktop && !import_obsidian25.Platform.isTablet && this.plugin.settings.useSubmenus) {
item.setTitle("Folder Note Commands").setIcon("folder-edit");
}
let subMenu;
if (!import_obsidian25.Platform.isDesktopApp || !import_obsidian25.Platform.isDesktop || import_obsidian25.Platform.isTablet || !this.plugin.settings.useSubmenus) {
subMenu = menu;
item.setDisabled(true);
} else {
subMenu = item.setSubmenu();
}
if (file instanceof import_obsidian25.TFile) {
subMenu.addItem((item2) => {
item2.setTitle("Create folder note").setIcon("edit").onClick(async () => {
if (!folder)
return;
let newPath = folder.path + "/" + file.basename;
if (folder.path === "" || folder.path === "/") {
newPath = file.basename;
}
if (this.plugin.app.vault.getAbstractFileByPath(newPath)) {
return new import_obsidian25.Notice("Folder already exists");
}
const automaticallyCreateFolderNote = this.plugin.settings.autoCreate;
this.plugin.settings.autoCreate = false;
this.plugin.saveSettings();
await this.plugin.app.vault.createFolder(newPath);
const newFolder = this.plugin.app.vault.getAbstractFileByPath(newPath);
if (!(newFolder instanceof import_obsidian25.TFolder))
return;
await createFolderNote(this.plugin, newFolder.path, true, "." + file.extension, false, file);
this.plugin.settings.autoCreate = automaticallyCreateFolderNote;
this.plugin.saveSettings();
});
});
if (getFolderPathFromString(file.path) === "")
return;
if (!(folder instanceof import_obsidian25.TFolder))
return;
subMenu.addItem((item2) => {
item2.setTitle(`Turn into folder note for ${folder == null ? void 0 : folder.name}`).setIcon("edit").onClick(() => {
if (!folder || !(folder instanceof import_obsidian25.TFolder))
return;
const folderNote2 = getFolderNote(this.plugin, folder.path);
turnIntoFolderNote(this.plugin, file, folder, folderNote2);
});
});
}
if (!(file instanceof import_obsidian25.TFolder))
return;
if (this.plugin.settings.excludeFolders.find((folder2) => folder2.path === file.path)) {
subMenu.addItem((item2) => {
item2.setTitle("Remove folder from excluded folders").setIcon("trash").onClick(() => {
this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder2) => folder2.path !== file.path);
this.plugin.saveSettings();
new import_obsidian25.Notice("Successfully removed folder from excluded folders");
});
});
return;
}
subMenu.addItem((item2) => {
item2.setTitle("Exclude folder from folder notes").setIcon("x-circle").onClick(() => {
const excludedFolder = new ExcludedFolder(file.path, this.plugin.settings.excludeFolders.length, this.plugin);
this.plugin.settings.excludeFolders.push(excludedFolder);
this.plugin.saveSettings();
new import_obsidian25.Notice("Successfully excluded folder from folder notes");
});
});
if (!(file instanceof import_obsidian25.TFolder))
return;
const folderNote = getFolderNote(this.plugin, file.path);
if (folderNote instanceof import_obsidian25.TFile) {
subMenu.addItem((item2) => {
item2.setTitle("Delete folder note").setIcon("trash").onClick(() => {
deleteFolderNote(this.plugin, folderNote, true);
});
});
subMenu.addItem((item2) => {
item2.setTitle("Open folder note").setIcon("chevron-right-square").onClick(() => {
openFolderNote(this.plugin, folderNote);
});
});
subMenu.addItem((item2) => {
item2.setTitle("Copy Obsidian URL").setIcon("link").onClick(() => {
this.app.copyObsidianUrl(folderNote);
});
});
} else {
subMenu.addItem((item2) => {
item2.setTitle("Create markdown folder note").setIcon("edit").onClick(() => {
createFolderNote(this.plugin, file.path, true, ".md");
});
});
this.plugin.settings.supportedFileTypes.forEach((fileType) => {
if (fileType === "md")
return;
subMenu.addItem((item2) => {
item2.setTitle(`Create ${fileType} folder note`).setIcon("edit").onClick(() => {
createFolderNote(this.plugin, file.path, true, "." + fileType);
});
});
});
}
});
}));
}
editorCommands() {
this.plugin.registerEvent(this.plugin.app.workspace.on("editor-menu", (menu, editor, view) => {
const text = editor.getSelection().trim();
const line = editor.getCursor().line;
const lineText = editor.getLine(line);
if (lineText.trim() === "" || lineText.trim() === ">") {
menu.addItem((item) => {
item.setTitle("Create folder overview").setIcon("edit").onClick(() => {
let json = Object.assign({}, this.plugin.settings.defaultOverview);
json.id = crypto.randomUUID();
const yaml = (0, import_obsidian25.stringifyYaml)(json);
if (lineText.trim() === "") {
editor.replaceSelection(`\`\`\`folder-overview
${yaml}\`\`\`
`);
} else if (lineText.trim() === ">") {
const lines = yaml.split("\n");
const newLines = lines.map((line2) => {
return `> ${line2}`;
});
editor.replaceSelection(`\`\`\`folder-overview
${newLines.join("\n")}\`\`\`
`);
}
});
});
}
if (!text || text.trim() === "")
return;
menu.addItem((item) => {
item.setTitle("Create folder note").setIcon("edit").onClick(() => {
const file = view.file;
if (!(file instanceof import_obsidian25.TFile))
return;
const blacklist = ["*", "\\", '"', "/", "<", ">", "?", "|", ":"];
for (const char of blacklist) {
if (text.includes(char)) {
new import_obsidian25.Notice('File name cannot contain any of the following characters: * " \\ / < > : | ?');
return;
}
}
if (text.endsWith(".")) {
new import_obsidian25.Notice("File name cannot end with a dot");
return;
}
let folder;
const folderPath = getFolderPathFromString(file.path);
const fileName = this.plugin.settings.folderNoteName.replace("{{folder_name}}", text);
if (folderPath === "") {
folder = this.plugin.app.vault.getAbstractFileByPath(text);
if (folder instanceof import_obsidian25.TFolder) {
return new import_obsidian25.Notice("Folder note already exists");
} else {
this.plugin.app.vault.createFolder(text);
createFolderNote(this.plugin, text, false);
}
} else {
folder = this.plugin.app.vault.getAbstractFileByPath(folderPath + "/" + text);
if (folder instanceof import_obsidian25.TFolder) {
return new import_obsidian25.Notice("Folder note already exists");
}
if (this.plugin.settings.storageLocation === "parentFolder") {
if (this.app.vault.getAbstractFileByPath(folderPath + "/" + fileName + this.plugin.settings.folderNoteType)) {
return new import_obsidian25.Notice("File already exists");
}
}
this.plugin.app.vault.createFolder(folderPath + "/" + text);
createFolderNote(this.plugin, folderPath + "/" + text, false);
}
if (fileName !== text) {
editor.replaceSelection(`[[${fileName}]]`);
} else {
editor.replaceSelection(`[[${fileName}|${text}]]`);
}
});
});
}));
}
};
// src/events/handleClick.ts
var import_obsidian26 = require("obsidian");
async function handleViewHeaderClick(event, plugin) {
if (!(event.target instanceof HTMLElement))
return;
if (!plugin.settings.openFolderNoteOnClickInPath)
return;
const folderPath = event.target.getAttribute("data-path");
if (!folderPath) {
return;
}
const excludedFolder = getExcludedFolder(plugin, folderPath);
if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
event.target.onclick = null;
event.target.click();
return;
} else if ((excludedFolder == null ? void 0 : excludedFolder.enableCollapsing) || plugin.settings.enableCollapsing) {
event.target.onclick = null;
event.target.click();
}
const folderNote = getFolderNote(plugin, folderPath);
if (folderNote) {
return openFolderNote(plugin, folderNote, event);
} else if (event.altKey || import_obsidian26.Keymap.isModEvent(event) === "tab") {
if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian26.Keymap.isModEvent(event) === "tab") {
await createFolderNote(plugin, folderPath, true, void 0, true);
addCSSClassToTitleEL(folderPath, "has-folder-note");
removeCSSClassFromEL(folderPath, "has-not-folder-note");
return;
}
}
event.target.onclick = null;
event.target.click();
}
async function handleFolderClick(event, plugin) {
var _a, _b, _c;
if (!(event.target instanceof HTMLElement))
return;
if (!event || !event.target)
return;
event.stopImmediatePropagation();
const folderPath = (_a = event.target.parentElement) == null ? void 0 : _a.getAttribute("data-path");
if (!folderPath) {
return;
}
const excludedFolder = getExcludedFolder(plugin, folderPath);
if (excludedFolder == null ? void 0 : excludedFolder.disableFolderNote) {
event.target.onclick = null;
event.target.click();
return;
} else if ((excludedFolder == null ? void 0 : 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 && import_obsidian26.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;
(_b = event.target.parentElement) == null ? void 0 : _b.click();
return;
}
} else if (event.altKey || import_obsidian26.Keymap.isModEvent(event) === "tab") {
if (plugin.settings.altKey && event.altKey || plugin.settings.ctrlKey && import_obsidian26.Keymap.isModEvent(event) === "tab") {
await createFolderNote(plugin, folderPath, true, void 0, true);
addCSSClassToTitleEL(folderPath, "has-folder-note");
removeCSSClassFromEL(folderPath, "has-not-folder-note");
return;
}
} else if (!folderNote) {
if (plugin.settings.enableCollapsing)
return;
return (_c = event.target.parentElement) == null ? void 0 : _c.click();
}
event.target.onclick = null;
event.target.click();
}
// src/events/MutationObserver.ts
var import_obsidian27 = require("obsidian");
async function addObserver(plugin) {
plugin.observer = new MutationObserver((mutations) => {
mutations.forEach((rec) => {
if (rec.type === "childList") {
rec.target.querySelectorAll("div.nav-folder-title-content").forEach((element) => {
var _a;
if (element.onclick)
return;
if (import_obsidian27.Platform.isMobile && plugin.settings.disableOpenFolderNoteOnClick)
return;
const folderPath = ((_a = element.parentElement) == null ? void 0 : _a.getAttribute("data-path")) || "";
const apply = applyCSSClassesToFolder(folderPath, plugin);
element.addEventListener("auxclick", (event) => {
if (event.button == 1) {
handleFolderClick(event, plugin);
}
}, { capture: true });
element.onclick = (event) => handleFolderClick(event, plugin);
plugin.registerDomEvent(element, "pointerover", (event) => {
var _a2, _b;
plugin.hoveredElement = element;
plugin.mouseEvent = event;
if (!import_obsidian27.Keymap.isModEvent(event))
return;
if (!(event.target instanceof HTMLElement))
return;
const folderPath2 = ((_b = (_a2 = event == null ? void 0 : event.target) == null ? void 0 : _a2.parentElement) == null ? void 0 : _b.getAttribute("data-path")) || "";
const folderNote = getFolderNote(plugin, folderPath2);
if (!folderNote)
return;
plugin.app.workspace.trigger("hover-link", {
event,
source: "preview",
hoverParent: {
file: folderNote
},
targetEl: event.target,
linktext: folderNote == null ? void 0 : folderNote.basename,
sourcePath: folderNote == null ? void 0 : folderNote.path
});
plugin.hoverLinkTriggered = true;
});
plugin.registerDomEvent(element, "pointerout", () => {
plugin.hoveredElement = null;
plugin.mouseEvent = null;
plugin.hoverLinkTriggered = false;
});
});
if (!plugin.settings.openFolderNoteOnClickInPath) {
return;
}
rec.target.querySelectorAll("span.view-header-breadcrumb").forEach((element) => {
var _a, _b;
const breadcrumbs = (_a = element.parentElement) == null ? void 0 : _a.querySelectorAll("span.view-header-breadcrumb");
if (!breadcrumbs)
return;
let path = "";
breadcrumbs.forEach((breadcrumb) => {
var _a2;
if (breadcrumb.hasAttribute("old-name")) {
path += breadcrumb.getAttribute("old-name") + "/";
} else {
path += breadcrumb.innerText.trim() + "/";
}
const folderPath = path.slice(0, -1);
breadcrumb.setAttribute("data-path", folderPath);
const folder = (_a2 = plugin.fmtpHandler) == null ? void 0 : _a2.modifiedFolders.get(folderPath);
if (folder && plugin.settings.frontMatterTitle.path && plugin.settings.frontMatterTitle.enabled) {
breadcrumb.setAttribute("old-name", folder.name || "");
breadcrumb.innerText = folder.newName || "";
}
const folderNote = getFolderNote(plugin, folderPath);
if (folderNote) {
breadcrumb.classList.add("has-folder-note");
}
});
(_b = element.parentElement) == null ? void 0 : _b.setAttribute("data-path", path.slice(0, -1));
if (breadcrumbs.length > 0) {
breadcrumbs.forEach((breadcrumb) => {
if (breadcrumb.onclick)
return;
breadcrumb.onclick = (event) => handleViewHeaderClick(event, plugin);
});
}
});
}
});
});
}
// src/events/handleRename.ts
var import_obsidian28 = require("obsidian");
function handleRename(file, oldPath, plugin) {
if (!plugin.settings.syncFolderName) {
removeCSSClassFromEL(file.path, "has-folder-note");
removeCSSClassFromEL(file.path, "is-folder-note");
return;
}
const folder = file.parent;
const oldFolder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(oldPath));
if (folder instanceof import_obsidian28.TFolder) {
if (plugin.isEmptyFolderNoteFolder(folder)) {
addCSSClassToTitleEL(folder.path, "only-has-folder-note");
} else {
removeCSSClassFromEL(folder.path, "only-has-folder-note");
}
}
if (oldFolder instanceof import_obsidian28.TFolder) {
if (plugin.isEmptyFolderNoteFolder(oldFolder)) {
addCSSClassToTitleEL(oldFolder.path, "only-has-folder-note");
} else {
removeCSSClassFromEL(oldFolder.path, "only-has-folder-note");
}
}
if (file instanceof import_obsidian28.TFolder) {
plugin.tabManager.updateTab(file.path);
return handleFolderRename(file, oldPath, plugin);
} else if (file instanceof import_obsidian28.TFile) {
return handleFileRename(file, oldPath, plugin);
}
}
function handleFolderRename(file, oldPath, plugin) {
const fileName = plugin.settings.folderNoteName.replace("{{folder_name}}", file.name);
const folder = plugin.app.vault.getAbstractFileByPath(file.path);
const folderNote = getFolderNote(plugin, oldPath);
if (!(folderNote instanceof import_obsidian28.TFile))
return;
if (!(folder instanceof import_obsidian28.TFolder))
return;
const excludedFolders = plugin.settings.excludeFolders.filter((excludedFolder2) => excludedFolder2.path.includes(oldPath));
excludedFolders.forEach((excludedFolder2) => {
if (excludedFolder2.path === oldPath) {
excludedFolder2.path = folder.path;
return;
}
const folders = excludedFolder2.path.split("/");
if (folders.length < 1) {
folders.push(excludedFolder2.path);
}
folders[folders.indexOf(folder.name)] = folder.name;
excludedFolder2.path = folders.join("/");
});
plugin.saveSettings();
const excludedFolder = getExcludedFolder(plugin, file.path);
if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && !folderNote) {
return removeCSSClassFromEL(file.path, "has-folder-note");
}
let newPath = "";
if (plugin.settings.storageLocation === "parentFolder") {
const parentFolderPath = getFolderPathFromString(file.path);
const oldParentFolderPath = getFolderPathFromString(oldPath);
if (parentFolderPath !== oldParentFolderPath) {
if (!plugin.settings.syncMove) {
return;
}
newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`;
} else if (parentFolderPath.trim() === "") {
folderNote.path = `${folderNote.name}`;
newPath = `${fileName}.${folderNote.extension}`;
} else {
folderNote.path = `${parentFolderPath}/${folderNote.name}`;
newPath = `${parentFolderPath}/${fileName}.${folderNote.extension}`;
}
} else {
folderNote.path = `${file.path}/${folderNote.name}`;
newPath = `${file.path}/${fileName}.${folderNote.extension}`;
}
plugin.app.fileManager.renameFile(folderNote, newPath);
}
function handleFileRename(file, oldPath, plugin) {
const oldFileName = removeExtension(getFileNameFromPathString(oldPath));
const oldFolder = getFolderNoteFolder(plugin, oldPath, oldFileName);
const folderName = extractFolderName(plugin.settings.folderNoteName, file.basename) || file.basename;
const oldFolderName = extractFolderName(plugin.settings.folderNoteName, oldFileName) || oldFileName;
const newFolder = getFolderNoteFolder(plugin, file, file.basename);
let excludedFolder = getExcludedFolder(plugin, (newFolder == null ? void 0 : newFolder.path) || "");
const folderNote = getFolderNote(plugin, oldPath, plugin.settings.storageLocation, file);
if ((excludedFolder == null ? void 0 : excludedFolder.disableSync) && folderName === (newFolder == null ? void 0 : newFolder.name)) {
addCSSClassToTitleEL(file.path, "is-folder-note");
addCSSClassToTitleEL(newFolder.path, "has-folder-note");
return;
} else if (excludedFolder == null ? void 0 : excludedFolder.disableSync) {
removeCSSClassFromEL(file.path, "is-folder-note");
removeCSSClassFromEL((newFolder == null ? void 0 : newFolder.path) || "", "has-folder-note");
return;
}
if (folderName === (newFolder == null ? void 0 : newFolder.name) && folderNote) {
new import_obsidian28.Notice("Folder with same name already exists!");
let excludedFolderExisted = true;
let disabledSync = false;
if (!excludedFolder) {
excludedFolderExisted = false;
excludedFolder = new ExcludedFolder((oldFolder == null ? void 0 : oldFolder.path) || "", plugin.settings.excludeFolders.length, plugin);
addExcludedFolder(plugin, excludedFolder);
} else if (!excludedFolder.disableSync) {
disabledSync = false;
excludedFolder.disableSync = true;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
}
return plugin.app.fileManager.renameFile(file, oldPath).then(() => {
if (!excludedFolder) {
return;
}
if (!excludedFolderExisted) {
deleteExcludedFolder(plugin, excludedFolder);
} else if (!disabledSync) {
excludedFolder.disableSync = false;
updateExcludedFolder(plugin, excludedFolder, excludedFolder);
}
});
}
if (folderName === (newFolder == null ? void 0 : newFolder.name)) {
addCSSClassToTitleEL(file.path, "is-folder-note");
removeCSSClassFromEL(oldFolder == null ? void 0 : oldFolder.path, "has-folder-note");
addCSSClassToTitleEL(newFolder.path, "has-folder-note");
return;
}
if (!oldFolder)
return;
if (oldFolderName === oldFolder.name && (newFolder == null ? void 0 : newFolder.path) === oldFolder.path) {
return renameFolderOnFileRename(file, oldPath, oldFolder, plugin);
} else if (folderNote && oldFolderName === oldFolder.name) {
return renameFolderOnFileRename(file, oldPath, oldFolder, plugin);
}
if (oldFolder.name === oldFileName && (newFolder == null ? void 0 : newFolder.path) !== oldFolder.path) {
removeCSSClassFromEL(oldFolder.path, "has-folder-note");
removeCSSClassFromEL(file.path, "is-folder-note");
removeCSSClassFromEL(oldPath, "is-folder-note");
}
}
async function renameFolderOnFileRename(file, oldPath, oldFolder, plugin) {
var _a, _b;
const newFolderName = extractFolderName(plugin.settings.folderNoteName, file.basename);
if (!newFolderName) {
removeCSSClassFromEL(oldFolder.path, "has-folder-note");
removeCSSClassFromEL(file.path, "is-folder-note");
return;
} else if (newFolderName === oldFolder.name) {
addCSSClassToTitleEL(oldFolder.path, "has-folder-note");
addCSSClassToTitleEL(file.path, "is-folder-note");
return;
}
let newFolderPath = "";
if (plugin.settings.storageLocation === "insideFolder") {
if (((_a = oldFolder.parent) == null ? void 0 : _a.path) === "/") {
newFolderPath = `${newFolderName}`;
} else {
newFolderPath = ((_b = oldFolder.parent) == null ? void 0 : _b.path) + "/" + newFolderName;
}
} else {
const parentFolderPath = getFolderPathFromString(file.path);
if (parentFolderPath.trim() === "" || parentFolderPath.trim() === "/") {
newFolderPath = `${newFolderName}`;
} else {
newFolderPath = `${parentFolderPath}/${newFolderName}`;
}
}
if (plugin.app.vault.getAbstractFileByPath(newFolderPath)) {
await plugin.app.fileManager.renameFile(file, oldPath);
return new import_obsidian28.Notice("A folder with the same name already exists");
}
plugin.app.fileManager.renameFile(oldFolder, newFolderPath);
}
// src/events/handleCreate.ts
var import_obsidian29 = require("obsidian");
function handleCreate(file, plugin) {
if (!plugin.app.workspace.layoutReady)
return;
const folder = file.parent;
if (folder instanceof import_obsidian29.TFolder) {
if (plugin.isEmptyFolderNoteFolder(folder)) {
addCSSClassToTitleEL(folder.path, "only-has-folder-note");
} else {
removeCSSClassFromEL(folder.path, "only-has-folder-note");
}
}
if (file instanceof import_obsidian29.TFile) {
const folder2 = getFolder2(plugin, file);
if (!(folder2 instanceof import_obsidian29.TFolder)) {
return;
}
const folderNote2 = getFolderNote(plugin, folder2.path);
if (folderNote2 && folderNote2.path === file.path) {
addCSSClassToTitleEL(folder2.path, "has-folder-note");
addCSSClassToTitleEL(file.path, "is-folder-note");
return;
}
}
if (!plugin.app.workspace.layoutReady)
return;
if (!(file instanceof import_obsidian29.TFolder))
return;
if (!plugin.settings.autoCreate)
return;
const excludedFolder = getExcludedFolder(plugin, file.path);
if (excludedFolder == null ? void 0 : excludedFolder.disableAutoCreate)
return;
const folderNote = getFolderNote(plugin, file.path);
if (folderNote)
return;
createFolderNote(plugin, file.path, true, void 0, true);
addCSSClassToTitleEL(file.path, "has-folder-note");
}
// src/events/TabManager.ts
var import_obsidian30 = require("obsidian");
var TabManager = class {
constructor(plugin) {
this.plugin = plugin;
this.app = plugin.app;
}
resetTabs() {
if (!this.isEnabled())
return;
this.app.workspace.iterateAllLeaves((leaf) => {
var _a;
if (!(leaf.view instanceof import_obsidian30.EditableFileView))
return;
const file = (_a = leaf.view) == null ? void 0 : _a.file;
if (!file)
return;
leaf.tabHeaderInnerTitleEl.setText(file.basename);
});
}
updateTabs() {
if (!this.isEnabled())
return;
this.app.workspace.iterateAllLeaves((leaf) => {
var _a;
if (!(leaf.view instanceof import_obsidian30.EditableFileView))
return;
const file = (_a = leaf.view) == null ? void 0 : _a.file;
if (!file)
return;
const folder = getFolder2(this.plugin, file);
if (!folder)
return;
leaf.tabHeaderInnerTitleEl.setText(folder.name);
});
}
updateTab(folderPath) {
if (!this.isEnabled())
return;
const folder = this.app.vault.getAbstractFileByPath(folderPath);
if (!(folder instanceof import_obsidian30.TFolder))
return;
const folderNote = getFolderNote(this.plugin, folder.path);
if (!folderNote)
return;
this.app.workspace.iterateAllLeaves((leaf) => {
var _a;
if (!(leaf.view instanceof import_obsidian30.EditableFileView))
return;
const file = (_a = leaf.view) == null ? void 0 : _a.file;
if (!file)
return;
if (file.path === folderNote.path) {
leaf.tabHeaderInnerTitleEl.setText(folder.name);
}
});
}
isEnabled() {
if (this.plugin.settings.folderNoteName == "{{folder_name}}")
return false;
return this.plugin.settings.tabManagerEnabled;
}
};
// src/functions/ListComponent.ts
var import_obsidian31 = require("obsidian");
var ListComponent = class {
constructor(containerEl) {
this.containerEl = containerEl;
this.controlEl = containerEl.querySelector(".setting-item-control") || containerEl;
this.listEl = this.controlEl.createDiv("setting-command-hotkeys");
}
addModal(modal) {
this.modal = modal;
this.values = modal.yaml.includeTypes || [];
return this;
}
addSettings(settings) {
this.settings = settings;
return this;
}
setValues(values) {
this.listEl.empty();
this.values = values;
if (this.modal) {
this.modal.yaml.includeTypes = values;
}
if (values.length !== 0) {
values.forEach((value) => {
this.addElement(value);
});
}
if (this.modal && this.modal.defaultSettings) {
this.modal.plugin.saveSettings();
return this;
} else if (this.settings) {
this.settings.plugin.settings.supportedFileTypes = values;
this.settings.plugin.saveSettings();
return this;
}
if (!this.modal)
return this;
updateYaml(this.modal.plugin, this.modal.ctx, this.modal.el, this.modal.yaml);
return this;
}
addElement(value) {
this.listEl.createSpan("setting-hotkey", (span) => {
if (value.toLocaleLowerCase() === "md") {
span.innerText = "markdown";
} else {
span.innerText = value;
}
const removeSpan = span.createEl("span", { cls: "ofn-list-item-remove setting-hotkey-icon" });
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-x"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>';
const svgElement = removeSpan.createEl("span", { cls: "ofn-list-item-remove-icon" });
svgElement.innerHTML = svg;
removeSpan.onClickEvent((e) => {
this.removeValue(value);
span.remove();
});
});
}
async addValue(value) {
this.values.push(value);
this.addElement(value);
if (this.settings) {
this.settings.plugin.settings.supportedFileTypes = this.values;
this.settings.plugin.saveSettings();
}
if (!this.modal)
return this;
this.modal.yaml.includeTypes = this.values;
return this;
}
addResetButton() {
const resetButton = this.controlEl.createEl("span", { cls: "clickable-icon setting-restore-hotkey-button" });
const svg = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-rotate-ccw"><path d="M3 2v6h6"></path><path d="M3 13a9 9 0 1 0 3-7.7L3 8"></path></svg>';
resetButton.innerHTML = svg;
resetButton.onClickEvent((e) => {
if (this.modal) {
this.modal.plugin.loadSettings();
this.setValues(this.modal.plugin.settings.defaultOverview.includeTypes || []);
this.modal.display();
} else if (this.settings) {
this.setValues(["md", "canvas"]);
this.settings.display();
}
});
return this;
}
removeValue(value) {
if (value === "all") {
if (this.modal) {
this.modal.plugin.loadSettings();
this.setValues(this.modal.plugin.settings.defaultOverview.includeTypes || []);
this.modal.display();
} else if (this.settings) {
this.setValues(["md", "canvas"]);
this.settings.display();
}
} else {
this.values = this.values.filter((v) => v !== value);
this.setValues(this.values);
if (this.modal) {
this.modal.display();
} else if (this.settings) {
this.settings.display();
}
}
}
};
function createList(cb) {
const list = new ListComponent(this.settingEl);
cb(list);
return list;
}
import_obsidian31.Setting.prototype.createList = createList;
// src/events/handleDelete.ts
var import_obsidian32 = require("obsidian");
function handleDelete(file, plugin) {
const folder = plugin.app.vault.getAbstractFileByPath(getFolderPathFromString(file.path));
if (folder instanceof import_obsidian32.TFolder) {
if (plugin.isEmptyFolderNoteFolder(folder)) {
addCSSClassToTitleEL(folder.path, "only-has-folder-note");
} else {
removeCSSClassFromEL(folder.path, "only-has-folder-note");
}
}
if (file instanceof import_obsidian32.TFile) {
const folder2 = getFolder2(plugin, file);
if (!folder2) {
return;
}
const folderNote2 = getFolderNote(plugin, folder2.path);
if (folderNote2) {
return;
}
removeCSSClassFromEL(folder2.path, "has-folder-note");
removeCSSClassFromEL(folder2.path, "only-has-folder-note");
}
if (!(file instanceof import_obsidian32.TFolder)) {
return;
}
const folderNote = getFolderNote(plugin, file.path);
if (!folderNote) {
return;
}
removeCSSClassFromEL(folderNote.path, "is-folder-note");
if (!plugin.settings.syncDelete) {
return;
}
deleteFolderNote(plugin, folderNote, false);
}
// src/main.ts
var FolderNotesPlugin = class extends import_obsidian33.Plugin {
constructor() {
super(...arguments);
this.fmtpHandler = null;
this.hoveredElement = null;
this.mouseEvent = null;
this.hoverLinkTriggered = false;
this.settingsOpened = false;
}
async onload() {
console.log("loading folder notes plugin");
await this.loadSettings();
this.settingsTab = new SettingsTab(this.app, this);
this.addSettingTab(this.settingsTab);
this.saveSettings();
document.body.classList.add("folder-notes-plugin");
if (this.settings.hideFolderNote) {
document.body.classList.add("hide-folder-note");
}
if (this.settings.underlineFolder) {
document.body.classList.add("folder-note-underline");
}
if (this.settings.boldName) {
document.body.classList.add("folder-note-bold");
}
if (this.settings.cursiveName) {
document.body.classList.add("folder-note-cursive");
}
if (this.settings.boldNameInPath) {
document.body.classList.add("folder-note-bold-path");
}
if (this.settings.cursiveNameInPath) {
document.body.classList.add("folder-note-cursive-path");
}
if (this.settings.underlineFolderInPath) {
document.body.classList.add("folder-note-underline-path");
}
if (this.settings.stopWhitespaceCollapsing) {
document.body.classList.add("fn-whitespace-stop-collapsing");
}
if (this.settings.hideCollapsingIcon) {
document.body.classList.add("fn-hide-collapse-icon");
}
if ((0, import_obsidian33.requireApiVersion)("1.7.2")) {
document.body.classList.add("version-1-7-2");
}
new Commands(this.app, this).registerCommands();
this.app.workspace.onLayoutReady(() => {
if (this.settings.frontMatterTitle.enabled) {
this.fmtpHandler = new FrontMatterTitlePluginHandler(this);
}
this.tabManager = new TabManager(this);
this.tabManager.updateTabs();
});
await addObserver(this);
this.observer.observe(document.body, {
childList: true,
subtree: true
});
this.registerDomEvent(window, "keydown", (event) => {
var _a;
const hoveredElement = this.hoveredElement;
if (this.hoverLinkTriggered)
return;
if (!hoveredElement)
return;
if (!import_obsidian33.Keymap.isModEvent(event))
return;
const folderPath = ((_a = hoveredElement == null ? void 0 : hoveredElement.parentElement) == null ? void 0 : _a.getAttribute("data-path")) || "";
const folderNote = getFolderNote(this, folderPath);
if (!folderNote)
return;
this.app.workspace.trigger("hover-link", {
event: this.mouseEvent,
source: "preview",
hoverParent: {
file: folderNote
},
targetEl: hoveredElement,
linktext: folderNote == null ? void 0 : folderNote.basename,
sourcePath: folderNote == null ? void 0 : folderNote.path
});
this.hoverLinkTriggered = true;
});
this.registerEvent(this.app.vault.on("create", (file) => {
handleCreate(file, this);
}));
this.registerEvent(this.app.workspace.on("file-open", (openFile) => {
if (this.activeFolderDom) {
this.activeFolderDom.removeClass("fn-is-active");
this.activeFolderDom = null;
}
if (!openFile || !openFile.basename) {
return;
}
const folder = getFolder2(this, openFile);
if (!folder) {
return;
}
const folderNote = getFolderNote(this, folder.path);
if (!folderNote) {
return;
}
if (folderNote.path !== openFile.path) {
return;
}
this.activeFolderDom = getEl(folder.path);
if (this.activeFolderDom)
this.activeFolderDom.addClass("fn-is-active");
}));
this.registerEvent(this.app.vault.on("rename", (file, oldPath) => {
handleRename(file, oldPath, this);
}));
this.registerEvent(this.app.vault.on("delete", (file) => {
handleDelete(file, this);
}));
this.registerMarkdownCodeBlockProcessor("folder-overview", (source, el, ctx) => {
this.handleOverviewBlock(source, el, ctx);
});
if (this.app.workspace.layoutReady) {
loadFileClasses(void 0, this);
this.registerEvent(this.app.workspace.on("layout-change", () => {
var _a;
loadFileClasses(void 0, this);
(_a = this.tabManager) == null ? void 0 : _a.updateTabs();
}));
} else {
this.app.workspace.onLayoutReady(async () => {
loadFileClasses(void 0, this);
this.registerEvent(this.app.workspace.on("layout-change", () => {
var _a;
loadFileClasses(void 0, this);
(_a = this.tabManager) == null ? void 0 : _a.updateTabs();
}));
});
}
}
handleOverviewBlock(source, el, ctx) {
const observer = new MutationObserver(() => {
var _a;
const editButton = (_a = el.parentElement) == null ? void 0 : _a.childNodes.item(1);
if (editButton) {
editButton.addEventListener("click", (e) => {
e.stopImmediatePropagation();
e.preventDefault();
e.stopPropagation();
new FolderOverviewSettings(this.app, this, (0, import_obsidian33.parseYaml)(source), ctx, el).open();
}, { capture: true });
}
});
observer.observe(el, {
childList: true,
subtree: true
});
try {
const folderOverview = new FolderOverview(this, ctx, source, el);
folderOverview.create(this, (0, import_obsidian33.parseYaml)(source), el, ctx);
} catch (e) {
new import_obsidian33.Notice("Error creating folder overview (folder notes plugin) - check console for more details");
console.error(e);
}
}
isEmptyFolderNoteFolder(folder) {
var _a;
let attachmentFolderPath = this.app.vault.getConfig("attachmentFolderPath");
const cleanAttachmentFolderPath = (attachmentFolderPath == null ? void 0 : attachmentFolderPath.replace("./", "")) || "";
const attachmentsAreInRootFolder = attachmentFolderPath === "./" || attachmentFolderPath === "";
const threshold = this.settings.storageLocation === "insideFolder" ? 1 : 0;
if (folder.children.length == threshold) {
return true;
} else if (folder.children.length > threshold) {
if (attachmentsAreInRootFolder) {
return false;
} else if (this.settings.ignoreAttachmentFolder && this.app.vault.getAbstractFileByPath(`${folder.path}/${cleanAttachmentFolderPath}`)) {
const folderPath = `${folder.path}/${cleanAttachmentFolderPath}`;
const attachmentFolder = this.app.vault.getAbstractFileByPath(folderPath);
if (attachmentFolder instanceof import_obsidian33.TFolder && folder.children.length <= threshold + 1) {
if (!folder.collapsed) {
(_a = getEl(folder.path)) == null ? void 0 : _a.click();
}
}
return folder.children.length <= threshold + 1;
} else {
return false;
}
}
return true;
}
async changeName(folder, name, replacePath, waitForCreate = false, count = 0) {
if (!name)
name = folder.name;
let fileExplorerItem = getEl(folder.path);
if (!fileExplorerItem) {
if (waitForCreate && count < 5) {
await new Promise((r) => setTimeout(r, 500));
this.changeName(folder, name, replacePath, waitForCreate, count + 1);
return;
}
return;
}
fileExplorerItem = fileExplorerItem.querySelector("div.nav-folder-title-content");
if (!fileExplorerItem) {
return;
}
if (this.settings.frontMatterTitle.explorer && this.settings.frontMatterTitle.enabled) {
fileExplorerItem.innerText = name;
fileExplorerItem.setAttribute("old-name", folder.name);
} else {
fileExplorerItem.innerText = folder.name;
fileExplorerItem.removeAttribute("old-name");
}
if (replacePath) {
this.updateBreadcrumbs();
}
}
updateBreadcrumbs(remove) {
if (!this.settings.frontMatterTitle.path && !remove) {
return;
}
const viewHeaderItems = document.querySelectorAll("span.view-header-breadcrumb");
const files = this.app.vault.getAllLoadedFiles().filter((file) => file instanceof import_obsidian33.TFolder);
viewHeaderItems.forEach((item) => {
if (!item.hasAttribute("data-path")) {
return;
}
const path = item.getAttribute("data-path");
const folder = files.find((file) => file.path === path);
if (!(folder instanceof import_obsidian33.TFolder)) {
return;
}
if (remove) {
item.textContent = folder.name;
item.removeAttribute("old-name");
} else {
item.textContent = folder.newName || folder.name;
item.setAttribute("old-name", folder.name);
item.setAttribute("data-path", folder.path);
}
});
}
reloadHandlers() {
document.querySelectorAll("div.nav-folder-title-content").forEach((element) => {
if (element.onclick)
return;
element.onclick = (event) => handleFolderClick(event, this);
});
}
onunload() {
console.log("unloading folder notes plugin");
this.observer.disconnect();
document.body.classList.remove("folder-notes-plugin");
document.body.classList.remove("folder-note-underline");
document.body.classList.remove("hide-folder-note");
document.body.classList.remove("fn-whitespace-stop-collapsing");
if (this.activeFolderDom) {
this.activeFolderDom.removeClass("is-active");
}
if (this.fmtpHandler) {
this.fmtpHandler.deleteEvent();
}
}
async loadSettings() {
const data = await this.loadData();
if (data) {
if (data.allowWhitespaceCollapsing === true) {
data.stopWhitespaceCollapsing = false;
delete data.allowWhitespaceCollapsing;
} else if (data.allowWhitespaceCollapsing === false) {
data.stopWhitespaceCollapsing = true;
delete data.allowWhitespaceCollapsing;
}
}
this.settings = Object.assign({}, DEFAULT_SETTINGS, data);
if (!data) {
return;
}
const overview = data.defaultOverview;
if (!overview) {
return;
}
this.settings.defaultOverview = Object.assign({}, DEFAULT_SETTINGS.defaultOverview, overview);
}
async saveSettings(reloadStyles) {
await this.saveData(this.settings);
if (!this.settingsOpened || reloadStyles === true) {
loadFileClasses(true, this);
}
}
};