@@ -39,42 +39,68 @@ class Serialiser
3939 serialised
4040
4141 serialiseSpreadAndPairAttributes : (children ) ->
42- assigns = []
43- pairAttrsBuffer = []
42+ assigns = [] # nodes
43+ pairAttrsBuffer = [] # nodes
4444
4545 flushPairs = =>
4646 if pairAttrsBuffer .length
4747 serialisedChild = @ serialiseAttributePairs (pairAttrsBuffer)
4848 if serialisedChild
49- assigns .push (serialisedChild)
49+ assigns .push (type : $ . CS , value : serialisedChild)
5050 else
51- assigns .push (type : $ .CJSX_WHITESPACE , value : pairAttrsBuffer .map (@serialiseNode .bind (this )).join (' ' ).replace (' \n ' , ' \\\n ' ))
51+ serialisedPairs = pairAttrsBuffer
52+ .map ((p ) => @ serialiseNode (p))
53+ .join (' ' )
54+ # escaping newlines might create a syntax error if the newline is
55+ # after the last arg in a list, so we'll fix it below
56+ .replace (' \n ' , ' \\\n ' )
57+ assigns .push (type : $ .CJSX_WHITESPACE , value : serialisedPairs)
5258 pairAttrsBuffer = [] # reset buffer
5359
60+ # okay this is pretty gross. once source maps are up and running all of the
61+ # whitespace related bs can be nuked as there will no longer be a need to
62+ # torture the CS syntax to maintain whitespace and output the same number
63+ # of lines while also transforming syntax. however in the mean time, this is
64+ # what we're doing.
65+
66+ # this code rewrites attr pair, spread, etc nodes into CS (code fragment)
67+ # and whitespace nodes. then they are serialised and joined with whitespace
68+ # maintained, and newlines escaped (except at the end of an args list)
69+
70+ # initial object assign arg
5471 if firstNonWhitespaceChild (children)? .type is $ .CJSX_ATTR_SPREAD
55- assigns .push (' {}' )
72+ assigns .push (type : $ . CS , value : ' {}' )
5673
74+ # group sets of attr pairs between spreads
5775 for child, childIndex in children
5876 if child .type is $ .CJSX_ATTR_SPREAD
5977 flushPairs ()
60- assigns .push (child .value )
78+ assigns .push (type : $ . CS , value : child .value )
6179 else
6280 pairAttrsBuffer .push (child)
6381
82+ # finally group any remaining pairs
6483 flushPairs ()
6584
85+ # serialising the rewritten nodes with whitespace maintained
6686 accumulatedWhitespace = ' '
67- assignsWithWhitespace = []
87+ assignsWithWhitespace = [] # serialised nodes texts
6888 for assignItem, assignIndex in assigns
69- if typeof assignItem is ' object' and assignItem ? .type is $ .CJSX_WHITESPACE
70- accumulatedWhitespace += assignItem .value
71- if typeof assignItem is ' string'
72- assignsWithWhitespace .push accumulatedWhitespace+ assignItem
73- accumulatedWhitespace = ' '
89+ if assignItem?
90+ if assignItem .type is $ .CJSX_WHITESPACE
91+ accumulatedWhitespace += @ serialiseNode (assignItem)
92+ else
93+ assignsWithWhitespace .push (accumulatedWhitespace + @ serialiseNode (assignItem))
94+ accumulatedWhitespace = ' '
7495
7596 if assignsWithWhitespace .length
7697 lastAssignWithWhitespace = assignsWithWhitespace .pop ()
77- assignsWithWhitespace .push lastAssignWithWhitespace+ accumulatedWhitespace
98+ # hack to fix potential syntax error when newlines are escaped after last arg
99+ # TODO: kill this with fire once sourcemaps are available
100+ trailingWhiteplace = accumulatedWhitespace .replace (' \\\n ' , ' \n ' )
101+ assignsWithWhitespace .push (lastAssignWithWhitespace + trailingWhiteplace)
102+
103+ joinedAssigns = joinList (assignsWithWhitespace)
78104
79105 " React.__spread(#{ joinList (assignsWithWhitespace)} )"
80106
0 commit comments