@guardian/commercial-core 0.0.0-beta-20250716121613
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.
- package/LICENSE +201 -0
- package/README.md +45 -0
- package/dist/cjs/ad-sizes.d.ts +202 -0
- package/dist/cjs/ad-sizes.js +400 -0
- package/dist/cjs/breakpoint.d.ts +8 -0
- package/dist/cjs/breakpoint.js +10 -0
- package/dist/cjs/constants/ad-label-height.d.ts +4 -0
- package/dist/cjs/constants/ad-label-height.js +7 -0
- package/dist/cjs/constants/index.d.ts +3 -0
- package/dist/cjs/constants/index.js +9 -0
- package/dist/cjs/constants/prebid-timeout.d.ts +4 -0
- package/dist/cjs/constants/prebid-timeout.js +7 -0
- package/dist/cjs/constants/top-above-nav-height.d.ts +10 -0
- package/dist/cjs/constants/top-above-nav-height.js +48 -0
- package/dist/cjs/detect-ad-blocker.d.ts +12 -0
- package/dist/cjs/detect-ad-blocker.js +61 -0
- package/dist/cjs/event-timer.d.ts +103 -0
- package/dist/cjs/event-timer.js +204 -0
- package/dist/cjs/geo/country-code.d.ts +3 -0
- package/dist/cjs/geo/country-code.js +34 -0
- package/dist/cjs/geo/geo-utils.d.ts +11 -0
- package/dist/cjs/geo/geo-utils.js +31 -0
- package/dist/cjs/geo/get-locale.d.ts +8 -0
- package/dist/cjs/geo/get-locale.js +43 -0
- package/dist/cjs/global.d.ts +71 -0
- package/dist/cjs/global.js +2 -0
- package/dist/cjs/index.d.ts +13 -0
- package/dist/cjs/index.js +46 -0
- package/dist/cjs/messenger/post-message.d.ts +1 -0
- package/dist/cjs/messenger/post-message.js +7 -0
- package/dist/cjs/permutive.d.ts +9 -0
- package/dist/cjs/permutive.js +38 -0
- package/dist/cjs/send-commercial-metrics.d.ts +58 -0
- package/dist/cjs/send-commercial-metrics.js +209 -0
- package/dist/cjs/targeting/build-page-targeting.d.ts +47 -0
- package/dist/cjs/targeting/build-page-targeting.js +112 -0
- package/dist/cjs/targeting/content.d.ts +87 -0
- package/dist/cjs/targeting/content.js +76 -0
- package/dist/cjs/targeting/personalised.d.ts +83 -0
- package/dist/cjs/targeting/personalised.js +140 -0
- package/dist/cjs/targeting/pick-targeting-values.d.ts +25 -0
- package/dist/cjs/targeting/pick-targeting-values.js +47 -0
- package/dist/cjs/targeting/session.d.ts +111 -0
- package/dist/cjs/targeting/session.js +61 -0
- package/dist/cjs/targeting/shared.d.ts +156 -0
- package/dist/cjs/targeting/shared.js +28 -0
- package/dist/cjs/targeting/teads-eligibility.d.ts +2 -0
- package/dist/cjs/targeting/teads-eligibility.js +20 -0
- package/dist/cjs/targeting/types.d.ts +6 -0
- package/dist/cjs/targeting/types.js +2 -0
- package/dist/cjs/targeting/viewport.d.ts +48 -0
- package/dist/cjs/targeting/viewport.js +22 -0
- package/dist/cjs/targeting/youtube-ima.d.ts +12 -0
- package/dist/cjs/targeting/youtube-ima.js +76 -0
- package/dist/cjs/types.d.ts +426 -0
- package/dist/cjs/types.js +12 -0
- package/dist/esm/ad-sizes.d.ts +202 -0
- package/dist/esm/ad-sizes.js +390 -0
- package/dist/esm/breakpoint.d.ts +8 -0
- package/dist/esm/breakpoint.js +6 -0
- package/dist/esm/constants/ad-label-height.d.ts +4 -0
- package/dist/esm/constants/ad-label-height.js +4 -0
- package/dist/esm/constants/index.d.ts +3 -0
- package/dist/esm/constants/index.js +3 -0
- package/dist/esm/constants/prebid-timeout.d.ts +4 -0
- package/dist/esm/constants/prebid-timeout.js +4 -0
- package/dist/esm/constants/top-above-nav-height.d.ts +10 -0
- package/dist/esm/constants/top-above-nav-height.js +45 -0
- package/dist/esm/detect-ad-blocker.d.ts +12 -0
- package/dist/esm/detect-ad-blocker.js +58 -0
- package/dist/esm/event-timer.d.ts +103 -0
- package/dist/esm/event-timer.js +199 -0
- package/dist/esm/geo/country-code.d.ts +3 -0
- package/dist/esm/geo/country-code.js +31 -0
- package/dist/esm/geo/geo-utils.d.ts +11 -0
- package/dist/esm/geo/geo-utils.js +20 -0
- package/dist/esm/geo/get-locale.d.ts +8 -0
- package/dist/esm/geo/get-locale.js +38 -0
- package/dist/esm/global.d.ts +71 -0
- package/dist/esm/global.js +0 -0
- package/dist/esm/index.d.ts +13 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/messenger/post-message.d.ts +1 -0
- package/dist/esm/messenger/post-message.js +3 -0
- package/dist/esm/permutive.d.ts +9 -0
- package/dist/esm/permutive.js +33 -0
- package/dist/esm/send-commercial-metrics.d.ts +58 -0
- package/dist/esm/send-commercial-metrics.js +204 -0
- package/dist/esm/targeting/build-page-targeting.d.ts +47 -0
- package/dist/esm/targeting/build-page-targeting.js +108 -0
- package/dist/esm/targeting/content.d.ts +87 -0
- package/dist/esm/targeting/content.js +73 -0
- package/dist/esm/targeting/personalised.d.ts +83 -0
- package/dist/esm/targeting/personalised.js +137 -0
- package/dist/esm/targeting/pick-targeting-values.d.ts +25 -0
- package/dist/esm/targeting/pick-targeting-values.js +43 -0
- package/dist/esm/targeting/session.d.ts +111 -0
- package/dist/esm/targeting/session.js +57 -0
- package/dist/esm/targeting/shared.d.ts +156 -0
- package/dist/esm/targeting/shared.js +25 -0
- package/dist/esm/targeting/teads-eligibility.d.ts +2 -0
- package/dist/esm/targeting/teads-eligibility.js +17 -0
- package/dist/esm/targeting/types.d.ts +6 -0
- package/dist/esm/targeting/types.js +0 -0
- package/dist/esm/targeting/viewport.d.ts +48 -0
- package/dist/esm/targeting/viewport.js +19 -0
- package/dist/esm/targeting/youtube-ima.d.ts +12 -0
- package/dist/esm/targeting/youtube-ima.js +73 -0
- package/dist/esm/types.d.ts +426 -0
- package/dist/esm/types.js +10 -0
- package/package.json +65 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type { ConnectionType } from './types';
|
|
2
|
+
declare const supportsPerformanceAPI: () => boolean;
|
|
3
|
+
interface EventTimerProperties {
|
|
4
|
+
type?: ConnectionType;
|
|
5
|
+
downlink?: number;
|
|
6
|
+
effectiveType?: string;
|
|
7
|
+
adSlotsInline?: number;
|
|
8
|
+
adSlotsTotal?: number;
|
|
9
|
+
/** the height of the page / the viewport height */
|
|
10
|
+
pageHeightVH?: number;
|
|
11
|
+
gpcSignal?: number;
|
|
12
|
+
/** distance in percentage of viewport height at which ads are lazy loaded */
|
|
13
|
+
lazyLoadMarginPercent?: number;
|
|
14
|
+
hasLabsContainer?: boolean;
|
|
15
|
+
labsUrl?: string;
|
|
16
|
+
/** Record whether we've detected an ad blocker. This is intentionally
|
|
17
|
+
* distinct from the property we pass into commercial metrics, and in the
|
|
18
|
+
* future _could_ be removed in favour of this property */
|
|
19
|
+
detectedAdBlocker?: boolean;
|
|
20
|
+
/** Record whether we've shown the adblock as message */
|
|
21
|
+
didDisplayAdBlockAsk?: boolean;
|
|
22
|
+
/** creative ID of a video interscroller for video reporting metrics */
|
|
23
|
+
videoInterscrollerCreativeId?: number | null | undefined;
|
|
24
|
+
/** percentage progress of video interscroller on page unload */
|
|
25
|
+
videoInterscrollerPercentageProgress?: number;
|
|
26
|
+
}
|
|
27
|
+
declare class EventTimer {
|
|
28
|
+
private _marks;
|
|
29
|
+
private _measures;
|
|
30
|
+
properties: EventTimerProperties;
|
|
31
|
+
/**
|
|
32
|
+
* Initialise the EventTimer class on page.
|
|
33
|
+
* Returns the singleton instance of the EventTimer class and binds
|
|
34
|
+
* to window.guardian.commercialTimer. If it's been previously
|
|
35
|
+
* initialised and bound it returns the original instance
|
|
36
|
+
* Note: We save to window.guardian.commercialTimer because
|
|
37
|
+
* different bundles (DCR / DCP) can use commercial, and we want
|
|
38
|
+
* all timer events saved to a single instance per-page
|
|
39
|
+
* @returns {EventTimer} Instance of EventTimer
|
|
40
|
+
*/
|
|
41
|
+
static init(): EventTimer;
|
|
42
|
+
/**
|
|
43
|
+
* Just a helper method to access the singleton instance of EventTimer.
|
|
44
|
+
* Typical use case is EventTimer.get().trigger
|
|
45
|
+
*/
|
|
46
|
+
static get(): EventTimer;
|
|
47
|
+
/**
|
|
48
|
+
* These are marks that are not triggered by commercial but we are interested in
|
|
49
|
+
* tracking their performance. For example, CMP-related events.
|
|
50
|
+
**/
|
|
51
|
+
private get _externalMarks();
|
|
52
|
+
/**
|
|
53
|
+
* Returns all performance marks that should be saved as commercial metrics.
|
|
54
|
+
*/
|
|
55
|
+
get marks(): {
|
|
56
|
+
name: string;
|
|
57
|
+
ts: number;
|
|
58
|
+
}[];
|
|
59
|
+
/**
|
|
60
|
+
* Returns all performance measures that should be saved as commercial metrics.
|
|
61
|
+
*/
|
|
62
|
+
get measures(): {
|
|
63
|
+
name: string;
|
|
64
|
+
duration: number;
|
|
65
|
+
}[];
|
|
66
|
+
private constructor();
|
|
67
|
+
/**
|
|
68
|
+
* Adds a non timer measurement
|
|
69
|
+
*
|
|
70
|
+
* @param {string} name - the property's name
|
|
71
|
+
* @param value - the property's value
|
|
72
|
+
*/
|
|
73
|
+
setProperty<T extends keyof EventTimerProperties>(name: T, value: EventTimerProperties[T]): void;
|
|
74
|
+
/**
|
|
75
|
+
* Creates a new performance mark, and if the mark ends with 'End' it will
|
|
76
|
+
* create a performance measure between the start and end marks.
|
|
77
|
+
*
|
|
78
|
+
* Marks can be triggered multiple times, but we only save the first
|
|
79
|
+
* instance of a mark, as things like ad refreshes can trigger the same mark.
|
|
80
|
+
*
|
|
81
|
+
* More info on the performance API:
|
|
82
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark
|
|
83
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure
|
|
84
|
+
*
|
|
85
|
+
* @todo more strict typing for eventName and origin
|
|
86
|
+
* @param eventName The short name applied to the mark
|
|
87
|
+
* @param origin - Either 'page' (default) or the name of the slot
|
|
88
|
+
*/
|
|
89
|
+
mark(eventName: string, origin?: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Creates a performance measure given the name of the end marks.
|
|
92
|
+
* The start mark is inferred from the end mark.
|
|
93
|
+
*
|
|
94
|
+
* @param endMark - The name of the mark that ends the measure
|
|
95
|
+
**/
|
|
96
|
+
private measure;
|
|
97
|
+
}
|
|
98
|
+
declare const _: {
|
|
99
|
+
slotMarks: readonly ["slotReady", "adRenderStart", "prebidStart", "adOnPage", "viewable"];
|
|
100
|
+
slotMeasures: readonly ["adRender", "defineSlot", "prepareSlot", "prebid", "fetchAd"];
|
|
101
|
+
trackedSlots: readonly ["top-above-nav", "inline1", "inline2", "fronts-banner-1", "fronts-banner-2"];
|
|
102
|
+
};
|
|
103
|
+
export { EventTimer, _, supportsPerformanceAPI };
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.supportsPerformanceAPI = exports._ = exports.EventTimer = void 0;
|
|
4
|
+
const libs_1 = require("@guardian/libs");
|
|
5
|
+
const supportsPerformanceAPI = () => typeof window !== 'undefined' &&
|
|
6
|
+
typeof window.performance !== 'undefined' &&
|
|
7
|
+
typeof window.performance.mark === 'function';
|
|
8
|
+
exports.supportsPerformanceAPI = supportsPerformanceAPI;
|
|
9
|
+
// Events will be logged using the performance API for all slots, but only these slots will be tracked as commercial metrics and sent to the data lake
|
|
10
|
+
const trackedSlots = [
|
|
11
|
+
'top-above-nav',
|
|
12
|
+
'inline1',
|
|
13
|
+
'inline2',
|
|
14
|
+
'fronts-banner-1',
|
|
15
|
+
'fronts-banner-2',
|
|
16
|
+
];
|
|
17
|
+
// marks that we want to save as commercial metrics
|
|
18
|
+
const slotMarks = [
|
|
19
|
+
'slotReady',
|
|
20
|
+
'adRenderStart',
|
|
21
|
+
'prebidStart',
|
|
22
|
+
'adOnPage',
|
|
23
|
+
'viewable',
|
|
24
|
+
];
|
|
25
|
+
// measures that we want to save as commercial metrics
|
|
26
|
+
const slotMeasures = [
|
|
27
|
+
'adRender',
|
|
28
|
+
'defineSlot',
|
|
29
|
+
'prepareSlot',
|
|
30
|
+
'prebid',
|
|
31
|
+
'fetchAd',
|
|
32
|
+
];
|
|
33
|
+
const pageMarks = ['commercialStart', 'commercialModulesLoaded'];
|
|
34
|
+
// measures that we want to save as commercial metrics
|
|
35
|
+
const pageMeasures = ['commercialBoot', 'googletagInit'];
|
|
36
|
+
// all marks, including the measure start and end marks
|
|
37
|
+
const allSlotMarks = [
|
|
38
|
+
...slotMarks,
|
|
39
|
+
...slotMeasures.map((measure) => `${measure}Start`),
|
|
40
|
+
...slotMeasures.map((measure) => `${measure}End`),
|
|
41
|
+
];
|
|
42
|
+
const externalMarks = [
|
|
43
|
+
'cmp-init',
|
|
44
|
+
'cmp-ui-displayed',
|
|
45
|
+
'cmp-got-consent',
|
|
46
|
+
];
|
|
47
|
+
const shouldSave = (name) => {
|
|
48
|
+
let [origin, type] = name.split('_');
|
|
49
|
+
if (!type) {
|
|
50
|
+
type = origin;
|
|
51
|
+
origin = 'page';
|
|
52
|
+
}
|
|
53
|
+
const shouldSaveMark = (trackedSlots.includes(origin) &&
|
|
54
|
+
slotMarks.includes(type)) ||
|
|
55
|
+
(origin === 'page' && pageMarks.includes(type));
|
|
56
|
+
const shouldSaveMeasure = (trackedSlots.includes(origin) &&
|
|
57
|
+
slotMeasures.includes(type)) ||
|
|
58
|
+
(origin === 'page' && pageMeasures.includes(type));
|
|
59
|
+
return shouldSaveMark || shouldSaveMeasure;
|
|
60
|
+
};
|
|
61
|
+
class EventTimer {
|
|
62
|
+
_marks;
|
|
63
|
+
_measures;
|
|
64
|
+
properties;
|
|
65
|
+
/**
|
|
66
|
+
* Initialise the EventTimer class on page.
|
|
67
|
+
* Returns the singleton instance of the EventTimer class and binds
|
|
68
|
+
* to window.guardian.commercialTimer. If it's been previously
|
|
69
|
+
* initialised and bound it returns the original instance
|
|
70
|
+
* Note: We save to window.guardian.commercialTimer because
|
|
71
|
+
* different bundles (DCR / DCP) can use commercial, and we want
|
|
72
|
+
* all timer events saved to a single instance per-page
|
|
73
|
+
* @returns {EventTimer} Instance of EventTimer
|
|
74
|
+
*/
|
|
75
|
+
static init() {
|
|
76
|
+
return (window.guardian.commercialTimer ??= new EventTimer());
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Just a helper method to access the singleton instance of EventTimer.
|
|
80
|
+
* Typical use case is EventTimer.get().trigger
|
|
81
|
+
*/
|
|
82
|
+
static get() {
|
|
83
|
+
return this.init();
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* These are marks that are not triggered by commercial but we are interested in
|
|
87
|
+
* tracking their performance. For example, CMP-related events.
|
|
88
|
+
**/
|
|
89
|
+
get _externalMarks() {
|
|
90
|
+
if (!supportsPerformanceAPI()) {
|
|
91
|
+
return new Map();
|
|
92
|
+
}
|
|
93
|
+
return externalMarks.reduce((map, mark) => {
|
|
94
|
+
const entries = window.performance.getEntriesByName(mark);
|
|
95
|
+
if (entries.length && entries[0]) {
|
|
96
|
+
map.set(mark, entries[0]);
|
|
97
|
+
}
|
|
98
|
+
return map;
|
|
99
|
+
}, new Map());
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Returns all performance marks that should be saved as commercial metrics.
|
|
103
|
+
*/
|
|
104
|
+
get marks() {
|
|
105
|
+
return [...this._marks, ...this._externalMarks].map(([name, timer]) => ({
|
|
106
|
+
name,
|
|
107
|
+
ts: timer.startTime,
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Returns all performance measures that should be saved as commercial metrics.
|
|
112
|
+
*/
|
|
113
|
+
get measures() {
|
|
114
|
+
return [...this._measures].map(([name, measure]) => ({
|
|
115
|
+
name,
|
|
116
|
+
duration: measure.duration,
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
constructor() {
|
|
120
|
+
this._marks = new Map();
|
|
121
|
+
this._measures = new Map();
|
|
122
|
+
this.properties = {};
|
|
123
|
+
if (window.navigator.connection) {
|
|
124
|
+
this.properties.type = window.navigator.connection.type;
|
|
125
|
+
this.properties.downlink = window.navigator.connection.downlink;
|
|
126
|
+
this.properties.effectiveType =
|
|
127
|
+
window.navigator.connection.effectiveType;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Adds a non timer measurement
|
|
132
|
+
*
|
|
133
|
+
* @param {string} name - the property's name
|
|
134
|
+
* @param value - the property's value
|
|
135
|
+
*/
|
|
136
|
+
setProperty(name, value) {
|
|
137
|
+
this.properties[name] = value;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Creates a new performance mark, and if the mark ends with 'End' it will
|
|
141
|
+
* create a performance measure between the start and end marks.
|
|
142
|
+
*
|
|
143
|
+
* Marks can be triggered multiple times, but we only save the first
|
|
144
|
+
* instance of a mark, as things like ad refreshes can trigger the same mark.
|
|
145
|
+
*
|
|
146
|
+
* More info on the performance API:
|
|
147
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Performance/mark
|
|
148
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure
|
|
149
|
+
*
|
|
150
|
+
* @todo more strict typing for eventName and origin
|
|
151
|
+
* @param eventName The short name applied to the mark
|
|
152
|
+
* @param origin - Either 'page' (default) or the name of the slot
|
|
153
|
+
*/
|
|
154
|
+
mark(eventName, origin = 'page') {
|
|
155
|
+
let name = eventName;
|
|
156
|
+
if (allSlotMarks.includes(eventName) && origin !== 'page') {
|
|
157
|
+
name = `${origin}_${name}`;
|
|
158
|
+
}
|
|
159
|
+
if (!!this._marks.get(name) || !supportsPerformanceAPI()) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const mark = window.performance.mark(name);
|
|
163
|
+
if (
|
|
164
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- browser support is patchy
|
|
165
|
+
typeof mark?.startTime === 'number' &&
|
|
166
|
+
// we only want to save the marks that are related to certain slots or the page
|
|
167
|
+
shouldSave(name)) {
|
|
168
|
+
this._marks.set(name, mark);
|
|
169
|
+
}
|
|
170
|
+
if (name.endsWith('End')) {
|
|
171
|
+
this.measure(name);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Creates a performance measure given the name of the end marks.
|
|
176
|
+
* The start mark is inferred from the end mark.
|
|
177
|
+
*
|
|
178
|
+
* @param endMark - The name of the mark that ends the measure
|
|
179
|
+
**/
|
|
180
|
+
measure(endMark) {
|
|
181
|
+
const startMark = endMark.replace('End', 'Start');
|
|
182
|
+
const measureName = endMark.replace('End', '');
|
|
183
|
+
const startMarkExists = window.performance.getEntriesByName(startMark).length > 0;
|
|
184
|
+
if (startMarkExists) {
|
|
185
|
+
try {
|
|
186
|
+
const measure = window.performance.measure(measureName, startMark, endMark);
|
|
187
|
+
// we only want to save the measures that are related to certain slots or the page
|
|
188
|
+
if (measure && shouldSave(measureName)) {
|
|
189
|
+
this._measures.set(measureName, measure);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch (e) {
|
|
193
|
+
(0, libs_1.log)('commercial', `error measuring ${measureName}`, e);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
exports.EventTimer = EventTimer;
|
|
199
|
+
const _ = {
|
|
200
|
+
slotMarks,
|
|
201
|
+
slotMeasures,
|
|
202
|
+
trackedSlots,
|
|
203
|
+
};
|
|
204
|
+
exports._ = _;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCountryCode = void 0;
|
|
4
|
+
const libs_1 = require("@guardian/libs");
|
|
5
|
+
const editionToCountryCodeMap = {
|
|
6
|
+
UK: 'GB',
|
|
7
|
+
US: 'US',
|
|
8
|
+
AU: 'AU',
|
|
9
|
+
};
|
|
10
|
+
const editionToCountryCode = (editionKey = 'UK') => editionToCountryCodeMap[editionKey];
|
|
11
|
+
const countryCookieName = 'GU_geo_country';
|
|
12
|
+
const countryOverrideName = 'gu.geo.override';
|
|
13
|
+
let locale;
|
|
14
|
+
/*
|
|
15
|
+
This method can be used as a non async way of getting the country code
|
|
16
|
+
after init has been called. Returning locale should cover all/most
|
|
17
|
+
of the cases but if a race condition happen or the cookie is not set,
|
|
18
|
+
we keep fallbacks to cookie or geo from edition.
|
|
19
|
+
*/
|
|
20
|
+
const getCountryCode = () => {
|
|
21
|
+
const pageEdition = window.guardian.config.page.edition;
|
|
22
|
+
const maybeCountryOverride = libs_1.storage.local.get(countryOverrideName);
|
|
23
|
+
const countryOverride = (0, libs_1.isString)(maybeCountryOverride)
|
|
24
|
+
? maybeCountryOverride
|
|
25
|
+
: null;
|
|
26
|
+
return (locale ??
|
|
27
|
+
countryOverride ??
|
|
28
|
+
(0, libs_1.getCookie)({
|
|
29
|
+
name: countryCookieName,
|
|
30
|
+
shouldMemoize: true,
|
|
31
|
+
}) ??
|
|
32
|
+
editionToCountryCode(pageEdition));
|
|
33
|
+
};
|
|
34
|
+
exports.getCountryCode = getCountryCode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const isInUk: () => boolean;
|
|
2
|
+
export declare const isInUsa: () => boolean;
|
|
3
|
+
export declare const isInCanada: () => boolean;
|
|
4
|
+
export declare const isInAustralia: () => boolean;
|
|
5
|
+
export declare const isInNewZealand: () => boolean;
|
|
6
|
+
export declare const isInUsOrCa: () => boolean;
|
|
7
|
+
export declare const isInAuOrNz: () => boolean;
|
|
8
|
+
export declare const isInRow: () => boolean;
|
|
9
|
+
export declare const _: {
|
|
10
|
+
resetModule: () => void;
|
|
11
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports._ = exports.isInRow = exports.isInAuOrNz = exports.isInUsOrCa = exports.isInNewZealand = exports.isInAustralia = exports.isInCanada = exports.isInUsa = exports.isInUk = void 0;
|
|
4
|
+
const country_code_1 = require("./country-code");
|
|
5
|
+
// cache the users location so we only have to look it up once
|
|
6
|
+
let geo;
|
|
7
|
+
const currentGeoLocation = () => {
|
|
8
|
+
geo = geo ?? (0, country_code_1.getCountryCode)();
|
|
9
|
+
return geo;
|
|
10
|
+
};
|
|
11
|
+
const isInUk = () => currentGeoLocation() === 'GB';
|
|
12
|
+
exports.isInUk = isInUk;
|
|
13
|
+
const isInUsa = () => currentGeoLocation() === 'US';
|
|
14
|
+
exports.isInUsa = isInUsa;
|
|
15
|
+
const isInCanada = () => currentGeoLocation() === 'CA';
|
|
16
|
+
exports.isInCanada = isInCanada;
|
|
17
|
+
const isInAustralia = () => currentGeoLocation() === 'AU';
|
|
18
|
+
exports.isInAustralia = isInAustralia;
|
|
19
|
+
const isInNewZealand = () => currentGeoLocation() === 'NZ';
|
|
20
|
+
exports.isInNewZealand = isInNewZealand;
|
|
21
|
+
const isInUsOrCa = () => (0, exports.isInUsa)() || (0, exports.isInCanada)();
|
|
22
|
+
exports.isInUsOrCa = isInUsOrCa;
|
|
23
|
+
const isInAuOrNz = () => (0, exports.isInAustralia)() || (0, exports.isInNewZealand)();
|
|
24
|
+
exports.isInAuOrNz = isInAuOrNz;
|
|
25
|
+
const isInRow = () => !(0, exports.isInUk)() && !(0, exports.isInUsOrCa)() && !(0, exports.isInAuOrNz)();
|
|
26
|
+
exports.isInRow = isInRow;
|
|
27
|
+
exports._ = {
|
|
28
|
+
resetModule: () => {
|
|
29
|
+
geo = undefined;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CountryCode } from '@guardian/libs';
|
|
2
|
+
export declare const __resetCachedValue: () => void;
|
|
3
|
+
/**
|
|
4
|
+
* Fetches the user's current location as an ISO 3166-1 alpha-2 string e.g. 'GB', 'AU' etc
|
|
5
|
+
* Note: This has been copied from guardian-libs and made syncronous by ommiting the call to
|
|
6
|
+
* the geolocation API
|
|
7
|
+
*/
|
|
8
|
+
export declare const getLocale: () => CountryCode;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getLocale = exports.__resetCachedValue = void 0;
|
|
4
|
+
const libs_1 = require("@guardian/libs");
|
|
5
|
+
const KEY = 'GU_geo_country';
|
|
6
|
+
const KEY_OVERRIDE = 'gu.geo.override';
|
|
7
|
+
const COUNTRY_REGEX = /^[A-Z]{2}$/;
|
|
8
|
+
// best guess that we have a valid code, without actually shipping the entire list
|
|
9
|
+
const isValidCountryCode = (country) => (0, libs_1.isString)(country) && COUNTRY_REGEX.test(country);
|
|
10
|
+
// we'll cache any successful lookups so we only have to do this once
|
|
11
|
+
let locale;
|
|
12
|
+
const editionToGeolocationMap = {
|
|
13
|
+
UK: 'GB',
|
|
14
|
+
US: 'US',
|
|
15
|
+
AU: 'AU',
|
|
16
|
+
};
|
|
17
|
+
const editionToGeolocation = (editionKey) => editionToGeolocationMap[editionKey];
|
|
18
|
+
// just used for tests
|
|
19
|
+
const __resetCachedValue = () => (locale = undefined);
|
|
20
|
+
exports.__resetCachedValue = __resetCachedValue;
|
|
21
|
+
/**
|
|
22
|
+
* Fetches the user's current location as an ISO 3166-1 alpha-2 string e.g. 'GB', 'AU' etc
|
|
23
|
+
* Note: This has been copied from guardian-libs and made syncronous by ommiting the call to
|
|
24
|
+
* the geolocation API
|
|
25
|
+
*/
|
|
26
|
+
const getLocale = () => {
|
|
27
|
+
if (locale)
|
|
28
|
+
return locale;
|
|
29
|
+
// return overridden geo from localStorage, used for changing geo only for development purposes
|
|
30
|
+
const geoOverride = libs_1.storage.local.get(KEY_OVERRIDE);
|
|
31
|
+
if (isValidCountryCode(geoOverride)) {
|
|
32
|
+
return (locale = geoOverride);
|
|
33
|
+
}
|
|
34
|
+
// return locale from cookie if it exists
|
|
35
|
+
const stored = (0, libs_1.getCookie)({ name: KEY });
|
|
36
|
+
if (stored && isValidCountryCode(stored)) {
|
|
37
|
+
return (locale = stored);
|
|
38
|
+
}
|
|
39
|
+
// return locale from edition
|
|
40
|
+
const editionCountryCode = editionToGeolocation(window.guardian.config.page.edition);
|
|
41
|
+
return (locale = editionCountryCode);
|
|
42
|
+
};
|
|
43
|
+
exports.getLocale = getLocale;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { EventTimer } from './event-timer';
|
|
2
|
+
import type { AdBlockers, Apstag, ArticleCounts, ComscoreGlobals, Confiant, Config, DfpEnv, FetchBidResponse, GoogleTagParams, GoogleTrackConversionObject, HeaderNotification, IasPET, NetworkInformation, NSdkInstance, Ophan, OptOutAdSlot, OptOutInitializeOptions, Permutive, SafeFrameAPI, TeadsAnalytics, Trac } from './types';
|
|
3
|
+
declare global {
|
|
4
|
+
interface Navigator {
|
|
5
|
+
readonly connection?: NetworkInformation;
|
|
6
|
+
readonly cookieDeprecationLabel?: {
|
|
7
|
+
getValue: () => Promise<string>;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
interface Window {
|
|
11
|
+
guardian: {
|
|
12
|
+
ophan?: Ophan;
|
|
13
|
+
config: Config;
|
|
14
|
+
queue: Array<() => Promise<void>>;
|
|
15
|
+
mustardCut?: boolean;
|
|
16
|
+
polyfilled?: boolean;
|
|
17
|
+
adBlockers: AdBlockers;
|
|
18
|
+
css: {
|
|
19
|
+
onLoad: () => void;
|
|
20
|
+
loaded: boolean;
|
|
21
|
+
};
|
|
22
|
+
articleCounts?: ArticleCounts;
|
|
23
|
+
commercial?: {
|
|
24
|
+
dfpEnv?: DfpEnv;
|
|
25
|
+
a9WinningBids?: FetchBidResponse[];
|
|
26
|
+
};
|
|
27
|
+
notificationEventHistory?: HeaderNotification[][];
|
|
28
|
+
commercialTimer?: EventTimer;
|
|
29
|
+
offlineCount?: number;
|
|
30
|
+
modules: {
|
|
31
|
+
sentry?: {
|
|
32
|
+
reportError?: (error: Error, feature: string, tags?: Record<string, string>, extras?: Record<string, unknown>) => void;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
ootag: {
|
|
37
|
+
queue: Array<() => void>;
|
|
38
|
+
initializeOo: (o: OptOutInitializeOptions) => void;
|
|
39
|
+
addParameter: (key: string, value: string | string[]) => void;
|
|
40
|
+
addParameterForSlot: (slotId: string, key: string, value: string | string[]) => void;
|
|
41
|
+
defineSlot: (o: OptOutAdSlot) => void;
|
|
42
|
+
makeRequests: () => void;
|
|
43
|
+
refreshSlot: (slotId: string) => void;
|
|
44
|
+
refreshAllSlots: () => void;
|
|
45
|
+
logger: (...args: unknown[]) => void;
|
|
46
|
+
};
|
|
47
|
+
readonly navigator: Navigator;
|
|
48
|
+
confiant?: Confiant;
|
|
49
|
+
apstag?: Apstag;
|
|
50
|
+
permutive?: Permutive;
|
|
51
|
+
_comscore?: ComscoreGlobals[];
|
|
52
|
+
__iasPET?: IasPET;
|
|
53
|
+
teads_analytics?: TeadsAnalytics;
|
|
54
|
+
$sf: SafeFrameAPI;
|
|
55
|
+
conf: unknown;
|
|
56
|
+
NOLCMB: {
|
|
57
|
+
getInstance: (apid: string) => NSdkInstance;
|
|
58
|
+
};
|
|
59
|
+
nol_t: (pvar: {
|
|
60
|
+
cid: string;
|
|
61
|
+
content: string;
|
|
62
|
+
server: string;
|
|
63
|
+
}) => Trac;
|
|
64
|
+
google_trackConversion?: (arg0: GoogleTrackConversionObject) => void;
|
|
65
|
+
google_tag_params?: GoogleTagParams;
|
|
66
|
+
_brandmetrics?: Array<{
|
|
67
|
+
cmd: string;
|
|
68
|
+
val: Record<string, unknown>;
|
|
69
|
+
}>;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { isAdBlockInUse } from './detect-ad-blocker';
|
|
2
|
+
export { EventTimer } from './event-timer';
|
|
3
|
+
export { adSizes } from './ad-sizes';
|
|
4
|
+
export * as constants from './constants';
|
|
5
|
+
export { bypassCommercialMetricsSampling, initCommercialMetrics, } from './send-commercial-metrics';
|
|
6
|
+
export { buildPageTargeting } from './targeting/build-page-targeting';
|
|
7
|
+
export { postMessage } from './messenger/post-message';
|
|
8
|
+
export { buildImaAdTagUrl } from './targeting/youtube-ima';
|
|
9
|
+
export { getPermutivePFPSegments } from './permutive';
|
|
10
|
+
export { isEligibleForTeads } from './targeting/teads-eligibility';
|
|
11
|
+
export type { AdSize, SizeMapping, SlotName } from './ad-sizes';
|
|
12
|
+
export type { PageTargeting } from './targeting/build-page-targeting';
|
|
13
|
+
export type { AdsConfigDisabled, AdsConfigUSNATorAus, AdsConfigTCFV2, } from './types';
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.isEligibleForTeads = exports.getPermutivePFPSegments = exports.buildImaAdTagUrl = exports.buildPageTargeting = exports.initCommercialMetrics = exports.bypassCommercialMetricsSampling = exports.constants = exports.adSizes = exports.EventTimer = exports.isAdBlockInUse = void 0;
|
|
27
|
+
var detect_ad_blocker_1 = require("./detect-ad-blocker");
|
|
28
|
+
Object.defineProperty(exports, "isAdBlockInUse", { enumerable: true, get: function () { return detect_ad_blocker_1.isAdBlockInUse; } });
|
|
29
|
+
var event_timer_1 = require("./event-timer");
|
|
30
|
+
Object.defineProperty(exports, "EventTimer", { enumerable: true, get: function () { return event_timer_1.EventTimer; } });
|
|
31
|
+
var ad_sizes_1 = require("./ad-sizes");
|
|
32
|
+
Object.defineProperty(exports, "adSizes", { enumerable: true, get: function () { return ad_sizes_1.adSizes; } });
|
|
33
|
+
exports.constants = __importStar(require("./constants"));
|
|
34
|
+
var send_commercial_metrics_1 = require("./send-commercial-metrics");
|
|
35
|
+
Object.defineProperty(exports, "bypassCommercialMetricsSampling", { enumerable: true, get: function () { return send_commercial_metrics_1.bypassCommercialMetricsSampling; } });
|
|
36
|
+
Object.defineProperty(exports, "initCommercialMetrics", { enumerable: true, get: function () { return send_commercial_metrics_1.initCommercialMetrics; } });
|
|
37
|
+
var build_page_targeting_1 = require("./targeting/build-page-targeting");
|
|
38
|
+
Object.defineProperty(exports, "buildPageTargeting", { enumerable: true, get: function () { return build_page_targeting_1.buildPageTargeting; } });
|
|
39
|
+
var post_message_1 = require("./messenger/post-message");
|
|
40
|
+
Object.defineProperty(exports, "postMessage", { enumerable: true, get: function () { return post_message_1.postMessage; } });
|
|
41
|
+
var youtube_ima_1 = require("./targeting/youtube-ima");
|
|
42
|
+
Object.defineProperty(exports, "buildImaAdTagUrl", { enumerable: true, get: function () { return youtube_ima_1.buildImaAdTagUrl; } });
|
|
43
|
+
var permutive_1 = require("./permutive");
|
|
44
|
+
Object.defineProperty(exports, "getPermutivePFPSegments", { enumerable: true, get: function () { return permutive_1.getPermutivePFPSegments; } });
|
|
45
|
+
var teads_eligibility_1 = require("./targeting/teads-eligibility");
|
|
46
|
+
Object.defineProperty(exports, "isEligibleForTeads", { enumerable: true, get: function () { return teads_eligibility_1.isEligibleForTeads; } });
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const postMessage: (message: Record<string, unknown>, target: MessageEventSource, targetOrigin?: string) => void;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postMessage = void 0;
|
|
4
|
+
const postMessage = (message, target, targetOrigin = '*') => {
|
|
5
|
+
target.postMessage(JSON.stringify(message), { targetOrigin });
|
|
6
|
+
};
|
|
7
|
+
exports.postMessage = postMessage;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare const getPermutiveSegments: () => string[];
|
|
2
|
+
declare const getPermutivePFPSegments: () => string[];
|
|
3
|
+
declare const clearPermutiveSegments: () => void;
|
|
4
|
+
export declare const _: {
|
|
5
|
+
PERMUTIVE_KEY: string;
|
|
6
|
+
PERMUTIVE_PFP_KEY: string;
|
|
7
|
+
getSegments: (key: string) => string[];
|
|
8
|
+
};
|
|
9
|
+
export { getPermutiveSegments, getPermutivePFPSegments, clearPermutiveSegments, };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clearPermutiveSegments = exports.getPermutivePFPSegments = exports.getPermutiveSegments = exports._ = void 0;
|
|
4
|
+
const libs_1 = require("@guardian/libs");
|
|
5
|
+
const PERMUTIVE_KEY = `_papns`;
|
|
6
|
+
const PERMUTIVE_PFP_KEY = `_pdfps`;
|
|
7
|
+
const getSegments = (key) => {
|
|
8
|
+
try {
|
|
9
|
+
const rawSegments = libs_1.storage.local.getRaw(key);
|
|
10
|
+
const segments = rawSegments
|
|
11
|
+
? JSON.parse(rawSegments)
|
|
12
|
+
: null;
|
|
13
|
+
if (!Array.isArray(segments))
|
|
14
|
+
return [];
|
|
15
|
+
return segments
|
|
16
|
+
.slice(0, 250)
|
|
17
|
+
.map((s) => Number.parseInt(s, 10))
|
|
18
|
+
.filter((n) => typeof n === 'number' && !Number.isNaN(n))
|
|
19
|
+
.map(String);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const getPermutiveSegments = () => getSegments(PERMUTIVE_KEY);
|
|
26
|
+
exports.getPermutiveSegments = getPermutiveSegments;
|
|
27
|
+
const getPermutivePFPSegments = () => getSegments(PERMUTIVE_PFP_KEY);
|
|
28
|
+
exports.getPermutivePFPSegments = getPermutivePFPSegments;
|
|
29
|
+
const clearPermutiveSegments = () => {
|
|
30
|
+
libs_1.storage.local.remove(PERMUTIVE_KEY);
|
|
31
|
+
libs_1.storage.local.remove(PERMUTIVE_PFP_KEY);
|
|
32
|
+
};
|
|
33
|
+
exports.clearPermutiveSegments = clearPermutiveSegments;
|
|
34
|
+
exports._ = {
|
|
35
|
+
PERMUTIVE_KEY,
|
|
36
|
+
PERMUTIVE_PFP_KEY,
|
|
37
|
+
getSegments,
|
|
38
|
+
};
|