@surfside/ads-core-web 0.1.0 → 0.1.2
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/README.md +15 -15
- package/lib/cjs/debug/carousel.js +74 -0
- package/lib/cjs/debug/carousel.js.map +1 -0
- package/lib/cjs/helpers/Dom.js +52 -0
- package/lib/cjs/helpers/Dom.js.map +1 -0
- package/lib/cjs/helpers/Trackers.js +20 -0
- package/lib/cjs/helpers/Trackers.js.map +1 -0
- package/lib/cjs/helpers/index.js +19 -0
- package/lib/cjs/helpers/index.js.map +1 -0
- package/lib/cjs/index.js +49 -6099
- package/lib/cjs/index.js.map +1 -0
- package/lib/cjs/rendering/Banner.js +93 -0
- package/lib/cjs/rendering/Banner.js.map +1 -0
- package/lib/cjs/rendering/Carousel.js +350 -0
- package/lib/cjs/rendering/Carousel.js.map +1 -0
- package/lib/cjs/rendering/Framework.js +90 -0
- package/lib/cjs/rendering/Framework.js.map +1 -0
- package/lib/cjs/rendering/ProductCard.js +106 -0
- package/lib/cjs/rendering/ProductCard.js.map +1 -0
- package/lib/cjs/rendering/Video.js +299 -0
- package/lib/cjs/rendering/Video.js.map +1 -0
- package/lib/cjs/rendering/Watermark.js +59 -0
- package/lib/cjs/rendering/Watermark.js.map +1 -0
- package/lib/cjs/rendering/index.js +23 -0
- package/lib/cjs/rendering/index.js.map +1 -0
- package/lib/esm/debug/carousel.js +72 -0
- package/lib/esm/debug/carousel.js.map +1 -0
- package/lib/esm/helpers/Dom.js +43 -0
- package/lib/esm/helpers/Dom.js.map +1 -0
- package/lib/esm/helpers/Trackers.js +15 -0
- package/lib/esm/helpers/Trackers.js.map +1 -0
- package/lib/esm/helpers/index.js +3 -0
- package/lib/esm/helpers/index.js.map +1 -0
- package/lib/esm/index.js +26 -6063
- package/lib/esm/index.js.map +1 -0
- package/lib/esm/rendering/Banner.js +88 -0
- package/lib/esm/rendering/Banner.js.map +1 -0
- package/lib/esm/rendering/Carousel.js +344 -0
- package/lib/esm/rendering/Carousel.js.map +1 -0
- package/lib/esm/rendering/Framework.js +83 -0
- package/lib/esm/rendering/Framework.js.map +1 -0
- package/lib/esm/rendering/ProductCard.js +101 -0
- package/lib/esm/rendering/ProductCard.js.map +1 -0
- package/lib/esm/rendering/Video.js +295 -0
- package/lib/esm/rendering/Video.js.map +1 -0
- package/lib/esm/rendering/Watermark.js +55 -0
- package/lib/esm/rendering/Watermark.js.map +1 -0
- package/lib/esm/rendering/index.js +7 -0
- package/lib/esm/rendering/index.js.map +1 -0
- package/package.json +37 -27
- package/lib/types/debug/dist/index-7was9ptg.d.ts +0 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"src/","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,qBAAqB,EACrB,EAAE,GAIL,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAyB,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAuB,MAAM,aAAa,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAA4B,MAAM,yBAAyB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAsB,MAAM,mBAAmB,CAAC;AAEpE,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAS1B,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EACvC,WAA4C,EAChB,EAAE;IAC9B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC;IACjC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACb,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,MAAM,EACF,MAAM,EACN,aAAa,EACb,MAAM,EACN,GAAG,EACH,2BAA2B,EAC3B,SAAS,EACZ,GAAG,MAAM,CAAC,KAAK,CAAC;IAEjB,2BAA2B,CAAC,EAAE,CAAC,CAAC;IAEhC,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC1D,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAC9D,aAAa,CAAC,SAAS,CAAC,qBAAqB,EAC7C,aAAa,CAAC,SAAS,CAAC,mBAAmB,EAC3C,2BAA2B,CAC9B,CAAC;IACF,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EACxD,2BAA2B,EAC3B,aAAa,CAAC,QAAQ,CAAC,kBAAkB,KAAK,IAAI,EAClD,aAAa,CAAC,SAAS,CAAC,qBAAqB,EAC7C,aAAa,CAAC,SAAS,CAAC,kBAAkB,EAC1C,aAAa,CAAC,SAAS,CAAC,mBAAmB,CAC9C,CAAC;IAEF,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAE1F,OAAO,EAAE,CAAC;QACN,GAAG,MAAM,CAAC,KAAK;QACf,YAAY;QACZ,iBAAiB;QACjB,cAAc;QACd,WAAW;KACd,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAC/B,SAAiB,EACjB,MAAc,EACd,SAAiB,EACjB,UAAkB,EAClB,MAA0B,EAC1B,MAAgB,EACY,EAAE;IAC9B,OAAO,sBAAsB,CAAC,qBAAqB,CAC/C,SAAS,EACT,MAAM,EACN,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,CACT,CAAC,CAAC;AACP,CAAC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Ctx, Err, Ok } from '@surfside/ads-core';
|
|
2
|
+
import { ReplaceWith, Template } from './Framework';
|
|
3
|
+
import { RenderWatermark } from './Watermark';
|
|
4
|
+
import { PixelTracker } from '../helpers/Trackers';
|
|
5
|
+
export const RenderBanner = (logger, builtBanner) => {
|
|
6
|
+
const log = Ctx(logger)?.with('RenderBanner');
|
|
7
|
+
log?.info('Rendering banner');
|
|
8
|
+
log?.debug(builtBanner);
|
|
9
|
+
/* Create container dom element */
|
|
10
|
+
const bannerContainer = document.createElement('div');
|
|
11
|
+
const shadow = bannerContainer.attachShadow({ mode: 'open' });
|
|
12
|
+
const creativeContainerRes = Template(log, 'surfside-banner', template, style);
|
|
13
|
+
if (!creativeContainerRes.ok) {
|
|
14
|
+
return creativeContainerRes;
|
|
15
|
+
}
|
|
16
|
+
const creativeContainer = creativeContainerRes.value;
|
|
17
|
+
shadow.appendChild(creativeContainer);
|
|
18
|
+
log?.debug('aspect', `${builtBanner.bid.w} / ${builtBanner.bid.h}`);
|
|
19
|
+
if (builtBanner.bid.w !== undefined && builtBanner.bid.h !== undefined) {
|
|
20
|
+
creativeContainer.style.aspectRatio = `${builtBanner.bid.w} / ${builtBanner.bid.h}`;
|
|
21
|
+
}
|
|
22
|
+
/* Create adm container */
|
|
23
|
+
const admContainerRes = Template(log, 'surfside-banner-adm', builtBanner.adm);
|
|
24
|
+
if (!admContainerRes.ok) {
|
|
25
|
+
return admContainerRes;
|
|
26
|
+
}
|
|
27
|
+
/* Replace adm container in template with new adm container */
|
|
28
|
+
const admRes = ReplaceWith(creativeContainer, '.surfside-banner-adm', admContainerRes.value);
|
|
29
|
+
if (!admRes.ok) {
|
|
30
|
+
return admRes;
|
|
31
|
+
}
|
|
32
|
+
/* Create Watermark */
|
|
33
|
+
const watermark = RenderWatermark(log);
|
|
34
|
+
if (!watermark.ok) {
|
|
35
|
+
return watermark;
|
|
36
|
+
}
|
|
37
|
+
/* Replace watermark container in template with new watermark container */
|
|
38
|
+
const watermarkRes = ReplaceWith(creativeContainer, '.surfside-banner-watermark', watermark.value);
|
|
39
|
+
if (!watermarkRes.ok) {
|
|
40
|
+
return watermarkRes;
|
|
41
|
+
}
|
|
42
|
+
const tracker = builtBanner.bid.nurl;
|
|
43
|
+
if (tracker === undefined) {
|
|
44
|
+
return Err(new MissingNurlError(builtBanner));
|
|
45
|
+
}
|
|
46
|
+
log?.debug('Appending banner win pixel', tracker);
|
|
47
|
+
creativeContainer.appendChild(PixelTracker(tracker));
|
|
48
|
+
return Ok(bannerContainer);
|
|
49
|
+
};
|
|
50
|
+
export class MissingNurlError extends Error {
|
|
51
|
+
bannerResponse;
|
|
52
|
+
constructor(bannerResponse) {
|
|
53
|
+
super('Missing win URL in banner - cannot render banner as it would result in uncounted impressions');
|
|
54
|
+
this.bannerResponse = bannerResponse;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
;
|
|
58
|
+
const template = `<div>
|
|
59
|
+
<div class="surfside-banner-adm">
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
<div class="surfside-banner-watermark">
|
|
63
|
+
|
|
64
|
+
</div>
|
|
65
|
+
</div>
|
|
66
|
+
`;
|
|
67
|
+
const style = `.surfside-banner {
|
|
68
|
+
position: relative;
|
|
69
|
+
display: inline-block;
|
|
70
|
+
overflow: hidden;
|
|
71
|
+
max-width: 100%;
|
|
72
|
+
height: auto;
|
|
73
|
+
width: 100%;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.surfside-banner-adm {
|
|
77
|
+
display: flex;
|
|
78
|
+
|
|
79
|
+
a {
|
|
80
|
+
width: 100%;
|
|
81
|
+
|
|
82
|
+
img {
|
|
83
|
+
width: 100%;
|
|
84
|
+
height: auto;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}`;
|
|
88
|
+
//# sourceMappingURL=Banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Banner.js","sourceRoot":"src/","sources":["rendering/Banner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { ConsumeNAsync, Ctx, Err, Ok, } from '@surfside/ads-core-client';
|
|
2
|
+
import { RenderProductCard } from './ProductCard';
|
|
3
|
+
import { GetNumberAttributeOr } from '../helpers/Dom';
|
|
4
|
+
import { Template } from './Framework';
|
|
5
|
+
;
|
|
6
|
+
;
|
|
7
|
+
;
|
|
8
|
+
export const RenderCarousel = async (logger, evaluateProductCardTemplate, sponsoredByEnabled, productCardStylesheet, carouselStylesheet, callbacks, carousel, cardMinWidth, carouselLimits, nextType) => {
|
|
9
|
+
const log = Ctx(logger)?.with('RenderCarousel');
|
|
10
|
+
log?.info('Rendering Carousel', cardMinWidth, carouselLimits);
|
|
11
|
+
const container = Template(log, 'surf-carousel', template, style + '\n' + carouselStylesheet);
|
|
12
|
+
if (!container.ok) {
|
|
13
|
+
return container;
|
|
14
|
+
}
|
|
15
|
+
log?.debug(container.value.outerHTML);
|
|
16
|
+
const rightArrow = container.value.querySelector('.arrow.right') ?? null;
|
|
17
|
+
const leftArrow = container.value.querySelector('.arrow.left') ?? null;
|
|
18
|
+
const items = container.value.querySelector('.items') ?? null;
|
|
19
|
+
if (rightArrow === null || leftArrow === null || items === null) {
|
|
20
|
+
return Err(new MalformedCarouselError(container.value));
|
|
21
|
+
}
|
|
22
|
+
const carouselState = {
|
|
23
|
+
element: container.value,
|
|
24
|
+
init: async () => {
|
|
25
|
+
const firstPage = await handleNextPage(log, evaluateProductCardTemplate, sponsoredByEnabled, productCardStylesheet, callbacks, container.value, items, cardMinWidth, carouselLimits, nextType, generator);
|
|
26
|
+
if (!firstPage.ok) {
|
|
27
|
+
return firstPage;
|
|
28
|
+
}
|
|
29
|
+
else if (firstPage.value.length === 0) {
|
|
30
|
+
log?.info('First page was empty!');
|
|
31
|
+
return Err(new EmptyFirstPageError(container.value));
|
|
32
|
+
}
|
|
33
|
+
log?.info('First page not empty', firstPage);
|
|
34
|
+
return Ok(true);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const generator = carousel.getProduct();
|
|
38
|
+
rightArrow.addEventListener('click', () => {
|
|
39
|
+
handleNextPage(log, evaluateProductCardTemplate, sponsoredByEnabled, productCardStylesheet, callbacks, container.value, items, cardMinWidth, carouselLimits, nextType, generator);
|
|
40
|
+
});
|
|
41
|
+
leftArrow.addEventListener('click', () => {
|
|
42
|
+
handleBackPage(log, sponsoredByEnabled, container.value, items, cardMinWidth);
|
|
43
|
+
});
|
|
44
|
+
return Ok(carouselState);
|
|
45
|
+
};
|
|
46
|
+
const addItems = (logger, stylesheet, callbacks, evaluateProductCardTemplate, items, itemsDiv, minWidth) => {
|
|
47
|
+
const log = Ctx(logger)?.with('addItems');
|
|
48
|
+
log?.info('Adding items to carousel', items.length);
|
|
49
|
+
const renderedCards = [];
|
|
50
|
+
for (const item of items) {
|
|
51
|
+
const productCard = RenderProductCard(log, stylesheet, callbacks, evaluateProductCardTemplate, item);
|
|
52
|
+
if (!productCard.ok) {
|
|
53
|
+
log?.warn('Failed to render product card, skipping', productCard.error);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
log?.debug('Rendering card', productCard.value.outerHTML);
|
|
57
|
+
const cardIndex = itemsDiv.children.length;
|
|
58
|
+
productCard.value.classList.add(`card-${cardIndex}`);
|
|
59
|
+
productCard.value.classList.add('surf-product-card');
|
|
60
|
+
productCard.value.style.width = `${minWidth}px`;
|
|
61
|
+
itemsDiv.appendChild(productCard.value);
|
|
62
|
+
renderedCards.push(item);
|
|
63
|
+
}
|
|
64
|
+
return renderedCards;
|
|
65
|
+
};
|
|
66
|
+
const handleNextPage = async (logger, evaluateProductCardTemplate, sponsoredByEnabled, stylesheet, callbacks, rootElement, itemsDiv, cardMinWidth, carouselLimits, nextType, carouselGenerator) => {
|
|
67
|
+
const log = Ctx(logger)?.with('handleNextPage');
|
|
68
|
+
log?.info('Handling next page request');
|
|
69
|
+
log?.debug(cardMinWidth, carouselLimits);
|
|
70
|
+
/* Get the card which the carousel is currently scrolled to (i.e, the left-most card) */
|
|
71
|
+
const currentIndex = GetNumberAttributeOr(itemsDiv, 'current-index', 0);
|
|
72
|
+
/* Get the total number of cards which have been rendered so far */
|
|
73
|
+
const totalRendered = itemsDiv.childElementCount;
|
|
74
|
+
log?.debug('currentIndex', currentIndex);
|
|
75
|
+
log?.debug('totalRendered', totalRendered);
|
|
76
|
+
/* Calculate how many cards fit into view currently */
|
|
77
|
+
const slotsAvailable = Math.ceil(rootElement.clientWidth / cardMinWidth);
|
|
78
|
+
log?.debug('slotsAvailable', slotsAvailable);
|
|
79
|
+
/* Calculate the total number of cards which have already been rendered to the RIGHT of the current page */
|
|
80
|
+
const totalSlotsRenderedAfterThisPage = Math.max(0, Math.min(totalRendered, totalRendered - (currentIndex + slotsAvailable)));
|
|
81
|
+
logger?.table({
|
|
82
|
+
clientWidth: itemsDiv.clientWidth,
|
|
83
|
+
currentIndex,
|
|
84
|
+
totalRendered,
|
|
85
|
+
slotsAvailable,
|
|
86
|
+
totalSlotsRenderedAfterThisPage
|
|
87
|
+
});
|
|
88
|
+
const numberOfCardsToAdd = Math.max(0, (() => {
|
|
89
|
+
/* NextType = product means only request a single product */
|
|
90
|
+
if (nextType === 'product') {
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
else if (carouselLimits.type === 'infinite') {
|
|
94
|
+
/* If infinite, that means we don't need to calculate how many slots are still available to fill,
|
|
95
|
+
* just request a whole page */
|
|
96
|
+
log?.debug('Infinite scroll, use slots available');
|
|
97
|
+
return slotsAvailable;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
/* If 'limited', we need to calculate how many slots are still available in the entire carousel */
|
|
101
|
+
const slotsRemaining = carouselLimits.limit - totalRendered;
|
|
102
|
+
return Math.min(slotsRemaining, slotsAvailable);
|
|
103
|
+
}
|
|
104
|
+
})() - totalSlotsRenderedAfterThisPage); /* Finally, remove the slots which have already been rendered within the
|
|
105
|
+
* next visible page scroll */
|
|
106
|
+
log?.debug('numberOfCardsToAdd', numberOfCardsToAdd);
|
|
107
|
+
const slotsVisible = Math.floor(rootElement.clientWidth / cardMinWidth);
|
|
108
|
+
if (numberOfCardsToAdd === 0) {
|
|
109
|
+
/* Scroll either to the calculated next page index, or to the last page, depending on which is smaller */
|
|
110
|
+
log?.info('No new cards requested');
|
|
111
|
+
log?.info('slotsVisible', slotsVisible);
|
|
112
|
+
const nextCardToScrollTo = Math.max(0, Math.min(totalRendered - slotsVisible, currentIndex + slotsVisible));
|
|
113
|
+
scrollTo(log, itemsDiv, nextCardToScrollTo);
|
|
114
|
+
checkSponsored(log, sponsoredByEnabled, rootElement, itemsDiv, nextCardToScrollTo, cardMinWidth);
|
|
115
|
+
return Ok([]);
|
|
116
|
+
}
|
|
117
|
+
const [builtProducts] = await ConsumeNAsync(carouselGenerator, numberOfCardsToAdd);
|
|
118
|
+
const nextCardToScrollTo = Math.min(currentIndex + slotsVisible, itemsDiv.childElementCount);
|
|
119
|
+
log?.info('Adding cards and scrolling!', numberOfCardsToAdd, builtProducts);
|
|
120
|
+
log?.info('builtProducts', builtProducts);
|
|
121
|
+
const items = addItems(log, stylesheet, callbacks, evaluateProductCardTemplate, builtProducts, itemsDiv, cardMinWidth);
|
|
122
|
+
scrollTo(log, itemsDiv, nextCardToScrollTo);
|
|
123
|
+
checkSponsored(log, sponsoredByEnabled, rootElement, itemsDiv, nextCardToScrollTo, cardMinWidth);
|
|
124
|
+
return Ok(items);
|
|
125
|
+
};
|
|
126
|
+
const handleBackPage = (logger, sponsoredByEnabled, rootElement, itemsDiv, cardMinWidth) => {
|
|
127
|
+
const log = Ctx(logger)?.with('handleBackPage');
|
|
128
|
+
log?.info('scrolling back');
|
|
129
|
+
const currentIndex = GetNumberAttributeOr(itemsDiv, 'current-index', 0);
|
|
130
|
+
const slotsInView = Math.floor(rootElement.clientWidth / cardMinWidth);
|
|
131
|
+
const nextIndex = Math.max(0, currentIndex - slotsInView);
|
|
132
|
+
scrollTo(log, itemsDiv, Math.max(0, currentIndex - slotsInView));
|
|
133
|
+
checkSponsored(log, sponsoredByEnabled, rootElement, itemsDiv, nextIndex, cardMinWidth);
|
|
134
|
+
};
|
|
135
|
+
const scrollTo = (logger, itemsDiv, index) => {
|
|
136
|
+
const log = Ctx(logger)?.with('scrollTo');
|
|
137
|
+
if (index === 0) {
|
|
138
|
+
log?.debug('Going back to origin');
|
|
139
|
+
itemsDiv.style.transform = 'translateX(0)';
|
|
140
|
+
itemsDiv.setAttribute('current-index', `${index}`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
;
|
|
144
|
+
log?.info(`Scrolling to item #${index}`);
|
|
145
|
+
const item = itemsDiv.querySelector(`.card-${index}`);
|
|
146
|
+
if (item === null) {
|
|
147
|
+
log?.warn(`Unable to scroll to .card-${index}: element does not exists`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const itemOffset = item.offsetLeft;
|
|
151
|
+
log?.info('itemOffset', itemOffset, item.clientWidth);
|
|
152
|
+
itemsDiv.setAttribute('current-index', `${index}`);
|
|
153
|
+
itemsDiv.style.transform = `translateX(calc(-${itemOffset}px + 37px))`;
|
|
154
|
+
};
|
|
155
|
+
const checkSponsored = (logger, sponsoredByEnabled, root, itemsDiv, index, cardMinWidth) => {
|
|
156
|
+
const log = Ctx(logger)?.with('checkSponsored');
|
|
157
|
+
log?.info('Checking sponsored tags');
|
|
158
|
+
const totalVisibleCards = Math.ceil(root.clientWidth / cardMinWidth);
|
|
159
|
+
const visibleCards = [];
|
|
160
|
+
for (let i = index; i < index + totalVisibleCards; i++) {
|
|
161
|
+
const card = itemsDiv.querySelector(`.card-${i}`);
|
|
162
|
+
if (card === null) {
|
|
163
|
+
break; // end of carousel, probably;
|
|
164
|
+
}
|
|
165
|
+
visibleCards.push(card);
|
|
166
|
+
}
|
|
167
|
+
const products = visibleCards
|
|
168
|
+
.map(card => card.productData)
|
|
169
|
+
.filter(product => product.sponsored);
|
|
170
|
+
const brands = new Set();
|
|
171
|
+
for (const product of products) {
|
|
172
|
+
brands.add(product.product.brandName ?? '');
|
|
173
|
+
}
|
|
174
|
+
const allSponsored = visibleCards.length === products.length;
|
|
175
|
+
log?.info('visibleCards', visibleCards.length, index);
|
|
176
|
+
const setTitle = (item, title, by) => {
|
|
177
|
+
item.classList.remove('sponsoredByMany');
|
|
178
|
+
item.classList.remove('sponsoredByOne');
|
|
179
|
+
item.classList.remove('recommended');
|
|
180
|
+
if (by !== undefined) {
|
|
181
|
+
item.innerHTML = by;
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
item.innerHTML = '';
|
|
185
|
+
}
|
|
186
|
+
item.classList.add(title);
|
|
187
|
+
};
|
|
188
|
+
if (sponsoredByEnabled === true) {
|
|
189
|
+
log?.info('Attempting sponsoredBy title');
|
|
190
|
+
const sponsoredBy = root.querySelector('.sponsored-by');
|
|
191
|
+
if (sponsoredBy === null) {
|
|
192
|
+
log?.error('Could not find sponsored by element');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
if (allSponsored) {
|
|
196
|
+
log?.info('All products are sponsored');
|
|
197
|
+
visibleCards.forEach(card => {
|
|
198
|
+
card.shadowRoot
|
|
199
|
+
?.querySelector('.surf-product-card')
|
|
200
|
+
?.classList.remove('sponsored');
|
|
201
|
+
});
|
|
202
|
+
if (brands.size === 1) {
|
|
203
|
+
log?.info('All brands are the same');
|
|
204
|
+
setTitle(sponsoredBy, 'sponsoredByOne', [...brands.values()][0]);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
log?.info('Multiple brands', brands);
|
|
208
|
+
setTitle(sponsoredBy, 'sponsoredByMany');
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
visibleCards.forEach(card => {
|
|
213
|
+
if (card.productData.sponsored) {
|
|
214
|
+
card.shadowRoot
|
|
215
|
+
?.querySelector('.surf-product-card')
|
|
216
|
+
?.classList.add('sponsored');
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
setTitle(sponsoredBy, 'recommended');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
export class MalformedCarouselError extends Error {
|
|
224
|
+
parent;
|
|
225
|
+
constructor(parent) {
|
|
226
|
+
super('Failed to construct carousel template! Missing child components');
|
|
227
|
+
this.parent = parent;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
;
|
|
231
|
+
export class EmptyFirstPageError extends Error {
|
|
232
|
+
parent;
|
|
233
|
+
constructor(parent) {
|
|
234
|
+
super('First page of carousel was empty. Returning nothing');
|
|
235
|
+
this.parent = parent;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
;
|
|
239
|
+
const template = `<div class="carousel-wrapper">
|
|
240
|
+
<div class="sponsored-by"></div>
|
|
241
|
+
<div class="surf-carousel">
|
|
242
|
+
<div class="items"></div>
|
|
243
|
+
</div>
|
|
244
|
+
<div class="arrows">
|
|
245
|
+
<div class="arrow left"></div>
|
|
246
|
+
<div class="arrow right"></div>
|
|
247
|
+
</div>
|
|
248
|
+
</div>`;
|
|
249
|
+
const style = `.surf-carousel {
|
|
250
|
+
width: 100%;
|
|
251
|
+
display: flex;
|
|
252
|
+
position: relative;
|
|
253
|
+
flex-grow: 1;
|
|
254
|
+
|
|
255
|
+
.sponsored-by {
|
|
256
|
+
font-family: 'Helvetica', Verdana, Geneva, Tahoma, sans-serif;
|
|
257
|
+
margin: 10px 0;
|
|
258
|
+
font-size: 24px;
|
|
259
|
+
|
|
260
|
+
&.sponsoredByOne::before {
|
|
261
|
+
content: 'Sponsored by ';
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
&.recommended::before {
|
|
265
|
+
content: 'Recommended';
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
&.sponsoredByMany::before {
|
|
269
|
+
content: 'Sponsored';
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.items {
|
|
274
|
+
z-index: 1;
|
|
275
|
+
display: flex;
|
|
276
|
+
flex-direction: row;
|
|
277
|
+
flex-grow: 1;
|
|
278
|
+
flex-wrap: nowrap;
|
|
279
|
+
align-items: stretch;
|
|
280
|
+
padding: 0 37px;
|
|
281
|
+
box-sizing: border-box;
|
|
282
|
+
transition: transform 0.4s ease-out;
|
|
283
|
+
|
|
284
|
+
.surf-product-card {
|
|
285
|
+
flex: 1;
|
|
286
|
+
display: flex;
|
|
287
|
+
padding: 5px;
|
|
288
|
+
box-sizing: border-box;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
.arrows {
|
|
296
|
+
|
|
297
|
+
.arrow {
|
|
298
|
+
z-index: 2;
|
|
299
|
+
position: absolute;
|
|
300
|
+
top: 50%;
|
|
301
|
+
transform: translateY(-50%);
|
|
302
|
+
width: 40px;
|
|
303
|
+
height: 40px;
|
|
304
|
+
display: flex;
|
|
305
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
306
|
+
margin: 0 1rem;
|
|
307
|
+
justify-content: center;
|
|
308
|
+
align-items: center;
|
|
309
|
+
border-radius: 50%;
|
|
310
|
+
cursor: pointer;
|
|
311
|
+
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.2),
|
|
312
|
+
0 2px 8px 0 rgba(0, 0, 0, 0.2);
|
|
313
|
+
|
|
314
|
+
&:hover {
|
|
315
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
&.left {
|
|
319
|
+
left: -10px;
|
|
320
|
+
|
|
321
|
+
&:before {
|
|
322
|
+
content: "";
|
|
323
|
+
background: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><path stroke="%23fff" stroke-opacity=".9" stroke-width="2" d="M24 10 14 20l10 10"/></svg>')
|
|
324
|
+
no-repeat center;
|
|
325
|
+
width: 40px;
|
|
326
|
+
height: 40px;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
&.right {
|
|
331
|
+
right: 0;
|
|
332
|
+
|
|
333
|
+
&:before {
|
|
334
|
+
content: "";
|
|
335
|
+
background: url('data:image/svg+xml;charset=UTF-8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" fill="none"><path stroke="%23fff" stroke-opacity=".9" stroke-width="2" d="M16 30l10-10L16 10"/></svg>')
|
|
336
|
+
no-repeat center;
|
|
337
|
+
width: 40px;
|
|
338
|
+
height: 40px;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}`;
|
|
344
|
+
//# sourceMappingURL=Carousel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Carousel.js","sourceRoot":"src/","sources":["rendering/Carousel.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Ctx, Err, Ok } from '@surfside/ads-core';
|
|
2
|
+
const BoundEvents = [
|
|
3
|
+
'click',
|
|
4
|
+
'mousemove',
|
|
5
|
+
'mouseover',
|
|
6
|
+
'mouseleave',
|
|
7
|
+
'mouseout',
|
|
8
|
+
'mouseup',
|
|
9
|
+
'mousedown',
|
|
10
|
+
'loadeddata',
|
|
11
|
+
'error',
|
|
12
|
+
'touchend',
|
|
13
|
+
'touchstart',
|
|
14
|
+
'touchmove'
|
|
15
|
+
];
|
|
16
|
+
;
|
|
17
|
+
export const Template = (logger, className, template, style, callbacks) => {
|
|
18
|
+
const log = Ctx(logger)?.with('Template');
|
|
19
|
+
log?.info('Rendering Template');
|
|
20
|
+
try {
|
|
21
|
+
const wrapper = document.createElement('div');
|
|
22
|
+
wrapper.classList.add(className);
|
|
23
|
+
if (style !== undefined) {
|
|
24
|
+
const styleElement = document.createElement('style');
|
|
25
|
+
styleElement.innerHTML = style;
|
|
26
|
+
wrapper.appendChild(styleElement);
|
|
27
|
+
}
|
|
28
|
+
wrapper.innerHTML += template;
|
|
29
|
+
if (callbacks !== undefined) {
|
|
30
|
+
log?.info('Adding callbacks');
|
|
31
|
+
for (const eventName of BoundEvents) {
|
|
32
|
+
log?.info('Adding', eventName);
|
|
33
|
+
const eventNameSelector = `_${eventName}`;
|
|
34
|
+
const boundNodes = wrapper.querySelectorAll(`[${eventNameSelector}]`);
|
|
35
|
+
log?.info('boundNodes', boundNodes);
|
|
36
|
+
boundNodes.forEach(node => {
|
|
37
|
+
log?.debug('binding node event ', eventNameSelector);
|
|
38
|
+
const handlerName = node.getAttribute(eventNameSelector);
|
|
39
|
+
if (handlerName === null) {
|
|
40
|
+
log?.warn('Failed to bind handler - handlerName is null');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const handler = callbacks.callbacks[handlerName];
|
|
44
|
+
if (handler === undefined) {
|
|
45
|
+
log?.warn('Could not find handler ', handlerName, callbacks.callbacks);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
log?.info('Added event ', eventNameSelector);
|
|
49
|
+
node.addEventListener(eventName, e => handler(e, callbacks.product));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return Ok(wrapper);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
return Err(err);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
export const QuerySelectorResult = (element, selector) => {
|
|
60
|
+
const child = element.querySelector(selector) ?? element.shadowRoot?.querySelector(selector) ?? null;
|
|
61
|
+
if (child === null) {
|
|
62
|
+
return Err(new MissingTemplateElementError(element, selector));
|
|
63
|
+
}
|
|
64
|
+
return Ok(child);
|
|
65
|
+
};
|
|
66
|
+
export const ReplaceWith = (parent, originalSelector, element) => {
|
|
67
|
+
const original = QuerySelectorResult(parent, originalSelector);
|
|
68
|
+
if (!original.ok) {
|
|
69
|
+
return original;
|
|
70
|
+
}
|
|
71
|
+
original.value.replaceWith(element);
|
|
72
|
+
return Ok(element);
|
|
73
|
+
};
|
|
74
|
+
export class MissingTemplateElementError extends Error {
|
|
75
|
+
parent;
|
|
76
|
+
selector;
|
|
77
|
+
constructor(parent, selector) {
|
|
78
|
+
super(`Missing child element "${selector}" on parent "${parent.tagName}"`);
|
|
79
|
+
this.parent = parent;
|
|
80
|
+
this.selector = selector;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=Framework.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Framework.js","sourceRoot":"src/","sources":["rendering/Framework.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Ctx, Err, EventTrackingMethods, Ok } from '@surfside/ads-core-client';
|
|
2
|
+
import { Template } from './Framework';
|
|
3
|
+
import { PixelTracker, ScriptTracker } from '../helpers/Trackers';
|
|
4
|
+
export const RenderProductCard = (logger, stylesheet, javascriptCallbacks, evaluateProductCardTemplate, productCard) => {
|
|
5
|
+
const log = Ctx(logger)?.with('RenderProductCard');
|
|
6
|
+
log?.info('Rendering product card');
|
|
7
|
+
log?.debug(productCard);
|
|
8
|
+
const container = document.createElement('div');
|
|
9
|
+
log?.info('product card container', container);
|
|
10
|
+
const shadow = container.attachShadow({ mode: 'open' });
|
|
11
|
+
const productCardHtml = evaluateProductCardTemplate(productCard.product, productCard.clickthrough);
|
|
12
|
+
if (!productCardHtml.ok) {
|
|
13
|
+
return productCardHtml;
|
|
14
|
+
}
|
|
15
|
+
logger?.info('productCardHtml', productCardHtml);
|
|
16
|
+
const productCardDomRes = Template(log, 'surf-product-card', productCardHtml.value, style + '\n' + stylesheet, {
|
|
17
|
+
callbacks: javascriptCallbacks,
|
|
18
|
+
product: productCard.product
|
|
19
|
+
});
|
|
20
|
+
if (!productCardDomRes.ok) {
|
|
21
|
+
return productCardDomRes;
|
|
22
|
+
}
|
|
23
|
+
if (productCard.sponsored) {
|
|
24
|
+
productCardDomRes.value.classList.add('sponsored');
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
log?.debug('Recommended', productCard);
|
|
28
|
+
}
|
|
29
|
+
productCardDomRes.value.style.display = 'flex';
|
|
30
|
+
log?.debug('Product Card Rendered');
|
|
31
|
+
shadow.appendChild(productCardDomRes.value);
|
|
32
|
+
attachClickthroughNotifiers(log, productCardDomRes.value, productCard.clickthrough);
|
|
33
|
+
if (productCard.trackers !== undefined) {
|
|
34
|
+
appendTrackers(log, productCardDomRes.value, productCard.trackers);
|
|
35
|
+
}
|
|
36
|
+
else if (productCard.sponsored) {
|
|
37
|
+
return Err(new MissingTrackersError(productCard));
|
|
38
|
+
}
|
|
39
|
+
container.productData = productCard;
|
|
40
|
+
return Ok(container);
|
|
41
|
+
};
|
|
42
|
+
const attachClickthroughNotifiers = (logger, root, clickthrough) => root.querySelectorAll('[_click]').forEach(e => e.addEventListener('click', callClickthroughNotifier(logger)(clickthrough)));
|
|
43
|
+
const callClickthroughNotifier = (logger) => (clickthrough) => () => {
|
|
44
|
+
const log = Ctx(logger)?.with('callClickthroughNotifier');
|
|
45
|
+
fetch(clickthrough)
|
|
46
|
+
.then(() => log?.debug('Called clickthrough notification'))
|
|
47
|
+
.catch(() => log?.debug('Called clickthrough handler, but got an error code. This is not ' +
|
|
48
|
+
'necessarily a problem, the clickthrough probably fired correctly.'));
|
|
49
|
+
};
|
|
50
|
+
const appendTrackers = (logger, root, trackers) => {
|
|
51
|
+
const log = Ctx(logger)?.with('appendTrackers');
|
|
52
|
+
log?.info('Appending trackers', trackers);
|
|
53
|
+
log?.debug('Appending win tracker', trackers.win);
|
|
54
|
+
root.appendChild(PixelTracker(trackers.win));
|
|
55
|
+
log?.debug('Appending impression trackers', trackers.imp);
|
|
56
|
+
trackers.imp
|
|
57
|
+
.map(PixelTracker)
|
|
58
|
+
.forEach(tracker => root.appendChild(tracker));
|
|
59
|
+
// Other javascript trackers
|
|
60
|
+
log?.debug('Appending other js trackers', trackers.others);
|
|
61
|
+
trackers.others.filter(t => t.type === EventTrackingMethods.JS)
|
|
62
|
+
.map(t => t.url)
|
|
63
|
+
.map(ScriptTracker)
|
|
64
|
+
.forEach(tracker => root.appendChild(tracker));
|
|
65
|
+
// Other pixel trackers
|
|
66
|
+
log?.debug('Appending other pixel trackers', trackers.others);
|
|
67
|
+
trackers.others.filter(t => t.type === EventTrackingMethods.Img)
|
|
68
|
+
.map(t => t.url)
|
|
69
|
+
.map(PixelTracker)
|
|
70
|
+
.forEach(tracker => root.appendChild(tracker));
|
|
71
|
+
};
|
|
72
|
+
export class MissingTrackersError extends Error {
|
|
73
|
+
productCardResponse;
|
|
74
|
+
constructor(productCardResponse) {
|
|
75
|
+
super('Sponsored product card response is missing trackers - cannot render card as it would ' +
|
|
76
|
+
'result in uncounted impressions');
|
|
77
|
+
this.productCardResponse = productCardResponse;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
;
|
|
81
|
+
const style = `.surf-product-card {
|
|
82
|
+
width: 100%;
|
|
83
|
+
|
|
84
|
+
&.sponsored {
|
|
85
|
+
position: relative;
|
|
86
|
+
|
|
87
|
+
&::after {
|
|
88
|
+
content: 'Sponsored';
|
|
89
|
+
position: absolute;
|
|
90
|
+
font-family: Verdana, Helvetica, 'sans-serif';
|
|
91
|
+
font-weight: 100;
|
|
92
|
+
color: rgba(0, 0, 0, 0.6);
|
|
93
|
+
font-size: 12px;
|
|
94
|
+
box-sizing: border-box;
|
|
95
|
+
bottom: -24px;
|
|
96
|
+
width: 100%;
|
|
97
|
+
text-align: center;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}`;
|
|
101
|
+
//# sourceMappingURL=ProductCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProductCard.js","sourceRoot":"src/","sources":["rendering/ProductCard.ts"],"names":[],"mappings":"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"}
|