@guardian/commercial-core 7.1.0 → 27.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +23 -34
  3. package/dist/cjs/ad-sizes.d.ts +150 -8
  4. package/dist/cjs/ad-sizes.js +129 -38
  5. package/dist/cjs/breakpoint.d.ts +8 -0
  6. package/dist/cjs/breakpoint.js +10 -0
  7. package/dist/cjs/constants/index.d.ts +1 -1
  8. package/dist/cjs/constants/index.js +2 -2
  9. package/dist/cjs/detect-ad-blocker.js +1 -2
  10. package/dist/cjs/event-timer.d.ts +60 -48
  11. package/dist/cjs/event-timer.js +149 -115
  12. package/dist/cjs/geo/country-code.d.ts +3 -0
  13. package/dist/cjs/geo/country-code.js +34 -0
  14. package/dist/cjs/geo/geo-utils.d.ts +11 -0
  15. package/dist/cjs/geo/geo-utils.js +31 -0
  16. package/dist/cjs/global.d.ts +58 -10
  17. package/dist/cjs/index.d.ts +9 -39
  18. package/dist/cjs/index.js +12 -67
  19. package/dist/cjs/send-commercial-metrics.d.ts +8 -2
  20. package/dist/cjs/send-commercial-metrics.js +51 -27
  21. package/dist/cjs/targeting/build-page-targeting.d.ts +4 -5
  22. package/dist/cjs/targeting/build-page-targeting.js +35 -7
  23. package/dist/cjs/targeting/content.d.ts +1 -1
  24. package/dist/cjs/targeting/content.js +1 -1
  25. package/dist/cjs/targeting/personalised.d.ts +2 -3
  26. package/dist/cjs/targeting/personalised.js +3 -3
  27. package/dist/cjs/targeting/pick-targeting-values.d.ts +1 -1
  28. package/dist/cjs/targeting/session.d.ts +2 -2
  29. package/dist/cjs/targeting/shared.d.ts +31 -20
  30. package/dist/cjs/targeting/shared.js +0 -30
  31. package/dist/cjs/targeting/teads-eligibility.d.ts +2 -0
  32. package/dist/cjs/targeting/teads-eligibility.js +20 -0
  33. package/dist/cjs/targeting/types.d.ts +6 -0
  34. package/dist/cjs/targeting/types.js +2 -0
  35. package/dist/cjs/targeting/viewport.d.ts +1 -1
  36. package/dist/cjs/targeting/youtube-ima.d.ts +4 -3
  37. package/dist/cjs/targeting/youtube-ima.js +7 -4
  38. package/dist/cjs/types.d.ts +403 -63
  39. package/dist/cjs/types.js +11 -0
  40. package/dist/esm/ad-sizes.d.ts +150 -8
  41. package/dist/esm/ad-sizes.js +127 -38
  42. package/dist/esm/breakpoint.d.ts +8 -0
  43. package/dist/esm/breakpoint.js +6 -0
  44. package/dist/esm/constants/index.d.ts +1 -1
  45. package/dist/esm/constants/index.js +1 -1
  46. package/dist/esm/event-timer.d.ts +60 -48
  47. package/dist/esm/event-timer.js +147 -115
  48. package/dist/esm/geo/country-code.d.ts +3 -0
  49. package/dist/esm/geo/country-code.js +31 -0
  50. package/dist/esm/geo/geo-utils.d.ts +11 -0
  51. package/dist/esm/geo/geo-utils.js +20 -0
  52. package/dist/esm/global.d.ts +58 -10
  53. package/dist/esm/global.js +0 -1
  54. package/dist/esm/index.d.ts +9 -39
  55. package/dist/esm/index.js +6 -31
  56. package/dist/esm/send-commercial-metrics.d.ts +8 -2
  57. package/dist/esm/send-commercial-metrics.js +48 -25
  58. package/dist/esm/targeting/build-page-targeting.d.ts +4 -5
  59. package/dist/esm/targeting/build-page-targeting.js +35 -7
  60. package/dist/esm/targeting/content.d.ts +1 -1
  61. package/dist/esm/targeting/content.js +1 -1
  62. package/dist/esm/targeting/personalised.d.ts +2 -3
  63. package/dist/esm/targeting/personalised.js +3 -3
  64. package/dist/esm/targeting/pick-targeting-values.d.ts +1 -1
  65. package/dist/esm/targeting/session.d.ts +2 -2
  66. package/dist/esm/targeting/shared.d.ts +31 -20
  67. package/dist/esm/targeting/shared.js +0 -30
  68. package/dist/esm/targeting/teads-eligibility.d.ts +2 -0
  69. package/dist/esm/targeting/teads-eligibility.js +17 -0
  70. package/dist/esm/targeting/types.d.ts +6 -0
  71. package/dist/esm/targeting/types.js +0 -0
  72. package/dist/esm/targeting/viewport.d.ts +1 -1
  73. package/dist/esm/targeting/youtube-ima.d.ts +4 -3
  74. package/dist/esm/targeting/youtube-ima.js +7 -4
  75. package/dist/esm/types.d.ts +403 -63
  76. package/dist/esm/types.js +11 -1
  77. package/package.json +64 -83
  78. package/dist/cjs/__vendor/a9-apstag.d.ts +0 -1
  79. package/dist/cjs/__vendor/a9-apstag.js +0 -34
  80. package/dist/cjs/__vendor/ipsos-mori.d.ts +0 -1
  81. package/dist/cjs/__vendor/ipsos-mori.js +0 -18
  82. package/dist/cjs/__vendor/launchpad.d.ts +0 -1
  83. package/dist/cjs/__vendor/launchpad.js +0 -25
  84. package/dist/cjs/__vendor/pubmatic.d.ts +0 -1
  85. package/dist/cjs/__vendor/pubmatic.js +0 -49
  86. package/dist/cjs/__vendor/twitter-script.d.ts +0 -1
  87. package/dist/cjs/__vendor/twitter-script.js +0 -26
  88. package/dist/cjs/create-ad-slot.d.ts +0 -17
  89. package/dist/cjs/create-ad-slot.js +0 -107
  90. package/dist/cjs/google-analytics.d.ts +0 -1
  91. package/dist/cjs/google-analytics.js +0 -14
  92. package/dist/cjs/lib/ab-localstorage.d.ts +0 -2
  93. package/dist/cjs/lib/ab-localstorage.js +0 -14
  94. package/dist/cjs/lib/breakpoint.d.ts +0 -4
  95. package/dist/cjs/lib/breakpoint.js +0 -5
  96. package/dist/cjs/lib/can-use-dom.d.ts +0 -2
  97. package/dist/cjs/lib/can-use-dom.js +0 -9
  98. package/dist/cjs/lib/construct-query.d.ts +0 -3
  99. package/dist/cjs/lib/construct-query.js +0 -12
  100. package/dist/cjs/messenger.d.ts +0 -97
  101. package/dist/cjs/messenger.js +0 -281
  102. package/dist/cjs/targeting/build-page-targeting-consentless.d.ts +0 -15
  103. package/dist/cjs/targeting/build-page-targeting-consentless.js +0 -46
  104. package/dist/cjs/targeting/youtube.d.ts +0 -13
  105. package/dist/cjs/targeting/youtube.js +0 -64
  106. package/dist/cjs/third-party-tags/ias.d.ts +0 -7
  107. package/dist/cjs/third-party-tags/ias.js +0 -14
  108. package/dist/cjs/third-party-tags/inizio.d.ts +0 -13
  109. package/dist/cjs/third-party-tags/inizio.js +0 -39
  110. package/dist/cjs/third-party-tags/permutive.d.ts +0 -6
  111. package/dist/cjs/third-party-tags/permutive.js +0 -13
  112. package/dist/cjs/third-party-tags/remarketing.d.ts +0 -7
  113. package/dist/cjs/third-party-tags/remarketing.js +0 -22
  114. package/dist/cjs/third-party-tags/twitter-uwt.d.ts +0 -7
  115. package/dist/cjs/third-party-tags/twitter-uwt.js +0 -15
  116. package/dist/cjs/track-gpc-signal.d.ts +0 -7
  117. package/dist/cjs/track-gpc-signal.js +0 -17
  118. package/dist/cjs/track-labs-container.d.ts +0 -7
  119. package/dist/cjs/track-labs-container.js +0 -35
  120. package/dist/cjs/track-scroll-depth.d.ts +0 -8
  121. package/dist/cjs/track-scroll-depth.js +0 -41
  122. package/dist/esm/__vendor/a9-apstag.d.ts +0 -1
  123. package/dist/esm/__vendor/a9-apstag.js +0 -30
  124. package/dist/esm/__vendor/ipsos-mori.d.ts +0 -1
  125. package/dist/esm/__vendor/ipsos-mori.js +0 -14
  126. package/dist/esm/__vendor/launchpad.d.ts +0 -1
  127. package/dist/esm/__vendor/launchpad.js +0 -21
  128. package/dist/esm/__vendor/pubmatic.d.ts +0 -1
  129. package/dist/esm/__vendor/pubmatic.js +0 -45
  130. package/dist/esm/__vendor/twitter-script.d.ts +0 -1
  131. package/dist/esm/__vendor/twitter-script.js +0 -22
  132. package/dist/esm/create-ad-slot.d.ts +0 -17
  133. package/dist/esm/create-ad-slot.js +0 -103
  134. package/dist/esm/google-analytics.d.ts +0 -1
  135. package/dist/esm/google-analytics.js +0 -10
  136. package/dist/esm/lib/ab-localstorage.d.ts +0 -2
  137. package/dist/esm/lib/ab-localstorage.js +0 -10
  138. package/dist/esm/lib/breakpoint.d.ts +0 -4
  139. package/dist/esm/lib/breakpoint.js +0 -2
  140. package/dist/esm/lib/can-use-dom.d.ts +0 -2
  141. package/dist/esm/lib/can-use-dom.js +0 -6
  142. package/dist/esm/lib/construct-query.d.ts +0 -3
  143. package/dist/esm/lib/construct-query.js +0 -9
  144. package/dist/esm/messenger.d.ts +0 -97
  145. package/dist/esm/messenger.js +0 -274
  146. package/dist/esm/targeting/build-page-targeting-consentless.d.ts +0 -15
  147. package/dist/esm/targeting/build-page-targeting-consentless.js +0 -43
  148. package/dist/esm/targeting/youtube.d.ts +0 -13
  149. package/dist/esm/targeting/youtube.js +0 -60
  150. package/dist/esm/third-party-tags/ias.d.ts +0 -7
  151. package/dist/esm/third-party-tags/ias.js +0 -10
  152. package/dist/esm/third-party-tags/inizio.d.ts +0 -13
  153. package/dist/esm/third-party-tags/inizio.js +0 -35
  154. package/dist/esm/third-party-tags/permutive.d.ts +0 -6
  155. package/dist/esm/third-party-tags/permutive.js +0 -9
  156. package/dist/esm/third-party-tags/remarketing.d.ts +0 -7
  157. package/dist/esm/third-party-tags/remarketing.js +0 -18
  158. package/dist/esm/third-party-tags/twitter-uwt.d.ts +0 -7
  159. package/dist/esm/third-party-tags/twitter-uwt.js +0 -11
  160. package/dist/esm/track-gpc-signal.d.ts +0 -7
  161. package/dist/esm/track-gpc-signal.js +0 -14
  162. package/dist/esm/track-labs-container.d.ts +0 -7
  163. package/dist/esm/track-labs-container.js +0 -32
  164. package/dist/esm/track-scroll-depth.d.ts +0 -8
  165. package/dist/esm/track-scroll-depth.js +0 -38
  166. /package/dist/cjs/constants/{adLabelHeight.d.ts → ad-label-height.d.ts} +0 -0
  167. /package/dist/cjs/constants/{adLabelHeight.js → ad-label-height.js} +0 -0
  168. /package/dist/cjs/{lib → geo}/get-locale.d.ts +0 -0
  169. /package/dist/cjs/{lib → geo}/get-locale.js +0 -0
  170. /package/dist/esm/constants/{adLabelHeight.d.ts → ad-label-height.d.ts} +0 -0
  171. /package/dist/esm/constants/{adLabelHeight.js → ad-label-height.js} +0 -0
  172. /package/dist/esm/{lib → geo}/get-locale.d.ts +0 -0
  173. /package/dist/esm/{lib → geo}/get-locale.js +0 -0
