- don't use global app instance

- remove unneeded code
- better await for modal closes
This commit is contained in:
Cleon 2023-02-04 17:08:33 +13:00
parent 24a3de716a
commit d2e0d4f7ea
10 changed files with 108 additions and 120 deletions

26
src/ToolbarButton.ts Normal file
View 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;
}
}

View file

@ -146,9 +146,19 @@ export class Compiler{
ui: new UiRunContextImplemention(), 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(), dv: dvGetAPI(),
} }

View file

@ -3,18 +3,9 @@ import * as HB from 'handlebars';
import { RunLogger } from 'src/run-logger'; import { RunLogger } from 'src/run-logger';
import { Compiler } from 'src/compiler'; import { Compiler } from 'src/compiler';
import { CODE_BLOCK_LANG_TOOLBAR, URL_HELP } from 'src/constants'; import { CODE_BLOCK_LANG_TOOLBAR, URL_HELP } from 'src/constants';
import { ToolbarButton } from './ToolbarButton';
interface MeldBuildPluginSettings {
mySetting: string;
}
const DEFAULT_SETTINGS: MeldBuildPluginSettings = {
mySetting: 'default'
}
export default class MeldBuildPlugin extends Plugin { export default class MeldBuildPlugin extends Plugin {
settings: MeldBuildPluginSettings;
private async codeblockProcessor(el: HTMLElement, ctx: MarkdownPostProcessorContext): Promise<void> { private async codeblockProcessor(el: HTMLElement, ctx: MarkdownPostProcessorContext): Promise<void> {
const els = el.querySelector('.language-js'); const els = el.querySelector('.language-js');
@ -31,8 +22,6 @@ export default class MeldBuildPlugin extends Plugin {
async onload() { async onload() {
await this.loadSettings();
await this.reloadActiveViewsWithToolbars(); await this.reloadActiveViewsWithToolbars();
this.registerHandlebarHelpers(); this.registerHandlebarHelpers();
@ -107,7 +96,7 @@ export default class MeldBuildPlugin extends Plugin {
} }
private async reloadActiveViewsWithToolbars(){ private async reloadActiveViewsWithToolbars(){
app.workspace.iterateAllLeaves( leaf =>{ this.app.workspace.iterateAllLeaves( leaf =>{
const view = leaf.view; const view = leaf.view;
if ( view instanceof MarkdownView ){ if ( view instanceof MarkdownView ){
@ -123,7 +112,7 @@ export default class MeldBuildPlugin extends Plugin {
} }
private async buildAndRunActiveView( runGroupTag?:string ){ private async buildAndRunActiveView( runGroupTag?:string ){
const view = app.workspace.getActiveViewOfType( MarkdownView ); const view = this.app.workspace.getActiveViewOfType( MarkdownView );
if (!view){ if (!view){
new Notice( 'Unable to run, no active Markdown View found' ); new Notice( 'Unable to run, no active Markdown View found' );
return; return;
@ -135,7 +124,7 @@ export default class MeldBuildPlugin extends Plugin {
if ( !( view instanceof MarkdownView ) ){ if ( !( view instanceof MarkdownView ) ){
return; return;
} }
const logger = new RunLogger(); const logger = new RunLogger( view.app.vault );
try{ try{
//await view.save(); //await view.save();
const compiler = new Compiler(); 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;
}
}

View file

@ -1,5 +1,4 @@
import { App, Modal, Setting } from "obsidian"; import { App, Modal, Setting } from "obsidian";
import { Utils } from "src/utils";
export class AskModal extends Modal { export class AskModal extends Modal {
@ -7,8 +6,6 @@ export class AskModal extends Modal {
private options:string[] = []; private options:string[] = [];
private answerInput:Setting; private answerInput:Setting;
public answer:string|undefined; public answer:string|undefined;
private completed = true;
//private cancelled = false;
constructor(app: App) { constructor(app: App) {
super(app); super(app);
@ -26,14 +23,16 @@ export class AskModal extends Modal {
this.answer = undefined; this.answer = undefined;
this.options = options ?? []; this.options = options ?? [];
this.completed = false; await new Promise<void>((resolve) => {
this.open(); this.open();
while(!this.completed){
await Utils.delay(250);
}
this.onClose = () => {
this.contentEl.empty();
resolve();
}
});
return this.answer; return this.answer;
} }
@ -60,7 +59,7 @@ export class AskModal extends Modal {
if (ev.key == 'Enter'){ if (ev.key == 'Enter'){
ev.stopPropagation(); ev.stopPropagation();
ev.preventDefault(); ev.preventDefault();
this.answer = answer; this.answer = answer ?? '';
this.close(); this.close();
} }
}) })
@ -74,17 +73,12 @@ export class AskModal extends Modal {
cb cb
.setButtonText('OK') .setButtonText('OK')
.onClick( ev => { .onClick( ev => {
this.answer = answer; this.answer = answer ?? '';
this.close(); this.close();
}) })
; ;
}) })
; ;
} }
override onClose() {
const { contentEl } = this;
this.completed = true;
contentEl.empty();
}
} }

View file

@ -1,10 +1,8 @@
import { App, Modal } from "obsidian"; import { App, Modal } from "obsidian";
import { Utils } from "src/utils";
export class MessageModal extends Modal { export class MessageModal extends Modal {
private message:string; private message:string;
private closed = true;
constructor(app: App) { constructor(app: App) {
super(app); super(app);
@ -18,14 +16,17 @@ export class MessageModal extends Modal {
this.titleEl.setText( title ); this.titleEl.setText( title );
this.message = message; this.message = message;
this.closed = false;
this.open();
while(!this.closed){
await Utils.delay(250);
}
await new Promise<void>((resolve) => {
this.open();
this.onClose = () => {
this.contentEl.empty();
resolve();
}
});
} }
onOpen() { onOpen() {
@ -33,10 +34,5 @@ export class MessageModal extends Modal {
const formattedLines = this.message.split('\n').join('<br/>'); const formattedLines = this.message.split('\n').join('<br/>');
contentEl.innerHTML = formattedLines; contentEl.innerHTML = formattedLines;
} }
onClose() {
const { contentEl } = this;
contentEl.empty();
this.closed = true;
}
} }

View file

@ -12,8 +12,8 @@ export class Parser {
const result: NamedCodeBlock[] = []; const result: NamedCodeBlock[] = [];
const file = view.file; const file = view.file;
const fileContent = await app.vault.read(file); const fileContent = await view.app.vault.read(file);
const fileCache = app.metadataCache.getFileCache( file ); const fileCache = view.app.metadataCache.getFileCache( file );
if ( fileCache == null ){ if ( fileCache == null ){
console.debug('Parser::fetchCodeBlocks, fileCache is null'); console.debug('Parser::fetchCodeBlocks, fileCache is null');
@ -214,8 +214,8 @@ export class Parser {
} = {}; } = {};
const file = view.file; const file = view.file;
const fileContent = await app.vault.read(file); const fileContent = await view.app.vault.read(file);
const fileCache = app.metadataCache.getFileCache( file ); const fileCache = view.app.metadataCache.getFileCache( file );
if ( fileCache == null ){ if ( fileCache == null ){
return result; return result;

View file

@ -1,4 +1,4 @@
import { normalizePath, TFile } from "obsidian"; import { normalizePath, TFile, Vault, Workspace } from "obsidian";
import { EXTENSION_MIMETYPE_MAP } from "./constants"; import { EXTENSION_MIMETYPE_MAP } from "./constants";
import { DataSet, IDataSetCollection } from "./data-set"; import { DataSet, IDataSetCollection } from "./data-set";
import { NamedCodeBlock } from "./named-code-block"; import { NamedCodeBlock } from "./named-code-block";
@ -9,18 +9,22 @@ import { Utils } from "./utils";
export class IoRunContextImplemention implements TIoRunContext { export class IoRunContextImplemention implements TIoRunContext {
private vault: Vault;
private workspace: Workspace;
private log: RunLogger; private log: RunLogger;
private data:IDataSetCollection; private data:IDataSetCollection;
private consumableBlocks:NamedCodeBlock[] 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.log = log;
this.data = data; this.data = data;
this.consumableBlocks = consumableBlocks; this.consumableBlocks = consumableBlocks;
} }
private getAbsoluteFilepathFromActiveFile( path:string ) : string | undefined { private getAbsoluteFilepathFromActiveFile( path:string ) : string | undefined {
const activeFile = app.workspace.getActiveFile(); const activeFile = this.workspace.getActiveFile();
if (activeFile == null){ if (activeFile == null){
return; return;
} }
@ -35,12 +39,12 @@ export class IoRunContextImplemention implements TIoRunContext {
return resultDataSet; return resultDataSet;
} }
const file = app.vault.getAbstractFileByPath(absFilepath); const file = this.vault.getAbstractFileByPath(absFilepath);
const pzr = new Parser(); const pzr = new Parser();
if (file instanceof TFile){ if (file instanceof TFile){
if (file.extension == 'csv'){ if (file.extension == 'csv'){
const csvdata = await app.vault.read( file ); const csvdata = await this.vault.read( file );
resultDataSet = pzr.loadCsv(csvdata); resultDataSet = pzr.loadCsv(csvdata);
this.data[name??file.basename] = resultDataSet; this.data[name??file.basename] = resultDataSet;
} }
@ -56,7 +60,7 @@ export class IoRunContextImplemention implements TIoRunContext {
return false; return false;
} }
const file = app.vault.getAbstractFileByPath(absFilepath); const file = this.vault.getAbstractFileByPath(absFilepath);
if (!(file instanceof TFile)){ if (!(file instanceof TFile)){
await this.log.error(`import::File not found: "${path}"`); await this.log.error(`import::File not found: "${path}"`);
@ -64,7 +68,7 @@ export class IoRunContextImplemention implements TIoRunContext {
} }
if ( file.extension == 'md' ){ if ( file.extension == 'md' ){
const content = await app.vault.read( file ); const content = await this.vault.read( file );
const pzr = new Parser(); const pzr = new Parser();
pzr.applyMarkdownContent( pzr.applyMarkdownContent(
file.basename, file.basename,
@ -82,13 +86,13 @@ export class IoRunContextImplemention implements TIoRunContext {
async load(path: string): Promise<string | undefined> { async load(path: string): Promise<string | undefined> {
const filepath = Utils.getSameFolderFilepath(path); const filepath = Utils.getSameFolderFilepath(path);
const af = app.vault.getAbstractFileByPath(filepath); const af = this.vault.getAbstractFileByPath(filepath);
if (!(af instanceof TFile)){ if (!(af instanceof TFile)){
return undefined; return undefined;
} }
return await app.vault.read(af) return await this.vault.read(af)
} }
async load_data(path: string, name?: string | undefined): Promise<DataSet> { 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> { async load_data_url(path: string, mimetype?: string | undefined): Promise<string | undefined> {
const filepath = Utils.getSameFolderFilepath(path); const filepath = Utils.getSameFolderFilepath(path);
const af = app.vault.getAbstractFileByPath(filepath); const af = this.vault.getAbstractFileByPath(filepath);
if (!(af instanceof TFile)){ if (!(af instanceof TFile)){
return Promise.resolve(undefined); 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}`; 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> { async output(file: string, content: string, open?: boolean | undefined): Promise<void> {
const newFilepath = Utils.getSameFolderFilepath(file); const newFilepath = Utils.getSameFolderFilepath(file);
const af = app.vault.getAbstractFileByPath(newFilepath); const af = this.vault.getAbstractFileByPath(newFilepath);
if (af instanceof TFile){ 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`); //new Notice(`${newFilepath} created`);
if (open == true){ if (open == true){
await app.workspace.openLinkText( newFilepath, '' ); await this.workspace.openLinkText( newFilepath, '' );
} }
} }
async open(linktext: string): Promise<void> { async open(linktext: string): Promise<void> {
await app.workspace.openLinkText( linktext, '' ); await this.workspace.openLinkText( linktext, '' );
} }
async delete(path: string): Promise<void> { async delete(path: string): Promise<void> {
const filepath = Utils.getSameFolderFilepath(path); const filepath = Utils.getSameFolderFilepath(path);
const af = app.vault.getAbstractFileByPath(filepath); const af = this.vault.getAbstractFileByPath(filepath);
if (af instanceof TFile){ if (af instanceof TFile){
await app.vault.trash(af, false); await this.vault.trash(af, false);
} }
} }

View file

@ -1,4 +1,4 @@
import { TFile } from "obsidian"; import { TFile, Vault } from "obsidian";
import { MarkerChange, MarkerValue, TMarkerRunContext } from "./run-context"; import { MarkerChange, MarkerValue, TMarkerRunContext } from "./run-context";
import { RunLogger } from "./run-logger"; import { RunLogger } from "./run-logger";
@ -10,7 +10,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
private markerEndPrefix = '%%='; private markerEndPrefix = '%%=';
private markerEndSuffix = '%%' private markerEndSuffix = '%%'
private vault: Vault;
private log: RunLogger; private log: RunLogger;
private currentPath: string; private currentPath: string;
@ -18,7 +18,8 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
private newValues = new Map<string,string|null>(); 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.log = log;
this.currentPath = currentPath; this.currentPath = currentPath;
this.targetPath = currentPath; this.targetPath = currentPath;
@ -47,7 +48,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
} }
private getTargetFileOrThrow(): TFile{ private getTargetFileOrThrow(): TFile{
const targetFile = app.vault.getAbstractFileByPath( this.targetPath ); const targetFile = this.vault.getAbstractFileByPath( this.targetPath );
if (!(targetFile instanceof TFile)){ if (!(targetFile instanceof TFile)){
throw new Error(`Target file path was not found. '${this.targetPath}'`); 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>{ private async getTargetContents() : Promise<string>{
const targetFile = this.getTargetFileOrThrow(); const targetFile = this.getTargetFileOrThrow();
return await app.vault.read( targetFile ); return await this.vault.read( targetFile );
} }
async fetch(): Promise<MarkerValue[]> { async fetch(): Promise<MarkerValue[]> {
@ -159,7 +160,7 @@ export class MarkerRunContextImplemention implements TMarkerRunContext {
//console.debug({targetFileContent}); //console.debug({targetFileContent});
const targetFile = this.getTargetFileOrThrow(); const targetFile = this.getTargetFileOrThrow();
await app.vault.modify( targetFile, targetFileContent ); await this.vault.modify( targetFile, targetFileContent );
return result; return result;
} }

View file

@ -1,10 +1,15 @@
import { TFile } from "obsidian"; import { TFile, Vault } from "obsidian";
import { Utils } from "src/utils"; import { Utils } from "src/utils";
export class RunLogger { export class RunLogger {
private vault:Vault;
private file: TFile|undefined; private file: TFile|undefined;
constructor( vault:Vault ){
this.vault = vault;
}
private console_info( ...params: any[] ){ private console_info( ...params: any[] ){
window.console.info( 'meld-build', ...params ); window.console.info( 'meld-build', ...params );
} }
@ -53,7 +58,7 @@ export class RunLogger {
logLine += '\n'; 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 filepath = Utils.getSameFolderFilepath(filename);
const af = app.vault.getAbstractFileByPath(filepath); const af = this.vault.getAbstractFileByPath(filepath);
if ( af instanceof TFile ){ if ( af instanceof TFile ){
this.file = af; this.file = af;
if ( clear == true ){ if ( clear == true ){
app.vault.modify( this.file, '' ); this.vault.modify( this.file, '' );
} }
}else{ }else{
this.file = await app.vault.create( filepath, '' ); this.file = await this.vault.create( filepath, '' );
} }
} }

View file

@ -20,10 +20,6 @@ export class Utils{
return normalizePath( parentPath + finalFilename ); return normalizePath( parentPath + finalFilename );
} }
public static delay(ms: number) : Promise<()=>void> {
return new Promise( resolve => setTimeout(resolve, ms) );
}
public static toBase64( buf: ArrayBuffer ) : string { public static toBase64( buf: ArrayBuffer ) : string {
return arrayBufferToBase64( buf ); return arrayBufferToBase64( buf );
} }