@mparticle/web-sdk 3.29.0 → 3.29.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.
@@ -162,8 +162,9 @@ export class ButtonTracker {
162
162
  // Bumped on reset so classification queued before it is dropped.
163
163
  private generation = 0;
164
164
  private lastCommitClick = -Infinity;
165
- // The latest trusted click: whether the page excluded it, and the intent it
166
- // already carries to the kit, with its source, if any.
165
+ // The latest trusted click: whether the page excluded it or it was withheld
166
+ // from the kit, and the intent it already carries to the kit, with its
167
+ // source, if any.
167
168
  private lastClick: {
168
169
  t: number;
169
170
  excluded: boolean;
@@ -408,15 +409,26 @@ export class ButtonTracker {
408
409
  ? undefined
409
410
  : findControl(path, true, PATH_LIMIT) ||
410
411
  findRoleControl(path, PATH_LIMIT));
412
+ // A click that link tracking logs as Auto Link Click gives the kit no
413
+ // intent when the Rokt connection does not receive those events.
414
+ let withheld = false;
411
415
  if (logged) {
412
416
  // With links alone, only an anchor can be logged.
413
- click =
417
+ const logsThis =
414
418
  logsEvents &&
415
- (this.logButtons || logged.matches('a[href]'))
419
+ (this.logButtons || logged.matches('a[href]'));
420
+ const linksWithheld =
421
+ signalsKit && this.logLinks && !this.linkClicksReachKit();
422
+ const described =
423
+ logsThis || linksWithheld
416
424
  ? describeButtonClick(logged, path)
417
425
  : undefined;
426
+ const linkClick =
427
+ this.logLinks && !!described && isLinkClick(described);
428
+ withheld = linksWithheld && linkClick;
429
+ click = logsThis ? described : undefined;
418
430
  if (click) {
419
- asLink = this.logLinks && isLinkClick(click);
431
+ asLink = linkClick;
420
432
  // Without link tracking, a link that leaves the page stays a
421
433
  // button click, except a plain link to another page of the
422
434
  // site, which button tracking never logged.
@@ -435,7 +447,7 @@ export class ButtonTracker {
435
447
  box = logged as HTMLInputElement;
436
448
  }
437
449
  }
438
- if (control) {
450
+ if (control && !withheld) {
439
451
  // Checkout intent is only worked out when the kit can use it.
440
452
  const intent = signalsKit
441
453
  ? classifyIntent(control, pathname)
@@ -460,7 +472,14 @@ export class ButtonTracker {
460
472
  checkedNames = checked ? checked.names : undefined;
461
473
  }
462
474
  }
463
- this.lastClick = { t, excluded, kind, source };
475
+ // A withheld click cannot start an Apple Pay session for the kit
476
+ // either.
477
+ this.lastClick = {
478
+ t,
479
+ excluded: excluded || withheld,
480
+ kind,
481
+ source,
482
+ };
464
483
  } else if (layer === 'submit') {
465
484
  const submitter = (event as Event & { submitter?: Element | null })
466
485
  .submitter;
@@ -643,6 +662,11 @@ export class ButtonTracker {
643
662
  );
644
663
  }
645
664
 
665
+ private linkClicksReachKit(): boolean {
666
+ const roktManager = this.mpInstance._RoktManager;
667
+ return !!roktManager && roktManager.areAutoLinkClicksForwarded();
668
+ }
669
+
646
670
  private log(message: string): void {
647
671
  this.mpInstance.Logger.verbose('mParticle button tracking: ' + message);
648
672
  }
@@ -1390,6 +1390,7 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1390
1390
  // Button tracking never runs as a native passthrough.
1391
1391
  resetButtonTracking();
1392
1392
  mpInstance._RoktManager.setAutoButtonClicksForwarded(false);
1393
+ mpInstance._RoktManager.setAutoLinkClicksForwarded(false);
1393
1394
  } else {
1394
1395
  // Main SDK initialization flow
1395
1396
 
@@ -1459,8 +1460,8 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1459
1460
  // init or from a returning shopper's landing page view.
1460
1461
  const logButtons = !!getFeatureFlag(AutoButtonTracking);
1461
1462
  const logLinks = !!getFeatureFlag(AutoLinkTracking);
1462
- // Links feed intent too, so with link tracking on the kit must also
1463
- // receive Auto Link Click events.
1463
+ // With link tracking on, a click logged as Auto Link Click feeds intent
1464
+ // only when the kit also receives those events; button clicks still do.
1464
1465
  const buttonClickBlocker = roktConfig
1465
1466
  ? getButtonClickBlocker(roktConfig, kitBlocker)
1466
1467
  : undefined;
@@ -1472,11 +1473,14 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1472
1473
  mpInstance.Logger.warning(
1473
1474
  buttonClickBlocker
1474
1475
  ? `Checkout intent is off: the ${buttonClickBlocker} keeps some or all Auto Button Click events from the Rokt kit.`
1475
- : `Checkout intent is off: the ${linkClickBlocker} keeps some or all Auto Link Click events from the Rokt kit.`
1476
+ : `Checkout intent skips link clicks: the ${linkClickBlocker} keeps some or all Auto Link Click events from the Rokt kit.`
1476
1477
  );
1477
1478
  }
1478
1479
  mpInstance._RoktManager.setAutoButtonClicksForwarded(
1479
- !!roktConfig && !buttonClickBlocker && !linkClickBlocker
1480
+ !!roktConfig && !buttonClickBlocker
1481
+ );
1482
+ mpInstance._RoktManager.setAutoLinkClicksForwarded(
1483
+ !!roktConfig && !linkClickBlocker
1480
1484
  );
1481
1485
 
1482
1486
  mpInstance._Forwarders.processForwarders(
@@ -175,6 +175,9 @@ export default class RoktManager {
175
175
  private pendingCheckoutIntents: Array<{ signal: ICheckoutIntentSignal; pathname: string }> = [];
176
176
  // Off until SDK init finds the Rokt connection receives auto button clicks.
177
177
  private autoButtonClicksForwarded = false;
178
+ // Off until SDK init finds the Rokt connection receives auto link clicks, or
179
+ // link tracking is off. Only link clicks lose their intent without it.
180
+ private autoLinkClicksForwarded = false;
178
181
 
179
182
  // Keys this manager's route subscription, so a re-executed bundle's manager replaces
180
183
  // it while a second named instance keeps its own.
@@ -331,6 +334,16 @@ export default class RoktManager {
331
334
  this.autoButtonClicksForwarded = forwarded;
332
335
  }
333
336
 
337
+ public setAutoLinkClicksForwarded(forwarded: boolean): void {
338
+ this.autoLinkClicksForwarded = forwarded;
339
+ }
340
+
341
+ // The Rokt kit reads this too: while false, its page views keep
342
+ // dispatchDelayMs, since a checkout link could never release the wait.
343
+ public areAutoLinkClicksForwarded(): boolean {
344
+ return this.autoLinkClicksForwarded;
345
+ }
346
+
334
347
  // noTargeting (which noDeviceId implies), doNotShareOrSell or Global Privacy
335
348
  // Control. Unlike noFunctional, these also stop auto button and link clicks
336
349
  // from being logged.