add mark demos
This commit is contained in:
15
demos/src/Marks/Bold/Vue/index.html
Normal file
15
demos/src/Marks/Bold/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Bold', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
91
demos/src/Marks/Bold/Vue/index.spec.js
Normal file
91
demos/src/Marks/Bold/Vue/index.spec.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
context('/demos/Marks/Bold', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Bold')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform b tags to strong tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><b>Example Text</b></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><strong>Example Text</strong></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sould omit b tags with normal font weight inline style', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><b style="font-weight: normal">Example Text</b></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p>Example Text</p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform any tag with bold inline style to strong tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="font-weight: bold">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><strong>Example Text</strong></p>')
|
||||||
|
|
||||||
|
editor.commands.setContent('<p><span style="font-weight: bolder">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><strong>Example Text</strong></p>')
|
||||||
|
|
||||||
|
editor.commands.setContent('<p><span style="font-weight: 500">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><strong>Example Text</strong></p>')
|
||||||
|
|
||||||
|
editor.commands.setContent('<p><span style="font-weight: 900">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><strong>Example Text</strong></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should make the selected text bold', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('strong')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text bold', () => {
|
||||||
|
cy.get('button:first').click()
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
cy.get('button:first').click()
|
||||||
|
cy.get('.ProseMirror strong').should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should make the selected text bold when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'b' })
|
||||||
|
.find('strong')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle the selected text bold when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'b' })
|
||||||
|
.find('strong')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'b' })
|
||||||
|
|
||||||
|
cy.get('.ProseMirror strong').should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should make a bold text from the default markdown shortcut', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('**Bold**')
|
||||||
|
.find('strong')
|
||||||
|
.should('contain', 'Bold')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should make a bold text from the alternative markdown shortcut', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('__Bold__')
|
||||||
|
.find('strong')
|
||||||
|
.should('contain', 'Bold')
|
||||||
|
})
|
||||||
|
})
|
||||||
53
demos/src/Marks/Bold/Vue/index.vue
Normal file
53
demos/src/Marks/Bold/Vue/index.vue
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }">
|
||||||
|
bold
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Bold from '@tiptap/extension-bold'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Bold,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This isn’t bold.</p>
|
||||||
|
<p><strong>This is bold.</strong></p>
|
||||||
|
<p><b>And this.</b></p>
|
||||||
|
<p style="font-weight: bold">This as well.</p>
|
||||||
|
<p style="font-weight: bolder">Oh, and this!</p>
|
||||||
|
<p style="font-weight: 500">Cool, isn’t it!?</p>
|
||||||
|
<p style="font-weight: 999">Up to font weight 999!!!</p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/Code/Vue/index.html
Normal file
15
demos/src/Marks/Code/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Code', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
71
demos/src/Marks/Code/Vue/index.spec.js
Normal file
71
demos/src/Marks/Code/Vue/index.spec.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
context('/demos/Marks/Code', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Code')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse code tags correctly', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><code>Example Text</code></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><code>Example Text</code></p>')
|
||||||
|
|
||||||
|
editor.commands.setContent('<code>Example Text</code>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><code>Example Text</code></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should mark the selected text as inline code', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('code')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle the selected text as inline code', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('{selectall}')
|
||||||
|
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror code')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should make the selected text bold when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'e' })
|
||||||
|
.find('code')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle the selected text bold when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'e' })
|
||||||
|
.find('code')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'e' })
|
||||||
|
|
||||||
|
cy.get('.ProseMirror code').should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should make inline code from the markdown shortcut', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('`Example`')
|
||||||
|
.find('code')
|
||||||
|
.should('contain', 'Example')
|
||||||
|
})
|
||||||
|
})
|
||||||
48
demos/src/Marks/Code/Vue/index.vue
Normal file
48
demos/src/Marks/Code/Vue/index.vue
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleCode().run()" :class="{ 'is-active': editor.isActive('code') }">
|
||||||
|
code
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
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: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Code,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This isn’t code.</p>
|
||||||
|
<p><code>This is code.</code></p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/Highlight/Vue/index.html
Normal file
15
demos/src/Marks/Highlight/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Highlight', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
139
demos/src/Marks/Highlight/Vue/index.spec.js
Normal file
139
demos/src/Marks/Highlight/Vue/index.spec.js
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
context('/demos/Marks/Highlight', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Highlight')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor
|
||||||
|
.chain()
|
||||||
|
.setContent('<p>Example Text</p>')
|
||||||
|
.selectAll()
|
||||||
|
.run()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should highlight the selected text', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('mark')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should highlight the text in a specific color', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.toggleHighlight({ color: 'red' })
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('mark')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
.should('have.attr', 'data-color', 'red')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should update the attributes of existing marks', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor
|
||||||
|
.chain()
|
||||||
|
.setContent('<p><mark style="background-color: blue;">Example Text</mark></p>')
|
||||||
|
.selectAll()
|
||||||
|
.toggleHighlight({ color: 'rgb(255, 0, 0)' })
|
||||||
|
.run()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('mark')
|
||||||
|
.should('have.css', 'background-color', 'rgb(255, 0, 0)')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should remove existing marks with the same attributes', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor
|
||||||
|
.chain()
|
||||||
|
.setContent('<p><mark style="background-color: rgb(255, 0, 0);">Example Text</mark></p>')
|
||||||
|
.selectAll()
|
||||||
|
.toggleHighlight({ color: 'rgb(255, 0, 0)' })
|
||||||
|
.run()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('mark')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('is active for mark with any attributes', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor
|
||||||
|
.chain()
|
||||||
|
.setContent('<p><mark data-color="red">Example Text</mark></p>')
|
||||||
|
.selectAll()
|
||||||
|
.run()
|
||||||
|
|
||||||
|
expect(editor.isActive('highlight')).to.eq(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('is active for mark with same attributes', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor
|
||||||
|
.chain()
|
||||||
|
.setContent('<p><mark style="background-color: rgb(255, 0, 0);">Example Text</mark></p>')
|
||||||
|
.selectAll()
|
||||||
|
.run()
|
||||||
|
|
||||||
|
const isActive = editor.isActive('highlight', {
|
||||||
|
color: 'rgb(255, 0, 0)',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(isActive).to.eq(true)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('isn’t active for mark with other attributes', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor
|
||||||
|
.chain()
|
||||||
|
.setContent('<p><mark style="background-color: rgb(255, 0, 0);">Example Text</mark></p>')
|
||||||
|
.selectAll()
|
||||||
|
.run()
|
||||||
|
|
||||||
|
const isActive = editor.isActive('highlight', {
|
||||||
|
color: 'rgb(0, 0, 0)',
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(isActive).to.eq(false)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text highlighted', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('{selectall}')
|
||||||
|
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('mark')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should highlight the selected text when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, shiftKey: true, key: 'h' })
|
||||||
|
.find('mark')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle the selected text highlighted when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, shiftKey: true, key: 'h' })
|
||||||
|
.trigger('keydown', { modKey: true, shiftKey: true, key: 'h' })
|
||||||
|
.find('mark')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
87
demos/src/Marks/Highlight/Vue/index.vue
Normal file
87
demos/src/Marks/Highlight/Vue/index.vue
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleHighlight().run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('highlight') }"
|
||||||
|
>
|
||||||
|
highlight (any)
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="editor.chain().focus().toggleHighlight({
|
||||||
|
color: ''
|
||||||
|
}).run()"
|
||||||
|
:class="{ 'is-active': editor.isActive('highlight', {
|
||||||
|
color: ''
|
||||||
|
}) }"
|
||||||
|
>
|
||||||
|
highlight (default)
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().toggleHighlight({ color: 'red' }).run()" :class="{ 'is-active': editor.isActive('highlight', { color: 'red' }) }">
|
||||||
|
"red"
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().toggleHighlight({ color: '#ffa8a8' }).run()" :class="{ 'is-active': editor.isActive('highlight', { color: '#ffa8a8' }) }">
|
||||||
|
red
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().toggleHighlight({ color: '#ffc078' }).run()" :class="{ 'is-active': editor.isActive('highlight', { color: '#ffc078' }) }">
|
||||||
|
orange
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().toggleHighlight({ color: '#8ce99a' }).run()" :class="{ 'is-active': editor.isActive('highlight', { color: '#8ce99a' }) }">
|
||||||
|
green
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().toggleHighlight({ color: '#74c0fc' }).run()" :class="{ 'is-active': editor.isActive('highlight', { color: '#74c0fc' }) }">
|
||||||
|
blue
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().toggleHighlight({ color: '#b197fc' }).run()" :class="{ 'is-active': editor.isActive('highlight', { color: '#b197fc' }) }">
|
||||||
|
purple
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Highlight from '@tiptap/extension-highlight'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Highlight.configure({ multicolor: true }),
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This isn’t highlighted.</s></p>
|
||||||
|
<p><mark>But that one is.</mark></p>
|
||||||
|
<p><mark style="background-color: red;">And this is highlighted too, but in a different color.</mark></p>
|
||||||
|
<p><mark data-color="#ffa8a8">And this one has a data attribute.</mark></p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
mark {
|
||||||
|
background-color: #ffe066;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
15
demos/src/Marks/Italic/Vue/index.html
Normal file
15
demos/src/Marks/Italic/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Italic', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
71
demos/src/Marks/Italic/Vue/index.spec.js
Normal file
71
demos/src/Marks/Italic/Vue/index.spec.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
context('/demos/Marks/Italic', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Italic')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('i tags should be transformed to em tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><i>Example Text</i></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><em>Example Text</em></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('i tags with normal font style should be omitted', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><i style="font-style: normal">Example Text</i></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p>Example Text</p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('generic tags with italic style should be transformed to strong tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="font-style: italic">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><em>Example Text</em></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should make the selected text italic', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('em')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text italic', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('{selectall}')
|
||||||
|
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror em')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the keyboard shortcut should make the selected text italic', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'i' })
|
||||||
|
.find('em')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the keyboard shortcut should toggle the selected text italic', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'i' })
|
||||||
|
.trigger('keydown', { modKey: true, key: 'i' })
|
||||||
|
.find('em')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
50
demos/src/Marks/Italic/Vue/index.vue
Normal file
50
demos/src/Marks/Italic/Vue/index.vue
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleItalic().run()" :class="{ 'is-active': editor.isActive('italic') }">
|
||||||
|
italic
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Italic from '@tiptap/extension-italic'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Italic,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This isn’t italic.</p>
|
||||||
|
<p><em>This is italic.</em></p>
|
||||||
|
<p><i>And this.</i></p>
|
||||||
|
<p style="font-style: italic">This as well.</p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/Link/Vue/index.html
Normal file
15
demos/src/Marks/Link/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Link', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
76
demos/src/Marks/Link/Vue/index.spec.js
Normal file
76
demos/src/Marks/Link/Vue/index.spec.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
context('/demos/Marks/Link', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Link')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse a tags correctly', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><a href="#">Example Text</a></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><a target="_blank" rel="noopener noreferrer nofollow" href="#">Example Text</a></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse a tags with target attribute correctly', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><a href="#" target="_self">Example Text</a></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><a target="_self" rel="noopener noreferrer nofollow" href="#">Example Text</a></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse a tags with rel attribute correctly', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><a href="#" rel="follow">Example Text</a></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><a target="_blank" rel="noopener noreferrer nofollow" href="#">Example Text</a></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should add a link to the selected text', () => {
|
||||||
|
cy.window().then(win => {
|
||||||
|
cy.stub(win, 'prompt').returns('https://tiptap.dev')
|
||||||
|
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.window().its('prompt').should('be.called')
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('a')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
.should('have.attr', 'href', 'https://tiptap.dev')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('detects a pasted URL within a text', () => {
|
||||||
|
cy.get('.ProseMirror').paste({ pastePayload: 'some text https://example.com around an url', pasteType: 'text/plain' })
|
||||||
|
.find('a')
|
||||||
|
.should('contain', 'https://example.com')
|
||||||
|
.should('have.attr', 'href', 'https://example.com')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('detects a pasted URL', () => {
|
||||||
|
cy.get('.ProseMirror').paste({ pastePayload: 'https://example.com', pasteType: 'text/plain' })
|
||||||
|
.find('a')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
.should('have.attr', 'href', 'https://example.com')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('correctly detects multiple pasted URLs', () => {
|
||||||
|
cy.get('.ProseMirror').paste({ pastePayload: 'https://example1.com, https://example2.com/foobar, (http://example3.com/foobar)', pasteType: 'text/plain' })
|
||||||
|
|
||||||
|
cy.get('.ProseMirror').find('a[href="https://example1.com"]')
|
||||||
|
.should('contain', 'https://example1.com')
|
||||||
|
|
||||||
|
cy.get('.ProseMirror').find('a[href="https://example2.com/foobar"]')
|
||||||
|
.should('contain', 'https://example2.com/foobar')
|
||||||
|
|
||||||
|
cy.get('.ProseMirror').find('a[href="http://example3.com/foobar"]')
|
||||||
|
.should('contain', 'http://example3.com/foobar')
|
||||||
|
})
|
||||||
|
})
|
||||||
82
demos/src/Marks/Link/Vue/index.vue
Normal file
82
demos/src/Marks/Link/Vue/index.vue
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="setLink" :class="{ 'is-active': editor.isActive('link') }">
|
||||||
|
link
|
||||||
|
</button>
|
||||||
|
<button @click="editor.chain().focus().unsetLink().run()" v-if="editor.isActive('link')">
|
||||||
|
remove
|
||||||
|
</button>
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Link from '@tiptap/extension-link'
|
||||||
|
import Bold from '@tiptap/extension-bold'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Bold,
|
||||||
|
Link,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>
|
||||||
|
Wow, this editor has support for links to the whole <strong><a href="https://en.wikipedia.org/wiki/World_Wide_Web">world wide web</a></strong>. We tested a lot of URLs and I think you can add *every URL* you want. Isn’t that cool? Let’s try <a href="https://statamic.com/">another one!</a> Yep, seems to work.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
By default every link will get a \`rel="noopener noreferrer nofollow"\` attribute. It’s configurable though.
|
||||||
|
</p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
setLink() {
|
||||||
|
const url = window.prompt('URL')
|
||||||
|
|
||||||
|
this.editor
|
||||||
|
.chain()
|
||||||
|
.focus()
|
||||||
|
.extendMarkRange('link')
|
||||||
|
.setLink({ href: url })
|
||||||
|
.run()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
/* Basic editor styles */
|
||||||
|
.ProseMirror {
|
||||||
|
> * + * {
|
||||||
|
margin-top: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #68CEF8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
15
demos/src/Marks/Strike/Vue/index.html
Normal file
15
demos/src/Marks/Strike/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Strike', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
86
demos/src/Marks/Strike/Vue/index.spec.js
Normal file
86
demos/src/Marks/Strike/Vue/index.spec.js
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
context('/demos/Marks/Strike', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Strike')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse s tags correctly', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><s>Example Text</s></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><s>Example Text</s></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform del tags to s tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><del>Example Text</del></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><s>Example Text</s></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform strike tags to s tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><strike>Example Text</strike></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><s>Example Text</s></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform any tag with text decoration line through to s tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="text-decoration: line-through">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><s>Example Text</s></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should strike the selected text', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('s')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text striked', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('{selectall}')
|
||||||
|
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('s')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should strike the selected text when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, shiftKey: true, key: 'x' })
|
||||||
|
.find('s')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle the selected text striked when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, shiftKey: true, key: 'x' })
|
||||||
|
.trigger('keydown', { modKey: true, shiftKey: true, key: 'x' })
|
||||||
|
.find('s')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should make a striked text from the markdown shortcut', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('~~Strike~~')
|
||||||
|
.find('s')
|
||||||
|
.should('contain', 'Strike')
|
||||||
|
})
|
||||||
|
})
|
||||||
51
demos/src/Marks/Strike/Vue/index.vue
Normal file
51
demos/src/Marks/Strike/Vue/index.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleStrike().run()" :class="{ 'is-active': editor.isActive('strike') }">
|
||||||
|
strike
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Strike from '@tiptap/extension-strike'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Strike,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This isn’t striked through.</s></p>
|
||||||
|
<p><s>But that’s striked through.</s></p>
|
||||||
|
<p><del>And this.</del></p>
|
||||||
|
<p><strike>This too.</strike></p>
|
||||||
|
<p style="text-decoration: line-through">This as well.</p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/Subscript/Vue/index.html
Normal file
15
demos/src/Marks/Subscript/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Subscript', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
42
demos/src/Marks/Subscript/Vue/index.spec.js
Normal file
42
demos/src/Marks/Subscript/Vue/index.spec.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
context('/demos/Marks/Subscript', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Subscript')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform inline style to sub tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="vertical-align: sub">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><sub>Example Text</sub></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sould omit inline style with a different vertical align', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><b style="vertical-align: middle">Example Text</b></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p>Example Text</p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should make the selected text bold', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('sub')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text bold', () => {
|
||||||
|
cy.get('button:first').click()
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
cy.get('button:first').click()
|
||||||
|
cy.get('.ProseMirror sub').should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
49
demos/src/Marks/Subscript/Vue/index.vue
Normal file
49
demos/src/Marks/Subscript/Vue/index.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleSubscript().run()" :class="{ 'is-active': editor.isActive('subscript') }">
|
||||||
|
subscript
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Subscript from '@tiptap/extension-subscript'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Subscript,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This is regular text.</p>
|
||||||
|
<p><sub>This is subscript.</sub></p>
|
||||||
|
<p><span style="vertical-align: sub">And this.</span></p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/Superscript/Vue/index.html
Normal file
15
demos/src/Marks/Superscript/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Superscript', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
42
demos/src/Marks/Superscript/Vue/index.spec.js
Normal file
42
demos/src/Marks/Superscript/Vue/index.spec.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
context('/demos/Marks/Superscript', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Superscript')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform inline style to sup tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="vertical-align: super">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><sup>Example Text</sup></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('sould omit inline style with a different vertical align', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="vertical-align: middle">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p>Example Text</p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should make the selected text bold', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('sup')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text bold', () => {
|
||||||
|
cy.get('button:first').click()
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
cy.get('button:first').click()
|
||||||
|
cy.get('.ProseMirror sup').should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
49
demos/src/Marks/Superscript/Vue/index.vue
Normal file
49
demos/src/Marks/Superscript/Vue/index.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleSuperscript().run()" :class="{ 'is-active': editor.isActive('superscript') }">
|
||||||
|
superscript
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Superscript from '@tiptap/extension-superscript'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Superscript,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>This is regular text.</p>
|
||||||
|
<p><sup>This is superscript.</sup></p>
|
||||||
|
<p><span style="vertical-align: super">And this.</span></p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/TextStyle/Vue/index.html
Normal file
15
demos/src/Marks/TextStyle/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/TextStyle', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
7
demos/src/Marks/TextStyle/Vue/index.spec.js
Normal file
7
demos/src/Marks/TextStyle/Vue/index.spec.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
context('/demos/Marks/TextStyle', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/TextStyle')
|
||||||
|
})
|
||||||
|
|
||||||
|
// TODO: Write tests
|
||||||
|
})
|
||||||
44
demos/src/Marks/TextStyle/Vue/index.vue
Normal file
44
demos/src/Marks/TextStyle/Vue/index.vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import TextStyle from '@tiptap/extension-text-style'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
TextStyle,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p><span>This has a <span> tag without a style attribute, so it’s thrown away.</span></p>
|
||||||
|
<p><span style="">But this one is wrapped in a <span> tag with an inline style attribute, so it’s kept - even if it’s empty for now.</span></p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
15
demos/src/Marks/Underline/Vue/index.html
Normal file
15
demos/src/Marks/Underline/Vue/index.html
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module">
|
||||||
|
import setup from '../../../../setup/vue.ts'
|
||||||
|
import source from '@source'
|
||||||
|
setup('Marks/Underline', source)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
65
demos/src/Marks/Underline/Vue/index.spec.js
Normal file
65
demos/src/Marks/Underline/Vue/index.spec.js
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
context('/demos/Marks/Underline', () => {
|
||||||
|
before(() => {
|
||||||
|
cy.visit('/demos/Marks/Underline')
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p>Example Text</p>')
|
||||||
|
cy.get('.ProseMirror').type('{selectall}')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse u tags correctly', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><u>Example Text</u></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><u>Example Text</u></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should transform any tag with text decoration underline to u tags', () => {
|
||||||
|
cy.get('.ProseMirror').then(([{ editor }]) => {
|
||||||
|
editor.commands.setContent('<p><span style="text-decoration: underline">Example Text</span></p>')
|
||||||
|
expect(editor.getHTML()).to.eq('<p><u>Example Text</u></p>')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should underline the selected text', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('u')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('the button should toggle the selected text underline', () => {
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.type('{selectall}')
|
||||||
|
|
||||||
|
cy.get('button:first')
|
||||||
|
.click()
|
||||||
|
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.find('u')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should underline the selected text when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'u' })
|
||||||
|
.find('u')
|
||||||
|
.should('contain', 'Example Text')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should toggle the selected text underline when the keyboard shortcut is pressed', () => {
|
||||||
|
cy.get('.ProseMirror')
|
||||||
|
.trigger('keydown', { modKey: true, key: 'u' })
|
||||||
|
.trigger('keydown', { modKey: true, key: 'u' })
|
||||||
|
.find('u')
|
||||||
|
.should('not.exist')
|
||||||
|
})
|
||||||
|
})
|
||||||
49
demos/src/Marks/Underline/Vue/index.vue
Normal file
49
demos/src/Marks/Underline/Vue/index.vue
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="editor">
|
||||||
|
<button @click="editor.chain().focus().toggleUnderline().run()" :class="{ 'is-active': editor.isActive('underline') }">
|
||||||
|
underline
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<editor-content :editor="editor" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||||
|
import Document from '@tiptap/extension-document'
|
||||||
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
import Text from '@tiptap/extension-text'
|
||||||
|
import Underline from '@tiptap/extension-underline'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
EditorContent,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.editor = new Editor({
|
||||||
|
extensions: [
|
||||||
|
Document,
|
||||||
|
Paragraph,
|
||||||
|
Text,
|
||||||
|
Underline,
|
||||||
|
],
|
||||||
|
content: `
|
||||||
|
<p>There is no underline here.</p>
|
||||||
|
<p><u>This is underlined though.</u></p>
|
||||||
|
<p style="text-decoration: underline">And this as well.</p>
|
||||||
|
`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.editor.destroy()
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
Reference in New Issue
Block a user