@@ -1,274 +0,0 @@
1
- import { postMessage } from './messenger/post-message';
2
- const LISTENERS = {};
3
- let REGISTERED_LISTENERS = 0;
4
- let reportError = () => {
5
- // not set yet
6
- };
7
- const error405 = {
8
- code: 405,
9
- message: 'Service %% not implemented',
10
- };
11
- const error500 = {
12
- code: 500,
13
- message: 'Internal server error\n\n%%',
14
- };
15
- /**
16
- * Determine if an unknown payload has the shape of a programmatic message
17
- *
18
- * @param payload The unknown message payload
19
- */
20
- const isProgrammaticMessage = (payload) => {
21
- const payloadToCheck = payload;
22
- return (payloadToCheck.type === 'set-ad-height' &&
23
- ('id' in payloadToCheck.value || 'slotId' in payloadToCheck.value) &&
24
- 'height' in payloadToCheck.value);
25
- };
26
- /**
27
- * Convert a legacy programmatic message to a standard message
28
- *
29
- * Note that this only applies to specific resize programmatic messages
30
- * (these include specific width and height values)
31
- */
32
- const toStandardMessage = (payload) => ({
33
- id: 'aaaa0000-bb11-cc22-dd33-eeeeee444444',
34
- type: 'resize',
35
- iframeId: payload.value.id,
36
- slotId: payload.value.slotId,
37
- value: {
38
- height: payload.value.height,
39
- width: payload.value.width,
40
- },
41
- });
42
- /**
43
- * Retrieve a reference to the calling iFrame
44
- *
45
- * Attempts the following strategies to find the correct iframe:
46
- * - using the slotId from the incoming message
47
- * - using the iframeId from the incoming message
48
- * - checking message event.source (i.e. window) against all page level iframe contentWindows
49
- *
50
- * Listeners can then use the iFrame to determine the slot making the postMessage call
51
- */
52
- const getIframe = (message, messageEventSource) => {
53
- if (message.slotId) {
54
- const container = document.getElementById(`dfp-ad--${message.slotId}`);
55
- return container?.querySelector('iframe') ?? undefined;
56
- }
57
- else if (message.iframeId) {
58
- const el = document.getElementById(message.iframeId);
59
- return el instanceof HTMLIFrameElement ? el : undefined;
60
- }
61
- else if (messageEventSource) {
62
- const iframes = document.querySelectorAll('iframe');
63
- return Array.from(iframes).find((iframe) => iframe.contentWindow === messageEventSource);
64
- }
65
- };
66
- // Regex for testing validity of message ids
67
- const validMessageRegex = /^[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}$/;
68
- /**
69
- * Narrow an `unknown` payload to the standard message format
70
- *
71
- * Until DFP provides a way for us to identify with 100% certainty our
72
- * in-house creatives, we are left with doing some basic tests
73
- * such as validating the anatomy of the payload and whitelisting
74
- * event type
75
- */
76
- const isValidPayload = (payload) => {
77
- const payloadToCheck = payload;
78
- return ('type' in payloadToCheck &&
79
- 'value' in payloadToCheck &&
80
- 'id' in payloadToCheck &&
81
- payloadToCheck.type in LISTENERS &&
82
- validMessageRegex.test(payloadToCheck.id));
83
- };
84
- /**
85
- * Cheap string formatting function
86
- *
87
- * @param error An object `{ code, message }`. `message` is a string where successive
88
- * occurrences of %% will be replaced by the following arguments
89
- * @param args Arguments that will replace %%
90
- *
91
- * @example
92
- * formatError({ message: "%%, you are so %%" }, "Regis", "lovely")
93
- * => { message: "Regis, you are so lovely" }
94
- */
95
- const formatError = (error, ...args) => args.reduce((e, arg) => {
96
- e.message = e.message.replace('%%', arg);
97
- return e;
98
- }, error);
99
- /**
100
- * Convert a posted message to our StandardMessage format
101
- *
102
- * @param event The message event received on the window
103
- * @returns A message with the `StandardMessage` format, or null if the conversion was unsuccessful
104
- */
105
- const eventToStandardMessage = (event) => {
106
- try {
107
- // Currently all non-string messages are discarded here since parsing throws an error
108
- // TODO Review whether this is the desired outcome
109
- const data = JSON.parse(event.data);
110
- const message = isProgrammaticMessage(data)
111
- ? toStandardMessage(data)
112
- : data;
113
- if (isValidPayload(message)) {
114
- return message;
115
- }
116
- }
117
- catch (ex) {
118
- // Do nothing
119
- }
120
- };
121
- /**
122
- * Respond to the original iframe with the result of calling the
123
- * persistent listener / listener chain
124
- */
125
- const respond = (id, target, error, result) => {
126
- postMessage({
127
- id,
128
- error,
129
- result,
130
- }, target ?? window);
131
- };
132
- /**
133
- * Callback that is fired when an arbitrary message is received on the window
134
- *
135
- * @param event The message event received on the window
136
- */
137
- const onMessage = async (event) => {
138
- const message = eventToStandardMessage(event);
139
- if (!message) {
140
- return;
141
- }
142
- const listener = LISTENERS[message.type];
143
- if (Array.isArray(listener) && listener.length) {
144
- // Because any listener can have side-effects (by unregistering itself),
145
- // we run the promise chain on a copy of the `LISTENERS` array.
146
- // Hat tip @piuccio
147
- const promise =
148
- // We offer, but don't impose, the possibility that a listener returns
149
- // a value that must be sent back to the calling frame. To do this,
150
- // we pass the cumulated returned value as a second argument to each
151
- // listener. Notice we don't try some clever way to compose the result
152
- // value ourselves, this would only make the solution more complex.
153
- // That means a listener can ignore the cumulated return value and
154
- // return something else entirely—life is unfair.
155
- // We don't know what each callack will be made of, we don't want to.
156
- // And so we wrap each call in a promise chain, in case one drops the
157
- // occasional fastdom bomb in the middle.
158
- listener.reduce((func, listener) => func.then((ret) => {
159
- const thisRet = listener(message.value, ret, getIframe(message, event.source));
160
- return thisRet === undefined ? ret : thisRet;
161
- }), Promise.resolve());
162
- return promise
163
- .then((response) => {
164
- respond(message.id, event.source, null, response);
165
- })
166
- .catch((ex) => {
167
- reportError(ex, {
168
- feature: 'native-ads',
169
- });
170
- respond(message.id, event.source, formatError(error500, ex.toString()), null);
171
- });
172
- }
173
- else if (typeof listener === 'function') {
174
- // We found a persistent listener, to which we just delegate
175
- // responsibility to write something. Anything. Really.
176
- // The listener writes something by being given the `respond` function as the spec
177
- listener(
178
- // TODO change the arguments expected by persistent listeners to avoid this
179
- (error, result) => respond(message.id, event.source, error, result), message.value, getIframe(message, event.source));
180
- }
181
- else {
182
- // If there is no routine attached to this event type, we just answer
183
- // with an error code
184
- respond(message.id, event.source, formatError(error405, message.type), null);
185
- }
186
- };
187
- const on = (window) => {
188
- window.addEventListener('message', (event) => void onMessage(event));
189
- };
190
- const off = (window) => {
191
- window.removeEventListener('message', (event) => void onMessage(event));
192
- };
193
- /**
194
- * Register a listener for a given type of iframe message
195
- *
196
- * @param type The `type` of message to register against
197
- * @param callback The listener callback to register that will receive messages of the given type
198
- * @param options Options for the target window
199
- */
200
- export const register = (type, callback, options) => {
201
- if (REGISTERED_LISTENERS === 0) {
202
- on(options?.window ?? window);
203
- }
204
- const listeners = LISTENERS[type] ?? [];
205
- if (Array.isArray(listeners) && !listeners.includes(callback)) {
206
- LISTENERS[type] = [...listeners, callback];
207
- REGISTERED_LISTENERS += 1;
208
- }
209
- };
210
- /**
211
- * Register a persistent listener for a given type of iframe message
212
- *
213
- * @param type The `type` of message to register against
214
- * @param callback The persistent listener callback to register that will receive messages of the given type
215
- * @param options Options for the target window and whether the callback is persistent
216
- */
217
- export const registerPersistentListener = (type, callback, options) => {
218
- if (REGISTERED_LISTENERS === 0) {
219
- on(options?.window ?? window);
220
- }
221
- LISTENERS[type] = callback;
222
- REGISTERED_LISTENERS += 1;
223
- };
224
- /**
225
- * Unregister a callback for a given type
226
- *
227
- * @param type The type of message to unregister against. An iframe will send
228
- * messages annotated with the type
229
- * @param callback Optionally include the original callback. If this is included
230
- * for a persistent callback this function will be unregistered. If it's
231
- * included for a non-persistent callback only the matching callback is removed,
232
- * otherwise all callbacks for that type will be unregistered
233
- * @param options Option for the target window
234
- */
235
- export const unregister = (type, callback, options) => {
236
- const listeners = LISTENERS[type];
237
- if (listeners === undefined) {
238
- throw new Error(formatError(error405, type).message);
239
- }
240
- else if (listeners === callback) {
241
- LISTENERS[type] = undefined;
242
- REGISTERED_LISTENERS -= 1;
243
- }
244
- else if (Array.isArray(listeners)) {
245
- if (callback === undefined) {
246
- LISTENERS[type] = [];
247
- REGISTERED_LISTENERS -= listeners.length;
248
- }
249
- else {
250
- LISTENERS[type] = listeners.filter((cb) => {
251
- const callbacksEqual = cb === callback;
252
- if (callbacksEqual) {
253
- REGISTERED_LISTENERS -= 1;
254
- }
255
- return !callbacksEqual;
256
- });
257
- }
258
- }
259
- if (REGISTERED_LISTENERS === 0) {
260
- off(options?.window ?? window);
261
- }
262
- };
263
- /**
264
- * Initialize an array of listener callbacks in a batch
265
- *
266
- * @param listeners The listener registration functions
267
- * @param persistentListeners The persistent listener registration functions
268
- */
269
- export const init = (listeners, persistentListeners, errorHandler) => {
270
- reportError = errorHandler;
271
- listeners.forEach((moduleInit) => moduleInit(register, errorHandler));
272
- persistentListeners.forEach((moduleInit) => moduleInit(registerPersistentListener, errorHandler));
273
- };
274
- export const _ = { onMessage };
@@ -1,15 +0,0 @@
1
- import type { ConsentState } from '@guardian/consent-management-platform/dist/types';
2
- import type { PageTargeting } from './build-page-targeting';
3
- declare const consentlessTargetingKeys: readonly ["ab", "at", "bl", "bp", "br", "cc", "ct", "dcre", "edition", "k", "rc", "rp", "s", "se", "sens", "sh", "si", "skinsize", "su", "tn", "url", "urlkw"];
4
- type ConsentlessTargetingKeys = (typeof consentlessTargetingKeys)[number];
5
- type ConsentlessPageTargeting = Partial<Pick<PageTargeting, ConsentlessTargetingKeys>>;
6
- /**
7
- * Call buildPageTargeting then filter out the keys that are not needed for
8
- * consentless targeting.
9
- *
10
- * @param {ConsentState} consentState
11
- * @param {boolean} adFree
12
- * @returns ConsentlessPageTargeting
13
- */
14
- declare const buildPageTargetingConsentless: (consentState: ConsentState, adFree: boolean) => ConsentlessPageTargeting;
15
- export { buildPageTargetingConsentless };
@@ -1,43 +0,0 @@
1
- import { buildPageTargeting } from './build-page-targeting';
2
- const consentlessTargetingKeys = [
3
- 'ab',
4
- 'at',
5
- 'bl',
6
- 'bp',
7
- 'br',
8
- 'cc',
9
- 'ct',
10
- 'dcre',
11
- 'edition',
12
- 'k',
13
- 'rc',
14
- 'rp',
15
- 's',
16
- 'se',
17
- 'sens',
18
- 'sh',
19
- 'si',
20
- 'skinsize',
21
- 'su',
22
- 'tn',
23
- 'url',
24
- 'urlkw',
25
- ];
26
- const isConsentlessKey = (key) => consentlessTargetingKeys.includes(key);
27
- /**
28
- * Call buildPageTargeting then filter out the keys that are not needed for
29
- * consentless targeting.
30
- *
31
- * @param {ConsentState} consentState
32
- * @param {boolean} adFree
33
- * @returns ConsentlessPageTargeting
34
- */
35
- const buildPageTargetingConsentless = (consentState, adFree) => {
36
- const consentedPageTargeting = buildPageTargeting({
37
- adFree,
38
- consentState,
39
- clientSideParticipations: {},
40
- });
41
- return Object.fromEntries(Object.entries(consentedPageTargeting).filter(([k]) => isConsentlessKey(k)));
42
- };
43
- export { buildPageTargetingConsentless };
@@ -1,13 +0,0 @@
1
- import type { Participations } from '@guardian/ab-core';
2
- import type { ConsentState } from '@guardian/consent-management-platform/dist/types';
3
- import type { AdsConfig, AdsConfigDisabled, CustomParams } from '../types';
4
- declare const disabledAds: AdsConfigDisabled;
5
- type BuildAdsConfigWithConsent = {
6
- isAdFreeUser: boolean;
7
- adUnit: string;
8
- customParams: CustomParams;
9
- consentState: ConsentState;
10
- clientSideParticipations: Participations;
11
- };
12
- declare const buildAdsConfigWithConsent: ({ adUnit, clientSideParticipations, consentState, customParams, isAdFreeUser, }: BuildAdsConfigWithConsent) => AdsConfig;
13
- export { buildAdsConfigWithConsent, disabledAds };
@@ -1,60 +0,0 @@
1
- import { constructQuery } from '../lib/construct-query';
2
- import { buildPageTargeting } from './build-page-targeting';
3
- const disabledAds = { disableAds: true };
4
- const buildAdsConfig = (cmpConsent, adUnit, customParams, clientSideParticipations) => {
5
- const mergedCustomParams = {
6
- ...customParams,
7
- ...buildPageTargeting({
8
- adFree: false,
9
- clientSideParticipations,
10
- consentState: cmpConsent,
11
- youtube: true,
12
- }),
13
- // 19/04/2023 This is a temporary update to assist reporting for a YouTube IMA test
14
- yt_embed_ima: '0',
15
- };
16
- const defaultAdsConfig = {
17
- adTagParameters: {
18
- iu: adUnit,
19
- // TODO: Why are we double encoding? Following Frontend process for now
20
- cust_params: encodeURIComponent(constructQuery(mergedCustomParams)),
21
- },
22
- };
23
- if (cmpConsent.ccpa) {
24
- const canTarget = !cmpConsent.ccpa.doNotSell;
25
- return {
26
- ...defaultAdsConfig,
27
- restrictedDataProcessor: !canTarget,
28
- };
29
- }
30
- if (cmpConsent.aus) {
31
- const canTarget = cmpConsent.aus.personalisedAdvertising;
32
- return {
33
- ...defaultAdsConfig,
34
- restrictedDataProcessor: !canTarget,
35
- };
36
- }
37
- if (cmpConsent.tcfv2) {
38
- const tcfData = cmpConsent.tcfv2;
39
- const canTarget = Object.values(tcfData.consents).every(Boolean);
40
- const mergedAdTagParameters = {
41
- ...defaultAdsConfig.adTagParameters,
42
- cmpGdpr: tcfData.gdprApplies ? 1 : 0,
43
- cmpGvcd: tcfData.addtlConsent,
44
- cmpVcd: tcfData.tcString,
45
- };
46
- return {
47
- adTagParameters: mergedAdTagParameters,
48
- nonPersonalizedAd: !canTarget,
49
- };
50
- }
51
- // Shouldn't happen but handle if no matching framework
52
- return disabledAds;
53
- };
54
- const buildAdsConfigWithConsent = ({ adUnit, clientSideParticipations, consentState, customParams, isAdFreeUser, }) => {
55
- if (isAdFreeUser) {
56
- return disabledAds;
57
- }
58
- return buildAdsConfig(consentState, adUnit, customParams, clientSideParticipations);
59
- };
60
- export { buildAdsConfigWithConsent, disabledAds };
@@ -1,7 +0,0 @@
1
- import type { GetThirdPartyTag } from '../types';
2
- /**
3
- * IAS script filters bad ads
4
- * https://integralads.com/uk/
5
- * @param {} {shouldRun}
6
- */
7
- export declare const ias: GetThirdPartyTag;
@@ -1,10 +0,0 @@
1
- /**
2
- * IAS script filters bad ads
3
- * https://integralads.com/uk/
4
- * @param {} {shouldRun}
5
- */
6
- export const ias = ({ shouldRun }) => ({
7
- shouldRun,
8
- url: '//cdn.adsafeprotected.com/iasPET.1.js',
9
- name: 'ias',
10
- });
@@ -1,13 +0,0 @@
1
- import type { GetThirdPartyTag } from '../types';
2
- /**
3
- * Allows creatives to show survey
4
- * https://trello.com/c/wHffHVF1/171-integrate-and-test-inizio
5
- * @param {} {shouldRun}
6
- */
7
- export declare const inizio: GetThirdPartyTag;
8
- export declare const _: {
9
- onLoad: () => void;
10
- handleQuerySurveyDone: (surveyAvailable: boolean, survey: {
11
- measurementId: string;
12
- }) => void;
13
- };
@@ -1,35 +0,0 @@
1
- const handleQuerySurveyDone = (surveyAvailable, survey) => {
2
- if (surveyAvailable) {
3
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- @types/googletag declares it, but it may be missing
4
- if (window.googletag) {
5
- window.googletag.cmd.push(() => {
6
- window.googletag.pubads().setTargeting('inizio', 't');
7
- });
8
- }
9
- console.log(`surveyAvailable: ${survey.measurementId}`);
10
- }
11
- };
12
- const onLoad = () => {
13
- window._brandmetrics || (window._brandmetrics = []);
14
- window._brandmetrics.push({
15
- cmd: '_querySurvey',
16
- val: {
17
- callback: handleQuerySurveyDone,
18
- },
19
- });
20
- };
21
- /**
22
- * Allows creatives to show survey
23
- * https://trello.com/c/wHffHVF1/171-integrate-and-test-inizio
24
- * @param {} {shouldRun}
25
- */
26
- export const inizio = ({ shouldRun }) => ({
27
- shouldRun,
28
- url: '//cdn.brandmetrics.com/survey/script/e96d04c832084488a841a06b49b8fb2d.js',
29
- name: 'inizio',
30
- onLoad,
31
- });
32
- export const _ = {
33
- onLoad,
34
- handleQuerySurveyDone,
35
- };
@@ -1,6 +0,0 @@
1
- import type { GetThirdPartyTag } from '../types';
2
- /**
3
- * Permutive script updates local user segmentation data
4
- * @param {} {shouldRun}
5
- */
6
- export declare const permutive: GetThirdPartyTag;
@@ -1,9 +0,0 @@
1
- /**
2
- * Permutive script updates local user segmentation data
3
- * @param {} {shouldRun}
4
- */
5
- export const permutive = ({ shouldRun }) => ({
6
- shouldRun,
7
- url: '//cdn.permutive.com/d6691a17-6fdb-4d26-85d6-b3dd27f55f08-web.js',
8
- name: 'permutive',
9
- });
@@ -1,7 +0,0 @@
1
- import type { GetThirdPartyTag } from '../types';
2
- /**
3
- * Google conversion tracking
4
- * https://support.google.com/google-ads/answer/6095821
5
- * @param {} {shouldRun}
6
- */
7
- export declare const remarketing: GetThirdPartyTag;
@@ -1,18 +0,0 @@
1
- const onLoad = () => {
2
- window.google_trackConversion?.({
3
- google_conversion_id: 971225648,
4
- google_custom_params: window.google_tag_params,
5
- google_remarketing_only: true,
6
- });
7
- };
8
- /**
9
- * Google conversion tracking
10
- * https://support.google.com/google-ads/answer/6095821
11
- * @param {} {shouldRun}
12
- */
13
- export const remarketing = ({ shouldRun }) => ({
14
- shouldRun,
15
- url: '//www.googleadservices.com/pagead/conversion_async.js',
16
- name: 'remarketing',
17
- onLoad,
18
- });
@@ -1,7 +0,0 @@
1
- import type { GetThirdPartyTag } from '../types';
2
- /**
3
- * tracking pixel
4
- * https://business.twitter.com/en/help/campaign-measurement-and-analytics/conversion-tracking-for-websites.html
5
- * @param {} {shouldRun}
6
- */
7
- export declare const twitter: GetThirdPartyTag;
@@ -1,11 +0,0 @@
1
- import { twitterScript as insertSnippet } from '../__vendor/twitter-script';
2
- /**
3
- * tracking pixel
4
- * https://business.twitter.com/en/help/campaign-measurement-and-analytics/conversion-tracking-for-websites.html
5
- * @param {} {shouldRun}
6
- */
7
- export const twitter = ({ shouldRun }) => ({
8
- shouldRun,
9
- name: 'twitter',
10
- insertSnippet,
11
- });
@@ -1,7 +0,0 @@
1
- import type { ConsentState } from '@guardian/consent-management-platform/dist/types';
2
- /**
3
- * Collect metrics on gpcSignal presence and value
4
- * https://globalprivacycontrol.github.io/gpc-spec/
5
- */
6
- declare const initTrackGpcSignal: (consentState: ConsentState) => void;
7
- export { initTrackGpcSignal };
@@ -1,14 +0,0 @@
1
- import { log } from '@guardian/libs';
2
- import { EventTimer } from './event-timer';
3
- /**
4
- * Collect metrics on gpcSignal presence and value
5
- * https://globalprivacycontrol.github.io/gpc-spec/
6
- */
7
- const initTrackGpcSignal = (consentState) => {
8
- // If undefined we set the property value to -1, false is 0, true is 1
9
- const gpcSignal = consentState.gpcSignal === undefined ? -1 : +consentState.gpcSignal;
10
- const eventTimer = EventTimer.get();
11
- log('commercial', `gpcSignal ${gpcSignal}`);
12
- eventTimer.setProperty('gpcSignal', gpcSignal);
13
- };
14
- export { initTrackGpcSignal };
@@ -1,7 +0,0 @@
1
- /**
2
- * Collect commercial metrics on:
3
- * - whether the page contains a Guardian Labs container element (aka 'dumathoin'), and if so
4
- * - when the element is scrolled into view
5
- */
6
- declare const initTrackLabsContainer: () => void;
7
- export { initTrackLabsContainer };
@@ -1,32 +0,0 @@
1
- import { log } from '@guardian/libs';
2
- import { EventTimer } from './event-timer';
3
- /**
4
- * Collect commercial metrics on:
5
- * - whether the page contains a Guardian Labs container element (aka 'dumathoin'), and if so
6
- * - when the element is scrolled into view
7
- */
8
- const initTrackLabsContainer = () => {
9
- const target = document.querySelector('section.dumathoin');
10
- if (target === null)
11
- return;
12
- const labsUrl = document
13
- .querySelector('h1.dumathoin__title a')
14
- ?.getAttribute('href');
15
- if (labsUrl === null)
16
- return;
17
- const eventTimer = EventTimer.get();
18
- log('commercial', 'Page has labs container');
19
- eventTimer.setProperty('hasLabsContainer', true);
20
- eventTimer.setProperty('labsUrl', labsUrl);
21
- const observer = new IntersectionObserver((entries) => {
22
- entries.map((entry) => {
23
- if (entry.isIntersecting) {
24
- log('commercial', 'Labs container in view');
25
- eventTimer.trigger('labsContainerInView');
26
- observer.unobserve(entry.target);
27
- }
28
- });
29
- });
30
- observer.observe(target);
31
- };
32
- export { initTrackLabsContainer };
@@ -1,8 +0,0 @@
1
- /**
2
- * Collect commercial metrics on scroll depth
3
- * Insert hidden elements at intervals of 1 viewport height
4
- * then use an intersection observer to mark the time when the viewport intersects with these elements.
5
- * Approach inspired by https://gist.github.com/bgreater/2412517f5a3f9c6fc4cafeb1ca71384f
6
- */
7
- declare const initTrackScrollDepth: () => void;
8
- export { initTrackScrollDepth };
@@ -1,38 +0,0 @@
1
- import { log } from '@guardian/libs';
2
- import { EventTimer } from './event-timer';
3
- /**
4
- * Collect commercial metrics on scroll depth
5
- * Insert hidden elements at intervals of 1 viewport height
6
- * then use an intersection observer to mark the time when the viewport intersects with these elements.
7
- * Approach inspired by https://gist.github.com/bgreater/2412517f5a3f9c6fc4cafeb1ca71384f
8
- */
9
- const initTrackScrollDepth = () => {
10
- const pageHeight = document.body.offsetHeight;
11
- const intViewportHeight = window.innerHeight;
12
- // how many viewports tall is the page?
13
- const pageHeightVH = Math.floor(pageHeight / intViewportHeight);
14
- const eventTimer = EventTimer.get();
15
- eventTimer.setProperty('pageHeightVH', pageHeightVH);
16
- const observer = new IntersectionObserver(
17
- /* istanbul ignore next */
18
- (entries) => {
19
- entries.forEach((entry) => {
20
- if (entry.isIntersecting) {
21
- const currentDepthVH = String(entry.target.getAttribute('data-depth'));
22
- log('commercial', `current scroll depth ${currentDepthVH}`);
23
- eventTimer.trigger(`scroll-depth-vh-${currentDepthVH}`);
24
- observer.unobserve(entry.target);
25
- }
26
- });
27
- });
28
- for (let depth = 1; depth <= pageHeightVH; depth++) {
29
- const div = document.createElement('div');
30
- div.dataset.depth = String(depth);
31
- div.style.top = String(100 * depth) + '%';
32
- div.style.position = 'absolute';
33
- div.className = 'scroll-depth-marker';
34
- document.body.appendChild(div);
35
- observer.observe(div);
36
- }
37
- };
38
- export { initTrackScrollDepth };
File without changes
File without changes