-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathindex.js
69 lines (58 loc) · 1.79 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React from 'react'
import JsonML from 'jsonml.js/lib/utils'
import { toStyleObject } from './utils'
/**
* JsonmlToReact class
*/
export default class JsonmlToReact {
/**
* Constructor
* @param {Object} converters - Aditional converters
*/
constructor (converters = {}) {
this.converters = converters
}
/**
* Visit JsonML nodes recursively and convert to React
* @param {Array} node - JsonML structure
* @param {Number} index - Node index to be used as key
* @param {Object} [data] - Data to be passed to the converters
* @returns {Object} React component
* @private
*/
_visit (node, index, data) {
// Is leaf node
if (!node || typeof node === 'string') {
return node
}
let attrs = Object.assign({ key: index }, JsonML.getAttributes(node))
if (attrs.class) {
attrs.className = attrs.class
attrs.class = undefined
}
if (attrs.style) {
attrs.style = toStyleObject(attrs.style)
}
const tag = JsonML.getTagName(node)
const converter = this.converters[tag]
const result = converter ? converter(attrs, data) : {}
const type = result.type || tag
const props = result.props || attrs
// reassign key in case `converter` removed it
props.key = props.key || index
const children = JsonML.getChildren(node)
if (!children || children.length === 0) {
return React.createElement(type, props)
}
return React.createElement(type, props, children.map((child, index) => this._visit(child, index, data)))
}
/**
* Convert JsonML to React component
* @param {Array} jsonml - JsonML structure
* @param {Object} [data] - Data to be passed to the converters
* @returns {Object} React component
*/
convert (jsonml, data) {
return this._visit(jsonml, 0, data)
}
}