Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions packages/core/src/api/FileAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MDLinkParser } from 'packages/core/src/parsers/MarkdownLinkParser';
import { ErrorLevel, MetaBindParsingError } from 'packages/core/src/utils/errors/MetaBindErrors';
import type { LineNumberContext } from 'packages/core/src/utils/LineNumberExpression';
import type { MB_Comps, MetaBind } from '..';
import type { ButtonPaneType } from '../config/ButtonConfig';

export abstract class FileAPI<Components extends MB_Comps> {
readonly mb: MetaBind<Components>;
Expand Down Expand Up @@ -57,9 +58,9 @@ export abstract class FileAPI<Components extends MB_Comps> {
*
* @param filePath
* @param callingFilePath
* @param newTab
* @param PaneType
*/
public abstract open(filePath: string, callingFilePath: string, newTab: boolean): Promise<void>;
public abstract open(filePath: string, callingFilePath: string, PaneType: ButtonPaneType | boolean): Promise<void>;

/**
* Resolves a file name to a file path.
Expand Down
16 changes: 15 additions & 1 deletion packages/core/src/config/ButtonConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ export enum ButtonActionType {
INLINE_JS = 'inlineJS',
}

export enum ButtonPaneType {
NewTab = 'tab',
NewSplit = 'split',
NewWindow = 'window',
}

export interface CommandButtonAction {
type: ButtonActionType.COMMAND;
command: string;
Expand All @@ -50,7 +56,7 @@ export interface JSButtonAction {
export interface OpenButtonAction {
type: ButtonActionType.OPEN;
link: string;
newTab?: boolean;
panetype?: ButtonPaneType; // "tab" | "split" | "window"
}

export interface InputButtonAction {
Expand Down Expand Up @@ -233,6 +239,14 @@ export class ButtonClickContext {
openInNewTab(): boolean {
return this.type === ButtonClickType.MIDDLE || this.ctrlKey;
}

openInNewWindow(): boolean {
return this.type === ButtonClickType.LEFT && this.ctrlKey && this.altKey && this.shiftKey;
}

openInNewSplit(): boolean {
return this.type === ButtonClickType.MIDDLE && this.ctrlKey && this.altKey;
}
}

export enum ButtonClickType {
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/config/validators/ButtonConfigValidators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {
TemplaterCreateNoteButtonAction,
UpdateMetadataButtonAction,
} from 'packages/core/src/config/ButtonConfig';
import { ButtonActionType, ButtonStyleType } from 'packages/core/src/config/ButtonConfig';
import { ButtonActionType, ButtonPaneType, ButtonStyleType } from 'packages/core/src/config/ButtonConfig';
import { oneOf, schemaForType } from 'packages/core/src/utils/ZodUtils';
import { z } from 'zod';

Expand Down Expand Up @@ -91,7 +91,7 @@ export const V_OpenButtonAction = schemaForType<OpenButtonAction>()(
z.object({
type: z.literal(ButtonActionType.OPEN),
link: actionFieldString('open', 'link', 'link to open'),
newTab: actionFieldBool('open', 'newTab', '').optional(),
panetype: z.enum([ButtonPaneType.NewTab, ButtonPaneType.NewSplit, ButtonPaneType.NewWindow]).optional(),
}),
);

Expand Down
29 changes: 21 additions & 8 deletions packages/core/src/fields/button/actions/OpenButtonActionConfig.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import type { MetaBind } from 'packages/core/src';
import type {
ButtonClickContext,
ButtonConfig,
ButtonContext,
OpenButtonAction,
import {
type ButtonClickContext,
type ButtonConfig,
type ButtonContext,
type OpenButtonAction,
ButtonPaneType,
} from 'packages/core/src/config/ButtonConfig';
import { ButtonActionType } from 'packages/core/src/config/ButtonConfig';
import { AbstractButtonActionConfig } from 'packages/core/src/fields/button/AbstractButtonActionConfig';
import { MDLinkParser } from 'packages/core/src/parsers/MarkdownLinkParser';
import Button from 'packages/core/src/utils/components/Button.svelte';

export class OpenButtonActionConfig extends AbstractButtonActionConfig<OpenButtonAction> {
constructor(mb: MetaBind) {
Expand All @@ -21,16 +23,27 @@ export class OpenButtonActionConfig extends AbstractButtonActionConfig<OpenButto
_context: ButtonContext,
click: ButtonClickContext,
): Promise<void> {
const newTab = click.openInNewTab() || (action.newTab ?? false);
const link = MDLinkParser.interpretAsLink(action.link);
if (!link) {
throw new Error('Invalid link');
}
link.open(this.mb, filePath, newTab);

let pane: ButtonPaneType | boolean | undefined = action.panetype;
if (click.openInNewSplit()) {
pane = ButtonPaneType.NewSplit;
}
if (click.openInNewTab()) {
pane = ButtonPaneType.NewTab;
}
if (click.openInNewWindow()) {
pane = ButtonPaneType.NewWindow;
}

link.open(this.mb, filePath, pane ?? (undefined as unknown as ButtonPaneType));
}

create(): Required<OpenButtonAction> {
return { type: ButtonActionType.OPEN, link: '', newTab: true };
return { type: ButtonActionType.OPEN, link: '', panetype: ButtonPaneType.NewTab };
}

getActionLabel(): string {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import type { MetaBind } from 'packages/core/src';
import { ButtonStyleType, type OpenButtonAction } from 'packages/core/src/config/ButtonConfig';
import { ButtonStyleType, ButtonPaneType, type OpenButtonAction } from 'packages/core/src/config/ButtonConfig';

import Button from 'packages/core/src/utils/components/Button.svelte';
import Icon from 'packages/core/src/utils/components/Icon.svelte';
Expand Down Expand Up @@ -29,6 +29,11 @@
>
</SettingComponent>

<SettingComponent name="New tab" description="Whether to open the link in a new tab.">
<Toggle bind:checked={action.newTab}></Toggle>
<SettingComponent name="Open in" description="How the link should open.">
<select bind:value={action.panetype}>
<option value={false}>Same Tab</option>
<option value={ButtonPaneType.NewTab}>New Tab</option>
<option value={ButtonPaneType.NewSplit}>New Split</option>
<option value={ButtonPaneType.NewWindow}>New Window</option>
</select>
</SettingComponent>
5 changes: 3 additions & 2 deletions packages/core/src/parsers/MarkdownLinkParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { P_FilePath } from 'packages/core/src/parsers/nomParsers/GeneralNomParse
import { runParser } from 'packages/core/src/parsers/ParsingError';
import { isUrl, openURL } from 'packages/core/src/utils/Utils';
import type { MetaBind } from '..';
import type { ButtonPaneType } from '../config/ButtonConfig';

const P_MDLinkInner: Parser<[string, string | undefined, string | undefined]> = P.sequence(
P_FilePath, // the file path
Expand Down Expand Up @@ -63,9 +64,9 @@ export class MarkdownLink {
return this.block ? `${this.target}#${this.block}` : this.target;
}

open(mb: MetaBind, relativeFilePath: string, newTab: boolean): void {
open(mb: MetaBind, relativeFilePath: string, PaneType: ButtonPaneType): void {
if (this.internal) {
void mb.file.open(this.fullTarget(), relativeFilePath, newTab);
void mb.file.open(this.fullTarget(), relativeFilePath, PaneType);
} else {
openURL(this.target);
}
Expand Down
5 changes: 3 additions & 2 deletions packages/obsidian/src/ObsFileAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { App } from 'obsidian';
import { normalizePath, TFile, TFolder } from 'obsidian';
import { FileAPI } from 'packages/core/src/api/FileAPI';
import type { ObsComponents, ObsMetaBind } from 'packages/obsidian/src/main';
import type { ButtonPaneType } from './docsExports';

export class ObsFileAPI extends FileAPI<ObsComponents> {
readonly app: App;
Expand Down Expand Up @@ -72,8 +73,8 @@ export class ObsFileAPI extends FileAPI<ObsComponents> {
.map(file => file.path);
}

public async open(filePath: string, callingFilePath: string, newTab: boolean): Promise<void> {
void this.app.workspace.openLinkText(filePath, callingFilePath, newTab);
public async open(filePath: string, callingFilePath: string, PaneType: ButtonPaneType): Promise<void> {
void this.app.workspace.openLinkText(filePath, callingFilePath, PaneType);
}

public async openInSourceMode(file: TFile, newTab: boolean): Promise<void> {
Expand Down
3 changes: 2 additions & 1 deletion packages/publish/src/PublishFileAPI.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FileAPI } from 'packages/core/src/api/FileAPI';
import type { ButtonPaneType } from 'packages/core/src/config/ButtonConfig';
import type { PublishComponents } from 'packages/publish/src/main';

export class PublishFileAPI extends FileAPI<PublishComponents> {
Expand Down Expand Up @@ -40,7 +41,7 @@ export class PublishFileAPI extends FileAPI<PublishComponents> {
return Array.from(folders);
}

public open(_filePath: string, _callingFilePath: string, _newTab: boolean): Promise<void> {
public open(_filePath: string, _callingFilePath: string, _paneType: ButtonPaneType | boolean): Promise<void> {
throw new Error('not implemented');
}

Expand Down
3 changes: 2 additions & 1 deletion tests/fields/Button.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ButtonActionType,
ButtonClickContext,
ButtonClickType,
ButtonPaneType,
} from 'packages/core/src/config/ButtonConfig';
import { TestMetaBind } from 'tests/__mocks__/TestPlugin';

Expand Down Expand Up @@ -55,7 +56,7 @@ const buttonActionTests: Record<ButtonActionType, () => void> = {
await simplifiedRunAction({
type: ButtonActionType.OPEN,
link: '[[test/otherFile.md]]',
newTab: true,
panetype: ButtonPaneType.NewSplit,
});
}).not.toThrow();
});
Expand Down