7
7
REVISION_CHANGES
8
8
} from './base' ;
9
9
import { moveHelperToHooks } from './helpers' ;
10
+ import { wrapHelper } from './internal/wrapHelper' ;
11
+ import { createNewLookupObject } from './internal/createNewLookupObject' ;
10
12
11
13
export function checkRevision ( compilerInfo ) {
12
14
const compilerRevision = ( compilerInfo && compilerInfo [ 0 ] ) || 1 ,
@@ -66,13 +68,17 @@ export function template(templateSpec, env) {
66
68
}
67
69
partial = env . VM . resolvePartial . call ( this , partial , context , options ) ;
68
70
69
- let optionsWithHooks = Utils . extend ( { } , options , { hooks : this . hooks } ) ;
71
+ let extendedOptions = Utils . extend ( { } , options , {
72
+ hooks : this . hooks ,
73
+ allowedProtoMethods : this . allowedProtoMethods ,
74
+ allowedProtoProperties : this . allowedProtoProperties
75
+ } ) ;
70
76
71
77
let result = env . VM . invokePartial . call (
72
78
this ,
73
79
partial ,
74
80
context ,
75
- optionsWithHooks
81
+ extendedOptions
76
82
) ;
77
83
78
84
if ( result == null && env . compile ) {
@@ -81,7 +87,7 @@ export function template(templateSpec, env) {
81
87
templateSpec . compilerOptions ,
82
88
env
83
89
) ;
84
- result = options . partials [ options . name ] ( context , optionsWithHooks ) ;
90
+ result = options . partials [ options . name ] ( context , extendedOptions ) ;
85
91
}
86
92
if ( result != null ) {
87
93
if ( options . indent ) {
@@ -115,10 +121,26 @@ export function template(templateSpec, env) {
115
121
}
116
122
return obj [ name ] ;
117
123
} ,
124
+ lookupProperty : function ( parent , propertyName ) {
125
+ let result = parent [ propertyName ] ;
126
+ if ( Object . prototype . hasOwnProperty . call ( parent , propertyName ) ) {
127
+ return result ;
128
+ }
129
+ const whitelist =
130
+ typeof result === 'function'
131
+ ? container . allowedProtoMethods
132
+ : container . allowedProtoProperties ;
133
+
134
+ if ( whitelist [ propertyName ] === true ) {
135
+ return result ;
136
+ }
137
+ return undefined ;
138
+ } ,
118
139
lookup : function ( depths , name ) {
119
140
const len = depths . length ;
120
141
for ( let i = 0 ; i < len ; i ++ ) {
121
- if ( depths [ i ] && depths [ i ] [ name ] != null ) {
142
+ let result = depths [ i ] && container . lookupProperty ( depths [ i ] , name ) ;
143
+ if ( result != null ) {
122
144
return depths [ i ] [ name ] ;
123
145
}
124
146
}
@@ -226,7 +248,9 @@ export function template(templateSpec, env) {
226
248
227
249
function _setup ( options ) {
228
250
if ( ! options . partial ) {
229
- container . helpers = Utils . extend ( { } , env . helpers , options . helpers ) ;
251
+ let mergedHelpers = Utils . extend ( { } , env . helpers , options . helpers ) ;
252
+ wrapHelpersToPassLookupProperty ( mergedHelpers , container ) ;
253
+ container . helpers = mergedHelpers ;
230
254
231
255
if ( templateSpec . usePartial ) {
232
256
// Use mergeIfNeeded here to prevent compiling global partials multiple times
@@ -244,13 +268,21 @@ export function template(templateSpec, env) {
244
268
}
245
269
246
270
container . hooks = { } ;
271
+ container . allowedProtoProperties = createNewLookupObject (
272
+ options . allowedProtoProperties
273
+ ) ;
274
+ container . allowedProtoMethods = createNewLookupObject (
275
+ options . allowedProtoMethods
276
+ ) ;
247
277
248
278
let keepHelperInHelpers =
249
279
options . allowCallsToHelperMissing ||
250
280
templateWasPrecompiledWithCompilerV7 ;
251
281
moveHelperToHooks ( container , 'helperMissing' , keepHelperInHelpers ) ;
252
282
moveHelperToHooks ( container , 'blockHelperMissing' , keepHelperInHelpers ) ;
253
283
} else {
284
+ container . allowedProtoProperties = options . allowedProtoProperties ;
285
+ container . allowedProtoMethods = options . allowedProtoMethods ;
254
286
container . helpers = options . helpers ;
255
287
container . partials = options . partials ;
256
288
container . decorators = options . decorators ;
@@ -381,3 +413,17 @@ function executeDecorators(fn, prog, container, depths, data, blockParams) {
381
413
}
382
414
return prog ;
383
415
}
416
+
417
+ function wrapHelpersToPassLookupProperty ( mergedHelpers , container ) {
418
+ Object . keys ( mergedHelpers ) . forEach ( helperName => {
419
+ let helper = mergedHelpers [ helperName ] ;
420
+ mergedHelpers [ helperName ] = passLookupPropertyOption ( helper , container ) ;
421
+ } ) ;
422
+ }
423
+
424
+ function passLookupPropertyOption ( helper , container ) {
425
+ const lookupProperty = container . lookupProperty ;
426
+ return wrapHelper ( helper , options => {
427
+ return Utils . extend ( { lookupProperty } , options ) ;
428
+ } ) ;
429
+ }
0 commit comments