@mparticle/web-sdk 3.25.0 → 3.26.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/mparticle.common.js +1 -1
- package/dist/mparticle.esm.js +1 -1
- package/dist/mparticle.js +44 -18
- package/dist/types/src/buttonTracking/checkoutIntent.d.ts +1 -0
- package/dist/types/src/roktManager.d.ts +1 -0
- package/package.json +1 -1
- package/src/buttonTracking/buttonTracker.ts +19 -7
- package/src/buttonTracking/checkoutIntent.ts +14 -8
- package/src/roktManager.ts +12 -3
package/dist/mparticle.js
CHANGED
|
@@ -204,7 +204,7 @@ var mParticle = (function () {
|
|
|
204
204
|
Base64: Base64$1
|
|
205
205
|
};
|
|
206
206
|
|
|
207
|
-
var version = "3.
|
|
207
|
+
var version = "3.26.1";
|
|
208
208
|
|
|
209
209
|
var Constants = {
|
|
210
210
|
sdkVersion: version,
|
|
@@ -10881,8 +10881,9 @@ var mParticle = (function () {
|
|
|
10881
10881
|
}
|
|
10882
10882
|
|
|
10883
10883
|
var PASSBACK_CONVERSION_TRACKING_ID = 'passbackconversiontrackingid';
|
|
10884
|
-
// One signal per kind (commit, wallet, checkout_step, frame and cart),
|
|
10885
|
-
|
|
10884
|
+
// One signal per kind (commit, wallet, checkout_step, frame and cart), with an
|
|
10885
|
+
// add-to-cart click apart from a cart open, so a new one never evicts another.
|
|
10886
|
+
var CHECKOUT_INTENT_BUFFER_LIMIT = 6;
|
|
10886
10887
|
var CHECKOUT_INTENT_MAX_AGE_MS = 30000;
|
|
10887
10888
|
var ON_SHOPPABLE_ADS_READY_METHOD = 'onShoppableAdsReady';
|
|
10888
10889
|
// The purpose of this class is to create a link between the Core mParticle SDK and the
|
|
@@ -11085,8 +11086,10 @@ var mParticle = (function () {
|
|
|
11085
11086
|
}
|
|
11086
11087
|
var kit = this.kit;
|
|
11087
11088
|
if (!kit) {
|
|
11089
|
+
// One per kind, with an add-to-cart click kept apart from a
|
|
11090
|
+
// click that opens the cart.
|
|
11088
11091
|
this.pendingCheckoutIntents = this.pendingCheckoutIntents.filter(function (pending) {
|
|
11089
|
-
return pending.signal.kind !== signal.kind;
|
|
11092
|
+
return pending.signal.kind !== signal.kind || !!pending.signal.adds !== !!signal.adds;
|
|
11090
11093
|
}).concat({
|
|
11091
11094
|
signal: signal,
|
|
11092
11095
|
pathname: pathname
|
|
@@ -12729,17 +12732,17 @@ var mParticle = (function () {
|
|
|
12729
12732
|
// does. Only the cart rule reads the title. Opening the cart counts only for a
|
|
12730
12733
|
// control that opens it on the page, such as a flyout: one that leads to the cart
|
|
12731
12734
|
// page unloads before a call made on the click can return.
|
|
12732
|
-
function
|
|
12735
|
+
function cartControlAction(control, cores) {
|
|
12733
12736
|
var title = cores.length ? undefined : normalize(control.getAttribute('title'));
|
|
12734
12737
|
var texts = title ? [coreLabel(title)] : cores;
|
|
12735
12738
|
if (texts.some(function (text) {
|
|
12736
12739
|
return addToCartLabels.test(text);
|
|
12737
12740
|
})) {
|
|
12738
|
-
return
|
|
12741
|
+
return 'add';
|
|
12739
12742
|
}
|
|
12740
12743
|
return (control.hasAttribute('aria-expanded') || control.hasAttribute('aria-haspopup')) && texts.some(function (text) {
|
|
12741
12744
|
return openCartLabels.test(text);
|
|
12742
|
-
});
|
|
12745
|
+
}) ? 'open' : undefined;
|
|
12743
12746
|
}
|
|
12744
12747
|
// "Buy now" and "Purchase" count only on a checkout route, and never on a plain
|
|
12745
12748
|
// link, which is navigation.
|
|
@@ -12768,10 +12771,20 @@ var mParticle = (function () {
|
|
|
12768
12771
|
}
|
|
12769
12772
|
var texts = labels(control);
|
|
12770
12773
|
var cores = texts.map(coreLabel);
|
|
12771
|
-
var
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12774
|
+
var cartAction = cartControlAction(control, cores);
|
|
12775
|
+
var cart;
|
|
12776
|
+
if (cartAction === 'add') {
|
|
12777
|
+
cart = {
|
|
12778
|
+
kind: 'cart',
|
|
12779
|
+
source: 'label',
|
|
12780
|
+
adds: true
|
|
12781
|
+
};
|
|
12782
|
+
} else if (cartAction === 'open') {
|
|
12783
|
+
cart = {
|
|
12784
|
+
kind: 'cart',
|
|
12785
|
+
source: 'label'
|
|
12786
|
+
};
|
|
12787
|
+
}
|
|
12775
12788
|
if (isQuietIntentControl(control, false, !!cart)) {
|
|
12776
12789
|
return undefined;
|
|
12777
12790
|
}
|
|
@@ -13005,8 +13018,9 @@ var mParticle = (function () {
|
|
|
13005
13018
|
passive: true
|
|
13006
13019
|
};
|
|
13007
13020
|
// Logs button clicks and clicks on links that leave the page as mParticle events, and hands checkout
|
|
13008
|
-
// intent to the Rokt kit as a frozen {kind, t, source, pathname}
|
|
13009
|
-
// and so do payment picks: a payment radio's option
|
|
13021
|
+
// intent to the Rokt kit as a frozen {kind, t, source, pathname}, with adds on an add-to-cart click.
|
|
13022
|
+
// Submits and wallet frame focus feed the kit only, and so do payment picks: a payment radio's option
|
|
13023
|
+
// names, or the payment family of a focused frame.
|
|
13010
13024
|
var ButtonTracker = /** @class */function () {
|
|
13011
13025
|
function ButtonTracker(mpInstance) {
|
|
13012
13026
|
var _this = this;
|
|
@@ -13206,6 +13220,7 @@ var mParticle = (function () {
|
|
|
13206
13220
|
var box;
|
|
13207
13221
|
var kind;
|
|
13208
13222
|
var source;
|
|
13223
|
+
var adds;
|
|
13209
13224
|
var choice;
|
|
13210
13225
|
var family;
|
|
13211
13226
|
var unconfirmedCommit = false;
|
|
@@ -13234,6 +13249,7 @@ var mParticle = (function () {
|
|
|
13234
13249
|
var intent = signalsKit ? classifyIntent(control, pathname) : undefined;
|
|
13235
13250
|
kind = intent ? intent.kind : undefined;
|
|
13236
13251
|
source = intent ? intent.source : undefined;
|
|
13252
|
+
adds = intent ? intent.adds : undefined;
|
|
13237
13253
|
choice = signalsKit ? describePaymentChoice(control, path) : undefined;
|
|
13238
13254
|
}
|
|
13239
13255
|
this.lastClick = {
|
|
@@ -13254,6 +13270,7 @@ var mParticle = (function () {
|
|
|
13254
13270
|
var intent = classifyIntent(control, pathname);
|
|
13255
13271
|
kind = intent ? intent.kind : undefined;
|
|
13256
13272
|
source = intent ? intent.source : undefined;
|
|
13273
|
+
adds = intent ? intent.adds : undefined;
|
|
13257
13274
|
}
|
|
13258
13275
|
unconfirmedCommit = !submitter;
|
|
13259
13276
|
}
|
|
@@ -13292,7 +13309,7 @@ var mParticle = (function () {
|
|
|
13292
13309
|
_this.pickPayment(t, pathname, undefined, family);
|
|
13293
13310
|
}
|
|
13294
13311
|
if (kind) {
|
|
13295
|
-
_this.emit(kind, source, layer, t, pathname);
|
|
13312
|
+
_this.emit(kind, source, layer, t, pathname, adds);
|
|
13296
13313
|
}
|
|
13297
13314
|
} catch (e) {
|
|
13298
13315
|
_this.log('[error] delivery threw: ' + e);
|
|
@@ -13355,22 +13372,31 @@ var mParticle = (function () {
|
|
|
13355
13372
|
}
|
|
13356
13373
|
this.uploadHeld = false;
|
|
13357
13374
|
};
|
|
13358
|
-
ButtonTracker.prototype.emit = function (kind, source, layer, t, pathname) {
|
|
13375
|
+
ButtonTracker.prototype.emit = function (kind, source, layer, t, pathname, adds) {
|
|
13359
13376
|
if (this.isKitSuppressed()) {
|
|
13360
13377
|
return;
|
|
13361
13378
|
}
|
|
13362
13379
|
if (kind === 'commit' && layer === 'click') {
|
|
13363
13380
|
this.lastCommitClick = t;
|
|
13364
13381
|
}
|
|
13365
|
-
|
|
13382
|
+
// An add-to-cart click throttles apart from a click that opens the
|
|
13383
|
+
// cart, so opening the cart first never drops the add.
|
|
13384
|
+
var key = adds ? kind + ':adds' : kind;
|
|
13385
|
+
var last = this.lastSent[key];
|
|
13366
13386
|
if (last && last.pathname === pathname && t - last.t < THROTTLE_MS) {
|
|
13367
13387
|
return;
|
|
13368
13388
|
}
|
|
13369
|
-
this.lastSent[
|
|
13389
|
+
this.lastSent[key] = {
|
|
13370
13390
|
t: t,
|
|
13371
13391
|
pathname: pathname
|
|
13372
13392
|
};
|
|
13373
|
-
this.mpInstance._RoktManager.notifyCheckoutIntent(Object.freeze({
|
|
13393
|
+
this.mpInstance._RoktManager.notifyCheckoutIntent(Object.freeze(adds ? {
|
|
13394
|
+
kind: kind,
|
|
13395
|
+
t: t,
|
|
13396
|
+
source: source,
|
|
13397
|
+
pathname: pathname,
|
|
13398
|
+
adds: adds
|
|
13399
|
+
} : {
|
|
13374
13400
|
kind: kind,
|
|
13375
13401
|
t: t,
|
|
13376
13402
|
source: source,
|
|
@@ -4,6 +4,7 @@ export type CheckoutIntentSource = 'vendor' | 'label' | 'brand' | 'frame' | 'sub
|
|
|
4
4
|
export interface ICheckoutIntent {
|
|
5
5
|
kind: Exclude<CheckoutIntentKind, 'frame'>;
|
|
6
6
|
source: CheckoutIntentSource;
|
|
7
|
+
adds?: true;
|
|
7
8
|
}
|
|
8
9
|
export declare function classifyIntent(control: Element, pathname: string): ICheckoutIntent | undefined;
|
|
9
10
|
export declare function classifyIntentControl(control: Element, pathname: string): Exclude<CheckoutIntentKind, 'frame'> | undefined;
|
package/package.json
CHANGED
|
@@ -149,8 +149,9 @@ const CAPTURE_PASSIVE: AddEventListenerOptions = {
|
|
|
149
149
|
const PASSIVE: AddEventListenerOptions = { passive: true };
|
|
150
150
|
|
|
151
151
|
// Logs button clicks and clicks on links that leave the page as mParticle events, and hands checkout
|
|
152
|
-
// intent to the Rokt kit as a frozen {kind, t, source, pathname}
|
|
153
|
-
// and so do payment picks: a payment radio's option
|
|
152
|
+
// intent to the Rokt kit as a frozen {kind, t, source, pathname}, with adds on an add-to-cart click.
|
|
153
|
+
// Submits and wallet frame focus feed the kit only, and so do payment picks: a payment radio's option
|
|
154
|
+
// names, or the payment family of a focused frame.
|
|
154
155
|
export class ButtonTracker {
|
|
155
156
|
private readonly mpInstance: IMParticleWebSDKInstance;
|
|
156
157
|
private active = false;
|
|
@@ -399,6 +400,7 @@ export class ButtonTracker {
|
|
|
399
400
|
let box: HTMLInputElement | undefined;
|
|
400
401
|
let kind: CheckoutIntentKind | undefined;
|
|
401
402
|
let source: CheckoutIntentSource | undefined;
|
|
403
|
+
let adds: true | undefined;
|
|
402
404
|
let choice: IPaymentChoice | undefined;
|
|
403
405
|
let family: PaymentFrameFamily | undefined;
|
|
404
406
|
let unconfirmedCommit = false;
|
|
@@ -441,6 +443,7 @@ export class ButtonTracker {
|
|
|
441
443
|
: undefined;
|
|
442
444
|
kind = intent ? intent.kind : undefined;
|
|
443
445
|
source = intent ? intent.source : undefined;
|
|
446
|
+
adds = intent ? intent.adds : undefined;
|
|
444
447
|
choice = signalsKit
|
|
445
448
|
? describePaymentChoice(control, path)
|
|
446
449
|
: undefined;
|
|
@@ -459,6 +462,7 @@ export class ButtonTracker {
|
|
|
459
462
|
const intent = classifyIntent(control, pathname);
|
|
460
463
|
kind = intent ? intent.kind : undefined;
|
|
461
464
|
source = intent ? intent.source : undefined;
|
|
465
|
+
adds = intent ? intent.adds : undefined;
|
|
462
466
|
}
|
|
463
467
|
unconfirmedCommit = !submitter;
|
|
464
468
|
}
|
|
@@ -507,7 +511,7 @@ export class ButtonTracker {
|
|
|
507
511
|
this.pickPayment(t, pathname, undefined, family);
|
|
508
512
|
}
|
|
509
513
|
if (kind) {
|
|
510
|
-
this.emit(kind, source, layer, t, pathname);
|
|
514
|
+
this.emit(kind, source, layer, t, pathname, adds);
|
|
511
515
|
}
|
|
512
516
|
} catch (e) {
|
|
513
517
|
this.log('[error] delivery threw: ' + e);
|
|
@@ -591,7 +595,8 @@ export class ButtonTracker {
|
|
|
591
595
|
source: CheckoutIntentSource | undefined,
|
|
592
596
|
layer: string,
|
|
593
597
|
t: number,
|
|
594
|
-
pathname: string
|
|
598
|
+
pathname: string,
|
|
599
|
+
adds?: true
|
|
595
600
|
): void {
|
|
596
601
|
if (this.isKitSuppressed()) {
|
|
597
602
|
return;
|
|
@@ -600,14 +605,21 @@ export class ButtonTracker {
|
|
|
600
605
|
this.lastCommitClick = t;
|
|
601
606
|
}
|
|
602
607
|
|
|
603
|
-
|
|
608
|
+
// An add-to-cart click throttles apart from a click that opens the
|
|
609
|
+
// cart, so opening the cart first never drops the add.
|
|
610
|
+
const key = adds ? kind + ':adds' : kind;
|
|
611
|
+
const last = this.lastSent[key];
|
|
604
612
|
if (last && last.pathname === pathname && t - last.t < THROTTLE_MS) {
|
|
605
613
|
return;
|
|
606
614
|
}
|
|
607
|
-
this.lastSent[
|
|
615
|
+
this.lastSent[key] = { t, pathname };
|
|
608
616
|
|
|
609
617
|
this.mpInstance._RoktManager.notifyCheckoutIntent(
|
|
610
|
-
Object.freeze(
|
|
618
|
+
Object.freeze(
|
|
619
|
+
adds
|
|
620
|
+
? { kind, t, source, pathname, adds }
|
|
621
|
+
: { kind, t, source, pathname }
|
|
622
|
+
),
|
|
611
623
|
pathname
|
|
612
624
|
);
|
|
613
625
|
}
|
|
@@ -230,16 +230,16 @@ function labels(element: Element): string[] {
|
|
|
230
230
|
// does. Only the cart rule reads the title. Opening the cart counts only for a
|
|
231
231
|
// control that opens it on the page, such as a flyout: one that leads to the cart
|
|
232
232
|
// page unloads before a call made on the click can return.
|
|
233
|
-
function
|
|
233
|
+
function cartControlAction(control: Element, cores: string[]): 'add' | 'open' | undefined {
|
|
234
234
|
const title = cores.length ? undefined : normalize(control.getAttribute('title'));
|
|
235
235
|
const texts = title ? [coreLabel(title)] : cores;
|
|
236
236
|
if (texts.some(text => addToCartLabels.test(text))) {
|
|
237
|
-
return
|
|
237
|
+
return 'add';
|
|
238
238
|
}
|
|
239
|
-
return (
|
|
240
|
-
(control.hasAttribute('aria-expanded') || control.hasAttribute('aria-haspopup')) &&
|
|
239
|
+
return (control.hasAttribute('aria-expanded') || control.hasAttribute('aria-haspopup')) &&
|
|
241
240
|
texts.some(text => openCartLabels.test(text))
|
|
242
|
-
|
|
241
|
+
? 'open'
|
|
242
|
+
: undefined;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
// Which rule recognised the intent: a vendor's own markup, a phrase in the
|
|
@@ -258,6 +258,8 @@ export type CheckoutIntentSource =
|
|
|
258
258
|
export interface ICheckoutIntent {
|
|
259
259
|
kind: Exclude<CheckoutIntentKind, 'frame'>;
|
|
260
260
|
source: CheckoutIntentSource;
|
|
261
|
+
// Set on a cart click that puts something in the cart, not one that opens it.
|
|
262
|
+
adds?: true;
|
|
261
263
|
}
|
|
262
264
|
|
|
263
265
|
// "Buy now" and "Purchase" count only on a checkout route, and never on a plain
|
|
@@ -294,9 +296,13 @@ export function classifyIntent(
|
|
|
294
296
|
}
|
|
295
297
|
const texts = labels(control);
|
|
296
298
|
const cores = texts.map(coreLabel);
|
|
297
|
-
const
|
|
298
|
-
|
|
299
|
-
|
|
299
|
+
const cartAction = cartControlAction(control, cores);
|
|
300
|
+
let cart: ICheckoutIntent | undefined;
|
|
301
|
+
if (cartAction === 'add') {
|
|
302
|
+
cart = { kind: 'cart', source: 'label', adds: true };
|
|
303
|
+
} else if (cartAction === 'open') {
|
|
304
|
+
cart = { kind: 'cart', source: 'label' };
|
|
305
|
+
}
|
|
300
306
|
if (isQuietIntentControl(control, false, !!cart)) {
|
|
301
307
|
return undefined;
|
|
302
308
|
}
|
package/src/roktManager.ts
CHANGED
|
@@ -26,8 +26,9 @@ import { subscribeToRouteChange } from "./routeChangeMonitor";
|
|
|
26
26
|
import type { CheckoutIntentKind, CheckoutIntentSource, PaymentFrameFamily } from "./buttonTracking/checkoutIntent";
|
|
27
27
|
|
|
28
28
|
const PASSBACK_CONVERSION_TRACKING_ID = 'passbackconversiontrackingid';
|
|
29
|
-
// One signal per kind (commit, wallet, checkout_step, frame and cart),
|
|
30
|
-
|
|
29
|
+
// One signal per kind (commit, wallet, checkout_step, frame and cart), with an
|
|
30
|
+
// add-to-cart click apart from a cart open, so a new one never evicts another.
|
|
31
|
+
const CHECKOUT_INTENT_BUFFER_LIMIT = 6;
|
|
31
32
|
const CHECKOUT_INTENT_MAX_AGE_MS = 30000;
|
|
32
33
|
|
|
33
34
|
type AttributeTargetUser = Pick<IMParticleUser, 'getUserIdentities' | 'setUserAttributes'>;
|
|
@@ -83,6 +84,8 @@ export interface ICheckoutIntentSignal {
|
|
|
83
84
|
t: number;
|
|
84
85
|
source?: CheckoutIntentSource;
|
|
85
86
|
pathname?: string;
|
|
87
|
+
// On a cart click that puts something in the cart. Older kits ignore it.
|
|
88
|
+
adds?: true;
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
// What a kit receives when the shopper picks a payment method: the names of a
|
|
@@ -375,8 +378,14 @@ export default class RoktManager {
|
|
|
375
378
|
|
|
376
379
|
const kit = this.kit;
|
|
377
380
|
if (!kit) {
|
|
381
|
+
// One per kind, with an add-to-cart click kept apart from a
|
|
382
|
+
// click that opens the cart.
|
|
378
383
|
this.pendingCheckoutIntents = this.pendingCheckoutIntents
|
|
379
|
-
.filter(
|
|
384
|
+
.filter(
|
|
385
|
+
pending =>
|
|
386
|
+
pending.signal.kind !== signal.kind ||
|
|
387
|
+
!!pending.signal.adds !== !!signal.adds
|
|
388
|
+
)
|
|
380
389
|
.concat({ signal, pathname })
|
|
381
390
|
.slice(-CHECKOUT_INTENT_BUFFER_LIMIT);
|
|
382
391
|
return;
|