mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-12-12 16:59:01 +08:00
add some old functions
This commit is contained in:
parent
d5e25de018
commit
3d866d9c1c
@ -147,24 +147,24 @@
|
|||||||
<script>
|
<script>
|
||||||
import Icon from 'Components/Icon'
|
import Icon from 'Components/Icon'
|
||||||
import { Editor, EditorContent } from 'tiptap'
|
import { Editor, EditorContent } from 'tiptap'
|
||||||
// import {
|
import {
|
||||||
// BlockquoteNode,
|
BlockquoteNode,
|
||||||
// BulletListNode,
|
BulletListNode,
|
||||||
// CodeBlockNode,
|
CodeBlockNode,
|
||||||
// HardBreakNode,
|
HardBreakNode,
|
||||||
// HeadingNode,
|
HeadingNode,
|
||||||
// ListItemNode,
|
ListItemNode,
|
||||||
// OrderedListNode,
|
OrderedListNode,
|
||||||
// TodoItemNode,
|
TodoItemNode,
|
||||||
// TodoListNode,
|
TodoListNode,
|
||||||
// BoldMark,
|
BoldMark,
|
||||||
// CodeMark,
|
CodeMark,
|
||||||
// ItalicMark,
|
ItalicMark,
|
||||||
// LinkMark,
|
LinkMark,
|
||||||
// StrikeMark,
|
StrikeMark,
|
||||||
// UnderlineMark,
|
UnderlineMark,
|
||||||
// HistoryExtension,
|
HistoryExtension,
|
||||||
// } from 'tiptap-extensions'
|
} from 'tiptap-extensions'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -174,23 +174,24 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
editor: new Editor({
|
editor: new Editor({
|
||||||
|
editable: true,
|
||||||
extensions: [
|
extensions: [
|
||||||
// new BlockquoteNode(),
|
new BlockquoteNode(),
|
||||||
// new BulletListNode(),
|
new BulletListNode(),
|
||||||
// new CodeBlockNode(),
|
new CodeBlockNode(),
|
||||||
// new HardBreakNode(),
|
new HardBreakNode(),
|
||||||
// new HeadingNode({ maxLevel: 3 }),
|
new HeadingNode({ maxLevel: 3 }),
|
||||||
// new ListItemNode(),
|
new ListItemNode(),
|
||||||
// new OrderedListNode(),
|
new OrderedListNode(),
|
||||||
// new TodoItemNode(),
|
new TodoItemNode(),
|
||||||
// new TodoListNode(),
|
new TodoListNode(),
|
||||||
// new BoldMark(),
|
new BoldMark(),
|
||||||
// new CodeMark(),
|
new CodeMark(),
|
||||||
// new ItalicMark(),
|
new ItalicMark(),
|
||||||
// new LinkMark(),
|
new LinkMark(),
|
||||||
// new StrikeMark(),
|
new StrikeMark(),
|
||||||
// new UnderlineMark(),
|
new UnderlineMark(),
|
||||||
// new HistoryExtension(),
|
new HistoryExtension(),
|
||||||
],
|
],
|
||||||
content: {
|
content: {
|
||||||
type: 'doc',
|
type: 'doc',
|
||||||
|
@ -6,12 +6,6 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
render(createElement) {
|
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')
|
return createElement('div')
|
||||||
},
|
},
|
||||||
watch: {
|
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);
|
|
||||||
},
|
|
||||||
}
|
}
|
89
packages/tiptap/src/utils/ComponentView.js
Normal file
89
packages/tiptap/src/utils/ComponentView.js
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
@ -10,10 +10,10 @@ import { inputRules } from 'prosemirror-inputrules'
|
|||||||
import {
|
import {
|
||||||
// buildMenuActions,
|
// buildMenuActions,
|
||||||
ExtensionManager,
|
ExtensionManager,
|
||||||
// initNodeViews,
|
initNodeViews,
|
||||||
// menuBubble,
|
// menuBubble,
|
||||||
// floatingMenu,
|
// floatingMenu,
|
||||||
// builtInKeymap,
|
builtInKeymap,
|
||||||
} from '../Utils'
|
} from '../Utils'
|
||||||
|
|
||||||
import builtInNodes from '../Nodes'
|
import builtInNodes from '../Nodes'
|
||||||
@ -21,8 +21,6 @@ import builtInNodes from '../Nodes'
|
|||||||
export default class Editor {
|
export default class Editor {
|
||||||
|
|
||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
console.log('construct editor')
|
|
||||||
|
|
||||||
this.element = document.createElement('div')
|
this.element = document.createElement('div')
|
||||||
this.bus = new Vue()
|
this.bus = new Vue()
|
||||||
|
|
||||||
@ -30,14 +28,16 @@ export default class Editor {
|
|||||||
this.extensions = this.createExtensions()
|
this.extensions = this.createExtensions()
|
||||||
this.nodes = this.createNodes()
|
this.nodes = this.createNodes()
|
||||||
this.marks = this.createMarks()
|
this.marks = this.createMarks()
|
||||||
|
this.views = this.createViews()
|
||||||
this.schema = this.createSchema()
|
this.schema = this.createSchema()
|
||||||
|
this.plugins = this.createPlugins()
|
||||||
|
this.keymaps = this.createKeymaps()
|
||||||
|
this.inputRules = this.createInputRules()
|
||||||
this.state = this.createState()
|
this.state = this.createState()
|
||||||
this.view = this.createView()
|
this.view = this.createView()
|
||||||
|
this.commands = this.createCommands()
|
||||||
|
|
||||||
console.log('emit init')
|
|
||||||
this.emit('init')
|
this.emit('init')
|
||||||
|
|
||||||
console.log(this.view)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createExtensions() {
|
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() {
|
createNodes() {
|
||||||
const { nodes } = this.extensions
|
return this.extensions.nodes
|
||||||
return nodes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createMarks() {
|
createMarks() {
|
||||||
return []
|
return this.extensions.marks
|
||||||
|
}
|
||||||
|
|
||||||
|
createViews() {
|
||||||
|
return this.extensions.views
|
||||||
}
|
}
|
||||||
|
|
||||||
createSchema() {
|
createSchema() {
|
||||||
@ -67,9 +93,40 @@ export default class Editor {
|
|||||||
return EditorState.create({
|
return EditorState.create({
|
||||||
schema: this.schema,
|
schema: this.schema,
|
||||||
doc: this.createDocument(this.options.content),
|
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) {
|
createDocument(content) {
|
||||||
if (typeof content === 'object') {
|
if (typeof content === 'object') {
|
||||||
return this.schema.nodeFromJSON(content)
|
return this.schema.nodeFromJSON(content)
|
||||||
@ -84,10 +141,10 @@ export default class Editor {
|
|||||||
return new EditorView(this.element, {
|
return new EditorView(this.element, {
|
||||||
state: this.state,
|
state: this.state,
|
||||||
dispatchTransaction: this.dispatchTransaction.bind(this),
|
dispatchTransaction: this.dispatchTransaction.bind(this),
|
||||||
// nodeViews: initNodeViews({
|
nodeViews: initNodeViews({
|
||||||
// nodes: this.views,
|
nodes: this.views,
|
||||||
// editable: this.editable,
|
editable: this.options.editable,
|
||||||
// }),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +180,52 @@ export default class Editor {
|
|||||||
return div.innerHTML
|
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) {
|
emit(event, ...data) {
|
||||||
this.bus.$emit(event, ...data)
|
this.bus.$emit(event, ...data)
|
||||||
}
|
}
|
||||||
@ -131,4 +234,12 @@ export default class Editor {
|
|||||||
this.bus.$on(event, callback)
|
this.bus.$on(event, callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.emit('destroy')
|
||||||
|
|
||||||
|
if (this.view) {
|
||||||
|
this.view.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
10
packages/tiptap/src/utils/builtInKeymap.js
Normal file
10
packages/tiptap/src/utils/builtInKeymap.js
Normal 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
|
@ -1,7 +1,7 @@
|
|||||||
// export { default as buildMenuActions } from './buildMenuActions'
|
// export { default as buildMenuActions } from './buildMenuActions'
|
||||||
// export { default as builtInKeymap } from './builtInKeymap'
|
export { default as builtInKeymap } from './builtInKeymap'
|
||||||
// export { default as ComponentView } from './ComponentView'
|
export { default as ComponentView } from './ComponentView'
|
||||||
// export { default as initNodeViews } from './initNodeViews'
|
export { default as initNodeViews } from './initNodeViews'
|
||||||
// export { default as floatingMenu } from './floatingMenu'
|
// export { default as floatingMenu } from './floatingMenu'
|
||||||
// export { default as menuBubble } from './menuBubble'
|
// export { default as menuBubble } from './menuBubble'
|
||||||
export { default as ExtensionManager } from './ExtensionManager'
|
export { default as ExtensionManager } from './ExtensionManager'
|
||||||
|
21
packages/tiptap/src/utils/initNodeViews.js
Normal file
21
packages/tiptap/src/utils/initNodeViews.js
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user