@temple-wallet/extension-ads 7.1.1 → 8.1.0-dev.1
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/dist/index.d.ts +33 -52
- package/dist/index.js +13 -12
- package/package.json +3 -6
- package/src/ads-actions/helpers.ts +25 -11
- package/src/ads-actions/index.ts +6 -3
- package/src/ads-actions/process-permanent-rule.ts +9 -1
- package/src/ads-actions/process-providers-ads.ts +39 -16
- package/src/ads-actions/process-rule.ts +2 -0
- package/src/ads-configuration.ts +8 -8
- package/src/constants.ts +2 -0
- package/src/execute-ads-actions/ads-views/index.ts +2 -2
- package/src/execute-ads-actions/ads-views/{make-hypelab-ad.ts → make-ads-tw-view.ts} +11 -9
- package/src/execute-ads-actions/ads-views/make-extension-iframe-view.ts +26 -0
- package/src/execute-ads-actions/ads-views/make-tkey-ad.ts +1 -1
- package/src/execute-ads-actions/observing.ts +13 -7
- package/src/execute-ads-actions/process-insert-ad-action.ts +11 -3
- package/src/render-ads-stack.ts +70 -14
- package/src/temple-wallet-api.ts +9 -2
- package/src/transform-raw-rules.ts +27 -11
- package/src/types/ad-view.ts +3 -0
- package/src/types/ads-actions.ts +4 -1
- package/src/types/ads-meta.ts +3 -18
- package/src/types/ads-provider.ts +1 -0
- package/src/types/ads-rules.ts +1 -1
- package/src/types/temple-wallet-api.ts +1 -0
- package/src/utils.ts +0 -4
- package/dist/referrals/index.d.ts +0 -33
- package/dist/referrals/index.js +0 -18
- package/src/execute-ads-actions/ads-views/make-persona-ad.ts +0 -15
- package/src/referrals/index.ts +0 -5
- package/src/referrals/replace.ts +0 -129
- package/src/referrals/takeads.ts +0 -44
- package/src/referrals/utils.ts +0 -14
package/src/ads-configuration.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { AdMetadata } from './types/ads-meta';
|
|
2
2
|
|
|
3
3
|
interface IAdsConfiguration {
|
|
4
|
-
|
|
4
|
+
adsTwWindowUrl: string;
|
|
5
5
|
tkeyInpageAdUrl: string;
|
|
6
6
|
smallTkeyInpageAdUrl?: string;
|
|
7
7
|
swapTkeyUrl: string;
|
|
8
8
|
externalAdsActivityMessageType: string;
|
|
9
|
-
|
|
9
|
+
personaIframePath: string;
|
|
10
10
|
getAdsStackIframeURL: (id: string, adsMetadataIds: (number | AdMetadata)[], origin: string) => string;
|
|
11
11
|
buildNativeAdsMeta: (containerWidth: number, containerHeight: number) => AdMetadata[];
|
|
12
12
|
bannerAdsMeta: AdMetadata[];
|
|
@@ -17,12 +17,12 @@ interface IAdsConfiguration {
|
|
|
17
17
|
|
|
18
18
|
export class AdsConfiguration {
|
|
19
19
|
static IS_MISES_BROWSER = false;
|
|
20
|
-
static
|
|
20
|
+
static ADS_TW_WINDOW_URL = '';
|
|
21
21
|
static TKEY_INPAGE_AD_URL = '';
|
|
22
22
|
static SMALL_TKEY_INPAGE_AD_URL = '';
|
|
23
23
|
static SWAP_TKEY_URL = '';
|
|
24
24
|
static EXTERNAL_ADS_ACTIVITY_MESSAGE_TYPE = '';
|
|
25
|
-
static
|
|
25
|
+
static personaIframePath: IAdsConfiguration['personaIframePath'] = '';
|
|
26
26
|
static getAdsStackIframeURL: IAdsConfiguration['getAdsStackIframeURL'] = () => '';
|
|
27
27
|
static buildNativeAdsMeta: IAdsConfiguration['buildNativeAdsMeta'] = () => [];
|
|
28
28
|
static bannerAdsMeta: AdMetadata[] = [];
|
|
@@ -32,12 +32,12 @@ export class AdsConfiguration {
|
|
|
32
32
|
|
|
33
33
|
export const configureAds = (config: IAdsConfiguration) => {
|
|
34
34
|
const {
|
|
35
|
-
|
|
35
|
+
adsTwWindowUrl,
|
|
36
36
|
tkeyInpageAdUrl,
|
|
37
37
|
smallTkeyInpageAdUrl,
|
|
38
38
|
swapTkeyUrl,
|
|
39
39
|
externalAdsActivityMessageType,
|
|
40
|
-
|
|
40
|
+
personaIframePath,
|
|
41
41
|
getAdsStackIframeURL,
|
|
42
42
|
buildNativeAdsMeta,
|
|
43
43
|
bannerAdsMeta,
|
|
@@ -50,11 +50,11 @@ export const configureAds = (config: IAdsConfiguration) => {
|
|
|
50
50
|
AdsConfiguration.SMALL_TKEY_INPAGE_AD_URL = smallTkeyInpageAdUrl;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
AdsConfiguration.
|
|
53
|
+
AdsConfiguration.ADS_TW_WINDOW_URL = adsTwWindowUrl;
|
|
54
54
|
AdsConfiguration.TKEY_INPAGE_AD_URL = tkeyInpageAdUrl;
|
|
55
55
|
AdsConfiguration.SWAP_TKEY_URL = swapTkeyUrl;
|
|
56
56
|
AdsConfiguration.EXTERNAL_ADS_ACTIVITY_MESSAGE_TYPE = externalAdsActivityMessageType;
|
|
57
|
-
AdsConfiguration.
|
|
57
|
+
AdsConfiguration.personaIframePath = personaIframePath;
|
|
58
58
|
AdsConfiguration.getAdsStackIframeURL = getAdsStackIframeURL;
|
|
59
59
|
AdsConfiguration.buildNativeAdsMeta = buildNativeAdsMeta;
|
|
60
60
|
AdsConfiguration.bannerAdsMeta = bannerAdsMeta;
|
package/src/constants.ts
CHANGED
|
@@ -7,3 +7,5 @@ export const AD_RESIZE_MESSAGE_TYPE = 'resize';
|
|
|
7
7
|
export const AD_READY_MESSAGE_TYPE = 'ready';
|
|
8
8
|
export const AD_ERROR_MESSAGE_TYPE = 'error';
|
|
9
9
|
export const IFRAME_ALLOWANCE = 'accelerometer; gyroscope';
|
|
10
|
+
export const CRYPTO_CATEGORY_NAME = 'crypto';
|
|
11
|
+
export const BACKGROUND_ELEMENT_ID = 'background';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { makeTKeyAdView } from './make-tkey-ad';
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
2
|
+
export { makeAdsTwView } from './make-ads-tw-view';
|
|
3
|
+
export { makeExtensionIframeView } from './make-extension-iframe-view';
|
|
@@ -3,17 +3,17 @@ import { AES } from 'crypto-js';
|
|
|
3
3
|
import { AdsConfiguration } from 'src/ads-configuration';
|
|
4
4
|
import { IFRAME_ALLOWANCE } from 'src/constants';
|
|
5
5
|
import { AdView } from 'src/types/ad-view';
|
|
6
|
-
import { AdDimensions,
|
|
6
|
+
import { AdDimensions, AdSource } from 'src/types/ads-meta';
|
|
7
7
|
|
|
8
|
-
export const
|
|
8
|
+
export const makeAdsTwView = (
|
|
9
9
|
id: string,
|
|
10
|
-
source:
|
|
10
|
+
source: AdSource,
|
|
11
11
|
{ width, height }: AdDimensions,
|
|
12
12
|
origin: string
|
|
13
13
|
): AdView => {
|
|
14
14
|
const iframe = document.createElement('iframe');
|
|
15
15
|
iframe.id = id;
|
|
16
|
-
iframe.src =
|
|
16
|
+
iframe.src = getAdsTwUrl(source, origin, width, height, iframe.id);
|
|
17
17
|
iframe.style.width = source.native ? '100%' : `${width}px`;
|
|
18
18
|
iframe.style.height = `${height}px`;
|
|
19
19
|
iframe.style.border = 'none';
|
|
@@ -23,21 +23,23 @@ export const makeHypelabAdView = (
|
|
|
23
23
|
};
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
* Returns URL for
|
|
26
|
+
* Returns URL for ads.templewallet.com or its preview iframe
|
|
27
27
|
* @param placementType Placement type
|
|
28
28
|
* @param origin Full URL of the page
|
|
29
29
|
* @param width Frame width
|
|
30
30
|
* @param height Frame height
|
|
31
31
|
*/
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
32
|
+
const getAdsTwUrl = (source: AdSource, origin: string, width: number, height: number, id: string) => {
|
|
33
|
+
const { providerName, slug, native } = source;
|
|
34
|
+
const url = new URL(AdsConfiguration.ADS_TW_WINDOW_URL);
|
|
35
|
+
url.searchParams.set('ap', providerName.toLowerCase());
|
|
36
|
+
if (native) {
|
|
35
37
|
url.searchParams.set('vh', String(height));
|
|
36
38
|
} else {
|
|
37
39
|
url.searchParams.set('w', String(width));
|
|
38
40
|
}
|
|
39
41
|
url.searchParams.set('h', String(height));
|
|
40
|
-
url.searchParams.set('p',
|
|
42
|
+
url.searchParams.set('p', slug);
|
|
41
43
|
url.searchParams.set('o', encryptWithAES(origin));
|
|
42
44
|
if (id) {
|
|
43
45
|
url.searchParams.set('id', id);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { AdsConfiguration } from 'src/ads-configuration';
|
|
2
|
+
import { AdView } from 'src/types/ad-view';
|
|
3
|
+
import { AdDimensions, AdSource } from 'src/types/ads-meta';
|
|
4
|
+
|
|
5
|
+
export const makeExtensionIframeView = (id: string, source: AdSource, { width, height }: AdDimensions): AdView => {
|
|
6
|
+
const element = document.createElement('iframe');
|
|
7
|
+
let iframePath = '';
|
|
8
|
+
switch (source.providerName) {
|
|
9
|
+
case 'Persona':
|
|
10
|
+
iframePath = AdsConfiguration.personaIframePath;
|
|
11
|
+
break;
|
|
12
|
+
default:
|
|
13
|
+
throw new Error(`Ads from ${source.providerName} are unavailable via extension iframe`);
|
|
14
|
+
}
|
|
15
|
+
const iframeUrl = new URL(iframePath);
|
|
16
|
+
iframeUrl.searchParams.set('id', id);
|
|
17
|
+
iframeUrl.searchParams.set('slug', source.slug);
|
|
18
|
+
element.src = iframeUrl.toString();
|
|
19
|
+
element.id = id;
|
|
20
|
+
|
|
21
|
+
element.style.width = `${width}px`;
|
|
22
|
+
element.style.height = `${height}px`;
|
|
23
|
+
element.style.border = 'none';
|
|
24
|
+
|
|
25
|
+
return { element };
|
|
26
|
+
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import browser from 'webextension-polyfill';
|
|
2
2
|
|
|
3
|
+
import { extendOrKeepDimension } from 'src/ads-actions/helpers';
|
|
3
4
|
import { AdsConfiguration } from 'src/ads-configuration';
|
|
4
5
|
import {
|
|
5
6
|
AD_ERROR_MESSAGE_TYPE,
|
|
@@ -46,21 +47,26 @@ export const subscribeToAdsStackIframeLoadIfNecessary = async (element: HTMLIFra
|
|
|
46
47
|
reject(new Error(data.reason ?? 'Unknown error'));
|
|
47
48
|
break;
|
|
48
49
|
case AD_RENDER_START_MESSAGE_TYPE:
|
|
49
|
-
const { dimensions }: AdMetadata = data.adMetadata;
|
|
50
|
+
const { dimensions, source }: AdMetadata = data.adMetadata;
|
|
50
51
|
const { width, height } = dimensions;
|
|
51
52
|
if (width > 0 && height > 0) {
|
|
52
|
-
if (
|
|
53
|
-
element.style.
|
|
53
|
+
if (source.native) {
|
|
54
|
+
element.style.height = `${height}px`;
|
|
55
|
+
} else {
|
|
56
|
+
extendOrKeepDimension(element, 'width', width);
|
|
57
|
+
extendOrKeepDimension(element, 'height', height);
|
|
54
58
|
}
|
|
55
|
-
element.style.height = `${dimensions.height}px`;
|
|
56
59
|
}
|
|
57
60
|
break;
|
|
58
61
|
case AD_RESIZE_MESSAGE_TYPE:
|
|
59
62
|
const { width: newWidth, height: newHeight } = data;
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
|
|
64
|
+
if (element.style.width?.endsWith('%')) {
|
|
65
|
+
element.style.height = `${newHeight + verticalBordersWidth}px`;
|
|
66
|
+
} else {
|
|
67
|
+
extendOrKeepDimension(element, 'width', newWidth + horizontalBordersWidth);
|
|
68
|
+
extendOrKeepDimension(element, 'height', newHeight + verticalBordersWidth);
|
|
62
69
|
}
|
|
63
|
-
element.style.height = `${newHeight + verticalBordersWidth}px`;
|
|
64
70
|
}
|
|
65
71
|
} catch (error) {
|
|
66
72
|
console.error('Observing error:', error);
|
|
@@ -14,7 +14,7 @@ import { AdDimensions } from 'src/types/ads-meta';
|
|
|
14
14
|
import { subscribeToAdsStackIframeLoadIfNecessary } from './observing';
|
|
15
15
|
import { overrideElementStyles } from './override-element-styles';
|
|
16
16
|
|
|
17
|
-
const adjustToAd = (wrapperElement: HTMLDivElement, adDimensions: AdDimensions) => {
|
|
17
|
+
const adjustToAd = (wrapperElement: HTMLDivElement, adDimensions: Pick<AdDimensions, 'width' | 'height'>) => {
|
|
18
18
|
const predefinedStylesKeyToOverride = ['width', 'height'] as const;
|
|
19
19
|
predefinedStylesKeyToOverride.forEach(dimensionName => {
|
|
20
20
|
const predefinedStyleValue = wrapperElement.style[dimensionName] ?? '';
|
|
@@ -33,7 +33,7 @@ const processInsertAdActionOnce = async (
|
|
|
33
33
|
insertionPoint: HTMLDivElement | HTMLTableCellElement,
|
|
34
34
|
onAdsStackError: (error: Error) => void
|
|
35
35
|
) => {
|
|
36
|
-
const { elementStyle = {}, stylesOverrides = [], adsMetadata, wrapperType } = action;
|
|
36
|
+
const { elementStyle = {}, stylesOverrides = [], adsMetadata, wrapperType, originalHeight, originalWidth } = action;
|
|
37
37
|
|
|
38
38
|
stylesOverrides.sort((a, b) => a.parentDepth - b.parentDepth);
|
|
39
39
|
|
|
@@ -41,12 +41,17 @@ const processInsertAdActionOnce = async (
|
|
|
41
41
|
|
|
42
42
|
const adId = nanoid();
|
|
43
43
|
const adElement = document.createElement('iframe');
|
|
44
|
+
adElement.loading = 'lazy';
|
|
44
45
|
adElement.src = AdsConfiguration.getAdsStackIframeURL(adId, adsMetadata, window.location.href);
|
|
45
46
|
adElement.id = adId;
|
|
46
47
|
adElement.allow = IFRAME_ALLOWANCE;
|
|
47
48
|
const firstAdMetadataOrId = adsMetadata[0];
|
|
48
|
-
const { dimensions } =
|
|
49
|
+
const { dimensions: minDimensions } =
|
|
49
50
|
typeof firstAdMetadataOrId === 'number' ? AdsConfiguration.bannerAdsMeta[firstAdMetadataOrId] : firstAdMetadataOrId;
|
|
51
|
+
const dimensions = {
|
|
52
|
+
width: Math.max(originalWidth, minDimensions.width),
|
|
53
|
+
height: Math.max(originalHeight, minDimensions.height)
|
|
54
|
+
};
|
|
50
55
|
adElement.style.width = wrapperType === 'tbody' ? '100%' : `${dimensions.width}px`;
|
|
51
56
|
adElement.style.height = `${dimensions.height}px`;
|
|
52
57
|
adElement.style.border = 'none';
|
|
@@ -157,6 +162,9 @@ export const processInsertAdAction = async (action: InsertAdAction) => {
|
|
|
157
162
|
if (isNativeAd) {
|
|
158
163
|
emptyAdElement.setAttribute(TEMPLE_WALLET_NATIVE_AD_ATTRIBUTE_NAME, 'true');
|
|
159
164
|
}
|
|
165
|
+
if (action.type === AdActionType.SimpleInsertAd && action.isSiblingReplacement) {
|
|
166
|
+
emptyAdElement.setAttribute(SIBLING_REPLACEMENT_ATTRIBUTE_NAME, 'true');
|
|
167
|
+
}
|
|
160
168
|
emptyAdElement.style.display = 'none';
|
|
161
169
|
wrapperElement.replaceWith(emptyAdElement);
|
|
162
170
|
};
|
package/src/render-ads-stack.ts
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
|
+
import { extendOrKeepDimension } from './ads-actions/helpers';
|
|
1
2
|
import { AdsConfiguration } from './ads-configuration';
|
|
2
3
|
import {
|
|
3
4
|
AD_ERROR_MESSAGE_TYPE,
|
|
4
5
|
AD_READY_MESSAGE_TYPE,
|
|
5
6
|
AD_RENDER_START_MESSAGE_TYPE,
|
|
6
|
-
AD_RESIZE_MESSAGE_TYPE
|
|
7
|
+
AD_RESIZE_MESSAGE_TYPE,
|
|
8
|
+
BACKGROUND_ELEMENT_ID
|
|
7
9
|
} from './constants';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
+
import { makeAdsTwView, makeExtensionIframeView, makeTKeyAdView } from './execute-ads-actions/ads-views';
|
|
11
|
+
import { overrideElementStyles } from './execute-ads-actions/override-element-styles';
|
|
12
|
+
import { AdView, CreativeSet } from './types/ad-view';
|
|
10
13
|
import { AdMetadata } from './types/ads-meta';
|
|
11
14
|
|
|
12
15
|
const broadcastMessage = (content: unknown) => window.parent.postMessage(JSON.stringify(content), '*');
|
|
@@ -34,17 +37,16 @@ export const renderAdsStack = async (
|
|
|
34
37
|
|
|
35
38
|
const { source, dimensions } = adMetadata;
|
|
36
39
|
let adView: AdView;
|
|
37
|
-
let withTempleLabel = true;
|
|
38
40
|
switch (source.providerName) {
|
|
39
41
|
case 'Temple':
|
|
40
42
|
adView = makeTKeyAdView(dimensions.width, dimensions.height, source.native);
|
|
41
43
|
break;
|
|
42
44
|
case 'HypeLab':
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
case 'SmartyAds':
|
|
46
|
+
adView = makeAdsTwView(adId, source, dimensions, origin);
|
|
45
47
|
break;
|
|
46
48
|
default:
|
|
47
|
-
adView =
|
|
49
|
+
adView = makeExtensionIframeView(adId, source, dimensions);
|
|
48
50
|
}
|
|
49
51
|
|
|
50
52
|
const { element } = adView;
|
|
@@ -52,9 +54,57 @@ export const renderAdsStack = async (
|
|
|
52
54
|
const templeLabelElement = document.getElementById('temple-label')!;
|
|
53
55
|
rootElement.replaceChildren(element);
|
|
54
56
|
|
|
55
|
-
if (
|
|
57
|
+
if (!source.native) templeLabelElement.setAttribute('active', '');
|
|
56
58
|
else templeLabelElement.removeAttribute('active');
|
|
57
59
|
|
|
60
|
+
const updateBackground = (creativeSet: CreativeSet = {}) => {
|
|
61
|
+
try {
|
|
62
|
+
const { image, video } = creativeSet;
|
|
63
|
+
const prevBackgroundElement = document.getElementById(BACKGROUND_ELEMENT_ID);
|
|
64
|
+
let backgroundElement: HTMLImageElement | HTMLVideoElement | undefined;
|
|
65
|
+
if (image) {
|
|
66
|
+
backgroundElement = document.createElement('img');
|
|
67
|
+
backgroundElement.src = image.url;
|
|
68
|
+
backgroundElement.alt = '';
|
|
69
|
+
} else if (video) {
|
|
70
|
+
backgroundElement = document.createElement('video');
|
|
71
|
+
backgroundElement.src = video.url;
|
|
72
|
+
backgroundElement.autoplay = true;
|
|
73
|
+
backgroundElement.preload = 'auto';
|
|
74
|
+
backgroundElement.playsInline = true;
|
|
75
|
+
backgroundElement.muted = true;
|
|
76
|
+
backgroundElement.loop = true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!backgroundElement && prevBackgroundElement) {
|
|
80
|
+
rootElement.removeChild(prevBackgroundElement);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!backgroundElement) return;
|
|
84
|
+
|
|
85
|
+
backgroundElement.id = BACKGROUND_ELEMENT_ID;
|
|
86
|
+
backgroundElement.style.zIndex = '-1';
|
|
87
|
+
overrideElementStyles(backgroundElement, {
|
|
88
|
+
position: 'absolute',
|
|
89
|
+
top: '0px',
|
|
90
|
+
left: '0px',
|
|
91
|
+
right: '0px',
|
|
92
|
+
bottom: '0px',
|
|
93
|
+
width: '100%',
|
|
94
|
+
height: '100%',
|
|
95
|
+
'object-fit': 'cover',
|
|
96
|
+
filter: 'blur(12px)'
|
|
97
|
+
});
|
|
98
|
+
if (prevBackgroundElement) {
|
|
99
|
+
rootElement.replaceChild(backgroundElement, prevBackgroundElement);
|
|
100
|
+
} else {
|
|
101
|
+
rootElement.appendChild(backgroundElement);
|
|
102
|
+
}
|
|
103
|
+
} catch (e) {
|
|
104
|
+
console.error(e);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
58
108
|
if (element instanceof HTMLIFrameElement) {
|
|
59
109
|
return new Promise<void>((resolve, reject) => {
|
|
60
110
|
const responseTimeout = setTimeout(
|
|
@@ -82,19 +132,24 @@ export const renderAdsStack = async (
|
|
|
82
132
|
clearTimeout(responseTimeout);
|
|
83
133
|
resolve();
|
|
84
134
|
}
|
|
135
|
+
updateBackground(data.ad?.creative_set);
|
|
85
136
|
break;
|
|
86
137
|
case AD_ERROR_MESSAGE_TYPE:
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
138
|
+
if (!wasReady) {
|
|
139
|
+
window.removeEventListener('message', messageListener);
|
|
140
|
+
clearTimeout(responseTimeout);
|
|
141
|
+
reject(new Error(data.reason ?? 'Unknown error'));
|
|
142
|
+
}
|
|
90
143
|
break;
|
|
91
144
|
case AD_RESIZE_MESSAGE_TYPE:
|
|
92
145
|
const { width, height } = data;
|
|
93
146
|
if (width > 0 && height > 0) {
|
|
94
|
-
if (
|
|
95
|
-
element.style.
|
|
147
|
+
if (adMetadata.source.native) {
|
|
148
|
+
element.style.height = `${height}px`;
|
|
149
|
+
} else {
|
|
150
|
+
extendOrKeepDimension(element, 'width', width);
|
|
151
|
+
extendOrKeepDimension(element, 'height', height);
|
|
96
152
|
}
|
|
97
|
-
element.style.height = `${height}px`;
|
|
98
153
|
broadcastMessage({ ...data, id: adId });
|
|
99
154
|
}
|
|
100
155
|
}
|
|
@@ -111,5 +166,6 @@ export const renderAdsStack = async (
|
|
|
111
166
|
});
|
|
112
167
|
}
|
|
113
168
|
|
|
169
|
+
updateBackground(adView.creativeSet);
|
|
114
170
|
broadcastMessage({ id: adId, type: AD_READY_MESSAGE_TYPE, adMetadata });
|
|
115
171
|
};
|
package/src/temple-wallet-api.ts
CHANGED
|
@@ -42,6 +42,10 @@ export class TempleWalletApi {
|
|
|
42
42
|
this.api.get<string[]>('/slise-ad-rules/providers/all-sites')
|
|
43
43
|
);
|
|
44
44
|
|
|
45
|
+
getProvidersCategories = withFetchDataExtraction(() =>
|
|
46
|
+
this.api.get<Record<string, string[]>>('/slise-ad-rules/providers/categories')
|
|
47
|
+
);
|
|
48
|
+
|
|
45
49
|
getProvidersRulesForAllDomains = withFetchDataExtraction(() =>
|
|
46
50
|
this.api.get<Record<string, RawAdProvidersRule[]>>('/slise-ad-rules/providers/by-sites')
|
|
47
51
|
);
|
|
@@ -92,7 +96,8 @@ export class TempleWalletApi {
|
|
|
92
96
|
permanentNativeAdPlacesRulesForAllDomains,
|
|
93
97
|
adsReplaceUrlsBlacklist,
|
|
94
98
|
providersNegativeSelectors,
|
|
95
|
-
elementsToHideOrRemoveRules
|
|
99
|
+
elementsToHideOrRemoveRules,
|
|
100
|
+
providersCategories
|
|
96
101
|
] = await Promise.all([
|
|
97
102
|
this.getAdPlacesRulesForAllDomains(),
|
|
98
103
|
this.getProvidersRulesForAllDomains(),
|
|
@@ -102,7 +107,8 @@ export class TempleWalletApi {
|
|
|
102
107
|
this.getPermanentNativeAdPlacesRulesForAllDomains(),
|
|
103
108
|
this.getAdsReplaceUrlsBlacklist(),
|
|
104
109
|
this.getNegativeSelectorsForAllProviders(),
|
|
105
|
-
this.getElementsToHideOrRemoveRules()
|
|
110
|
+
this.getElementsToHideOrRemoveRules(),
|
|
111
|
+
this.getProvidersCategories()
|
|
106
112
|
]);
|
|
107
113
|
|
|
108
114
|
return {
|
|
@@ -115,6 +121,7 @@ export class TempleWalletApi {
|
|
|
115
121
|
adsReplaceUrlsBlacklist,
|
|
116
122
|
providersNegativeSelectors,
|
|
117
123
|
elementsToHideOrRemoveRules,
|
|
124
|
+
providersCategories,
|
|
118
125
|
timestamp: Date.now()
|
|
119
126
|
};
|
|
120
127
|
};
|
|
@@ -3,6 +3,8 @@ import { isEqual } from 'lodash';
|
|
|
3
3
|
import { AdPlacesRule, AdsRules } from 'src/types/ads-rules';
|
|
4
4
|
import { RawAllAdsRules, RawPermanentAdPlacesRule } from 'src/types/temple-wallet-api';
|
|
5
5
|
|
|
6
|
+
import { CRYPTO_CATEGORY_NAME } from './constants';
|
|
7
|
+
|
|
6
8
|
export const transformRawRules = (location: Location, rules: RawAllAdsRules): AdsRules => {
|
|
7
9
|
const {
|
|
8
10
|
adPlacesRulesForAllDomains,
|
|
@@ -14,6 +16,7 @@ export const transformRawRules = (location: Location, rules: RawAllAdsRules): Ad
|
|
|
14
16
|
permanentNativeAdPlacesRulesForAllDomains = {},
|
|
15
17
|
adsReplaceUrlsBlacklist = [],
|
|
16
18
|
elementsToHideOrRemoveRules = {},
|
|
19
|
+
providersCategories = {},
|
|
17
20
|
timestamp
|
|
18
21
|
} = rules;
|
|
19
22
|
const { hostname, href } = location;
|
|
@@ -50,14 +53,16 @@ export const transformRawRules = (location: Location, rules: RawAllAdsRules): Ad
|
|
|
50
53
|
hrefMatchPredicate,
|
|
51
54
|
providersRulesForAllDomains,
|
|
52
55
|
providersSelectors,
|
|
53
|
-
providersToReplaceAtAllSites
|
|
56
|
+
providersToReplaceAtAllSites,
|
|
57
|
+
providersCategories
|
|
54
58
|
),
|
|
55
59
|
providersNegativeSelectors: buildProvidersSelectors(
|
|
56
60
|
hostname,
|
|
57
61
|
hrefMatchPredicate,
|
|
58
62
|
providersRulesForAllDomains,
|
|
59
63
|
providersNegativeSelectors,
|
|
60
|
-
providersToReplaceAtAllSites
|
|
64
|
+
providersToReplaceAtAllSites,
|
|
65
|
+
providersCategories
|
|
61
66
|
),
|
|
62
67
|
elementsToHideOrRemoveRules: buildElementsToHideOrRemoveRules(
|
|
63
68
|
hostname,
|
|
@@ -163,7 +168,8 @@ const buildProvidersSelectors = (
|
|
|
163
168
|
hrefMatchPredicate: (regex: RegExp) => boolean,
|
|
164
169
|
providersRulesForAllDomains: RawAllAdsRules['providersRulesForAllDomains'],
|
|
165
170
|
providersSelectors: RawAllAdsRules['providersSelectors'],
|
|
166
|
-
providersToReplaceAtAllSites: RawAllAdsRules['providersToReplaceAtAllSites']
|
|
171
|
+
providersToReplaceAtAllSites: RawAllAdsRules['providersToReplaceAtAllSites'],
|
|
172
|
+
providersCategories: RawAllAdsRules['providersCategories']
|
|
167
173
|
): AdsRules['providersSelectors'] => {
|
|
168
174
|
const providersRulesByHostname = (providersRulesForAllDomains[hostname] ?? []).map(
|
|
169
175
|
({ urlRegexes, ...restRuleProps }) => ({
|
|
@@ -176,19 +182,24 @@ const buildProvidersSelectors = (
|
|
|
176
182
|
urlRegexes.some(hrefMatchPredicate)
|
|
177
183
|
);
|
|
178
184
|
const alreadyProcessedProviders = new Set<string>();
|
|
179
|
-
const
|
|
185
|
+
const adsSelectors: Record<string, Record<number, Set<string>>> = {};
|
|
180
186
|
const handleProvider = (provider: string) => {
|
|
181
187
|
if (alreadyProcessedProviders.has(provider)) return;
|
|
182
188
|
|
|
189
|
+
const categoriesSlug = (providersCategories[provider] ?? [CRYPTO_CATEGORY_NAME]).join('|');
|
|
183
190
|
const newSelectors = providersSelectors[provider] ?? [];
|
|
184
191
|
newSelectors.forEach(selector => {
|
|
185
192
|
const { selector: cssString, parentDepth } =
|
|
186
193
|
typeof selector === 'string' ? { selector, parentDepth: 0 } : selector;
|
|
187
194
|
|
|
188
|
-
if (!
|
|
189
|
-
|
|
195
|
+
if (!adsSelectors[categoriesSlug]) {
|
|
196
|
+
adsSelectors[categoriesSlug] = {};
|
|
197
|
+
}
|
|
198
|
+
const sameCategoriesAdsSelectors = adsSelectors[categoriesSlug];
|
|
199
|
+
if (!sameCategoriesAdsSelectors[parentDepth]) {
|
|
200
|
+
sameCategoriesAdsSelectors[parentDepth] = new Set();
|
|
190
201
|
}
|
|
191
|
-
|
|
202
|
+
sameCategoriesAdsSelectors[parentDepth].add(cssString);
|
|
192
203
|
});
|
|
193
204
|
alreadyProcessedProviders.add(provider);
|
|
194
205
|
};
|
|
@@ -196,8 +207,13 @@ const buildProvidersSelectors = (
|
|
|
196
207
|
providersToReplaceAtAllSites.forEach(handleProvider);
|
|
197
208
|
relatedProvidersRulesByUrl.forEach(({ providers }) => providers.forEach(handleProvider));
|
|
198
209
|
|
|
199
|
-
return Object.entries(
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
210
|
+
return Object.entries(adsSelectors)
|
|
211
|
+
.map(([categoriesSlug, sameCategoriesSelectors]) =>
|
|
212
|
+
Object.entries(sameCategoriesSelectors).map(([parentDepth, selectors]) => ({
|
|
213
|
+
parentDepth: Number(parentDepth),
|
|
214
|
+
selector: quickJoinSelectors(selectors),
|
|
215
|
+
categories: categoriesSlug.split('|')
|
|
216
|
+
}))
|
|
217
|
+
)
|
|
218
|
+
.flat();
|
|
203
219
|
};
|
package/src/types/ad-view.ts
CHANGED
package/src/types/ads-actions.ts
CHANGED
|
@@ -29,6 +29,8 @@ interface InsertAdActionProps
|
|
|
29
29
|
adsMetadata: (number | AdMetadata)[];
|
|
30
30
|
elementStyle?: StringRecord<string>;
|
|
31
31
|
stylesOverrides?: AdStylesOverrides[];
|
|
32
|
+
originalWidth: number;
|
|
33
|
+
originalHeight: number;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export interface ReplaceAllChildrenWithAdAction extends AdActionBase, InsertAdActionProps {
|
|
@@ -60,7 +62,7 @@ export interface HideElementAction extends AdActionBase {
|
|
|
60
62
|
|
|
61
63
|
export type InsertAdAction = ReplaceAllChildrenWithAdAction | ReplaceElementWithAdAction | SimpleInsertAdAction;
|
|
62
64
|
|
|
63
|
-
export type OmitAdInAction<T extends InsertAdActionProps> = Omit<T, 'adsMetadata'>;
|
|
65
|
+
export type OmitAdInAction<T extends InsertAdActionProps> = Omit<T, 'adsMetadata' | 'originalWidth' | 'originalHeight'>;
|
|
64
66
|
|
|
65
67
|
export type InsertAdActionWithoutMeta =
|
|
66
68
|
| OmitAdInAction<ReplaceAllChildrenWithAdAction>
|
|
@@ -73,5 +75,6 @@ export type AddActionsIfAdResolutionAvailable = (
|
|
|
73
75
|
elementsToMeasure: Record<'width' | 'height', HTMLElement>,
|
|
74
76
|
adType: AdType,
|
|
75
77
|
adIsNative: boolean,
|
|
78
|
+
expectedCategories: string[],
|
|
76
79
|
...actionsBases: (InsertAdActionWithoutMeta | HideElementAction | RemoveElementAction)[]
|
|
77
80
|
) => boolean;
|
package/src/types/ads-meta.ts
CHANGED
|
@@ -1,26 +1,11 @@
|
|
|
1
|
-
interface
|
|
1
|
+
export interface AdSource {
|
|
2
2
|
shouldNotUseStrictContainerLimits?: boolean;
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/** Only covers TKEY ads for now */
|
|
6
|
-
interface TempleAdSource extends AdSourceBase {
|
|
7
|
-
providerName: 'Temple';
|
|
3
|
+
providerName: 'Temple' | 'Persona' | 'HypeLab' | 'SmartyAds';
|
|
8
4
|
native?: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface PersonaAdSource extends AdSourceBase {
|
|
12
|
-
providerName: 'Persona';
|
|
13
5
|
slug: string;
|
|
6
|
+
categories?: string[];
|
|
14
7
|
}
|
|
15
8
|
|
|
16
|
-
export interface HypeLabAdSource extends AdSourceBase {
|
|
17
|
-
providerName: 'HypeLab';
|
|
18
|
-
native: boolean;
|
|
19
|
-
slug: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
type AdSource = HypeLabAdSource | TempleAdSource | PersonaAdSource;
|
|
23
|
-
|
|
24
9
|
export interface AdDimensions {
|
|
25
10
|
width: number;
|
|
26
11
|
height: number;
|
package/src/types/ads-rules.ts
CHANGED
|
@@ -17,7 +17,7 @@ export interface ElementsToHideOrRemoveRule extends Omit<RawElementsToHideOrRemo
|
|
|
17
17
|
export interface AdsRules {
|
|
18
18
|
adPlacesRules: Array<Omit<AdPlacesRule, 'urlRegexes'>>;
|
|
19
19
|
permanentAdPlacesRules: PermanentAdPlacesRule[];
|
|
20
|
-
providersSelectors: Array<{ selector: string; parentDepth: number }>;
|
|
20
|
+
providersSelectors: Array<{ selector: string; parentDepth: number; categories: string[] }>;
|
|
21
21
|
providersNegativeSelectors: Array<{ selector: string; parentDepth: number }>;
|
|
22
22
|
elementsToHideOrRemoveRules: ElementsToHideOrRemoveRule[];
|
|
23
23
|
timestamp: number;
|
|
@@ -65,6 +65,7 @@ export interface RawElementsToHideOrRemoveEntry {
|
|
|
65
65
|
|
|
66
66
|
export interface RawAllAdsRules {
|
|
67
67
|
adPlacesRulesForAllDomains: Record<string, RawAdPlacesRule[]>;
|
|
68
|
+
providersCategories: Record<string, string[]>;
|
|
68
69
|
providersRulesForAllDomains: Record<string, RawAdProvidersRule[]>;
|
|
69
70
|
providersSelectors: Record<string, (string | { selector: string; parentDepth: number })[]>;
|
|
70
71
|
providersNegativeSelectors: Record<string, (string | { selector: string; parentDepth: number })[]>;
|
package/src/utils.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
export const IS_DEV = process && process.env && process.env.NODE_ENV === 'development';
|
|
2
|
-
|
|
3
|
-
export const IS_MAC_OS = navigator.userAgent.includes('Macintosh');
|
|
4
|
-
|
|
5
1
|
/** From lodash */
|
|
6
2
|
type Truthy<T> = T extends null | undefined | void | false | '' | 0 | 0n ? never : T;
|
|
7
3
|
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import memoizee from 'memoizee';
|
|
2
|
-
import * as lodash from 'lodash';
|
|
3
|
-
|
|
4
|
-
declare function processAnchors(supportedDomains: Set<string>, AdsBrowserExtensionMessageType: AdsBrowserExtensionMessageTypeI): Promise<undefined>;
|
|
5
|
-
interface AdsBrowserExtensionMessageTypeI {
|
|
6
|
-
FetchReferrals: string;
|
|
7
|
-
ReferralClick: string;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* API docs: https://docs.takeads.com
|
|
12
|
-
*/
|
|
13
|
-
declare class TakeAdsClient {
|
|
14
|
-
private publicKey;
|
|
15
|
-
readonly apiUrl: string;
|
|
16
|
-
private axios;
|
|
17
|
-
constructor(publicKey: string, apiUrl?: string);
|
|
18
|
-
affiliateLinks(websiteUrls: string[], subId?: string): Promise<TekeadsAffiliateResponse>;
|
|
19
|
-
}
|
|
20
|
-
declare const buildTakeadsClient: ((publicKey: string) => TakeAdsClient) & memoizee.Memoized<(publicKey: string) => TakeAdsClient>;
|
|
21
|
-
interface TekeadsAffiliateResponse {
|
|
22
|
-
data: AffiliateLink[];
|
|
23
|
-
}
|
|
24
|
-
interface AffiliateLink {
|
|
25
|
-
iri: string;
|
|
26
|
-
trackingLink: string;
|
|
27
|
-
imageUrl: string | null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Current page's domain with 'www' stripped off */
|
|
31
|
-
declare const getCurrentPageDomain: (() => string) & lodash.MemoizedFunction;
|
|
32
|
-
|
|
33
|
-
export { buildTakeadsClient, getCurrentPageDomain, processAnchors };
|