1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-29 09:59:48 +02:00

refactor raw serializer to not be terse by default

This commit is contained in:
Ian Storm Taylor
2016-07-25 13:29:29 -07:00
parent 81c956228b
commit 98c78e4d96
602 changed files with 2266 additions and 1986 deletions

View File

@@ -5,6 +5,13 @@ This document maintains a list of changes to Slate with each new version. Until
---
### `0.7.0` — _July 24, 2016_
#### BREAKING CHANGES
- **The `Raw` serializer is no longer terse by default!** Previously, the `Raw` serializer would return a "terse" representation of the document, omitting information that wasn't _strictly_ necessary to deserialize later, like the `key` of nodes. By default this no longer happens. You have to opt-in to the behavior by passing `{ terse: true }` as the second `options` argument of the `deserialize` and `serialize` methods.
### `0.6.0` — _July 22, 2016_
#### BREAKING CHANGES

View File

@@ -7,10 +7,10 @@ import { Raw } from 'slate'
The raw JSON serialized that ships by default with Slate. It converts a [`State`](../models/state.md) into a JSON object.
The raw JSON object created will omit default-value properties to reduce the serialized data's size. For example, if the dictionary of [`Data`](../models/data.md) for a [`Node`](../models/node.md) is empty, it will be omitted.
In the raw format, text is represented as "ranges", which are a more compact way to represent the formatting applied to characters than the immutable model Slate uses internally.
When saving the data to size-sensitive places, you the raw serializer can be told to omit properties that aren't _strictly_ required to deserialize later, reducing the serialized data's size. For example, if the dictionary of [`Data`](../models/data.md) for a [`Node`](../models/node.md) is empty, it will be omitted.
- [Example](#example)
- [Static Methods](#methods)
- [`Raw.deserialize`](#rawdeserialize)
@@ -123,11 +123,11 @@ In the raw format, text is represented as "ranges", which are a more compact way
## Methods
### `Raw.deserialize`
`Raw.deserialize(object: Object) => State`
`Raw.deserialize(object: Object, [options: Object]) => State`
Deserialize a raw JSON `object` into a [`State`](../models/state.md).
Deserialize a raw JSON `object` into a [`State`](../models/state.md). You must pass the `terse: true` option if you want to deserialize a state that was previously serialized with `terse: true`.
### `Raw.serialize`
`Raw.serialize(state: State) => Object`
`Raw.serialize(state: State, [options: Object]) => Object`
Serialize a `state` into a raw JSON object.
Serialize a `state` into a raw JSON object. If you pass the `terse: true` option, the serialized format will omit properties that aren't _strictly_ required to deserialize later, reducing the serialized data's size. For example, if the dictionary of [`Data`](../models/data.md) for a [`Node`](../models/node.md) is empty, it will be omitted.

View File

@@ -27,6 +27,7 @@ import Text from './models/text'
*/
import Html from './serializers/html'
import Json from './serializers/json'
import Plain from './serializers/plain'
import Raw from './serializers/raw'
@@ -55,6 +56,7 @@ export {
Editor,
Html,
Inline,
Json,
Mark,
Placeholder,
Plain,
@@ -75,6 +77,7 @@ export default {
Editor,
Html,
Inline,
Json,
Mark,
Placeholder,
Plain,

View File

@@ -33,14 +33,14 @@ const TEXT_RULE = {
if (el.tagName == 'br') {
return {
kind: 'text',
ranges: [{ text: '\n' }]
text: '\n'
}
}
if (el.type == 'text') {
return {
kind: 'text',
ranges: [{ text: el.data }]
text: el.data
}
}
},
@@ -117,7 +117,7 @@ class Html {
return memo
}, [])
const state = Raw.deserialize({ nodes })
const state = Raw.deserialize({ nodes }, { terse: true })
return state
}
@@ -188,6 +188,7 @@ class Html {
}
else if (node.kind == 'text') {
if (!node.ranges) node.ranges = [{ text: node.text }]
node.ranges = node.ranges.map((range) => {
range.marks = range.marks || []
range.marks.push({ type, data })

View File

@@ -6,191 +6,577 @@ import Inline from '../models/inline'
import Mark from '../models/mark'
import State from '../models/state'
import Text from '../models/text'
import isEmpty from 'is-empty'
/**
* Serialize a `state`.
* Raw.
*
* @param {State} state
* @return {Object} object
* @type {Object}
*/
function serialize(state) {
return serializeNode(state.document)
}
const Raw = {
/**
* Serialize a `node`.
*
* @param {Node} node
* @return {Object} object
*/
/**
* Deserialize a JSON `object`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Block}
*/
function serializeNode(node) {
switch (node.kind) {
case 'document': {
return {
nodes: node.nodes.toArray().map(child => serializeNode(child))
deserialize(object, options) {
return Raw.deserializeState(object, options)
},
/**
* Deserialize a JSON `object` representing a `Block`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Block}
*/
deserializeBlock(object, options = {}) {
if (options.terse) object = Raw.untersifyBlock(object)
return Block.create({
key: object.key,
type: object.type,
data: object.data,
isVoid: object.isVoid,
nodes: Block.createList(object.nodes.map((node) => {
return Raw.deserializeNode(node, options)
}))
})
},
/**
* Deserialize a JSON `object` representing a `Document`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Document}
*/
deserializeDocument(object, options) {
return Document.create({
nodes: Block.createList(object.nodes.map((node) => {
return Raw.deserializeNode(node, options)
}))
})
},
/**
* Deserialize a JSON `object` representing an `Inline`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Inline}
*/
deserializeInline(object, options = {}) {
if (options.terse) object = Raw.untersifyInline(object)
return Inline.create({
key: object.key,
type: object.type,
data: object.data,
isVoid: object.isVoid,
nodes: Inline.createList(object.nodes.map((node) => {
return Raw.deserializeNode(node, options)
}))
})
},
/**
* Deserialize a JSON `object` representing a `Mark`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Mark} mark
*/
deserializeMark(object, options) {
return Mark.create(object)
},
/**
* Deserialize a JSON object representing a `Node`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Text}
*/
deserializeNode(object, options) {
switch (object.kind) {
case 'block': return Raw.deserializeBlock(object, options)
case 'document': return Raw.deserializeDocument(object, options)
case 'inline': return Raw.deserializeInline(object, options)
case 'text': return Raw.deserializeText(object, options)
default: {
throw new Error(`Unrecognized node kind "${object.kind}".`)
}
}
case 'text': {
const obj = {}
obj.key = node.key
obj.kind = node.kind
obj.ranges = serializeRanges(node)
return obj
}
case 'block':
case 'inline': {
const obj = {}
obj.key = node.key
obj.kind = node.kind
obj.type = node.type
obj.nodes = node.nodes.toArray().map(child => serializeNode(child))
if (node.isVoid) obj.isVoid = node.isVoid
if (node.data.size) obj.data = node.data.toJSON()
return obj
}
default: {
throw new Error(`Unknown node kind "${node.kind}".`)
}
}
}
},
/**
* Serialize the ranges of a text `node`.
*
* @param {Text} text
* @return {Array}
*/
/**
* Deserialize a JSON `object` representing a `Range`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {List}
*/
function serializeRanges(text) {
return text
.getRanges()
.toArray()
.map((range) => {
const obj = {}
obj.text = range.text
if (range.marks.size) obj.marks = range.marks.toArray().map(serializeMark)
return obj
})
}
deserializeRange(object, options = {}) {
if (options.terse) object = Raw.untersifyRange(object)
/**
* Serialize a `mark`.
*
* @param {Mark} mark
* @return {Object} Object
*/
function serializeMark(mark) {
const obj = {}
obj.type = mark.type
if (mark.data.size) obj.data = mark.data.toJSON()
return obj
}
/**
* Deserialize a state JSON `object`.
*
* @param {Object} object
* @return {State} state
*/
function deserialize(object) {
return State.create({
document: Document.create({
nodes: Block.createList(object.nodes.map(deserializeNode))
})
})
}
/**
* Deserialize a node JSON `object`.
*
* @param {Object} object
* @return {Node} node
*/
function deserializeNode(object) {
switch (object.kind) {
case 'block': {
return Block.create({
key: object.key,
type: object.type,
data: object.data,
isVoid: object.isVoid,
nodes: Block.createList((object.nodes || []).map(deserializeNode))
})
}
case 'inline': {
return Inline.create({
key: object.key,
type: object.type,
data: object.data,
isVoid: object.isVoid,
nodes: Inline.createList((object.nodes || []).map(deserializeNode))
})
}
case 'text': {
if (object.ranges == null && object.text != null) {
object.ranges = [{ text: object.text }]
}
return Text.create({
key: object.key,
characters: object.ranges ? deserializeRanges(object.ranges) : ''
})
}
default: {
throw new Error(`Unknown node kind "${object.kind}".`)
}
}
}
/**
* Deserialize a JSON `array` of ranges.
*
* @param {Array} array
* @return {List} characters
*/
function deserializeRanges(array = []) {
return array.reduce((characters, object) => {
const marks = object.marks || []
const chars = object.text
return Character.createList(object.text
.split('')
.map((char) => {
return Character.create({
text: char,
marks: Mark.createSet(marks.map(deserializeMark))
marks: Mark.createSet(object.marks.map((mark) => {
return Raw.deserializeMark(mark, options)
}))
})
})
}))
},
return characters.push(...chars)
}, Character.createList())
}
/**
* Deserialize a JSON `object` representing a `State`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {State}
*/
/**
* Deserialize a mark JSON `object`.
*
* @param {Object} object
* @return {Mark} mark
*/
deserializeState(object, options = {}) {
if (options.terse) object = Raw.untersifyState(object)
function deserializeMark(object) {
return Mark.create(object)
return State.create({
document: Raw.deserializeDocument(object.document, options)
})
},
/**
* Deserialize a JSON `object` representing a `Text`.
*
* @param {Object} object
* @param {Object} options (optional)
* @return {Text}
*/
deserializeText(object, options = {}) {
if (options.terse) object = Raw.untersifyText(object)
return Text.create({
key: object.key,
characters: object.ranges.reduce((characters, range) => {
return characters.concat(Raw.deserializeRange(range, options))
}, Character.createList())
})
},
/**
* Serialize a `model`.
*
* @param {Mixed} model
* @param {Object} options (optional)
* @return {Object}
*/
serialize(model, options) {
return Raw.serializeState(model, options)
},
/**
* Serialize a `block` node.
*
* @param {Block} block
* @param {Object} options (optional)
* @return {Object}
*/
serializeBlock(block, options = {}) {
const object = {
data: block.data.toJSON(),
key: block.key,
kind: block.kind,
isVoid: block.isVoid,
type: block.type,
nodes: block.nodes
.toArray()
.map(node => Raw.serializeNode(node, options))
}
return options.terse
? Raw.tersifyBlock(object)
: object
},
/**
* Serialize a `document`.
*
* @param {Document} document
* @param {Object} options (optional)
* @return {Object}
*/
serializeDocument(document, options = {}) {
const object = {
kind: document.kind,
nodes: document.nodes
.toArray()
.map(node => Raw.serializeNode(node, options))
}
return options.terse
? Raw.tersifyDocument(object)
: object
},
/**
* Serialize an `inline` node.
*
* @param {Inline} inline
* @param {Object} options (optional)
* @return {Object}
*/
serializeInline(inline, options = {}) {
const object = {
data: inline.data.toJSON(),
key: inline.key,
kind: inline.kind,
isVoid: inline.isVoid,
type: inline.type,
nodes: inline.nodes
.toArray()
.map(node => Raw.serializeNode(node, options))
}
return options.terse
? Raw.tersifyInline(object)
: object
},
/**
* Serialize a `mark`.
*
* @param {Mark} mark
* @param {Object} options (optional)
* @return {Object} Object
*/
serializeMark(mark, options = {}) {
const object = {
data: mark.data.toJSON(),
kind: mark.kind,
type: mark.type
}
return options.terse
? Raw.tersifyMark(object)
: object
},
/**
* Serialize a `node`.
*
* @param {Node} node
* @param {Object} options (optional)
* @return {Object} object
*/
serializeNode(node, options) {
switch (node.kind) {
case 'block': return Raw.serializeBlock(node, options)
case 'document': return Raw.serializeDocument(node, options)
case 'inline': return Raw.serializeInline(node, options)
case 'text': return Raw.serializeText(node, options)
default: {
throw new Error(`Unrecognized node kind "${node.kind}".`)
}
}
},
/**
* Serialize a `range`.
*
* @param {Range} range
* @param {Object} options (optional)
* @return {Object}
*/
serializeRange(range, options = {}) {
const object = {
kind: range.kind,
text: range.text,
marks: range.marks
.toArray()
.map(mark => Raw.serializeMark(mark, options))
}
return options.terse
? Raw.tersifyRange(object)
: object
},
/**
* Serialize a `state`.
*
* @param {State} state
* @param {Object} options (optional)
* @return {Object}
*/
serializeState(state, options = {}) {
const object = {
document: Raw.serializeDocument(state.document, options),
kind: state.kind
}
return options.terse
? Raw.tersifyState(object)
: object
},
/**
* Serialize a `text` node.
*
* @param {Text} text
* @param {Object} options (optional)
* @return {Object}
*/
serializeText(text, options = {}) {
const object = {
key: text.key,
kind: text.kind,
ranges: text
.getRanges()
.toArray()
.map(range => Raw.serializeRange(range, options))
}
return options.terse
? Raw.tersifyText(object)
: object
},
/**
* Create a terse representation of a block `object`.
*
* @param {Object} object
* @return {Object}
*/
tersifyBlock(object) {
const ret = {}
ret.kind = object.kind
ret.type = object.type
if (!object.isVoid) ret.nodes = object.nodes
if (object.isVoid) ret.isVoid = object.isVoid
if (!isEmpty(object.data)) ret.data = object.data
return ret
},
/**
* Create a terse representation of a document `object.
*
* @param {Object} object
* @return {Object}
*/
tersifyDocument(object) {
return {
nodes: object.nodes
}
},
/**
* Create a terse representation of a inline `object`.
*
* @param {Object} object
* @return {Object}
*/
tersifyInline(object) {
const ret = {}
ret.kind = object.kind
ret.type = object.type
if (!object.isVoid) ret.nodes = object.nodes
if (object.isVoid) ret.isVoid = object.isVoid
if (!isEmpty(object.data)) ret.data = object.data
return ret
},
/**
* Create a terse representation of a mark `object`.
*
* @param {Object} object
* @return {Object}
*/
tersifyMark(object) {
const ret = {}
ret.type = object.type
if (!isEmpty(object.data)) ret.data = object.data
return ret
},
/**
* Create a terse representation of a range `object`.
*
* @param {Object} object
* @return {Object}
*/
tersifyRange(object) {
const ret = {}
ret.text = object.text
if (!isEmpty(object.marks)) ret.marks = object.marks
return ret
},
/**
* Create a terse representation of a state `object`.
*
* @param {Object} object
* @return {Object}
*/
tersifyState(object) {
return object.document
},
/**
* Create a terse representation of a text `object`.
*
* @param {Object} object
* @return {Object}
*/
tersifyText(object) {
if (object.ranges.length == 1 && object.ranges[0].marks == null) {
return {
kind: object.kind,
text: object.ranges[0].text
}
}
return {
kind: object.kind,
ranges: object.ranges
}
},
/**
* Convert a terse representation of a block `object` into a non-terse one.
*
* @param {Object} object
* @return {Object}
*/
untersifyBlock(object) {
if (object.isVoid) {
return {
data: object.data,
kind: object.kind,
type: object.type,
isVoid: object.isVoid,
nodes: [
{
kind: 'text',
text: ''
}
]
}
}
return object
},
/**
* Convert a terse representation of a inline `object` into a non-terse one.
*
* @param {Object} object
* @return {Object}
*/
untersifyInline(object) {
if (object.isVoid) {
return {
data: object.data,
kind: object.kind,
type: object.type,
isVoid: object.isVoid,
nodes: [
{
kind: 'text',
text: ''
}
]
}
}
return object
},
/**
* Convert a terse representation of a range `object` into a non-terse one.
*
* @param {Object} object
* @return {Object}
*/
untersifyRange(object) {
return {
kind: 'range',
text: object.text,
marks: object.marks || []
}
},
/**
* Convert a terse representation of a state `object` into a non-terse one.
*
* @param {Object} object
* @return {Object}
*/
untersifyState(object) {
return {
kind: 'state',
document: {
kind: 'document',
nodes: object.nodes
}
}
},
/**
* Convert a terse representation of a text `object` into a non-terse one.
*
* @param {Object} object
* @return {Object}
*/
untersifyText(object) {
if (object.ranges) return object
return {
kind: object.kind,
ranges: [{
text: object.text
}]
}
}
}
/**
* Export.
*/
export default {
serialize,
serializeRanges,
serializeMark,
serializeNode,
deserialize,
deserializeNode,
deserializeRanges
}
export default Raw

View File

@@ -11,6 +11,7 @@
"es6-symbol": "^3.1.0",
"esrever": "^0.2.0",
"immutable": "^3.8.1",
"is-empty": "^1.0.0",
"keycode": "^2.1.2",
"lodash": "^4.13.1",
"react-portal": "^2.2.0",

View File

@@ -5,7 +5,3 @@ nodes:
isVoid: true
data:
src: https://img.washingtonpost.com/wp-apps/imrs.php?src=https://img.washingtonpost.com/news/speaking-of-science/wp-content/uploads/sites/36/2015/10/as12-49-7278-1024x1024.jpg&w=1484
nodes:
- kind: text
ranges:
- text: another

View File

@@ -21,7 +21,7 @@ describe('rendering', () => {
const input = readMetadata.sync(resolve(dir, 'input.yaml'))
const output = fs.readFileSync(resolve(dir, 'output.html'), 'utf8')
const props = {
state: Raw.deserialize(input),
state: Raw.deserialize(input, { terse: true }),
onChange: () => {},
...require(dir)
}

View File

@@ -0,0 +1,11 @@
nodes:
- kind: block
type: quote
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,17 @@
nodes:
- type: quote
isVoid: false
data: {}
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- characters:
- text: o
marks: []
- text: n
marks: []
- text: e
marks: []

View File

@@ -0,0 +1,10 @@
nodes:
- kind: block
type: paragraph
data:
key: value
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,14 @@
nodes:
- type: paragraph
isVoid: false
data:
key: value
nodes:
- characters:
- text: o
marks: []
- text: n
marks: []
- text: e
marks: []

View File

@@ -0,0 +1,9 @@
nodes:
- kind: block
type: paragraph
isVoid: true
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,7 @@
nodes:
- type: paragraph
isVoid: true
data: {}
nodes:
- characters: []

View File

@@ -0,0 +1,8 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,14 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: inline
type: hashtag
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,21 @@
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- type: link
isVoid: false
data: {}
nodes:
- type: hashtag
isVoid: false
data: {}
nodes:
- characters:
- text: o
marks: []
- text: n
marks: []
- text: e
marks: []

View File

@@ -0,0 +1,13 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
data:
key: value
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,18 @@
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- type: link
isVoid: false
data:
key: value
nodes:
- characters:
- text: o
marks: []
- text: n
marks: []
- text: e
marks: []

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
isVoid: true
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,11 @@
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- type: link
isVoid: true
data: {}
nodes:
- characters: []

View File

@@ -0,0 +1,11 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
ranges:
- text: one

View File

@@ -0,0 +1,17 @@
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- type: link
isVoid: false
data: {}
nodes:
- characters:
- text: o
marks: []
- text: n
marks: []
- text: e
marks: []

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: o
- text: n
marks:
- type: bold
- text: e

View File

@@ -0,0 +1,15 @@
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- characters:
- text: o
marks: []
- text: n
marks:
- type: bold
data: {}
- text: e
marks: []

View File

@@ -0,0 +1,13 @@
nodes:
- type: paragraph
isVoid: false
data: {}
nodes:
- characters:
- text: o
marks: []
- text: n
marks: []
- text: e
marks: []

View File

@@ -1,11 +1,16 @@
nodes:
- kind: block
type: quote
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: quote
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,10 +1,15 @@
nodes:
- kind: block
type: paragraph
data:
key: value
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data:
key: value
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,9 +1,14 @@
nodes:
- kind: block
type: paragraph
isVoid: true
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
isVoid: true
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,8 +1,13 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,14 +1,19 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: inline
type: hashtag
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: inline
type: hashtag
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,13 +1,18 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
data:
key: value
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
data:
key: value
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,12 +1,17 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
isVoid: true
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
isVoid: true
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,11 +1,16 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,12 +1,21 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: o
- text: n
marks:
- type: bold
- text: e
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- kind: range
text: o
marks: []
- kind: range
text: n
marks:
- kind: mark
type: bold
- kind: range
text: e
marks: []

View File

@@ -0,0 +1,26 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'quote',
nodes: Block.createList([
{
type: 'paragraph',
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
}
])
})
})

View File

@@ -0,0 +1,10 @@
nodes:
- kind: block
type: quote
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one

View File

@@ -0,0 +1,22 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
data: { key: 'value' },
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
})
})

View File

@@ -0,0 +1,9 @@
nodes:
- kind: block
type: paragraph
data:
key: value
nodes:
- kind: text
text: one

View File

@@ -0,0 +1,22 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
isVoid: true,
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
})
})

