@searchspring/snap-controller 0.72.1 → 0.73.5
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/cjs/Autocomplete/AutocompleteController.d.ts +13 -13
- package/dist/cjs/Autocomplete/AutocompleteController.d.ts.map +1 -1
- package/dist/cjs/Autocomplete/AutocompleteController.js +151 -147
- package/dist/cjs/Recommendation/RecommendationController.d.ts +5 -13
- package/dist/cjs/Recommendation/RecommendationController.d.ts.map +1 -1
- package/dist/cjs/Recommendation/RecommendationController.js +81 -92
- package/dist/cjs/Search/SearchController.d.ts +12 -5
- package/dist/cjs/Search/SearchController.d.ts.map +1 -1
- package/dist/cjs/Search/SearchController.js +144 -168
- package/dist/cjs/utils/isClickWithinBannerLink.d.ts +2 -0
- package/dist/cjs/utils/isClickWithinBannerLink.d.ts.map +1 -0
- package/dist/cjs/utils/isClickWithinBannerLink.js +21 -0
- package/dist/esm/Autocomplete/AutocompleteController.d.ts +13 -13
- package/dist/esm/Autocomplete/AutocompleteController.d.ts.map +1 -1
- package/dist/esm/Autocomplete/AutocompleteController.js +131 -139
- package/dist/esm/Recommendation/RecommendationController.d.ts +5 -13
- package/dist/esm/Recommendation/RecommendationController.d.ts.map +1 -1
- package/dist/esm/Recommendation/RecommendationController.js +72 -80
- package/dist/esm/Search/SearchController.d.ts +12 -5
- package/dist/esm/Search/SearchController.d.ts.map +1 -1
- package/dist/esm/Search/SearchController.js +128 -165
- package/dist/esm/utils/isClickWithinBannerLink.d.ts +2 -0
- package/dist/esm/utils/isClickWithinBannerLink.d.ts.map +1 -0
- package/dist/esm/utils/isClickWithinBannerLink.js +17 -0
- package/package.json +10 -10
|
@@ -4,8 +4,8 @@ import { AbstractController } from '../Abstract/AbstractController';
|
|
|
4
4
|
import { StorageStore, ErrorType } from '@searchspring/snap-store-mobx';
|
|
5
5
|
import { getSearchParams } from '../utils/getParams';
|
|
6
6
|
import { ControllerTypes } from '../types';
|
|
7
|
-
import { ItemTypeEnum, } from '@searchspring/beacon';
|
|
8
7
|
import { CLICK_DUPLICATION_TIMEOUT, isClickWithinProductLink } from '../utils/isClickWithinProductLink';
|
|
8
|
+
import { isClickWithinBannerLink } from '../utils/isClickWithinBannerLink';
|
|
9
9
|
const BACKGROUND_FILTER_FIELD_MATCHES = ['collection', 'category', 'categories', 'hierarchy', 'brand', 'manufacturer'];
|
|
10
10
|
const BACKGROUND_FILTERS_VALUE_FLAGS = [1, 0, '1', '0', 'true', 'false', true, false];
|
|
11
11
|
const defaultConfig = {
|
|
@@ -24,7 +24,6 @@ const defaultConfig = {
|
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
|
-
const schemaMap = {};
|
|
28
27
|
export class SearchController extends AbstractController {
|
|
29
28
|
constructor(config, { client, store, urlManager, eventManager, profiler, logger, tracker }, context) {
|
|
30
29
|
super(config, { client, store, urlManager, eventManager, profiler, logger, tracker }, context);
|
|
@@ -33,13 +32,56 @@ export class SearchController extends AbstractController {
|
|
|
33
32
|
this.page = {
|
|
34
33
|
type: 'search',
|
|
35
34
|
};
|
|
36
|
-
this.events = {
|
|
35
|
+
this.events = {};
|
|
37
36
|
this.track = {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (this.events
|
|
37
|
+
banner: {
|
|
38
|
+
impression: ({ uid, responseId }) => {
|
|
39
|
+
if (this.events[responseId]?.banner[uid]?.impression) {
|
|
41
40
|
return;
|
|
42
41
|
}
|
|
42
|
+
const banner = { uid };
|
|
43
|
+
const data = {
|
|
44
|
+
responseId,
|
|
45
|
+
banners: [banner],
|
|
46
|
+
results: [],
|
|
47
|
+
};
|
|
48
|
+
this.eventManager.fire('track.banner.impression', { controller: this, product: { uid }, trackEvent: data });
|
|
49
|
+
this.tracker.events[this.page.type].impression({ data, siteId: this.config.globals?.siteId });
|
|
50
|
+
this.events[responseId].banner[uid] = this.events[responseId].banner[uid] || {};
|
|
51
|
+
this.events[responseId].banner[uid].impression = true;
|
|
52
|
+
},
|
|
53
|
+
click: (e, banner) => {
|
|
54
|
+
const { responseId, uid } = banner;
|
|
55
|
+
if (isClickWithinBannerLink(e)) {
|
|
56
|
+
if (this.events?.[responseId]?.banner[uid]?.clickThrough) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.track.banner.clickThrough(e, banner);
|
|
60
|
+
this.events[responseId].banner[uid] = this.events[responseId].banner[uid] || {};
|
|
61
|
+
this.events[responseId].banner[uid].clickThrough = true;
|
|
62
|
+
setTimeout(() => {
|
|
63
|
+
this.events[responseId].banner[uid].clickThrough = false;
|
|
64
|
+
}, CLICK_DUPLICATION_TIMEOUT);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
clickThrough: (e, { uid, responseId }) => {
|
|
68
|
+
const banner = { uid };
|
|
69
|
+
const data = {
|
|
70
|
+
responseId,
|
|
71
|
+
banners: [banner],
|
|
72
|
+
};
|
|
73
|
+
this.eventManager.fire('track.banner.clickThrough', { controller: this, event: e, product: { uid }, trackEvent: data });
|
|
74
|
+
this.tracker.events[this.page.type].clickThrough({ data, siteId: this.config.globals?.siteId });
|
|
75
|
+
this.events[responseId].banner[uid] = this.events[responseId].banner[uid] || {};
|
|
76
|
+
this.events[responseId].banner[uid].clickThrough = true;
|
|
77
|
+
setTimeout(() => {
|
|
78
|
+
this.events[responseId].banner[uid].clickThrough = false;
|
|
79
|
+
}, CLICK_DUPLICATION_TIMEOUT);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
product: {
|
|
83
|
+
clickThrough: (e, result) => {
|
|
84
|
+
const responseId = result.responseId;
|
|
43
85
|
const target = e.target;
|
|
44
86
|
const resultHref = result.display?.mappings.core?.url || result.mappings.core?.url || '';
|
|
45
87
|
const elemHref = target?.getAttribute('href');
|
|
@@ -66,58 +108,88 @@ export class SearchController extends AbstractController {
|
|
|
66
108
|
}
|
|
67
109
|
// store position data or empty object
|
|
68
110
|
this.storage.set('scrollMap', scrollMap);
|
|
69
|
-
const
|
|
111
|
+
const item = {
|
|
112
|
+
type: result.type,
|
|
113
|
+
uid: result.id,
|
|
114
|
+
parentId: result.id,
|
|
115
|
+
sku: result.mappings.core?.sku,
|
|
116
|
+
};
|
|
117
|
+
const data = {
|
|
118
|
+
responseId,
|
|
119
|
+
results: [item],
|
|
120
|
+
};
|
|
70
121
|
this.eventManager.fire('track.product.clickThrough', { controller: this, event: e, product: result, trackEvent: data });
|
|
71
122
|
this.tracker.events[this.page.type].clickThrough({ data, siteId: this.config.globals?.siteId });
|
|
72
|
-
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
73
|
-
this.events.product[result.id].clickThrough = true;
|
|
74
123
|
},
|
|
75
124
|
click: (e, result) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
125
|
+
const responseId = result.responseId;
|
|
126
|
+
if (result.type === 'banner' && isClickWithinBannerLink(e)) {
|
|
127
|
+
if (this.events?.[responseId]?.product[result.id]?.inlineBannerClickThrough) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.track.product.clickThrough(e, result);
|
|
131
|
+
this.events[responseId].product[result.id] = this.events[responseId].product[result.id] || {};
|
|
132
|
+
this.events[responseId].product[result.id].inlineBannerClickThrough = true;
|
|
133
|
+
setTimeout(() => {
|
|
134
|
+
this.events[responseId].product[result.id].inlineBannerClickThrough = false;
|
|
135
|
+
}, CLICK_DUPLICATION_TIMEOUT);
|
|
81
136
|
}
|
|
82
|
-
isClickWithinProductLink(e, result)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
this.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
137
|
+
else if (isClickWithinProductLink(e, result)) {
|
|
138
|
+
if (this.events?.[responseId]?.product[result.id]?.productClickThrough) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
this.track.product.clickThrough(e, result);
|
|
142
|
+
this.events[responseId].product[result.id] = this.events[responseId].product[result.id] || {};
|
|
143
|
+
this.events[responseId].product[result.id].productClickThrough = true;
|
|
144
|
+
setTimeout(() => {
|
|
145
|
+
this.events[responseId].product[result.id].productClickThrough = false;
|
|
146
|
+
}, CLICK_DUPLICATION_TIMEOUT);
|
|
92
147
|
}
|
|
93
|
-
const data = schemaMap[result.id];
|
|
94
|
-
this.eventManager.fire('track.product.render', { controller: this, product: result, trackEvent: data });
|
|
95
|
-
this.tracker.events[this.page.type].render({ data, siteId: this.config.globals?.siteId });
|
|
96
|
-
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
97
|
-
this.events.product[result.id].render = true;
|
|
98
148
|
},
|
|
99
149
|
impression: (result) => {
|
|
100
|
-
|
|
150
|
+
const responseId = result.responseId;
|
|
151
|
+
if (this.events[responseId]?.product[result.id]?.impression) {
|
|
101
152
|
return;
|
|
102
153
|
}
|
|
103
|
-
const
|
|
154
|
+
const item = {
|
|
155
|
+
type: result.type,
|
|
156
|
+
uid: result.id,
|
|
157
|
+
parentId: result.id,
|
|
158
|
+
sku: result.mappings.core?.sku,
|
|
159
|
+
};
|
|
160
|
+
const data = {
|
|
161
|
+
responseId,
|
|
162
|
+
results: [item],
|
|
163
|
+
banners: [],
|
|
164
|
+
};
|
|
104
165
|
this.eventManager.fire('track.product.impression', { controller: this, product: result, trackEvent: data });
|
|
105
166
|
this.tracker.events[this.page.type].impression({ data, siteId: this.config.globals?.siteId });
|
|
106
|
-
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
107
|
-
this.events.product[result.id].impression = true;
|
|
167
|
+
this.events[responseId].product[result.id] = this.events[responseId].product[result.id] || {};
|
|
168
|
+
this.events[responseId].product[result.id].impression = true;
|
|
108
169
|
},
|
|
109
170
|
addToCart: (result) => {
|
|
110
|
-
const
|
|
171
|
+
const responseId = result.responseId;
|
|
172
|
+
const product = {
|
|
173
|
+
parentId: result.id,
|
|
174
|
+
uid: result.id,
|
|
175
|
+
sku: result.mappings.core?.sku,
|
|
176
|
+
qty: result.quantity || 1,
|
|
177
|
+
price: Number(result.mappings.core?.price),
|
|
178
|
+
};
|
|
179
|
+
const data = {
|
|
180
|
+
responseId,
|
|
181
|
+
results: [product],
|
|
182
|
+
};
|
|
111
183
|
this.eventManager.fire('track.product.addToCart', { controller: this, product: result, trackEvent: data });
|
|
112
|
-
this.tracker.events[this.page.type].addToCart({
|
|
113
|
-
data,
|
|
114
|
-
siteId: this.config.globals?.siteId,
|
|
115
|
-
});
|
|
184
|
+
this.tracker.events[this.page.type].addToCart({ data, siteId: this.config.globals?.siteId });
|
|
116
185
|
},
|
|
117
186
|
},
|
|
118
|
-
redirect: (redirectURL) => {
|
|
119
|
-
const data =
|
|
120
|
-
|
|
187
|
+
redirect: ({ redirectURL, responseId }) => {
|
|
188
|
+
const data = {
|
|
189
|
+
responseId,
|
|
190
|
+
redirect: redirectURL,
|
|
191
|
+
};
|
|
192
|
+
this.eventManager.fire('track.redirect', { controller: this, redirectURL, trackEvent: data });
|
|
121
193
|
this.tracker.events.search.redirect({ data, siteId: this.config.globals?.siteId });
|
|
122
194
|
},
|
|
123
195
|
};
|
|
@@ -156,7 +228,7 @@ export class SearchController extends AbstractController {
|
|
|
156
228
|
}
|
|
157
229
|
const searchProfile = this.profiler.create({ type: 'event', name: 'search', context: params }).start();
|
|
158
230
|
let meta = {};
|
|
159
|
-
let response
|
|
231
|
+
let response;
|
|
160
232
|
// infinite scroll functionality (after page 1)
|
|
161
233
|
if (this.config.settings?.infinite && params.pagination?.page && params.pagination.page > 1) {
|
|
162
234
|
const preventBackfill = this.config.settings.infinite?.backfill && !this.store.results.length && params.pagination.page > this.config.settings.infinite.backfill;
|
|
@@ -185,7 +257,7 @@ export class SearchController extends AbstractController {
|
|
|
185
257
|
}
|
|
186
258
|
}
|
|
187
259
|
backfillRequestsParams.push(backfillParams);
|
|
188
|
-
return this.client.
|
|
260
|
+
return this.client[this.page.type](backfillParams);
|
|
189
261
|
});
|
|
190
262
|
const backfillResponses = await Promise.all(backfillRequests);
|
|
191
263
|
// backfillResponses are [meta, searchResponse][]
|
|
@@ -193,8 +265,9 @@ export class SearchController extends AbstractController {
|
|
|
193
265
|
meta = backfillResponses[0][0];
|
|
194
266
|
response = backfillResponses[0][1];
|
|
195
267
|
// accumulate results from all backfill responses
|
|
196
|
-
const backfillResults = backfillResponses.reduce((results, response
|
|
197
|
-
|
|
268
|
+
const backfillResults = backfillResponses.reduce((results, response) => {
|
|
269
|
+
const responseId = response[1].tracking.responseId;
|
|
270
|
+
this.events[responseId] = this.events[responseId] || { product: {}, banner: {} };
|
|
198
271
|
return results.concat(...response[1].results);
|
|
199
272
|
}, []);
|
|
200
273
|
// overwrite pagination params to expected state
|
|
@@ -205,20 +278,20 @@ export class SearchController extends AbstractController {
|
|
|
205
278
|
}
|
|
206
279
|
else {
|
|
207
280
|
// infinite with no backfills.
|
|
208
|
-
[meta, response] = await this.client.
|
|
209
|
-
|
|
281
|
+
[meta, response] = await this.client[this.page.type](params);
|
|
282
|
+
const responseId = response.tracking.responseId;
|
|
283
|
+
this.events[responseId] = this.events[responseId] || { product: {}, banner: {} };
|
|
210
284
|
// append new results to previous results
|
|
211
285
|
response.results = [...this.previousResults, ...(response.results || [])];
|
|
212
286
|
}
|
|
213
287
|
}
|
|
214
288
|
else {
|
|
215
289
|
// normal request
|
|
216
|
-
// reset events for new search
|
|
217
|
-
this.events = { product: {} };
|
|
218
290
|
// clear previousResults to prevent infinite scroll from using them
|
|
219
291
|
this.previousResults = [];
|
|
220
|
-
[meta, response] = await this.client.
|
|
221
|
-
|
|
292
|
+
[meta, response] = await this.client[this.page.type](params);
|
|
293
|
+
const responseId = response.tracking.responseId;
|
|
294
|
+
this.events[responseId] = this.events[responseId] || { product: {}, banner: {} };
|
|
222
295
|
}
|
|
223
296
|
// MockClient will overwrite the client search() method and use SearchData to return mock data which already contains meta data
|
|
224
297
|
if (!response.meta) {
|
|
@@ -380,7 +453,7 @@ export class SearchController extends AbstractController {
|
|
|
380
453
|
if (redirectURL && config?.settings?.redirects?.merchandising && !search?.response?.filters?.length && !searchStore.loaded) {
|
|
381
454
|
//set loaded to true to prevent infinite search/reloading from happening
|
|
382
455
|
searchStore.loaded = true;
|
|
383
|
-
this.track.redirect(redirectURL);
|
|
456
|
+
this.track.redirect({ redirectURL, responseId: search.response.tracking.responseId });
|
|
384
457
|
window.location.replace(redirectURL);
|
|
385
458
|
return false;
|
|
386
459
|
}
|
|
@@ -441,21 +514,12 @@ export class SearchController extends AbstractController {
|
|
|
441
514
|
this.eventManager.on('afterStore', async (search, next) => {
|
|
442
515
|
await next();
|
|
443
516
|
const controller = search.controller;
|
|
517
|
+
const responseId = search.response.tracking.responseId;
|
|
444
518
|
if (controller.store.loaded && !controller.store.error) {
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
// handle no results
|
|
448
|
-
const data = getSearchSchemaData({ params: search.request, response: search.response });
|
|
449
|
-
this.eventManager.fire('track.product.render', { controller: this, trackEvent: data });
|
|
519
|
+
if (!search.response._cached) {
|
|
520
|
+
const data = { responseId };
|
|
450
521
|
this.tracker.events[this.page.type].render({ data, siteId: this.config.globals?.siteId });
|
|
451
522
|
}
|
|
452
|
-
products.forEach((result) => {
|
|
453
|
-
if (!search.response._cached) {
|
|
454
|
-
this.track.product.render(result);
|
|
455
|
-
}
|
|
456
|
-
this.events.product[result.id] = this.events.product[result.id] || {};
|
|
457
|
-
this.events.product[result.id].render = true;
|
|
458
|
-
});
|
|
459
523
|
const config = search.controller.config;
|
|
460
524
|
const nonBackgroundFilters = search?.request?.filters?.filter((filter) => !filter.background);
|
|
461
525
|
if (config?.settings?.redirects?.singleResult &&
|
|
@@ -582,26 +646,6 @@ export class SearchController extends AbstractController {
|
|
|
582
646
|
return params;
|
|
583
647
|
}
|
|
584
648
|
}
|
|
585
|
-
function createResultSchemaMapping({ request, response }) {
|
|
586
|
-
const [_, searchResponse] = response;
|
|
587
|
-
const schema = getSearchSchemaData({
|
|
588
|
-
params: request,
|
|
589
|
-
response: searchResponse,
|
|
590
|
-
});
|
|
591
|
-
searchResponse.results?.forEach((result, idx) => {
|
|
592
|
-
schemaMap[result.id] = {
|
|
593
|
-
...schema,
|
|
594
|
-
results: [
|
|
595
|
-
{
|
|
596
|
-
type: ItemTypeEnum.Product,
|
|
597
|
-
position: idx + 1,
|
|
598
|
-
uid: result.mappings?.core?.uid || '',
|
|
599
|
-
sku: result.mappings?.core?.sku,
|
|
600
|
-
},
|
|
601
|
-
],
|
|
602
|
-
};
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
649
|
export function getStorableRequestParams(request) {
|
|
606
650
|
return {
|
|
607
651
|
siteId: request.siteId,
|
|
@@ -644,84 +688,3 @@ export function generateHrefSelector(element, href, levels = 7) {
|
|
|
644
688
|
}
|
|
645
689
|
return;
|
|
646
690
|
}
|
|
647
|
-
function getSearchRedirectSchemaData({ redirectURL }) {
|
|
648
|
-
return {
|
|
649
|
-
redirect: redirectURL,
|
|
650
|
-
};
|
|
651
|
-
}
|
|
652
|
-
function getSearchAddtocartSchemaData({ searchSchemaData, results, }) {
|
|
653
|
-
return {
|
|
654
|
-
...searchSchemaData,
|
|
655
|
-
results: results?.map((result) => {
|
|
656
|
-
const core = result.mappings.core;
|
|
657
|
-
return {
|
|
658
|
-
uid: core.uid || '',
|
|
659
|
-
sku: core.sku,
|
|
660
|
-
price: Number(core.price),
|
|
661
|
-
qty: result.quantity || 1,
|
|
662
|
-
};
|
|
663
|
-
}) || [],
|
|
664
|
-
};
|
|
665
|
-
}
|
|
666
|
-
function getSearchSchemaData({ params, response }) {
|
|
667
|
-
const filters = params.filters?.reduce((acc, filter) => {
|
|
668
|
-
const key = filter.background ? 'bgfilter' : 'filter';
|
|
669
|
-
acc[key] = acc[key] || [];
|
|
670
|
-
const value = filter.type === 'range' &&
|
|
671
|
-
!isNaN(filter.value?.low) &&
|
|
672
|
-
!isNaN(filter.value?.high)
|
|
673
|
-
? [`low=${filter.value?.low}`, `high=${filter.value?.high}`]
|
|
674
|
-
: [`${filter.value}`];
|
|
675
|
-
const existing = acc[key].find((item) => item.field === filter.field);
|
|
676
|
-
if (existing && !existing.value.includes(value[0])) {
|
|
677
|
-
existing.value.push(...value);
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
acc[key].push({
|
|
681
|
-
field: filter.field,
|
|
682
|
-
value,
|
|
683
|
-
});
|
|
684
|
-
}
|
|
685
|
-
return acc;
|
|
686
|
-
}, {});
|
|
687
|
-
let correctedQuery;
|
|
688
|
-
if (response?.search?.originalQuery && response?.search?.query) {
|
|
689
|
-
correctedQuery = response?.search?.query;
|
|
690
|
-
}
|
|
691
|
-
const campaigns = response?.merchandising?.campaigns || [];
|
|
692
|
-
const experiments = response?.merchandising?.experiments || [];
|
|
693
|
-
return {
|
|
694
|
-
q: params.search?.query?.string || '',
|
|
695
|
-
rq: params.search?.subQuery ? params.search?.subQuery : undefined,
|
|
696
|
-
correctedQuery,
|
|
697
|
-
matchType: response?.search?.matchType,
|
|
698
|
-
...filters,
|
|
699
|
-
sort: params.sorts?.map((sort) => {
|
|
700
|
-
return {
|
|
701
|
-
field: sort.field,
|
|
702
|
-
dir: sort.direction,
|
|
703
|
-
};
|
|
704
|
-
}),
|
|
705
|
-
pagination: {
|
|
706
|
-
totalResults: response?.pagination?.totalResults,
|
|
707
|
-
page: response?.pagination?.page,
|
|
708
|
-
resultsPerPage: response?.pagination?.pageSize,
|
|
709
|
-
},
|
|
710
|
-
merchandising: {
|
|
711
|
-
personalized: response?.merchandising?.personalized,
|
|
712
|
-
redirect: response?.merchandising?.redirect,
|
|
713
|
-
triggeredCampaigns: (campaigns.length &&
|
|
714
|
-
campaigns.map((campaign) => {
|
|
715
|
-
const experiement = experiments.find((experiment) => experiment.campaignId === campaign.id);
|
|
716
|
-
return {
|
|
717
|
-
id: campaign.id,
|
|
718
|
-
experimentId: experiement?.experimentId,
|
|
719
|
-
variationId: experiement?.variationId,
|
|
720
|
-
};
|
|
721
|
-
})) ||
|
|
722
|
-
undefined,
|
|
723
|
-
},
|
|
724
|
-
banners: [],
|
|
725
|
-
results: [],
|
|
726
|
-
};
|
|
727
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"isClickWithinBannerLink.d.ts","sourceRoot":"","sources":["../../../src/utils/isClickWithinBannerLink.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,uBAAuB,MAAO,UAAU,KAAG,OAcvD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { CLICK_THROUGH_CLOSEST_MAX_LEVELS } from './isClickWithinProductLink';
|
|
2
|
+
const TRACKING_ATTRIBUTE = 'sstracking';
|
|
3
|
+
export const isClickWithinBannerLink = (e) => {
|
|
4
|
+
let currentElement = e.target;
|
|
5
|
+
let href = null;
|
|
6
|
+
let level = 0;
|
|
7
|
+
while (currentElement && (level < CLICK_THROUGH_CLOSEST_MAX_LEVELS || !currentElement.getAttribute(TRACKING_ATTRIBUTE))) {
|
|
8
|
+
href = currentElement.getAttribute('href');
|
|
9
|
+
const isAnchor = currentElement.tagName.toLowerCase() === 'a';
|
|
10
|
+
if (href && isAnchor) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
currentElement = currentElement.parentElement;
|
|
14
|
+
level++;
|
|
15
|
+
}
|
|
16
|
+
return false;
|
|
17
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@searchspring/snap-controller",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.73.5",
|
|
4
4
|
"description": "Snap Controllers",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -20,22 +20,22 @@
|
|
|
20
20
|
"test:watch": "jest --watch"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@searchspring/snap-toolbox": "0.
|
|
23
|
+
"@searchspring/snap-toolbox": "0.73.5",
|
|
24
24
|
"css.escape": "1.5.1",
|
|
25
25
|
"deepmerge": "4.3.1"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@searchspring/snap-client": "0.
|
|
29
|
-
"@searchspring/snap-event-manager": "0.
|
|
30
|
-
"@searchspring/snap-logger": "0.
|
|
31
|
-
"@searchspring/snap-profiler": "0.
|
|
32
|
-
"@searchspring/snap-store-mobx": "0.
|
|
33
|
-
"@searchspring/snap-tracker": "0.
|
|
34
|
-
"@searchspring/snap-url-manager": "0.
|
|
28
|
+
"@searchspring/snap-client": "0.73.5",
|
|
29
|
+
"@searchspring/snap-event-manager": "0.73.5",
|
|
30
|
+
"@searchspring/snap-logger": "0.73.5",
|
|
31
|
+
"@searchspring/snap-profiler": "0.73.5",
|
|
32
|
+
"@searchspring/snap-store-mobx": "0.73.5",
|
|
33
|
+
"@searchspring/snap-tracker": "0.73.5",
|
|
34
|
+
"@searchspring/snap-url-manager": "0.73.5"
|
|
35
35
|
},
|
|
36
36
|
"sideEffects": false,
|
|
37
37
|
"files": [
|
|
38
38
|
"dist/**/*"
|
|
39
39
|
],
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "3052c4ea9cc631b0b398c72ea0f155084e15b7ee"
|
|
41
41
|
}
|