@searchspring/snap-preact 0.77.0 → 0.79.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
- package/dist/cjs/Instantiators/RecommendationInstantiator.js +33 -13
- package/dist/esm/Instantiators/RecommendationInstantiator.d.ts.map +1 -1
- package/dist/esm/Instantiators/RecommendationInstantiator.js +31 -13
- package/package.json +13 -13
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAA2D,MAAM,2BAA2B,CAAC;AACtI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjI,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAInE,MAAM,MAAM,gCAAgC,GAAG;IAC9C,IAAI,CAAC,EAAE,MAAM,OAAO,OAAO,GAAG,OAAO,CAAC;IACtC,MAAM,CAAC,EAAE;QACR,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;IACF,UAAU,EAAE;QACX,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;KACzC,CAAC;IACF,MAAM,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,MAAM,CAAC,EAAE,cAAc,CAAC;KACxB,GAAG,WAAW,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"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"}
|
|
@@ -111,20 +111,22 @@ var RecommendationInstantiator = /** @class */ (function () {
|
|
|
111
111
|
selector: "".concat(this.config.selector || 'script[type="searchspring/recommend"], script[type="searchspring/personalized-recommendations"]', ", script[type=\"searchspring/recommend\"][profile=\"email\"]"),
|
|
112
112
|
autoRetarget: true,
|
|
113
113
|
clickRetarget: true,
|
|
114
|
+
navigationRetarget: true,
|
|
114
115
|
emptyTarget: false,
|
|
115
116
|
},
|
|
116
117
|
{
|
|
117
118
|
selector: 'script[type="searchspring/recommendations"]',
|
|
118
119
|
autoRetarget: true,
|
|
119
120
|
clickRetarget: true,
|
|
121
|
+
navigationRetarget: true,
|
|
120
122
|
emptyTarget: false,
|
|
121
123
|
},
|
|
122
|
-
], function (target, elem
|
|
124
|
+
], function (target, elem) { return __awaiter(_this, void 0, void 0, function () {
|
|
123
125
|
var scriptElement, elemContext, scriptContextProfiles, scriptContextGlobals_1, requestGlobals_1, profile, products, product, seed, filters, blockedItems, options, shopper, shopperId, combinedProducts, shopperIdentifier, profileRequestGlobals_1, profileAttr, recsContainer, legacyContext_1;
|
|
124
126
|
var _this = this;
|
|
125
127
|
var _a;
|
|
126
128
|
return __generator(this, function (_b) {
|
|
127
|
-
this.
|
|
129
|
+
this.cleanupStaleControllers();
|
|
128
130
|
scriptElement = elem;
|
|
129
131
|
elemContext = (0, snap_toolbox_1.getContext)([
|
|
130
132
|
'shopperId',
|
|
@@ -154,12 +156,13 @@ var RecommendationInstantiator = /** @class */ (function () {
|
|
|
154
156
|
}));
|
|
155
157
|
// create a per-profile DomTargeter for each profile so each controller
|
|
156
158
|
// gets its own targeter tracking its specific element
|
|
157
|
-
scriptContextProfiles.forEach(function (profile) {
|
|
159
|
+
scriptContextProfiles.forEach(function (profile, index) {
|
|
158
160
|
if (profile.selector) {
|
|
159
161
|
var profileTarget = {
|
|
160
162
|
selector: profile.selector,
|
|
161
163
|
autoRetarget: true,
|
|
162
164
|
profile: profile,
|
|
165
|
+
order: index,
|
|
163
166
|
};
|
|
164
167
|
// track the controller for this profile so multiple matched elements share it
|
|
165
168
|
var profileControllerPromise_1;
|
|
@@ -169,15 +172,18 @@ var RecommendationInstantiator = /** @class */ (function () {
|
|
|
169
172
|
return __generator(this, function (_d) {
|
|
170
173
|
switch (_d.label) {
|
|
171
174
|
case 0:
|
|
172
|
-
// skip retarget if the source script element was removed
|
|
173
|
-
if (
|
|
175
|
+
// skip retarget if the source script element was removed and release the current target
|
|
176
|
+
if (scriptElement.isConnected === false) {
|
|
177
|
+
if (targetElem) {
|
|
178
|
+
targeter === null || targeter === void 0 ? void 0 : targeter.releaseTargets([targetElem]);
|
|
179
|
+
}
|
|
174
180
|
return [2 /*return*/];
|
|
175
181
|
}
|
|
176
182
|
if (!(((_a = target.profile) === null || _a === void 0 ? void 0 : _a.profile) || ((_b = target.profile) === null || _b === void 0 ? void 0 : _b.tag))) return [3 /*break*/, 3];
|
|
177
|
-
profileRequestGlobals = __assign(__assign({}, requestGlobals_1), { profile: (_c = target.profile) === null || _c === void 0 ? void 0 : _c.options, tag: target.profile.tag || target.profile.profile });
|
|
183
|
+
profileRequestGlobals = __assign(__assign({}, requestGlobals_1), { profile: __assign(__assign({}, (_c = target.profile) === null || _c === void 0 ? void 0 : _c.options), { order: target.order }), tag: target.profile.tag || target.profile.profile });
|
|
178
184
|
profileContext = (0, deepmerge_1.default)(this.context, defined({ globals: scriptContextGlobals_1, profile: target.profile }));
|
|
179
185
|
if (elemContext.custom) {
|
|
180
|
-
profileContext.custom = elemContext.custom;
|
|
186
|
+
profileContext.custom = (0, deepmerge_1.default)(profileContext.custom, elemContext.custom);
|
|
181
187
|
}
|
|
182
188
|
if (!!profileControllerPromise_1) return [3 /*break*/, 1];
|
|
183
189
|
// first element match — create the controller
|
|
@@ -217,8 +223,11 @@ var RecommendationInstantiator = /** @class */ (function () {
|
|
|
217
223
|
// create a per-element DomTargeter for the injected div (mirrors grouped block pattern)
|
|
218
224
|
new snap_toolbox_1.DomTargeter([{ selector: "[searchspring-recommend=\"".concat(profileAttr, "\"]"), name: "legacy_".concat(profile, "_").concat(profileCount[profile || ''] || 0) }], function (_target, targetElem, _originalElem, targeter) { return __awaiter(_this, void 0, void 0, function () {
|
|
219
225
|
return __generator(this, function (_a) {
|
|
220
|
-
// skip retarget if the source script element was removed
|
|
221
|
-
if (
|
|
226
|
+
// skip retarget if the source script element was removed and release the current target
|
|
227
|
+
if (scriptElement.isConnected === false) {
|
|
228
|
+
if (targetElem) {
|
|
229
|
+
targeter === null || targeter === void 0 ? void 0 : targeter.releaseTargets([targetElem]);
|
|
230
|
+
}
|
|
222
231
|
return [2 /*return*/];
|
|
223
232
|
}
|
|
224
233
|
readyTheController(this, targetElem, legacyContext_1, profileCount, scriptElement, profileRequestGlobals_1, targeter);
|
|
@@ -254,8 +263,14 @@ var RecommendationInstantiator = /** @class */ (function () {
|
|
|
254
263
|
var _a;
|
|
255
264
|
var controller = _this.controller[id];
|
|
256
265
|
var targeters = Object.values(controller.targeters);
|
|
257
|
-
var hasConnectedTarget = targeters.some(function (targeter) {
|
|
266
|
+
var hasConnectedTarget = targeters.some(function (targeter) {
|
|
267
|
+
return targeter.getTargetedElems().some(function (elem) {
|
|
268
|
+
var attr = elem.isConnected !== false && elem.getAttribute('ss-controller-id');
|
|
269
|
+
return attr === id;
|
|
270
|
+
});
|
|
271
|
+
});
|
|
258
272
|
if (!hasConnectedTarget) {
|
|
273
|
+
Object.keys(controller.targeters).forEach(function (targeterId) { return controller.targeters[targeterId].destroy(); });
|
|
259
274
|
controller.targeters = {};
|
|
260
275
|
delete _this.controller[id];
|
|
261
276
|
if ((_a = window.searchspring) === null || _a === void 0 ? void 0 : _a.controller) {
|
|
@@ -293,8 +308,6 @@ function readyTheController(instance, targetElem, context, profileCount, scriptE
|
|
|
293
308
|
if (profile === null || profile === void 0 ? void 0 : profile.branch) {
|
|
294
309
|
controllerConfigBase.branch = profile === null || profile === void 0 ? void 0 : profile.branch;
|
|
295
310
|
}
|
|
296
|
-
// clean up controllers whose rendered elements are no longer in the DOM (SPA navigation)
|
|
297
|
-
instance.cleanupStaleControllers();
|
|
298
311
|
profileCount[tag] = profileCount[tag] + 1 || 1;
|
|
299
312
|
controllerConfig = __assign({ id: "recommend_".concat(tag, "_").concat(profileCount[tag] - 1) }, controllerConfigBase);
|
|
300
313
|
controller = (0, create_1.createRecommendationController)({
|
|
@@ -303,6 +316,10 @@ function readyTheController(instance, targetElem, context, profileCount, scriptE
|
|
|
303
316
|
context: context,
|
|
304
317
|
mode: instance.config.mode,
|
|
305
318
|
}, { client: instance.client, tracker: instance.tracker });
|
|
319
|
+
// mark element with controller id so cleanupStaleControllers knows it's active
|
|
320
|
+
if (targetElem) {
|
|
321
|
+
targetElem.setAttribute('ss-controller-id', controller.id);
|
|
322
|
+
}
|
|
306
323
|
instance.uses.forEach(function (attachements) { return controller.use(attachements); });
|
|
307
324
|
instance.plugins.forEach(function (plugin) { return controller.plugin.apply(controller, __spreadArray([plugin.func], plugin.args, false)); });
|
|
308
325
|
instance.middleware.forEach(function (middleware) { return controller.on.apply(controller, __spreadArray([middleware.event], middleware.func, false)); });
|
|
@@ -349,6 +366,10 @@ function renderController(instance, controller, targetElem, scriptElem) {
|
|
|
349
366
|
return __generator(this, function (_c) {
|
|
350
367
|
switch (_c.label) {
|
|
351
368
|
case 0:
|
|
369
|
+
// update the element with the controller id
|
|
370
|
+
if (targetElem) {
|
|
371
|
+
targetElem.setAttribute('ss-controller-id', controller.id);
|
|
372
|
+
}
|
|
352
373
|
tag = controller.config.tag;
|
|
353
374
|
component = (_a = controller.store.profile.display.template) === null || _a === void 0 ? void 0 : _a.component;
|
|
354
375
|
if (!component) {
|
|
@@ -368,7 +389,6 @@ function renderController(instance, controller, targetElem, scriptElem) {
|
|
|
368
389
|
return [2 /*return*/];
|
|
369
390
|
}
|
|
370
391
|
setTimeout(function () {
|
|
371
|
-
targetElem.setAttribute('ss-controller-id', controller.config.id);
|
|
372
392
|
(0, preact_1.render)((0, jsx_runtime_1.jsx)(RecommendationsComponent, { controller: controller }), targetElem);
|
|
373
393
|
});
|
|
374
394
|
return [2 /*return*/];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAA2D,MAAM,2BAA2B,CAAC;AACtI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjI,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAInE,MAAM,MAAM,gCAAgC,GAAG;IAC9C,IAAI,CAAC,EAAE,MAAM,OAAO,OAAO,GAAG,OAAO,CAAC;IACtC,MAAM,CAAC,EAAE;QACR,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;IACF,UAAU,EAAE;QACX,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;KACzC,CAAC;IACF,MAAM,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,MAAM,CAAC,EAAE,cAAc,CAAC;KACxB,GAAG,WAAW,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;
|
|
1
|
+
{"version":3,"file":"RecommendationInstantiator.d.ts","sourceRoot":"","sources":["../../../src/Instantiators/RecommendationInstantiator.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAErD,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAA2D,MAAM,2BAA2B,CAAC;AACtI,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjI,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AAInE,MAAM,MAAM,gCAAgC,GAAG;IAC9C,IAAI,CAAC,EAAE,MAAM,OAAO,OAAO,GAAG,OAAO,CAAC;IACtC,MAAM,CAAC,EAAE;QACR,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,CAAC,EAAE,YAAY,CAAC;KACtB,CAAC;IACF,UAAU,EAAE;QACX,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;KACzC,CAAC;IACF,MAAM,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,MAAM,CAAC,EAAE,cAAc,CAAC;KACxB,GAAG,WAAW,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,mBAAmB,CAAC;IAC1B,OAAO,CAAC,EAAE,gBAAgB,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,kCAAkC,GAAG;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AA8BF,qBAAa,0BAA0B;IACtC,OAAO,CAAC,IAAI,CAAsB;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE;QAClB,CAAC,GAAG,EAAE,MAAM,GAAG,wBAAwB,CAAC;KACxC,CAAM;IACA,MAAM,EAAE,gCAAgC,CAAC;IACzC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,EAAE,WAAW,CAAC;IAEtB,IAAI,EAAE,WAAW,EAAE,CAAM;IACzB,OAAO,EAAE;QAAE,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAE,EAAE,CAAM;IACvG,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAA;KAAE,EAAE,CAAM;gBAE7D,MAAM,EAAE,gCAAgC,EAAE,QAAQ,CAAC,EAAE,kCAAkC,EAAE,OAAO,CAAC,EAAE,gBAAgB;IAqNxH,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAInG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI;IAIvD,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAKnC,uBAAuB,IAAI,IAAI;CAqBtC;AAgKD,KAAK,YAAY,GAAG;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACnB,CAAC;AAEF,wBAAgB,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,YAAY,CAUrE"}
|
|
@@ -47,16 +47,18 @@ export class RecommendationInstantiator {
|
|
|
47
47
|
selector: `${this.config.selector || 'script[type="searchspring/recommend"], script[type="searchspring/personalized-recommendations"]'}, script[type="searchspring/recommend"][profile="email"]`,
|
|
48
48
|
autoRetarget: true,
|
|
49
49
|
clickRetarget: true,
|
|
50
|
+
navigationRetarget: true,
|
|
50
51
|
emptyTarget: false,
|
|
51
52
|
},
|
|
52
53
|
{
|
|
53
54
|
selector: 'script[type="searchspring/recommendations"]',
|
|
54
55
|
autoRetarget: true,
|
|
55
56
|
clickRetarget: true,
|
|
57
|
+
navigationRetarget: true,
|
|
56
58
|
emptyTarget: false,
|
|
57
59
|
},
|
|
58
|
-
], async (target, elem
|
|
59
|
-
this.
|
|
60
|
+
], async (target, elem) => {
|
|
61
|
+
this.cleanupStaleControllers();
|
|
60
62
|
const scriptElement = elem;
|
|
61
63
|
const elemContext = getContext([
|
|
62
64
|
'shopperId',
|
|
@@ -91,29 +93,33 @@ export class RecommendationInstantiator {
|
|
|
91
93
|
};
|
|
92
94
|
// create a per-profile DomTargeter for each profile so each controller
|
|
93
95
|
// gets its own targeter tracking its specific element
|
|
94
|
-
scriptContextProfiles.forEach((profile) => {
|
|
96
|
+
scriptContextProfiles.forEach((profile, index) => {
|
|
95
97
|
if (profile.selector) {
|
|
96
98
|
const profileTarget = {
|
|
97
99
|
selector: profile.selector,
|
|
98
100
|
autoRetarget: true,
|
|
99
101
|
profile,
|
|
102
|
+
order: index,
|
|
100
103
|
};
|
|
101
104
|
// track the controller for this profile so multiple matched elements share it
|
|
102
105
|
let profileControllerPromise;
|
|
103
106
|
new DomTargeter([profileTarget], async (target, targetElem, _originalElem, targeter) => {
|
|
104
|
-
// skip retarget if the source script element was removed
|
|
105
|
-
if (
|
|
107
|
+
// skip retarget if the source script element was removed and release the current target
|
|
108
|
+
if (scriptElement.isConnected === false) {
|
|
109
|
+
if (targetElem) {
|
|
110
|
+
targeter?.releaseTargets([targetElem]);
|
|
111
|
+
}
|
|
106
112
|
return;
|
|
107
113
|
}
|
|
108
114
|
if (target.profile?.profile || target.profile?.tag) {
|
|
109
115
|
const profileRequestGlobals = {
|
|
110
116
|
...requestGlobals,
|
|
111
|
-
profile: target.profile?.options,
|
|
117
|
+
profile: { ...target.profile?.options, order: target.order },
|
|
112
118
|
tag: target.profile.tag || target.profile.profile, // have to support both tag and profile due to having profile at release, but will favor tag
|
|
113
119
|
};
|
|
114
120
|
const profileContext = deepmerge(this.context, defined({ globals: scriptContextGlobals, profile: target.profile }));
|
|
115
121
|
if (elemContext.custom) {
|
|
116
|
-
profileContext.custom = elemContext.custom;
|
|
122
|
+
profileContext.custom = deepmerge(profileContext.custom, elemContext.custom);
|
|
117
123
|
}
|
|
118
124
|
if (!profileControllerPromise) {
|
|
119
125
|
// first element match — create the controller
|
|
@@ -155,8 +161,11 @@ export class RecommendationInstantiator {
|
|
|
155
161
|
const legacyContext = deepmerge(this.context, elemContext);
|
|
156
162
|
// create a per-element DomTargeter for the injected div (mirrors grouped block pattern)
|
|
157
163
|
new DomTargeter([{ selector: `[searchspring-recommend="${profileAttr}"]`, name: `legacy_${profile}_${profileCount[profile || ''] || 0}` }], async (_target, targetElem, _originalElem, targeter) => {
|
|
158
|
-
// skip retarget if the source script element was removed
|
|
159
|
-
if (
|
|
164
|
+
// skip retarget if the source script element was removed and release the current target
|
|
165
|
+
if (scriptElement.isConnected === false) {
|
|
166
|
+
if (targetElem) {
|
|
167
|
+
targeter?.releaseTargets([targetElem]);
|
|
168
|
+
}
|
|
160
169
|
return;
|
|
161
170
|
}
|
|
162
171
|
readyTheController(this, targetElem, legacyContext, profileCount, scriptElement, profileRequestGlobals, targeter);
|
|
@@ -178,8 +187,12 @@ export class RecommendationInstantiator {
|
|
|
178
187
|
Object.keys(this.controller).forEach((id) => {
|
|
179
188
|
const controller = this.controller[id];
|
|
180
189
|
const targeters = Object.values(controller.targeters);
|
|
181
|
-
const hasConnectedTarget = targeters.some((targeter) => targeter.getTargetedElems().some((elem) =>
|
|
190
|
+
const hasConnectedTarget = targeters.some((targeter) => targeter.getTargetedElems().some((elem) => {
|
|
191
|
+
const attr = elem.isConnected !== false && elem.getAttribute('ss-controller-id');
|
|
192
|
+
return attr === id;
|
|
193
|
+
}));
|
|
182
194
|
if (!hasConnectedTarget) {
|
|
195
|
+
Object.keys(controller.targeters).forEach((targeterId) => controller.targeters[targeterId].destroy());
|
|
183
196
|
controller.targeters = {};
|
|
184
197
|
delete this.controller[id];
|
|
185
198
|
if (window.searchspring?.controller) {
|
|
@@ -216,8 +229,6 @@ async function readyTheController(instance, targetElem, context, profileCount, s
|
|
|
216
229
|
if (profile?.branch) {
|
|
217
230
|
controllerConfigBase.branch = profile?.branch;
|
|
218
231
|
}
|
|
219
|
-
// clean up controllers whose rendered elements are no longer in the DOM (SPA navigation)
|
|
220
|
-
instance.cleanupStaleControllers();
|
|
221
232
|
profileCount[tag] = profileCount[tag] + 1 || 1;
|
|
222
233
|
const controllerConfig = {
|
|
223
234
|
id: `recommend_${tag}_${profileCount[tag] - 1}`,
|
|
@@ -229,6 +240,10 @@ async function readyTheController(instance, targetElem, context, profileCount, s
|
|
|
229
240
|
context,
|
|
230
241
|
mode: instance.config.mode,
|
|
231
242
|
}, { client: instance.client, tracker: instance.tracker });
|
|
243
|
+
// mark element with controller id so cleanupStaleControllers knows it's active
|
|
244
|
+
if (targetElem) {
|
|
245
|
+
targetElem.setAttribute('ss-controller-id', controller.id);
|
|
246
|
+
}
|
|
232
247
|
instance.uses.forEach((attachements) => controller.use(attachements));
|
|
233
248
|
instance.plugins.forEach((plugin) => controller.plugin(plugin.func, ...plugin.args));
|
|
234
249
|
instance.middleware.forEach((middleware) => controller.on(middleware.event, ...middleware.func));
|
|
@@ -262,6 +277,10 @@ async function readyTheController(instance, targetElem, context, profileCount, s
|
|
|
262
277
|
return controller;
|
|
263
278
|
}
|
|
264
279
|
async function renderController(instance, controller, targetElem, scriptElem) {
|
|
280
|
+
// update the element with the controller id
|
|
281
|
+
if (targetElem) {
|
|
282
|
+
targetElem.setAttribute('ss-controller-id', controller.id);
|
|
283
|
+
}
|
|
265
284
|
const tag = controller.config.tag;
|
|
266
285
|
const component = controller.store.profile.display.template?.component;
|
|
267
286
|
if (!component) {
|
|
@@ -275,7 +294,6 @@ async function renderController(instance, controller, targetElem, scriptElem) {
|
|
|
275
294
|
return;
|
|
276
295
|
}
|
|
277
296
|
setTimeout(() => {
|
|
278
|
-
targetElem.setAttribute('ss-controller-id', controller.config.id);
|
|
279
297
|
render(_jsx(RecommendationsComponent, { controller: controller }), targetElem);
|
|
280
298
|
});
|
|
281
299
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@searchspring/snap-preact",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.79.0",
|
|
4
4
|
"description": "Snap Preact",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -20,17 +20,17 @@
|
|
|
20
20
|
"test:watch": "jest --watch"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@searchspring/snap-client": "0.
|
|
24
|
-
"@searchspring/snap-controller": "0.
|
|
25
|
-
"@searchspring/snap-event-manager": "0.
|
|
26
|
-
"@searchspring/snap-logger": "0.
|
|
27
|
-
"@searchspring/snap-platforms": "0.
|
|
28
|
-
"@searchspring/snap-preact-components": "0.
|
|
29
|
-
"@searchspring/snap-profiler": "0.
|
|
30
|
-
"@searchspring/snap-store-mobx": "0.
|
|
31
|
-
"@searchspring/snap-toolbox": "0.
|
|
32
|
-
"@searchspring/snap-tracker": "0.
|
|
33
|
-
"@searchspring/snap-url-manager": "0.
|
|
23
|
+
"@searchspring/snap-client": "0.79.0",
|
|
24
|
+
"@searchspring/snap-controller": "0.79.0",
|
|
25
|
+
"@searchspring/snap-event-manager": "0.79.0",
|
|
26
|
+
"@searchspring/snap-logger": "0.79.0",
|
|
27
|
+
"@searchspring/snap-platforms": "0.79.0",
|
|
28
|
+
"@searchspring/snap-preact-components": "0.79.0",
|
|
29
|
+
"@searchspring/snap-profiler": "0.79.0",
|
|
30
|
+
"@searchspring/snap-store-mobx": "0.79.0",
|
|
31
|
+
"@searchspring/snap-toolbox": "0.79.0",
|
|
32
|
+
"@searchspring/snap-tracker": "0.79.0",
|
|
33
|
+
"@searchspring/snap-url-manager": "0.79.0",
|
|
34
34
|
"deepmerge": "4.3.1",
|
|
35
35
|
"intersection-observer": "0.12.0",
|
|
36
36
|
"is-plain-object": "5.0.0"
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"files": [
|
|
44
44
|
"dist/**/*"
|
|
45
45
|
],
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "909e8cfd98fae2c6de81de2e9b0c68e07649f76f"
|
|
47
47
|
}
|