mirror of
https://github.com/dragonish/obsidian-heading-decorator.git
synced 2026-07-22 05:42:05 +00:00
parent
eaa8b0dce6
commit
d00a090099
8 changed files with 477 additions and 9 deletions
|
|
@ -61,6 +61,7 @@ export type HeadingPluginSettings = {
|
|||
enabledInReading: boolean;
|
||||
enabledInPreview: boolean;
|
||||
enabledInSource: boolean;
|
||||
enabledInOutline: boolean;
|
||||
} & Record<PluginDecoratorSettingsType, HeadingDecoratorSettings>;
|
||||
|
||||
export type HeadingPluginData = Omit<
|
||||
|
|
@ -74,6 +75,8 @@ export const previewHeadingDecoratorClassName =
|
|||
"preview-custom-heading-decorator";
|
||||
export const sourceHeadingDecoratorClassName =
|
||||
"source-custom-heading-decorator";
|
||||
export const outlineHeadingDecoratorClassName =
|
||||
"outline-custom-heading-decorator";
|
||||
export const beforeDecoratorClassName = "before-heading-decorator";
|
||||
export const afterDecoratorClassName = "after-heading-decorator";
|
||||
export const headingsSelector =
|
||||
|
|
@ -181,3 +184,37 @@ export function getUnorderedLevelHeadings(value: string): HeadingTuple {
|
|||
export function getOrderedCustomIdents(value: string) {
|
||||
return value.split(/\s+/g).filter((v) => v);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diff level between two numbers.
|
||||
*
|
||||
* @param current current level.
|
||||
* @param last last level.
|
||||
* @returns boolean. if current level is less than or equal to last level, return true. otherwise, return false.
|
||||
*/
|
||||
export function diffLevel(current: number, last: number): boolean {
|
||||
const diff = current - last;
|
||||
if (diff > 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare heading text.
|
||||
*
|
||||
* @param l left heading text.
|
||||
* @param r right heading text.
|
||||
* @returns boolean. if left heading text is equal to right heading text, return true. otherwise, return false.
|
||||
*/
|
||||
export function compareHeadingText(l: string, r: string): boolean {
|
||||
if (l === r) {
|
||||
return true;
|
||||
} else if (
|
||||
l.replaceAll(/[`=_~*\s]/g, "") === r.replaceAll(/[`=_~*\s]/g, "")
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import {
|
|||
readingHeadingDecoratorClassName,
|
||||
beforeDecoratorClassName,
|
||||
afterDecoratorClassName,
|
||||
outlineHeadingDecoratorClassName,
|
||||
} from "./data";
|
||||
|
||||
/**
|
||||
|
|
@ -69,3 +70,60 @@ export function decorateHTMLElement(
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the tree item level of a given element.
|
||||
*
|
||||
* @param element The element to get the tree item level for.
|
||||
* @returns The tree item level.
|
||||
*/
|
||||
export function getTreeItemLevel(element: Element): number {
|
||||
let level = 0;
|
||||
let current = element.closest(".tree-item");
|
||||
while (current) {
|
||||
level++;
|
||||
current = current.parentElement?.closest(".tree-item") || null;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text of a given tree item.
|
||||
* @param element The HTML element to get the text for.
|
||||
* @returns The text of the tree item.
|
||||
*/
|
||||
export function getTreeItemText(element: HTMLElement): string {
|
||||
const inner = element.querySelector<HTMLElement>(
|
||||
".tree-item-self .tree-item-inner"
|
||||
);
|
||||
return inner ? inner.innerText : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate an outline HTML element with a given content, opacity and position.
|
||||
*
|
||||
* @param element The HTML element to decorate.
|
||||
* @param content The content to decorate with.
|
||||
* @param opacity The opacity of the decorator.
|
||||
* @param position The position of the decorator.
|
||||
*/
|
||||
export function decorateOutlineElement(
|
||||
element: HTMLElement,
|
||||
content: string,
|
||||
opacity: OpacityOptions,
|
||||
position: PostionOptions
|
||||
): void {
|
||||
if (content) {
|
||||
const inner = element.querySelector<HTMLElement>(
|
||||
".tree-item-self .tree-item-inner"
|
||||
);
|
||||
if (inner) {
|
||||
inner.dataset.headingDecorator = content;
|
||||
inner.dataset.decoratorOpacity = `${opacity}%`;
|
||||
inner.classList.add(
|
||||
outlineHeadingDecoratorClassName,
|
||||
getPositionClassName(position)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
40
components/outline.ts
Normal file
40
components/outline.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { Component } from "obsidian";
|
||||
|
||||
export class OutlineChildComponent extends Component {
|
||||
private containerEl: HTMLElement | null;
|
||||
private callback: () => void;
|
||||
private observer: MutationObserver | null = null;
|
||||
private config: MutationObserverInit = {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
};
|
||||
|
||||
constructor(containerEl: HTMLElement, callback: () => void) {
|
||||
super();
|
||||
this.containerEl = containerEl;
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
onload(): void {
|
||||
this.callback();
|
||||
|
||||
this.observer = new MutationObserver(() => {
|
||||
this.observer?.disconnect();
|
||||
this.callback();
|
||||
if (this.containerEl) {
|
||||
this.observer?.observe(this.containerEl, this.config);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.containerEl) {
|
||||
this.observer.observe(this.containerEl, this.config);
|
||||
}
|
||||
}
|
||||
|
||||
onunload(): void {
|
||||
this.observer?.takeRecords();
|
||||
this.observer?.disconnect();
|
||||
this.observer = null;
|
||||
this.containerEl = null;
|
||||
}
|
||||
}
|
||||
255
main.ts
255
main.ts
|
|
@ -6,6 +6,7 @@ import {
|
|||
PluginSettingTab,
|
||||
Setting,
|
||||
Editor,
|
||||
WorkspaceLeaf,
|
||||
debounce,
|
||||
} from "obsidian";
|
||||
import { EditorView, ViewPlugin } from "@codemirror/view";
|
||||
|
|
@ -20,21 +21,34 @@ import {
|
|||
defaultHeadingDecoratorSettings,
|
||||
getUnorderedLevelHeadings,
|
||||
getOrderedCustomIdents,
|
||||
diffLevel,
|
||||
compareHeadingText,
|
||||
} from "./common/data";
|
||||
import { Counter, Querier } from "./common/counter";
|
||||
import { Heading } from "./common/heading";
|
||||
import { decorateHTMLElement, queryHeadingLevelByElement } from "./common/dom";
|
||||
import {
|
||||
decorateHTMLElement,
|
||||
decorateOutlineElement,
|
||||
queryHeadingLevelByElement,
|
||||
getTreeItemLevel,
|
||||
getTreeItemText,
|
||||
} from "./common/dom";
|
||||
import {
|
||||
HeadingViewPlugin,
|
||||
headingDecorationsField,
|
||||
editorModeField,
|
||||
updateEditorMode,
|
||||
} from "./components/view";
|
||||
import { OutlineChildComponent } from "./components/outline";
|
||||
|
||||
interface ObsidianEditor extends Editor {
|
||||
cm: EditorView;
|
||||
}
|
||||
|
||||
interface ObsidianWorkspaceLeaf extends WorkspaceLeaf {
|
||||
id: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: HeadingPluginSettings = {
|
||||
enabledInReading: true,
|
||||
readingSettings: defaultHeadingDecoratorSettings(),
|
||||
|
|
@ -42,11 +56,16 @@ const DEFAULT_SETTINGS: HeadingPluginSettings = {
|
|||
previewSettings: defaultHeadingDecoratorSettings(),
|
||||
enabledInSource: false,
|
||||
sourceSettings: defaultHeadingDecoratorSettings(),
|
||||
enabledInOutline: false,
|
||||
outlineSettings: defaultHeadingDecoratorSettings(),
|
||||
};
|
||||
|
||||
export default class HeadingPlugin extends Plugin {
|
||||
settings: HeadingPluginSettings;
|
||||
|
||||
private outlineIdList: string[] = [];
|
||||
private outlineComponents: OutlineChildComponent[] = [];
|
||||
|
||||
async onload() {
|
||||
await this.loadSettings();
|
||||
|
||||
|
|
@ -218,28 +237,57 @@ export default class HeadingPlugin extends Plugin {
|
|||
|
||||
// Listen for editor mode changes
|
||||
this.registerEvent(
|
||||
this.app.workspace.on(
|
||||
"active-leaf-change",
|
||||
this.handleModeChange.bind(this)
|
||||
)
|
||||
this.app.workspace.on("active-leaf-change", () => {
|
||||
this.handleModeChange();
|
||||
this.loadOutlineComponents();
|
||||
})
|
||||
);
|
||||
this.registerEvent(
|
||||
this.app.workspace.on("layout-change", this.handleModeChange.bind(this))
|
||||
this.app.workspace.on("layout-change", () => {
|
||||
this.handleModeChange();
|
||||
this.loadOutlineComponents();
|
||||
})
|
||||
);
|
||||
|
||||
this.loadOutlineComponents();
|
||||
|
||||
this.addSettingTab(new HeadingSettingTab(this.app, this));
|
||||
}
|
||||
|
||||
onunload(): void {
|
||||
this.unloadOutlineComponents();
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
async saveSettings(outlineState?: boolean) {
|
||||
await this.saveData(this.settings);
|
||||
|
||||
if (outlineState != undefined) {
|
||||
if (outlineState) {
|
||||
this.loadOutlineComponents();
|
||||
} else {
|
||||
this.unloadOutlineComponents();
|
||||
}
|
||||
}
|
||||
|
||||
this.debouncedSaveSettings();
|
||||
}
|
||||
|
||||
private loadOutlineComponents() {
|
||||
if (this.settings.enabledInOutline) {
|
||||
this.handleOutline();
|
||||
}
|
||||
}
|
||||
|
||||
private unloadOutlineComponents() {
|
||||
this.outlineComponents.forEach((child) => child.onunload());
|
||||
this.outlineComponents = [];
|
||||
this.outlineIdList = [];
|
||||
}
|
||||
|
||||
private craeteHeadingViewPlugin(
|
||||
getPluginData: () => Promise<HeadingPluginData>
|
||||
) {
|
||||
|
|
@ -269,6 +317,176 @@ export default class HeadingPlugin extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
private handleOutline() {
|
||||
const leaves = this.app.workspace.getLeavesOfType("outline");
|
||||
leaves.forEach((leaf: ObsidianWorkspaceLeaf) => {
|
||||
if (!leaf.id || this.outlineIdList.includes(leaf.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const view = leaf.view;
|
||||
const viewContent = view.containerEl.querySelector<HTMLElement>(
|
||||
'[data-type="outline"] .view-content'
|
||||
);
|
||||
if (!viewContent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.outlineIdList.push(leaf.id);
|
||||
const oc = new OutlineChildComponent(viewContent, () => {
|
||||
const headingElements =
|
||||
viewContent.querySelectorAll<HTMLElement>(".tree-item");
|
||||
if (headingElements.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const {
|
||||
opacity,
|
||||
position,
|
||||
ordered,
|
||||
orderedDelimiter,
|
||||
orderedTrailingDelimiter,
|
||||
orderedStyleType,
|
||||
orderedSpecifiedString,
|
||||
orderedCustomIdents,
|
||||
orderedIgnoreSingle,
|
||||
orderedBasedOnExisting,
|
||||
orderedAllowZeroLevel,
|
||||
unorderedLevelHeadings,
|
||||
} = this.settings.outlineSettings;
|
||||
|
||||
let fromFile = false;
|
||||
const state = view.getState();
|
||||
if (typeof state.file === "string") {
|
||||
const file = this.app.vault.getFileByPath(state.file);
|
||||
if (file) {
|
||||
const cacheHeadings =
|
||||
this.app.metadataCache.getFileCache(file)?.headings || [];
|
||||
|
||||
let ignoreTopLevel = 0;
|
||||
if (ordered && (orderedIgnoreSingle || orderedBasedOnExisting)) {
|
||||
const queier = new Querier(orderedAllowZeroLevel);
|
||||
for (const cacheHeading of cacheHeadings) {
|
||||
queier.handler(cacheHeading.level);
|
||||
ignoreTopLevel = queier.query(orderedIgnoreSingle);
|
||||
if (ignoreTopLevel === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const counter = new Counter({
|
||||
ordered,
|
||||
delimiter: orderedDelimiter,
|
||||
trailingDelimiter: orderedTrailingDelimiter,
|
||||
styleType: orderedStyleType,
|
||||
customIdents: getOrderedCustomIdents(orderedCustomIdents),
|
||||
specifiedString: orderedSpecifiedString,
|
||||
ignoreTopLevel,
|
||||
allowZeroLevel: orderedAllowZeroLevel,
|
||||
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
|
||||
});
|
||||
|
||||
let lastCacheLevel = 0;
|
||||
let lastReadLevel = 0;
|
||||
for (
|
||||
let i = 0, j = 0;
|
||||
i < headingElements.length && j < cacheHeadings.length;
|
||||
i++, j++
|
||||
) {
|
||||
const readLevel = getTreeItemLevel(headingElements[i]);
|
||||
const readText = getTreeItemText(headingElements[i]);
|
||||
let cacheLevel = cacheHeadings[j].level;
|
||||
if (i > 0) {
|
||||
const diff = diffLevel(readLevel, lastReadLevel);
|
||||
while (
|
||||
j < cacheHeadings.length - 1 &&
|
||||
(diffLevel(cacheLevel, lastCacheLevel) !== diff ||
|
||||
!compareHeadingText(cacheHeadings[j].heading, readText))
|
||||
) {
|
||||
counter.handler(cacheLevel);
|
||||
j++;
|
||||
cacheLevel = cacheHeadings[j].level;
|
||||
}
|
||||
}
|
||||
|
||||
const decoratorContent = counter.decorator(cacheLevel);
|
||||
decorateOutlineElement(
|
||||
headingElements[i],
|
||||
decoratorContent,
|
||||
opacity,
|
||||
position
|
||||
);
|
||||
|
||||
lastCacheLevel = cacheLevel;
|
||||
lastReadLevel = readLevel;
|
||||
}
|
||||
|
||||
fromFile = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fromFile) {
|
||||
if (ordered) {
|
||||
let ignoreTopLevel = 0;
|
||||
if (orderedIgnoreSingle || orderedBasedOnExisting) {
|
||||
const queier = new Querier();
|
||||
for (let i = 0; i < headingElements.length; i++) {
|
||||
const element = headingElements[i];
|
||||
const level = getTreeItemLevel(element);
|
||||
queier.handler(level);
|
||||
ignoreTopLevel = queier.query(orderedIgnoreSingle);
|
||||
if (ignoreTopLevel === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const counter = new Counter({
|
||||
ordered: true,
|
||||
delimiter: orderedDelimiter,
|
||||
trailingDelimiter: orderedTrailingDelimiter,
|
||||
styleType: orderedStyleType,
|
||||
customIdents: getOrderedCustomIdents(orderedCustomIdents),
|
||||
specifiedString: orderedSpecifiedString,
|
||||
ignoreTopLevel,
|
||||
allowZeroLevel: orderedAllowZeroLevel,
|
||||
});
|
||||
|
||||
headingElements.forEach((headingElement) => {
|
||||
const level = getTreeItemLevel(headingElement);
|
||||
const decoratorContent = counter.decorator(level);
|
||||
decorateOutlineElement(
|
||||
headingElement,
|
||||
decoratorContent,
|
||||
opacity,
|
||||
position
|
||||
);
|
||||
});
|
||||
} else {
|
||||
const counter = new Counter({
|
||||
ordered: false,
|
||||
levelHeadings: getUnorderedLevelHeadings(unorderedLevelHeadings),
|
||||
});
|
||||
|
||||
headingElements.forEach((headingElement) => {
|
||||
const level = getTreeItemLevel(headingElement);
|
||||
const decoratorContent = counter.decorator(level);
|
||||
decorateOutlineElement(
|
||||
headingElement,
|
||||
decoratorContent,
|
||||
opacity,
|
||||
position
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
this.outlineComponents.push(oc);
|
||||
view.addChild(oc);
|
||||
});
|
||||
}
|
||||
|
||||
private debouncedSaveSettings = debounce(
|
||||
this.rerenderPreviewMarkdown.bind(this),
|
||||
1000,
|
||||
|
|
@ -378,6 +596,29 @@ class HeadingSettingTab extends PluginSettingTab {
|
|||
this.manageHeadingDecoratorSettings("sourceSettings");
|
||||
});
|
||||
});
|
||||
|
||||
//* enabledInOutline
|
||||
new Setting(containerEl)
|
||||
.setName("Enabled in outline plugin")
|
||||
.setDesc("Decorate the heading under the outline plugin.")
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.enabledInOutline)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.enabledInOutline = value;
|
||||
await this.plugin.saveSettings(
|
||||
this.plugin.settings.enabledInOutline
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName("Manage outline plugin heading decorator")
|
||||
.addButton((button) => {
|
||||
button.setButtonText("Manage").onClick(() => {
|
||||
this.manageHeadingDecoratorSettings("outlineSettings");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private isOpacityValue(value: number): value is OpacityOptions {
|
||||
|
|
|
|||
57
styles.css
57
styles.css
|
|
@ -384,3 +384,60 @@
|
|||
opacity: 100%;
|
||||
}
|
||||
/* source end */
|
||||
|
||||
/* outline start */
|
||||
.outline-custom-heading-decorator.before-heading-decorator::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator::after {
|
||||
content: attr(data-heading-decorator);
|
||||
opacity: 20%;
|
||||
}
|
||||
|
||||
.outline-custom-heading-decorator.before-heading-decorator::before {
|
||||
margin-inline-end: var(--size-4-1);
|
||||
}
|
||||
|
||||
.outline-custom-heading-decorator.after-heading-decorator::after {
|
||||
margin-inline-start: var(--size-4-1);
|
||||
}
|
||||
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="10%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="10%"]::after {
|
||||
opacity: 10%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="20%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="20%"]::after {
|
||||
opacity: 20%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="30%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="30%"]::after {
|
||||
opacity: 30%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="40%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="40%"]::after {
|
||||
opacity: 40%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="50%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="50%"]::after {
|
||||
opacity: 50%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="60%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="60%"]::after {
|
||||
opacity: 60%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="70%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="70%"]::after {
|
||||
opacity: 70%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="80%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="80%"]::after {
|
||||
opacity: 80%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="90%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="90%"]::after {
|
||||
opacity: 90%;
|
||||
}
|
||||
.outline-custom-heading-decorator.before-heading-decorator[data-decorator-opacity="100%"]::before,
|
||||
.outline-custom-heading-decorator.after-heading-decorator[data-decorator-opacity="100%"]::after {
|
||||
opacity: 100%;
|
||||
}
|
||||
/* outline end */
|
||||
|
|
|
|||
34
test/common/data.spec.ts
Normal file
34
test/common/data.spec.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import "mocha";
|
||||
import { expect } from "chai";
|
||||
import { diffLevel, compareHeadingText } from "../../common/data";
|
||||
|
||||
describe("common/data", function () {
|
||||
it("diffLevel", function () {
|
||||
expect(diffLevel(1, 1)).to.be.true;
|
||||
expect(diffLevel(2, 1)).to.be.false;
|
||||
expect(diffLevel(1, 2)).to.be.true;
|
||||
expect(diffLevel(3, 1)).be.false;
|
||||
expect(diffLevel(1, 3)).to.be.true;
|
||||
expect(diffLevel(4, 1)).be.false;
|
||||
expect(diffLevel(1, 4)).to.be.true;
|
||||
expect(diffLevel(5, 2)).be.false;
|
||||
expect(diffLevel(2, 5)).to.be.true;
|
||||
expect(diffLevel(6, 1)).be.false;
|
||||
expect(diffLevel(1, 6)).to.be.true;
|
||||
});
|
||||
|
||||
it("compareHeadingText", function () {
|
||||
expect(compareHeadingText("", "")).to.be.true;
|
||||
expect(compareHeadingText("h1", "h1")).to.be.true;
|
||||
expect(compareHeadingText("h1", "h2")).to.be.false;
|
||||
expect(compareHeadingText("h1", "`h1`")).to.be.true;
|
||||
expect(compareHeadingText("h1 h2", "`h1` h2")).to.be.true;
|
||||
expect(compareHeadingText("h1 `", "h1 `` ` ``")).to.be.true;
|
||||
expect(compareHeadingText("h1", "*h1*")).to.be.true;
|
||||
expect(compareHeadingText("h1", "**h1**")).to.be.true;
|
||||
expect(compareHeadingText("h1", "_h1_")).to.be.true;
|
||||
expect(compareHeadingText("h1", "__h1__")).to.be.true;
|
||||
expect(compareHeadingText("h1", "==h1==")).to.be.true;
|
||||
expect(compareHeadingText("h1", "~~h1~~")).to.be.true;
|
||||
});
|
||||
});
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"importHelpers": true,
|
||||
"isolatedModules": true,
|
||||
"strictNullChecks": true,
|
||||
"lib": ["DOM", "ES5", "ES6", "ES7"]
|
||||
"lib": ["DOM", "ES5", "ES6", "ES7", "ES2021"]
|
||||
},
|
||||
"include": ["**/*.ts"]
|
||||
}
|
||||
|
|
|
|||
3
types.d.ts
vendored
3
types.d.ts
vendored
|
|
@ -16,4 +16,5 @@ type PostionOptions = "before" | "after";
|
|||
type PluginDecoratorSettingsType =
|
||||
| "readingSettings"
|
||||
| "previewSettings"
|
||||
| "sourceSettings";
|
||||
| "sourceSettings"
|
||||
| "outlineSettings";
|
||||
|
|
|
|||
Loading…
Reference in a new issue