View File

@@ -0,0 +1,5 @@
nodes:
- kind: block
type: paragraph
isVoid: true

View File

@@ -0,0 +1,21 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
})
})

View File

@@ -0,0 +1,7 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
text: one

View File

@@ -0,0 +1,26 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
nodes: Text.createList([
{
characters: Character.createList([
{
text: 'e',
marks: Mark.createSet([
{
type: 'bold'
}
])
}
])
}
])
}
])
})
})

View File

@@ -0,0 +1,10 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: e
marks:
- type: bold

View File

@@ -0,0 +1,31 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
nodes: Inline.createList([
{
type: 'link',
nodes: Inline.createList([
{
type: 'hashtag',
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
}
])
}
])
})
})

View File

@@ -0,0 +1,13 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: inline
type: hashtag
nodes:
- kind: text
text: one

View File

@@ -0,0 +1,27 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
nodes: Inline.createList([
{
type: 'link',
data: { key: 'value' },
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
}
])
})
})

View File

@@ -0,0 +1,12 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
data:
key: value
nodes:
- kind: text
text: one

View File

@@ -0,0 +1,27 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
nodes: Inline.createList([
{
type: 'link',
isVoid: true,
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
}
])
})
})

View File

@@ -0,0 +1,8 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
isVoid: true

