mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-07 17:43:49 +08:00
feat(html): switch from zeed-dom
to happy-dom-without-node
(#5984)
Some checks are pending
build / build (20) (push) Waiting to run
build / test (20, map[name:Demos/Commands spec:./demos/src/Commands/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Examples spec:./demos/src/Examples/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Experiments spec:./demos/src/Experiments/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Extensions spec:./demos/src/Extensions/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/GuideContent spec:./demos/src/GuideContent/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/GuideGettingStarted spec:./demos/src/GuideGettingStarted/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Marks spec:./demos/src/Marks/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Nodes spec:./demos/src/Nodes/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Integration spec:./tests/cypress/integration/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / release (20) (push) Blocked by required conditions
Publish / Release (20) (push) Waiting to run
Some checks are pending
build / build (20) (push) Waiting to run
build / test (20, map[name:Demos/Commands spec:./demos/src/Commands/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Examples spec:./demos/src/Examples/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Experiments spec:./demos/src/Experiments/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Extensions spec:./demos/src/Extensions/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/GuideContent spec:./demos/src/GuideContent/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/GuideGettingStarted spec:./demos/src/GuideGettingStarted/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Marks spec:./demos/src/Marks/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Demos/Nodes spec:./demos/src/Nodes/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / test (20, map[name:Integration spec:./tests/cypress/integration/**/*.spec.{js,ts}]) (push) Blocked by required conditions
build / release (20) (push) Blocked by required conditions
Publish / Release (20) (push) Waiting to run
This commit is contained in:
parent
efe6dafa57
commit
bf040b9044
5
.changeset/quick-days-matter.md
Normal file
5
.changeset/quick-days-matter.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@tiptap/html": major
|
||||
---
|
||||
|
||||
Replace `zeed-dom` with `happy-dom-without-node` for broader compatibility of the HTML parser. The only difference you should see is that `happy-dom-without-node` will output `xmlns="http://www.w3.org/1999/xhtml"` on root elements, which makes it compliant with the HTML5 specification.
|
@ -6,6 +6,6 @@ context('/src/GuideContent/GenerateHTML/React/', () => {
|
||||
it('should render the content as an HTML string', () => {
|
||||
cy.get('pre code').should('exist')
|
||||
|
||||
cy.get('pre code').should('contain', '<p>Example <strong>Text</strong></p>')
|
||||
cy.get('pre code').should('contain', '<p xmlns="http://www.w3.org/1999/xhtml">Example <strong>Text</strong></p>')
|
||||
})
|
||||
})
|
||||
|
@ -6,6 +6,6 @@ context('/src/GuideContent/GenerateHTML/Vue/', () => {
|
||||
it('should render the content as an HTML string', () => {
|
||||
cy.get('pre code').should('exist')
|
||||
|
||||
cy.get('pre code').should('contain', '<p>Example <strong>Text</strong></p>')
|
||||
cy.get('pre code').should('contain', '<p xmlns="http://www.w3.org/1999/xhtml">Example <strong>Text</strong></p>')
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
context('/src/GuideContent/GenerateHTML/Vue/', () => {
|
||||
context('/src/GuideContent/StaticRenderHTML/Vue/', () => {
|
||||
before(() => {
|
||||
cy.visit('/src/GuideContent/GenerateHTML/Vue/')
|
||||
cy.visit('/src/GuideContent/StaticRenderHTML/Vue/')
|
||||
})
|
||||
|
||||
it('should render the content as an HTML string', () => {
|
||||
|
@ -39,7 +39,7 @@
|
||||
"@tiptap/pm": "^3.0.0-next.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"zeed-dom": "^0.15.1"
|
||||
"happy-dom-without-node": "^14.12.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Extensions, getSchema } from '@tiptap/core'
|
||||
import { DOMParser, ParseOptions } from '@tiptap/pm/model'
|
||||
import { parseHTML } from 'zeed-dom'
|
||||
import { DOMParser as HappyDOMParser, Window as HappyDOMWindow } from 'happy-dom-without-node'
|
||||
|
||||
/**
|
||||
* Generates a JSON object from the given HTML string and converts it into a Prosemirror node with content.
|
||||
@ -16,7 +16,10 @@ import { parseHTML } from 'zeed-dom'
|
||||
*/
|
||||
export function generateJSON(html: string, extensions: Extensions, options?: ParseOptions): Record<string, any> {
|
||||
const schema = getSchema(extensions)
|
||||
const dom = parseHTML(html) as unknown as Node
|
||||
|
||||
return DOMParser.fromSchema(schema).parse(dom, options).toJSON()
|
||||
const parseInstance = window ? new window.DOMParser() : new HappyDOMParser(new HappyDOMWindow())
|
||||
|
||||
return DOMParser.fromSchema(schema)
|
||||
.parse(parseInstance.parseFromString(html, 'text/html').body as Node, options)
|
||||
.toJSON()
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { DOMSerializer, Node, Schema } from '@tiptap/pm/model'
|
||||
import { createHTMLDocument, VHTMLDocument } from 'zeed-dom'
|
||||
import { Window } from 'happy-dom-without-node'
|
||||
|
||||
/**
|
||||
* Returns the HTML string representation of a given document node.
|
||||
@ -23,10 +23,14 @@ export function getHTMLFromFragment(doc: Node, schema: Schema, options?: { docum
|
||||
return wrap.innerHTML
|
||||
}
|
||||
|
||||
// Use zeed-dom for serialization.
|
||||
const zeedDocument = DOMSerializer.fromSchema(schema).serializeFragment(doc.content, {
|
||||
document: createHTMLDocument() as unknown as Document,
|
||||
}) as unknown as VHTMLDocument
|
||||
// Use happy-dom for serialization.
|
||||
const browserWindow = window || new Window()
|
||||
|
||||
return zeedDocument.render()
|
||||
const fragment = DOMSerializer.fromSchema(schema).serializeFragment(doc.content, {
|
||||
document: browserWindow.document as unknown as Document,
|
||||
})
|
||||
|
||||
const serializer = new browserWindow.XMLSerializer()
|
||||
|
||||
return serializer.serializeToString(fragment as any)
|
||||
}
|
||||
|
@ -439,15 +439,6 @@ importers:
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
|
||||
packages/extension-line-height:
|
||||
devDependencies:
|
||||
'@tiptap/core':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../extension-text-style
|
||||
|
||||
packages/extension-link:
|
||||
dependencies:
|
||||
linkifyjs:
|
||||
@ -622,9 +613,9 @@ importers:
|
||||
|
||||
packages/html:
|
||||
dependencies:
|
||||
zeed-dom:
|
||||
specifier: ^0.15.1
|
||||
version: 0.15.1
|
||||
happy-dom-without-node:
|
||||
specifier: ^14.12.3
|
||||
version: 14.12.3
|
||||
devDependencies:
|
||||
'@tiptap/core':
|
||||
specifier: ^3.0.0-next.3
|
||||
@ -3113,10 +3104,6 @@ packages:
|
||||
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
|
||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
|
||||
|
||||
css-what@6.1.0:
|
||||
resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
cssesc@3.0.0:
|
||||
resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
|
||||
engines: {node: '>=4'}
|
||||
@ -3438,10 +3425,6 @@ packages:
|
||||
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
entities@5.0.0:
|
||||
resolution: {integrity: sha512-BeJFvFRJddxobhvEdm5GqHzRV/X+ACeuw0/BuuxsCh1EUZcAIz8+kYmBp/LrQuloy6K1f3a0M7+IhmZ7QnkISA==}
|
||||
engines: {node: '>=0.12'}
|
||||
|
||||
env-paths@2.2.1:
|
||||
resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
|
||||
engines: {node: '>=6'}
|
||||
@ -3931,6 +3914,10 @@ packages:
|
||||
graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
|
||||
happy-dom-without-node@14.12.3:
|
||||
resolution: {integrity: sha512-1wp8+GFneT8mBjVnzancXHRuscEUH3vnb38lfCHPxuSu6OiRw1kQzHFbTGYlNCU2YXOlVIlzsS6xg9nAr7Xg6Q==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
has-bigints@1.1.0:
|
||||
resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@ -5561,6 +5548,10 @@ packages:
|
||||
tr46@1.0.1:
|
||||
resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==}
|
||||
|
||||
tr46@5.0.0:
|
||||
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
tree-kill@1.2.2:
|
||||
resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==}
|
||||
hasBin: true
|
||||
@ -5941,6 +5932,10 @@ packages:
|
||||
webidl-conversions@4.0.2:
|
||||
resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==}
|
||||
|
||||
webidl-conversions@7.0.0:
|
||||
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
webpack-sources@3.2.3:
|
||||
resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==}
|
||||
engines: {node: '>=10.13.0'}
|
||||
@ -5959,6 +5954,14 @@ packages:
|
||||
resolution: {integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
whatwg-mimetype@3.0.0:
|
||||
resolution: {integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
whatwg-url@14.1.0:
|
||||
resolution: {integrity: sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
whatwg-url@7.1.0:
|
||||
resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==}
|
||||
|
||||
@ -6089,10 +6092,6 @@ packages:
|
||||
resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==}
|
||||
engines: {node: '>=12.20'}
|
||||
|
||||
zeed-dom@0.15.1:
|
||||
resolution: {integrity: sha512-dtZ0aQSFyZmoJS0m06/xBN1SazUBPL5HpzlAcs/KcRW0rzadYw12deQBjeMhGKMMeGEp7bA9vmikMLaO4exBcg==}
|
||||
engines: {node: '>=14.13.1'}
|
||||
|
||||
zod-package-json@1.0.3:
|
||||
resolution: {integrity: sha512-Mb6GzuRyUEl8X+6V6xzHbd4XV0au/4gOYrYP+CAfHL32uPmGswES+v2YqonZiW1NZWVA3jkssCKSU2knonm/aQ==}
|
||||
engines: {node: '>=20'}
|
||||
@ -8638,8 +8637,6 @@ snapshots:
|
||||
mdn-data: 2.0.30
|
||||
source-map-js: 1.2.1
|
||||
|
||||
css-what@6.1.0: {}
|
||||
|
||||
cssesc@3.0.0: {}
|
||||
|
||||
csstype@3.1.3: {}
|
||||
@ -9019,8 +9016,6 @@ snapshots:
|
||||
|
||||
entities@4.5.0: {}
|
||||
|
||||
entities@5.0.0: {}
|
||||
|
||||
env-paths@2.2.1: {}
|
||||
|
||||
environment@1.1.0: {}
|
||||
@ -9685,6 +9680,13 @@ snapshots:
|
||||
|
||||
graphemer@1.4.0: {}
|
||||
|
||||
happy-dom-without-node@14.12.3:
|
||||
dependencies:
|
||||
entities: 4.5.0
|
||||
webidl-conversions: 7.0.0
|
||||
whatwg-mimetype: 3.0.0
|
||||
whatwg-url: 14.1.0
|
||||
|
||||
has-bigints@1.1.0: {}
|
||||
|
||||
has-flag@3.0.0: {}
|
||||
@ -11406,6 +11408,10 @@ snapshots:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
tr46@5.0.0:
|
||||
dependencies:
|
||||
punycode: 2.3.1
|
||||
|
||||
tree-kill@1.2.2: {}
|
||||
|
||||
trim-lines@3.0.1: {}
|
||||
@ -11760,6 +11766,8 @@ snapshots:
|
||||
|
||||
webidl-conversions@4.0.2: {}
|
||||
|
||||
webidl-conversions@7.0.0: {}
|
||||
|
||||
webpack-sources@3.2.3: {}
|
||||
|
||||
webpack@5.97.1(esbuild@0.24.2):
|
||||
@ -11796,6 +11804,13 @@ snapshots:
|
||||
dependencies:
|
||||
iconv-lite: 0.6.3
|
||||
|
||||
whatwg-mimetype@3.0.0: {}
|
||||
|
||||
whatwg-url@14.1.0:
|
||||
dependencies:
|
||||
tr46: 5.0.0
|
||||
webidl-conversions: 7.0.0
|
||||
|
||||
whatwg-url@7.1.0:
|
||||
dependencies:
|
||||
lodash.sortby: 4.7.0
|
||||
@ -11942,11 +11957,6 @@ snapshots:
|
||||
|
||||
yocto-queue@1.1.1: {}
|
||||
|
||||
zeed-dom@0.15.1:
|
||||
dependencies:
|
||||
css-what: 6.1.0
|
||||
entities: 5.0.0
|
||||
|
||||
zod-package-json@1.0.3:
|
||||
dependencies:
|
||||
zod: 3.24.1
|
||||
|
@ -3,7 +3,10 @@
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import { generateHTML } from '@tiptap/html'
|
||||
import { TextStyle } from '@tiptap/extension-text-style'
|
||||
import Youtube from '@tiptap/extension-youtube'
|
||||
import { generateHTML, generateJSON } from '@tiptap/html'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
|
||||
describe('generateHTML', () => {
|
||||
it('generate HTML from JSON without an editor instance', () => {
|
||||
@ -24,6 +27,222 @@ describe('generateHTML', () => {
|
||||
|
||||
const html = generateHTML(json, [Document, Paragraph, Text])
|
||||
|
||||
expect(html).to.eq('<p>Example Text</p>')
|
||||
expect(html).to.eq('<p xmlns="http://www.w3.org/1999/xhtml">Example Text</p>')
|
||||
})
|
||||
|
||||
it('can convert from & to html', async () => {
|
||||
const extensions = [Document, Paragraph, Text, Youtube]
|
||||
const html = `<p>Tiptap now supports YouTube embeds! Awesome!</p>
|
||||
<div data-youtube-video>
|
||||
<iframe src="https://www.youtube.com/watch?v=cqHqLQgVCgY"></iframe>
|
||||
</div>`
|
||||
const json = generateJSON(html, extensions)
|
||||
|
||||
expect(json).to.deep.equal({
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Tiptap now supports YouTube embeds! Awesome!',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'youtube',
|
||||
attrs: {
|
||||
src: 'https://www.youtube.com/watch?v=cqHqLQgVCgY',
|
||||
start: 0,
|
||||
width: 640,
|
||||
height: 480,
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
expect(generateHTML(json, extensions)).to.equal(
|
||||
'<p xmlns="http://www.w3.org/1999/xhtml">Tiptap now supports YouTube embeds! Awesome!</p><div xmlns="http://www.w3.org/1999/xhtml" data-youtube-video=""><iframe width="640" height="480" allowfullscreen="true" autoplay="false" disablekbcontrols="false" enableiframeapi="false" endtime="0" ivloadpolicy="0" loop="false" modestbranding="false" origin="" playlist="" src="https://www.youtube.com/embed/cqHqLQgVCgY" start="0"></iframe></div>',
|
||||
)
|
||||
})
|
||||
|
||||
it('can convert from & to HTML with a complex schema', async () => {
|
||||
const extensions = [StarterKit, TextStyle]
|
||||
const html = `
|
||||
<h2>
|
||||
Hi there,
|
||||
</h2>
|
||||
<p>
|
||||
this is a <em>basic</em> example of <strong>Tiptap</strong>. Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
That’s a bullet list with one …
|
||||
</li>
|
||||
<li>
|
||||
… or two list items.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:
|
||||
</p>
|
||||
<pre><code class="language-css">body {
|
||||
display: none;
|
||||
}</code></pre>
|
||||
<p>
|
||||
I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.
|
||||
</p>
|
||||
<blockquote>
|
||||
Wow, that’s amazing. Good work, boy! 👏
|
||||
<br />
|
||||
— Mom
|
||||
</blockquote>`
|
||||
const json = generateJSON(html, extensions)
|
||||
|
||||
const expected = {
|
||||
type: 'doc',
|
||||
content: [
|
||||
{
|
||||
type: 'heading',
|
||||
attrs: {
|
||||
level: 2,
|
||||
},
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Hi there,',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'this is a ',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
marks: [
|
||||
{
|
||||
type: 'italic',
|
||||
},
|
||||
],
|
||||
text: 'basic',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: ' example of ',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
marks: [
|
||||
{
|
||||
type: 'bold',
|
||||
},
|
||||
],
|
||||
text: 'Tiptap',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: '. Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists:',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'bulletList',
|
||||
content: [
|
||||
{
|
||||
type: 'listItem',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'That’s a bullet list with one …',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'listItem',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: '… or two list items.',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'codeBlock',
|
||||
attrs: {
|
||||
language: 'css',
|
||||
},
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'body {\n display: none;\n}',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'blockquote',
|
||||
content: [
|
||||
{
|
||||
type: 'paragraph',
|
||||
content: [
|
||||
{
|
||||
type: 'text',
|
||||
text: 'Wow, that’s amazing. Good work, boy! 👏 ',
|
||||
},
|
||||
{
|
||||
type: 'hardBreak',
|
||||
},
|
||||
{
|
||||
type: 'text',
|
||||
text: '— Mom',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
expect(json).to.deep.equal(expected)
|
||||
|
||||
expect(generateHTML(json, extensions)).to.equal(
|
||||
`<h2 xmlns="http://www.w3.org/1999/xhtml">Hi there,</h2><p xmlns="http://www.w3.org/1999/xhtml">this is a <em>basic</em> example of <strong>Tiptap</strong>. Sure, there are all kind of basic text styles you’d probably expect from a text editor. But wait until you see the lists:</p><ul xmlns="http://www.w3.org/1999/xhtml"><li><p>That’s a bullet list with one …</p></li><li><p>… or two list items.</p></li></ul><p xmlns="http://www.w3.org/1999/xhtml">Isn’t that great? And all of that is editable. But wait, there’s more. Let’s try a code block:</p><pre xmlns="http://www.w3.org/1999/xhtml"><code class="language-css">body {
|
||||
display: none;
|
||||
}</code></pre><p xmlns="http://www.w3.org/1999/xhtml">I know, I know, this is impressive. It’s only the tip of the iceberg though. Give it a try and click a little bit around. Don’t forget to check the other examples too.</p><blockquote xmlns="http://www.w3.org/1999/xhtml"><p>Wow, that’s amazing. Good work, boy! 👏 <br />— Mom</p></blockquote>`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user