@@ -4,7 +4,10 @@ const get = require("lodash/get");
4
4
const set = require ( "lodash/set" ) ;
5
5
const wrap = require ( "lodash/wrap" ) ;
6
6
const template = require ( "lodash/template" ) ;
7
+ const mapKeys = require ( "lodash/mapKeys" ) ;
8
+ const isArray = require ( "lodash/isArray" ) ;
7
9
const isObject = require ( "lodash/isObject" ) ;
10
+ const isPlainObject = require ( "lodash/isPlainObject" ) ;
8
11
const Module = require ( "module" ) ;
9
12
const InstantiateReactComponent = require ( "react-dom/lib/instantiateReactComponent" ) ;
10
13
const escapeTextContentForBrowser = require ( "react-dom/lib/escapeTextContentForBrowser" ) ;
@@ -82,12 +85,50 @@ class InstantiateReactComponentOptimizer {
82
85
}
83
86
}
84
87
85
- /* eslint-disable max-params, no-console*/
88
+ /* eslint-disable max-params, no-console, prefer-template*/
89
+
90
+ const restoreAttr = ( origProps , lookupPropTable , propKey , arrNotaKey , propValue ) => {
91
+ if ( isPlainObject ( propValue ) ) {
92
+ mapKeys ( propValue , ( value , key ) => {
93
+ restoreAttr ( origProps , lookupPropTable , `${ propKey } .${ key } ` ,
94
+ `${ propKey } ["${ key } "]` , value ) ;
95
+ } ) ;
96
+ } else if ( isArray ( propValue ) ) {
97
+ for ( let i = 0 ; i < propValue . length ; i ++ ) {
98
+ restoreAttr ( origProps , lookupPropTable , `${ propKey } .${ i } ` , `${ propKey } [${ i } ]` ,
99
+ propValue [ i ] ) ;
100
+ }
101
+ } else {
102
+ const _attrKey = propKey . replace ( / _ / gi, "__" ) . replace ( / \. / gi, "_" ) ;
103
+ set ( origProps , arrNotaKey , lookupPropTable [ _attrKey ] ) ;
104
+ }
105
+ } ;
106
+
107
+ const templatizeAttr = ( origProps , lookupPropTable , propKey , arrNotaKey ,
108
+ propValue , addlCacheForArr ) => {
109
+ if ( isPlainObject ( propValue ) ) {
110
+ mapKeys ( propValue , ( value , key ) => {
111
+ templatizeAttr ( origProps , lookupPropTable , `${ propKey } .${ key } ` , `${ propKey } ["${ key } "]` ,
112
+ value , addlCacheForArr ) ;
113
+ } ) ;
114
+ } else if ( isArray ( propValue ) ) {
115
+ addlCacheForArr . push ( propKey + "_" + propValue . length ) ;
116
+ for ( let i = 0 ; i < propValue . length ; i ++ ) {
117
+ templatizeAttr ( origProps , lookupPropTable , `${ propKey } .${ i } ` , `${ propKey } [${ i } ]` ,
118
+ propValue [ i ] , addlCacheForArr ) ;
119
+ }
120
+ } else {
121
+ const _attrKey = propKey . replace ( / _ / gi, "__" ) . replace ( / \. / gi, "_" ) ;
122
+ lookupPropTable [ _attrKey ] = escapeTextContentForBrowser ( propValue ) ;
123
+ set ( origProps , arrNotaKey , "${" + _attrKey + "}" ) ;
124
+ }
125
+ } ;
126
+
86
127
const restorePropsAndProcessTemplate = ( compiled , templateAttrs , templateAttrValues , curEl ) => {
87
128
templateAttrs . forEach ( ( attrKey ) => {
88
- const _attrKey = attrKey . replace ( "." , "__" ) ;
89
- set ( curEl . props , attrKey , templateAttrValues [ _attrKey ] ) ;
90
- templateAttrValues [ _attrKey ] = escapeTextContentForBrowser ( templateAttrValues [ _attrKey ] ) ;
129
+ const value = get ( curEl . props , attrKey ) ;
130
+ restoreAttr ( { a : curEl . props } , templateAttrValues , `a. ${ attrKey } ` , `a. ${ attrKey } ` ,
131
+ value ) ;
91
132
} ) ;
92
133
return compiled ( templateAttrValues ) ;
93
134
} ;
@@ -99,19 +140,6 @@ class InstantiateReactComponentOptimizer {
99
140
self . componentsToCache . indexOf ( curEl . type . name ) > EMPTY_ID ) ;
100
141
} ;
101
142
102
- /* eslint-disable max-params */
103
- const templatizeProps = function ( attrKey , templateAttrValues , curEl , cmpName ) {
104
- const _attrKey = attrKey . replace ( "." , "__" ) ;
105
- templateAttrValues [ _attrKey ] = get ( curEl . props , attrKey ) ;
106
- if ( isObject ( templateAttrValues [ _attrKey ] ) ) {
107
- throw new Error (
108
- `Cannot templatize Object at ${ attrKey } for component ${ cmpName } `
109
- ) ;
110
- }
111
- /* eslint-disable prefer-template */
112
- set ( curEl . props , attrKey , "${" + _attrKey + "}" ) ;
113
- } ;
114
-
115
143
const WrappedInstantiateReactComponent = wrap ( InstantiateReactComponent ,
116
144
function ( instantiate ) {
117
145
const component = instantiate . apply (
@@ -132,13 +160,16 @@ class InstantiateReactComponentOptimizer {
132
160
if ( generatedKey === null ) {
133
161
return mount . apply ( component , [ ] . slice . call ( arguments , 1 ) ) ;
134
162
}
135
- const cacheKey = ` ${ cmpName } : ${ generatedKey } ` ;
163
+ const addlCacheForArr = [ ] ;
136
164
const rootID = arguments [ 1 ] ;
137
165
const templateAttrs = self . config . components [ cmpName ] . templateAttrs || [ ] ;
138
166
const templateAttrValues = { } ;
139
167
templateAttrs . forEach ( ( attrKey ) => {
140
- templatizeProps ( attrKey , templateAttrValues , curEl , cmpName ) ;
168
+ const value = get ( curEl . props , attrKey ) ;
169
+ templatizeAttr ( { a : curEl . props } , templateAttrValues , `a.${ attrKey } ` ,
170
+ `a.${ attrKey } ` , value , addlCacheForArr ) ;
141
171
} ) ;
172
+ const cacheKey = `${ cmpName } :${ generatedKey } :${ addlCacheForArr } ` ;
142
173
const cachedObj = self . lruCache . get ( cacheKey ) ;
143
174
if ( cachedObj ) {
144
175
eventCallback ( { type : "cache" , event : "hit" , cmpName : cmpName } ) ;
0 commit comments