jsx-parser
jsx-parser copied to clipboard
genCode
function avalon() {
}
//单例HTML标签,多例自定义标签
var aslice = Array.prototype.slice
avalon.createElement = function (type, props, children) {
var obj = {
type: type,
props: props,
children: aslice.call(arguments, 2)
}
if (obj.children[2] == null) {
if (props && Array.isArray(props.children)) {
obj.children = props.children
}
}
return obj
}
function genCode(array) {
this.nodes = this.genChildren(array)
}
var pp = genCode.prototype
pp.genFn = function () {
console.log(this.nodes)
return new Function('return ' + this.nodes)
}
//如果一个元素没有JSX,那么它
pp.genTag = function (el) {
var children = this.genChildren(el.children, el)
return 'avalon.createElement(' + JSON.stringify(el.type) +
',' + this.genProps(el.props, el) +
',' + children + ')'
}
pp.genChildren = function (children, obj, join) {
if (obj) {
if (obj.isVoidTag||!obj.children.length){
obj.static = true
return 'null'
}
}
obj.static = true
var static = true
var ret = []
for (var i = 0, el; el = children[i++]; ) {
if (el.type === '#js') {
static = false
if (Array.isArray(el.nodeValue)) {
ret[ret.length] = this.genChildren(el.nodeValue, null, ' ')
} else {
ret[ret.length] = el.nodeValue
}
} else if (el.type === '#text') {
ret[ret.length] = JSON.stringify(el.nodeValue)
} else if (el) {
ret[ret.length] = this.genTag(el)
if(!el.static){
static = false
}
}
}
if(static === false)
delete obj.static
return ret.join(join || ',')
}
var staticID = 0
function getStaticID(){
return '$'+(++staticID)
}
pp.genProps = function (props, el) {
if (!props) {
if(el.static)
el.static = true
return '{$staticID:"'+ getStaticID() +'"}'
}
var peg = {index: 0}
var ret = '{'
for (var i in props) {
ret += JSON.stringify(i) + ':' + this.genPropValue(props[i], peg) + ',\n'
}
if(!peg.index && el.static){
el.static = true
ret += '$staticID' + ':' + getStaticID() + ',\n'
} else{
delete el.static
}
return ret.replace(/\,\n$/, '') + '}'
}
pp.genPropValue = function (val, peg) {
if (typeof val === 'string') {
return JSON.stringify(val)
}
if (val) {
++peg.index
if (Array.isArray(val.nodeValue)) {
return this.genChildren(val.nodeValue)
}
if (val) {
return val.nodeValue
}
}
}
//return <div ><span></span></div>
// React.createElement('div', {$staicID: "$3434"})
//单例HTML标签,多例自定义标签
function genCode(str, config) {
config = config || {}
config.ns = config.ns || 'anu'
config.type = config.type || 'eval'
this.ns = config.ns
this.type = config.type
if (typeof JSXParser === 'function') {
var array = (new JSXParser(str)).parse()
var evalCode = this.genChildren(array)
return evalCode
}
}
var pp = genCode.prototype
var rComponent = /^(this|[A-Z])/
//如果一个元素没有JSX,那么它
pp.genTag = function(el) {
var children = this.genChildren(el.children, el)
var ns = this.ns
var type = rComponent.test(el.type) ? el.type : JSON.stringify(el.type)
return ns + '.createElement(' + type +
',' + this.genProps(el.props, el) +
',' + children + ')'
}
pp.genChildren = function(children, obj, join) {
if (obj) {
if (obj.isVoidTag || !obj.children.length) {
return 'null'
}
}
var ret = []
for (var i = 0, el; el = children[i++];) {
if (el.type === '#jsx') {
static = false
if (Array.isArray(el.nodeValue)) {
ret[ret.length] = this.genChildren(el.nodeValue, null, ' ')
} else {
ret[ret.length] = el.nodeValue
}
} else if (el.type === '#text') {
ret[ret.length] = JSON.stringify(el.nodeValue)
} else if (el) {
ret[ret.length] = this.genTag(el)
}
}
return ret.join(join || ',')
}
pp.genProps = function(props, el) {
if (!props) {
return 'null'
}
var ret = '{'
for (var i in props) {
ret += JSON.stringify(i) + ':' + this.genPropValue(props[i]) + ',\n'
}
return ret.replace(/\,\n$/, '') + '}'
}
pp.genPropValue = function(val) {
if (typeof val === 'string') {
return JSON.stringify(val)
}
if (val) {
if (Array.isArray(val.nodeValue)) {
return this.genChildren(val.nodeValue)
}
if (val) {
return val.nodeValue
}
}
}
function parseCode(string) { // <div id={ function(){<div/>} }>
var word = '', //用于匹配前面的单词
braceIndex = 1,
codeIndex = 0,
nodes = [],
quote
for (var i = 0, n = string.length; i < n; i++) {
var c = string[i]
if (quote) {
if (c === quote) {
quote = ''
}
} else {
if (c === '"' || c === "'") {
word = ''
quote = c
} else if (c === '{') {
word = ''
braceIndex++
} else if (c === '}') {
word = ''
braceIndex--
if (braceIndex === 0) {
var nodeValue = string.slice(codeIndex, i)
if (/\S/.test(nodeValue)) { //将{前面的东西放进去
nodes.push({
type: '#jsx',
nodeValue: nodeValue
})
}
return [string.slice(0, i), nodes]
}
} else if (c === '[' || c === ']' || c === '(' || c === ')' || c === ',') {
word = ''
} else if (c === '<') {
var chunkString = string.slice(i)
if ((word === '' || word === 'return' || word.slice(-2) == '=>') && /\<\w/.test(chunkString)) {
var nodeValue = string.slice(codeIndex, i)
if (/\S/.test(nodeValue)) { //将{前面的东西放进去
nodes.push({
type: '#jsx',
nodeValue: nodeValue
})
}
var chunk = lexer(chunkString, true)
nodes.push(chunk[1])
i += (chunk[0].length - 1) //因为已经包含了<, 需要减1
codeIndex = i + 1
}
word = ''
} else if (c !== ' ') { //非空字符
word += c
} //空字符
}
}
}