diff --git a/docs/reference/serializers/html.md b/docs/reference/serializers/html.md
index 62f77167d..75bdf0748 100644
--- a/docs/reference/serializers/html.md
+++ b/docs/reference/serializers/html.md
@@ -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
diff --git a/docs/reference/serializers/plain.md b/docs/reference/serializers/plain.md
index 9cdbb6b33..409a4b250 100644
--- a/docs/reference/serializers/plain.md
+++ b/docs/reference/serializers/plain.md
@@ -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`
diff --git a/src/serializers/html.js b/src/serializers/html.js
index 3e8c1405d..8ecd648b3 100644
--- a/src/serializers/html.js
+++ b/src/serializers/html.js
@@ -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
}
diff --git a/src/serializers/plain.js b/src/serializers/plain.js
index 93020f2b0..81491b63a 100644
--- a/src/serializers/plain.js
+++ b/src/serializers/plain.js
@@ -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)
}
/**
diff --git a/src/serializers/raw.js b/src/serializers/raw.js
index dc000c361..b4327e32b 100644
--- a/src/serializers/raw.js
+++ b/src/serializers/raw.js
@@ -671,7 +671,7 @@ const Raw = {
*/
untersifyState(object) {
- if (object.selection != null) {
+ if (object.selection || object.document) {
return {
kind: 'state',
document: object.document,
diff --git a/test/serializers/index.js b/test/serializers/index.js
index 8a71af4e5..bc9e59599 100644
--- a/test/serializers/index.js
+++ b/test/serializers/index.js
@@ -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()', () => {