Merge branch 'main' of github.com:ueberdosis/tiptap-next into main
This commit is contained in:
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
insert_final_newline = true
|
||||||
|
max_line_length = 100
|
||||||
|
|
||||||
|
[*.{html,ts,js,jsx,css,scss,vue}]
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
67
.eslintrc.js
Normal file
67
.eslintrc.js
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
module.exports = {
|
||||||
|
parserOptions: {
|
||||||
|
parser: '@typescript-eslint/parser',
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
es6: true,
|
||||||
|
node: true,
|
||||||
|
},
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'./**/*.ts',
|
||||||
|
'./**/*.js',
|
||||||
|
'./**/*.vue',
|
||||||
|
],
|
||||||
|
excludedFiles: [
|
||||||
|
'dist/**',
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
'html',
|
||||||
|
'cypress',
|
||||||
|
'@typescript-eslint',
|
||||||
|
],
|
||||||
|
env: {
|
||||||
|
'cypress/globals': true,
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
document: false,
|
||||||
|
window: false,
|
||||||
|
},
|
||||||
|
extends: [
|
||||||
|
'plugin:vue/strongly-recommended',
|
||||||
|
'airbnb-base',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
semi: ['error', 'never'],
|
||||||
|
'import/extensions': 'off',
|
||||||
|
'import/no-extraneous-dependencies': 'off',
|
||||||
|
'import/no-unresolved': 'off',
|
||||||
|
'import/no-dynamic-require': 'off',
|
||||||
|
'arrow-parens': ['error', 'as-needed'],
|
||||||
|
'padded-blocks': 'off',
|
||||||
|
'class-methods-use-this': 'off',
|
||||||
|
'global-require': 'off',
|
||||||
|
'func-names': ['error', 'never'],
|
||||||
|
'arrow-body-style': 'off',
|
||||||
|
'max-len': 'off',
|
||||||
|
'vue/this-in-template': ['error', 'never'],
|
||||||
|
'vue/max-attributes-per-line': ['error', {
|
||||||
|
singleline: 3,
|
||||||
|
multiline: {
|
||||||
|
max: 1,
|
||||||
|
allowFirstLine: false,
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
'no-param-reassign': 'off',
|
||||||
|
'import/prefer-default-export': 'off',
|
||||||
|
'consistent-return': 'off',
|
||||||
|
'no-unused-vars': 'off',
|
||||||
|
'@typescript-eslint/no-unused-vars': ['error'],
|
||||||
|
'no-use-before-define': 'off',
|
||||||
|
'@typescript-eslint/no-use-before-define': ['error'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
@@ -5,4 +5,4 @@ module.exports = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
'@babel/plugin-proposal-optional-chaining',
|
'@babel/plugin-proposal-optional-chaining',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ module.exports = {
|
|||||||
plugins: [
|
plugins: [
|
||||||
'@babel/plugin-proposal-optional-chaining',
|
'@babel/plugin-proposal-optional-chaining',
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ module.exports = {
|
|||||||
autolinkHeadings: {
|
autolinkHeadings: {
|
||||||
content: {
|
content: {
|
||||||
type: 'text',
|
type: 'text',
|
||||||
value: '#'
|
value: '#',
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ const packages = globby.sync('../packages/*', { onlyDirectories: true })
|
|||||||
excludePrivate: true,
|
excludePrivate: true,
|
||||||
// excludeNotDocumented: true,
|
// excludeNotDocumented: true,
|
||||||
exclude: [
|
exclude: [
|
||||||
"**/*.test.ts",
|
'**/*.test.ts',
|
||||||
"**/__tests__/*",
|
'**/__tests__/*',
|
||||||
"**/__mocks__/*"
|
'**/__mocks__/*',
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -68,16 +68,16 @@ module.exports = function (api) {
|
|||||||
|
|
||||||
config.module
|
config.module
|
||||||
.rule('typescript')
|
.rule('typescript')
|
||||||
.test(/\.tsx?$/)
|
.test(/\.tsx?$/)
|
||||||
.use()
|
.use()
|
||||||
.loader('ts-loader')
|
.loader('ts-loader')
|
||||||
.options({ transpileOnly: false, appendTsSuffixTo: [/\.vue$/] })
|
.options({ transpileOnly: false, appendTsSuffixTo: [/\.vue$/] })
|
||||||
|
|
||||||
config.module
|
config.module
|
||||||
.rule('jsx')
|
.rule('jsx')
|
||||||
.test(/\.jsx?$/)
|
.test(/\.jsx?$/)
|
||||||
.use()
|
.use()
|
||||||
.loader('babel-loader')
|
.loader('babel-loader')
|
||||||
|
|
||||||
globby.sync('../packages/*', { onlyDirectories: true })
|
globby.sync('../packages/*', { onlyDirectories: true })
|
||||||
.map(name => name.replace('../packages/', ''))
|
.map(name => name.replace('../packages/', ''))
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="demo__meta">
|
<div class="demo__meta">
|
||||||
<div class="demo__name">
|
<div class="demo__name">
|
||||||
Demo/{{ this.name }}
|
Demo/{{ name }}
|
||||||
</div>
|
</div>
|
||||||
<a class="demo__link" :href="githubUrl" target="_blank">
|
<a class="demo__link" :href="githubUrl" target="_blank">
|
||||||
Edit on GitHub →
|
Edit on GitHub →
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div v-else class="demo__error">
|
<div v-else class="demo__error">
|
||||||
Could not find a demo called “{{ this.name }}”.
|
Could not find a demo called “{{ name }}”.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -66,7 +66,7 @@ export default {
|
|||||||
hideSourceCode: {
|
hideSourceCode: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@@ -106,7 +106,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.files = collect(require.context(`~/demos/`, true, /.+\..+$/).keys())
|
this.files = collect(require.context('~/demos/', true, /.+\..+$/).keys())
|
||||||
.filter(path => path.startsWith(`./${this.name}`))
|
.filter(path => path.startsWith(`./${this.name}`))
|
||||||
.map(path => path.replace('./', ''))
|
.map(path => path.replace('./', ''))
|
||||||
.map(path => {
|
.map(path => {
|
||||||
@@ -120,13 +120,13 @@ export default {
|
|||||||
highlight: this.syntax[extension] || extension,
|
highlight: this.syntax[extension] || extension,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter((item) => {
|
.filter(item => {
|
||||||
return ['vue', 'jsx', 'scss'].includes(item.extension)
|
return ['vue', 'jsx', 'scss'].includes(item.extension)
|
||||||
})
|
})
|
||||||
.sortBy(item => item.path.split('/').length)
|
.sortBy(item => item.path.split('/').length)
|
||||||
.toArray()
|
.toArray()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss" scoped />
|
<style lang="scss" src="./style.scss" scoped />
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ export default {
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
items() {
|
items() {
|
||||||
return this.linkGroups.reduce((acc, group) => (acc.push(...group.items), acc), [])
|
return this.linkGroups.reduce((acc, group) => ((acc.push(...group.items), acc)), [])
|
||||||
},
|
},
|
||||||
|
|
||||||
currentIndex() {
|
currentIndex() {
|
||||||
@@ -51,8 +51,8 @@ export default {
|
|||||||
previousPage() {
|
previousPage() {
|
||||||
return this.items[this.currentIndex - 1]
|
return this.items[this.currentIndex - 1]
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss" scoped></style>
|
<style lang="scss" src="./style.scss" scoped></style>
|
||||||
|
|||||||
@@ -34,11 +34,11 @@ export default {
|
|||||||
methods: {
|
methods: {
|
||||||
highlightCode() {
|
highlightCode() {
|
||||||
Prism.highlightAllUnder(this.$el)
|
Prism.highlightAllUnder(this.$el)
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.highlightCode()
|
this.highlightCode()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export default {
|
|||||||
props: {
|
props: {
|
||||||
component: {
|
component: {
|
||||||
required: true,
|
required: true,
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -21,4 +21,4 @@ export default {
|
|||||||
ReactDOM.unmountComponentAtNode(this.$el)
|
ReactDOM.unmountComponentAtNode(this.$el)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,18 +8,18 @@ import { outdent } from '@mvasilkov/outdent'
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
formattedCode: null
|
formattedCode: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
updateCode() {
|
updateCode() {
|
||||||
const text = this.$slots.default[0].text
|
const { text } = this.$slots.default[0]
|
||||||
|
|
||||||
if (text) {
|
if (text) {
|
||||||
this.formattedCode = outdent(text)
|
this.formattedCode = outdent(text)
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeUpdate() {
|
beforeUpdate() {
|
||||||
@@ -30,4 +30,4 @@ export default {
|
|||||||
this.updateCode()
|
this.updateCode()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<pre>{{ this.html }}</pre>
|
<pre>{{ html }}</pre>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -9,22 +9,21 @@ import Paragraph from '@tiptap/extension-paragraph'
|
|||||||
import Text from '@tiptap/extension-text'
|
import Text from '@tiptap/extension-text'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
doc: {
|
doc: {
|
||||||
'type': 'document',
|
type: 'document',
|
||||||
'content': [{
|
content: [{
|
||||||
'type': 'paragraph',
|
type: 'paragraph',
|
||||||
'attrs': {
|
attrs: {
|
||||||
'align': 'left'
|
align: 'left',
|
||||||
},
|
},
|
||||||
'content': [{
|
content: [{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'text': 'Example Text'
|
text: 'Example Text',
|
||||||
}]
|
}],
|
||||||
}]
|
}],
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -35,8 +34,7 @@ export default {
|
|||||||
Paragraph(),
|
Paragraph(),
|
||||||
Text(),
|
Text(),
|
||||||
])
|
])
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
this.editor = new Editor({
|
this.editor = new Editor({
|
||||||
extensions: defaultExtensions(),
|
extensions: defaultExtensions(),
|
||||||
content: `
|
content: `
|
||||||
<h2>
|
<h2>
|
||||||
Hi there,
|
Hi there,
|
||||||
</h2>
|
</h2>
|
||||||
@@ -112,4 +112,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -8,44 +8,44 @@ context('/examples/export-html-or-json', () => {
|
|||||||
const json = editor.json()
|
const json = editor.json()
|
||||||
|
|
||||||
expect(json).to.deep.equal({
|
expect(json).to.deep.equal({
|
||||||
'type': 'document',
|
type: 'document',
|
||||||
'content': [
|
content: [
|
||||||
{
|
{
|
||||||
'type': 'paragraph',
|
type: 'paragraph',
|
||||||
'content': [
|
content: [
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'text': 'You are able to export your data as '
|
text: 'You are able to export your data as ',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'marks': [
|
marks: [
|
||||||
{
|
{
|
||||||
'type': 'code'
|
type: 'code',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
'text': 'HTML'
|
text: 'HTML',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'text': ' or '
|
text: ' or ',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'marks': [
|
marks: [
|
||||||
{
|
{
|
||||||
'type': 'code'
|
type: 'code',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
'text': 'JSON'
|
text: 'JSON',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'text': '.'
|
text: '.',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -57,4 +57,4 @@ context('/examples/export-html-or-json', () => {
|
|||||||
expect(html).to.equal('<p>You are able to export your data as <code>HTML</code> or <code>JSON</code>.</p>')
|
expect(html).to.equal('<p>You are able to export your data as <code>HTML</code> or <code>JSON</code>.</p>')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -88,4 +88,4 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss">
|
<style lang="scss" src="./style.scss">
|
||||||
|
|||||||
@@ -10,4 +10,4 @@ context('/examples/focus', () => {
|
|||||||
cy.get('.ProseMirror p:first').should('have.class', 'has-focus')
|
cy.get('.ProseMirror p:first').should('have.class', 'has-focus')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -55,4 +55,4 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss">
|
<style lang="scss" src="./style.scss">
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ context('/examples/history', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
it('should not have a mistake', () => {
|
it('should not have a mistake', () => {
|
||||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
cy.get('.ProseMirror').then(() => {
|
||||||
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
|
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -22,4 +22,4 @@ context('/examples/history', () => {
|
|||||||
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
|
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export default {
|
|||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.editor = new Editor({
|
this.editor = new Editor({
|
||||||
content: `
|
content: `
|
||||||
<h2>
|
<h2>
|
||||||
History
|
History
|
||||||
</h2>
|
</h2>
|
||||||
@@ -44,4 +44,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -99,4 +99,4 @@ context('/examples/markdown-shortcuts', () => {
|
|||||||
.find('blockquote')
|
.find('blockquote')
|
||||||
.should('contain', 'foobar')
|
.should('contain', 'foobar')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default {
|
|||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.editor = new Editor({
|
this.editor = new Editor({
|
||||||
content: `
|
content: `
|
||||||
<p>
|
<p>
|
||||||
Start a new line and type <code>#</code> followed by a space to get a headline. Try <code>#</code>, <code>##</code>, <code>###</code>, <code>####</code>, <code>#####</code>, <code>######</code> for different levels.
|
Start a new line and type <code>#</code> followed by a space to get a headline. Try <code>#</code>, <code>##</code>, <code>###</code>, <code>####</code>, <code>#####</code>, <code>######</code> for different levels.
|
||||||
</p>
|
</p>
|
||||||
@@ -39,4 +39,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -22,4 +22,4 @@ context('/examples/read-only', () => {
|
|||||||
cy.get('.ProseMirror p:first').should('contain', 'Edited: ')
|
cy.get('.ProseMirror p:first').should('contain', 'Edited: ')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,4 +49,4 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss">
|
<style lang="scss" src="./style.scss">
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ context('/examples/simple', () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
cy.visit('/examples/simple')
|
cy.visit('/examples/simple')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -38,4 +38,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -73,4 +73,4 @@ context('/api/extensions/blockquote', () => {
|
|||||||
.find('blockquote')
|
.find('blockquote')
|
||||||
.should('contain', 'Quote')
|
.should('contain', 'Quote')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -46,6 +46,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -58,4 +58,4 @@ context('/api/extensions/bold', () => {
|
|||||||
.find('strong')
|
.find('strong')
|
||||||
.should('contain', 'Bold')
|
.should('contain', 'Bold')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -49,6 +49,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -128,4 +128,4 @@ context('/api/extensions/bullet-list', () => {
|
|||||||
.find('p')
|
.find('p')
|
||||||
.should('contain', '* Example')
|
.should('contain', '* Example')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -48,6 +48,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -32,4 +32,4 @@ context('/api/extensions/code', () => {
|
|||||||
cy.get('.ProseMirror code')
|
cy.get('.ProseMirror code')
|
||||||
.should('not.exist')
|
.should('not.exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -44,6 +44,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -64,4 +64,4 @@ context('/api/extensions/code-block', () => {
|
|||||||
.find('pre')
|
.find('pre')
|
||||||
.should('contain', 'Code')
|
.should('contain', 'Code')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -59,6 +59,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ context('/api/extensions/document', () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
cy.visit('/api/extensions/document')
|
cy.visit('/api/extensions/document')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ context('/api/extensions/hard-break', () => {
|
|||||||
cy.get('.ProseMirror br')
|
cy.get('.ProseMirror br')
|
||||||
.should('exist')
|
.should('exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -52,6 +52,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -74,4 +74,4 @@ context('/api/extensions/heading', () => {
|
|||||||
.find('h1')
|
.find('h1')
|
||||||
.should('contain', 'Headline')
|
.should('contain', 'Headline')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -54,6 +54,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ context('/api/extensions/history', () => {
|
|||||||
.should('not.contain', 'Mistake')
|
.should('not.contain', 'Mistake')
|
||||||
|
|
||||||
cy.get('.demo__preview button:nth-child(2)')
|
cy.get('.demo__preview button:nth-child(2)')
|
||||||
.click()
|
.click()
|
||||||
|
|
||||||
cy.get('.ProseMirror')
|
cy.get('.ProseMirror')
|
||||||
.should('contain', 'Mistake')
|
.should('contain', 'Mistake')
|
||||||
|
|||||||
@@ -46,6 +46,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -49,4 +49,4 @@ context('/api/extensions/horizontal-rule', () => {
|
|||||||
.should('exist')
|
.should('exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,6 +47,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -47,4 +47,4 @@ context('/api/extensions/italic', () => {
|
|||||||
.find('em')
|
.find('em')
|
||||||
.should('not.exist')
|
.should('not.exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -46,6 +46,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -9,4 +9,4 @@ context('/api/extensions/link', () => {
|
|||||||
editor.selectAll()
|
editor.selectAll()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -41,6 +41,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ context('/api/extensions/list-item', () => {
|
|||||||
before(() => {
|
before(() => {
|
||||||
cy.visit('/api/extensions/list-item')
|
cy.visit('/api/extensions/list-item')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -68,6 +68,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -94,4 +94,4 @@ context('/api/extensions/ordered-list', () => {
|
|||||||
.find('p')
|
.find('p')
|
||||||
.should('contain', '1. Example')
|
.should('contain', '1. Example')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -48,6 +48,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -42,4 +42,4 @@ context('/api/extensions/paragraph', () => {
|
|||||||
.find('p')
|
.find('p')
|
||||||
.should('have.length', 1)
|
.should('have.length', 1)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -55,4 +55,4 @@ context('/api/extensions/strike', () => {
|
|||||||
.find('s')
|
.find('s')
|
||||||
.should('contain', 'Strike')
|
.should('contain', 'Strike')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -47,6 +47,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ context('/api/extensions/text', () => {
|
|||||||
.find('p')
|
.find('p')
|
||||||
.should('contain', 'Example Text')
|
.should('contain', 'Example Text')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -37,6 +37,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -48,4 +48,4 @@ context('/api/extensions/underline', () => {
|
|||||||
.find('u')
|
.find('u')
|
||||||
.should('not.exist')
|
.should('not.exist')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -45,6 +45,6 @@ export default {
|
|||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -72,4 +72,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -27,4 +27,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
import React, { useState, useRef, useEffect, createContext, useContext } from 'react'
|
import {
|
||||||
|
useState, useRef, useEffect, createContext, useContext,
|
||||||
|
} from 'react'
|
||||||
import { Editor as Tiptap } from '@tiptap/core'
|
import { Editor as Tiptap } from '@tiptap/core'
|
||||||
|
|
||||||
export const EditorContext = createContext({})
|
export const EditorContext = createContext({})
|
||||||
|
|
||||||
export const useEditor = () => useContext(EditorContext)
|
export const useEditor = () => useContext(EditorContext)
|
||||||
|
|
||||||
export const Editor = ({ value, onChange, children, ...props }) => {
|
export const Editor = ({
|
||||||
|
value, onChange, children, ...props
|
||||||
|
}) => {
|
||||||
const [editor, setEditor] = useState(null)
|
const [editor, setEditor] = useState(null)
|
||||||
const editorRef = useRef(null)
|
const editorRef = useRef(null)
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState } from 'react'
|
import { useState } from 'react'
|
||||||
import { useEditor, Editor } from './components/Editor'
|
|
||||||
import extensions from '@tiptap/starter-kit'
|
import extensions from '@tiptap/starter-kit'
|
||||||
|
import { useEditor, Editor } from './components/Editor'
|
||||||
|
|
||||||
// Menu bar example component
|
// Menu bar example component
|
||||||
// useEditor only works for child components of <Editor />
|
// useEditor only works for child components of <Editor />
|
||||||
@@ -24,39 +24,39 @@ const MenuBar = () => {
|
|||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [value, setValue] = useState({
|
const [value, setValue] = useState({
|
||||||
'type': 'document',
|
type: 'document',
|
||||||
'content': [
|
content: [
|
||||||
{
|
{
|
||||||
'type': 'paragraph',
|
type: 'paragraph',
|
||||||
'content': [
|
content: [
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'text': 'rendered in '
|
text: 'rendered in ',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'marks': [
|
marks: [
|
||||||
{
|
{
|
||||||
'type': 'bold'
|
type: 'bold',
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
'text': 'react'
|
text: 'react',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'type': 'text',
|
type: 'text',
|
||||||
'text': '!'
|
text: '!',
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p>
|
<p>
|
||||||
<button onClick={() => alert(JSON.stringify(value))}>Alert state</button>
|
<button onClick={() => alert(JSON.stringify(value))}>Alert state</button>
|
||||||
</p>
|
</p>
|
||||||
<hr style={{ margin: '0.85rem 0'}} />
|
<hr style={{ margin: '0.85rem 0' }} />
|
||||||
<Editor
|
<Editor
|
||||||
value={value}
|
value={value}
|
||||||
onChange={setValue}
|
onChange={setValue}
|
||||||
|
|||||||
@@ -41,4 +41,4 @@ export default {
|
|||||||
this.editor.destroy()
|
this.editor.destroy()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
{{ $static.metadata.siteName }}
|
{{ $static.metadata.siteName }}
|
||||||
</g-link>
|
</g-link>
|
||||||
<div>
|
<div>
|
||||||
<input class="search" type="search" placeholder="Search" />
|
<input class="search" type="search" placeholder="Search">
|
||||||
<a href="https://github.com/sponsors/ueberdosis">
|
<a href="https://github.com/sponsors/ueberdosis">
|
||||||
Sponsor
|
Sponsor
|
||||||
</a>
|
</a>
|
||||||
@@ -58,9 +58,9 @@
|
|||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<main class="app__main">
|
<main class="app__main">
|
||||||
<slot/>
|
<slot />
|
||||||
<p>
|
<p>
|
||||||
<br />
|
<br>
|
||||||
<a :href="editLink" target="_blank">
|
<a :href="editLink" target="_blank">
|
||||||
<span>Edit this page on GitHub</span>
|
<span>Edit this page on GitHub</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -103,11 +103,11 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
currentPath () {
|
currentPath() {
|
||||||
return this.$route.matched[0].path
|
return this.$route.matched[0].path
|
||||||
},
|
},
|
||||||
editLink () {
|
editLink() {
|
||||||
const currentPath = this.currentPath
|
const { currentPath } = this
|
||||||
const filePath = currentPath === '' ? '/introduction' : currentPath
|
const filePath = currentPath === '' ? '/introduction' : currentPath
|
||||||
|
|
||||||
return `https://github.com/ueberdosis/tiptap-next/blob/main/docs/src/docPages${filePath}.md`
|
return `https://github.com/ueberdosis/tiptap-next/blob/main/docs/src/docPages${filePath}.md`
|
||||||
@@ -116,13 +116,14 @@ export default {
|
|||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
initSearch() {
|
initSearch() {
|
||||||
|
// eslint-disable-next-line
|
||||||
docsearch({
|
docsearch({
|
||||||
apiKey: '1abe7fb0f0dac150d0e963d2eda930fe',
|
apiKey: '1abe7fb0f0dac150d0e963d2eda930fe',
|
||||||
indexName: 'ueberdosis_tiptap',
|
indexName: 'ueberdosis_tiptap',
|
||||||
inputSelector: '.search',
|
inputSelector: '.search',
|
||||||
debug: false,
|
debug: false,
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
@@ -134,4 +135,4 @@ export default {
|
|||||||
<style lang="scss" src="./fonts.scss"></style>
|
<style lang="scss" src="./fonts.scss"></style>
|
||||||
<style lang="scss" src="./base.scss"></style>
|
<style lang="scss" src="./base.scss"></style>
|
||||||
<style lang="scss" src="./prism.scss"></style>
|
<style lang="scss" src="./prism.scss"></style>
|
||||||
<style lang="scss" src="./style.scss" scoped></style>
|
<style lang="scss" src="./style.scss" scoped></style>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// eslint-disable-next-line
|
||||||
import Prism from 'prismjs'
|
import Prism from 'prismjs'
|
||||||
import 'prismjs/components/prism-jsx.js'
|
import 'prismjs/components/prism-jsx.js'
|
||||||
import 'prismjs/components/prism-scss.js'
|
import 'prismjs/components/prism-scss.js'
|
||||||
@@ -6,7 +7,7 @@ import Demo from '~/components/Demo'
|
|||||||
import Tab from '~/components/Tab'
|
import Tab from '~/components/Tab'
|
||||||
import ReactRenderer from '~/components/ReactRenderer'
|
import ReactRenderer from '~/components/ReactRenderer'
|
||||||
|
|
||||||
export default function (Vue, { router, head, isClient }) {
|
export default function (Vue) {
|
||||||
Vue.component('Layout', App)
|
Vue.component('Layout', App)
|
||||||
Vue.component('Demo', Demo)
|
Vue.component('Demo', Demo)
|
||||||
Vue.component('Tab', Tab)
|
Vue.component('Tab', Tab)
|
||||||
|
|||||||
@@ -35,4 +35,4 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss" scoped></style>
|
<style lang="scss" src="./style.scss" scoped></style>
|
||||||
|
|||||||
@@ -6,4 +6,4 @@
|
|||||||
</Layout>
|
</Layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" src="./style.scss" scoped></style>
|
<style lang="scss" src="./style.scss" scoped></style>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
"build:docs": "yarn --cwd ./docs build",
|
"build:docs": "yarn --cwd ./docs build",
|
||||||
"build:packages": "yarn clean:packages && lerna exec --parallel -- microbundle --compress",
|
"build:packages": "yarn clean:packages && lerna exec --parallel -- microbundle --compress",
|
||||||
"clean:packages": "rm -rf ./packages/*/dist",
|
"clean:packages": "rm -rf ./packages/*/dist",
|
||||||
|
"lint": "eslint --quiet --no-error-on-unmatched-pattern ./",
|
||||||
"test:open": "cypress open --project tests",
|
"test:open": "cypress open --project tests",
|
||||||
"test": "cypress run --project tests",
|
"test": "cypress run --project tests",
|
||||||
"reset": "yarn clean:packages && rm -rf ./**/.cache && rm -rf ./**/node_modules && rm -rf ./yarn.lock && yarn install"
|
"reset": "yarn clean:packages && rm -rf ./**/.cache && rm -rf ./**/node_modules && rm -rf ./yarn.lock && yarn install"
|
||||||
@@ -30,7 +31,15 @@
|
|||||||
"@types/prosemirror-state": "^1.2.5",
|
"@types/prosemirror-state": "^1.2.5",
|
||||||
"@types/prosemirror-transform": "^1.1.1",
|
"@types/prosemirror-transform": "^1.1.1",
|
||||||
"@types/prosemirror-view": "^1.15.0",
|
"@types/prosemirror-view": "^1.15.0",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^4.2.0",
|
||||||
|
"@typescript-eslint/parser": "^4.2.0",
|
||||||
"cypress": "^5.2.0",
|
"cypress": "^5.2.0",
|
||||||
|
"eslint": "^7.9.0",
|
||||||
|
"eslint-config-airbnb-base": "^14.2.0",
|
||||||
|
"eslint-plugin-cypress": "^2.11.1",
|
||||||
|
"eslint-plugin-html": "^6.1.0",
|
||||||
|
"eslint-plugin-import": "^2.22.0",
|
||||||
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
"lerna": "^3.22.1",
|
"lerna": "^3.22.1",
|
||||||
"microbundle": "^0.12.3",
|
"microbundle": "^0.12.3",
|
||||||
"sass-loader": "^9.0.3",
|
"sass-loader": "^9.0.3",
|
||||||
|
|||||||
@@ -1,14 +1,18 @@
|
|||||||
import { EditorState, Transaction } from "prosemirror-state"
|
import { EditorState, Transaction } from 'prosemirror-state'
|
||||||
import { ChainedCommands, Editor, CommandSpec } from "./Editor"
|
import { ChainedCommands, Editor, CommandSpec } from './Editor'
|
||||||
import getAllMethodNames from './utils/getAllMethodNames'
|
import getAllMethodNames from './utils/getAllMethodNames'
|
||||||
|
|
||||||
export default class CommandManager {
|
export default class CommandManager {
|
||||||
|
|
||||||
editor: Editor
|
editor: Editor
|
||||||
|
|
||||||
commands: { [key: string]: any } = {}
|
commands: { [key: string]: any } = {}
|
||||||
|
|
||||||
|
methodNames: string[] = []
|
||||||
|
|
||||||
constructor(editor: Editor) {
|
constructor(editor: Editor) {
|
||||||
this.editor = editor
|
this.editor = editor
|
||||||
|
this.methodNames = getAllMethodNames(this.editor)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -22,7 +26,7 @@ export default class CommandManager {
|
|||||||
throw new Error(`tiptap: command '${name}' is already defined.`)
|
throw new Error(`tiptap: command '${name}' is already defined.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getAllMethodNames(this.editor).includes(name)) {
|
if (this.methodNames.includes(name)) {
|
||||||
throw new Error(`tiptap: '${name}' is a protected name.`)
|
throw new Error(`tiptap: '${name}' is a protected name.`)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,13 +39,13 @@ export default class CommandManager {
|
|||||||
const { commands, editor } = this
|
const { commands, editor } = this
|
||||||
const { state, view } = editor
|
const { state, view } = editor
|
||||||
const command = commands[name]
|
const command = commands[name]
|
||||||
|
|
||||||
if (!command) {
|
if (!command) {
|
||||||
// TODO: prevent vue devtools to throw error
|
// TODO: prevent vue devtools to throw error
|
||||||
// throw new Error(`tiptap: command '${name}' not found.`)
|
// throw new Error(`tiptap: command '${name}' not found.`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return (...args: any) => {
|
return (...args: any) => {
|
||||||
const { tr } = state
|
const { tr } = state
|
||||||
const props = this.buildProps(tr)
|
const props = this.buildProps(tr)
|
||||||
@@ -87,7 +91,7 @@ export default class CommandManager {
|
|||||||
|
|
||||||
return proxy
|
return proxy
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}) as ChainedCommands
|
}) as ChainedCommands
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,16 +112,16 @@ export default class CommandManager {
|
|||||||
.map(([name, command]) => {
|
.map(([name, command]) => {
|
||||||
return [name, (...args: any[]) => command(...args)(props)]
|
return [name, (...args: any[]) => command(...args)(props)]
|
||||||
}))
|
}))
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return props
|
return props
|
||||||
}
|
}
|
||||||
|
|
||||||
public chainableState(tr: Transaction, state: EditorState): EditorState {
|
public chainableState(tr: Transaction, state: EditorState): EditorState {
|
||||||
let selection = tr.selection
|
let { selection } = tr
|
||||||
let doc = tr.doc
|
let { doc } = tr
|
||||||
let storedMarks = tr.storedMarks
|
let { storedMarks } = tr
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
@@ -143,7 +147,7 @@ export default class CommandManager {
|
|||||||
|
|
||||||
return tr
|
return tr
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,4 +2,4 @@ export default abstract class ComponentRenderer {
|
|||||||
|
|
||||||
static type: string
|
static type: string
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { EditorState, Plugin, Transaction } from 'prosemirror-state'
|
import { EditorState, Plugin, Transaction } from 'prosemirror-state'
|
||||||
import { EditorView} from 'prosemirror-view'
|
import { EditorView } from 'prosemirror-view'
|
||||||
import { Schema, DOMParser, DOMSerializer } from 'prosemirror-model'
|
import { Schema, DOMParser } from 'prosemirror-model'
|
||||||
import magicMethods from './utils/magicMethods'
|
import magicMethods from './utils/magicMethods'
|
||||||
import elementFromString from './utils/elementFromString'
|
import elementFromString from './utils/elementFromString'
|
||||||
import nodeIsActive from './utils/nodeIsActive'
|
import nodeIsActive from './utils/nodeIsActive'
|
||||||
@@ -16,9 +16,8 @@ import EventEmitter from './EventEmitter'
|
|||||||
import Extension from './Extension'
|
import Extension from './Extension'
|
||||||
import Node from './Node'
|
import Node from './Node'
|
||||||
import Mark from './Mark'
|
import Mark from './Mark'
|
||||||
import ComponentRenderer from './ComponentRenderer'
|
|
||||||
import defaultPlugins from './plugins'
|
import defaultPlugins from './plugins'
|
||||||
import * as commands from './commands'
|
import * as coreCommands from './commands'
|
||||||
|
|
||||||
export type Command = (props: {
|
export type Command = (props: {
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
@@ -41,14 +40,14 @@ export interface Commands {}
|
|||||||
export type CommandNames = Extract<keyof Commands, string>
|
export type CommandNames = Extract<keyof Commands, string>
|
||||||
|
|
||||||
export type SingleCommands = {
|
export type SingleCommands = {
|
||||||
[Command in keyof Commands]: Commands[Command] extends (...args: any[]) => any
|
[Item in keyof Commands]: Commands[Item] extends (...args: any[]) => any
|
||||||
? (...args: Parameters<Commands[Command]>) => boolean
|
? (...args: Parameters<Commands[Item]>) => boolean
|
||||||
: never
|
: never
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ChainedCommands = {
|
export type ChainedCommands = {
|
||||||
[Command in keyof Commands]: Commands[Command] extends (...args: any[]) => any
|
[Item in keyof Commands]: Commands[Item] extends (...args: any[]) => any
|
||||||
? (...args: Parameters<Commands[Command]>) => ChainedCommands
|
? (...args: Parameters<Commands[Item]>) => ChainedCommands
|
||||||
: never
|
: never
|
||||||
} & {
|
} & {
|
||||||
run: () => boolean
|
run: () => boolean
|
||||||
@@ -77,14 +76,23 @@ declare module './Editor' {
|
|||||||
export class Editor extends EventEmitter {
|
export class Editor extends EventEmitter {
|
||||||
|
|
||||||
public renderer!: any
|
public renderer!: any
|
||||||
|
|
||||||
private proxy!: Editor
|
private proxy!: Editor
|
||||||
|
|
||||||
private commandManager!: CommandManager
|
private commandManager!: CommandManager
|
||||||
|
|
||||||
private extensionManager!: ExtensionManager
|
private extensionManager!: ExtensionManager
|
||||||
|
|
||||||
private css!: HTMLStyleElement
|
private css!: HTMLStyleElement
|
||||||
|
|
||||||
public schema!: Schema
|
public schema!: Schema
|
||||||
|
|
||||||
public view!: EditorView
|
public view!: EditorView
|
||||||
|
|
||||||
public selection = { from: 0, to: 0 }
|
public selection = { from: 0, to: 0 }
|
||||||
|
|
||||||
public isFocused = false
|
public isFocused = false
|
||||||
|
|
||||||
public options: EditorOptions = {
|
public options: EditorOptions = {
|
||||||
element: document.createElement('div'),
|
element: document.createElement('div'),
|
||||||
content: '',
|
content: '',
|
||||||
@@ -109,7 +117,7 @@ export class Editor extends EventEmitter {
|
|||||||
this.createSchema()
|
this.createSchema()
|
||||||
this.extensionManager.resolveConfigs()
|
this.extensionManager.resolveConfigs()
|
||||||
this.createView()
|
this.createView()
|
||||||
this.registerCommands(commands)
|
this.registerCommands(coreCommands)
|
||||||
|
|
||||||
if (this.options.injectCSS) {
|
if (this.options.injectCSS) {
|
||||||
require('./style.css')
|
require('./style.css')
|
||||||
@@ -123,6 +131,7 @@ export class Editor extends EventEmitter {
|
|||||||
*
|
*
|
||||||
* @param name The name of the command
|
* @param name The name of the command
|
||||||
*/
|
*/
|
||||||
|
// eslint-disable-next-line
|
||||||
private __get(name: string) {
|
private __get(name: string) {
|
||||||
return this.commandManager.runSingleCommand(name)
|
return this.commandManager.runSingleCommand(name)
|
||||||
}
|
}
|
||||||
@@ -190,7 +199,7 @@ export class Editor extends EventEmitter {
|
|||||||
* @param plugin A ProseMirror plugin
|
* @param plugin A ProseMirror plugin
|
||||||
* @param handlePlugins Control how to merge the plugin into the existing plugins.
|
* @param handlePlugins Control how to merge the plugin into the existing plugins.
|
||||||
*/
|
*/
|
||||||
public registerPlugin(plugin: Plugin, handlePlugins?: (plugin: Plugin, plugins: Plugin[]) => Plugin[]) {
|
public registerPlugin(plugin: Plugin, handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[]) {
|
||||||
const plugins = typeof handlePlugins === 'function'
|
const plugins = typeof handlePlugins === 'function'
|
||||||
? handlePlugins(plugin, this.state.plugins)
|
? handlePlugins(plugin, this.state.plugins)
|
||||||
: [plugin, ...this.state.plugins]
|
: [plugin, ...this.state.plugins]
|
||||||
@@ -333,7 +342,7 @@ export class Editor extends EventEmitter {
|
|||||||
|
|
||||||
if (schemaType === 'node') {
|
if (schemaType === 'node') {
|
||||||
return nodeIsActive(this.state, this.schema.nodes[name], attrs)
|
return nodeIsActive(this.state, this.schema.nodes[name], attrs)
|
||||||
} else if (schemaType === 'mark') {
|
} if (schemaType === 'mark') {
|
||||||
return markIsActive(this.state, this.schema.marks[name])
|
return markIsActive(this.state, this.schema.marks[name])
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,5 +390,5 @@ export class Editor extends EventEmitter {
|
|||||||
this.removeAllListeners()
|
this.removeAllListeners()
|
||||||
removeElement(this.css)
|
removeElement(this.css)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
export default class EventEmitter {
|
export default class EventEmitter {
|
||||||
|
|
||||||
_callbacks: { [key: string]: Function[] } = {}
|
private callbacks: { [key: string]: Function[] } = {}
|
||||||
|
|
||||||
on(event: string, fn: Function) {
|
public on(event: string, fn: Function) {
|
||||||
if (!this._callbacks[event]) {
|
if (!this.callbacks[event]) {
|
||||||
this._callbacks[event] = []
|
this.callbacks[event] = []
|
||||||
}
|
}
|
||||||
|
|
||||||
this._callbacks[event].push(fn)
|
this.callbacks[event].push(fn)
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
emit(event: string, ...args: any) {
|
protected emit(event: string, ...args: any) {
|
||||||
const callbacks = this._callbacks[event]
|
const callbacks = this.callbacks[event]
|
||||||
|
|
||||||
if (callbacks) {
|
if (callbacks) {
|
||||||
callbacks.forEach(callback => callback.apply(this, args))
|
callbacks.forEach(callback => callback.apply(this, args))
|
||||||
@@ -22,21 +22,21 @@ export default class EventEmitter {
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
off(event: string, fn?: Function) {
|
public off(event: string, fn?: Function) {
|
||||||
const callbacks = this._callbacks[event]
|
const callbacks = this.callbacks[event]
|
||||||
|
|
||||||
if (callbacks) {
|
if (callbacks) {
|
||||||
if (fn) {
|
if (fn) {
|
||||||
this._callbacks[event] = callbacks.filter(callback => callback !== fn)
|
this.callbacks[event] = callbacks.filter(callback => callback !== fn)
|
||||||
} else {
|
} else {
|
||||||
delete this._callbacks[event]
|
delete this.callbacks[event]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
removeAllListeners() {
|
protected removeAllListeners() {
|
||||||
this._callbacks = {}
|
this.callbacks = {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,11 @@ export default class Extension<
|
|||||||
Methods extends ExtensionMethods<Props, Options> = ExtensionMethods<Props, Options>
|
Methods extends ExtensionMethods<Props, Options> = ExtensionMethods<Props, Options>
|
||||||
> {
|
> {
|
||||||
type = 'extension'
|
type = 'extension'
|
||||||
|
|
||||||
config: AnyObject = {}
|
config: AnyObject = {}
|
||||||
configs: Configs = {}
|
|
||||||
|
configs: Configs = {}
|
||||||
|
|
||||||
options: Partial<Options> = {}
|
options: Partial<Options> = {}
|
||||||
|
|
||||||
protected storeConfig(key: string, value: any, stategy: MergeStrategy) {
|
protected storeConfig(key: string, value: any, stategy: MergeStrategy) {
|
||||||
@@ -102,12 +105,10 @@ export default class Extension<
|
|||||||
this.storeConfig(key, value, 'extend')
|
this.storeConfig(key, value, 'extend')
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
public create() {
|
|
||||||
type ParentOptions = Options
|
|
||||||
|
|
||||||
return <Options = ParentOptions>(options?: Partial<NoInfer<Options>>) => {
|
public create() {
|
||||||
return cloneDeep(this, true).configure(options as Options)
|
return <NewOptions = Options>(options?: Partial<NoInfer<NewOptions>>) => {
|
||||||
|
return cloneDeep(this, true).configure(options as NewOptions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ import collect from 'collect.js'
|
|||||||
import { Plugin } from 'prosemirror-state'
|
import { Plugin } from 'prosemirror-state'
|
||||||
import { keymap } from 'prosemirror-keymap'
|
import { keymap } from 'prosemirror-keymap'
|
||||||
import { Schema } from 'prosemirror-model'
|
import { Schema } from 'prosemirror-model'
|
||||||
|
// import { Schema, Node as ProsemirrorNode } from 'prosemirror-model'
|
||||||
import { inputRules } from 'prosemirror-inputrules'
|
import { inputRules } from 'prosemirror-inputrules'
|
||||||
import { EditorView, Decoration } from 'prosemirror-view'
|
// import { EditorView, Decoration } from 'prosemirror-view'
|
||||||
import { Node as ProsemirrorNode } from 'prosemirror-model'
|
|
||||||
import { Editor } from './Editor'
|
import { Editor } from './Editor'
|
||||||
import capitalize from './utils/capitalize'
|
// import capitalize from './utils/capitalize'
|
||||||
import { Extensions } from './types'
|
import { Extensions } from './types'
|
||||||
import getTopNodeFromExtensions from './utils/getTopNodeFromExtensions'
|
import getTopNodeFromExtensions from './utils/getTopNodeFromExtensions'
|
||||||
import getNodesFromExtensions from './utils/getNodesFromExtensions'
|
import getNodesFromExtensions from './utils/getNodesFromExtensions'
|
||||||
@@ -18,6 +19,7 @@ import getSchema from './utils/getSchema'
|
|||||||
export default class ExtensionManager {
|
export default class ExtensionManager {
|
||||||
|
|
||||||
editor: Editor
|
editor: Editor
|
||||||
|
|
||||||
extensions: Extensions
|
extensions: Extensions
|
||||||
|
|
||||||
constructor(extensions: Extensions, editor: Editor) {
|
constructor(extensions: Extensions, editor: Editor) {
|
||||||
@@ -28,17 +30,27 @@ export default class ExtensionManager {
|
|||||||
resolveConfigs() {
|
resolveConfigs() {
|
||||||
this.extensions.forEach(extension => {
|
this.extensions.forEach(extension => {
|
||||||
const { editor } = this
|
const { editor } = this
|
||||||
const name = extension.config.name
|
const { name } = extension.config
|
||||||
const options = deepmerge(extension.config.defaults, extension.options)
|
const options = deepmerge(extension.config.defaults, extension.options)
|
||||||
const type = extension.type === 'node'
|
const type = extension.type === 'node'
|
||||||
? editor.schema.nodes[name]
|
? editor.schema.nodes[name]
|
||||||
: editor.schema.marks[name]
|
: editor.schema.marks[name]
|
||||||
|
|
||||||
resolveExtensionConfig(extension, 'commands', { name, options, editor, type })
|
resolveExtensionConfig(extension, 'commands', {
|
||||||
resolveExtensionConfig(extension, 'inputRules', { name, options, editor, type })
|
name, options, editor, type,
|
||||||
resolveExtensionConfig(extension, 'pasteRules', { name, options, editor, type })
|
})
|
||||||
resolveExtensionConfig(extension, 'keys', { name, options, editor, type })
|
resolveExtensionConfig(extension, 'inputRules', {
|
||||||
resolveExtensionConfig(extension, 'plugins', { name, options, editor, type })
|
name, options, editor, type,
|
||||||
|
})
|
||||||
|
resolveExtensionConfig(extension, 'pasteRules', {
|
||||||
|
name, options, editor, type,
|
||||||
|
})
|
||||||
|
resolveExtensionConfig(extension, 'keys', {
|
||||||
|
name, options, editor, type,
|
||||||
|
})
|
||||||
|
resolveExtensionConfig(extension, 'plugins', {
|
||||||
|
name, options, editor, type,
|
||||||
|
})
|
||||||
|
|
||||||
if (extension.config.commands) {
|
if (extension.config.commands) {
|
||||||
editor.registerCommands(extension.config.commands)
|
editor.registerCommands(extension.config.commands)
|
||||||
@@ -57,7 +69,7 @@ export default class ExtensionManager {
|
|||||||
get nodes(): any {
|
get nodes(): any {
|
||||||
return getNodesFromExtensions(this.extensions)
|
return getNodesFromExtensions(this.extensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
get marks(): any {
|
get marks(): any {
|
||||||
return getMarksFromExtensions(this.extensions)
|
return getMarksFromExtensions(this.extensions)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ export default class Mark<
|
|||||||
this.storeConfig('schema', value, 'overwrite')
|
this.storeConfig('schema', value, 'overwrite')
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { deleteSelection as originalDeleteSelection } from 'prosemirror-commands'
|
import { deleteSelection as originalDeleteSelection } from 'prosemirror-commands'
|
||||||
|
import { Command } from '../Editor'
|
||||||
|
|
||||||
type DeleteSelectionCommand = () => Command
|
type DeleteSelectionCommand = () => Command
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { Editor, Command } from '../Editor'
|
|
||||||
import { TextSelection } from 'prosemirror-state'
|
import { TextSelection } from 'prosemirror-state'
|
||||||
|
import { Editor, Command } from '../Editor'
|
||||||
import minMax from '../utils/minMax'
|
import minMax from '../utils/minMax'
|
||||||
|
|
||||||
|
type Position = 'start' | 'end' | number | boolean | null
|
||||||
type FocusCommand = (position?: Position) => Command
|
type FocusCommand = (position?: Position) => Command
|
||||||
|
|
||||||
declare module '../Editor' {
|
declare module '../Editor' {
|
||||||
@@ -15,8 +16,6 @@ interface ResolvedSelection {
|
|||||||
to: number,
|
to: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
type Position = 'start' | 'end' | number | boolean | null
|
|
||||||
|
|
||||||
function resolveSelection(editor: Editor, position: Position = null): ResolvedSelection {
|
function resolveSelection(editor: Editor, position: Position = null): ResolvedSelection {
|
||||||
if (position === null) {
|
if (position === null) {
|
||||||
return editor.selection
|
return editor.selection
|
||||||
@@ -31,7 +30,7 @@ function resolveSelection(editor: Editor, position: Position = null): ResolvedSe
|
|||||||
|
|
||||||
if (position === 'end') {
|
if (position === 'end') {
|
||||||
const { size } = editor.state.doc.content
|
const { size } = editor.state.doc.content
|
||||||
|
|
||||||
return {
|
return {
|
||||||
from: size,
|
from: size,
|
||||||
to: size - 1, // TODO: -1 only for nodes with content
|
to: size - 1, // TODO: -1 only for nodes with content
|
||||||
@@ -54,9 +53,9 @@ export const focus: FocusCommand = (position = null) => ({ editor, view, tr }) =
|
|||||||
const resolvedFrom = minMax(from, 0, doc.content.size)
|
const resolvedFrom = minMax(from, 0, doc.content.size)
|
||||||
const resolvedEnd = minMax(to, 0, doc.content.size)
|
const resolvedEnd = minMax(to, 0, doc.content.size)
|
||||||
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
|
const selection = TextSelection.create(doc, resolvedFrom, resolvedEnd)
|
||||||
|
|
||||||
tr.setSelection(selection)
|
tr.setSelection(selection)
|
||||||
view.focus()
|
view.focus()
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { DOMParser } from 'prosemirror-model'
|
import { DOMParser } from 'prosemirror-model'
|
||||||
import { Selection, Transaction } from 'prosemirror-state'
|
import { Selection, Transaction } from 'prosemirror-state'
|
||||||
|
import { ReplaceStep, ReplaceAroundStep } from 'prosemirror-transform'
|
||||||
import { Command } from '../Editor'
|
import { Command } from '../Editor'
|
||||||
import elementFromString from '../utils/elementFromString'
|
import elementFromString from '../utils/elementFromString'
|
||||||
import {ReplaceStep, ReplaceAroundStep} from "prosemirror-transform"
|
|
||||||
|
|
||||||
type InsertHTMLCommand = (value: string) => Command
|
type InsertHTMLCommand = (value: string) => Command
|
||||||
|
|
||||||
@@ -15,13 +15,13 @@ declare module '../Editor' {
|
|||||||
// TODO: move to utils
|
// TODO: move to utils
|
||||||
// https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.js#L466
|
// https://github.com/ProseMirror/prosemirror-state/blob/master/src/selection.js#L466
|
||||||
function selectionToInsertionEnd(tr: Transaction, startLen: number, bias: number) {
|
function selectionToInsertionEnd(tr: Transaction, startLen: number, bias: number) {
|
||||||
let last = tr.steps.length - 1
|
const last = tr.steps.length - 1
|
||||||
if (last < startLen) return
|
if (last < startLen) return
|
||||||
let step = tr.steps[last]
|
const step = tr.steps[last]
|
||||||
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return
|
if (!(step instanceof ReplaceStep || step instanceof ReplaceAroundStep)) return
|
||||||
let map = tr.mapping.maps[last]
|
const map = tr.mapping.maps[last]
|
||||||
let end = 0
|
let end = 0
|
||||||
map.forEach((_from, _to, _newFrom, newTo) => { if (end == 0) end = newTo })
|
map.forEach((_from, _to, _newFrom, newTo) => { if (end === 0) end = newTo })
|
||||||
tr.setSelection(Selection.near(tr.doc.resolve(end as unknown as number), bias))
|
tr.setSelection(Selection.near(tr.doc.resolve(end as unknown as number), bias))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,4 +34,4 @@ export const insertHTML: InsertHTMLCommand = value => ({ tr, state }) => {
|
|||||||
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
selectionToInsertionEnd(tr, tr.steps.length - 1, -1)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { liftListItem as originalLiftListItem } from 'prosemirror-schema-list'
|
import { liftListItem as originalLiftListItem } from 'prosemirror-schema-list'
|
||||||
import { NodeType } from 'prosemirror-model'
|
import { NodeType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getNodeType from '../utils/getNodeType'
|
import getNodeType from '../utils/getNodeType'
|
||||||
|
|
||||||
type LiftListItem = (typeOrName: string | NodeType) => Command
|
type LiftListItem = (typeOrName: string | NodeType) => Command
|
||||||
@@ -11,7 +11,7 @@ declare module '../Editor' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const liftListItem: LiftListItem = (typeOrName) => ({ state, dispatch }) => {
|
export const liftListItem: LiftListItem = typeOrName => ({ state, dispatch }) => {
|
||||||
const type = getNodeType(typeOrName, state.schema)
|
const type = getNodeType(typeOrName, state.schema)
|
||||||
|
|
||||||
return originalLiftListItem(type)(state, dispatch)
|
return originalLiftListItem(type)(state, dispatch)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { MarkType } from 'prosemirror-model'
|
import { MarkType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getMarkType from '../utils/getMarkType'
|
import getMarkType from '../utils/getMarkType'
|
||||||
import getMarkRange from '../utils/getMarkRange'
|
import getMarkRange from '../utils/getMarkRange'
|
||||||
|
|
||||||
@@ -11,10 +11,11 @@ declare module '../Editor' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeMark: RemoveMarkCommand = (typeOrName) => ({ tr, state }) => {
|
export const removeMark: RemoveMarkCommand = typeOrName => ({ tr, state }) => {
|
||||||
const { selection } = tr
|
const { selection } = tr
|
||||||
const type = getMarkType(typeOrName, state.schema)
|
const type = getMarkType(typeOrName, state.schema)
|
||||||
let { from, to, $from, empty } = selection
|
let { from, to } = selection
|
||||||
|
const { $from, empty } = selection
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
const range = getMarkRange($from, type)
|
const range = getMarkRange($from, type)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ declare module '../Editor' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const removeMarks: RemoveMarksCommand = () => ({ tr, state, view }) => {
|
export const removeMarks: RemoveMarksCommand = () => ({ tr, state }) => {
|
||||||
const { selection } = tr
|
const { selection } = tr
|
||||||
const { from, to, empty } = selection
|
const { from, to, empty } = selection
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ export const removeMarks: RemoveMarksCommand = () => ({ tr, state, view }) => {
|
|||||||
|
|
||||||
Object
|
Object
|
||||||
.entries(state.schema.marks)
|
.entries(state.schema.marks)
|
||||||
.forEach(([name, mark]) => {
|
.forEach(([, mark]) => {
|
||||||
tr.removeMark(from, to, mark as any)
|
tr.removeMark(from, to, mark as any)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { NodeType } from 'prosemirror-model'
|
import { NodeType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getNodeType from '../utils/getNodeType'
|
import getNodeType from '../utils/getNodeType'
|
||||||
|
|
||||||
interface Range {
|
interface Range {
|
||||||
@@ -29,7 +29,7 @@ export const replaceWithNode: ReplaceWithNodeCommand = (typeOrName, attrs = {},
|
|||||||
if (!$from.parent.canReplaceWith(index, index, type)) {
|
if (!$from.parent.canReplaceWith(index, index, type)) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
view.dispatch(tr.replaceWith(from, to, type.create(attrs)))
|
view.dispatch(tr.replaceWith(from, to, type.create(attrs)))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { selectAll as originalSelectAll } from 'prosemirror-commands'
|
import { selectAll as originalSelectAll } from 'prosemirror-commands'
|
||||||
|
import { Command } from '../Editor'
|
||||||
|
|
||||||
type SelectAllCommand = () => Command
|
type SelectAllCommand = () => Command
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { selectParentNode as originalSelectParentNode } from 'prosemirror-commands'
|
import { selectParentNode as originalSelectParentNode } from 'prosemirror-commands'
|
||||||
|
import { Command } from '../Editor'
|
||||||
|
|
||||||
type SelectParentNodeCommand = () => Command
|
type SelectParentNodeCommand = () => Command
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { TextSelection } from 'prosemirror-state'
|
import { TextSelection } from 'prosemirror-state'
|
||||||
|
import { Command } from '../Editor'
|
||||||
|
|
||||||
type SetContentCommand = (
|
type SetContentCommand = (
|
||||||
content: string,
|
content: string,
|
||||||
@@ -18,7 +18,7 @@ export const setContent: SetContentCommand = (content = '', emitUpdate = false,
|
|||||||
const { doc } = tr
|
const { doc } = tr
|
||||||
const document = createDocument(content, parseOptions)
|
const document = createDocument(content, parseOptions)
|
||||||
const selection = TextSelection.create(doc, 0, doc.content.size)
|
const selection = TextSelection.create(doc, 0, doc.content.size)
|
||||||
|
|
||||||
tr.setSelection(selection)
|
tr.setSelection(selection)
|
||||||
.replaceSelectionWith(document, false)
|
.replaceSelectionWith(document, false)
|
||||||
.setMeta('preventUpdate', !emitUpdate)
|
.setMeta('preventUpdate', !emitUpdate)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
|
import { sinkListItem as originalSinkListItem } from 'prosemirror-schema-list'
|
||||||
import { NodeType } from 'prosemirror-model'
|
import { NodeType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getNodeType from '../utils/getNodeType'
|
import getNodeType from '../utils/getNodeType'
|
||||||
|
|
||||||
type SinkListItem = (typeOrName: string | NodeType) => Command
|
type SinkListItem = (typeOrName: string | NodeType) => Command
|
||||||
@@ -11,7 +11,7 @@ declare module '../Editor' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const sinkListItem: SinkListItem = (typeOrName) => ({ state, dispatch }) => {
|
export const sinkListItem: SinkListItem = typeOrName => ({ state, dispatch }) => {
|
||||||
const type = getNodeType(typeOrName, state.schema)
|
const type = getNodeType(typeOrName, state.schema)
|
||||||
|
|
||||||
return originalSinkListItem(type)(state, dispatch)
|
return originalSinkListItem(type)(state, dispatch)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { splitListItem as originalSplitListItem } from 'prosemirror-schema-list'
|
import { splitListItem as originalSplitListItem } from 'prosemirror-schema-list'
|
||||||
import { NodeType } from 'prosemirror-model'
|
import { NodeType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getNodeType from '../utils/getNodeType'
|
import getNodeType from '../utils/getNodeType'
|
||||||
|
|
||||||
type SplitListItem = (typeOrName: string | NodeType) => Command
|
type SplitListItem = (typeOrName: string | NodeType) => Command
|
||||||
@@ -11,7 +11,7 @@ declare module '../Editor' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const splitListItem: SplitListItem = (typeOrName) => ({ state, dispatch }) => {
|
export const splitListItem: SplitListItem = typeOrName => ({ state, dispatch }) => {
|
||||||
const type = getNodeType(typeOrName, state.schema)
|
const type = getNodeType(typeOrName, state.schema)
|
||||||
|
|
||||||
return originalSplitListItem(type)(state, dispatch)
|
return originalSplitListItem(type)(state, dispatch)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { wrapInList, liftListItem } from 'prosemirror-schema-list'
|
import { wrapInList, liftListItem } from 'prosemirror-schema-list'
|
||||||
import { findParentNode } from 'prosemirror-utils'
|
import { findParentNode } from 'prosemirror-utils'
|
||||||
import { Node, NodeType, Schema } from 'prosemirror-model'
|
import { Node, NodeType, Schema } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getNodeType from '../utils/getNodeType'
|
import getNodeType from '../utils/getNodeType'
|
||||||
|
|
||||||
type ToggleListCommand = (
|
type ToggleListCommand = (
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { toggleMark as originalToggleMark } from 'prosemirror-commands'
|
import { toggleMark as originalToggleMark } from 'prosemirror-commands'
|
||||||
import { MarkType } from 'prosemirror-model'
|
import { MarkType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getMarkType from '../utils/getMarkType'
|
import getMarkType from '../utils/getMarkType'
|
||||||
|
|
||||||
type ToggleMarkCommand = (typeOrName: string | MarkType) => Command
|
type ToggleMarkCommand = (typeOrName: string | MarkType) => Command
|
||||||
@@ -11,7 +11,7 @@ declare module '../Editor' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const toggleMark: ToggleMarkCommand = (typeOrName) => ({ state, dispatch }) => {
|
export const toggleMark: ToggleMarkCommand = typeOrName => ({ state, dispatch }) => {
|
||||||
const type = getMarkType(typeOrName, state.schema)
|
const type = getMarkType(typeOrName, state.schema)
|
||||||
|
|
||||||
return originalToggleMark(type)(state, dispatch)
|
return originalToggleMark(type)(state, dispatch)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ export const toggleNode: ToggleNodeCommand = (typeOrName, toggleTypeOrName, attr
|
|||||||
|
|
||||||
if (isActive) {
|
if (isActive) {
|
||||||
return setBlockType(toggleType)(state, dispatch)
|
return setBlockType(toggleType)(state, dispatch)
|
||||||
} else {
|
|
||||||
return setBlockType(type, attrs)(state, dispatch)
|
|
||||||
}
|
}
|
||||||
|
return setBlockType(type, attrs)(state, dispatch)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from '../Editor'
|
|
||||||
import { MarkType } from 'prosemirror-model'
|
import { MarkType } from 'prosemirror-model'
|
||||||
|
import { Command } from '../Editor'
|
||||||
import getMarkType from '../utils/getMarkType'
|
import getMarkType from '../utils/getMarkType'
|
||||||
import getMarkRange from '../utils/getMarkRange'
|
import getMarkRange from '../utils/getMarkRange'
|
||||||
|
|
||||||
@@ -16,7 +16,8 @@ declare module '../Editor' {
|
|||||||
|
|
||||||
export const updateMark: UpdateMarkCommand = (typeOrName, attrs = {}) => ({ tr, state }) => {
|
export const updateMark: UpdateMarkCommand = (typeOrName, attrs = {}) => ({ tr, state }) => {
|
||||||
const { selection, doc } = tr
|
const { selection, doc } = tr
|
||||||
let { from, to, $from, empty } = selection
|
let { from, to } = selection
|
||||||
|
const { $from, empty } = selection
|
||||||
const type = getMarkType(typeOrName, state.schema)
|
const type = getMarkType(typeOrName, state.schema)
|
||||||
|
|
||||||
if (empty) {
|
if (empty) {
|
||||||
|
|||||||
@@ -12,4 +12,4 @@ export default function (regexp: RegExp, type: NodeType, getAttrs?: Function) {
|
|||||||
|
|
||||||
return tr
|
return tr
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ export default function (regexp: RegExp, type: MarkType, getAttrs?: Function) {
|
|||||||
|
|
||||||
const handler = (fragment: Fragment, parent?: any) => {
|
const handler = (fragment: Fragment, parent?: any) => {
|
||||||
const nodes: any[] = []
|
const nodes: any[] = []
|
||||||
|
|
||||||
fragment.forEach(child => {
|
fragment.forEach(child => {
|
||||||
if (child.isText && child.text) {
|
if (child.isText && child.text) {
|
||||||
const { text } = child
|
const { text } = child
|
||||||
let pos = 0
|
let pos = 0
|
||||||
let match
|
let match
|
||||||
|
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
while ((match = regexp.exec(text)) !== null) {
|
while ((match = regexp.exec(text)) !== null) {
|
||||||
const m = match.length - 1
|
const m = match.length - 1
|
||||||
|
|||||||
@@ -6,4 +6,4 @@ export default (editor: Editor) => new Plugin({
|
|||||||
props: {
|
props: {
|
||||||
editable: () => editor.options.editable,
|
editable: () => editor.options.editable,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ export default (editor: Editor) => new Plugin({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user