1
1
"use strict" ;
2
+ var objectAssign = require ( "object-assign" ) ;
2
3
var parser = require ( "handlebars-html-parser" ) ;
4
+ var React = require ( "react" ) ;
5
+ var uglify = require ( "uglify-js" ) ;
6
+
7
+ var defaultOptions =
8
+ {
9
+ beautify : true ,
10
+ prefix : "" ,
11
+ suffix : ""
12
+ } ;
13
+
14
+ var createElementFunction = 'React.createElement(' ;
3
15
4
16
5
17
@@ -40,7 +52,9 @@ var parser = require("handlebars-html-parser");
40
52
41
53
function compiler ( options )
42
54
{
43
- this . parser = new parser ( options ) ;
55
+ this . options = objectAssign ( { } , defaultOptions , options ) ;
56
+
57
+ this . parser = new parser ( this . options ) ;
44
58
}
45
59
46
60
@@ -50,7 +64,7 @@ compiler.prototype.compile = function(str)
50
64
var attrCount , childrenCount /*,state*/ ;
51
65
//var elementStack = [];
52
66
var nodeStack = this . parser . parse ( str ) ;
53
- var result = '' ;
67
+ var result = [ ] ;
54
68
55
69
console . log ( nodeStack ) ;
56
70
@@ -92,12 +106,14 @@ compiler.prototype.compile = function(str)
92
106
}
93
107
case parser . type . HTML_ATTR_START :
94
108
{
95
- result += ',' ;
109
+ append ( ',' , result ) ;
110
+
96
111
if ( attrCount ++ === 0 )
97
112
{
98
113
//state = "attrs";
99
- result += '{' ;
114
+ append ( '{' , result ) ;
100
115
}
116
+
101
117
break ;
102
118
}
103
119
@@ -118,7 +134,7 @@ compiler.prototype.compile = function(str)
118
134
}
119
135
case parser . type . HTML_ATTR_VALUE_START :
120
136
{
121
- result += ':' ;
137
+ append ( ':' , result ) ;
122
138
break ;
123
139
}
124
140
@@ -135,11 +151,13 @@ compiler.prototype.compile = function(str)
135
151
136
152
case parser . type . HTML_TAG_END :
137
153
{
138
- result += closeAttrs ( nodeStack , nodeIndex ) ;
139
- if ( isClosingTag ( nodeStack , nodeIndex , - 4 ) === true )
154
+ append ( closeAttrs ( nodeStack , nodeIndex ) , result ) ;
155
+
156
+ if ( isClosingTag ( nodeStack , nodeIndex , - 4 ) === true )
140
157
{
141
- result += ')' ;
158
+ append ( ')' , result ) ;
142
159
}
160
+
143
161
break ;
144
162
}
145
163
case parser . type . HTML_TAG_START :
@@ -148,9 +166,10 @@ compiler.prototype.compile = function(str)
148
166
{
149
167
attrCount = 0 ;
150
168
childrenCount = 0 ;
151
- result += prefix ( nodeStack , nodeIndex ) ;
152
- result += 'React.createElement(' ;
169
+ append ( prefix ( nodeStack , nodeIndex ) , result ) ;
170
+ append ( createElementFunction , result ) ;
153
171
}
172
+
154
173
break ;
155
174
}
156
175
@@ -167,11 +186,15 @@ compiler.prototype.compile = function(str)
167
186
168
187
case parser . type . TEXT :
169
188
{
170
- if ( isClosingTag ( nodeStack , nodeIndex , - 2 ) !== true )
189
+ if ( isClosingTag ( nodeStack , nodeIndex , - 2 ) !== true )
171
190
{
172
- result += prefix ( nodeStack , nodeIndex ) ;
173
- result += '"' + node . value + '"' ;
191
+ //if (changeTagFunction(nodeStack, nodeIndex, node.value, result) === false)
192
+ //{
193
+ append ( prefix ( nodeStack , nodeIndex ) , result ) ;
194
+ append ( '"' + node . value + '"' , result ) ;
195
+ //}
174
196
}
197
+
175
198
break ;
176
199
}
177
200
@@ -183,11 +206,49 @@ compiler.prototype.compile = function(str)
183
206
}
184
207
} ) ;
185
208
186
- return result ;
209
+ return finalize ( result , this . options ) ;
187
210
} ;
188
211
189
212
190
213
214
+ function append ( string , resultArray )
215
+ {
216
+ if ( string != null && string !== "" )
217
+ {
218
+ resultArray . push ( string ) ;
219
+ }
220
+ }
221
+
222
+
223
+
224
+ function changeTagFunction ( nodeStack , nodeIndex , tagName , resultArray )
225
+ {
226
+ var lastResultIndex ;
227
+
228
+ // If we're defining a tag name
229
+ if ( previousNode ( nodeStack , nodeIndex ) . type === parser . type . HTML_TAG_NAME_START )
230
+ {
231
+ lastResultIndex = resultArray . length - 1 ;
232
+
233
+ // If last result index is `React.createElement`
234
+ if ( resultArray [ lastResultIndex ] === createElementFunction )
235
+ {
236
+ tagName = tagName . toLowerCase ( ) ;
237
+
238
+ // If tag name has a `React.DOM` function
239
+ if ( typeof React . DOM [ tagName ] === "function" )
240
+ {
241
+ resultArray [ lastResultIndex ] = 'React.DOM.' + tagName + '(' ;
242
+ return true ;
243
+ }
244
+ }
245
+ }
246
+
247
+ return false ;
248
+ }
249
+
250
+
251
+
191
252
function closeAttrs ( nodeStack , nodeIndex )
192
253
{
193
254
var prevNode = previousNode ( nodeStack , nodeIndex ) ;
@@ -205,6 +266,36 @@ function closeAttrs(nodeStack, nodeIndex)
205
266
206
267
207
268
269
+ function finalize ( resultArray , options )
270
+ {
271
+ var js = options . prefix + resultArray . join ( "" ) + options . suffix ;
272
+
273
+ // Check that the compiled JavaScript code is valid
274
+ try
275
+ {
276
+ Function ( "" , js ) ;
277
+ }
278
+ catch ( error )
279
+ {
280
+ console . log ( js ) ;
281
+ throw error ;
282
+ }
283
+
284
+ if ( options . beautify === true )
285
+ {
286
+ js = uglify . parse ( js ) . print_to_string (
287
+ {
288
+ beautify : true ,
289
+ comments : true ,
290
+ indent_level : 2
291
+ } ) ;
292
+ }
293
+
294
+ return js ;
295
+ }
296
+
297
+
298
+
208
299
function isClosingTag ( nodeStack , nodeIndex , numPrev )
209
300
{
210
301
var twoNodesBack = previousNode ( nodeStack , nodeIndex , numPrev ) ;
0 commit comments