Merge branch 'main' of https://github.com/ueberdosis/tiptap-next into feature/replace-classes

This commit is contained in:
Philipp Kühn
2020-09-08 09:01:29 +02:00
58 changed files with 1063 additions and 254 deletions

View File

@@ -21,6 +21,7 @@ module.exports = {
typeName: 'DocPage',
baseDir: './src/docPages',
template: './src/templates/DocPage',
index: './introduction',
plugins: [
'@gridsome/remark-prismjs',
'remark-container',
@@ -35,6 +36,12 @@ module.exports = {
}
},
},
{
use: 'gridsome-plugin-simple-analytics',
options: {
domain: 'data.tiptap.dev',
},
},
],
chainWebpack(config) {
// Load variables for all vue-files

View File

@@ -10,11 +10,12 @@
"@gridsome/remark-prismjs": "^0.4.0",
"@gridsome/source-filesystem": "^0.6.2",
"@gridsome/transformer-json": "^0.2.1",
"@gridsome/vue-remark": "^0.2.0",
"@gridsome/vue-remark": "^0.2.4",
"@mvasilkov/outdent": "^1.0.4",
"collect.js": "^4.28.2",
"globby": "^11.0.0",
"gridsome": "0.7.20",
"gridsome-plugin-simple-analytics": "^1.1.0",
"raw-loader": "^4.0.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
@@ -23,12 +24,12 @@
"vue-github-button": "^1.1.2"
},
"devDependencies": {
"@babel/preset-env": "^7.11.0",
"@babel/preset-env": "^7.11.5",
"@babel/preset-react": "^7.10.4",
"html-loader": "^1.1.0",
"node-sass": "^4.14.1",
"sass-loader": "^9.0.3",
"style-resources-loader": "^1.3.3",
"ts-loader": "^8.0.2"
"ts-loader": "^8.0.3"
}
}

View File

@@ -5,7 +5,7 @@
<component :is="mainFile" v-if="mode === 'vue'" />
<react-renderer :component="mainFile" v-if="mode === 'react'" />
</div>
<div class="demo__source">
<div class="demo__source" v-if="!hideSourceCode">
<div class="demo__tabs" v-if="showFileNames">
<button
class="demo__tab"
@@ -62,6 +62,11 @@ export default {
type: String,
default: null,
},
hideSourceCode: {
type: Boolean,
default: false,
}
},
data() {

View File

@@ -6,9 +6,9 @@
&__preview {
padding: 1.5rem;
border: 1px solid rgba($colorBlack, 0.1);
border-bottom-width: 0;
border-top-left-radius: inherit;
border-top-right-radius: inherit;
border-bottom-width: 0;
}
&__source {
@@ -53,11 +53,14 @@
display: flex;
justify-content: space-between;
width: 100%;
padding: 1rem 1.5rem;
padding: 0.5rem 1.5rem;
border: 1px solid rgba($colorWhite, 0.1);
border: 1px solid rgba($colorBlack, 0.1);
border-top-width: 0;
border-bottom-left-radius: inherit;
border-bottom-right-radius: inherit;
border-top-width: 0;
background-color: rgba($colorBlack, 0.9);
color: $colorWhite;
}
&__link {

View File

@@ -1,6 +1,11 @@
context('basic', () => {
beforeEach(() => {
cy.visit('/examples/basic')
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.setContent('<p>foo</p>')
})
})
describe('export', () => {
@@ -41,7 +46,7 @@ context('basic', () => {
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.insertText('bar')
editor.focus(1).insertText('bar')
cy.get('.ProseMirror p:first').should('contain', 'barfoo')
})
})

View File

@@ -1,5 +1,48 @@
<template>
<editor-content :editor="editor" />
<div>
<div v-if="editor">
<button @click="editor.focus().removeMarks()">
clear format
</button>
<button @click="editor.focus().bold()" :class="{ 'is-active': editor.isActive('bold') }">
bold
</button>
<button @click="editor.focus().italic()" :class="{ 'is-active': editor.isActive('italic') }">
italic
</button>
<button @click="editor.focus().code()" :class="{ 'is-active': editor.isActive('code') }">
code
</button>
<button @click="editor.focus().codeBlock()" :class="{ 'is-active': editor.isActive('code_block') }">
code_block
</button>
<button @click="editor.focus().heading({ level: 1 })" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }">
h1
</button>
<button @click="editor.focus().heading({ level: 2 })" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }">
h2
</button>
<button @click="editor.focus().heading({ level: 3 })" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }">
h3
</button>
<button @click="editor.focus().heading({ level: 4 })" :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }">
h4
</button>
<button @click="editor.focus().heading({ level: 5 })" :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }">
h5
</button>
<button @click="editor.focus().heading({ level: 6 })" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }">
h6
</button>
<button @click="editor.focus().undo()">
undo
</button>
<button @click="editor.focus().redo()">
redo
</button>
</div>
<editor-content :editor="editor" />
</div>
</template>
<script>
@@ -18,7 +61,10 @@ export default {
mounted() {
this.editor = new Editor({
content: '<p>foo</p>',
content: `
<h2>Hey there!</h2>
<p>This editor is based on Prosemirror, fully extendable and renderless. You can easily add custom nodes as Vue components.</p>
`,
extensions: defaultExtensions(),
})

View File

@@ -1,3 +0,0 @@
.this-is-a-test {
color: black;
}

View File

@@ -0,0 +1,36 @@
context('history', () => {
beforeEach(() => {
cy.visit('/examples/history')
})
describe('undo', () => {
it('should not have a mistake', () => {
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
const html = editor.html()
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
})
})
it('should have a mistake', () => {
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
const html = editor.html()
editor.insertText('Mistake')
cy.get('.ProseMirror h2:first').should('contain', 'Mistake')
})
})
it('the mistake should be removed again', () => {
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
const html = editor.html()
editor.undo()
cy.get('.ProseMirror h2:first').should('not.contain', 'Mistake')
})
})
})
})

View File

@@ -0,0 +1,49 @@
<template>
<div>
<div v-if="editor">
<button @click="editor.focus().undo()">
undo
</button>
<button @click="editor.focus().redo()">
redo
</button>
</div>
<editor-content :editor="editor" />
</div>
</template>
<script>
import { Editor, EditorContent, defaultExtensions } from '@tiptap/vue-starter-kit'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
content: `
<h2>
History
</h2>
<p>
Try to change some content here. With the <code>History</code> extension you are able to undo and redo your changes. You can also use keyboard shortcuts for this (<code>Control/Command + Z</code> and <code>Control/Command + Shift + Z</code>).
</p>
`,
extensions: defaultExtensions(),
})
window.editor = this.editor
},
beforeDestroy() {
this.editor.destroy()
},
}
</script>

View File