View File

@@ -0,0 +1,26 @@
import { Block, Character, Document, Inline, Mark, State, Text } from '../../../../../..'
export default State.create({
document: Document.create({
nodes: Block.createList([
{
type: 'paragraph',
nodes: Inline.createList([
{
type: 'link',
nodes: Text.createList([
{
characters: Character.createList([
{ text: 'o' },
{ text: 'n' },
{ text: 'e' }
])
}
])
}
])
}
])
})
})

View File

@@ -0,0 +1,10 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
text: one

View File

@@ -1,11 +1,20 @@
nodes:
- kind: block
type: quote
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: quote
data: {}
isVoid: false
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,10 +1,16 @@
nodes:
- kind: block
type: paragraph
data:
key: value
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
isVoid: false
data:
key: value
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,9 +1,15 @@
nodes:
- kind: block
type: paragraph
isVoid: true
nodes:
- kind: text
ranges:
- text: ""
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: true
nodes:
- kind: text
ranges:
- kind: range
text: ""
marks: []

View File

@@ -1,8 +1,15 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,11 +1,21 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: "on"
- text: e
marks:
- type: bold
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: text
ranges:
- kind: range
text: "on"
marks: []
- kind: range
text: e
marks:
- kind: mark
type: bold
data: {}

View File

@@ -1,14 +1,25 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: inline
type: hashtag
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: inline
type: link
data: {}
isVoid: false
nodes:
- kind: inline
type: hashtag
data: {}
isVoid: false
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,13 +1,21 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
data:
key: value
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: inline
type: link
isVoid: false
data:
key: value
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -1,12 +1,20 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
isVoid: true
nodes:
- kind: text
ranges:
- text: ""
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: inline
type: link
isVoid: true
data: {}
nodes:
- kind: text
ranges:
- kind: range
text: ""
marks: []

