87 lines
2.1 KiB
JavaScript
87 lines
2.1 KiB
JavaScript
import {EditorState, Plugin} from "prosemirror-state";
|
|
import {EditorView} from "prosemirror-view";
|
|
import {history} from "prosemirror-history";
|
|
import {keymap} from "prosemirror-keymap";
|
|
import {baseKeymap} from "prosemirror-commands";
|
|
import {DOMParser, DOMSerializer} from "prosemirror-model";
|
|
|
|
import {buildKeymap} from "./godo-additional-keymap.mjs";
|
|
import {basic_schema, headers_schema, full_schema} from "./godo-schemas.mjs";
|
|
import {Menu, blocks, marks} from "./godo-menus.mjs";
|
|
|
|
function menuPlugin(menu) {
|
|
return new Plugin({
|
|
view(editorView) {
|
|
let menuView = new Menu(menu, editorView);
|
|
editorView.dom.parentNode.insertBefore(menuView.el, editorView.dom);
|
|
return menuView;
|
|
}
|
|
});
|
|
}
|
|
|
|
export default class Godo {
|
|
|
|
constructor (textarea, options) {
|
|
this.textarea = textarea;
|
|
|
|
this.schema = (() => {
|
|
switch(options.schema) {
|
|
case 'basic':
|
|
return basic_schema;
|
|
break;
|
|
case 'headers':
|
|
return headers_schema;
|
|
break;
|
|
case 'full':
|
|
default:
|
|
return full_schema
|
|
};
|
|
})();
|
|
|
|
this.editor_wrapper = document.createElement('div');
|
|
this.editor_wrapper.className = "godo";
|
|
textarea.insertAdjacentElement('afterend', this.editor_wrapper);
|
|
|
|
this.marksMenu = menuPlugin(marks(this.schema));
|
|
this.blockMenu = menuPlugin(blocks(this.schema));
|
|
|
|
this.state = EditorState.create({
|
|
schema: this.schema,
|
|
doc: DOMParser.fromSchema(this.schema).parse(this.get_textarea_content()),
|
|
plugins: [
|
|
history(),
|
|
keymap(baseKeymap),
|
|
keymap(buildKeymap(this.schema)),
|
|
this.marksMenu,
|
|
this.blockMenu
|
|
]
|
|
});
|
|
|
|
this.view = new EditorView(this.editor_wrapper, {
|
|
state: this.state,
|
|
attributes: {
|
|
class: "godo--editor"
|
|
}
|
|
});
|
|
|
|
this.textarea.form.addEventListener('submit', e => {
|
|
textarea.value = this.getHTML();
|
|
});
|
|
}
|
|
|
|
get_textarea_content() {
|
|
const w = document.createElement('div');
|
|
w.innerHTML = this.textarea.value;
|
|
return w;
|
|
}
|
|
|
|
getHTML() {
|
|
const div = document.createElement('div');
|
|
const fragment = DOMSerializer
|
|
.fromSchema(this.schema)
|
|
.serializeFragment(this.view.state.doc.content);
|
|
div.appendChild(fragment);
|
|
return div.innerHTML;
|
|
}
|
|
}
|