import config from "../config";
import Html from "../lib/html";
import Notebook from "../notebook";
class Editor {
notebook: Notebook;
defaults: Record;
modules = [
"view",
"state",
"history",
"gutter",
"fold",
"language",
"commands",
"search",
"autocomplete",
"highlight",
];
constructor(notebook: Notebook, defaults?: any) {
this.notebook = notebook;
this.defaults = { theme: "neo", mode: "javascript", ...defaults };
}
async load(): Promise {
const repo = Object.create(null);
const loadToRepo = async (key: string) => {
const module = await this.loadModule(key);
repo[key] = module;
};
await Promise.all(this.modules.map(loadToRepo));
return repo;
}
async loadModule(module: string): Promise {
return await this.notebook.importModule(`${config.CODEMIRROR}/${module}`);
}
async render(text: string, parent: HTMLElement, options?: any): Promise {
const opts = { ...this.defaults, ...options };
const { tabSize = 2, events = {} } = opts;
const extensions: any[] = [];
const cm = await this.notebook.importModule(config.CODEMIRROR);
const { EditorView } = cm;
if (tabSize) {
//const ts = new Compartment();
// extensions.push(keymap.of([indentWithTab]));
//extensions.push(ts.of(EditorState.tabSize.of(+tabSize)));
}
// if (lineNumbers === "") extensions.push(cm.gutter.lineNumbers());
extensions.push(
EditorView.updateListener.of((update: any) => {
const { docChanged } = update;
if (docChanged && events.change)
events.change(update.state.doc.toString());
})
);
new EditorView({
doc: text,
extensions,
parent,
});
}
lineNumbers(mode: string, lineNumbers: any) {
return lineNumbers || mode !== "markdown";
}
tabSize(mode: string, tabSize: any) {
return tabSize || mode === "python" ? 4 : 2;
}
}
export class EditorComponent extends HTMLElement {
async connectedCallback() {
const html = new Html(this);
const editor = Notebook.installed().editor;
const text = this.textContent || "";
const options = html.getAttrs();
await editor.render(text, this, options);
}
}
export default Editor;