@codecademy/tracking 1.2.0-alpha.ec7903070d.0 → 2.0.0-alpha.4e24057d69.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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@codecademy/tracking",
3
3
  "description": "Tracking library for Codecademy",
4
- "version": "1.2.0-alpha.ec7903070d.0",
4
+ "version": "2.0.0-alpha.4e24057d69.0",
5
5
  "author": "Codecademy Engineering <dev@codecademy.com>",
6
6
  "dependencies": {
7
7
  "@qwik.dev/partytown": "0.11.0"
@@ -1,3 +0,0 @@
1
- export * from './track';
2
- export * from './user';
3
- export * from './types';
@@ -1,3 +0,0 @@
1
- export * from './track';
2
- export * from './user';
3
- export * from './types';
@@ -1,12 +0,0 @@
1
- import type { BaseEventData, EventDataTypes, TrackingOptions, UserClickData, UserImpressionData, UserVisitData } from './types';
2
- export type TrackerOptions = {
3
- apiBaseUrl: string;
4
- verbose?: boolean;
5
- };
6
- export declare const createTracker: ({ apiBaseUrl, verbose }: TrackerOptions) => {
7
- event: <Category extends keyof EventDataTypes, Event extends string & keyof EventDataTypes[Category], Data extends EventDataTypes[Category][Event] & BaseEventData>(category: Category, event: Event, userData: Data, options?: TrackingOptions) => void;
8
- click: (data: UserClickData) => void;
9
- impression: (data: UserImpressionData) => void;
10
- visit: (data: UserVisitData) => void;
11
- pushDataLayerEvent: (eventName: string) => void;
12
- };
@@ -1,119 +0,0 @@
1
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
2
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
3
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
4
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
5
- function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
6
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
7
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
9
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
10
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
11
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
12
- import { getClientType } from '../integrations/device';
13
- const browserSupportsKeepalive = () => 'keepalive' in window.Request.prototype;
14
- export const createTracker = _ref => {
15
- let apiBaseUrl = _ref.apiBaseUrl,
16
- verbose = _ref.verbose;
17
- const beacon = (endpoint, data) => {
18
- const _URL = new URL(apiBaseUrl),
19
- origin = _URL.origin;
20
- const uri = new URL(endpoint, origin).toString();
21
- const form = new FormData();
22
- for (const _ref2 of Object.entries(data)) {
23
- var _ref3 = _slicedToArray(_ref2, 2);
24
- const k = _ref3[0];
25
- const v = _ref3[1];
26
- form.append(k, v.toString());
27
- }
28
- try {
29
- // Firefox allows users to disable navigator.sendBeacon, and very old Safari versions don't have it.
30
- // [WEB-1700]: Additionally, Chrome 79-80 gives "Illegal invocation" with ?., so through 2022 we should support them.
31
- // It seems similar to this: https://github.com/vercel/next.js/issues/23856
32
- if (navigator.sendBeacon && navigator.sendBeacon(uri, form)) {
33
- return;
34
- }
35
- } catch (_unused) {
36
- // Even with the proper scoping, Chrome 79-80 still gives "Illegal invocation" crashes. Sigh.
37
- }
38
-
39
- // Either way, we fall back to standard fetch if sendBeacon fails.
40
- // We don't mind this rejecting with an error because it's tracking, and we'll know if that starts to fail.
41
- window.fetch(uri, _objectSpread({
42
- method: 'POST',
43
- body: form
44
- }, browserSupportsKeepalive() && {
45
- keepalive: true
46
- }));
47
- };
48
- const serverSideBeacon = (endpoint, data) => {
49
- const _URL2 = new URL(apiBaseUrl),
50
- origin = _URL2.origin;
51
- const uri = new URL(endpoint, origin).toString();
52
- const form = new URLSearchParams();
53
- for (const _ref4 of Object.entries(data)) {
54
- var _ref5 = _slicedToArray(_ref4, 2);
55
- const k = _ref5[0];
56
- const v = _ref5[1];
57
- form.append(k, v.toString());
58
- }
59
- fetch(uri, {
60
- method: 'POST',
61
- body: form
62
- });
63
- };
64
- const event = function (category, event, userData) {
65
- let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
66
- // support server-side-only as well as client-side events
67
- const properties = typeof window !== 'undefined' ? _objectSpread(_objectSpread({}, userData), {}, {
68
- fullpath: window.location.pathname + window.location.search,
69
- search: window.location.search,
70
- path: window.location.pathname,
71
- title: window.document.title,
72
- url: window.location.href,
73
- referrer: userData.referrer || window.document.referrer,
74
- client: getClientType()
75
- }) : userData;
76
- if (verbose) {
77
- console.groupCollapsed("%cTracking Event Fired: ".concat(category, ":").concat(event), 'color: #4b35ef; font-style: italic;');
78
- console.log({
79
- category,
80
- event,
81
- properties: JSON.parse(JSON.stringify(properties))
82
- });
83
- console.groupEnd();
84
- }
85
-
86
- // Use /analytics path if path is not already specified in apiBaseUrl
87
- const _URL3 = new URL(apiBaseUrl),
88
- pathname = _URL3.pathname;
89
- const basePath = pathname === '/' ? '/analytics' : pathname;
90
- if (typeof window !== 'undefined') {
91
- // This allows the UTM query params to get registered in the user session.
92
- const queryParams = window.location.search;
93
- beacon("".concat(basePath, "/").concat(category).concat(queryParams), {
94
- category,
95
- event,
96
- properties: JSON.stringify(properties),
97
- gdpr_safe: "".concat(options.gdprSafe)
98
- });
99
- } else {
100
- serverSideBeacon("".concat(basePath, "/").concat(category), {
101
- category,
102
- event,
103
- properties: JSON.stringify(properties)
104
- });
105
- }
106
- };
107
- return {
108
- event,
109
- click: data => event('user', 'click', data),
110
- impression: data => event('user', 'impression', data),
111
- visit: data => event('user', 'visit', data),
112
- pushDataLayerEvent: eventName => {
113
- var _ref6;
114
- ((_ref6 = window).dataLayer || (_ref6.dataLayer = [])).push({
115
- event: eventName
116
- });
117
- }
118
- };
119
- };
@@ -1,264 +0,0 @@
1
- /**
2
- * The Data types for all of our events.
3
- * Follows the format EventDataTypes[Category].[Event].EventData
4
- * Category + Event gives the corresponding event table in redshift
5
- */
6
- export type EventDataTypes = {
7
- user: {
8
- click: UserClickData;
9
- visit: UserVisitData;
10
- impression: UserImpressionData;
11
- email_trigger: BaseEventAnyData;
12
- content_completed: BaseEventAnyData;
13
- submit: BaseEventAnyData;
14
- workspace_init: BaseEventAnyData;
15
- meaningful_content_loaded: BaseEventAnyData;
16
- practice_completed: BaseEventAnyData;
17
- };
18
- ad: {
19
- click: BaseEventAnyData;
20
- impression: BaseEventAnyData;
21
- };
22
- calendar: {
23
- reminder: BaseEventAnyData;
24
- };
25
- notification: {
26
- clicked: BaseEventAnyData;
27
- ion: BaseEventAnyData;
28
- };
29
- form: {
30
- submit: BaseEventAnyData;
31
- };
32
- sorting_quiz: {
33
- result: BaseEventAnyData;
34
- impression: BaseEventAnyData;
35
- answer: EventAnswerData;
36
- };
37
- onboarding_survey: {
38
- answer: BaseEventAnyData;
39
- recommendation: BaseEventAnyData;
40
- submission_recommendation: BaseEventAnyData;
41
- user_selected_recommendation: BaseEventAnyData;
42
- };
43
- exercise: {
44
- force_pass: BaseEventAnyData;
45
- };
46
- experiment: {
47
- contentful_experiment_assignment_event: BaseEventAnyData;
48
- };
49
- payments: {
50
- cancel_survey: BaseEventAnyData;
51
- extend_trial_survey: BaseEventAnyData;
52
- };
53
- search: {
54
- visit: BaseEventAnyData;
55
- click: BaseEventAnyData;
56
- query: BaseEventAnyData;
57
- result: BaseEventAnyData;
58
- };
59
- page: {
60
- career_path_visited: PagePathVisitedData;
61
- skill_path_visited: PagePathVisitedData;
62
- course_page_visited: CoursePageVisitedData;
63
- };
64
- business: {
65
- filter_event: BusinessFilterData;
66
- search_event: BusinessSearchData;
67
- };
68
- gpt_plugin: {
69
- search: ChatGPTPluginSearchEventData;
70
- };
71
- };
72
- /**
73
- * Base event data shared by all events
74
- */
75
- export type BaseEventData = {
76
- fullpath?: null;
77
- search?: null;
78
- path?: null;
79
- title?: null;
80
- url?: null;
81
- referrer?: string | null;
82
- id?: null;
83
- };
84
- /**
85
- * Generic type to use for event data not typed yet
86
- */
87
- export type BaseEventAnyData = BaseEventData & {
88
- [key: string]: any;
89
- };
90
- /**
91
- * Options to pass to the tracking function
92
- */
93
- export type TrackingOptions = {
94
- /** tells backend not to merge user-identifying data onto the event payload */
95
- gdprSafe?: boolean;
96
- };
97
- /**
98
- * The Content IDs related to the current event, to help build the content context of the event.
99
- * These IDs get hashed into a single value and overwrite content_id before they are sent to
100
- * redshift in lib/content_group_id.rb
101
- */
102
- export type TrackingContentIds = {
103
- assessment_id?: string;
104
- content_item_id?: string;
105
- exercise_id?: string;
106
- learning_standard_id?: string;
107
- module_id?: string;
108
- path_id?: string;
109
- program_id?: string;
110
- program_unit_id?: string;
111
- review_card_id?: string;
112
- skill_benchmark_id?: string;
113
- track_id?: string;
114
- journey_id?: string;
115
- external_course_id?: string;
116
- external_path_id?: string;
117
- lo_id?: string;
118
- };
119
- /**
120
- * Shared data relevant for all user events
121
- */
122
- export type UserSharedData = BaseEventData & {
123
- /** the click target of the event */
124
- target?: string;
125
- /** the page the event is coming from */
126
- page_name?: string;
127
- /** a context id for the event, for events that occur in more than one place */
128
- context?: string;
129
- /** the link being clicked on */
130
- href?: string;
131
- /** a version id for the element (ex. different version ids for redesigns) */
132
- version?: string;
133
- /** an object of content ids related to this event */
134
- content_ids?: TrackingContentIds;
135
- /** the repo that this event is being fired from */
136
- source_codebase?: string;
137
- /** Should be used for arbitrary JSON that has been passed through JSON.stringify. */
138
- misc?: string;
139
- };
140
- /**
141
- * Data sent to user click event table
142
- * NOTE: avoid adding additional properties to these objects
143
- * Instead, reuse existing properties, or make any additional properties generic so that they can be reused.
144
- * https://www.notion.so/codecademy/Guide-to-Event-Tracking-Schema-5d40b09a297743f7a30a2690208194c8#800bbf6cdf2e44de9823cd75bcc574e5
145
- */
146
- export type UserClickData = UserSharedData & {
147
- target: string;
148
- id?: string;
149
- distinct_id?: string;
150
- content_id?: string;
151
- slug?: string;
152
- name?: string;
153
- action?: string;
154
- type?: string;
155
- location?: string;
156
- element?: string;
157
- weekly_goal?: string | number;
158
- complete?: string;
159
- video_url?: string;
160
- path_id?: string;
161
- path_slug?: string;
162
- event_name?: string;
163
- onboarding_entrypoint?: string;
164
- content_slug?: string;
165
- module_id?: string;
166
- track_slug?: string;
167
- module_slug?: string;
168
- button?: string;
169
- current_challenge_day?: string | number;
170
- track_id?: string;
171
- course?: string;
172
- path_name?: string;
173
- event_id?: string;
174
- unit?: string;
175
- lesson?: string;
176
- community_prompt?: string;
177
- contentItem?: any;
178
- unit_slug?: string;
179
- course_slug?: string;
180
- course_progress?: number;
181
- assessment_id?: string;
182
- container_slugs?: string[];
183
- search_id?: string;
184
- business_user?: BaseEventAnyData;
185
- };
186
- /**
187
- * Data sent to user visit event table
188
- * NOTE: avoid adding additional properties to these objects
189
- * Instead, reuse existing properties, or make any additional properties generic so that they can be reused.
190
- * https://www.notion.so/codecademy/Guide-to-Event-Tracking-Schema-5d40b09a297743f7a30a2690208194c8#800bbf6cdf2e44de9823cd75bcc574e5
191
- */
192
- export type UserVisitData = UserSharedData & {
193
- page_name: string;
194
- category?: string;
195
- distinct_id?: string;
196
- type?: string;
197
- target?: string;
198
- section?: string;
199
- plan?: string;
200
- path_id?: string;
201
- post?: string;
202
- story_type?: string;
203
- path_title?: string;
204
- onboarding_entrypoint?: string;
205
- course_slug?: string;
206
- course?: string;
207
- interstitial_name?: string;
208
- content_id?: string;
209
- story_slug?: string;
210
- unit?: string;
211
- lesson?: string;
212
- };
213
- export type UserImpressionData = Pick<UserSharedData, 'context' | 'source_codebase' | 'content_ids' | 'misc'> & {
214
- page_name: string;
215
- target: string;
216
- slug?: string;
217
- };
218
- export type EventAnswerData = BaseEventData & {
219
- question_index: number;
220
- answer_index: number;
221
- answer: any;
222
- answer_slug: string;
223
- };
224
- export type User = {
225
- id?: string;
226
- auth_token: string;
227
- profile_image_url?: string;
228
- email?: string;
229
- is_pro?: boolean;
230
- username?: string;
231
- location: {
232
- in_eu: boolean;
233
- geo_country: string;
234
- };
235
- features: string[];
236
- };
237
- export type UseUserResponse = {
238
- user?: User;
239
- status: string;
240
- };
241
- export type PagePathVisitedData = BaseEventData & {
242
- path_id: string;
243
- path_full_title: string;
244
- };
245
- export type CoursePageVisitedData = BaseEventData & {
246
- course_id: string;
247
- course_full_title: string;
248
- };
249
- export type FilterType = string | string[] | number | boolean;
250
- export type BusinessFilterData = BaseEventData & {
251
- filter_key: string;
252
- filter_value: FilterType;
253
- };
254
- export type BusinessSearchData = BaseEventData & {
255
- search_query: string;
256
- };
257
- export declare enum ChatGPTSearchResource {
258
- CATALOG = "catalog",
259
- LITERATURE = "literature"
260
- }
261
- export type ChatGPTPluginSearchEventData = {
262
- resource: ChatGPTSearchResource;
263
- query: string;
264
- };
@@ -1,49 +0,0 @@
1
- /**
2
- * The Data types for all of our events.
3
- * Follows the format EventDataTypes[Category].[Event].EventData
4
- * Category + Event gives the corresponding event table in redshift
5
- */
6
-
7
- /**
8
- * Base event data shared by all events
9
- */
10
-
11
- /**
12
- * Generic type to use for event data not typed yet
13
- */
14
-
15
- /**
16
- * Options to pass to the tracking function
17
- */
18
-
19
- /**
20
- * The Content IDs related to the current event, to help build the content context of the event.
21
- * These IDs get hashed into a single value and overwrite content_id before they are sent to
22
- * redshift in lib/content_group_id.rb
23
- */
24
-
25
- /**
26
- * Shared data relevant for all user events
27
- */
28
-
29
- /**
30
- * Data sent to user click event table
31
- * NOTE: avoid adding additional properties to these objects
32
- * Instead, reuse existing properties, or make any additional properties generic so that they can be reused.
33
- * https://www.notion.so/codecademy/Guide-to-Event-Tracking-Schema-5d40b09a297743f7a30a2690208194c8#800bbf6cdf2e44de9823cd75bcc574e5
34
- */
35
-
36
- /**
37
- * Data sent to user visit event table
38
- * NOTE: avoid adding additional properties to these objects
39
- * Instead, reuse existing properties, or make any additional properties generic so that they can be reused.
40
- * https://www.notion.so/codecademy/Guide-to-Event-Tracking-Schema-5d40b09a297743f7a30a2690208194c8#800bbf6cdf2e44de9823cd75bcc574e5
41
- */
42
-
43
- export let ChatGPTSearchResource = /*#__PURE__*/function (ChatGPTSearchResource) {
44
- ChatGPTSearchResource["CATALOG"] = "catalog";
45
- ChatGPTSearchResource["LITERATURE"] = "literature";
46
- return ChatGPTSearchResource;
47
- }({});
48
-
49
- // does not extend base event (all client side fields there)
@@ -1,2 +0,0 @@
1
- import { User } from './types';
2
- export declare const fetchUser: (apiBaseUrl: string) => Promise<User>;
@@ -1,11 +0,0 @@
1
- export const fetchUser = async apiBaseUrl => {
2
- const response = await fetch("".concat(apiBaseUrl, "/users/web"), {
3
- method: 'GET',
4
- headers: {
5
- 'Content-type': 'application/json',
6
- Accept: 'application/json'
7
- },
8
- credentials: 'include'
9
- });
10
- return response.json();
11
- };
package/dist/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './integrations';
2
- export type { TrackingWindow } from './integrations/types';
3
- export * from './events';
package/dist/index.js DELETED
@@ -1,3 +0,0 @@
1
- export * from './integrations';
2
- export * from './events';
3
- export {};
@@ -1,9 +0,0 @@
1
- /**
2
- * @see https://www.notion.so/codecademy/GDPR-Compliance-141ebcc7ffa542daa0da56e35f482b41
3
- */
4
- export declare enum Consent {
5
- Functional = "C0003",
6
- Performance = "C0002",
7
- StrictlyNecessary = "C0001",
8
- Targeting = "C0004"
9
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * @see https://www.notion.so/codecademy/GDPR-Compliance-141ebcc7ffa542daa0da56e35f482b41
3
- */
4
- export let Consent = /*#__PURE__*/function (Consent) {
5
- Consent["Functional"] = "C0003";
6
- Consent["Performance"] = "C0002";
7
- Consent["StrictlyNecessary"] = "C0001";
8
- Consent["Targeting"] = "C0004";
9
- return Consent;
10
- }({});
@@ -1,13 +0,0 @@
1
- /**
2
- * @returns Whether the site is running both in ChromeOS and in PWA mode.
3
- */
4
- export declare const isChromeOSPWA: () => boolean;
5
- /**
6
- * @returns Whether the site is running in ChromeOS
7
- */
8
- export declare const isChromeOS: () => boolean;
9
- export declare enum ClientTypes {
10
- PWA = "pwa",
11
- Default = "default"
12
- }
13
- export declare const getClientType: () => ClientTypes;
@@ -1,19 +0,0 @@
1
- /**
2
- * @returns Whether the site is running both in ChromeOS and in PWA mode.
3
- */
4
- export const isChromeOSPWA = () => isChromeOS() && 'getDigitalGoodsService' in window &&
5
- // https://stackoverflow.com/questions/41742390/javascript-to-check-if-pwa-or-mobile-web
6
- window.matchMedia('(display-mode: standalone)').matches;
7
-
8
- /**
9
- * @returns Whether the site is running in ChromeOS
10
- */
11
- export const isChromeOS = () => typeof navigator !== 'undefined' &&
12
- // https://stackoverflow.com/questions/29657165/detecting-chrome-os-with-javascript
13
- /\bCrOS\b/.test(navigator.userAgent);
14
- export let ClientTypes = /*#__PURE__*/function (ClientTypes) {
15
- ClientTypes["PWA"] = "pwa";
16
- ClientTypes["Default"] = "default";
17
- return ClientTypes;
18
- }({});
19
- export const getClientType = () => isChromeOSPWA() ? ClientTypes.PWA : ClientTypes.Default;
@@ -1 +0,0 @@
1
- export declare const initializeFides: () => Promise<void>;
@@ -1,54 +0,0 @@
1
- import { theme } from '@codecademy/gamut-styles';
2
- /**
3
- * Fides property ID for `www.codecademy.com`.
4
- */
5
-
6
- const PROPERTY_ID = 'FDS-3RC5S1';
7
- const ot_fides_mapping = encodeURIComponent(JSON.stringify({
8
- C0001: ['essential'],
9
- C0002: ['analytics'],
10
- C0003: ['functional'],
11
- C0004: ['marketing']
12
- }));
13
- const importFides = async () => {
14
- var _win$define;
15
- const win = window;
16
- // Disable AMD globals for the Fides script
17
- const oldAmd = (_win$define = win.define) === null || _win$define === void 0 ? void 0 : _win$define.amd;
18
- if (oldAmd) {
19
- win.define.amd = undefined;
20
- }
21
- // Fides gets stored on the window object
22
- await import(/* webpackIgnore: true */"https://skillsoft-codecademy.fides-cdn.ethyca.com/fides.js?property_id=".concat(PROPERTY_ID, "&ot_fides_mapping=").concat(ot_fides_mapping));
23
- if (oldAmd) {
24
- win.define.amd = oldAmd;
25
- }
26
- if (!win.Fides) {
27
- throw new Error('Failed to import Fides');
28
- }
29
- return win.Fides;
30
- };
31
- export const initializeFides = async () => {
32
- try {
33
- const fides = await importFides();
34
- fides.gtm();
35
- const unsubscribe = fides.onFidesEvent('FidesUIShown', detail => {
36
- if (detail.extraDetails.servingComponent === 'banner') {
37
- const banner = document.getElementById('fides-banner');
38
- if (banner) {
39
- banner.setAttribute('tabIndex', '-1');
40
- }
41
- }
42
- unsubscribe();
43
- });
44
- } catch (err) {
45
- console.error('Error initializing Fides', err);
46
- }
47
- const style = document.createElement('style');
48
- style.textContent = rawStyles;
49
- document.body.appendChild(style);
50
- };
51
-
52
- // For now, these three values duplicate theme colors from gamut-styles
53
- // We don't want to take a full dependency on that package here...
54
- const rawStyles = "\n:root {\n /* Colors */\n\n --fides-overlay-primary-color: ".concat(theme.colors.hyper, ";\n --fides-overlay-body-font-color: #484848;\n\n /* Buttons */\n\n --fides-overlay-primary-button-background-hover-color: ").concat(theme.colors.hyper, ";\n\n /* Toggles */\n --fides-overlay-primary-active-color: var(--fides-overlay-primary-color);\n --fides-overlay-primary-active-disabled-color: #bda4f7;\n --fides-overlay-inactive-color: #cbd5e0;\n --fides-overlay-disabled-color: #e1e7ee;\n\n /* Everything else */\n --fides-overlay-button-border-radius: ").concat(theme.borderRadii.md, ";\n --fides-overlay-font-family: inherit;\n --fides-overlay-font-size-body: 0.875rem !important;\n --fides-overlay-line-height: 1.375rem !important;\n --fides-overlay-padding: padding: 1rem !important;\n --fides-overlay-padding: 0.875rem 1rem !important;\n}\n\n.fides-banner, .fides-modal-container {\n -webkit-font-smoothing: auto;\n}\n\ndiv#fides-overlay {\n font-size: var(--fides-overlay-font-size-body);\n line-height: var(--fides-overlay-line-height);\n z-index: 1000;\n position: fixed;\n white-space: pre-line;\n font-family: inherit;\n line-height: calc(1em + 0.4rem);\n -webkit-font-smoothing: auto;\n z-index: 9948031 !important\n}\n\n#fides-modal-link {\n cursor: pointer;\n display: none;\n}\n\n#fides-modal .fides-notice-toggle-title:hover {\n background-color: ").concat(theme.colors.white, " !important\n}\n\n#fides-modal .fides-modal-content {\n background-color: ").concat(theme.colors.white, " !important;\n border:0;\n font-size: 14px;\n line-height: 1.4;\n}\n\n.fides-modal-description a:focus {\n outline: 1px solid ").concat(theme.colors.black, " !important;\n}\n\n.fides-notice-toggle-title a:focus {\n outline: 1px solid ").concat(theme.colors.black, " !important;\n}\n\n#fides-modal .fides-notice-toggle, #fides-modal fides-notice-toggle-expanded {\n background-color: ").concat(theme.colors.white, " !important;\n}\n\n#fides-modal .fides-banner-button-secondary.fides-save-button {\n color: var(--fides-overlay-primary-button-background-color) !important;\n}\n\n#fides-modal .fides-modal-footer {\n background-color: ").concat(theme.colors.white, "\n}\n\n#fides-modal .fides-toggle-display {\n color: transparent;\n padding: 0;\n padding-block: 2px;\n --offset: 0.2em !important;\n --diameter: 1.2em !important;\n background-color: #828285\n}\n\n.fides-toggle .fides-toggle-input:checked + .fides-toggle-display {\n background-color: var(--fides-overlay-primary-active-color) !important;\n}\n\n#fides-modal .fides-divider {\n display: none !important\n}\n\n#fides-modal .fides-modal-title {\n text-align: left !important;\n font-size: 20px !important;\n}\n\ndiv#fides-banner-container {\n bottom: 0 !important;\n left: 0 !important;\n}\n\ndiv#fides-banner-container button.fides-banner-button {\n font-size: 16px !important;\n}\n\ndiv#fides-banner {\n line-height: var(--fides-overlay-line-height);\n color: var(--fides-overlay-body-font-color) !important;\n width: 100% !important;\n overflow-y: hidden;\n border: 0 !important;\n box-shadow: 0 0 18px rgba(0, 0, 0, 0.2) !important;\n background-color: ").concat(theme.colors.white, ";\n -webkit-font-smoothing: auto;\n bottom: 1px;\n}\n\ndiv#fides-banner:focus {\n outline: 1px solid ").concat(theme.colors.black, " !important\n}\n\ndiv#fides-banner-inner {\n display: flex;\n flex-direction: column;\n align-items: center;\n max-width: 1436px;\n margin: 0 auto;\n row-gap: 16px;\n row-gap: unset !important\n}\n\n/* Responsive banner */\n\ndiv#fides-banner-description {\n margin-top: 0;\n margin-bottom: 10px;\n}\n\ndiv#fides-banner-description span {\n line-height: 1.375rem !important;\n}\n\ndiv#fides-banner-description > div {\n text-align: center;\n}\n\ndiv#fides-banner-description > div a {\n font-weight: bold;\n}\n\ndiv#fides-button-group {\n justify-content: center;\n gap: 2em;\n background-color: transparent;\n}\n\n#fides-banner div#fides-button-group {\n margin-top: 0.5em;\n display: flex;\n display: flex;\n justify-content: center;\n background-color: transparent;\n gap: 16px !important;\n}\n\ndiv#fides-button-group .fides-banner-secondary-actions > button {\n cursor: pointer;\n text-decoration: none;\n font-weight: bold;\n padding: 10px 16px !important\n padding-top: 3px !important;\n margin-top: 0;\n border: 1px solid var(--fides-overlay-primary-color);\n border-radius: 2px;\n box-sizing: border-box;\n}\n\n#fides-banner .fides-acknowledge-button, #fides-banner .fides-manage-preferences-button {\n margin-right: 0px !important;\n}\n\n.fides-modal-footer div#fides-button-group {\n width: 100% !important\n}\n\n#fides-modal .fides-modal-button-group.fides-modal-primary-actions {\n margin-left: 0 !important;\n}\n\n.fides-gpc-label {\n display: none !important;\n}\n\nbutton.fides-banner-button.fides-banner-button-tertiary {\n background: none;\n border: none;\n padding: 0;\n color: var(--fides-overlay-link-font-color);\n text-decoration: underline;\n cursor: pointer;\n line-height: 2em;\n}\n\n/** Modal */\n\ndiv.fides-modal-content {\n line-height: var(--fides-overlay-line-height);\n color: var(--fides-overlay-body-font-color) !important;\n box-sizing: border-box;\n padding: var(--fides-overlay-padding);\n border: 1px solid var(--fides-overlay-primary-color);\n background-color: var(--fides-overlay-background-color);\n border-radius: var(--fides-overlay-component-border-radius);\n max-height: 100%;\n max-width: 100%;\n overflow-y: scroll;\n z-index: 2;\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n.fides-toggle .fides-toggle-display {\n --offset: 0.1em;\n --diameter: 1em;\n /** Because we have a \"hidden\" attr on this toggle element, some CSS libs customers use may include a global display: none on the hidden attr. To prevent our toggles from being hidden we use !important here **/\n display: inline-flex !important;\n align-items: center;\n justify-content: space-around;\n width: calc(var(--diameter) * 2 + var(--offset) * 2);\n height: calc(var(--diameter) + var(--offset) * 2);\n box-sizing: content-box;\n position: relative;\n border-radius: 100vw;\n background-color: var(--fides-overlay-inactive-color);\n transition: 250ms;\n}\n\n/* Checked/unchecked states */\n.fides-toggle .fides-toggle-input:checked + .fides-toggle-display {\n background-color: var(--fides-overlay-primary-active-color);\n}\n.fides-toggle .fides-toggle-input:checked + .fides-toggle-display::before {\n transform: translate(100%, -50%);\n}\n\n/* Disabled state */\n.fides-toggle .fides-toggle-input:disabled {\n cursor: not-allowed;\n}\n.fides-toggle .fides-toggle-input:disabled + .fides-toggle-display {\n background-color: var(--fides-overlay-disabled-color);\n}\n.fides-toggle .fides-toggle-input:disabled:checked + .fides-toggle-display {\n background-color: var(--fides-overlay-primary-active-disabled-color);\n}\n\n/* Focus ring when using keyboard */\n.fides-toggle .fides-toggle-input:focus + .fides-toggle-display {\n /* Firefox only has Highlight, not -webkit-focus-ring-color */\n outline: 1px auto Highlight;\n outline: 1px auto -webkit-focus-ring-color;\n}\n\n/* Disclosure */\n\n.fides-notice-toggle .fides-notice-toggle-title {\n border: 0;\n}\n\n#fides-modal .fides-modal-secondary-actions {\n display: none !important;\n}\n\n.fides-notice-toggle .fides-notice-toggle-trigger {\n padding-left: 4px;\n position: relative;\n left: -4px;\n}\n\n.fides-notice-toggle-trigger > .fides-flex-center.fides-justify-space-between {\n font-weight: bold\n}\n\n/* Tabs */\n\n.fides-tab-button::focus-visible {\n outline: 1px auto ").concat(theme.colors.black, ";\n}\n\n.fides-tab-button:focus:not(:focus-visible) {\n outline: 4px solid ").concat(theme.colors.hyper, " !important;\n}\n\n.fides-toggle-input.focus-visible + .fides-toggle-display,\n.fides-banner-button.fides-banner-button-primary.focus-visible,\n.fides-banner-button.fides-banner-button-secondary.focus-visible,\n.fides-banner-button.fides-banner-button-tertiary.focus-visible {\n outline: 3px solid ").concat(theme.colors.hyper, " !important;\n outline-offset: 2px;\n}\n\n/* Table */\n\n.fides-cookies-table {\n border-collapse: collapse;\n width: 100%;\n text-align: left;\n}\n\n.fides-cookies-table th {\n text-transform: uppercase;\n}\n\n.fides-cookies-table td, .fides-cookies-table th {\n border: 1px solid var(--fides-overlay-row-divider-color);\n padding-left: 1.1em;\n padding-right: 0.6em;\n}\n\n#fides-banner #fides-button-group button {\n font-weight: bold;\n padding: 10px 16px;\n margin-top: 0;\n border: 1px solid var(--fides-overlay-primary-color);\n border-radius: 2px;\n}\n\n#fides-banner #fides-button-group div:nth-child(2) > button:nth-child(1) {\n background-color: white;\n color: #3a10e5;\n}\n\n#fides-banner-button-tertiary {\n display: none;\n}\n\n#fides-banner-heading {\n display: none !important;\n}\n\ndiv#fides-banner-inner div#fides-button-group {\n flex-direction: row !important;\n}\n\n.fides-banner-description a:hover, .fides-modal-description a:hover {\n text-decoration: none;\n}\n\n#fides-banner-inner-container a.focus-visible {\n outline: 1px solid ").concat(theme.colors.black, " !important;\n}\n\ndiv#fides-banner-inner div#fides-button-group {\n padding-top: 0 !important\n}\n\n#fides-banner .fides-acknowledge-button, #fides-banner .fides-manage-preferences-button {\n width: auto !important\n}\n\n#fides-banner .fides-banner-button-group.fides-banner-primary-actions {\n align-items: flex-end !important;\n align-self: stretch !important\n}\n\n#fides-banner .fides-banner-button-group.fides-banner-secondary-actions {\n align-items: flex-start !important;\n}\n\n.fides-notice-toggle:focus-visible {\n outline: 1px solid ").concat(theme.colors.black, " !important;\n}\n\n@media (min-width: 37.5rem) {\n #fides-banner {\n padding: 0.875rem 1rem !important;\n }\n}\n\n").concat(theme.breakpoints.sm, " {\n div#fides-button-group .fides-banner-secondary-actions > button {\n padding: 4px 16px !important\n }\n\n div#fides-banner-inner {\n row-gap: 16px;\n }\n\n #fides-banner {\n padding: 0.875rem 1.25rem !important;\n }\n}\n\n@media only screen and (min-width: 1650px) {\n #fides-banner-inner {\n flex-direction: row !important;\n max-width: 1600px !important;\n }\n\n #fides-banner-inner-container {\n width: 72%;\n }\n\n #fides-banner div#fides-button-group {\n width: 28% !important;\n }\n\n div#fides-banner-description {\n margin-bottom: 0 !important;\n }\n}");
@@ -1,9 +0,0 @@
1
- import { TrackingWindow } from './types';
2
- export type GTMSettings = {
3
- environment: string;
4
- scope: TrackingWindow;
5
- optedOutExternalTracking?: boolean;
6
- enablePartytown?: boolean;
7
- };
8
- export declare const OPT_OUT_DATALAYER_VAR = "user_opted_out_external_tracking";
9
- export declare const initializeGTM: ({ scope, environment, optedOutExternalTracking, enablePartytown, }: GTMSettings) => void;
@@ -1,36 +0,0 @@
1
- export const OPT_OUT_DATALAYER_VAR = 'user_opted_out_external_tracking';
2
- export const initializeGTM = _ref => {
3
- var _scope$dataLayer;
4
- let scope = _ref.scope,
5
- environment = _ref.environment,
6
- optedOutExternalTracking = _ref.optedOutExternalTracking,
7
- enablePartytown = _ref.enablePartytown;
8
- (_scope$dataLayer = scope.dataLayer) !== null && _scope$dataLayer !== void 0 ? _scope$dataLayer : scope.dataLayer = [];
9
- scope.dataLayer.push({
10
- 'gtm.start': new Date().getTime(),
11
- event: 'gtm.js'
12
- });
13
- if (optedOutExternalTracking) {
14
- scope.dataLayer.push({
15
- [OPT_OUT_DATALAYER_VAR]: true
16
- });
17
- }
18
- let preview_env = '';
19
- if (environment === 'development') {
20
- preview_env = '&gtm_auth=DoN0WSxjuUkImaph8PYXmA&gtm_preview=env-233';
21
- } else if (environment === 'staging') {
22
- preview_env = '&gtm_auth=VrQuCDuWXkLlTwNHJYEKTg&gtm_preview=env-232';
23
- }
24
- const gtm = document.createElement('script');
25
- gtm.src = "https://www.googletagmanager.com/gtm.js?id=GTM-KTLK85W".concat(preview_env);
26
- if (enablePartytown) {
27
- gtm.type = 'text/partytown';
28
- } else {
29
- gtm.async = true;
30
- }
31
- document.getElementsByTagName('head')[0].appendChild(gtm);
32
- if (enablePartytown) {
33
- // Let Partytown know that a new script has been added.
34
- window.dispatchEvent(new CustomEvent('ptupdate'));
35
- }
36
- };
@@ -1,31 +0,0 @@
1
- import { TrackingWindow } from './types';
2
- export type TrackingIntegrationsSettings = {
3
- /**
4
- * Current environment.
5
- */
6
- environment: string;
7
- /**
8
- * Global scope (often the window) where globals such as analytics are stored.
9
- */
10
- scope: TrackingWindow;
11
- /**
12
- * Whether user has opted out or is excluded from external tracking
13
- */
14
- optedOutExternalTracking?: boolean;
15
- /**
16
- * id for the one trust script being used, defaults to the script for `www.codecademy.com`
17
- */
18
- oneTrustScript?: string;
19
- /**
20
- * Use Partytown to load 3rd party scripts in a worker.
21
- */
22
- enablePartytown?: boolean;
23
- /**
24
- * Whether to use Fides (new implementation) or OneTrust
25
- */
26
- isFidesEnabled?: boolean;
27
- };
28
- /**
29
- * @see README.md for details and usage.
30
- */
31
- export declare const initializeTrackingIntegrations: ({ environment, scope, optedOutExternalTracking, oneTrustScript, enablePartytown, isFidesEnabled, }: TrackingIntegrationsSettings) => Promise<void>;
@@ -1,43 +0,0 @@
1
- import { initializeFides } from './fides';
2
- import { initializeGTM } from './gtm';
3
- import { initializeOneTrust } from './onetrust';
4
- import { initializePartytown } from './partytown';
5
- let init = false;
6
-
7
- /**
8
- * @see README.md for details and usage.
9
- */
10
- export const initializeTrackingIntegrations = async _ref => {
11
- let environment = _ref.environment,
12
- scope = _ref.scope,
13
- optedOutExternalTracking = _ref.optedOutExternalTracking,
14
- oneTrustScript = _ref.oneTrustScript,
15
- enablePartytown = _ref.enablePartytown,
16
- isFidesEnabled = _ref.isFidesEnabled;
17
- if (init) return; // Prevent multiple initializations
18
- init = true;
19
- if (enablePartytown) {
20
- initializePartytown();
21
- } else {
22
- // Wait to allow any other post-hydration logic to run first
23
- await new Promise(resolve => setTimeout(resolve, 1000));
24
- }
25
- if (isFidesEnabled) {
26
- await initializeFides();
27
- } else {
28
- // Load in OneTrust's banner and wait for its `OptanonWrapper` callback
29
- await initializeOneTrust({
30
- scope,
31
- environment,
32
- scriptId: oneTrustScript
33
- });
34
- }
35
-
36
- // Load GTM
37
- initializeGTM({
38
- scope,
39
- environment,
40
- optedOutExternalTracking,
41
- enablePartytown
42
- });
43
- };
@@ -1,7 +0,0 @@
1
- import { TrackingWindow } from './types';
2
- export type OneTrustSettings = {
3
- environment: string;
4
- scope: TrackingWindow;
5
- scriptId?: string;
6
- };
7
- export declare const initializeOneTrust: ({ environment, scope, scriptId, }: OneTrustSettings) => Promise<void>;
@@ -1,34 +0,0 @@
1
- /**
2
- * Onetrust script ID for `www.codecademy.com`, other domains require passing in a specific script ID
3
- */
4
- const DEFAULT_SCRIPT_ID = 'cfa7b129-f37b-4f5a-9991-3f75ba7b85fb';
5
- export const initializeOneTrust = async _ref => {
6
- let environment = _ref.environment,
7
- scope = _ref.scope,
8
- _ref$scriptId = _ref.scriptId,
9
- scriptId = _ref$scriptId === void 0 ? DEFAULT_SCRIPT_ID : _ref$scriptId;
10
- const script = document.createElement('script');
11
- script.setAttribute('async', 'true');
12
- script.setAttribute('src', 'https://cdn.cookielaw.org/scripttemplates/otSDKStub.js');
13
- script.setAttribute('type', 'text/javascript');
14
- script.setAttribute('data-domain-script', "".concat(scriptId).concat(environment === 'production' ? '' : '-test'));
15
- document.body.appendChild(script);
16
- const style = document.createElement('style');
17
- style.textContent = rawStyles;
18
- document.body.appendChild(style);
19
- return new Promise(resolve => {
20
- scope.OptanonWrapper = () => {
21
- var _scope$dataLayer, _script$parentNode;
22
- (_scope$dataLayer = scope.dataLayer) !== null && _scope$dataLayer !== void 0 ? _scope$dataLayer : scope.dataLayer = [];
23
- scope.dataLayer.push({
24
- event: 'OneTrustGroupsUpdated'
25
- });
26
- resolve();
27
- (_script$parentNode = script.parentNode) === null || _script$parentNode === void 0 ? void 0 : _script$parentNode.removeChild(script);
28
- };
29
- });
30
- };
31
-
32
- // For now, these three values duplicate theme colors from gamut-styles
33
- // We don't want to take a full dependency on that package here...
34
- const rawStyles = "\n:root {\n --onetrust-brand-purple: #3A10E5;\n --onetrust-color-gray-500: #828285;\n --onetrust-color-white: #fff;\n}\n\n#onetrust-banner-sdk {\n padding: 1rem !important;\n}\n#onetrust-banner-sdk > .ot-sdk-container {\n width: 100% !important;\n}\n#onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row {\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n max-width: 1436px !important;\n margin: 0 auto !important;\n}\n#onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row:after {\n content: none !important;\n}\n#onetrust-banner-sdk > div > .ot-sdk-container > .ot-sdk-row {\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n max-width: 1436px !important;\n margin: 0 auto !important;\n}\n#onetrust-banner-sdk > div > .ot-sdk-container > .ot-sdk-row:after {\n content: none !important;\n}\n#onetrust-group-container {\n display: flex !important;\n justify-content: center;\n float: none !important;\n width: 100% !important;\n max-width: 1148px !important;\n margin-left: 0 !important;\n margin-bottom: 0.625rem !important;\n}\n\n#onetrust-policy,\n#onetrust-policy-text {\n margin: 0 !important;\n font-size: 0.875rem !important;\n line-height: 1.375rem !important;\n text-align: center !important;\n float: none !important;\n}\n#onetrust-policy-text a {\n text-decoration: none;\n line-height: 26px !important;\n margin-left: 0 !important;\n}\n#onetrust-button-group-parent {\n position: relative !important;\n top: initial !important;\n left: initial !important;\n transform: initial !important;\n width: 264px !important;\n margin: 0 !important;\n padding: 0 !important;\n float: none !important;\n}\n#onetrust-button-group {\n display: flex !important;\n margin: 0 !important;\n}\n#onetrust-pc-btn-handler, #onetrust-accept-btn-handler {\n min-width: initial !important;\n padding: 0.375rem 1rem !important;\n margin: 0 !important;\n opacity: 1 !important;\n border-radius: 2px !important;\n line-height: 1.5 !important;\n user-select: none !important;\n font-size: 1rem !important;\n}\n#onetrust-pc-btn-handler:focus, #onetrust-accept-btn-handler:focus {\n box-shadow: 0 0 0 2px var(--onetrust-color-white), 0 0 0 4px var(--onetrust-brand-purple);\n text-decoration: none !important;\n outline: none !important;\n}\n#onetrust-pc-btn-handler{\n color: var(--onetrust-brand-purple) !important;\n border: 1px solid var(--onetrust-brand-purple)!important;\n background: var(--onetrust-color-white) !important\n}\n#onetrust-accept-btn-handler {\n color: var(--onetrust-color-white) !important;\n background: var(--onetrust-brand-purple)!important;\n margin-left: 1rem !important;\n}\n#onetrust-close-btn-container {\n display: none !important;\n}\n\n.pc-logo {\n display: none !important;\n}\n\n#accept-recommended-btn-handler,\n.ot-pc-refuse-all-handler,\n.save-preference-btn-handler {\n margin-left: 4px !important;\n font-size: 14px !important;\n}\n\n#accept-recommended-btn-handler:focus,\n#onetrust-pc-sdk .ot-pc-refuse-all-handler:focus,\n#onetrust-pc-sdk .save-preference-btn-handler:focus {\n box-shadow: 0 0 0 2px var(--onetrust-color-white), 0 0 0 4px var(--onetrust-brand-purple);\n text-decoration: none !important;\n outline: none !important;\n opacity: 1 !important;\n}\n\n.ot-switch-label {\n border: 1px solid var(--onetrust-color-gray-500) !important;\n background-color: var(--onetrust-color-gray-500) !important;\n}\n\n.ot-switch-nob {\n background: var(--onetrust-color-white) !important;\n}\n\n.ot-switch-inner:before {\n background-color: var(--onetrust-brand-purple) !important;\n}\n\n.switch-checkbox:checked+.ot-switch-label .ot-switch-nob {\n border-color: var(--onetrust-brand-purple) !important;\n}\n\n.ot-pc-footer-logo {\n display: none !important;\n}\n\n#onetrust-banner-sdk>.ot-sdk-container {\n overflow: visible !important;\n}\n\n#onetrust-pc-sdk .category-item .ot-switch.ot-toggle input:focus + .ot-switch-label {\n \toutline-color: var(--onetrust-brand-purple) !important;\n}\n#onetrust-pc-sdk .category-item .ot-switch.ot-toggle input:focus+.ot-switch-label {\n outline-width: 3px !important;\n outline-offset: 2px !important;\n}\n\n@media (max-width: 30rem) {\n #accept-recommended-btn-handler,\n .ot-pc-refuse-all-handler,\n .save-preference-btn-handler {\n width: 96% !important;\n }\n}\n\n@media (min-width: 37.5rem) {\n #onetrust-banner-sdk {\n padding: 0.875rem 1rem !important;\n }\n}\n@media (min-width: 48rem) {\n #onetrust-banner-sdk {\n padding: 0.875rem 1.25rem !important;\n }\n}\n@media (min-width: 1650px) {\n #onetrust-banner-sdk > .ot-sdk-container > .ot-sdk-row {\n flex-direction: row !important;\n justify-content: space-between !important;\n }\n #onetrust-banner-sdk > div > .ot-sdk-container > .ot-sdk-row {\n flex-direction: row !important;\n justify-content: space-between !important;\n }\n #onetrust-group-container {\n margin-bottom: 0 !important;\n }\n #onetrust-button-group {\n flex-direction: row !important;\n }\n}\n";
@@ -1,2 +0,0 @@
1
- import { PartytownConfig } from '@qwik.dev/partytown/integration';
2
- export declare const partytownConfig: () => PartytownConfig;
@@ -1,70 +0,0 @@
1
- export const partytownConfig = () => ({
2
- forward: ['dataLayer.push',
3
- // for GTM
4
- 'fbq',
5
- // for Facebook Pixel
6
- '_hsq.push' // for Hubspot
7
- ],
8
- lib: '/partytown/',
9
- // path for loading from static asset CMS
10
- loadScriptsOnMainThread: [/pepperjam/,
11
- // Pepperjam
12
- /snap/,
13
- // Snap Pixel
14
- /lightboxcdn/,
15
- // Digioh
16
- /linkedin/,
17
- // linkedin
18
- /debug/ // GTM debugging
19
- ],
20
- // This function runs in a worker and can't access other vars in this file.
21
- resolveUrl(url, location, type) {
22
- // Hoist GTM iframe out of Partytown so that GTM can create its own worker normally.
23
- if (url.hostname === 'www.googletagmanager.com' && type === 'iframe') {
24
- new BroadcastChannel('gtm-iframe').postMessage(url.href);
25
- return new URL('data:'); // blank url to prevent iframe within Partytown
26
- }
27
-
28
- /*
29
- * Proxy Facebook Pixel requests to resolve CORS issues
30
- * see https://partytown.builder.io/facebook-pixel#proxy-requests
31
- */
32
- if (url.hostname === 'connect.facebook.net') {
33
- return new URL("partytown-fb".concat(url.pathname).concat(url.search), location.origin);
34
- }
35
-
36
- /*
37
- * Proxy Reddit Pixel requests to resolve CORS issues
38
- */
39
- if (url.hostname === 'www.redditstatic.com') {
40
- return new URL("partytown-reddit".concat(url.pathname).concat(url.search), location.origin);
41
- }
42
-
43
- /*
44
- * Proxy Google Ads requests to resolve CORS issues
45
- */
46
- if (url.hostname === 'googleads.g.doubleclick.net') {
47
- let p = url.pathname;
48
- if (p.endsWith('/')) {
49
- // Google Ads returns a redirect if path has a trailing slash
50
- p = p.slice(0, -1);
51
- }
52
- return new URL("partytown-googleads".concat(p).concat(url.search), location.origin);
53
- }
54
-
55
- /*
56
- * Proxy Bing requests to resolve CORS issues
57
- */
58
- if (url.hostname === 'bat.bing.com') {
59
- return new URL("partytown-bing".concat(url.pathname).concat(url.search), location.origin);
60
- }
61
-
62
- /*
63
- * Proxy YouTube requests to resolve CORS issues
64
- */
65
- if (url.hostname === 'www.youtube.com') {
66
- return new URL("partytown-youtube".concat(url.pathname).concat(url.search), location.origin);
67
- }
68
- return url;
69
- }
70
- });
@@ -1 +0,0 @@
1
- export declare function gtmDoubleFrame(src: string): void;
@@ -1,15 +0,0 @@
1
- function hiddenFrame(doc) {
2
- const f = doc.createElement('iframe');
3
- f.setAttribute('height', '0');
4
- f.setAttribute('width', '0');
5
- f.setAttribute('style', 'display: none; visibility: hidden;');
6
- doc.body.appendChild(f);
7
- return f;
8
- }
9
-
10
- // Double frame is what GTM would normally use without Partytown.
11
- export function gtmDoubleFrame(src) {
12
- const outerFrame = hiddenFrame(document);
13
- const innerFrame = hiddenFrame(outerFrame.contentWindow.document);
14
- innerFrame.src = src;
15
- }
@@ -1 +0,0 @@
1
- export declare function initializePartytown(): void;
@@ -1,24 +0,0 @@
1
- import { partytownSnippet } from '@qwik.dev/partytown/integration';
2
- import { partytownConfig } from './config';
3
- import { gtmDoubleFrame } from './gtmDoubleFrame';
4
-
5
- // Encapsulate to avoid collision of global vars aliased in minification.
6
- const encapsulate = js => "(() => {".concat(js, "})();");
7
- export function initializePartytown() {
8
- const ptScript = document.createElement('script');
9
- ptScript.innerHTML = encapsulate(partytownSnippet(partytownConfig()));
10
- document.head.appendChild(ptScript);
11
- new BroadcastChannel('gtm-iframe').onmessage = _ref => {
12
- let data = _ref.data;
13
- gtmDoubleFrame(data);
14
- };
15
-
16
- /*
17
- * Img elements added by GTM tags for Google Ads normally set themselves as
18
- * position:absolute. Since Partytown prevents this, a stylesheet is added to
19
- * restore the style (and remove the added whitespace).
20
- */
21
- const styles = document.createElement('style');
22
- styles.innerText = "body > img[aria-hidden=true] { position: absolute; }";
23
- document.head.appendChild(styles);
24
- }
@@ -1,6 +0,0 @@
1
- import { Consent } from './consent';
2
- export interface TrackingWindow {
3
- dataLayer?: unknown[];
4
- OnetrustActiveGroups?: Consent[] | string;
5
- OptanonWrapper?: () => void;
6
- }
@@ -1 +0,0 @@
1
- export {};