@@ -161,14 +161,14 @@ export function newNativeAssetManager(win, pubUrl) {
161
161
}
162
162
163
163
function loadMobileAssets ( tagData , cb ) {
164
- const placeholders = scanForPlaceholders ( ) ;
164
+ const placeholders = scanDOMForPlaceHolders ( ) ;
165
165
if ( placeholders . length > 0 ) {
166
166
callback = cb ;
167
167
requestAssetsFromCache ( tagData ) ;
168
168
}
169
169
}
170
170
171
- function pbNativeDataHasValidType ( ) {
171
+ function hasPbNativeData ( ) {
172
172
return typeof win . pbNativeData !== 'undefined'
173
173
}
174
174
@@ -180,16 +180,16 @@ export function newNativeAssetManager(win, pubUrl) {
180
180
* to retrieve native assets that have a value on the corresponding bid
181
181
*/
182
182
function loadAssets ( adId , cb ) {
183
- const placeholders = scanForPlaceholders ( adId ) ;
183
+ const placeholders = scanDOMForPlaceHolders ( adId ) ;
184
184
185
- if ( pbNativeDataHasValidType ( ) && win . pbNativeData . hasOwnProperty ( 'assetsToReplace' ) ) {
185
+ if ( hasPbNativeData ( ) && win . pbNativeData . hasOwnProperty ( 'assetsToReplace' ) ) {
186
186
win . pbNativeData . assetsToReplace . forEach ( ( asset ) => {
187
187
const key = ( asset . match ( / h b _ n a t i v e _ / i) ) ? asset : NATIVE_KEYS [ asset ] ;
188
188
if ( key ) { placeholders . push ( key ) ; }
189
189
} ) ;
190
190
}
191
191
192
- if ( pbNativeDataHasValidType ( ) && win . pbNativeData . hasOwnProperty ( 'requestAllAssets' ) && win . pbNativeData . requestAllAssets ) {
192
+ if ( hasPbNativeData ( ) && win . pbNativeData . hasOwnProperty ( 'requestAllAssets' ) && win . pbNativeData . requestAllAssets ) {
193
193
callback = cb ;
194
194
cancelMessageListener = requestAllAssets ( adId ) ;
195
195
} else if ( placeholders . length > 0 ) {
@@ -198,24 +198,29 @@ export function newNativeAssetManager(win, pubUrl) {
198
198
}
199
199
}
200
200
201
+ function placeholderFor ( key , adId ) {
202
+ return ( adId && ! hasPbNativeData ( ) ) ? `${ key } :${ adId } ` : ( ( hasPbNativeData ( ) ) ? `##${ key } ##` : key )
203
+ }
204
+
205
+ function scanForPlaceHolders ( adId , ...markupFragments ) {
206
+ return Object . values ( NATIVE_KEYS )
207
+ . reduce ( ( found , key ) => {
208
+ const placeholder = placeholderFor ( key , adId ) ;
209
+ for ( const mkup of markupFragments . filter ( Boolean ) ) {
210
+ if ( mkup . indexOf ( placeholder ) >= 0 ) {
211
+ found . push ( key ) ;
212
+ break ;
213
+ }
214
+ }
215
+ return found ;
216
+ } , [ ] ) ;
217
+ }
218
+
201
219
/*
202
220
* Searches the DOM for placeholder values sent in by Prebid Native
203
221
*/
204
- function scanForPlaceholders ( adId ) {
205
- let placeholders = [ ] ;
206
- const doc = win . document ;
207
-
208
- Object . keys ( NATIVE_KEYS ) . forEach ( key => {
209
- const placeholderKey = NATIVE_KEYS [ key ] ;
210
- const placeholder = ( adId && ! pbNativeDataHasValidType ( ) ) ? `${ placeholderKey } :${ adId } ` : `${ placeholderKey } ` ;
211
- const placeholderIndex = ( ~ doc . body . innerHTML . indexOf ( placeholder ) ) ? doc . body . innerHTML . indexOf ( placeholder ) : ( doc . head . innerHTML && doc . head . innerHTML . indexOf ( placeholder ) ) ;
212
-
213
- if ( ~ placeholderIndex ) {
214
- placeholders . push ( placeholderKey ) ;
215
- }
216
- } ) ;
217
-
218
- return placeholders ;
222
+ function scanDOMForPlaceHolders ( adId ) {
223
+ return scanForPlaceHolders ( adId , win . document . body . innerHTML , win . document . head . innerHTML ) ;
219
224
}
220
225
221
226
/*
@@ -281,13 +286,12 @@ export function newNativeAssetManager(win, pubUrl) {
281
286
if ( data . message === 'assetResponse' ) {
282
287
const body = win . document . body . innerHTML ;
283
288
const head = win . document . head . innerHTML ;
284
- const flag = pbNativeDataHasValidType ( ) ;
285
289
286
- if ( flag && data . adId !== win . pbNativeData . adId ) return ;
290
+ if ( hasPbNativeData ( ) && data . adId !== win . pbNativeData . adId ) return ;
287
291
288
292
if ( head ) win . document . head . innerHTML = replace ( head , data ) ;
289
293
290
- if ( ( data . hasOwnProperty ( 'rendererUrl' ) && data . rendererUrl ) || ( flag && win . pbNativeData . hasOwnProperty ( 'rendererUrl' ) ) ) {
294
+ if ( ( data . hasOwnProperty ( 'rendererUrl' ) && data . rendererUrl ) || ( hasPbNativeData ( ) && win . pbNativeData . hasOwnProperty ( 'rendererUrl' ) ) ) {
291
295
if ( win . renderAd ) {
292
296
const newHtml = ( win . renderAd && win . renderAd ( data . assets ) ) || '' ;
293
297
@@ -305,7 +309,7 @@ export function newNativeAssetManager(win, pubUrl) {
305
309
requestHeightResize ( data . adId , ( document . body . clientHeight || document . body . offsetHeight ) ) ;
306
310
} ) ;
307
311
} else {
308
- loadScript ( win , ( ( flag && win . pbNativeData . hasOwnProperty ( 'rendererUrl' ) && win . pbNativeData . rendererUrl ) || data . rendererUrl ) , function ( ) {
312
+ loadScript ( win , ( ( hasPbNativeData ( ) && win . pbNativeData . hasOwnProperty ( 'rendererUrl' ) && win . pbNativeData . rendererUrl ) || data . rendererUrl ) , function ( ) {
309
313
const newHtml = ( win . renderAd && win . renderAd ( data . assets ) ) || '' ;
310
314
311
315
win . document . body . innerHTML = body + newHtml ;
@@ -314,8 +318,8 @@ export function newNativeAssetManager(win, pubUrl) {
314
318
requestHeightResize ( data . adId , ( document . body . clientHeight || document . body . offsetHeight ) ) ;
315
319
} )
316
320
}
317
- } else if ( ( data . hasOwnProperty ( 'adTemplate' ) && data . adTemplate ) || ( flag && win . pbNativeData . hasOwnProperty ( 'adTemplate' ) ) ) {
318
- const template = ( flag && win . pbNativeData . hasOwnProperty ( 'adTemplate' ) && win . pbNativeData . adTemplate ) || data . adTemplate ;
321
+ } else if ( ( data . hasOwnProperty ( 'adTemplate' ) && data . adTemplate ) || ( hasPbNativeData ( ) && win . pbNativeData . hasOwnProperty ( 'adTemplate' ) ) ) {
322
+ const template = ( hasPbNativeData ( ) && win . pbNativeData . hasOwnProperty ( 'adTemplate' ) && win . pbNativeData . adTemplate ) || data . adTemplate ;
319
323
const newHtml = replace ( template , data ) ;
320
324
win . document . body . innerHTML = body + newHtml ;
321
325
callback && callback ( ) ;
@@ -336,12 +340,11 @@ export function newNativeAssetManager(win, pubUrl) {
336
340
* in the given document.
337
341
* If there's no actual value, the placeholder gets replaced by an empty string.
338
342
*/
339
- function replace ( document , { assets, adId } ) {
340
- let html = document ;
343
+ function replace ( html , { assets, adId } ) {
344
+ assets = assets || [ ] ;
341
345
342
- scanForPlaceholders ( ) . forEach ( placeholder => {
343
- const flag = pbNativeDataHasValidType ( ) ;
344
- const searchString = ( adId && ! flag ) ? `${ placeholder } :${ adId } ` : ( ( flag ) ? '##' + `${ placeholder } ` + '##' : `${ placeholder } ` ) ;
346
+ scanForPlaceHolders ( adId , html ) . forEach ( placeholder => {
347
+ const searchString = placeholderFor ( placeholder , adId ) ;
345
348
const searchStringRegex = new RegExp ( searchString , 'g' ) ;
346
349
const fittingAsset = assets . find ( asset => placeholder === NATIVE_KEYS [ asset . key ] ) ;
347
350
html = html . replace ( searchStringRegex , fittingAsset ? fittingAsset . value : '' ) ;
0 commit comments