From 7feb19eb72d04faf4fc32bb491b54c4b9322c0c6 Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Wed, 5 May 2021 21:24:24 +0200 Subject: [PATCH 1/5] feature: add generateJSON utility function to generate JSON from a HTML string --- .../Guide/Content/GenerateJSON/index.spec.js | 7 +++++ .../Guide/Content/GenerateJSON/index.vue | 27 +++++++++++++++++ docs/src/docPages/api/utilities/html.md | 4 +++ docs/src/docPages/guide/output.md | 6 +++- packages/core/src/helpers/generateJSON.ts | 13 +++++++++ packages/core/src/index.ts | 1 + .../integration/core/generateJSON.spec.ts | 29 +++++++++++++++++++ 7 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 docs/src/demos/Guide/Content/GenerateJSON/index.spec.js create mode 100644 docs/src/demos/Guide/Content/GenerateJSON/index.vue create mode 100644 packages/core/src/helpers/generateJSON.ts create mode 100644 tests/cypress/integration/core/generateJSON.spec.ts diff --git a/docs/src/demos/Guide/Content/GenerateJSON/index.spec.js b/docs/src/demos/Guide/Content/GenerateJSON/index.spec.js new file mode 100644 index 00000000..78d6813c --- /dev/null +++ b/docs/src/demos/Guide/Content/GenerateJSON/index.spec.js @@ -0,0 +1,7 @@ +context('/demos/Guide/Content/GenerateJSON', () => { + before(() => { + cy.visit('/demos/Guide/Content/GenerateJSON') + }) + + // TODO: Write tests +}) diff --git a/docs/src/demos/Guide/Content/GenerateJSON/index.vue b/docs/src/demos/Guide/Content/GenerateJSON/index.vue new file mode 100644 index 00000000..4ecf7034 --- /dev/null +++ b/docs/src/demos/Guide/Content/GenerateJSON/index.vue @@ -0,0 +1,27 @@ + + + diff --git a/docs/src/docPages/api/utilities/html.md b/docs/src/docPages/api/utilities/html.md index de242ae8..13de12e7 100644 --- a/docs/src/docPages/api/utilities/html.md +++ b/docs/src/docPages/api/utilities/html.md @@ -9,3 +9,7 @@ The utility helps rendering JSON content as HTML without an editor instance, for ## Usage + +By the way, the other way is possible, too. The below examples shows how to generate JSON from HTML. + + diff --git a/docs/src/docPages/guide/output.md b/docs/src/docPages/guide/output.md index 7c587ecd..9771ec3b 100644 --- a/docs/src/docPages/guide/output.md +++ b/docs/src/docPages/guide/output.md @@ -117,7 +117,11 @@ If you need to render the content on the server side, for example to generate th That’s what the `generateHTML()` is for. It’s a helper function which renders HTML without an actual editor instance. - + + +By the way, the other way is possible, too. The below examples shows how to generate JSON from HTML. + + ## Migration If you’re migrating existing content to tiptap we would recommend to get your existing output to HTML. That’s probably the best format to get your initial content into tiptap, because ProseMirror ensures there is nothing wrong with it. Even if there are some tags or attributes that aren’t allowed (based on your configuration), tiptap just throws them away quietly. diff --git a/packages/core/src/helpers/generateJSON.ts b/packages/core/src/helpers/generateJSON.ts new file mode 100644 index 00000000..ec025f49 --- /dev/null +++ b/packages/core/src/helpers/generateJSON.ts @@ -0,0 +1,13 @@ +import { DOMParser } from 'prosemirror-model' +import getSchema from './getSchema' +import elementFromString from '../utilities/elementFromString' +import { Extensions } from '../types' + +export default function generateJSON(html: string, extensions: Extensions): Record { + const schema = getSchema(extensions) + const dom = elementFromString(html) + + return DOMParser.fromSchema(schema) + .parse(dom) + .toJSON() +} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 276f58af..a5043d6b 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -18,6 +18,7 @@ export { default as findChildren } from './helpers/findChildren' export { default as findParentNode } from './helpers/findParentNode' export { default as findParentNodeClosestToPos } from './helpers/findParentNodeClosestToPos' export { default as generateHTML } from './helpers/generateHTML' +export { default as generateJSON } from './helpers/generateJSON' export { default as getSchema } from './helpers/getSchema' export { default as getHTMLFromFragment } from './helpers/getHTMLFromFragment' export { default as getMarkAttributes } from './helpers/getMarkAttributes' diff --git a/tests/cypress/integration/core/generateJSON.spec.ts b/tests/cypress/integration/core/generateJSON.spec.ts new file mode 100644 index 00000000..57f96421 --- /dev/null +++ b/tests/cypress/integration/core/generateJSON.spec.ts @@ -0,0 +1,29 @@ +/// + +import { generateJSON } from '@tiptap/core' +import Document from '@tiptap/extension-document' +import Paragraph from '@tiptap/extension-paragraph' +import Text from '@tiptap/extension-text' + +describe('generateJSON', () => { + it('generate HTML from JSON without an editor instance', () => { + const html = '

Example Text

' + + const json = generateJSON(html, [ + Document, + Paragraph, + Text, + ]) + + expect(JSON.stringify(json)).to.eq(JSON.stringify({ + type: 'doc', + content: [{ + type: 'paragraph', + content: [{ + type: 'text', + text: 'Example Text', + }], + }], + })) + }) +}) From 90380f207d76b35ac75b1b3b604018021e587aa5 Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Wed, 5 May 2021 21:33:39 +0200 Subject: [PATCH 2/5] fix typo --- tests/cypress/integration/core/generateJSON.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cypress/integration/core/generateJSON.spec.ts b/tests/cypress/integration/core/generateJSON.spec.ts index 57f96421..d589dc2b 100644 --- a/tests/cypress/integration/core/generateJSON.spec.ts +++ b/tests/cypress/integration/core/generateJSON.spec.ts @@ -6,7 +6,7 @@ import Paragraph from '@tiptap/extension-paragraph' import Text from '@tiptap/extension-text' describe('generateJSON', () => { - it('generate HTML from JSON without an editor instance', () => { + it('generate JSON from HTML without an editor instance', () => { const html = '

Example Text

' const json = generateJSON(html, [ From a9c0bf5982224e99f9129b8f71dbd7df33be7dfe Mon Sep 17 00:00:00 2001 From: Hans Pagel Date: Wed, 5 May 2021 23:10:45 +0200 Subject: [PATCH 3/5] add a generateJSON utility to the HTML package --- .../Guide/Content/GenerateJSON/index.vue | 5 +++- docs/src/docPages/api/utilities/html.md | 11 +++---- docs/src/docPages/guide/output.md | 2 +- packages/html/src/example.js | 24 --------------- packages/html/src/generateHTML.ts | 10 +++++++ packages/html/src/generateJSON.ts | 13 +++++++++ packages/html/src/index.ts | 12 ++------ .../integration/core/generateHTML.spec.ts | 2 +- .../integration/html/generateHTML.spec.ts | 29 +++++++++++++++++++ .../integration/html/generateJSON.spec.ts | 29 +++++++++++++++++++ 10 files changed, 95 insertions(+), 42 deletions(-) delete mode 100644 packages/html/src/example.js create mode 100644 packages/html/src/generateHTML.ts create mode 100644 packages/html/src/generateJSON.ts create mode 100644 tests/cypress/integration/html/generateHTML.spec.ts create mode 100644 tests/cypress/integration/html/generateJSON.spec.ts diff --git a/docs/src/demos/Guide/Content/GenerateJSON/index.vue b/docs/src/demos/Guide/Content/GenerateJSON/index.vue index 4ecf7034..aff6599d 100644 --- a/docs/src/demos/Guide/Content/GenerateJSON/index.vue +++ b/docs/src/demos/Guide/Content/GenerateJSON/index.vue @@ -3,7 +3,10 @@