Skip to content

Commit eb89426

Browse files
committed
fix issue with button note positions
1 parent b43742c commit eb89426

File tree

9 files changed

+107
-63
lines changed

9 files changed

+107
-63
lines changed

packages/core/src/api/API.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
type InputFieldOptions,
1111
isFieldTypeAllowedInline,
1212
type JsViewFieldOptions,
13-
type NotePosition,
13+
NotePosition,
1414
RenderChildType,
1515
type TableFieldOptions,
1616
type ViewFieldOptions,
@@ -748,4 +748,22 @@ export abstract class API<Plugin extends IPlugin> {
748748
subscription.unsubscribe();
749749
});
750750
}
751+
752+
public createNotePosition(lineStart: number, lineEnd: number): NotePosition {
753+
validate(
754+
z.object({
755+
lineStart: z.number(),
756+
lineEnd: z.number(),
757+
}),
758+
{
759+
lineStart: lineStart,
760+
lineEnd: lineEnd,
761+
},
762+
);
763+
764+
return new NotePosition({
765+
lineStart: lineStart,
766+
lineEnd: lineEnd,
767+
});
768+
}
751769
}

packages/core/src/api/Validators.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
type InputFieldOptions,
88
InputFieldType,
99
type JsViewFieldOptions,
10-
type NotePosition,
10+
NotePosition,
1111
RenderChildType,
1212
type TableFieldOptions,
1313
type ViewFieldOptions,
@@ -62,6 +62,8 @@ export const V_VoidFunction = schemaForType<() => void>()(z.function().args().re
6262

6363
export const V_FieldMountable = schemaForType<FieldMountable>()(z.instanceof(FieldMountable));
6464

65+
export const V_NotePosition = schemaForType<NotePosition>()(z.instanceof(NotePosition));
66+
6567
export const V_ParsingPosition = schemaForType<ParsingPosition>()(
6668
z.object({
6769
index: z.number(),
@@ -221,13 +223,6 @@ export const V_TableFieldOptions = schemaForType<TableFieldOptions>()(
221223
}),
222224
);
223225

224-
export const V_NotePosition = schemaForType<NotePosition>()(
225-
z.object({
226-
lineStart: z.number(),
227-
lineEnd: z.number(),
228-
}),
229-
);
230-
231226
export const V_InlineButtonOptions = schemaForType<ButtonGroupOptions>()(
232227
z.object({
233228
renderChildType: V_RenderChildType,

packages/core/src/config/FieldConfigs.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,19 @@ export interface ButtonOptions {
629629
isPreview: boolean;
630630
}
631631

632-
export interface NotePosition {
632+
export class NotePosition {
633+
linePosition: LinePosition | undefined;
634+
635+
constructor(linePosition: LinePosition | undefined) {
636+
this.linePosition = linePosition;
637+
}
638+
639+
getPosition(): LinePosition | undefined {
640+
return this.linePosition;
641+
}
642+
}
643+
644+
export interface LinePosition {
633645
lineStart: number;
634646
lineEnd: number;
635647
}

packages/core/src/fields/button/ButtonActionRunner.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -305,19 +305,21 @@ export class ButtonActionRunner {
305305
throw new Error('Replace self action not supported for inline buttons');
306306
}
307307

308-
if (position === undefined) {
308+
const linePosition = position?.getPosition();
309+
310+
if (linePosition === undefined) {
309311
throw new Error('Position of the button in the note is unknown');
310312
}
311313

312-
if (position.lineStart > position.lineEnd) {
314+
if (linePosition.lineStart > linePosition.lineEnd) {
313315
throw new Error('Position of the button in the note is invalid');
314316
}
315317

316318
const content = await this.plugin.internal.readFilePath(filePath);
317319

318320
let splitContent = content.split('\n');
319321

320-
if (position.lineStart < 0 || position.lineEnd > splitContent.length + 1) {
322+
if (linePosition.lineStart < 0 || linePosition.lineEnd > splitContent.length + 1) {
321323
throw new Error('Position of the button in the note is out of bounds');
322324
}
323325

@@ -326,9 +328,9 @@ export class ButtonActionRunner {
326328
: action.replacement;
327329

328330
splitContent = [
329-
...splitContent.slice(0, position.lineStart),
331+
...splitContent.slice(0, linePosition.lineStart),
330332
replacement,
331-
...splitContent.slice(position.lineEnd + 1),
333+
...splitContent.slice(linePosition.lineEnd + 1),
332334
];
333335

334336
await this.plugin.internal.writeFilePath(filePath, splitContent.join('\n'));
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { type LinePosition, NotePosition } from 'packages/core/src/config/FieldConfigs';
2+
import { type MarkdownPostProcessorContext } from 'obsidian';
3+
4+
export class ObsidianNotePosition extends NotePosition {
5+
ctx: MarkdownPostProcessorContext;
6+
element: HTMLElement;
7+
8+
constructor(ctx: MarkdownPostProcessorContext, element: HTMLElement) {
9+
super(undefined);
10+
11+
this.ctx = ctx;
12+
this.element = element;
13+
}
14+
15+
public getPosition(): LinePosition | undefined {
16+
const pos = this.ctx.getSectionInfo(this.element);
17+
18+
if (!pos) {
19+
return undefined;
20+
}
21+
22+
return {
23+
lineStart: pos.lineStart,
24+
lineEnd: pos.lineEnd,
25+
};
26+
}
27+
}

packages/obsidian/src/main.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { DependencyManager } from 'packages/obsidian/src/dependencies/Dependency
2222
import { Version } from 'packages/obsidian/src/dependencies/Version';
2323
import { FaqView, MB_FAQ_VIEW_TYPE } from 'packages/obsidian/src/faq/FaqView';
2424
import { MetaBindSettingTab } from 'packages/obsidian/src/settings/SettingsTab';
25+
import { ObsidianNotePosition } from 'packages/obsidian/src/ObsidianNotePosition';
2526

2627
export enum MetaBindBuild {
2728
DEV = 'dev',
@@ -198,23 +199,13 @@ export default class MetaBindPlugin extends Plugin implements IPlugin {
198199
return;
199200
}
200201

201-
const sectionInfo = ctx.getSectionInfo(el);
202-
let position = undefined;
203-
204-
if (sectionInfo) {
205-
position = {
206-
lineStart: sectionInfo.lineStart,
207-
lineEnd: sectionInfo.lineEnd,
208-
};
209-
}
210-
211202
const mountable = this.api.createInlineFieldOfTypeFromString(
212203
fieldType,
213204
content,
214205
filePath,
215206
undefined,
216207
RenderChildType.BLOCK,
217-
position,
208+
new ObsidianNotePosition(ctx, el),
218209
);
219210
this.api.wrapInMDRC(mountable, codeBlock, ctx);
220211
});
@@ -251,20 +242,10 @@ export default class MetaBindPlugin extends Plugin implements IPlugin {
251242

252243
// "meta-bind-button" code blocks
253244
this.registerMarkdownCodeBlockProcessor('meta-bind-button', (source, el, ctx) => {
254-
const sectionInfo = ctx.getSectionInfo(el);
255-
let position = undefined;
256-
257-
if (sectionInfo) {
258-
position = {
259-
lineStart: sectionInfo.lineStart,
260-
lineEnd: sectionInfo.lineEnd,
261-
};
262-
}
263-
264245
const mountable = this.api.createButtonMountable(ctx.sourcePath, {
265246
declaration: source,
266247
isPreview: false,
267-
position: position,
248+
position: new ObsidianNotePosition(ctx, el),
268249
});
269250

270251
this.api.wrapInMDRC(mountable, el, ctx);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { type LinePosition, NotePosition } from 'packages/core/src/config/FieldConfigs';
2+
import { type MarkdownPostProcessorContext } from 'obsidian/publish';
3+
4+
export class PublishNotePosition extends NotePosition {
5+
ctx: MarkdownPostProcessorContext;
6+
element: HTMLElement;
7+
8+
constructor(ctx: MarkdownPostProcessorContext, element: HTMLElement) {
9+
super(undefined);
10+
11+
this.ctx = ctx;
12+
this.element = element;
13+
}
14+
15+
public getPosition(): LinePosition | undefined {
16+
const pos = this.ctx.getSectionInfo(this.element);
17+
18+
if (!pos) {
19+
return undefined;
20+
}
21+
22+
return {
23+
lineStart: pos.lineStart,
24+
lineEnd: pos.lineEnd,
25+
};
26+
}
27+
}

packages/publish/src/main.ts

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { PublishMetadataSource } from 'packages/publish/src/PublishMetadataSourc
1010
import { EMBED_MAX_DEPTH, RenderChildType } from 'packages/core/src/config/FieldConfigs';
1111
import { DateParser } from 'packages/core/src/parsers/DateParser';
1212
import { setFirstWeekday } from 'packages/core/src/utils/DatePickerUtils';
13+
import { PublishNotePosition } from 'packages/publish/src/PublishNotePosition';
1314

1415
export class MetaBindPublishPlugin implements IPlugin {
1516
settings: MetaBindPluginSettings;
@@ -83,23 +84,13 @@ export class MetaBindPublishPlugin implements IPlugin {
8384
return;
8485
}
8586

86-
const sectionInfo = ctx.getSectionInfo(el);
87-
let position = undefined;
88-
89-
if (sectionInfo) {
90-
position = {
91-
lineStart: sectionInfo.lineStart,
92-
lineEnd: sectionInfo.lineEnd,
93-
};
94-
}
95-
9687
const mountable = this.api.createInlineFieldOfTypeFromString(
9788
fieldType,
9889
content,
9990
filePath,
10091
undefined,
10192
RenderChildType.BLOCK,
102-
position,
93+
new PublishNotePosition(ctx, el),
10394
);
10495
const mdrc = this.api.wrapInMDRC(mountable, codeBlock, ctx);
10596

@@ -144,20 +135,10 @@ export class MetaBindPublishPlugin implements IPlugin {
144135

145136
// "meta-bind-button" code blocks
146137
publish.registerMarkdownCodeBlockProcessor('meta-bind-button', (source, el, ctx) => {
147-
const sectionInfo = ctx.getSectionInfo(el);
148-
let position = undefined;
149-
150-
if (sectionInfo) {
151-
position = {
152-
lineStart: sectionInfo.lineStart,
153-
lineEnd: sectionInfo.lineEnd,
154-
};
155-
}
156-
157138
const mountable = this.api.createButtonMountable(ctx.sourcePath, {
158139
declaration: source,
159140
isPreview: false,
160-
position: position,
141+
position: new PublishNotePosition(ctx, el),
161142
});
162143

163144
const mdrc = this.api.wrapInMDRC(mountable, el, ctx);

tests/fields/Button.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { beforeEach, describe, expect, test } from 'bun:test';
22
import { ButtonAction, ButtonActionType } from 'packages/core/src/config/ButtonConfig';
33
import { TestPlugin } from 'tests/__mocks__/TestPlugin';
4+
import { NotePosition } from 'packages/core/src/config/FieldConfigs';
45

56
let testPlugin: TestPlugin;
67
const testFilePath = 'test/file.md';
@@ -175,11 +176,11 @@ const buttonActionTests: Record<ButtonActionType, () => void> = {
175176
},
176177
testFilePath,
177178
false,
178-
{
179+
new NotePosition({
179180
// these line numbers start at 0
180181
lineStart: 1,
181182
lineEnd: 1,
182-
},
183+
}),
183184
);
184185

185186
expect(testPlugin.internal.fileSystem.readFile('test/file.md')).toBe('line1\nno button\nline3\n');
@@ -196,11 +197,11 @@ const buttonActionTests: Record<ButtonActionType, () => void> = {
196197
},
197198
testFilePath,
198199
false,
199-
{
200+
new NotePosition({
200201
// these line numbers start at 0
201202
lineStart: 1,
202203
lineEnd: 3,
203-
},
204+
}),
204205
);
205206

206207
expect(testPlugin.internal.fileSystem.readFile('test/file.md')).toBe('line1\nno button\nline3\n');

0 commit comments

Comments
 (0)