obsidian#TextFileView TypeScript Examples
The following examples show how to use
obsidian#TextFileView.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PumlView.ts From obsidian-plantuml with MIT License | 4 votes |
export class PumlView extends TextFileView {
editor: EditorView;
previewEl: HTMLElement;
sourceEl: HTMLElement;
changeModeButton: HTMLElement;
currentView: 'source' | 'preview';
plugin: PlantumlPlugin;
dispatchId = -1;
debounced: Debouncer<any>;
extensions: Extension[] = [
highlightActiveLine(),
highlightActiveLineGutter(),
highlightSelectionMatches(),
drawSelection(),
keymap.of([...defaultKeymap, indentWithTab]),
history(),
search(),
EditorView.updateListener.of(v => {
if(v.docChanged) {
this.requestSave();
this.renderPreview();
}
})
]
constructor(leaf: WorkspaceLeaf, plugin: PlantumlPlugin) {
super(leaf);
this.plugin = plugin;
this.debounced = debounce(this.plugin.getProcessor().png, this.plugin.settings.debounce * 1000, true);
this.sourceEl = this.contentEl.createDiv({cls: 'plantuml-source-view', attr: {'style': 'display: block'}});
this.previewEl = this.contentEl.createDiv({cls: 'plantuml-preview-view', attr: {'style': 'display: none'}});
const vault = (this.app.vault as any);
if (vault.getConfig("showLineNumber")) {
this.extensions.push(lineNumbers());
}
if(vault.getConfig("lineWrap")) {
this.extensions.push(EditorView.lineWrapping);
}
this.editor = new EditorView({
state: EditorState.create({
extensions: this.extensions,
doc: this.data,
}),
parent: this.sourceEl,
dispatch: syncDispatch(views.length),
});
this.dispatchId = views.push(this.editor) - 1;
}
getViewType(): string {
return VIEW_TYPE;
}
getState(): any {
return super.getState();
}
setState(state: any, result: ViewStateResult): Promise<void> {
// switch to preview mode
if (state.mode === 'preview') {
this.currentView = 'preview';
setIcon(this.changeModeButton, 'pencil');
this.changeModeButton.setAttribute('aria-label', 'Edit (Ctrl+Click to edit in new pane)');
this.previewEl.style.setProperty('display', 'block');
this.sourceEl.style.setProperty('display', 'none');
this.renderPreview();
}
// switch to source mode
else {
this.currentView = 'source';
setIcon(this.changeModeButton, 'lines-of-text');
this.changeModeButton.setAttribute('aria-label', 'Preview (Ctrl+Click to open in new pane)');
this.previewEl.style.setProperty('display', 'none');
this.sourceEl.style.setProperty('display', 'block');
//this.editor.refresh();
}
return super.setState(state, result);
}
async onload() {
// add the action to switch between source and preview mode
this.changeModeButton = this.addAction('lines-of-text', 'Preview (Ctrl+Click to open in new pane)', (evt) => this.switchMode(evt), 17);
// undocumented: Get the current default view mode to switch to
const defaultViewMode = (this.app.vault as any).getConfig('defaultViewMode');
this.currentView = defaultViewMode;
await this.setState({...this.getState(), mode: defaultViewMode}, {});
}
onunload() {
views.remove(views[this.dispatchId]);
this.editor.destroy();
}
// function to switch between source and preview mode
async switchMode(arg: 'source' | 'preview' | MouseEvent) {
let mode = arg;
// if force mode not provided, switch to opposite of current mode
if (!mode || mode instanceof MouseEvent) mode = this.currentView === 'source' ? 'preview' : 'source';
if (arg instanceof MouseEvent) {
if (Keymap.isModEvent(arg)) {
this.app.workspace.duplicateLeaf(this.leaf).then(async () => {
const viewState = this.app.workspace.activeLeaf?.getViewState();
if (viewState) {
viewState.state = {...viewState.state, mode: mode};
await this.app.workspace.activeLeaf?.setViewState(viewState);
}
});
} else {
await this.setState({...this.getState(), mode: mode}, {});
}
}
}
// get the data for save
getViewData() : string {
return this.editor.state.sliceDoc();
}
// load the data into the view
async setViewData(data: string, clear: boolean) {
this.data = data;
if (clear) {
this.editor.setState(EditorState.create({
doc: data,
extensions: this.extensions
}));
}else {
this.editor.dispatch({
changes: {
from: 0,
to: this.editor.state.doc.length,
insert: data,
}
})
}
// if we're in preview view, also render that
if (this.currentView === 'preview') this.renderPreview();
}
// clear the editor, etc
clear() {
this.previewEl.empty();
this.data = null;
}
getDisplayText() {
if (this.file) return this.file.basename;
else return "PlantUML (no file)";
}
canAcceptExtension(extension: string) {
return extension == 'puml';
}
getIcon() {
return "document-plantuml";
}
async renderPreview() {
if(this.currentView !== "preview") return;
this.previewEl.empty();
const loadingHeader = this.previewEl.createEl("h1", {text: "Loading"});
const previewDiv = this.previewEl.createDiv();
this.debounced(this.getViewData(), previewDiv, null);
loadingHeader.remove();
}
}