1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-21 14:41:23 +02:00

Html serializer: optionally return React elements (#408)

* Html serializer optionally returns React elements

* update heredoc to indicate optional return value of array

* update documentation for html serializer to include React return option

* move returnElements argument to render:false
This commit is contained in:
jasonphillips
2016-10-26 14:46:24 -05:00
committed by Ian Storm Taylor
parent 270c2ab219
commit dca60c42ce
4 changed files with 23 additions and 7 deletions

View File

@@ -51,9 +51,9 @@ An array of rules to initialize the `Html` serializer with, defining your schema
Deserialize an HTML `string` into a [`State`](../models/state.md). How the string is deserialized will be determined by the rules that the `Html` serializer was constructed with. Deserialize an HTML `string` into a [`State`](../models/state.md). How the string is deserialized will be determined by the rules that the `Html` serializer was constructed with.
### `Html.serialize` ### `Html.serialize`
`Html.serialize(state: State) => String` `Html.serialize(state: State, [options: Object]) => String || Array`
Serialize a `state` into an HTML string. How the string is serialized will be determined by the rules that the `Html` serializer was constructed with. Serialize a `state` into an HTML string. How the string is serialized will be determined by the rules that the `Html` serializer was constructed with. If you pass `render: false` as an option, the return value will instead be an iterable list of the top-level React elements, to be rendered as children in your own React component.
## Rules ## Rules

View File

@@ -12,6 +12,8 @@ It doesn't hardcode any information about the schema itself (like which tag mean
It handles all of the heavy lifting of actually parsing the HTML, and iterating over the elements, and all you have to supply it is a `serialize()` and `deserialize()` function for each type of [`Node`](../models#node) or [`Mark`](../models/#mark) you want it to handle. It handles all of the heavy lifting of actually parsing the HTML, and iterating over the elements, and all you have to supply it is a `serialize()` and `deserialize()` function for each type of [`Node`](../models#node) or [`Mark`](../models/#mark) you want it to handle.
If called with `{render: false}` as the optional second argument, the serializer will return an iterable list of the top-level React elements generated, instead of automatically rendering these to a markup string.
#### Raw #### Raw
@@ -20,4 +22,3 @@ The `Raw` serializer is the simplest serializer, which translates a [`State`](..
It doesn't just use Immutable.js's [`.toJSON()`](https://facebook.github.io/immutable-js/docs/#/List/toJS) method. Instead, it performs a little bit of "minifying" logic to reduce unnecessary information from being in the raw output. It doesn't just use Immutable.js's [`.toJSON()`](https://facebook.github.io/immutable-js/docs/#/List/toJS) method. Instead, it performs a little bit of "minifying" logic to reduce unnecessary information from being in the raw output.
It also transforms [`Text`](../models#text) nodes's content from being organized by [`Characters`](../models#character) into the concept of "ranges", which have a unique set of [`Marks`](../models#mark). It also transforms [`Text`](../models#text) nodes's content from being organized by [`Characters`](../models#character) into the concept of "ranges", which have a unique set of [`Marks`](../models#mark).

View File

@@ -231,12 +231,16 @@ class Html {
* Serialize a `state` object into an HTML string. * Serialize a `state` object into an HTML string.
* *
* @param {State} state * @param {State} state
* @return {String} html * @param {Object} options
* @property {Boolean} render
* @return {String|Array} html
*/ */
serialize = (state) => { serialize = (state, options = {}) => {
const { document } = state const { document } = state
const elements = document.nodes.map(this.serializeNode) const elements = document.nodes.map(this.serializeNode)
if (options.render === false) return elements
const html = ReactDOMServer.renderToStaticMarkup(<body>{elements}</body>) const html = ReactDOMServer.renderToStaticMarkup(<body>{elements}</body>)
const inner = html.slice(6, -7) const inner = html.slice(6, -7)
return inner return inner

View File

@@ -1,11 +1,14 @@
import assert from 'assert' import assert from 'assert'
import type from 'type-of'
import fs from 'fs' import fs from 'fs'
import readMetadata from 'read-metadata' import readMetadata from 'read-metadata'
import strip from '../helpers/strip-dynamic' import strip from '../helpers/strip-dynamic'
import { Html, Json, Plain, Raw } from '../..' import { Html, Json, Plain, Raw } from '../..'
import { equal, strictEqual } from '../helpers/assert-json' import { equal, strictEqual } from '../helpers/assert-json'
import { resolve } from 'path' import { resolve } from 'path'
import React from 'react'
import { Iterable } from 'immutable'
/** /**
* Tests. * Tests.
@@ -46,6 +49,14 @@ describe('serializers', () => {
strictEqual(serialized, expected.trim()) strictEqual(serialized, expected.trim())
}) })
} }
it('optionally returns an iterable list of React elements', () => {
const html = new Html(require('./fixtures/html/serialize/block-nested').default)
const input = require('./fixtures/html/serialize/block-nested/input.js').default
const serialized = html.serialize(input, { render: false })
assert(Iterable.isIterable(serialized), 'did not return an interable list')
assert(React.isValidElement(serialized.first()), 'did not return valid React elements')
})
}) })
}) })