diff --git a/src/adocNewFileModal.ts b/src/adocNewFileModal.ts
index b3c9a1b..c6341f6 100644
--- a/src/adocNewFileModal.ts
+++ b/src/adocNewFileModal.ts
@@ -1,6 +1,5 @@
import {
ButtonComponent,
- DropdownComponent,
Modal,
normalizePath,
Notice,
@@ -10,12 +9,14 @@ import {
TFolder
} from "obsidian";
+import AsciidocPlugin from "./main"
+
export class AdocNewFileModal extends Modal {
fileName = "new_name";
ext = "adoc";
parent: TAbstractFile;
- constructor(private plugin: CodeFilesPlugin, parent?: TAbstractFile) {
+ constructor(private plugin: AsciidocPlugin, parent?: TAbstractFile) {
super(plugin.app);
this.parent = parent ?? this.plugin.app.vault.getRoot();
}
@@ -38,7 +39,7 @@ export class AdocNewFileModal extends Modal {
submitButton.setButtonText("Create");
submitButton.onClick(() => this.complete());
- fileName.inputEl.focus();
+ pathInput.inputEl.focus();
}
async complete() {
diff --git a/src/asciidocView.ts b/src/asciidocView.ts
new file mode 100644
index 0000000..638be0c
--- /dev/null
+++ b/src/asciidocView.ts
@@ -0,0 +1,296 @@
+import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, TextFileView, TFile } from 'obsidian';
+import { ItemView, ViewStateResult, WorkspaceLeaf } from 'obsidian';
+import { Component, editorInfoField } from 'obsidian';
+
+import AsciidocPlugin from "./main"
+
+import asciidoctor from 'asciidoctor'
+
+import Mark from 'mark.js'
+
+export const ASCIIDOC_EDITOR_VIEW = "asciidoc-editor-view";
+
+import "codemirror-asciidoc"
+import CodeMirror from 'codemirror'
+
+import 'codemirror/addon/selection/active-line.js'
+import 'codemirror/addon/display/fullscreen.js'
+import 'codemirror/addon/display/fullscreen.css'
+import 'codemirror/addon/selection/mark-selection.js'
+import 'codemirror/addon/search/searchcursor.js'
+import 'codemirror/addon/search/search.js'
+import 'codemirror/addon/scroll/annotatescrollbar.js'
+import 'codemirror/addon/search/matchesonscrollbar.js'
+import 'codemirror/addon/dialog/dialog.js'
+import 'codemirror/addon/hint/show-hint.js'
+import 'codemirror/addon/fold/foldcode.js'
+import 'codemirror/addon/fold/foldgutter.js'
+import 'codemirror/addon/fold/foldgutter.css'
+
+//import 'codemirror/lib/codemirror.css'
+
+function isValidUrl(str: string): boolean {
+ let url;
+ try {
+ url = new URL(str);
+ } catch (_) {
+ return false;
+ }
+ return true
+}
+
+function deleteChildNodes(el: any) {
+ while (el.hasChildNodes())
+ el.removeChild(el.children[0]);
+}
+
+let isEditMode = true;
+
+export class AsciidocView extends TextFileView {
+ private pageData: string; //TODO: for view-only mode
+ private plugin: AsciidocPlugin;
+ private div: any;
+ private options: any;
+ private adoc: any;
+ private cm: any;
+ private mark: any;
+ private isSearchActive: boolean;
+
+ constructor(plugin: AsciidocPlugin, leaf: WorkspaceLeaf) {
+ super(leaf);
+ this.plugin = plugin;
+ this.div = null;
+ this.isSearchActive = false;
+ console.log("CONSTRUCTOR")
+
+ // For viewer mode
+ this.adoc = asciidoctor();
+ this.options = {
+ standalone: false,
+ safe: 'safe',
+ attributes: { 'showtitle': true, 'icons': 'font' }
+ };
+ this.mark = null;
+
+ let tmp = document.createElement("div");
+ // @ts-ignore
+ this.cm = CodeMirror(tmp,
+ {
+ tabSize: 2,
+ mode: "asciidoc",
+ lineNumbers: true,
+ lineWrapping: true,
+ // @ts-ignore
+ line: true,
+ styleActiveLine: true,
+ highlightSelectionMatches: {
+ annotateScrollbar: true
+ },
+ viewportMargin: 2,
+ inputStyle: 'contenteditable',
+ allowDropFileTypes: ['image/jpg', 'image/png', 'image/svg', 'image/jpeg', 'image/gif'],
+ gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
+ })
+
+ this.addAction("book-open", "preview/editor mode", (evt: MouseEvent ) => { this.changeViewMode() });
+ }
+
+ changeViewMode() {
+ isEditMode = !isEditMode;
+ console.log("change edit mode ", isEditMode);
+ deleteChildNodes(this.div);
+ this.isSearchActive = false;
+ this.renderCurrentMode();
+ }
+
+ renderCurrentMode() {
+ if (!this.div) {
+ console.log("SHOULD NOT REACH");
+ }
+
+ if (isEditMode) {
+ console.log("render editor");
+ this.div.appendChild(this.cm.getWrapperElement());
+ this.cm.refresh();
+ } else {
+ console.log("render viewer");
+ this.div.appendChild(this.renderViewerMode());
+ }
+ }
+
+ renderViewerMode() {
+ let contents = this.cm.getValue();
+ let htmlStr = this.adoc.convert(contents, this.options);
+
+ let parser = new window.DOMParser();
+ let dom = document.createElement("div");
+
+ dom.innerHTML = htmlStr;
+ let collection = dom.getElementsByTagName("a");
+
+ while (collection.length > 0) {
+ let item = collection[0];
+
+ let txt = item.getText().trim();
+ let cls = "cm-hmd-internal-link";
+ if (isValidUrl(txt)) {
+ cls = "cm-url";
+ }
+ let s = ` ${txt} `;
+ let div = document.createElement('div');
+ div.innerHTML = s;
+ if (item.parentNode) {
+ item.parentNode.replaceChild(div, item);
+ }
+
+ div.onclick = () => {
+ console.log(`CLICK ${txt}`);
+ this.app.workspace.openLinkText(txt, '', false);
+ }
+ }
+ this.mark = new Mark(dom);
+ return dom;
+ }
+
+ renderSearchDialog() {
+ let cm = this.cm;
+
+ let searchDialog = '' + cm.phrase("Search:") + ' ';
+
+ let item = document.createElement("div");
+ item.className = "CodeMirror-dialog-top";
+ item.innerHTML = searchDialog;
+
+ let root = document.createElement("div");
+ root.className = "CodeMirror-dialog";
+ root.innerHTML = item.outerHTML;
+ this.div.insertBefore(root, this.div.children[0])
+
+ let collection = root.getElementsByTagName("input");
+ collection[0].focus();
+
+ collection[0].addEventListener("keyup", (e: KeyboardEvent) => {
+ if (e.keyCode == 13)
+ this.doSearch(collection[0].value);
+ }, true)
+
+ this.isSearchActive = true;
+ }
+
+ doSearch(val: string) {
+ this.mark.unmark();
+ this.mark.mark(val, { separateWordSearch: false } );
+ let elements = this.div.getElementsByTagName("mark");
+ if (elements.length)
+ elements[0].scrollIntoView();
+ }
+
+ async onOpen() {
+ await super.onOpen();
+ }
+
+ async onLoadFile(file: TFile) {
+ console.log("onLoadFile", isEditMode);
+
+ if (this.div == null)
+ this.div = this.contentEl.createEl("div", { cls: "adoc-view" });
+
+ this.renderCurrentMode()
+ this.addKeyEvents();
+ await super.onLoadFile(file);
+ }
+
+ async onUnloadFile(file: TFile) {
+ console.log("onUnloadFile ", isEditMode)
+ window.removeEventListener('keydown', this.keyHandle, true);
+ await super.onUnloadFile(file);
+ deleteChildNodes(this.div);
+ }
+
+ async onClose() {
+ await super.onClose();
+ console.log("onClose")
+ }
+
+ onResize() {
+ }
+
+ getContext(file?: TFile) {
+ return file?.path ?? this.file?.path;
+ }
+
+ getViewType() {
+ return ASCIIDOC_EDITOR_VIEW;
+ }
+
+ getViewData = () => {
+ return this.cm.getValue();
+ }
+
+ setViewData = (data: string, clear: boolean) => {
+ console.log(`setViewData ${clear} buf = ${data.substr(0, 10)}`)
+ this.pageData = data;
+ this.cm.setValue(data)
+ if (isEditMode)
+ this.cm.refresh();
+ if (clear) {
+ if (!isEditMode) {
+ deleteChildNodes(this.div);
+ this.div.appendChild(this.renderViewerMode());
+ }
+ }
+ }
+
+ clear = () => {
+ this.cm.setValue("")
+ }
+
+ addKeyEvents() {
+ window.addEventListener('keydown', this.keyHandle, true);
+ }
+
+ private keyHandle = (event: KeyboardEvent) => {
+ if (app.workspace.activeLeaf != this.leaf)
+ return;
+
+ type myCallback = () => void;
+ const ctrlMap = new Map([
+ /* "f" */ [70, () => { this.commandFind() } ],
+ /* "e" */ [69, () => { this.changeViewMode() } ],
+
+ ]);
+ if (event.ctrlKey) {
+ const cb = ctrlMap.get(event.keyCode);
+ if (cb)
+ cb()
+ } else if (event.key == 'Escape') {
+ this.commandEsc()
+ }
+ }
+
+ commandFind() {
+ if (isEditMode) {
+ CodeMirror.commands.find(this.cm);
+ } else {
+ if (this.isSearchActive) {
+ let collection = this.div.getElementsByTagName("input");
+ if (collection.length)
+ collection[0].focus();
+ return;
+ }
+ this.renderSearchDialog();
+ }
+ }
+
+ commandEsc() {
+ console.log('esc')
+ if (isEditMode)
+ return;
+ if (!this.isSearchActive)
+ return;
+
+ this.div.removeChild(this.div.children[0]);
+ this.isSearchActive = false;
+ }
+}
+
diff --git a/src/main.ts b/src/main.ts
index 3f07f0d..f869a4f 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,301 +1,7 @@
-import { App, Editor, MarkdownView, Modal, Notice, Plugin, PluginSettingTab, Setting, TextFileView, TFile } from 'obsidian';
-import { ItemView, ViewStateResult, WorkspaceLeaf } from 'obsidian';
-import { Component, editorInfoField } from 'obsidian';
+import { App, Plugin, TFile, PluginSettingTab, Setting, Menu, MenuItem } from 'obsidian';
import { AdocNewFileModal } from './adocNewFileModal';
-import asciidoctor from 'asciidoctor'
-
-import Mark from 'mark.js'
-
-export const ASCIIDOC_EDITOR_VIEW = "asciidoc-editor-view";
-
-import "codemirror-asciidoc"
-import CodeMirror from 'codemirror'
-
-import 'codemirror/addon/selection/active-line.js'
-import 'codemirror/addon/display/fullscreen.js'
-import 'codemirror/addon/display/fullscreen.css'
-import 'codemirror/addon/selection/mark-selection.js'
-import 'codemirror/addon/search/searchcursor.js'
-import 'codemirror/addon/search/search.js'
-import 'codemirror/addon/scroll/annotatescrollbar.js'
-import 'codemirror/addon/search/matchesonscrollbar.js'
-import 'codemirror/addon/dialog/dialog.js'
-import 'codemirror/addon/hint/show-hint.js'
-import 'codemirror/addon/fold/foldcode.js'
-import 'codemirror/addon/fold/foldgutter.js'
-import 'codemirror/addon/fold/foldgutter.css'
-
-//import 'codemirror/lib/codemirror.css'
-
-function isValidUrl(str: string): boolean {
- let url;
- try {
- url = new URL(str);
- } catch (_) {
- return false;
- }
- return true
-}
-
-function deleteChildNodes(el: any) {
- while (el.hasChildNodes())
- el.removeChild(el.children[0]);
- }
-
-let isEditMode = true;
-
-export class AsciidocView extends TextFileView {
- private pageData: string; //TODO: for view-only mode
- private plugin: AsciidocPlugin;
- private div: any;
- private options: any;
- private adoc: any;
- private cm: any;
- private mark: any;
- private isSearchActive: boolean;
- private leaf: WorkspaceLeaf;
-
- constructor(plugin: AsciidocPlugin, leaf: WorkspaceLeaf) {
- super(leaf);
- this.leaf = leaf;
- this.plugin = plugin;
- this.div = null;
- this.isSearchActive = false;
- console.log("CONSTRUCTOR")
-
- // For viewer mode
- this.adoc = asciidoctor();
- this.options = {
- standalone: false,
- safe: 'safe',
- attributes: { 'showtitle': true, 'icons': 'font' }
- };
- this.mark = null;
-
- let tmp = document.createElement("div");
- // @ts-ignore
- this.cm = CodeMirror(tmp,
- {
- tabSize: 2,
- mode: "asciidoc",
- lineNumbers: true,
- lineWrapping: true,
- // @ts-ignore
- line: true,
- styleActiveLine: true,
- highlightSelectionMatches: {
- annotateScrollbar: true
- },
- viewportMargin: 2,
- inputStyle: 'contenteditable',
- allowDropFileTypes: ['image/jpg', 'image/png', 'image/svg', 'image/jpeg', 'image/gif'],
- gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter']
- })
-
- this.addAction("book-open", "preview/editor mode", (evt :MouseEvent ) => { this.changeViewMode() });
- }
-
- changeViewMode() {
- isEditMode = !isEditMode;
- console.log("change edit mode ", isEditMode);
- deleteChildNodes(this.div);
- this.isSearchActive = false;
- this.renderCurrentMode();
- }
-
- renderCurrentMode() {
- if (!this.div) {
- console.log("SHOULD NOT REACH");
- }
-
- if (isEditMode) {
- console.log("render editor");
- this.div.appendChild(this.cm.getWrapperElement());
- this.cm.refresh();
- } else {
- console.log("render viewer");
- this.div.appendChild(this.renderViewerMode());
- }
- }
-
- renderViewerMode() {
- let contents = this.cm.getValue();
- let htmlStr = this.adoc.convert(contents, this.options);
-
- let parser = new window.DOMParser();
- let dom = document.createElement("div");
-
- dom.innerHTML = htmlStr;
- let collection = dom.getElementsByTagName("a");
-
- while (collection.length > 0) {
- let item = collection[0];
-
- let txt = item.getText().trim();
- let cls = "cm-hmd-internal-link";
- if (isValidUrl(txt)) {
- cls = "cm-url";
- }
- let s = ` ${txt} `;
- let div = document.createElement('div');
- div.innerHTML = s;
- if (item.parentNode) {
- item.parentNode.replaceChild(div, item);
- }
-
- div.onclick = () => {
- console.log(`CLICK ${txt}`);
- this.app.workspace.openLinkText(txt, '', false);
- }
- }
- this.mark = new Mark(dom);
- return dom;
- }
-
- renderSearchDialog() {
- let cm = this.cm;
-
- let searchDialog = '' + cm.phrase("Search:") + ' ';
-
- let item = document.createElement("div");
- item.className = "CodeMirror-dialog-top";
- item.innerHTML = searchDialog;
-
- let root = document.createElement("div");
- root.className = "CodeMirror-dialog";
- root.innerHTML = item.outerHTML;
- this.div.insertBefore(root, this.div.children[0])
-
- let collection = root.getElementsByTagName("input");
- collection[0].focus();
-
- collection[0].addEventListener("keyup", (e: KeyboardEvent) => {
- if (e.keyCode == 13)
- this.doSearch(collection[0].value);
- }, true)
-
- this.isSearchActive = true;
- }
-
- doSearch(val: string) {
- this.mark.unmark();
- this.mark.mark(val, { separateWordSearch: false } );
- let elements = this.div.getElementsByTagName("mark");
- if (elements.length)
- elements[0].scrollIntoView();
- }
-
- async onOpen() {
- await super.onOpen();
- }
-
- async onLoadFile(file: TFile) {
- console.log("onLoadFile", isEditMode);
-
- if (this.div == null)
- this.div = this.contentEl.createEl("div", { cls: "adoc-view" });
-
- this.renderCurrentMode()
- this.addKeyEvents();
- await super.onLoadFile(file);
- }
-
- async onUnloadFile(file: TFile) {
- console.log("onUnloadFile ", isEditMode)
- window.removeEventListener('keydown', this.keyHandle, true);
- await super.onUnloadFile(file);
- deleteChildNodes(this.div);
- }
-
- async onClose() {
- await super.onClose();
- console.log("onClose")
- }
-
- onResize() {
- }
-
- getContext(file?: TFile) {
- return file?.path ?? this.file?.path;
- }
-
- getViewType() {
- return ASCIIDOC_EDITOR_VIEW;
- }
-
- getViewData = () => {
- return this.cm.getValue();
- }
-
- setViewData = (data: string, clear: boolean) => {
- console.log(`setViewData ${clear} buf = ${data.substr(0, 10)}`)
- this.pageData = data;
- this.cm.setValue(data)
- if (isEditMode)
- this.cm.refresh();
- if (clear) {
- if (!isEditMode) {
- deleteChildNodes(this.div);
- this.div.appendChild(this.renderViewerMode());
- }
- }
- }
-
- clear = () => {
- this.cm.setValue("")
- }
-
- addKeyEvents() {
- window.addEventListener('keydown', this.keyHandle, true);
- }
-
- private keyHandle = (event: KeyboardEvent) => {
- if (app.workspace.activeLeaf != this.leaf)
- return;
-
- type myCallback = () => void;
- const ctrlMap = new Map([
- /* "f" */ [70, () => { this.commandFind() } ],
- /* "e" */ [69, () => { this.changeViewMode() } ],
-
- ]);
- if (event.ctrlKey) {
- const cb = ctrlMap.get(event.keyCode);
- if (cb)
- cb()
- } else if (event.key == 'Escape') {
- this.commandEsc()
- }
- }
-
- commandFind() {
- if (isEditMode) {
- CodeMirror.commands.find(this.cm);
- } else {
- if (this.isSearchActive) {
- let collection = this.div.getElementsByTagName("input");
- if (collection.length)
- collection[0].focus();
- return;
- }
- this.renderSearchDialog();
- }
- }
-
- commandEsc() {
- console.log('esc')
- if (isEditMode)
- return;
- if (!this.isSearchActive)
- return;
-
- this.div.removeChild(this.div.children[0]);
- this.isSearchActive = false;
- }
-}
-
-// Remember to rename these classes and interfaces!
+import { AsciidocView, ASCIIDOC_EDITOR_VIEW } from './asciidocView';
interface MyPluginSettings {
mySetting: string;
@@ -328,8 +34,8 @@ export default class AsciidocPlugin extends Plugin {
statusBarItemEl.setText('Status Bar Text');
this.registerEvent(
- this.app.workspace.on("file-menu", (menu, file) => {
- menu.addItem((item) => {
+ this.app.workspace.on("file-menu", (menu: Menu, file: TFile) => {
+ menu.addItem((item: MenuItem) => {
item
.setTitle("New asciidoc file")
.setIcon("scroll-text")
@@ -353,16 +59,6 @@ export default class AsciidocPlugin extends Plugin {
});
- // This adds a settings tab so the user can configure various aspects of the plugin
- //this.addSettingTab(new SampleSettingTab(this.app, this));
-
- // If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
- // Using this function will automatically remove the event listener when this plugin is disabled.
- /*
- this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
- console.log('click', evt);
- });
- */
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));