@@ -0,0 +1,126 @@
context('markdown-shortcuts', () => {
beforeEach(() => {
cy.visit('/examples/markdown-shortcuts')
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.setContent('<p></p>')
})
})
describe('headlines', () => {
it('should make a h1', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('# Headline', {force: true})
.contains('h1', 'Headline')
})
})
it('should make a h2', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('## Headline', {force: true})
.contains('h2', 'Headline')
})
})
it('should make a h3', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('### Headline', {force: true})
.contains('h3', 'Headline')
})
})
it('should make a h4', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('#### Headline', {force: true})
.contains('h4', 'Headline')
})
})
it('should make a h5', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('##### Headline', {force: true})
.contains('h5', 'Headline')
})
})
it('should make a h6', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('###### Headline', {force: true})
.contains('h6', 'Headline')
})
})
})
describe('code', () => {
it('should create inline code', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('`$foobar`', {force: true})
.contains('code', '$foobar')
})
})
})
describe('code block', () => {
it('should create a code block without language', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('``` {enter}const foo = bar{enter}```', {force: true})
.contains('pre', 'const foo = bar')
})
})
})
describe('bullet list', () => {
it('should create a bullet list from asteriks', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('* foobar', {force: true})
.contains('ul', 'foobar')
})
})
it('should create a bullet list from dashes', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('- foobar', {force: true})
.contains('ul', 'foobar')
})
})
it('should create a bullet list from pluses', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('+ foobar', {force: true})
.contains('ul', 'foobar')
})
})
})
describe('ordered list', () => {
it('should create a ordered list', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('1. foobar', {force: true})
.contains('ol', 'foobar')
})
})
})
describe('blockquote', () => {
it('should create a blockquote', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror')
.type('> foobar', {force: true})
.contains('blockquote', 'foobar')
})
})
})
})

View File

@@ -0,0 +1,44 @@
<template>
<div>
<editor-content :editor="editor" />
</div>
</template>
<script>
import { Editor, EditorContent, defaultExtensions } from '@tiptap/vue-starter-kit'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
content: `
<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.
</p>
<p>
Those conventions are called <strong>input rules</strong> in tiptap. Some of those shortcuts are enabled by default. Try <code>></code> for blockquotes, <code>*</code>, <code>-</code> or <code>+</code> for bullet lists, <code>\`foobar\`</code> to highlight code.
</p>
<p>
You can add your own input rules through adding the <code>inputRules()</code> method in your nodes and marks.
</p>
`,
extensions: defaultExtensions(),
})
window.editor = this.editor
},
beforeDestroy() {
this.editor.destroy()
},
}
</script>

View File

@@ -0,0 +1,5 @@
context('simple', () => {
beforeEach(() => {
cy.visit('/examples/simple')
})
})

View File

@@ -0,0 +1,40 @@
<template>
<editor-content :editor="editor" />
</template>
<script>
import { Editor, EditorContent } from '@tiptap/vue-starter-kit'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
content: '<p>This is a radically reduced version of tiptap for minimalisits. It has only support for a document, paragraphs and text, thats it.</p>',
extensions: [
new Document(),
new Paragraph(),
new Text(),
],
})
window.editor = this.editor
},
beforeDestroy() {
this.editor.destroy()
},
}
</script>

View File

@@ -0,0 +1,37 @@
context('/api/extensions/bold', () => {
beforeEach(() => {
cy.visit('/api/extensions/bold')
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.setContent('<p>Example Text</p>')
editor.focus().selectAll()
})
})
describe('bold', () => {
it('the button should make the selected text bold', () => {
cy.get('.demo__preview button:first').click({ force: true })
cy.get('.ProseMirror').contains('strong', 'Example Text')
})
it('the button should toggle the selected text bold', () => {
cy.get('.demo__preview button:first').dblclick({ force: true })
cy.get('.ProseMirror strong').should('not.exist')
})
it('the keyboard shortcut should make the selected text bold', () => {
const shortcut = Cypress.platform === 'darwin' ? '{meta}b' : '{ctrl}b'
cy.get('.ProseMirror').type(shortcut, {force: true})
cy.get('.ProseMirror').contains('strong', 'Example Text')
})
it('the keyboard shortcut should toggle the selected text bold', () => {
const shortcut = Cypress.platform === 'darwin' ? '{meta}b' : '{ctrl}b'
cy.get('.ProseMirror').type(shortcut, {force: true}).type(shortcut, {force: true})
cy.get('.ProseMirror strong').should('not.exist')
})
})
})

View File

@@ -45,6 +45,8 @@ export default {
<p style="font-weight: 999">Up to font weight 999!!!</p>
`,
})
window.editor = this.editor
},
beforeDestroy() {

View File

@@ -0,0 +1,23 @@
context('/api/extensions/code', () => {
beforeEach(() => {
cy.visit('/api/extensions/code')
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.setContent('<p>Example Text</p>')
editor.focus().selectAll()
})
})
describe('code', () => {
it('should mark the selected text as inline code', () => {
cy.get('.demo__preview button:first').click({ force: true })
cy.get('.ProseMirror').contains('code', 'Example Text')
})
it('should toggle the selected text as inline code', () => {
cy.get('.demo__preview button:first').dblclick({ force: true })
cy.get('.ProseMirror code').should('not.exist')
})
})
})

View File

@@ -0,0 +1,51 @@
<template>
<div v-if="editor">
<button @click="editor.focus().code()" :class="{ 'is-active': editor.isActive('code') }">
code
</button>
<editor-content :editor="editor" />
</div>
</template>
<script>
import { Editor } from '@tiptap/core'
import { EditorContent } from '@tiptap/vue'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import Code from '@tiptap/extension-code'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
new Document(),
new Paragraph(),
new Text(),
new Code(),
],
content: `
<p>This isnt code.</p>
<p><code>This is code.</code></p>
`,
})
window.editor = this.editor
},
beforeDestroy() {
this.editor.destroy()
}
}
</script>

View File

@@ -0,0 +1,52 @@
context('/api/extensions/history', () => {
beforeEach(() => {
cy.visit('/api/extensions/history')
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.setContent('<p>Mistake</p>')
})
})
describe('undo', () => {
it('should make the last change undone', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror').should('contain', 'Mistake')
cy.get('.demo__preview button:first').click({ force: true })
cy.get('.ProseMirror').should('not.contain', 'Mistake')
})
})
it('the keyboard shortcut should make the last change undone', () => {
const shortcut = Cypress.platform === 'darwin' ? '{meta}z' : '{ctrl}z'
cy.get('.ProseMirror').type(shortcut, {force: true})
cy.get('.ProseMirror').should('not.contain', 'Mistake')
})
})
describe('redo', () => {
it('should apply the last undone change again', () => {
cy.get('.ProseMirror').window().then(window => {
cy.get('.ProseMirror').should('contain', 'Mistake')
cy.get('.demo__preview button:first').click({ force: true })
cy.get('.ProseMirror').should('not.contain', 'Mistake')
cy.get('.demo__preview button:nth-child(2)').click({ force: true })
cy.get('.ProseMirror').should('contain', 'Mistake')
})
})
it('the keyboard shortcut should apply the last undone change again', () => {
const undoShortcut = Cypress.platform === 'darwin' ? '{meta}z' : '{ctrl}z'
const redoShortcut = Cypress.platform === 'darwin' ? '{meta}{shift}z' : '{ctrl}{shift}z'
cy.get('.ProseMirror').type(undoShortcut, {force: true})
cy.get('.ProseMirror').should('not.contain', 'Mistake')
cy.get('.ProseMirror').type(redoShortcut, {force: true})
cy.get('.ProseMirror').should('contain', 'Mistake')
})
})
})

View File

@@ -0,0 +1,53 @@
<template>
<div v-if="editor">
<button @click="editor.focus().undo()">
undo
</button>
<button @click="editor.focus().redo()">
redo
</button>
<editor-content :editor="editor" />
</div>
</template>
<script>
import { Editor } from '@tiptap/core'
import { EditorContent } from '@tiptap/vue'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
import History from '@tiptap/extension-history'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
new Document(),
new Paragraph(),
new Text(),
new History(),
],
content: `
<p>Edit this text and press undo to test this extension.</p>
`,
})
window.editor = this.editor
},
beforeDestroy() {
this.editor.destroy()
}
}
</script>

View File

@@ -0,0 +1,37 @@
context('/api/extensions/italic', () => {
beforeEach(() => {
cy.visit('/api/extensions/italic')
cy.get('.ProseMirror').window().then(window => {
const { editor } = window
editor.setContent('<p>Example Text</p>')
editor.focus().selectAll()
})
})
describe('italic', () => {
it('the button should make the selected text italic', () => {
cy.get('.demo__preview button:first').click({ force: true })
cy.get('.ProseMirror').contains('em', 'Example Text')
})
it('the button should toggle the selected text italic', () => {
cy.get('.demo__preview button:first').dblclick({ force: true })
cy.get('.ProseMirror em').should('not.exist')
})
it('the keyboard shortcut should make the selected text italic', () => {
const shortcut = Cypress.platform === 'darwin' ? '{meta}i' : '{ctrl}i'
cy.get('.ProseMirror').type(shortcut, {force: true})
cy.get('.ProseMirror').contains('em', 'Example Text')
})
it('the keyboard shortcut should toggle the selected text italic', () => {
const shortcut = Cypress.platform === 'darwin' ? '{meta}i' : '{ctrl}i'
cy.get('.ProseMirror').type(shortcut, {force: true}).type(shortcut, {force: true})
cy.get('.ProseMirror em').should('not.exist')
})
})
})

View File

@@ -42,6 +42,8 @@ export default {
<p style="font-style: italic">This as well.</p>
`,
})
window.editor = this.editor
},
beforeDestroy() {

View File

@@ -1,10 +1,13 @@
# Commands
:::warning Out of date
This content is written for tiptap 1 and needs an update.
:::
- menus
- buttons
- commands
## .clearContent()
Clear the whole document.

View File

@@ -1,3 +1,7 @@
# Editor
:::warning Out of date
This content is written for tiptap 1 and needs an update.
:::
This class is a central building block of tiptap. It does most of the heavy lifting of creating a working [ProseMirror](https://ProseMirror.net/) editor such as creating the [`EditorView`](https://ProseMirror.net/docs/ref/#view.EditorView), setting the initial [`EditorState`](https://ProseMirror.net/docs/ref/#state.Editor_State) and so on.

View File

@@ -1,32 +1,55 @@
# Extensions
> ⚠️ TODO: This is old content.
By default, the editor will only support paragraphs. Other nodes and marks are available as **extensions**. You must
install `tiptap-extensions` package separately so that you can use basic Nodes, Marks, or Plugins. An extension is
usually tied to a Command. The official set of commands are part of the
[`tiptap-commands`][@npmjs-tiptap-commands] package.
## Default extensions
Starterkits have defaultExtensions, that include ...
Extensions are the way to add functionality to tiptap. By default tiptap comes bare, without any of them, but we have a long list of extensions that are ready to be used with tiptap.
## A minimalist set of extensions
Document, Paragraph, Text
Youll need at least three extensions: Document, Paragraph and Text. See [an example of a tiptap version for minimalists](/examples/simple).
## List of extensions
## Default extensions
* Bold
* Italic
...
You dont have to use it, but we prepared a `@tiptap/vue-starter-kit` which includes the most common extensions. See [how you can use the `defaultExtensions()`](/examples/basic).
## List of supported extensions
| Title | Default Extension | Source Code |
| ----- | ------- | ----------- |
| [Blockquote](/api/extensions/blockquote) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-blockquote/)
| [Bold](/api/extensions/bold) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/)
| [BulletList](/api/extensions/bullet-list) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bullet-list/)
| [Code](/api/extensions/code) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/)
| [CodeBlock](/api/extensions/code-block) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code-block/)
| [CodeBlockHighlight](/api/extensions/code-block-highlight) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packagescode-block-highlight/extension-/)
| [Collaboration](/api/extensions/collaboration) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-collaboration/)
| [Document](/api/extensions/document) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-document/)
| [HardBreak](/api/extensions/hard-break) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-hard-break/)
| [Heading](/api/extensions/heading) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-heading/)
| [History](/api/extensions/history) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-history/)
| [HorizontalRule](/api/extensions/horizontal-rule) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-horizontal-rule/)
| [Italic](/api/extensions/italic) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/)
| [Link](/api/extensions/link) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-link/)
| [ListItem](/api/extensions/list-item) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-list-item/)
| [Mention](/api/extensions/mention) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-mention/)
| [OrderedList](/api/extensions/ordered-list) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-ordered-list/)
| [Paragraph](/api/extensions/paragraph) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-paragraph/)
| [Placeholder](/api/extensions/placeholder) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-placeholder/)
| [Strike](/api/extensions/strike) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-strike/)
| [TableCell](/api/extensions/table-cell) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-table-cell/)
| [TableHeader](/api/extensions/table-header) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-table-header/)
| [TableTow](/api/extensions/table-row) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-table-row/)
| [Text](/api/extensions/text) | Yes | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-text/)
| [TodoItem](/api/extensions/todo-item) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-todo-item/)
| [TodoList](/api/extensions/todo-list) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-todo-list/)
| [Underline](/api/extensions/underline) | | [GitHub](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-underline/)
## Community extensions
How does that work?
:::warning Work in Progress
This section is not ready yet. Meanwhile, [search through the GitHub issues](https://github.com/ueberdosis/tiptap/issues) to find code snippets.
:::
## Your custom extensions
Link to the Guide
Didnt find what youre looking for? No worries, [you can build your own extensions](/guide/custom-extensions).
[@npmjs-tiptap-commands]: https://npmjs.org/package/tiptap-commands

View File

@@ -10,7 +10,7 @@ The extension will generate the corresponding `<strong>` HTML tags when reading
## Commands
| Command | Options | Description |
| ------ | ---- | ---------------- |
| ------- | ------- | ----------- |
| bold | — | Mark text bold. |
## Keybindings
@@ -21,4 +21,4 @@ The extension will generate the corresponding `<strong>` HTML tags when reading
[packages/extension-bold/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-bold/)
## Usage
<Demo name="Extensions/Bold" highlight="3-5,17,36" />
<demo name="Extensions/Bold" highlight="3-5,17,36" />

View File

@@ -1,55 +1,19 @@
# Code
The Code extensions enables you to use the `<code>` HTML tag in the editor.
The Code extensions enables you to use the `<code>` HTML tag in the editor. If you paste in text with `<code>` tags it will rendered accordingly.
## Options
*None*
## Commands
| Command | Options | Description |
| ------ | ---- | ---------------- |
| code | — | Mark text as code. |
| ------- | ------- | ----------- |
| code | — | Mark text as inline code. |
## Keybindings
* `Alt` + `
## Source Code
[packages/extension-code/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-code/)
## Usage
```markup
<template>
<div>
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
<button type="button" :class="{ 'is-active': isActive.code() }" @click="commands.code">
Code
</button>
</editor-menu-bar>
<editor-content :editor="editor" />
</div>
</template>
<script>
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
import { Code } from 'tiptap-extensions'
export default {
components: {
EditorMenuBar,
EditorContent,
},
data() {
return {
editor: new Editor({
extensions: [
new Code(),
],
content: `
<p>This is some <code>inline code.</code></p>
`,
}),
}
},
beforeDestroy() {
this.editor.destroy()
}
}
</script>
```
<demo name="Extensions/Code" highlight="3-5,17,36" />

View File

@@ -0,0 +1 @@
# Document

View File

@@ -1,58 +1,25 @@
# History
Enables history support.
This extension provides history support. All changes to the document will be tracked and can be removed with `undo`. Undone changes can be applied with `redo` again.
## Options
*None*
## Commands
| Command | Options | Description |
| ------ | ---- | ---------------- |
| undo | — | Undo the latest change. |
| redo | — | Redo the latest change. |
| ------- | ------- | ----------- |
| undo | — | Undo the last change. |
| redo | — | Redo the last change. |
## Keybindings
* Windows & Linux: `Control` + `Z` → Undo
* Windows & Linux: `Shift` + `Control` + `Z` → Redo
* macOS: `Command` + `Z` → Undo
* macOS: `Shift` + `Command` + `Z` Redo
* Windows & Linux: `Control` + `Z`
* macOS: `Command` + `Z`
### Redo
* Windows & Linux: `Shift` + `Control` + `Z`
* macOS: `Shift` + `Command` + `Z`
## Source Code
[packages/extension-history/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-history/)
## Usage
```markup
<template>
<div>
<editor-menu-bar :editor="editor" v-slot="{ commands, isActive }">
<div>
<button type="button" @click="commands.undo">
Undo
</button>
<button type="button" @click="commands.redo">
Redo
</button>
</div>
</editor-menu-bar>
<editor-content :editor="editor" />
</div>
</template>
<script>
import { Editor, EditorContent, EditorMenuBar } from 'tiptap'
import { History } from 'tiptap-extensions'
export default {
components: {
EditorMenuBar,
EditorContent,
},
data() {
return {
editor: new Editor({
extensions: [
new History(),
],
}),
}
},
beforeDestroy() {
this.editor.destroy()
}
}
</script>
```
<demo name="Extensions/History" highlight="3-8,20,39" />

View File

@@ -10,7 +10,7 @@ The extension will generate the corresponding `<em>` HTML tags when reading cont
## Commands
| Command | Options | Description |
| ------ | ---- | ---------------- |
| ------- | ------- | ----------- |
| italic | — | Mark text italic. |
## Keybindings
@@ -21,4 +21,4 @@ The extension will generate the corresponding `<em>` HTML tags when reading cont
[packages/extension-italic/](https://github.com/ueberdosis/tiptap-next/blob/main/packages/extension-italic/)
## Usage
<Demo name="Extensions/Italic" highlight="3-5,17,36" />
<demo name="Extensions/Italic" highlight="3-5,17,36" />

View File

@@ -1,2 +1,2 @@
## Mention
# Mention
Enables you to use mentions in the editor.

View File

@@ -0,0 +1,2 @@
# Paragraph
Enables you to use paragraphs in the editor.

View File

@@ -0,0 +1,2 @@
# Text
Enables you to use text in the editor.

View File

@@ -1,5 +1,9 @@
# Schema
:::warning Out of date
This content is written for tiptap 1 and needs an update.
:::
Unlike many other editors, tiptap is based on a [schema](https://prosemirror.net/docs/guide/#schema) that defines how your content is structured. This enables you to define the kind of nodes that may occur in the document, its attributes and the way they can be nested.
This schema is *very* strict. You cant use any HTML-element or attribute that is not defined in your schema.

View File

@@ -1,15 +0,0 @@
# Use tiptap with Vue.js
tiptap is framework-agnostic and works with plain JavaScript, Vue.js and React. To use tiptap with Vue.js or one of the tools that are based on Vue.js like Nuxt.js or Gridsome, youll need the tiptap Vue.js adapter. Install it as an dependency in your project:
```bash
# Install tiptap & Vue.js adapter with npm
npm install @tiptap/core @tiptap/starter-kit @tiptap/vue
# Install tiptap & Vue.js adapter with Yarn
yarn add @tiptap/core @tiptap/starter-kit @tiptap/vue
```
Create a new Vue component (e. g. `<Tiptap />`) and add the following content. Thats the shortest way to get tiptap up and running with Vue.js. No worries, youll be able to add more functionality soon.
<demo name="VueSetup" />

View File

@@ -1,3 +1,5 @@
# Basic
TODO: CodeBlock throws an exception.
<demo name="Examples/Basic" />

View File

@@ -1,3 +1,3 @@
# History
<demo name="Examples/History" />
<demo name="Examples/History" highlight="4-9" />

View File

@@ -0,0 +1,3 @@
# Simple
<demo name="Examples/Simple" highlight="7-9,27-29" />

View File

@@ -41,7 +41,7 @@ yarn add @tiptap/vue @tiptap/vue-starter-kit
We even prepared a Vue.js starter kit for you. That should give you a good headstart. Create a new component and add the following content to get a basic version of tiptap:
<demo name="VueSetup" />
<demo name="General/Installation" />
## CodeSandbox

View File

@@ -0,0 +1,73 @@
# Roadmap
## New features
* generate schema without initializing tiptap, to make SSR easier (e. g. `getSchema([new Doc(), new Paragraph()])`)
## Requested features
* Basic Styling
* https://github.com/ueberdosis/tiptap/issues/507
* Support vor Vue.js 3
* Easily add custom classes to everything
* https://github.com/ueberdosis/tiptap/discussions/817
* Text snippets
* https://github.com/ueberdosis/tiptap/issues/737
* Markdown Support
## Requested extensions
* Alignment
* https://github.com/ueberdosis/tiptap/pull/544
* Font color
* Font family
* Font size
* Created embed from pasted YouTube URL
* Superscript/Subscript
* https://github.com/ueberdosis/tiptap/discussions/813
* Math Support
* https://github.com/ueberdosis/tiptap/issues/179
* https://github.com/ueberdosis/tiptap/issues/698
* Resizeable Images
* https://gist.github.com/zachjharris/a5442efbdff11948d085b6b1406dfbe6
## Ideas
* A `@tiptap/extensions` package would be helpful to make imports easier.
* Add more shorcuts:
* Ctrl+I → Italic ✅
* Ctrl+B → Bold ✅
* Ctrl+K → Link (Medium, Tumblr, Slack, Google Docs, Word)
* Ctrl+Shift+K → Code (Slack)
* Shift+Enter → Line break
* Ctrl+Shift+X → Strikethrough (Slack)
* Alt+Shift+5 → Strikethrough (Google Docs)
* Ctrl+Shift+6 → Strikethrough (Tumblr)
* Ctrl+Alt+0 → Paragraph (Google Docs)
* Ctrl+Alt+1 to 6 → Heading (Google Docs, Word, ~Medium, ~Slack)
* Ctrl+Shift+2 → Heading (Tumblr)
* Ctrl+Shift+7 → Ordered list (Google Docs, Slack, Tumblr)
* Ctrl+Shift+8 → Unordered list (Google Docs, Slack, Tumblr)
* Tab, Shift+Tab → Increase / decrease nesting in lists
* Ctrl+], Ctrl+[ → Same as above (when Tab needs to be used)
* Ctrl+Shift+9 → Blockquote (Tumblr)
* Ctrl+Alt+K → Code block (Slack)
* Ctrl+R → Horizontal ruler (Stack Overflow)
* Markdown shortcuts
* #+Space → Heading (the number of # determines the header level)
* *+Space, -+Space → Unordered list
* 1.+Space → Ordered list
* >+Space → Blockquote
* ```+Space → Code block
* ---- → Horizontal ruler
* ![] → Embedded resource (not part of Slack, but would it not be fancy?)
* :emoji: → Emoji (based on the name). A nice-to-have, most certainly.
* General shortcuts
* Ctrl+C, Ctrl+X, Ctrl+V: copy, cut, paste
* Ctrl+Z, Ctrl+Shift+Z, Ctrl+Y: undo, redo
* Ctrl+Backspace: delete previous word
* Ctrl+Delete: delete next word
* Ctrl+Home, Ctrl+End: go to the start / end of the whole document
* Ctrl+F, Ctrl+G: find, find next occurrence
* Ctrl+S: if there is no auto-saving, this should save the document
* Ctrl+/: show shortcuts (Medium, Slack)

View File

@@ -22,7 +22,7 @@ You are free to choose which parts of tiptap you want to use. Tiptap has support
Note that `Document`, `Paragraph` and `Text` are required. Otherwise you wont be able to add any plain text.
<demo name="ExtensionConfiguration" highlight="10-13,30-33" />
<demo name="Guide/BuildYourEditor" highlight="10-13,30-33" />
Thats also the place where you can register custom extensions, which you or someone else built for tiptap.

View File

@@ -20,7 +20,7 @@ The `@tiptap/vue-starter-kit` includes a few basics you would probably need anyw
Create a new Vue component (you can call it `<Tiptap />`) and add the following content. This is the fastest way to get tiptap up and running with Vue.js. It will give you a very basic version of tiptap, without any buttons. No worries, you will be able to add more functionality soon.
<demo name="GettingStarted" />
<demo name="Guide/GettingStarted" />
::: warning Using with Nuxt.js
If you are using Nuxt.js, note that tiptap needs to run in the client, not on the server. Its required to wrap the editor in a `<client-only>` tag.

View File

@@ -1,10 +1,18 @@
# Introduction
tiptap is a <g-link to="/renderless">renderless</g-link> wrapper around [ProseMirror](https://ProseMirror.net) a toolkit for building rich-text editors that are already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*.
Although tiptap tries to hide most of the complexity of ProseMirror, its is built on top of its APIs and we strongly recommend you to read through the [ProseMirror Guide](https://ProseMirror.net/docs/guide/). Youll have a better understanding of how everything works under the hood and get familiar with many terms and jargon used by tiptap.
## Who is using tiptap?
## Renderless
The implementation of a text editor can be very specific for each use case. We dont want to tell you what a menu should look like or where it should be rendered in the DOM. Thats why tiptap is renderless and comes without any CSS. Youll have full control over markup and styling.
## TypeScript
Tiptap 2 is written in TypeScript. That gives you a nice autocomplete for the API (if your IDE supports those), helps us to find bugs early and makes it possible to generate [a complete API documentation](#) on top of the extensive human written documentation.
## Framework-agnostic
We dont care what framework you use. Tiptap is ready to be used with plain JavaScript, Vue.js or React. That makes it even possible to write a renderer for Svelte and others.
## Who uses tiptap?
- [GitLab](https://gitlab.com)
- [Statamic CMS](https://statamic.com)
- [Twill CMS](https://twill.io)

View File

@@ -1,3 +0,0 @@
# Renderless
The implementation of a text editor can be very specific for each use case. We dont want to tell you what a menu should look like or where it should be rendered in the DOM. Thats why tiptap is renderless and comes without any CSS. Youll have full control over markup and styling.

View File

@@ -93,4 +93,10 @@ blockquote {
.is-active {
background: black;
color: white;
}
.ProseMirror {
p {
margin: 0.5rem 0;
}
}

View File

@@ -45,13 +45,13 @@
</div>
<ul class="app__link-list">
<li v-for="(item, j) in linkGroup.items" :key="j">
<g-link class="app__link" :to="item.link">
<g-link :class="{ 'app__link': true, 'app__link--draft': item.draft === true }" :to="item.link" :exact="item.link === '/'">
{{ item.title }}
</g-link>
<ul v-if="item.items" class="app__link-list">
<li v-for="(item, k) in item.items" :key="k">
<g-link class="app__link" :to="item.link">
<g-link :class="{ 'app__link': true, 'app__link--draft': item.draft === true }" :to="item.link" exact>
{{ item.title }}
</g-link>
</li>
@@ -69,6 +69,9 @@
<span>Edit this page on GitHub</span>
</a>
</p>
<p>
Made with 🖤 by <a href="https://twitter.com/_ueberdosis">überdosis</a>
</p>
<page-navigation />
</main>
</div>

View File

@@ -25,12 +25,17 @@ $menuBreakPoint: 750px;
}
&__link-list &__link-list {
display: none;
padding-left: 1rem;
margin-top: 0.5rem;
margin-bottom: 1.5rem;
border-left: 2px solid rgba($colorBlack, 0.1);
}
.active + &__link-list {
display: block;
}
&__link {
display: block;
padding: 0.1rem 0.5rem;
@@ -48,6 +53,10 @@ $menuBreakPoint: 750px;
color: $colorBlack;
background-color: rgba($colorBlack, 0.05);
}
&--draft {
color: rgba($colorBlack, 0.2);
}
}
&__header {
@@ -156,4 +165,4 @@ $menuBreakPoint: 750px;
min-width: 0;
padding-top: $navHeight + 2rem;
}
}
}

View File

@@ -1,73 +1,101 @@
- title: Getting Started
- title: General
items:
- title: Introduction
link: /getting-started/introduction/
link: /
- title: Installation
link: /getting-started/installation/
link: /general/installation
- title: Upgrade Guide
link: /getting-started/upgrade-guide/
link: /general/upgrade-guide
draft: true
- title: Roadmap
link: /general/roadmap
draft: true
- title: Guide
items:
- title: Getting started
link: /guide/getting-started/
link: /guide/getting-started
- title: Configuration
link: /guide/configuration/
link: /guide/configuration
draft: true
- title: Build your editor
link: /guide/build-your-editor/
link: /guide/build-your-editor
draft: true
- title: Custom styling
link: /guide/custom-styling/
link: /guide/custom-styling
draft: true
- title: Get content
link: /guide/get-content/
link: /guide/get-content
draft: true
- title: Custom extensions
link: /guide/custom-extensions/
link: /guide/custom-extensions
draft: true
- title: Use Vue Components
link: /guide/use-vue-components/
link: /guide/use-vue-components
draft: true
- title: Examples
items:
- title: Basic
link: /examples/basic
- title: Simple
link: /examples/simple
- title: Menu Bubble
link: /examples/menu-bubble
draft: true
- title: Floating Menu
link: /examples/floating-menu
draft: true
- title: Links
link: /examples/links
draft: true
- title: Images
link: /examples/images
draft: true
- title: Hiding Menu Bar
link: /examples/hiding-menu-bar
draft: true
- title: Todo List
link: /examples/todo-list
draft: true
- title: Tables
link: /examples/tables
draft: true
- title: Search and Replace
link: /examples/search-and-replace
draft: true
- title: Suggestions
link: /examples/suggestions
draft: true
- title: Markdown Shortcuts
link: /examples/markdown-shortcuts
- title: Code Highlighting
link: /examples/code-highlighting
draft: true
- title: History
link: /examples/history
- title: Read-Only
link: /examples/read-only
- title: Embeds
link: /examples/embeds
draft: true
- title: Placeholder
link: /examples/placeholder
draft: true
- title: Focus
link: /examples/focus
- title: Collaboration
link: /examples/collaboration
draft: true
- title: Title
link: /examples/title
draft: true
- title: Trailing Paragraph
link: /examples/trailing-paragraph
draft: true
- title: Drag Handle
link: /examples/drag-handle
draft: true
- title: Export HTML or JSON
link: /examples/export-html-or-json
@@ -75,60 +103,93 @@
items:
- title: Editor
link: /api/editor/
draft: true
- title: Extensions
link: /api/extensions/
items:
- title: Blockquote
link: /api/extensions/blockquote
draft: true
- title: Bold
link: /api/extensions/bold
- title: BulletList
link: /api/extensions/bullet-list
draft: true
- title: Code
link: /api/extensions/code
- title: CodeBlock
link: /api/extensions/code-block
draft: true
- title: CodeBlockHighlight
link: /api/extensions/code-block-highlight
draft: true
- title: Collaboration
link: /api/extensions/collaboration
draft: true
- title: Document
link: /api/extensions/document
draft: true
- title: Hardbreak
link: /api/extensions/hard-break
draft: true
- title: Heading
link: /api/extensions/heading
draft: true
- title: History
link: /api/extensions/history
- title: HorizontalRule
link: /api/extensions/horizontal-rule
draft: true
- title: Italic
link: /api/extensions/italic
- title: Link
link: /api/extensions/link
draft: true
- title: ListItem
link: /api/extensions/list-item
draft: true
- title: Mention
link: /api/extensions/mention
draft: true
- title: OrderedList
link: /api/extensions/ordered-list
draft: true
- title: Paragraph
link: /api/extensions/paragraph
draft: true
- title: Placeholder
link: /api/extensions/placeholder
draft: true
- title: Strike
link: /api/extensions/strike
draft: true
- title: Text
link: /api/extensions/text
draft: true
- title: TableCell
link: /api/extensions/table-cell
draft: true
- title: TableHeader
link: /api/extensions/table-header
draft: true
- title: TableRow
link: /api/extensions/table-row
draft: true
- title: TodoItem
link: /api/extensions/todo-item
draft: true
- title: TodoList
link: /api/extensions/todo-list
draft: true
- title: Underline
link: /api/extensions/underline
draft: true
- title: Commands
link: /api/commands/
link: /api/commands
draft: true
- title: Events
link: /api/events/
link: /api/events
draft: true
- title: Schema
link: /api/schema/
link: /api/schema
draft: true

View File

@@ -1,5 +0,0 @@
<template>
<Layout>
Hi there! 👋
</Layout>
</template>

View File

@@ -58,7 +58,7 @@
> * + * {
margin-top: 0.5rem;
}
}
li {
position: relative;
@@ -80,7 +80,7 @@
> * + * {
margin-top: 0.5rem;
}
}
li {
position: relative;
@@ -146,7 +146,7 @@
padding: 1rem;
border: 2px solid rgba($colorBlack, 0.1);
border-radius: 0.25rem;
&.warning {
border-color:#ffd8a8;
background-color: #fff4e6;

View File

@@ -19,16 +19,16 @@
"reset": "clean:packages && rm -rf ./**/.cache && rm -rf ./**/node_modules && rm -rf ./yarn.lock && yarn install"
},
"devDependencies": {
"@babel/preset-env": "^7.11.0",
"@babel/preset-env": "^7.11.5",
"@types/prosemirror-commands": "^1.0.3",
"@types/prosemirror-history": "^1.0.1",
"@types/prosemirror-inputrules": "^1.0.2",
"@types/prosemirror-inputrules": "^1.0.3",
"@types/prosemirror-keymap": "^1.0.3",
"@types/prosemirror-model": "^1.7.2",
"@types/prosemirror-state": "^1.2.5",
"@types/prosemirror-transform": "^1.1.1",
"@types/prosemirror-view": "^1.15.0",
"cypress": "^5.0.0",
"cypress": "^5.1.0",
"lerna": "^3.22.1",
"microbundle": "^0.12.3",
"sass-loader": "^9.0.3",

View File

@@ -27,7 +27,7 @@
"prosemirror-state": "^1.3.3",
"prosemirror-tables": "^1.1.1",
"prosemirror-utils": "^0.9.6",
"prosemirror-view": "^1.15.3",
"prosemirror-view": "^1.15.6",
"verbal-expressions": "^1.0.2"
},
"scripts": {

View File

@@ -76,13 +76,13 @@ export class Editor extends EventEmitter {
if (this.options.injectCSS) {
require('./style.css')
}
this.proxy.focus(this.options.autoFocus)
}
/**
* A magic method to call commands.
*
*
* @param name The name of the command
*/
private __get(name: string) {
@@ -99,7 +99,7 @@ export class Editor extends EventEmitter {
/**
* Update editor options.
*
*
* @param options A list of options
*/
public setOptions(options: Partial<EditorOptions> = {}) {
@@ -109,7 +109,7 @@ export class Editor extends EventEmitter {
this.view.updateState(this.state)
}
}
/**
* Returns whether the editor is editable.
*/
@@ -126,7 +126,7 @@ export class Editor extends EventEmitter {
/**
* Register a list of commands.
*
*
* @param commands A list of commands
*/
public registerCommands(commands: CommandSpec) {
@@ -137,7 +137,7 @@ export class Editor extends EventEmitter {
/**
* Register a command.
*
*
* @param name The name of your command
* @param callback The method of your command
*/
@@ -159,7 +159,7 @@ export class Editor extends EventEmitter {
/**
* Register a ProseMirror plugin.
*
*
* @param plugin A ProseMirror plugin
* @param handlePlugins Control how to merge the plugin into the existing plugins.
*/
@@ -175,7 +175,7 @@ export class Editor extends EventEmitter {
/**
* Unregister a ProseMirror plugin.
*
*
* @param name The plugins name
*/
public unregisterPlugin(name: string) {
@@ -189,7 +189,7 @@ export class Editor extends EventEmitter {
/**
* Call a command.
*
*
* @param name The name of the command you want to call.
* @param options The options of the command.
*/
@@ -199,8 +199,8 @@ export class Editor extends EventEmitter {
/**
* Wraps a command to make it chainable.
*
* @param method
*
* @param method
*/
private chainCommand = (method: Function) => (...args: any) => {
this.lastCommand = this.lastCommand
@@ -278,7 +278,7 @@ export class Editor extends EventEmitter {
/**
* The callback over which to send transactions (state updates) produced by the view.
*
*
* @param transaction An editor state transaction
*/
private dispatchTransaction(transaction: Transaction) {
@@ -296,7 +296,7 @@ export class Editor extends EventEmitter {
/**
* Get attributes of the currently selected node.
*
*
* @param name Name of the node
*/
public getNodeAttrs(name: string) {
@@ -305,7 +305,7 @@ export class Editor extends EventEmitter {
/**
* Get attributes of the currently selected mark.
*
*
* @param name Name of the mark
*/
public getMarkAttrs(name: string) {
@@ -314,7 +314,7 @@ export class Editor extends EventEmitter {
/**
* Returns if the currently selected node or mark is active.
*
*
* @param name Name of the node or mark
* @param attrs Attributes of the node or mark
*/

View File

@@ -8,7 +8,7 @@ export default class CodeBlock extends Node {
schema(): NodeSpec {
return {
content: 'text*',
marks: '',
marks: '',
group: 'block',
code: true,
defining: true,

188
yarn.lock
View File

@@ -926,6 +926,80 @@
levenary "^1.1.1"
semver "^5.5.0"
"@babel/preset-env@^7.11.5":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272"
integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==
dependencies:
"@babel/compat-data" "^7.11.0"
"@babel/helper-compilation-targets" "^7.10.4"
"@babel/helper-module-imports" "^7.10.4"
"@babel/helper-plugin-utils" "^7.10.4"
"@babel/plugin-proposal-async-generator-functions" "^7.10.4"
"@babel/plugin-proposal-class-properties" "^7.10.4"
"@babel/plugin-proposal-dynamic-import" "^7.10.4"
"@babel/plugin-proposal-export-namespace-from" "^7.10.4"
"@babel/plugin-proposal-json-strings" "^7.10.4"
"@babel/plugin-proposal-logical-assignment-operators" "^7.11.0"
"@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4"
"@babel/plugin-proposal-numeric-separator" "^7.10.4"
"@babel/plugin-proposal-object-rest-spread" "^7.11.0"
"@babel/plugin-proposal-optional-catch-binding" "^7.10.4"
"@babel/plugin-proposal-optional-chaining" "^7.11.0"
"@babel/plugin-proposal-private-methods" "^7.10.4"
"@babel/plugin-proposal-unicode-property-regex" "^7.10.4"
"@babel/plugin-syntax-async-generators" "^7.8.0"
"@babel/plugin-syntax-class-properties" "^7.10.4"
"@babel/plugin-syntax-dynamic-import" "^7.8.0"
"@babel/plugin-syntax-export-namespace-from" "^7.8.3"
"@babel/plugin-syntax-json-strings" "^7.8.0"
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0"
"@babel/plugin-syntax-numeric-separator" "^7.10.4"
"@babel/plugin-syntax-object-rest-spread" "^7.8.0"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.0"
"@babel/plugin-syntax-optional-chaining" "^7.8.0"
"@babel/plugin-syntax-top-level-await" "^7.10.4"
"@babel/plugin-transform-arrow-functions" "^7.10.4"
"@babel/plugin-transform-async-to-generator" "^7.10.4"
"@babel/plugin-transform-block-scoped-functions" "^7.10.4"
"@babel/plugin-transform-block-scoping" "^7.10.4"
"@babel/plugin-transform-classes" "^7.10.4"
"@babel/plugin-transform-computed-properties" "^7.10.4"
"@babel/plugin-transform-destructuring" "^7.10.4"
"@babel/plugin-transform-dotall-regex" "^7.10.4"
"@babel/plugin-transform-duplicate-keys" "^7.10.4"
"@babel/plugin-transform-exponentiation-operator" "^7.10.4"
"@babel/plugin-transform-for-of" "^7.10.4"
"@babel/plugin-transform-function-name" "^7.10.4"
"@babel/plugin-transform-literals" "^7.10.4"
"@babel/plugin-transform-member-expression-literals" "^7.10.4"
"@babel/plugin-transform-modules-amd" "^7.10.4"
"@babel/plugin-transform-modules-commonjs" "^7.10.4"
"@babel/plugin-transform-modules-systemjs" "^7.10.4"
"@babel/plugin-transform-modules-umd" "^7.10.4"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4"
"@babel/plugin-transform-new-target" "^7.10.4"
"@babel/plugin-transform-object-super" "^7.10.4"
"@babel/plugin-transform-parameters" "^7.10.4"
"@babel/plugin-transform-property-literals" "^7.10.4"
"@babel/plugin-transform-regenerator" "^7.10.4"
"@babel/plugin-transform-reserved-words" "^7.10.4"
"@babel/plugin-transform-shorthand-properties" "^7.10.4"
"@babel/plugin-transform-spread" "^7.11.0"
"@babel/plugin-transform-sticky-regex" "^7.10.4"
"@babel/plugin-transform-template-literals" "^7.10.4"
"@babel/plugin-transform-typeof-symbol" "^7.10.4"
"@babel/plugin-transform-unicode-escapes" "^7.10.4"
"@babel/plugin-transform-unicode-regex" "^7.10.4"
"@babel/preset-modules" "^0.1.3"
"@babel/types" "^7.11.5"
browserslist "^4.12.0"
core-js-compat "^3.6.2"
invariant "^2.2.2"
levenary "^1.1.1"
semver "^5.5.0"
"@babel/preset-flow@^7.10.1":
version "7.10.4"
resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.10.4.tgz#e0d9c72f8cb02d1633f6a5b7b16763aa2edf659f"
@@ -998,6 +1072,15 @@
lodash "^4.17.19"
to-fast-properties "^2.0.0"
"@babel/types@^7.11.5":
version "7.11.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d"
integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==
dependencies:
"@babel/helper-validator-identifier" "^7.10.4"
lodash "^4.17.19"
to-fast-properties "^2.0.0"
"@cypress/listr-verbose-renderer@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a"
@@ -1165,15 +1248,13 @@
dependencies:
json-parse-better-errors "^1.0.2"
"@gridsome/transformer-remark@^0.6.1":
version "0.6.1"
resolved "https://registry.yarnpkg.com/@gridsome/transformer-remark/-/transformer-remark-0.6.1.tgz#0fa71527289a21ff9cfeaf3a07c236b4165772ed"
integrity sha512-2GHBYB9qP4MvOK8gVTZvSzzaeP5qsjqO+1zscYQ4rfstsv7/BjBQ54oGWTMsg9UqYJLxZAl45eEhgkM6CyO0lg==
"@gridsome/transformer-remark@^0.6.2":
version "0.6.2"
resolved "https://registry.yarnpkg.com/@gridsome/transformer-remark/-/transformer-remark-0.6.2.tgz#ab8822556cdbc9dd4a53115aa125668b233d6998"
integrity sha512-6kkdKg35vuCiZYfNxM+rqkZjG9ztgCAVT8bb3Kqqu+/FNCwMYUInIfWeW7ApAjj+ng/YFG1tB+fAABCeH3sEbw==
dependencies:
gray-matter "^4.0.2"
hash-sum "^1.0.2"
hast-util-to-html "^4.0.1"
html-to-text "^4.0.0"
lodash "^4.17.11"
lru-cache "^5.1.1"
remark-autolink-headings "^5.0.0"
@@ -1188,17 +1269,17 @@
unist-util-visit "^1.4.0"
vfile "^4.0.0"
"@gridsome/vue-remark@^0.2.0":
version "0.2.3"
resolved "https://registry.yarnpkg.com/@gridsome/vue-remark/-/vue-remark-0.2.3.tgz#daebd2ffbcb1da2e89b8a2381835c6135a4eb68b"
integrity sha512-aNkyYy+CFu6T4QtOOb8bRm5zSBc4WFsbhQpJhEZIJjxeJK380dr0AW5Rb2KnJ3CTfDuu5L0/UMoZdfATa8Mfkw==
"@gridsome/vue-remark@^0.2.4":
version "0.2.4"
resolved "https://registry.yarnpkg.com/@gridsome/vue-remark/-/vue-remark-0.2.4.tgz#42bf05135269e4b550ca0ab34ba634b5e7d89627"
integrity sha512-l6MMzkcsWcwruuV9Ug3CFHA9187qgAK0BHe45/9cSG/Byqh78wsgC9ltZ8b0LroZTdKOb5m83pD0ptNlGETBnQ==
dependencies:
"@babel/core" "^7.0.0"
"@babel/parser" "^7.0.0"
"@babel/preset-env" "^7.0.0"
"@babel/traverse" "^7.0.0"
"@gridsome/source-filesystem" "^0.6.2"
"@gridsome/transformer-remark" "^0.6.1"
"@gridsome/transformer-remark" "^0.6.2"
hash-sum "^1.0.2"
hast-util-to-html "^5.0.0"
he "^1.2.0"
@@ -2277,10 +2358,10 @@
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
"@types/prosemirror-inputrules@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.2.tgz#60b946ca2782f0f453b65105e2ebfd1730324caa"
integrity sha512-bKFneQUPnkZmzCJ1uoitpKH6PFW0hc4q55NsC7mFUCvX0eZl0GRKxyfV47jkJbsbyUQoO/QFv0WwLDz2bo15sA==
"@types/prosemirror-inputrules@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@types/prosemirror-inputrules/-/prosemirror-inputrules-1.0.3.tgz#3f8f07921f692b6c7e4781fa426aee3e76b9018c"
integrity sha512-cxMkCcu/di8//68jWc/NrRpvpCbizgq9vqv4rCRsAiuSiJ8L5hf4aFlCBUYCffuQnrY98uOfJ8YAUY3dbtaF9A==
dependencies:
"@types/prosemirror-model" "*"
"@types/prosemirror-state" "*"
@@ -4622,10 +4703,10 @@ cyclist@^1.0.1:
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=
cypress@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-5.0.0.tgz#6957e299b790af8b1cd7bea68261b8935646f72e"
integrity sha512-jhPd0PMO1dPSBNpx6pHVLkmnnaTfMy3wCoacHAKJ9LJG06y16zqUNSFri64N4BjuGe8y6mNMt8TdgKnmy9muCg==
cypress@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/cypress/-/cypress-5.1.0.tgz#979e9ff3e0acd792eefd365bf104046479a9643b"
integrity sha512-craPRO+Viu4268s7eBvX5VJW8aBYcAQT+EwEccQSMY+eH1ZPwnxIgyDlmMWvxLVX9SkWxOlZbEycPyzanQScBQ==
dependencies:
"@cypress/listr-verbose-renderer" "^0.4.1"
"@cypress/request" "^2.88.5"
@@ -6459,6 +6540,13 @@ gray-matter@^4.0.2:
section-matter "^1.0.0"
strip-bom-string "^1.0.0"
gridsome-plugin-simple-analytics@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/gridsome-plugin-simple-analytics/-/gridsome-plugin-simple-analytics-1.1.0.tgz#3ad44908ac767c603943ddc928d09e23304edee2"
integrity sha512-LiONYi1hRlSEC15UfDnDahbMowo0diWFHyAdzKNKWJFDBf31Z06DnHbZiQyRlGJNF18MqJRJXQIa0xwo6zehQw==
dependencies:
simple-analytics-vue "^1.1.0"
gridsome@0.7.20:
version "0.7.20"
resolved "https://registry.yarnpkg.com/gridsome/-/gridsome-0.7.20.tgz#6b45135468db1185e5aea4b3e699d2c2d1e3557d"
@@ -6716,7 +6804,7 @@ hast-util-sanitize@^1.0.0:
dependencies:
xtend "^4.0.1"
hast-util-to-html@^4.0.0, hast-util-to-html@^4.0.1:
hast-util-to-html@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/hast-util-to-html/-/hast-util-to-html-4.0.1.tgz#3666b05afb62bd69f8f5e6c94db04dea19438e2a"
integrity sha512-2emzwyf0xEsc4TBIPmDJmBttIw8R4SXAJiJZoiRR/s47ODYWgOqNoDbf2SJAbMbfNdFWMiCSOrI3OVnX6Qq2Mg==
@@ -6779,7 +6867,7 @@ hastscript@^5.1.0:
property-information "^5.0.0"
space-separated-tokens "^1.0.0"
he@1.2.x, he@^1.0.0, he@^1.1.0, he@^1.2.0:
he@1.2.x, he@^1.1.0, he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@@ -6879,16 +6967,6 @@ html-tags@^3.1.0:
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
html-to-text@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/html-to-text/-/html-to-text-4.0.0.tgz#c1f4e100d74e9feab5b152d7b6b3be3c1c6412b0"
integrity sha512-QQl5EEd97h6+3crtgBhkEAO6sQnZyDff8DAeJzoSkOc1Dqe1UvTUZER0B+KjBe6fPZqq549l2VUhtracus3ndA==
dependencies:
he "^1.0.0"
htmlparser2 "^3.9.2"
lodash "^4.17.4"
optimist "^0.6.1"
html-void-elements@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483"
@@ -6907,7 +6985,7 @@ html-webpack-plugin@^3.2.0:
toposort "^1.0.0"
util.promisify "1.0.0"
htmlparser2@^3.3.0, htmlparser2@^3.9.2:
htmlparser2@^3.3.0:
version "3.10.1"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
@@ -8225,7 +8303,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@~4.17.10:
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.5, lodash@^4.2.1, lodash@~4.17.10:
version "4.17.20"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
@@ -8820,11 +8898,6 @@ minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
minimist@~0.0.1:
version "0.0.10"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=
minipass@^2.3.5, minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6"
@@ -9451,14 +9524,6 @@ onetime@^5.1.0:
dependencies:
mimic-fn "^2.1.0"
optimist@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686"
integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY=
dependencies:
minimist "~0.0.1"
wordwrap "~0.0.2"
optimize-css-assets-webpack-plugin@^5.0.1:
version "5.0.3"
resolved "https://registry.yarnpkg.com/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz#e2f1d4d94ad8c0af8967ebd7cf138dcb1ef14572"
@@ -10642,7 +10707,7 @@ prosemirror-utils@^0.9.6:
resolved "https://registry.yarnpkg.com/prosemirror-utils/-/prosemirror-utils-0.9.6.tgz#3d97bd85897e3b535555867dc95a51399116a973"
integrity sha512-UC+j9hQQ1POYfMc5p7UFxBTptRiGPR7Kkmbl3jVvU8VgQbkI89tR/GK+3QYC8n+VvBZrtAoCrJItNhWSxX3slA==
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.15.3:
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3:
version "1.15.4"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.15.4.tgz#69a6217e3557dd1eb34a6d45caed1c3ee8e05b12"
integrity sha512-SzcszIrDJnQIS+f7WiS5KmQBfdYEhPqp/Hx9bKmXH7ZxrxRiBKPy1/9MoZzxjXUkm+5WHjX+N1fjAMXKoz/OQw==
@@ -10651,6 +10716,15 @@ prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, pros
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
prosemirror-view@^1.15.6:
version "1.15.6"
resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.15.6.tgz#446bf7662235300c5f47362af2db805c6df3ad24"
integrity sha512-9FBFB+rK5pvvzHsHOacy0T/Jf+OxZSzY8tSlQiur3SZwAVaNVQm+fl23V/6gU2dHBnreGxjYx9jK+F3XPsPCGw==
dependencies:
prosemirror-model "^1.1.0"
prosemirror-state "^1.0.0"
prosemirror-transform "^1.1.0"
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
@@ -11830,6 +11904,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
simple-analytics-vue@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/simple-analytics-vue/-/simple-analytics-vue-1.1.1.tgz#1d0ee7f31d4b341442e35dfbbef57cc0fb4bb0e7"
integrity sha512-vdp1hdT9MhA1iTeri5A/KfwHSlc060MNpeydZmugXiuVDOFCMPGiNAPuFh2Vn18Ia2pMfPvzCrKpQ9At+fm22w==
dependencies:
vue "^2.6.10"
simple-concat@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f"
@@ -12854,10 +12935,10 @@ trough@^1.0.0:
dependencies:
glob "^7.1.2"
ts-loader@^8.0.2:
version "8.0.2"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.2.tgz#ee73ca9350f745799396fff8578ba29b1e95616b"
integrity sha512-oYT7wOTUawYXQ8XIDsRhziyW0KUEV38jISYlE+9adP6tDtG+O5GkRe4QKQXrHVH4mJJ88DysvEtvGP65wMLlhg==
ts-loader@^8.0.3:
version "8.0.3"
resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.0.3.tgz#56858f4296edf1ed55e01f8520552984d3f0911c"
integrity sha512-wsqfnVdB7xQiqhqbz2ZPLGHLPZbHVV5Qn/MNFZkCFxRU1miDyxKORucDGxKtsQJ63Rfza0udiUxWF5nHY6bpdQ==
dependencies:
chalk "^2.3.0"
enhanced-resolve "^4.0.0"
@@ -13724,11 +13805,6 @@ wordwrap@^1.0.0:
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc=
worker-farm@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8"