add some old functions

This commit is contained in:
Philipp Kühn 2018-10-21 21:55:24 +02:00
parent d5e25de018
commit 3d866d9c1c
7 changed files with 283 additions and 67 deletions

View File

@ -147,24 +147,24 @@
<script>
import Icon from 'Components/Icon'
import { Editor, EditorContent } from 'tiptap'
// import {
// BlockquoteNode,
// BulletListNode,
// CodeBlockNode,
// HardBreakNode,
// HeadingNode,
// ListItemNode,
// OrderedListNode,
// TodoItemNode,
// TodoListNode,
// BoldMark,
// CodeMark,
// ItalicMark,
// LinkMark,
// StrikeMark,
// UnderlineMark,
// HistoryExtension,
// } from 'tiptap-extensions'
import {
BlockquoteNode,
BulletListNode,
CodeBlockNode,
HardBreakNode,
HeadingNode,
ListItemNode,
OrderedListNode,
TodoItemNode,
TodoListNode,
BoldMark,
CodeMark,
ItalicMark,
LinkMark,
StrikeMark,
UnderlineMark,
HistoryExtension,
} from 'tiptap-extensions'
export default {
components: {
@ -174,23 +174,24 @@ export default {
data() {
return {
editor: new Editor({
editable: true,
extensions: [
// new BlockquoteNode(),
// new BulletListNode(),
// new CodeBlockNode(),
// new HardBreakNode(),
// new HeadingNode({ maxLevel: 3 }),
// new ListItemNode(),
// new OrderedListNode(),
// new TodoItemNode(),
// new TodoListNode(),
// new BoldMark(),
// new CodeMark(),
// new ItalicMark(),
// new LinkMark(),
// new StrikeMark(),
// new UnderlineMark(),
// new HistoryExtension(),
new BlockquoteNode(),
new BulletListNode(),
new CodeBlockNode(),
new HardBreakNode(),
new HeadingNode({ maxLevel: 3 }),
new ListItemNode(),
new OrderedListNode(),
new TodoItemNode(),
new TodoListNode(),
new BoldMark(),
new CodeMark(),
new ItalicMark(),
new LinkMark(),
new StrikeMark(),
new UnderlineMark(),
new HistoryExtension(),
],
content: {
type: 'doc',

View File

@ -6,12 +6,6 @@ export default {
},
},
render(createElement) {
// console.log('createElement', this.editor)
// if (this.editor) {
// console.log('create element', this.editor.element)
// return this.editor.element
// // return createElement('div', {}, this.editor.element.innerHTML)
// }
return createElement('div')
},
watch: {
@ -26,14 +20,4 @@ export default {
},
}
},
created() {
// console.log('on init')
// this.editor.on('init', () => {
// console.log('iniiiitttt!!!')
// })
// setTimeout(() => {
// // this.$el.innerHTML = this.editor.element.innerHTML
// this.$el.append(this.editor.element)
// }, 1000);
},
}

View File

@ -0,0 +1,89 @@
import Vue from 'vue'
export default class ComponentView {
constructor(component, {
node,
view,
getPos,
decorations,
editable,
}) {
this.component = component
this.node = node
this.view = view
this.getPos = getPos
this.decorations = decorations
this.editable = editable
this.dom = this.createDOM()
this.contentDOM = this.vm.$refs.content
}
createDOM() {
const Component = Vue.extend(this.component)
this.vm = new Component({
propsData: {
node: this.node,
view: this.view,
getPos: this.getPos,
decorations: this.decorations,
editable: this.editable,
updateAttrs: attrs => this.updateAttrs(attrs),
updateContent: content => this.updateContent(content),
},
}).$mount()
return this.vm.$el
}
updateAttrs(attrs) {
if (!this.editable) {
return
}
const transaction = this.view.state.tr.setNodeMarkup(this.getPos(), null, {
...this.node.attrs,
...attrs,
})
this.view.dispatch(transaction)
}
updateContent(content) {
if (!this.editable) {
return
}
const transaction = this.view.state.tr.setNodeMarkup(this.getPos(), this.node.type, { content })
this.view.dispatch(transaction)
}
ignoreMutation() {
return true
}
stopEvent(event) {
// TODO: find a way to pass full extensions to ComponentView
// so we could check for schema.draggable
// for now we're allowing all drag events for node views
return !/drag/.test(event.type)
}
update(node, decorations) {
if (node.type !== this.node.type) {
return false
}
if (node === this.node && this.decorations === decorations) {
return true
}
this.node = node
this.decorations = decorations
this.vm._props.node = node
this.vm._props.decorations = decorations
return true
}
destroy() {
this.vm.$destroy()
}
}

View File

@ -10,10 +10,10 @@ import { inputRules } from 'prosemirror-inputrules'
import {
// buildMenuActions,
ExtensionManager,
// initNodeViews,
initNodeViews,
// menuBubble,
// floatingMenu,
// builtInKeymap,
builtInKeymap,
} from '../Utils'
import builtInNodes from '../Nodes'
@ -21,8 +21,6 @@ import builtInNodes from '../Nodes'
export default class Editor {
constructor(options = {}) {
console.log('construct editor')
this.element = document.createElement('div')
this.bus = new Vue()
@ -30,14 +28,16 @@ export default class Editor {
this.extensions = this.createExtensions()
this.nodes = this.createNodes()
this.marks = this.createMarks()
this.views = this.createViews()
this.schema = this.createSchema()
this.plugins = this.createPlugins()
this.keymaps = this.createKeymaps()
this.inputRules = this.createInputRules()
this.state = this.createState()
this.view = this.createView()
this.commands = this.createCommands()
console.log('emit init')
this.emit('init')
console.log(this.view)
}
createExtensions() {
@ -47,13 +47,39 @@ export default class Editor {
])
}
createPlugins() {
return this.extensions.plugins
}
createKeymaps() {
return this.extensions.keymaps({
schema: this.schema,
})
}
createInputRules() {
return this.extensions.inputRules({
schema: this.schema,
})
}
createCommands() {
return this.extensions.commands({
schema: this.schema,
view: this.view,
})
}
createNodes() {
const { nodes } = this.extensions
return nodes
return this.extensions.nodes
}
createMarks() {
return []
return this.extensions.marks
}
createViews() {
return this.extensions.views
}
createSchema() {
@ -67,9 +93,40 @@ export default class Editor {
return EditorState.create({
schema: this.schema,
doc: this.createDocument(this.options.content),
plugins: [
...this.plugins,
...this.getPlugins(),
],
})
}
getPlugins() {
const plugins = [
inputRules({
rules: this.inputRules,
}),
...this.keymaps,
keymap(builtInKeymap),
keymap(baseKeymap),
gapCursor(),
new Plugin({
props: {
editable: () => this.options.editable,
},
}),
]
// if (this.menububbleNode) {
// plugins.push(menuBubble(this.menububbleNode))
// }
// if (this.floatingMenuNode) {
// plugins.push(floatingMenu(this.floatingMenuNode))
// }
return plugins
}
createDocument(content) {
if (typeof content === 'object') {
return this.schema.nodeFromJSON(content)
@ -84,10 +141,10 @@ export default class Editor {
return new EditorView(this.element, {
state: this.state,
dispatchTransaction: this.dispatchTransaction.bind(this),
// nodeViews: initNodeViews({
// nodes: this.views,
// editable: this.editable,
// }),
nodeViews: initNodeViews({
nodes: this.views,
editable: this.options.editable,
}),
})
}
@ -123,6 +180,52 @@ export default class Editor {
return div.innerHTML
}
getJSON() {
return this.state.doc.toJSON()
}
getDocFromContent(content) {
if (typeof content === 'object') {
return this.schema.nodeFromJSON(content)
}
if (typeof content === 'string') {
const element = document.createElement('div')
element.innerHTML = content.trim()
return DOMParser.fromSchema(this.schema).parse(element)
}
return false
}
setContent(content = {}, emitUpdate = false) {
this.state = EditorState.create({
schema: this.state.schema,
doc: this.getDocFromContent(content),
plugins: this.state.plugins,
})
this.view.updateState(this.state)
if (emitUpdate) {
this.emitUpdate()
}
}
clearContent(emitUpdate = false) {
this.setContent({
type: 'doc',
content: [{
type: 'paragraph',
}],
}, emitUpdate)
}
focus() {
this.view.focus()
}
emit(event, ...data) {
this.bus.$emit(event, ...data)
}
@ -131,4 +234,12 @@ export default class Editor {
this.bus.$on(event, callback)
}
destroy() {
this.emit('destroy')
if (this.view) {
this.view.destroy()
}
}
}

View File

@ -0,0 +1,10 @@
import { lift, selectParentNode } from 'prosemirror-commands'
import { undoInputRule } from 'prosemirror-inputrules'
const keymap = {
'Mod-BracketLeft': lift,
Backspace: undoInputRule,
Escape: selectParentNode,
}
export default keymap

View File

@ -1,7 +1,7 @@
// export { default as buildMenuActions } from './buildMenuActions'
// export { default as builtInKeymap } from './builtInKeymap'
// export { default as ComponentView } from './ComponentView'
// export { default as initNodeViews } from './initNodeViews'
export { default as builtInKeymap } from './builtInKeymap'
export { default as ComponentView } from './ComponentView'
export { default as initNodeViews } from './initNodeViews'
// export { default as floatingMenu } from './floatingMenu'
// export { default as menuBubble } from './menuBubble'
export { default as ExtensionManager } from './ExtensionManager'

View File

@ -0,0 +1,21 @@
import ComponentView from './ComponentView'
export default function initNodeViews({ nodes, editable }) {
const nodeViews = {}
Object.keys(nodes).forEach(nodeName => {
nodeViews[nodeName] = (node, view, getPos, decorations) => {
const component = nodes[nodeName]
return new ComponentView(component, {
node,
view,
getPos,
decorations,
editable,
})
}
})
return nodeViews
}