<!doctype html>
<meta charset=utf8>
<link rel=stylesheet href="https://prosemirror.net/css/editor.css">
<script src="https://prosemirror.net/examples/prosemirror.js"></script>
<script src="require-pm.js"></script>
<script src="index.js" defer></script>
<base href="http://prosemirror.net/">
<style>
.menubar {
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
line-height: 0.1;
}
.menuicon {
display: inline-block;
border-right: 1px solid rgba(0, 0, 0, 0.2);
color: #888;
line-height: 1;
padding: 0 7px;
margin: 1px;
cursor: pointer;
text-align: center;
min-width: 1.4em;
}
.strong, .heading { font-weight: bold; }
.em { font-style: italic; }
#editor { padding-top: 0 }
</style>
<div id=editor></div>
<div style="display: none" id=content>
<h3>Simple editor</h3>
<p>With a very crude menu bar.
</div>
javascript prosemirror :
class MenuView {
constructor(items, editorView) {
this.items = items
this.editorView = editorView
this.dom = document.createElement("div")
this.dom.className = "menubar"
items.forEach(({dom}) => this.dom.appendChild(dom))
this.update()
this.dom.addEventListener("mousedown", e => {
e.preventDefault()
editorView.focus()
items.forEach(({command, dom}) => {
if (dom.contains(e.target))
command(editorView.state, editorView.dispatch, editorView)
})
})
}
update() {
this.items.forEach(({command, dom}) => {
let active = command(this.editorView.state, null, this.editorView)
dom.style.display = active ? "" : "none"
})
}
destroy() { this.dom.remove() }
}
const {Plugin} = require("prosemirror-state")
function menuPlugin(items) {
return new Plugin({
view(editorView) {
let menuView = new MenuView(items, editorView)
editorView.dom.parentNode.insertBefore(menuView.dom, editorView.dom)
return menuView
}
})
}
const {toggleMark, setBlockType, wrapIn} = require("prosemirror-commands")
const {schema} = require("prosemirror-schema-basic")
// Helper function to create menu icons
function icon(text, name) {
let span = document.createElement("span")
span.className = "menuicon " + name
span.title = name
span.textContent = text
return span
}
// Create an icon for a heading at the given level
function heading(level) {
return {
command: setBlockType(schema.nodes.heading, {level}),
dom: icon("H" + level, "heading")
}
}
let menu = menuPlugin([
{command: toggleMark(schema.marks.strong), dom: icon("B", "strong")},
{command: toggleMark(schema.marks.em), dom: icon("i", "em")},
{command: setBlockType(schema.nodes.paragraph), dom: icon("p", "paragraph")},
heading(1), heading(2), heading(3),
{command: wrapIn(schema.nodes.blockquote), dom: icon(">", "blockquote")}
])
const {EditorState} = require("prosemirror-state")
const {EditorView} = require("prosemirror-view")
const {baseKeymap} = require("prosemirror-commands")
const {keymap} = require("prosemirror-keymap")
const {DOMParser} = require("prosemirror-model")
window.view = new EditorView(document.querySelector("#editor"), {
state: EditorState.create({
doc: DOMParser.fromSchema(schema).parse(document.querySelector("#content")),
plugins: [keymap(baseKeymap), menu]
})
})
require-pm.js
// Kludge to make requiring prosemirror core libraries possible. The
// PM global is defined by http://prosemirror.net/examples/prosemirror.js,
// which bundles all the core libraries.
function require(name) {
let id = /^prosemirror-(.*)/.exec(name), mod = id && PM[id[1].replace(/-/g, "_")]
if (!mod) throw new Error(`Library menu isn't loaded`)
return mod
}
Leave a Reply