@highfivve/ad-tag 5.11.9 → 5.12.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.
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { AssetLoadMethod } from 'ad-tag/util/assetLoaderService';
|
|
2
|
+
import { mkConfigureStepOncePerRequestAdsCycle, mkInitStep } from 'ad-tag/ads/adPipeline';
|
|
3
|
+
const name = 'inline-ai';
|
|
4
|
+
export const createInlineAi = () => {
|
|
5
|
+
let inlineAiConfig = null;
|
|
6
|
+
let scriptLoaded = false;
|
|
7
|
+
const config__ = () => inlineAiConfig;
|
|
8
|
+
const configure__ = (moduleConfig) => {
|
|
9
|
+
if (moduleConfig?.inlineAi?.enabled) {
|
|
10
|
+
inlineAiConfig = moduleConfig.inlineAi;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const hasConsent = (context) => !context.tcData__.gdprApplies || !!context.tcData__.purpose.consents['1'];
|
|
14
|
+
const isPlacementActive = (context, placement) => !placement.labelCondition ||
|
|
15
|
+
context.labelConfigService__.isLabelConditionMet(placement.labelCondition);
|
|
16
|
+
const mountCommand = (placement) => {
|
|
17
|
+
switch (placement.type) {
|
|
18
|
+
case 'widget':
|
|
19
|
+
return ['mount', placement.type];
|
|
20
|
+
case 'search-fab':
|
|
21
|
+
return placement.options
|
|
22
|
+
? ['mount', placement.type, undefined, placement.options]
|
|
23
|
+
: ['mount', placement.type];
|
|
24
|
+
case 'search-embed':
|
|
25
|
+
case 'search-icon':
|
|
26
|
+
return placement.options
|
|
27
|
+
? ['mount', placement.type, placement.target, placement.options]
|
|
28
|
+
: ['mount', placement.type, placement.target];
|
|
29
|
+
case 'key-takeaways':
|
|
30
|
+
case 'single-question':
|
|
31
|
+
case 'basic-embed':
|
|
32
|
+
return ['mount', placement.type, placement.target];
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const mountPlacements = (context, cmd, config) => {
|
|
36
|
+
(config.placements ?? [])
|
|
37
|
+
.filter(placement => isPlacementActive(context, placement))
|
|
38
|
+
.forEach(placement => cmd.push(mountCommand(placement)));
|
|
39
|
+
};
|
|
40
|
+
const applyMode = (context, cmd, config) => {
|
|
41
|
+
switch (config.mode) {
|
|
42
|
+
case 'auto':
|
|
43
|
+
return;
|
|
44
|
+
case 'programmatic':
|
|
45
|
+
cmd.push(['init', { publisherId: config.publisherId }]);
|
|
46
|
+
mountPlacements(context, cmd, config);
|
|
47
|
+
return;
|
|
48
|
+
case 'hybrid':
|
|
49
|
+
mountPlacements(context, cmd, config);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const loadScript = (context, config) => {
|
|
54
|
+
if (scriptLoaded) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
scriptLoaded = true;
|
|
58
|
+
context.assetLoaderService__
|
|
59
|
+
.loadScript({
|
|
60
|
+
name,
|
|
61
|
+
loadMethod: AssetLoadMethod.TAG,
|
|
62
|
+
assetUrl: `${config.scriptUrl}?key=${config.publisherId}`,
|
|
63
|
+
type: 'module'
|
|
64
|
+
})
|
|
65
|
+
.catch(error => context.logger__.error(name, 'failed to load InlineAI script', error));
|
|
66
|
+
};
|
|
67
|
+
const isFirstRun = (context) => context.requestAdsCalls__ === 1;
|
|
68
|
+
const runInlineAi = (context, config) => {
|
|
69
|
+
if (context.env__ === 'test') {
|
|
70
|
+
return Promise.resolve();
|
|
71
|
+
}
|
|
72
|
+
if (!hasConsent(context)) {
|
|
73
|
+
context.logger__.warn(name, 'no gdpr consent, InlineAI will not be loaded');
|
|
74
|
+
return Promise.resolve();
|
|
75
|
+
}
|
|
76
|
+
if (config.mode !== 'auto') {
|
|
77
|
+
context.window__.InlineAI = context.window__.InlineAI || { cmd: [] };
|
|
78
|
+
const cmd = context.window__.InlineAI.cmd;
|
|
79
|
+
if (!isFirstRun(context)) {
|
|
80
|
+
cmd.push(['destroy']);
|
|
81
|
+
}
|
|
82
|
+
applyMode(context, cmd, config);
|
|
83
|
+
}
|
|
84
|
+
loadScript(context, config);
|
|
85
|
+
return Promise.resolve();
|
|
86
|
+
};
|
|
87
|
+
const initSteps__ = () => {
|
|
88
|
+
const config = inlineAiConfig;
|
|
89
|
+
return config
|
|
90
|
+
? [
|
|
91
|
+
mkInitStep('inline-ai-init', context => context.config__.spa?.enabled ? Promise.resolve() : runInlineAi(context, config))
|
|
92
|
+
]
|
|
93
|
+
: [];
|
|
94
|
+
};
|
|
95
|
+
const configureSteps__ = () => {
|
|
96
|
+
const config = inlineAiConfig;
|
|
97
|
+
return config
|
|
98
|
+
? [
|
|
99
|
+
mkConfigureStepOncePerRequestAdsCycle('inline-ai-configure', context => context.config__.spa?.enabled ? runInlineAi(context, config) : Promise.resolve())
|
|
100
|
+
]
|
|
101
|
+
: [];
|
|
102
|
+
};
|
|
103
|
+
return {
|
|
104
|
+
name,
|
|
105
|
+
configKey: 'inlineAi',
|
|
106
|
+
description: 'loads the InlineAI SDK and drives placement rendering',
|
|
107
|
+
moduleType: 'engagement',
|
|
108
|
+
config__,
|
|
109
|
+
configure__,
|
|
110
|
+
initSteps__,
|
|
111
|
+
configureSteps__,
|
|
112
|
+
prepareRequestAdsSteps__: () => []
|
|
113
|
+
};
|
|
114
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { mkInitStep } from 'ad-tag/ads/adPipeline';
|
|
2
|
+
const name = 'styles loader';
|
|
3
|
+
export const createStylesLoader = () => {
|
|
4
|
+
let stylesConfig = null;
|
|
5
|
+
const config__ = () => stylesConfig;
|
|
6
|
+
const configure__ = (moduleConfig) => {
|
|
7
|
+
if (moduleConfig?.styles?.enabled) {
|
|
8
|
+
stylesConfig = moduleConfig.styles;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const loadStylesheet = (context, config) => {
|
|
12
|
+
const link = context.window__.document.createElement('link');
|
|
13
|
+
link.rel = 'stylesheet';
|
|
14
|
+
link.href = config.href;
|
|
15
|
+
link.addEventListener('error', () => context.logger__.error(name, `failed to load stylesheet ${config.href}`));
|
|
16
|
+
context.window__.document.head.prepend(link);
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
};
|
|
19
|
+
const initSteps__ = () => {
|
|
20
|
+
const config = stylesConfig;
|
|
21
|
+
return config ? [mkInitStep('styles-init', ctx => loadStylesheet(ctx, config))] : [];
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
name,
|
|
25
|
+
configKey: 'styles',
|
|
26
|
+
description: "injects the publisher's stylesheet as a base layer in <head>",
|
|
27
|
+
moduleType: 'creatives',
|
|
28
|
+
config__,
|
|
29
|
+
configure__,
|
|
30
|
+
initSteps__,
|
|
31
|
+
configureSteps__: () => [],
|
|
32
|
+
prepareRequestAdsSteps__: () => []
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -321,6 +321,17 @@ const MoliAnalyticsModule = ({ config }) => (React.createElement(React.Fragment,
|
|
|
321
321
|
"delay: ",
|
|
322
322
|
config.batchDelay ?? 100,
|
|
323
323
|
"ms"))));
|
|
324
|
+
const StylesModule = ({ config }) => (React.createElement(Row, { label: "Stylesheet" },
|
|
325
|
+
React.createElement(Tag, null, config.href)));
|
|
326
|
+
const InlineAiModule = ({ config }) => (React.createElement(React.Fragment, null,
|
|
327
|
+
React.createElement(Row, { label: "Publisher ID" },
|
|
328
|
+
React.createElement(Tag, null, config.publisherId)),
|
|
329
|
+
React.createElement(Row, { label: "Mode" },
|
|
330
|
+
React.createElement(Tag, null, config.mode)),
|
|
331
|
+
React.createElement(Row, { label: "Script URL" },
|
|
332
|
+
React.createElement(Tag, { variant: "grey" }, config.scriptUrl)),
|
|
333
|
+
React.createElement(Row, { label: "Placements" },
|
|
334
|
+
React.createElement(ListTags, { values: config.placements?.map(placement => placement.name) }))));
|
|
324
335
|
const GenericModule = ({ config, subEntry }) => (React.createElement(React.Fragment, null, Object.entries(config)
|
|
325
336
|
.filter(([key]) => key !== 'enabled')
|
|
326
337
|
.map(([key, value]) => (React.createElement(TagContainer, { key: key, subEntry: subEntry },
|
|
@@ -336,8 +347,10 @@ const moduleComponents = {
|
|
|
336
347
|
emetriq: EmetriqModule,
|
|
337
348
|
geoedge: GeoEdgeModule,
|
|
338
349
|
identitylink: IdentityLinkModule,
|
|
350
|
+
inlineAi: InlineAiModule,
|
|
339
351
|
pubstack: PubstackModule,
|
|
340
352
|
skin: SkinModule,
|
|
353
|
+
styles: StylesModule,
|
|
341
354
|
stickyHeaderAd: StickyHeaderAdModule,
|
|
342
355
|
utiq: UtiqModule,
|
|
343
356
|
prebidFirstPartyData: PrebidFirstPartyDataModule,
|
package/lib/gen/packageJson.js
CHANGED