Skip to content

Commit 1db362c

Browse files
committed
buttons LP support
1 parent 8bfa196 commit 1db362c

29 files changed

+397
-262
lines changed

exampleVault/Advanced Examples/PF2e Encounter Calculator.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
playerCount: 6
3-
playerLevel: 4
3+
playerLevel: 6
44
enemy:
55
- name: Somthing
66
level: 2
@@ -11,11 +11,11 @@ enemy:
1111
count: 1
1212
variant: 0
1313
- name: dragon
14-
level: 2
14+
level: 3
1515
count: 2
1616
variant: -1
1717
- name: test
18-
level: 1
18+
level: 5
1919
count: 1
2020
variant: 0
2121
test:

exampleVault/Button Example.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,4 +137,17 @@ actions:
137137
- type: input
138138
str: PF2e
139139
140+
```
141+
142+
```meta-bind-button
143+
label: Test
144+
hidden: false
145+
id: ""
146+
style: default
147+
actions:
148+
- type: sleep
149+
ms: 1000
150+
- type: command
151+
command: obsidian-meta-bind-plugin:open-help
152+
140153
```

src/api/API.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { type ButtonActionRunner } from '../fields/button/ButtonActionRunner';
3030
import { ButtonManager } from '../fields/button/ButtonManager';
3131
import { type BindTargetDeclaration, BindTargetStorageType } from '../parsers/BindTargetDeclaration';
3232
import { ObsidianButtonActionRunner } from '../fields/button/ObsidianButtonActionRunner';
33+
import { ButtonMDRC } from '../renderChildren/ButtonMDRC';
34+
import { InlineButtonMDRC } from '../renderChildren/InlineButtonMDRC';
3335

3436
export class API implements IAPI {
3537
public plugin: MetaBindPlugin;
@@ -275,4 +277,36 @@ export class API implements IAPI {
275277
public createBindTarget(fullDeclaration: string, currentFilePath: string): BindTargetDeclaration {
276278
return this.bindTargetParser.parseAndValidateBindTarget(fullDeclaration, currentFilePath);
277279
}
280+
281+
public createButtonFromString(
282+
fullDeclaration: string,
283+
filePath: string,
284+
containerEl: HTMLElement,
285+
component: Component | MarkdownPostProcessorContext,
286+
): ButtonMDRC | ExcludedMDRC {
287+
if (this.plugin.isFilePathExcluded(filePath)) {
288+
return this.createExcludedField(containerEl, filePath, component);
289+
}
290+
291+
const button = new ButtonMDRC(containerEl, fullDeclaration, this.plugin, filePath, getUUID());
292+
component.addChild(button);
293+
294+
return button;
295+
}
296+
297+
public createInlineButtonFromString(
298+
fullDeclaration: string,
299+
filePath: string,
300+
containerEl: HTMLElement,
301+
component: Component | MarkdownPostProcessorContext,
302+
): InlineButtonMDRC | ExcludedMDRC {
303+
if (this.plugin.isFilePathExcluded(filePath)) {
304+
return this.createExcludedField(containerEl, filePath, component);
305+
}
306+
307+
const button = new InlineButtonMDRC(containerEl, fullDeclaration, this.plugin, filePath, getUUID());
308+
component.addChild(button);
309+
310+
return button;
311+
}
278312
}

src/cm6/Cm6_Util.ts

Lines changed: 1 addition & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { type EditorSelection, type EditorState } from '@codemirror/state';
2-
import type MetaBindPlugin from '../main';
3-
import { type Component, editorInfoField, type TFile } from 'obsidian';
4-
import { ErrorLevel, MetaBindInternalError } from '../utils/errors/MetaBindErrors';
5-
import { InputFieldWidget, type MarkdownRenderChildWidget, MBWidgetType, ViewFieldWidget } from './Cm6_Widgets';
2+
import { editorInfoField, type TFile } from 'obsidian';
63
import { type DecorationSet, type EditorView } from '@codemirror/view';
7-
import { type AbstractMDRC } from '../renderChildren/AbstractMDRC';
84

95
export class Cm6_Util {
106
/**
@@ -39,84 +35,6 @@ export class Cm6_Util {
3935
return state.sliceDoc(from, to);
4036
}
4137

42-
/**
43-
* Creates a MDRC widget from a given widget type.
44-
*
45-
* @param widgetType
46-
* @param content
47-
* @param filePath
48-
* @param component
49-
* @param plugin
50-
*/
51-
static constructMarkdownRenderChildWidget(
52-
widgetType: MBWidgetType,
53-
content: string,
54-
filePath: string,
55-
component: Component,
56-
plugin: MetaBindPlugin,
57-
): MarkdownRenderChildWidget<AbstractMDRC> | undefined {
58-
if (widgetType === MBWidgetType.INPUT_FIELD_WIDGET) {
59-
return new InputFieldWidget(content, filePath, component, plugin);
60-
} else if (widgetType === MBWidgetType.VIEW_FIELD_WIDGET) {
61-
return new ViewFieldWidget(content, filePath, component, plugin);
62-
}
63-
64-
return undefined;
65-
}
66-
67-
/**
68-
* Gets the prefix of a given widget type. (e.g. INPUT or VIEW)
69-
*
70-
* @param widgetType
71-
*/
72-
static getDeclarationPrefix(widgetType: MBWidgetType): string {
73-
if (widgetType === MBWidgetType.INPUT_FIELD_WIDGET) {
74-
return 'INPUT';
75-
} else if (widgetType === MBWidgetType.VIEW_FIELD_WIDGET) {
76-
return 'VIEW';
77-
}
78-
79-
throw new MetaBindInternalError({
80-
errorLevel: ErrorLevel.CRITICAL,
81-
effect: 'failed to get declaration prefix',
82-
cause: `Invalid widget type "${widgetType}"`,
83-
});
84-
}
85-
86-
/**
87-
* Checks if a string is a declaration of a given widget type.
88-
*
89-
* @param widgetType
90-
* @param str
91-
*/
92-
static isDeclaration(widgetType: MBWidgetType, str: string): boolean {
93-
const startStr: string = Cm6_Util.getDeclarationPrefix(widgetType) + '[';
94-
const endStr: string = ']';
95-
96-
return str.startsWith(startStr) && str.endsWith(endStr);
97-
}
98-
99-
/**
100-
* Checks if a string is any declaration and if yes returns the widget type.
101-
* This does not use {@link isDeclaration} because of performance reasons.
102-
*
103-
* @param str
104-
*/
105-
static isDeclarationAndGetWidgetType(str: string): MBWidgetType | undefined {
106-
if (!str.endsWith(']')) {
107-
return undefined;
108-
}
109-
110-
for (const widgetType of Object.values(MBWidgetType)) {
111-
const startStr: string = Cm6_Util.getDeclarationPrefix(widgetType) + '[';
112-
if (str.startsWith(startStr)) {
113-
return widgetType;
114-
}
115-
}
116-
117-
return undefined;
118-
}
119-
12038
/**
12139
* Gets the current file of an editor.
12240
*

src/cm6/Cm6_ViewPlugin.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { syntaxTree } from '@codemirror/language';
44
import { type SyntaxNode } from '@lezer/common';
55
import { Component, editorLivePreviewField, type TFile } from 'obsidian';
66
import type MetaBindPlugin from '../main';
7-
import { type MBWidgetType } from './Cm6_Widgets';
87
import { Cm6_Util } from './Cm6_Util';
8+
import { InlineMDRCUtils, type InlineMDRCType } from '../utils/InlineMDRCUtils';
99

1010
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1111
export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlugin): ViewPlugin<any> {
@@ -107,7 +107,7 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
107107
* @param content the content of the node
108108
* @param widgetType the type of the widget to add
109109
*/
110-
addDecoration(node: SyntaxNode, view: EditorView, content: string, widgetType: MBWidgetType): void {
110+
addDecoration(node: SyntaxNode, view: EditorView, content: string, widgetType: InlineMDRCType): void {
111111
const from = node.from - 1;
112112
const to = node.to + 1;
113113

@@ -141,7 +141,7 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
141141
getRenderInfo(
142142
view: EditorView,
143143
node: SyntaxNode,
144-
): { shouldRender: boolean; content: string | undefined; widgetType: MBWidgetType | undefined } {
144+
): { shouldRender: boolean; content: string | undefined; widgetType: InlineMDRCType | undefined } {
145145
// get the node props
146146
// const propsString: string | undefined = node.type.prop<string>(tokenClassNodeProp);
147147
// workaround until bun installs https://github.com/lishid/cm-language/ correctly
@@ -174,11 +174,11 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
174174
view: EditorView,
175175
from: number,
176176
to: number,
177-
): { content: string; widgetType: MBWidgetType | undefined } {
177+
): { content: string; widgetType: InlineMDRCType | undefined } {
178178
const content = Cm6_Util.getContent(view.state, from, to);
179179
return {
180180
content: content,
181-
widgetType: Cm6_Util.isDeclarationAndGetWidgetType(content),
181+
widgetType: InlineMDRCUtils.isDeclarationAndGetMDRCType(content),
182182
};
183183
}
184184

@@ -234,20 +234,17 @@ export function createMarkdownRenderChildWidgetEditorPlugin(plugin: MetaBindPlug
234234
*/
235235
renderWidget(
236236
node: SyntaxNode,
237-
widgetType: MBWidgetType,
237+
widgetType: InlineMDRCType,
238238
content: string,
239239
currentFile: TFile,
240240
): Range<Decoration> | undefined {
241-
const widget = Cm6_Util.constructMarkdownRenderChildWidget(
241+
const widget = InlineMDRCUtils.constructMDRCWidget(
242242
widgetType,
243243
content,
244244
currentFile.path,
245245
this.component,
246246
plugin,
247247
);
248-
if (!widget) {
249-
return;
250-
}
251248

252249
return Decoration.replace({
253250
widget: widget,

src/cm6/Cm6_Widgets.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { type ViewFieldMDRC } from '../renderChildren/ViewFieldMDRC';
55
import { type InputFieldMDRC } from '../renderChildren/InputFieldMDRC';
66
import { type Component } from 'obsidian';
77
import { type ExcludedMDRC } from '../renderChildren/ExcludedMDRC';
8-
import { RenderChildType } from '../config/FieldConfigs';
8+
import { InlineMDRCUtils } from '../utils/InlineMDRCUtils';
99

1010
export abstract class MarkdownRenderChildWidget<T extends AbstractMDRC> extends WidgetType {
1111
content: string;
@@ -22,7 +22,8 @@ export abstract class MarkdownRenderChildWidget<T extends AbstractMDRC> extends
2222
this.plugin = plugin;
2323
}
2424

25-
eq(other: ViewFieldWidget): boolean {
25+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
26+
eq(other: MarkdownRenderChildWidget<any>): boolean {
2627
return other.content === this.content;
2728
}
2829

@@ -43,31 +44,32 @@ export abstract class MarkdownRenderChildWidget<T extends AbstractMDRC> extends
4344
}
4445
}
4546

46-
export class ViewFieldWidget extends MarkdownRenderChildWidget<ViewFieldMDRC> {
47-
public createRenderChild(container: HTMLElement, component: Component): ViewFieldMDRC | ExcludedMDRC {
48-
return this.plugin.api.createViewFieldFromString(
47+
export class InputFieldWidget extends MarkdownRenderChildWidget<InputFieldMDRC> {
48+
public createRenderChild(container: HTMLElement, component: Component): InputFieldMDRC | ExcludedMDRC {
49+
return InlineMDRCUtils.createInlineInputFieldMDRC(
4950
this.content,
50-
RenderChildType.INLINE,
5151
this.filePath,
5252
container,
5353
component,
54+
this.plugin,
5455
);
5556
}
5657
}
5758

58-
export class InputFieldWidget extends MarkdownRenderChildWidget<InputFieldMDRC> {
59-
public createRenderChild(container: HTMLElement, component: Component): InputFieldMDRC | ExcludedMDRC {
60-
return this.plugin.api.createInputFieldFromString(
59+
export class ViewFieldWidget extends MarkdownRenderChildWidget<ViewFieldMDRC> {
60+
public createRenderChild(container: HTMLElement, component: Component): ViewFieldMDRC | ExcludedMDRC {
61+
return InlineMDRCUtils.createInlineViewFieldMDRC(
6162
this.content,
62-
RenderChildType.INLINE,
6363
this.filePath,
6464
container,
6565
component,
66+
this.plugin,
6667
);
6768
}
6869
}
6970

70-
export enum MBWidgetType {
71-
INPUT_FIELD_WIDGET = 'INPUT_FIELD_WIDGET',
72-
VIEW_FIELD_WIDGET = 'VIEW_FIELD_WIDGET',
71+
export class ButtonWidget extends MarkdownRenderChildWidget<InputFieldMDRC> {
72+
public createRenderChild(container: HTMLElement, component: Component): InputFieldMDRC | ExcludedMDRC {
73+
return InlineMDRCUtils.createInlineButtonMDRC(this.content, this.filePath, container, component, this.plugin);
74+
}
7375
}

src/config/ButtonConfig.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { z } from 'zod';
2-
import { oneOf, schemaForType } from '../utils/ZodHelpers';
2+
import { oneOf, schemaForType } from '../utils/ZodUtils';
33

44
export enum ButtonStyleType {
55
DEFAULT = 'default',

src/faq/FaqComponent.svelte

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts">
2-
import { DocsHelper } from '../utils/DocsHelper';
2+
import { DocsUtils } from '../utils/DocsUtils';
33
import ErrorIndicatorComponent from '../utils/errors/ErrorIndicatorComponent.svelte';
44
import { App } from 'obsidian';
55
import { ErrorCollection } from '../utils/errors/ErrorCollection';
@@ -48,30 +48,30 @@
4848
<Button
4949
variant="primary"
5050
on:click={() => {
51-
DocsHelper.open(DocsHelper.linkToHome());
51+
DocsUtils.open(DocsUtils.linkToHome());
5252
}}
5353
>Docs
5454
</Button>
5555
<Button
5656
variant="default"
5757
on:click={() => {
58-
DocsHelper.open(DocsHelper.linkToGithub());
58+
DocsUtils.open(DocsUtils.linkToGithub());
5959
}}
6060
>GitHub
6161
</Button>
6262
<Button
6363
variant="default"
6464
on:click={() => {
65-
DocsHelper.open(DocsHelper.linkToIssues());
65+
DocsUtils.open(DocsUtils.linkToIssues());
6666
}}
6767
>Report Issue
6868
</Button>
6969
</p>
7070

7171
<h2>Error Messages</h2>
7272
<p>
73-
When creating <a href={DocsHelper.linkToInputFields()}>Input Fields</a> or
74-
<a href={DocsHelper.linkToViewFields()}>View Fields</a>
73+
When creating <a href={DocsUtils.linkToInputFields()}>Input Fields</a> or
74+
<a href={DocsUtils.linkToViewFields()}>View Fields</a>
7575
<strong>warnings</strong>
7676
(
7777
<ErrorIndicatorComponent
@@ -92,7 +92,7 @@
9292

9393
<h2>Input Fields</h2>
9494
<p>
95-
<a href={DocsHelper.linkToInputFields()}>Input Fields</a> let you change the frontmatter of your notes from inside
95+
<a href={DocsUtils.linkToInputFields()}>Input Fields</a> let you change the frontmatter of your notes from inside
9696
of notes.
9797
</p>
9898

@@ -103,7 +103,7 @@
103103

104104
<h2>View Fields</h2>
105105
<p>
106-
<a href={DocsHelper.linkToViewFields()}>View Fields</a> let you view and perform calculations using the frontmatter
106+
<a href={DocsUtils.linkToViewFields()}>View Fields</a> let you view and perform calculations using the frontmatter
107107
of your notes from inside of notes. They will update instantly to reflect changes to the frontmatter made by input
108108
fields and as fast as obsidian allows it for changes from other sources.
109109
</p>
@@ -114,8 +114,8 @@
114114
>Bind Targets</a
115115
>
116116
let the plugin know what frontmatter properties to bind
117-
<a href={DocsHelper.linkToInputFields()}>Input Fields</a>
117+
<a href={DocsUtils.linkToInputFields()}>Input Fields</a>
118118
and
119-
<a href={DocsHelper.linkToViewFields()}>View Fields</a> to.
119+
<a href={DocsUtils.linkToViewFields()}>View Fields</a> to.
120120
</p>
121121
</div>

0 commit comments

Comments
 (0)