View File

@@ -1,11 +1,20 @@
nodes:
- kind: block
type: paragraph
nodes:
- kind: inline
type: link
nodes:
- kind: text
ranges:
- text: one
kind: state
document:
kind: document
nodes:
- kind: block
type: paragraph
data: {}
isVoid: false
nodes:
- kind: inline
type: link
data: {}
isVoid: false
nodes:
- kind: text
ranges:
- kind: range
text: one
marks: []

View File

@@ -3,7 +3,7 @@ import assert from 'assert'
import fs from 'fs'
import readMetadata from 'read-metadata'
import strip from '../helpers/strip-dynamic'
import { Html, Plain, Raw } from '../..'
import { Html, Json, Plain, Raw } from '../..'
import { equal, strictEqual } from '../helpers/assert-json'
import { resolve } from 'path'
@@ -47,6 +47,9 @@ describe('serializers', () => {
})
})
describe('json', () => {
})
describe('plain', () => {
describe('deserialize()', () => {
const dir = resolve(__dirname, './fixtures/plain/deserialize')
@@ -107,6 +110,38 @@ describe('serializers', () => {
const input = require(resolve(innerDir, 'input.js')).default
const expected = readMetadata.sync(resolve(innerDir, 'output.yaml'))
const serialized = Raw.serialize(input)
serialized.document = strip(serialized.document)
strictEqual(serialized, expected)
})
}
})
describe('deserialize({ terse: true })', () => {
const dir = resolve(__dirname, './fixtures/raw/deserialize-terse')
const tests = fs.readdirSync(dir)
for (const test of tests) {
it(test, () => {
const innerDir = resolve(dir, test)
const expected = readMetadata.sync(resolve(innerDir, 'output.yaml'))
const input = readMetadata.sync(resolve(innerDir, 'input.yaml'))
const state = Raw.deserialize(input, { terse: true })
const json = state.document.toJS()
strictEqual(strip(json), expected)
})
}
})
describe('serialize({ terse: true })', () => {
const dir = resolve(__dirname, './fixtures/raw/serialize-terse')
const tests = fs.readdirSync(dir)
for (const test of tests) {
it(test, () => {
const innerDir = resolve(dir, test)
const input = require(resolve(innerDir, 'input.js')).default
const expected = readMetadata.sync(resolve(innerDir, 'output.yaml'))
const serialized = Raw.serialize(input, { terse: true })
strictEqual(strip(serialized), expected)
})
}

View File

@@ -4,11 +4,9 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -7,8 +7,7 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
@@ -16,5 +15,4 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,11 +4,9 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -7,8 +7,7 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
@@ -16,5 +15,4 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -7,8 +7,7 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
@@ -16,5 +15,4 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -7,11 +7,9 @@ nodes:
type: link
nodes:
- kind: text
ranges:
- text: wo
text: wo
- kind: inline
type: link
nodes:
- kind: text
ranges:
- text: other
text: other

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: ord
text: ord

View File

@@ -4,11 +4,9 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: woother
text: woother

View File

@@ -4,11 +4,9 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: wordanother
text: wordanother

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: wor
text: wor

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: wrd
text: wrd

View File

@@ -4,8 +4,7 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word
- kind: block
type: paragraph
nodes:
@@ -13,11 +12,9 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: middle
text: middle
- kind: block
type: paragraph
nodes:
- kind: text
ranges:
- text: another
text: another

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: woother
text: woother

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: ""
text: ""

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: word
text: word

View File

@@ -4,5 +4,4 @@ nodes:
type: paragraph
nodes:
- kind: text
ranges:
- text: ord
text: ord

Some files were not shown because too many files have changed in this diff Show More