1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-26 00:27:28 +02:00

added toRaw option to Html and Plain serializers, fixes #583 #584

This commit is contained in:
Ian Storm Taylor
2017-02-06 17:28:46 -08:00
parent 44cef94b04
commit a7f6584179
6 changed files with 106 additions and 44 deletions

View File

@@ -46,14 +46,18 @@ An array of rules to initialize the `Html` serializer with, defining your schema
## Methods
### `Html.deserialize`
`Html.deserialize(html: String) => State`
`Html.deserialize(html: String, [options: Object]) => State`
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.
If you pass `toRaw: true` as an option, the return value will be a [`Raw`](./raw.md) JSON object instead of a [`State`](../models/state.md) object.
### `Html.serialize`
`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. 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.
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

View File

@@ -25,10 +25,12 @@ Check out http://slatejs.org for examples!
## Methods
### `Plain.deserialize`
`Plain.deserialize(string: String) => State`
`Plain.deserialize(string: String, [options: Object]) => State`
Deserialize a plain text `string` into a [`State`](../models/state.md). A series of blocks will be created by splitting the input string on `\n` characters. Each block is given a type of `'line'`.
If you pass `toRaw: true` as an option, the return value will be a [`Raw`](./raw.md) JSON object instead of a [`State`](../models/state.md) object.
### `Plain.serialize`
`Plain.serialize(state: State) => String`

View File

@@ -85,10 +85,12 @@ class Html {
* Deserialize pasted HTML.
*
* @param {String} html
* @param {Object} options
* @property {Boolean} toRaw
* @return {State}
*/
deserialize = (html) => {
deserialize = (html, options = {}) => {
const $ = cheerio.load(html).root()
const children = $.children().toArray()
let nodes = this.deserializeElements(children)
@@ -116,7 +118,19 @@ class Html {
return memo
}, [])
const state = Raw.deserialize({ nodes }, { terse: true })
const raw = {
kind: 'state',
document: {
kind: 'document',
nodes,
}
}
if (options.toRaw) {
return raw
}
const state = Raw.deserialize(raw, { terse: true })
return state
}

View File

@@ -1,51 +1,41 @@
import Block from '../models/block'
import Document from '../models/document'
import State from '../models/state'
import Text from '../models/text'
import Raw from '../serializers/raw'
/**
* Deserialize a plain text `string` to a state.
*
* @param {String} string
* @param {Object} options
* @property {Boolean} toRaw
* @return {State}
*/
function deserialize(string) {
return State.create({
document: Document.create({
nodes: string.split('\n').map(deserializeLine)
})
})
}
function deserialize(string, options = {}) {
const raw = {
kind: 'state',
document: {
kind: 'document',
nodes: string.split('\n').map((line) => {
return {
kind: 'block',
type: 'line',
nodes: [
{
kind: 'text',
ranges: [
{
text: line,
marks: [],
}
]
}
]
}
}),
}
}
/**
* Deserialize a `line` of text.
*
* @param {String} line
* @return {Block}
*/
function deserializeLine(line) {
return Block.create({
type: 'line',
nodes: [
Text.create({
characters: line.split('').map(deserializeCharacter)
})
]
})
}
/**
* Deserialize a `character`.
*
* @param {String} char
* @return {Character}
*/
function deserializeCharacter(char) {
return { text: char }
return options.toRaw ? raw : Raw.deserialize(raw)
}
/**

View File

@@ -671,7 +671,7 @@ const Raw = {
*/
untersifyState(object) {
if (object.selection != null) {
if (object.selection || object.document) {
return {
kind: 'state',
document: object.document,

View File

@@ -30,6 +30,30 @@ describe('serializers', () => {
assert.deepEqual(strip(json), expected)
})
}
it('optionally returns a raw representation', () => {
const html = new Html(require('./fixtures/html/deserialize/block').default)
const input = fs.readFileSync(resolve(__dirname, './fixtures/html/deserialize/block/input.html'), 'utf8')
const serialized = html.deserialize(input, { toRaw: true })
assert.deepEqual(serialized, {
kind: 'state',
document: {
kind: 'document',
nodes: [
{
kind: 'block',
type: 'paragraph',
nodes: [
{
kind: 'text',
text: 'one'
}
]
}
]
}
})
})
})
describe('serialize()', () => {
@@ -74,6 +98,34 @@ describe('serializers', () => {
assert.deepEqual(strip(json), expected)
})
}
it('optionally returns a raw representation', () => {
const input = fs.readFileSync(resolve(__dirname, './fixtures/plain/deserialize/line/input.txt'), 'utf8')
const serialized = Plain.deserialize(input.replace(/\n$/m, ''), { toRaw: true })
assert.deepEqual(serialized, {
kind: 'state',
document: {
kind: 'document',
nodes: [
{
kind: 'block',
type: 'line',
nodes: [
{
kind: 'text',
ranges: [
{
marks: [],
text: 'one',
}
]
}
]
}
]
}
})
})
})
describe('serialize()', () => {