Skip to content

Commit

Permalink
test(html): add and organise for slate-serializers-demo#36 (#173)
Browse files Browse the repository at this point in the history
* test(html): add and organise for slate-serializers-demo#36

* fix(packagelock): restore

* test(texttags.spec.ts): use domutils

* test(htmltoslate): add textTags vs elementTags

* test(elementattributetransform): add test

* test(htmltoslate): move whitespace tests

* style(types): remove unused type
  • Loading branch information
thompsonsj authored Oct 28, 2024
1 parent e291dd8 commit 1ae6cfc
Show file tree
Hide file tree
Showing 10 changed files with 832 additions and 359 deletions.
11 changes: 8 additions & 3 deletions packages/html/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,18 @@ const html = `<h1>Heading 1</h1><p>Paragraph 1</p>`
const serializedToSlate = htmlToSlate(html, payloadHtmlToSlateConfig)
```
##### Custom configuration
#### Options
Create your own configuration file that implements your schema.
- See [packages/html/src/lib/serializers/htmlToSlate/config/payload.ts](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/payload.ts) for an example of how to extend the default configuration; or
- copy [packages/html/src/lib/serializers/htmlToSlate/config/default.ts](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/default.ts) and rewrite it as appropriate.
You can create your own configuration file that implements your schema. See [packages/html/src/lib/serializers/htmlToSlate/config/payload.ts](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/payload.ts) for an example of how to extend the default configuration or copy [packages/html/src/lib/serializers/htmlToSlate/config/default.ts](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/default.ts) and rewrite it as appropriate.
For more detailed documentation and examples, see [htmlToSlate | `slate-serializers`](https://thompsonsj.github.io/slate-serializers-demo/html-to-slate/docs).
| Option | Description | Default |
| - | - | - |
| `textTags` | Define transform functions for HTML formatting elements. | See [default config](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/default.ts). Example `{ i: () => ({ italic: true }), /* ... */ }`. |
| `textTags` | Define transform functions for HTML formatting elements. | See [default config](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/default.ts). Examples: [textTags.spec.ts](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/tests/htmlToSlate/configuration/textTags.spec.ts). |
| `elementTags` | Define transform functions for HTML element tag names. | See [default config](https://github.com/thompsonsj/slate-serializers/blob/main/packages/html/src/lib/serializers/htmlToSlate/config/default.ts). Example `{ p: () => ({ type: 'p' }), /* ... */ }`. |
| `htmlPreProcessString` | Perform operations on the HTML string before serialization. | `(html) => html.replace(/<pre[^>]*>/g, '<code>').replace(/<\/pre>/g, '</code>')` | /* ... */ }`. |
| `filterWhitespaceNodes` | Remove whitespace that does not contribute meaning. | `true` |
Expand Down
4 changes: 0 additions & 4 deletions packages/html/src/lib/serializers/htmlToSlate/config/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@ export type AttributeTransform = ({
* @see /docs/config/htmlToSlate.md
*/
export interface Config {
/* Shortcut to map all HTML attribute/values */
elementAttributeMap?: {
style?: { [key: string]: string }
}
/* Use a custom function to generate Slate node attributes based on every Element passed through the serializer */
elementAttributeTransform?: AttributeTransform
/* Map HTML element tags to Slate JSON object attributes */
Expand Down
351 changes: 0 additions & 351 deletions packages/html/src/lib/serializers/htmlToSlate/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,214 +1,4 @@
import { htmlToSlate } from '.'
import { config as htmlToSlateConfig } from './config/default'
import { config as payloadHtmlToSlateConfig } from './config/payload'

describe('htmlToSlate whitespace handling', () => {
describe('inline formatting context', () => {
/**
* inline formatting example from mdn web docs
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Whitespace
*
* <h1>◦◦◦Hello◦⏎
* ⇥⇥⇥⇥<span>◦World!</span>⇥◦◦</h1>
*/
it('processes the hello world example in the same way as mdn docs', () => {
const fixture = `<h1> Hello
<span> World!</span> </h1>`
const expected: any[] = [
{
children: [
{
text: `Hello `,
},
{
children: [
{
text: ' World!',
},
],
type: 'span',
},
],
type: 'h1',
},
]
// extend the config to handle span tags
const config = {
...htmlToSlateConfig,
elementTags: {
...htmlToSlateConfig.elementTags,
span: () => ({ type: 'span' }),
},
}
expect(htmlToSlate(fixture, config)).toEqual(expected)
})
})

describe('block formatting context', () => {
it('processes the hello world example in the same way as mdn docs', () => {
const fixture = ` <div> Hello </div>
<div> World! </div> .
`
const expected: any[] = [
{
children: [
{
text: 'Hello',
},
],
type: 'div',
},
{
children: [
{
text: 'World!',
},
],
type: 'div',
},
{
children: [
{
text: ` . `,
},
],
},
]
// extend the config to handle span tags
const config = {
...htmlToSlateConfig,
elementTags: {
...htmlToSlateConfig.elementTags,
div: () => ({ type: 'div' }),
},
}
expect(htmlToSlate(fixture, config)).toEqual(expected)
})

it('preserves white space in the mdn docs hello world example if trimWhitespace is disabled', () => {
const fixture = `<h1> Hello
<span> World!</span> </h1>`
const expected: any[] = [
{
children: [
{
text: `Hello `,
},
{
children: [
{
text: ' World!',
},
],
type: 'span',
},
],
type: 'h1',
},
]
// extend the config to handle span tags
const config = {
...htmlToSlateConfig,
elementTags: {
...htmlToSlateConfig.elementTags,
span: () => ({ type: 'span' }),
},
trimWhiteSpace: false,
}
expect(htmlToSlate(fixture, config)).toEqual(expected)
})

/**
* @see https://github.com/fb55/htmlparser2/issues/90
*/
it('processes the example from htmlparser2 #90', () => {
const fixture = '<p>foo<b> <i>bar</i></b></p>'
const expected: any[] = [
{
children: [
{
text: 'foo',
},
{
text: ' ',
},
{
italic: true,
text: 'bar',
},
],
type: 'p',
},
]
expect(htmlToSlate(fixture)).toEqual(expected)
})
})

describe('preserve formatting context', () => {
it('preserves whitespace for pre tags', () => {
const fixture = `<pre> two spaces before
then spaces and a line break with a space after. </pre>`
const expected: any[] = [
{
children: [
{
code: true,
text: ` two spaces before
then spaces and a line break with a space after. `,
},
],
},
]
expect(htmlToSlate(fixture)).toEqual(expected)
})

it('removes non-mapped block elements containing whitespace only', () => {
const fixture =
'<div>Für Ihre Sicherheit&nbsp;</div>\n<div> </div>\n<div>Bitte beachten Sie die Ansagen der Besatzung</div>'
const expected: any[] = [
{
children: [
{
text: 'Für Ihre Sicherheit',
},
],
},
{
children: [
{
text: 'Bitte beachten Sie die Ansagen der Besatzung',
},
],
},
]
expect(htmlToSlate(fixture, payloadHtmlToSlateConfig)).toEqual(expected)
})

it('does not remove non-mapped block elements with text contents consisting of a non-breaking line space', () => {
const fixture =
'<div>Für Ihre Sicherheit&nbsp;</div>\n<div>&nbsp;</div>\n<div>Bitte beachten Sie die Ansagen der Besatzung</div>'
const expected: any[] = [
{
children: [
{
text: 'Für Ihre Sicherheit',
},
],
},
{
children: [
{
text: 'Bitte beachten Sie die Ansagen der Besatzung',
},
],
},
]
expect(htmlToSlate(fixture, payloadHtmlToSlateConfig)).toEqual(expected)
})
})
})

describe('inline code and pre HTML elements', () => {
it('can handle inline code tags', () => {
Expand Down Expand Up @@ -324,147 +114,6 @@ describe('empty content', () => {
]
expect(htmlToSlate(html)).toEqual(slate)
})

it('converts a br tag to a line break', () => {
const html = 'Line 1<br />Line 2'
const slate: any[] = [
{
children: [
{
text: 'Line 1',
},
],
},
{
children: [
{
text: '',
},
],
},
{
children: [
{
text: 'Line 2',
},
],
},
]
expect(htmlToSlate(html)).toEqual(slate)
})

it('converts a br tag in a paragraph to a line break', () => {
const html = '<p>Paragraph with line<br /><br />breaks.</p>'
const slate: any[] = [
{
children: [
{
text: 'Paragraph with line',
},
{
text: '\n',
},
{
text: '\n',
},
{
text: 'breaks.',
},
],
type: 'p',
},
]
expect(htmlToSlate(html)).toEqual(slate)
})

it('does nothing with a br tag if convertBrToLineBreak is false', () => {
const html = '<br />'
const slate: any[] = []
expect(htmlToSlate(html, { ...htmlToSlateConfig, convertBrToLineBreak: false })).toEqual(slate)
})

it('converts a br tag to a slate node if defined as an element tag', () => {
const html = '<br />'
const slate: any[] = [
{
children: [
{
text: '',
},
],
type: 'br',
},
]
expect(
htmlToSlate(html, {
...htmlToSlateConfig,
convertBrToLineBreak: false,
elementTags: {
...htmlToSlateConfig.elementTags,
br: () => ({ type: 'br' }),
},
}),
).toEqual(slate)
})

it('adds an empty text element in place of a br tag as a line break', () => {
const html = 'Line 1<br>\n<span>Line 2</span>'
const slate: any[] = [
{
children: [
{
text: 'Line 1',
},
],
},
{
children: [
{
text: '',
},
],
},
{
children: [
{
text: 'Line 2',
},
],
},
]
expect(
htmlToSlate(html, {
...htmlToSlateConfig,
convertBrToLineBreak: true,
}),
).toEqual(slate)
})

it('adds a line break in place of a br tag inside of a block element', () => {
const html = '<p>Line 1<br>\n<span>Line 2</span></p>'
const slate: any[] = [
{
type: 'p',
children: [
{
text: 'Line 1',
},
{
text: '\n',
},
{
text: 'Line 2',
},
],
},
]
expect(
htmlToSlate(html, {
...htmlToSlateConfig,
convertBrToLineBreak: true,
}),
).toEqual(slate)
})
})
})

Expand Down
Loading

0 comments on commit 1ae6cfc

Please sign in to comment.