Skip to content

Instantly share code, notes, and snippets.

@wmertens
Created July 6, 2018 05:17
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmertens/0b4fd66ca7055fd290ecc4b9d95271a9 to your computer and use it in GitHub Desktop.
Save wmertens/0b4fd66ca7055fd290ecc4b9d95271a9 to your computer and use it in GitHub Desktop.
Convert Slate JSON object to React element tree
@@ -0,0 +1,62 @@
import React from 'react'
import RULES from './somewhere' // What you normally feed slate-html-serializer
const rules = [
...RULES,
// from slate-html-serializer
{
serialize(obj, children) {
if (obj.object === 'string') {
return children.split('\n').reduce((array, text, i) => {
if (i != 0) array.push(<br key={i} />)
array.push(text)
return array
}, [])
}
},
},
]
let serializeNode, serializeLeaf, serializeString, cruftNewline, addKey
const toReact = (value, options = {}) => {
const {document} = value
const elements = document.nodes.map(serializeNode).filter(Boolean)
return elements
}
serializeNode = node => {
if (node.object === 'text') {
const {leaves} = node
return leaves.map(serializeLeaf)
}
const children = node.nodes.map(serializeNode)
for (const rule of rules) {
if (!rule.serialize) continue
const ret = rule.serialize(node, children)
if (ret === null) return
if (ret) return addKey(ret)
}
throw new Error(`No serializer defined for node of type "${node.type}".`)
}
serializeLeaf = leaf => {
const string = {object: 'string', text: leaf.text}
const text = serializeString(string)
return leaf.marks.reduce((children, mark) => {
for (const rule of rules) {
if (!rule.serialize) continue
const ret = rule.serialize(mark, children)
if (ret === null) return
if (ret) return addKey(ret)
}
throw new Error(`No serializer defined for mark of type "${mark.type}".`)
}, text)
}
serializeString = string => {
for (const rule of rules) {
if (!rule.serialize) continue
const ret = rule.serialize(string, string.text)
if (ret) return ret
}
}
cruftNewline = element =>
!(element.nodeName === '#text' && element.nodeValue == '\n')
let key = 0
addKey = element => React.cloneElement(element, {key: key++})
export default toReact
@dmitrizzle
Copy link

Can't seem to make it work, keep getting Error: No serializer defined for node of type "paragraph". I'm using https://github.com/roast-cms/french-press-editor/blob/develop/src/rules.js as rules. Am I doing something wrong?

@wmertens
Copy link
Author

Note that github doesn't send notifications for comments on gists, so if you want to ask me things, please mail at Wout.Mertens@gmail.com.

The problem dmitrizzle had was that he did not include a serialization rule for paragraph.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment