mirror of
https://github.com/meld-cp/obsidian-build.git
synced 2026-07-22 07:30:25 +00:00
- don't use global app instance
- remove unneeded code - better await for modal closes
This commit is contained in:
parent
24a3de716a
commit
d2e0d4f7ea
10 changed files with 108 additions and 120 deletions
26
src/ToolbarButton.ts
Normal file
26
src/ToolbarButton.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
export class ToolbarButton {
|
||||
id: string;
|
||||
label?: string;
|
||||
params: string[];
|
||||
|
||||
constructor(id: string, label?: string, params?: string[]) {
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
this.params = params ?? [];
|
||||
}
|
||||
|
||||
public static parse(line: string): ToolbarButton | null {
|
||||
const pair = line.split('=');
|
||||
if (pair.length == 2) {
|
||||
|
||||
const buttonParts = pair[0].split('|').map(e => e.trim());
|
||||
const id = buttonParts.shift() ?? '';
|
||||
const params = buttonParts;
|
||||
|
||||
const label = pair[1].trim();
|
||||
|
||||
return new ToolbarButton(id, label, params);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -146,9 +146,19 @@ export class Compiler{
|
|||
|
||||
ui: new UiRunContextImplemention(),
|
||||
|
||||
io: new IoRunContextImplemention( log, data, consumableBlocks ),
|
||||
io: new IoRunContextImplemention(
|
||||
view.app.vault,
|
||||
view.app.workspace,
|
||||
log,
|
||||
data,
|
||||
consumableBlocks
|
||||
),
|
||||
|
||||
markers: new MarkerRunContextImplemention(log, view.file.path ),
|
||||
markers: new MarkerRunContextImplemention(
|
||||
view.app.vault,
|
||||
log,
|
||||
view.file.path
|
||||
),
|
||||
|
||||
dv: dvGetAPI(),
|
||||
}
|
||||
|
|
|
|||
52
src/main.ts
52
src/main.ts
|
|
@ -3,18 +3,9 @@ import * as HB from 'handlebars';
|
|||
import { RunLogger } from 'src/run-logger';
|
||||
import { Compiler } from 'src/compiler';
|
||||
import { CODE_BLOCK_LANG_TOOLBAR, URL_HELP } from 'src/constants';
|
||||
|
||||
interface MeldBuildPluginSettings {
|
||||
mySetting: string;
|
||||
}
|
||||
|
||||
const DEFAULT_SETTINGS: MeldBuildPluginSettings = {
|
||||
mySetting: 'default'
|
||||
}
|
||||
import { ToolbarButton } from './ToolbarButton';
|
||||
|
||||
export default class MeldBuildPlugin extends Plugin {
|
||||
settings: MeldBuildPluginSettings;
|
||||
|
||||
|
||||
private async codeblockProcessor(el: HTMLElement, ctx: MarkdownPostProcessorContext): Promise<void> {
|
||||
const els = el.querySelector('.language-js');
|
||||
|
|
@ -31,8 +22,6 @@ export default class MeldBuildPlugin extends Plugin {
|
|||
|
||||
async onload() {
|
||||
|
||||
await this.loadSettings();
|
||||
|
||||
await this.reloadActiveViewsWithToolbars();
|
||||
|
||||
this.registerHandlebarHelpers();
|
||||
|
|
@ -107,7 +96,7 @@ export default class MeldBuildPlugin extends Plugin {
|
|||
}
|
||||
|
||||
private async reloadActiveViewsWithToolbars(){
|
||||
app.workspace.iterateAllLeaves( leaf =>{
|
||||
this.app.workspace.iterateAllLeaves( leaf =>{
|
||||
const view = leaf.view;
|
||||
if ( view instanceof MarkdownView ){
|
||||
|
||||
|
|
@ -123,7 +112,7 @@ export default class MeldBuildPlugin extends Plugin {
|
|||
}
|
||||
|
||||
private async buildAndRunActiveView( runGroupTag?:string ){
|
||||
const view = app.workspace.getActiveViewOfType( MarkdownView );
|
||||
const view = this.app.workspace.getActiveViewOfType( MarkdownView );
|
||||
if (!view){
|
||||
new Notice( 'Unable to run, no active Markdown View found' );
|
||||
return;
|
||||
|
|
@ -135,7 +124,7 @@ export default class MeldBuildPlugin extends Plugin {
|
|||
if ( !( view instanceof MarkdownView ) ){
|
||||
return;
|
||||
}
|
||||
const logger = new RunLogger();
|
||||
const logger = new RunLogger( view.app.vault );
|
||||
try{
|
||||
//await view.save();
|
||||
const compiler = new Compiler();
|
||||
|
|
@ -173,39 +162,6 @@ export default class MeldBuildPlugin extends Plugin {
|
|||
|
||||
}
|
||||
|
||||
async loadSettings() {
|
||||
this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
|
||||
}
|
||||
|
||||
async saveSettings() {
|
||||
await this.saveData(this.settings);
|
||||
}
|
||||
}
|
||||
|
||||
class ToolbarButton{
|
||||
id:string;
|
||||
label?: string;
|
||||
params: string[];
|
||||
|
||||
constructor( id:string, label?:string, params?:string[] ){
|
||||
this.id = id;
|
||||
this.label = label;
|
||||
this.params = params ?? [];
|
||||
}
|
||||
|
||||
public static parse( line:string ) : ToolbarButton|null{
|
||||
const pair = line.split( '=' );
|
||||
if( pair.length == 2 ){
|
||||
|
||||
const buttonParts = pair[0].split( '|' ).map( e => e.trim() );
|
||||
const id = buttonParts.shift() ?? '';
|
||||
const params = buttonParts;
|
||||
|
||||
const label = pair[1].trim();
|
||||
|
||||
return new ToolbarButton( id, label, params );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { App, Modal, Setting } from "obsidian";
|
||||
import { Utils } from "src/utils";
|
||||
|
||||
export class AskModal extends Modal {
|
||||
|
||||
|
|
@ -7,8 +6,6 @@ export class AskModal extends Modal {
|
|||
private options:string[] = [];
|
||||
private answerInput:Setting;
|
||||
public answer:string|undefined;
|
||||
private completed = true;
|
||||
//private cancelled = false;
|
||||
|
||||
constructor(app: App) {
|
||||
super(app);
|
||||
|
|
@ -26,13 +23,15 @@ export class AskModal extends Modal {
|
|||
this.answer = undefined;
|
||||
this.options = options ?? [];
|
||||
|
||||
this.completed = false;
|
||||
await new Promise<void>((resolve) => {
|
||||
|
||||
this.open();
|
||||
|
||||
while(!this.completed){
|
||||
await Utils.delay(250);
|
||||
this.onClose = () => {
|
||||
this.contentEl.empty();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
return this.answer;
|
||||
}
|
||||
|
|
@ -60,7 +59,7 @@ export class AskModal extends Modal {
|
|||
if (ev.key == 'Enter'){
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.answer = answer;
|
||||
this.answer = answer ?? '';
|
||||
this.close();
|
||||
}
|
||||
})
|
||||
|
|
@ -74,7 +73,7 @@ export class AskModal extends Modal {
|
|||
cb
|
||||
.setButtonText('OK')
|
||||
.onClick( ev => {
|
||||
this.answer = answer;
|
||||
this.answer = answer ?? '';
|
||||
this.close();
|
||||
})
|
||||
;
|
||||
|
|
@ -82,9 +81,4 @@ export class AskModal extends Modal {
|
|||
;
|
||||
}
|
||||
|
||||
override onClose() {
|
||||
const { contentEl } = this;
|
||||
this.completed = true;
|
||||
contentEl.empty();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
import { App, Modal } from "obsidian";
|
||||
import { Utils } from "src/utils";
|
||||
|
||||
export class MessageModal extends Modal {
|
||||
|
||||
private message:string;
|
||||
private closed = true;
|
||||
|
||||
constructor(app: App) {
|
||||
super(app);
|
||||
|
|
@ -18,13 +16,16 @@ export class MessageModal extends Modal {
|
|||
this.titleEl.setText( title );
|
||||
|
||||
this.message = message;
|
||||
this.closed = false;
|
||||
|
||||
await new Promise<void>((resolve) => {
|
||||
|
||||
this.open();
|
||||
|
||||
while(!this.closed){
|
||||
await Utils.delay(250);
|
||||
this.onClose = () => {
|
||||
this.contentEl.empty();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -34,9 +35,4 @@ export class MessageModal extends Modal {
|
|||
contentEl.innerHTML = formattedLines;
|
||||
}
|
||||
|
||||
onClose() {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
this.closed = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,8 +12,8 @@ export class Parser {
|
|||
const result: NamedCodeBlock[] = [];
|
||||
|
||||
const file = view.file;
|
||||
const fileContent = await app.vault.read(file);
|
||||
const fileCache = app.metadataCache.getFileCache( file );
|
||||
const fileContent = await view.app.vault.read(file);
|
||||
const fileCache = view.app.metadataCache.getFileCache( file );
|
||||
|
||||
if ( fileCache == null ){
|
||||
console.debug('Parser::fetchCodeBlocks, fileCache is null');
|
||||
|
|
@ -214,8 +214,8 @@ export class Parser {
|
|||
} = {};
|
||||
|
||||
const file = view.file;
|
||||
const fileContent = await app.vault.read(file);
|
||||
const fileCache = app.metadataCache.getFileCache( file );
|
||||
const fileContent = await view.app.vault.read(file);
|
||||
const fileCache = view.app.metadataCache.getFileCache( file );
|
||||
|
||||
if ( fileCache == null ){
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { normalizePath, TFile } from "obsidian";
|
||||
import { normalizePath, TFile, Vault, Workspace } from "obsidian";
|
||||
import { EXTENSION_MIMETYPE_MAP } from "./constants";
|
||||
import { DataSet, IDataSetCollection } from "./data-set";
|
||||
import { NamedCodeBlock } from "./named-code-block";
|
||||
|
|
@ -9,18 +9,22 @@ import { Utils } from "./utils";
|
|||
|
||||
export class IoRunContextImplemention implements TIoRunContext {
|
||||
|
||||
private vault: Vault;
|
||||
private workspace: Workspace;
|
||||
private log: RunLogger;
|
||||
private data:IDataSetCollection;
|
||||
private consumableBlocks:NamedCodeBlock[]
|
||||
|
||||
constructor( log: RunLogger, data:IDataSetCollection, consumableBlocks:NamedCodeBlock[] ){
|
||||
constructor( vault:Vault, workspace:Workspace, log: RunLogger, data:IDataSetCollection, consumableBlocks:NamedCodeBlock[] ){
|
||||
this.vault = vault;
|
||||
this.workspace = workspace;
|
||||
this.log = log;
|
||||
this.data = data;
|
||||
this.consumableBlocks = consumableBlocks;
|
||||
}
|
||||
|
||||
private getAbsoluteFilepathFromActiveFile( path:string ) : string | undefined {
|
||||
const activeFile = app.workspace.getActiveFile();
|
||||
const activeFile = this.workspace.getActiveFile();
|
||||
if (activeFile == null){
|
||||
return;
|
||||
}
|
||||
|
|
@ -35,12 +39,12 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
return resultDataSet;
|
||||
}
|
||||
|
||||
const file = app.vault.getAbstractFileByPath(absFilepath);
|
||||
const file = this.vault.getAbstractFileByPath(absFilepath);
|
||||
|
||||
const pzr = new Parser();
|
||||
if (file instanceof TFile){
|
||||
if (file.extension == 'csv'){
|
||||
const csvdata = await app.vault.read( file );
|
||||
const csvdata = await this.vault.read( file );
|
||||
resultDataSet = pzr.loadCsv(csvdata);
|
||||
this.data[name??file.basename] = resultDataSet;
|
||||
}
|
||||
|
|
@ -56,7 +60,7 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
return false;
|
||||
}
|
||||
|
||||
const file = app.vault.getAbstractFileByPath(absFilepath);
|
||||
const file = this.vault.getAbstractFileByPath(absFilepath);
|
||||
|
||||
if (!(file instanceof TFile)){
|
||||
await this.log.error(`import::File not found: "${path}"`);
|
||||
|
|
@ -64,7 +68,7 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
}
|
||||
|
||||
if ( file.extension == 'md' ){
|
||||
const content = await app.vault.read( file );
|
||||
const content = await this.vault.read( file );
|
||||
const pzr = new Parser();
|
||||
pzr.applyMarkdownContent(
|
||||
file.basename,
|
||||
|
|
@ -82,13 +86,13 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
async load(path: string): Promise<string | undefined> {
|
||||
const filepath = Utils.getSameFolderFilepath(path);
|
||||
|
||||
const af = app.vault.getAbstractFileByPath(filepath);
|
||||
const af = this.vault.getAbstractFileByPath(filepath);
|
||||
|
||||
if (!(af instanceof TFile)){
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return await app.vault.read(af)
|
||||
return await this.vault.read(af)
|
||||
}
|
||||
|
||||
async load_data(path: string, name?: string | undefined): Promise<DataSet> {
|
||||
|
|
@ -98,7 +102,7 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
async load_data_url(path: string, mimetype?: string | undefined): Promise<string | undefined> {
|
||||
const filepath = Utils.getSameFolderFilepath(path);
|
||||
|
||||
const af = app.vault.getAbstractFileByPath(filepath);
|
||||
const af = this.vault.getAbstractFileByPath(filepath);
|
||||
|
||||
if (!(af instanceof TFile)){
|
||||
return Promise.resolve(undefined);
|
||||
|
|
@ -109,7 +113,7 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
?? ''
|
||||
;
|
||||
|
||||
const base64Data = Utils.toBase64( await app.vault.readBinary(af) );
|
||||
const base64Data = Utils.toBase64( await this.vault.readBinary(af) );
|
||||
|
||||
return `data:${finalMimeType};base64,${base64Data}`;
|
||||
}
|
||||
|
|
@ -117,28 +121,28 @@ export class IoRunContextImplemention implements TIoRunContext {
|
|||
async output(file: string, content: string, open?: boolean | undefined): Promise<void> {
|
||||
const newFilepath = Utils.getSameFolderFilepath(file);
|
||||
|
||||
const af = app.vault.getAbstractFileByPath(newFilepath);
|
||||
const af = this.vault.getAbstractFileByPath(newFilepath);
|
||||
if (af instanceof TFile){
|
||||
await app.vault.trash(af, false);
|
||||
await this.vault.trash(af, false);
|
||||
}
|
||||
|
||||
await app.vault.create( newFilepath, content );
|
||||
await this.vault.create( newFilepath, content );
|
||||
|
||||
//new Notice(`${newFilepath} created`);
|
||||
if (open == true){
|
||||
await app.workspace.openLinkText( newFilepath, '' );
|
||||
await this.workspace.openLinkText( newFilepath, '' );
|
||||
}
|
||||
}
|
||||
|
||||
async open(linktext: string): Promise<void> {
|
||||
await app.workspace.openLinkText( linktext, '' );
|
||||
await this.workspace.openLinkText( linktext, '' );
|
||||
}
|
||||
|
||||
async delete(path: string): Promise<void> {
|
||||
const filepath = Utils.getSameFolderFilepath(path);
|
||||
const af = app.vault.getAbstractFileByPath(filepath);
|
||||
const af = this.vault.getAbstractFileByPath(filepath);
|
||||
if (af instanceof TFile){
|
||||
await app.vault.trash(af, false);
|
||||
await this.vault.trash(af, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { TFile } from "obsidian";
|
||||
import { TFile, Vault } from "obsidian";
|
||||
import { MarkerChange, MarkerValue, TMarkerRunContext } from "./run-context";
|
||||
import { RunLogger } from "./run-logger";
|
||||
|
||||
|
|
@ -10,7 +10,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
|
|||
private markerEndPrefix = '%%=';
|
||||
private markerEndSuffix = '%%'
|
||||
|
||||
|
||||
private vault: Vault;
|
||||
private log: RunLogger;
|
||||
|
||||
private currentPath: string;
|
||||
|
|
@ -18,7 +18,8 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
|
|||
|
||||
private newValues = new Map<string,string|null>();
|
||||
|
||||
constructor( log: RunLogger, currentPath:string ){
|
||||
constructor( vault:Vault, log: RunLogger, currentPath:string ){
|
||||
this.vault = vault;
|
||||
this.log = log;
|
||||
this.currentPath = currentPath;
|
||||
this.targetPath = currentPath;
|
||||
|
|
@ -47,7 +48,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
|
|||
}
|
||||
|
||||
private getTargetFileOrThrow(): TFile{
|
||||
const targetFile = app.vault.getAbstractFileByPath( this.targetPath );
|
||||
const targetFile = this.vault.getAbstractFileByPath( this.targetPath );
|
||||
|
||||
if (!(targetFile instanceof TFile)){
|
||||
throw new Error(`Target file path was not found. '${this.targetPath}'`);
|
||||
|
|
@ -57,7 +58,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
|
|||
|
||||
private async getTargetContents() : Promise<string>{
|
||||
const targetFile = this.getTargetFileOrThrow();
|
||||
return await app.vault.read( targetFile );
|
||||
return await this.vault.read( targetFile );
|
||||
}
|
||||
|
||||
async fetch(): Promise<MarkerValue[]> {
|
||||
|
|
@ -159,7 +160,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
|
|||
//console.debug({targetFileContent});
|
||||
const targetFile = this.getTargetFileOrThrow();
|
||||
|
||||
await app.vault.modify( targetFile, targetFileContent );
|
||||
await this.vault.modify( targetFile, targetFileContent );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import { TFile } from "obsidian";
|
||||
import { TFile, Vault } from "obsidian";
|
||||
import { Utils } from "src/utils";
|
||||
|
||||
export class RunLogger {
|
||||
|
||||
private vault:Vault;
|
||||
private file: TFile|undefined;
|
||||
|
||||
constructor( vault:Vault ){
|
||||
this.vault = vault;
|
||||
}
|
||||
|
||||
private console_info( ...params: any[] ){
|
||||
window.console.info( 'meld-build', ...params );
|
||||
}
|
||||
|
|
@ -53,7 +58,7 @@ export class RunLogger {
|
|||
|
||||
logLine += '\n';
|
||||
|
||||
await app.vault.append( this.file, logLine );
|
||||
await this.vault.append( this.file, logLine );
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -65,14 +70,14 @@ export class RunLogger {
|
|||
|
||||
const filepath = Utils.getSameFolderFilepath(filename);
|
||||
|
||||
const af = app.vault.getAbstractFileByPath(filepath);
|
||||
const af = this.vault.getAbstractFileByPath(filepath);
|
||||
if ( af instanceof TFile ){
|
||||
this.file = af;
|
||||
if ( clear == true ){
|
||||
app.vault.modify( this.file, '' );
|
||||
this.vault.modify( this.file, '' );
|
||||
}
|
||||
}else{
|
||||
this.file = await app.vault.create( filepath, '' );
|
||||
this.file = await this.vault.create( filepath, '' );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,10 +20,6 @@ export class Utils{
|
|||
return normalizePath( parentPath + finalFilename );
|
||||
}
|
||||
|
||||
public static delay(ms: number) : Promise<()=>void> {
|
||||
return new Promise( resolve => setTimeout(resolve, ms) );
|
||||
}
|
||||
|
||||
public static toBase64( buf: ArrayBuffer ) : string {
|
||||
return arrayBufferToBase64( buf );
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue