Merge branch 'feature/text-style-mark' of https://github.com/ueberdosis/tiptap-next into feature/text-style-mark
# Conflicts: # docs/src/demos/Marks/TextStyle/index.vue
This commit is contained in:
@@ -1,14 +1,83 @@
|
||||
<template>
|
||||
<div>
|
||||
<button @click="setName">
|
||||
Set Name
|
||||
</button>
|
||||
<button @click="changeName">
|
||||
Random Name
|
||||
</button>
|
||||
<button @click="changeColor">
|
||||
Random Color
|
||||
</button>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().bold().run()" :class="{ 'is-active': editor.isActive('bold') }">
|
||||
bold
|
||||
</button>
|
||||
<button @click="editor.chain().focus().italic().run()" :class="{ 'is-active': editor.isActive('italic') }">
|
||||
italic
|
||||
</button>
|
||||
<button @click="editor.chain().focus().strike().run()" :class="{ 'is-active': editor.isActive('strike') }">
|
||||
strike
|
||||
</button>
|
||||
<button @click="editor.chain().focus().code().run()" :class="{ 'is-active': editor.isActive('code') }">
|
||||
code
|
||||
</button>
|
||||
<button @click="editor.chain().focus().removeMarks().run()">
|
||||
clear marks
|
||||
</button>
|
||||
<button @click="editor.chain().focus().clearNodes().run()">
|
||||
clear nodes
|
||||
</button>
|
||||
<button @click="editor.chain().focus().paragraph().run()" :class="{ 'is-active': editor.isActive('paragraph') }">
|
||||
paragraph
|
||||
</button>
|
||||
<button @click="editor.chain().focus().heading({ level: 1 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 1 }) }">
|
||||
h1
|
||||
</button>
|
||||
<button @click="editor.chain().focus().heading({ level: 2 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 2 }) }">
|
||||
h2
|
||||
</button>
|
||||
<button @click="editor.chain().focus().heading({ level: 3 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 3 }) }">
|
||||
h3
|
||||
</button>
|
||||
<button @click="editor.chain().focus().heading({ level: 4 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 4 }) }">
|
||||
h4
|
||||
</button>
|
||||
<button @click="editor.chain().focus().heading({ level: 5 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 5 }) }">
|
||||
h5
|
||||
</button>
|
||||
<button @click="editor.chain().focus().heading({ level: 6 }).run()" :class="{ 'is-active': editor.isActive('heading', { level: 6 }) }">
|
||||
h6
|
||||
</button>
|
||||
<button @click="editor.chain().focus().bulletList().run()" :class="{ 'is-active': editor.isActive('bulletList') }">
|
||||
bullet list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().orderedList().run()" :class="{ 'is-active': editor.isActive('orderedList') }">
|
||||
ordered list
|
||||
</button>
|
||||
<button @click="editor.chain().focus().codeBlock().run()" :class="{ 'is-active': editor.isActive('codeBlock') }">
|
||||
code block
|
||||
</button>
|
||||
<button @click="editor.chain().focus().blockquote().run()" :class="{ 'is-active': editor.isActive('blockquote') }">
|
||||
blockquote
|
||||
</button>
|
||||
<button @click="editor.chain().focus().horizontalRule().run()">
|
||||
horizontal rule
|
||||
</button>
|
||||
<button @click="editor.chain().focus().hardBreak().run()">
|
||||
hard break
|
||||
</button>
|
||||
<button @click="editor.chain().focus().undo().run()">
|
||||
undo
|
||||
</button>
|
||||
<button @click="editor.chain().focus().redo().run()">
|
||||
redo
|
||||
</button>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
<button @click="setName">
|
||||
Set Name
|
||||
</button>
|
||||
<button @click="changeName">
|
||||
Random Name
|
||||
</button>
|
||||
<button @click="changeColor">
|
||||
Random Color
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="collaboration-status">
|
||||
{{ users.length }} user{{ users.length === 1 ? '' : 's' }}
|
||||
@@ -29,7 +98,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Editor, EditorContent } from '@tiptap/vue-starter-kit'
|
||||
import { Editor, EditorContent, defaultExtensions } from '@tiptap/vue-starter-kit'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
@@ -60,21 +129,15 @@ export default {
|
||||
|
||||
mounted() {
|
||||
this.ydoc = new Y.Doc()
|
||||
this.provider = new WebrtcProvider(this.documentName, this.ydoc)
|
||||
this.type = this.ydoc.getXmlFragment('prosemirror')
|
||||
this.indexdb = new IndexeddbPersistence(this.documentName, this.ydoc)
|
||||
|
||||
this.provider = new WebrtcProvider(this.documentName, this.ydoc)
|
||||
this.provider.awareness.on('change', this.updateState)
|
||||
|
||||
this.editor = new Editor({
|
||||
// TODO: This is added by every new user.
|
||||
// content: `
|
||||
// <p>Example Text</p>
|
||||
// `,
|
||||
extensions: [
|
||||
Document(),
|
||||
Paragraph(),
|
||||
Text(),
|
||||
...defaultExtensions(),
|
||||
Collaboration({
|
||||
provider: this.provider,
|
||||
type: this.type,
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
context('/examples/focus', () => {
|
||||
before(() => {
|
||||
cy.visit('/examples/focus')
|
||||
})
|
||||
|
||||
it('should have class', () => {
|
||||
cy.get('.ProseMirror p:first').should('have.class', 'has-focus')
|
||||
})
|
||||
})
|
||||
@@ -1,66 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</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'
|
||||
import Code from '@tiptap/extension-code'
|
||||
import BulletList from '@tiptap/extension-bullet-list'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import Focus from '@tiptap/extension-focus'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [
|
||||
Document(),
|
||||
Paragraph(),
|
||||
Text(),
|
||||
Code(),
|
||||
BulletList(),
|
||||
ListItem(),
|
||||
Focus({
|
||||
className: 'has-focus',
|
||||
nested: true,
|
||||
}),
|
||||
],
|
||||
autoFocus: true,
|
||||
content: `
|
||||
<p>
|
||||
The focus extension adds a class to the focused node only. That enables you to add a custom styling to just that node. By default, it’ll add <code>.has-focus</code>, even to nested nodes.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Nested elements (like this list item) will be focused with the default setting of <code>nested: true</code>.</li>
|
||||
<li>Otherwise the whole list will get the focus class, even when just a single list item is selected.</li>
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.has-focus {
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 0 3px #3ea4ffe6;
|
||||
}
|
||||
</style>
|
||||
@@ -1,31 +0,0 @@
|
||||
context('/examples/history', () => {
|
||||
before(() => {
|
||||
cy.visit('/examples/history')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.clearContent()
|
||||
})
|
||||
})
|
||||
|
||||
it('should not have a mistake', () => {
|
||||
cy.get('.ProseMirror').then(() => {
|
||||
cy.get('.ProseMirror').should('not.contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
it('should have a mistake', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.insertText('Mistake')
|
||||
cy.get('.ProseMirror').should('contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
|
||||
it('the mistake should be removed again', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.undo()
|
||||
cy.get('.ProseMirror').should('not.contain', 'Mistake')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,47 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="editor">
|
||||
<button @click="editor.chain().focus().undo().run()">
|
||||
undo
|
||||
</button>
|
||||
<button @click="editor.chain().focus().redo().run()">
|
||||
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: `
|
||||
<p>
|
||||
With the <code>History</code> extension the Editor will keep track of your changes. And if you think you made a mistake, you can redo your changes. Try it out, change the content and hit the undo button!
|
||||
</p>
|
||||
<p>
|
||||
And yes, you can also use a keyboard shortcut to undo changes (<code>Control/Cmd</code> <code>Z</code>) or redo changes (<code>Control/Cmd</code> <code>Shift</code> <code>Z</code>).
|
||||
</p>
|
||||
`,
|
||||
extensions: defaultExtensions(),
|
||||
})
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -17,6 +17,10 @@ const CustomDocument = Document.extend({
|
||||
content: 'taskList',
|
||||
})
|
||||
|
||||
const CustomTaskItem = TaskItem.extend({
|
||||
content: 'paragraph',
|
||||
})
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
@@ -35,10 +39,10 @@ export default {
|
||||
Paragraph(),
|
||||
Text(),
|
||||
TaskList(),
|
||||
TaskItem(),
|
||||
CustomTaskItem(),
|
||||
],
|
||||
content: `
|
||||
<ul data-type="task_list">
|
||||
<ul data-type="taskList">
|
||||
<li data-type="taskItem" data-checked="true">A list item</li>
|
||||
<li data-type="taskItem" data-checked="false">And another one</li>
|
||||
</ul>
|
||||
|
||||
@@ -10,6 +10,9 @@ import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import Focus from '@tiptap/extension-focus'
|
||||
import Code from '@tiptap/extension-code'
|
||||
import BulletList from '@tiptap/extension-bullet-list'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -32,15 +35,19 @@ export default {
|
||||
className: 'has-focus',
|
||||
nested: true,
|
||||
}),
|
||||
Code(),
|
||||
BulletList(),
|
||||
ListItem(),
|
||||
],
|
||||
autoFocus: true,
|
||||
content: `
|
||||
<p>
|
||||
The focus extension adds a class to the focused node only. That enables you to add a custom styling to just that node. By default, it’ll add <code>.has-focus</code>, even to nested nodes.
|
||||
</p>
|
||||
<p>
|
||||
Nested elements will be focused with the default setting nested: true. Otherwise the whole item will get the focus class, even when just a single nested item is selected.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Nested elements (like this list item) will be focused with the default setting of <code>nested: true</code>.</li>
|
||||
<li>Otherwise the whole list will get the focus class, even when just a single list item is selected.</li>
|
||||
</ul>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
@@ -39,7 +39,12 @@ export default {
|
||||
History(),
|
||||
],
|
||||
content: `
|
||||
<p>Edit this text and press undo to test this extension.</p>
|
||||
<p>
|
||||
With the History extension the Editor will keep track of your changes. And if you think you made a mistake, you can redo your changes. Try it out, change the content and hit the undo button!
|
||||
</p>
|
||||
<p>
|
||||
And yes, you can also use a keyboard shortcut to undo changes (Control/Cmd Z) or redo changes (Control/Cmd Shift Z).
|
||||
</p>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
@@ -1,18 +1,84 @@
|
||||
context('/api/nodes/text', () => {
|
||||
context('/api/extensions/text-align', () => {
|
||||
before(() => {
|
||||
cy.visit('/api/nodes/text')
|
||||
cy.visit('/api/extensions/text-align')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.clearContent()
|
||||
editor.setContent('<p>Example Text</p>')
|
||||
})
|
||||
})
|
||||
|
||||
it('text should be wrapped in a paragraph by default', () => {
|
||||
it('should parse left align text correctly', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.setContent('<p style="text-align: left">Example Text</p>')
|
||||
expect(editor.getHTML()).to.eq('<p style="text-align: left">Example Text</p>')
|
||||
})
|
||||
})
|
||||
|
||||
it('should parse center align text correctly', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.setContent('<p style="text-align: center">Example Text</p>')
|
||||
expect(editor.getHTML()).to.eq('<p style="text-align: center">Example Text</p>')
|
||||
})
|
||||
})
|
||||
|
||||
it('should parse right align text correctly', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.setContent('<p style="text-align: right">Example Text</p>')
|
||||
expect(editor.getHTML()).to.eq('<p style="text-align: right">Example Text</p>')
|
||||
})
|
||||
})
|
||||
|
||||
it('should parse left justify text correctly', () => {
|
||||
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||
editor.setContent('<p style="text-align: justify">Example Text</p>')
|
||||
expect(editor.getHTML()).to.eq('<p style="text-align: justify">Example Text</p>')
|
||||
})
|
||||
})
|
||||
|
||||
it('aligns the text left on the 1st button', () => {
|
||||
cy.get('.demo__preview button:nth-child(1)')
|
||||
.click()
|
||||
|
||||
cy.get('.ProseMirror')
|
||||
.type('Example Text')
|
||||
.find('p')
|
||||
.should('contain', 'Example Text')
|
||||
.should('have.css', 'text-align', 'left')
|
||||
})
|
||||
|
||||
it('aligns the text center on the 2nd button', () => {
|
||||
cy.get('.demo__preview button:nth-child(2)')
|
||||
.click()
|
||||
|
||||
cy.get('.ProseMirror')
|
||||
.find('p')
|
||||
.should('have.css', 'text-align', 'center')
|
||||
})
|
||||
|
||||
it('aligns the text right on the 3rd button', () => {
|
||||
cy.get('.demo__preview button:nth-child(3)')
|
||||
.click()
|
||||
|
||||
cy.get('.ProseMirror')
|
||||
.find('p')
|
||||
.should('have.css', 'text-align', 'right')
|
||||
})
|
||||
|
||||
it('aligns the text justified on the 4th button', () => {
|
||||
cy.get('.demo__preview button:nth-child(4)')
|
||||
.click()
|
||||
|
||||
cy.get('.ProseMirror')
|
||||
.find('p')
|
||||
.should('have.css', 'text-align', 'justify')
|
||||
})
|
||||
|
||||
it('aligns the text default on the 5th button', () => {
|
||||
cy.get('.demo__preview button:nth-child(5)')
|
||||
.click()
|
||||
|
||||
cy.get('.ProseMirror')
|
||||
.find('p')
|
||||
.should('have.css', 'text-align', 'left')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
<button @click="editor.chain().focus().textAlign('right').run()">
|
||||
right
|
||||
</button>
|
||||
<button @click="editor.chain().focus().textAlign('justify').run()">
|
||||
justify
|
||||
</button>
|
||||
<button @click="editor.chain().focus().resetNodeAttributes(['textAlign']).run()">
|
||||
set default
|
||||
</button>
|
||||
|
||||
@@ -98,4 +98,28 @@ context('/api/extensions/typography', () => {
|
||||
.type('>> raquorow')
|
||||
.should('contain', '» raquo')
|
||||
})
|
||||
|
||||
it('should make a multiplication sign from an asterisk', () => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('1*1 multiplication')
|
||||
.should('contain', '1×1 multiplication')
|
||||
})
|
||||
|
||||
it('should make a multiplication sign from an x', () => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('1x1 multiplication')
|
||||
.should('contain', '1×1 multiplication')
|
||||
})
|
||||
|
||||
it('should make a multiplication sign from an asterisk with spaces', () => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('1 * 1 multiplication')
|
||||
.should('contain', '1 × 1 multiplication')
|
||||
})
|
||||
|
||||
it('should make a multiplication sign from an x with spaces', () => {
|
||||
cy.get('.ProseMirror')
|
||||
.type('1 x 1 multiplication')
|
||||
.should('contain', '1 × 1 multiplication')
|
||||
})
|
||||
})
|
||||
|
||||
5
docs/src/demos/Marks/TextStyle/index.spec.js
Normal file
5
docs/src/demos/Marks/TextStyle/index.spec.js
Normal file
@@ -0,0 +1,5 @@
|
||||
context('/api/marks/text-style', () => {
|
||||
before(() => {
|
||||
cy.visit('/api/marks/text-style')
|
||||
})
|
||||
})
|
||||
@@ -1,13 +1,34 @@
|
||||
<template>
|
||||
<div v-if="editor">
|
||||
<button
|
||||
@click="editor.chain().focus().fontFamily('Comic Sans MS').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { fontFamily: 'Comic Sans MS' }) }"
|
||||
@click="editor.chain().focus().fontFamily('Inter').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { fontFamily: 'Inter' }) }"
|
||||
>
|
||||
Inter
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().fontFamily('Comic Sans MS, Comic Sans').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { fontFamily: 'Comic Sans MS, Comic Sans' }) }"
|
||||
>
|
||||
Comic Sans
|
||||
</button>
|
||||
<button @click="editor.chain().focus().fontFamily().run()">
|
||||
Remove font-family
|
||||
<button
|
||||
@click="editor.chain().focus().fontFamily('serif').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { fontFamily: 'serif' }) }"
|
||||
>
|
||||
serif
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().fontFamily('monospace').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { fontFamily: 'monospace' }) }"
|
||||
>
|
||||
monospace
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().fontFamily('cursive').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { fontFamily: 'cursive' }) }"
|
||||
>
|
||||
cursive
|
||||
</button>
|
||||
|
||||
<editor-content :editor="editor" />
|
||||
@@ -44,7 +65,11 @@ export default {
|
||||
FontFamily(),
|
||||
],
|
||||
content: `
|
||||
<p><span style="font-family: Comic Sans MS">Welcome to the internet.</span></p>
|
||||
<p><span style="font-family: Inter">Inter</span></p>
|
||||
<p><span style="font-family: Comic Sans MS, Comic Sans">Comic Sans</span></p>
|
||||
<p><span style="font-family: serif">serif</span></p>
|
||||
<p><span style="font-family: monospace">monospace</span></p>
|
||||
<p><span style="font-family: cursive">cursive</span></p>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user