758 lines
No EOL
26 KiB
JavaScript
758 lines
No EOL
26 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 __defProp = Object.defineProperty;
|
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
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 __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
var __async = (__this, __arguments, generator) => {
|
|
return new Promise((resolve, reject) => {
|
|
var fulfilled = (value) => {
|
|
try {
|
|
step(generator.next(value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
};
|
|
var rejected = (value) => {
|
|
try {
|
|
step(generator.throw(value));
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
};
|
|
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
});
|
|
};
|
|
|
|
// src/main.ts
|
|
var main_exports = {};
|
|
__export(main_exports, {
|
|
default: () => HeadingIndent
|
|
});
|
|
module.exports = __toCommonJS(main_exports);
|
|
var import_obsidian2 = require("obsidian");
|
|
|
|
// src/editingMode.ts
|
|
var import_language = require("@codemirror/language");
|
|
var import_state = require("@codemirror/state");
|
|
var import_view = require("@codemirror/view");
|
|
|
|
// src/FrontmatterListener.ts
|
|
var FrontmatterListener = class {
|
|
constructor(app) {
|
|
this.currentIndentState = null;
|
|
this.currentFile = null;
|
|
this.listeners = [];
|
|
this.fileChanged = false;
|
|
this.valueChanged = false;
|
|
this.eventRefs = [];
|
|
this.app = app;
|
|
}
|
|
/**
|
|
* Update current value and detect whether `heading-indent` has changed
|
|
*/
|
|
update() {
|
|
const prevIndentState = this.currentIndentState;
|
|
const prevFile = this.currentFile;
|
|
const currentFile = this.app.workspace.getActiveFile();
|
|
this.currentFile = currentFile;
|
|
if (currentFile) {
|
|
const metadata = this.app.metadataCache.getFileCache(currentFile);
|
|
const frontmatter = metadata == null ? void 0 : metadata.frontmatter;
|
|
this.currentIndentState = (frontmatter == null ? void 0 : frontmatter["heading-indent"]) !== void 0 ? String(frontmatter["heading-indent"]) : "1";
|
|
} else {
|
|
this.currentIndentState = null;
|
|
}
|
|
this.fileChanged = prevFile !== currentFile;
|
|
this.valueChanged = this.currentIndentState !== prevIndentState;
|
|
if (this.valueChanged) {
|
|
this.notifyListeners(this.currentIndentState, prevIndentState, currentFile, prevFile);
|
|
}
|
|
return this.currentIndentState;
|
|
}
|
|
/**
|
|
* Add a listener callback
|
|
*/
|
|
addListener(callback) {
|
|
this.listeners.push(callback);
|
|
}
|
|
/**
|
|
* Remove a listener callback
|
|
*/
|
|
removeListener(callback) {
|
|
const index = this.listeners.indexOf(callback);
|
|
if (index > -1) {
|
|
this.listeners.splice(index, 1);
|
|
}
|
|
}
|
|
/**
|
|
* Notify all registered listeners
|
|
*/
|
|
notifyListeners(newValue, oldValue, newFile, oldFile) {
|
|
this.listeners.forEach((listener) => {
|
|
try {
|
|
listener(newValue, oldValue, newFile, oldFile);
|
|
} catch (error) {
|
|
console.error("Listener execution error:", error);
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Determines if heading indentation should be applied to the current file.
|
|
*
|
|
* Checks frontmatter field 'heading-indent':
|
|
* - false/0: disabled
|
|
* - Any other value or missing: enabled (default)
|
|
*
|
|
* @returns true if indentation should be applied
|
|
*/
|
|
isIndentEnabled() {
|
|
if (this.currentIndentState === null) {
|
|
return false;
|
|
}
|
|
const val = String(this.currentIndentState).toLowerCase();
|
|
return !(val === "false" || val === "0");
|
|
}
|
|
/**
|
|
* Start listening to workspace and metadata changes
|
|
*/
|
|
start() {
|
|
const leafChangeRef = this.app.workspace.on("active-leaf-change", () => {
|
|
this.update();
|
|
});
|
|
this.eventRefs.push(leafChangeRef);
|
|
const metadataChangeRef = this.app.metadataCache.on("changed", (file) => {
|
|
const activeFile = this.app.workspace.getActiveFile();
|
|
if (activeFile && activeFile.path === file.path) {
|
|
this.update();
|
|
}
|
|
});
|
|
this.eventRefs.push(metadataChangeRef);
|
|
this.update();
|
|
}
|
|
/**
|
|
* Stop listening and clean up event handlers
|
|
*/
|
|
stop() {
|
|
this.eventRefs.forEach((ref) => this.app.workspace.offref(ref));
|
|
this.eventRefs = [];
|
|
}
|
|
};
|
|
var _listener = null;
|
|
function initFrontmatterListener(app) {
|
|
if (!_listener) {
|
|
_listener = new FrontmatterListener(app);
|
|
}
|
|
}
|
|
function getFrontmatterListener() {
|
|
if (!_listener) {
|
|
throw new Error("FrontmatterListener not initialized");
|
|
}
|
|
return _listener;
|
|
}
|
|
function cleanupFrontmatterListener() {
|
|
if (_listener) {
|
|
_listener.stop();
|
|
_listener = null;
|
|
}
|
|
}
|
|
|
|
// src/editingMode.ts
|
|
var indentStateField = import_state.StateField.define({
|
|
create(state) {
|
|
return getDecorationSet(state);
|
|
},
|
|
/**
|
|
* lifecicle for an update: DOM event -> transaction -> create new state -> view update
|
|
*/
|
|
update(currentValue, tr) {
|
|
let needUpdate = false;
|
|
for (const e of tr.effects) {
|
|
if (e.is(updateNeededNotificationEffect)) {
|
|
needUpdate = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!needUpdate && syntaxTreeChanged(tr)) {
|
|
needUpdate = true;
|
|
}
|
|
if (needUpdate) {
|
|
const newValue = getDecorationSet(tr.state);
|
|
const isIndentEnabled = getFrontmatterListener().isIndentEnabled();
|
|
const newHasDecorations = newValue.decorations.size > 0;
|
|
if (isIndentEnabled && !newHasDecorations)
|
|
return currentValue;
|
|
else
|
|
return newValue;
|
|
}
|
|
return currentValue;
|
|
},
|
|
provide(field) {
|
|
return import_view.EditorView.decorations.from(field, (value) => value.decorations);
|
|
}
|
|
});
|
|
function syntaxTreeChanged(tr) {
|
|
const oldTree = (0, import_language.syntaxTree)(tr.startState);
|
|
const newTree = (0, import_language.syntaxTree)(tr.state);
|
|
return oldTree !== newTree;
|
|
}
|
|
function getDecorationSet(state) {
|
|
var _a;
|
|
if (!getFrontmatterListener().isIndentEnabled())
|
|
return { decorations: import_view.Decoration.none, intervals: [] };
|
|
const settings = window.app.plugins.plugins["heading-level-indent"].settings;
|
|
const headings = [];
|
|
let highestLevelInDocument = 6;
|
|
(0, import_language.syntaxTree)(state).iterate({
|
|
enter(node) {
|
|
if (node.type.name.startsWith("HyperMD-header_HyperMD-header-")) {
|
|
const lineAt = state.doc.lineAt(node.from);
|
|
const text = state.doc.sliceString(node.from, node.to);
|
|
const level = Number(node.type.name.slice(-1));
|
|
const posAt = node.from;
|
|
headings.push({
|
|
text,
|
|
level,
|
|
headingLineNumber: lineAt.number,
|
|
headingPos: posAt
|
|
});
|
|
highestLevelInDocument = Math.min(highestLevelInDocument, level);
|
|
}
|
|
}
|
|
});
|
|
if (settings.treatHighestPresentHeadingAsH1) {
|
|
for (const heading of headings) {
|
|
heading.level -= highestLevelInDocument - 1;
|
|
}
|
|
}
|
|
const builder = new import_state.RangeSetBuilder();
|
|
const el = document.querySelector(".workspace-leaf.mod-active .cm-content");
|
|
if (el === null) return { decorations: import_view.Decoration.none, intervals: [] };
|
|
const containerWidth = parseInt(getComputedStyle(el).width);
|
|
const intervals = [];
|
|
for (const [index, heading] of headings.entries()) {
|
|
const { level, headingLineNumber, headingPos } = heading;
|
|
const headingLine = state.doc.line(headingLineNumber);
|
|
const firstDataLineNumber = headingLineNumber + 1;
|
|
const lastDataLineNumber = ((_a = headings[index + 1]) == null ? void 0 : _a.headingLineNumber) - 1 || state.doc.lines;
|
|
const pxForDataLine = settings[`h${level}`] || 0;
|
|
const pxForHeadingLine = settings[`h${level - 1}` || 0];
|
|
intervals.push([headingPos, pxForDataLine]);
|
|
const dataStyles = `left:${pxForDataLine}px;width:${containerWidth - pxForDataLine}px;`;
|
|
const headingStyles = `left:${pxForHeadingLine}px;width:${containerWidth - pxForHeadingLine}px;`;
|
|
builder.add(
|
|
headingLine.from,
|
|
headingLine.from,
|
|
import_view.Decoration.line({
|
|
attributes: { style: headingStyles }
|
|
})
|
|
);
|
|
for (let j = firstDataLineNumber; j < lastDataLineNumber + 1; j++) {
|
|
const dataLine = state.doc.line(j);
|
|
builder.add(
|
|
dataLine.from,
|
|
dataLine.from,
|
|
import_view.Decoration.line({
|
|
attributes: { style: dataStyles }
|
|
})
|
|
);
|
|
}
|
|
}
|
|
return { decorations: builder.finish(), intervals };
|
|
}
|
|
var indentEmbedsPlugin = import_view.ViewPlugin.fromClass(
|
|
class {
|
|
constructor(view) {
|
|
this.view = view;
|
|
this.scheduleIndentEmbedsAfterRender();
|
|
}
|
|
update(update) {
|
|
for (const tr of update.transactions) {
|
|
for (const e of tr.effects) {
|
|
if (e.is(updateNeededNotificationEffect)) {
|
|
this.scheduleIndentEmbedsAfterRender();
|
|
}
|
|
}
|
|
}
|
|
if (update.docChanged || update.viewportChanged) {
|
|
this.scheduleIndentEmbedsAfterRender();
|
|
}
|
|
}
|
|
scheduleIndentEmbedsAfterRender() {
|
|
this.view.requestMeasure({
|
|
read: () => {
|
|
},
|
|
write: (measure, view) => {
|
|
const { intervals } = view.state.field(indentStateField);
|
|
const dom = this.view.dom;
|
|
const el = document.querySelector(".workspace-leaf.mod-active .cm-content");
|
|
if (el === null) return;
|
|
const containerWidth = parseInt(getComputedStyle(el).width);
|
|
const embeds = Array.from(
|
|
dom.querySelectorAll("div.cm-content > div.cm-embed-block")
|
|
);
|
|
const mathBlocks = Array.from(
|
|
dom.querySelectorAll("div.cm-content > div.math-block")
|
|
);
|
|
let prevIntervalIndex = 0;
|
|
for (const embed of [...embeds, ...mathBlocks]) {
|
|
const [intervalIndex, offset] = findIntervalOffset(
|
|
intervals,
|
|
view.posAtDOM(embed),
|
|
prevIntervalIndex
|
|
);
|
|
prevIntervalIndex = intervalIndex;
|
|
embed.style.left = `${offset}px`;
|
|
embed.style.width = `${containerWidth - offset}px`;
|
|
}
|
|
const internalEmbeds = Array.from(
|
|
dom.querySelectorAll("div.cm-content > div.internal-embed")
|
|
);
|
|
prevIntervalIndex = 0;
|
|
for (const embed of internalEmbeds) {
|
|
const [intervalIndex, offset] = findIntervalOffset(
|
|
intervals,
|
|
view.posAtDOM(embed),
|
|
prevIntervalIndex
|
|
);
|
|
prevIntervalIndex = intervalIndex;
|
|
embed.style.position = "relative";
|
|
embed.style.left = `${offset}px`;
|
|
embed.style.width = `${containerWidth - offset}px`;
|
|
}
|
|
const imgs = Array.from(
|
|
dom.querySelectorAll("div.cm-content > img")
|
|
);
|
|
prevIntervalIndex = 0;
|
|
for (const img of imgs) {
|
|
const [intervalIndex, offset] = findIntervalOffset(
|
|
intervals,
|
|
view.posAtDOM(img),
|
|
prevIntervalIndex
|
|
);
|
|
prevIntervalIndex = intervalIndex;
|
|
img.style.position = "relative";
|
|
img.style.left = `${offset}px`;
|
|
img.style.maxWidth = `${containerWidth - offset}px`;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
);
|
|
function findIntervalOffset(intervals, pos, start) {
|
|
if (!intervals.length || pos < intervals[0][0]) {
|
|
return [0, 0];
|
|
}
|
|
let low = start;
|
|
let high = intervals.length - 1;
|
|
let result = [0, 0];
|
|
while (low <= high) {
|
|
const mid = low + high >> 1;
|
|
const [midPos, midOffset] = intervals[mid];
|
|
if (midPos < pos) {
|
|
result = [mid, midOffset];
|
|
low = mid + 1;
|
|
} else {
|
|
high = mid - 1;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
var updateNeededNotificationEffect = import_state.StateEffect.define();
|
|
var resizeNotificationPlugin = import_view.ViewPlugin.define((view) => {
|
|
let resizeTimeout;
|
|
const observer = new ResizeObserver((entries) => {
|
|
clearTimeout(resizeTimeout);
|
|
resizeTimeout = window.setTimeout(() => {
|
|
view.dispatch({
|
|
effects: updateNeededNotificationEffect.of()
|
|
});
|
|
}, 100);
|
|
});
|
|
observer.observe(view.dom);
|
|
return {
|
|
destroy() {
|
|
observer.disconnect();
|
|
}
|
|
};
|
|
});
|
|
|
|
// src/renderedMode.ts
|
|
var RenderedModeIndenter = class {
|
|
/**
|
|
* Apply indentation to markdown elements in reading view or PDF export.
|
|
* Works by processing the DOM after Obsidian renders the markdown.
|
|
*/
|
|
static applyIndent(element, settings) {
|
|
try {
|
|
if (!getFrontmatterListener().isIndentEnabled()) return;
|
|
} catch (e) {
|
|
console.warn("FrontmatterListener not initialized, applying indent by default");
|
|
}
|
|
this.currentSettings = settings;
|
|
if (this.processingInProgress) return;
|
|
const rootContainer = element.closest(".markdown-preview-view");
|
|
if (!rootContainer) return;
|
|
this.setupObserver(rootContainer, settings);
|
|
this.processingInProgress = true;
|
|
requestAnimationFrame(() => {
|
|
const processor = new IndentProcessor(settings, rootContainer);
|
|
processor.process();
|
|
this.processingInProgress = false;
|
|
});
|
|
}
|
|
/**
|
|
* Set up MutationObserver to watch for DOM changes when scrolling in virtualized documents.
|
|
* Obsidian only renders viewport content in large documents, adding/removing nodes as you scroll.
|
|
*/
|
|
static setupObserver(rootContainer, settings) {
|
|
const previewSection = rootContainer.querySelector(".markdown-preview-section");
|
|
if (!previewSection) return;
|
|
this.setupObserverForSection(previewSection, rootContainer, settings);
|
|
}
|
|
/**
|
|
* Set up a global observer that watches for new preview sections across all markdown views.
|
|
* This ensures observers are attached when switching files or opening new views.
|
|
*/
|
|
static setupGlobalObserver(app, getSettings) {
|
|
const workspaceContainer = document.querySelector(".workspace");
|
|
if (!workspaceContainer) return;
|
|
const globalObserver = new MutationObserver(() => {
|
|
const previewSections = document.querySelectorAll(".markdown-preview-section");
|
|
previewSections.forEach((section) => {
|
|
if (!this.observers.has(section)) {
|
|
const rootContainer = section.closest(".markdown-preview-view");
|
|
if (rootContainer) {
|
|
this.setupObserverForSection(section, rootContainer, getSettings());
|
|
}
|
|
}
|
|
});
|
|
});
|
|
globalObserver.observe(workspaceContainer, { childList: true, subtree: true });
|
|
this.observers.set(workspaceContainer, globalObserver);
|
|
const existingSections = document.querySelectorAll(".markdown-preview-section");
|
|
existingSections.forEach((section) => {
|
|
const rootContainer = section.closest(".markdown-preview-view");
|
|
if (rootContainer) {
|
|
this.setupObserverForSection(section, rootContainer, getSettings());
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Set up observer for a specific preview section
|
|
*/
|
|
static setupObserverForSection(previewSection, rootContainer, settings) {
|
|
if (this.observers.has(previewSection)) return;
|
|
const observer = new MutationObserver((mutations) => {
|
|
const hasChildListChanges = mutations.some((m) => m.type === "childList");
|
|
if (!hasChildListChanges) return;
|
|
if (!this.processingInProgressForObserver) {
|
|
this.processingInProgressForObserver = true;
|
|
requestAnimationFrame(() => {
|
|
const processor = new IndentProcessor(settings, rootContainer);
|
|
if (getFrontmatterListener().isIndentEnabled()) {
|
|
processor.process();
|
|
} else {
|
|
processor.clear();
|
|
}
|
|
this.processingInProgressForObserver = false;
|
|
});
|
|
}
|
|
});
|
|
observer.observe(previewSection, { childList: true });
|
|
this.observers.set(previewSection, observer);
|
|
}
|
|
/**
|
|
* Remove indentation from all preview views of the current file
|
|
*/
|
|
static clearCurrentView() {
|
|
const allPreviewViews = activeDocument.querySelectorAll(".markdown-preview-view");
|
|
allPreviewViews.forEach((previewView) => {
|
|
const processor = new IndentProcessor(null, previewView);
|
|
processor.clear();
|
|
});
|
|
}
|
|
/**
|
|
* Apply indentation to all preview views of the current file
|
|
*/
|
|
static applyToCurrentView(settings) {
|
|
const allPreviewViews = activeDocument.querySelectorAll(".markdown-preview-view");
|
|
allPreviewViews.forEach((previewView) => {
|
|
const processor = new IndentProcessor(settings, previewView);
|
|
processor.process();
|
|
});
|
|
}
|
|
/**
|
|
* Disconnect all MutationObservers and clear all indentation (call when plugin unloads)
|
|
*/
|
|
static cleanup() {
|
|
this.observers.forEach((observer) => observer.disconnect());
|
|
this.observers.clear();
|
|
this.currentSettings = null;
|
|
const allPreviewViews = document.querySelectorAll(".markdown-preview-view");
|
|
allPreviewViews.forEach((previewView) => {
|
|
const processor = new IndentProcessor(null, previewView);
|
|
processor.clear();
|
|
});
|
|
}
|
|
};
|
|
RenderedModeIndenter.processingInProgress = false;
|
|
RenderedModeIndenter.processingInProgressForObserver = false;
|
|
RenderedModeIndenter.observers = /* @__PURE__ */ new Map();
|
|
RenderedModeIndenter.currentSettings = null;
|
|
var IndentProcessor = class {
|
|
constructor(settings, rootElement) {
|
|
this.settings = settings;
|
|
this.rootElement = rootElement;
|
|
this.currentHeadingLevel = 0;
|
|
this.lastHeadingElement = null;
|
|
}
|
|
process() {
|
|
const selectors = this.getContentSelectors();
|
|
const elements = this.rootElement.querySelectorAll(
|
|
selectors.map((tag) => `div > ${tag}`).join(", ")
|
|
);
|
|
for (const element of Array.from(elements)) {
|
|
if (this.shouldSkipElement(element)) {
|
|
continue;
|
|
}
|
|
const tagName = element.tagName.toLowerCase();
|
|
if (this.isHeading(tagName)) {
|
|
this.processHeading(element, tagName);
|
|
} else if (this.currentHeadingLevel > 0) {
|
|
this.processContent(element);
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Remove all indentation styles and classes
|
|
*/
|
|
clear() {
|
|
const elDivs = this.rootElement.querySelectorAll('div[class*="el-"]');
|
|
for (const div of Array.from(elDivs)) {
|
|
const htmlDiv = div;
|
|
htmlDiv.style.paddingLeft = "";
|
|
const classesToRemove = [];
|
|
htmlDiv.classList.forEach((className) => {
|
|
if (className.startsWith("heading_") || className.startsWith("data_")) {
|
|
classesToRemove.push(className);
|
|
}
|
|
});
|
|
classesToRemove.forEach((className) => htmlDiv.classList.remove(className));
|
|
}
|
|
}
|
|
getContentSelectors() {
|
|
return [
|
|
"h1",
|
|
"h2",
|
|
"h3",
|
|
"h4",
|
|
"h5",
|
|
"h6",
|
|
"p",
|
|
"ul",
|
|
"ol",
|
|
"blockquote",
|
|
"table",
|
|
"pre",
|
|
"div.callout"
|
|
];
|
|
}
|
|
shouldSkipElement(element) {
|
|
const isPdfExport = this.rootElement.closest(".print") !== null;
|
|
if (isPdfExport && element.classList.contains("__title__")) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
isHeading(tagName) {
|
|
return /^h[1-6]$/.test(tagName);
|
|
}
|
|
processHeading(element, tagName) {
|
|
const level = parseInt(tagName.charAt(1));
|
|
this.currentHeadingLevel = level;
|
|
this.lastHeadingElement = element;
|
|
const parentDiv = element.parentElement;
|
|
if ((parentDiv == null ? void 0 : parentDiv.tagName) === "DIV") {
|
|
const indent = this.getIndentForLevel(level - 1);
|
|
parentDiv.style.paddingLeft = `${indent}px`;
|
|
parentDiv.classList.add(`heading_h${level}`);
|
|
}
|
|
}
|
|
processContent(element) {
|
|
var _a;
|
|
const parentDiv = element.parentElement;
|
|
if ((parentDiv == null ? void 0 : parentDiv.tagName) === "DIV" && parentDiv !== ((_a = this.lastHeadingElement) == null ? void 0 : _a.parentElement)) {
|
|
const indent = this.getIndentForLevel(this.currentHeadingLevel);
|
|
parentDiv.style.paddingLeft = `${indent}px`;
|
|
parentDiv.classList.add(`data_h${this.currentHeadingLevel}`);
|
|
}
|
|
}
|
|
getIndentForLevel(level) {
|
|
if (level === 0) return 0;
|
|
const key = `h${level}`;
|
|
return parseInt(String(this.settings[key])) || 0;
|
|
}
|
|
};
|
|
|
|
// src/settings.ts
|
|
var import_obsidian = require("obsidian");
|
|
var DEFAULT_SETTINGS = {
|
|
h1: "30",
|
|
h2: "50",
|
|
h3: "70",
|
|
h4: "90",
|
|
h5: "110",
|
|
h6: "130",
|
|
treatHighestPresentHeadingAsH1: false
|
|
};
|
|
var IndentSettingTab = class extends import_obsidian.PluginSettingTab {
|
|
constructor(app, plugin) {
|
|
super(app, plugin);
|
|
this.plugin = plugin;
|
|
}
|
|
display() {
|
|
const { containerEl } = this;
|
|
containerEl.empty();
|
|
containerEl.createEl("h3", {
|
|
text: "Set indentation for the content of each heading in pixels"
|
|
});
|
|
containerEl.createEl("div", {
|
|
text: `Indentation applied for the heading lines itself will be the same as the
|
|
content of inmediately previous heading. For example, if the indentation
|
|
for the content of H3 is set to 70 pixels, H2 heading line itself
|
|
will be indented the same`,
|
|
attr: { style: "margin-bottom: 10px; color: gray;" }
|
|
});
|
|
new import_obsidian.Setting(containerEl).setName("Content under H1").addText(
|
|
(number) => number.setPlaceholder("").setValue(this.plugin.settings.h1).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.h1 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
new import_obsidian.Setting(containerEl).setName("Content under H2").addText(
|
|
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h2).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.h2 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
new import_obsidian.Setting(containerEl).setName("Content under H3").addText(
|
|
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h3).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.h3 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
new import_obsidian.Setting(containerEl).setName("Content under H4").addText(
|
|
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h4).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.h4 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
new import_obsidian.Setting(containerEl).setName("Content under H5").addText(
|
|
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h5).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.h5 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
new import_obsidian.Setting(containerEl).setName("Content under H6").addText(
|
|
(text) => text.setPlaceholder("").setValue(this.plugin.settings.h6).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.h6 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
new import_obsidian.Setting(containerEl).setName("Treat the highest present heading in the document as H1 (editing mode only)").addToggle(
|
|
(toggle) => toggle.setValue(this.plugin.settings.treatHighestPresentHeadingAsH1).onChange((value) => __async(this, null, function* () {
|
|
this.plugin.settings.treatHighestPresentHeadingAsH1 = value;
|
|
yield this.plugin.saveSettings();
|
|
}))
|
|
);
|
|
}
|
|
};
|
|
|
|
// src/main.ts
|
|
var HeadingIndent = class extends import_obsidian2.Plugin {
|
|
// Configure resources needed by the plugin.
|
|
onload() {
|
|
return __async(this, null, function* () {
|
|
yield this.loadSettings();
|
|
this.addSettingTab(new IndentSettingTab(this.app, this));
|
|
initFrontmatterListener(this.app);
|
|
getFrontmatterListener().start();
|
|
this.registerEditorExtension(indentStateField);
|
|
this.registerEditorExtension(indentEmbedsPlugin);
|
|
this.registerEditorExtension(resizeNotificationPlugin);
|
|
this.registerMarkdownPostProcessor((element, _context) => {
|
|
RenderedModeIndenter.applyIndent(element, this.settings);
|
|
}, 10);
|
|
this.frontmatterChangeHandler = (_newValue, _oldValue, _newFile, _oldFile) => {
|
|
if (getFrontmatterListener().isIndentEnabled()) {
|
|
RenderedModeIndenter.applyToCurrentView(this.settings);
|
|
} else {
|
|
RenderedModeIndenter.clearCurrentView();
|
|
}
|
|
this.app.workspace.iterateAllLeaves((leaf) => {
|
|
var _a;
|
|
const view = (_a = leaf.view.editor) == null ? void 0 : _a.cm;
|
|
if (view) {
|
|
view.dispatch({
|
|
effects: updateNeededNotificationEffect.of()
|
|
});
|
|
}
|
|
});
|
|
};
|
|
getFrontmatterListener().addListener(this.frontmatterChangeHandler);
|
|
this.app.workspace.onLayoutReady(() => {
|
|
RenderedModeIndenter.setupGlobalObserver(this.app, () => this.settings);
|
|
});
|
|
});
|
|
}
|
|
/**
|
|
* Release any resources configured by the plugin; Automatically clean up registered event listeners
|
|
*/
|
|
onunload() {
|
|
if (this.frontmatterChangeHandler) {
|
|
getFrontmatterListener().removeListener(this.frontmatterChangeHandler);
|
|
}
|
|
cleanupFrontmatterListener();
|
|
RenderedModeIndenter.cleanup();
|
|
}
|
|
loadSettings() {
|
|
return __async(this, null, function* () {
|
|
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
|
|
});
|
|
}
|
|
saveSettings() {
|
|
return __async(this, null, function* () {
|
|
yield this.saveData(this.settings);
|
|
this.app.workspace.iterateAllLeaves((leaf) => {
|
|
var _a;
|
|
const view = (_a = leaf.view.editor) == null ? void 0 : _a.cm;
|
|
if (view) {
|
|
view.dispatch({
|
|
effects: updateNeededNotificationEffect.of()
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
};
|
|
|
|
/* nosourcemap */ |