• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

prebid / Prebid.js / 16197995703

10 Jul 2025 02:32PM UTC coverage: 96.232% (+0.003%) from 96.229%
16197995703

push

github

web-flow
Linting: remove exception (#13518)

* bump coveralls

* remove exceptions

* results

* eslint fix

* Update package-lock.json

* Update package-lock.json

* Core: remove codex comments and unused lint rule (#13520)

---------

Co-authored-by: Demetrio Girardi <dgirardi@prebid.org>

39174 of 48116 branches covered (81.42%)

9842 of 9975 new or added lines in 861 files covered. (98.67%)

15 existing lines in 8 files now uncovered.

192483 of 200020 relevant lines covered (96.23%)

88.4 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

84.51
/src/secureCreatives.js
1
/* Secure Creatives
2
  Provides support for rendering creatives into cross domain iframes such as SafeFrame to prevent
3
   access to a publisher page from creative payloads.
4
 */
5

6
import {getAllAssetsMessage, getAssetMessage} from './native.js';
7
import {BID_STATUS, MESSAGES} from './constants.js';
8
import {isApnGetTagDefined, isGptPubadsDefined, logError, logWarn} from './utils.js';
9
import {
10
  deferRendering,
11
  getBidToRender,
12
  handleCreativeEvent,
13
  handleNativeMessage,
14
  handleRender,
15
  markWinner
16
} from './adRendering.js';
17
import {getCreativeRendererSource, PUC_MIN_VERSION} from './creativeRenderers.js';
18

19
const { REQUEST, RESPONSE, NATIVE, EVENT } = MESSAGES;
4✔
20

21
const HANDLER_MAP = {
4✔
22
  [REQUEST]: handleRenderRequest,
23
  [EVENT]: handleEventRequest,
24
};
25

26
if (FEATURES.NATIVE) {
4✔
27
  Object.assign(HANDLER_MAP, {
4✔
28
    [NATIVE]: handleNativeRequest,
29
  });
30
}
31

32
export function listenMessagesFromCreative() {
33
  window.addEventListener('message', function (ev) {
1✔
34
    receiveMessage(ev);
×
35
  }, false);
36
}
37

38
export function getReplier(ev) {
39
  if (ev.origin == null && ev.ports.length === 0) {
21✔
40
    return function () {
1✔
41
      const msg = 'Cannot post message to a frame with null origin. Please update creatives to use MessageChannel, see https://github.com/prebid/Prebid.js/issues/7870';
1✔
42
      logError(msg);
1✔
43
      throw new Error(msg);
1✔
44
    };
45
  } else if (ev.ports.length > 0) {
20✔
46
    return function (message) {
1✔
47
      ev.ports[0].postMessage(JSON.stringify(message));
1✔
48
    };
49
  } else {
50
    return function (message) {
19✔
51
      ev.source.postMessage(JSON.stringify(message), ev.origin);
7✔
52
    };
53
  }
54
}
55

56
function ensureAdId(adId, reply) {
57
  return function (data, ...args) {
18!
58
    return reply(Object.assign({}, data, {adId}), ...args);
6✔
59
  }
60
}
61

62
export function receiveMessage(ev) {
63
  var key = ev.message ? 'message' : 'data';
18!
64
  var data = {};
18✔
65
  try {
18✔
66
    data = JSON.parse(ev[key]);
18✔
67
  } catch (e) {
68
    return;
×
69
  }
70

71
  if (data && data.adId && data.message && HANDLER_MAP.hasOwnProperty(data.message)) {
18✔
72
    return getBidToRender(data.adId, data.message === MESSAGES.REQUEST).then(adObject => {
18✔
73
      HANDLER_MAP[data.message](ensureAdId(data.adId, getReplier(ev)), data, adObject);
18✔
74
    })
75
  }
76
}
77

78
function getResizer(adId, bidResponse) {
79
  // in some situations adId !== bidResponse.adId
80
  // the first is the one that was requested and is tied to the element
81
  // the second is the one that is being rendered (sometimes different, e.g. in some paapi setups)
82
  return function (width, height) {
11✔
83
    resizeRemoteCreative({...bidResponse, width, height, adId});
2✔
84
  }
85
}
86
function handleRenderRequest(reply, message, bidResponse) {
87
  handleRender({
9✔
88
    renderFn(adData) {
89
      reply(Object.assign({
3✔
90
        message: RESPONSE,
91
        renderer: getCreativeRendererSource(bidResponse),
92
        rendererVersion: PUC_MIN_VERSION
93
      }, adData));
94
    },
95
    resizeFn: getResizer(message.adId, bidResponse),
96
    options: message.options,
97
    adId: message.adId,
98
    bidResponse
99
  });
100
}
101

102
function handleNativeRequest(reply, data, adObject) {
103
  // handle this script from native template in an ad server
104
  // window.parent.postMessage(JSON.stringify({
105
  //   message: 'Prebid Native',
106
  //   adId: '%%PATTERN:hb_adid%%'
107
  // }), '*');
108
  if (adObject == null) {
5!
109
    logError(`Cannot find ad for x-origin event request: '${data.adId}'`);
×
110
    return;
×
111
  }
112
  switch (data.action) {
5!
113
    case 'assetRequest':
114
      deferRendering(adObject, () => reply(getAssetMessage(data, adObject)));
×
115
      break;
×
116
    case 'allAssetRequest':
117
      deferRendering(adObject, () => reply(getAllAssetsMessage(data, adObject)));
3✔
118
      break;
3✔
119
    default:
120
      handleNativeMessage(data, adObject, {resizeFn: getResizer(data.adId, adObject)});
2✔
121
      markWinner(adObject);
2✔
122
  }
123
}
124

125
function handleEventRequest(reply, data, adObject) {
126
  if (adObject == null) {
4!
127
    logError(`Cannot find ad '${data.adId}' for x-origin event request`);
×
128
    return;
×
129
  }
130
  if (adObject.status !== BID_STATUS.RENDERED) {
4✔
131
    logWarn(`Received x-origin event request without corresponding render request for ad '${adObject.adId}'`);
2✔
132
    return;
2✔
133
  }
134
  return handleCreativeEvent(data, adObject);
2✔
135
}
136

137
export function resizeRemoteCreative({instl, adId, adUnitCode, width, height}) {
4✔
138
  // do not resize interstitials - the creative frame takes the full screen and sizing of the ad should
139
  // be handled within it.
140
  if (instl) return;
4✔
141
  function getDimension(value) {
142
    return value ? value + 'px' : '100%';
2!
143
  }
144
  // resize both container div + iframe
145
  ['div', 'iframe'].forEach(elmType => {
3✔
146
    // not select element that gets removed after dfp render
147
    const element = getElementByAdUnit(elmType + ':not([style*="display: none"])');
6✔
148
    if (element) {
6✔
149
      const elementStyle = element.style;
1✔
150
      elementStyle.width = getDimension(width)
1✔
151
      elementStyle.height = getDimension(height);
1✔
152
    } else {
153
      logError(`Unable to locate matching page element for adUnitCode ${adUnitCode}.  Can't resize it to ad's dimensions.  Please review setup.`);
5✔
154
    }
155
  });
156

157
  function getElementByAdUnit(elmType) {
158
    const id = getElementIdBasedOnAdServer(adId, adUnitCode);
6✔
159
    const parentDivEle = document.getElementById(id);
6✔
160
    return parentDivEle && parentDivEle.querySelector(elmType);
6✔
161
  }
162

163
  function getElementIdBasedOnAdServer(adId, adUnitCode) {
164
    if (isGptPubadsDefined()) {
6✔
165
      return getDfpElementId(adId);
4✔
166
    } else if (isApnGetTagDefined()) {
2!
167
      return getAstElementId(adUnitCode);
×
168
    } else {
169
      return adUnitCode;
2✔
170
    }
171
  }
172

173
  function getDfpElementId(adId) {
174
    const slot = window.googletag.pubads().getSlots().find(slot => {
4✔
175
      return slot.getTargetingKeys().find(key => {
8✔
176
        return slot.getTargeting(key).includes(adId);
6✔
177
      });
178
    });
179
    return slot ? slot.getSlotElementId() : null;
4✔
180
  }
181

182
  function getAstElementId(adUnitCode) {
NEW
183
    const astTag = window.apntag.getTag(adUnitCode);
×
184
    return astTag && astTag.targetId;
×
185
  }
186
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc